diff options
-rw-r--r-- | Completion/Cvs/.distfiles | 15 | ||||
-rw-r--r-- | Completion/Pbmplus/.distfiles | 19 | ||||
-rw-r--r-- | Completion/Rpm/.distfiles | 7 | ||||
-rw-r--r-- | Completion/User/_gv | 14 | ||||
-rw-r--r-- | Completion/X/.distfiles | 6 | ||||
-rw-r--r-- | Completion/X/_x_display | 3 | ||||
-rw-r--r-- | Completion/X/_x_options | 6 | ||||
-rw-r--r-- | Completion/X/_xfig | 34 | ||||
-rw-r--r-- | Completion/X/_xsetroot | 12 | ||||
-rw-r--r-- | Completion/X/_xterm | 96 | ||||
-rw-r--r-- | Etc/completion-style-guide | 44 | ||||
-rw-r--r-- | Etc/zsh-development-guide | 673 |
12 files changed, 929 insertions, 0 deletions
diff --git a/Completion/Cvs/.distfiles b/Completion/Cvs/.distfiles new file mode 100644 index 000000000..e2f1d55ee --- /dev/null +++ b/Completion/Cvs/.distfiles @@ -0,0 +1,15 @@ +DISTFILES_SRC=' + .distfiles + _cvs _cvs_D _cvs_add _cvs_admin _cvs_admin_t _cvs_annotate _cvs_bindir + _cvs_checkout _cvs_command _cvs_commit _cvs_diff _cvs_diff_arg + _cvs_directories _cvs_edit _cvs_editor _cvs_editors _cvs_export + _cvs_extract_directory_entries _cvs_extract_file_entries + _cvs_extract_modifiedfile_entries _cvs_files _cvs_files_modified + _cvs_files_removed _cvs_files_unmaintained _cvs_gzip_level _cvs_history + _cvs_history_x _cvs_import _cvs_init _cvs_k _cvs_login _cvs_logout + _cvs_m _cvs_modules _cvs_rdiff _cvs_release _cvs_remove _cvs_revisions + _cvs_root _cvs_setup_allentries _cvs_setup_direntries + _cvs_setup_modentries _cvs_setup_prefix _cvs_status _cvs_tag + _cvs_tempdir _cvs_unedit _cvs_update _cvs_user_variable _cvs_watch + _cvs_watchers +' diff --git a/Completion/Pbmplus/.distfiles b/Completion/Pbmplus/.distfiles new file mode 100644 index 000000000..6c979fbd7 --- /dev/null +++ b/Completion/Pbmplus/.distfiles @@ -0,0 +1,19 @@ +DISTFILES_SRC=' + .distfiles + _asciitopnm _fitstopgm _fitstopnm _g3topbm _giftopnm _macptopbm + _pbm_file _pbmclean _pbmmake _pbmmask _pbmpscale _pbmreduce _pbmtext + _pbmto10x _pbmtobg _pbmtoepsi _pbmtolj _pbmtoln03 _pbmtolps _pbmtomacp + _pbmtopgm _pbmtopk _pbmupc _pgmcrater _pgmkernel _pgmnoise _pgmnorm + _pgmoil _pgmramp _pgmtexture _pgmtopbm _pgmtoppm _pktopbm _pnmalias + _pnmarith _pnmcat _pnmcomp _pnmconvol _pnmcrop _pnmcut _pnmdepth + _pnmenlarge _pnmflip _pnmgamma _pnmhistmap _pnmindex _pnmmargin + _pnmnlfilt _pnmpad _pnmpaste _pnmrotate _pnmscale _pnmshear _pnmtile + _pnmtoddif _pnmtofits _pnmtops _pnmtorast _pnmtosgi _pnmtotiff + _pnmtoxwd _ppm3d _ppmbrighten _ppmchange _ppmdim _ppmdist _ppmdither + _ppmflash _ppmforge _ppmmake _ppmmix _ppmntsc _ppmpat _ppmquant + _ppmquantall _ppmshift _ppmspread _ppmtoacad _ppmtobmp _ppmtogif + _ppmtoicr _ppmtoilbm _ppmtomap _ppmtomitsu _ppmtopj _ppmtopjxl + _ppmtosixel _ppmtotga _ppmtouil _ppmtoyuvsplit _psidtopgm _pstopnm + _rawtopgm _rawtoppm _rgb3toppm _sgitopnm _sldtoppm _yuvsplittoppm + _yuvtoppm _zeisstopnm +' diff --git a/Completion/Rpm/.distfiles b/Completion/Rpm/.distfiles new file mode 100644 index 000000000..61e104615 --- /dev/null +++ b/Completion/Rpm/.distfiles @@ -0,0 +1,7 @@ +DISTFILES_SRC=' + .distfiles + _rpm _rpm_arguments _rpm_build _rpm_capability _rpm_install + _rpm_package _rpm_pkg_file _rpm_pkg_or_file _rpm_query _rpm_rebuild + _rpm_rebuilddb _rpm_relocate _rpm_resign _rpm_sigcheck _rpm_tags + _rpm_uninstall _rpm_upgrade _rpm_verify +' diff --git a/Completion/User/_gv b/Completion/User/_gv new file mode 100644 index 000000000..887224a0f --- /dev/null +++ b/Completion/User/_gv @@ -0,0 +1,14 @@ +#compdef gv gview + +_xt_arguments \ + -{,no}{safer,quiet,center,swap,antialias,dsc,eof,pixmap,watch,resize} \ + -{monochrome,grayscale,color,portrait,landscape,upsidedown,seascape,h,help,v,spartan} \ + + '-arguments:ghostscript arguments:' \ + '-page:label of first page:' \ + '-media:page size:(Letter Legal Statement Tabloid Ledger Folio Quarto 10x14 Executive A3 A4 A5 B4 B5)' \ + '-scale:scale entry:' \ + '-scalebase:scale base:' \ + '-ad:resource file:_files' \ + '-style:resource file:_files' + '*:file:_pspdf' diff --git a/Completion/X/.distfiles b/Completion/X/.distfiles new file mode 100644 index 000000000..dd427af1c --- /dev/null +++ b/Completion/X/.distfiles @@ -0,0 +1,6 @@ +DISTFILES_SRC=' + .distfiles + _x_borderwidth _x_display _x_font _x_geometry _x_locale _x_name + _x_options _x_resource _x_selection_timeout _x_title _xdvi _xfig + _xsetroot _xt_arguments _xt_session_id _xterm _xv +' diff --git a/Completion/X/_x_display b/Completion/X/_x_display new file mode 100644 index 000000000..e3f9af479 --- /dev/null +++ b/Completion/X/_x_display @@ -0,0 +1,3 @@ +#autoload + +_hosts -S ':0 ' -r : diff --git a/Completion/X/_x_options b/Completion/X/_x_options new file mode 100644 index 000000000..23243002c --- /dev/null +++ b/Completion/X/_x_options @@ -0,0 +1,6 @@ +#compdef -P */X11/* + +_arguments \ + '-display:display:_x_display' \ + '-geometry:geometry:_x_geometry' \ + "$@" diff --git a/Completion/X/_xfig b/Completion/X/_xfig new file mode 100644 index 000000000..a0d36c189 --- /dev/null +++ b/Completion/X/_xfig @@ -0,0 +1,34 @@ +#compdef xfig + +_x_options \ + -{help,Landscape,Portrait,debug,dontswitchcmap,flushleft,inches,inverse,latexfonts,left,metric,monochrome,multiple,noscalablefonts,notrack,right,scalablefonts,showallbuttons,single,specialtext,tablet,track} \ + '-bold:bold font:_x_font' \ + '-button:button font:_x_font' \ + '-but_per_row:number of buttons:' \ + '-cbg:canvas background color:_colors' \ + '-cfg:canvas foreground color:_colors' \ + '-depth:visual depth:_x_visdepth' \ + '-exportlanguage:export language:(box latex epic eepic eepicemu pictex ibmgl eps ps pstex textyl tpic pic mf acad pcx png gif jpeg tiff ppm xbm xpm)' \ + '-iconGeometry:icon geometry:_x_geometry' \ + '-internalBW:internal border width:' \ + '-keyfile:compose key file:_files' \ + '-magnification:magnification factor:' \ + '-max_image_colors:maximum number of colors:' \ + '-normal:normal font:_x_font' \ + '-papersize:output paper size:((Letter\:8.5\"\ x\ 11\" Legal\:8.5\"\ x\ 14\" Ledger\:17\"\ x\ 11\" Tabloid\:11\"\ x\ 17\" A\:8.5\"\ x\ 11\" B\:11\"\ x\ 17\" C\:17\"\ x\ 22\" D\:22\"\ x\ 34\" E\:34\"\ x\ 44\" A4\:21\ cm\ x\ 29.7\ cm A3\:29.7\ cm\ x\ 42\ cm A2\:42\ cm\ x\ 59.4\ cm A1\:59.4\ cm\ x\ 84.1\ cm A0\:84.1\ cm\ x\ 118.9\ cm B%\:18.2\ cm\ x\ 25.7\ cm))' \ + '-pheight:canvas height:' \ + '-pwidth:canvas width:' \ + '-spellcheckcommand:program: _command_names -e' \ + '-startfillstyle:fill style (-1 to 21):' \ + '-startfontsize:font size (in points):' \ + '-startgridmode:grid mode:((0\:no\ grid 1\:1/4\ inch\ or\ 5\ mm 2\:1/2\ inch\ or\ 1\ cm 3\:1\ inch\ or\ 2\ cm))' \ + '-startlatexfont:latex font:' \ + '-startlinewidth:line width:' \ + '-startposnmode:positioning mode:((0\:any 1\:1/16\ inch\ or\ 1\ mm 2\:1/4\ inch\ or\ 5\ mm 3\:1/2\ inch\ or\ 1\ cm 4\:1\ inch\ or\ 2\ cm))' \ + '-startpsfont:postscript font:' \ + '-starttextstep:text step:' \ + '-userscale:scale factor:' \ + '-userunit:unit string:' \ + '-visual:visual:(TrueColor StaticColor DirectColor StaticGray GrayScale PseudoColor)' \ + '-zoom:zoom scale:' \ + '*:xfig file:_files -g \*.\(\#i\)\(\|x\)fig' diff --git a/Completion/X/_xsetroot b/Completion/X/_xsetroot new file mode 100644 index 000000000..a6f62e998 --- /dev/null +++ b/Completion/X/_xsetroot @@ -0,0 +1,12 @@ +#compdef xsetroot + +_x_options \ + -{help,def,gray,grey,rv} \ + '-cursor:cursor file:_files -g \*.\(\#i\)\(xbm\|curs\(\|or\)\):mask file:_files -g \*.\(\#i\)\(xbm\|curs\(\|or\)\|mask\)' \ + '-cursor_name:cursor name:_cursors' \ + '-bitmap:bitmap file:_files -g \*.\(\#i\)xbm' \ + '-mod:x grid distance (1-16): :y grid distance (1-16):' \ + '-fg:foreground color:_colors' \ + '-bg:background color:_colors' \ + '-solid:screen solid color:_colors' \ + '-name:root window name:' diff --git a/Completion/X/_xterm b/Completion/X/_xterm new file mode 100644 index 000000000..750f7bf88 --- /dev/null +++ b/Completion/X/_xterm @@ -0,0 +1,96 @@ +#compdef xterm + +_xt_arguments \ + -+{ah,ai,aw,bc,bdc,cb,cm,cn,cu,dc,hf,ie,im,j,ls,mb,nul,pc,rw,s,sb,sf,si,sk,sp,t,u8,ulc,ut,vb,wc,wf,samename} \ + -{version,help,132,leftbar,rightbar,C} \ + '-b:inner border size:' \ + '-bcf:time text cursor is off when blinking (milliseconds):' \ + '-bcn:time text cursor is on when blinking (milliseconds):' \ + '-cc:character class:' \ + '-cr:text cursor color:_colors' \ + '-e:program: _command_names -e:*::program arguments: _normal' \ + '-fb:bold font:_x_font' \ + '-fi:icon font:_x_font' \ + '-hc:background color for highlighted text:_colors' \ + '-mc:multi-click threshold (milliseconds):' \ + '-ms:pointer cursor color:_colors' \ + '-nb:margin bell number:' \ + '-sl:save lines:' \ + '-ti:terminal ID:(vt52 vt100 vt101 vt102 vt220)' \ + '-tm:terminal setting:' \ + '-tn:terminal type:' \ + '-ziconbeep:iconbeep (percent):' \ + '-C' \ + '-S-:pseudo-terminal and file descriptor:' +#compdef xterm + +_arguments \ + '-version' \ + '-help' \ + '-132' \ + '-ah' '+ah' \ + '-ai' '+ai' \ + '-aw' '+aw' \ + '-b:inner border size:' \ + '-bc' '+bc' \ + '-bcf:time text cursor is off when blinking (milliseconds):' \ + '-bcn:time text cursor is on when blinking (milliseconds):' \ + '-bdc' '+bdc' \ + '-cb' '+cb' \ + '-cc:character class:' \ + '-cm' '+cm' \ + '-cn' '+cn' \ + '-cr:text cursor color:_color' \ + '-cu' '+cu' \ + '-dc' '+dc' \ + '-e:*::program: _normal' \ + '-fb:bold font:' \ + '-fi:icon font:' \ + '-hc:background color for highlighted text:_color' \ + '-hf' '+hf' \ + '-ie' '+ie' \ + '-im' '+im' \ + '-j' '+j' \ + '-leftbar' \ + '-ls' '+ls' \ + '-mb' '+mb' \ + '-mc:multi-click threshold (milliseconds):' \ + '-ms:pointer cursor color:_color' \ + '-nb:margin bell number:' \ + '-nul' '+nul' \ + '-pc' '+pc' \ + '-rightbar' \ + '-rw' '+rw' \ + '-s' '+s' \ + '-samename' '+samename' \ + '-sb' '+sb' \ + '-sf' '+sf' \ + '-si' '+si' \ + '-sk' '+sk' \ + '-sl:save lines:' \ + '-sp' '+sp' \ + '-t' '+t' \ + '-ti:terminal ID:(vt52 vt100 vt101 vt102 vt220)' \ + '-tm:terminal setting:' \ + '-tn:terminal type:' \ + '-u8' '+u8' \ + '-ulc' '+ulc' \ + '-ut' '+ut' \ + '-vb' '+vb' \ + '-wc' '+wc' \ + '-wf' '+wf' \ + '-ziconbeep:iconbeep (percent):' \ + '-C' \ + '-S-:pseudo-terminal and file descriptor:' \ + '-bd:border color:_color' \ + '-bg:background color:_color' \ + '-bw:border width:' \ + '-display:display:' \ + '-fg:foreground color:_color' \ + '-fn:font:' \ + '-geometry:geometry:' \ + '-iconic' \ + '-name:name:' \ + '-rv' \ + '-title:title:' \ + '-xrm:resource:' diff --git a/Etc/completion-style-guide b/Etc/completion-style-guide new file mode 100644 index 000000000..307954760 --- /dev/null +++ b/Etc/completion-style-guide @@ -0,0 +1,44 @@ +For now this is just a list of things one should or shouldn't do. + +1) Use the functions `_files' and `_path_files' instead of `compgen' + with the `-f', `-/', or `-g' options. +2) *Never* use `compgen' with the `-s' option. This can always be done + by a call to `compadd' which is faster. +3) Using `compgen' with the `-k' option should only be done if a) the + array is already existent or b) it is very large (several hundred + or thousend elements). In other cases using `compadd' is faster. +4) Supply match specifications to `compadd' and `compgen' if there are + sensible ones. +5) Use `_description' when adding matches with `compadd' or + `compgen'. Use `_message' in places where no matches can be + generated. If you want to add different types of matches, add them + with multiple calls to `compadd' or `compgen', supplying different + descriptions. +6) Use helper functions that do option completion for you (like + `_arguments' and `_long_options') -- it will make your life much + easier. +7) Use helper functions like `_users' and `_groups' instead of direct + calls to `compgen -u' or some ad hoc mechanisms to generate such + information. This ensures that user can change the way these things + will be completed everywhere by just using their own implementations + for these functions. +8) Make sure that the return value of your functions is correct: zero + if matches where added and non-zero if no matches were found. + In some cases you'll need to test the value of `$compstate[nmatches]' + for this. This should always be done by first saving the old value + (`local nm="$compstate[nmatches]"') and later comparing this with + the current value after all matches have been added (e.g. by + writing `[[ nmm -ne compstate[nmatches] ]]' at the end of your + function). This guarantees that your functions will be re-usable + because calling functions may rely on the correct return value. +9) In places where different behaviors may be useful, add a + configuration key to allow users to select the behavior they + prefer. Names for configuration keys should look like `prefix_name', + where `prefix' is the (probably abbreviated) name of your function + and `name' describes what can be configured. + When testing the values of configuration keys, the empty string + should result in the same behavior as if the key were unset. This + can be achieved by the test `[[ -n "$compconfig[prefix_name]" ]]'. +10) When writing helper functions that generate matches, the arguments + of these should be given unchanged to `compadd' or `compgen' (if + they are not used by the helper function itself). diff --git a/Etc/zsh-development-guide b/Etc/zsh-development-guide new file mode 100644 index 000000000..4ec4ff079 --- /dev/null +++ b/Etc/zsh-development-guide @@ -0,0 +1,673 @@ +------------------------------ +GUIDELINES FOR ZSH DEVELOPMENT +------------------------------ + +Zsh is currently developed and maintained by the Zsh Development Group. +This development takes place by mailing list. Check the META-FAQ for the +various zsh mailing lists and how to subscribe to them. The development +is very open and anyone is welcomed and encouraged to join and contribute. +Because zsh is a very large package whose development can sometimes +be very rapid, I kindly ask that people observe a few guidelines when +contributing patches and feedback to the mailing list. These guidelines +are very simple and hopefully should make for a more orderly development +of zsh. + +Patches +------- + +* Send all patches to the mailing list rather than directly to me. + +* Send only context diffs "diff -c oldfile newfile" or unified diffs + "diff -u oldfile newfile". They are much easier to read and + understand while also allowing the patch program to patch more + intelligently. Please make sure the filenames in the diff header + are relative to the top-level directory of the zsh distribution; for + example, it should say "Src/init.c" rather than "init.c" or + "zsh/Src/init.c". + +* Please put only one bug fix or feature enhancement in a single patch and + only one patch per mail message. This helps me to multiplex the many + (possibly conflicting) patches that I receive for zsh. You shouldn't + needlessly split patches, but send them in the smallest LOGICAL unit. + +* If a patch depends on other patches, then please say so. Also please + mention what version of zsh this patch is for. + +* Please test your patch and make sure it applies cleanly. It takes + considerably more time to manually merge a patch into the baseline code. + +* There is now a zsh patch archive. To have your patches appear in the + archive, send them to the mailing list with a Subject: line starting + with "PATCH:". + +C coding style +-------------- + +* The primary language is ANSI C as defined by the 1989 standard, but the + code should always be compatible with late K&R era compilers ("The C + Programming Language" 1st edition, plus "void" and "enum"). There are + many hacks to avoid the need to actually restrict the code to K&R C -- + check out the configure tests -- but always bear the compatibility + requirements in mind. In particular, preprocessing directives must + have the "#" unindented, and string pasting is not available. + +* Conversely, there are preprocessor macros to provide safe access to some + language features not present in pure ANSI C, such as variable-length + arrays. Always use the macros if you want to use these facilities. + +* Avoid writing code that generates warnings under gcc with the default + options set by the configure script. For example, write + "if ((foo = bar))" rather than "if (foo = bar)". + +* Please try not using lines longer than 79 characters. + +* The indent/brace style is Kernighan and Ritchie with 4 characters + indentations (with leading tab characters replacing sequences of + 8 spaces). This means that the opening brace is the last character + in the line of the if/while/for/do statement and the closing brace + has its own line: + + if (foo) { + do that + } + +* Put only one simple statement on a line. The body of an if/while/for/do + statement has its own line with 4 characters indentation even if there + are no braces. + +* Do not use space between the function name and the opening parenthesis. + Use space after if/for/while. Use space after type casts. + +* Do not use (unsigned char) casts since some compilers do not handle + them properly. Use the provided STOUC(X) macro instead. + +* If you use emacs 19.30 or newer you can put the following line to your + ~/.emacs file to make these formatting rules the default: + + (add-hook 'c-mode-common-hook (function (lambda () (c-set-style "BSD")))) + +* Function declarations must look like this: + + /**/ + int + foo(char *s, char **p) + { + function body + } + + There must be an empty line, a line with "/**/", a line with the + type of the function, and finally the name of the function with typed + arguments. These lines must not be indented. The script generating + function prototypes and the ansi2knr program depend on this format. + If the function is not used outside the file it is defined in, it + should be declared "static"; this keyword goes on the type line, + before the return type. + +* Global variable declarations must similarly be preceded by a + line containing only "/**/", for the prototype generation script. + The declaration itself should be all on one line (except for multi-line + initialisers). + +* Leave a blank line between the declarations and statements in a compound + statement, if both are present. Use blank lines elsewhere to separate + groups of statements in the interests of clarity. There should never + be two consecutive blank lines. + +Modules +------- + +Modules are described by a file named `foo.mdd' for a module +`foo'. This file is actually a shell script that will sourced when zsh +is build. To describe the module it can/should set the following shell +variables: + + - moddeps modules on which this module depends (default none) + - nozshdep non-empty indicates no dependence on the `zsh' pseudo-module + - alwayslink if non-empty, always link the module into the executable + - autobins builtins defined by the module, for autoloading + - autoinfixconds infix condition codes defined by the module, for + autoloading (without the leading `-') + - autoprefixconds like autoinfixconds, but for prefix condition codes + - autoparams parameters defined by the module, for autoloading + - objects .o files making up this module (*must* be defined) + - proto .pro files for this module (default generated from $objects) + - headers extra headers for this module (default none) + - hdrdeps extra headers on which the .mdh depends (default none) + - otherincs extra headers that are included indirectly (default none) + +Be sure to put the values in quotes. For further enlightenment have a +look at the `mkmakemod.sh' script in the Src directory of the +distribution. + +Modules have to define four functions which will be called automatically +by the zsh core. The first one, named `setup_foo' for a module named +`foo', should set up any data needed in the module, at least any data +other modules may be interested in. The second one, named `boot_foo', +should register all builtins, conditional codes, and function wrappers +(i.e. anything that will be visible to the user) and will be called +after the `setup'-function. +The third one, named `cleanup_foo' for module `foo' is called when the +user tries to unload a module and should de-register the builtins +etc. The last function, `finish_foo' is called when the module is +actually unloaded and should finalize all the data initialized in the +`setup'-function. Since the last two functions are only executed when +the module is used as an dynamically loaded module you can surround +it with `#ifdef MODULE' and `#endif'. +In short, the `cleanup'-function should undo what the `boot'-function +did, and the `finish'-function should undo what the `setup'-function +did. +All of these functions should return zero if they succeeded and +non-zero otherwise. + +Builtins are described in a table, for example: + + static struct builtin bintab[] = { + BUILTIN("example", 0, bin_example, 0, -1, 0, "flags", NULL), + }; + +Here `BUILTIN(...)' is a macro that simplifies the description. Its +arguments are: + - the name of the builtin as a string + - optional flags (see BINF_* in zsh.h) + - the C-function implementing the builtin + - the minimum number of arguments the builtin needs + - the maximum number of arguments the builtin can handle or -1 if + the builtin can get any number of arguments + - an integer that is passed to the handler function and can be used + to distinguish builtins if the same C-function is used to + implement multiple builtins + - the options the builtin accepts, given as a string containing the + option characters (the above example makes the builtin accept the + options `f', `l', `a', `g', and `s') + - and finally a optional string containing option characters that + will always be reported as set when calling the C-function (this, + too, can be used when using one C-function to implement multiple + builtins) + +The definition of the handler function looks like: + + /**/ + static int + bin_example(char *nam, char **args, char *ops, int func) + { + ... + } + +The special comment /**/ is used by the zsh Makefile to generate the +`*.pro' files. The arguments of the function are the number under +which this function was invoked (the name of the builtin, but for +functions that implement more than one builtin this information is +needed). The second argument is the array of arguments *excluding* the +options that were defined in the struct and which are handled by the +calling code. These options are given as the third argument. It is an +array of 256 characters in which the n'th element is non-zero if the +option with ASCII-value n was set (i.e. you can easily test if an +option was used by `if (ops['f'])' etc.). The last argument is the +integer value from the table (the sixth argument to `BUILTIN(...)'). +The integer return value by the function is the value returned by the +builtin in shell level. + +To register builtins in zsh and thereby making them visible to the +user the function `addbuiltins()' is used: + + /**/ + int + boot_example(Module m) + { + int ret; + + ret = addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); + ... + } + +The arguments are the name of the module (taken from the argument in +the example), the table of definitions and the number of entries in +this table. +The return value is 1 if everything went fine, 2 if at least one +builtin couldn't be defined, and 0 if none of the builtin could be +defined. + +To de-register builtins use the function `deletebuiltins()': + + /**/ + int + cleanup_example(Module m) + { + deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); + ... + } + +The arguments and the return value are the same as for `addbuiltins()' + +The definition of condition codes in modules is equally simple. First +we need a table with the descriptions: + + static struct conddef cotab[] = { + CONDDEF("len", 0, cond_p_len, 1, 2, 0), + CONDDEF("ex", CONDF_INFIX, cond_i_ex, 0, 0, 0), + }; + +Again a macro is used, with the following arguments: + + - the name of the condition code without the leading hyphen + (i.e. the example makes the condition codes `-len' and `-ex' + usable in `[[...]]' constructs) + - an optional flag which for now can only be CONDF_INFIX; if this is + given, an infix operator is created (i.e. the above makes + `[[ -len str ]]' and `[[ s1 -ex s2 ]]' available) + - the C-function implementing the conditional + - for non-infix condition codes the next two arguments give the + minimum and maximum number of string the conditional can handle + (i.e. `-len' can get one or two strings); as with builtins giving + -1 as the maximum number means that the conditional accepts any + number of strings + - finally as the last argument an integer that is passed to the + handler function that can be used to distinguish different + condition codes if the same C-function implements more than one of + them + +The definition for the function looks like: + + /**/ + static int + cond_p_len(char **a, int id) + { + ... + } + +The first argument is an array containing the strings (NULL-terminated +like the array of arguments for builtins), the second argument is the +integer value stored in the table (the last argument to `CONDDEF(...)'). +The value returned by the function should be non-zero if the condition +is true and zero otherwise. + +Note that no preprocessing is done on the strings. This means that +no substitutions are performed on them and that they will be +tokenized. There are three helper functions available: + + - char *cond_str(args, num, raw) + The first argument is the array of strings the handler function + got as an argument and the second one is an index into this array. + The return value is the num'th string from the array with + substitutions performed. If the last argument is zero, the string + will also be untokenized. + - long cond_val(args, num) + The arguments are the same as for cond_str(). The return value is + the result of the mathematical evaluation of the num'th string + form the array. + - int cond_match(args, num, str) + Again, the first two arguments are the same as for the other + functions. The third argument is any string. The result of the + function is non-zero if the the num'th string from the array taken + as a glob pattern matches the given string. + +Registering and de-resgitering condition codes with the shell is +almost exactly the same as for builtins, using the functions +`addconddefs()' and `deleteconddefs()' instead: + + /**/ + int + boot_example(Module m) + { + int ret; + + ret = addconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab)); + ... + } + + /**/ + int + cleanup_example(Module m) + { + deleteconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab)); + ... + } + +Arguments and return values are the same as for the functions for +builtins. + +For defining parameters, a module can call `createparam()' directly or +use a table to describe them, e.g.: + + static struct paramdef patab[] = { + PARAMDEF("foo", PM_INTEGER, NULL, get_foo, set_foo, unset_foo), + INTPARAMDEF("exint", &intparam), + STRPARAMDEF("exstr", &strparam), + ARRPARAMDEF("exarr", &arrparam), + }; + +There are four macros used: + + - PARAMDEF() gets as arguments: + - the name of the parameter + - the parameter flags to set for it (from the PM_* flags defined + in zsh.h) + - optionally a pointer to a variable holding the value of the + parameter + - three functions that will be used to get the value of the + parameter, store a value in the parameter, and unset the + parameter + - the other macros provide simple ways to define the most common + types of parameters; they get the name of the parameter and a + pointer to a variable holding the value as arguments; they are + used to define integer-, scalar-, and array-parameters, so the + variables whose addresses are given should be of type `long', + `char *', and `char **', respectively + +For a description of how to write functions for getting or setting the +value of parameters, or how to write a function to unset a parameter, +see the description of the following functions in the `params.c' file: + + - `intvargetfn()' and `intvarsetfn()' for integer parameters + - `strvargetfn()' and `strvarsetfn()' for scalar parameters + - `arrvargetfn()' and `arrvarsetfn()' for array parameters + - `stdunsetfn()' for unsetting parameters + +Note that if one defines parameters using the last two macros (for +scalars and arrays), the variable holding the value should be +initialized to either `NULL' or to a a piece of memory created with +`zalloc()'. But this memory should *not* be freed in the +finish-function of the module because that will be taken care of by +the `deleteparamdefs()' function described below. + +To register the parameters in the zsh core, the function +`addparamdefs()' is called as in: + + /**/ + int + boot_example(Module m) + { + int ret; + + ret = addparamdefs(m->nam, patab, sizeof(patab)/sizeof(*patab)) + ... + } + +The arguments and the return value are as for the functions used to +add builtins and condition codes and like these, it should be called +in the boot-function of the module. To remove the parameters defined, +the function `deleteparamdefs()' should be called, again with the same +arguments and the same return value as for the functions to remove +builtins and condition codes: + + /**/ + int + cleanup_example(Module m) + { + deleteparamdefs(m->nam, patab, sizeof(patab)/sizeof(*patab)); + ... + } + +Modules can also define function hooks. Other modules can then add +functions to these hooks to make the first module call these functions +instead of the default. + +Again, an array is used to define hooks: + + static struct hookdef foohooks[] = { + HOOKDEF("foo", foofunc, 0), + }; + +The first argument of the macro is the name of the hook. This name +is used whenever the hook is used. The second argument is the default +function for the hook or NULL if no default function exists. The +last argument is used to define flags for the hook. Currently only one +such flag is defined: `HOOKF_ALL'. If this flag is given and more than +one function was added to the hook, all functions will be called +(including the default function). Otherwise only the last function +added will be called. + +The functions that can be used as default functions or that can be +added to a hook have to be defined like: + + /**/ + static int + foofunc(Hookdef h, void *data) + { + ... + } + +The first argument is a pointer to the struct defining the hook. The +second argument is an arbitrary pointer that is given to the function +used to invoke hooks (see below). + +The functions to register and de-register hooks look like those for +the other things that can be defined by modules: + + /**/ + int + boot_foo(Module m) + { + int ret; + + ret = addhookdefs(m->nam, foohooks, sizeof(foohooks)/sizeof(*foohooks)) + ... + } + ... + /**/ + int + cleanup_foo(Module m) + { + deletehookdefs(m->nam, foohooks, sizeof(foohooks)/sizeof(*foohooks)); + ... + } + +Modules that define hooks can invoke the function(s) registered for +them by calling the function `runhook(name, data)'. The first argument +is the name of the hook and the second one is the pointer given to the +hook functions as their second argument. Hooks that have the `HOOKF_ALL' +flag call all function defined for them until one returns non-zero. +The return value of `runhook()' is the return value of the last hook +function called or zero if none was called. + +To add a function to a hook, the function `addhookfunc(name, func)' is +called with the name of the hook and a hook function as arguments. +Deleting them is done by calling `deletehookfunc(name, func)' with the +same arguments as for the corresponding call to `addhookfunc()'. + +Alternative forms of the last three function are provided for hooks +that are changed or called very often. These functions, +`runhookdef(def, data)', `addhookdeffunc(def, func)', and +`deletehookdeffunc(def, func)' get a pointer to the `hookdef' +structure defining the hook instead of the name and otherwise behave +like their counterparts. + +Modules can also define function hooks. Other modules can then add +functions to these hooks to make the first module call these functions +instead of the default. + +Again, an array is used to define hooks: + + static struct hookdef foohooks[] = { + HOOKDEF("foo", foofunc, 0), + }; + +The first argument of the macro is the name of the hook. This name +is used whenever the hook is used. The second argument is the default +function for the hook or NULL if no default function exists. The +last argument is used to define flags for the hook. Currently only one +such flag is defined: `HOOKF_ALL'. If this flag is given and more than +one function was added to the hook, all functions will be called +(including the default function). Otherwise only the last function +added will be called. + +The functions that can be used as default functions or that can be +added to a hook have to be defined like: + + /**/ + static int + foofunc(Hookdef h, void *data) + { + ... + } + +The first argument is a pointer to the struct defining the hook. The +second argument is an arbitrary pointer that is given to the function +used to invoke hooks (see below). + +The functions to register and de-register hooks look like those for +the other things that can be defined by modules: + + /**/ + int + boot_foo(Module m) + { + int ret; + + ret = addhookdefs(m->nam, foohooks, sizeof(foohooks)/sizeof(*foohooks)) + ... + } + ... + /**/ + int + cleanup_foo(Module m) + { + deletehookdefs(m->nam, foohooks, sizeof(foohooks)/sizeof(*foohooks)); + ... + } + +Modules that define hooks can invoke the function(s) registered for +them by calling the function `runhook(name, data)'. The first argument +is the name of the hook and the second one is the pointer given to the +hook functions as their second argument. Hooks that have the `HOOKF_ALL' +flag call all function defined for them until one returns non-zero. +The return value of `runhook()' is the return value of the last hook +function called or zero if none was called. + +To add a function to a hook, the function `addhookfunc(name, func)' is +called with the name of the hook and a hook function as arguments. +Deleting them is done by calling `deletehookfunc(name, func)' with the +same arguments as for the corresponding call to `addhookfunc()'. + +Alternative forms of the last three function are provided for hooks +that are changed or called very often. These functions, +`runhookdef(def, data)', `addhookdeffunc(def, func)', and +`deletehookdeffunc(def, func)' get a pointer to the `hookdef' +structure defining the hook instead of the name and otherwise behave +like their counterparts. + +Finally, modules can define wrapper functions. These functions are +called whenever a shell function is to be executed. + +The definition is simple: + + static struct funcwrap wrapper[] = { + WRAPDEF(ex_wrapper), + }; + +The macro `WRAPDEF(...)' gets the C-function as its only argument. +This function should be defined like: + + /**/ + static int + ex_wrapper(List list, FuncWrap w, char *name) + { + ... + runshfunc(list, w, name); + ... + return 0; + } + +The first two arguments should only be used to pass them to +`runshfunc()' which will execute the shell function. The last argument +is the name of the function to be executed. The arguments passed to +the function can be accessed vie the global variable `pparams' (a +NULL-terminated array of strings). +The return value of the wrapper function should be zero if it calls +`runshfunc()' itself and non-zero otherwise. This can be used for +wrapper functions that only need to run under certain conditions or +that don't need to clean anything up after the shell function has +finished: + + /**/ + static int + ex_wrapper(List list, FuncWrap w, char *name) + { + if (wrapper_need_to_run) { + ... + runshfunc(list, w, name); + ... + return 0; + } + return 1; + } + +Inside these wrapper functions the global variable `sfcontext' will be +set to a vlue indicating the circumstances under which the shell +function was called. It can have any of the following values: + + - SFC_DIRECT: the function was invoked directly by the user + - SFC_SIGNAL: the function was invoked as a signal handler + - SFC_HOOK: the function was automatically invoked as one of the + special functions known by the shell (like `chpwd') + - SFC_WIDGET: the function was called from the zsh line editor as a + user-defined widget + - SFC_COMPLETE: the function was called from the completion code + (e.g. with `compctl -K func') + +If a module invokes a shell function (e.g. as a hook function), the +value of this variable should only be changed temporarily and restored +to its previous value after the shell function has finished. + +There is a problem when the user tries to unload a module that has +defined wrappers from a shell function. In this case the module can't +be unloaded immediately since the wrapper function is still on the +call stack. The zsh code delays unloading modules until all wrappers +from them have finished. To hide this from the user, the module's +cleanup function is run immediatly so that all builtins, condition +codes, and wrapper function defined by the module are +de-registered. But if there is some module-global state that has to be +finalized (e.g. some memory that has to be freed) and that is used by +the wrapper functions finalizing this data in the cleanup function +won't work. +This is why ther are two functions each for the initialization and +finalization of modules. The `boot'- and `cleanup'-functions are run +whenever the user calls `zmodload' or `zmodload -u' and should only +register or de-register the module's interface that is visible to the +user. Anything else should be done in the `setup'- and +`finish'-functions. Otherwise modules that other modules depend upon +may destroy their state too early and wrapper functions in the latter +modules may stop working since the state they use is already destroyed. + +Documentation +------------- + +* Edit only the .yo files. All other formats (man pages, TeXinfo, HTML, + etc.) are automatically generated from the yodl source. + +* Always use the correct markup. em() is used for emphasis, and bf() + for citations. tt() marks text that is literal input to or output + from the shell. var() marks metasyntactic variables. + +* In addition to appropriate markup, always use quotes (`') where + appropriate. Specifically, use quotes to mark text that is not a part + of the actual text of the documentation (i.e., that it is being quoted). + In principle, all combinations of quotes and markup are possible, + because the purposes of the two devices are completely orthogonal. + For example, + + Type `tt(xyzzy)' to let zsh know you have played tt(advent). + Saying `plugh' aloud doesn't have much effect, however. + + In this case, "zsh" is normal text (a name), "advent" is a command name + ocurring in the main text, "plugh" is a normal word that is being quoted + (it's the user that says `plugh', not the documentation), and "xyzzy" + is some text to be typed literally that is being quoted. + +* For multiple-line pieces of text that should not be filled, there are + various models. + - If the text is pure example, i.e. with no metasyntactic variables etc., + it should be included within `example(...)'. The text will be + indented, will not be filled and will be put into a fixed width font. + - If the text includes mixed fonts, it should be included within + `indent(...)'. The text is now filled unless `nofill(...)' is also + used, and explicit font-changing commands are required inside. + - If the text appears inside some other format, such as for example the + `item()' list structure, then the instruction `nofill(...)', which + simply turns off filling should be used; as with `indent(...)', + explicit font changing commands are required. This can be used + without `indent()' when no identation is required, e.g. if the + accumulated indentation would otherwise be too long. + All the above should appear on their own, separated by newlines from the + surrounding text. No extra newlines after the opening or before the + closing parenthesis are required. |