From fd43209f3ac0b5e85def5951ad7e5db3c8535595 Mon Sep 17 00:00:00 2001 From: fishBone000 Date: Tue, 17 Sep 2024 06:37:21 +0000 Subject: [PATCH] Beginning of zh_cn translation --- zsh-completions-howto.org.zh | 464 +++++++++++++++++++++++++++++++++++ 1 file changed, 464 insertions(+) create mode 100644 zsh-completions-howto.org.zh diff --git a/zsh-completions-howto.org.zh b/zsh-completions-howto.org.zh new file mode 100644 index 0000000..094e29b --- /dev/null +++ b/zsh-completions-howto.org.zh @@ -0,0 +1,464 @@ +* Table of Contents :TOC: +- [[#intro][Intro]] +- [[#getting-started][Getting started]] + - [[#telling-zsh-which-function-to-use-for-completing-a-command][Telling zsh which function to use for completing a command]] + - [[#completing-generic-gnu-commands][Completing generic gnu commands]] + - [[#copying-completions-from-another-command][Copying completions from another command]] +- [[#writing-your-own-completion-functions][Writing your own completion functions]] + - [[#utility-functions][Utility functions]] + - [[#writing-simple-completion-functions-using-_describe][Writing simple completion functions using _describe]] + - [[#writing-completion-functions-using-_alternative][Writing completion functions using _alternative]] + - [[#writing-completion-functions-using-_arguments][Writing completion functions using _arguments]] + - [[#writing-completion-functions-using-_regex_arguments-and-_regex_words][Writing completion functions using _regex_arguments and _regex_words]] + - [[#complex-completions-with-_values-_sep_parts--_multi_parts][complex completions with _values, _sep_parts, & _multi_parts]] + - [[#adding-completion-words-directly-using-compadd][Adding completion words directly using compadd]] +- [[#testing--debugging][Testing & debugging]] +- [[#gotchas-things-to-watch-out-for][Gotchas (things to watch out for)]] +- [[#tips][Tips]] +- [[#other-resources][Other resources]] + +* Intro +The official documentation for writing zsh completion functions is difficult to understand, and doesn't give many examples. +At the time of writing this document I was able to find a few other tutorials on the web, however those tutorials only +explain a small portion of the capabilities of the completion system. This document aims to cover areas not explained elsewhere, +with examples, so that you can learn how to write more advanced completion functions. I do not go into all the details, but will +give enough information and examples to get you up and running. If you need more details you can look it up for yourself in the + [[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][official documentation]]. + +Please make any scripts that you create publicly available for others (e.g. by forking this repo and making a [[id:64bcd501-b0f0-48c7-b8e2-07af708b95ec][pull request]]). +Also if you have any more information to add or improvements to make to this tutorial, please do. +* Getting started +** Telling zsh which function to use for completing a command +Completion functions for commands are stored in files with names beginning with an underscore _, and these files should +be placed in a directory listed in the $fpath variable. +You can add a directory to $fpath by adding a line like this to your ~/.zshrc file: +#+BEGIN_SRC sh +fpath=(~/newdir $fpath) +#+END_SRC +The first line of a completion function file can look something like this: +#+BEGIN_SRC sh +#compdef foobar +#+END_SRC +This tells zsh that the file contains code for completing the foobar command. +This is the format that you will use most often for the first line, but you can also use the same file for completing +several different functions if you want. See [[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Autoloaded-files][here]] for more details. + +You can also use the compdef command directly (e.g. in your ~/.zshrc file) to tell zsh which function to use for completing +a command like this: +#+BEGIN_SRC sh +> compdef _function foobar +#+END_SRC +or to use the same completions for several commands: +#+BEGIN_SRC sh +> compdef _function foobar goocar hoodar +#+END_SRC +or if you want to supply arguments: +#+BEGIN_SRC sh +> compdef '_function arg1 arg2' foobar +#+END_SRC +See [[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Functions-4][here]] for more details. +** Completing generic gnu commands +Many [[https://www.gnu.org/][gnu]] commands have a standardized way of listing option descriptions (when the --help option is used). +For these commands you can use the _gnu_generic function for automatically creating completions, like this: +#+BEGIN_SRC sh +> compdef _gnu_generic foobar +#+END_SRC +or to use _gnu_generic with several different commands: +#+BEGIN_SRC sh +> compdef _gnu_generic foobar goocar hoodar +#+END_SRC +This line can be placed in your ~/.zshrc file. +** Copying completions from another command +If you want a command, say cmd1, to have the same completions as another, say cmd2, which has already had +completions defined for it, you can do this: +#+BEGIN_SRC sh +> compdef cmd1=cmd2 +#+END_SRC +This can be useful for example if you have created an alias for a command to help you remember it. +* Writing your own completion functions +A good way to get started is to look at some already defined completion functions. +On my linux installation these are found in /usr/share/zsh/functions/Completion/Unix +and /usr/share/zsh/functions/Completion/Linux and a few other subdirs. + +You will notice that the _arguments function is used a lot in these files. +This is a utility function that makes it easy to write simple completion functions. +The _arguments function is a wrapper around the compadd builtin function. +The compadd builtin is the core function used to add completion words to the command line, and control its behaviour. +However, most of the time you will not need to use compadd, since there are many utility functions such as _arguments +and _describe which are easier to use. + +For very basic completions the _describe function should be adequate + +** Utility functions +Here is a list of some of the utility functions that may be of use. +The full list of utility functions, with full explanations, is available [[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-Functions][here]]. +Examples of how to use these functions are given in the next section. + +*** main utility functions for overall completion +| _alternative | Can be used to generate completion candidates from other utility functions or shell code. | +| _arguments | Used to specify how to complete individual options & arguments for a command with unix style options. | +| _describe | Used for creating simple completions consisting of words with descriptions (but no actions). Easier to use than _arguments | +| _gnu_generic | Can be used to complete options for commands that understand the `--help' option. | +| _regex_arguments | Creates a function for matching commandline arguments with regular expressions, and then performing actions/completions. | +*** functions for performing complex completions of single words +| _values | Used for completing arbitrary keywords (values) and their arguments, or comma separated lists of such combinations. | +| _combination | Used to complete combinations of values, for example pairs of hostnames and usernames. | +| _multi_parts | Used for completing multiple parts of words separately where each part is separated by some char, e.g. for completing partial filepaths: /u/i/sy -> /usr/include/sys | +| _sep_parts | Like _multi_parts but allows different separators at different parts of the completion. | +| _sequence | Used as a wrapper around another completion function to complete a delimited list of matches generated by that other function. +*** functions for completing specific types of objects +| _path_files | Used to complete filepaths. Take several options to control behaviour. | +| _files | Calls _path_files with all options except -g and -/. These options depend on file-patterns style setting. | +| _net_interfaces | Used for completing network interface names | +| _users | Used for completing user names | +| _groups | Used for completing group names | +| _options | Used for completing the names of shell options. | +| _parameters | Used for completing the names of shell parameters/variables (can restrict to those matching a pattern). | +*** functions for handling cached completions +If you have a very large number of completions you can save them in a cache file so that the completions load quickly. +| _cache_invalid | indicates whether the completions cache corresponding to a given cache identifier needs rebuilding | +| _retrieve_cache | retrieves completion information from a cache file | +| _store_cache | store completions corresponding to a given cache identifier in a cache file | +*** other functions +| _message | Used for displaying help messages in places where no completions can be generated. | +| _regex_words | Can be used to generate arguments for the _regex_arguments command. This is easier than writing the arguments manually. | +| _guard | Can be used in the ACTION of specifications for _arguments and similar functions to check the word being completed. | +*** Actions +Many of the utility functions such as _arguments, _regex_arguments, _alternative and _values may include an action +at the end of an option/argument specification. This action indicates how to complete the corresponding argument. +The actions can take one of the following forms: +| ( ) | Argument is required but no matches are generated for it. | +| (ITEM1 ITEM2) | List of possible matches | +| ((ITEM1\:'DESC1' ITEM2\:'DESC2')) | List of possible matches, with descriptions. Make sure to use different quotes than those around the whole specification. | +| ->STRING | Set $state to STRING and continue ($state can be checked in a case statement after the utility function call) | +| FUNCTION | Name of a function to call for generating matches or performing some other action, e.g. _files or _message | +| {EVAL-STRING} | Evaluate string as shell code to generate matches. This can be used to call a utility function with arguments, e.g. _values or _describe | +| =ACTION | Inserts a dummy word into completion command line without changing the point at which completion takes place. | +Not all action types are available for all utility functions that use them. For example the ->STRING type is not available in the +_regex_arguments or _alternative functions. +** Writing simple completion functions using _describe +The _describe function can be used for simple completions where the order and position of the options/arguments is +not important. You just need to create an array parameter to hold the options & their descriptions, and then pass +the parameter name as an argument to _describe. The following example creates completion candidates c and d, with +the descriptions (note this should be put in a file called _cmd in some directory listed in $fpath). +#+BEGIN_SRC sh +#compdef cmd +local -a subcmds +subcmds=('c:description for c command' 'd:description for d command') +_describe 'command' subcmds +#+END_SRC + +You can use several different lists separated by a double hyphen as follows but note that this mixes the matches under and single heading and is not intended to be used with different types of completion candidates: +#+BEGIN_SRC sh +local -a subcmds topics +subcmds=('c:description for c command' 'd:description for d command') +topics=('e:description for e help topic' 'f:description for f help topic') +_describe 'command' subcmds -- topics +#+END_SRC + +If two candidates have the same description, _describe collects them together on the same row and ensures that descriptions are aligned in neatly in columns. +The _describe function can be used in an ACTION as part of a specification for _alternative, _arguments or _regex_arguments. +In this case you will have to put it in braces with its arguments, e.g. 'TAG:DESCRIPTION:{_describe 'values' options}' +** Writing completion functions using _alternative +Like _describe, this function performs simple completions where the order and position of options/arguments is not important. +However, unlike _describe, instead of fixed matches further functions may be called to generate the completion candidates. Furthermore, _alternative allows a mix of different types of completion candidates to be mixed. + +As arguments it takes a list of specifications each in the form 'TAG:DESCRIPTION:ACTION' where TAG is a special tag that identifies the type of completion matches, +DESCRIPTION is used as a heading to describe the group of completion candidates collectively, and ACTION is one of the action types listed previously (apart from the ->STRING and =ACTION forms). +For example: +#+BEGIN_SRC sh +_alternative 'arguments:custom arg:(a b c)' 'files:filename:_files' +#+END_SRC +The first specification adds completion candidates a, b & c, and the second specification calls the _files function for completing filepaths. + +We could split the specifications over several lines with \ and add descriptions to each of the custom args like this: +#+BEGIN_SRC sh +_alternative \ + 'args:custom arg:((a\:"description a" b\:"description b" c\:"description c"))' \ + 'files:filename:_files' +#+END_SRC + +If we want to pass arguments to _files they can simply be included, like this: +#+BEGIN_SRC sh +_alternative \ + 'args:custom arg:((a\:"description a" b\:"description b" c\:"description c"))'\ + 'files:filename:_files -/' +#+END_SRC + +To use parameter expansion to create our list of completions we must use double quotes to quote the specifications, +e.g: +#+BEGIN_SRC sh +_alternative \ + "dirs:user directory:($userdirs)" \ + "pids:process ID:($(ps -A o pid=))" +#+END_SRC +In this case the first specification adds the words stored in the $userdirs variable, and the second specification +evaluates 'ps -A o pid=' to get a list of pids to use as completion candidates. In practice, we would make used of the existing _pids function for this. + +We can use other utility functions such as _values in the ACTION to perform more complex completions, e.g: +#+BEGIN_SRC sh +_alternative \ + "directories:user directory:($userdirs)" \ + 'options:comma-separated opt: _values -s , letter a b c' +#+END_SRC +this will complete the items in $userdirs, as well as a comma separated list containing a, b &/or c. Note the use of the initial space before _values. This is needed because _values doesn't understand standard compadd options for descriptions. + +As with _describe, the _alternative function can itself be used in an ACTION as part of a specification for _arguments +or _regex_arguments. +** Writing completion functions using _arguments +With a single call to the _arguments function you can create fairly sophisticated completion functions. It is intended to handle typical commands that take a variety of options along with some normal arguments. +Like the _alternative function, _arguments takes a list of specification strings as arguments. +These specification strings specify options and any corresponding option arguments (e.g. -f filename), +or command arguments. + +Basic option specifications take the form '-OPT[DESCRIPTION]', e.g. like this: +#+BEGIN_SRC sh +_arguments '-s[sort output]' '--l[long output]' '-l[long output]' +#+END_SRC +Arguments for the option can be specified after the option description in this form '-OPT[DESCRIPTION]:MESSAGE:ACTION', +where MESSAGE is a message to display and ACTION can be any of the forms mentioned in the ACTIONS section above. +For example: +#+BEGIN_SRC sh +_arguments '-f[input file]:filename:_files' +#+END_SRC + +Command argument specifications take the form 'N:MESSAGE:ACTION' where N indicates that it is the Nth command argument, +and MESSAGE & ACTION are as before. If the N is omitted then it just means the next command argument (after any that have +already been specified). If a double colon is used at the start (after N) then the argument is optional. +For example: +#+BEGIN_SRC sh +_arguments '-s[sort output]' '1:first arg:_net_interfaces' '::optional arg:_files' ':next arg:(a b c)' +#+END_SRC +here the first arg is a network interface, the next optional arg is a file name, the last arg can be either a, b or c, +and the -s option may be completed at any position. + +The _arguments function allows the full set of ACTION forms listed in the ACTION section above. +This means that you can use actions for selecting case statement branches like this: +#+BEGIN_SRC sh +_arguments '-m[music file]:filename:->files' '-f[flags]:flag:->flags' +case "$state" in + files) + local -a music_files + music_files=( Music/**/*.{mp3,wav,flac,ogg} ) + _multi_parts / music_files + ;; + flags) + _values -s , 'flags' a b c d e + ;; +esac +#+END_SRC +In this case paths to music files are completed stepwise descending down directories using the _multi_parts function, +and the flags are completed as a comma separated list using the _values function. + +I have just given you the basics of _arguments specifications here, you can also specify mutually exclusive options, +repeated options & arguments, options beginning with + instead of -, etc. For more details see the [[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][official documentation]]. +Also have a look at the tutorials mentioned at the end of this document, and the completion functions in the [[https://github.com/vapniks/zsh-completions/tree/master/src][src directory]]. +** Writing completion functions using _regex_arguments and _regex_words +If you have a complex command line specification with several different possible argument sequences then +the _regex_arguments function may be what you need. It typically works well where you have a series of keywords followed by a variable number of arguments. + +_regex_arguments creates a completion function whose name is given by the first argument. +Hence you need to first call _regex_arguments to create the completion function, and then call that function, +e.g. like this: +#+BEGIN_SRC sh +_regex_arguments _cmd OTHER_ARGS.. +_cmd "$@" +#+END_SRC + +The OTHER_ARGS should be sequences of specifications for matching & completing words on the command line. +These sequences can be separated by '|' to represent alternative sequences of words. +You can use bracketing to arbitrary depth to specify alternate subsequences, but the brackets must be backslashed like this \( \) +or quoted like this '(' ')'. + +For example: +#+BEGIN_SRC sh +_regex_arguments _cmd SEQ1 '|' SEQ2 \( SEQ2a '|' SEQ2b \) +_cmd "$@" +#+END_SRC +This specifies a command line matching either SEQ1, or SEQ2 followed by SEQ2a or SEQ2b. You are describing the form arguments to the command take in the form of a regular expression grammar. + +Each specification in a sequence must contain a / PATTERN/ part at the start followed by an optional ':TAG:DESCRIPTION:ACTION' +part. + +Each PATTERN is a regular expression to match a word on the command line. These patterns are processed sequentially +until we reach a pattern that doesn't match at which point any corresponding ACTION is performed to obtain completions +for that word. Note that there needs to be a pattern to match the initial command itself. +See below for further explanation about PATTERNs. + +The ':TAG:DESCRIPTION:ACTION' part is interpreted in the same way as for the _alternative function specifications, +except that it has an extra : at the start, and now all of the possible ACTION formats listed previously are allowed. + +Here is an example: +#+BEGIN_SRC sh +_regex_arguments _cmd /$'[^\0]##\0'/ \( /$'word1(a|b|c)\0'/ ':word:first word:(word1a word1b word1c)' '|'\ + /$'word11(a|b|c)\0'/ ':word:first word:(word11a word11b word11c)' \( /$'word2(a|b|c)\0'/ ':word:second word:(word2a word2b word2c)'\ + '|' /$'word22(a|b|c)\0'/ ':word:second word:(word22a word22b word22c)' \) \) +_cmd "$@" +#+END_SRC +in this case the first word can be word1 or word11 followed by an a, b or c, and if the first word contains 11 then a second +word is allowed which can be word2 followed by and a, b, or c, or a filename. + +If this sounds too complicated a much simpler alternative is to use the _regex_words function for creating +specifications for _regex_arguments. +*** Patterns +You may notice that the / PATTERN/ specs in the previous example don't look like normal regular expressions. +Often a string parameter in the form $'foo\0' is used. This is so that the \0 in the string is interpreted correctly +as a null char which is used to separate words in the internal representation. If you don't include the \0 at the end +of the pattern you may get problems matching the next word. If you need to use the contents of a variable in a pattern, +you can double quote it so that it gets expanded and then put a string parameter containing a null char afterwards, +like this: "$somevar"$'\0' + +The regular expression syntax for patterns seems to be a bit different from normal regular expressions, +and I can't find documentation anywhere. +However I have managed to work out what the following special chars are for: +| * | wildcard - any number of chars | +| ? | wildcard - single char | +| # | zero or more of the previous char (like * in a normal regular expression) | +| ## | one or more of the previous char (like + in a normal regular expression) | +*** _regex_words +The _regex_words function makes it much easier to create specifications for _regex_arguments. +The results of calling _regex_words can be stored in a variable which can then be used instead +of a specification for _regex_arguments. + +To create a specification using _regex_words you supply it with a tag followed by a description followed by a list +of specifications for individual words. These specifications take the form 'WORD:DESCRIPTION:SPEC' where WORD is the +word to be completed, DESCRIPTION is a description for it, and SPEC can be another variable created by _regex_words +specifying words that come after the current word or blank if there are no further words. +For example: +#+BEGIN_SRC sh +_regex_words firstword 'The first word' 'word1a:a word:' 'word1b:b word:' 'word1c:c word' +#+END_SRC +the results of this function call will be stored in the $reply array, and so we should store it in another array +before $reply gets changed again, like this: +#+BEGIN_SRC sh +local -a firstword +_regex_words word 'The first word' 'word1a:a word:' 'word1b:b word:' 'word1c:c word' +firstword="$reply[@]" +#+END_SRC +we could then use it with _regex_arguments like this: +#+BEGIN_SRC sh +_regex_arguments _cmd /$'[^\0]##\0'/ "$firstword[@]" +_cmd "$@" +#+END_SRC +Note that I have added an extra pattern for the initial command word itself. + +Here is a more complex example where we call _regex_words for different words on the command line +#+BEGIN_SRC sh +local -a firstword firstword2 secondword secondword2 +_regex_words word1 'The second word' 'woo:tang clan' 'hoo:not me' +secondword=("$reply[@]") +_regex_words word2 'Another second word' 'yee:thou' 'haa:very funny!' +secondword2=("$reply[@]") +_regex_words commands 'The first word' 'foo:do foo' 'man:yeah man' 'chu:at chu' +firstword=("$reply[@]") +_regex_words word4 'Another first word' 'boo:scare somebody:$secondword' 'ga:baby noise:$secondword'\ + 'loo:go to the toilet:$secondword2' +firstword2=("$reply[@]") + +_regex_arguments _hello /$'[^\0]##\0'/ "${firstword[@]}" "${firstword2[@]}" +_hello "$@" +#+END_SRC +In this case the first word can be one of "foo", "man", "chu", "boo", "ga" or "loo". +If the first word is "boo" or "ga" then the second word can be "woo" or "hoo", +and if the first word is "loo" then the second word can be "yee" or "haa", in the other +cases there is no second word. + +For a good example of the usage of _regex_words have a look at the _ip function. +** complex completions with _values, _sep_parts, & _multi_parts +The _values, _sep_parts & _multi_parts functions can be used either on their own, or as ACTIONs in specifications for +_alternative, _arguments or _regex_arguments. The following examples may be instructive. +See the [[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][official documentation]] for more info. + +Space separated list of mp3 files: +#+BEGIN_SRC sh +_values 'mp3 files' ~/*.mp3 +#+END_SRC + +Comma separated list of session id numbers: +#+BEGIN_SRC sh +_values -s , 'session id' "${(uonzf)$(ps -A o sid=)}" +#+END_SRC + +Completes foo@news:woo, or foo@news:laa, or bar@news:woo, etc: +#+BEGIN_SRC sh +_sep_parts '(foo bar)' @ '(news ftp)' : '(woo laa)' +#+END_SRC + +Complete some MAC addresses one octet at a time: +#+BEGIN_SRC sh +_multi_parts : '(00:11:22:33:44:55 00:23:34:45:56:67 00:23:45:56:67:78)' +#+END_SRC + +** Adding completion words directly using compadd +For more fine grained control you can use the builtin compadd function to add completion words directly. +This function has many different options for controlling how completions are displayed and how text on the command line +can be altered when words are completed. Read the [[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][official documentation]] for full details. +Here I just give a few simple examples. + +Add some words to the list of possible completions: +#+BEGIN_SRC sh +compadd foo bar blah +#+END_SRC + +As above but also display an explanation: +#+BEGIN_SRC sh +compadd -X 'Some completions' foo bar blah +#+END_SRC + +As above but automatically insert a prefix of "what_" before the completed word: +#+BEGIN_SRC sh +compadd -P what_ foo bar blah +#+END_SRC + +As above but automatically insert a suffix of "_todo" after the completed word: +#+BEGIN_SRC sh +compadd -S _todo foo bar blah +#+END_SRC + +As above but automatically remove the "_todo" suffix if a blank char is typed after the suffix: +#+BEGIN_SRC sh +compadd -P _todo -q foo bar blah +#+END_SRC + +Add words in array $wordsarray to the list of possible completions +#+BEGIN_SRC sh +compadd -a wordsarray +#+END_SRC + +* Testing & debugging +To reload a completion function: +#+BEGIN_SRC sh +> unfunction _func +> autoload -U _func +#+END_SRC + +The following functions can be called to obtain useful information. +If the default keybindings don't work you can try pressing Alt+x and then enter the command name. +| Function | Default keybinding | Description | +|-----------------+--------------------+--------------------------------------------------------------------------------------------------------------------------------| +| _complete_help | Ctrl+x h | displays information about context names, tags, and completion functions used when completing at the current cursor position | +| _complete_help | Alt+2 Ctrl+x h | as above but displays even more information | +| _complete_debug | Ctrl+x ? | performs ordinary completion, but captures in a temporary file a trace of the shell commands executed by the completion system | +* Gotchas (things to watch out for) +Remember to include a #compdef line at the beginning of the file containing the completion function. + +Take care to use the correct type of quoting for specifications to _arguments or _regex_arguments: +use double quotes if there is a parameter that needs to be expanded in the specification, single quotes otherwise, +and make sure to use different quotes around item descriptions. + +Check that you have the correct number of :'s in the correct places for specifications for _arguments, +_alternative, _regex_arguments, etc. + +Remember to include an initial pattern to match the command word when using _regex_arguments (it does not need a matching action). + +Remember to put a null char $'\0' at the end of any PATTERN argument for _regex_arguments +* Tips +Sometimes you have a situation where there is just one option that can come after a subcommand, and zsh will complete this +automatically when tab is pressed after the subcommand. If instead you want it listed with its description before completing +you can add another empty option (i.e. \:) to the ACTION like this ':TAG:DESCRIPTION:((opt1\:"description for opt1" \:))' +Note this only applies to utility functions that use ACTIONs in their specification arguments (_arguments, _regex_arguments, etc.) + +* Other resources +[[https://wikimatze.de/writing-zsh-completion-for-padrino/][Here]] is a nicely formatted short tutorial showing basic usage of the _arguments function, +and [[https://web.archive.org/web/20190411104837/http://www.linux-mag.com/id/1106/][here]] is a slightly more advanced tutorial using the _arguments function. +[[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][Here]] is the zshcompsys man page.