diff options
author | Frank Terbeck <ft@bewatermyfriend.org> | 2011-12-01 10:02:04 +0100 |
---|---|---|
committer | Frank Terbeck <ft@bewatermyfriend.org> | 2011-12-01 10:02:04 +0100 |
commit | d8da5ea2f2bc5f837d0b364fff2636ebdb2f90ca (patch) | |
tree | 9fd9a57486ac4702608d92088ffd91f52971244f | |
parent | af2bb4fdb09414d21922d3fafe4e3a0ac1332f01 (diff) | |
parent | 9d71f4c207fb34e8d64af0443c83231b1cc3b494 (diff) | |
download | zsh-d8da5ea2f2bc5f837d0b364fff2636ebdb2f90ca.tar.gz zsh-d8da5ea2f2bc5f837d0b364fff2636ebdb2f90ca.zip |
Merge commit 'zsh-4.3.13' into debian
131 files changed, 5597 insertions, 1395 deletions
@@ -1,8 +1,752 @@ +2011-11-30 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Config/version.mk: 4.3.13 release. + +2011-11-28 Peter Stephenson <pws@csr.com> + + * Ismail Dönmez: 29920: Src/Subst.c: error with arithmetic + substitution with NO_EXEC. + +2011-11-25 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * unposted: Config/version.mk: 4.3.12-test-3. + +2011-11-24 Simon Ruderich <simon@ruderich.org> + + * 29916: Completion/Unix/Command/_git: Prevent clash with + _remote_files() in _ssh. + +2011-11-24 Peter Stephenson <pws@csr.com> + + * 29915: Completion/Unix/Command/.distfiles, + Completion/Unix/Command/_nm: new nm completion. + +2011-11-23 Peter Stephenson <pws@csr.com> + + * Ignacy Gawędzki: 29912: Completion/Unix/Command/_ssh: add "--" + to end options to ls. + +2011-11-21 Peter Stephenson <pws@csr.com> + + * Foudil Brétel: 29911: add --no-legend support (v37+); multiple + bug fixes (aliases, array range); workaround compadd bug + (compadd handles its own options) + +2011-11-20 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * gi1242+zsh: users/16587: Completion/Unix/Command_lp: tidy up. + +2011-11-18 Peter Stephenson <pws@csr.com> + + * 29908: Doc/Zsh/contrib.yo, Functions/MIME/.distfiles, + Functions/MIME/zsh-mime-contexts, Functions/MIME/zsh-mime-handler: + make MIME functions handle contexts with stacked suffixes such + as .pdf.gz. + +2011-11-17 Peter Stephenson <pws@csr.com> + + * Jun T.: 29907: Src/Modules/pcre.c: remove declaration of + unused variable. + +2011-11-15 Barton E. Schaefer <schaefer@zsh.org> + + * users/16581: Src/utils.c: it seems wrong to shortcut correction + of words not in command position by comparing them to the command + tables, so don't; if a command correction is rejected, reset the + incremental path hashing so the new command can be "learned". + +2011-11-14 Peter Stephenson <pws@csr.com> + + * gi1242: users/16578: Completion/Unix/Command/_lp: lpadmin, + lpinfo and other changes. + +2011-11-09 Frank Terbeck <ft@bewatermyfriend.org> + + * Akinori MUSHA: 29900: + Functions/VCS_Info/Backends/VCS_INFO_detect_svn: Adjust detection + to support subversion 1.7. + +2011-11-08 Peter Stephenson <pws@csr.com> + + * Haakon Riiser: 29895, 29887: Completion/Unix/Command/_ffmpeg, + Completion/Linux/Command/_nmcli (plus + Completion/Linux/Command/.distfiles): update and new + NetworkManager client completion. + +2011-11-07 Simon Ruderich <simon@ruderich.org> + + * 29893: Completion/Unix/Command/_ssh: Update (mostly) for 5.9. + +2011-11-07 Peter Stephenson <pws@csr.com> + + * 29894: Doc/Zsh/contrib.yo, Functions/Zle/replace-string: + display previous replacement and reuse if source string is empty. + +2011-11-04 Peter Stephenson <pws@csr.com> + + * 29892: Functions/Zle/read-from-minibuffer, + Functions/Zle/replace-string: fix regular expression + replacements right of the cursor; make save and restore + in read-from-minibuffer more automated. + + * 29891: Doc/Zsh/zle.yo, Src/Zle/zle_thingy.c: allow "zle -lL" + with arguments to list in -L format. + +2011-10-31 Peter Stephenson <pws@csr.com> + + * Jun T: 29883: Src/Builtins/rlimits.c, Src/Modules/zftp.c: cast + to type in printf to work around cases where types aren't + properly distinguished. + +2011-10-30 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * users/16547: Completion/Unix/Command/_perforce: quote + arguments with colon in from _describe. + +2011-10-28 Peter Stephenson <pws@csr.com> + + * Src/module.c (do_load_module): 29879: (via takimoto-j): Metafy + dlerror message to avoid corruption. + +2011-10-26 Phil Pennock <pdpennock@users.sourceforge.net> + + * 29867: Bart Schaefer: Test/V07pcre.ztst: exit early with + unimplemented status if zsh/pcre not available; combined with + Peter's 29865 fix, should make PCRE testing robust. + +2011-10-26 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 29844, 29845: Src/exec.c, Test/A04redirect.ztst: remove bogus + error on closing fd's 0 to 9; update test. + +2011-10-26 Peter Stephenson <pws@csr.com> + + * 29865: Src/Modules/pcre.mdd: don't compile if no pcre-config. + + * 29859: Src/Zle/Complete.c: compadd handles its own options. + +2011-10-24 Peter Stephenson <pws@csr.com> + + * Jérémie Roquet: c.f. users/16541: Doc/Zsh/cond.yo: + should be "filename generation", not "file generation". + + * Foudil Brétel: 29842: Completion/Unix/Command/_systemctl: + major rewrite. + +2011-10-24 Phil Pennock <pdpennock@users.sourceforge.net> + + * 29838: Src/Modules/pcre.c: metafy/unmetafy strings, to + correctly handle non-ASCII characters in UTF-8 for regexp + matches. + + * unposted: Test/V07pcre.ztst: some PCRE tests + +2011-10-23 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * users/16492: MACHINES: OpenIndiana issue. + +2011-10-22 Simon Ruderich <simon@ruderich.org> + + * 29823: Completion/Unix/Command/_perl: Update for 5.14.1. + +2011-10-19 Frank Terbeck <ft@bewatermyfriend.org> + + * Suraj N. Kurapati: 29828: Misc/vcs_info-examples: Mention + different ways to handle remote branch names in + `vi-git-remotebranch()'. + +2011-10-17 Peter Stephenson <pws@csr.com> + + * unposted: NEWS, README, Config/version.mk, Etc/.distfiles, + Etc/FAQ.yo, Etc/relnote_4.3.12.txt: tidy up and update for + 4.3.12-test-2. + + * unposted: Completion/Unix/Command/_perforce: small + documentation update. + +2011-10-14 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 29820: Doc/Zsh/compsys.yo, + Completion/Base/Utility/_pick_variant: -b option to match + builtins. + +2011-10-12 Mikael Magnusson <mikachu@gmail.com> + + * 29815: Doc/Makefile.in: include mod_langinfo in documentation. + +2011-09-25 Barton E. Schaefer <schaefer@zsh.org> + + * 29799: Src/utils.c: swap order of RESET_PROMPT / REFRESH in + adjustwinsize() so that the cursor is moved to the start of a + multi-line prompt before the prompt is actually displayed. + + * 29769: Src/signals.c: handle thisjob == -1 (no foreground job) + when checking for whether a background job is allowed to suspend. + + * unposted: Doc/Zsh/modules.yo: cross-reference zmodload. + +2011-09-22 Peter Stephenson <pws@csr.com> + + * Daniel Friesel: 29796: Completion/X/Command/_mplayer: complete + .webm. + +2011-09-21 Peter Stephenson <pws@csr.com> + + * Luka Perkov: 29788: Completion/Unix/Command/_quilt: + improved quilt completion. + +2011-09-18 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * users/16375: Src/Zle/complist.c: initialise number of + references each time for multiple match tests when + highlighting. + +2011-09-16 Mikael Magnusson <mikachu@gmail.com> + + * 29764, 29765: Completion/Unix/Command/_pgrep: use _users and + _groups rather than reimplementing them, use _wanted instead + of plain compadd to get descriptions, return 0 on success, + fix conditions on -f and -x, complete pts/* for -t too. + +2011-09-15 Peter Stephenson <pws@csr.com> + + * 29776 (modified as noted): Src/lex.c, Test/D08cmdsubst.ztst: + double quotes are not special in double-quote-style parsing + if the end character is something else. + + * 29773: Marco Hinz: Completion/Unix/Type/_perl_modules: + complete some missed modules. + +2011-09-10 Clint Adams <clint@zsh.org> + + * 29762: Completion/Debian/Command/_bts: bts completion tag + update from Ansgar Burchardt. + +2011-09-10 Barton E. Schaefer <schaefer@zsh.org> + + * 29760: Completion/compaudit: declare _i_ulwdirs and make sure + it is correctly referenced. + +2011-09-07 Peter Stephenson <pws@csr.com> + + * unposted: Completion/Unix/Command/_perforce: updates for + 2010.2 release. + +2011-09-07 Simon Ruderich <simon@ruderich.org> + + * 29756: Doc/Zsh/params.yo: DIRSTACKSIZE is unlimited by default. + + * 29757: Doc/Zsh/compsys.yo: Remove superfluous brace. + +2011-09-07 Mikael Magnusson <mikachu@gmail.com> + + * 29755: Completion/Unix/Command/_ssh: add -O stop to to _ssh. + +2011-09-06 Mikael Magnusson <mikachu@gmail.com> + + * 29736: Doc/Zsh/mod_zutil.yo: mention when zstyle -t returns 1. + + * 29738: Completion/Unix/Command/_ssh: add PreferredAuthentications + completion. + + * 29739: Completion/Unix/Command/_rsync: redefine _rsync(), make + -e accept cuddled arguments. + + * 29740: Completion/Unix/Command/_wget: add --content-disposition. + + * 29741: Completion/Zsh/Command/_zattr: add ret=0, fix filename + globbing like in 27658 for _zip. + + * 29733: Jonathan Kolberg: Completion/Debian/Command/_apt: add + completion for apt-get changelog. + +2011-09-05 Barton E. Schaefer <schaefer@zsh.org> + + * users/16302: Completion/Unix/Type/_path_files: pattern matching + for plain files (e.g., *.pdf for xpdf completion) was broken by + 29444. Hopefully this does not re-break directory patterns. + +2011-08-30 Simon Ruderich <simon@ruderich.org> + + * 29745: Mikael Magnusson: Completion/X/Command/_mplayer: fix -ss + completion. + +2011-08-29 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 29744: Src/builtin.c: don't mess up non '-A' case in + 29731. + +2011-08-29 Barton E. Schaefer <schaefer@zsh.org> + + * users/16291: Functions/Prompts/prompt_bart_setup: revert to + using history text in non-"fg" case to avoid alias expansion. + +2011-08-29 Mikael Magnusson <mikachu@gmail.com> + + * 29722: Completion/X/Command/_mplayer: escape colon. + + * 29706: Completion/X/Command/_mplayer: add missing ret=0. + +2011-08-28 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 29731: Src/builtin.c, Test/B04read.ztst: fix output from `read + -AE' and test that and `read -Ae'. + + * users/16289: Doc/Zsh/expn.yo, Src/exec.c, Src/jobs.c: don't + delete temporary files when disowning and document this. + +2011-08-20 Barton E. Schaefer <schaefer@zsh.org> + + * unposted: Functions/Zle/.distfiles: add move-line-in-buffer + + * 29711: Completion/compaudit: avoid calling potentially-slow + "getent group" unless group-writable directories are found. + +2011-08-20 Nikolai Weibull <now@bitwi.se> + + * 29707: Completion/Unix/Command/.distfiles, + Completion/Unix/Command/_ln: New _ln completer. + +2011-08-18 Mikael Magnusson <mikachu@gmail.com> + + * unposted: Completion/Linux/Command/.distfiles, + Completion/Linux/Command/_schedtool, + Completion/Zsh/Command/.distfiles, + Completion/Zsh/Command/_schedtool: move _schedtool completion + to correct directory. + + * 29705: Completion/Unix/Command/_iconv: add correct number of + slashes when completing //TRANSLIT. + +2011-08-17 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 29703: Src/exec.c, Src/subst.c, Test/D03procsubst.ztst: + + * users/16253, users/16255: Src/utils.c, Test/D04parameter.ztst: + A nulstring should be split like an empty string. + + * Anthony R Fletcher: users/16260: + Completion/Unix/Command/_systemctl: new completion. + +2011-08-17 Nikolai Weibull <now@bitwi.se> + + * 29698: Completion/Unix/Command/_git: Complete diff options for git + log. + +2011-08-17 Mikael Magnusson <mikachu@gmail.com> + + * 29681: Src/Zle/zle_refresh.c: consistently use [] to access + region_highlights. + + * 29682: Completion/Zsh/Command/.distfiles, + Completion/Zsh/Command/_schedtool: new _schedtool completer. + + * 29683: Completion/Unix/Command/_ssh: add -O forward to _ssh. + + * Daniel Friesel: 29690: Completion/Linux/Command/_cryptsetup, + Completion/Unix/Command/_twidge: new _twidge and _cryptsetup + completers. + +2011-08-16 Barton E. Schaefer <schaefer@zsh.org> + + * 29694: Src/hist.c: Don't overwrite the current history word if + we aren't actually expanding an alias or history event. + + * users/16251: Functions/Prompts/prompt_bart_setup: use a preexec + hook to replace "fg" et al. with the jobtext of the resumed job. + +2011-08-16 Wayne Davison <wayned@users.sourceforge.net> + + * 29650: Src/jobs.c: don't lose the the time info after a + suspend+restore. + +2011-08-15 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * unposted: Src/Modules/datetime.c: use pm->node.nam to get + parameter names for errors. + +2011-08-14 Mikael Magnusson <mikachu@gmail.com> + + * 29673: Doc/Zsh/compsys.yo: clarify what 'other' in the + ignore-line style does. + + * 28852: Misc/zargs, Zle/match-words-by-style: use syntax that + doesn't depend on SHORT_LOOPS being set. + + * unposted: Src/hist.c: fix a typo in a comment. + + * unposted: Src/jobs.c: fix capitalized word in the middle of + a sentence. + + * 29388, 29680: Doc/Zsh/expn.yo: clarify note about e:string: + quoting. + + * 29504: Doc/Zsh/expn.yo: note when (#cN,M) can't be used in + place of # or ##. + +2011-08-14 Barton E. Schaefer <schaefer@zsh.org> + + * 29677: Src/exec.c, Src/signals.c, Src/zsh.h: flag jobs that are + builtins running in the current shell, and if they control a + pipeline, do not allow the external processes in that pipeline to + become suspended when the foreground shell cannot suspend. + +2011-08-11 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Src/Modules/datetime.mdd: unposted: also fix the autofeatures. + + * Src/params.c: unposted: Src/params.c, Test/V04features.ztst: + fix some tests I broke. + + * Src/subst.c: 29674: Src/Modules/datetime.c, + Doc/Zsh/mod_datetime.yo: add $epochtime array. + +2011-08-10 Peter Stephenson <pws@csr.com> + + * 29663: configure.ac, Src/module.c, Src/Modules/datetime.c, + Doc/Zsh/mod_datetime.yo: add $EPOCHREALTIME for time in + double precision floating point. + +2011-08-04 Peter Stephenson <pws@csr.com> + + * 29643: Src/signals.c, Src/utils.c, Src/zle_main.c: set + incompfunc to zero when executing hook or trap function. + +2011-08-09 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 29661: Doc/Zsh/redirect.yo: Improve the documentation for + {var}>... redirections. + +2011-08-09 Barton E. Schaefer <schaefer@zsh.org> + + * 29654: Src/jobs.c: "wait" should resume stopped jobs identified + by process ID as well as by job number. + + * 29654: Src/exec.c: don't hide the job table entry for the left + side of a pipline that ends in a shell builtin. This change may + be backed out if the patch in 29660 can be improved. + +2011-08-03 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 29644: Functions/Chpwd/zsh_directory_name_cdr, + Src/Zle/compcore.c, Src/Zle/zle_tricky.c: Work round a bug in + _describe, plus a new comment and some more braces. + + * 29633: Doc/Zsh/func.yo, Src/parse.c, Test/C04funcdef.ztst: be + more careful that anonymous function syntax doesn't mess up + working syntax with other functions. + +2011-08-03 Peter Stephenson <pws@csr.com> + + * 29635: Completion/Base/Widget/_complete_debug: Improve file + descriptor handling and standardise syntax. + +2011-07-29 Frank Terbeck <ft@bewatermyfriend.org> + + * Luka Perkov: 29624: Completion/Unix/Command/_quilt: Improve + `push' and `pop' completion. + +2011-07-28 Peter Stephenson <pws@csr.com> + + * 29626: Src/parse.c, Test/C04funcdef.ztst: arguments to + anonymous functions shouldn't be parsed as command words. + + * 29602 and subsequent changes: Doc/Zsh/expn.yo: clarify meaning + of filename extension in :r and :e modifiers (which were + slightly inconsistent). + +2011-07-27 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 29561: Test/A04redirect.ztst: this bit didn't get committed, + somehow. + +2011-07-27 Mikael Magnusson <mikachu@gmail.com> + + * 29618: Completion/Linux/Command/_ethtool, + Completion/Zsh/Type/_file_descriptors: Fix some syntax to not depend + on SHORT_LOOPS being set. + +2011-07-25 Peter Stephenson <pws@csr.com> + + * 29561: Src/exec.c, Src/utils.c, Test/A04redirect.ztst: Allow + closing of file descriptors not recorded internally by the shell. + +2011-07-22 Mikael Magnusson <mikachu@gmail.com> + + * 29596: Completion/compinit: Fix syntax to work with KSH_ARRAYS + set. + +2011-07-22 Nikolai Weibull <now@bitwi.se> + + * unposted: Completion/Unix/Command/_git: Use _files, not _path_files. + + * 29582: Completion/Unix/Command/_git: Alter the way that commands and + aliases are listed when both are requested. + + * 29589: Completion/Unix/Command/_git, + Completion/Debian/Command/_git-buildpackage: Use #description instead + of #desc: for description of third-party commands. Also, refactor the + code to match the rest of the file. + +2011-07-21 Nikolai Weibull <now@bitwi.se> + + * 29272: Completion/Unix/Command/_git: Use return values correctly + accross all completion functions. + + * unposted: Completion/Unix/Command/_git: Move _gitk and _tig to + correct location. + + * unposted: Completion/Unix/Command/_git: Fix bug in git-add completion + that prevented -f option from being used correctly. + + * unposted: Completion/Unix/Command/_git: Update git-add completion to + not complete already given file arguments and also to not list file + completions if an option is being completed. + + * unposted: Completion/Unix/Command/_git: Adjust some TODO items. + +2011-07-19 Peter Stephenson <pws@csr.com> + + * 29555: Src/exec.c: fix problem that shell failed to use file + descriptor opened in parent if beyond max_zsh_fd. + +2011-07-18 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * users/16131: Src/hist.c: skip reading an empty history file. + +2011-07-18 Peter Stephenson <pws@csr.com> + + * Matthieu Baerts: 29547: Completion/Unix/Command/_bzr: cdiff + subcommand. + +2011-07-12 Peter Stephenson <pws@csr.com> + + * 29543: Src/hist.c: saved history lines with backslash-newline + in the middle of words confused histlexwords. + + * 29542: Src/hist.c, Src/Zle/zle_main.c: remove test when + initialising history that could cause crashes (and was probably + never useful); ensure ZLE returns NULL if there's an error. + +2011-07-04 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Eric Moors: 29531: Completion/Unix/Command/_adb: completion + for Android debugger. + +2011-07-03 Frank Terbeck <ft@bewatermyfriend.org> + + * unposted: Doc/Zsh/contrib.yo: Fix typo "paramter". Caught by + debian's lintian. + +2011-07-01 Peter Stephenson <pws@csr.com> + + * 29530: Src/subst.c, Test/E01options.ztst: ${..?..} shouldn't + cause an error with NO_EXEC option. + +2011-07-01 Frank Terbeck <ft@bewatermyfriend.org> + + * 29518: Completion/Unix/Command/_git: Fall back to file + completion for unknown sub-commands. + + * 29527: Completion/Unix/Command/_git: Make file-completion + fallback optional. + + * 29519: Completion/Unix/Command/_git: Pick up addon completions + from $fpath. + + * 29521: Completion/Unix/Command/_git: Add `user-commands' support + again. + + * 29523: Completion/Debian/Command/_git-buildpackage: Use "#desc:" + line for _git third-party add-on completion description. + + * Daniel Bolton: 29529: Completion/Debian/Command/_aptitude: Complete + format specifiers with the `-F' option. + +2011-06-30 Frank Terbeck <ft@bewatermyfriend.org> + + * 29526: Functions/VCS_Info/vcs_info: Set `max-exports' early + after certain `start-up' hooks. + +2011-06-28 Frank Terbeck <ft@bewatermyfriend.org> + + * Sebastian Ramacher: 29513: Completion/Debian/Command/_apt: Add + markauto and unmarkauto sub-commands. + +2011-06-27 Peter Stephenson <pws@csr.com> + + * Mikael Muszynski: 29510: Completion/X/Command/_mplayer: + complete .m4v files. + +2011-06-25 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Axel Beckert: 29506: Doc/Zsh/params.yo: use format + SINGLE_LINE_ZLE as elsewhere in manual. + +2011-06-23 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 29503: Src/exec.c: Missing popheap() on failed autoload. + +2011-06-20 Peter Stephenson <pws@csr.com> + + * unposted: update version to 4.3.12-dev-1 as wordcode + now incompatible with anonymous functions. + +2011-06-20 Doug Kearns <dougkearns@gmail.com> + + * unposted: Completion/BSD/Command/_sockstat, + Completion/Debian/Command/_git-buildpackage, + Completion/Unix/Command/_at, Completion/Unix/Command/_lp, + Completion/Unix/Command/_unison, Completion/X/Command/_matlab, + Completion/X/Command/_okular, Completion/Zsh/Function/_zargs: clean up + completion descriptions as per Etc/completion-style-guide. + +2011-06-19 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Luka Perkov: 29493: Completion/Unix/Type/_pdf: handle apvlv. + + * 29492: Doc/Zsh/func.yo, Src/exec.c, Src/parse.c, Src/text.c, + Test/C04funcdef.ztst: add argument handling to anonymous functions. + + * unposted: Src/Zle/zle_refresh.c: remove additional loop + noticed by Mikael. + + * 29491: Src/glob.c, Src/lex.c, Src/math.c, Src/params.c, + Src/parse.c, Src/utils.c, Src/Modules/db_gdbm.c, + Src/Zle/compcore.c, Src/Zle/complist.c, Src/Zle/zle_refresh.c, + Src/Zle/zle_tricky.c: remove some variables set but not used. + + * 29490: Src/Builtins/rlimits.awk, Src/Builtins/rlimits.c, + Src/Builtins/rlimits.mdd: add RLIMIT_RTTIME. + +2011-06-18 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Michel Dos Reis: 29482: Completion/Linux/Command/_modutils: + handle .gz kernel modules. + +2011-06-16 Doug Kearns <dougkearns@gmail.com> + + * 29483: Completion/Unix/Command/_vim: add --servername completion. + +2011-06-15 Barton E. Schaefer <schaefer@zsh.org> + + * 29481: Src/jobs.c, Src/signals.c: always return a matching job + in findproc() [reverses 28967 and 29472], but scan the whole list + to prefer running jobs in the rare event that one running and one + exited job share a PID. + +2011-06-14 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * unposted: Doc/Zsh/compwid.yo: document change to brace + parameter context in 29452/29459. + +2011-06-12 Barton E. Schaefer <schaefer@zsh.org> + + * 29472: Src/jobs.c: findproc() needs at least to also return + stopped jobs. See 28967. + +2011-06-08 Peter Stephenson <pws@csr.com> + + * Jeremy Sylvestre: 29468: Functions/Zle/define-composed-chars: + add some ligatures and symbols. + +2011-06-06 Peter Stephenson <pws@csr.com> + + * 29462: Src/subst.c: fix warning with some compilers (code was + already safe). + +2011-06-05 Clint Adams <clint@zsh.org> + + * unposted: Functions/Zle/move-line-in-buffer: clean + the funny characters out of move-line-in-buffer. + +2011-06-04 Barton E. Schaefer <schaefer@zsh.org> + + * 29444: Completion/Unix/Type/_path_files: when called with a + pattern to match directories, as from _files with list-dirs-first, + do not descend into subdirectories looking for fake files unless + some fake files have been defined. + +2011-06-04 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 29459: Completion/Zsh/Context/_brace_parameter, + Src/Zle/compcore.c (check_param): In shell function, check for + ${( not at start of match; in C code, check for untokenized + parentheses when in double quotes. + +2011-06-03 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 29452: Completion/Zsh/Context/_brace_parameter, + Src/Zle/compcore.c (typo corrected): allow completion + of parameter flags. + +2011-06-03 Mikael Magnusson <mikachu@gmail.com> + + * 29438: Completion/Zsh/Context/_subscript: adjust pattern so + we complete dynamic directory names in command position as well. + + * 29448: Completion/Unix/Command/_initctl: complete symlinks + to files too. + + * 29422: Test/D04parameter.ztst: Fix test for g:: to not depend + on the current locale. + +2011-06-03 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 29451: Src/subst.c, Test/D04parameter.ztst: ${##stuff} + removes stuff from the head of $#. + + * 29413: Doc/Zsh/builtins.yo, Src/builtin.c, Src/hist.c: print + -S takes a single argument, applies lexical history word + splitting, and puts it on the history. + +2011-06-02 Frank Terbeck <ft@bewatermyfriend.org> + + * 29434: Doc/Zsh/contrib.yo: Use PLUS() to avoid a + being + silently dropped. + +2011-06-01 Frank Terbeck <ft@bewatermyfriend.org> + + * 29412: Completion/Unix/Command/_tmux: Disable sub-command + completions if tmux is not found in `$path'. + + * Valentin Haenel: 29431: Misc/vcs_info-examples: Hook example for + signaling untracked files in git repositories. + +2011-06-01 Barton E. Schaefer <schaefer@zsh.org> + + * users/16064: Functions/Zle/move-line-in-buffer: example widget + for moving in multiline buffers without navigating history + + * 29416 (plus typo fixes): Doc/Zsh/contrib.yo: Fix (mis-)uses of + var() in vcs_info documentation. + +2011-05-31 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * unposted: Config/version.mk: update version to 4.3.12-dev-0 + to avoid confusion with release. + +2011-05-31 Frank Terbeck <ft@bewatermyfriend.org> + + * Jan Pobrislo: 29411: + Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr: vcs_info: Major + bzr backend update. + +2011-05-31 Barton E. Schaefer <schaefer@zsh.org> + + * 29410: Test/V01zmodload.ztst: skip autoload persistence test + when zsh/example module is not available. + +2011-05-31 Mikael Magnusson <mikachu@gmail.com> + + * Omari Norman: users/16057: Completion/Unix/Command/.distfiles, + Completion/Unix/Command/_tree: Add completion for tree. + 2011-05-31 Peter Stephenson <pws@csr.com> * unposted: Config/version.mk: release 4.3.12. -2011-05-29 Nikolai Weibull <now@bitwi.se> +2011-05-29 Nikolai Weibull <now@bitwi.se> * unposted: Completion/Unix/Command/_git: Update git-branch completion to deal with -r and -d correctly. @@ -11,7 +755,7 @@ * 29403: Src/hist.c: histlexwords splitting of ";;" in case. -2011-05-27 Mikael Magnusson <mikachu@gmail.com> +2011-05-27 Mikael Magnusson <mikachu@gmail.com> * 28364: Doc/Zsh/zle.yo: Document that space left by wrapping double-width characters is highlighted with the 'special' style. @@ -38,7 +782,7 @@ * 29382: Src/Modules/curses.c: apply 29374 to zccmd_input too. -2011-05-27 Mikael Magnusson <mikachu@gmail.com> +2011-05-27 Mikael Magnusson <mikachu@gmail.com> * 29331: NEWS: Note g:: parameter expansion flag. @@ -78,7 +822,7 @@ assumptions introduced by 25145 and add check of redirection inside a function body. -2011-05-24 Mikael Magnusson <mikachu@gmail.com> +2011-05-24 Mikael Magnusson <mikachu@gmail.com> * 29364: Completion/Unix/Command/_make: Partial fix for completion in dirs with spaces and other unusual characters. @@ -102,7 +846,7 @@ Completion/Unix/Command/.distfiles: basic completion for commands associated with the Go programming language. -2011-05-22 Mikael Magnusson <mikachu@gmail.com> +2011-05-22 Mikael Magnusson <mikachu@gmail.com> * unposted: Doc/Zsh/compsys.yo, ChangeLog: Quote -e with tt(). Fix some formatting in ChangeLog. @@ -113,7 +857,7 @@ Completion/Unix/Command/_php: Another missing backslash in _git, remove some not needed backslashes in array definitions. -2011-05-19 Mikael Magnusson <mikachu@gmail.com> +2011-05-19 Mikael Magnusson <mikachu@gmail.com> * 29224: Doc/Zsh/expn.yo, NEWS, Src/subst.c, Test/D04parameter.ztst: Support negative LEN in ${VAR:OFFSET:LEN} @@ -165,7 +909,7 @@ * Nikolai Weibull: 29166: Completion/Unix/Command/_git: Speed improvements for file completion. -2011-05-17 Nikolai Weibull <now@bitwi.se> +2011-05-17 Nikolai Weibull <now@bitwi.se> * 29273: Completion/Unix/Command/_git: Parse compadd options in __git_guard_number. @@ -175,7 +919,7 @@ * 29278: Completion/Unix/Type/_path_files: fix use of the $skips pattern from the squeeze-slashes style. -2011-05-14 Mikael Magnusson <mikachu@gmail.com> +2011-05-14 Mikael Magnusson <mikachu@gmail.com> * 29271: Doc/Zsh/compwid.yo: document _alternative -O name. @@ -213,7 +957,7 @@ * unposted (late commit): Completion/Unix/Command/.distfiles, Config/version.mk, Test/.distfiles: update for 4.3.11-dev-3. -2011-05-12 Mikael Magnusson <mikachu@gmail.com> +2011-05-12 Mikael Magnusson <mikachu@gmail.com> * 29245: Completion/X/Command/_xset: pass -O instead of -o to _describe. @@ -226,7 +970,7 @@ * 29208: Src/Zle/zle_move.c: make vimatchbracket check the character left of the cursor when at the end of the line. -2011-05-11 Mikael Magnusson <mikachu@gmail.com> +2011-05-11 Mikael Magnusson <mikachu@gmail.com> * 29206: Doc/Zsh/mod_complist.yo: fix formatting. @@ -352,7 +1096,7 @@ * 29107: Src/Zle/zle_tricky.c: replace overlapping strcpy with memmove. -2011-04-27 Mikael Magnusson <mikachu@gmail.com> +2011-04-27 Mikael Magnusson <mikachu@gmail.com> * 29051: Completion/Unix/Command/_make: add _make- prefix to internal helper functions. @@ -425,7 +1169,7 @@ * Simon Ruderich: 28927: Completion/Unix/Command/_git: Fix "git tag -v" completion. -2011-04-15 Mikael Magnusson <mikachu@gmail.com> +2011-04-15 Mikael Magnusson <mikachu@gmail.com> * 28998: Completion/Unix/Command/_make: set return status correctly. @@ -463,7 +1207,7 @@ 2011-04-01 Peter Stephenson <pws@csr.com> - * Stef van Vlierberghe: 28965 (as posted in 28967): + * Stef van Vlierberghe: Src/jobs.c: 28965 (as posted in 28967): findproc() should not return processes not marked as SP_RUNNING since findproc() is used find processes still known to the OS. @@ -494,7 +1238,7 @@ Functions/VCS_Info/vcs_info: Make the nvcsformats style be used if vcs_info is disabled. -2011-03-29 Mikael Magnusson <mikachu@gmail.com> +2011-03-29 Mikael Magnusson <mikachu@gmail.com> * unposted: Completion/Unix/Command/_vim: Fix typo in description for -N. @@ -602,7 +1346,7 @@ 2011-03-01 Peter Stephenson <p.w.stephenson@ntlworld.com> * Baptiste: 28819: Completion/BSD/Command/_sockstat, - Completion/Unix/Command/_mount, + Completion/Unix/Command/_mount, Completion/Unix/Type/_file_systems: FreeBSD completion tweaks. 2011-02-28 Barton E. Schaefer <schaefer@zsh.org> @@ -2112,11 +2856,11 @@ * Frank: 27717: Functions/VCS_Info/vcs_info_lastmsg: add option terminators for builtins. -2010-12-17 Andrey Borzenkov <bor@zsh.org> +2010-12-17 Andrey Borzenkov <bor@zsh.org> * unposted: Doc/Zsh/compsys.yo: typo fix -2010-12-16 Andrey Borzenkov <bor@zsh.org> +2010-12-16 Andrey Borzenkov <bor@zsh.org> * 27715: Completion/Unix/Command/_stgit: fixes for new version (workaround removed commands); autogenerate list @@ -2394,7 +3138,7 @@ * 27518: Completion/Unix/Command/_configure: suggest some more patterns for arguments. -2009-12-14 Andrey Borzenkov <bor@zsh.org> +2009-12-14 Andrey Borzenkov <bor@zsh.org> * unposted: Completion/Unix/Command/_grep: add --exclude-dir option @@ -3011,7 +3755,7 @@ save and restore the lexical context to avoid pulling the rug out when called in some nested fashion. -2009-06-28 Andrey Borzenkov <bor@zsh.org> +2009-06-28 Andrey Borzenkov <bor@zsh.org> * unposted: Completion/Unix/Command/_man: support lzma compression of man pages used in Mandriva @@ -3197,7 +3941,7 @@ variables should be zeroed even if the module is being unloaded (problem on HP-UX). -2009-05-09 Andrey Borzenkov <bor@zsh.org> +2009-05-09 Andrey Borzenkov <bor@zsh.org> * unposted: Completion/Unix/Command/_getfacl: fix options definition; add file names completion for variant=unix @@ -3308,7 +4052,7 @@ * Kalle Olavi Niemitalo: 26850: Completion/Unix/Command/_git: fix breakage in git write-tree and git send-pack. -2009-04-18 Andrey Borzenkov <bor@zsh.org> +2009-04-18 Andrey Borzenkov <bor@zsh.org> * users/14033 as modified by users/14037 and added doc: Completion/Base/Utility/_describe, Doc/Zsh/compsys.yo: allow @@ -3772,7 +4516,7 @@ * Richard Hartmann: 26535: Doc/Zsh/options.yo: remove typo. -2009-02-08 Andrey Borzenkov <bor@zsh.org> +2009-02-08 Andrey Borzenkov <bor@zsh.org> * 26530: Doc/Zsh/builtins.yo: clarify that "emulate -c" restores all options on return, not only those related @@ -3805,7 +4549,7 @@ * 26513: README: note that addition of ".." in completion was broken. -2009-02-01 Andrey Borzenkov <bor@zsh.org> +2009-02-01 Andrey Borzenkov <bor@zsh.org> * 26504: Doc/Zsh/options.yo: document that LOCAL_OPTIONS does not restore PRIVILEGED and RESTRICTED @@ -3879,7 +4623,7 @@ * Greg Klanderman: 26439: Doc/Zsh/mod_system.yo: convert sections to subsections. -2009-01-25 Andrey Borzenkov <bor@zsh.org> +2009-01-25 Andrey Borzenkov <bor@zsh.org> * 26425: Doc/Zsh/builtins.yo Src/builtin.c: "emulate csh -c command" will evaluate `command' after temporary @@ -4005,7 +4749,7 @@ * unposted: add RCS Revision tag for use in patchlevel recording. -2009-01-09 Andrey Borzenkov <bor@zsh.org> +2009-01-09 Andrey Borzenkov <bor@zsh.org> * 26270: Completion/Base/Utility/_values, Doc/Zsh/compwid.yo, Src/Zle/compcore.c, Src/Zle/complete.c, Src/Zle/compresult.c: @@ -4043,7 +4787,7 @@ Completion/Unix/Type/_ps, Completion/Unix/Type/_pdf: files compressed with .bz2. -2009-01-05 Andrey Borzenkov <bor@zsh.org> +2009-01-05 Andrey Borzenkov <bor@zsh.org> * 26247: configure.ac, Src/Zle/zle_tricky.c: fix compilation with -Werror=format-security GCC option. @@ -5083,7 +5827,7 @@ of complex sublists were wrong, plus test; another place to make lineno more consistent. -2008-08-31 Andrey Borzenkov <bor@zsh.org> +2008-08-31 Andrey Borzenkov <bor@zsh.org> * users/13169: Src/exec.c: really restore emulation mode when exiting shell function if 'emulate -L' has been used (actually @@ -6088,7 +6832,7 @@ * users/12793: William Scott: Completion/BSD/Command/_chflags: hidden/nohidden flags. -2008-04-20 Andrey Borzenkov <bor@zsh.org> +2008-04-20 Andrey Borzenkov <bor@zsh.org> * 24851: Doc/Zsh/mod_complist.yo, Src/Zle/complist.c: support colour codes for from current GNU ls @@ -6354,7 +7098,7 @@ 2008-03-22 Barton E. Schaefer <schaefer@zsh.org> * unposted: Doc/Zsh/params.yo: further documentation tweak for the - (R) and (I) subscript flags. + (R) and (I) subscript flags. 2008-03-18 Barton E. Schaefer <schaefer@zsh.org> @@ -7923,7 +8667,7 @@ words immediately followed by () or something that looks like it's going to be one. -2007-08-12 Andrey Borzenkov <bor@zsh.org> +2007-08-12 Andrey Borzenkov <bor@zsh.org> * 23751: Completion/Linux/Command/_modutils: support for completing module files directly @@ -8094,7 +8838,7 @@ make autoloads persistent. Put modules in hash table. Rationalise error handling and error messages. Improve module listing. Abort at top level of list execution when - errflag is set instead of relying on called functions returning + errflag is set instead of relying on called functions returning early. 2007-07-06 Clint Adams <clint@zsh.org> @@ -8562,7 +9306,7 @@ * 23433: Src/Zle/zle_main.c: cast for ZMAXTIMEOUT was wrong where sizeof(long) > sizeof(int). -2007-05-10 Andrey Borzenkov <bor@zsh.org> +2007-05-10 Andrey Borzenkov <bor@zsh.org> * 23409 with extra comment: Src/init.c, Src/utils.c: after ZLE displayed "use 'exit' to exit" message, PROMPT_SP will overwrite @@ -8847,7 +9591,7 @@ * 23214: Completion/Unix/Command/_subversion: complete files after svn commit --file. -2007-02-10 Felix Rosencrantz <f.rosencrantz@gmail.com> +2007-02-10 Felix Rosencrantz <f.rosencrantz@gmail.com> * unposted: Completion/Unix/Command/_comm: added -s flag to _arguments so completion could deal with combined flags. @@ -8979,7 +9723,7 @@ try to parse base indicators in octal and raise error for bases above 36. -2007-02-10 Felix Rosencrantz <f.rosencrantz@gmail.com> +2007-02-10 Felix Rosencrantz <f.rosencrantz@gmail.com> * 23164: Src/builtin.c when PUSHD_SILENT is set, don't print anything from popd/pushd. @@ -9606,7 +10350,7 @@ * 22835: Completion/Unix/Command/_pon: tidy up pon bit and add poff completion. -2006-10-07 Andrey Borzenkov <bor@zsh.org> +2006-10-07 Andrey Borzenkov <bor@zsh.org> * 22831: Src/Zle/comp.h, Src/Zle/compresult.c, Src/Zle/computil.c: make CM_SPACE definition global and use it consistently in @@ -9713,7 +10457,7 @@ Completion/Linux/Type/_wakeup_capable_devices: completion for acpitool. -2006-09-30 Andrey Borzenkov <bor@zsh.org> +2006-09-30 Andrey Borzenkov <bor@zsh.org> * unposted: Src/Zle/compmatch.c: fix thinko in 22787 that changed semantic of pattern matching in join_strs @@ -9722,7 +10466,7 @@ * 22789: Src/init.c: Source zshenv even if non-interactive. -2006-09-29 Andrey Borzenkov <bor@zsh.org> +2006-09-29 Andrey Borzenkov <bor@zsh.org> * 22787: Srz/Zsh/compmatch.c: change calling convention of pattern_match to not depend on current implementation that works @@ -9753,7 +10497,7 @@ Src/Zle/zle_main.c: rename some MB_ macros to WC_ since they act on wchar_t's. -2006-09-23 Andrey Borzenkov <bor@zsh.org> +2006-09-23 Andrey Borzenkov <bor@zsh.org> * unposted: Test/A06assign.ztst, Test/B03print.ztst, Test/E01options.ztst, Test/ztst.zsh: as pointed by Bart in 22759, @@ -9764,7 +10508,7 @@ to consistently use character width when laying out matches. This supercedes fix in 22729. -2006-09-22 Andrey Borzenkov <bor@zsh.org> +2006-09-22 Andrey Borzenkov <bor@zsh.org> * 22758: Test/A06assign.ztst, Test/B03print.ztst, Test/E01options.ztst: force locale to C to avoid test failures @@ -9815,7 +10559,7 @@ * 22727: Src/init.c, Src/Zle/zle_main.c: "use 'exit' to exit" was suboptimal. -2006-09-16 Andrey Borzenkov <bor@zsh.org> +2006-09-16 Andrey Borzenkov <bor@zsh.org> * 22721: Makefile.in: add pdf target @@ -10012,7 +10756,7 @@ 2006-08-09 Peter Stephenson <p.w.stephenson@ntlworld.com> * unposted: Functions/Example/pushd: maintain pushdignoredups if - it was set on entry to the function. I have a weird sense of + it was set on entry to the function. I have a weird sense of deja vu about this... * 22594: Src/Zle/complist.c, Src/Zle/compresult.c, @@ -12045,7 +12789,7 @@ * 21609: Src/glob.c: fixed the readlink() call in statfullpath(). -2005-08-15 Felix Rosencrantz <f.rosencrantz@gmail.com> +2005-08-15 Felix Rosencrantz <f.rosencrantz@gmail.com> * 21611: Completion/X/Command/_mozilla: Added Firefox support. @@ -12652,7 +13396,7 @@ Completion/Zsh/Type/_options, Completion/Zsh/Type/_options_set, Completion/Zsh/Type/_options_unset: make completion functions give precedence to descriptions passed as parameters and - cleanup descriptions in calling functions + cleanup descriptions in calling functions * 21314: Doc/Zsh/compsys.yo: declare expl local in example use of _wanted @@ -12772,12 +13516,12 @@ * unposted: Completion/X/Command/_qiv: new completion for qiv -2005-05-13 Motoi Washida <a66@h8.dion.ne.jp> +2005-05-13 Motoi Washida <a66@h8.dion.ne.jp> * users/8826: Completion/Darwin/Type/_retrieve_mac_apps: search applications using spotlight. -2005-05-12 Felix Rosencrantz <f.rosencrantz@gmail.com> +2005-05-12 Felix Rosencrantz <f.rosencrantz@gmail.com> * 21257: Completion/Unix/Command/_perforce: fix minor typo in completion for the p4 password command. @@ -12922,7 +13666,7 @@ * 21156: Completion/Debian/Command/_dpkg: tweaks to dpkg-reconfigure completion. -2005-04-18 Felix Rosencrantz <f_rosencrantz@gmail.com> +2005-04-18 Felix Rosencrantz <f_rosencrantz@gmail.com> * 21154: Completion/Unix/Command/_perforce: add pid completion for monitor (clear|terminate) commands. @@ -13421,7 +14165,7 @@ cleanup and 2 more options for the upcoming rsync 2.6.4 release. -2005-02-19 Motoi Washida <a66@h8.dion.ne.jp> +2005-02-19 Motoi Washida <a66@h8.dion.ne.jp> * users/8522: Completion/Darwin/Command/_defaults: fixed the number of spaces broken while sending the patch by email. @@ -13930,7 +14674,7 @@ * 20528: Src/exec.c: Clint spotted that fix in 18492 to make > >(...) synchronous failed in the case of an fd opened for the - shell's own use with an exec. + shell's own use with an exec. 2004-10-26 Peter Stephenson <pws@csr.com> @@ -14526,7 +15270,7 @@ * 20024: Doc/Zsh/func.yo: Improve documentation for TRAPNAL functions. -2004-06-03 Felix Rosencrantz <f_rosencrantz@yahoo.com> +2004-06-03 Felix Rosencrantz <f_rosencrantz@yahoo.com> * 20002: Src/Zle/compmatch.c: Fix a problem with an inconsistent struct change in cmp_anchors(). @@ -14852,7 +15596,7 @@ configure.ac, Doc/Zsh/mod_zftp.yo, Src/Modules/zftp.c, Etc/NEWS, Functions/Zftp/zfstat: Add support for non-standard ports to core zftp. Not yet handled by the function system - (except zfstat reports port): needed in lastloc and bookmarks. + (except zfstat reports port): needed in lastloc and bookmarks. 2004-03-23 Peter Stephenson <pws@csr.com> @@ -14883,5 +15627,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5346 $ +* $Revision: 1.5509 $ ***************************************************** diff --git a/Completion/BSD/Command/_sockstat b/Completion/BSD/Command/_sockstat index 2acbe6bec..e61854622 100644 --- a/Completion/BSD/Command/_sockstat +++ b/Completion/BSD/Command/_sockstat @@ -3,10 +3,10 @@ local tmp_proto protocols proto tmp_proto=(${${(M)${(f)"$(</etc/protocols)"}##[a-z0-9]*}}) -for proto ($tmp_proto) { +for proto ($tmp_proto) { case $proto in *\#*) - protocols=($protocols ${${(j: :)${=proto}}// *\# /:}) + protocols=($protocols ${${(j: :)${=proto}}// *\# /:}) ;; *) protocols=($protocols ${${(j: :)${=proto}}// */}) @@ -14,10 +14,10 @@ for proto ($tmp_proto) { } _arguments -s \ - '-4[Show AF_INET (IPv4) sockets]' \ - '-6[Show AF_INET6 (IPv6) sockets]' \ - '-c[Show connected sockets]' \ - '-l[Show listening sockets]' \ - '-u[Show AF_LOCAL (UNIX) sockets]' \ - '-p[Only show Internet sockets if the port number is on the specified list]' \ - '-P[Only show sockets of the specified protocols]:protocols:(($protocols))' + '-4[show AF_INET (IPv4) sockets]' \ + '-6[show AF_INET6 (IPv6) sockets]' \ + '-c[show connected sockets]' \ + '-l[show listening sockets]' \ + '-u[show AF_LOCAL (UNIX) sockets]' \ + '-p[only show Internet sockets if the port number is on the specified list]' \ + '-P[only show sockets of the specified protocols]:protocols:(($protocols))' diff --git a/Completion/Base/Utility/_pick_variant b/Completion/Base/Utility/_pick_variant index 01fa2b98f..9099e3599 100644 --- a/Completion/Base/Utility/_pick_variant +++ b/Completion/Base/Utility/_pick_variant @@ -6,7 +6,7 @@ local -A opts (( $+_cmd_variant )) || typeset -gA _cmd_variant -zparseopts -D -A opts c: r: +zparseopts -D -A opts b: c: r: : ${opts[-c]:=$words[1]} while [[ $1 = *=* ]]; do @@ -19,6 +19,12 @@ if (( $+_cmd_variant[$opts[-c]] )); then return 0 fi +if [[ $+opts[-b] -eq 1 && -n $builtins[$opts[-c]] ]]; then + _cmd_variant[$opts[-c]]=$opts[-b] + (( $+opts[-r] )) && eval "${opts[-r]}=${_cmd_variant[$opts[-c]]}" + return 0 +fi + output="$(_call_program variant $opts[-c] "${@[2,-1]}" </dev/null 2>&1)" for cmd pat in "$var[@]"; do diff --git a/Completion/Base/Widget/_complete_debug b/Completion/Base/Widget/_complete_debug index 39350b5c5..eff0f8e28 100644 --- a/Completion/Base/Widget/_complete_debug +++ b/Completion/Base/Widget/_complete_debug @@ -6,21 +6,27 @@ eval "$_comp_setup" local tmp=${TMPPREFIX}${$}${words[1]:t}$[++_debug_count] local pager w="${(qq)words}" -exec 3>&- # Too bad if somebody else is using it ... -[[ -t 2 ]] && { exec 3>&2 2>| $tmp ; trap 'exec 2>&3 3>&-' EXIT INT } +integer debug_fd=-1 +{ + if [[ -t 2 ]]; then + exec {debug_fd}>&2 2>| $tmp + fi -setopt xtrace -: $ZSH_NAME $ZSH_VERSION -${1:-_main_complete} -integer ret=$? -unsetopt xtrace + setopt xtrace + : $ZSH_NAME $ZSH_VERSION + ${1:-_main_complete} + integer ret=$? + unsetopt xtrace -[[ -t 3 ]] && { + if (( debug_fd != -1 )); then zstyle -s ':completion:complete-debug::::' pager pager print -sR "${pager:-${PAGER:-${VISUAL:-${EDITOR:-more}}}} ${(q)tmp} ;: $w" _message -r "Trace output left in $tmp (up-history to view)" - [[ $compstate[nmatches] -le 1 && $compstate[list] != *force* ]] && + if [[ $compstate[nmatches] -le 1 && $compstate[list] != *force* ]]; then compstate[list]='list force messages' + fi + fi +} always { + (( debug_fd != -1 )) && exec 2>&$debug_fd {debug_fd}>&- } - return ret diff --git a/Completion/Debian/Command/_apt b/Completion/Debian/Command/_apt index 788fe3127..b51b2fc74 100644 --- a/Completion/Debian/Command/_apt +++ b/Completion/Debian/Command/_apt @@ -433,12 +433,15 @@ _apt-get () { /$'dselect-upgrade\0'/ \| \ /$'clean\0'/ \| \ /$'autoclean\0'/ \| \ + /$'changelog\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" avail' \# \| \ /$'check\0'/ \| \ /$'source\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" avail' \# \| \ /$'build-dep\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" avail' \# \| \ /$'autoremove\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ /$'help\0/' \| \ - /"[]"/ ':argument-1::compadd "$expl_action[@]" update upgrade install remove purge dist-upgrade dselect-upgrade clean autoclean check source build-dep autoremove help' + /$'markauto\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ + /$'unmarkauto\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ + /"[]"/ ':argument-1::compadd "$expl_action[@]" update upgrade install remove purge dist-upgrade dselect-upgrade clean autoclean changelog check source build-dep autoremove help markauto unmarkauto' _apt-get () { local expl_action expl_packages diff --git a/Completion/Debian/Command/_aptitude b/Completion/Debian/Command/_aptitude index bfec49730..2c462e462 100644 --- a/Completion/Debian/Command/_aptitude +++ b/Completion/Debian/Command/_aptitude @@ -13,6 +13,39 @@ ${${(M)${(f)"$(</etc/apt/sources.list)"}\ #}}} } +# Helper function for -F / --display-format +function _aptitude_format_strings() { + _values -s , 'format string' \ + '%%[Literal %]' \ + '%#number[Parameter replacement]' \ + '%a[Action flag]' \ + '%A[Action]' \ + '%B[Broken count]' \ + '%c[Current state flag]' \ + '%C[Current state]' \ + '%d[Description]' \ + '%H[Hostname]' \ + '%i[Pin priority]' \ + '%I[Installed size]' \ + '%m[Maintainer]' \ + '%M[Automatic flag]' \ + '%n[Program version]' \ + '%N[Program name]' \ + '%o[Download size]' \ + '%p[Package name]' \ + '%P[Priority]' \ + '%r[Reverse depends count]' \ + '%R[Abbreviated priority]' \ + '%s[Section]' \ + '%S[Trust status]' \ + '%t[Archive]' \ + '%T[Tagged]' \ + '%u[Disk usage change]' \ + '%v[Current version]' \ + '%V[Candidate version]' \ + '%Z[Size change]' +} + _arguments -C \ '(- 1 *)'{-h,--help}'[display help information]' \ '(- 1 *)--version[display version information]' \ @@ -20,7 +53,7 @@ _arguments -C \ '(-d --download-only)'{-d,--download-only}"[just download packages - don\'t install]" \ '(-P --prompt)'{-P,--prompt}'[always display a prompt]' \ '(-y --assume-yes)'{-y,--assume-yes}'[assume yes answer to questions]' \ - '(-F --display-format)'{-F,--display-format}'[specify output format for search command]:format' \ + '(-F --display-format)'{-F,--display-format}'[specify output format for search command]:format:_aptitude_format_strings' \ '(-O --sort)'{-O,--sort}'[specify sort order]:sort order:()' \ '(-w --width)'{-w,--width}'[specify output width]:width' \ '-f[aggressivley try to fix dependencies of broken packages]' \ diff --git a/Completion/Debian/Command/_bts b/Completion/Debian/Command/_bts index 8ef1530c7..4907d15c1 100644 --- a/Completion/Debian/Command/_bts +++ b/Completion/Debian/Command/_bts @@ -85,16 +85,18 @@ case "$words[1]" in _wanted operator expl 'operator' compadd - '+' '-' '=' elif [[ CURRENT -eq 4 ]]; then _wanted tag expl 'tag' \ - compadd patch wontfix moreinfo unreproducible fixed security \ - potato woody sid help pending upstream lfs sarge experimental \ - sarge-ignore d-i confirmed ipv6 fixed-in-experimental \ - fixed-upstream + compadd patch wontfix moreinfo unreproducible help pending \ + fixed security upstream confirmed fixed-upstream \ + fixed-in-experimental d-i ipv6 lfs l10n potato woody sarge \ + sarge-ignore etch etch-ignore lenny lenny-ignore squeeze \ + squeeze-ignore wheezy wheezy-ignore sid experimental else _wanted tag expl 'tag' \ - compadd patch wontfix moreinfo unreproducible fixed security \ - potato woody sid help pending upstream lfs sarge experimental \ - sarge-ignore d-i confirmed ipv6 fixed-in-experimental \ - fixed-upstream + compadd patch wontfix moreinfo unreproducible help pending \ + fixed security upstream confirmed fixed-upstream \ + fixed-in-experimental d-i ipv6 lfs l10n potato woody sarge \ + sarge-ignore etch etch-ignore lenny lenny-ignore squeeze \ + squeeze-ignore wheezy wheezy-ignore sid experimental _wanted sep expl 'separator' compadd -S ' ' , . fi ;; diff --git a/Completion/Debian/Command/_git-buildpackage b/Completion/Debian/Command/_git-buildpackage index 784d53028..a2dc65689 100644 --- a/Completion/Debian/Command/_git-buildpackage +++ b/Completion/Debian/Command/_git-buildpackage @@ -1,4 +1,5 @@ #compdef git-buildpackage +#description build Debian packages from a git repository _arguments \ '--version[show program version number and exit]' \ @@ -30,7 +31,7 @@ _arguments \ '--git-prebuild=-[command to run before a build]:command:' \ '--git-postbuild=-[hook run after a successful build]:command:' \ '--git-posttag=-[hook run after a successful tag operation]:command:' \ - '--git-pbuilder[Invoke git-pbuilder for building]' \ + '--git-pbuilder[invoke git-pbuilder for building]' \ '--git-no-pbuilder[negates --git-pbuilder]' \ '--git-dist=-[build for this distribution when using git-pbuilder]:distribution:' \ '--git-arch=-[build for this architecture when using git-pbuilder]:architecture:' \ diff --git a/Completion/Linux/Command/.distfiles b/Completion/Linux/Command/.distfiles index 251204e3b..0d817fc5d 100644 --- a/Completion/Linux/Command/.distfiles +++ b/Completion/Linux/Command/.distfiles @@ -5,6 +5,7 @@ _acpitool _analyseplugin _brctl _chrt +_cryptsetup _ethtool _fusermount _ionice @@ -17,8 +18,10 @@ _mdadm _mii-tool _modutils _mondo +_nmcli _pkgtool _rpmbuild +_schedtool _sshfs _strace _tpb diff --git a/Completion/Linux/Command/_cryptsetup b/Completion/Linux/Command/_cryptsetup new file mode 100644 index 000000000..3519336e8 --- /dev/null +++ b/Completion/Linux/Command/_cryptsetup @@ -0,0 +1,103 @@ +#compdef cryptsetup +## completion for cryptsetup 1.3.0, based on cryptsetup(1) + +function _cryptsetup_action { + typeset -a actions + actions=( + 'create:create a mapping' + 'remove:remove an existing mapping' + 'status:report mapping status' + 'resize:resize an active mapping' + 'luksFormat:Initialize a LUKS partition' + 'luksOpen:Open LUKS partition' + 'luksClose:remove an existing mapping' + 'luksSuspend:suspend active device' + 'luksResume:resume suspended device' + 'luksAddKey:add a new key' + 'luksRemoveKey:remove a key' + 'luksChangeKey:change a key' + 'luksKillSlot:wipe key from slot' + 'luksUUID:print/change device UUID' + 'isLuks:check if device is a LUKS partition' + 'luksDump:dump header information' + 'luksHeaderBackup:store binary backup of headers' + 'luksHeaderRestore:restore header backup' + ) + _describe action actions +} + +function _cryptsetup_device { + typeset expl + _wanted file expl device \ + _files +} + +function _cryptsetup_mapping { + typeset expl + _wanted file expl 'mapping name' \ + _path_files -W /dev/mapper +} + +function _cryptsetup_arguments { + + case ${words[1]} in + + create) + _arguments ':mapping:_cryptsetup_mapping' ':device:_cryptsetup_device' + ;; + + remove|status|resize|luksClose|luksSuspend|luksResume) + _arguments ': :_cryptsetup_mapping' + ;; + + luks(AddKey|RemoveKey|DelKey|UUID|Dump)|isLuks) + _arguments ': :_cryptsetup_device' + ;; + + luks(Format|AddKey|RemoveKey|ChangeKey)) + _arguments ': :_cryptsetup_device' ':key file:_files' + ;; + + luksKillSlot) + _arguments ': :_cryptsetup_device' ':key slot number' + ;; + + luksOpen) + _arguments ': :_cryptsetup_device' ': :_cryptsetup_mapping' + ;; + + esac +} + +function _cryptsetup { + _arguments \ + '(-v --verbose)'{-v,--verbose}'[enable verbose mode]' \ + '--debug[enable debug mode]' \ + '(-h --hash)'{-h,--hash}'[hash algorithm]:hash algorithm' \ + '(-c --cipher)'{-c,--cipher}'[set cipher]:cipher specification' \ + '(-y --verify-passphrase)'{-y,--verify-passphrase}'[query for password twice]' \ + '(-d --key-file)'{-d,--key-file}'[set keyfile]:key file:_files' \ + '(-l --keyfile-size)'{-l,--keyfile-size}'[set keyfile size]:bytes' \ + '--new-keyfile-size[set new keyfile size (luksAddKey)]:bytes' \ + '--master-key-file[set master key]:key file:_files' \ + '--dump-master-key[dump luks master key]' \ + '(--use-urandom)--use-random[use /dev/random to generate volume key]' \ + '(--use-random)--use-urandom[use /dev/urandom to generate volume key]' \ + '(-S --key-slot)'{-S,--key-slot}'[select key slot]:key slot' \ + '(-s --key-size)'{-s,--key-size}'[set key size]:bits' \ + '(-b --size)'{-b,--size}'[force device size]:sectors' \ + '(-o --offset)'{-o,--offset}'[set start offset]:sectors' \ + '(-p --skip)'{-p,--skip}'[data to skip at beginning]:sectors' \ + '--readonly[set up read-only mapping]' \ + '(-i --iter-time)'{-i,--iter-time}'[set password processing duration]:milliseconds' \ + '(-q --batch-mode)'{-q,--batch-mode}'[do not ask for confirmation]' \ + '(-t --timeout)'{-t,--timeout}'[set password prompt timeout]:seconds' \ + '(-T --tries)'{-T,--tries}'[set maximum number of retries]:maximum retries' \ + '--align-payload[set payload alignment]:sectors' \ + '--uuid[set device UUID]:uuid' \ + '--version[show version information]' \ + ':action:_cryptsetup_action' \ + '*::arguments:_cryptsetup_arguments' +} + +_cryptsetup "$@" diff --git a/Completion/Linux/Command/_ethtool b/Completion/Linux/Command/_ethtool index a01d38823..5d607741f 100644 --- a/Completion/Linux/Command/_ethtool +++ b/Completion/Linux/Command/_ethtool @@ -3,9 +3,9 @@ local -a cmds if [[ $CURRENT -ge 4 ]]; then - case $words[CURRENT-1]; in + case $words[CURRENT-1] in rx|tx) - if [[ $words[2] = '-G' ]] && _message -e n 'number of ring entries' || _wanted -x onoff expl 'enabled' compadd off on + [[ $words[2] = '-G' ]] && _message -e n 'number of ring entries' || _wanted -x onoff expl 'enabled' compadd off on ;; autoneg|adaptive-rx|adaptive-tx|raw|hex|sg|tso|ufo|gso) _wanted -x onoff expl 'enabled' compadd off on @@ -55,7 +55,7 @@ if [[ $CURRENT -ge 4 ]]; then _wanted files expl 'raw register dump files' _files ;; *) - case $words[2]; in + case $words[2] in -A|--pause) _values -S ' ' -w 'pause options' \ 'autoneg[specify if pause autonegotiation is enabled]' \ @@ -111,7 +111,7 @@ if [[ $CURRENT -ge 4 ]]; then 'gso[specify if generic segmentation offload is enabled]' ;; -p|--identify) - if [[ $CURRENT -eq 4 ]] && _message -e length 'seconds' + [[ $CURRENT -eq 4 ]] && _message -e length 'seconds' ;; -t|--test) _values -S ' ' -w 'selftest option' \ diff --git a/Completion/Linux/Command/_modutils b/Completion/Linux/Command/_modutils index b3f8fcd46..e2671f2a7 100644 --- a/Completion/Linux/Command/_modutils +++ b/Completion/Linux/Command/_modutils @@ -107,7 +107,7 @@ case "$state" in ! _retrieve_cache modules-$kver; then # 2011-01-02 gi1242: Do we need .o files? Or is .ko enough? - modules=( $modules_dir/$kver/(*~(source|build))/**/*.(o|ko)(.:t:r) ) + modules=( $modules_dir/$kver/(*~(source|build))/**/*.(o|ko|ko.gz)(.:t:r:r) ) _store_cache modules-$kver modules fi diff --git a/Completion/Linux/Command/_nmcli b/Completion/Linux/Command/_nmcli new file mode 100644 index 000000000..a6b97a36c --- /dev/null +++ b/Completion/Linux/Command/_nmcli @@ -0,0 +1,244 @@ +#compdef nmcli + +local context state line expl +typeset -A opt_args + +if [[ -z $_nmcli_version ]]; then + _nmcli_version="${"$(_call_program nmcli $words[1] --version)"##*version }" +fi + +(( $+functions[_nmcli_is_running] )) || _nmcli_is_running() { + [[ $(_call_program nmcli $words[1] -f running nm) != *'not running'* ]] +} + +(( $+functions[_nmcli_con_ids] )) || _nmcli_con_ids() { + _nmcli_is_running || return + local -a con_ids + con_ids=(${(f)"$(_call_program nmcli $words[1] -f name con)"}) + con_ids=(${con_ids[2,-2]}) + con_ids=(${con_ids[@]%%\ ##}) + _describe 'select connection' con_ids +} + +(( $+functions[_nmcli_con_uuids] )) || _nmcli_con_uuids() { + _nmcli_is_running || return + local -a con_uuids + con_uuids=(${(f)"$(_call_program nmcli $words[1] -f uuid con)"}) + con_uuids=(${con_uuids[2,-2]}) + con_uuids=(${con_uuids[@]%%\ ##}) + _describe 'select connection' con_uuids +} + +(( $+functions[_nmcli_objects] )) || _nmcli_objects() { + local -a objects_array + objects_array=( + 'nm:NetworkManager status' + 'con:NetworkManager connections' + 'dev:devices managed by NetworkManager' + ) + _describe 'nmcli object' objects_array +} + +(( $+functions[_nmcli_nm] )) || _nmcli_nm() { + local -a nm_array + nm_array=( + 'status:show overall status of NetworkManager' + 'enable:get status or enable/disable networking' + 'sleep:get sleep status or put to sleep/awake NetworkManager' + 'wifi:inquire or set status of WiFi in NetworkManager' + 'wwan:inquire or set status of WWAN in NetworkManager' + ) + _describe 'inquire and change state of NetworkManager' nm_array +} + +(( $+functions[_nmcli_con] )) || _nmcli_con() { + local -a con_array + con_array=( + 'list:list configured connections' + 'status:print status of active connections' + 'up:activate a connection' + 'down:deactivate a connection' + ) + if [[ $_nmcli_version == 0.9.[1-9]* ]]; then + con_array[5]="delete:delete a connection" + fi + _describe "get information about NetworkManager's connections" con_array +} + +(( $+functions[_nmcli_con_list] )) || _nmcli_con_list() { + local -a con_list_array + con_list_array=( + 'id:get details on connection specified by id' + 'uuid:get details on connection specified by uuid' + ) + if [[ $_nmcli_version == 0.8* ]]; then + con_list_array[3]='system:only list system connections' + con_list_array[4]='user:only list user connections' + fi + _describe 'list configured connections' con_list_array +} + +(( $+functions[_nmcli_con_up] )) || _nmcli_con_up() { + local -a con_up_array + con_up_array=( + 'id:activate connection specified by id' + 'uuid:activate connection specified by uuid' + ) + _describe 'activate connection by id or uuid' con_up_array +} + +(( $+functions[_nmcli_con_down] )) || _nmcli_con_down() { + local -a con_down_array + con_down_array=( + 'id:deactivate connection specified by id' + 'uuid:deactivate connection specified by uuid' + ) + _describe 'deactivate connection by id or uuid' con_down_array +} + +(( $+functions[_nmcli_con_delete] )) || _nmcli_con_delete() { + local -a con_delete_array + con_delete_array=( + 'id:delete connection specified by id' + 'uuid:delete connection specified by uuid' + ) + _describe 'delete connection by id or uuid' con_delete_array +} + +(( $+functions[_nmcli_con_up_extraargs] )) || _nmcli_con_up_extraargs() { + local -a con_up_extraargs_array + con_up_extraargs_array=( + 'iface:require a particular interface' + 'ap:require a specific access point' + '--nowait:don''t wait for command completion' + '--timeout:specify how long to wait for operation to complete' + ) + _describe 'extra options for "con up"' con_up_extraargs_array +} + +(( $+functions[_nmcli_dev_disconnect_extraargs] )) || _nmcli_dev_disconnect_extraargs() { + local -a dev_disconnect_extraargs_array + dev_disconnect_extraargs_array=( + '--nowait:don''t wait for command completion' + '--timeout:specify how long to wait for operation to complete' + ) + _describe 'extra options for "dev disconnect"' dev_disconnect_extraargs_array +} + +(( $+functions[_nmcli_dev_wifi_list] )) || _nmcli_dev_wifi_list() { + local -a dev_wifi_list_array + dev_wifi_list_array=( + 'iface:list APs for a particular interface' + ) + if [[ $_nmcli_version == 0.8* || $_nmcli_version == 0.9.0* ]]; then + dev_wifi_list_array[2] = 'hwaddr:list a specific AP by MAC address' + elif [[ $_nmcli_version == 0.9.[1-9]* ]]; then + dev_wifi_list_array[2] = 'bssid:list a specific AP by BSSID' + fi + _describe 'options for specifying the AP to list' dev_wifi_list_array +} + +(( $+functions[_nmcli_dev] )) || _nmcli_dev() { + local -a dev_array + dev_array=( + 'status:print status of devices' + 'list:get detailed information about devices' + 'disconnect:disconnect device and prevent it from automatically activating' + 'wifi:list available WiFi access points' + ) + _describe "get information about devices" dev_array +} + +(( $+functions[_nmcli_truefalse] )) || _nmcli_truefalse() { + _wanted boolean expl 'use true/false to modify (nothing = query status)' compadd true false +} + +(( $+functions[_nmcli_onoff] )) || _nmcli_onoff() { + _wanted onoff expl 'use on/off to modify (nothing = query status)' compadd on off +} + +local w1="${words[$#words - 1]}" +local w2="${words[$#words - 2]}" +local w3="${words[$#words - 3]}" +local w4="${words[$#words - 4]}" + +if [[ $w2 == nm && $w1 == (sleep|enable) ]]; then + _nmcli_truefalse && return +elif [[ $w2 == nm && $w1 == (wifi|wwan) ]]; then + _nmcli_onoff && return +elif [[ $w1 == nm ]]; then + _nmcli_nm && return +elif [[ $w3 == con && $w2 == list && $w1 == id ]]; then + _nmcli_con_ids && return +elif [[ $w3 == con && $w2 == list && $w1 == uuid ]]; then + _nmcli_con_uuids && return +elif [[ $w2 == con && $w1 == list ]]; then + _nmcli_con_list && return +elif [[ $w3 == con && $w2 == (up|down) && $w1 == id ]]; then + _nmcli_con_ids && return +elif [[ $_nmcli_version == 0.9.[1-9]* && $w3 == con && $w2 == delete && $w1 == id ]]; then + _nmcli_con_ids && return +elif [[ $w3 == con && $w2 == (up|down) && $w1 == uuid ]]; then + _nmcli_con_uuids && return +elif [[ $_nmcli_version == 0.9.[1-9]* && $w3 == con && $w2 == delete && $w1 == uuid ]]; then + _nmcli_con_uuids && return +elif [[ ${(pj:\0:)words} == *$'\0con\0up\0'(id|uuid)$'\0'* ]]; then + if [[ $w1 == iface ]]; then + _net_interfaces && return + elif [[ $w1 == ap ]]; then + _message -e descriptions 'enter MAC address' && return + elif [[ $w1 == --timeout ]]; then + _message -e descriptions 'enter timeout' && return + else + _nmcli_con_up_extraargs && return + fi +elif [[ $w2 == con && $w1 == up ]]; then + _nmcli_con_up && return +elif [[ $w2 == con && $w1 == down ]]; then + _nmcli_con_down && return +elif [[ $_nmcli_version == 0.9.[1-9]* && $w2 == con && $w1 == delete ]]; then + _nmcli_con_delete && return +elif [[ $w1 == con ]]; then + _nmcli_con && return +elif [[ $w3 == dev && $w2 == (list|disconnect) && $w1 == iface ]]; then + _net_interfaces && return +elif [[ ${(pj:\0:)words} == *$'\0dev\0disconnect\0iface\0'* ]]; then + if [[ $w1 == --timeout ]]; then + _message -e descriptions 'enter timeout' && return + else + _nmcli_dev_disconnect_extraargs && return + fi +elif [[ $w2 == dev && $w1 == list ]]; then + compadd iface && return +elif [[ $w2 == dev && $w1 == disconnect ]]; then + compadd iface && return +elif [[ $w4 == dev && $w3 == wifi && $w2 == list && $w1 == iface ]]; then + _net_interfaces && return +elif [[ $w4 == dev && $w3 == wifi && $w2 == list && $w1 == hwaddr ]]; then + _message -e descriptions 'enter MAC address' && return +elif [[ $w3 == dev && $w2 == wifi && $w1 == list ]]; then + _nmcli_dev_wifi_list && return +elif [[ $w2 == dev && $w1 == wifi ]]; then + compadd list && return +elif [[ $w1 == dev ]]; then + _nmcli_dev && return +else + _arguments \ + {'(--terse)-t','(-t)--terse'}'[terse output]' \ + {'(--pretty)-p','(-p)--pretty'}'[pretty output]' \ + {'(--mode)-m','(-m)--mode'}'[output mode]:output mode:(tabular multiline)' \ + {'(--fields)-f','(-f)--fields'}'[specify fields to output]: :->fields' \ + {'(--escape)-e','(-e)--escape'}'[escape columns separators in values]:escape columns separators in values:(yes no)' \ + {'(--version)-v','(-v)--version'}'[show program version]' \ + {'(--help)-h','(-h)--help'}'[print this help]' \ + '*::nmcli object:_nmcli_objects' \ + && return +fi + +[[ "$state" == "fields" ]] && + _values -s , 'fields to be printed' \ + all common \ + autoconnect dbus-path device name net-enabled readonly running \ + scope state timestamp timestamp-real type uuid wifi wifi-hardware \ + wwan wwan-hardware \ + && return diff --git a/Completion/Linux/Command/_schedtool b/Completion/Linux/Command/_schedtool new file mode 100644 index 000000000..869f146e3 --- /dev/null +++ b/Completion/Linux/Command/_schedtool @@ -0,0 +1,25 @@ +#compdef schedtool + +local curcontext="$curcontext" line state ret=1 + +_arguments -C \ + '(-p -F -R -B -I -D -M)-N[for SCHED_NORMAL]' \ + '( -N -R -B -I -D -M)-F[for SCHED_FIFO]' \ + '( -N -F -B -I -D -M)-R[for SCHED_RR]' \ + '(-p -N -F -R -I -D -M)-B[for SCHED_BATCH]' \ + '( -N -F -R -B -D -M)-I[for SCHED_ISO]' \ + '(-p -N -F -R -B -I -M)-D[for SCHED_IDLEPRIO]' \ + '( -N -F -R -B -I -D )-M[for manual mode; raw number for POLICY]:raw policy number' \ + '( -N -B -D )-p[usually 1-99; only for FIFO, RR or ISO]:static priority' \ + '-a[cpu affinity]:mask or list' \ + '-n[set niceness to NICE_LEVEL]:priority' \ + '-e[start COMMAND with specified policy/priority]:program: _command_names -e:*::program arguments: _normal' \ + '-v[be verbose]' \ + '*:processes:->processes' && ret=0 + +if [[ -n "$state" ]]; then + _alternative \ + 'processes:: _pids' && ret=0 +fi + +return ret diff --git a/Completion/Unix/Command/.distfiles b/Completion/Unix/Command/.distfiles index cc47a7a0b..a89b7d923 100644 --- a/Completion/Unix/Command/.distfiles +++ b/Completion/Unix/Command/.distfiles @@ -2,6 +2,7 @@ DISTFILES_SRC=' .distfiles _a2ps _aap +_adb _ant _antiword _apachectl @@ -110,6 +111,7 @@ _last _ldd _less _links +_ln _loadkeys _locate _look @@ -139,6 +141,7 @@ _mysqldiff _ncftp _netcat _nice +_nm _nmap _notmuch _npm @@ -207,6 +210,7 @@ _subversion _sudo _surfraw _sysctl +_systemctl _tar _tardy _tcpdump @@ -224,6 +228,8 @@ _toilet _topgit _totd _tracepath +_tree +_twidge _twisted _unace _uname diff --git a/Completion/Unix/Command/_adb b/Completion/Unix/Command/_adb new file mode 100644 index 000000000..2e36046c7 --- /dev/null +++ b/Completion/Unix/Command/_adb @@ -0,0 +1,541 @@ +#compdef adb -value-,ADB_TRACE,-default- -value-,ANDROID_SERIAL,-default- -value-,ANDROID_LOG_TAGS,-default- + +local ADB_DEVICE_SPECIFICATION LOG_REDIRECT + +_adb() { + # rely on localoptions + setopt nonomatch + + ADB_DEVICE_SPECIFICATION="" + + if [[ $1 = -l ]]; then + # Run to load _adb and associated functions but do + # nothing else. + return + fi + + if [[ $service = -value-* ]]; then + #_message compstate=$compstate[parameter] + case $compstate[parameter] in + (ADB_TRACE) + _adb_trace_opts + ;; + + (ANDROID_SERIAL) + _adb_device_serial + ADB_DEVICE_SPECIFICATION="-s ${ANDROID_SERIAL}" + ;; + + (ANDROID_LOG_TAGS) + _adb_logcat_filter_specification + ;; + + esac + # We do not handle values anywhere else. + return + fi + + local -a ALL_ADB_COMMANDS + ALL_ADB_COMMANDS=( + "connect" + "disconnect" + "shell" + "wait-for-device" + "push" + "pull" + "logcat" + "jdwp" + "bugreport" + "version" + "forward" + "install" + "uninstall" + "help" + "start-server" + "kill-server" + "devices" + "get-state" + "get-serialno" + "status-window" + "remount" + "reboot" + "reboot-bootloader" + "root" + "usb" + "tcpip" + "ppp" + ) + + (( $+functions[_adb_device_specification] )) && _adb_device_specification + + adb ${=ADB_DEVICE_SPECIFICATION} shell exit 2>/dev/null || { + # early bail-out until a single valid device/emulator is specified and up-and-running + _message -r "No (started) device specified, completions do not yet work" + _arguments \ + '(-d -e )-s[serial]: :_adb_device_serial' \ + '( -e -s)-d[device]' \ + '(-d -s)-e[emulator]' \ + '*:"options":_adb_options_handler' + + return; + } + + (( $+functions[_adb_check_log_redirect] )) && _adb_check_log_redirect + + (( $+functions[_adb_dispatch_command] )) && _adb_dispatch_command +} + +(( $+functions[_adb_dispatch_command] )) || +_adb_dispatch_command () { + local curcontext="${curcontext}" + local integer last_command_pos=-1 + + (( $+functions[_adb_sanitize_context] )) && _adb_sanitize_context + if [[ ${last_command_pos} -gt 0 ]] + then + shift ${last_command_pos}-1 words + CURRENT=$(( ${CURRENT} - ${last_command_pos} + 1 )) + fi + + case ${curcontext} in + (*:adb:shell) + (( $+functions[_adb_dispatch_shell] )) && _adb_dispatch_shell + ;; + (*:adb:connect|*:adb:disconnect) + (( $+functions[_adb_dispatch_connection_handling] )) && _adb_dispatch_connection_handling + ;; + (*:adb:logcat) + (( $+functions[_adb_dispatch_logcat] )) && _adb_dispatch_logcat + ;; + (*:adb:push) + (( $+functions[_adb_dispatch_push] )) && _adb_dispatch_push + ;; + (*:adb:pull) + (( $+functions[_adb_dispatch_pull] )) && _adb_dispatch_pull + ;; + (*:adb:install) + (( $+functions[_adb_dispatch_install] )) && _adb_dispatch_install + ;; + (*:adb:uninstall) + (( $+functions[_adb_dispatch_uninstall] )) && _adb_dispatch_uninstall + ;; + (*) + _arguments \ + '(-d -e)-s["serial"]: :_adb_device_serial' \ + '(-s -e)-d["device"]' \ + '(-d -s)-e["emulator"]' \ + '*:"options":_adb_options_handler' + ;; + esac +} + +(( $+functions[_adb_sanitize_context] )) || +_adb_sanitize_context () { + local -a mywords + for adbcommand in "${ALL_ADB_COMMANDS[@]}" + do + if [[ -n "${adbcommand}" ]] && [[ ${words[(I)${adbcommand}]} -gt 0 ]] + then + last_command_pos=${words[(I)${adbcommand}]} + mywords[${last_command_pos}]=${adbcommand} + fi + done + ##expand unquoted to remove sparse elements + mywords=( ${mywords[@]} ) + curcontext="${curcontext}${mywords[-1]}" +} + +(( $+functions[_adb_device_specification] )) || +_adb_device_specification () { + local integer i=1 + foreach word ($words) + do + i=$(( ++i )) + case ${words[$i]} in + (-d|-e) + ADB_DEVICE_SPECIFICATION="${words[$i]}" + break + ;; + (-s) + ADB_DEVICE_SPECIFICATION="-s ${words[$i + 1]}" + break + ;; + (-*) + continue + ;; + (*) + break + ;; + esac + done +} + +(( $+functions[_adb_dispatch_shell] )) || +_adb_dispatch_shell () { + if [[ ${#words} -le 2 ]] + then + (( $+functions[_adb_shell_commands_handler] )) && _adb_shell_commands_handler + return + fi + + case ${words[2]} in + (am) + (( $+functions[_adb_activity_manager_handler] )) && _adb_activity_manager_handler + ;; + (pm) + (( $+functions[_adb_package_manager_handler] )) && _adb_package_manager_handler + ;; + (*) + _arguments '*:adb_remote_folder:_adb_remote_folder' + ;; + esac +} + +(( $+functions[_adb_pm_list] )) || +_adb_pm_list () { + case ${words[4]} in + (packages) + _arguments -s '-f[see their associated file]' \ + ':' + ;; + (permissions) + _arguments -s '-g[organize by group]' \ + '-f[print all information]' \ + '-d[only list dangerous pemissions]' \ + '-u[only list user visible permissions]' \ + '-s[short summary]' \ + ':' + ;; + (permission-groups) + ;; + (instrumentation) + _arguments -s '-f[see their associated file]' \ + ':' + ;; + (features) + ;; + (*) + _wanted pm_list_argument expl 'pm list argument' compadd packages permission-groups permissions instrumentation features + ;; + esac +} + +(( $+functions[_adb_intent_handler] )) || +_adb_intent_handler () { + _message -r "<INTENT> specifications include these flags: + [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>] + [-c <CATEGORY> [-c <CATEGORY>] ...] + [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...] + [--esn <EXTRA_KEY> ...] + [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...] + [-e|--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...] + [-n <COMPONENT>] [-f <FLAGS>] + [--grant-read-uri-permission] [--grant-write-uri-permission] + [--debug-log-resolution] + [--activity-brought-to-front] [--activity-clear-top] + [--activity-clear-when-task-reset] [--activity-exclude-from-recents] + [--activity-launched-from-history] [--activity-multiple-task] + [--activity-no-animation] [--activity-no-history] + [--activity-no-user-action] [--activity-previous-is-top] + [--activity-reorder-to-front] [--activity-reset-task-if-needed] + [--activity-single-top] + [--receiver-registered-only] [--receiver-replace-pending] + [<URI>]" +} + +(( $+functions[_adb_activity_manager_handler] )) || +_adb_activity_manager_handler () { + if [[ ${#words} -le 3 ]] + then + _wanted am_argument expl 'am argument' compadd start startservice broadcast instrument profile + return + fi + case ${words[3]} in + (start) + _arguments -s '-D[enable debugging]' \ + '-W[wait for launch to complete]' \ + '*:intent:_adb_intent_handler' + ;; + (startservice) + _arguments -s '*:intent:_adb_intent_handler' + ;; + (broadcast) + _arguments -s '*:intent:_adb_intent_handler' + ;; + (instrument) + _arguments -s '-r[print raw results]' \ + '-e[set argument NAME to VALUE]:<NAME> <VALUE>:' \ + '-p[write profiling data to FILE]:<FILE>:' \ + '-w[wait for instrumenation to finish]' \ + ':' + ;; + (profile) + _message -r "<PROCESS> start/stop <FILE>" + ;; + esac +} + +(( $+functions[_adb_package_manager_handler] )) || +_adb_package_manager_handler () { + case ${words[3]} in + (list) + (( $+functions[_adb_pm_list] )) && _adb_pm_list + ;; + (path) + (( $+functions[_adb_installed_packages] )) && _adb_installed_packages + ;; + (enable) + (( $+functions[_adb_installed_packages] )) && _adb_installed_packages + ;; + (disable) + (( $+functions[_adb_installed_packages] )) && _adb_installed_packages + ;; + (setInstallLocation) + _wanted set_installlcation expl 'install location' compadd -d "(0:auto 1:internal 2:external)" 0 1 2 + ;; + (getInstallLocation) + ;; + (*) + _wanted pm_argument expl 'pm argument' compadd list path install unistall enable disable setInstallLocation getInstallLocation + ;; + esac +} + +(( $+functions[_adb_dispatch_uninstall] )) || +_adb_dispatch_uninstall () { + argcount=${#${(M)words#-*}} + if [[ $CURRENT -gt (( argcount + 2 )) ]] + then + _message -r "Notice: you can only uninstall one package at a time" + return + fi + + _arguments \ + '-k["keep data and cache"]' \ + '*:"installed package":_adb_installed_packages' +} + +(( $+functions[_adb_dispatch_install] )) || +_adb_dispatch_install () { + argcount=${#${(M)words#-*}} + if [[ $CURRENT -gt (( argcount + 2 )) ]] + then + _message -r "Notice: you can only install one package at a time" + return + fi + + _arguments \ + '-l["forward lock"]' \ + '-r["reinstall"]' \ + '-s["install on sd"]' \ + '*:"select apk file":_path_files -g "*(/)|*.apk"' +} + +(( $+functions[_adb_dispatch_push] )) || +_adb_dispatch_push () { + if [[ ${#words} -gt 3 ]] + then + _message -r "Notice: you can only push a single item at a time" + return + fi + if [[ ${#words} -gt 2 ]] + then + _arguments '*:adb_remote_folder:_adb_remote_folder' + else + _arguments '*:"local file/folder":_files' + fi +} + +(( $+functions[_adb_dispatch_pull] )) || +_adb_dispatch_pull () { + if [[ ${#words} -gt 3 ]] + then + _message -r "Notice: you can only pull a single item at a time" + return + fi + if [[ ${#words} -gt 2 ]] + then + _arguments '*:"local file/folder":_files' + else + _arguments '*:adb_remote_folder:_adb_remote_folder' + fi +} + +(( $+functions[_adb_dispatch_connection_handling] )) || +_adb_dispatch_connection_handling () { + if compset -P '*:' + then + local expl + _wanted ports expl port compadd "$@" 5555 + else + _hosts -qS: + fi +} + +(( $+functions[adb_check_log_redirect] )) || +_adb_check_log_redirect () { + LOG_REDIRECT=${$(adb ${=ADB_DEVICE_SPECIFICATION} shell getprop log.redirect-stdio)// +/} + [[ ${LOG_REDIRECT[1,4]} == "true" ]] && _message -r "Notice: stdio log redirection enabled on the device, so some completions will not work" +} + +(( $+functions[_adb_trace_opts] )) || +_adb_trace_opts() { + _values -s , 'adb trace options' \ + '(1 adb sockets packets rwx usb sync sysdeps transport jdwp)all' \ + '(all adb sockets packets rwx usb sync sysdeps transport jdwp)1' \ + 'adb' \ + 'sockets' \ + 'packets' \ + 'rwx' \ + 'usb' \ + 'sync' \ + 'sysdeps' \ + 'transport' \ + 'jdwp' +} + +(( $+functions[_adb_device_serial] )) || +_adb_device_serial() { + local expl + _wanted dev_serial expl 'available devices' compadd $(command adb devices | sed -n 's/^\([^[:space:]]*\)\t.*$/\1/p') +} + +(( $+functions[_adb_logcat_filter_specification] )) || +_adb_logcat_filter_specification() { + zstyle ":completion:${curcontext}:" cache-policy _adb_cache_policy_single_command + + local cacheid=logcat_filter_cache_${$(adb ${=ADB_DEVICE_SPECIFICATION} get-serialno)} + typeset -a logcat_filter_tags + if _cache_invalid "$cacheid" || ! _retrieve_cache "$cacheid" + then + logcat_filter_tags=( $(command adb ${=ADB_DEVICE_SPECIFICATION} logcat -d | sed -n 's#^[VDIWEF]/\([^[:space:](]*\).*#\1#p' |sort | uniq) ) + _store_cache "$cacheid" logcat_filter_tags + fi + local expl + if compset -P '*:' + then + _wanted filter expl filter compadd W S E I D V \* + else + _wanted filtertags expl filtertags compadd -qS: ${logcat_filter_tags[@]} \* + fi +} + +(( $+functions[_adb_dispatch_logcat] )) || +_adb_dispatch_logcat() { + _arguments \ + '(-c -g)-s[set default filter to silent]' \ + '(-c -g)-f[log output to file (defaults to stdout)]:logfile:_files' \ + '(-c -g -d)-r[rotate log every kbytes (default 16, requires -f)]:logsize:_guard "[0-9]#" "numeric value"' \ + '(-c -g -d)-n[max number of rotated logs (default 4)]:number :_guard "[0-9]#" "numeric value"' \ + '(-c -g -d)-v[log format]:format: _values "format" brief process tag thread raw time threadtime long' \ + '(-d -t -g)-c[clear log]' \ + '(-c -g)-d[dump log]' \ + '(-c -g)-t[print only recent lines (implies -d)]:linecount:_guard "[0-9]#" "numeric value"' \ + '(-c -g)-B[output log in binary]' \ + '(-c -g)*:filtering:_adb_logcat_filter_specification' +} + +(( $+functions[_adb_options_handler] )) || +_adb_options_handler() { + local expl + _wanted adb_options expl 'adb options' compadd "${ALL_ADB_COMMANDS[@]}" +} + +(( $+functions[_adb_shell_commands_handler] )) || +_adb_shell_commands_handler() { + local expl + _wanted adb_shell_commands expl 'adb shell commands' compadd ls pm am mkdir rmdir rm cat +} + +(( $+functions[_adb_any_device_available] )) || +_adb_any_device_available() { + _any_device_available=${#$(adb devices | sed -n 's/^\([^[:space:]]*\)\t.*$/\1/p')} +} + +(( $+functions[_adb_device_available] )) || +_adb_device_available() { + [[ $(adb ${=ADB_DEVICE_SPECIFICATION} get-state 2>&1) == "device" ]] && return 0 + return 1 +} + +(( $+functions[_adb_full_folder_scan] )) || +_adb_full_folder_scan() { + local -a rv; + rv=( ${$(adb ${=ADB_DEVICE_SPECIFICATION} shell 'for i in $(ls -d /*) + do + case $i in + /proc|/sys|/acct) + ;; + *) + ls -R $i + ;; + esac + done' )//'$\r'/} ) + for line in ${rv[@]}; + do + [[ ${line[1]} == '/' ]] && folder="${line%:}" && adb_device_folders+=$folder && continue; + adb_device_folders+=$folder/$line; + done +} + +(( $+functions[_adb_remote_folder] )) || +_adb_remote_folder () { + local expl + zstyle -s ":completion:${curcontext}:" cache-policy update_policy + if [[ -z "$update_policy" ]]; then + zstyle ":completion:${curcontext}:" cache-policy _adb_cache_policy_daily + fi + local cacheid=package_cache_${$(adb ${=ADB_DEVICE_SPECIFICATION} get-serialno)} + typeset -a filesystem_content + if _cache_invalid "$cacheid" || ! _retrieve_cache "$cacheid" + then + local -a adb_device_folders + _adb_full_folder_scan + # remove any duplicates and the initial slash => should still remove bare folders from it when it has children + filesystem_content=( ${(u)adb_device_folders#/} ) + _store_cache "$cacheid" filesystem_content + fi + _adb_device_available && \ + _wanted adb_remote_folder expl 'file/folder on device' _multi_parts $@ -i / filesystem_content +} + +(( $+functions[_adb_installed_packages] )) || +_adb_installed_packages() { + zstyle -s ":completion:${curcontext}:" cache-policy update_policy + if [[ -z "$update_policy" ]]; then + zstyle ":completion:${curcontext}:" cache-policy _adb_cache_policy_single_command + fi + + local cacheid=package_cache_${$(adb ${=ADB_DEVICE_SPECIFICATION} get-serialno)} + typeset -a installed_packages + if _cache_invalid "$cacheid" || ! _retrieve_cache "$cacheid" + then + installed_packages=(${$( adb ${=ADB_DEVICE_SPECIFICATION} shell pm list packages )//#package:/}) + _store_cache "$cacheid" installed_packages + fi + + _wanted adb_installed_packages expl 'packages that are installed' compadd ${installed_packages} +} + +(( $+functions[_adb_cache_policy_single_command] )) || +_adb_cache_policy_single_command () { + typeset -a old + + # cache is valid for 1 minute + old=( "$1"(mm+1) ) + (( $#old )) +} + +(( $+functions[_adb_cache_policy_daily] )) || +_adb_cache_policy_daily () { + typeset -a old + + # cache is valid for a day + old=( "$1"(mh+12) ) + (( $#old )) +} + + + +_adb $@ diff --git a/Completion/Unix/Command/_at b/Completion/Unix/Command/_at index 4e2d28e27..8734e6b55 100644 --- a/Completion/Unix/Command/_at +++ b/Completion/Unix/Command/_at @@ -7,29 +7,29 @@ typeset -A opt_args case $service in atrm) _arguments \ - '-V[Print version number]' \ + '-V[print version number]' \ '*:job number:->jobs' ;; atq) _arguments \ - '-V[Print version number]' \ - '-q[Uses specified queue]:a-z+A-Z' + '-V[print version number]' \ + '-q[uses specified queue]:a-z+A-Z' ;; at|batch) _arguments \ - new-job \ - '-V[Print version number]' \ - '-q[Uses specified queue, uppercase acts as batch]:a-z+A-Z' \ - '-f[Read job from file rather than from stdin]:file:_files' \ - '-v[Show the time the job will be executed]' \ - '-m[Send mail even if there was no output]' \ + '-V[print version number]' \ + '-q[uses specified queue, uppercase acts as batch]:a-z+A-Z' \ + '-f[read job from file rather than from stdin]:file:_files' \ + '-v[show the time the job will be executed]' \ + '-m[send mail even if there was no output]' \ ':time:' \ - atq \ - '-l[Alias for atq]' \ + '-l[alias for atq]' \ - atrm \ - '-d[Alias for atrm]' \ + '-d[alias for atrm]' \ - show-job \ - '-c[Cat specified jobs to stdout]:*:job number:->jobs' + '-c[cat specified jobs to stdout]:*:job number:->jobs' esac case $state in diff --git a/Completion/Unix/Command/_bzr b/Completion/Unix/Command/_bzr index 47083ca49..83f6fd19b 100644 --- a/Completion/Unix/Command/_bzr +++ b/Completion/Unix/Command/_bzr @@ -259,7 +259,7 @@ case $cmd in ) ;; -(diff|dif|di) +(diff|dif|di|cdiff) args+=( '(-r --revision)'{--revision=,-r}'[revision]:revision:' '--diff-options=[options to pass to gdiff]:diff options:' diff --git a/Completion/Unix/Command/_ffmpeg b/Completion/Unix/Command/_ffmpeg index 8f9b2c9cb..6a4ba234d 100644 --- a/Completion/Unix/Command/_ffmpeg +++ b/Completion/Unix/Command/_ffmpeg @@ -21,6 +21,12 @@ typeset -A opt_args _wanted ffmpeg-video-codecs expl 'force video codec (''copy'' to copy stream)' compadd -a vcodecs } +(( $+functions[_ffmpeg_scodecs] )) || _ffmpeg_scodecs() { + local scodecs + scodecs=(copy ${${(M)${(f)"$(_call_program video-codecs $words[1] -codecs 2>/dev/null)"}:#[[:space:]][D[:space:]][E[:space:]]S[S[:space:]][D[:space:]][T[:space:]][[:space:]][^[:space:]]##*}//(#b)????????([^[:space:]]##)*/$match[1]}) + _wanted ffmpeg-video-codecs expl 'force video codec (''copy'' to copy stream)' compadd -a scodecs +} + (( $+functions[_ffmpeg_formats] )) || _ffmpeg_formats() { local formats formats=(${(ou)${=${(s:,:)${${(M)${(f)"$(_call_program formats $words[1] -formats 2>/dev/null)"}:#[[:space:]][D[:space:]][E[:space:]][[:space:]][^[:space:]]##*}//(#b)????([^[:space:]]##)*/$match[1]}}}}) @@ -84,6 +90,7 @@ typeset -A _ffmpeg_flags lastopt+=":$lastopt_description:" if (( $#lastopt_values )); then if [[ $lastopt_type == flags ]]; then + lastopt="*$lastopt" flagtype=${${lastopt%%:*}#-} lastopt+="->$flagtype" _ffmpeg_flags[$flagtype]="${lastopt_values[*]}" @@ -125,6 +132,7 @@ local -a _ffmpeg_argspecs lastopt+=":$lastopt_description:_files" elif [[ $lastopt == -[asv]pre ]]; then lastopt_takesargs=0 + lastopt="*$lastopt" lastopt+=": :_ffmpeg_presets" elif [[ $lastopt == -acodec ]]; then lastopt_takesargs=0 @@ -132,11 +140,16 @@ local -a _ffmpeg_argspecs elif [[ $lastopt == -vcodec ]]; then lastopt_takesargs=0 lastopt+=": :_ffmpeg_vcodecs" + elif [[ $lastopt == -scodec ]]; then + lastopt_takesargs=0 + lastopt+=": :_ffmpeg_scodecs" elif [[ $lastopt == -f ]]; then lastopt_takesargs=0 + lastopt="*$lastopt" lastopt+=": :_ffmpeg_formats" elif [[ $lastopt == -pix_fmt ]]; then lastopt_takesargs=0 + lastopt="*$lastopt" lastopt+=": :_ffmpeg_pix_fmts" elif [[ $example == bitstream_filter ]]; then lastopt_takesargs=0 diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index e062705ee..4a830f281 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -2,7 +2,7 @@ # Some parts of this completion's behaviour are configurable: # -# Say, you got your own git sub-commands (git will run a program `git-foo' +# Say you got your own git sub-commands (git will run a program `git-foo' # when you run "git foo") and you want "git f<tab>" to complete that sub # commands name for you. You can make that sub-command know to the completion # via the user-command style: @@ -15,8 +15,31 @@ # # % zstyle ':completion:*:*:git:*' user-commands ${${(M)${(k)commands}:#git-*}/git-/} # -# You could even create a function _git-foo() to handle specific completion -# for that command. +# A better solution is to create a function _git-foo() to handle specific +# completion for that command. This also allows you to add command-specific +# completion as well. Place such a function inside an autoloaded #compdef file +# and you should be all set. You can add a description to such a function by +# adding a line matching +# +# #description DESCRIPTION +# +# as the second line in the file. See +# Completion/Debian/Command/_git-buildpackage in the Zsh sources for an +# example. +# +# As this solution is so much better than the user-commands zstyle method, the +# zstyle method is now DEPRECATED. It will most likely be removed in the next +# major release of Zsh (5.0). +# +# When _git does not know a given sub-command (say `bar'), it falls back to +# completing file names for all arguments to that sub command. I.e.: +# +# % git bar <tab> +# +# ...will complete file names. If you do *not* want that fallback to be used, +# use the `use-fallback' style like this: +# +# % zstyle ':completion:*:*:git*:*' use-fallback false # TODO: There is still undocumented configurability in here. @@ -26,7 +49,7 @@ (( $+functions[_git-add] )) || _git-add () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args local ignore_missing= @@ -47,24 +70,25 @@ _git-add () { '--refresh[do not add files, but refresh their stat() info in index]' \ '--ignore-errors[continue adding if an error occurs]' \ $ignore_missing \ - '*:: :->file' && ret=0 + '*:: :->file' && return case $state in (file) - # TODO: Use __git_ignore_line_inside_arguments. declare -a ignored_files_alternatives - if [[ -n ${line[(I)-f|--force]} ]]; then + if [[ -n ${opt_args[(I)-f|--force]} ]]; then ignored_files_alternatives=( - 'ignored-modified-files:ignored modified files:__git_modified_files --ignored' - 'ignored-other-files:ignored other files:__git_other_files --ignored') + 'ignored-modified-files:ignored modified files:__git_ignore_line_inside_arguments __git_modified_files --ignored' + 'ignored-other-files:ignored other files:__git_ignore_line_inside_arguments __git_other_files --ignored') fi _alternative \ - 'modified-files::__git_modified_files' \ - 'other-files::__git_other_files' \ + 'modified-files::__git_ignore_line_inside_arguments __git_modified_files' \ + 'other-files::__git_ignore_line_inside_arguments __git_other_files' \ $ignored_files_alternatives && ret=0 ;; esac + + return ret } (( $+functions[_git-am] )) || @@ -72,11 +96,10 @@ _git-am () { local -a apply_options __git_setup_apply_options - # NOTE: --resolvemsg is only for internal use between git rebase and git am. + # NOTE: --rebasing and --resolvemsg are only for internal use between git + # rebase and git am. # TODO: --patch-format is undocumented. - # TODO: --ignore-date is incorrectly documented as being passed to git - # mailsplit. - # TODO: --rebasing, --rerere-autoupdate, and --no-rerere-autoupdate are + # TODO: --rerere-autoupdate and --no-rerere-autoupdate are # undocumented (and not implemented here). _arguments -S \ '(-s --signoff)'{-s,--signoff}'[add Signed-off-by: line to the commit message]' \ @@ -99,12 +122,12 @@ _git-am () { '--patch-format=-[specify format patches are in]:patch format:((mbox\:"mbox format" stgit-series\:"StGit patch series" stgit\:"stgit format"))' \ - '*:mbox file:_files' && ret=0 + '*:mbox file:_files' } (( $+functions[_git-archive] )) || _git-archive () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args declare -a backend_args @@ -145,6 +168,8 @@ _git-archive () { __git_tree_files ${PREFIX:-.} $line[1] && ret=0 ;; esac + + return ret } (( $+functions[_git-applymbox] )) || @@ -156,14 +181,14 @@ _git-applymbox () { '-u[encode commit information in UTF-8]' \ '(1)-c[restart command after fixing an unclean patch]:patch:_files -g ".dotest/0*"' \ ':mbox file:_files' \ - '::signoff file:__git_signoff_file' && ret=0 + '::signoff file:__git_signoff_file' } (( $+functions[_git-bisect] )) || _git-bisect () { # TODO: next subcommand is undocumented. Git-bisect.sh mentions that the # subcommand might be removed from the UI level. - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -C \ @@ -246,6 +271,8 @@ _git-bisect () { esac ;; esac + + return ret } (( $+functions[_git-branch] )) || @@ -306,12 +333,12 @@ _git-branch () { $dependent_modification_args \ "($l $c $m -D)-d[delete a fully merged branch]" \ "($l $c $m -d)-D[delete a branch]" \ - $dependent_deletion_args && ret=0 + $dependent_deletion_args } (( $+functions[_git-bundle] )) || _git-bundle () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -C \ @@ -359,6 +386,8 @@ _git-bundle () { esac ;; esac + + return ret } (( $+functions[_git-checkout] )) || @@ -371,7 +400,7 @@ _git-checkout () { new_branch_reflog_opt="(--patch)-l[create the new branch's reflog]" fi - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -w -C -s \ @@ -420,7 +449,7 @@ _git-checkout () { $tree_ish_arg \ $file_arg && ret=0 elif [[ -n ${opt_args[(I)-b|-B|-t|--track|--orphan]} ]]; then - _nothing && ret=0 + _nothing elif [[ -n $line[1] ]] && __git_is_treeish $line[1]; then __git_ignore_line __git_tree_files ${PREFIX:-.} $line[1] && ret=0 else @@ -428,6 +457,8 @@ _git-checkout () { fi ;; esac + + return ret } (( $+functions[_git-cherry-pick] )) || @@ -439,7 +470,7 @@ _git-cherry-pick () { '(-n --no-commit --ff)'{-n,--no-commit}'[do not make the actually commit]' \ '(-s --signoff --ff)'{-s,--signoff}'[add Signed-off-by line at the end of the commit message]' \ '(-e --edit -x -n --no-commit -s --signoff)--ff[fast forward, if possible]' \ - ': :__git_revisions' && ret=0 + ': :__git_revisions' } (( $+functions[_git-citool] )) || @@ -449,7 +480,7 @@ _git-citool () { (( $+functions[_git-clean] )) || _git-clean () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -w -C -S -s \ @@ -499,11 +530,13 @@ _git-clean () { $other_files_alt && ret=0 ;; esac + + return ret } (( $+functions[_git-clone] )) || _git-clone () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args # TODO: Argument to -o should be a remote name. @@ -538,6 +571,8 @@ _git-clone () { fi ;; esac + + return ret } (( $+functions[_git-commit] )) || @@ -589,7 +624,7 @@ _git-commit () { {-F,--file=}'[read commit message from given file]: :_files' \ {-m,--message=}'[use the given message as the commit message]:message' \ {-t,--template=}'[use file as a template commit message]:template:_files' \ - $amend_opt && ret=0 + $amend_opt } (( $+functions[_git-describe] )) || @@ -606,12 +641,12 @@ _git-describe () { '(--abbrev)--long[always show full format, even for exact matches]' \ '--match=[only consider tags matching glob pattern]:pattern' \ '--always[show uniquely abbreviated commit object as fallback]' \ - '*: :__git_committishs' && ret=0 + '*: :__git_committishs' } (( $+functions[_git-diff] )) || _git-diff () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args local -a diff_options @@ -689,11 +724,13 @@ _git-diff () { esac ;; esac + + return ret } (( $+functions[_git-fetch] )) || _git-fetch () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args local -a fetch_options @@ -717,11 +754,13 @@ _git-fetch () { fi ;; esac + + return ret } (( $+functions[_git-format-patch] )) || _git-format-patch () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args local -a diff_options @@ -770,6 +809,8 @@ _git-format-patch () { fi ;; esac + + return ret } (( $+functions[_git-gc] )) || @@ -779,7 +820,7 @@ _git-gc () { '--auto[check whether housekeeping is required]' \ '( --no-prune)--prune=[prune loose objects older than given date]: :__git_datetimes' \ '(--prune )--no-prune[do not prune any loose objects]' \ - '--quiet[suppress all progress reports]' && ret=0 + '--quiet[suppress all progress reports]' } (( $+functions[_git-grep] )) || @@ -794,7 +835,7 @@ _git-grep () { '--not[the following pattern must not match]') fi - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args # TODO: Need to implement -<num> as a shorthand for -C<num> @@ -871,17 +912,19 @@ _git-grep () { fi ;; esac + + return ret } (( $+functions[_git-gui] )) || _git-gui () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -C \ '--version[display version information]' \ ': :->command' \ - '*:: :->arg' + '*:: :->arg' && ret=0 case $state in (command) @@ -900,7 +943,7 @@ _git-gui () { case $line[1] in (blame) - _git-blame + _git-blame && ret=0 ;; (browser) _arguments -C \ @@ -914,7 +957,7 @@ _git-gui () { esac ;; (citool) - _git-citool + _git-citool && ret=0 ;; (version) _nothing @@ -925,6 +968,8 @@ _git-gui () { esac ;; esac + + return ret } (( $+functions[_git-init] )) || @@ -934,21 +979,23 @@ _git-init () { '--bare[create a bare repository]' \ '--template=[directory to use as a template for the object database]: :_directories' \ '--shared=[share repository amongst several users]:: :__git_repository_permissions' \ - ':: :_directories' && ret=0 + ':: :_directories' } (( $+functions[_git-log] )) || _git-log () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args - local -a log_options revision_options + local -a log_options revision_options diff_options __git_setup_log_options __git_setup_revision_options + __git_setup_diff_options _arguments -w -C -s \ $log_options \ $revision_options \ + $diff_options \ '(-)--[start file arguments]' \ '*:: :->commit-range-or-file' && ret=0 @@ -978,6 +1025,8 @@ _git-log () { ;; esac esac + + return ret } (( $+functions[_git-merge] )) || @@ -990,12 +1039,12 @@ _git-merge () { '-m[set the commit message to be used for the merge commit]:merge message' \ '( --no-rerere-autoupdate)--rerere-autoupdate[allow the rerere mechanism to update the index]' \ '(--rerere-autoupdate )--no-rerere-autoupdate[do not allow the rerere mechanism to update the index]' \ - '*: :__git_commits' && ret=0 + '*: :__git_commits' } (( $+functions[_git-mv] )) || _git-mv () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -w -C -S -s \ @@ -1012,11 +1061,13 @@ _git-mv () { 'directories:destination directory:_directories' && ret=0 ;; esac + + return ret } (( $+functions[_git-notes] )) || _git-notes () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -C \ @@ -1082,6 +1133,8 @@ _git-notes () { esac ;; esac + + return ret } (( $+functions[_git-pull] )) || @@ -1096,7 +1149,7 @@ _git-pull () { '(--rebase )--no-rebase[do not perform a rebase after fetching]' \ $fetch_options \ ': :__git_any_repositories' \ - '*: :__git_ref_specs' && ret=0 + '*: :__git_ref_specs' } (( $+functions[_git-push] )) || @@ -1122,7 +1175,7 @@ _git-push () { '(-q --quiet -v --verbose)'{-v,--verbose}'[output additional information]' \ '(-q --quiet)--progress[output progress information]' \ ':: :__git_any_repositories' \ - '*: :__git_ref_specs' && ret=0 + '*: :__git_ref_specs' } (( $+functions[_git-rebase] )) || @@ -1157,12 +1210,12 @@ _git-rebase () { '--no-ff[cherry-pick all rebased commits with --interactive, otherwise synonymous to --force-rebase]' \ '--onto[start new branch with HEAD equal to given revision]:newbase:__git_revisions' \ ':upstream branch:__git_revisions' \ - '::working branch:__git_branch_names' && ret=0 + '::working branch:__git_branch_names' } (( $+functions[_git-reset] )) || _git-reset () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 typeset -A opt_args _arguments -w -C -s \ @@ -1186,6 +1239,8 @@ _git-reset () { __git_tree_files ${PREFIX:-.} $commit && ret=0 ;; esac + + return ret } (( $+functions[_git-revert] )) || @@ -1196,12 +1251,12 @@ _git-revert () { '(-e --edit)--no-edit[do not edit the commit message]' \ '(-n --no-commit)'{-n,--no-commit}'[do not commit the reversion]' \ '(-s --signoff)'{-s,--signoff}'[add Signed-off-by line at the end of the commit message]' \ - ': :__git_commits' && ret=0 + ': :__git_commits' } (( $+functions[_git-rm] )) || _git-rm () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -w -C -S -s \ @@ -1222,11 +1277,13 @@ _git-rm () { fi ;; esac + + return ret } (( $+functions[_git-shortlog] )) || _git-shortlog () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args local -a revision_options @@ -1258,11 +1315,13 @@ _git-shortlog () { fi ;; esac + + return ret } (( $+functions[_git-show] )) || _git-show () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 typeset -A opt_args local -a log_options revision_options @@ -1283,11 +1342,13 @@ _git-show () { 'blobs::__git_blobs' && ret=0 ;; esac + + return ret } (( $+functions[_git-stash] )) || _git-stash () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -C \ @@ -1368,6 +1429,8 @@ _git-stash () { esac ;; esac + + return ret } (( $+functions[_git-status] )) || @@ -1387,12 +1450,12 @@ _git-status () { all\:"also show untracked files in untracked directories (default)"))' \ '--ignore-submodules[ignore changes to submodules]:: :__git_ignore_submodules_whens' \ '(--porcelain)-z[use NUL termination on output]' \ - '*: :__git_ignore_line_inside_arguments _files' && ret=0 + '*: :__git_ignore_line_inside_arguments _files' } (( $+functions[_git-submodule] )) || _git-submodule () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -C -A '-*' \ @@ -1493,6 +1556,8 @@ _git-submodule () { esac ;; esac + + return ret } (( $+functions[_git-tag] )) || @@ -1524,7 +1589,17 @@ _git-tag () { '::pattern' \ - verification \ '-v[verifies gpg signutare of tags]' \ - '*:: :__git_ignore_line_inside_arguments __git_tags' && ret=0 + '*:: :__git_ignore_line_inside_arguments __git_tags' +} + +(( $+functions[_gitk] )) || +_gitk () { + _git-log +} + +(( $+functions[_tig] )) || +_tig () { + _git-log } # Ancillary Commands (Manipulators) @@ -1532,7 +1607,7 @@ _git-tag () { (( $+functions[_git-config] )) || _git-config () { local name_arg value_arg - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args if (( words[(I)--get-regexp] )); then @@ -1955,7 +2030,7 @@ _git-config () { case $state in (section) - __git_config_sections -b '(|)' '^' section-names 'section name' $* + __git_config_sections -b '(|)' '^' section-names 'section name' $* && ret=0 ;; (is-a-tty) declare -a values @@ -1963,7 +2038,7 @@ _git-config () { true false auto) - _describe -t values 'stdout is a tty' values + _describe -t values 'stdout is a tty' values && ret=0 ;; (option) local label=option @@ -2054,7 +2129,7 @@ _git-config () { __git_mergetools -S . && ret=0 ;; (pager.) - __git_aliases_and_commands && ret=0 + _git_commands && ret=0 ;; (pretty.) __git_config_sections -a '(|)' '^pretty\..+\.[^.]+$' prettys 'pretty format string' && ret=0 @@ -2145,7 +2220,7 @@ _git-config () { ;; (gettable-option) _describe -t git-options option \ - ${${${(0)"$(_call_program gettable-options git config -z --list)"}%%$'\n'*}//:/\\:} + ${${${(0)"$(_call_program gettable-options git config -z --list)"}%%$'\n'*}//:/\\:} && ret=0 ;; (gettable-colorbool-option) __git_config_sections -b '(|)' -a '(|)' '^color\.[^.]+$' gettable-colorbool-options option && ret=0 @@ -2178,7 +2253,7 @@ _git-config () { # TODO: Should really only complete unique remotes, that is, not the same # remote more than once in the list. __git_remotes -S $suffix -q && ret=0 - return + return ret ;; esac local z=$'\0' @@ -2187,7 +2262,7 @@ _git-config () { if (( $#parts < 2 )) && [[ $line[1] == [^.]##.*.[^.]## ]]; then parts=("${(S@0)${git_options_static[(r)(#i)${line[1]%%.*}.\*.${line[1]##*.}:*]}//(#b)(*[^\\]|):/$match[1]$z}") fi - (( $#parts > 0 )) || return + (( $#parts > 0 )) || return ret case $parts[4] in ('->'*) case ${parts[4]#->} in @@ -2453,6 +2528,8 @@ _git-config () { esac ;; esac + + return ret } (( $+functions[_git-fast-export] )) || @@ -2474,7 +2551,7 @@ _git-fast-export () { '--fake-missing-tagger=[fake a tagger when tags lack them]' \ '--no-data[do not output blocb objects, instead referring to them via their SHA-1 hash]' \ '--full-tree[output full tree for each commit]' \ - '*: :__git_commit_ranges' && ret=0 + '*: :__git_commit_ranges' } (( $+functions[_git-fast-import] )) || @@ -2494,7 +2571,7 @@ _git-fast-import () { '*--no-relative-marks[paths for export/import are not relative to internal directory in current repository]' \ '--export-pack-edges=-[list packfiles and last commit on branches in them in given file]: :_files' \ '--quiet[disable all non-fatal output]' \ - '--stats[display statistics about object created]' && ret=0 + '--stats[display statistics about object created]' } (( $+functions[_git-filter-branch] )) || @@ -2516,7 +2593,7 @@ _git-filter-branch () { '--original[namespace where original commits will be stored]:namespace:_directories' \ '-d[temporary directory used for rewriting]: :_directories' \ '(-f --force)'{-f,--force}'[force operation]' \ - '*: :__git_commit_ranges' && ret=0 + '*: :__git_commit_ranges' } (( $+functions[_git-mergetool] )) || @@ -2526,7 +2603,7 @@ _git-mergetool () { '(-t --tool)'{-t,--tool=}'[merge resolution program to use]: :__git_mergetools' \ '(-y --no-prompt --prompt)'{-y,--no-prompt}'[do not prompt before invocation of merge resolution program]' \ '(-y --no-prompt)--prompt[prompt before invocation of merge resolution program]' \ - '*:conflicted file:_files' && ret=0 + '*:conflicted file:_files' } (( $+functions[_git-pack-refs] )) || @@ -2535,7 +2612,7 @@ _git-pack-refs () { '( --no-all)--all[pack all refs]' \ '(--all )--no-all[do not pack all refs]' \ '( --no-prune)--prune[remove loose refs after packing them]' \ - '(--prune )--no-prune[do not remove loose refs after packing them]' && ret=0 + '(--prune )--no-prune[do not remove loose refs after packing them]' } (( $+functions[_git-prune] )) || @@ -2544,7 +2621,7 @@ _git-prune () { '(-n --dry-run)'{-n,--dry-run}'[do not remove anything; just report what would be removed]' \ '(-v --verbose)'{-v,--rerbose}'[report all removed objects]' \ '--expire[only expire loose objects older than given date]: :__git_datetimes' \ - '*:: :__git_heads' && ret=0 + '*:: :__git_heads' } (( $+functions[_git-reflog] )) || @@ -2555,9 +2632,9 @@ _git-reflog () { if [[ $words[2] == --* ]]; then _arguments -S \ $revision_options \ - ':: :__git_references' && ret=0 + ':: :__git_references' else - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args # TODO: -h is undocumented. @@ -2616,6 +2693,8 @@ _git-reflog () { ;; esac esac + + return ret fi } @@ -2627,12 +2706,12 @@ _git-relink () { '--help[display help]' \ ': :_directories' \ ': :_directories' \ - '*: :_directories' && ret=0 + '*: :_directories' } (( $+functions[_git-remote] )) || _git-remote () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -C \ @@ -2725,6 +2804,8 @@ _git-remote () { esac ;; esac + + return ret } (( $+functions[_git-repack] )) || @@ -2742,7 +2823,7 @@ _git-repack () { '--window=-[number of objects to consider when doing delta compression]: :__git_guard_number "number of objects"' \ '--depth=-[maximum delta depth]: :__git_guard_number "maximum delta depth"' \ '--window-memory=-[scale window size dynamically to not use more than N bytes of memory]: :__git_guard_bytes' \ - '--max-pack-size=-[maximum size of each output packfile]:maximum pack size:__git_guard_bytes' && ret=0 + '--max-pack-size=-[maximum size of each output packfile]:maximum pack size:__git_guard_bytes' } (( $+functions[_git-replace] )) || @@ -2753,14 +2834,14 @@ _git-replace () { '(- : *)-l[list replace refs]:pattern' \ ': :__git_objects' \ ':replacement:__git_objects' \ - '*: :__git_objects' && ret=0 + '*: :__git_objects' } # Ancillary Commands (Interrogators) (( $+functions[_git-blame] )) || _git-blame () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args declare -a revision_options @@ -2804,6 +2885,8 @@ _git-blame () { fi ;; esac + + return ret } (( $+functions[_git-cherry] )) || @@ -2814,13 +2897,13 @@ _git-cherry () { '--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length' \ ':upstream commit:__git_commits' \ '::head commit:__git_commits' \ - '::limit commit:__git_commits' && ret=0 + '::limit commit:__git_commits' } (( $+functions[_git-count-objects] )) || _git-count-objects () { _arguments \ - '(-v --verbose)'{-v,--verbose}'[also report number of in-pack objects and objects that can be removed]' && ret=0 + '(-v --verbose)'{-v,--verbose}'[also report number of in-pack objects and objects that can be removed]' } (( $+functions[_git-difftool] )) || @@ -2847,7 +2930,7 @@ _git-fsck () { '--strict[do strict checking]' \ '(-v --verbose)'{-v,--verbose}'[output additional information]' \ '--lost-found[write dangling objects into .git/lost-found]' \ - '*: :__git_objects' && ret=0 + '*: :__git_objects' } (( $+functions[_git-get-tar-commit-id] )) || @@ -2862,12 +2945,12 @@ _git-help () { '(-a --all -m --man -w --web)'{-i,--info}'[show all available commands]' \ '(-a --all -i --info -w --web)'{-m,--man}'[show all available commands]' \ '(-a --all -i --info -m --man )'{-w,--web}'[show all available commands]' \ - ': :__git_aliases_and_commands' && ret=0 + ': :_git_commands' } (( $+functions[_git-instaweb] )) || _git-instaweb () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -w -C -S -s \ @@ -2893,6 +2976,8 @@ _git-instaweb () { _describe -t commands command commands && ret=0 ;; esac + + return ret } (( $+functions[_git-merge-tree] )) || @@ -2900,12 +2985,12 @@ _git-merge-tree () { _arguments \ ':base-tree:__git_tree_ishs' \ ':branch 1:__git_tree_ishs' \ - ':branch 2:__git_tree_ishs' && ret=0 + ':branch 2:__git_tree_ishs' } (( $+functions[_git-rerere] )) || _git-rerere () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args # TODO: --rerere-autoupdate is undocumented. @@ -2924,6 +3009,8 @@ _git-rerere () { 'gc[prune old records of conflicted merges]' && ret=0 ;; esac + + return ret } (( $+functions[_git-rev-parse] )) || @@ -2941,6 +3028,8 @@ _git-rev-parse () { quiet_opts=({-q,--quiet}'[do not output error messages]') fi + local ret=0 + if (( words[(I)--parseopt] )); then if (( words[(I)--] )); then _message 'argument' @@ -2991,11 +3080,13 @@ _git-rev-parse () { '(--until --before)'{--until=-,--before=-}'[show --min-age= parameter corresponding given date string]:datestring' \ '*: :__git_objects' && ret=0 fi + + return ret } (( $+functions[_git-show-branch] )) || _git-show-branch () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -w -C -S -s -A '-*' \ @@ -3031,6 +3122,8 @@ _git-show-branch () { fi ;; esac + + return ret } (( $+functions[_git-verify-tag] )) || @@ -3038,7 +3131,7 @@ _git-verify-tag () { # TODO: -v and --verbose are undocumented. _arguments -w -S -s \ '(-v --verbose)'{-v,--verbose}'[output additional information]' \ - '*: :__git_tags' && ret=0 + '*: :__git_tags' } (( $+functions[_git-whatchanged] )) || @@ -3049,7 +3142,7 @@ _git-whatchanged () { _arguments -S \ $revision_options \ '1:: :__git_commits' \ - '*: :__git_cached_files' && ret=0 + '*: :__git_cached_files' } # Interacting With Others @@ -3067,7 +3160,7 @@ _git-archimport () { '-D[attempt to import trees that have been merged from]: :__git_guard_number depth' \ '-a[auto-register archives at http://mirrors.sourcecontrol.net]' \ '-t[use given directory as temporary directory]: :_directories' \ - '*:archive/branch' && ret=0 + '*:archive/branch' } (( $+functions[_git-cvsexportcommit] )) || @@ -3088,7 +3181,7 @@ _git-cvsexportcommit () { '-v[verbose output]' \ '-h[display usage]' \ ':: :__git_commits' \ - ': :__git_commits' && ret=0 + ': :__git_commits' } (( $+functions[_git-cvsimport] )) || @@ -3115,7 +3208,7 @@ _git-cvsimport () { '-A[specify author-conversion file]:author-conversion file:_files' \ '-R[generate cvs-revisions file mapping CVS revision numbers to commit IDs]' \ '-h[display usage information]' \ - ':cvsmodule' && ret=0 + ':cvsmodule' } (( $+functions[_git-cvsserver] )) || @@ -3127,7 +3220,7 @@ _git-cvsserver () { '(- * -V --version)'{-V,--version}'[display version information]' \ '(- * -h --help)'{-h,-H,--help}'[display usage information]' \ '::type:(pserver server)' \ - '*: :_directories' && ret=0 + '*: :_directories' } (( $+functions[_git-imap-send] )) || @@ -3140,7 +3233,7 @@ _git-quiltimport () { _arguments -S \ '(-n --dry-run)'{-n,--dry-run}'[check patches and warn if they cannot be imported]' \ '--author[default author name and email address to use for patches]: :_email_addresses' \ - '--patches[set directory containing patches]:patch directory:_directories' && ret=0 + '--patches[set directory containing patches]:patch directory:_directories' } (( $+functions[_git-request-pull] )) || @@ -3190,12 +3283,12 @@ _git-send-email () { '( --no-validate)--validate[perform sanity checks on patches]' \ '(--validate )--validate[do not perform sanity checks on patches]' \ '--force[send emails even if safetiy checks would prevent it]' \ - '*: :_files' && ret=0 + '*: :_files' } (( $+functions[_git-svn] )) || _git-svn () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -C \ @@ -3438,6 +3531,8 @@ _git-svn () { esac ;; esac + + return ret } # LOW-LEVEL COMMANDS (PLUMBING) @@ -3468,7 +3563,7 @@ _git-apply () { '--inaccurate-eof[work around missing-new-line-at-EOF bugs]' \ '(-v --verbose)'{-v,--verbose}'[display progress on stderr]' \ '--recount[do not trust line counts in hunk headers]' \ - '*:patch:_files' && ret=0 + '*:patch:_files' } (( $+functions[_git-checkout-index] )) || @@ -3490,7 +3585,7 @@ _git-checkout-index () { '--temp[write content to temporary files]' \ '(-a --all *)--stdin[read list of paths from the standard input]' \ $z_opt \ - '*: :__git_cached_files' && ret=0 + '*: :__git_cached_files' } (( $+functions[_git-commit-tree] )) || @@ -3498,11 +3593,11 @@ _git-commit-tree () { if (( CURRENT == 2 )); then _arguments \ '-h[display usage]' \ - ': :__git_trees' && ret=0 + ': :__git_trees' elif [[ $words[CURRENT-1] == -p ]]; then local expl _description commits expl 'parent commit' - __git_objects $expl && ret=0 + __git_objects $expl else compadd - '-p' fi @@ -3520,7 +3615,7 @@ _git-hash-object () { '(: --stdin --path)--stdin-paths[read file names from standard input instead of from command line]' \ '( --no-filters)--path=[hash object as if it were located at given path]: :_files' \ '(--path )--no-filters[hash contents as is, ignoring any input filters]' \ - '(--stdin --stdin-paths):file:_files' && ret=0 + '(--stdin --stdin-paths):file:_files' } (( $+functions[_git-index-pack] )) || @@ -3541,7 +3636,7 @@ _git-index-pack () { '--stdin[read pack from stdin and instead write to specified file]' \ $stdin_opts \ '--strict[die if the pack contains broken objects or links]' \ - ':pack file:_files -g "*.pack"' && ret=0 + ':pack file:_files -g "*.pack"' } (( $+functions[_git-merge-file] )) || @@ -3570,7 +3665,7 @@ _git-merge-file () { '--diff3[undocumented]' \ ':current file:_files' \ ':base file:_files' \ - ':other file:_files' && ret=0 + ':other file:_files' } (( $+functions[_git-merge-index] )) || @@ -3578,7 +3673,7 @@ _git-merge-index () { if (( CURRENT > 2 )) && [[ $words[CURRENT-1] != -[oq] ]]; then _arguments -S \ '(:)-a[run merge against all files in index that need merging]' \ - '*: :__git_cached_files' && ret=0 + '*: :__git_cached_files' else declare -a arguments @@ -3586,7 +3681,7 @@ _git-merge-index () { (( CURRENT == 2 || CURRENT == 3 )) && arguments+='(-o)-q[do not complain about failed merges]' (( 2 <= CURRENT && CURRENT <= 4 )) && arguments+='*:merge program:_files -g "*(*)"' - _arguments -S $arguments && ret=0 + _arguments -S $arguments fi } @@ -3600,7 +3695,7 @@ _git-mktree () { _arguments -w -S -s \ '-z[read NUL-terminated ls-tree -z output]' \ '--missing[allow missing objects]' \ - '--batch[allow creation of more than one tree]' && ret=0 + '--batch[allow creation of more than one tree]' } (( $+functions[_git-pack-objects] )) || @@ -3642,14 +3737,14 @@ _git-pack-objects () { '--keep-true-parents[pack parents hidden by grafts]' \ '( --unpack-unreachable)--keep-unreachable[undocumented]' \ '(--keep-unreachable )--unpack-unreachable[undocumented]' \ - ':base-name:_files' && ret=0 + ':base-name:_files' } (( $+functions[_git-prune-packed] )) || _git-prune-packed () { _arguments -w -S -s \ '(-n --dry-run)'{-n,--dry-run}'[only list objects that would be removed]' \ - '(-q --quiet)'{-q,--quiet}'[do not display progress on standard error]' && ret=0 + '(-q --quiet)'{-q,--quiet}'[do not display progress on standard error]' } (( $+functions[_git-read-tree] )) || @@ -3688,7 +3783,7 @@ _git-read-tree () { '--no-sparse-checkout[display sparse checkout support]' \ '1:first tree-ish to be read/merged:__git_tree_ishs' \ '2::second tree-ish to be read/merged:__git_tree_ishs' \ - '3::third tree-ish to be read/merged:__git_tree_ishs' && ret=0 + '3::third tree-ish to be read/merged:__git_tree_ishs' } (( $+functions[_git-symbolic-ref] )) || @@ -3697,7 +3792,7 @@ _git-symbolic-ref () { '(-q --quiet)'{-q,--quiet}'[do not issue error if specified name is not a symbolic ref]' \ '-m[update reflog for specified name with specied reason]:reason for update' \ ':symbolic reference:__git_heads' \ - ':: :__git_references' && ret=0 + ':: :__git_references' } (( $+functions[_git-unpack-objects] )) || @@ -3706,7 +3801,7 @@ _git-unpack-objects () { '-n[only list the objects that would be unpacked]' \ '-q[run quietly]' \ '-r[try recovering objects from corrupt packs]' \ - '--strict[do not write objects with broken content or links]' && ret=0 + '--strict[do not write objects with broken content or links]' } (( $+functions[_git-update-index] )) || @@ -3744,7 +3839,7 @@ _git-update-index () { '(: -)--stdin[read list of paths from standard input]' \ '--verbose[report what is being added and removed from the index]' \ $z_opt \ - '*:: :_files' && ret=0 + '*:: :_files' } (( $+functions[_git-update-ref] )) || @@ -3755,7 +3850,7 @@ _git-update-ref () { '--no-deref[overwrite ref itself, not what it points to]' \ ':symbolic reference:__git_revisions' \ ':new reference:__git_revisions' \ - '::old reference:__git_revisions' && ret=0 + '::old reference:__git_revisions' } (( $+functions[_git-write-tree] )) || @@ -3763,7 +3858,7 @@ _git-write-tree () { # NOTE: --ignore-cache-tree is only used for debugging. _arguments -w -S -s \ '--missing-ok[ignore objects in index that are missing in object database]' \ - '--prefix=[write tree representing given sub-directory]:sub-directory:_directories -r ""' && ret=0 + '--prefix=[write tree representing given sub-directory]:sub-directory:_directories -r ""' } # Interrogation commands @@ -3779,7 +3874,7 @@ _git-cat-file () { '(- :)--batch[print SHA1, type, size, and contents of each object provided on stdin]' \ '(- :)--batch-check[print SHA1, type, and size of each object provided on stdin]' \ '(-):object type:(blob commit tag tree)' \ - ': :__git_objects' && ret=0 + ': :__git_objects' } (( $+functions[_git-diff-files] )) || @@ -3791,7 +3886,7 @@ _git-diff-files () { $revision_options \ ': :__git_changed-in-working-tree_files' \ ': :__git_changed-in-working-tree_files' \ - '*: :__git_changed-in-working-tree_files' && ret=0 + '*: :__git_changed-in-working-tree_files' } (( $+functions[_git-diff-index] )) || @@ -3808,12 +3903,12 @@ _git-diff-index () { '--cached[do not consider the work tree at all]' \ '-m[flag non-checked-out files as up-to-date]' \ ': :__git_tree_ishs' \ - '*: :__git_cached_files' && ret=0 + '*: :__git_cached_files' } (( $+functions[_git-diff-tree] )) || _git-diff-tree () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args declare -a revision_options @@ -3858,6 +3953,8 @@ _git-diff-tree () { fi ;; esac + + return ret } (( $+functions[_git-for-each-ref] )) || @@ -3873,7 +3970,7 @@ _git-for-each-ref () { '(-s --shell -p --perl --python --tcl)'{-p,--perl}'[use string literals suitable for Perl]' \ '(-s --shell -p --perl --tcl)'--python'[use string literals suitable for Python]' \ '(-s --shell -p --perl --python )'--tcl'[use string literals suitable for Tcl]' \ - ':: :_guard "([^-]?#|)" pattern' && ret=0 + ':: :_guard "([^-]?#|)" pattern' } (( $+functions[_git-ls-files] )) || @@ -3908,7 +4005,7 @@ _git-ls-files () { '-v[identify each files status (hmrck?)]' \ '--full-name[force paths to be output relative to the project top directory]' \ '--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length' \ - '*:: :_files' && ret=0 + '*:: :_files' } (( $+functions[_git-ls-remote] )) || @@ -3919,12 +4016,12 @@ _git-ls-remote () { '(-t --tags)'{-t,--tags}'[show only refs under refs/tags]' \ '(-u --upload-pack)'{-u,--upload-pack=-}'[specify path to git-upload-pack on remote side]:remote path' \ ': :__git_any_repositories' \ - '*: :__git_references' && ret=0 + '*: :__git_references' } (( $+functions[_git-ls-tree] )) || _git-ls-tree () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -w -C -S -s \ @@ -3945,6 +4042,8 @@ _git-ls-tree () { __git_ignore_line __git_tree_files ${PREFIX:-.} $line[1] && ret=0 ;; esac + + return ret } (( $+functions[_git-merge-base] )) || @@ -3954,7 +4053,7 @@ _git-merge-base () { '--octopus[compute best common ancestors of all supplied commits]' \ '(-)--independent[display minimal subset of supplied commits with same ancestors]' \ ': :__git_commits' \ - '*: :__git_commits' && ret=0 + '*: :__git_commits' } (( $+functions[_git-name-rev] )) || @@ -3967,7 +4066,7 @@ _git-name-rev () { '--name-only[display only name of commits]' \ '--no-undefined[die with non-zero return when a reference is undefined]' \ '--always[show uniquely abbreviated commit object as fallback]' \ - '(--stdin --all)*: :__git_commits' && ret=0 + '(--stdin --all)*: :__git_commits' } (( $+functions[_git-pack-redundant] )) || @@ -3976,12 +4075,12 @@ _git-pack-redundant () { '(:)--all[process all packs]' \ '--alt-odb[do not require objects to be present in local packs]' \ '--verbose[output some statistics to standard error]' \ - '(--all)*::packs:_files -g "*.pack"' && ret=0 + '(--all)*::packs:_files -g "*.pack"' } (( $+functions[_git-rev-list] )) || _git-rev-list () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args declare -a revision_options @@ -4008,6 +4107,8 @@ _git-rev-list () { fi ;; esac + + return ret } (( $+functions[_git-show-index] )) || @@ -4029,14 +4130,14 @@ _git-show-ref () { '(-q --quiet)'{-q,--quiet}'[do not print any results]' \ '*: :_guard "([^-]?#|)" pattern' \ - exclude \ - '--exclude-existing=-[filter out existing refs from stdin]:: :_guard "([^-]?#|)" pattern' && ret=0 + '--exclude-existing=-[filter out existing refs from stdin]:: :_guard "([^-]?#|)" pattern' } (( $+functions[_git-unpack-file] )) || _git-unpack-file () { _arguments -A '-*' \ '(:)-h[display usage information]' \ - '(-): :__git_blobs' && ret=0 + '(-): :__git_blobs' } (( $+functions[_git-var] )) || @@ -4046,7 +4147,7 @@ _git-var () { '(-):variable:((GIT_AUTHOR_IDENT\:"name and email of author" \ GIT_COMMITTER_IDENT\:"name and email of committer" \ GIT_EDITOR\:"text editor used by git commands" \ - GIT_PAGER\:"text viewer used by git commands"))' && ret=0 + GIT_PAGER\:"text viewer used by git commands"))' } (( $+functions[_git-verify-pack] )) || @@ -4054,7 +4155,7 @@ _git-verify-pack () { _arguments -w -S -s \ '(-v --verbose)'{-v,--verbose}'[show objects contained in pack]' \ '(-s --stat-only)'{-s,--stat-only}'[do not verify pack contents; only display histogram of delta chain length]' \ - '*:index file:_files -g "*.idx"' && ret=0 + '*:index file:_files -g "*.idx"' } # Synching Repositories @@ -4088,7 +4189,7 @@ _git-daemon () { '--disable=-[disable site-wide service]: :__git_daemon_service' \ '--allow-override[allow overriding site-wide service]: :__git_daemon_service' \ '--forbid-override[forbid overriding site-wide service]: :__git_daemon_service' \ - '*:repository:_directories' && ret=0 + '*:repository:_directories' } (( $+functions[_git-fetch-pack] )) || @@ -4105,7 +4206,7 @@ _git-fetch-pack () { '--no-progress[do not display progress]' \ '-v[produce verbose output]' \ ': :__git_any_repositories' \ - '*: :__git_references' && ret=0 + '*: :__git_references' } (( $+functions[_git-http-backend] )) || @@ -4129,13 +4230,13 @@ _git-send-pack () { '--stateless-rpc[undocumented]' \ '--helper-status[undocumented]' \ ': :__git_any_repositories' \ - '*: :__git_remote_references' && ret=0 + '*: :__git_remote_references' } (( $+functions[_git-update-server-info] )) || _git-update-server-info () { _arguments -w -S -s \ - '(-f --force)'{-f,--force}'[update the info files from scratch]' && ret=0 + '(-f --force)'{-f,--force}'[update the info files from scratch]' } (( $+functions[_git-http-fetch] )) || @@ -4149,7 +4250,7 @@ _git-http-fetch () { '--recover[recover from a failed fetch]' \ '(1)--stdin[read commit ids and refs from standard input]' \ ': :__git_commits' \ - ': :_urls' && ret=0 + ': :_urls' } (( $+functions[_git-http-push] )) || @@ -4162,7 +4263,7 @@ _git-http-push () { '( -D)-d[remove refs from remote repository]' \ '(-d )-D[forcefully remove refs from remote repository]' \ ': :_urls' \ - '*: :__git_remote_references' && ret=0 + '*: :__git_remote_references' } # NOTE: git-parse-remote isn’t a user command. @@ -4174,12 +4275,12 @@ _git-receive-pack () { _arguments -A '-*' \ '--advertise-refs[undocumented]' \ '--stateless-rpc[undocumented]' \ - ':directory to sync into:_directories' && ret=0 + ':directory to sync into:_directories' } (( $+functions[_git-shell] )) || _git-shell () { - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args _arguments -C \ @@ -4217,13 +4318,15 @@ _git-shell () { esac ;; esac + + return ret } (( $+functions[_git-upload-archive] )) || _git-upload-archive () { _arguments \ - ':directory to get tar archive from:_directories' && ret=0 + ':directory to get tar archive from:_directories' } (( $+functions[_git-upload-pack] )) || @@ -4235,7 +4338,7 @@ _git-upload-pack () { '--timeout=-[interrupt transfer after given number of seconds of inactivity]: :__git_guard_number "inactivity timeout"' \ '--advertise-refs[undocumented]' \ '--stateless-rpc[undocumented]' \ - ': :_directories' && ret=0 + ': :_directories' } # Internal Helper Commands @@ -4244,7 +4347,7 @@ _git-upload-pack () { _git-check-attr () { local z_opt= - local curcontext=$curcontext state line + local curcontext=$curcontext state line ret=1 declare -A opt_args if (( words[(I)--stdin] )); then @@ -4280,6 +4383,8 @@ _git-check-attr () { fi ;; esac + + return ret } (( $+functions[_git-check-ref-format] )) || @@ -4288,7 +4393,7 @@ _git-check-ref-format () { '-h[display usage information]' \ '--print[display canonicalized name of hypothetical reference of given name]' \ '--branch[expand previous branch syntax]' \ - ': :__git_references' && ret=0 + ': :__git_references' } (( $+functions[_git-fmt-merge-msg] )) || @@ -4297,7 +4402,7 @@ _git-fmt-merge-msg () { '( --no-log)--log[display one-line descriptions from actual commits being merged]' \ '(--log )--no-log[do not display one-line descriptions from actual commits being merged]' \ '(-m --message)'{-m+,--message=}'[use given message instead of branch names for first line in log message]:message' \ - '(-F --file)'{-F,--file}'[specify list of merged objects from file]: :_files' && ret=0 + '(-F --file)'{-F,--file}'[specify list of merged objects from file]: :_files' } (( $+functions[_git-mailinfo] )) || @@ -4312,7 +4417,7 @@ _git-mailinfo () { '(--scissors )--no-scissors[do not remove everything in body before a scissors line]' \ '--no-inbody-headers[undocumented]' \ ':message file:_files' \ - ':patch file:_files' && ret=0 + ':patch file:_files' } (( $+functions[_git-mailsplit] )) || @@ -4323,7 +4428,7 @@ _git-mailsplit () { '-d-[specify number of leading zeros]: :__git_guard_number precision' \ '-f-[skip the first N numbers]: :__git_guard_number' \ '--keep-cr[do not remove CR from lines ending with CR+LF]' \ - '*::mbox file:_files' && ret=0 + '*::mbox file:_files' } (( $+functions[_git-merge-one-file] )) || @@ -4341,7 +4446,7 @@ _git-patch-id () { (( $+functions[_git-stripspace] )) || _git-stripspace () { _arguments \ - '(-s --strip-comments)'{-s,--strip-comments}'[also strip lines starting with #]' && ret=0 + '(-s --strip-comments)'{-s,--strip-comments}'[also strip lines starting with #]' } # INTERNAL GIT COMPLETION FUNCTIONS @@ -4432,7 +4537,11 @@ __git_ignore_line () { (( $+functions[__git_ignore_line_inside_arguments] )) || __git_ignore_line_inside_arguments () { - __git_ignore_line ${*[-1]} ${*[1,-2]} + declare -a compadd_opts + + zparseopts -D -E -a compadd_opts V: J: 1 2 n f X: M: P: S: r: R: q F: + + __git_ignore_line $* $compadd_opts } # Common Argument Types @@ -4591,10 +4700,41 @@ _git_commands () { patch-id:'compute unique ID for a patch' stripspace:'filter out empty lines') + local -a user_commands + zstyle -a :completion:$curcontext: user-commands user_commands + + local -a third_party_commands + local command + for command in $_git_third_party_commands; do + (( $+commands[git-${command%%:*}] )) && third_party_commands+=$command + done + + local -a aliases unique_aliases + __git_extract_aliases + local alias + for alias in $aliases; do + local name=${alias%%:*} + (( main_porcelain_commands[(I)$name:*] || + user_commands[(I)$name:*] || + third_party_commands[(I)$name:*] || + ancillary_manipulator_commands[(I)$name:*] || + ancillary_interrogator_commands[(I)$name:*] || + interaction_commands[(I)$name:*] || + plumbing_manipulator_commands[(I)$name:*] || + plumbing_interrogator_commands[(I)$name:*] || + plumbing_sync_commands[(I)$name:*] || + plumbing_sync_helper_commands[(I)$name:*] || + plumbing_internal_helper_commands[(I)$name:*] )) || unique_aliases+=$alias + done + integer ret=1 - # TODO: Is this the correct way of doing it? - # TODO: Should we be chaining them together with || instead? + + # TODO: Is this the correct way of doing it? Should we be using _alternative + # and separate functions for each set of commands instead? + _describe -t aliases alias unique_aliases && ret=0 _describe -t main-porcelain-commands 'main porcelain command' main_porcelain_commands && ret=0 + _describe -t user-commands 'user command' user_commands && ret=0 + _describe -t third-party-commands 'third-party command' third_party_commands && ret=0 _describe -t ancillary-manipulator-commands 'ancillary manipulator command' ancillary_manipulator_commands && ret=0 _describe -t ancillary-interrogator-commands 'ancillary interrogator command' ancillary_interrogator_commands && ret=0 _describe -t interaction-commands 'interaction command' interaction_commands && ret=0 @@ -4603,24 +4743,23 @@ _git_commands () { _describe -t plumbing-sync-commands 'plumbing sync command' plumbing_sync_commands && ret=0 _describe -t plumbing-sync-helper-commands 'plumbing sync helper command' plumbing_sync_helper_commands && ret=0 _describe -t plumbing-internal-helper-commands 'plumbing internal helper command' plumbing_internal_helper_commands && ret=0 + return ret } (( $+functions[__git_aliases] )) || __git_aliases () { - declare -a aliases - - aliases=(${^${${(0)"$(_call_program aliases "git config -z --get-regexp '^alias.'")"}#alias.}/$'\n'/:alias for \'}\') + local -a aliases + __git_extract_aliases _describe -t aliases alias aliases $* } -(( $+functions[__git_aliases_and_commands] )) || -__git_aliases_and_commands () { - _alternative \ - 'aliases::__git_aliases' \ - 'commands::_git_commands' +(( $+functions[__git_extract_aliases] )) || +__git_extract_aliases () { + aliases=(${^${${(0)"$(_call_program aliases "git config -z --get-regexp '^alias.'")"}#alias.}/$'\n'/:alias for \'}\') } + (( $+functions[__git_date_formats] )) || __git_date_formats () { declare -a date_formats @@ -4651,7 +4790,7 @@ __git_merge_strategies () { local -a merge_strategies merge_strategies=(${=${${(M)${(f)"$(_call_program merge-strategies "git merge -s '' 2>&1")"}:#[Aa]vailable (custom )#strategies are: *}#[Aa]vailable (custom )#strategies are: }%.}) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 _wanted merge-strategies expl 'merge strategy' compadd $* - $merge_strategies } @@ -4815,7 +4954,7 @@ __git_reflog_entries () { declare -a reflog_entries reflog_entries=(${${${(f)"$(_call_program reflog-entries git reflog 2>/dev/null)"}#* }%%:*}) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 if compset -P '*@'; then reflog_entries=(${${(M)reflog_entries:#$IPREFIX*}#$IPREFIX}) @@ -4876,7 +5015,7 @@ __git_stashes () { declare -a stashes stashes=(${${(f)"$(_call_program stashes git stash list 2>/dev/null)"}/: */}) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 _wanted stashes expl stash compadd $* - $stashes } @@ -4915,7 +5054,7 @@ __git_branch_names () { declare -a branch_names branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/}) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 _wanted branch-names expl branch-name compadd $* - $branch_names } @@ -4926,7 +5065,7 @@ __git_remote_branch_names () { declare -a branch_names branch_names=(${${(f)"$(_call_program remote-branch-refs git for-each-ref --format='"%(refname)"' refs/remotes 2>/dev/null)"}#refs/remotes/}) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 _wanted remote-branch-names expl 'remote branch name' compadd $* - $branch_names } @@ -5046,7 +5185,7 @@ __git_submodules () { declare -a submodules submodules=(${${(f)"$(_call_program submodules git submodule 2>/dev/null)"}#* }) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 _wanted submodules expl submodule compadd $* - $submodules } @@ -5059,7 +5198,7 @@ __git_tags () { declare -a tags tags=(${${(f)"$(_call_program tagrefs git for-each-ref --format='"%(refname)"' refs/tags 2>/dev/null)"}#refs/tags/}) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 _wanted tags expl tag compadd $* - $tags } @@ -5082,15 +5221,11 @@ __git_tags_of_type () { type=$1; shift tags=(${${(M)${(f)"$(_call_program $type-tag-refs "git for-each-ref --format='%(*objecttype)%(objecttype) %(refname)' refs/tags 2>/dev/null")"}:#$type(tag|) *}#$type(tag|) refs/tags/}) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 _wanted $type-tags expl "$type tag" compadd $* - $tags } -(( $+functions[__git_tag_ids] )) || -__git_tag_ids () { -} - # Reference Argument Types (( $+functions[__git_references] )) || @@ -5107,7 +5242,7 @@ __git_references () { # TODO: deal with GIT_DIR if [[ $_git_refs_cache_pwd != $PWD ]]; then _git_refs_cache=(${${${(f)"$(_call_program references git ls-remote ./. 2>/dev/null)"}#*$'\t'}#refs/(heads|tags)/}) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 _git_refs_cache_pwd=$PWD fi @@ -5120,7 +5255,7 @@ __git_local_references () { if [[ $_git_local_refs_cache_pwd != $PWD ]]; then _git_local_refs_cache=(${${${(f)"$(_call_program references git ls-remote ./. 2>/dev/null)"}#*$'\t'}#refs/}) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 _git_local_refs_cache_pwd=$PWD fi @@ -5137,7 +5272,7 @@ __git_local_references () { local references expl references=(${${(M)${${(f)"$(_call_program references git ls-remote ./. 2>/dev/null)"}#*$'\t'}:#refs/notes/*}#refs/notes/}) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 _wanted references expl reference compadd - $references } @@ -5147,9 +5282,9 @@ __git_notes_refs () { declare -a notes_refs notes_refs=(${${(f)"$(_call_program notes-refs git for-each-ref --format='"%(refname)"' refs/notes 2>/dev/null)"}#$type refs/notes/}) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 - _wanted notes-refs expl "notes ref" compadd $* - $notes_refs + _wanted notes-refs expl 'notes ref' compadd $* - $notes_refs } # File Argument Types @@ -5159,7 +5294,7 @@ __git_files_relative () { local files file f_parts prefix p_parts tmp prefix=$(_call_program gitprefix git rev-parse --show-prefix 2>/dev/null) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 if (( $#prefix == 0 )); then print $1 @@ -5196,10 +5331,10 @@ __git_files () { tag=$1 description=$2; shift 2 gitcdup=$(_call_program gitcdup git rev-parse --show-cdup 2>/dev/null) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 gitprefix=$(_call_program gitprefix git rev-parse --show-prefix 2>/dev/null) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 # TODO: --directory should probably be added to $opts when --others is given. @@ -5207,6 +5342,7 @@ __git_files () { files=(${(0)"$(_call_program files git ls-files -z --exclude-standard $opts -- ${pref:+$pref\*} 2>/dev/null)"}) __git_command_successful $pipestatus || return +# _wanted $tag expl $description _files -g '{'${(j:,:)files}'}' $compadd_opts - _wanted $tag expl $description _multi_parts -f $compadd_opts - / files } @@ -5255,9 +5391,9 @@ __git_changed-in-index_files () { local files expl files=$(_call_program files git diff-index -z --name-only --no-color --cached HEAD 2>/dev/null) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 files=(${(0)"$(__git_files_relative $files)"}) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 _wanted changed-in-index-files expl 'changed in index file' _multi_parts $@ - / files } @@ -5267,9 +5403,9 @@ __git_changed-in-working-tree_files () { local files expl files=$(_call_program changed-in-working-tree-files git diff -z --name-only --no-color 2>/dev/null) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 files=(${(0)"$(__git_files_relative $files)"}) - __git_command_successful $pipestatus || return + __git_command_successful $pipestatus || return 1 _wanted changed-in-working-tree-files expl 'changed in working tree file' _multi_parts $@ -f - / files } @@ -5309,7 +5445,7 @@ __git_tree_files () { # Repository Argument Types # _remote_files -_remote_files () { +_remote_files_git () { # FIXME: these should be imported from _ssh # TODO: this should take -/ to only get directories # There should be coloring based on all the different ls -F classifiers. @@ -5348,7 +5484,7 @@ __git_remote_repositories () { service= _ssh if compset -P '*:'; then - _remote_files + _remote_files_git else _ssh_hosts -S: fi @@ -5410,7 +5546,7 @@ __git_guard_branch-name () { __git_guard_diff-stat-width () { if [[ $PREFIX == *,* ]]; then compset -P '*,' - __git_guard_number "filename width" + __git_guard_number 'filename width' else compset -S ',*' __git_guard_number width @@ -5423,7 +5559,7 @@ __git_guard_number () { zparseopts -K -D -A opts M: J: V: 1 2 n F: X: - _guard "[[:digit:]]#" ${1:-number} + _guard '[[:digit:]]#' ${1:-number} } (( $+functions[__git_guard_bytes] )) || @@ -5434,17 +5570,17 @@ __git_guard_bytes () { (( $+functions[__git_datetimes] )) || __git_datetimes () { # TODO: Use this in more places. - _guard "*" 'time specification' + _guard '*' 'time specification' } (( $+functions[__git_stages] )) || __git_stages () { - __git_guard $* "[[:digit:]]#" 'stage' + __git_guard $* '[[:digit:]]#' 'stage' } (( $+functions[__git_svn_revision_numbers] )) || __git_svn_revision_numbers () { - __git_guard_number "revision number" + __git_guard_number 'revision number' } # _arguments Helpers @@ -5960,16 +6096,6 @@ __git_color_attributes () { _describe -t attributes attribute attributes $* } -(( $+functions[_gitk] )) || -_gitk () { - _git-log -} - -(( $+functions[_tig] )) || -_tig () { - _git-log -} - # Now, for the main driver… _git() { if (( CURRENT > 2 )); then @@ -5979,7 +6105,7 @@ _git() { aliases=(${(f)${${${(f)"$(_call_program aliases git config --get-regexp '\^alias\.')"}#alias.}/ /$'\n'}/(#e)/$'\n'}) (( $#aliases % 2 == 0 )) && git_aliases=($aliases) - if [[ -n ${git_aliases[$words[2]]} ]] ; then + if (( $+git_aliases[$words[2]] && !$+commands[git-$words[2]] )); then local -a tmpwords expalias expalias=(${(z)git_aliases[$words[2]]}) tmpwords=(${words[1]} ${expalias}) @@ -5995,7 +6121,8 @@ _git() { unset git_aliases aliases fi - local ret=1 + integer ret=1 + if [[ $service == git ]]; then local curcontext=$curcontext state line declare -A opt_args @@ -6016,20 +6143,54 @@ _git() { '--no-replace-objects[do not use replacement refs to replace git objects]' \ '(-): :->command' \ '(-)*:: :->option-or-argument' && return + case $state in (command) - __git_aliases_and_commands && ret=0 + _git_commands && ret=0 ;; (option-or-argument) curcontext=${curcontext%:*:*}:git-$words[1]: - _call_function ret _git-$words[1] + if (( $+functions[_git-$words[1]] )); then + _call_function ret _git-$words[1] + elif zstyle -T :completion:$curcontext: use-fallback; then + _files && ret=0 + else + _message 'unknown sub-command' + fi ;; esac else _call_function ret _$service fi + return ret } +# Load any _git-* definitions so that they may be completed as commands. +declare -gUa _git_third_party_commands +_git_third_party_commands=() + +local file +for file in ${^fpath}/_git-*~(*~|*.zwc)(.N); do + local name=${${file:t}#_git-} + if (( $+_git_third_party_commands[$name] )); then + continue + fi + + local desc= + integer i=1 + while read input; do + if (( i == 2 )); then + if [[ $input == '#description '* ]]; then + desc=:${input#\#description } + fi + break + fi + (( i++ )) + done < $file + + _git_third_party_commands+=$name$desc +done + _git diff --git a/Completion/Unix/Command/_iconv b/Completion/Unix/Command/_iconv index 2cd69b21a..75fe521ee 100644 --- a/Completion/Unix/Command/_iconv +++ b/Completion/Unix/Command/_iconv @@ -21,7 +21,7 @@ if _pick_variant gnu=GNU unix --version; then '1:input file:_files' && return 0 if [[ $state = codeset ]]; then - if compset -P '*/'; then + if compset -P '*[^/]/'; then _wanted option expl option compadd "$@" /TRANSLIT && ret=0 else _wanted codesets expl 'code set' compadd "$@" \ diff --git a/Completion/Unix/Command/_initctl b/Completion/Unix/Command/_initctl index 11bd59b50..6505e4298 100644 --- a/Completion/Unix/Command/_initctl +++ b/Completion/Unix/Command/_initctl @@ -37,7 +37,7 @@ _initctl_fillarray_events_args () # list all upstart jobs, i.e. all files in /etc/init/ _initctl_helper_jobs() { - _path_files -W "/etc/init/" -g "*.conf(.:r)" + _path_files -W "/etc/init/" -g "*.conf(-.:r)" } # list events, generate array if necessary diff --git a/Completion/Unix/Command/_ln b/Completion/Unix/Command/_ln new file mode 100644 index 000000000..89b7177ab --- /dev/null +++ b/Completion/Unix/Command/_ln @@ -0,0 +1,76 @@ +#compdef ln gln + +local curcontext="$curcontext" state line ret=1 +local -A opt_args + +local -a args +args=( + '-f[remove existing destination files]' + '-s[create symbolic links instead of hard links]') + +local -a opts + +local variant +_pick_variant -r variant gnu=gnu unix --help +if [[ $variant == gnu ]]; then + opts=(-S) + args=( + '(-b --backup)-b[create a backup of each existing destination file]' \ + '(-b --backup)--backup=[create a backup of each existing destination file]::method:(( + none\:"never create backups" + off\:"never create backups" + numbered\:"create numbered backup" + t\:"create numbered backup" + existing\:"same as numbered if numbered backups exist, otherwise same as simple" + nil\:"same as numbered if numbered backups exist, otherwise same as simple" + simple\:"always create simple backups" + never\:"always create simple backups"))' + '(-d -F --directory)'{-d,-F,--directory}'[allow the superuser to attempt to hard link directories]' + '(-f --force)'{-f,--force}'[remove existing destination files]' + '(-i --interactive)'{-i,--interactive}'[prompt before removing destination files]' + '(-L --logical)'{-L,--logical}'[create hard links to symbolic link references]' + '(-n --no-dereference)'{-n,--no-dereference}'[treat destination symbolic link to a directory as if it were a normal file]' + '(-P --physical)'{-P,--physical}'[create hard links directly to symbolic links]' + '(-s --symbolic)'{-s,--symbolic}'[create symbolic links instead of hard links]' + '(-S --suffix)'{-S,--suffix=}'[override default backup suffix]:suffix' + '(-t --target-directory)'{-t,--target-directory=}'[specify directory in which to create the links]: :_directories' + '(-T --no-target-directory)'{-T,--no-target-directory}'[treat destination as a normal file]' + '(-v --verbose)'{-v,--verbose}'[print name of each linked file]' + '--help[display usage information and exit]' + '--version[display version information and exit]') +elif (( ${+builtins[ln]} )); then + args+=( + '-d[attempt to hard link directories]' + {-h,-n}'[do not dereference destination]' + '-i[prompt before removing destination files]') +elif [[ $OSTYPE == darwin* ]]; then + args+=( + '-F[remove existing destination directories]' + {-h,-n}'[do not dereference destination]' + '-i[prompt before removing destination files]' + '-v[print name of each linked file]') +fi + +_arguments -s $opts \ + $args \ + ':link target:_files' \ + '*:: :->files' && ret=0 + +case $state in + (files) + if [[ $variant == gnu && -n ${opt_args[(I)-t|--target-directory]} ]]; then + _wanted files expl 'link target' _files && ret=0 + else + if (( CURRENT == 2 )); then + local expl + _wanted files expl 'additional link target or link name' _files && ret=0 + else + _alternative \ + 'link-targets:additional link target:_files' \ + 'target-directories:target directory:_directories' && ret=0 + fi + fi + ;; +esac + +return ret diff --git a/Completion/Unix/Command/_lp b/Completion/Unix/Command/_lp index 5d46a75bb..e0654e711 100644 --- a/Completion/Unix/Command/_lp +++ b/Completion/Unix/Command/_lp @@ -1,9 +1,9 @@ -#compdef lp lpr lpq lprm lpoptions lpstat +#compdef lp lpr lpq lprm lpoptions lpstat lpinfo lpadmin _lp_get_printer() { - # No reason to call _lp_get_printer when service == lpstat. Others matched - # below. + # No reason to call _lp_get_printer when service == lpstat or lpinfo. Others + # matched below. case $service in (lpr|lpq|lprm) [[ "$words" == (#I)*-P* ]] && printer="${${words##*(#I)-P( |)}%% *}" @@ -11,6 +11,9 @@ _lp_get_printer() (lp) [[ "$words" == (#I)*-d* ]] && printer="${${words##*(#I)-d( |)}%% *}" ;; + (lpadmin) + [[ "$words" == (#I)*-p* ]] && printer="${${words##*(#I)-p( |)}%% *}" + ;; (lpoptions) [[ "$words" == (#I)*-(d|p)* ]] && \ printer="${${words##*(#I)-(d|p)( |)}%% *}" @@ -29,6 +32,13 @@ _lp_job_options() lopts_no_args=(fitplot landscape) + if [[ $service == 'lpadmin' ]]; then + # Extra options from lpadmin man page. + lopts_with_args+=(cupsIPPSupplies cupsSNMPSupplies job-k-limit + job-page-limit job-quota-period job-sheets-default name name-default + port-monitor printer-error-policy printer-is-shared printer-op-policy) + fi + _lp_get_printer [[ -n "$printer" ]] && printer=(-p $printer) @@ -53,6 +63,12 @@ _lp_job_options() (scaling|cpi|lpi|page-(bottom|left|right|top)) return 0; # Don't complete anything ;; + (cupsIPPSupplies|cupsSNMPSupplies|printer-is-shared) + compadd "$@" true false + ;; + (printer-error-policy) + compadd "$@" abort-job retry-job retry-current-job stop-printer + ;; (*) compadd "$@" \ $(_call_program list-printer-options lpoptions $printer -l | \ @@ -136,9 +152,9 @@ _lp() '-E[Force encryption]' \ '-U:username (for connection to server):_users' \ '-h:alternate server:_hosts' \ - '(-a)-P+[destination printer]:printers:_printers' \ - '(-P)-a[all printers]' \ - '-l[long listing]' \ + '(-a)-P+[Destination printer]:printers:_printers' \ + '(-P)-a[All printers]' \ + '-l[Long listing]' \ '*:poll interval (+seconds):' ;; @@ -147,7 +163,7 @@ _lp() '-E[Force encryption]' \ '-U:username (for connection to server):_users' \ '-h:alternate server:_hosts' \ - '-P+[destination printer]:printers:_printers' \ + '-P+[Destination printer]:printers:_printers' \ '*:job ids:_lp_list_jobs' ;; @@ -156,12 +172,12 @@ _lp() '-E[Force encryption]' \ '-U:username (for connection to server):_users' \ '-h:alternate server:_hosts' \ - '(-p -l -r -x)-d[set default printer]:printers:_printers' \ + '(-p -l -r -x)-d+[Set default printer]:printers:_printers' \ '(-l -x)*-o:job options:_lp_job_options' \ - '(-d -x)-p[destination printer for options]:printers:_printers' \ - '(-d -o -r -x)-l[list options]' \ + '(-d -x)-p+[Destination printer for options]:printers:_printers' \ + '(-d -o -r -x)-l[List options]' \ '(-d -l -x)*-r:remove option:_lp_job_options' \ - '(-d -l -r -o)-x[remove all options]:printers:_printers' + '(-d -l -r -o)-x+[Remove all options]:printers:_printers' ;; (lpstat) @@ -170,18 +186,18 @@ _lp() '-R[Shows print job ranking]' \ '-U:username (for connection to server):_users' \ '-W:which jobs:(completed not-completed)' \ - '-a[Show accepting state]:printers:_printers' \ + '-a+[Show accepting state]:printers:_printers' \ '-c:printer classes:' \ '-d[Show current default destination]' \ '-h:hostname (alternate server):_hosts' \ - '-l[long listing]' \ - '-o[destinations]:printers:_printers' \ - '-p:printers:_printers' \ + '-l[Long listing]' \ + '-o+[Destinations]:printers:_printers' \ + '-p+:printers:_printers' \ '-r[CUPS server running status]' \ '-s[Status summary]' \ '-t[All status info]' \ - '-u[list jobs by users]:users:_users' \ - '-v[show devices]:printers:_printers' + '-u[List jobs by users]:users:_users' \ + '-v+[Show devices]:printers:_printers' ;; (lpr) @@ -189,38 +205,73 @@ _lp() '-E[Force encryption]' \ '-H:hostname (alternate server):_hosts' \ '(-C -J -T)'-{C,J,T}':job name:' \ - '-P+[destination printer]:printers:_printers' \ + '-P+[Destination printer]:printers:_printers' \ '-U:username (for connection to server):_users' \ '-#[Copies]:copies (1--100):' \ '-h[Disables banner printing]' \ - '-l[raw file]' \ + '-l[Raw file]' \ '-m[Send an email on job completion]' \ '*-o:print job options:_lp_job_options' \ - '-p[format with shaded header incl. date, time etc.]' \ + '-p[Format with shaded header incl. date, time etc.]' \ '-q[Hold job for printing.]' \ - '-r[delete files after printing]' \ + '-r[Delete files after printing]' \ '*:PS/PDF files:_pspdf' ;; (lp) _arguments \ '-E[Force encryption]' \ - '-U[username (for connection to server)]:username:_users' \ + '-U[Username (for connection to server)]:username:_users' \ '-c[(OBSOLETE) copy to spool dir before printing]' \ - '-d[destination printer]:printers:_printers' \ + '-d+[Destination printer]:printers:_printers' \ '-h:hostname (alternate server):_hosts' \ - '-i[job id to modify]:job id:' \ + '-i[Job id to modify]:job id:' \ '-m[Send an email on job completion]' \ '-n[Copies]:copies (1--100):' \ '*-o:print job options:_lp_job_options' \ '-q[Job priority -- 1 (lowest) to 100 (highest)]:priority:' \ '-s[Dont report resulting job IDs]' \ '-t[Sets the job name]:job name:' \ - '-u[job submission username]:username:_users' \ + '-u[Job submission username]:username:_users' \ '-H[Time to print]:print time (or enter hh\:mm):(hold immediate restart resume)' \ '-P:page range list:' \ '*:PS/PDF files:_pspdf' ;; + + (lpinfo) + _arguments \ + '-E[Force encryption]' \ + '-U[Username (for connection to server)]:username:_users' \ + '-h:hostname (alternate server):_hosts' \ + '-l[Shows a "long" listing of devices or drivers]' \ + {--exclude-schemes,--include-schemes}'[Device/PPD schemes to filter from results]:scheme-list:' \ + '(-v --timeout)--device-id[IEEE-1284 device ID to match]:device-id-string:' \ + '(-v --timeout)--language:locale:' \ + '(-v --timeout)--product[Product to match]:name:' \ + '(-v --timeout)--make-and-model[Make and model to match]:name:' \ + '(-v --timeout)-m[List available drivers]' \ + '(-m --device-id --language --make-and-model --product)--timeout[Timeout when listing devices with -v]:timeout (seconds):' \ + '(-m --device-id --language --make-and-model --product)-v[List available devices]' + ;; + + (lpadmin) + _arguments \ + '-E[Force encryption/Enable destination]' \ + '-U[Username (for connection to server)]:username:_users' \ + '-h:hostname (alternate server):_hosts' \ + '(-p -R -x -o)-d+[Default printer]:printers:_printers' \ + '(-d -x)-p+[Configure printer]:printers:_printers' \ + '(-p -R -d -o)-x+[Delete printer]:printers:_printers' \ + '(-x -d)-R[Name-default]:name-default:' \ + '-c:printer classes:' \ + '-m:model:' \ + '(-x -d)*-o:options:_lp_job_options' \ + '-r[Remove from class]:class:' \ + '-u[Access policy]:access policy:' \ + '-v[Device-uri of printer queue]:device-uri:' \ + '-D[Text description of destination]:info:' \ + '-L[Location of the printer]:location:' \ + '-P[PPD file to use]:PPD file:_files "*.(#i)ppd(-.)"' esac } diff --git a/Completion/Unix/Command/_nm b/Completion/Unix/Command/_nm new file mode 100644 index 000000000..276a38f19 --- /dev/null +++ b/Completion/Unix/Command/_nm @@ -0,0 +1,29 @@ +#compdef nm + +# This is a stub. It's main reason for existence is to offer +# object files with nm. Feel free to extend it. If you do, remove +# this comment. + +local state context line expl +local -A opt_args +local -a args +integer ret=1 + +if _pick_variant gnu='Free Soft' unix --version; then + args+=(-s --) +fi +args+=('*:file:->file') + +_arguments "$args[@]" && ret=0 + +case $state in + (file) + _alternative \ + "object-files:object file:_path_files -g '*.o'" \ + "executable-files:executable file:_path_files -g '*(*)'" \ + "dynamic-libraries:dynamic library:_path_files -g '*.so'" \ + "static-libraries:static library:_path_files -g '*.a'" && ret=0 + ;; +esac + +return ret diff --git a/Completion/Unix/Command/_perforce b/Completion/Unix/Command/_perforce index 08c42cbce..2c1365a79 100644 --- a/Completion/Unix/Command/_perforce +++ b/Completion/Unix/Command/_perforce @@ -3,7 +3,7 @@ # Maintainer: Peter Stephenson <pws@csr.com>. # Increasingly loosely based on _cvs version 1.17. -# Completions currently based on Perforce release 2006.2. +# Completions currently based on Perforce release 2010.2. # Styles, tags and contexts # ========================= @@ -603,7 +603,7 @@ _perforce_global_options() { _perforce_branches() { local bline match mbegin mend local -a bl - bl=(${${${(f)"$(_perforce_call_p4 branches branches 2>/dev/null)"}##Branch }/ /:}) + bl=(${${${${(f)"$(_perforce_call_p4 branches branches 2>/dev/null)"}##Branch }//:/\\:}/ /:}) [[ $#bl -eq 1 && $bl[1] = '' ]] && bl=() (( $#bl )) && _describe -t branches 'Perforce branch' bl } @@ -685,7 +685,7 @@ awk '/^Client:/ { print $2 }')") # Limit to the 20 most recent changes by default to avoid huge # output. cl=( -${${${${(f)"$(_perforce_call_p4 changes changes $amax $xargs $cstatus \$file)"}##Change\ }//\ on\ /:}/\ by\ /\ } +${${${${${(f)"$(_perforce_call_p4 changes changes $amax $xargs $cstatus \$file)"}##Change\ }//:/\\:}//\ on\ /:}/\ by\ /\ } ) # "default" can't have shelved files in it... [[ $ctype = shelved* ]] || cl+=("default:change not yet numbered") @@ -711,7 +711,7 @@ _perforce_clients() { compset -P '//' && slash=(-S/ -q) fi - cl=(${${${(f)"$(_perforce_call_p4 clients clients)"}##Client\ }/\ /:}) + cl=(${${${${(f)"$(_perforce_call_p4 clients clients)"}##Client\ }//:/\\:}/\ /:}) [[ $#cl -eq 1 && $cl[1] = '' ]] && cl=() _describe -t clients 'Perforce client' cl $slash } @@ -722,7 +722,7 @@ _perforce_counters() { local cline match mbegin mend local -a cl - cl=(${${${(f)"$(_perforce_call_p4 counters counters)"}/\ /:}/\=/current value}) + cl=(${${${${(f)"$(_perforce_call_p4 counters counters)"}//:/\\:}/\ /:}/\=/current value}) [[ $#cl -eq 1 && $cl[1] = '' ]] && cl=() _describe -t counters 'Perforce counter' cl } @@ -796,7 +796,7 @@ _perforce_depots() { local dline match mbegin mend local -a dl - dl=(${${${(f)"$(_perforce_call_p4 depots depots)"}##Depot\ }/\ /:}) + dl=(${${${${(f)"$(_perforce_call_p4 depots depots)"}##Depot\ }//:/\\:}/\ /:}) [[ $#dl -eq 1 && $dl[1] = '' ]] && dl=() _describe -t depots 'depot name' dl } @@ -1594,7 +1594,7 @@ _perforce_submit_options() { _perforce_pids() { local -a ul - ul=(${${${(f)"$(_perforce_call_p4 monitor monitor show 2>/dev/null)"}# *}/\ /:}) + ul=(${${${${(f)"$(_perforce_call_p4 monitor monitor show 2>/dev/null)"}# *}//:/\\:}/\ /:}) [[ $#ul -eq 1 && $ul[1] = '' ]] && ul=() _describe -t id 'process ID' ul } @@ -1604,7 +1604,7 @@ _perforce_pids() { _perforce_users() { local -a ul - ul=(${${(f)"$(_perforce_call_p4 users users)"}/\ /:}) + ul=(${${${(f)"$(_perforce_call_p4 users users)"}//:/\\:}/\ /:}) [[ $#ul -eq 1 && $ul[1] = '' ]] && ul=() _describe -t users 'Perforce user' ul } @@ -1686,6 +1686,7 @@ _perforce_cmd_annotate() { '-a[all, show both added and deleted lines]' \ '-c[output change numbers instead of revisions]' \ '-i[follow branches (integration records)]' \ + '-I[follow integrations to get change numbers]' \ '-q[quiet, suppress one-line file header]' \ '*::file:_perforce_files -tR' } @@ -1748,7 +1749,8 @@ _perforce_cmd_change() { '(-d -i -f)-o[output specification to standard output]' \ '(-d -o)-i[read specification from standard input]' \ '(-d -o)-u[force change of jobs or description by owner]' \ - "(-i)1::change:_perforce_changes$ctype" + "(-i)1::change:_perforce_changes$ctype" \ + '-t[specify visibility type]:visibility type:(public restricted)' } @@ -1800,6 +1802,22 @@ _perforce_cmd_clients() { } +(( $+functions[_perforce_cmd_copy] )) || +_perforce_cmd_copy() { + local range + # If -s is present, the first normal argument can't have revRange. + [[ ${words[(I)-s]} -eq 0 ]] && range=" -tR" + _arguments -s : \ + '-b[select branch]:branch:_perforce_branches' \ + '-c[select change for copy]:change:_perforce_changes -tc' \ + '-n[no action, dummy run]' \ + '-r[reverse direction of copy with branch]' \ + '-s[select source with -b]:source file:_perforce_files -tR' \ + '-v[leave newly copied files uncopied till sync]' \ + "1:file:_perforce_files$range" \ + '*::file:_perforce_files' +} + (( $+functions[_perforce_cmd_counter] )) || _perforce_cmd_counter() { _arguments -s : \ @@ -1942,7 +1960,8 @@ _perforce_cmd_export() { '(-j)-l[specify number of lines]:number of lines: ' \ '(-j)-F[specify filter]:filter pattern: ' \ '(-c)-r[raw format]' \ - '-J[specify file prefix]:file prefix: ' + '-J[specify file prefix]:file prefix: ' \ + '-T[space-separated list of tables not to export]' } @@ -2117,8 +2136,8 @@ _perforce_cmd_help() { (( $+functions[_perforce_cmd_info] )) || _perforce_cmd_info() { - # No arguments - _arguments -s : + _arguments -s : \ + '-s[don'\''t check for unknown users or clients]' } @@ -2257,6 +2276,7 @@ _perforce_cmd_labelsync() { '-d[delete files from label]' \ '-n[no effect, dummy run]' \ '-l[specify label]:label:_perforce_labels' \ + '-q[suppress informational messages]' \ '*::file:_perforce_files -tR' } @@ -2407,6 +2427,19 @@ _perforce_cmd_passwd() { } +(( $+functions[_perforce_cmd_ping] )) || +_perforce_cmd_ping() { + _arguments -s : \ + '-c[specify count of messages]:count of messages: ' \ + '-t[specify total time of test]:time in seconds: ' \ + '-i[specify iterations for test]:number of iterations: ' \ + '-f[transmit continuously without waiting for responses]' \ + '-p[specify pause between tests]:pause in seconds: ' \ + '-s[specify send size]:send size in octets: ' \ + '-r[specify receive size]:receive size in octets: ' +} + + (( $+functions[_perforce_cmd_print] )) || _perforce_cmd_print() { _arguments -s : \ @@ -2437,6 +2470,15 @@ _perforce_cmd_protects() { } +(( $+functions[_perforce_cmd_pull] )) || +_perforce_cmd_pull() { + _arguments -s : \ + '-i[repeat as specified]:seconds between repeats: ' \ + '-u[retrieve file content rather than journal]' \ + '-p[display information about pending transfers]' \ + '-J[specify prefix for journal file]:journal file prefix: ' +} + (( $+functions[_perforce_cmd_reopen] )) || _perforce_cmd_reopen() { # Assume user doesn't want to reopen to same changelist. @@ -2462,7 +2504,9 @@ _perforce_cmd_replicate() { '-J[specify file prefix]:file prefix: ' \ '-k[keep pipe open]' \ '-o[specify output file]:output file:_files' \ + '-R[reconnect on failure, needs -i]' \ '-s[specify file to track state]:state file:_files' \ + '-T[space-separate list of tables not to transfer]' \ '-x[terminate when journal rotates]' \ '*::->_command' } @@ -2580,6 +2624,7 @@ _perforce_cmd_sync() { '-f[force resynchronisation]' \ '-n[show operations but don'\''t perform them]' \ '-k[bypass client file update]' \ + '-q[suppress informational messages]' \ '*::file:_perforce_files -tR' } diff --git a/Completion/Unix/Command/_perl b/Completion/Unix/Command/_perl index 20d9f2d83..b00baa6ed 100644 --- a/Completion/Unix/Command/_perl +++ b/Completion/Unix/Command/_perl @@ -3,17 +3,23 @@ # zsh completion code for the Perl interpreter # Adam Spiers <adam@spiers.net> # +# Completions currently based on Perl 5.14.1. _perl () { _arguments -s \ - '-0-:input record separator in octal (\0, if no argument): ' \ + '-0-[input record separator ($/)]:$/ in octal or hex (\0, if no argument)' \ '-a[autosplit mode with -n or -p (splits $_ into @F)]' \ + '-C-[control some unicode features]: :_perl_unicode_flags' \ "-c[check syntax only (runs BEGIN and END blocks)]" \ - '-d[run scripts under debugger]' \ - '-d\:-[run under control of a debugging/tracing module]:debugging/tracing module:_perl_modules --strip-prefix --perl-hierarchy=Devel' \ - '-D-:set debugging flags (argument is a bit mask or flags): ' \ - "*-e+:one line of script. Several -e's allowed. Omit [programfile]." \ - "-F-:split() pattern for autosplit (-a). The //'s are optional.: " \ + '( -dt -d: -dt:)-d[run scripts under debugger]' \ + '(-d -d: -dt:)-dt[run scripts under debugger (debugged code uses threads)]' \ + '(-d -dt -dt:)-d\:-[run under control of a debugging/tracing module]:debugging/tracing module:_perl_modules --strip-prefix --perl-hierarchy=Devel' \ + '(-d -dt -d: )-dt\:-[run under control of a debugging/tracing module (debugged coded uses threads)]:debugging/tracing module:_perl_modules --strip-prefix --perl-hierarchy=Devel' \ + '-D-[set debugging flags]: :_perl_debugging_flags' \ + '( -E)*-e+[run one line of program]:one line of program' \ + '(-e )*-E+[like -e but enable all optional features]:one line of program: ' \ + '-f[disable executing $Config{sitelib}/sitecustomize.pl at startup]' \ + '-F-[split() pattern for autosplit (-a)]:split() pattern, // is optional' \ '-h[list help summary]' \ '-i-[edit <> files in place (make backup if extension supplied)]:backup file extension: ' \ '*-I-[specify @INC/#include directory (may be used more than once)]:include path:_files -/' \ @@ -21,18 +27,21 @@ _perl () { \*{-m,-M}"-[module.. executes \`use/no module...' before executing your script]:module:_perl_m_opt" \ "-n[assume 'while (<>) { ... }' loop around your script]" \ "-p[assume loop like -n but print line also like sed]" \ - "-P[run script through C preprocessor before compilation]" \ + '-P[run script through C preprocessor before compilation (deprecated)]' \ "-s[enable some switch parsing for switches after script name]" \ "-S[look for the script using PATH environment variable]" \ - "-T[turn on tainted checks]" \ + '( -T)-t[turn on taint checks but only issue warnings]' \ + '(-t )-T[turn on taint checks]' \ "-u[dump core after parsing script]" \ "-U[allow unsafe operations]" \ "-v[print version number, patchlevel plus VERY IMPORTANT perl info]" \ "-V-[print perl configuration information]:configuration keys:_perl_config_vars" \ - '-w[turn warnings on for compilation of your script. Recommended]' \ + '( -W -X)-w[turn warnings on for compilation of your script (recommended)]' \ + "(-w -X)-W[enable all warnings (ignores 'no warnings')]" \ + "(-w -W )-X[disable all warnings (ignores 'use warnings')]" \ '-x-[strip off text before #!perl line and perhaps cd to directory]:directory to cd to:_files -/' \ '1:Perl script:_files -/ -g "*.(p[ml]|PL|t)(-.)"' \ - '*::args: _normal' + '*::args: _normal' } _perl_m_opt () { @@ -60,4 +69,46 @@ _perl_config_vars () { compadd "$expl[@]" $add_colon -S$delimiter -q -a _perl_config_vars } +_perl_unicode_flags () { + _values -s '' 'unicode bitmask or flags' \ + 'I[ 1 STDIN is assumed to be in UTF-8]' \ + 'O[ 2 STDOUT will be in UTF-8]' \ + 'E[ 4 STDERR will be in UTF-8]' \ + 'S[ 7 I + O + E]' \ + 'i[ 8 UTF-8 is the default PerlIO layer for input streams]' \ + 'o[ 16 UTF-8 is the default PerlIO layer for output streams]' \ + 'D[ 24 i + o]' \ + 'A[ 32 the @ARGV elements are expected to be strings encoded in UTF-8]' \ + 'L[ 64 make "IOEioA" conditional on the locale environment variables]' \ + 'a[256 set ${^UTF8CACHE} to -1, used for debugging]' \ +} + +_perl_debugging_flags () { + _values -s '' 'debugging bitmask or flags' \ + 'p[ 1 Tokenizing and parsing (with v, displays parse stack)]' \ + 's[ 2 Stack snapshots (with v, displays all stacks)]' \ + 'l[ 4 Context (loop) stack processing]' \ + 't[ 8 Trace execution]' \ + 'o[ 16 Method and overloading resolution]' \ + 'c[ 32 String/numeric conversions]' \ + 'P[ 64 Print profiling info, preprocessor command for -P, source file input state]' \ + 'm[ 128 Memory and SV allocation]' \ + 'f[ 256 Format processing]' \ + 'r[ 512 Regular expression parsing and execution]' \ + 'x[ 1024 Syntax tree dump]' \ + 'u[ 2048 Tainting checks]' \ + 'U[ 4096 Unofficial, User hacking (reserved for private, unreleased use)]' \ + 'H[ 8192 Hash dump -- usurps values()]' \ + 'X[ 16384 Scratchpad allocation]' \ + 'D[ 32768 Cleaning up]' \ + 'S[ 66536 Thread synchronization]' \ + 'T[ 131072 Tokenising]' \ + 'R[ 262144 Include reference counts of dumped variables (eg when using -Ds)]' \ + 'J[ 524288 Do not s,t,P-debug (Jump over) opcodes within package DB]' \ + 'v[1048576 Verbose: use in conjunction with other flags]' \ + 'C[2097152 Copy On Write]' \ + 'A[4194304 Consistency checks on internal structures]' \ + 'q[8388608 quiet - currently only suppresses the "EXECUTING" message]' \ +} + _perl "$@" diff --git a/Completion/Unix/Command/_pgrep b/Completion/Unix/Command/_pgrep index f65324a81..e460202a1 100644 --- a/Completion/Unix/Command/_pgrep +++ b/Completion/Unix/Command/_pgrep @@ -1,112 +1,89 @@ #compdef pgrep pkill -local context state line +local context state line ret=1 expl typeset -A opt_args typeset -a arguments arguments=('-P[parent process id]:parent process id:->ppid' - '-g[match only in process group ids]:group:->pgid' - '-G[match only real group id]:group:->group' - '-s[match only session id]:session id:->sid' - '-t[match only controlled by terminal]:terminal device:->tty' - '-u[match only effective user id]:user:->user' - '-U[match only real user id]:user:->user' + '-g[match only in process group ids]:group:->pgid' + '-G[match only real group id]:group:_groups' + '-s[match only session id]:session id:->sid' + '-t[match only controlled by terminal]:terminal device:->tty' + '-u[match only effective user id]:user:_users' + '-U[match only real user id]:user:_users' '(-n)-o[oldest process]' - '(-o)-n[newest process]' - '-f[match against full command line]' - '-v[negate matching]' - '-x[match exactly]' - '*:process name:->pname') + '(-o)-n[newest process]' + '-f[match against full command line]' + '-v[negate matching]' + '-x[match exactly]' + '*:process name:->pname') if [[ $service == 'pkill' ]] then - arguments+=('-'${^signals}'[signal]') + arguments+=('-'${^signals}'[signal]') elif [[ $service == 'pgrep' ]] then - arguments+=('-d[output delimiter]:delimiter:compadd ${(s\:\:)IFS}' - '-l[list name in addition to id]') + arguments+=('-d[output delimiter]:delimiter:compadd ${(s\:\:)IFS}' + '-l[list name in addition to id]') fi -_arguments -s -w $arguments +_arguments -s -w $arguments && ret=0 case $state in - (tty) - compset -P '*,' - - local -a used - used=(${(s:,:)IPREFIX}) - - compadd -S ',' -q -F used /dev/tty*(:t) - ;; - - (sid) - compset -P '*,' - - local -a used sid - used=(${(s:,:)IPREFIX}) - sid=(${(uon)$(ps -A o sid=)}) - - compadd -S ',' -q -F used $sid - ;; - - (ppid) - compset -P '*,' - - local -a used ppid - used=(${(s:,:)IPREFIX}) - ppid=(${(uon)$(ps -A o ppid=)}) - - compadd -S ',' -q -F used $ppid - ;; - - (pgid) - compset -P '*,' - - local -a used pgid - used=(${(s:,:)IPREFIX}) - pgid=(${(uon)$(ps -A o pgid=)}) - - compadd -S ',' -q -F used $pgid - ;; - - (pname) - if (( ${+opt_args[-x]} )) && (( ${+opt_args[-f]} )) - then - compadd ${(u)${(f)"$(ps -A o cmd=)"}} - else - compadd ${(u)${(f)"$(ps -A co cmd=)"}} - fi - ;; - - (group) - compset -P '*,' - - local group - group=$(getent group) - - local -a groups ids - groups=(${${(f)group}%%:*}) - ids=(${${${(f)group}#*:*:}%%:*}) - - local -a used - used=(${(s:,:)IPREFIX}) - - compadd -S ',' -q -F used -d ids $groups $groups - ;; - - (user) - compset -P '*,' - - local passwd - passwd=$(getent passwd) - - local -a users ids - users=(${${(f)passwd}%%:*}) - ids=(${${${(f)passwd}#*:*:}%%:*}) - - local -a used - used=(${(s:,:)IPREFIX}) - - compadd -S ',' -q -F used -d ids $users $users - ;; -esac + (tty) + compset -P '*,' + + local -a used ttys + used=(${(s:,:)IPREFIX}) + + ttys=( /dev/tty*(N) /dev/pts/*(N) ) + _wanted tty expl 'terminal device' compadd -S ',' -q -F used ${ttys#/dev/} + ;; + + (sid) + compset -P '*,' + + local -a used sid + used=(${(s:,:)IPREFIX}) + sid=(${(uon)$(ps -A o sid=)}) + + _wanted sid expl 'session id' compadd -S ',' -q -F used $sid + ;; + + (ppid) + compset -P '*,' + + local -a used ppid + used=(${(s:,:)IPREFIX}) + ppid=(${(uon)$(ps -A o ppid=)}) + + _wanted ppid expl 'parent process id' compadd -S ',' -q -F used $ppid + ;; + + (pgid) + compset -P '*,' + + local -a used pgid + used=(${(s:,:)IPREFIX}) + pgid=(${(uon)$(ps -A o pgid=)}) + + _wanted pgid expl 'process group id' compadd -S ',' -q -F used $pgid + ;; + + (pname) + local ispat="pattern matching " + if (( ${+opt_args[-x]} )) + then + ispat="" + fi + if (( ${+opt_args[-f]} )) + then + _wanted pname expl $ispat'process command line' compadd ${(u)${(f)"$(ps -A o cmd=)"}} + else + _wanted pname expl $ispat'process name' compadd ${(u)${(f)"$(ps -A co cmd=)"}} + fi + ;; + +esac && ret=0 + +return ret diff --git a/Completion/Unix/Command/_quilt b/Completion/Unix/Command/_quilt index a2fd799a6..130f38149 100644 --- a/Completion/Unix/Command/_quilt +++ b/Completion/Unix/Command/_quilt @@ -1,30 +1,241 @@ #compdef quilt +local -a tmp +local rc + +_quilt_applied () { + tmp=( ${(f)"$(quilt applied 2>&1)"} ) + rc=$? + if (( rc == 0 )); then + _wanted -V 'applied patches' expl 'patch' compadd "${tmp[@]}" + else + _message "No applied patches" + fi +} + +_quilt_series () { + _wanted -V 'patches' expl 'patch' compadd ${(f)"$(quilt series)"} +} + +_quilt_unapplied () { + tmp=( ${(f)"$(quilt unapplied 2>&1)"} ) + rc=$? + if (( rc == 0 )); then + _wanted -V 'unapplied patches' expl 'patch' compadd "${tmp[@]}" + else + _message "No unapplied patches" + fi +} + _arguments \ - '--trace' \ - '--quiltrc:config file:_files' \ - '--version' \ - ':quilt command:(add files import previous setup annotate fold mail push - snapshot applied fork new refresh top delete graph next remove unapplied - diff grep patches rename upgrade edit header pop series)' \ + '--trace[Runs the command in bash trace mode]' \ + '--quiltrc[Use the specified configuration file]:files:_files' \ + '--version[Print the version number and exit]' \ + ':quilt command:(add annotate applied delete diff edit files fold fork graph + grep header import mail new next patches pop previous push refresh rename + revert series setup shell snapshot top unapplied upgrade)' \ '*::subcmd:->subcmd' && return 0 -case "$state" in - (subcmd) - +case "$state" in (subcmd) case "$words[1]" in - (applied|delete|files|graph|header|next|previous|refresh|unapplied) - _wanted -V 'patches' expl 'patch' compadd ${(f)"$(quilt series)"} - ;; - (push) - _wanted -V 'unapplied patches' expl 'patch' compadd ${(f)"$(quilt unapplied)"} - ;; + (add) + _arguments '-h' \ + '-P[Patch to add files to]:quilt series:_quilt_series' \ + '*:files:_files' + ;; + (annotate) + _arguments '-h' \ + '-P[Stop checking for changes at the specified rather than the topmost patch]:quilt series:_quilt_series' \ + ':files:_files' + ;; + (applied) + _arguments '-h' \ + ':quilt series:_quilt_series' + ;; + (delete) + _arguments '-h' \ + '-n[Delete the next patch after topmost]' \ + '-r[Remove the deleted patch file from the patches directory as well]' \ + '--backup[Rename the patch file to patch~ rather than deleting it]' \ + ':quilt series:_quilt_series' + ;; + (diff) + _arguments '-h' \ + '-p[Select a patch style]:quilt patch style:(0 1 ab)' \ + '-u[Create a unified diff]' \ + '-U[Create a unified diff with num lines of context]:quilt unified diff: ' \ + '-c[Create a context diff]' \ + '-C[Create a context diff with num lines of context]:quilt context diff: ' \ + '--no-timestamps[Do not include file timestamps in patch headers]' \ + '--no-index[Do not output Index: lines]' \ + '-z[Write to standard output the changes that have been made relative to the topmost or specified patch]' \ + '-R[Create a reverse diff]' \ + '-P[Create a diff for the specified patch]:quilt series:_quilt_series' \ + '--combine[Create a combined diff for all patches between this patch and the patch specified with -P]:quilt series:_quilt_series' \ + '--snapshot[Diff against snapshot]' \ + '--diff=[Use the specified utility for generating the diff]:quilt select diff utility:_command_names -e' \ + '--color=[Use syntax coloring]:quilt select color:(always auto never)' \ + '--sort[Sort files by their name]' \ + '*:files:_files' + ;; + (edit) + _arguments '-h' \ + '*:files:_files' + ;; + (files) + _arguments '-h' \ + '-a[List all files in all applied patches]' \ + '-l[Add patch name to output]' \ + '-v[Verbose, more user friendly output]' \ + '--combine[Create a listing for all patches between this patch and the topmost or specified patch]:quilt series:_quilt_series' \ + ':quilt series:_quilt_series' + ;; + (fold) + _arguments '-h' \ + '-R[Apply patch in reverse]' \ + '-q[Quiet operation]' \ + '-f[Force apply]' \ + '-p[The number of pathname components to strip]:quilt select strip-level: ' + ;; + (fork) + _arguments '-h' + ;; + (graph) + _arguments '-h' \ + '--all[Generate a graph including all applied patches and their dependencies]' \ + '--reduce[Eliminate transitive edges from the graph]' \ + '--lines[Compute dependencies by looking at the lines the patches modify]:quilt select lines: ' \ + '--edge-labels=files[Label graph edges with the file names that the adjacent patches modify]' \ + '-T ps[Directly produce a PostScript output file]' \ + ':quilt series:_quilt_series' + ;; + (header) + _arguments '-h' \ + '-a[Append the exiting patch header]' \ + '-r[Replace the exiting patch header]' \ + '-e[Edit the header in $EDITOR]' \ + '--strip-diffstat[Strip diffstat output from the header]' \ + '--strip-trailing-whitespace[Strip trailing whitespace at the end of lines of the header]' \ + '--backup[Create a backup copy of the old version of a patch as patch~]' \ + ':quilt series:_quilt_series' + ;; + (import) + _arguments '-h' \ + '-p[Number of directory levels to strip when applying]:quilt select strip-level: ' \ + '-R[Apply patch in reverse]' \ + '-P[Patch filename to use inside quilt]:quilt select patch filename: ' \ + '-f[Overwrite/update existing patches]' \ + '-d[When overwriting in existing patch, keep the old (o), all (a), or new (n) patch header]:quilt select patch:(a n o)' \ + '*:files:_files' + ;; + (mail) + _arguments '-h' \ + '-m[Text to use as the text in the introduction]:quilt select text: ' \ + '--prefix[Use an alternate prefix in the bracketed part of the subjects generated]:quilt select prefix: ' \ + '--mbox[Store all messages in the specified file in mbox format]:files:_files' \ + '--send[Send the messages directly]' \ + '--sender[The envelope sender address to use]:quilt select sender: ' \ + '--from[From header]:quilt select from: ' \ + '--subject[Subject header]:quilt select subject: ' \ + '--to[Append a recipient to the To header]:quilt select to: ' \ + '--cc[Append a recipient to the Cc header]:quilt select cc: ' \ + '--bcc[Append a recipient to the Bcc header]:quilt select bcc: ' \ + '--signature[Append the specified signature to messages]:files:_files' \ + '--reply-to[Add the appropriate headers to reply to the specified message]:quilt select reply-to: ' \ + '*:quilt series:_quilt_series' + ;; + (new) + _arguments '-h' + ;; + (next) + _arguments '-h' \ + ':quilt series:_quilt_series' + ;; + (patches) + _arguments '-h' \ + '-v[Verbose, more user friendly output]' \ + ':files:_files' + ;; (pop) - _wanted -V 'applied patches' expl 'patch' compadd ${(f)"$(quilt applied)"} - ;; + _arguments '-h' \ + '-a[Remove all applied patches]' \ + '-f[Force remove]' \ + '-R[Always verify if the patch removes cleanly]' \ + '-q[Quiet operation]' \ + '-v[Verbose operation]' \ + ':quilt applied:_quilt_applied' + ;; + (previous) + _arguments '-h' \ + ':quilt series:_quilt_series' + ;; + (push) + _arguments '-h' \ + '-a[Apply all patches in the series file]' \ + '-q[Quiet operation]' \ + '-f[Force apply, even if the patch has rejects]' \ + '-v[Verbose operation]' \ + '--leave-rejects[Leave around the reject files patch produced]' \ + '--color=[Use syntax coloring]:quilt select color:(always auto never)' \ + ':quilt unapplied:_quilt_unapplied' + ;; + (refresh) + _arguments '-h' \ + '-p[Select a patch style]:quilt patch style:(0 1 ab)' \ + '-u[Create a unified diff]' \ + '-U[Create a unified diff with num lines of context]:quilt unified diff: ' \ + '-c[Create a context diff]' \ + '-C[Create a context diff with num lines of context]:quilt context diff: ' \ + '-z[Create a new patch containing the changes instead of refreshing the topmost patch]:quilt select new patch name: ' \ + '--no-timestamps[Do not include file timestamps in patch headers]' \ + '--no-index[Do not output Index: lines]' \ + '--diffstat[Add a diffstat section to the patch header, or replace the existing diffstat section]' \ + '-f[Enforce refreshing of a patch that is not on top]' \ + '--backup[Create a backup copy of the old version of a patch as patch~]' \ + '--sort[Sort files by their name instead of preserving the original order]' \ + '--strip-trailing-whitespace[Strip trailing whitespace at the end of lines]' \ + ':quilt series:_quilt_series' + ;; + (rename) + _arguments '-h' \ + '-P[Patch to rename]:quilt series:_quilt_series' + ;; + (revert) + _arguments '-h' \ + '-P[Revert changes in the named patch]:quilt series:_quilt_series' \ + '*:files:_files' + ;; + (series) + _arguments '-h' \ + '-v[Verbose, more user friendly output]' + ;; + (setup) + _arguments '-h' \ + '-d[Optional path prefix for the resulting source tree]:quilt select path-prefix: ' \ + '--sourcedir[Directory that contains the package sources]:quilt select package sources directory: ' \ + '-v[Verbose debug output]' \ + ':files:_files' + ;; + (shell) + _arguments '-h' \ + ':quilt select shell command:_command_names -e' + ;; + (snapshot) + _arguments '-h' \ + '-d[Remove current snapshot]' + ;; + (top) + _arguments '-h' + ;; + (unapplied) + _arguments '-h' \ + ':quilt series:_quilt_series' + ;; + (upgrade) + _arguments '-h' + ;; (*) - _files - ;; + ;; esac ;; esac diff --git a/Completion/Unix/Command/_rsync b/Completion/Unix/Command/_rsync index cdb40ab46..b999c1bbd 100644 --- a/Completion/Unix/Command/_rsync +++ b/Completion/Unix/Command/_rsync @@ -96,144 +96,148 @@ _rsync_files() { _alternative "files:file:_files" "remote-files:remote file:_rsync_remote_files" } -_arguments -s \ - '*'{-v,--verbose}'[increase verbosity]' \ - {--no-v,--no-verbose}'[turn off --verbose]' \ - '--bwlimit=[limit I/O bandwidth]:KBytes per second' \ - '--port=[specify alternate port number]:port:(873)' \ - '--address=[bind to the specified address]:bind address:_bind_addresses' \ - '(-T --temp-dir)'{-T,--temp-dir=}'[create temporary files in specified directory]:directory:_directories' \ - '--sockopts=[specify custom TCP options]' \ - '(-4 -6 --ipv4 --ipv6)'{-4,--ipv4}'[prefer IPv4]' \ - '(-4 -6 --ipv4 --ipv6)'{-6,--ipv6}'[prefer IPv6]' \ - - daemon \ - '(-)'{-h,--help}'[display help information]' \ - '--config=[specify alternate rsyncd.conf file]:file:_files' \ - '--daemon[run as an rsync daemon]' \ - '--detach[detach from the parent]' \ - '--no-detach[do not detach from the parent]' \ - - client \ - '(-)--help[display help information]' \ - '*: :_rsync_files' \ - '(-q --quiet)'{-q,--quiet}'[suppress non-error messages]' \ - '--no-motd[suppress the daemon message-of-the-day output]' \ - '(-c --checksum)'{-c,--checksum}'[skip based on checksums, not mod-time & size]' \ - '(-a --archive)'{-a,--archive}'[archive mode; same as -rlptgoD (no -H)]' \ - '(-r --recursive)'{-r,--recursive}'[recurse into directories]' \ - {--no-r,--no-recursive}'[turn off --recursive]' \ - {--no-inc-recursive,--no-i-r}'[disable incremental recursive mode]' \ - '(-R --relative)'{-R,--relative}'[use relative path names]' \ - {--no-R,--no-relative}'[turn off --relative]' \ - {--no-implied-dirs,--no-i-d}'[do not send implied dirs with --relative]' \ - '(-b --backup)'{-b,--backup}'[make backups into hierarchy at indicated directory]' \ - '--backup-dir=[make backups into specified directory]:backup directory:_directories' \ - '--suffix=[set backup suffix]:suffix:(\~)' \ - '(-u --update)'{-u,--update}'[skip files that are newer on the receiving side]' \ - '--inplace[update destination files in-place]' \ - '(--append-verify)--append[append data onto shorter files]' \ - '(--append)--append-verify[append data onto shorter files, verifying old data]' \ - '(-A --acls)'{-A,--acls}'[preserve access-control lists]' \ - '(-X --xattrs)'{-X,--xattrs}'[preserve extended attributes]' \ - '--fake-super[use xattrs to save all file attributes]' \ - '(-d --dirs)'{-d,--dirs}'[transfer directories without recursing]' \ - {--no-d,--no-dirs}'[turn off --dirs]' \ - '(-l --links)'{-l,--links}'[copy symlinks as symlinks]' \ - {--no-l,--no-links}'[turn off --links]' \ - '(-L --copy-links)'{-L,--copy-links}'[transform symlinks into referent file/dir]' \ - '(-k --copy-dirlinks)'{-k,--copy-dirlinks}'[transform a symlink to a dir into referent dir]' \ - '--copy-unsafe-links[only "unsafe" symlinks are transformed]' \ - '--safe-links[ignore symlinks that point outside the source tree]' \ - '(-H --hard-links)'{-H,--hard-links}'[preserve hard links]' \ - {--no-H,--no-hard-links}'[turn off --hard-links]' \ - '(-K --keep-dirlinks)'{-K,--keep-dirlinks}'[treat symlinked dir on receiver as dir]' \ - '(-p --perms -E --executability)'{-p,--perms}'[preserve permissions]' \ - {--no-p,--no-perms}'[turn off --perms]' \ - '(-E --executability)'{-E,--executability}'[preserve executability]' \ - '(-o --owner)'{-o,--owner}'[preserve owner]' \ - {--no-o,--no-owner}'[turn off --owner]' \ - '(-g --group)'{-g,--group}'[preserve group]' \ - {--no-g,--no-group}'[turn off --group]' \ - '(--devices --specials)-D[same as --devices --specials]' \ - '(-D)--devices[preserve devices]' \ - '--no-devices[turn off --devices]' \ - '(-D)--specials[preserve special files]' \ - '--no-specials[turn off --specials]' \ - '--no-D[turn off --devices and --specials]' \ - '(-t --times)'{-t,--times}'[preserve times]' \ - {--no-t,--no-times}'[turn off --times]' \ - '(-O --omit-dir-times)'{-O,--omit-dir-times}'[omit directories when preserving times]' \ - '--chmod[change destination permissions]:mods' \ - '(-S --sparse)'{-S,--sparse}'[handle sparse files efficiently]' \ - '(-n --dry-run)'{-n,--dry-run}'[show what would have been transferred]' \ - '(-W --whole-file)'{-W,--whole-file}'[copy files whole (without delta-transfer algorithm)]' \ - {--no-W,--no-whole-file}'[turn off --whole-file]' \ - '(-x --one-file-system)'{-x,--one-file-system}'[do not cross filesystem boundaries]' \ - '(-B --block-size)'{-B,--block-size=}'[force a fixed checksum block-size]:block size' \ - '(-e --rsh)'{-e,--rsh=}'[specify the remote shell to use]:remote-shell command:(rsh ssh)' \ - '--rsync-path=[specify path to rsync on the remote machine]:remote command' \ - '--ignore-existing[ignore files that already exist on receiving side]' \ - '(--existing --ignore-non-existing)'{--existing,--ignore-non-existing}'[ignore files that do not exist on receiving side]' \ - '--remove-source-files[synchronized files are removed from sending side]' \ - '(--delete-before --delete-during --delete-after --delete-delay)--del[an alias for --delete-during]' \ - '--delete[delete files that do not exist on the sending side]' \ - '(--del --delete-during --delete-after --delete-delay)--delete-before[receiver deletes before transfer]' \ - '(--del --delete-before --delete-after --delete-delay)--delete-during[receiver deletes during transfer]' \ - '(--del --delete-before --delete-during --delete-delay)--delete-after[receiver deletes after transfer]' \ - '(--del --delete-before --delete-during --delete-after)--delete-delay[receiver deletes after transfer]' \ - '--delete-excluded[also delete excluded files on the receiving side]' \ - '--ignore-errors[delete even if there are I/O errors]' \ - '--force[force deletion of directories even if not empty]' \ - '--max-delete=[do not delete more than NUM files]:number' \ - '--max-size=[do not transfer any file larger than specified size]:number' \ - '--min-size=[do not transfer any file smaller than specified size]:number' \ - '(-P)--partial[keep partially transferred files]' \ - '--no-partial[turn off --partial]' \ - '--partial-dir=[put a partially transferred file into specified directory]:directory:_directories' \ - '--super[receiver attempts super-user activities]' \ - '--no-super[receiver performs normal-user activities]' \ - '--delay-updates[put all updated files into place at end of transfer]' \ - '(-m --prune-empty-dirs)'{-m,--prune-empty-dirs}'[prune empty directory chains from file-list]' \ - '--numeric-ids[do not map uid/gid values by user/group name]' \ - '--timeout=[set I/O timeout in seconds for lulls in a transfer]:seconds' \ - '--contimeout=[set connect timeout in seconds for daemon connections]:seconds' \ - '(-I --ignore-times)'{-I,--ignore-times}'[do not skip files that match in size and mod-time]' \ - '--size-only[skip files that match in size]' \ - '--modify-window=[compare mod-times with reduced accuracy]:seconds' \ - '(-y --fuzzy)'{-y,--fuzzy}'[find similar file for basis if no destination file]' \ - '(--copy-dest --link-dest)*--compare-dest=[also compare destination files relative to specified directory]:directory:_directories' \ - '(--compare-dest --link-dest)*--copy-dest=[like --compare-dest, but also includes copies of unchanged files]:directory:_directories' \ - '(--compare-dest --copy-dest)*--link-dest=[hardlink to files in specified directory hierarchy when unchanged]:directory:_directories' \ - '(-z --compress)'{-z,--compress}'[compress file data during the transfer]' \ - '--compress-level=[explicitly set compression level]:number' \ - '--skip-compress=[skip compressing files with a listed suffix]:suffixes' \ - '(-C --cvs-exclude)'{-C,--cvs-exclude}'[auto-ignore files the same way CVS does]' \ - '*'{-f=,--filter=}'[add a file-filtering rule]:rule' \ - '*-F[same as --filter="dir-merge /.rsync-filter", repeated: --filter="- .rsync-filter"]' \ - '--exclude-from=[read exclude patterns from specified file]:file:_files' \ - '*--exclude=[exclude files matching pattern]:pattern' \ - '--include-from=[read include patterns from specified file]:file:_files' \ - '*--include=[do not exclude files matching pattern]:pattern' \ - '--files-from=[read list of source-file names from specified file]:file:_files' \ - '(-0 --from0)'{-0,--from0}'[all *-from file lists are delimited by nulls]' \ - '(-s --protect-args)'{-s,--protect-args}'[no space-splitting; only wildcard special-chars]' \ - '--version[print version number]' \ - '*'{-h,--human-readable}'[output numbers in a human-readable format]' \ - '--blocking-io[use blocking I/O for the remote shell]' \ - '--no-blocking-io[turn off --blocking-io]' \ - '--stats[give some file-transfer stats]' \ - '(-8 --8-bit-output)'{-8,--8-bit-output}'[leave high-bit chars unescaped in output]' \ - '(-P)--progress[show progress during transfer]' \ - '--no-progress[turn off --progress]' \ - '(--partial --progress)-P[same as --partial --progress]' \ - '(-i --itemize-changes)'{-i,--itemize-changes}'[output a change-summary for all updates]' \ - '--log-format=[deprecated version of --out-format]' \ - '--out-format=[output updates using specified format]:format' \ - '--log-file-format=[log updates using specified format]:format' \ - '--log-file=[log what rsync is doing to the specified file]:file:_files' \ - '--password-file=[read daemon-access password from file]:file:_files' \ - '--list-only[list the files instead of copying them]' \ - '(--only-write-batch)--write-batch=[write a batched update to the specified file]:file:_files' \ - '(--write-batch)--only-write-batch=[like --write-batch but w/o updating destination]:file:_files' \ - '--protocol=[force an older protocol version to be used]:number' \ - '--iconv=[request charset conversion of filenames]:number' \ - '--read-batch=[read a batched update from the specified file]:file:_files' +_rsync() { + _arguments -s \ + '*'{-v,--verbose}'[increase verbosity]' \ + {--no-v,--no-verbose}'[turn off --verbose]' \ + '--bwlimit=[limit I/O bandwidth]:KBytes per second' \ + '--port=[specify alternate port number]:port:(873)' \ + '--address=[bind to the specified address]:bind address:_bind_addresses' \ + '(-T --temp-dir)'{-T,--temp-dir=}'[create temporary files in specified directory]:directory:_directories' \ + '--sockopts=[specify custom TCP options]' \ + '(-4 -6 --ipv4 --ipv6)'{-4,--ipv4}'[prefer IPv4]' \ + '(-4 -6 --ipv4 --ipv6)'{-6,--ipv6}'[prefer IPv6]' \ + - daemon \ + '(-)'{-h,--help}'[display help information]' \ + '--config=[specify alternate rsyncd.conf file]:file:_files' \ + '--daemon[run as an rsync daemon]' \ + '--detach[detach from the parent]' \ + '--no-detach[do not detach from the parent]' \ + - client \ + '(-)--help[display help information]' \ + '*: :_rsync_files' \ + '(-q --quiet)'{-q,--quiet}'[suppress non-error messages]' \ + '--no-motd[suppress the daemon message-of-the-day output]' \ + '(-c --checksum)'{-c,--checksum}'[skip based on checksums, not mod-time & size]' \ + '(-a --archive)'{-a,--archive}'[archive mode; same as -rlptgoD (no -H)]' \ + '(-r --recursive)'{-r,--recursive}'[recurse into directories]' \ + {--no-r,--no-recursive}'[turn off --recursive]' \ + {--no-inc-recursive,--no-i-r}'[disable incremental recursive mode]' \ + '(-R --relative)'{-R,--relative}'[use relative path names]' \ + {--no-R,--no-relative}'[turn off --relative]' \ + {--no-implied-dirs,--no-i-d}'[do not send implied dirs with --relative]' \ + '(-b --backup)'{-b,--backup}'[make backups into hierarchy at indicated directory]' \ + '--backup-dir=[make backups into specified directory]:backup directory:_directories' \ + '--suffix=[set backup suffix]:suffix:(\~)' \ + '(-u --update)'{-u,--update}'[skip files that are newer on the receiving side]' \ + '--inplace[update destination files in-place]' \ + '(--append-verify)--append[append data onto shorter files]' \ + '(--append)--append-verify[append data onto shorter files, verifying old data]' \ + '(-A --acls)'{-A,--acls}'[preserve access-control lists]' \ + '(-X --xattrs)'{-X,--xattrs}'[preserve extended attributes]' \ + '--fake-super[use xattrs to save all file attributes]' \ + '(-d --dirs)'{-d,--dirs}'[transfer directories without recursing]' \ + {--no-d,--no-dirs}'[turn off --dirs]' \ + '(-l --links)'{-l,--links}'[copy symlinks as symlinks]' \ + {--no-l,--no-links}'[turn off --links]' \ + '(-L --copy-links)'{-L,--copy-links}'[transform symlinks into referent file/dir]' \ + '(-k --copy-dirlinks)'{-k,--copy-dirlinks}'[transform a symlink to a dir into referent dir]' \ + '--copy-unsafe-links[only "unsafe" symlinks are transformed]' \ + '--safe-links[ignore symlinks that point outside the source tree]' \ + '(-H --hard-links)'{-H,--hard-links}'[preserve hard links]' \ + {--no-H,--no-hard-links}'[turn off --hard-links]' \ + '(-K --keep-dirlinks)'{-K,--keep-dirlinks}'[treat symlinked dir on receiver as dir]' \ + '(-p --perms -E --executability)'{-p,--perms}'[preserve permissions]' \ + {--no-p,--no-perms}'[turn off --perms]' \ + '(-E --executability)'{-E,--executability}'[preserve executability]' \ + '(-o --owner)'{-o,--owner}'[preserve owner]' \ + {--no-o,--no-owner}'[turn off --owner]' \ + '(-g --group)'{-g,--group}'[preserve group]' \ + {--no-g,--no-group}'[turn off --group]' \ + '(--devices --specials)-D[same as --devices --specials]' \ + '(-D)--devices[preserve devices]' \ + '--no-devices[turn off --devices]' \ + '(-D)--specials[preserve special files]' \ + '--no-specials[turn off --specials]' \ + '--no-D[turn off --devices and --specials]' \ + '(-t --times)'{-t,--times}'[preserve times]' \ + {--no-t,--no-times}'[turn off --times]' \ + '(-O --omit-dir-times)'{-O,--omit-dir-times}'[omit directories when preserving times]' \ + '--chmod[change destination permissions]:mods' \ + '(-S --sparse)'{-S,--sparse}'[handle sparse files efficiently]' \ + '(-n --dry-run)'{-n,--dry-run}'[show what would have been transferred]' \ + '(-W --whole-file)'{-W,--whole-file}'[copy files whole (without delta-transfer algorithm)]' \ + {--no-W,--no-whole-file}'[turn off --whole-file]' \ + '(-x --one-file-system)'{-x,--one-file-system}'[do not cross filesystem boundaries]' \ + '(-B --block-size)'{-B,--block-size=}'[force a fixed checksum block-size]:block size' \ + '(-e --rsh)'{-e+,--rsh=}'[specify the remote shell to use]:remote-shell command:(rsh ssh)' \ + '--rsync-path=[specify path to rsync on the remote machine]:remote command' \ + '--ignore-existing[ignore files that already exist on receiving side]' \ + '(--existing --ignore-non-existing)'{--existing,--ignore-non-existing}'[ignore files that do not exist on receiving side]' \ + '--remove-source-files[synchronized files are removed from sending side]' \ + '(--delete-before --delete-during --delete-after --delete-delay)--del[an alias for --delete-during]' \ + '--delete[delete files that do not exist on the sending side]' \ + '(--del --delete-during --delete-after --delete-delay)--delete-before[receiver deletes before transfer]' \ + '(--del --delete-before --delete-after --delete-delay)--delete-during[receiver deletes during transfer]' \ + '(--del --delete-before --delete-during --delete-delay)--delete-after[receiver deletes after transfer]' \ + '(--del --delete-before --delete-during --delete-after)--delete-delay[receiver deletes after transfer]' \ + '--delete-excluded[also delete excluded files on the receiving side]' \ + '--ignore-errors[delete even if there are I/O errors]' \ + '--force[force deletion of directories even if not empty]' \ + '--max-delete=[do not delete more than NUM files]:number' \ + '--max-size=[do not transfer any file larger than specified size]:number' \ + '--min-size=[do not transfer any file smaller than specified size]:number' \ + '(-P)--partial[keep partially transferred files]' \ + '--no-partial[turn off --partial]' \ + '--partial-dir=[put a partially transferred file into specified directory]:directory:_directories' \ + '--super[receiver attempts super-user activities]' \ + '--no-super[receiver performs normal-user activities]' \ + '--delay-updates[put all updated files into place at end of transfer]' \ + '(-m --prune-empty-dirs)'{-m,--prune-empty-dirs}'[prune empty directory chains from file-list]' \ + '--numeric-ids[do not map uid/gid values by user/group name]' \ + '--timeout=[set I/O timeout in seconds for lulls in a transfer]:seconds' \ + '--contimeout=[set connect timeout in seconds for daemon connections]:seconds' \ + '(-I --ignore-times)'{-I,--ignore-times}'[do not skip files that match in size and mod-time]' \ + '--size-only[skip files that match in size]' \ + '--modify-window=[compare mod-times with reduced accuracy]:seconds' \ + '(-y --fuzzy)'{-y,--fuzzy}'[find similar file for basis if no destination file]' \ + '(--copy-dest --link-dest)*--compare-dest=[also compare destination files relative to specified directory]:directory:_directories' \ + '(--compare-dest --link-dest)*--copy-dest=[like --compare-dest, but also includes copies of unchanged files]:directory:_directories' \ + '(--compare-dest --copy-dest)*--link-dest=[hardlink to files in specified directory hierarchy when unchanged]:directory:_directories' \ + '(-z --compress)'{-z,--compress}'[compress file data during the transfer]' \ + '--compress-level=[explicitly set compression level]:number' \ + '--skip-compress=[skip compressing files with a listed suffix]:suffixes' \ + '(-C --cvs-exclude)'{-C,--cvs-exclude}'[auto-ignore files the same way CVS does]' \ + '*'{-f=,--filter=}'[add a file-filtering rule]:rule' \ + '*-F[same as --filter="dir-merge /.rsync-filter", repeated: --filter="- .rsync-filter"]' \ + '--exclude-from=[read exclude patterns from specified file]:file:_files' \ + '*--exclude=[exclude files matching pattern]:pattern' \ + '--include-from=[read include patterns from specified file]:file:_files' \ + '*--include=[do not exclude files matching pattern]:pattern' \ + '--files-from=[read list of source-file names from specified file]:file:_files' \ + '(-0 --from0)'{-0,--from0}'[all *-from file lists are delimited by nulls]' \ + '(-s --protect-args)'{-s,--protect-args}'[no space-splitting; only wildcard special-chars]' \ + '--version[print version number]' \ + '*'{-h,--human-readable}'[output numbers in a human-readable format]' \ + '--blocking-io[use blocking I/O for the remote shell]' \ + '--no-blocking-io[turn off --blocking-io]' \ + '--stats[give some file-transfer stats]' \ + '(-8 --8-bit-output)'{-8,--8-bit-output}'[leave high-bit chars unescaped in output]' \ + '(-P)--progress[show progress during transfer]' \ + '--no-progress[turn off --progress]' \ + '(--partial --progress)-P[same as --partial --progress]' \ + '(-i --itemize-changes)'{-i,--itemize-changes}'[output a change-summary for all updates]' \ + '--log-format=[deprecated version of --out-format]' \ + '--out-format=[output updates using specified format]:format' \ + '--log-file-format=[log updates using specified format]:format' \ + '--log-file=[log what rsync is doing to the specified file]:file:_files' \ + '--password-file=[read daemon-access password from file]:file:_files' \ + '--list-only[list the files instead of copying them]' \ + '(--only-write-batch)--write-batch=[write a batched update to the specified file]:file:_files' \ + '(--write-batch)--only-write-batch=[like --write-batch but w/o updating destination]:file:_files' \ + '--protocol=[force an older protocol version to be used]:number' \ + '--iconv=[request charset conversion of filenames]:number' \ + '--read-batch=[read a batched update from the specified file]:file:_files' +} + +_rsync "$@" diff --git a/Completion/Unix/Command/_ssh b/Completion/Unix/Command/_ssh index eb5947ce0..0ec9c84a0 100644 --- a/Completion/Unix/Command/_ssh +++ b/Completion/Unix/Command/_ssh @@ -1,5 +1,11 @@ #compdef ssh slogin=ssh scp ssh-add ssh-agent ssh-keygen sftp +# Completions currently based on OpenSSH 5.9 (released on 2011-09-06). +# +# TODO: update ssh-keygen (not based on 5.9) +# TODO: sshd, ssh-keyscan, ssh-keysign + + _remote_files () { # There should be coloring based on all the different ls -F classifiers. local expl rempat remfiles remdispf remdispd args suf ret=1 @@ -10,7 +16,7 @@ _remote_files () { then rempat="${PREFIX%%[^./][^/]#}\*" else rempat="${(q)PREFIX%%[^./][^/]#}\*" fi - remfiles=(${(M)${(f)"$(_call_program files ssh -o BatchMode=yes $args -a -x ${IPREFIX%:} ls -d1FL "$rempat" 2>/dev/null)"}%%[^/]#(|/)}) + remfiles=(${(M)${(f)"$(_call_program files ssh -o BatchMode=yes $args -a -x ${IPREFIX%:} ls -d1FL -- "$rempat" 2>/dev/null)"}%%[^/]#(|/)}) compset -P '*/' compset -S '/*' || suf='remote file' @@ -38,79 +44,100 @@ _ssh () { typeset -A opt_args common=( - '-c+[select encryption cipher]:encryption cipher:(idea des 3des blowfish arcfour tss none)' - '-C[compress data]' - '-F+[specify alternate config file]:config file:_files' - '-i+[select identity file]:SSH identity file:_files' - '*-o+[specify extra options]:option string:->option' '(-2)-1[forces ssh to try protocol version 1 only]' '(-1)-2[forces ssh to try protocol version 2 only]' '(-6)-4[forces ssh to use IPv4 addresses only]' '(-4)-6[forces ssh to use IPv6 addresses only]' + '-C[compress data]' + '-c+[select encryption cipher]:encryption cipher:(idea des 3des blowfish arcfour tss none)' + '-F+[specify alternate config file]:config file:_files' + '-i+[select identity file]:SSH identity file:_files' + '*-o+[specify extra options]:option string:->option' + ) + common_transfer=( + '-l[limit used bandwidth]:bandwidth in KiB/s:' + '-P+[specify port on remote host]:port number on remote host' + '-p[preserve modification times, access times and modes]' + '-q[disable progress meter and warnings]' + '-r[recursively copy directories (follows symbolic links)]' + '-S+[specify ssh program]:path to ssh:_command_names -e' \ + '-v[verbose mode]' ) case "$service" in ssh) _arguments -C -s \ - '(-A)-a[disable forwarding of authentication agent connection]' \ '(-a)-A[enables forwarding of the authentication agent connection]' \ + '(-A)-a[disable forwarding of authentication agent connection]' \ '(-P)-b+[specify interface to transmit on]:bind address:_bind_addresses' \ - '-D+[specify a dynamic port forwarding]:port' \ + '-D+[specify a dynamic port forwarding]:[bind-address]\:port' \ '-e+[set escape character]:escape character (or `none'"'"'):' \ '(-n)-f[go to background]' \ '-g[allow remote hosts to connect to local forwarded ports]' \ - '-I+[specify smartcard device]:device:_files' \ - '-k[disable forwarding of kerberos tickets]' \ + '-I+[specify the PKCS#11 shared library to use]' \ + '-K[enable GSSAPI-based authentication and forwarding]' \ + '-k[disable forwarding of GSSAPI credentials]' \ + '*-L[specify local port forwarding]:local port forwarding:->forward' \ '-l+[specify login name]:login name:_ssh_users' \ + '-M[master mode for connection sharing]' \ '(-1)-m+[specify mac algorithms]:mac spec' \ + '(-1)-N[do not execute a remote command (protocol version 2 only)]' \ '-n[redirect stdin from /dev/null]' \ - '(-1)-N[do not execute a remote command. (protocol version 2 only)]' \ - '-p+[specify port on remote host]:port number on remote host' \ + '-O[control active connection multiplexing master process]:multiplex control command:(( + check\:"check that the master process is running" + forward\:"request forwardings without command execution" + cancel\:"cancel forwardings" + exit\:"request the master to exit" + stop\:"request the master to stop accepting further multiplexing requests"))' \ '-P[use non privileged port]' \ + '-p+[specify port on remote host]:port number on remote host' \ '(-v)*-q[quiet operation]' \ + '*-R[specify remote port forwarding]:remote port forwarding:->forward' \ + '-S+[specify location of control socket for connection sharing]:path to control socket:_files' \ '(-1)-s[invoke subsystem]' \ - '(-T)-t[force pseudo-tty allocation]' \ '(-1 -t)-T[disable pseudo-tty allocation (protocol version 2 only)]' \ - '(-q)*-v[verbose mode]' \ + '(-T)-t[force pseudo-tty allocation]' \ '-V[show version number]' \ - '(-X -Y)-x[disable X11 forwarding]' \ + '(-q)*-v[verbose mode]' \ + '(-N)-W[forward standard input/output over host:port (protocol version 2 only)]:host\:port' \ + '-w[request tunnel device forwarding with the specified tun devices]:local_tun[\:remote_tun]' \ '(-x -Y)-X[enable (untrusted) X11 forwarding]' \ + '(-X -Y)-x[disable X11 forwarding]' \ '(-x -X)-Y[enable trusted X11 forwarding]' \ - '-M[master mode for connection sharing]' \ - '-S+:path to control socket:_files' \ - '-O:multiplex control command:(check exit)' \ - '*-L[specify local port forwarding]:local port forwarding:->forward' \ - '*-R[specify remote port forwarding]:remote port forwarding:->forward' \ + '-y[send log information using the syslog module]' \ ':remote host name:->userhost' \ '*::args:->command' "$common[@]" && ret=0 ;; scp) _arguments -C -s \ - '-p[preserve modification times]' \ - '-r[recursively copy directories]' \ - '-v[verbose mode]' \ - '-B[batch mode]' \ - '-q[disables the progress meter]' \ - '-P+[specify port on remote host]:port number on remote host' \ - '-S+[specify ssh program]:path to ssh:_command_names -e' \ - '*:file:->file' "$common[@]" && ret=0 + '-3[copy through local host, not directly between the remote hosts]' \ + '-B[batch mode (don'"'"'t ask for passphrases)]' \ + '*:file:->file' "$common[@]" "$common_transfer[@]" && ret=0 ;; ssh-add) _arguments -s \ - '-l[list all identities]' \ - '-L[lists public key parameters of all identities in the agent]'\ - '-d[remove identity]' \ + '-c[identity is subject to confirmation via SSH_ASKPASS]' \ '-D[delete all identities]' \ - '-p[read passphrase from stdin]' \ + '-d[remove identity]' \ + '-e[remove keys provided by the PKCS#11 shared library]:library:' \ + '-k[load plain private keys only and skip certificates]' \ + '-L[lists public key parameters of all identities in the agent]'\ + '-l[list all identities]' \ + '-s[add keys provided by the PKCS#11 shared library]:library:' \ + '-t[set maximum lifetime for identity]:maximum lifetime (in seconds or time format):' \ + '-X[unlock the agent]' \ + '-x[lock the agent with a password]' \ '*:SSH identity file:_files' return ;; ssh-agent) _arguments -s \ - '(*)-k[kill agent automatically]' \ - '(-c)-s[force sh-style shell]' \ - '(-s)-c[force csh-style shell]' \ + '(-k)-a[UNIX-domain socket to bind agent to]:UNIX-domain socket:_files' \ + '(-k -s)-c[force csh-style shell]' \ '(-k)-d[debug mode]' \ + '-k[kill current agent]' \ + '(-k -c)-s[force sh-style shell]' \ + '-t[set default maximum lifetime for identities]:maximum lifetime (in seconds or time format):' \ '*::command: _normal' return ;; @@ -137,16 +164,12 @@ _ssh () { ;; sftp) _arguments -C -s \ - '-C[compress data]' \ - '-F+[specify alternate config file]:config file:_files' \ - '(-1)-s[invoke subsystem]' \ - '-S+[specify program]:program:_command_names -e' \ - '-B+[specify buffer size]:buffer size' \ + '-B+[specify buffer size]:buffer size in bytes (default\: 32768):' \ '-b+[specify batch file to read]:batch file:_files' \ - '*-v[verbose mode]' \ - '-1[forces ssh to try protocol version 1 only]' \ - '*-o+[specify extra options]:option string:->option' \ - '1:file:->rfile' '*:file:->file' && ret=0 + '-D[connect directly to a local sftp server]:sftp server path:' \ + '-R[specify number of outstanding requests]:number of requests (default\: 64):' \ + '-s[SSH2 subsystem or path to sftp server on the remote host]' \ + '1:file:->rfile' '*:file:->file' "$common[@]" "$common_transfer[@]" && ret=0 ;; esac @@ -163,22 +186,36 @@ _ssh () { ;; *(#i)ciphers*) _values -s , 'encryption cipher' \ - 'aes128-cbc' \ '3des-cbc' \ - 'blowfish-cbc' \ - 'cast128-cbc' \ - 'arcfour' \ + 'aes128-cbc' \ 'aes192-cbc' \ 'aes256-cbc' \ + 'aes128-ctr' \ + 'aes192-ctr' \ + 'aes256-ctr' \ + 'arcfour128' \ + 'arcfour256' \ + 'arcfour' \ + 'blowfish-cbc' \ + 'cast128-cbc' \ + \ 'rijndael128-cbc' \ 'rijndael192-cbc' \ 'rijndael256-cbc' \ - 'rijndael-cbc@lysator.liu.se' && ret=0 + 'rijndael-cbc@lysator.liu.se' \ + && ret=0 ;; *(#i)cipher*) - _wanted values expl 'encryption cipher' \ - compadd idea des 3des blowfish arcfour tss none && ret=0 + _wanted values expl 'encryption cipher (protocol version 1)' \ + compadd blowfish 3des des idea arcfour tss none && ret=0 ;; + *(#i)controlmaster*) + _wanted values expl 'truthish value' compadd yes no auto autoask && ret=0 + ;; + *(#i)controlpath*) + _description files expl 'path to control socket' + _files "$expl[@]" && ret=0 + ;; *(#i)globalknownhostsfile*) _description files expl 'global file with known hosts' _files "$expl[@]" && ret=0 @@ -193,6 +230,10 @@ _ssh () { *(#i)(local|remote)forward*) state=forward ;; + *(#i)preferredauthentications*) + _values -s , 'authentication method' gssapi-with-mic \ + hostbased publickey keyboard-interactive password && ret=0 + ;; *(#i)protocol*) _values -s , 'protocol version' \ '1' \ @@ -218,41 +259,95 @@ _ssh () { _description files expl 'xauth program' _files "$expl[@]" -g '*(-*)' && ret=0 ;; - *(#i)controlmaster*) - _wanted values expl 'truthish value' compadd yes no auto autoask && ret=0 - ;; - *(#i)controlpath*) - _description files expl 'path to control socket' - _files "$expl[@]" && ret=0 - ;; esac else + # old options are after the empty "\"-line _wanted values expl 'configure file option' \ compadd -M 'm:{a-z}={A-Z}' -qS '=' - \ - AddressFamily \ - AFSTokenPassing BatchMode BindAddress \ - ChallengeResponseAuthentication CheckHostIP \ - Cipher Ciphers ClearAllForwardings Compression \ - CompressionLevel ConnectionAttempts ConnectTimeout \ - ControlMaster ControlPath \ - DynamicForward EnableSSHKeysign \ - EscapeChar FallBackToRsh ForwardAgent ForwardX11 \ - ForwardX11Trusted \ - GatewayPorts GlobalKnownHostsFile GSSAPIAuthentication \ - GSSAPIDelegateCredentials HostbasedAuthentication \ - HostKeyAlgorithms HostKeyAlias HostName IdentityFile \ - IdentitiesOnly KbdInteractiveDevices \ - KeepAlive KerberosAuthentication KerberosTgtPassing \ - LocalForward LogLevel MACs NoHostAuthenticationForLocalhost \ - NumberOfPasswordPrompts PreferredAuthentications \ - PasswordAuthentication Port Protocol ProtocolKeepAlives \ - ProxyCommand PubkeyAuthentication RemoteForward \ - RhostsAuthentication RhostsRSAAuthentication \ - RSAAuthentication ServerAliveInterval ServerAliveCountMax \ - SetupTimeOut SmartcardDevice StrictHostKeyChecking \ - TCPKeepAlive \ - UsePrivilegedPort User UserKnownHostsFile UseRsh \ - VerifyHostKeyDNS XAuthLocation && ret=0 + AddressFamily \ + BatchMode \ + BindAddress \ + ChallengeResponseAuthentication \ + CheckHostIP \ + Cipher \ + Ciphers \ + ClearAllForwardings \ + Compression \ + CompressionLevel \ + ConnectionAttempts \ + ConnectTimeout \ + ControlMaster \ + ControlPath \ + ControlPersist \ + DynamicForward \ + EnableSSHKeysign \ + EscapeChar \ + ExitOnForwardFailure \ + ForwardAgent \ + ForwardX11 \ + ForwardX11Timeout \ + ForwardX11Trusted \ + GatewayPorts \ + GlobalKnownHostsFile \ + GSSAPIAuthentication \ + GSSAPIDelegateCredentials \ + HashKnownHosts \ + Host \ + HostbasedAuthentication \ + HostKeyAlgorithms \ + HostKeyAlias \ + HostName \ + IdentitiesOnly \ + IdentityFile \ + IPQoS \ + KbdInteractiveAuthentication \ + KbdInteractiveDevices \ + KexAlgorithms \ + LocalCommand \ + LocalForward \ + LogLevel \ + MACs \ + NoHostAuthenticationForLocalhost \ + NumberOfPasswordPrompts \ + PasswordAuthentication \ + PermitLocalCommand \ + PKCS11Provider \ + Port \ + PreferredAuthentications \ + Protocol \ + ProxyCommand \ + PubkeyAuthentication \ + RekeyLimit \ + RemoteForward \ + RequestTTY \ + RhostsRSAAuthentication \ + RSAAuthentication \ + SendEnv \ + ServerAliveCountMax \ + ServerAliveInterval \ + StrictHostKeyChecking \ + TCPKeepAlive \ + Tunnel \ + TunnelDevice \ + UsePrivilegedPort \ + User \ + UserKnownHostsFile \ + VerifyHostKeyDNS \ + VisualHostKey \ + XAuthLocation \ + \ + AFSTokenPassing \ + FallBackToRsh \ + KeepAlive \ + KerberosAuthentication \ + KerberosTgtPassing \ + PreferredAuthentications \ + ProtocolKeepAlives \ + RhostsAuthentication \ + SetupTimeOut \ + SmartcardDevice \ + UseRsh \ + && ret=0 fi ;; forward) diff --git a/Completion/Unix/Command/_systemctl b/Completion/Unix/Command/_systemctl new file mode 100644 index 000000000..69adcf775 --- /dev/null +++ b/Completion/Unix/Command/_systemctl @@ -0,0 +1,305 @@ +#compdef systemctl + +# Copyright (c) 2011 Foudil Brétel <foudil.newbie+zshsystemctl@gmail.com> +# +# This file is released under the GPLv3. +# +# inspired from _yum and systemctl-bash-completion.sh (shipped with systemctl) +# +# TODO: enable options after commands. Ex: systemctl list-units --all --full + +# Main dispatcher +_systemctl() +{ + local curcontext="$curcontext" state lstate line + + # -s for aggregated options like -aP + _arguments -s \ + {-h,--help}'[Show help]' \ + '--version[Show package version]' \ + {-t,--type=}'[List only units of a particular type]:unit type:(automount device mount path service snapshot socket swap target timer)' \ + \*{-p,--property=}'[Show only properties by specific name]:unit property:' \ + {-a,--all}'[Show all units/properties, including dead/empty ones]' \ + '--failed[Show only failed units]' \ + "--full[Don't ellipsize unit names on output]" \ + '--fail[When queueing a new job, fail if conflicting jobs are pending]' \ + '--ignore-dependencies[When queueing a new job, ignore all its dependencies]' \ + '--kill-mode=[How to send signal]:killmode:(control-group process)' \ + '--kill-who=[Who to send signal to]:killwho:(main control all)' \ + {-s,--signal=}'[Which signal to send]:signal:_signals' \ + {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ + {-P,--privileged}'[Acquire privileges before execution]' \ + {-q,--quiet}'[Suppress output]' \ + '--no-block[Do not wait until operation finished]' \ + "--no-wall[Don't send wall message before halt/power-off/reboot]" \ + "--no-reload[When enabling/disabling unit files, don't reload daemon configuration]" \ + '--no-legend[Do not print a legend, i.e. the column headers and the footer with hints]' \ + '--no-pager[Do not pipe output into a pager]' \ + '--no-ask-password[Do not ask for system passwords]' \ + '--order[When generating graph for dot, show only order]' \ + '--require[When generating graph for dot, show only requirement]' \ + '--system[Connect to system manager]' \ + '--user[Connect to user service manager]' \ + '--global[Enable/disable unit files globally]' \ + {-f,--force}'[When enabling unit files, override existing symlinks. When shutting down, execute action immediately]' \ + '--defaults[When disabling unit files, remove default symlinks only]' \ + '*::systemctl command:_systemctl_command' +} + +_hosts_or_user_at_host() +{ + _alternative \ + 'users-hosts:: _user_at_host' \ + 'hosts:: _hosts' +} + +(( $+functions[_systemctl_command] )) || _systemctl_command() +{ + local -a _systemctl_cmds + _systemctl_cmds=( + "list-units:List units" + "start:Start (activate) one or more units" + "stop:Stop (deactivate) one or more units" + "reload:Reload one or more units" + "restart:Start or restart one or more units" + "condrestart:Restart one or more units if active" + "try-restart:Restart one or more units if active" + "reload-or-restart:Reload one or more units is possible, otherwise start or restart" + "force-reload:Reload one or more units is possible, otherwise restart if active" + "reload-or-try-restart:Reload one or more units is possible, otherwise restart if active" + "isolate:Start one unit and stop all others" + "kill:Send signal to processes of a unit" + "is-active:Check whether units are active" + "status:Show runtime status of one or more units" + "show:Show properties of one or more units/jobs or the manager" + "reset-failed:Reset failed state for all, one, or more units" + "enable:Enable one or more unit files" + "disable:Disable one or more unit files" + "is-enabled:Check whether unit files are enabled" + "load:Load one or more units" + "list-jobs:List jobs" + "cancel:Cancel all, one, or more jobs" + "monitor:Monitor unit/job changes" + "dump:Dump server status" + "dot:Dump dependency graph for dot(1)" + "snapshot:Create a snapshot" + "delete:Remove one or more snapshots" + "daemon-reload:Reload systemd manager configuration" + "daemon-reexec:Reexecute systemd manager" + "show-environment:Dump environment" + "set-environment:Set one or more environment variables" + "unset-environment:Unset one or more environment variables" + "default:Enter system default mode" + "rescue:Enter system rescue mode" + "emergency:Enter system emergency mode" + "halt:Shut down and halt the system" + "poweroff:Shut down and power-off the system" + "reboot:Shut down and reboot the system" + "kexec:Shut down and reboot the system with kexec" + "exit:Ask for user instance termination" + ) + + if (( CURRENT == 1 )); then + _describe -t commands 'systemctl command' _systemctl_cmds || compadd "$@" + else + local curcontext="$curcontext" + + cmd="${${_systemctl_cmds[(r)$words[1]:*]%%:*}}" + # Deal with any aliases + case $cmd in + condrestart) cmd="try-restart";; + force-reload) cmd="reload-or-try-restart";; + esac + + if (( $#cmd )); then + curcontext="${curcontext%:*:*}:systemctl-${cmd}:" + + local update_policy + zstyle -s ":completion:${curcontext}:" cache-policy update_policy + if [[ -z "$update_policy" ]]; then + zstyle ":completion:${curcontext}:" cache-policy _systemctl_caching_policy + fi + + _call_function ret _systemctl_$cmd || _message 'no more arguments' + else + _message "unknown systemctl command: $words[1]" + fi + return ret + fi +} + +__check_option_nolegend() +{ + systemctl --no-legend --version 2>&1 | grep -q 'unrecognized option' + print -Pn '%(?..--no-legend)' +} +nolegend=$(__check_option_nolegend) + + +# Fills the unit lists +_systemctl_all_units() +{ + if ( [[ ${+_sys_all_units} -eq 0 ]] || _cache_invalid SYS_ALL_UNITS ) && + ! _retrieve_cache SYS_ALL_UNITS; + then + _sys_all_units=( $(systemctl ${nolegend} list-units --full --all \ + | cut -d' ' -f1 2>/dev/null) ) + _store_cache SYS_ALL_UNITS _sys_all_units + fi +} + +_systemctl_inactive_units() +{ + _sys_inactive_units=( $(systemctl ${nolegend} list-units --full --all \ + | awk '$3 != "active" {print $1}' 2>/dev/null) ) +} + +_systemctl_active_units() +{ + _sys_active_units=( $(systemctl ${nolegend} list-units --full \ + | cut -d' ' -f1 2>/dev/null) ) +} + +_systemctl_failed_units() +{ + _sys_failed_units=( $(systemctl ${nolegend} list-units --full --failed \ + | cut -d' ' -f1 2>/dev/null) ) +} + +_filter_units_by_property () { + local property=$1 value=$2 ; shift ; shift + local -a units ; units=($*) + local -a props ; props=( $(systemctl show --property "$property" -- \ + ${units[*]} | grep -v '^$') ) + for ((i=1; $i <= ${#units[*]}; i++)); do + if [[ "${props[i]}" = "$property=$value" ]]; then + echo "${units[i]}" + fi + done +} + +# Completion functions for ALL_UNITS +for fun in enable disable is-active is-enabled status show ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_all_units + compadd "$@" -a - _sys_all_units + } +done + +# Completion functions for STARTABLE_UNITS +(( $+functions[_systemctl_start] )) || _systemctl_start() +{ + _systemctl_inactive_units + compadd "$@" - $( _filter_units_by_property CanStart yes \ + ${_sys_inactive_units[*]} | grep -Ev '\.(device|snapshot)$' ) +} + +# Completion functions for RESTARTABLE_UNITS +for fun in restart reload-or-restart ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_all_units + compadd "$@" - $( _filter_units_by_property CanStart yes \ + ${_sys_all_units[*]} | grep -Ev '\.(device|snapshot|socket|timer)$' ) + } +done + +# Completion functions for STOPPABLE_UNITS +for fun in stop kill try-restart condrestart ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_active_units + compadd "$@" - $( _filter_units_by_property CanStop yes \ + ${_sys_active_units[*]} ) + } +done + +# Completion functions for RELOADABLE_UNITS +for fun in reload reload-or-try-restart force-reload ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_active_units + compadd "$@" - $( _filter_units_by_property CanReload yes \ + ${_sys_active_units[*]} ) + } +done + +# Completion functions for ISOLATABLE_UNITS +(( $+functions[_systemctl_isolate] )) || _systemctl_isolate() +{ + _systemctl_all_units + compadd "$@" - $( _filter_units_by_property AllowIsolate yes \ + ${_sys_all_units[*]} ) +} + +# Completion functions for FAILED_UNITS +(( $+functions[_systemctl_reset-failed] )) || _systemctl_reset-failed() +{ + _systemctl_failed_units + compadd "$@" -a - _sys_failed_units || _message "no failed-unit found" +} + +# Completion functions for JOBS +(( $+functions[_systemctl_cancel] )) || _systemctl_cancel() +{ + compadd "$@" - $(systemctl ${nolegend} list-jobs \ + | cut -d' ' -f1 2>/dev/null ) || _message "no job found" +} + +# Completion functions for SNAPSHOTS +(( $+functions[_systemctl_delete] )) || _systemctl_delete() +{ + compadd "$@" - $(systemctl ${nolegend} list-units --type snapshot --full \ + --all | cut -d' ' -f1 2>/dev/null ) || _message "no snampshot found" +} + +# Completion functions for ENVS +for fun in set-environment unset-environment ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + local fun=$0 ; fun=${fun##_systemctl_} + local suf + if [[ "${fun}" = "set-environment" ]]; then + suf='-S=' + fi + + compadd "$@" ${suf} - $(systemctl show-environment \ + | sed 's_\([^=]\+\)=.*_\1_' ) + } +done + +# no completion for: +# [STANDALONE]='daemon-reexec daemon-reload default dot dump emergency exit +# halt kexec list-jobs list-units monitor poweroff reboot +# rescue show-environment' +# [NAME]='snapshot load' + +_systemctl_caching_policy() +{ + local _sysunits + local -a oldcache + + # rebuild if cache is more than a day old + oldcache=( "$1"(mh+1) ) + (( $#oldcache )) && return 0 + + _sysunits=($(systemctl ${nolegend} --full --all | cut -d' ' -f1)) + + if (( $#_sysunits )); then + for unit in $_sysunits; do + [[ "$unit" -nt "$1" ]] && return 0 + done + fi + + return 1 +} + +_systemctl "$@" + +# Local Variables: +# mode: sh +# sh-indentation: 2 +# indent-tabs-mode: nil +# sh-basic-offset: 2 +# End: diff --git a/Completion/Unix/Command/_tmux b/Completion/Unix/Command/_tmux index e9977fbbd..5fb721960 100644 --- a/Completion/Unix/Command/_tmux +++ b/Completion/Unix/Command/_tmux @@ -1520,6 +1520,10 @@ function _tmux() { _describe -t subcommands 'tmux commands and aliases' _tmux_commands -- _tmux_aliases fi else + if (( ${+commands[tmux]} == 0 )); then + _message '`tmux'\'' not found in $path; sub-cmd completions disabled.' + return 0 + fi tmuxcommand="${words[1]}" if [[ -n ${_tmux_aliasmap[$tmuxcommand]} ]] ; then tmuxcommand="${_tmux_aliasmap[$tmuxcommand]}" diff --git a/Completion/Unix/Command/_tree b/Completion/Unix/Command/_tree new file mode 100644 index 000000000..d759409b5 --- /dev/null +++ b/Completion/Unix/Command/_tree @@ -0,0 +1,51 @@ +#compdef tree + +# Completions for tree, version 1.5.3 +# Tree is available at +# http://mama.indstate.edu/users/ice/tree/ + +typeset -a opts + +opts=( +'--help[verbose usage listing]' +'--version[version of tree]' +'-a[show all files, including hidden ones]' +'-d[list directories only]' +'-f[print full path prefix for each file]' +'-i[do not print indentation lines]' +'-l[follow symlinks that point to directories]' +'-x[stay on current filesystem]' +'-P[list only files matching a pattern]:pattern:' +'-I[do not list files matching a pattern]:pattern:' +'--noreport[do not print file and directory report at end]' +'-p[print file type and permissions, like ls -l]' +'-s[print size of each file in bytes]' +'-h[print human readable file size]' +'-u[print username]' +'-g[print group name]' +'-D[print date of last modification]' +'--inodes[print inode numbers]' +'--device[print device number to which file or directory belongs]' +'-F[append descriptive character to end, like ls -F]' +'-q[print non-printable characters as question mark, not caret]' +'-N[print non-printable characters as is, not as caret]' +'-v[sort the output as version]' +'-r[sort output in reverse alphabetic order]' +'-t[sort output by last modification time instead of alphabetically]' +'--dirsfirst[list directories before files]' +'-n[turn colorization off always, over-ridden by the -C option]' +'-C[turn colorization on always]' +'-A[turn on ANSI line graphics hack when printing indentation lines]' +'-S[turn on ASCII line graphics]' +'-L[max display depth of tree]:level:' +'--filelimit[do not descend directories with more than number of entries]:number:' +'-R[recursively cross down the tree and execute tree again]' +'-H[turn on HTML output]' +'-T[title for HTML output]' +'--charset[character set for HTML and for line drawing]:charset:' +'--nolinks[turn off hyperlinks in HTML output]' +'-o[send output to file]:filename:_files' +'*:directory:_files -/' +) + +_arguments $opts diff --git a/Completion/Unix/Command/_twidge b/Completion/Unix/Command/_twidge new file mode 100644 index 000000000..d8b3b3def --- /dev/null +++ b/Completion/Unix/Command/_twidge @@ -0,0 +1,77 @@ +#compdef twidge +## completion for twidge 1.0.8, based on twidge(1) + +function _twidge_command { + typeset -a twidge_commands + typeset -i skip=1 + + twidge lscommands | while read cmd desc; do + if [[ $cmd == ---* ]] { + skip=0 + continue + } + if (( skip )) { + continue + } + twidge_commands+="${cmd}:${desc}" + done + + _describe command twidge_commands +} + +function _twidge_args { + typeset -a args_common args_more args_other args_update + + args_common=( + '(-a --all)'{-a,--all}'[receive all content]' + '(-e --exec)'{-e,--exec}'[execute command for each retrieved item]:command' + '(-l --long)'{-l,--long}'[long output format]' + '(-m --mailto)'{-m,--mailto}'[mail retrieved items]:mail address' + ) + + args_more=( + '(-s --saveid)'{-s,--saveid}'[save ID of most recent message]' + '(-u --unseen)'{-u,--unseen}'[only show unseen messages]' + ) + + args_other=( + '(-U --username)'{-U,--username}'[show updates of different user]:username' + ) + + args_update=( + '(-i --inreplyto)'{-i,--inreplyto}'[update in reply to a message]:message id' + '(-i --inreplyto 1)-r[read RFC2822 Mail]' + ':status' + ) + + case ${words[1]} in + lsarchive) + _arguments $args_common $args_more $args_other + ;; + ls(dm(|archive)|recent|replies|rt(|archive|replies))) + _arguments $args_common $args_more + ;; + lsfollow(ers|ing)) + _arguments $args_common :username + ;; + dmsend) + _arguments :recipient :status + ;; + (un|)follow) + _message username + ;; + update) + _arguments $args_update + ;; + esac +} + +function _twidge { + _arguments \ + '(-c --config)'{-c,--config}'[config file]:file:_files' \ + '(-d --debug)'{-d,--debug}'[enable debugging output]' \ + '(-): :_twidge_command' \ + '(-)*:: :_twidge_args' +} + +_twidge "$@" diff --git a/Completion/Unix/Command/_unison b/Completion/Unix/Command/_unison index bb8edd489..5725575c5 100644 --- a/Completion/Unix/Command/_unison +++ b/Completion/Unix/Command/_unison @@ -42,7 +42,7 @@ _arguments \ '-copythreshold[use copyprog on files bigger than this]:size (kb):' \ '-debug:debug module:(all verbose)' \ '-diff[command for showing differences between files]:program:_files -g "*(-x)"' \ - '-dontchmod[When set, never use the chmod system call]' \ + '-dontchmod[when set, never use the chmod system call]' \ '-dumbtty[do not change terminal settings in text UI]' \ '-fastcheck:fast update detection:(true false default)' \ '-forcepartial[add a pattern to the forcepartial list]:pattern:' \ @@ -63,7 +63,7 @@ _arguments \ '-mountpoint[abort if this path does not exist]:mountpoint:_files -/' \ '-numericids[dont map uid/gid values by user/group names]' \ '-preferpartial[add a pattern to the preferpartial list]:pattern:' \ - '-pretendwin[Use creation times for detecting updates]' \ + '-pretendwin[use creation times for detecting updates]' \ '-repeat[synchronize repeatedly (text interface only)]:repeat:' \ '-retry[re-try failed synchronizations N times (text ui only)]:retry times:' \ '-rootalias[register alias for canonical root names]:root alias:' \ diff --git a/Completion/Unix/Command/_vim b/Completion/Unix/Command/_vim index af5afd347..7aec1ecf7 100644 --- a/Completion/Unix/Command/_vim +++ b/Completion/Unix/Command/_vim @@ -12,6 +12,9 @@ _vim_files () { esac } +local curcontext="$curcontext" state line expl +typeset -A opt_args + local arguments arguments=( @@ -46,7 +49,7 @@ arguments=( {-r,-L}'[list swap files and exit or recover from a swap file]::swap file:_vim_files -g \*.sw\?' '( -H -F)-A[start in Arabic mode]' '(-A -F)-H[start in Hebrew mode]' - '(-A -H )-H[start in Farsi mode]' + '(-A -H )-F[start in Farsi mode]' '-T[set terminal type]:::_terminals' '-u[use given vimrc file instead of default .vimrc]::rc file:_files' '-U[use given gvimrc file instead of default .gvimrc]::rc file:_files' @@ -54,7 +57,7 @@ arguments=( '-o-[number of windows to open (default: one for each file)]::window count: ' '-O-[number of windows to vertically split open (default is one for each file)]::window count: ' '-p-[number of tabs to open (default: one for each file)]::tab count: ' - '-q-[quickfix file]:*:file:_vim_files' + '(* -t)-q-[quickfix file]:*:file:_vim_files' '*--cmd[execute given command before loading any RC files]:command: ' '-c[execute given command after loading the first file]:command: ' '-S[source a session file after loading the first file]:session file:_files' @@ -76,14 +79,22 @@ arguments=( '--echo-wid[echo window ID on STDOUT, GUI version only]' '--literal[do not expand wildcards in arguments (this is useless with ZSH)]' '(- *)--serverlist[list available vim servers and exit]' - '--servername[name of vim server to send to or name of server to become]:server name: ' + '--servername[name of vim server to send to or name of server to become]:server name:->server' '--startuptime[write startup timing messages to given file]:log file:_files' '--socketid[run GVIM in another window]' '-i[use given viminfo file instead of default .viminfo]:viminfo file:_files' '(- *)'{-h,--help}'[print help and exit]' '(- *)--version[print version information and exit]' - '(*)-t[edit file where tag is defined]:tag:_complete_tag' - '(-t)*:file:_vim_files' + '(* -q)-t[edit file where tag is defined]:tag:_complete_tag' + '(-t -q)*:file:_vim_files' ) -_arguments -S $arguments +_arguments -C -S $arguments && return + +if [[ "$state" = server ]]; then + local -a servers + servers=( ${(f)"$(_call_program servers $words[1] --serverlist 2>/dev/null)"} ) + _wanted servers expl server compadd -M 'm:{a-z}={A-Z}' -a servers && return +fi + +return 1 diff --git a/Completion/Unix/Command/_wget b/Completion/Unix/Command/_wget index 54c09a377..e54a08b27 100644 --- a/Completion/Unix/Command/_wget +++ b/Completion/Unix/Command/_wget @@ -21,6 +21,7 @@ _arguments -C -s \ '--retry-connrefused[retry even if connection is refused]' \ '(--output-document -O)'{--output-document=,-O+}'[specify file to write documents to]:output file:_files' \ '(--continue -c)'{--continue,-c}'[continue getting an existing file]' \ + '--content-disposition[honor the Content-Disposition header when choosing local file names]' \ '--progress=[set progress gauge type]:gauge type:->gauge' \ '(--timestamping -N)'{--timestamping,-N}'[retrieve only files newer than existing]' \ '(--server-response -S)'{--server-response,-S}'[print server response]' \ diff --git a/Completion/Unix/Type/_path_files b/Completion/Unix/Type/_path_files index 858fe3f74..a170983ba 100644 --- a/Completion/Unix/Type/_path_files +++ b/Completion/Unix/Type/_path_files @@ -438,8 +438,19 @@ for prepath in "$prepaths[@]"; do tmp2=( "$tmp1[@]" ) - if [[ "$tpre$tsuf" = */* ]]; then - compfiles -P$cfopt tmp1 accex "$skipped" "$_matcher $matcher[2]" "$sdirs" fake + if [[ "$tpre$tsuf" = (#b)*/(*) ]]; then + + # We are going to be looping over the leading path segments. + # This means we should not apply special-dirs handling unless + # the path tail is a fake directory that needs to be simulated, + # and we should not apply pattern matching until we are looking + # for files rather than for intermediate directories. + + if [[ -n "$fake${match[1]}" ]]; then + compfiles -P$cfopt tmp1 accex "$skipped" "$_matcher $matcher[2]" "$sdirs" fake + else + compfiles -P$cfopt tmp1 accex "$skipped" "$_matcher $matcher[2]" '' fake + fi elif [[ "$sopt" = *[/f]* ]]; then compfiles -p$cfopt tmp1 accex "$skipped" "$_matcher $matcher[2]" "$sdirs" fake "$pats[@]" else diff --git a/Completion/Unix/Type/_pdf b/Completion/Unix/Type/_pdf index a2fbbc552..a2601997b 100644 --- a/Completion/Unix/Type/_pdf +++ b/Completion/Unix/Type/_pdf @@ -1,4 +1,4 @@ -#compdef pdf2dsc pdf2ps pdfimages pdfinfo pdftopbm pdftops pdftotext pdfopt pdffonts kpdf +#compdef pdf2dsc pdf2ps pdfimages pdfinfo pdftopbm pdftops pdftotext pdfopt pdffonts kpdf apvlv local expl ext='' diff --git a/Completion/Unix/Type/_perl_modules b/Completion/Unix/Type/_perl_modules index 26cab0c23..1b61043e7 100644 --- a/Completion/Unix/Type/_perl_modules +++ b/Completion/Unix/Type/_perl_modules @@ -101,7 +101,7 @@ _perl_modules () { # Find all modules if [[ -d $libdir && -x $libdir ]]; then - new_pms=( $libdir/{[A-Z]*/***/,}*${~sufpat}~*blib* ) + new_pms=( $libdir/{[A-Za-z]*/***/,}*${~sufpat}~*blib* ) new_pms=( "${(@)new_pms##$libdir/##}" ) fi diff --git a/Completion/X/Command/_matlab b/Completion/X/Command/_matlab index 64d076f43..e912b68c1 100644 --- a/Completion/X/Command/_matlab +++ b/Completion/X/Command/_matlab @@ -1,19 +1,19 @@ #compdef matlab _arguments : \ - {-h,-help}'[Display arguments.]' \ - '(-e)-n[Display final environment variables, and exit]' \ - '(-n)-e[Display ALL the environment variables and values, and exit]' \ - '-arch[Start MATLAB assuming architecture arch]:architecture:' \ - '-c[Set location of the license file]:licensefile:_files' \ + {-h,-help}'[display arguments]' \ + '(-e)-n[display final environment variables, and exit]' \ + '(-n)-e[display ALL the environment variables and values, and exit]' \ + '-arch[start MATLAB assuming architecture arch]:architecture:' \ + '-c[set location of the license file]:licensefile:_files' \ '(-nodisplay)-display:display:_x_display' \ - '(-display)-nodisplay[Do not display any X commands.]' \ - '-nosplash[Do not display the splash screen during startup.]' \ - '-mwvisual[The default X visual to use for figure windows.]:visualid:' \ - '-debug[Provide debugging information especially for X based problems.]' \ - '(-nodesktop -nojvm)-desktop[Allow the MATLAB desktop to be started by a process without a controlling terminal.]' \ - '(-desktop -nojvm)-nodesktop[Do not start the MATLAB desktop.]' \ - '(-nodesktop -desktop)-nojvm[Shut off all Java support by not starting the Java virtual machine.]' \ - '-r[Start MATLAB and execute the MATLAB_command.]:MATLAB_command:' \ - '-logfile[Make a copy of any output to the command window in file log.]:log file:' \ + '(-display)-nodisplay[do not display any X commands]' \ + '-nosplash[do not display the splash screen during startup]' \ + '-mwvisual[the default X visual to use for figure windows]:visualid:' \ + '-debug[provide debugging information especially for X based problems]' \ + '(-nodesktop -nojvm)-desktop[allow the MATLAB desktop to be started by a process without a controlling terminal]' \ + '(-desktop -nojvm)-nodesktop[do not start the MATLAB desktop]' \ + '(-nodesktop -desktop)-nojvm[shut off all Java support by not starting the Java virtual machine]' \ + '-r[start MATLAB and execute the MATLAB_command]:MATLAB_command:' \ + '-logfile[make a copy of any output to the command window in file log]:log file:' \ '-D-:debugger:_path_commands' diff --git a/Completion/X/Command/_mplayer b/Completion/X/Command/_mplayer index d3d1e6046..85c4f6d12 100644 --- a/Completion/X/Command/_mplayer +++ b/Completion/X/Command/_mplayer @@ -77,7 +77,7 @@ _x_arguments -C -s \ '-sid[turn on DVD subtitles]:language id' \ '-speed[set playback speed rate]:playback speed rate' \ '-srate[specify frequency of audio playback]:frequency (Hz)' \ - '-ss[seek to given time position]:position (hh:mm\[\:ss\])' \ + '-ss[seek to given time position]:position ([[hh\:]mm\:]ss[.sss])' \ '-sstep[specify time between displayed frames]:time (seconds)' \ -ssf:mode -stop_xscreensaver \ '-stereo:mode:((0\:stereo 1\:left\ channel 2\:right\ channel))' \ @@ -108,14 +108,14 @@ _x_arguments -C -s \ '-z[specify compression level for png output]:compression-level:((0\:no\ compression 1 2 3 4 5 6\:default\ compression 7 8 9\:max\ compression))' \ '-zoom[use software scaling, where available (use with -nofs)]' \ -zrbw -zrcrop -zrdev -zrfd -zrhelp -zrnorm -zrquality -zr{h,v}dec -zr{x,y}doff \ - '(-use-stdin)*:video file:->mfiles' + '(-use-stdin)*:video file:->mfiles' && ret=0 case "$state" in mfiles) _tags files urls while _tags; do _requested files expl 'video file' _files -g \ - "*.(#i)(asf|asx|avi|flac|flv|m1v|m2p|m2v|mjpg|mka|mkv|mov|mp3|mp4|mpe|mpeg|mpg|ogg|ogm|qt|rm|vob|wav|wma|wmv)(-.)" && ret=0 + "*.(#i)(asf|asx|avi|flac|flv|m1v|m2p|m2v|m4v|mjpg|mka|mkv|mov|mp3|mp4|mpe|mpeg|mpg|ogg|ogm|qt|rm|vob|wav|webm|wma|wmv)(-.)" && ret=0 if _requested urls; then while _next_label urls expl URL; do _urls "$expl[@]" && ret=0 diff --git a/Completion/X/Command/_okular b/Completion/X/Command/_okular index 0b81e2f9d..bfdb4de4b 100644 --- a/Completion/X/Command/_okular +++ b/Completion/X/Command/_okular @@ -4,7 +4,7 @@ local extns extns="{pdf,ps,eps,dvi}(.gz|.bz2)(#c,1)|djvu|tiff|chm|cbr|cbz" _arguments \ - '(-p --page)'{-p,--page}'[Page of the document to be shown]:page: ' \ - '--presentation[Start the document in presentation mode]' \ - '--unique[Unique instance control]' \ + '(-p --page)'{-p,--page}'[page of the document to be shown]:page: ' \ + '--presentation[start the document in presentation mode]' \ + '--unique[unique instance control]' \ "*:Okular documents:_files -g '*.(#i)($extns)(-.)'" diff --git a/Completion/Zsh/Command/_zattr b/Completion/Zsh/Command/_zattr index cdc52281d..1924bb28d 100644 --- a/Completion/Zsh/Command/_zattr +++ b/Completion/Zsh/Command/_zattr @@ -26,9 +26,9 @@ _arguments \ '1:file:_files' \ '2:parameter' ;; -esac +esac && ret=0 if [[ $state = attrs ]]; then - zlistattr $~line[1] REPLY 2> /dev/null + zlistattr ${~${(Q)line[1]}} REPLY 2> /dev/null _wanted attrs expl 'attribute' compadd $REPLY fi diff --git a/Completion/Zsh/Context/_brace_parameter b/Completion/Zsh/Context/_brace_parameter index fde6d4f0f..c0ecf251b 100644 --- a/Completion/Zsh/Context/_brace_parameter +++ b/Completion/Zsh/Context/_brace_parameter @@ -1,3 +1,190 @@ #compdef -brace-parameter- +local char delim found_percent found_m exp +local -a flags +integer q_last n_q + +if [[ $PREFIX = *'${('[^\)]# ]]; then + # Parameter flags. + compset -p 3 + + # Based on code in _globquals. + while [[ -n $PREFIX ]]; do + char=$PREFIX[1] + compset -p 1 + if [[ $char = q ]]; then + (( q_last++, n_q++ )) + continue + else + (( q_last = 0 )) + fi + # Skip arguments to find what's left to complete + case $char in + (%) + found_percent=1 + ;; + + (m) + found_m=1 + ;; + + ([gIjsZ_]) + # Single delimited argument. + if [[ -z $PREFIX ]]; then + _delimiters qualifer-$char + return + elif ! _globqual_delims; then + # still completing argument + case $char in + (g) + compset -P '*' + flags=('o:octal escapes' 'c:expand ^X etc.' 'e:expand \M-t etc.') + _describe -t format 'format option' flags -Q -S '' + ;; + + (I) + _message 'integer expression' + ;; + + (js) + _message "separator" + ;; + + (Z) + compset -P '*' + flags=( + 'c:parse comments as strings (else as ordinary words)' + 'C:strip comments (else treat as ordinary words)' + 'n:treat newlines as whitespace' + ) + _describe -t format 'format option' flags -Q -S '' + ;; + + (_) + _message "no useful values" + ;; + esac + return + fi + ;; + + ([lr]) + # One compulsory argument, two optional. + if [[ -z $PREFIX ]]; then + _delimiters qualifer-$char + return + else + delim=$PREFIX[1] + if ! _globqual_delims; then + # still completing argument + _message "padding width" + return + fi + # TBD if $PREFIX is empty can complete + # either repeat delimiter or a new qualifier. + # You might think it would just be easier + # for the user to type the delimiter at + # this stage, but users are astonishingly lazy. + if [[ $delim = $PREFIX[1] ]]; then + # second argument + if ! _globqual_delims; then + _message "repeated padding" + return + fi + if [[ $delim = $PREFIX[1] ]]; then + if ! _globqual_delims; then + _message "one-off padding" + return + fi + fi + fi + fi + ;; + esac + done + + if [[ -z $found_percent ]]; then + flags=("%:Expand prompt sequences") + else + flags=("%:Expand prompts respecting options") + fi + case $q_last in + (0) + if (( n_q == 0 )); then + flags+=("q:quote with backslashes") + fi + ;; + + (1) + flags+=( + "q:quote with single quotes" + "-:quote minimally for readability" + ) + ;; + + (2) + flags+=("q:quote with double quotes") + ;; + + (3) + flags+=("q:quote with \$'...'") + ;; + esac + if (( !n_q )); then + flags+=("Q:remove one level of quoting") + fi + if [[ -z $found_m ]]; then + flags+=("m:Count multibyte width in padding calculation") + else + flags+=("m:Count number of character code points in padding calculation") + fi + flags+=( + "#:Evaluate as numeric expression" + "@:Double-quoted splitting of scalars" + "A:Create array parameter" + "a:Sort in array index order (with O to reverse)" + "c:Count characters in an array (with \${(c)#...})" + "C:Capitalize words" + "D:Perform directory name abbreviation" + "e:Perform single-word shell expansions" + "f:Split the result on newlines" + "F:Join arrays with newlines" + "g:Process echo array sequences (needs options)" + "i:Sort case-insensitively" + "k:Subsitute keys of associative arrays" + "L:Lower case all letters" + "n:Sort decimal integers numerically" + "o:Sort in ascending order (lexically if no other sort option)" + "O:Sort in descending order (lexically if no other sort option)" + "P:Use parameter value as name of parameter for redirected lookup" + "t:Substitute type of parameter" + "u:Substitute first occurrence of each unique word" + "U:Upper case all letters" + "v:Substitute values of associative arrays (with (k))" + "V:Visibility enhancements for special characters" + "w:Count words in array or string (with \${(w)#...})" + "W:Count words including empty words (with \${(W)#...})" + "X:Report parsing errors and eXit substitution" + "z:Split words as if zsh command line" + "0:Split words on null bytes" + "p:Handle print escapes in parameter flag arguments" + "~:Treat strings in parameter flag arguments as patterns" + "j:Join arrays with specified string" + "l:Left-pad resulting words" + "r:Right-pad resulting words" + "s:Split words on specified string" + "Z:Split words as if zsh command line (with options)" + # "_:Extended flags, for future expansion" + "S:Search substrings in #, %, / expressions" + "I:Search <argument>th match in #, %, / expressions" + "B:Include index of beginning of match in #, %, / expressions" + "E:Include index of end of match in #, %, / expressions" + "M:Include matched portion in #, %, / expressions" + "N:Include length of match in #, %, expressions" + "R:Include rest (unmatched portion) in #, %, / expressions" + ) + _describe -t flags "parameter flag" flags -Q -S '' + return +fi + _parameters -e diff --git a/Completion/Zsh/Context/_subscript b/Completion/Zsh/Context/_subscript index 31da97e26..cf1ec49a4 100644 --- a/Completion/Zsh/Context/_subscript +++ b/Completion/Zsh/Context/_subscript @@ -18,7 +18,7 @@ compset -P '\(([^\(\)]|\(*\))##\)' # remove subscript flags # or colon list. integer pos=$((CURSOR+1)) while [[ pos -gt 1 && $BUFFER[pos-1] != '[' ]]; do (( pos-- )); done -if [[ $BUFFER[1,pos-1] = *[[:space:]:=]##\~\[ ]]; then +if [[ $BUFFER[1,pos-1] = (|*[[:space:]:=]##)\~\[ ]]; then _dynamic_directory_name elif [[ "$PREFIX" = :* ]]; then _wanted characters expl 'character class' \ diff --git a/Completion/Zsh/Function/_zargs b/Completion/Zsh/Function/_zargs index a4cf0a89e..f1f87b447 100644 --- a/Completion/Zsh/Function/_zargs +++ b/Completion/Zsh/Function/_zargs @@ -4,19 +4,19 @@ local arguments arguments=( $arguments[@] - '(--eof -e)'{--eof=,-e+}'[Change the end-of-input-args string from "--" to eof-str]' - '(--exit, -x)'{--exit,-x}'[Exit if the size (see --max-chars) is exceeded]' - '--help[Print summary and exit]' - '(--interactive, -p)'{--interactive,-p}'[Prompt before executing each command line]' - '(--max-args, -n)'{--max-args=,-n+}'[Use at most max-args arguments per command line]' - '(--max-chars, -s)'{--max-chars=,-s+}'[Use at most max-chars characters per command line]' - '(--max-lines, -l)'{--max-lines=,-l+}'[Use at most max-lines of the input-args per command line]' - '(--max-procs, -P)'{--max-procs=,-P+}'[Run up to max-procs command lines in the background at once]' - '(--no-run-if-empty, -r)'{--no-run-if-empty,-r}'[Do nothing if there are no input arguments before the eof-str]' - '(--null, -0)'{--null,-0}'[Split each input-arg at null bytes, for xargs compatibility]' - '(--replace, -i)'{--replace=,-i}'[Substitute replace-str in the initial-args by each initial-arg]' - '(--verbose, -t)'{--verbose,-t}'[Print each command line to stderr before executing it]' - '--version[Print the version number of zargs and exit]' + '(--eof -e)'{--eof=,-e+}'[change the end-of-input-args string from "--" to eof-str]' + '(--exit, -x)'{--exit,-x}'[exit if the size (see --max-chars) is exceeded]' + '--help[print summary and exit]' + '(--interactive, -p)'{--interactive,-p}'[prompt before executing each command line]' + '(--max-args, -n)'{--max-args=,-n+}'[use at most max-args arguments per command line]' + '(--max-chars, -s)'{--max-chars=,-s+}'[use at most max-chars characters per command line]' + '(--max-lines, -l)'{--max-lines=,-l+}'[use at most max-lines of the input-args per command line]' + '(--max-procs, -P)'{--max-procs=,-P+}'[run up to max-procs command lines in the background at once]' + '(--no-run-if-empty, -r)'{--no-run-if-empty,-r}'[do nothing if there are no input arguments before the eof-str]' + '(--null, -0)'{--null,-0}'[split each input-arg at null bytes, for xargs compatibility]' + '(--replace, -i)'{--replace=,-i}'[substitute replace-str in the initial-args by each initial-arg]' + '(--verbose, -t)'{--verbose,-t}'[print each command line to stderr before executing it]' + '--version[print the version number of zargs and exit]' ) _arguments -S -s $arguments[@] diff --git a/Completion/Zsh/Type/_file_descriptors b/Completion/Zsh/Type/_file_descriptors index 1dac47f61..3e251b733 100644 --- a/Completion/Zsh/Type/_file_descriptors +++ b/Completion/Zsh/Type/_file_descriptors @@ -13,7 +13,9 @@ if zstyle -T ":completion:${curcontext}:" verbose && [[ -h /proc/$$/fd/$fds[1] ] list+=( "$i $sep ${link[1]}" ) done elif (( $+commands[readlink] )); then - for i in "${fds[@]}"; list+=( "$i $sep $(readlink /proc/$$/fd/$i)" ) + for i in "${fds[@]}"; do + list+=( "$i $sep $(readlink /proc/$$/fd/$i)" ) + done else for i in "${fds[@]}"; do list+=( "$i $sep $(ls -l /proc/$$/fd/$i|sed 's/.*-> //' )" ) diff --git a/Completion/compaudit b/Completion/compaudit index 7107c2fff..72e0b62ba 100644 --- a/Completion/compaudit +++ b/Completion/compaudit @@ -82,19 +82,6 @@ fi [[ $_i_fail == use ]] && return 0 -# RedHat Linux "per-user groups" check. This is tricky, because it's very -# difficult to tell whether the sysadmin has put someone else into your -# "private" group (e.g., via the default group field in /etc/passwd, or -# by NFS group sharing with an untrustworthy machine). So we must assume -# that this has not happened, and pick the best group. - -local GROUP GROUPMEM _i_pw _i_gid _i_ulwdirs -if ((UID == EUID )); then - getent group $LOGNAME | IFS=: read GROUP _i_pw _i_gid GROUPMEM -else - getent group $EGID | IFS=: read GROUP _i_pw _i_gid GROUPMEM -fi - # We search for: # - world/group-writable directories in fpath not owned by root and the user # - parent-directories of directories in fpath that are world/group-writable @@ -105,18 +92,34 @@ fi # - and for files in directories from fpath not owned by root and the user # (including zwc files) -if [[ $GROUP == $LOGNAME && ( -z $GROUPMEM || $GROUPMEM == $LOGNAME ) ]]; then - _i_wdirs=( ${^fpath}(N-f:g+w:^g:${GROUP}:,-f:o+w:,-^u0u${EUID}) - ${^fpath:h}(N-f:g+w:^g:${GROUP}:,-f:o+w:,-^u0u${EUID}) ) -else - _i_wdirs=( ${^fpath}(N-f:g+w:,-f:o+w:,-^u0u${EUID}) - ${^fpath:h}(N-f:g+w:,-f:o+w:,-^u0u${EUID}) ) +_i_wdirs=( ${^fpath}(N-f:g+w:,-f:o+w:,-^u0u${EUID}) + ${^fpath:h}(N-f:g+w:,-f:o+w:,-^u0u${EUID}) ) + +# RedHat Linux "per-user groups" check. This is tricky, because it's very +# difficult to tell whether the sysadmin has put someone else into your +# "private" group (e.g., via the default group field in /etc/passwd, or +# by NFS group sharing with an untrustworthy machine). So we must assume +# that this has not happened, and pick the best group. + +if (( $#_i_wdirs )); then + local GROUP GROUPMEM _i_pw _i_gid + if ((UID == EUID )); then + getent group $LOGNAME | IFS=: read GROUP _i_pw _i_gid GROUPMEM + else + getent group $EGID | IFS=: read GROUP _i_pw _i_gid GROUPMEM + fi + + if [[ $GROUP == $LOGNAME && ( -z $GROUPMEM || $GROUPMEM == $LOGNAME ) ]] + then + _i_wdirs=( ${^_i_wdirs}(N-f:g+w:^g:${GROUP}:,-f:o+w:,-^u0u${EUID}) ) + fi fi if [[ -f /etc/debian_version ]] then -_i_ulwdirs=( ${(M)_i_wdirs:#/usr/local/*} ) -_i_wdirs=( ${_i_wdirs:#/usr/local/*} ${^_i_ulwdir}(Nf:g+ws:^g:staff:,f:o+w:,^u0) ) + local _i_ulwdirs + _i_ulwdirs=( ${(M)_i_wdirs:#/usr/local/*} ) + _i_wdirs=( ${_i_wdirs:#/usr/local/*} ${^_i_ulwdirs}(Nf:g+ws:^g:staff:,f:o+w:,^u0) ) fi _i_wdirs=( $_i_wdirs ${^fpath}.zwc^([^_]*|*~)(N-^u0u${EUID}) ) diff --git a/Completion/compinit b/Completion/compinit index a0f2348a9..d25642e5d 100644 --- a/Completion/compinit +++ b/Completion/compinit @@ -161,7 +161,7 @@ _comp_options=( # and don't get confused by user's ZERR trap handlers. typeset -g _comp_setup='local -A _comp_caller_options; - _comp_caller_options=(${(kv)options}); + _comp_caller_options=(${(kv)options[@]}); setopt localoptions localtraps ${_comp_options[@]}; local IFS=$'\'\ \\t\\r\\n\\0\'' exec </dev/null; diff --git a/Config/version.mk b/Config/version.mk index 37193970a..adde27080 100644 --- a/Config/version.mk +++ b/Config/version.mk @@ -27,5 +27,5 @@ # This must also serve as a shell script, so do not add spaces around the # `=' signs. -VERSION=4.3.12 -VERSION_DATE='May 31, 2011' +VERSION=4.3.13 +VERSION_DATE='November 30, 2011' diff --git a/Doc/Makefile.in b/Doc/Makefile.in index f7f5915c1..d30149da0 100644 --- a/Doc/Makefile.in +++ b/Doc/Makefile.in @@ -59,7 +59,7 @@ Zsh/mod_attr.yo Zsh/mod_cap.yo Zsh/mod_clone.yo \ Zsh/mod_compctl.yo Zsh/mod_complete.yo Zsh/mod_complist.yo \ Zsh/mod_computil.yo Zsh/mod_curses.yo \ Zsh/mod_datetime.yo Zsh/mod_deltochar.yo \ -Zsh/mod_example.yo Zsh/mod_files.yo \ +Zsh/mod_example.yo Zsh/mod_files.yo Zsh/mod_langinfo.yo \ Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo Zsh/mod_newuser.yo \ Zsh/mod_parameter.yo Zsh/mod_pcre.yo Zsh/mod_regex.yo \ Zsh/mod_sched.yo Zsh/mod_socket.yo \ diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 7170b13b9..5d717479a 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -914,7 +914,7 @@ and the new directory stack is not printed. This is useful for calls to tt(popd) that do not change the environment seen by an interactive user. ) findex(print) -xitem(tt(print) [ tt(-abcDilmnNoOpPrsz) ] [ tt(-u) var(n) ] [ tt(-f) var(format) ] [ tt(-C) var(cols) ]) +xitem(tt(print) [ tt(-abcDilmnNoOpPrsSz) ] [ tt(-u) var(n) ] [ tt(-f) var(format) ] [ tt(-C) var(cols) ]) item( [ tt(-R) [ tt(-en) ]] [ var(arg) ... ])( With the `tt(-f)' option the arguments are printed as described by tt(printf). With no flags or with the flag `tt(-)', the arguments are printed on @@ -994,6 +994,15 @@ tt(-R); all other arguments and options are printed. ) item(tt(-s))( Place the results in the history list instead of on the standard output. +Each argument to the tt(print) command is treated as a single word in the +history, regardless of its content. +) +item(tt(-S))( +Place the results in the history list instead of on the standard output. +In this case only a single argument is allowed; it will be split into +words as if it were a full shell command line. The effect is +similar to reading the line from a history file with the +tt(HIST_LEX_WORDS) option active. ) item(tt(-u) var(n))( Print the arguments to file descriptor var(n). diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index ad2562a26..e07ac0e9e 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -1085,7 +1085,7 @@ Some of these styles are tested first for every possible tag corresponding to a type of match, and if no style was found, for the tt(default) tag. The most notable styles of this type are tt(menu), tt(list-colors) and styles controlling completion listing such as -tt(list-packed) and tt(last-prompt)). When tested for the tt(default) +tt(list-packed) and tt(last-prompt). When tested for the tt(default) tag, only the var(function) field of the context will be set so that a style using the default tag will normally be defined along the lines of: @@ -1684,8 +1684,8 @@ will be considered as possible completions. If it is set to `tt(current)', the word the cursor is on will not be considered as a possible completion. The value `tt(current-shown)' is similar but only applies if the list of completions is currently shown on the screen. -Finally, if the style is set to `tt(other)', no word apart from the -current one will be considered as a possible completion. +Finally, if the style is set to `tt(other)', all words on the line except +for the current one will be excluded from the possible completions. The values `tt(current)' and `tt(current-shown)' are a bit like the opposite of the tt(accept-exact) style: only strings with @@ -4387,7 +4387,9 @@ tt(ambiguous), tt(special-dirs), tt(list-suffixes) and tt(file-sort) described above. ) findex(_pick_variant) -item(tt(_pick_variant [ tt(-c) var(command) ] [ tt(-r) var(name) ] var(label)tt(=)var(pattern) ... var(label) [ var(args) ... ]))( +xitem(tt(_pick_variant) [ tt(-b) var(builtin-label) ] [ tt(-c) +var(command) ] [ tt(-r) var(name) ]) +item( var(label)tt(=)var(pattern) ... var(label) [ var(args) ... ])( This function is used to resolve situations where a single command name requires more than one type of handling, either because it has more than one variant or because there is a name clash between two @@ -4403,6 +4405,10 @@ tt(...)' contains var(pattern), then tt(label) is selected as the label for the command variant. If none of the patterns match, the final command label is selected and status 1 is returned. +If the `tt(-b) var(builtin-label)' is given, the command is tested to +see if it is provided as a shell builtin, possibly autoloaded; if so, +the label var(builtin-label) is selected as the label for the variant. + If the `tt(-r) var(name)' is given, the var(label) picked is stored in the parameter named var(name). diff --git a/Doc/Zsh/compwid.yo b/Doc/Zsh/compwid.yo index 3042fa373..37a568f58 100644 --- a/Doc/Zsh/compwid.yo +++ b/Doc/Zsh/compwid.yo @@ -162,7 +162,10 @@ this case the tt(words) array contains the words inside the parentheses. ) item(tt(brace_parameter))( when completing the name of a parameter in a parameter expansion beginning -with tt(${). +with tt(${). This context will also be set when completing parameter +flags following tt(${LPAR()); the full command line argument is presented +and the handler must test the value to be completed to ascertain that +this is the case. ) item(tt(assign_parameter))( when completing the name of a parameter in a parameter assignment. diff --git a/Doc/Zsh/cond.yo b/Doc/Zsh/cond.yo index 489ee356b..71971b4b3 100644 --- a/Doc/Zsh/cond.yo +++ b/Doc/Zsh/cond.yo @@ -184,7 +184,7 @@ enditem() Normal shell expansion is performed on the var(file), var(string) and var(pattern) arguments, but the result of each expansion is constrained to be a single word, similar to the effect of double quotes. -File generation is not performed on any form of argument to conditions. +Filename generation is not performed on any form of argument to conditions. However, pattern metacharacters are active for the var(pattern) arguments; the patterns are the same as those used for filename generation, see ifzman(\ diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index cf42e28a9..aee0bd7f4 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -614,7 +614,7 @@ There is also support for the patch management system tt(quilt) (http://savannah.nongnu.org/projects/quilt). See tt(Quilt Support) below for details. -To load var(vcs_info): +To load tt(vcs_info): example(autoload -Uz vcs_info) @@ -624,21 +624,21 @@ tt($psvar) entries to be left available. subsect(Quickstart) To get this feature working quickly (including colors), you can do the -following (assuming, you loaded var(vcs_info) properly - see above): +following (assuming, you loaded tt(vcs_info) properly - see above): -example(zstyle ':vcs_info:*' actionformats \ +example(zstyle ':vcs_info:*' actionformats \ '%F{5}(%f%s%F{5})%F{3}-%F{5}[%F{2}%b%F{3}|%F{1}%a%F{5}]%f ' -zstyle ':vcs_info:*' formats \ +zstyle ':vcs_info:*' formats \ '%F{5}(%f%s%F{5})%F{3}-%F{5}[%F{2}%b%F{5}]%f ' zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat '%b%F{1}:%F{3}%r' precmd () { vcs_info } PS1='%F{5}[%F{2}%n%F{5}] %F{3}%3~ ${vcs_info_msg_0_}%f%# ') Obviously, the last two lines are there for demonstration. You need to -call var(vcs_info) from your var(precmd) function. Once that is done you need -a tt(single quoted) var('${vcs_info_msg_0_}') in your prompt. +call tt(vcs_info) from your tt(precmd) function. Once that is done you need +a tt(single quoted) tt('${vcs_info_msg_0_}') in your prompt. -To be able to use var('${vcs_info_msg_0_}') directly in your prompt like +To be able to use tt('${vcs_info_msg_0_}') directly in your prompt like this, you will need to have the tt(PROMPT_SUBST) option enabled. Now call the tt(vcs_info_printsys) utility from the command line: @@ -678,54 +678,55 @@ You may also pick a few from that list and enable only those: example(zstyle ':vcs_info:*' enable git cvs svn) If you rerun tt(vcs_info_printsys) after one of these commands, you will -see the backends listed in the var(disable) style (or backends not in the -var(enable) style - if you used that) marked as disabled by a hash sign. -That means the detection of these systems is skipped tt(completely). No +see the backends listed in the tt(disable) style (or backends not in the +tt(enable) style - if you used that) marked as disabled by a hash sign. +That means the detection of these systems is skipped em(completely). No wasted time there. subsect(Configuration) -The var(vcs_info) feature can be configured via var(zstyle). +The tt(vcs_info) feature can be configured via tt(zstyle). First, the context in which we are working: -example(:vcs_info:<vcs-string>:<user-context>:<repo-root-name>) +example(:vcs_info:var(vcs-string):var(user-context):var(repo-root-name)) startitem() -item(tt(<vcs-string>))( -is one of: git, git-svn, git-p4, hg, hg-git, hg-hgsubversion, hg-hgsvn, -darcs, bzr, cdv, mtn, svn, cvs, svk, tla, p4 or fossil. When hooks are -active the hooks name is added after a `+'. (See tt(Hooks in vcs_info) +item(var(vcs-string))( +is one of: bf(git), bf(git-svn), bf(git-p4), bf(hg), bf(hg-git), +bf(hg-hgsubversion), bf(hg-hgsvn), bf(darcs), bf(bzr), bf(cdv), bf(mtn), +bf(svn), bf(cvs), bf(svk), bf(tla), bf(p4) or bf(fossil). When hooks are +active the hooks name is added after a `+'. (See bf(Hooks in vcs_info) below.) ) -item(tt(<user-context>))( +item(var(user-context))( is a freely configurable string, assignable by -the user as the first argument to var(vcs_info) (see its description +the user as the first argument to tt(vcs_info) (see its description below). ) -item(tt(<repo-root-name>))( +item(var(repo-root-name))( is the name of a repository in which you want a -style to match. So, if you want a setting specific to var(/usr/src/zsh), -with that being a CVS checkout, you can set tt(<repo-root-name>) to -var(zsh) to make it so. +style to match. So, if you want a setting specific to tt(/usr/src/zsh), +with that being a CVS checkout, you can set var(repo-root-name) to +tt(zsh) to make it so. ) enditem() -There are three special values for tt(<vcs-string>): The first is named -var(-init-), that is in effect as long as there was no decision what VCS -backend to use. The second is var(-preinit-); it is used tt(before) -var(vcs_info) is run, when initializing the data exporting variables. The -third special value is var(formats) and is used by the tt(vcs_info_lastmsg) +There are three special values for var(vcs-string): The first is named +tt(-init-), that is in effect as long as there was no decision what VCS +backend to use. The second is tt(-preinit-); it is used em(before) +tt(vcs_info) is run, when initializing the data exporting variables. The +third special value is tt(formats) and is used by the tt(vcs_info_lastmsg) for looking up its styles. -The initial value of tt(<repo-root-name>) is var(-all-) and it is replaced +The initial value of var(repo-root-name) is tt(-all-) and it is replaced with the actual name, as soon as it is known. Only use this part of the -context for defining the var(formats), var(actionformats) or -var(branchformat) styles, as it is guaranteed that tt(<repo-root-name>) is +context for defining the tt(formats), tt(actionformats) or +tt(branchformat) styles, as it is guaranteed that var(repo-root-name) is set up correctly for these only. For all other styles, just use tt('*') instead. -There are two pre-defined values for tt(<user-context>): +There are two pre-defined values for var(user-context): startsitem() sitem(tt(default))(the one used if none is specified) sitem(tt(command))(used by vcs_info_lastmsg to lookup its styles) @@ -750,15 +751,15 @@ a merge conflict. ) kindex(branchformat) item(tt(branchformat))( -Some backends replace var(%b) in the formats and +Some backends replace tt(%b) in the formats and actionformats styles above, not only by a branch name but also by a revision number. This style lets you modify how that string should look. ) kindex(nvcsformats) item(tt(nvcsformats))( These "formats" are exported when we didn't detect a version control system -for the current directory or var(vcs_info) was disabled. This is useful if -you want var(vcs_info) to completely take over the generation of your +for the current directory or tt(vcs_info) was disabled. This is useful if +you want tt(vcs_info) to completely take over the generation of your prompt. You would do something like tt(PS1='${vcs_info_msg_0_}') to accomplish that. ) @@ -766,36 +767,36 @@ kindex(hgrevformat) item(tt(hgrevformat))( tt(hg) uses both a hash and a revision number to reference a specific changeset in a repository. With this style you can format the revision -string (see var(branchformat)) to include either or both. It's only -useful when var(get-revision) is true. +string (see tt(branchformat)) to include either or both. It's only +useful when tt(get-revision) is true. ) kindex(max-exports) item(tt(max-exports))( Defines the maximum number of -var(vcs_info_msg_*_) variables var(vcs_info) will export. +tt(vcs_info_msg_*_) variables tt(vcs_info) will export. ) kindex(enable) item(tt(enable))( -A list of backends you want to use. Checked in the var(-init-) context. If +A list of backends you want to use. Checked in the tt(-init-) context. If this list contains an item called tt(NONE) no backend is used at all and -var(vcs_info) will do nothing. If this list contains tt(ALL) var(vcs_info) +tt(vcs_info) will do nothing. If this list contains tt(ALL), tt(vcs_info) will use all known backends. Only with tt(ALL) in tt(enable) will the tt(disable) style have any effect. tt(ALL) and tt(NONE) are case insensitive. ) kindex(disable) item(tt(disable))( -A list of VCSs you don't want var(vcs_info) to test for -repositories (checked in the var(-init-) context, too). Only used if +A list of VCSs you don't want tt(vcs_info) to test for +repositories (checked in the tt(-init-) context, too). Only used if tt(enable) contains tt(ALL). ) kindex(disable-patterns) item(tt(disable-patterns))( A list of patterns that are checked against tt($PWD). If a pattern -matches, var(vcs_info) will be disabled. This style is checked in the -var(:vcs_info:-init-:*:-all-) context. +matches, tt(vcs_info) will be disabled. This style is checked in the +tt(:vcs_info:-init-:*:-all-) context. Say, tt(~/.zsh) is a directory under version control, in which you do -not want var(vcs_info) to be active, do: +not want tt(vcs_info) to be active, do: example(zstyle ':vcs_info:*' disable-patterns "$HOME/.zsh+LPAR()|/*+RPAR()") ) kindex(use-quilt) @@ -810,7 +811,7 @@ in a given directory. See tt(Quilt Support) for details. ) kindex(quilt-patch-dir) item(tt(quilt-patch-dir))( -Overwrite the value of the var($QUILT_PATCHES) environment variable. See +Overwrite the value of the tt($QUILT_PATCHES) environment variable. See tt(Quilt Support) for details. ) kindex(quiltcommand) @@ -822,12 +823,12 @@ kindex(check-for-changes) item(tt(check-for-changes))( If enabled, this style causes the tt(%c) and tt(%u) format escapes to show when the working directory has uncommitted changes. The strings displayed by -these escapes can be controlled via the var(stagedstr) and var(unstagedstr) +these escapes can be controlled via the tt(stagedstr) and tt(unstagedstr) styles. The only backends that currently support this option are tt(git) and tt(hg) (tt(hg) only supports unstaged). -For this style to be evaluated with the tt(hg) backend, the var(get-revision) -style needs to be set and the var(use-simple) style needs to be unset. The +For this style to be evaluated with the tt(hg) backend, the tt(get-revision) +style needs to be set and the tt(use-simple) style needs to be unset. The latter is the default; the former is not. Note, the actions taken if this style is enabled are potentially expensive @@ -846,19 +847,19 @@ in the repository. ) kindex(command) item(tt(command))( -This style causes var(vcs_info) to use the supplied string as the command +This style causes tt(vcs_info) to use the supplied string as the command to use as the VCS's binary. Note, that setting this in ':vcs_info:*' is not a good idea. If the value of this style is empty (which is the default), the used binary -name is the name of the backend in use (e.g. var(svn) is used in an var(svn) +name is the name of the backend in use (e.g. tt(svn) is used in an tt(svn) repository). -The var(repo-root-name) part in the context is always the default tt(-all-) +The tt(repo-root-name) part in the context is always the default tt(-all-) when this style is looked up. For example, this style can be used to use binaries from non-default -installation directories. Assume, var(git) is installed in /usr/bin but +installation directories. Assume, tt(git) is installed in /usr/bin but your sysadmin installed a newer version in /usr/bin/local. Instead of changing the order of your tt($PATH) parameter, you can do this: example(zstyle ':vcs_info:git:*:-all-' command /usr/local/bin/git) @@ -869,7 +870,7 @@ This is used by the Perforce backend (tt(p4)) to decide if it should contact the Perforce server to find out if a directory is managed by Perforce. This is the only reliable way of doing this, but runs the risk of a delay if the server name cannot be found. If the -server (more specifically, the var(host)tt(:)var(port) pair describing the +server (more specifically, the tt(host)tt(:)tt(port) pair describing the server) cannot be contacted, its name is put into the associative array tt(vcs_info_p4_dead_servers) and is not contacted again during the session until it is removed by hand. If you do not set this style, the tt(p4) @@ -910,17 +911,17 @@ bookmarks. They will be available via the `tt(%m)' replacement. kindex(use-prompt-escapes) item(tt(use-prompt-escapes))( Determines if we assume that the assembled -string from var(vcs_info) includes prompt escapes. (Used by +string from tt(vcs_info) includes prompt escapes. (Used by tt(vcs_info_lastmsg).) ) kindex(debug) item(tt(debug))( Enable debugging output to track possible problems. Currently this style -is only used by var(vcs_info)'s hooks system. +is only used by tt(vcs_info)'s hooks system. ) kindex(hooks) item(tt(hooks))( -A list style that defines hook-function names. See tt(Hooks in vcs_info) +A list style that defines hook-function names. See bf(Hooks in vcs_info) below for details. ) enditem() @@ -951,7 +952,7 @@ sitem(tt(debug))(false) sitem(tt(hooks))((empty list)) sitem(tt(use-quilt))(false) sitem(tt(quilt-standalone))(false) -sitem(tt(quilt-patch-dir))(empty - use var($QUILT_PATCHES)) +sitem(tt(quilt-patch-dir))(empty - use tt($QUILT_PATCHES)) sitem(tt(quiltcommand))(quilt) endsitem() @@ -962,18 +963,18 @@ startsitem() sitem(tt(%s))(The VCS in use (git, hg, svn, etc.).) sitem(tt(%b))(Information about the current branch.) sitem(tt(%a))(An identifier that describes the action. Only makes sense in -var(actionformats).) +tt(actionformats).) sitem(tt(%i))(The current revision number or identifier. For tt(hg) -the var(hgrevformat) style may be used to customize the output.) -sitem(tt(%c))(The string from the var(stagedstr) style if there are staged +the tt(hgrevformat) style may be used to customize the output.) +sitem(tt(%c))(The string from the tt(stagedstr) style if there are staged changes in the repository.) -sitem(tt(%u))(The string from the var(unstagedstr) style if there are +sitem(tt(%u))(The string from the tt(unstagedstr) style if there are unstaged changes in the repository.) sitem(tt(%R))(The base directory of the repository.) -sitem(tt(%r))(The repository name. If tt(%R) is var(/foo/bar/repoXY), tt(%r) -is var(repoXY).) +sitem(tt(%r))(The repository name. If tt(%R) is tt(/foo/bar/repoXY), tt(%r) +is tt(repoXY).) sitem(tt(%S))(A subdirectory within a repository. If tt($PWD) is -var(/foo/bar/repoXY/beer/tasty), tt(%S) is var(beer/tasty).) +tt(/foo/bar/repoXY/beer/tasty), tt(%S) is tt(beer/tasty).) sitem(tt(%m))(A "misc" replacement. It is at the discretion of the backend to decide what this replacement expands to. It is currently used by the tt(hg) and tt(git) backends to display patch information from the tt(mq) and @@ -984,7 +985,7 @@ In tt(branchformat) these replacements are done: startsitem() sitem(tt(%b))(The branch name.) -sitem(tt(%r))(The current revision number or the var(hgrevformat) style for +sitem(tt(%r))(The current revision number or the tt(hgrevformat) style for tt(hg).) endsitem() @@ -1011,18 +1012,18 @@ no replacements are performed at all, it is just a string. subsect(Oddities) -If you want to use the tt(%b) (bold off) prompt expansion in var(formats), -which expands tt(%b) itself, use tt(%%b). That will cause the var(vcs_info) +If you want to use the tt(%b) (bold off) prompt expansion in tt(formats), +which expands tt(%b) itself, use tt(%%b). That will cause the tt(vcs_info) expansion to replace tt(%%b) with tt(%b), so that zsh's prompt expansion mechanism can handle it. Similarly, to hand down tt(%b) from -var(branchformat), use tt(%%%%b). Sorry for this inconvenience, but it +tt(branchformat), use tt(%%%%b). Sorry for this inconvenience, but it cannot be easily avoided. Luckily we do not clash with a lot of prompt expansions and this only needs to be done for those. subsect(Quilt Support) -tt(Quilt) is not a version control system, therefore this is not implemented +bf(Quilt) is not a version control system, therefore this is not implemented as a backend. It can help keeping track of a series of patches. People use it to keep a set of changes they want to use on top of software packages (which is tightly integrated into the package build process - the Debian project @@ -1030,63 +1031,63 @@ does this for a large number of packages). Quilt can also help individual developers keep track of their own patches on top of real version control systems. -The var(vcs_info) integration tries to support both ways of using quilt by +The tt(vcs_info) integration tries to support both ways of using quilt by having two slightly different modes of operation: `addon' mode and `standalone' mode). -For `addon' mode to become active var(vcs_info) must have already detected a +For `addon' mode to become active tt(vcs_info) must have already detected a real version control system controlling the directory. If that is the case, a directory that holds quilt's patches needs to be found. That directory is -configurable via the var(`QUILT_PATCHES') environment variable. If that -variable exists its value is used, otherwise the value tt(`patches') is -assumed. The value from var($QUILT_PATCHES) can be overwritten using the -tt(`quilt-patches') style. (Note: you can use var(vcs_info) to keep the value -of var($QUILT_PATCHES) correct all the time via the tt(post-quilt) hook). +configurable via the `tt(QUILT_PATCHES)' environment variable. If that +variable exists its value is used, otherwise the value `tt(patches)' is +assumed. The value from tt($QUILT_PATCHES) can be overwritten using the +tt(`quilt-patches') style. (Note: you can use tt(vcs_info) to keep the value +of tt($QUILT_PATCHES) correct all the time via the tt(post-quilt) hook). When the directory in question is found, quilt is assumed to be active. To -gather more information, var(vcs_info) looks for a directory called `.pc'; +gather more information, tt(vcs_info) looks for a directory called `.pc'; Quilt uses that directory to track its current state. If this directory does not exist we know that quilt has not done anything to the working directory (read: no patches have been applied yet). -If patches are applied, var(vcs_info) will try to find out which. If you want +If patches are applied, tt(vcs_info) will try to find out which. If you want to know which patches of a series are not yet applied, you need to activate the tt(get-unapplied) style in the appropriate context. -var(vcs_info) allows for very detailed control over how the gathered -information is presented (see the below sections, tt(Styles) and tt(Hooks in +tt(vcs_info) allows for very detailed control over how the gathered +information is presented (see the below sections, bf(Styles) and bf(Hooks in vcs_info)), all of which are documented below. Note there are a number of other patch tracking systems that work on top of a certain version control -system (like tt(stgit) for tt(git), or tt(mq) for tt(hg)); the configuration -for systems like that are generally configured the same way as the tt(quilt) +system (like tt(stgit) for bf(git), or tt(mq) for bf(hg)); the configuration +for systems like that are generally configured the same way as the bf(quilt) support. -If the tt(quilt) support is working in `addon' mode, the produced string is -available as a simple format replacement (var(%Q) to be precise), which can +If the bf(quilt) support is working in `addon' mode, the produced string is +available as a simple format replacement (tt(%Q) to be precise), which can be used in tt(formats) and tt(actionformats); see below for details). If, on the other hand, the support code is working in `standalone' mode, -var(vcs_info) will pretend as if tt(quilt) were an actual version control +tt(vcs_info) will pretend as if tt(quilt) were an actual version control system. That means that the version control system identifier (which otherwise would be something like `svn' or `cvs') will be set to `tt(-quilt-)'. This has implications on the used style context where this -identifier is the second element. var(vcs_info) will have filled in a proper +identifier is the second element. tt(vcs_info) will have filled in a proper value for the "repository's" root directory and the string containing the information about quilt's state will be available as the `misc' replacement -(and var(%Q) for compatibility with `addon' mode. +(and tt(%Q) for compatibility with `addon' mode. What is left to discuss is how `standalone' mode is detected. The detection itself is a series of searches for directories. You can have this detection enabled all the time in every directory that is not otherwise under version control. If you know there is only a limited set of trees where you would -like var(vcs_info) to try and look for Quilt in `standalone' mode to minimise -the amount of searching on every call to var(vcs_info), there are a number of +like tt(vcs_info) to try and look for Quilt in `standalone' mode to minimise +the amount of searching on every call to tt(vcs_info), there are a number of ways to do that: Essentially, `standalone' mode detection is controlled by a style called `tt(quilt-standalone)'. It is a string style and its value can have different effects. The simplest values are: `tt(always)' to run detection every time -var(vcs_info) is run, and `tt(never)' to turn the detection off entirely. +tt(vcs_info) is run, and `tt(never)' to turn the detection off entirely. If the value of tt(quilt-standalone) is something else, it is interpreted differently. If the value is the name of a scalar variable the value of that @@ -1115,10 +1116,10 @@ startitem() findex(vcs_info) item(tt(vcs_info) [var(user-context)])( The main function, that runs all backends and assembles all data into -var(${vcs_info_msg_*_}). This is the function you want to call from +tt(${vcs_info_msg_*_}). This is the function you want to call from tt(precmd) if you want to include up-to-date information in your prompt (see tt(Variable description) below). If an argument is given, that string will be -used instead of tt(default) in the tt(user-context) field of the style +used instead of tt(default) in the var(user-context) field of the style context. ) findex(vcs_info_hookadd) @@ -1126,7 +1127,7 @@ item(tt(vcs_info_hookadd))( Statically registers a number of functions to a given hook. The hook needs to be given as the first argument; what follows is a list of hook-function names to register to the hook. The `tt(+vi-)' prefix needs to be left out -here. See tt(Hooks in vcs_info) below for details. +here. See bf(Hooks in vcs_info) below for details. ) findex(vcs_info_hookdel) item(tt(vcs_info_hookdel))( @@ -1136,24 +1137,24 @@ names to un-register from the hook. If `tt(-a)' is used as the first argument, tt(all) occurances of the functions are unregistered. Otherwise only the last occurance is removed (if a function was registered to a hook more than once) . The `tt(+vi-)' prefix needs to be left out here. See -tt(Hooks in vcs_info) below for details. +bf(Hooks in vcs_info) below for details. ) findex(vcs_info_lastmsg) item(tt(vcs_info_lastmsg))( -Outputs the last var(${vcs_info_msg_*_}) value. +Outputs the last tt(${vcs_info_msg_*_}) value. Takes into account the value of the tt(use-prompt-escapes) style in -var(':vcs_info:formats:command:-all-'). It also only prints tt(max-exports) +tt(':vcs_info:formats:command:-all-'). It also only prints tt(max-exports) values. ) findex(vcs_info_printsys) item(tt(vcs_info_printsys) [var(user-context)])( Prints a list of all supported version control systems. Useful to find out possible contexts -(and which of them are enabled) or values for the var(disable) style. +(and which of them are enabled) or values for the tt(disable) style. ) findex(vcs_info_setsys) item(tt(vcs_info_setsys))( -Initializes var(vcs_info)'s internal list of +Initializes tt(vcs_info)'s internal list of available backends. With this function, you can add support for new VCSs without restarting the shell. ) @@ -1164,15 +1165,15 @@ All functions named VCS_INFO_* are for internal use only. subsect(Variable Description) startitem() -item(tt(${vcs_info_msg_N_}) (Note the trailing underscore)) +item(tt(${vcs_info_msg_)var(N)tt(_}) (Note the trailing underscore)) ( -Where var(N) is an integer, e.g., var(vcs_info_msg_0_). These variables -are the storage for the informational message the last var(vcs_info) call +Where var(N) is an integer, e.g., tt(vcs_info_msg_0_). These variables +are the storage for the informational message the last tt(vcs_info) call has assembled. These are strongly connected to the tt(formats), tt(actionformats) and tt(nvcsformats) styles described above. Those styles are lists. The first member of that list gets expanded into -var(${vcs_info_msg_0_}), the second into var(${vcs_info_msg_1_}) -and the Nth into var(${vcs_info_msg_N-1_}). These parameters are +tt(${vcs_info_msg_0_}), the second into tt(${vcs_info_msg_1_}) +and the Nth into tt(${vcs_info_msg_N-1_}). These parameters are exported into the environment. (See the tt(max-exports) style above.) ) enditem() @@ -1181,12 +1182,12 @@ All variables named VCS_INFO_* are for internal use only. subsect(Hooks in vcs_info) -Hooks are places in var(vcs_info) where you can run your own code. That +Hooks are places in tt(vcs_info) where you can run your own code. That code can communicate with the code that called it and through that, change the system's behaviour. For configuration, hooks change the style context: -example(:vcs_info:<vcs-string>+<hook-name>:<user-context>:<repo-root-name>) +example(:vcs_info:var(vcs-string)PLUS()var(hook-name):var(user-context):var(repo-root-name)) To register functions to a hook, you need to list them in the tt(hooks) style in the appropriate context. @@ -1200,8 +1201,8 @@ a `+vi-', so the actual functions called for the `foo' hook are `tt(+vi-bar)' and `tt(+vi-baz)'. If you would like to register a function to a hook regardless of the -current context, you may use the var(vcs_info_hookadd) function. To remove -a function that was added like that, the var(vcs_info_hookdel) function +current context, you may use the tt(vcs_info_hookadd) function. To remove +a function that was added like that, the tt(vcs_info_hookdel) function can be used. If something seems weird, you can enable the `debug' boolean style in @@ -1212,7 +1213,7 @@ When you register more than one function to a hook, all functions are executed one after another until one function returns non-zero or until all functions have been called. Context-sensitive hook functions are executed tt(before) statically registered ones (the ones added by -var(vcs_info_hookadd)). +tt(vcs_info_hookadd)). You may pass data between functions via an associative array, tt(user_data). For example: @@ -1251,10 +1252,10 @@ Finally, the full list of currently available hooks: startitem() item(tt(start-up))( -Called after starting var(vcs_info) but before the VCS in this directory is -determined. It can be used to deactivate var(vcs_info) temporarily if -necessary. When tt(ret) is set to var(1), var(vcs_info) aborts and does -nothing; when set to var(2), var(vcs_info) sets up everything as if no +Called after starting tt(vcs_info) but before the VCS in this directory is +determined. It can be used to deactivate tt(vcs_info) temporarily if +necessary. When tt(ret) is set to tt(1), tt(vcs_info) aborts and does +nothing; when set to tt(2), tt(vcs_info) sets up everything as if no version control were active and exits. ) item(tt(pre-get-data))( @@ -1265,40 +1266,40 @@ Called in the Mercurial backend when a bookmark string is generated; the tt(get-revision) and tt(get-bookmarks) styles must be true. This hook gets the names of the Mercurial bookmarks that -var(vcs_info) collected from `hg'. +tt(vcs_info) collected from `hg'. When setting tt(ret) to non-zero, the string in -tt(${hook_com[hg-bookmark-string]}) will be used in the var(%m) escape in +tt(${hook_com[hg-bookmark-string]}) will be used in the tt(%m) escape in tt(formats) and tt(actionformats) and will be availabe in the global -var(backend_misc) array as tt(${backend_misc[bookmarks]}). +tt(backend_misc) array as tt(${backend_misc[bookmarks]}). ) item(tt(gen-applied-string))( Called in the tt(git) (with tt(stgit)), and tt(hg) (with tt(mq)) backends -and in tt(quilt) support when the var(applied-string) is generated; the +and in tt(quilt) support when the tt(applied-string) is generated; the tt(use-quilt) zstyle must be true for tt(quilt) (the tt(mq) and tt(stgit) backends are active by default). -This hook gets the names of all applied patches which var(vcs_info) collected +This hook gets the names of all applied patches which tt(vcs_info) collected so far in the opposite order, which means that the first argument is the top-most patch and so forth. When setting tt(ret) to non-zero, the string in -tt(${hook_com[applied-string]}) will be used in the var(%m) escape in +tt(${hook_com[applied-string]}) will be used in the tt(%m) escape in tt(formats) and tt(actionformats); it will be available in the global -var(backend_misc) array as tt($backend_misc[patches]}); and it will be -available as var(%p) in the tt(patch-format) and tt(nopatch-format) styles. +tt(backend_misc) array as tt($backend_misc[patches]}); and it will be +available as tt(%p) in the tt(patch-format) and tt(nopatch-format) styles. ) item(tt(gen-unapplied-string))( Called in the tt(git) (with tt(stgit)), and tt(hg) (with tt(mq)) backend -and in tt(quilt) support when the var(unapplied-string) is generated; the +and in tt(quilt) support when the tt(unapplied-string) is generated; the tt(get-unapplied) style must be true. -This hook gets the names of all unapplied patches which var(vcs_info) +This hook gets the names of all unapplied patches which tt(vcs_info) collected so far in the opposite order, which mean that the first argument is the patch next-in-line to be applied and so forth. When setting tt(ret) to non-zero, the string in -tt(${hook_com[unapplied-string]}) will be available as var(%u) in the +tt(${hook_com[unapplied-string]}) will be available as tt(%u) in the tt(patch-format) and tt(nopatch-format) styles. ) item(tt(gen-mqguards-string))( @@ -1308,7 +1309,7 @@ tt(get-mq) style must be true (default). This hook gets the names of any active tt(mq) guards. When setting tt(ret) to non-zero, the string in -tt(${hook_com[guards-string]}) will be used in the var(%g) escape in the +tt(${hook_com[guards-string]}) will be used in the tt(%g) escape in the tt(patch-format) and tt(nopatch-format) styles. ) item(tt(no-vcs))( @@ -1330,24 +1331,24 @@ Called before `tt(branchformat)' is set. The only argument to the hook is the format that is configured at this point. The `tt(hook_com)' keys considered are `tt(branch)' and `tt(revision)'. -They are set to the values figured out so far by var(vcs_info) and any +They are set to the values figured out so far by tt(vcs_info) and any change will be used directly when the actual replacement is done. If tt(ret) is set to non-zero, the string in tt(${hook_com[branch-replace]}) will be used unchanged as the -`tt(%b)' replacement in the variables set by var(vcs_info). +`tt(%b)' replacement in the variables set by tt(vcs_info). ) item(tt(set-hgrev-format))( Called before a `tt(hgrevformat)' is set. The only argument to the hook is the format that is configured at this point. The `tt(hook_com)' keys considered are `tt(hash)' and `tt(localrev)'. -They are set to the values figured out so far by var(vcs_info) and any +They are set to the values figured out so far by tt(vcs_info) and any change will be used directly when the actual replacement is done. If tt(ret) is set to non-zero, the string in tt(${hook_com[rev-replace]}) will be used unchanged as the -`tt(%i)' replacement in the variables set by var(vcs_info). +`tt(%i)' replacement in the variables set by tt(vcs_info). ) item(tt(set-message))( Called each time before a `tt(vcs_info_msg_N_)' message is set. @@ -1360,7 +1361,7 @@ There are a number of `tt(hook_com)' keys, that are used here: `tt(staged)', `tt(unstaged)', `tt(revision)', `tt(misc)', `tt(vcs)' and one `tt(miscN)' entry for each backend-specific data field (tt(N) starting at zero). They are set to the values figured out so far by -var(vcs_info) and any change will be used directly when the actual +tt(vcs_info) and any change will be used directly when the actual replacement is done. Since this hook is triggered multiple times (once for each configured @@ -1372,7 +1373,7 @@ probably not a good idea. If tt(ret) is set to non-zero, the string in tt(${hook_com[message]}) will be used unchanged as the message by -var(vcs_info). +tt(vcs_info). ) enditem() @@ -1382,7 +1383,7 @@ They contain some explanatory code. subsect(Examples) -Don't use var(vcs_info) at all (even though it's in your prompt): +Don't use tt(vcs_info) at all (even though it's in your prompt): example(zstyle ':vcs_info:*' enable NONE) Disable the backends for tt(bzr) and tt(svk): @@ -1415,7 +1416,7 @@ Display the revision number in yellow for tt(bzr) and tt(svn): example(zstyle ':vcs_info:(svn|bzr):*' branchformat '%b%{'${fg[yellow]}'%}:%r') If you want colors, make sure you enclose the color codes in tt(%{...%}) -if you want to use the string provided by var(vcs_info) in prompts. +if you want to use the string provided by tt(vcs_info) in prompts. Here is how to print the VCS information as a command (not in a prompt): example(alias vcsi='vcs_info command; vcs_info_lastmsg') @@ -1425,9 +1426,9 @@ tt(vcs_info_lastmsg) in the ':vcs_info:*:command:*' namespace. Now as promised, some code that uses hooks: say, you'd like to replace the string `svn' by `subversion' in -var(vcs_info)'s tt(%s) tt(formats) replacement. +tt(vcs_info)'s tt(%s) tt(formats) replacement. -First, we will tell var(vcs_info) to call a function when populating +First, we will tell tt(vcs_info) to call a function when populating the message variables with the gathered information: example(zstyle ':vcs_info:*+set-message:*' hooks svn2subversion) @@ -1503,7 +1504,7 @@ Some longer examples and code snippets which might be useful are available in the examples file located at Misc/vcs_info-examples in the Zsh source directory. -This concludes our guided tour through zsh's var(vcs_info). +This concludes our guided tour through zsh's tt(vcs_info). texinode(Prompt Themes)(ZLE Functions)(Version Control Information)(User Contributions) @@ -2334,6 +2335,11 @@ regular expression matching is performed, else a literal string replacement. Note that the previous source and replacement text are the same whether pattern, regular expression or string matching is used. +In addition, tt(replace-string) shows the previous replacement above +the prompt, so long as there was one during the current session; if the +source string is empty, that replacement will be repeated without +the widget prompting for a replacement string. + For example, starting from the line: example(print This line contains fan and fond) @@ -2355,7 +2361,7 @@ This is similar to read-from-minibuffer in that it may be called as a function from a widget or as a widget of its own, and interactively reads input from the keyboard. However, the input being typed is concealed and a string of asterisks (`tt(*)') is shown instead. The value is saved in -the paramter tt($INVISIBLE) to which a reference is inserted into the +the parameter tt($INVISIBLE) to which a reference is inserted into the editing buffer at the restored cursor position. If the read was aborted by a keyboard break (typically tt(^G)) or another escape from editing such as tt(push-line), tt($INVISIBLE) is set to empty and the original buffer @@ -2797,6 +2803,23 @@ start with tt(:mime:), with additional components in some cases. It is recommended that a trailing tt(*) (suitably quoted) be appended to style patterns in case the system is extended in future. Some examples are given below. + +For files that have multiple suffixes, e.g. tt(.pdf.gz), where the +context includes the suffix it will be looked up starting with the +longest possible suffix until a match for the style is found. +For example, if tt(.pdf.gz) produces a match for the handler, that +will be used; otherwise the handler for tt(.gz) will be used. Note +that, owing to the way suffix aliases work, it is always required that +there be a handler for the shortest possible suffix, so in this example +tt(.pdf.gz) can only be handled if tt(.gz) is also handled (though +not necessarily in the same way). Alternatively, if no handling +for tt(.gz) on its own is needed, simply adding the command + +example(alias -s gz=zsh-mime-handler) + +to the initialisation code is sufficient; tt(.gz) will not be handled +on its own, but may be in combination with other suffixes. + startitem() kindex(current-shell, MIME style) item(tt(current-shell))( diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index ce122cade..28d525f14 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -236,7 +236,10 @@ a glob qualifier unless a file of the same name is found in the current directory. ) item(tt(e))( -Remove all but the extension. +Remove all but the part of the filename extension following the `tt(.)'; +see the definition of the filename extension in the description of the +tt(r) modifier below. Note that according to that definition the result +will be empty if the string ends with a `tt(.)'. ) item(tt(h))( Remove a trailing pathname component, leaving the head. This works @@ -259,8 +262,12 @@ item(tt(Q))( Remove one level of quotes from the substituted words. ) item(tt(r))( -Remove a filename extension of the form `tt(.)var(xxx)', leaving -the root name. +Remove a filename extension leaving the root name. Strings with no +filename extension are not altered. A filename +extension is a `tt(.)' followed by any number of characters (including +zero) that are neither `tt(.)' nor `tt(/)' and that continue to the end +of the string. For example, the extension of +`tt(foo.orig.c)' is `tt(.c)', and `tt(dir.c/foo)' has no extension. ) item(tt(s/)var(l)tt(/)var(r)[tt(/)])( Substitute var(r) for var(l) as described below. @@ -464,6 +471,18 @@ example(tt({ paste <LPAR()cut -f1) var(file1)tt(RPAR() <LPAR()cut -f3) var(file2 The extra processes here are spawned from the parent shell which will wait for their completion. +Another problem arises any time a job with a substitution that requires +a temporary file is disowned by the shell, including the case where +`tt(&!)' or `tt(&|)' appears at the end of a command containing a +subsitution. In that case the temporary file will not be cleaned up as +the shell no longer has any memory of the job. A workaround is to use +a subshell, for example, + +example(LPAR()mycmd =(myoutput)RPAR() &!) + +as the forked subshell will wait for the command to finish then remove +the temporary file. + texinode(Parameter Expansion)(Command Substitution)(Process Substitution)(Expansion) sect(Parameter Expansion) cindex(parameter expansion) @@ -1992,15 +2011,16 @@ point on. ) item(tt(c)var(N)tt(,)var(M))( The flag tt(LPAR()#c)var(N)tt(,)var(M)tt(RPAR()) can be used anywhere -that the tt(#) or tt(##) operators can be used; it cannot be combined -with other globbing flags and a bad pattern error occurs if it is -misplaced. It is equivalent to the form tt({)var(N)tt(,)var(M)tt(}) in -regular expressions. The previous character or group is required to -match between var(N) and var(M) times, inclusive. The form -tt(LPAR()#c)var(N)tt(RPAR()) requires exactly tt(N) matches; -tt(LPAR()#c,)var(M)tt(RPAR()) is equivalent to specifying var(N) as 0; -tt(LPAR()#c)var(N)tt(,RPAR()) specifies that there is no maximum limit -on the number of matches. +that the tt(#) or tt(##) operators can be used except in the expressions +`tt((*/)#)' and `tt((*/)##)' in filename generation, where `tt(/)' +has special meaning; it cannot be combined with other globbing flags and +a bad pattern error occurs if it is misplaced. It is equivalent to the +form tt({)var(N)tt(,)var(M)tt(}) in regular expressions. The previous +character or group is required to match between var(N) and var(M) times, +inclusive. The form tt(LPAR()#c)var(N)tt(RPAR()) requires exactly tt(N) +matches; tt(LPAR()#c,)var(M)tt(RPAR()) is equivalent to specifying var(N) +as 0; tt(LPAR()#c)var(N)tt(,RPAR()) specifies that there is no maximum +limit on the number of matches. ) item(tt(m))( Set references to the match data for the entire string matched; this is @@ -2360,8 +2380,8 @@ latter is inserted into the command line word by word. For example, suppose a directory contains a single file `tt(lonely)'. Then the expression `tt(*(e:'reply=(${REPLY}{1,2})':))' will cause the words -`tt(lonely1 lonely2)' to be inserted into the command line. Note the -quotation marks. +`tt(lonely1)' and `tt(lonely2)' to be inserted into the command line. Note +the quoting of var(string). The form tt(PLUS())var(cmd) has the same effect, but no delimiters appear around var(cmd). Instead, var(cmd) is taken as the longest sequence of diff --git a/Doc/Zsh/func.yo b/Doc/Zsh/func.yo index 28bc6329a..7c391f80d 100644 --- a/Doc/Zsh/func.yo +++ b/Doc/Zsh/func.yo @@ -158,9 +158,20 @@ If no name is given for a function, it is `anonymous' and is handled specially. Either form of function definition may be used: a `tt(())' with no preceding name, or a `tt(function)' with an immediately following open brace. The function is executed immediately at the point of definition and -is not stored for future use. The function name is set to `tt((anon))' and -the parameter list passed to the function is empty. Note that this means -the argument list of any enclosing script or function is hidden. +is not stored for future use. The function name is set to `tt((anon))'. + +Arguments to the function may be specified as words following the +closing brace defining the function, hence if there are none no +arguments (other than tt($0)) are set. This is a difference from the +way other functions are parsed: normal function definitions may be +followed by certain keywords such as `tt(else)' or `tt(fi)', which will +be treated as arguments to anonymous functions, so that a newline or +semicolon is needed to force keyword interpretation. + +Note also that the argument list of any enclosing script or function is +hidden (as would be the case for any other function called at this +point). + Redirections may be applied to the anonymous function in the same manner as to a current-shell structure enclosed in braces. The main use of anonymous functions is to provide a scope for local variables. This is particularly @@ -172,13 +183,13 @@ For example, example(variable=outside function { local variable=inside - print "I am $variable" -} + print "I am $variable with arguments $*" +} this and that print "I am $variable") outputs the following: -example(I am inside +example(I am inside with arguments this and that I am outside) Note that function definitions with arguments that expand to nothing, diff --git a/Doc/Zsh/mod_datetime.yo b/Doc/Zsh/mod_datetime.yo index 145d4a181..619067698 100644 --- a/Doc/Zsh/mod_datetime.yo +++ b/Doc/Zsh/mod_datetime.yo @@ -30,12 +30,35 @@ in seconds if tt(-r) is given) to var(scalar) instead of printing it. ) enditem() -The tt(zsh/datetime) module makes available one parameter: +The tt(zsh/datetime) module makes available several parameters; +all are readonly: startitem() +vindex(EPOCHREALTIME) +item(tt(EPOCHREALTIME))( +A floating point value representing the number of seconds since +the epoch. The notional accuracy is to nanoseconds if the +tt(clock_gettime) call is available and to microseconds otherwise, +but in practice the range of double precision floating point and +shell scheduling latencies may be significant effects. +) vindex(EPOCHSECONDS) item(tt(EPOCHSECONDS))( An integer value representing the number of seconds since the epoch. ) +vindex(epochtime) +item(tt(epochtime))( +An array value containing the number of seconds since the epoch +in the first element and the remainder of the time since the epoch +in nanoseconds in the second element. To ensure the two elements +are consistent the array should be copied or otherwise referenced +as a single substitution before the values are used. The following +idiom may be used: + +example(for secs nsecs in $epochtime; do + ... +done) + +) enditem() diff --git a/Doc/Zsh/mod_zutil.yo b/Doc/Zsh/mod_zutil.yo index 1838eab5e..726b0f055 100644 --- a/Doc/Zsh/mod_zutil.yo +++ b/Doc/Zsh/mod_zutil.yo @@ -101,7 +101,8 @@ style is defined for at least one matching pattern, has only one string in its value, and that is equal to one of `tt(true)', `tt(yes)', `tt(on)' or `tt(1)'. If any var(strings) are given the status is zero if and only if at least one of the var(strings) is equal to at least one of the strings -in the value. If the style is not defined, the status is tt(2). +in the value. If the style is defined but doesn't match, the return status +is tt(1). If the style is not defined, the status is tt(2). The tt(-T) option tests the values of the style like tt(-t), but it returns status zero (rather than tt(2)) if the style is not defined for any diff --git a/Doc/Zsh/modules.yo b/Doc/Zsh/modules.yo index 3f9986096..c8b846b95 100644 --- a/Doc/Zsh/modules.yo +++ b/Doc/Zsh/modules.yo @@ -6,7 +6,11 @@ Some optional parts of zsh are in modules, separate from the core of the shell. Each of these modules may be linked in to the shell at build time, or can be dynamically linked while the shell is running -if the installation supports this feature. The modules that -are bundled with the zsh distribution are: +if the installation supports this feature. +Modules are linked at runtime with the tt(zmodload) command, +see ifzman(zmanref(zshbuiltins))\ +ifnzman(noderef(Shell Builtin Commands)). + +The modules that are bundled with the zsh distribution are: includefile(Zsh/modlist.yo) diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 22a00f5c2..e9a3c722d 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -907,7 +907,7 @@ directory would still be completed). ) vindex(DIRSTACKSIZE) item(tt(DIRSTACKSIZE))( -The maximum size of the directory stack. If the +The maximum size of the directory stack, by default there is no limit. If the stack gets larger than this, it will be truncated automatically. This is useful with the tt(AUTO_PUSHD) option. pindex(AUTO_PUSHD, use of) @@ -1226,7 +1226,7 @@ vindex(RPS1) item(tt(RPS1) <S>)( This prompt is displayed on the right-hand side of the screen when the primary prompt is being displayed on the left. -This does not work if the tt(SINGLELINEZLE) option is set. +This does not work if the tt(SINGLE_LINE_ZLE) option is set. It is expanded in the same way as tt(PS1). ) vindex(RPROMPT2) @@ -1235,7 +1235,7 @@ vindex(RPS2) item(tt(RPS2) <S>)( This prompt is displayed on the right-hand side of the screen when the secondary prompt is being displayed on the left. -This does not work if the tt(SINGLELINEZLE) option is set. +This does not work if the tt(SINGLE_LINE_ZLE) option is set. It is expanded in the same way as tt(PS2). ) vindex(SAVEHIST) diff --git a/Doc/Zsh/redirect.yo b/Doc/Zsh/redirect.yo index 3877b2313..8d231f40f 100644 --- a/Doc/Zsh/redirect.yo +++ b/Doc/Zsh/redirect.yo @@ -149,13 +149,32 @@ file descriptor 2 would be associated with the terminal (assuming file descriptor 1 had been) and then file descriptor 1 would be associated with file var(fname). -If instead of a digit one of the operators above is preceded by -a valid identifier enclosed in braces, the shell will open a new -file descriptor that is guaranteed to be at least 10 and set the -parameter named by the identifier to the file descriptor opened. -No whitespace is allowed between the closing brace and the redirection -character. The option tt(IGNORE_BRACES) must not be set. -For example: +The `tt(|&)' command separator described in +ifzman(em(Simple Commands & Pipelines) in zmanref(zshmisc))\ +ifnzman(noderef(Simple Commands & Pipelines)) +is a shorthand for `tt(2>&1 |)'. + +The various forms of process substitution, `tt(<LPAR())var(list)tt(RPAR())', +and `tt(=LPAR())var(list)(RPAR())' for input and +`tt(>LPAR())var(list)tt(RPAR())' for output, are often used together with +redirection. For example, if var(word) in an output redirection is of the +form `tt(>LPAR())var(list)tt(RPAR())' then the output is piped to the +command represented by var(list). See +ifzman(\ +em(Process Substitution) in zmanref(zshexpn))\ +ifnzman(\ +noderef(Process Substitution)). +sect(Opening file descriptors using parameters) +cindex(file descriptors, use with parameters) +cindex(parameters, for using file descriptors) + +When the shell is parsing arguments to a command, and the shell option +tt(IGNORE_BRACES) is not set, a different form of redirection is allowed: +instead of a digit before the operator there is a valid shell identifier +enclosed in braces. The shell will open a new file descriptor that +is guaranteed to be at least 10 and set the parameter named by the +identifier to the file descriptor opened. No whitespace is allowed +between the closing brace and the redirection character. For example: indent(... {myfd}>&1) @@ -181,8 +200,12 @@ using it for allocating a file descriptor avoids the error. Note that this mechanism merely allocates or closes a file descriptor; it does not perform any redirections from or to it. It is usually convenient -to allocate a file descriptor prior to use as an argument to tt(exec). The -following shows a typical sequence of allocation, use, and closing of a +to allocate a file descriptor prior to use as an argument to tt(exec). +The syntax does not in any case work when used around complex commands +such as parenthesised subshells or loops, where the opening brace is +interpreted as part of a command list to be executed in the current shell. + +The following shows a typical sequence of allocation, use, and closing of a file descriptor: example(integer myfd @@ -194,22 +217,6 @@ Note that the expansion of the variable in the expression tt(>&$myfd) occurs at the point the redirection is opened. This is after the expansion of command arguments and after any redirections to the left on the command line have been processed. - -The `tt(|&)' command separator described in -ifzman(em(Simple Commands & Pipelines) in zmanref(zshmisc))\ -ifnzman(noderef(Simple Commands & Pipelines)) -is a shorthand for `tt(2>&1 |)'. - -The various forms of process substitution, `tt(<LPAR())var(list)tt(RPAR())', -and `tt(=LPAR())var(list)(RPAR())' for input and -`tt(>LPAR())var(list)tt(RPAR())' for output, are often used together with -redirection. For example, if var(word) in an output redirection is of the -form `tt(>LPAR())var(list)tt(RPAR())' then the output is piped to the -command represented by var(list). See -ifzman(\ -em(Process Substitution) in zmanref(zshexpn))\ -ifnzman(\ -noderef(Process Substitution)). sect(Multios) cindex(multios) pindex(MULTIOS, use of) diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 5f4d639d3..752247461 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -392,11 +392,16 @@ commands to create the widgets. When combined with the tt(-a) option, all widget names are listed, including the builtin ones. In this case the tt(-L) option is ignored. -If at least one var(string) is given, nothing will be printed but the -return status will be zero if all var(string)s are names of existing -widgets (or of user-defined widgets if the tt(-a) flag is not given) -and non-zero if at least one var(string) is not a name of an defined -widget. +If at least one var(string) is given, and tt(-a) is present or tt(-L) is +not used, nothing will be printed. The return status will be zero if +all var(string)s are names of existing widgets and non-zero if at least one +var(string) is not a name of a defined widget. If tt(-a) is also +present, all widget names are used for the comparison including builtin +widgets, else only user-defined widgets are used. + +If at least one var(string) is present and the tt(-L) option is used, +user-defined widgets matching any var(string) are listed in the form of +tt(zle) commands to create the widgets. ) item(tt(-D) var(widget) ...)( Delete the named var(widget)s. diff --git a/Etc/.distfiles b/Etc/.distfiles index 22cabe7f2..1f31e7acb 100644 --- a/Etc/.distfiles +++ b/Etc/.distfiles @@ -20,5 +20,6 @@ relnote_4.3.7.txt relnote_4.3.8.txt relnote_4.3.9.txt relnote_4.3.10.txt +relnote_4.3.12.txt zsh-development-guide ' diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index 509d924c5..b401c632e 100644 --- a/Etc/FAQ.yo +++ b/Etc/FAQ.yo @@ -302,7 +302,7 @@ sect(On what machines will it run?) sect(What's the latest version?) Zsh 4.2.7 is the latest production version. The latest development - version is 4.3.12; this contains support for multibyte character strings + version is 4.3.13; this contains support for multibyte character strings (such as UTF-8 locales). All the main features for multibyte support are now in place and this is likely soon to become the stable series 4.4. diff --git a/Etc/relnote_4.3.12.txt b/Etc/relnote_4.3.12.txt new file mode 100644 index 000000000..2f60d97be --- /dev/null +++ b/Etc/relnote_4.3.12.txt @@ -0,0 +1,3 @@ +Versions 4.3.12 largely contains bugfixes with a few minor additions. + +See the NEWS file for more detailed information. diff --git a/Functions/Chpwd/zsh_directory_name_cdr b/Functions/Chpwd/zsh_directory_name_cdr index 09aa35a93..c9be7db0c 100644 --- a/Functions/Chpwd/zsh_directory_name_cdr +++ b/Functions/Chpwd/zsh_directory_name_cdr @@ -18,7 +18,7 @@ elif [[ $1 = c ]]; then values=(${${(f)"$(cdr -l)"}/ ##/:}) keys=(${values%%:*}) _describe -t dir-index 'recent directory index' \ - values keys -V unsorted -S']' + values -V unsorted -S']' return fi fi diff --git a/Functions/MIME/.distfiles b/Functions/MIME/.distfiles index 01ac0d7ef..93c13f7da 100644 --- a/Functions/MIME/.distfiles +++ b/Functions/MIME/.distfiles @@ -1,4 +1,7 @@ DISTFILES_SRC=' .distfiles -zsh-mime-setup zsh-mime-handler pick-web-browser +pick-web-browser +zsh-mime-contexts +zsh-mime-handler +zsh-mime-setup ' diff --git a/Functions/MIME/zsh-mime-contexts b/Functions/MIME/zsh-mime-contexts new file mode 100644 index 000000000..08f125158 --- /dev/null +++ b/Functions/MIME/zsh-mime-contexts @@ -0,0 +1,24 @@ +# Helper for zsh-mime-handler. +# +# Pass in a zstyle option, a suffix, which might include multiple parts +# (e.g. pdf.gz), plus remaining zstyle arguments plus arguments to zstyle. +# Try to match the style starting with the longest possible suffix. + +local context suffix option + +option=$1 +shift +suffix=$1 +shift + +while true; do + context=":mime:.${suffix}:" + zstyle $option $context "$@" && return 0 + if [[ $suffix = *.* ]]; then + suffix=${suffix#*.} + else + break + fi +done + +return 1 diff --git a/Functions/MIME/zsh-mime-handler b/Functions/MIME/zsh-mime-handler index 9a40e67bb..abaf0b6e3 100644 --- a/Functions/MIME/zsh-mime-handler +++ b/Functions/MIME/zsh-mime-handler @@ -34,6 +34,8 @@ setopt extendedglob cbases nullglob $autocd # We need zformat from zsh/zutil for %s replacement. zmodload -i zsh/zutil +autoload -Uz zsh-mime-contexts + # Look for options. Because of the way this is usually invoked, # (there is always a command to be handled), only handle options # up to second last argument. @@ -62,12 +64,15 @@ shift $(( OPTIND - 1 )) # just as well pass them all down. However, we just take the # suffix from the first since that's what invoked us via suffix -s. -local suffix context +local suffix s local -a match mbegin mend -[[ $1 = (#b)*.([^.]##) ]] || return 1 -suffix=${(L)match[1]} -context=":mime:.${suffix}:" +suffix=${1:t} +if [[ $suffix != *.* ]]; then + "No suffix in command: $1" >&2 + return 1 +fi +suffix=${suffix#*.} local handler flags no_sh no_bg arg integer i @@ -77,11 +82,11 @@ local -a exec_asis hand_nonex # despite being called for interpretation by the mime handler. # Defaults to executable files, which ensures that they are executed as # they are, even if they have a suffix. -zstyle -a $context execute-as-is exec_asis || exec_asis=('*(*)' '*(/)') +zsh-mime-contexts -a $suffix execute-as-is exec_asis || exec_asis=('*(*)' '*(/)') # Set to a list of patterns for which the handler will be used even # if the file doesn't exist on the disk. -zstyle -a $context handle-nonexistent hand_nonex || +zsh-mime-contexts -a $suffix handle-nonexistent hand_nonex || hand_nonex=('[[:alpha:]]#:/*') local pattern @@ -92,9 +97,9 @@ local -a files # actual file or its directory. local dir local -a filepath -if zstyle -t $context find-file-in-path && [[ $1 != /* ]] && +if zsh-mime-contexts -t $suffix find-file-in-path && [[ $1 != /* ]] && [[ $1 != */* || -o pathdirs ]]; then - zstyle -a $context file-path filepath || filepath=($path) + zsh-mime-contexts -a $suffix file-path filepath || filepath=($path) for dir in $filepath; do if [[ -e $dir/$1 ]]; then 1=$dir/$1 @@ -153,19 +158,54 @@ if [[ ! -e $1 ]]; then fi fi -zstyle -s $context handler handler || - handler="${zsh_mime_handlers[$suffix]}" -zstyle -s $context flags flags || - flags="${zsh_mime_flags[$suffix]}" +if ! zsh-mime-contexts -s $suffix handler handler; then + # Look for handler starting with longest suffix match. + # Typically we'd only get a match for the shortest, but don't assume so. + s=$suffix + while true; do + handler="${zsh_mime_handlers[$s]}" + if [[ -n $handler ]]; then + break + fi + if [[ $s = *.* ]]; then + s=${s#*.} + else + break + fi + done + if [[ -z $handler ]]; then + if [[ $suffix = *.* ]]; then + print "No handler specified for suffix .$suffix or any final part" >&2 + else + print "No handler specified for suffix .$suffix" >&2 + fi + return 1 + fi +fi +if ! zsh-mime-contexts -s $suffix flags flags; then + # Same again for flags. + s=$suffix + while true; do + flags="${zsh_mime_flags[$suffix]}" + if [[ -n $flags ]]; then + break + fi + if [[ $s = *.* ]]; then + s=${s#*.} + else + break + fi + done +fi # Set to yes if we use eval instead of sh -c for complicated mailcap lines # Can possibly break some mailcap entries which expect sh compatibility, # but is faster, as a new process is not spawned. -zstyle -t $context current-shell && no_sh=yes +zsh-mime-contexts -t $suffix current-shell && no_sh=yes # Set to yes if the process shouldn't be backgrounded even if it doesn't need a # terminal and display is set. -zstyle -t $context never-background && no_bg=yes +zsh-mime-contexts -t $suffix never-background && no_bg=yes local hasmeta stdin @@ -241,7 +281,7 @@ if [[ $flags = *copiousoutput* ]]; then # We need to page the output. # Careful in case PAGER is a set of commands and arguments. local -a pager - zstyle -a $context pager pager || pager=(${=PAGER:-more}) + zsh-mime-contexts -a $suffix pager pager || pager=(${=PAGER:-more}) if [[ -n $stdin ]]; then cat $argv | $execargs | $pager else diff --git a/Functions/Misc/zargs b/Functions/Misc/zargs index 58d84617e..8350b1aba 100644 --- a/Functions/Misc/zargs +++ b/Functions/Misc/zargs @@ -207,7 +207,7 @@ then else call=($command) # Use "repeat" here so "continue" won't complain. - repeat 1 eval "$execute ; $analyze" + repeat 1; do eval "$execute ; $analyze"; done return $ret fi fi @@ -273,7 +273,7 @@ do repeat $P do ((ARGC)) || break - for (( end=l; end && ${(c)#argv[1,end]} > s; end/=2 )) : + for (( end=l; end && ${(c)#argv[1,end]} > s; end/=2 )) { } (( end > n && ( end = n ) )) args=( $argv[1,end] ) shift $((end > ARGC ? ARGC : end)) diff --git a/Functions/Prompts/prompt_bart_setup b/Functions/Prompts/prompt_bart_setup index 1cc7b6f08..6cbbb71c7 100644 --- a/Functions/Prompts/prompt_bart_setup +++ b/Functions/Prompts/prompt_bart_setup @@ -67,15 +67,39 @@ prompt_bart_help () { } integer PSCOL=1 +typeset PSCMD= + +prompt_bart_preexec () { + setopt localoptions noxtrace noshwordsplit noksharrays unset + local -a cmd; cmd=( ${(z)3} ) + if [[ $cmd[1] = fg ]] + then + shift cmd + cmd[1]=${cmd[1]:-%+} + fi + if [[ $#cmd -eq 1 && $cmd[1] = %* ]] + then + PSCMD=$jobtexts[$cmd[1]] + elif [[ -o autoresume && -n $jobtexts[%?$2] ]] + then + PSCMD=$jobtexts[%?$2] + else + # Use history text to avoid alias expansion + PSCMD=$history[$HISTCMD] + fi + return 0 +} prompt_bart_precmd () { setopt localoptions noxtrace noksharrays unset local zero='%([BSUbfksu]|[FB]{*})' escape colno lineno + : "${PSCMD:=$history[$[HISTCMD-1]]}" # Default to history text + # Using psvar here protects against unwanted promptsubst expansions. - psvar[7]="$history[$[HISTCMD-1]]" # Use history text, not just number - psvar[8]='' # No padding until we compute it + psvar[7]="$PSCMD" + psvar[8]='' # No padding until we compute it psvar[9]=() typeset -g PSCOL @@ -153,6 +177,7 @@ prompt_bart_setup () { repeat 1 case "$1:l" in (off|disable) add-zsh-hook -D precmd "prompt_*_precmd" + add-zsh-hook -D preexec "prompt_*_preexec" functions[TRAPWINCH]="${functions[TRAPWINCH]//prompt_bart_winch}" [[ $prompt_theme[1] = bart ]] && PS1=${${(f)PS1}[-1]} return 1 @@ -182,6 +207,7 @@ prompt_bart_setup () { # Paste our special commands into precmd and TRAPWINCH add-zsh-hook precmd prompt_bart_precmd + add-zsh-hook preexec prompt_bart_preexec functions[TRAPWINCH]="${functions[TRAPWINCH]//prompt_bart_winch} prompt_bart_winch" diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_svn b/Functions/VCS_Info/Backends/VCS_INFO_detect_svn index a777ecc43..43dedcde9 100644 --- a/Functions/VCS_Info/Backends/VCS_INFO_detect_svn +++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_svn @@ -7,5 +7,5 @@ setopt localoptions NO_shwordsplit [[ $1 == '--flavours' ]] && return 1 VCS_INFO_check_com ${vcs_comm[cmd]} || return 1 -{ [[ -f ".svn/entries" ]] || [[ -f ".svn/format" ]] } && return 0 -return 1 +vcs_comm[detect_need_file]="entries format" +VCS_INFO_bydir_detect '.svn' || return 1 diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr b/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr index 5d4deaac9..cae1a3b08 100644 --- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr +++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr @@ -1,13 +1,52 @@ -## vim:ft=zsh +## vim:ft=zsh et ## bazaar support by: Frank Terbeck <ft@bewatermyfriend.org> +## mostly rewritten by: Jan Pobrislo <ccx@webprojekty.cz> ## Distributed under the same BSD-ish license as zsh itself. setopt localoptions noksharrays extendedglob NO_shwordsplit -local bzrbase bzrbr +local bzrbase bzrbr bzr_changes bzr_type local -a bzrinfo -local -xA hook_com +local -xA hook_com bzr_info + +VCS_INFO_bzr_get_info() { + bzrinfo=( ${(s.:.)$( ${vcs_comm[cmd]} version-info --custom \ + --template="{revno}:{branch_nick}:{clean}")} ) + if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "check-for-changes" + then + VCS_INFO_bzr_get_changes + elif [[ ${bzrinfo[2]} == 1 ]] + then + bzr_changes = '1' + fi +} + +VCS_INFO_bzr_get_info_restricted() { + # we are forbidden from fetching info on bound branch from remote repository + bzrinfo=( $(${vcs_comm[cmd]} revno) ${bzrbase:t} ) + if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "check-for-changes" && \ + [[ ! $bzr_type == lightweigth ]] + then + VCS_INFO_bzr_get_changes + fi +} + +VCS_INFO_bzr_get_changes() { + local -A counts + local line flag + bzr_changes=$( + ${vcs_comm[cmd]} stat -SV | while read flag line + do + counts[${flag}]=$(( ${counts[${flag}]:-0} + 1 )) + done + for flag in ${(k)counts} + do + printf "%s:%d " $flag ${counts[${flag}]} + done + ) +} if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "use-simple" ; then + # simple parsing will fail to fetch information from lightweigth checkouts bzrbase=${vcs_comm[basedir]} bzrinfo[2]=${bzrbase:t} if [[ -f ${bzrbase}/.bzr/branch/last-revision ]] ; then @@ -15,9 +54,46 @@ if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "use-simple" ; then bzrinfo[1]=${${bzrinfo[1]}%% *} fi else - bzrbase=${${(M)${(f)"$( ${vcs_comm[cmd]} info )"}:# ##branch\ root:*}/*: ##/} - bzrinfo=( ${${${(M)${(f)"$( ${vcs_comm[cmd]} version-info )"}:#(#s)(revno|branch-nick)*}/*: /}/*\//} ) + # Parse the output of 'bzr info' into associative array bzr_info + ${vcs_comm[cmd]} info | { + local line key value dirtype + read dirtype + grep '^[ a-zA-Z0-9]\+: ' | while read line + do + value=${line#*': '} + key=${${line%%: *}// /_} + bzr_info[$key]=$value + done + } + + case "$dirtype" in + ('Checkout'*) + bzr_type=checkout + bzrbase=${bzr_info[checkout_root]} ;; + ('Repository checkout'*) + bzr_type=checkout + bzrbase=${bzr_info[repository_checkout_root]} ;; + ('Lightweight checkout'*) + bzr_type=lightweigth + bzrbase=${bzr_info[light_checkout_root]} ;; + (*) + bzr_type=standalone + bzrbase=${bzr_info[branch_root]} ;; + esac + bzrbase="$(VCS_INFO_realpath ${bzrbase})" + + if [ -n "${bzr_info[checkout_of_branch]}" ] && \ + zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "use-server" + then + VCS_INFO_bzr_get_info + else + case ${bzr_info[checkout_of_branch]} in + (file://*) VCS_INFO_bzr_get_info ;; + (*://*) VCS_INFO_bzr_get_info_restricted ;; + (*) VCS_INFO_bzr_get_info ;; + esac + fi fi rrn=${bzrbase:t} @@ -29,5 +105,6 @@ else bzrbr=${hook_com[branch-replace]} fi hook_com=() -VCS_INFO_formats '' "${bzrbr}" "${bzrbase}" '' '' "${bzrinfo[1]}" '' + +VCS_INFO_formats '' "${bzrbr}" "${bzrbase}" '' "${bzr_changes}" "${bzrinfo[1]}" "${bzr_changes}" return 0 diff --git a/Functions/VCS_Info/vcs_info b/Functions/VCS_Info/vcs_info index 513489b70..5a421dfed 100644 --- a/Functions/VCS_Info/vcs_info +++ b/Functions/VCS_Info/vcs_info @@ -70,6 +70,9 @@ vcs_info () { if (( retval == 1 )); then return 0 elif (( retval == 2 )); then + # This needs `max-exports' set. We're still setting it again later + # for more specific contexts. + VCS_INFO_maxexports VCS_INFO_set --nvcs return 0 fi diff --git a/Functions/Zle/.distfiles b/Functions/Zle/.distfiles index 22eef1e6e..256044fa5 100644 --- a/Functions/Zle/.distfiles +++ b/Functions/Zle/.distfiles @@ -25,6 +25,7 @@ kill-word-match match-word-context match-words-by-style modify-current-argument +move-line-in-buffer narrow-to-region narrow-to-region-invisible predict-on diff --git a/Functions/Zle/define-composed-chars b/Functions/Zle/define-composed-chars index 12a357fc1..15d693a3f 100644 --- a/Functions/Zle/define-composed-chars +++ b/Functions/Zle/define-composed-chars @@ -135,6 +135,26 @@ a=j z[$a]="\ i 133 \ " +# ligature with f +a=f +z[$a]="\ +f FB00 \ +" +# ligature with i +a=i +z[$a]="\ +f FB01 \ +" +# ligature with l +a=l +z[$a]="\ +f FB02 \ +" +# ligature with t +a=t +z[$a]="\ +f FB05 s FB06 \ +" # eszett a=s z[$a]="\ @@ -252,6 +272,19 @@ z[$a]+=" Z 5e6" a=h z[$a]+=" S 5e9" +# Superscripts +a=S +z[$a]+=" \ +0 2070 1 B9 2 B2 3 B3 4 2074 5 2075 6 2076 7 2077 8 2078 9 2079 \ ++ 207a - 207b = 207C ( 207D ) 207E n 207f \ +" +# Subscripts +a=s +z[$a]+=" \ +0 2080 1 2081 2 2082 3 2083 4 2084 5 2085 6 2086 7 2087 8 2088 9 2089 \ ++ 208a - 208b = 208C ( 208D ) 208E \ +" + typeset -i 16 -Z 4 ia typeset -i 16 -Z 6 iuni # Extended width characters ^A, ^B, ... (not RFC1345) @@ -327,10 +360,14 @@ z[g]+=" R AE" z[m]+=" ' AF" # degree z[G]+=" D B0" +# degree centigrade +z[C]+=" o 2103" +# degree fahrenheit +z[F]+=" o 2109" +# numero +z[0]+=" N 2116" # +/- z[-]+=" + B1" -# superscripts -z[S]+=" 2 B2 3 B3" # lonely acute a=\' z[$a]+=" ' B4" @@ -342,8 +379,6 @@ z[I]+=" P B6" z[M]+=" . B7" # Lonely cedilla z[,]+=" ' B8" -# Superscript one -z[S]+=" 1 B9" # spanish masculine ordinal z[o]+=" - BA" # right guillemet @@ -415,5 +450,20 @@ z[0]+=" 0 221E" # Female and male z[m]+=" F 2640" z[l]+=" M 2642" +# Commercial AT +z[t]+=" A 40" +# Prime, double prime, triple prime +a=\' +z[$a]+=" 1 2032 2 2033 3 2034" +# Arrows +z[-]+=" < 2190" +a=\! +z[$a]+=" - 2191" +a=\> +z[$a]+=" - 2192 < 2194 = 21D2" +z[v]+=" - 2193" +z[D]+=" U 2195" +a=\= +z[$a]+=" < 21D0 = 21D4" zsh_accented_chars=("${(kv)z[@]}") diff --git a/Functions/Zle/match-words-by-style b/Functions/Zle/match-words-by-style index 69ceba76a..b387828f3 100644 --- a/Functions/Zle/match-words-by-style +++ b/Functions/Zle/match-words-by-style @@ -220,8 +220,7 @@ if [[ $wordstyle = *subword* ]]; then fi match=() -charskip= -repeat $skip charskip+=\? +charskip=${(l:skip::?:)} eval pat2='${RBUFFER##(#b)('${charskip}${spacepat}')('\ ${wordpat2}')('${spacepat}')}' diff --git a/Functions/Zle/move-line-in-buffer b/Functions/Zle/move-line-in-buffer new file mode 100644 index 000000000..5f37a9d71 --- /dev/null +++ b/Functions/Zle/move-line-in-buffer @@ -0,0 +1,16 @@ +#autoload + +# Line motions that do not leave the current history entry, +# for editing in multi-line buffers. + +# To use: +# autoload -Uz move-line-in-buffer +# zle -N up-line-in-buffer move-line-in-buffer +# zle -N down-line-in-buffer move-line-in-buffer +# +# then bindkey as you prefer + +local hno=$HISTNO curs=$CURSOR +zle .${WIDGET:s/in-buffer/or-history} "$@" && + (( HISTNO != hno && (HISTNO=hno, CURSOR=curs) )) +return 0 diff --git a/Functions/Zle/read-from-minibuffer b/Functions/Zle/read-from-minibuffer index fce6b5319..57e926884 100644 --- a/Functions/Zle/read-from-minibuffer +++ b/Functions/Zle/read-from-minibuffer @@ -19,26 +19,19 @@ while getopts "k:" opt; do done (( OPTIND > 1 )) && shift $(( OPTIND - 1 )) +local readprompt="$1" lbuf_init="$2" rbuf_init="$3" + +# Use anonymous function to make sure special values get restored, +# even if this function is called as a widget. +# local +h ensures special parameters stay special. +() { local pretext="$PREDISPLAY$LBUFFER$RBUFFER$POSTDISPLAY " -# We could use the local variables mechanism to save these -# values, but if read-from-minibuffer is called as a widget -# (which isn't actually all that useful) the values won't be -# restored because the variables are already local at the current -# level and don't get restored when they go out of scope. -# We could do it with an additional function level. - local save_lbuffer=$LBUFFER - local save_rbuffer=$RBUFFER - local save_predisplay=$PREDISPLAY - local save_postdisplay=$POSTDISPLAY - local -a save_region_highlight - save_region_highlight=("${region_highlight[@]}") - -{ - LBUFFER="$2" - RBUFFER="$3" - PREDISPLAY="$pretext${1:-? }" - POSTDISPLAY= + local +h LBUFFER="$lbuf_init" + local +h RBUFFER="$rbuf_init" + local +h PREDISPLAY="$pretext${readprompt:-? }" + local +h POSTDISPLAY= + local +h -a region_highlight region_highlight=("P${#pretext} ${#PREDISPLAY} bold") if [[ -n $keys ]]; then @@ -50,12 +43,6 @@ done stat=$? (( stat )) || REPLY=$BUFFER fi -} always { - LBUFFER=$save_lbuffer - RBUFFER=$save_rbuffer - PREDISPLAY=$save_predisplay - POSTDISPLAY=$save_postdisplay - region_highlight=("${save_region_highlight[@]}") } return $stat diff --git a/Functions/Zle/replace-string b/Functions/Zle/replace-string index bc608e577..a3416a403 100644 --- a/Functions/Zle/replace-string +++ b/Functions/Zle/replace-string @@ -3,7 +3,15 @@ setopt extendedglob autoload -Uz read-from-minibuffer replace-string-again -local p1="Replace: " p2=" with: " +local p1 p2 + +if [[ -n $_replace_string_src ]]; then + p1="[$_replace_string_src -> $_replace_string_rep]"$'\n' +fi + +p1+="Replace: " +p2=" with: " + # Saving curwidget is necessary to avoid the widget name being overwritten. local REPLY previous curwidget=$WIDGET @@ -14,10 +22,12 @@ else fi read-from-minibuffer $p1 ${previous:+$_replace_string_src} || return 1 -typeset -g _replace_string_src=$REPLY +if [[ -n $REPLY ]]; then + typeset -g _replace_string_src=$REPLY -read-from-minibuffer "$p1$_replace_string_src$p2" \ - ${previous:+$_replace_string_rep} || return 1 -typeset -g _replace_string_rep=$REPLY + read-from-minibuffer "$p1$_replace_string_src$p2" \ + ${previous:+$_replace_string_rep} || return 1 + typeset -g _replace_string_rep=$REPLY +fi replace-string-again $curwidget diff --git a/Functions/Zle/replace-string-again b/Functions/Zle/replace-string-again index f24c14f88..dac3db755 100644 --- a/Functions/Zle/replace-string-again +++ b/Functions/Zle/replace-string-again @@ -40,8 +40,10 @@ if [[ $curwidget = *(pattern|regex)* ]]; then rep2+=$rep if [[ $curwidget = *regex* ]]; then autoload -Uz regexp-replace - regexp-replace LBUFFER $_replace_string_src $rep2 || return 1 - regexp-replace RBUFFER $_replace_string_src $rep2 || return 1 + integer ret=1 + regexp-replace LBUFFER $_replace_string_src $rep2 && ret=0 + regexp-replace RBUFFER $_replace_string_src $rep2 && ret=0 + return ret else LBUFFER=${LBUFFER//(#bm)$~_replace_string_src/${(e)rep2}} RBUFFER=${RBUFFER//(#bm)$~_replace_string_src/${(e)rep2}} @@ -159,6 +159,11 @@ NetBSD: NetBSD 1.x OpenBSD: OpenBSD 2.x, 3.x Should build `out-of-the-box'. +OpenIndiana: OpenIndiana 151a + Problems have been reported with awk when used to generate + prototype files for building zsh. Upgrading to gawk (GNU awk) + version 4.0.0 fixes this. + SIEMENS: Reliant UNIX [Out of date.] diff --git a/Misc/vcs_info-examples b/Misc/vcs_info-examples index bc10a2179..ba3b2c367 100644 --- a/Misc/vcs_info-examples +++ b/Misc/vcs_info-examples @@ -155,6 +155,23 @@ function +vi-hg-shorthash() { ret=1 } +### Display the existence of files not yet known to VCS + +### git: Show marker (T) if there are untracked files in repository +# Make sure you have added staged to your 'formats': %c +zstyle ':vcs_info:git*+set-message:*' hooks git-untracked + ++vi-git-untracked(){ + if [[ $(git rev-parse --is-inside-work-tree 2> /dev/null) == 'true' ]] && \ + git status --porcelain | grep '??' &> /dev/null ; then + # This will show the marker if there are any untracked files in repo. + # If instead you want to show the marker only if there are untracked + # files in $PWD, use: + #[[ -n $(git ls-files --others --exclude-standard) ]] ; then + hook_com[staged]+='T' + fi +} + ### Compare local changes to remote changes @@ -188,7 +205,11 @@ function +vi-git-remotebranch() { remote=${$(git rev-parse --verify ${hook_com[branch]}@{upstream} \ --symbolic-full-name 2>/dev/null)/refs\/remotes\/} + # The first test will show a tracking branch whenever there is one. The + # second test, however, will only show the remote branch's name if it + # differs from the local one. if [[ -n ${remote} ]] ; then + #if [[ -n ${remote} && ${remote#*/} != ${hook_com[branch]} ]] ; then hook_com[branch]="${hook_com[branch]} [${remote}]" fi } @@ -4,6 +4,12 @@ CHANGES FROM PREVIOUS VERSIONS OF ZSH Note also the list of incompatibilities in the README file. +Changes since 4.3.12 +-------------------- + +There are no significant feature changes to the shell itself, although +many bug fixes and improvements to functions. + Changes since 4.3.11 -------------------- @@ -5,11 +5,11 @@ THE Z SHELL (ZSH) Version ------- -This is version 4.3.12 of the shell. This is a development release, +This is version 4.3.13 of the shell. This is a development release, but is believed to be reasonably stable. Sites where the users need to edit command lines with multibyte characters (in particular UTF-8) will probably want to upgrade. The previous widely released version -of the shell was 4.3.11. +of the shell was 4.3.12. Installing Zsh -------------- diff --git a/Src/Builtins/rlimits.awk b/Src/Builtins/rlimits.awk index b96941125..418206a66 100644 --- a/Src/Builtins/rlimits.awk +++ b/Src/Builtins/rlimits.awk @@ -53,6 +53,7 @@ BEGIN {limidx = 0} if (limnam == "MSGQUEUE") { msg[limnum] = "Nmsgqueue" } if (limnam == "NICE") { msg[limnum] = "Nnice" } if (limnam == "RTPRIO") { msg[limnum] = "Nrt_priority" } + if (limnam == "RTTIME") { msg[limnum] = "Urt_time" } } } } @@ -99,6 +100,7 @@ END { if(limtype == "M") { limtype = "MEMORY" } if(limtype == "N") { limtype = "NUMBER" } if(limtype == "T") { limtype = "TIME" } + if(limtype == "U") { limtype = "MICROSECONDS" } } printf("\tZLIMTYPE_%s,\n", limtype) } diff --git a/Src/Builtins/rlimits.c b/Src/Builtins/rlimits.c index ffcb92052..670516169 100644 --- a/Src/Builtins/rlimits.c +++ b/Src/Builtins/rlimits.c @@ -36,6 +36,7 @@ enum { ZLIMTYPE_MEMORY, ZLIMTYPE_NUMBER, ZLIMTYPE_TIME, + ZLIMTYPE_MICROSECONDS, ZLIMTYPE_UNKNOWN }; @@ -101,9 +102,9 @@ showlimitvalue(int lim, rlim_t val) printf("%lld\n", val); # else # ifdef RLIM_T_IS_UNSIGNED - printf("%lu\n", val); + printf("%lu\n", (unsigned long)val); # else - printf("%ld\n", val); + printf("%ld\n", (long)val); # endif /* RLIM_T_IS_UNSIGNED */ # endif /* RLIM_T_IS_LONG_LONG */ # endif /* RLIM_T_IS_QUAD_T */ @@ -113,10 +114,37 @@ showlimitvalue(int lim, rlim_t val) seconds. */ printf("%d:%02d:%02d\n", (int)(val / 3600), (int)(val / 60) % 60, (int)(val % 60)); + } else if (limtype[lim] == ZLIMTYPE_MICROSECONDS) { + /* microseconds */ +# ifdef RLIM_T_IS_QUAD_T + printf("%qdus\n", val); +# else +# ifdef RLIM_T_IS_LONG_LONG + printf("%lldus\n", val); +# else +# ifdef RLIM_T_IS_UNSIGNED + printf("%luus\n", (unsigned long)val); +# else + printf("%ldus\n", (long)val); +# endif /* RLIM_T_IS_UNSIGNED */ +# endif /* RLIM_T_IS_LONG_LONG */ +# endif /* RLIM_T_IS_QUAD_T */ } else if (limtype[lim] == ZLIMTYPE_NUMBER || limtype[lim] == ZLIMTYPE_UNKNOWN) { /* pure numeric resource */ - printf("%d\n", (int)val); +# ifdef RLIM_T_IS_QUAD_T + printf("%qd\n", val); +# else +# ifdef RLIM_T_IS_LONG_LONG + printf("%lld\n", val); +# else +# ifdef RLIM_T_IS_UNSIGNED + printf("%lu\n", (unsigned long)val); +# else + printf("%ld\n", (long)val); +# endif /* RLIM_T_IS_UNSIGNED */ +# endif /* RLIM_T_IS_LONG_LONG */ +# endif /* RLIM_T_IS_QUAD_T */ } else if (val >= 1024L * 1024L) /* memory resource -- display with `K' or `M' modifier */ # ifdef RLIM_T_IS_QUAD_T @@ -125,18 +153,18 @@ showlimitvalue(int lim, rlim_t val) printf("%qdkB\n", val / 1024L); # else # ifdef RLIM_T_IS_LONG_LONG - printf("%lldMB\n", val / (1024L * 1024L)); + printf("%lldMB\n", val / (1024L * 1024L)); else printf("%lldkB\n", val / 1024L); # else # ifdef RLIM_T_IS_UNSIGNED - printf("%luMB\n", val / (1024L * 1024L)); + printf("%luMB\n", (unsigned long)(val / (1024L * 1024L))); else - printf("%lukB\n", val / 1024L); + printf("%lukB\n", (unsigned long)(val / 1024L)); # else - printf("%ldMB\n", val / (1024L * 1024L)); + printf("%ldMB\n", (long)val / (1024L * 1024L)); else - printf("%ldkB\n", val / 1024L); + printf("%ldkB\n", (long)val / 1024L); # endif /* RLIM_T_IS_UNSIGNED */ # endif /* RLIM_T_IS_LONG_LONG */ # endif /* RLIM_T_IS_QUAD_T */ @@ -370,9 +398,9 @@ printulimit(char *nam, int lim, int hard, int head) printf("%lld\n", limit); # else # ifdef RLIM_T_IS_UNSIGNED - printf("%lu\n", limit); + printf("%lu\n", (unsigned long)limit); # else - printf("%ld\n", limit); + printf("%ld\n", (long)limit); # endif /* RLIM_T_IS_UNSIGNED */ # endif /* RLIM_T_IS_LONG_LONG */ # endif /* RLIM_T_IS_QUAD_T */ @@ -539,7 +567,9 @@ bin_limit(char *nam, char **argv, Options ops, UNUSED(int func)) return 1; } } - } else if (limtype[lim] == ZLIMTYPE_NUMBER || limtype[lim] == ZLIMTYPE_UNKNOWN) { + } else if (limtype[lim] == ZLIMTYPE_NUMBER || + limtype[lim] == ZLIMTYPE_UNKNOWN || + limtype[lim] == ZLIMTYPE_MICROSECONDS) { /* pure numeric resource -- only a straight decimal number is permitted. */ char *t = s; diff --git a/Src/Builtins/rlimits.mdd b/Src/Builtins/rlimits.mdd index ca9fa8b84..9e6e9e598 100644 --- a/Src/Builtins/rlimits.mdd +++ b/Src/Builtins/rlimits.mdd @@ -14,7 +14,7 @@ rlimits.o rlimits..o: rlimits.h rlimits.h: rlimits.awk @RLIMITS_INC_H@ $(AWK) -f $(sdir)/rlimits.awk @RLIMITS_INC_H@ /dev/null > rlimits.h @if grep ZLIMTYPE_UNKNOWN rlimits.h >/dev/null; then \ - echo >&2 WARNING: unknown limits: mail rlimits.h to developers; \ + echo >&2 WARNING: unknown limits: mail Src/Builtins/rlimits.h to developers; \ else :; fi clean-here: clean.rlimits diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c index 45818b968..a4e7eca86 100644 --- a/Src/Modules/datetime.c +++ b/Src/Modules/datetime.c @@ -151,6 +151,69 @@ getcurrentsecs(UNUSED(Param pm)) return (zlong) time(NULL); } +static double +getcurrentrealtime(Param pm) +{ +#ifdef HAVE_CLOCK_GETTIME + struct timespec now; + + if (clock_gettime(CLOCK_REALTIME, &now) < 0) { + zwarn("%s: unable to retrieve time: %e", pm->node.nam, errno); + return (double)0.0; + } + + return (double)now.tv_sec + (double)now.tv_nsec * 1e-9; +#else + struct timeval now; + struct timezone dummy_tz; + + (void)pm; + gettimeofday(&now, &dummy_tz); + + return (double)now.tv_sec + (double)now.tv_usec * 1e-6; +#endif +} + +static char ** +getcurrenttime(Param pm) +{ + char **arr; + char buf[DIGBUFSIZE]; + +#ifdef HAVE_CLOCK_GETTIME + struct timespec now; + + if (clock_gettime(CLOCK_REALTIME, &now) < 0) { + zwarn("%s: unable to retrieve time: %e", pm->node.nam, errno); + return NULL; + } + + arr = (char **)zhalloc(3 * sizeof(*arr)); + sprintf(buf, "%ld", (long)now.tv_sec); + arr[0] = dupstring(buf); + sprintf(buf, "%ld", now.tv_nsec); + arr[1] = dupstring(buf); + arr[2] = NULL; + + return arr; +#else + struct timeval now; + struct timezone dummy_tz; + + (void)pm; + gettimeofday(&now, &dummy_tz); + + arr = (char **)zhalloc(3 * sizeof(*arr)); + sprintf(buf, "%ld", (long)now.tv_sec); + arr[0] = dupstring(buf); + sprintf(buf, "%ld", (long)now.tv_usec * 1000); + arr[1] = dupstring(buf); + arr[2] = NULL; + + return arr; +#endif +} + static struct builtin bintab[] = { BUILTIN("strftime", 0, bin_strftime, 2, 2, 0, "qrs:", NULL), }; @@ -158,9 +221,19 @@ static struct builtin bintab[] = { static const struct gsu_integer epochseconds_gsu = { getcurrentsecs, NULL, stdunsetfn }; +static const struct gsu_float epochrealtime_gsu = +{ getcurrentrealtime, NULL, stdunsetfn }; + +static const struct gsu_array epochtime_gsu = +{ getcurrenttime, NULL, stdunsetfn }; + static struct paramdef patab[] = { SPECIALPMDEF("EPOCHSECONDS", PM_INTEGER|PM_READONLY, &epochseconds_gsu, NULL, NULL), + SPECIALPMDEF("EPOCHREALTIME", PM_FFLOAT|PM_READONLY, + &epochrealtime_gsu, NULL, NULL), + SPECIALPMDEF("epochtime", PM_ARRAY|PM_READONLY, + &epochtime_gsu, NULL, NULL) }; static struct features module_features = { diff --git a/Src/Modules/datetime.mdd b/Src/Modules/datetime.mdd index 0e5ffffb2..b7c1a4a95 100644 --- a/Src/Modules/datetime.mdd +++ b/Src/Modules/datetime.mdd @@ -4,6 +4,6 @@ link=either load=no functions='Functions/Calendar/*' -autofeatures="b:strftime p:EPOCHSECONDS" +autofeatures="b:strftime p:EPOCHSECONDS p:EPOCHREALTIME p:epochtime" objects="datetime.o" diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c index bdbbe19d8..9a2a7a5b9 100644 --- a/Src/Modules/db_gdbm.c +++ b/Src/Modules/db_gdbm.c @@ -39,7 +39,9 @@ #include <gdbm.h> +#if 0 /* what is this for? */ static char *backtype = "db/gdbm"; +#endif static const struct gsu_scalar gdbm_gsu = { gdbmgetfn, gdbmsetfn, gdbmunsetfn }; @@ -138,7 +140,6 @@ static void gdbmsetfn(Param pm, char *val) { datum key, content; - int ret; GDBM_FILE dbf; key.dptr = pm->node.nam; @@ -147,7 +148,7 @@ gdbmsetfn(Param pm, char *val) content.dsize = strlen(content.dptr) + 1; dbf = (GDBM_FILE)(pm->u.hash->tmpdata); - ret = gdbm_store(dbf, key, content, GDBM_REPLACE); + (void)gdbm_store(dbf, key, content, GDBM_REPLACE); } /**/ @@ -155,14 +156,13 @@ static void gdbmunsetfn(Param pm, int um) { datum key; - int ret; GDBM_FILE dbf; key.dptr = pm->node.nam; key.dsize = strlen(key.dptr) + 1; dbf = (GDBM_FILE)(pm->u.hash->tmpdata); - ret = gdbm_delete(dbf, key); + (void)gdbm_delete(dbf, key); } /**/ @@ -171,12 +171,10 @@ getgdbmnode(HashTable ht, const char *name) { int len; char *nameu; - datum key; Param pm = NULL; nameu = dupstring(name); unmetafy(nameu, &len); - key.dptr = nameu; pm = (Param) hcalloc(sizeof(struct param)); pm->node.nam = nameu; diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c index e1a897944..2e3556a8d 100644 --- a/Src/Modules/pcre.c +++ b/Src/Modules/pcre.c @@ -77,6 +77,7 @@ bin_pcre_compile(char *nam, char **args, Options ops, UNUSED(int func)) { int pcre_opts = 0, pcre_errptr; const char *pcre_error; + char *target; if(OPT_ISSET(ops,'a')) pcre_opts |= PCRE_ANCHORED; if(OPT_ISSET(ops,'i')) pcre_opts |= PCRE_CASELESS; @@ -92,8 +93,13 @@ bin_pcre_compile(char *nam, char **args, Options ops, UNUSED(int func)) if (pcre_pattern) pcre_free(pcre_pattern); - pcre_pattern = pcre_compile(*args, pcre_opts, &pcre_error, &pcre_errptr, NULL); + target = ztrdup(*args); + unmetafy(target, NULL); + + pcre_pattern = pcre_compile(target, pcre_opts, &pcre_error, &pcre_errptr, NULL); + free(target); + if (pcre_pattern == NULL) { zwarnnam(nam, "error in regex: %s", pcre_error); @@ -161,7 +167,7 @@ zpcre_get_substrings(char *arg, int *ovec, int ret, char *matchvar, sprintf(offset_all, "%d %d", ovec[0], ovec[1]); setsparam("ZPCRE_OP", ztrdup(offset_all)); } - match_all = ztrdup(captures[0]); + match_all = metafy(captures[0], -1, META_DUP); setsparam(matchvar, match_all); /* * If we're setting match, mbegin, mend we only do @@ -169,7 +175,15 @@ zpcre_get_substrings(char *arg, int *ovec, int ret, char *matchvar, * (c.f. regex.c). */ if (!want_begin_end || nelem) { - matches = zarrdup(&captures[capture_start]); + char **x, **y; + y = &captures[capture_start]; + matches = x = (char **) zalloc(sizeof(char *) * (arrlen(y) + 1)); + do { + if (*y) + *x++ = metafy(*y, -1, META_DUP); + else + *x++ = NULL; + } while (*y++); setaparam(substravar, matches); } @@ -255,6 +269,7 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) { int ret, capcount, *ovec, ovecsize, c; char *matched_portion = NULL; + char *plaintext = NULL; char *receptacle = NULL; int return_value = 1; /* The subject length and offset start are both int values in pcre_exec */ @@ -278,7 +293,7 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) } /* For the entire match, 'Return' the offset byte positions instead of the matched string */ if(OPT_ISSET(ops,'b')) want_offset_pair = 1; - + if(!*args) { zwarnnam(nam, "not enough arguments"); } @@ -288,26 +303,28 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) zwarnnam(nam, "error %d in fullinfo", ret); return 1; } - + ovecsize = (capcount+1)*3; ovec = zalloc(ovecsize*sizeof(int)); - - subject_len = (int)strlen(*args); + + plaintext = ztrdup(*args); + unmetafy(plaintext, NULL); + subject_len = (int)strlen(plaintext); if (offset_start < 0 || offset_start >= subject_len) ret = PCRE_ERROR_NOMATCH; else - ret = pcre_exec(pcre_pattern, pcre_hints, *args, subject_len, offset_start, 0, ovec, ovecsize); + ret = pcre_exec(pcre_pattern, pcre_hints, plaintext, subject_len, offset_start, 0, ovec, ovecsize); if (ret==0) return_value = 0; else if (ret==PCRE_ERROR_NOMATCH) /* no match */; else if (ret>0) { - zpcre_get_substrings(*args, ovec, ret, matched_portion, receptacle, + zpcre_get_substrings(plaintext, ovec, ret, matched_portion, receptacle, want_offset_pair, 0, 0); return_value = 0; } else { - zwarnnam(nam, "error in pcre_exec"); + zwarnnam(nam, "error in pcre_exec [%d]", ret); } if (ovec) @@ -322,7 +339,7 @@ cond_pcre_match(char **a, int id) { pcre *pcre_pat; const char *pcre_err; - char *lhstr, *rhre, *avar=NULL; + char *lhstr, *rhre, *lhstr_plain, *rhre_plain, *avar=NULL; int r = 0, pcre_opts = 0, pcre_errptr, capcnt, *ov, ovsize; int return_value = 0; @@ -331,6 +348,10 @@ cond_pcre_match(char **a, int id) lhstr = cond_str(a,0,0); rhre = cond_str(a,1,0); + lhstr_plain = ztrdup(lhstr); + rhre_plain = ztrdup(rhre); + unmetafy(lhstr_plain, NULL); + unmetafy(rhre_plain, NULL); pcre_pat = NULL; ov = NULL; @@ -339,7 +360,7 @@ cond_pcre_match(char **a, int id) switch(id) { case CPCRE_PLAIN: - pcre_pat = pcre_compile(rhre, pcre_opts, &pcre_err, &pcre_errptr, NULL); + pcre_pat = pcre_compile(rhre_plain, pcre_opts, &pcre_err, &pcre_errptr, NULL); if (pcre_pat == NULL) { zwarn("failed to compile regexp /%s/: %s", rhre, pcre_err); break; @@ -347,7 +368,7 @@ cond_pcre_match(char **a, int id) pcre_fullinfo(pcre_pat, NULL, PCRE_INFO_CAPTURECOUNT, &capcnt); ovsize = (capcnt+1)*3; ov = zalloc(ovsize*sizeof(int)); - r = pcre_exec(pcre_pat, NULL, lhstr, strlen(lhstr), 0, 0, ov, ovsize); + r = pcre_exec(pcre_pat, NULL, lhstr_plain, strlen(lhstr_plain), 0, 0, ov, ovsize); /* r < 0 => error; r==0 match but not enough size in ov * r > 0 => (r-1) substrings found; r==1 => no substrings */ @@ -356,13 +377,16 @@ cond_pcre_match(char **a, int id) return_value = 1; break; } - else if (r==PCRE_ERROR_NOMATCH) return 0; /* no match */ + else if (r==PCRE_ERROR_NOMATCH) { + return_value = 0; /* no match */ + break; + } else if (r<0) { - zwarn("pcre_exec() error: %d", r); + zwarn("pcre_exec() error [%d]", r); break; } else if (r>0) { - zpcre_get_substrings(lhstr, ov, r, NULL, avar, 0, + zpcre_get_substrings(lhstr_plain, ov, r, NULL, avar, 0, isset(BASHREMATCH), !isset(BASHREMATCH)); return_value = 1; @@ -371,6 +395,10 @@ cond_pcre_match(char **a, int id) break; } + if (lhstr_plain) + free(lhstr_plain); + if(rhre_plain) + free(rhre_plain); if (pcre_pat) pcre_free(pcre_pat); if (ov) diff --git a/Src/Modules/pcre.mdd b/Src/Modules/pcre.mdd index 3e1579117..6eb3c691b 100644 --- a/Src/Modules/pcre.mdd +++ b/Src/Modules/pcre.mdd @@ -1,5 +1,5 @@ name=zsh/pcre -link=`if test x$enable_pcre = xyes; then echo dynamic; else echo no; fi` +link=`if test x$enable_pcre = xyes && (pcre-config --version >/dev/null 2>/dev/null); then echo dynamic; else echo no; fi` load=no autofeatures="b:pcre_compile b:pcre_study b:pcre_match" diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c index 8d688abd4..d16e2f618 100644 --- a/Src/Modules/zftp.c +++ b/Src/Modules/zftp.c @@ -2520,7 +2520,7 @@ zftp_local(UNUSED(char *name), char **args, int flags) printf("%s %s\n", output64(sz), mt); #else DPUTS(sizeof(sz) > 4, "Shell compiled with wrong off_t size"); - printf("%ld %s\n", sz, mt); + printf("%ld %s\n", (long)sz, mt); #endif zsfree(mt); if (dofd) diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 5514e2e1d..b1de6c6cc 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -607,7 +607,7 @@ callcompfunc(char *s, char *fn) if (rdstr) compredirect = rdstr; kset |= CP_REDIRECT; - } else + } else { switch (linwhat) { case IN_ENV: compcontext = (linarr ? "array_value" : "value"); @@ -637,6 +637,7 @@ callcompfunc(char *s, char *fn) aadd = 1; } } + } compcontext = ztrdup(compcontext); if (compwords) freearray(compwords); @@ -1099,7 +1100,7 @@ mod_export char * check_param(char *s, int set, int test) { char *p; - int found = 0; + int found = 0, qstring = 0; zsfree(parpre); parpre = NULL; @@ -1126,6 +1127,7 @@ check_param(char *s, int set, int test) !(*p == String && p[1] == Snull) && !(*p == Qstring && p[1] == '\'')) { found = 1; + qstring = (*p == Qstring); break; } } @@ -1150,7 +1152,7 @@ check_param(char *s, int set, int test) p[1] != Inpar && p[1] != Inbrack && p[1] != Snull) { /* This is a parameter expression, not $(...), $[...], $'...'. */ char *b = p + 1, *e = b, *ie; - int n = 0, br = 1, nest = 0; + int br = 1, nest = 0; if (*b == Inbrace) { char *tb = b; @@ -1161,7 +1163,18 @@ check_param(char *s, int set, int test) /* Ignore the possible (...) flags. */ b++, br++; - n = skipparens(Inpar, Outpar, &b); + if ((qstring ? skipparens('(', ')', &b) : + skipparens(Inpar, Outpar, &b)) > 0) { + /* + * We are still within the parameter flags. There's no + * point trying to do anything clever here with + * parameter names. Instead, just report that we are in + * a brace parameter but let the completion function + * decide what to do about it. + */ + ispar = 2; + return NULL; + } for (tb = p - 1; tb > s && *tb != Outbrace && *tb != Inbrace; tb--); if (tb > s && *tb == Inbrace && (tb[-1] == String || *tb == Qstring)) @@ -1204,7 +1217,7 @@ check_param(char *s, int set, int test) } /* Now make sure that the cursor is inside the name. */ - if (offs <= e - s && offs >= b - s && n <= 0) { + if (offs <= e - s && offs >= b - s) { char sav; if (br) { @@ -1465,7 +1478,7 @@ set_comp_sep(void) * when stripping single quotes: 1 for RCQUOTES, 3 otherwise * (because we leave a "'" in the final string). */ - int dq = 0, odq, sq = 0, osq, qttype, sqq = 0, lsq = 0, qa = 0; + int dq = 0, odq, sq = 0, qttype, sqq = 0, lsq = 0, qa = 0; /* dolq: like sq and dq but for dollars quoting. */ int dolq = 0; /* remember some global variable values (except lp is local) */ @@ -1570,7 +1583,6 @@ set_comp_sep(void) } odq = dq; - osq = sq; inpush(dupstrspace(tmp), 0, NULL); zlemetaline = tmp; /* @@ -3294,7 +3306,7 @@ dupmatch(Cmatch m, int nbeg, int nend) mod_export int permmatches(int last) { - Cmgroup g = amatches, n, opm; + Cmgroup g = amatches, n; Cmatch *p, *q; Cexpl *ep, *eq, e, o; LinkList mlist; @@ -3308,7 +3320,6 @@ permmatches(int last) } newmatches = fi = 0; - opm = pmatches; pmatches = lmatches = NULL; nmatches = smatches = diffmatches = 0; diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c index 6398fd3e7..ea5e41f5f 100644 --- a/Src/Zle/complete.c +++ b/Src/Zle/complete.c @@ -1544,7 +1544,7 @@ cond_range(char **a, int id) } static struct builtin bintab[] = { - BUILTIN("compadd", 0, bin_compadd, 0, -1, 0, NULL, NULL), + BUILTIN("compadd", BINF_HANDLES_OPTS, bin_compadd, 0, -1, 0, NULL, NULL), BUILTIN("compset", 0, bin_compset, 1, 3, 0, NULL, NULL), }; diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c index fdca7a99f..bcf356179 100644 --- a/Src/Zle/complist.c +++ b/Src/Zle/complist.c @@ -849,9 +849,9 @@ putmatchcol(char *group, char *n) { Patcol pc; - nrefs = MAX_POS - 1; + for (pc = mcolors.pats; pc; pc = pc->next) { + nrefs = MAX_POS - 1; - for (pc = mcolors.pats; pc; pc = pc->next) if ((!pc->prog || !group || pattry(pc->prog, group)) && pattryrefs(pc->pat, n, -1, -1, 0, &nrefs, begpos, endpos)) { if (pc->cols[1]) { @@ -863,6 +863,7 @@ putmatchcol(char *group, char *n) return 0; } + } zcputs(group, COL_NO); @@ -880,9 +881,9 @@ putfilecol(char *group, char *filename, mode_t m, int special) Patcol pc; int len; - nrefs = MAX_POS - 1; + for (pc = mcolors.pats; pc; pc = pc->next) { + nrefs = MAX_POS - 1; - for (pc = mcolors.pats; pc; pc = pc->next) if ((!pc->prog || !group || pattry(pc->prog, group)) && pattryrefs(pc->pat, filename, -1, -1, 0, &nrefs, begpos, endpos)) { if (pc->cols[1]) { @@ -894,6 +895,7 @@ putfilecol(char *group, char *filename, mode_t m, int special) return 0; } + } if (special != -1) { colour = special; @@ -1369,8 +1371,6 @@ compprintlist(int showall) } #endif if ((e = g->expls)) { - int l; - if (!lastused && lasttype == 1) { e = lastexpl; ml = lastml; @@ -1393,9 +1393,9 @@ compprintlist(int showall) } if (mlbeg < 0 && mfirstl < 0) mfirstl = ml; - l = compprintfmt((*e)->str, - ((*e)->always ? -1 : (*e)->count), - dolist(ml), 1, ml, &stop); + (void)compprintfmt((*e)->str, + ((*e)->always ? -1 : (*e)->count), + dolist(ml), 1, ml, &stop); if (mselect >= 0) { int mm = (mcols * ml), i; diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 6acedee70..3cdc3b2ed 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -53,11 +53,6 @@ mod_export int zlecs, zlell; /**/ mod_export int incompctlfunc; -/* != 0 if we are in a new style completion function */ - -/**/ -mod_export int incompfunc; - /* != 0 if completion module is loaded */ /**/ @@ -1233,7 +1228,7 @@ zleread(char **lp, char **rp, int flags, int context) alarm(0); freeundo(); - if (eofsent) { + if (eofsent || errflag) { s = NULL; } else { zleline[zlell++] = ZWC('\n'); diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index 797f86251..260df8bf6 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -341,7 +341,7 @@ zle_set_highlight(void) match_highlight(*atrs + 8, &special_atr_on); special_atr_on_set = 1; } else if (strpfx("region:", *atrs)) { - match_highlight(*atrs + 7, ®ion_highlights->atr); + match_highlight(*atrs + 7, ®ion_highlights[0].atr); region_atr_on_set = 1; } else if (strpfx("isearch:", *atrs)) { match_highlight(*atrs + 8, &(region_highlights[1].atr)); @@ -357,7 +357,7 @@ zle_set_highlight(void) if (!special_atr_on_set) special_atr_on = TXTSTANDOUT; if (!region_atr_on_set) - region_highlights->atr = TXTSTANDOUT; + region_highlights[0].atr = TXTSTANDOUT; if (!isearch_atr_on_set) region_highlights[1].atr = TXTUNDERLINE; if (!suffix_atr_on_set) @@ -1022,14 +1022,14 @@ zrefresh(void) /* check for region between point ($CURSOR) and mark ($MARK) */ if (region_active) { if (zlecs <= mark) { - region_highlights->start = zlecs; - region_highlights->end = mark; + region_highlights[0].start = zlecs; + region_highlights[0].end = mark; } else { - region_highlights->start = mark; - region_highlights->end = zlecs; + region_highlights[0].start = mark; + region_highlights[0].end = zlecs; } } else { - region_highlights->start = region_highlights->end = -1; + region_highlights[0].start = region_highlights[0].end = -1; } /* check for isearch string to highlight */ if (isearch_active) { @@ -2418,8 +2418,6 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) all_atr_off = TXT_ATTR_OFF_FROM_ON(all_atr_on); if (tmpline[t0] == ZWC('\t')) { - REFRESH_ELEMENT sp = zr_sp; - sp.atr = base_atr_on; for (*vp++ = zr_sp; (vp - vbuf) & 7; ) *vp++ = zr_sp; vp[-1].atr |= base_atr_off; diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c index f712e1750..03e73b4ca 100644 --- a/Src/Zle/zle_thingy.c +++ b/Src/Zle/zle_thingy.c @@ -394,9 +394,13 @@ bin_zle_list(UNUSED(char *name), char **args, Options ops, UNUSED(char func)) Thingy t; for (; *args && !ret; args++) { - if (!(t = (Thingy) thingytab->getnode2(thingytab, *args)) || + HashNode hn = thingytab->getnode2(thingytab, *args); + if (!(t = (Thingy) hn) || (!OPT_ISSET(ops,'a') && (t->widget->flags & WIDGET_INT))) ret = 1; + else if (OPT_ISSET(ops,'L')) { + scanlistwidgets(hn, 1); + } } return ret; } @@ -483,6 +487,12 @@ bin_zle_keymap(char *name, char **args, UNUSED(Options ops), UNUSED(char func)) return selectkeymap(*args, 0); } +/* + * List a widget. + * If list is negative, just print the name. + * If list is 0, use abbreviated format. + * If list is positive, output as a command. + */ /**/ static void scanlistwidgets(HashNode hn, int list) diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 8f7c2aac1..6fa887a1e 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -398,7 +398,18 @@ mod_export char *cmdstr; /**/ mod_export char *varname; -/* != 0 if we are in a subscript */ +/* + * != 0 if we are in a subscript. + * Of course, this being the completion code, you're expected to guess + * what the different numbers actually mean, but here's a cheat: + * 1: Key of an ordinary array + * 2: Key of a hash + * 3: Ummm.... this appears to be a special case of 2. After a lot + * of uncommented code looking for groups of brackets, we suddenly + * decide to set it to 2. The only upshot seems to be that compctl + * then doesn't add a matching ']' at the end, so I think it means + * there's one there already. + */ /**/ mod_export int insubscr; @@ -529,7 +540,7 @@ parambeg(char *s) * or $'...'). */ char *b = p + 1, *e = b; - int n = 0, br = 1, nest = 0; + int n = 0, br = 1; if (*b == Inbrace) { char *tb = b; @@ -541,10 +552,6 @@ parambeg(char *s) /* Ignore the possible (...) flags. */ b++, br++; n = skipparens(Inpar, Outpar, &b); - - for (tb = p - 1; tb > s && *tb != Outbrace && *tb != Inbrace; tb--); - if (tb > s && *tb == Inbrace && (tb[-1] == String || *tb == Qstring)) - nest = 1; } /* Ignore the stuff before the parameter name. */ @@ -1862,6 +1869,10 @@ get_comp_string(void) } } else if (p < curs) { if (*p == Outbrace) { + /* + * HERE: strip and remember code from last + * comma to here. + */ cant = 1; break; } @@ -1869,6 +1880,16 @@ get_comp_string(void) char *tp = p; if (!skipparens(Inbrace, Outbrace, &tp)) { + /* + * Balanced brace: skip. + * We only deal with unfinished braces, so + * something{foo<x>bar,morestuff}else + * doesn't work + * + * HERE: instead, continue, look for a comma. + * Stack tp and brace for popping when we + * find a comma at each level. + */ i += tp - p - 1; dp += tp - p - 1; p = tp - 1; @@ -1911,10 +1932,16 @@ get_comp_string(void) hascom = 1; } } else { + /* On or after the cursor position */ if (*p == Inbrace) { char *tp = p; if (!skipparens(Inbrace, Outbrace, &tp)) { + /* + * Balanced braces after the cursor. + * Could do the same with these as + * those before the cursor. + */ i += tp - p - 1; dp += tp - p - 1; p = tp - 1; @@ -1925,6 +1952,14 @@ get_comp_string(void) break; } if (p == curs) { + /* + * We've reached the cursor position. + * If there's a pending open brace at this + * point we need to stack the text. + * We've marked the bit we don't want from + * bbeg to bend, which might be a comma + * between the opening brace and us. + */ if (bbeg) { Brinfo new; int len = bend - bbeg; @@ -1954,10 +1989,23 @@ get_comp_string(void) bbeg = NULL; } if (*p == Comma) { + /* + * Comma on or after cursor. + * We set bbeg to NULL at the cursor; here + * it's being used to find the first comma + * afterwards. + */ if (!bbeg) bbeg = p; hascom = 2; } else if (*p == Outbrace) { + /* + * Closing brace on or after the cursor. + * Not sure how this can be after the cursor; + * if it was matched, wouldn't we have skipped + * over the group, and if it wasn't, surely we're + * not interested in it? + */ Brinfo new; int len; @@ -2150,10 +2198,6 @@ doexpansion(char *s, int lst, int olst, int explincmd) ss = quotename(ss, NULL); untokenize(ss); inststr(ss); -#if 0 - if (olst != COMP_EXPAND_COMPLETE || nonempty(vl) || - (zlemetacs && zlemetaline[zlemetacs-1] != '/')) { -#endif if (nonempty(vl) || !first) { spaceinline(1); zlemetaline[zlemetacs++] = ' '; diff --git a/Src/builtin.c b/Src/builtin.c index fc98eb1b1..71fc04ce1 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -99,7 +99,7 @@ static struct builtin builtins[] = #endif BUILTIN("popd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 1, BIN_POPD, "q", NULL), - BUILTIN("print", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, "abcC:Df:ilmnNoOpPrRsu:z-", NULL), + BUILTIN("print", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, "abcC:Df:ilmnNoOpPrRsSu:z-", NULL), BUILTIN("printf", 0, bin_print, 1, -1, BIN_PRINTF, NULL, NULL), BUILTIN("pushd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_PUSHD, "qsPL", NULL), BUILTIN("pushln", 0, bin_print, 0, -1, BIN_PRINT, NULL, "-nz"), @@ -3965,25 +3965,45 @@ bin_print(char *name, char **args, Options ops, int func) return 0; } /* -s option -- add the arguments to the history list */ - if (OPT_ISSET(ops,'s')) { + if (OPT_ISSET(ops,'s') || OPT_ISSET(ops,'S')) { int nwords = 0, nlen, iwords; char **pargs = args; queue_signals(); - ent = prepnexthistent(); while (*pargs++) nwords++; - if ((ent->nwords = nwords)) { - ent->words = (short *)zalloc(nwords*2*sizeof(short)); - nlen = iwords = 0; - for (pargs = args; *pargs; pargs++) { - ent->words[iwords++] = nlen; - nlen += strlen(*pargs); - ent->words[iwords++] = nlen; - nlen++; + if (nwords) { + if (OPT_ISSET(ops,'S')) { + int wordsize; + short *words; + if (nwords > 1) { + zwarnnam(name, "option -S takes a single argument"); + return 1; + } + words = NULL; + wordsize = 0; + histsplitwords(*args, &words, &wordsize, &nwords, 1); + ent = prepnexthistent(); + ent->words = (short *)zalloc(nwords*sizeof(short)); + memcpy(ent->words, words, nwords*sizeof(short)); + free(words); + ent->nwords = nwords/2; + } else { + ent = prepnexthistent(); + ent->words = (short *)zalloc(nwords*2*sizeof(short)); + ent->nwords = nwords; + nlen = iwords = 0; + for (pargs = args; *pargs; pargs++) { + ent->words[iwords++] = nlen; + nlen += strlen(*pargs); + ent->words[iwords++] = nlen; + nlen++; + } } - } else + } else { + ent = prepnexthistent(); ent->words = (short *)NULL; + } ent->node.nam = zjoin(args, ' ', 0); ent->stim = ent->ftim = time(NULL); ent->node.flags = 0; @@ -5529,7 +5549,14 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) *bptr = '\0'; #endif /* dispose of word appropriately */ - if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) { + if (OPT_ISSET(ops,'e') || + /* + * When we're doing an array assignment, we'll + * handle echoing at that point. In all other + * cases (including -A with no assignment) + * we'll do it here. + */ + (OPT_ISSET(ops,'E') && !OPT_ISSET(ops,'A'))) { zputs(buf, stdout); putchar('\n'); } @@ -5561,7 +5588,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) : (char **)zalloc((al + 1) * sizeof(char *))); for (pp = p, n = firstnode(readll); n; incnode(n)) { - if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) { + if (OPT_ISSET(ops,'E')) { zputs((char *) getdata(n), stdout); putchar('\n'); } diff --git a/Src/exec.c b/Src/exec.c index 2558185c8..2c644e6b7 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -50,20 +50,20 @@ int noerrexit; * noerrs = 1: suppress error messages * noerrs = 2: don't set errflag on parse error, either */ - + /**/ mod_export int noerrs; - + /* do not save history on exec and exit */ /**/ int nohistsave; - + /* error/break flag */ - + /**/ mod_export int errflag; - + /* * State of trap return value. Value is from enum trap_state. */ @@ -88,23 +88,23 @@ int trap_state; * - non-negative in a trap once it was triggered. It should remain * non-negative until restored after execution of the trap. */ - + /**/ int trap_return; - + /* != 0 if this is a subshell */ - + /**/ int subsh; - + /* != 0 if we have a return pending */ - + /**/ mod_export int retflag; /**/ long lastval2; - + /* The table of file descriptors. A table element is zero if the * * corresponding fd is not used by the shell. It is greater than * * 1 if the fd is used by a <(...) or >(...) substitution and 1 if * @@ -148,12 +148,12 @@ int fdtable_flocks; mod_export int zleactive; /* pid of process undergoing 'process substitution' */ - + /**/ pid_t cmdoutpid; - + /* exit status of process undergoing 'process substitution' */ - + /**/ int cmdoutval; @@ -166,7 +166,7 @@ int cmdoutval; /**/ int use_cmdoutval; -/* The context in which a shell function is called, see SFC_* in zsh.h. */ +/* The context in which a shell function is called, see SFC_* in zsh.h. */ /**/ mod_export int sfcontext; @@ -239,7 +239,7 @@ parse_string(char *s, int reset_lineno) /**/ mod_export struct rlimit current_limits[RLIM_NLIMITS], limits[RLIM_NLIMITS]; - + /**/ mod_export int zsetlimit(int limnum, char *nam) @@ -340,7 +340,7 @@ zfork(struct timeval *tv) * * (when waiting for the grep, ignoring execpline2 for now). At this time, * zsh has built two job-table entries for it: one for the cat and one for - * the grep. If the user hits ^Z at this point (and jobbing is used), the + * the grep. If the user hits ^Z at this point (and jobbing is used), the * shell is notified that the grep was suspended. The list_pipe flag is * used to tell the execpline where it was waiting that it was in a pipeline * with a shell construct at the end (which may also be a shell function or @@ -351,7 +351,7 @@ zfork(struct timeval *tv) * shell (its pid and the text for it) in the job entry of the cat. The pid * is passed down in the list_pipe_pid variable. * But there is a problem: the suspended grep is a child of the parent shell - * and can't be adopted by the sub-shell. So the parent shell also has to + * and can't be adopted by the sub-shell. So the parent shell also has to * keep the information about this process (more precisely: this pipeline) * by keeping the job table entry it created for it. The fact that there * are two jobs which have to be treated together is remembered by setting @@ -405,7 +405,7 @@ execcursh(Estate state, int do_exec) state->pc++; if (!list_pipe && thisjob != list_pipe_job && !hasprocs(thisjob)) - deletejob(jobtab + thisjob); + deletejob(jobtab + thisjob, 0); cmdpush(CS_CURSH); execlist(state, 1, do_exec); cmdpop(); @@ -528,10 +528,10 @@ isgooderr(int e, char *dir) { /* * Maybe the directory was unreadable, or maybe it wasn't - * even a directory. + * even a directory. */ return ((e != EACCES || !access(dir, X_OK)) && - e != ENOENT && e != ENOTDIR); + e != ENOENT && e != ENOTDIR); } /* @@ -639,7 +639,7 @@ execute(LinkList args, int flags, int defpath) break; } - /* for command -p, search the default path */ + /* for command -p, search the default path */ if (defpath) { char *s, pbuf[PATH_MAX]; char *dptr, *pe, *ps = DEFAULT_PATH; @@ -676,7 +676,7 @@ execute(LinkList args, int flags, int defpath) eno = ee; } else { - + if ((cn = (Cmdnam) cmdnamtab->getnode(cmdnamtab, arg0))) { char nn[PATH_MAX], *dptr; @@ -1312,9 +1312,9 @@ sublist_done: donetrap = 1; } if (lastval) { - int errreturn = isset(ERRRETURN) && + int errreturn = isset(ERRRETURN) && (isset(INTERACTIVE) || locallevel || sourcelevel); - int errexit = isset(ERREXIT) || + int errexit = isset(ERREXIT) || (isset(ERRRETURN) && !errreturn); if (errexit) { if (sigtrapped[SIGEXIT]) @@ -1434,7 +1434,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) zclose(opipe[0]); } if (how & Z_DISOWN) { - deletejob(jobtab + thisjob); + deletejob(jobtab + thisjob, 1); thisjob = -1; } else @@ -1484,7 +1484,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) printjob(jn, !!isset(LONGLISTJOBS), 1); } else if (newjob != list_pipe_job) - deletejob(jn); + deletejob(jn, 0); else lastwj = -1; } @@ -1536,7 +1536,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) else if (pid) { char dummy; - lpforked = + lpforked = (killpg(jobtab[list_pipe_job].gleader, 0) == -1 ? 2 : 1); list_pipe_pid = pid; list_pipe_start = bgtime; @@ -1588,7 +1588,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) if (list_pipe && (lastval & 0200) && pj >= 0 && (!(jn->stat & STAT_INUSE) || (jn->stat & STAT_DONE))) { - deletejob(jn); + deletejob(jn, 0); jn = jobtab + pj; if (jn->gleader) killjb(jn, lastval & ~0200); @@ -1596,7 +1596,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) if (list_pipe_child || ((jn->stat & STAT_DONE) && (list_pipe || (pline_level && !(jn->stat & STAT_SUBJOB))))) - deletejob(jn); + deletejob(jn, 0); thisjob = pj; } @@ -2845,7 +2845,11 @@ execcmd(Estate state, int input, int output, int how, int last1) /* This is a current shell procedure that didn't need to fork. * * This includes current shell procedures that are being exec'ed, * * as well as null execs. */ - jobtab[thisjob].stat |= STAT_CURSH|STAT_NOPRINT; + jobtab[thisjob].stat |= STAT_CURSH; + if (!jobtab[thisjob].procs) + jobtab[thisjob].stat |= STAT_NOPRINT; + if (is_builtin) + jobtab[thisjob].stat |= STAT_BUILTIN; } else { /* This is an exec (real or fake) for an external command. * * Note that any form of exec means that the subshell is fake * @@ -2908,6 +2912,7 @@ execcmd(Estate state, int input, int output, int how, int last1) } addfd(forked, save, mfds, fn->fd1, fn->fd2, 1, fn->varid); } else { + int closed; if (fn->type != REDIR_HERESTR && xpandredir(fn, redir)) continue; if (errflag) { @@ -2975,17 +2980,16 @@ execcmd(Estate state, int input, int output, int how, int last1) fn->fd1 = (int)getintvalue(v); if (errflag) bad = 1; - else if (fn->fd1 > max_zsh_fd) - bad = 3; - else if (fn->fd1 >= 10 && + else if (fn->fd1 <= max_zsh_fd) { + if (fn->fd1 >= 10 && fdtable[fn->fd1] == FDT_INTERNAL) - bad = 4; + bad = 3; + } } if (bad) { const char *bad_msg[] = { "parameter %s does not contain a file descriptor", "can't close file descriptor from readonly parameter %s", - "file descriptor %d out of range, not closed", "file descriptor %d used by shell, not closed" }; if (bad > 2) @@ -2995,11 +2999,27 @@ execcmd(Estate state, int input, int output, int how, int last1) execerr(); } } - if (!forked && fn->fd1 < 10 && save[fn->fd1] == -2) + /* + * Note we may attempt to close an fd beyond max_zsh_fd: + * OK as long as we never look in fdtable for it. + */ + closed = 0; + if (!forked && fn->fd1 < 10 && save[fn->fd1] == -2) { save[fn->fd1] = movefd(fn->fd1); + if (save[fn->fd1] >= 0) { + /* + * The original fd is now closed, we don't need + * to do it below. + */ + closed = 1; + } + } if (fn->fd1 < 10) closemn(mfds, fn->fd1); - zclose(fn->fd1); + if (!closed && zclose(fn->fd1) < 0) { + zwarn("failed to close file descriptor %d: %e", + fn->fd1, errno); + } break; case REDIR_MERGEIN: case REDIR_MERGEOUT: @@ -3008,11 +3028,17 @@ execcmd(Estate state, int input, int output, int how, int last1) if (!checkclobberparam(fn)) fil = -1; else if (fn->fd2 > 9 && - (fn->fd2 > max_zsh_fd || - (fdtable[fn->fd2] != FDT_UNUSED && - fdtable[fn->fd2] != FDT_EXTERNAL) || - fn->fd2 == coprocin || - fn->fd2 == coprocout)) { + /* + * If the requested fd is > max_zsh_fd, + * the shell doesn't know about it. + * Just assume the user knows what they're + * doing. + */ + (fn->fd2 <= max_zsh_fd && + ((fdtable[fn->fd2] != FDT_UNUSED && + fdtable[fn->fd2] != FDT_EXTERNAL) || + fn->fd2 == coprocin || + fn->fd2 == coprocout))) { fil = -1; errno = EBADF; } else { @@ -3112,7 +3138,7 @@ execcmd(Estate state, int input, int output, int how, int last1) ESUB_PGRP | ESUB_FAKE; if (type != WC_SUBSH) flags |= ESUB_KEEPTRAP; - if ((do_exec || (type >= WC_CURSH && last1 == 1)) + if ((do_exec || (type >= WC_CURSH && last1 == 1)) && !forked) flags |= ESUB_REVERTPGRP; entersubsh(flags); @@ -3739,7 +3765,15 @@ parsecmd(char *cmd, char **eptr) for (str = cmd + 2; *str && *str != Outpar; str++); if (!*str || cmd[1] != Inpar) { - zerr("oops."); + /* + * This can happen if the expression is being parsed + * inside another construct, e.g. as a value within ${..:..} etc. + * So print a proper error message instead of the not very + * useful but traditional "oops". + */ + char *errstr = dupstrpfx(cmd, 2); + untokenize(errstr); + zerr("unterminated `%s...)'", errstr); return NULL; } *str = '\0'; @@ -4184,10 +4218,19 @@ execfuncdef(Estate state, UNUSED(int do_exec)) * Anonymous function, execute immediately. * Function name is "(anon)", parameter list is empty. */ - LinkList args = newlinklist(); + LinkList args; + state->pc = end; + end += *state->pc++; + args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok); + + if (htok && args) + execsubst(args); + + if (!args) + args = newlinklist(); shf->node.nam = "(anon)"; - addlinknode(args, shf->node.nam); + pushnode(args, shf->node.nam); execshfunc(shf, args); ret = lastval; @@ -4238,7 +4281,7 @@ execshfunc(Shfunc shf, LinkList args) * would be filled by a recursive function. */ last_file_list = jobtab[thisjob].filelist; jobtab[thisjob].filelist = NULL; - deletejob(jobtab + thisjob); + deletejob(jobtab + thisjob, 0); } if (isset(XTRACE)) { @@ -4267,7 +4310,7 @@ execshfunc(Shfunc shf, LinkList args) cmdsp = ocsp; if (!list_pipe) - deletefilelist(last_file_list); + deletefilelist(last_file_list, 0); } /* Function to execute the special type of command that represents an * @@ -4334,6 +4377,7 @@ loadautofn(Shfunc shf, int fksh, int autol) } if (!prog) { zsfree(fname); + popheap(); return NULL; } if (ksh == 2 || (ksh == 1 && isset(KSHAUTOLOAD))) { diff --git a/Src/glob.c b/Src/glob.c index bfc7f0416..cf4a5a537 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -1801,7 +1801,7 @@ zglob(LinkList list, LinkNode np, int nountok) Eprog prog; if ((prog = parse_string(sortp->exec, 0))) { - int ef = errflag, lv = lastval, ret; + int ef = errflag, lv = lastval; /* Parsed OK, execute for each name */ for (tmpptr = matchbuf; tmpptr < matchptr; tmpptr++) { @@ -1814,7 +1814,6 @@ zglob(LinkList list, LinkNode np, int nountok) tmpptr->sortstrs[iexec] = tmpptr->name; } - ret = lastval; errflag = ef; lastval = lv; } else { diff --git a/Src/hist.c b/Src/hist.c index 01a97da2b..aeb6edda5 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -229,7 +229,7 @@ ihwaddc(int c) /* Quote un-expanded bangs in the history line. */ if (c == bangchar && stophist < 2 && qbang) /* If qbang is not set, we do not escape this bangchar as it's * - * not mecessary (e.g. it's a bang in !=, or it is followed * + * not necessary (e.g. it's a bang in !=, or it is followed * * by a space). Roughly speaking, qbang is zero only if the * * history interpreter has already digested this bang and * * found that it is not necessary to escape it. */ @@ -876,7 +876,18 @@ hbegin(int dohist) stophist = (!interact || unset(SHINSTDIN)) ? 2 : 0; else stophist = 0; - if (stophist == 2 || (inbufflags & INP_ALIAS)) { + /* + * pws: We used to test for "|| (inbufflags & INP_ALIAS)" + * in this test, but at this point we don't have input + * set up up so this can trigger unnecessarily. + * I don't see how the test at this point could ever be + * useful, since we only get here when we're initialising + * the history mechanism, before we've done any input. + * + * (I also don't see any point where this function is called with + * dohist=0.) + */ + if (stophist == 2) { chline = hptr = NULL; hlinesz = 0; chwords = NULL; @@ -1344,7 +1355,8 @@ ihwend(void) (chwordlen += 32) * sizeof(short)); } - if (hwgetword > -1) { + if (hwgetword > -1 && + (inbufflags & INP_ALIAS) && !(inbufflags & INP_HIST)) { /* We want to reuse the current word position */ chwordpos = hwgetword; /* Start from where previous word ended, if possible */ @@ -2235,10 +2247,12 @@ readhistfile(char *fn, int err, int readflags) if (!fn && !(fn = getsparam("HISTFILE"))) return; + if (stat(unmeta(fn), &sb) < 0 || + sb.st_size == 0) + return; if (readflags & HFILE_FAST) { - if (stat(unmeta(fn), &sb) < 0 - || (lasthist.fsiz == sb.st_size && lasthist.mtim == sb.st_mtime) - || lockhistfile(fn, 0)) + if ((lasthist.fsiz == sb.st_size && lasthist.mtim == sb.st_mtime) + || lockhistfile(fn, 0)) return; lasthist.fsiz = sb.st_size; lasthist.mtim = sb.st_mtime; @@ -2338,110 +2352,11 @@ readhistfile(char *fn, int err, int readflags) /* * Divide up the words. */ - nwordpos = 0; start = pt; uselex = isset(HISTLEXWORDS) && !(readflags & HFILE_FAST); - if (uselex) { - /* - * Attempt to do this using the lexer. - */ - LinkList wordlist = bufferwords(NULL, pt, NULL, - LEXFLAGS_COMMENTS_KEEP); - LinkNode wordnode; - int nwords_max; - nwords_max = 2 * countlinknodes(wordlist); - if (nwords_max > nwords) { - nwords = nwords_max; - words = (short *)realloc(words, nwords*sizeof(short)); - } - for (wordnode = firstnode(wordlist); - wordnode; - incnode(wordnode)) { - char *word = getdata(wordnode); - - for (;;) { - /* - * Not really an oddity: "\\\n" is - * removed from input as if whitespace. - */ - if (inblank(*pt)) - pt++; - else if (pt[0] == '\\' && pt[1] == '\n') - pt += 2; - else - break; - } - if (!strpfx(word, pt)) { - int bad = 0; - /* - * Oddity 1: newlines turn into semicolons. - */ - if (!strcmp(word, ";")) - continue; - while (*pt) { - if (!*word) { - bad = 1; - break; - } - /* - * Oddity 2: !'s turn into |'s. - */ - if (*pt == *word || - (*pt == '!' && *word == '|')) { - pt++; - word++; - } else { - bad = 1; - break; - } - } - if (bad) { -#ifdef DEBUG - dputs(ERRMSG("bad wordsplit reading history: " - "%s\nat: %s\nword: %s"), - start, pt, word); -#endif - pt = start; - nwordpos = 0; - uselex = 0; - break; - } - } else if (!strcmp(word, ";") && strpfx(";;", pt)) { - /* - * Don't get confused between a semicolon that's - * probably really a newline and a double - * semicolon that's terminating a case. - */ - continue; - } - words[nwordpos++] = pt - start; - pt += strlen(word); - words[nwordpos++] = pt - start; - } + histsplitwords(pt, &words, &nwords, &nwordpos, uselex); + if (uselex) freeheap(); - } - if (!uselex) { - do { - for (;;) { - if (inblank(*pt)) - pt++; - else if (pt[0] == '\\' && pt[1] == '\n') - pt += 2; - else - break; - } - if (*pt) { - if (nwordpos >= nwords) - words = (short *) - realloc(words, (nwords += 64)*sizeof(short)); - words[nwordpos++] = pt - start; - while (*pt && !inblank(*pt)) - pt++; - words[nwordpos++] = pt - start; - } - } while (*pt); - - } he->nwords = nwordpos/2; if (he->nwords) { @@ -3141,6 +3056,207 @@ bufferwords(LinkList list, char *buf, int *index, int flags) return list; } +/* + * Split up a line into words for use in a history file. + * + * lineptr is the line to be split. + * + * *wordsp and *nwordsp are an array already allocated to hold words + * and its length. The array holds both start and end positions, + * so *nwordsp actually counts twice the number of words in the + * original string. *nwordsp may be zero in which case the array + * will be allocated. + * + * *nwordposp returns the used length of *wordsp in the same units as + * *nwordsp, i.e. twice the number of words in the input line. + * + * If uselex is 1, attempt to do this using the lexical analyser. + * This is more accurate, but slower; for reading history files it's + * controlled by the option HISTLEXWORDS. If this failed (which + * indicates a bug in the shell) it falls back to whitespace-separated + * strings, printing a message if in debug mode. + * + * If uselex is 0, just look for whitespace-separated words; the only + * special handling is for a backslash-newline combination as used + * by the history file format to save multiline buffers. + */ +/**/ +mod_export void +histsplitwords(char *lineptr, short **wordsp, int *nwordsp, int *nwordposp, + int uselex) +{ + int nwords = *nwordsp, nwordpos = 0; + short *words = *wordsp; + char *start = lineptr; + + if (uselex) { + LinkList wordlist = bufferwords(NULL, lineptr, NULL, + LEXFLAGS_COMMENTS_KEEP); + LinkNode wordnode; + int nwords_max; + + nwords_max = 2 * countlinknodes(wordlist); + if (nwords_max > nwords) { + *nwordsp = nwords = nwords_max; + *wordsp = words = (short *)zrealloc(words, nwords*sizeof(short)); + } + for (wordnode = firstnode(wordlist); + wordnode; + incnode(wordnode)) { + char *word = getdata(wordnode); + char *lptr, *wptr = word; + int loop_next = 0, skipping; + + /* Skip stuff at the start of the word */ + for (;;) { + /* + * Not really an oddity: "\\\n" is + * removed from input as if whitespace. + */ + if (inblank(*lineptr)) + lineptr++; + else if (lineptr[0] == '\\' && lineptr[1] == '\n') { + /* + * Optimisation: we handle this in the loop below, + * too. + */ + lineptr += 2; + } else + break; + } + lptr = lineptr; + /* + * Skip chunks of word with possible intervening + * backslash-newline. + * + * To get round C's annoying lack of ability to + * reference the outer loop, we'll break from this + * one with + * loop_next = 0: carry on as normal + * loop_next = 1: break from outer loop + * loop_next = 2: continue round outer loop. + */ + do { + skipping = 0; + if (strpfx(wptr, lptr)) { + /* + * Normal case: word from lexer matches start of + * string from line. Just advance over it. + */ + int len; + if (!strcmp(wptr, ";") && strpfx(";;", lptr)) { + /* + * Don't get confused between a semicolon that's + * probably really a newline and a double + * semicolon that's terminating a case. + */ + loop_next = 2; + break; + } + len = strlen(wptr); + lptr += len; + wptr += len; + } else { + /* + * Didn't get to the end of the word. + * See what's amiss. + */ + int bad = 0; + /* + * Oddity 1: newlines turn into semicolons. + */ + if (!strcmp(wptr, ";")) + { + loop_next = 2; + break; + } + while (*lptr) { + if (!*wptr) { + /* + * End of the word before the end of the + * line: not good. + */ + bad = 1; + loop_next = 1; + break; + } + /* + * Oddity 2: !'s turn into |'s. + */ + if (*lptr == *wptr || + (*lptr == '!' && *wptr == '|')) { + lptr++; + wptr++; + } else if (lptr[0] == '\\' && + lptr[1] == '\n') { + /* + * \\\n can occur in the middle of a word; + * wptr is already pointing at this, we + * just need to skip over the break + * in lptr and look at the next chunk. + */ + lptr += 2; + skipping = 1; + break; + } else { + bad = 1; + loop_next = 1; + break; + } + } + if (bad) { +#ifdef DEBUG + dputs(ERRMSG("bad wordsplit reading history: " + "%s\nat: %s\nword: %s"), + start, lineptr, word); +#endif + lineptr = start; + nwordpos = 0; + uselex = 0; + loop_next = 1; + } + } + } while (skipping); + if (loop_next) { + if (loop_next == 1) + break; + continue; + } + /* Record position of current word... */ + words[nwordpos++] = lineptr - start; + words[nwordpos++] = lptr - start; + + /* ready for start of next word. */ + lineptr = lptr; + } + } + if (!uselex) { + do { + for (;;) { + if (inblank(*lineptr)) + lineptr++; + else if (lineptr[0] == '\\' && lineptr[1] == '\n') + lineptr += 2; + else + break; + } + if (*lineptr) { + if (nwordpos >= nwords) { + *nwordsp = nwords = nwords + 64; + *wordsp = words = (short *) + zrealloc(words, nwords*sizeof(*words)); + } + words[nwordpos++] = lineptr - start; + while (*lineptr && !inblank(*lineptr)) + lineptr++; + words[nwordpos++] = lineptr - start; + } + } while (*lineptr); + } + + *nwordposp = nwordpos; +} + /* Move the current history list out of the way and prepare a fresh history * list using hf for HISTFILE, hs for HISTSIZE, and shs for SAVEHIST. If * the hf value is an empty string, HISTFILE will be unset from the new diff --git a/Src/jobs.c b/Src/jobs.c index b3ec0008c..94d25bb85 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -160,6 +160,8 @@ findproc(pid_t pid, Job *jptr, Process *pptr, int aux) Process pn; int i; + *jptr = NULL; + *pptr = NULL; for (i = 1; i <= maxjob; i++) { /* @@ -189,15 +191,16 @@ findproc(pid_t pid, Job *jptr, Process *pptr, int aux) * the termination of the process which pid we were supposed * to return in a different job. */ - if (pn->pid == pid && pn->status == SP_RUNNING) { + if (pn->pid == pid) { *pptr = pn; *jptr = jobtab + i; - return 1; + if (pn->status == SP_RUNNING) + return 1; } } } - return 0; + return (*pptr && *jptr); } /* Does the given job number have any processes? */ @@ -266,7 +269,7 @@ handle_sub(int job, int fg) sleep, the rest will be executed by a sub-shell, but the parent shell gets notified for the sleep. - deletejob(sj); */ + deletejob(sj, 0); */ /* If this super-job contains only the sub-shell, we have to attach the tty to its process group now. */ @@ -950,7 +953,9 @@ printjob(Job jn, int lng, int synch) if (skip_print) { if (jn->stat & STAT_DONE) { - deletejob(jn); + if (should_report_time(jn)) + dumptime(jn); + deletejob(jn, 0); if (job == curjob) { curjob = prevjob; prevjob = job; @@ -1080,7 +1085,7 @@ printjob(Job jn, int lng, int synch) if (jn->stat & STAT_DONE) { if (should_report_time(jn)) dumptime(jn); - deletejob(jn); + deletejob(jn, 0); if (job == curjob) { curjob = prevjob; prevjob = job; @@ -1095,12 +1100,13 @@ printjob(Job jn, int lng, int synch) /**/ void -deletefilelist(LinkList file_list) +deletefilelist(LinkList file_list, int disowning) { char *s; if (file_list) { while ((s = (char *)getlinknode(file_list))) { - unlink(s); + if (!disowning) + unlink(s); zsfree(s); } zfree(file_list, sizeof(struct linklist)); @@ -1136,7 +1142,7 @@ freejob(Job jn, int deleting) /* careful in case we shrink and move the job table */ int job = jn - jobtab; if (deleting) - deletejob(jobtab + jn->other); + deletejob(jobtab + jn->other, 0); else freejob(jobtab + jn->other, 0); jn = jobtab + job; @@ -1156,13 +1162,17 @@ freejob(Job jn, int deleting) /* * We are actually finished with this job, rather * than freeing it to make space. + * + * If "disowning" is set, files associated with the job are not + * actually deleted --- and won't be as there is nothing left + * to clear up. */ /**/ void -deletejob(Job jn) +deletejob(Job jn, int disowning) { - deletefilelist(jn->filelist); + deletefilelist(jn->filelist, disowning); if (jn->stat & STAT_ATTACH) { attachtty(mypgrp); adjustwinsize(0); @@ -1338,7 +1348,7 @@ zwaitjob(int job, int wait_cmd) child_block(); } } else { - deletejob(jn); + deletejob(jn, 0); pipestats[0] = lastval; numpipestats = 1; } @@ -1361,7 +1371,7 @@ waitjobs(void) if (jn->procs || jn->auxprocs) zwaitjob(thisjob, 0); else { - deletejob(jn); + deletejob(jn, 0); pipestats[0] = lastval; numpipestats = 1; } @@ -1489,7 +1499,7 @@ spawnjob(void) } } if (!hasprocs(thisjob)) - deletejob(jobtab + thisjob); + deletejob(jobtab + thisjob, 0); else jobtab[thisjob].stat |= STAT_LOCKED; thisjob = -1; @@ -1930,12 +1940,19 @@ bin_fg(char *name, char **argv, Options ops, int func) Process p; if (findproc(pid, &j, &p, 0)) { - /* - * returns 0 for normal exit, else signal+128 - * in which case we should return that status. - */ - retval = waitforpid(pid, 1); - if (!retval) + if (j->stat & STAT_STOPPED) { + retval = (killjb(j, SIGCONT) != 0); + if (retval == 0) + makerunning(j); + } + if (retval == 0) { + /* + * returns 0 for normal exit, else signal+128 + * in which case we should return that status. + */ + retval = waitforpid(pid, 1); + } + if (retval == 0) retval = lastval2; } else if (isset(POSIXJOBS) && pid == lastpid && lastpid_status >= 0L) { @@ -2058,7 +2075,7 @@ bin_fg(char *name, char **argv, Options ops, int func) waitjobs(); retval = lastval2; } else if (ofunc == BIN_DISOWN) - deletejob(jobtab + job); + deletejob(jobtab + job, 1); break; case BIN_JOBS: printjob(job + (oldjobtab ? oldjobtab : jobtab), lng, 2); @@ -2094,7 +2111,7 @@ bin_fg(char *name, char **argv, Options ops, int func) #endif pids); } - deletejob(jobtab + job); + deletejob(jobtab + job, 1); break; } thisjob = ocj; @@ -2245,7 +2262,7 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func)) } if (sig > SIGCOUNT) { zwarnnam(nam, "unknown signal: SIG%s", signame); - zwarnnam(nam, "type kill -l for a List of signals"); + zwarnnam(nam, "type kill -l for a list of signals"); return 1; } } @@ -1567,7 +1567,7 @@ dquote_parse(char endchar, int sub) err = (!brct-- && math); break; case '"': - if (intick || ((endchar == ']' || !endchar) && !bct)) + if (intick || (endchar != '"' && !bct)) break; if (bct) { add(Dnull); @@ -1698,7 +1698,7 @@ parse_subscript(char *s, int sub, int endchar) mod_export int parse_subst_string(char *s) { - int c, l = strlen(s), err, olen, lexstop_ret; + int c, l = strlen(s), err; char *ptr; if (!*s || !strcmp(s, nulstring)) @@ -1711,13 +1711,11 @@ parse_subst_string(char *s) bptr = tokstr = s; bsiz = l + 1; c = hgetc(); - lexstop_ret = lexstop; c = gettokstr(c, 1); err = errflag; strinend(); inpop(); DPUTS(cmdsp, "BUG: parse_subst_string: cmdstack not empty."); - olen = len; lexrestore(); errflag = err; if (c == LEXERR) { @@ -1726,8 +1724,9 @@ parse_subst_string(char *s) } #ifdef DEBUG /* - * Historical note: we used to check here for olen == l, but - * that's not necessarily the case if we stripped an RCQUOTE. + * Historical note: we used to check here for olen (the value of len + * before lexrestore()) == l, but that's not necessarily the case if + * we stripped an RCQUOTE. */ if (c != STRING || (errflag && !noerrs)) { fprintf(stderr, "Oops. Bug in parse_subst_string: %s\n", diff --git a/Src/math.c b/Src/math.c index beef74525..cca521098 100644 --- a/Src/math.c +++ b/Src/math.c @@ -969,7 +969,6 @@ void op(int what) { mnumber a, b, c, *spval; - char *lv; int tp = type[what]; if (errflag) @@ -1155,7 +1154,6 @@ op(int what) } if (tp & (OP_E2|OP_E2IO)) { struct mathvalue *mvp = stack + sp + 1; - lv = stack[sp+1].lval; c = setmathvar(mvp, c); push(c, mvp->lval, 0); } else diff --git a/Src/module.c b/Src/module.c index 219bdfa8e..5cc595c47 100644 --- a/Src/module.c +++ b/Src/module.c @@ -1081,6 +1081,11 @@ addparamdef(Paramdef d) pm->gsu.i = d->gsu ? (GsuInteger)d->gsu : &varinteger_gsu; break; + case PM_FFLOAT: + case PM_EFLOAT: + pm->gsu.f = d->gsu; + break; + case PM_ARRAY: pm->gsu.a = d->gsu ? (GsuArray)d->gsu : &vararray_gsu; break; @@ -1592,7 +1597,8 @@ do_load_module(char const *name, int silent) ret = try_load_module(name); if (!ret && !silent) { #ifdef HAVE_DLERROR - zwarn("failed to load module `%s': %s", name, dlerror()); + zwarn("failed to load module `%s': %s", name, + metafy(dlerror(), -1, META_USEHEAP)); #else zwarn("failed to load module: %s", name); #endif diff --git a/Src/params.c b/Src/params.c index a59c51767..446cccc7e 100644 --- a/Src/params.c +++ b/Src/params.c @@ -655,7 +655,10 @@ createparamtable(void) char **new_environ; int envsize; #endif - char **envp, **envp2, **sigptr, **t; +#ifndef USE_SET_UNSET_ENV + char **envp; +#endif + char **envp2, **sigptr, **t; char buf[50], *str, *iname, *ivalue, *hostnam; int oae = opts[ALLEXPORT]; #ifdef HAVE_UNAME @@ -721,7 +724,11 @@ createparamtable(void) /* Now incorporate environment variables we are inheriting * * into the parameter hash table. Copy them into dynamic * * memory so that we can free them if needed */ - for (envp = envp2 = environ; *envp2; envp2++) { + for ( +#ifndef USE_SET_UNSET_ENV + envp = +#endif + envp2 = environ; *envp2; envp2++) { if (split_env_string(*envp2, &iname, &ivalue)) { if (!idigit(*iname) && isident(iname) && !strchr(iname, '[')) { if ((!(pm = (Param) paramtab->getnode(paramtab, iname)) || @@ -993,9 +1000,7 @@ mod_export int isident(char *s) { char *ss; - int ne; - ne = noeval; /* save the current value of noeval */ if (!*s) /* empty string is definitely not valid */ return 0; @@ -3041,9 +3046,21 @@ mod_export void stdunsetfn(Param pm, UNUSED(int exp)) { switch (PM_TYPE(pm->node.flags)) { - case PM_SCALAR: pm->gsu.s->setfn(pm, NULL); break; - case PM_ARRAY: pm->gsu.a->setfn(pm, NULL); break; - case PM_HASHED: pm->gsu.h->setfn(pm, NULL); break; + case PM_SCALAR: + if (pm->gsu.s->setfn) + pm->gsu.s->setfn(pm, NULL); + break; + + case PM_ARRAY: + if (pm->gsu.a->setfn) + pm->gsu.a->setfn(pm, NULL); + break; + + case PM_HASHED: + if (pm->gsu.h->setfn) + pm->gsu.h->setfn(pm, NULL); + break; + default: if (!(pm->node.flags & PM_SPECIAL)) pm->u.str = NULL; @@ -4188,6 +4205,7 @@ arrfixenv(char *s, char **t) int zputenv(char *str) { + DPUTS(!str, "Attempt to put null string into environment."); #ifdef USE_SET_UNSET_ENV /* * If we are using unsetenv() to remove values from the diff --git a/Src/parse.c b/Src/parse.c index e59a882ca..e4d038b6e 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -1465,6 +1465,10 @@ par_funcdef(void) ecssub = oecssub; YYERRORV(oecused); } + if (num == 0) { + /* Anonymous function, possibly with arguments */ + incmdpos = 0; + } zshlex(); } else if (unset(SHORTLOOPS)) { lineno += oldlineno; @@ -1480,12 +1484,25 @@ par_funcdef(void) ecbuf[p + num + 4] = ecnpats; ecbuf[p + 1] = num; - lineno += oldlineno; ecnpats = onp; ecssub = oecssub; ecnfunc++; ecbuf[p] = WCB_FUNCDEF(ecused - 1 - p); + + if (num == 0) { + /* Unnamed function */ + int parg = ecadd(0); + ecadd(0); + while (tok == STRING) { + ecstr(tokstr); + num++; + zshlex(); + } + ecbuf[parg] = ecused - parg; /*?*/ + ecbuf[parg+1] = num; + } + lineno += oldlineno; } /* @@ -1707,13 +1724,17 @@ par_simple(int *complex, int nr) ecssub = oecssub; YYERROR(oecused); } + if (argc == 0) { + /* Anonymous function, possibly with arguments */ + incmdpos = 0; + } zshlex(); } else { - int ll, sl, pl, c = 0; + int ll, sl, c = 0; ll = ecadd(0); sl = ecadd(0); - pl = ecadd(WCB_PIPE(WC_PIPE_END, 0)); + (void)ecadd(WCB_PIPE(WC_PIPE_END, 0)); if (!par_cmd(&c)) { cmdpop(); @@ -1730,13 +1751,26 @@ par_simple(int *complex, int nr) ecbuf[p + argc + 3] = ecsoffs - so; ecbuf[p + argc + 4] = ecnpats; - lineno += oldlineno; ecnpats = onp; ecssub = oecssub; ecnfunc++; ecbuf[p] = WCB_FUNCDEF(ecused - 1 - p); + if (argc == 0) { + /* Unnamed function */ + int parg = ecadd(0); + ecadd(0); + while (tok == STRING) { + ecstr(tokstr); + argc++; + zshlex(); + } + ecbuf[parg] = ecused - parg; /*?*/ + ecbuf[parg+1] = argc; + } + lineno += oldlineno; + isfunc = 1; isnull = 0; break; diff --git a/Src/signals.c b/Src/signals.c index 456a85300..ad688094b 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -489,16 +489,24 @@ wait_for_processes(void) * Find the process and job containing this pid and * update it. */ - pn = NULL; if (findproc(pid, &jn, &pn, 0)) { + if (((jn->stat & STAT_BUILTIN) || + (list_pipe && + (thisjob == -1 || + (jobtab[thisjob].stat & STAT_BUILTIN)))) && + WIFSTOPPED(status) && WSTOPSIG(status) == SIGTSTP) { + killjb(jn, SIGCONT); + zwarn("job can't be suspended"); + } else { #if defined(HAVE_WAIT3) && defined(HAVE_GETRUSAGE) - struct timezone dummy_tz; - gettimeofday(&pn->endtime, &dummy_tz); - pn->status = status; - pn->ti = ru; + struct timezone dummy_tz; + gettimeofday(&pn->endtime, &dummy_tz); + pn->status = status; + pn->ti = ru; #else - update_process(pn, status); + update_process(pn, status); #endif + } update_job(jn); } else if (findproc(pid, &jn, &pn, 1)) { pn->status = status; @@ -1185,7 +1193,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn) traplocallevel = locallevel; runhookdef(BEFORETRAPHOOK, NULL); if (*sigtr & ZSIG_FUNC) { - int osc = sfcontext; + int osc = sfcontext, old_incompfunc = incompfunc; HashNode hn = gettrapnode(sig, 0); args = znewlinklist(); @@ -1211,8 +1219,10 @@ dotrapargs(int sig, int *sigtr, void *sigfn) trapisfunc = isfunc = 1; sfcontext = SFC_SIGNAL; + incompfunc = 0; doshfunc((Shfunc)sigfn, args, 1); sfcontext = osc; + incompfunc= old_incompfunc; freelinklist(args, (FreeFunc) NULL); zsfree(name); } else { diff --git a/Src/subst.c b/Src/subst.c index f9c48404b..4e8ed721d 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -162,6 +162,8 @@ stringsubst(LinkList list, LinkNode node, int ssub, int asssub) subst = getproc(str, &rest); /* <(...) or >(...) */ else subst = getoutputfile(str, &rest); /* =(...) */ + if (errflag) + return NULL; if (!subst) subst = ""; @@ -245,7 +247,10 @@ stringsubst(LinkList list, LinkNode node, int ssub, int asssub) if (endchar == Outpar && str2[1] == '(' && str[-2] == ')') { /* Math substitution of the form $((...)) */ str[-2] = '\0'; - str = arithsubst(str2 + 2, &str3, str); + if (isset(EXECOPT)) + str = arithsubst(str2 + 2, &str3, str); + else + strncpy(str3, str2, 1); setdata(node, (void *) str3); continue; } @@ -2080,7 +2085,16 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) || (cc = s[1]) == '*' || cc == Star || cc == '@' || cc == '?' || cc == Quest || cc == '$' || cc == String || cc == Qstring - || cc == '#' || cc == Pound + /* + * Me And My Squiggle: + * ${##} is the length of $#, but ${##foo} + * is $# with a "foo" removed from the start. + * If someone had defined the *@!@! language + * properly in the first place we wouldn't + * have this nonsense. + */ + || ((cc == '#' || cc == Pound) && + s[2] == Outbrace) || cc == '-' || (cc == ':' && s[2] == '-') || (isstring(cc) && (s[2] == Inbrace || s[2] == Inpar)))) { getlen = 1 + whichlen, s++; @@ -2706,19 +2720,21 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) case '?': case Quest: if (vunset) { - *idend = '\0'; - zerr("%s: %s", idbeg, *s ? s : "parameter not set"); - if (!interact) { - if (mypid == getpid()) { - /* - * paranoia: don't check for jobs, but there shouldn't - * be any if not interactive. - */ - stopmsg = 1; - zexit(1, 0); - } else - _exit(1); - } + if (isset(EXECOPT)) { + *idend = '\0'; + zerr("%s: %s", idbeg, *s ? s : "parameter not set"); + if (!interact) { + if (mypid == getpid()) { + /* + * paranoia: don't check for jobs, but there + * shouldn't be any if not interactive. + */ + stopmsg = 1; + zexit(1, 0); + } else + _exit(1); + } + } return NULL; } break; @@ -2839,7 +2855,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) char *check_offset = check_colon_subscript(s, &check_offset2); if (check_offset) { zlong offset = mathevali(check_offset); - zlong length; + zlong length = 0; int length_set = 0; int offset_hack_argzero = 0; if (errflag) diff --git a/Src/text.c b/Src/text.c index 669037a2d..f55553ed0 100644 --- a/Src/text.c +++ b/Src/text.c @@ -253,6 +253,7 @@ struct tstack { struct { char *strs; Wordcode end; + int nargs; } _funcdef; struct { Wordcode end; @@ -456,19 +457,31 @@ gettext2(Estate state) if (!s) { Wordcode p = state->pc; Wordcode end = p + WC_FUNCDEF_SKIP(code); + int nargs = *state->pc++; - taddlist(state, *state->pc++); + taddlist(state, nargs); + if (nargs) + taddstr(" "); if (tjob) { - taddstr(" () { ... }"); + taddstr("() { ... }"); state->pc = end; + if (!nargs) { + /* + * Unnamed fucntion. + * We're not going to pull any arguments off + * later, so skip them now... + */ + state->pc += *end; + } stack = 1; } else { - taddstr(" () {"); + taddstr("() {"); tindent++; taddnl(1); n = tpush(code, 1); n->u._funcdef.strs = state->strs; n->u._funcdef.end = end; + n->u._funcdef.nargs = nargs; state->strs += *state->pc; state->pc += 3; } @@ -478,6 +491,17 @@ gettext2(Estate state) dec_tindent(); taddnl(0); taddstr("}"); + if (s->u._funcdef.nargs == 0) { + /* Unnamed function with post-arguments */ + int nargs; + s->u._funcdef.end += *state->pc++; + nargs = *state->pc++; + if (nargs) { + taddstr(" "); + taddlist(state, nargs); + } + state->pc = s->u._funcdef.end; + } stack = 1; } break; diff --git a/Src/utils.c b/Src/utils.c index 066710e1e..6c2ea98d5 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -40,6 +40,11 @@ mod_export char *scriptname; /* is sometimes a function name */ /**/ mod_export char *scriptfilename; +/* != 0 if we are in a new style completion function */ + +/**/ +mod_export int incompfunc; + #ifdef MULTIBYTE_SUPPORT struct widechar_array { wchar_t *chars; @@ -1232,8 +1237,10 @@ callhookfunc(char *name, LinkList lnklst, int arrayp, int *retval) * to a list of jobs generated in a hook. */ int osc = sfcontext, osm = stopmsg, stat = 1, ret = 0; + int old_incompfunc = incompfunc; sfcontext = SFC_HOOK; + incompfunc = 0; if ((shfunc = getshfunc(name))) { ret = doshfunc(shfunc, lnklst, 1); @@ -1262,6 +1269,7 @@ callhookfunc(char *name, LinkList lnklst, int arrayp, int *retval) sfcontext = osc; stopmsg = osm; + incompfunc = old_incompfunc; if (retval) *retval = ret; @@ -1683,8 +1691,8 @@ adjustwinsize(int from) winchanged = #endif /* TIOCGWINSZ */ resetneeded = 1; - zleentry(ZLE_CMD_REFRESH); zleentry(ZLE_CMD_RESET_PROMPT); + zleentry(ZLE_CMD_REFRESH); } } @@ -1802,22 +1810,20 @@ zclose(int fd) { if (fd >= 0) { /* - * We sometimes zclose() an fd twice where the second - * time is a catch-all in case there was a failure using - * the fd. This is harmless but we need to trap it - * for the error check here. + * Careful: we allow closing of arbitrary fd's, beyond + * max_zsh_fd. In that case we don't try anything clever. */ - DPUTS2(fd > max_zsh_fd && fdtable[fd] != FDT_UNUSED, - "BUG: fd is %d, max_zsh_fd is %d", fd, max_zsh_fd); - if (fdtable[fd] == FDT_FLOCK) - fdtable_flocks--; - fdtable[fd] = FDT_UNUSED; - while (max_zsh_fd > 0 && fdtable[max_zsh_fd] == FDT_UNUSED) - max_zsh_fd--; - if (fd == coprocin) - coprocin = -1; - if (fd == coprocout) - coprocout = -1; + if (fd <= max_zsh_fd) { + if (fdtable[fd] == FDT_FLOCK) + fdtable_flocks--; + fdtable[fd] = FDT_UNUSED; + while (max_zsh_fd > 0 && fdtable[max_zsh_fd] == FDT_UNUSED) + max_zsh_fd--; + if (fd == coprocin) + coprocin = -1; + if (fd == coprocout) + coprocout = -1; + } return close(fd); } return -1; @@ -2492,16 +2498,18 @@ spckword(char **s, int hist, int cmd, int ask) return; if (!(*s)[0] || !(*s)[1]) return; - if (shfunctab->getnode(shfunctab, *s) || - builtintab->getnode(builtintab, *s) || - cmdnamtab->getnode(cmdnamtab, *s) || - aliastab->getnode(aliastab, *s) || - reswdtab->getnode(reswdtab, *s)) - return; - else if (isset(HASHLISTALL)) { - cmdnamtab->filltable(cmdnamtab); - if (cmdnamtab->getnode(cmdnamtab, *s)) + if (cmd) { + if (shfunctab->getnode(shfunctab, *s) || + builtintab->getnode(builtintab, *s) || + cmdnamtab->getnode(cmdnamtab, *s) || + aliastab->getnode(aliastab, *s) || + reswdtab->getnode(reswdtab, *s)) return; + else if (isset(HASHLISTALL)) { + cmdnamtab->filltable(cmdnamtab); + if (cmdnamtab->getnode(cmdnamtab, *s)) + return; + } } t = *s; if (*t == Tilde || *t == Equals || *t == String) @@ -2615,6 +2623,8 @@ spckword(char **s, int hist, int cmd, int ask) fflush(shout); zbeep(); x = getquery("nyae \t", 0); + if (cmd && x == 'n') + pathchecked = path; } else x = 'n'; } else @@ -3170,6 +3180,10 @@ sepsplit(char *s, char *sep, int allownull, int heap) int n, sl; char *t, *tt, **r, **p; + /* Null string? Treat as empty string. */ + if (s[0] == Nularg && !s[1]) + s++; + if (!sep) return spacesplit(s, allownull, heap, 0); @@ -3218,7 +3232,7 @@ getshfunc(char *nam) char ** subst_string_by_func(Shfunc func, char *arg1, char *orig) { - int osc = sfcontext, osm = stopmsg; + int osc = sfcontext, osm = stopmsg, old_incompfunc = incompfunc; LinkList l = newlinklist(); char **ret; @@ -3227,6 +3241,7 @@ subst_string_by_func(Shfunc func, char *arg1, char *orig) addlinknode(l, arg1); addlinknode(l, orig); sfcontext = SFC_SUBST; + incompfunc = 0; if (doshfunc(func, l, 1)) ret = NULL; @@ -3235,6 +3250,7 @@ subst_string_by_func(Shfunc func, char *arg1, char *orig) sfcontext = osc; stopmsg = osm; + incompfunc = old_incompfunc; return ret; } @@ -4689,7 +4705,7 @@ addunprintable(char *v, const char *u, const char *uend) mod_export char * quotestring(const char *s, char **e, int instring) { - const char *u, *tt; + const char *u; char *v; int alloclen; char *buf; @@ -4740,7 +4756,7 @@ quotestring(const char *s, char **e, int instring) break; } - tt = quotestart = v = buf = zshcalloc(alloclen); + quotestart = v = buf = zshcalloc(alloclen); DPUTS(instring < QT_BACKSLASH || instring == QT_BACKTICK || instring > QT_SINGLE_OPTIONAL, @@ -907,6 +907,8 @@ struct job { #define STAT_ATTACH (0x1000) /* delay reattaching shell to tty */ #define STAT_SUBLEADER (0x2000) /* is super-job, but leader is sub-shell */ +#define STAT_BUILTIN (0x4000) /* job at tail of pipeline is a builtin */ + #define SP_RUNNING -1 /* fake status for jobs currently running */ struct timeinfo { diff --git a/Test/A04redirect.ztst b/Test/A04redirect.ztst index 4d96d8bb9..e58102664 100644 --- a/Test/A04redirect.ztst +++ b/Test/A04redirect.ztst @@ -155,10 +155,16 @@ (exec 3<&- read foo <&-) 1:'<&-' redirection +?(eval):1: failed to close file descriptor 3: bad file descriptor print foo >&- 0:'>&-' redirection + (exec >&- + print foo) +0:'>&-' with attempt to use closed fd +?(eval):2: write error: bad file descriptor + fn() { local foo; read foo; print $foo; } coproc fn print test output >&p diff --git a/Test/B04read.ztst b/Test/B04read.ztst index ad427dc0d..25c3d4173 100644 --- a/Test/B04read.ztst +++ b/Test/B04read.ztst @@ -93,3 +93,20 @@ read foo) <<<bar 1:return status on failing to set parameter ?(eval):2: read-only variable: foo + + read -AE array <<<'one two three' + print ${(j.:.)array} +0:Behaviour of -A and -E combination +>one +>two +>three +>one:two:three + + array=() + read -Ae array <<<'four five six' + print ${(j.:.)array} +0:Behaviour of -A and -e combination +>four +>five +>six +> diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst index f71e5ce77..90f01e397 100644 --- a/Test/C04funcdef.ztst +++ b/Test/C04funcdef.ztst @@ -1,3 +1,8 @@ +%prep + + mkdir funcdef.tmp + cd funcdef.tmp + %test fn1() { return 1; } @@ -26,7 +31,7 @@ print regress expansion of function names } f$$ -0:Regression test: `function f$$ () { ... }' +0:Regression test: 'function f$$ () { ... }' >regress expansion of function names function foo () print bar @@ -109,6 +114,8 @@ >really useful >args +# ' deconfuse emacs + command_not_found_handler() { print "Your command:" >&2 print "$1" >&2 @@ -201,6 +208,49 @@ >Da de da >Do be do + () { print This has arguments $*; } of all sorts; print After the function + function { print More stuff $*; } and why not; print Yet more +0:Anonymous function with arguments +>This has arguments of all sorts +>After the function +>More stuff and why not +>Yet more + + fn() { + (){ print Anonymous function 1 $*; } with args + function { print Anonymous function 2 $*; } with more args + print Following bit + } + functions fn +0:Text representation of anonymous function with arguments +>fn () { +> () { +> print Anonymous function 1 $* +> } with args +> () { +> print Anonymous function 2 $* +> } with more args +> print Following bit +>} + + touch yes no + () { echo $1 } (y|z)* + (echo here) + () { echo $* } some (y|z)* + () { echo empty };(echo here) +0:Anonymous function arguments and command arguments +>yes +>here +>some yes +>empty +>here + + if true; then f() { echo foo1; } else f() { echo bar1; } fi; f + if false; then f() { echo foo2; } else f() { echo bar2; } fi; f +0:Compatibility with other shells when not anonymous functions +>foo1 +>bar2 + %clean rm -f file.in file.out diff --git a/Test/D03procsubst.ztst b/Test/D03procsubst.ztst index 37a67630f..602b1da15 100644 --- a/Test/D03procsubst.ztst +++ b/Test/D03procsubst.ztst @@ -84,3 +84,7 @@ ) 0:=(...) preceded by other stuff has no special effect >everything,=(here is left),alone + + print something=${:-=(echo 'C,D),(F,G)'} +1: Graceful handling of bad substitution in enclosed context +?(eval):1: unterminated `=(...)' diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 6379c8cd0..71c79687f 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -179,9 +179,17 @@ print ${##} set 1 2 3 4 5 6 7 8 9 10 print ${##} -0:${##} is length of $# + print ${##""} + print ${##1} + print ${##2} + print ${###<->} # oh, for pete's sake... +0:${##} is length of $#, and other tales of hash horror >1 >2 +>10 +>0 +>10 +> array=(once bitten twice shy) print IF${array}THEN @@ -300,23 +308,16 @@ foo='\u65\123' print -r ${(g:o:)foo} - foo='\u65\0123' + foo='\u65\0123^X\C-x' print -r ${(g::)foo} - foo='\u65^X' - print -r ${(V)${(g:c:)foo}} - foo='\u65\C-x\M-a' - print -r ${(V)${(g:e:)foo}} - foo='\u65\123\C-x' - print -r ${(V)${(g:eo:)foo}} - foo=('\u65' '\0123' '^X\M-a') - print -r ${(V)${(g:e:)foo}} + foo='^X' + bar='\C-\130' + [[ ${(g:c:)foo} == ${(g:oe:)bar} ]] + echo $? 0:${(g)...} >eS ->eS ->e^X ->e^X\M-a ->eS^X ->e S ^X\M-a +>eS^X\C-x +>0 foo='I'\''m nearly out of my mind with tedium' bar=foo @@ -1452,3 +1453,8 @@ print ${foo:5:-6} 1:Regression test for total length < 0 in array ?(eval):2: substring expression: 3 < 5 + + foo=(${(0)"$(print -n)"}) + print ${#foo} +0:Nularg removed from split empty string +>0 diff --git a/Test/D08cmdsubst.ztst b/Test/D08cmdsubst.ztst index 9962c6cad..5661b0aaa 100644 --- a/Test/D08cmdsubst.ztst +++ b/Test/D08cmdsubst.ztst @@ -98,3 +98,11 @@ echo `echo $?` 0:Non-empty command substitution inherits status >1 + + echo $(( ##\" )) + echo $(echo \") + echo $((echo \"); echo OK) +0:Handling of backslash double quote in parenthesised substitutions +>34 +>" +>" OK diff --git a/Test/E01options.ztst b/Test/E01options.ztst index 4b53840c6..1bbfdbda1 100644 --- a/Test/E01options.ztst +++ b/Test/E01options.ztst @@ -353,6 +353,10 @@ echo *NonExistentFile*) 0:NO_EXEC option should not do globbing + (setopt noexec + echo ${unset_var?Not an error}) +0:NO_EXEC should not test for unset variables + setopt NO_eval_lineno eval 'print $LINENO' setopt eval_lineno diff --git a/Test/V01zmodload.ztst b/Test/V01zmodload.ztst index d74b0ef18..ea908e952 100644 --- a/Test/V01zmodload.ztst +++ b/Test/V01zmodload.ztst @@ -125,8 +125,10 @@ fi 0d:Autoload a module via a builtin + if [[ $mods[(r)zsh/example] == zsh/example ]]; then zmodload -u zsh/example builtin example + fi 0d:Autoloads are persistent (zmodload -u zsh/parameter diff --git a/Test/V04features.ztst b/Test/V04features.ztst index 240336611..2790456e2 100644 --- a/Test/V04features.ztst +++ b/Test/V04features.ztst @@ -17,18 +17,24 @@ 0:Loading modules with no features >-b:strftime >-p:EPOCHSECONDS +>-p:EPOCHREALTIME +>-p:epochtime zmodload -F zsh/datetime b:strftime zmodload -lF zsh/datetime 0:Enabling features >+b:strftime >-p:EPOCHSECONDS +>-p:EPOCHREALTIME +>-p:epochtime zmodload -F zsh/datetime +p:EPOCHSECONDS -b:strftime zmodload -lF zsh/datetime 0:Disabling features >-b:strftime >+p:EPOCHSECONDS +>-p:EPOCHREALTIME +>-p:epochtime zmodload -Fe zsh/datetime p:EPOCHSECONDS b:strftime 0:Testing existing features @@ -109,6 +115,8 @@ 0:Feature state with loading after error enabling >+b:strftime >-p:EPOCHSECONDS +>+p:EPOCHREALTIME +>+p:epochtime zmodload -F zsh/datetime p:EPOCHSECONDS zmodload -Fe zsh/datetime +p:EPOCHSECONDS @@ -159,3 +167,5 @@ 0:zmodload with no -F enables all features >+b:strftime >+p:EPOCHSECONDS +>+p:EPOCHREALTIME +>+p:epochtime diff --git a/Test/V07pcre.ztst b/Test/V07pcre.ztst new file mode 100644 index 000000000..f5b05deaa --- /dev/null +++ b/Test/V07pcre.ztst @@ -0,0 +1,110 @@ +%prep + + if ! zmodload zsh/pcre 2>/dev/null + then + ZTST_unimplemented="the zsh/pcre module is not available" + return 0 + fi + setopt rematch_pcre +# Find a UTF-8 locale. + setopt multibyte +# Don't let LC_* override our choice of locale. + unset -m LC_\* + mb_ok= + langs=(en_{US,GB}.{UTF-,utf}8 en.UTF-8 + $(locale -a 2>/dev/null | egrep 'utf8|UTF-8')) + for LANG in $langs; do + if [[ é = ? ]]; then + mb_ok=1 + break; + fi + done + if [[ -z $mb_ok ]]; then + ZTST_unimplemented="no UTF-8 locale or multibyte mode is not implemented" + else + print -u $ZTST_fd Testing PCRE multibyte with locale $LANG + mkdir multibyte.tmp && cd multibyte.tmp + fi + +%test + + [[ 'foo→bar' =~ .([^[:ascii:]]). ]] + print $MATCH + print $match[1] +0:Basic non-ASCII regexp matching +>o→b +>→ + + [[ foo =~ f.+ ]] ; print $? + [[ foo =~ x.+ ]] ; print $? + [[ ! foo =~ f.+ ]] ; print $? + [[ ! foo =~ x.+ ]] ; print $? + [[ foo =~ f.+ && bar =~ b.+ ]] ; print $? + [[ foo =~ x.+ && bar =~ b.+ ]] ; print $? + [[ foo =~ f.+ && bar =~ x.+ ]] ; print $? + [[ ! foo =~ f.+ && bar =~ b.+ ]] ; print $? + [[ foo =~ f.+ && ! bar =~ b.+ ]] ; print $? + [[ ! ( foo =~ f.+ && bar =~ b.+ ) ]] ; print $? + [[ ! foo =~ x.+ && bar =~ b.+ ]] ; print $? + [[ foo =~ x.+ && ! bar =~ b.+ ]] ; print $? + [[ ! ( foo =~ x.+ && bar =~ b.+ ) ]] ; print $? +0:Regex result inversion detection +>0 +>1 +>1 +>0 +>0 +>1 +>1 +>1 +>1 +>1 +>0 +>1 +>0 + +# Note that PCRE_ANCHORED only means anchored at the start +# Also note that we don't unset MATCH/match on failed match (and it's an +# open issue as to whether or not we should) + pcre_compile '.(→.)' + pcre_match foo→bar + print $? $MATCH $match ; unset MATCH match + pcre_match foo.bar + print $? $MATCH $match ; unset MATCH match + pcre_match foo†bar + print $? $MATCH $match ; unset MATCH match + pcre_match foo→†ar + print $? $MATCH $match ; unset MATCH match + pcre_study + pcre_match foo→bar + print $? $MATCH $match ; unset MATCH match + pcre_compile -a '.(→.)' + pcre_match foo→bar + print $? $MATCH $match ; unset MATCH match + pcre_match o→bar + print $? $MATCH $match ; unset MATCH match + pcre_match o→b + print $? $MATCH $match ; unset MATCH match + pcre_compile 'x.(→.)' + pcre_match xo→t + print $? $MATCH $match ; unset MATCH match + pcre_match Xo→t + print $? $MATCH $match ; unset MATCH match + pcre_compile -i 'x.(→.)' + pcre_match xo→t + print $? $MATCH $match ; unset MATCH match + pcre_match Xo→t + print $? $MATCH $match ; unset MATCH match +0:pcre_compile interface testing: basic, anchored & case-insensitive +>0 o→b →b +>1 +>1 +>0 o→† →† +>0 o→b →b +>1 +>0 o→b →b +>0 o→b →b +>0 xo→t →t +>1 +>0 xo→t →t +>0 Xo→t →t diff --git a/configure.ac b/configure.ac index 1ce815ca5..54999b164 100644 --- a/configure.ac +++ b/configure.ac @@ -693,6 +693,8 @@ AC_CHECK_LIB(c, printf, [LIBS="$LIBS -lc"]) AC_CHECK_LIB(m, pow) +AC_CHECK_LIB(rt, clock_gettime) + dnl Various features of ncurses depend on having the right header dnl (the system's own curses.h may well not be good enough). dnl So don't search for ncurses unless we found the header. @@ -1170,7 +1172,7 @@ dnl need to integrate this function dnl AC_FUNC_STRFTIME AC_CHECK_FUNCS(strftime strptime mktime timelocal \ - difftime gettimeofday \ + difftime gettimeofday clock_gettime \ select poll \ readlink faccessx fchdir ftruncate \ fstat lstat lchown fchown fchmod \ |