diff options
author | Peter Stephenson <pws@users.sourceforge.net> | 2000-04-01 20:43:43 +0000 |
---|---|---|
committer | Peter Stephenson <pws@users.sourceforge.net> | 2000-04-01 20:43:43 +0000 |
commit | e025336f2f6d9f107ee1e03b9900f04af0544ba9 (patch) | |
tree | 37b0ce74587d42d4bcb024991526d2361fcdf04a /Etc | |
parent | 20c5fbe688f24010c578c48d4b4d228f0e1a56c3 (diff) | |
download | zsh-e025336f2f6d9f107ee1e03b9900f04af0544ba9.tar.gz zsh-e025336f2f6d9f107ee1e03b9900f04af0544ba9.tar.xz zsh-e025336f2f6d9f107ee1e03b9900f04af0544ba9.zip |
Updated from list as far as 10376
Diffstat (limited to 'Etc')
-rw-r--r-- | Etc/FAQ.yo | 686 | ||||
-rw-r--r-- | Etc/completion-style-guide | 426 |
2 files changed, 832 insertions, 280 deletions
diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index 3bb53de39..408cc5f5c 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -1,4 +1,4 @@ -mailto(pws@ifh.de)\ +mailto(pws@pwstephenson.fsnet.co.uk)\ whentxt(notableofcontents())\ COMMENT(-- mytt is like tt but adds quotes `like this' for plain text --)\ def(mytt)(1)(\ @@ -13,7 +13,7 @@ def(mybf)(1)(\ whenhtml(bf(ARG1))\ whenlatex(bf(ARG1))\ whenms(bf(ARG1))\ - whensgml(bf(ARG1))) + whensgml(bf(ARG1)))\ def(myem)(1)(\ whentxt(_ARG1_)\ whenhtml(em(ARG1))\ @@ -31,10 +31,10 @@ def(mydit)(1)(\ COMMENT(-- myeit is like eit but fancier text formatting --)\ def(myeit)(0)(\ whenlatex(eit())whenhtml(eit())whenman(eit())whenms(eit())whensgml(eit())\ - whentxt(USECOUNTER(XXenumcounter)CHAR(41)))\ + whentxt(eit()CHAR(41)))\ def(myeitd)(0)(\ whenlatex(eit())whenhtml(eit())whenman(eit())whenms(eit())whensgml(eit())\ - whentxt(USECOUNTER(XXenumcounter).))\ + whentxt(.))\ COMMENT(-- don't want headers for text, USENET headers must come first --)\ def(myreport)(3)(\ whentxt(report()()())\ @@ -43,22 +43,20 @@ whenlatex(report(ARG1)(ARG2)(ARG3))\ whenman(report(ARG1)(ARG2)(ARG3))\ whenms(report(ARG1)(ARG2)(ARG3))\ whensgml(report(ARG1)(ARG2)(ARG3))) -myreport(Z-Shell Frequently-Asked Questions)(Peter Stephenson)(1998/10/26) +myreport(Z-Shell Frequently-Asked Questions)(Peter Stephenson)(2000/1/25) COMMENT(-- the following are for Usenet and must appear first)\ -description( +description(\ mydit(Archive-Name:) unix-faq/shell/zsh -mydit(Last-Modified:) 1998/10/26 -mydit(Submitted-By:) email(pws@amtp.liv.ac.uk (Peter Stephenson)) -mydit(Version:) $Id: FAQ.yo,v 1.1 1999/04/15 18:05:37 akr Exp $ -mydit(Frequency:) Monthly -mydit(Copyright:) (C) P.W. Stephenson, 1995, 1996, 1997, 1998 \ -(see end of document) +mydit(Last-Modified:) 2000/11/25 +mydit(Submitted-By:) email(pws@ibmth.df.unipi.it (Peter Stephenson)) +mydit(Version:) $Id: FAQ.yo,v 1.2 2000/04/01 20:43:44 pws Exp $ +mydit(Posting-Frequency:) Monthly +mydit(Copyright:) (C) P.W. Stephenson, 1995--2000 (see end of document) ) -bf(Changes since issue posted September 1998:) +bf(Changes since issue posted December 1999:) description( -mydit(2.1) Another mytt(typeset) difference turned up. -mydit(5.4) Slight addition to Y2K item (prompt formatting) +mydit( ) None. Suggestions on a postcard. ) This document contains a list of frequently-asked (or otherwise @@ -99,25 +97,29 @@ Chapter 2: How does zsh differ from...? Chapter 3: How to get various things to work 3.1. Why does `$var' where `var="foo bar"' not do what I expect? -3.2. What is the difference between `export' and the ALL_EXPORT option? -3.3. How do I turn off spelling correction/globbing for a single command? -3.4. How do I get the meta key to work on my xterm? -3.5. How do I automatically display the directory in my xterm title bar? -3.6. How do I make the completion list use eight bit characters? -3.7. Why do the cursor (arrow) keys not work? -3.8. Why does my terminal act funny in some way? -3.9. Why does zsh not work in an Emacs shell mode any more? -3.10. Why do my autoloaded functions not autoload [the first time]? -3.11. How does base arithmetic work? -3.12. How do I get a newline in my prompt? -3.13. Why does `bindkey ^a command-name' or 'stty intr ^-' do something funny? -3.14. Why can't I bind \C-s and \C-q any more? -3.15. How do I execute command `foo' within function `foo'? -3.16. Why do history substitutions with single bangs do something funny? -3.17. Why does zsh kill off all my background jobs when I logout? -3.18. How do I list all my history entries? -3.19. How does the alternative loop syntax, e.g. mytt(while {...} {...}) work? -3.20. Why is my history not being saved? +3.2. In which startup file do I put...? +3.3. What is the difference between `export' and the ALL_EXPORT option? +3.4. How do I turn off spelling correction/globbing for a single command? +3.5. How do I get the meta key to work on my xterm? +3.6. How do I automatically display the directory in my xterm title bar? +3.7. How do I make the completion list use eight bit characters? +3.8. Why do the cursor (arrow) keys not work? +3.9. Why does my terminal act funny in some way? +3.10. Why does zsh not work in an Emacs shell mode any more? +3.11. Why do my autoloaded functions not autoload [the first time]? +3.12. How does base arithmetic work? +3.13. How do I get a newline in my prompt? +3.14. Why does `bindkey ^a command-name' or 'stty intr ^-' do something funny? +3.15. Why can't I bind \C-s and \C-q any more? +3.16. How do I execute command `foo' within function `foo'? +3.17. Why do history substitutions with single bangs do something funny? +3.18. Why does zsh kill off all my background jobs when I logout? +3.19. How do I list all my history entries? +3.20. How does the alternative loop syntax, e.g. mytt(while {...} {...}) work? +3.21. Why is my history not being saved? +3.22. How do I get a variable's value to be evaluated as another variable? +3.23. How do I prevent the prompt overwriting output when there is no newline? +3.24. What's wrong with cut and paste on my xterm? Chapter 4: The mysteries of completion 4.1. What is completion? @@ -155,29 +157,34 @@ url(http://sunsite.auc.dk/zsh/FAQ/)(http://sunsite.auc.dk/zsh/FAQ/) . The site also contains some contributed zsh scripts and functions; we are delighted to add more, or simply links to your own collection. - This document was originally written in YODL, allowing it to be - converted easily into various other formats. The master source - file lives at url(http://sunsite.auc.dk/zsh/FAQ/zshfaq.yo) -(http://sunsite.auc.dk/zsh/FAQ/zshfaq.yo) . + This document was originally written in YODL, allowing it to be converted + easily into various other formats. The master source file lives at + url(http://sunsite.auc.dk/zsh/FAQ/zshfaq.yo) +(http://sunsite.auc.dk/zsh/FAQ/zshfaq.yo) and the plain text version + can be found at url(http://sunsite.auc.dk/zsh/FAQ/zshfaq.txt) +(http://sunsite.auc.dk/zsh/FAQ/zshfaq.txt) . Another useful source of information is the collection of FAQ articles posted frequently to the Usenet news groups comp.unix.questions, comp.unix.shells and comp.answers with answers to general questions about UNIX. The fifth of the seven articles deals with shells, - including zsh, with a brief description of differences. (This article - also talks about shell startup files which would otherwise rate a - mention here.) There is also a separate FAQ on shell differences - and how to change your shell. Usenet FAQs are available via FTP - from rtfm.mit.edu and mirrors and also on the World Wide Web; see + including zsh, with a brief description of differences. There is + also a separate FAQ on shell differences and how to change your + shell. Usenet FAQs are available via FTP from rtfm.mit.edu and + mirrors and also on the World Wide Web; see description( mydit(USA) url(http://www.cis.ohio-state.edu/hypertext/faq/usenet/top.html) (http://www.cis.ohio-state.edu/hypertext/faq/usenet/top.html) mydit(UK) url(http://www.lib.ox.ac.uk/internet/news/faq/comp.unix.shell.html) (http://www.lib.ox.ac.uk/internet/news/faq/comp.unix.shell.html) - mydit(Netherlands) url(http://www.cs.ruu.nl/wais/html/na-dir/unix-faq/shell/.html) - (http://www.cs.ruu.nl/wais/html/na-dir/unix-faq/shell/.html) + mydit(Netherlands) url(http://www.cs.uu.nl/wais/html/na-dir/unix-faq/shell/.html) + (http://www.cs.uu.nl/wais/html/na-dir/unix-faq/shell/.html) ) + You can also get it via email by emailing \ +email(mail-server@rtfm.mit.edu) + with, in the body of the message, mytt(send faqs/unix-faq/shell/zsh). + The latest version of this FAQ is also available directly from any of the zsh archive sites listed in question link(1.6)(16). @@ -271,10 +278,9 @@ sect(On what machines will it run?) If you need to change something to support a new machine, it would be appreciated if you could add any necessary preprocessor code and - alter configure.in and config.h.in to configure zsh automatically, + alter configure.in and acconfig.h to configure zsh automatically, then send the required context diffs to the list (see question - link(5.2)(52)). Changes based on version 2.5 are very unlikely to - be useful. + link(5.2)(52)). Please make sure you have the latest version first. To get it to work, retrieve the source distribution (see question link(1.6)(16)), un-gzip it, un-tar it and read the INSTALL file in the top @@ -289,18 +295,21 @@ sect(On what machines will it run?) sect(What's the latest version?) - Zsh 3.0.5 is the latest production version. The new major number 3.0 - largely reflects the considerable internal changes in zsh to make it - more reliable, consistent and (where possible) compatible. Those - planning on upgrading their zsh installation should take a look at - the list of incompatibilities at the end of link(5.1)(51). This is - longer than usual due to enhanced sh, ksh and POSIX compatibility. - - The beta version 3.1.4 is also available. Development of zsh is - usually patch by patch, with each intermediate version publicly - available. Note that this `open' development system does mean bugs - are sometimes introduced into the most recent archived version. - These are usually fixed quickly. + Zsh 3.0.7 is the latest production version. The new major number 3.0 + largely reflects the considerable internal changes in zsh to make it more + reliable, consistent and (where possible) compatible. Those planning on + upgrading their zsh installation should take a look at the list of + incompatibilities at the end of link(5.1)(51). This is longer than usual + due to enhanced sh, ksh and POSIX compatibility. + + The beta version 3.1.6 is also available. Development of zsh is usually + patch by patch, with each intermediate version publicly available. Note + that this `open' development system does mean bugs are sometimes + introduced into the most recent archived version. These are usually + fixed quickly. If you are really interested in getting the latest + improvements, and less worried about providing a stable environment, + development versions are uploaded quite frequently to the archive in the + tt(development) subdirectory. Note also that as the shell changes, it may become incompatible with older versions; see the end of question link(5.1)(51) for a partial list. @@ -313,17 +322,20 @@ sect(What's the latest version?) sect(Where do I get it?) label(16) - The archive is now run by email(Andrew Main <zefram@tao.co.uk>). - The following are known mirrors (kept frequently up to date); the + The coordinator of development is currently me; the alias + email(coordinator@zsh.org) can be used to contact whoever is in the hot + seat. The following are known mirrors (kept frequently up to date); the first is the official archive site, currently in Australia. All are - available by anonymous FTP. The major sites keep test versions in - the 'testing' subdirectory: such up-to-the-minute development - versions should only be retrieved if you actually plan to help test - the latest version of the shell. The following list also appears - on the WWW at url(http://www.zsh.org)(http://www.zsh.org) . + available by anonymous FTP. The major sites keep test versions in the + `testing' subdirectory: such up-to-the-minute development versions should + only be retrieved if you actually plan to help test the latest version of + the shell. The following list also appears on the WWW at + url(http://www.zsh.org)(http://www.zsh.org) . description( mydit(Home site) url(ftp://ftp.zsh.org)(ftp://ftp.zsh.org) + mydit() url(http://www.zsh.org/pub/zsh/) +(http://www.zsh.org/pub/zsh/) mydit(Australia) url(ftp://ftp.ips.gov.au/mirror/zsh/) (ftp://ftp.ips.gov.au/mirror/zsh/) mydit(Denmark) url(ftp://sunsite.auc.dk/pub/unix/shells/zsh) @@ -334,45 +346,51 @@ label(16) (ftp://ftp.cenatls.cena.dgac.fr/pub/shells/zsh/) mydit(Germany) url(ftp://ftp.fu-berlin.de/pub/unix/shells/zsh/) (ftp://ftp.fu-berlin.de/pub/unix/shells/zsh/) - mydit() url(ftp://ftp.gmd.de/packages/zsh/) -(ftp://ftp.gmd.de/packages/zsh/) mydit() url(ftp://ftp.uni-trier.de/pub/unix/shell/zsh/) (ftp://ftp.uni-trier.de/pub/unix/shell/zsh/) mydit(Hungary) url(ftp://ftp.cs.elte.hu/pub/zsh/) (ftp://ftp.cs.elte.hu/pub/zsh/) mydit() (also url(http://www.cs.elte.hu/pub/zsh/) - (http://www.cs.elte.hu/pub/zsh/) ) +(http://www.cs.elte.hu/pub/zsh/) ) + mydit() url(ftp://ftp.kfki.hu/pub/packages/zsh/) +(ftp://ftp.kfki.hu/pub/packages/zsh/) mydit(Israel) \ url(ftp://ftp.math.technion.ac.il/mirror/ftp.zsh.org/pub/zsh/) (ftp://ftp.math.technion.ac.il/mirror/ftp.zsh.org/pub/zsh/) mydit() \ url(http://www.math.technion.ac.il/mirror/ftp.zsh.org/pub/zsh/) (http://www.math.technion.ac.il/mirror/ftp.zsh.org/pub/zsh/) - mydit(Japan) url(ftp://ftp.tohoku.ac.jp/mirror/zsh/) -(ftp://ftp.tohoku.ac.jp/mirror/zsh/) - mydit() url(ftp://ftp.nis.co.jp/pub/shells/zsh/) + mydit(Italy) url(ftp://ftp.unina.it/pub/Unix/pkgs/shell/zsh/) +(ftp://ftp.unina.it/pub/Unix/pkgs/shell/zsh/) + mydit(Japan) url(ftp://ftp.nisiq.net/pub/shells/zsh/) (ftp://ftp.nis.co.jp/pub/shells/zsh/) + mydit() url(ftp://ftp.win.ne.jp/pub/shell/zsh/) +(ftp://ftp.win.ne.jp/pub/shell/zsh/) mydit(Norway) url(ftp://ftp.uit.no/pub/unix/shells/zsh/) (ftp://ftp.uit.no/pub/unix/shells/zsh/) + mydit(Poland) url(ftp://sunsite.icm.edu.pl/pub/unix/shells/zsh/) +(ftp://sunsite.icm.edu.pl/pub/unix/shells/zsh/) mydit(Romania) url(ftp://ftp.roedu.net/pub/mirrors/ftp.zsh.org/pub/zsh/) (ftp://ftp.roedu.net/pub/mirrors/ftp.zsh.org/pub/zsh/) - mydit(Slovenia) url(ftp://ftp.siol.net/pub/unix/shells/zsh/) -(ftp://ftp.siol.net/pub/unix/shells/zsh/) + mydit() url(ftp://ftp.kappa.ro/pub/mirrors/ftp.zsh.org/pub/zsh/) +(ftp://ftp.kappa.ro/pub/mirrors/ftp.zsh.org/pub/zsh/) + mydit(Slovenia) url(ftp://ftp.siol.net/mirrors/zsh/) +(ftp://ftp.siol.net/mirrors/zsh/) mydit(Sweden) url(ftp://ftp.lysator.liu.se/pub/unix/zsh/) (ftp://ftp.lysator.liu.se/pub/unix/zsh/) mydit(UK) url(ftp://ftp.net.lut.ac.uk/zsh/) (ftp://ftp.net.lut.ac.uk/zsh/) mydit() (also by FSP at port 21) - mydit() url(ftp://src.doc.ic.ac.uk/packages/unix/shells/zsh/) -(ftp://src.doc.ic.ac.uk/packages/unix/shells/zsh/) - mydit(USA) url(ftp://ftp.math.gatech.edu/pub/zsh/) -(ftp://ftp.math.gatech.edu/pub/zsh/) - mydit() url(ftp://uiarchive.uiuc.edu/pub/packages/shells/zsh/) + mydit() url(ftp://sunsite.org.uk/packages/zsh/) +(ftp://sunsite.org.uk/packages/zsh/) + mydit(USA) url(ftp://uiarchive.uiuc.edu/pub/packages/shells/zsh/) (ftp://uiarchive.uiuc.edu/pub/packages/shells/zsh/) - mydit() url(ftp://ftp.sterling.com/zsh/) -(ftp://ftp.sterling.com/zsh/) mydit() url(ftp://ftp.rge.com/pub/shells/zsh/) (ftp://ftp.rge.com/pub/shells/zsh/) + mydit() url(ftp://foad.org/pub/zsh/) +(ftp://foad.org/pub/zsh/) + mydit() url(http://foad.org/zsh/) +(http://foad.org/zsh/) ) The Windows port mentioned above is maintained separately by email(Amol @@ -449,7 +467,6 @@ sect(I don't have root access: how do I make zsh my login shell?) endif ) - It's not a good idea to put this (even without the -l) into .cshrc, at least without some tests on what the csh is supposed to be doing, as that will cause _every_ instance of csh to turn into a zsh and @@ -513,18 +530,21 @@ label(21) The classic difference is word splitting, discussed in link(3.1)(31); this catches out very many beginning zsh users. As explained there, this is actually a bug in every other shell. The answer is to set - SH_WORD_SPLIT for backward compatibility. The next most classic + tt(SH_WORD_SPLIT) for backward compatibility. The next most classic difference is that unmatched glob patterns cause the command to - abort; set NO_NOMATCH for those. + abort; set tt(NO_NOMATCH) for those. Here is a list of various options which will increase ksh compatibility, though maybe decrease zsh's abilities: see the manual - entries for GLOB_SUBST, IGNORE_BRACES (though brace expansion occurs - in some versions of ksh), KSH_ARRAYS, KSH_GLOB, KSH_OPTION_PRINT, - LOCAL_OPTIONS, NO_BAD_PATTERN, NO_BANG_HIST, NO_EQUALS, NO_HUP, - NO_NOMATCH, NO_RCS, NO_SHORT_LOOPS, PROMPT_SUBST, RM_STAR_SILENT, - POSIX_BUILTINS, SH_FILE_EXPANSION, SH_GLOB, SH_OPTION_LETTERS, - SH_WORD_SPLIT (see question link(3.1)(31)) and SINGLE_LINE_ZLE. + entries for tt(GLOB_SUBST), tt(IGNORE_BRACES) (though brace expansion occurs + in some versions of ksh), tt(KSH_ARRAYS), tt(KSH_GLOB), tt(KSH_OPTION_PRINT), + tt(LOCAL_OPTIONS), tt(NO_BAD_PATTERN), tt(NO_BANG_HIST), tt(NO_EQUALS), \ +tt(NO_HUP,) + tt(NO_NOMATCH), tt(NO_RCS), tt(NO_SHORT_LOOPS), tt(PROMPT_SUBST), \ +tt(RM_STAR_SILENT), + tt(POSIX_BUILTINS), tt(SH_FILE_EXPANSION), tt(SH_GLOB), \ +tt(SH_OPTION_LETTERS), + tt(SH_WORD_SPLIT) (see question link(3.1)(31)) and tt(SINGLE_LINE_ZLE). Note that you can also disable any built-in commands which get in your way. If invoked as `ksh', the shell will try and set suitable options. @@ -545,7 +565,7 @@ label(21) subscripts start at 1, not 0; tt(array[0]) refers to tt(array[1]); mytt($array) refers to the whole array, not tt($array[0]); braces are unnecessary: tt($a[1] == ${a[1]}), etc. - The KSH_ARRAYS option is now available. + The tt(KSH_ARRAYS) option is now available. it() Coprocesses are established by mytt(coproc); mytt(|&) behaves like csh. Handling of coprocess file descriptors is also different. it() In mytt(cmd1 && cmd2 &), only mytt(cmd2) instead of the whole @@ -555,14 +575,10 @@ label(21) it() Command line substitutions, globbing etc.: itemize( it()* Failure to match a globbing pattern causes an error (use - NO_NOMATCH). + tt(NO_NOMATCH)). it()* The results of parameter substitutions are treated as plain text: - mytt(foo="*"; print $foo) prints all files in ksh but mytt(*) in zsh. - (GLOB_SUBST has been added to fix this.) - it() The backslash in tt($(echo '\$x')) is treated differently: in \ -ksh, it - is not stripped, in zsh it is. (The tt(`...`) form gives the same in - both shells.) + mytt(foo="*"; print $foo) prints all files in ksh but mytt(*) in zsh + (uset tt(GLOB_SUBST)). it()* tt($PSn) do not do parameter substitution by default (use \ PROMPT_SUBST). it()* Standard globbing does not allow ksh-style `pattern-lists'. @@ -580,9 +596,9 @@ PROMPT_SUBST). ---------------------------------------------------------------------- ) The mytt(^), mytt(~) and mytt(#) (but not mytt(|))forms require \ -EXTENDED_GLOB. +tt(EXTENDED_GLOB). From version 3.1.3, the ksh forms are fully supported when the - option KSH_GLOB is in effect; for previous versions you + option tt(KSH_GLOB) is in effect; for previous versions you must use the table above. [1] Note that mytt(~) is the only globbing operator to have a lower @@ -626,7 +642,8 @@ link(2.3)(23). ) it() Traps and signals: itemize( - it() Traps are not local to functions. + it()* Traps are not local to functions. The option LOCAL_TRAPS is + available from 3.1.6. it() TRAPERR has become TRAPZERR (this was forced by UNICOS which has SIGERR). ) @@ -641,6 +658,8 @@ link(2.3)(23). release either.) it() Management of histories in multiple shells is different: the history list is not saved and restored after each command. + The option tt(SHARE_HISTORY) appeared in 3.1.6 and is set in ksh + compatibility mode to remedy this. it() mytt(\) does not escape editing chars (use mytt(^V)). it() Not all ksh bindings are set (e.g. mytt(<ESC>#); try mytt(<ESC>q)). it()* mytt(#) in an interactive shell is not treated as a comment by @@ -677,7 +696,7 @@ sect(Similarities with csh) it() tt(*rc) file for interactive shells. it() Directory stacks. it() tt(cshjunkie*), tt(ignoreeof) options. - it() The CSH_NULL_GLOB option. + it() The tt(CSH_NULL_GLOB) option. it() tt(>&), tt(|&) etc. redirection. (Note that mytt(>file 2>&1) is the standard Bourne shell command for csh's mytt(>&file).) @@ -720,12 +739,12 @@ label(23) ) can be replaced by the zsh function, verb( - cd() { builtin cd $*; echo $PWD; } + cd() { builtin cd "$@"; echo $PWD; } ) (the `builtin' tells zsh to use its own `cd', avoiding an infinite loop) or, perhaps better, verb( - cd() { builtin cd $*; print -D $PWD; } + cd() { builtin cd "$@"; print -D $PWD; } ) (which converts your home directory to a tt(~)). In fact, this problem is better solved by defining the special function chpwd() (see the manual). @@ -734,7 +753,6 @@ label(23) Here is Bart Schaefer's guide to converting csh aliases for zsh. - SETCOUNTER(XXenumcounter)(0) enumerate( myeit() If the csh alias references "parameters" (tt(\!:1), tt(\!*) etc.), then in zsh you need a function (referencing tt($1), tt($*) etc.). @@ -746,7 +764,7 @@ label(23) myeit() If the csh alias references its own name (tt(alias rm "rm -i")), then in a zsh function you need the "command" keyword - (function tt(rm() { command rm -i $* })), but in a zsh alias + (function tt(rm() { command rm -i "$@" })), but in a zsh alias you don't (tt(alias rm="rm -i")). myeit() If you have aliases that refer to each other (tt(alias ls "ls -C"; @@ -761,7 +779,7 @@ label(23) heavy csh alias junkies: myeit() Mapping from csh alias "parameter referencing" into zsh function - (assuming shwordsplit and ksharrays are NOT set in zsh): + (assuming tt(SH_WORD_SPLIT) and tt(KSH_ARRAYS) are NOT set in zsh): verb( csh zsh ===== ========== @@ -773,7 +791,7 @@ label(23) \!:1-4 $*[1,4] \!:1- $*[1,$#-1] (or $*[1,-2]) \!^- $*[1,$#-1] - \!*:q "$@" ($*:q doesn't work (yet)) + \!*:q "$@" \!*:x $=* ($*:x doesn't work (yet)) ) @@ -799,7 +817,7 @@ label(23) There is one other serious problem with aliases: consider verb( alias l='/bin/ls -F' - l() { /bin/ls -la $* | more } + l() { /bin/ls -la "$@" | more } ) mytt(l) in the function definition is in command position and is expanded as an alias, defining mytt(/bin/ls) and mytt(-F) as functions which call @@ -844,7 +862,17 @@ sect(Similarities with tcsh) verb( bindkey '\eq' push-input ) - to save the entire buffer. + to save the entire buffer. In recent versions of zsh 3.1, you have + the following more sophisticated option, + verb( + run-fg-editor() { + zle push-input + BUFFER="fg %$EDITOR:t" + zle accept-line + } + zle -N run-fg-editor + ) + and can now bind tt(run-fg-editor) just like any other editor function. sect(Similarities with bash) @@ -868,7 +896,7 @@ sect(Shouldn't zsh be more/less like ksh/(t)csh?) would have features familiar to csh users. For a long time, csh was the preferred interactive shell and there is a strong resistance to changing to something unfamiliar, hence the additional syntax and - CSH_JUNKIE options. This argument still holds. On the other hand, + tt(CSH_JUNKIE) options. This argument still holds. On the other hand, the arguments for having what is close to a plug-in replacement for ksh are, if anything, even more powerful: the deficiencies of csh as a programming language are well known (look in any Usenet FAQ archive, e.g. @@ -896,8 +924,8 @@ label(31) ) are split into words when passed to a command or used in a mytt(for foo in $var) loop. By default, zsh does not have that behaviour: the - variable remains intact. (This is not a bug! See below.) An option - (SHWORDSPLIT) exists to provide compatibility. + variable remains intact. (This is not a bug! See below.) The option + tt(SH_WORD_SPLIT) exists to provide compatibility. For example, defining the function args to show the number of its arguments: @@ -931,7 +959,7 @@ label(31) verb( args $array ) - produces the output `4', regardless of the setting of SHWORDSPLIT. + produces the output `4', regardless of the setting of tt(SH_WORD_SPLIT). Arrays are also much more versatile than single strings. Probably if this mechanism had always been available there would never have been automatic word splitting in scalars, which is a sort of @@ -950,23 +978,78 @@ label(31) after which $words is an array with the words of $sentence (note characters special to the shell, such as the mytt(') in this example, must already be quoted), or, less standard but more reliable, - turning on SHWORDSPLIT for one variable only: + turning on tt(SH_WORD_SPLIT) for one variable only: verb( args ${=sentence} ) always returns 8 with the above definition of mytt(args). (In older - versions of zsh, tt(${=foo}) toggled SHWORDSPLIT; now it forces it on.) + versions of zsh, tt(${=foo}) toggled tt(SH_WORD_SPLIT); now it forces it on.) Note also the tt("$@") method of word splitting is always available in zsh functions and scripts (though strictly this does array splitting, not - word splitting). + word splitting). This is more portable than the tt($*), since it + will work regardless of the tt(SH_WORD_SPLIT) setting; the other + difference is that tt($*) removes empty arguments from the array. + You can fix the first half of that objection by using tt(${==*}), + which turns off tt(SH_WORD_SPLIT) for the duration of the expansion. - SHWORDSPLIT is set when zsh is invoked with the names `ksh' or `sh', + tt(SH_WORD_SPLIT) is set when zsh is invoked with the names `ksh' or `sh', or (entirely equivalent) when mytt(emulate ksh) or mytt(emulate sh) is in effect. -sect(What is the difference between `export' and the ALL_EXPORT option?) +sect(In which startup file do I put...?) + + When zsh starts up, there are four files you can change which it will + run under various circumstances: tt(.zshenv), tt(.zprofile), tt(.zshrc) + and tt(.zlogin). They are usually in your home directory, but the + variable tt($ZDOTDIR) may be set to alter that. Here are a few simple + hints about how to use them. There are also files which the system + administrator can set for all shells; you can avoid running all except + tt(/etc/zshenv) by starting zsh with the tt(-f) option --- for this + reason it is important for administrators to make sure tt(/etc/zshenv) + is as brief as possible. + + The order in which the four files are searched (none of them myem(need) + to exist) is the one just given. However, tt(.zprofile) and tt(.zlogin) + are only run when the shell is a login shell --- when you first login, + of course, and whenever you start zsh with the tt(-l) option. All + login shells are interactive. The order is the only difference + between those; you should decide whether you need things set before or + after tt(.zshrc). These files are a good place to set environment + variables (i.e. mytt(export) commands), since they are passed on to + all shells without you having to set them again, and also to check + that your terminal is set up properly (except that if you want to + change settings for terminal emulator windows like tt(xterm) you will + need to put those in tt(.zshrc), since usually you do not get a login + shell here). + + The only file you can alter which is started with every zsh (unless + you use the tt(-f) option) is tt(.zshenv), so this is a good place to \ + put + things you want even if the shell is non-interactive: options for + changing the the syntax, like tt(EXTENDED_GLOB), any changes to set with + mytt(limit), any more variables you want to make sure are set as for + example tt($fpath) to find functions. You almost certainly do not + want tt(.zshenv) to produce any output. Some people prefer not to + use tt(.zshenv) for setting options, as this affects scripts; but + making zsh scripts portable usually requires special handling anyway. + + Finally, tt(.zshrc) is run for every interactive shell; that includes + login shells, but also any other time you start up a shell, such as + simply by typing mytt(zsh) or opening a new terminal emulator window. + This file is the place to change the editing behaviour via options or + mytt(bindkey), control how your history is saved, set aliases unless + you want to use them in scripts too, and for any other clutter which + can't be exported but you only use when interacting directly with the + shell. You probably don't want tt(.zshrc) to produce output, either, + since there are occasions when this can be a problem, such as when + using mytt(rsh) from another host. See link(3.21)(321) for what to \ + put in tt(.zshrc) + to save your history. + + +sect(What is the difference between `export' and the tt(ALL_EXPORT) option?) Normally, you would put a variable into the environment by using mytt(export var). The command mytt(setopt allexport) causes all @@ -975,7 +1058,6 @@ sect(What is the difference between `export' and the ALL_EXPORT option?) This may seem a useful shorthand, but in practice it can have unhelpful side effects: - SETCOUNTER(XXenumcounter)(0) enumerate( myeit() Since every variable is in the environment as well as remembered by the shell, the memory for it needs to be allocated twice. @@ -986,7 +1068,7 @@ sect(What is the difference between `export' and the ALL_EXPORT option?) meaning to a command. Since all shell variables are visible to commands, there is no protection against this. ) - For these reasons it is usually best to avoid ALL_EXPORT unless you + For these reasons it is usually best to avoid tt(ALL_EXPORT) unless you have a specific use for it. One safe use is to set it before creating a list of variables in an initialisation file, then unset it immediately afterwards. Only those variables will be automatically @@ -1019,7 +1101,7 @@ sect(How do I turn off spelling correction/globbing for a single command?) sect(How do I get the meta key to work on my xterm?) -label(34) +label(35) As stated in the manual, zsh needs to be told about the meta key by using mytt(bindkey -me) or mytt(bindkey -mv) in your .zshrc or on the @@ -1046,7 +1128,7 @@ sect(How do I automatically display the directory in my xterm title bar?) You should use the special function mytt(chpwd), which is called when the directory changes. The following checks that standard output is a terminal, then puts the directory in the title bar if the terminal - is an tt(xterm) or a tt(sun-cmd). + is an tt(xterm) or some close relative, or a tt(sun-cmd). verb( chpwd() { @@ -1054,7 +1136,7 @@ sect(How do I automatically display the directory in my xterm title bar?) case $TERM in sun-cmd+CHAR(41) print -Pn "\e]l%~\e\\" ;; - xterm+CHAR(41) print -Pn "\e]2;%~\a" + *xterm*|rxvt|(dt|k|E)term+CHAR(41) print -Pn "\e]2;%~\a" ;; esac } @@ -1071,36 +1153,16 @@ sect(How do I automatically display the directory in my xterm title bar?) sect(How do I make the completion list use eight bit characters?) - A traditional UNIX environment (character terminal and ASCII - character sets) is not sufficient to be able to handle non-ASCII - characters, and there are so many possible enhancements that in - general this is hard. However, if you have something like an xterm - using a standard character set like ISO-8859-1 (which is often the - default for xterm), read on. You should also note question - link(3.4)(34) on the subject of eight bit characters. - - You are probably creating files with names including non-ASCII - accented characters, and find they show up in the completion list as - verb(\M-i) or something such. This is because the library routines - (not zsh itself) which test whether a character is printable have - replied that it is not; zsh has simply found a way to show them - anyway. - - The answer, under a modern POSIXy operating system, is to find a - locale where these are treated as printable characters. Zsh has - handling for locales built in and will recognise when you set a - relevant variable. You need to look in /usr/lib/locale to find one - which suits you; the subdirectories correspond to the locale names. - The simplest possibility is likely to be en_US, so that the simplest - answer to your problem is to set - - verb( - LC_CTYPE=en_US - ) - - when your terminal is capable of showing eight bit characters. If - you only have a default domain (called C), you may need to have some - additional files installed on your system. + If you are sure your terminal handles this, the easiest way from versions + 3.0.6 and 3.1 of the shell is to set the option tt(PRINT_EIGHT_BIT). In + principle, this will work automatically if your computer uses the + `locale' system and your locale variables are set properly, as zsh + understands this. However, it is quite complicated, so if it isn't + already set up, trying the option is a lot easier. For earlier versions + of zsh 3, you are stuck with trying to understand locales, see the + tt(setlocale(3)) and tt(zshparam(1)) manual pages: the simplest + possibility may be to set tt(LC_ALL=en_US). For older versions of the + shell, there is no easy way out. sect(Why do the cursor (arrow) keys not work?) @@ -1150,6 +1212,13 @@ sect(Why does my terminal act funny in some way?) from hiccups introduced by other programmes (kermit has been known to do this). + A problem I have experienced myself (on an AIX 3.2 workstation with + xterm) is that termcap deinitialization sequences sent by `less' + were causing automargins to be turned off --- not actually a shell + problem, but you might have thought it was. The fix is to put `tt(X)' + into the environment variable tt(LESS) to stop the sequences being sent. + Other programs (though not zsh) may also send that sequence. + If myem(that)'s not the problem, and you are having difficulties with external commands (not part of zsh), and you think some terminal setting is wrong (e.g. tt(^V) is getting interpreted as `literal next @@ -1163,12 +1232,6 @@ sect(Why does my terminal act funny in some way?) modes it uses itself and a number of special processing characters (see the tt(stty(1)) manual page). - At some point there may be an overhaul which allows the terminal - modes used by the shell to be modified separately from those seen by - external programmes. This is partially implemented already: from 2.5, - the shell is less susceptible to mode changes inherited from - programmes than it used to be. - sect(Why does zsh not work in an Emacs shell mode any more?) @@ -1205,7 +1268,6 @@ sect(Why do my autoloaded functions not autoload [the first time]?) The problem is that there are two possible ways of autoloading a function (see the AUTOLOADING FUNCTIONS section of the zsh manual page zshmisc for more detailed information): - SETCOUNTER(XXenumcounter)(0) enumerate( myeit() The file contains just the body of the function, i.e. there should be no line at the beginning saying mytt(function foo {) @@ -1232,7 +1294,7 @@ sect(Why do my autoloaded functions not autoload [the first time]?) incompatible with the old zsh behaviour which allowed you to redefine the function when you called it. - From version 3.1, there is an option KSHAUTOLOAD to allow full ksh + From version 3.1, there is an option tt(KSH_AUTOLOAD) to allow full ksh compatiblity, i.e. the function myem(must) be in the second form above. If that is not set, zsh tries to guess which form you are using: if the file contains only a complete definition of the @@ -1259,9 +1321,9 @@ sect(How does base arithmetic work?) ) or even verb( - foo=$[16#ff] + foo=$((16#ff)) ) - (note that `foo=$((16#ff))' is now supported). The original syntax was + The original syntax was verb( (( foo = [16]ff )) ) @@ -1288,6 +1350,7 @@ sect(How does base arithmetic work?) sect(How do I get a newline in my prompt?) +label(313) You can place a literal newline in quotes, i.e. verb( @@ -1299,13 +1362,14 @@ sect(How do I get a newline in my prompt?) mytt(unsetopt cshjunkiequotes) and mytt(setopt cshjunkiequotes), or put it in your tt(.zshrc) before the option is set. - Arguably the prompt code should handle `print'-like escapes. Feel - free to write this :-CHAR(41). Otherwise, you can use + In all recent versions of zsh, there is a form of quoting which will + interpret print sequences like `tt(\n)' but otherwise acts like single + quotes: surround the string with tt($'...'). Hence: verb( - PROMPT=$(print "Hi Joe,\nwhat now?%# ") + PROMPT=$'Hi Joe,\nwhat now?%# ' ) - in your initialisation file. - + is a neat way of doing what you want. Note that it is the quotes, not + the prompt expansion, which turns the `tt(\n)' into a newline. sect(Why does mytt(bindkey ^a command-name) or mytt(stty intr ^-) do something funny?) @@ -1324,7 +1388,7 @@ sect(Why can't I bind tt(\C-s) and tt(\C-q) any more?) settings.) In other words, tt(\C-s) stops all output to the terminal, while tt(\C-q) resumes it. - There is an option NO_FLOW_CONTROL to stop zsh from allowing flow + There is an option tt(NO_FLOW_CONTROL) to stop zsh from allowing flow control and hence restoring the use of the keys: put mytt(setopt noflowcontrol) in your tt(.zshrc) file. @@ -1346,7 +1410,7 @@ sect(Why do history substitutions with single bangs do something funny?) If you have a command like "tt(echo !-2:$ !$)", the first history substitution then sets a default to which later history substitutions with single unqualified bangs refer, so that !$ becomes equivalent to - tt(!-2:$). The option CSH_JUNKIE_HISTORY makes all single bangs refer + tt(!-2:$). The option tt(CSH_JUNKIE_HISTORY) makes all single bangs refer to the last command. @@ -1433,6 +1497,7 @@ work?) sect(Why is my history not being saved?) +label(321) In zsh, you need to set three variables to make sure your history is written out when the shell exits. For example, @@ -1449,6 +1514,94 @@ sect(Why is my history not being saved?) manual. +sect(How do I get a variable's value to be evaluated as another variable?) + + The problem is that you have a variable tt($E) containing the string + mytt(EDITOR), and a variable tt($EDITOR) containing the string mytt(emacs), + or something such. How do you get from tt($E) to emacs in one easy + stage? + + There is no standard single-stage way of doing this. However, there + is a zsh idiom (available in all versions of zsh since 3.0) for this: + verb( + print ${(e)E:+\$$E} + ) + Ignore the mytt((e)) for now. The mytt(:+) means: if the variable + tt($E) is set, substitute the following, i.e. mytt(\$$E). This is + expanded to mytt($EDITOR) by the normal rules. Finally, the mytt((e)) \ + means: + evaluate the expression you just made. This gives mytt(emacs). + + For a standard shell way of doing this, you are stuck with mytt(eval): + verb( + eval echo \$$E + ) + produces the same result. + + Versions 3.1.6 of allows you to do this directly with a new flag; + mytt(${(P)E}). + + As a slight aside, sometimes people note that the syntax mytt(${${E}}) + is valid and expect it to have this effect. It probably ought to, but + in the early days of zsh it was found convenient to have this way of + producing different substitutions on the same parameter; for example, + mytt(${${file##**/}%.*}) removes everything up to the last slash in + mytt($file), then everything from the last dot on, inclusive (try + it, this works). So in mytt(${${E}}), the internal mytt(${...}) + actually does nothing. + + +sect(How do I prevent the prompt overwriting output when there is no newline?) + + The problem is, for example, + verb( + % echo -n foo + % + ) + and the tt(foo) has been overwritten by the prompt tt(%). The answer is + simple: put tt(unsetopt promptcr) in your tt(.zshrc). The option \ + tt(PROMPT_CR), + to print a carriage return before a new prompt, is set by default because + a prompt at the right hand side (mytt($RPROMPT), mytt($RPS1)) will not appear + in the right place, and multi-line editing will be confused about the line + position, unless the line starts in the left hand column. Apart from + tt(PROMPT_CR), you can force this to happen by putting a newline in the + prompt (see question link(3.13)(313) for that). + + +sect(What's wrong with cut and paste on my xterm?) + + On the majority of modern UNIX systems, cutting text from one window and + pasting it into another should work fine. On a few, however, there are + problems due to issues about how the terminal is handled: most programs + expect the terminal to be in `canonical input mode', which means that the + program is passed a whole line of input at a time, while for editing + the shell needs a single character at a time and must be in + `non-canonical input mode'. On the systems in question, input can be + lost or re-ordered when the mode changes. There are actually two + slightly different problems: + enumerate( + myeit() When you paste something in while a programme is running, so that + the shell only retrieves it later. Traditionally, there was a test + which was used only on systems where the problem was known to exist, + so it is possible some other systems were not handled (for example, + certain versions of IRIX, it appears); also, continuation lines were + not handled properly. A more reliable approach appears from versions + 3.0.6 and 3.1.6. + myeit() When the shell is waiting for input, and you paste in a chunk of + text consisting of more than one complete set of commands. + Unfortunately, this is a much harder problem: the line editor is + already active, and needs to be turned off when the first command is + executed. The shell doesn't even know if the remaining text is input + to a command or for the shell, so there's simply nothing it can do. + However, if you have problems you can trick it: type `tt({)' on a line + by itself, then paste the input, then type `tt(})' on a line by + itself. The shell will not execute anything until the final brace is + read; all input is read as continuation lines (this may require the + fixes referred to above in order to be reliable). + ) + + chapter(The mysteries of completion) Programmable completion using the `compctl' command is one of the most @@ -1457,6 +1610,16 @@ a short introduction. There is a set of example completions supplied with the source in Misc/compctl-examples; completion definitions for many of the most obvious commands can be found there. +If this confuses you, you may like to know that there is a new, more +elegant completion system which appeared in version 3.1.6. This is based +on functions called automatically for completion in particular contexts +(for example, there is a function called tt(_cd) to handle completion for +the tt(cd) command) and is installed automatically with the shell, so all +you need to do, in principal, is to arrange for this to be loaded. Putting +`tt(autoload -U compinit; compinit)' in your tt(.zshrc) should be enough if +the system is installed properly. The rest of this section talks about the +old completion system. + sect(What is completion?) `Completion' is where you hit a particular command key (TAB is the @@ -1553,29 +1716,34 @@ sect(How does zsh deal with ambiguous completions?) flexibility for what it does here via its options. The default is for it to beep and completion to stop until you type another character. You can type tt(\C-D) to see all the possible completions. - (That's assuming your at the end of the line, otherwise tt(\C-D) will + (That's assuming you're at the end of the line, otherwise tt(\C-D) will delete the next character and you have to use tt(ESC-\C-D).) This can be changed by the following options, among others: itemize( - it() with nobeep set, that annoying beep goes away - it() with nolistbeep, beeping is only turned off for ambiguous completions - it() with autolist set, when the completion is ambiguous you get a + it() with tt(NO_BEEP) set, that annoying beep goes away + it() with tt(NO_LIST_BEEP), beeping is only turned off for ambiguous + completions + it() with tt(AUTO_LIST) set, when the completion is ambiguous you get a list without having to type tt(\C-D) - it() with listambigous, this is modified so that nothing is listed if - there is an unambiguous prefix or suffix to be inserted - it() with menucomplete set, one completion is always inserted + it() with tt(BASH_AUTO_LIST) set, the list only happens the second + time you hit tab on an ambiguous completion + it() with tt(LIST_AMBIGUOUS), this is modified so that nothing is listed if + there is an unambiguous prefix or suffix to be inserted --- this + can be combined with tt(BASH_AUTO_LIST), so that where both are + applicable you need to hit tab three times for a listing. + it() with tt(MENU_COMPLETE) set, one completion is always inserted completely, then when you hit TAB it changes to the next, and so on until you get back to where you started - it() with automenu, you only get the menu behaviour when you hit TAB + it() with tt(AUTO_MENU), you only get the menu behaviour when you hit TAB again on the ambiguous completion. it() Finally, although it affects all completion lists, including - those explicitly requested, note also alwayslastprompt, which + those explicitly requested, note also tt(ALWAYS_LAST_PROMPT), which causes the cursor to return to the line you were editing after printing the list, provided that is short enough. ) - Combinations of these are possible; for example, autolist and - automenu together give an intuitive combination. Note that - from version 3.1 listambiguous is set by default; if you use + Combinations of these are possible; for example, tt(AUTO_LIST) and + tt(AUTO_MENU) together give an intuitive combination. Note that + from version 3.1 tt(LIST_AMBIGUOUS) is set by default; if you use autolist, you may well want to `unsetopt listambiguous'. @@ -1608,7 +1776,7 @@ sect(How do I complete in the middle of words / just what's before the cursor?) ) then in the example you can move to just after mytt(/usr/loc), hit whatever key you've just bound, move to the end, and hit tab. - (Note that AUTO_REMOVE_SLASH behaviour applies here, see the manual.) + (Note that tt(AUTO_REMOVE_SLASH) behaviour applies here, see the manual.) Even that doesn't exhaust the possibilities. Included with the source distribution is the file tt(Functions/multicomp), a function @@ -1703,7 +1871,6 @@ label(45) Different conditions can also be combined. There are three levels of this (in decreasing order of precedence): - SETCOUNTER(XXenumcounter)(0) enumerate( myeit() multiple square brackets after a single condition give alternatives: for example, mytt(s[foo][bar]) says apply the @@ -1766,22 +1933,27 @@ this applies itemize( it() mytt(time) is ignored with builtins and can't be used with mytt({...}). - it() mytt(set -x) (mytt(setopt xtrace)) still has a few glitches. + it() When showing completion lists with exactly 80 columns, some + terminals print an extra newline which messes up zsh's logic. + it() mytt(set -x) (mytt(setopt xtrace)) still has a few glitches; these + are mostly fixed in 3.1.6. it() Zsh's notion of the current line number (via tt($LINENO)) is sometimes not well handled, particularly when using functions and traps. + This should also work reliably from 3.0.6 and 3.1.6. it() In vi mode, mytt(u) can go past the original modification point. it() The singlelinezle option has problems with prompts containing escapes. it() The mytt(r) command does not work inside mytt($(...)) or mytt(`...`) - expansions. (This is fixed in 3.1.) + expansions. This is fixed in 3.1. it() mytt(typeset) handling is non-optimal, particularly with regard to - flags, and is ksh-incompatible in unpredictable ways. + flags, and is ksh-incompatible in unpredictable ways. 3.1.6 has + been overhauled, but remaining glitches are to be expected. it() Nested closures in extended globbing and pattern matching, such as verb( [[ fofo = (fo#)# ]] ) were not correctly handled, and there were problems with - complicated exclusions using mytt(^) or mytt(~). (These - are fixed in version 3.1.3.) + complicated exclusions using mytt(^) or mytt(~). These + are fixed in version 3.1.3. ) Note that a few recent changes introduce incompatibilities (these @@ -1789,14 +1961,15 @@ this applies Changes after zsh 3.0 (3.1.x is still currently in beta): itemize( - it() The options ALWAYS_LAST_PROMPT (return to the line you were - editing after displaying completion lists) and LIST_AMBIGUOUS - (show matching files when there are several) are now set by - default. This is in response to complaints that too many zsh - features are never noticed by many users. To turn them off, + it() The options tt(ALWAYS_LAST_PROMPT) (return to the line you were + editing after displaying completion lists) and tt(LIST_AMBIGUOUS) + (don't do tt(AUTO_LIST) if there was an unambiguous prefix that could be + inserted, i.e. only list if it is ambiguous what to insert next) are + now set by default. This is in response to complaints that too many + zsh features are never noticed by many users. To turn them off, just put mytt(unsetopt alwayslastprompt listambiguous) in your tt(.zshrc) file. - it() tt(history-search-{forward,backward}) now only find previous + it() In 3.1.5, tt(history-search-{forward,backward}) only find previous lines where the first word is the same as the current one. For example, verb( @@ -1806,8 +1979,10 @@ this applies mytt(compress file) any more. For this reason, mytt(\M-n) and mytt(\M-p) use tt(history-beginning-search-{forward,backward}) which search for a line with the same prefix up to the cursor position. - It is possible to write functions which go a little closer to the - original behaviour; further changes are still possible. + From 3.1.6, there is a different implementation which makes this + closer (though not identical) to the old behaviour, and the + traditional bindings have been restored.. The story for the + tt({up,down}-line-or-search) commands is similar. it() In vi insert mode, the cursor keys no longer work. The following will bind them: COMMENT(-- note space after backslash --) @@ -1829,20 +2004,20 @@ this applies the environment of the caller, as in ksh, instead of as a new function level. Traps established as functions (e.g. mytt(TRAPINT() {...})) work as before. - it() The NO_CLOBBER option is now -C and PRINT_EXIT_VALUE -1; they used - to be the other way around. (Use of names rather than letters is + it() The tt(NO_CLOBBER) option is now -C and tt(PRINT_EXIT_VALUE) -1; they + used to be the other way around. (Use of names rather than letters is generally recommended.) it() mytt([[) is a reserved word, hence must be separated from other characters by whitespace; mytt({) and mytt(}) are also reserved - words if the IGNORE_BRACES option is set. - it() The option CSH_JUNKIE_PAREN has been removed: csh-like code now + words if the tt(IGNORE_BRACES) option is set. + it() The option tt(CSH_JUNKIE_PAREN) has been removed: csh-like code now always does what it looks like it does, so mytt(if ( ... ) ...) executes the code in parentheses in a subshell. To make this useful, the syntax expected after an mytt(if), etc., is less strict than in other shells. it() mytt(foo=*) does not perform globbing immediately on the right hand side of the assignment; the old behaviour now requires the - option GLOB_ASSIGN. (mytt(foo=(*)) is and has always been the + option tt(GLOB_ASSIGN). (mytt(foo=(*)) is and has always been the consistent way of doing this.) it() tt(<>) performs redirection of input and output to the specified file. For numeric globs, you now need tt(<->). @@ -1857,7 +2032,7 @@ this applies instead of tt(=)'s. This is for consistency: all other directory substitution (tt(~user), tt(~name), tt(~+), ...) used a tilde, while tt(=<number>) caused problems with tt(=program) substitution. - it() The `HISTLIT' option was broken in various ways and has been removed: + it() The tt(HISTLIT) option was broken in various ways and has been removed: the rewritten history mechanism doesn't alter history lines, making the option unnecessary. it() History expansion is disabled in single-quoted strings, like other @@ -1865,7 +2040,7 @@ this applies backslashed. it() The mytt($HISTCHARS) variable is now mytt($histchars). Currently both are tied together for compatibility. - it() The PROMPT_SUBST option now performs backquote expansion -- hence + it() The tt(PROMPT_SUBST) option now performs backquote expansion -- hence you should quote these in prompts. (SPROMPT has changed as a result.) it() Quoting in prompts has changed: close parentheses inside ternary expressions should be quoted with a tt(%); history is now tt(%!), not @@ -1879,13 +2054,18 @@ label(52) The shell is being maintained by various (entirely self-appointed) subscribers to the mailing list, verb( - zsh-workers@math.gatech.edu + zsh-workers@sunsite.auc.dk ) so mail on any issues (bug reports, suggestions, complaints...) related to the development of the shell should be sent there. If you want someone to mail you directly, say so. Most patches to zsh appear there first. + Note that this location has just changed (January 1999), and the + instructions to go with it are slightly different --- in particular, + if you are already subscribed, the instructions about how to + unsubscribe are different. + Please note when reporting bugs that many exist only on certain architectures, which the developers may not have access to. In this case debugging information, as detailed as possible, is @@ -1894,12 +2074,12 @@ label(52) Two progressively lower volume lists exist, one with messages concerning the use of zsh, verb( - zsh-users@math.gatech.edu + zsh-users@sunsite.auc.dk ) and one just containing announcements: about releases, about major changes in the shell, or this FAQ, for example, verb( - zsh-announce@math.gatech.edu + zsh-announce@sunsite.auc.dk ) (posting to the last one is currently restricted). @@ -1913,25 +2093,17 @@ label(52) To join zsh-workers, send email to verb( - zsh-workers-request@math.gatech.edu + zsh-workers-subscribe@sunsite.auc.dk ) - with the mybf(subject) line (this is a change from the old list) - verb( - subscribe <your-email-address> - ) - e.g. - verb( - Subject: subscribe P.Stephenson@swansea.ac.uk - ) - and you can unsubscribe in the same way. - The list maintainer, Richard Coleman, can be reached at - email(coleman@math.gatech.edu). - - The list from May 1992 to May 1995 is archived in - url(ftp://ftp.sterling.com/zsh/zsh-list/YY-MM) -(ftp://ftp.sterling.com/zsh/zsh-list/YY-MM) - where YY-MM are the year and month in digits. More recent - mailings up to date are to be found at + (the actual content is unimportant). Replace tt(subscribe) with + tt(unsubscribe) to unsubscribe. The mailing software (tt(ezlm)) has + various bells and whistles: you can retrieve archived messages. + Mail email(zsh-workers-help@sunsite.auc.dk) for detailed information. + Adminstrative matters are best sent to + email(zsh-workers-owner@sunsite.auc.dk). The list maintainer's + real name is email(Karsten Thygesen <karthy@kom.auc.dk>). + + An archive of mailings for the last few years can be found at url(http://www.zsh.org/mla/)(http://www.zsh.org/mla/) at the main zsh archive in Australia. @@ -1947,18 +2119,47 @@ sect(What's on the wish-list?) lexing/parsing/execution might also be an advantage. Volunteers are particularly welcome for these tasks. - An improved line editor, with user-definable functions and binding - of multiple functions to keystrokes, is being developed. - + Here are the latest changes, which appeared in zsh 3.1.6. + itemize( + it() Even more powerful new completion system, based on shell functions, + allowing much more detailed control both over generation of matches + for completion and how they are inserted and displayed. A set of + functions which work `out of the box' will be available, including + many functions for external commands: files in tar archives can + be listed for extraction as if they were real files; GNU commands + which accept the mytt(--help) option can generate completion lists for + themselves on the fly, etc., etc. + You can have old-style tt(compctl)-based completions for some commands, + and new-style ones for others; you can bind particular completion + commands of your own definition to key-strokes. + it() Other completion enhancements: matching control, allowing + case-insensitive matching and wild card anchors, e.g. mytt(z_t<TAB>) + can allow a wildcard before the mytt(_) so that this will expand + to mytt(zle_tricky.c) --- all under user control; completions can + be grouped; a new completion command, menu-select, allows real menu + selection --- you can move the cursor around to choose a completion. + it() Case-insensitive and approximate matching in the globbing code: + for example, mytt((#ia2)readme) matches the string mytt(readme) + case-insensitively with up to two errors, such as tt(README), + tt(READ.ME), tt(_README_), tt(Read!Me!). The new completion system + knows about these, allowing correcting completion, e.g. + mytt(mkaef<TAB>) can be made to complete to mytt(Makefile). + it() Associative arrays, declared with mytt(typeset -A aname); syntax + for creating, accessing and deleting elements of these. + it() Users can create their own tt(foopath)/tt(FOOPATH) array/path + combinations, just like tt(path) and tt(PATH). + it() A dynamically loadable library for FTP, complete with a suite of + functions to make it easy to use. This allows you to use the shell's + capabilities for scripting, line editing, completion, I/O redirection, + directory management etc. within an FTP session. + ) + + Other future possibilities which have been suggested: itemize( - it() Loadable module support (will be in 3.1 but much work still needs doing). + it() Further improvements in integrating the line editor with shell + functions. it() Ksh compatibility could be improved. it() Option for glob qualifiers to follow perl syntax (a traditional item). - it() Binding of shell functions to key strokes, accessing editing - buffer from functions, executing zle functions as a command: now - under development for 3.1. - it() Users should be able to create their own foopath/FOOPATH array/path - combinations. ) @@ -1996,17 +2197,18 @@ nsect(Acknowledgments:) Thanks to zsh-list, in particular Bart Schaefer, for suggestions regarding this document. Zsh has been in the hands of archivists Jim Mattson, Bas de Bakker, Richard Coleman, Zoltan Hidvegi and Andrew -Main, and the mailing list has been run by Peter Gray, Rick Ohnemus -and Richard Coleman, all of whom deserve thanks. The world is -eternally in the debt of Paul Falstad for inventing zsh in the first -place (though the wizzo extended completion is by Sven Wischnowsky). +Main, and the mailing list has been run by Peter Gray, Rick Ohnemus, +Richard Coleman and Karsten Thygesen, all of whom deserve thanks. The +world is eternally in the debt of Paul Falstad for inventing zsh in +the first place (though the wizzo extended completion is by Sven +Wischnowsky). nsect(Copyright Information:) This document is copyright (C) P.W. Stephenson, 1995, 1996, 1997, -1998. This text originates in the U.K. and the author asserts his -moral rights under the Copyrights, Designs and Patents Act, 1988. +1998, 1999, 2000. This text originates in the U.K. and the author asserts +his moral rights under the Copyrights, Designs and Patents Act, 1988. Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this diff --git a/Etc/completion-style-guide b/Etc/completion-style-guide index 307954760..d57a1a7fb 100644 --- a/Etc/completion-style-guide +++ b/Etc/completion-style-guide @@ -1,44 +1,394 @@ -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 +Contexts, tags and all that +--------------------------- + +The completion system keeps track of the current context in the +parameter `curcontext'. It's content is the hierarchical name for the +current context sans the `:completion:' and the last colon and the tag +currently tried. The tags represent different types of matches. So, +whenever you are about to add matches, you should use a tag for them +and test if the user wants this type of matches to be generated. +However, this only really needs to be done if no other function in the +call chain has tested that already or if you can offer different types +of matches or if you can handle tag aliases in some sophisticated way. + +Most of the utility functions do the testing themselves, so you don't +have to worry about that at all. For example if you are adding matches +with `_files', `_hosts' or functions like these, you can just call +them and they do the tests needed and the loops over the tag aliases. +The functions `_arguments' and `_values' do that too, but there is a +small difference. These functions effectively change the context +name and if you are using the `->state' form for actions, this changed +name component has to be reported back to the function calling +`_arguments' or `_values'. This is done with the parameter `context', +so you have to make that local in the calling function in the same way +as you have to make local `line', `state', and `{opt,val}_args'. This +parameter `context' should then be used when you start adding matches +by giving it to functions like `_tags' via the `-C' options, as in: + + local context ... + ... + _arguments ... '-foo:foo:->foo' + ... + if [[ "$state" = foo ]]; then + _tags -C "$context" ... + ... + fi + +This will put the context name given in the argument field of the +`curcontext' parameter and this context will then be used to look +up styles for the tags. + +But since this is often used, `_arguments' and `_values' have support +to make your life easier in such cases. With the `-C' option, these +functions set the parameter `curcontext', thus modifying the globally +used hierarchical context name. This means, that you have to make that +local, but then you don't have to worry about giving the context name +reported back to functions you call. E.g.: + + local curcontext="$curcontext" ... + ... + _arguments -C ... 'foo:foo:->foo' + ... + if [[ "$state" = foo ]]; then + _tags ... + ... + fi + +In this case the parameter `context' is not set, so you don't have to +make that local. But make sure that `curcontext' is local so that the +value changed by `_arguments' and `_values' is only used in your +function (and make sure to initialise it to its old value as in the +example). + +Then, before adding the matches, see if matches of that type are +requested by the user in the current context. If you will add only one +type of matches, this is very simple. You can use the function +`_wanted' for this. Its return value is zero only if the type of +matches is requested by the user, so you can just do: + + _wanted names || return 1 + + _all_labels names expl 'name' compadd - alice bob + +The `_all_labels' function implements the loop over the tag aliases and +handles the user-defined description, using (in the example) the +parameter `expl' to store options to give to the command. These option +are inserted into the command line either directly before a single +hyphen if there is such an argument or after the first word if there +is no single hyphen. Since using `_all_labels' is so much more conveient +than writing the loop with the `_next_label' function (see below), but +some function called to generate matches don't accept a single hyphen +as argument anywhere but want the options built as their last arguments, +`_all_labels' will *replace* the hyphen with the options if the hyphen is +the last argument. A good example for such a function is +`_combination' which can be called like: + + _all_labels foo expl 'descr...' _combination ... - + +And the `-' will be replaced by the options that are to be given to +`compadd'. + +Since the above sequence of command is used so often, the `_wanted' +function can also accept the same arguments as `_all_labels'. In this +case it will do the test for the requested tag and then just call +`_all_labels', so: + + _wanted names expl 'name' compadd - alice bob + +Note that you can also give the `-J' and `-V' options with the +optional `1' or `2' preceding them supported by `_description': + + _wanted -2V names expl 'name' compadd ... + +In some cases one needs to call multiple functions or call `compadd' +more than once to generate the matches. In such a case one needs to +implement the loop over the tag aliases directly. This is done with the +`_next_label' function. Like this: + + while _next_label names expl 'name'; do + compadd "$expl[@]" - alice bob && ret=0 + _other_names "$expl[@]" && ret=0 + done + return ret + +Simple enough, I hope. But `_next_label' can do some more: utility +functions normally accept options which are then given to `compadd'. +Since these may contain options for the description and `_next_label' may +generate such options, too, it isn't entirely trivial to decide which +of these options should take precedence. But `_next_label' can do the work +for you here. All you have to do is to give the options your utility +function gets to `_next_label', as in: + + while _next_label names expl 'name' "$@"; do + compadd "$expl[@]" - alice bob + ... + done + +That's all. Note that the positional argument "$@" are *not* given to +`compadd'. They will be stuffed into the `expl' array by `_next_label'. + +The most complicated case is where you can offer multiple types of +matches. In this case the user should be able to say which types he +wants to see at all and of those which he wants to see he should be +able to say which types should be tried first. The generic solution +for this uses `_tags' and `_requested': + + local expl ret=1 + + _tags friends users hosts + + while _tags; do + _requested friends expl friend compad alice bob && ret=0 + _requested users && _users && ret=0 + _requested hosts && _hosts && ret=0 + + (( ret )) || break # leave the loop if matches were added + done + +`_tags' with tags as arguments registers those tags and checks which +of them the user wants to see and in which order the tags are to be +tried. This means that internally these tags are stored in multiple +sets. The types of matches represented by the tags from the first set +should be tried first. If that generates no matches, the second set is +tried and so on. `_tags' without arguments just makes the next set be +tried (on the first call it makes the first set be used). The function +`_requested' then tests if the tag given as its first argument is in +the set currently used and returns zero if it is, i.e. if matches of +that type should be added now. The arguments accepted by `_requested' +are the same as for `_wanted'. I.e. you can call it with only the tag +to test, with the `tag array description' or with that plus the +command to execute. + +In some cases (like the `users' and `hosts' tags in the example) you +don't need do the loop over the tag aliases yourself, because the +utility functions like `_users' and `_hosts' do it automatically. + +This looks good already. But in many cases such as this one you can +also use the function `_alternative' which simply implements a loop +like the one above. It gets arguments of the form `tag:descr:action'. +E.g.: + + _alternative \ + 'friends:friend:(alice bob)' \ + 'users:: _users' \ + 'hosts:: _hosts' + +Which does the same as the previous example. (Note the empty +descriptions in the last two arguments -- the actions start with a +space so that they are executed without giving the description +build by `_alternative', i.e. we just use the description added by +`_users' and `_hosts'). + +In cases where you have to keep track of the context yourself, you can +give the sub-context you want to use to `_tags', `_wanted' and +`_alternative' with the `-C' option as described above. You don't need +to give it to `_requested' -- that function will work on the context +used by the corresponding call to `_tags' automatically. + +For the names of the tags: choose simple (short, if at all possible) +names in plural. Also, first have a look at the tag names already used +by other functions and if any of these names seem sensible for the +type of matches you are about to add, the use those names. This will +allow users to define styles for certain types of matches independent +of the place where they are added. + +One final comment about when to use your own argument-contexts: do +this when the command you are writing a completion function for has +different `modes'. E.g. if it accepts host names after a `-h' option +and users or hosts after `-u' and for some reason you can't use +`_arguments' to do the work for you, then use context names as in: + + case "$1" in + -h) + _tags -C -h hosts && _hosts && ret=0 + ;; + -u) + _alternative -C -u 'users:: _users' 'hosts:: _hosts' && ret=0 + ;; + esac + + +Styles +------ + +Users can associate patterns for hierarchical context names with +certain styles using the `zstyle' builtin. The completion code +should then use these styles to decide how matches should be added and +to get user-configured values. This, too, is done using the builtin +`zstyle'. + +Basically styles map names to a bunch of strings (the `value'). In +many cases you want to treat the value as a boolean, so let's start +with that. To test if, for example, the style `verbose' is set for +the tag `options' in the context you are currently in, you can just do: + + if zstyle -t ":completion:${curcontext}:options" verbose; then + # yes, it is set... + fi + +I.e. with the -t option and two arguments `zstyle' takes the first one +as a context and the second one as a style name and returns zero if that +style has the boolean value `true'. Internally it checks if the style +is set to one of `yes', `true', `on', or `1' and interprets that as +`true' and every other value as `false'. + +For more complicated styles for which you want to test if the value +matches a certain pattern, you can use `zstyle' with the -m option and +three arguments: + + if zstyle -m ":completion:${curcontext}:foo" bar '*baz*'; then + ... + fi + +This tests if the value of the style `bar' for the tag `foo' matches +the pattern `*baz*' and returns zero if it does. + +If you just want to see if one of the strings in the value is exactly +equal to any of a number of a strings, you can use the -t option and +give the strings after the style name: + + if zstyle -t ":completion:${curcontext}:foo" bar str1 str2; then + ... + fi + +But sometimes you want to actually get the value stored for a certain +style instead of just testing it. For this `zstyle' supports four +options: `-b', `-s', `-a', and `-h'. After these options, three +arguments are expected, the context, the style, and a parameter name. +The parameter will then be set to the value of the style and the option +says how the strings stored as a value will be stored in the +parameter: + + - `-b': the parameter will be set to a either `yes' or `no' + - `-s': the parameter will be set to all strings in the value + concatenated (separated by spaces) to one string + - `-a': the parameter will be set to an array containing the strings + from the value as elements + - `-h': the parameter will be set to an association with the strings + from the value being interpreted alternatingly as keys and + values + +Some random comments about style names. Use the ones already in use if +possible. Especially, use the `verbose' style if you can add +matches in a simple and a verbose way. Use the verbose form only if +the `verbose' style is `true' for the current context. Also, if +the matches you want to add have a common prefix which is somehow +special, use the `prefix-needed' and `prefix-hidden' styles. The first +one says if the user has to give the prefix on the line to make these +matches be added and the second one says if the prefix should be +visible in the list. + +And finally, if you need a style whose value can sensibly be +interpreted as a list of words, use array or association styles with +the `-a' or `-h' options to `zstyle'. Otherwise you should only make +sure that an empty value for a style is treated in the same way as if +the style wasn't set at all (this is used elsewhere and we want to +keep things consistent). + + +Descriptions +------------ + +Always use description. This is important. Really. *Always* use +descriptions. If you have just written down a `compadd' without a +"$expl[@]" (or equivalent), you have just made an error. Even in +helper functions where you use a "$@": if you can't be sure that there +is a description in the arguments, add one. You can (and, in most +cases, should) then give the description you generated after the +"$@". This makes sure that the, probably more specific, description +given by the calling function takes precedence over the generic one +you have just generated. + +And it really isn't that complicated, is it? Think about a string +people might want to see above the matches (in singular -- that's used +throughout the completion system) and do: + + local expl + + _description tag expl <descr> + compadd "$expl@]" - <matches ...> + +Note that this function also accepts `-V' und `-J', optionally (in the +same word) preceded by `1' or `2' to describe the type of group you +want to use. For example: + + _description tag expl '...' + compadd "$expl[@]" -1V foo - ... # THIS IS WRONG!!! + +is *not* the right way to use a unsorted group. Instead do: + + _description -1V tag expl '...' + compadd "$expl[@]" - ... + +and everything will work fine. + +Also, if you are about to add multiple different types of matches, use +multiple calls to `_description' and add them with multiple calls to +`compadd'. But in almost all cases you should then add them using +different tags anyway, so, see above. + +And since a tag directly corresponds to a group of matches, you'll +often be using the tags function that allows you to give the +explanation to the same function that is used to test if the tags are +requested (again: see above). Just as a reminder: + + _wanted [ -[1,2]V | -[1,2]J ] <tag> expl <descr> + +and + + _requested [ -[1,2]V | -[1,2]J ] <tag> expl <descr> + +is all you need to make your function work correctly with both tags +and description at the same time. + + +Misc. remarks +------------- + +1) Supply match specifications to `compadd' if there are sensible ones. +2) Use helper functions that do option completion for you (like + `_arguments' and `_values') -- 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 +3) Use helper functions like `_users' and `_groups' instead of some ad hoc + mechanisms to generate such information. This ensures that users can + change the way these things will be completed everywhere by just using + their own implementations for these functions. +4) 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). + writing `[[ nm -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. +5) When writing helper functions that generate matches, the arguments + of these should be given unchanged to `compadd' (if they are not + used by the helper function itself). +6) When matches with a common prefix such as option names are generated, + add them *with* the prefix (like `-', `+', or `--' for options). + Then check the `prefix-needed' style to see if the matches are to be + added when the prefix is on the line and use the `prefix-hidden' + style to see if the prefix should be listed or not. +7) If at all possible, completion code for a command or a suite of + commands should go into only one file. If a command has sub-commands, + implementing a state-machine might be a good idea. See the `_rpm' + and `_pbm' files for examples of different styles. Also see the + documentation for `_arguments' and `_values' for two functions + that may help you with this. +8) If a completion function generates completely different types of + completions (for example, because the comamnd has several + completely different modes), it should allow users to define + functions that separately override the behavior for these + different types. This can easily be achieved by using the + `_funcall' utility function, as in: + + _funcall ret _command_$subcommand && return ret + + This will try to call the function `_command_$subcommand' and if + it exists, it will be called and the completion function exits + with its exit status. After this call to `funcall' the completion + function would contain the code for the default way to generate + the matches. + See the `_rpm' and `_nslookup' files for examples. |