diff options
author | Axel Beckert <abe@deuxchevaux.org> | 2014-08-11 17:39:42 +0200 |
---|---|---|
committer | Axel Beckert <abe@deuxchevaux.org> | 2014-08-11 17:39:42 +0200 |
commit | 382c26acfc62a56744ab9eb603efc56130764fd3 (patch) | |
tree | 1b7cb9d3e372481007fc4546e7d06ce5bb1bc104 | |
parent | 73508e345b4925f33b7f652aba9bd313169e5ac2 (diff) | |
parent | f8ae47f29b766dc0330b19d7fdb35859d6aab930 (diff) | |
download | zsh-382c26acfc62a56744ab9eb603efc56130764fd3.tar.gz zsh-382c26acfc62a56744ab9eb603efc56130764fd3.zip |
New upstream release candidate: Merge branch 'upstream' into debian
154 files changed, 5979 insertions, 1093 deletions
diff --git a/.gitignore b/.gitignore index 5fd574b1f..4ae315baa 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ Doc/intro.a4.ps Doc/intro.us.pdf Doc/intro.us.ps Doc/version.yo +Doc/texi2html.conf Doc/zsh*.1 Doc/zsh.texi Doc/zsh.info* @@ -1,3 +1,897 @@ +2014-08-10 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * unposted: Completion/Base/Completer/.distfiles, + Completion/Linux/Command/.distfiles, + Completion/Unix/Command/.distfiles, Config/version.mk, + Etc/.distfiles, Etc/FAQ.yo, Functions/Zle/.distfiles, NEWS, + README: updates for 5.0.5-dev-1 and 5.0.6 release. + +2014-08-10 Axel Beckert <abe@deuxchevaux.org> + + * unposted: Doc/Zsh/expn.yo: Fix typo. + +2014-08-08 Barton E. Schaefer <schaefer@zsh.org> + + * unposted: NEWS, Doc/Zsh/prompt.yo: mention 32971 in NEWS, + clarify RPROMPT behavior in docs. + +2014-08-07 Barton E. Schaefer <schaefer@zsh.org> + + * 32971 (plus doc tweak): Doc/Zsh/prompt.yo, Src/prompt.c: + negative argument with %(l..) conditional and with %<< or %>> + truncation calculates space available before right margin + (positive argument still counts space used since left margin). + +2014-08-04 Barton E. Schaefer <schaefer@brasslantern.com> + + * Miles Ohlrich: 32958: Src/Zle/compctl.c: bitwise logic fix + +2014-08-04 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 32954: Doc/Zsh/expn.yo: missed this. + + * 32954 (plus new test): Src/cond.c, Test/D02glob.ztst: + (#q) on patterns with [[ ... = ... ] and [[ ... != ... ]] + shouldn't force a glob, it should simply be ignored. + + * unposted: Src/subst.c: remove unused variables. + +2014-08-04 Mikael Magnusson <mikachu@gmail.com> + + * 32949 (wip 32928, 32937): Doc/Zsh/expn.yo, Src/subst.c, + Test/D04parameter.ztst: Add :^ and :^^ for zipping arrays. + +2014-08-03 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 32944: Doc/Zsh/builtins.yo: read -qs is handled properly. + + * users/19006: Doc/Zsh/expn.yo: document position of + RC_EXPAND_PARAM handling during parameter substitution. + +2014-08-01 Peter Stephenson <p.stephenson@samsung.com> + + * 32932: Src/glob.c, Src/utils.c: add hmkarray() and + use to fix leak. + +2014-07-31 Barton E. Schaefer <schaefer@zsh.org> + + * 32931: Src/glob.c: with NO_NOMATCH, using a subscript glob + qualifier on a not-matching pattern should still return the + original pattern + +2014-07-30 Peter Stephenson <p.stephenson@samsung.com> + + * unposted: Src/Builtins/sched.c, Src/Modules/datetime.c, + Src/Modules/stat.c: missed updates to ztrftime(). + + * 32919: Doc/Zsh/tcpsys.yo Functions/TCP/tcp_output: %P + at start of prompt in TCP function system causes standard + %-style substitution. + + * 32918: Doc/Zsh/prompt.yo, Src/builtin.c,Src/prompt.c, + Src/utils.c, Src/watch.c: add ability to display times with + fractions of a second in prompts. + +2014-07-28 Barton E. Schaefer <schaefer@zsh.org> + + * 32593: Completion/Unix/Command/_qemu: update --vga option + +2014-07-26 Axel Beckert <abe@deuxchevaux.org> + + * Omari Norman: 32817: Add completion for moosic. + + * Sebastian Ramacher: 32816: Add completion for bpython and + variants. + + * 32911: Expand bpython completion to bpython2 and bpython3. + +2014-07-26 Barton E. Schaefer <schaefer@zsh.org> + + * 32910: Src/mkmakemod.sh: quiet update of timestamp files + +2014-07-24 Barton E. Schaefer <schaefer@zsh.org> + + * 32853: configure.ac, Src/mem.c, Src/zsh_system.h: redefine + the VARARR() macro to use heap rather than stack allocation; + enable old behavior via "configure --with-stack-allocation" + + * unposted (see 32892): Src/builtins.c: 'fc -I' is an error + + * 32903: Src/Modules/parameter.c: new empty (unset) elements in + the special parameter hash tables are special themselves, so that + adding elements via assignment syntax handles them correctly. + +2014-07-24 Peter Stephenson <p.stephenson@samsung.com> + + * unposted: Functions/Zle/replace-argument, Doc/Zsh/contrib.yo: + allow negative numeric prefix to count backwards from last + argument. + +2014-07-23 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Jai Keerthan: users/18981: Completion/Unix/Command/_tmux: + improved function completion. + +2014-07-23 Barton E. Schaefer <schaefer@zsh.org> + + * 32898 (credit Jun T.): Doc/Zsh/mod_pcre.yo: fix bug in 32891. + +2014-07-23 Ansgar Burchardt <ansgar@debian.org> + + * 32895: Completion/Unix/Command/_nm: Match more shared library + names. + +2014-07-20 Barton E. Schaefer <schaefer@zsh.org> + + * unposted: Doc/Zsh/builtins.yo: force retention of whitespace + in "fc" item prototype + + * 32891: Doc/Zsh/mod_pcre.yo Src/Modules/pcre.c: the CASE_MATCH + option should apply to =~ when using pcre; fix pcre_match bug + with handling of empty string argument. + +2014-07-17 Barton E. Schaefer <schaefer@zsh.org> + + * 32882 (cf. Augie Fackler 32879): Src/hist.c: restore correct + reload of backslash-continuation lines from history, broken by + workers/30443 just before the zsh 5.0.0 release; fix bad history + write of events ending with an even number of backslashes. + +2014-07-17 Oliver Kiddle <opk@zsh.org> + + * 32849: Completion/Linux/Command/_ss: new completion function + + * 32848: Completion/Unix/Command/_perl, + Completion/Unix/Command/_python, Completion/Unix/Command/_ruby: + fix words array before using _normal for script arguments + +2014-07-17 Peter Stephenson <p.stephenson@samsung.com> + + * 32866 (plus extra undo fix in read-from-minibuffer): + Doc/Zsh/contrib.yo, Functions/Zle/read-from-minibuffer, + Functions/Zle/replace-argument: new replace-argument function; + fixes in read-from-minibuffer not to pass through numeric + argument to recursive edit and to hide minibuffer edit from + undo history. + +2014-07-15 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Koen Wilde: 32863: Completion/Unix/Command/_mpc: mpc "insert" + command. + +2014-07-08 Peter Stephenson <p.stephenson@samsung.com> + + * Dominic Hopf: 32837: Config/defs.mk.in: improve handling of + installation location for help directories. + + * 32832: Doc/Zsh/grammar.yo Doc/Zsh/params.yo: attempt to + improve documentation for how assignment works. + +2014-07-03 Axel Beckert <abe@deuxchevaux.org> + + * Felipe Sateler: 32819: Completion/Debian/Command/_axi-cache: + Update for axi-cache completion. + + * Vincent Lefevre: 32818: Completion/Unix/Command/_gzip: + --rsyncable option is missing + + * Daniel Bolton: 32815: Completion/Debian/Command/_aptitude: + missing resolver options + + * Sebastian Ramacher: 32814: Completion/Debian/Command/_dpkg: + Add --add-architecture, --remove-architecture, and + --print-foreign-architectures options. + +2014-07-03 Mikael Magnusson <mikachu@gmail.com> + + * 32821: Completion/Unix/Command/_gcc: Update _gcc as of GCC + 4.8.3 for generic options and x86. + +2014-07-03 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Jun T: 32833: Completion/Unix/Command/_python, + Completion/Unix/Command/_ruby: complete file arguments as for + perl. + +2014-06-30 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Jun T: 32823: Completion/Unix/Command/_perl: complete file + instead of script after -e. + +2014-06-26 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Jun T: 32812: Doc/zsh.yo, Doc/ztexi.yo: put table of contents + at front of manual. + +2014-06-26 Peter Stephenson <p.stephenson@samsung.com> + + * 32799: Doc/Zsh/builtins.yo, Src/Builtins/rlimits.c: resource + NTHR is not properly handled on netBSD. + +2014-06-24 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 32789: Src/lex.c Src/mem.c Src/zsh_system.h configure.ac: + --enable-zsh-valgrind allows valgrind to analyse heap + allocations. + +2014-06-16 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Jun T: 32781: Doc/Zsh/options.yo: source builtin and path + search doc. + +2014-06-14 Jun T <takimoto-j@kba.biglobe.ne.jp> + + * 32779: Doc/Zsh/options.yo: fix a typo in options.yo + +2014-06-13 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 32768, with further modifications: Doc/Zsh/options.yo, + Src/exec.c, Src/options.c, Src/zsh.h, Test/E01options.ztst, + Test/ztst.zsh: LOCAL_LOOPS option to restrict effect of + continue and break in function scope. + + * 32666: Doc/Zsh/compat.yo: shell emulation based on executable + name incompletely documented. + +2014-06-11 Barton E. Schaefer <schaefer@zsh.org> + + * Jun T: 32767: Src/glob.c: another spot to tweak bracechardots() + +2014-06-10 Barton E. Schaefer <schaefer@zsh.org> + + * 32766: Src/glob.c: bracechardots() agrees with xpandbraces() + about what constitutes a {C1..C2} pattern, thus preventing crash + + * Jun T: 32765: Src/glob.c: fix build when not MULTIBYTE_SUPPORT + +2014-06-09 Peter Stephenson <p.stephenson@samsung.com> + + * Jun T: 32755: Doc/Zsh/grammar.yo: move line that was in the + wrong place. + +2014-06-07 Barton E. Schaefer <schaefer@zsh.org> + + * Nikolas Garofil: 32737: Src/utils.c: properly ifdef declarations + + * Nikolas Garofil: 32736 (tweak per 32741): Src/zsh_system.h: + memmove() should return its dest argument + + * Nikolas Garofil: 32735: Src/signals.c: define ret before use + + * Nikolas Garofil: 32734: Src/mem.c: remove unused pointers + + * Nikolas Garofil: 32733: Src/prototypes.h: use size_t in bcopy() + + * Nikolas Garofil: 32732 (tweak per 32739): Src/compat.c: fix + const declaration inconsistency + +2014-06-06 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Jun T: 32719: Doc/Zsh/contrib.yo: minor issues. + + * Jun T: 32715: Doc/Zsh/calsys.yo, Doc/Zsh/grammar.yo, + Doc/Zsh/zle.yo: formatting fixes. + + * 32682 with tweaks: Doc/Zsh/options.yo, Src/hist.c, + Src/options.c, Src/zsh.h: INC_APPEND_HISTORY_TIME is new + behaviour, with INC_APPEND_HISTORY reverting to its previous + behaviour. + + * Andrew Magee: 32698: Completion/Unix/Command/_hg: show + committable files. + +2014-06-05 Barton E. Schaefer <schaefer@zsh.org> + + * 32723: Src/glob.c: add braces around some if/else branches + + * 32716 (via Jun T. 31714): Src/utils.c: properly test iconv + return values for error conditions + +2014-06-04 Barton E. Schaefer <schaefer@zsh.org> + + * 32711: Test/A07control.ztst: run "continue" test in a new + shell, lest it inadvertently continue the loop that reads the + test chunks from this file + + * Daniel Shahaf: 32708: Doc/Zsh/expn.yo, Src/glob.c, + Test/D02glob.ztst: glob qualifier (Y) implies (oN), plus + incidental patch to avoid adding a meaningless bitvalue to + sort-order flags + +2014-06-03 Barton E. Schaefer <schaefer@zsh.org> + + * Daniel Shahaf: 32694: Completion/Zsh/Type/_globquals, + Doc/Zsh/expn.yo, Src/glob.c, Test/D02glob.ztst: the number + of matches to find is the suffix argument of (Y) qualifier + +2014-06-03 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Jun T: 32681: Doc/Zsh/zle.yo: formatting issue. + +2014-06-03 Peter Stephenson <p.stephenson@samsung.com> + + * unposted: Src/cond.c: restore cond_match() in case used in + modules. + +2014-06-02 Barton E. Schaefer <schaefer@zsh.org> + + * 32656 (via Jun T. via waltarix on github): when __APPLE__ is + defined at compile, normalize Unicode filenames in zreaddir() + +2014-06-02 Peter Stephenson <p.stephenson@samsung.com> + + * Daniel Shahaf: users/18870: Src/glob.c, Test/D02glob.ztst: + glob scanner needed some coaxing with counting matches with (Y) + glob qualifier. + +2014-06-02 Daniel Shahaf <d.s@daniel.shahaf.name> + + * 32662: Functions/VCS_Info/Backends/VCS_INFO_get_data_git: + vcs_info git: Fix stagedstr for empty repos + +2014-06-01 Barton E. Schaefer <schaefer@zsh.org> + + * 32653: Completion/Unix/Command/_php: complete files with the + ".phar" extension as well as ".php", and respect the suffixes + zstyle to change this + + * 32634 (plus doc): Doc/Zsh/options.yo, Doc/Zsh/params.yo, + Src/init.c, Src/options.c, Src/params.c, Src/zsh.h: add the + POSIX_ARGZERO option to allow toggling between the original + value of $0 and the value set by FUNCTION_ARGZERO + + * Daniel Shahaf: users/18857: Doc/Zsh/expn.yo, Src/glob.c, + Test/D02glob.ztst: add (Y) glob qualifier + +2014-06-01 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 32640: Doc/Zsh/cond.yo, Doc/Zsh/expn.yo, NEWS, Src/cond.c, + Src/glob.c, Test/D02glob.ztst: (#q) with EXTENDED_GLOB forces + globbing in [[ ... ]]. + +2014-05-29 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 32624: Src/builtin.c, Src/jobs.c: use correct scaling factor + (clock ticks) for times. + + * Keerthan Jai: users/18860: Completion/Unix/Command/_man: man + -M overrides manpath. + + * unposted: Src/params.c: use DIGBUFSIZE for pipestatus numeric + buffer. + +2014-05-29 Daniel Shahaf <d.s@daniel.shahaf.name> + + * 32619: Functions/VCS_Info/Backends/VCS_INFO_get_data_svn: + vcs_info svn: Use the revision of cwd + + * 32621: Functions/VCS_Info/Backends/VCS_INFO_get_data_svn: + vcs_info svn: 'Fix set-branch-format' when in subdirs + + * 32620: Doc/Zsh/contrib.yo: Typo fix after commit eb4c70d + +2014-05-18 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Jun T: 32616: Src/Builtins/rlimits.c: unnecessary printf + argument in limits on some systems. + +2014-05-16 Peter Stephenson <p.stephenson@samsung.com> + + * Roman Neuhauser: users/18827 (plus tweaks to original + comments): Doc/Zsh/contrib.yo: more efficient way of extracting + hg bookmarks. + +2014-05-13 Barton E. Schaefer <schaefer@zsh.org> + + * 32609: Src/parse.c, Test/CO2cond.ztst: [[ $var ]] behaves as + [[ -n $var ]] for bash/ksh compatibility; restore ksh [ -t ] + compatibility when POSIX_BUILTINS is not set; allow operators + defined by modules to be called with no arguments, although + this affects only runtime interpretation, not parsing. + +2014-05-09 Peter Stephenson <p.stephenson@samsung.com> + + * Eric Cook: 32602: Doc/Zsh/grammar.yo: status of try + always + block is from the former, not the latter. + +2014-05-08 Peter Stephenson <p.stephenson@samsung.com> + + * m0viefreak: 32600: Src/Zle/computil.c: fix problem with + _arguments thinking -- is a single letter option called '-', + which it isn't. + +2014-05-06 Daniel Shahaf <d.s@daniel.shahaf.name> + + * 32597: Functions/VCS_Info/Backends/VCS_INFO_get_data_git: + vcs_info git: Describe detached heads symbolically. + +2014-04-29 Peter Stephenson <p.stephenson@samsung.com> + + * Tomoki Sekiyama: 32592: add CORRECT_IGNORE_FILE variable. + +2014-04-23 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Sebastien Alaiwan: 32562: Completion/Unix/Command/_bzr: + updates for bzr completion. + + * Jasper Lievisse Adriaanse: 32558: configure.ac: + _XOPEN_SOURCE_EXTENDED now works OK on OpenBSD. + +2014-04-25 Barton E. Schaefer <schaefer@zsh.org> + + * 32580: Src/hist.c: avoid indefinite wait in lockhistfile() by + checking for lock file time stamp far in the future relative to + the local clock. Change behavior of HIST_FCNTL_LOCK to use only + fcntl() locking, rather than applying both kinds of lock. + +2014-04-20 Barton E. Schaefer <schaefer@zsh.org> + + * 32569: Src/loop.c: lastval ($?) should not be reset between + word list substitution and loop body execution in for/select. + + * 32568: Src/exec.c, Src/loop.c: consistency in handling of errflag + condition during substitutions in for/select word lists, function + definition name position, and anonymous function argument lists. + +2014-04-17 Barton E. Schaefer <schaefer@zsh.org> + + * Andrew Waldron: 32552 (updated by 32560): Src/exec.c, + Src/parse.c, Src/subst.c, Test/C04funcdef.ztst: fix segfault + when using process substitution in anonymous function argument + list; disallow process substitution in function name position. + +2014-04-15 Barton E. Schaefer <schaefer@zsh.org> + + * Jun T: 32546: Completion/Unix/Type/_path_files: better handling + of ignored files when using -W to specify prefixes. + +2014-04-13 Barton E. Schaefer <schaefer@zsh.org> + + * 32540: Src/Zle/zle_tricky.c, Src/Zle/zle_utils.c: following + successful history expansion, discard saved line position data + rather than restoring from it (updates 32531). + +2014-04-07 Peter Stephenson <p.stephenson@samsung.com> + + * 32527: Doc/Zsh/contrib.yo, Functions/Misc/zcalc, + Functions/Zle/zcalc-auto-insert: zcalc-auto-insert widget + for key binding in zcalc. + +2014-04-06 Barton E. Schaefer <schaefer@zsh.org> + + * unposted: Doc/Zsh/options.yo: fix typo in option cross-reference + + * 32531: Src/Zle/zle_refresh.c, Src/Zle/zle_tricky.c, Src/hist.c: + fix memory leaks detected by valgrind, two in ZLE region highlight + and one in :A history modifier. + +2014-04-06 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Sebastian Ramacher: 32533: Completion/Debian/Command/_apt: add + completion for "apt-mark". + + * Alessandro Ghedini: 32532: Completion/Debian/Command/_apt: + support 'apt' command. + + * 32530: llua: Completion/Unix/Command/_zfs: repeatable -o + argument. + + * 32521: Doc/Zsh/params.yo: document that LOGNAME comes + from getlogin(). + +2014-04-05 Daniel Shahaf <d.s@daniel.shahaf.name> + + * 32528: Completion/Zsh/Command/_zstyle, Doc/Zsh/contrib.yo, + Functions/VCS_Info/Backends/VCS_INFO_get_data_git, + Misc/vcs_info-examples: vcs_info: Add check-for-staged-changes + + * 32528: Doc/Zsh/contrib.yo: vcs_info: Document 'post-backend' + hook and bzr 'check-for-changes' support. + +2014-03-28 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Danek Duvall: 32505: Completion/Unix/Command/_pgrep: improved + Solaris compatibility for pgrep completion. + +2014-03-23 Barton E. Schaefer <schaefer@zsh.org> + + * m0viefreak: users/18660: Src/Zle/compresult.c, + Src/Zle/zle_misc.c, Src/Zle/zle_refresh.c: fix auto-removable + suffix highlighting + + * m0viefreak: users/18657: Completion/Unix/Command/_git: fix + compadd for auto-removable suffix in _git_stash + + * m0viefreak: users/18655: Completion/Unix/Command/_git: fix + compadd for auto-removable suffix in _git_commit_ranges + +2014-03-21 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Takeshi Banse: 32502: Completion/Unix/Command/_git: fix typo + in argument list. + +2014-03-20 Peter Stephenson <p.stephenson@samsung.com> + + * users/18644: Doc/Zsh/zle.yo: bindkey -s doc should refer to + documentation for argument interpretation. + + * Completion/Unix/Command/_perforce: finally, after more than + ten years, complete depots after // in file paths as it always + should have done. + +2014-03-18 Barton E. Schaefer <schaefer@zsh.org> + + * 32500: Src/pattern.c: handle interrupts during pattern matching + + * Jun T: 32497: Test/X02zlevi.ztst, Test/comptest: avoid using + comptesteval in the middle of a series of tests; the change in + control required for sourcing the command file can confuse the + simulated interactive input + +2014-03-17 Peter Stephenson <p.stephenson@samsung.com> + + * Jun T: 32494: Doc/zman.yo: Yodl hack to fix indentation + in nroff -man output. + + * Jun T: 32493: Doc/Zsh/contrib.yo, Doc/Zsh/mod_pcre.yo, + Doc/Zsh/mod_regex.yo, Doc/Zsh/mod_sched.yo: some formatting + fixes. + +2014-03-16 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Mariusz Fik: 32847: Completion/openSUSE/Command/_zypper: new + options. + +2014-03-14 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * unposted: Doc/Zsh/options.yo: document effect of 32479. + + * Jun T: 32482: Doc/zman.yo: fix character translation table + usage with some versions of Yodl. + +2014-03-14 Peter Stephenson <p.stephenson@samsung.com> + + * 32479: Src/builtin.c, Src/signals.c: with POSIXTRAPS + never propagate an implicit return from within a trap. + +2014-03-13 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Kosuke Asami: 32473: Completion/Unix/Command/_pgrep: tidy up + + * Kosuke Asami: 32471: Completion/Unix/Command/_pgrep: handle + BSD process options. + + * Kosuke Asami: 32472: Completion/Unix/Command/_pgrep: new options. + +2014-03-13 Peter Stephenson <p.stephenson@samsung.com> + + * Jun T: 32480: Src/Zle/zle_vi.c: fix crash in vi mode when too + few previous changes. + +2014-03-09 Barton E. Schaefer <schaefer@zsh.org> + + * 32468: Src/Modules/zutil.c: save/restore match/mbegin/mend + when doing pattern lookups against zstyle contexts + +2014-03-03 Barton E. Schaefer <schaefer@zsh.org> + + * users/18550: Doc/Zsh/compsys.yo: matcher-list clarifications + +2014-03-03 Simon Ruderich <simon@ruderich.org> + + * 32289: Doc: Add zsh version to footer in HTML documentation. + +2014-03-03 Oliver Kiddle <opk@zsh.org> + + * 32441: Completion/Base/Completer/_extensions, Doc/Zsh/compsys.yo: + add completer for file extensions + + * 32450: Src/Zle/zle_hist.c: make get-line set the history + number that was saved with the line + + * 32448: Src/Zle/zle_params.c: fix seg fault after recursive-edit + + * 32439 (with Yuri D'Elia): Completion/Base/Core/_main_complete: + add new show-ambiguity style + + * 32436: Src/Zle/complist.c: allow = to be used in ZLS_COLORS + patterns if it is quoted or inside parentheses + +2014-03-01 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 32453: Functions/Misc/zcalc: fix default base handling. + + * Manuel Presnitz: 32412 modified c.f. 32415: + Completion/Zsh/Type/_globquals, Doc/Zsh/expn.yo, Src/glob.c, + Src/zsh.h: gigabyte and terabyte units for glob qualifiers. + +2014-02-28 Peter Stephenson <p.stephenson@samsung.com> + + * users/18531 plus doc etc.: Doc/Zsh/contrib.yo, + Functions/Zle/.distfiles, Functions/Zle/expand-absolute-path: + new expand-absolute-path ZLE widget. + +2014-02-26 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Jun T: 32435: Completion/Base/Core/_description, + Completion/Unix/Command/_rm: improved quoting for ignore-line + style. + +2014-02-24 Oliver Kiddle <opk@zsh.org> + + * unposted: Doc/Zsh/compsys.yo: fix typo + + * unposted: Completion/X/Command/_x_utils: duplicate local + statement was printing variable value + + * users/18498: Completion/Base/Completer/_expand_alias: observe + add-space style in _expand_alias so suffix can be disabled + + * users/18485: Completion/Unix/Command/_git: add .. as an + auto-removable suffix in git revision ranges + +2014-02-24 Peter Stephenson <p.stephenson@samsung.com> + + * Hong Xu: 32492: Completion/Unix/Command/_npm: fix outdated + completion. + + * Sebastien Alaiwan: 32462: Completion/Unix/Command/_bzr: + improve completion with directory path. + +2014-02-23 Barton E. Schaefer <schaefer@zsh.org> + + * 32427: Doc/Zsh/zle.yo, Src/Zle/zle_main.c: avoid busy loop + on closed descriptors for "zle -F" handlers. Assure that the + handlers are called on error conditions and document the extra + argument that is passed in the error case. + +2014-02-19 Peter Stephenson <p.stephenson@samsung.com> + + * 32414: Src/glob.c: improved error message for missing glob + qualifier delimiters. + +2014-02-18 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Eric Cook: 32408: Completion/Linux/Command/_btrfs: additional + completions + + * Eric Cook: 32409: Completion/Linux/Command/_btrfs: updated + completion for subcommands. + + * Eric Cook: 32411: Completion/Linux/Command/_btrfs: minor typo. + + * Eric Cook: 32410: Completion/Linux/Command/_btrfs: remove hard tabs. + + * m0viefreak: Util/helpfiles: 32402: prefer col -bx to colcrt. + + * m0viefreak: Util/helpfiles: 32405: Util/helpfiles: remove old + example now shell code is integrated in distribution. + + * m0viefreak: 32404: Util/helpfiles: use env to find perl. + + * m0viefreak: 32403: Doc/Zsh/contrib.yo: update zshcontrib + manual for helpfiles improvements. + +2014-02-18 m0viefreak <m0viefreak.cm@googlemail.com> + + * 32396: Completion/Unix/Command/_git: _git: fix + __git_committish_range_{first,last} and __git_is_committish_range + + * 32395: Completion/Unix/Command/_git: _git: diff: refactor and + fix wrong completions + + * 32397: Completion/Unix/Command/_git: _git: fix __git_submodules + to only use the actual name of the submodule + + * 32398: Completion/Unix/Command/_git: _git: completion updates up + to latest git v1.9.0 + +2014-02-17 Barton E. Schaefer <schaefer@zsh.org> + + * unposted (users/18468): Doc/Zsh/builtins.yo, Doc/Zsh/params.yo: + document interactions of "fc -R" etc. with "fc -l" and $HISTCMD + +2014-02-15 Barton E. Schaefer <schaefer@zsh.org> + + * 32389 (with Jun Takimoto): Test/X02zlevi.ztst, Test/comptest: + additional PTY and keybinding adjustments + + * 32388: Doc/Zsh/mod_zutil.yo, Src/Modules/zutil.c: zparseopts -K + preserves individual associative array elements + +2014-02-14 Oliver Kiddle <opk@zsh.org> + + * 32361: Src/Zle/zle_tricky.c: don't reset lastline before completion + +2014-02-13 Barton E. Schaefer <schaefer@zsh.org> + + * 32377: Test/comptest: change keybindings and PTY control for + vi-mode tests to make them more reliable + +2014-02-08 Barton E. Schaefer <schaefer@zsh.org> + + * 32365: Src/Zle/zle_refresh.c, Src/init.c: another stab at the + heuristic for initializing rprompt_indent + +2014-02-07 Peter Stephenson <p.stephenson@samsung.com> + + * Martin Vaeth: 32356: Util/helpfiles: fix a typo. + +2014-02-05 Oliver Kiddle <opk@zsh.org> + + * 32355: Doc/Zsh/zle.yo Test/X02zlevi.ztst Test/comptest: document + and test vi mode undo changes + + * 32342: Src/Zle/zle_main.c, Src/Zle/zle_vi.c: fix overstrike for vi + mode and use varying vi commands at line start + + * 32334 (modified so KEEPSUFFIX is unchanged for vi-cmd-mode; based on + Jun T: 32324, 32330), 32347, Jun T: 32344, 32349: Src/Zle/iwidgets.list, + Src/Zle/zle_main.c, Src/Zle/zle_utils.c, Src/Zle/zle_vi.c + add split-undo zle widget for configurable breaks in undo sequence + +2014-02-02 Barton E. Schaefer <schaefer@zsh.org> + + * unposted: Doc/Zsh/builtins.yo, Doc/Zsh/expn.yo, + Doc/Zsh/roadmap.yo: tweak index markers and related whitespace + to make appearance consistent with other pages + + * 32341: Src/init.c: guess at best ZLE_RPROMPT_INDENT based on + termcap/terminfo description + + * unposted: Src/Zle/zle_tricky.c: whitespace in comment + + * 32340: Src/init.c, Src/Zle/compctl.c: add specifics to error + messages explaining failure of "read -c" / "read -l". + + * 32338: Doc/Makefile.in: create Doc/help.txt as an empty file + when Util/helpfiles fails, so that the rest of the build does not + yeild a spurious error + + * 32337: Src/params.c: initialize several special parameters to + unset for better compatibility in emulation modes; for the same + reason, remove the readonly flag from $_ + +2014-01-31 Oliver Kiddle <opk@zsh.org> + + * 32314: Src/Zle/zle_main.c, Src/Zle/zle_tricky.c, + Src/Zle/zle_utils.c, Src/Zle/zle_vi.c: merge undo events + corresponding to vi change in the vi-cmd-mode widget so undo from + insert mode is useful again + +2014-01-30 Barton E. Schaefer <schaefer@zsh.org> + + * 32322: Completion/Base/Core/_main_complete: display a message + when completion is interrupted from the keyboard + +2014-01-30 Peter Stephenson <p.stephenson@samsung.com> + + * Jun T: 32300: Completion/Unix/Command/_od: + + Completion/Unix/Command/.distfiles: new completion. + +2014-01-29 Peter Stephenson <p.stephenson@samsung.com> + + * Christian Hesse: 32316: Completion/Unix/Command/_ssh: complete + new ssh key type. + +2014-01-28 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 32303: Src/Zle/compcore.c, Completion/Zsh/Type/_parameters, + Completion/Zsh/Context/_brace_parameter: allow completion + of modifiers for parameters in a fairly simplistic way. + +2014-01-28 Peter Stephenson <p.stephenson@samsung.com> + + * 32308 (slightly modified to use "a" as the vi command at start + of line): Src/Zle/zle_main.c, Src/Zle/zle_vi.c: improve + initialising of vi mode change when entering viins at start of + editing. + +2014-01-27 Barton E. Schaefer <schaefer@zsh.org> + + * users/18368: Completion/Unix/Command/_git: in __git_files, + retry ls-files if nothing matched the prefix pattern, to give + _multi_parts a shot at the whole file list. Restores partial + path completion inadvertently removed by 31159. + +2014-01-27 Peter Stephenson <p.stephenson@samsung.com> + + * unposted: Src/zsh.mdd: update 31983 to suppress stdout from + cmp, too. + +2014-01-23 Bart Schaefer <schaefer@zsh.org> + + * unposted: Doc/Zsh/arith.yo: use LPAR()+RPAR() instead of parens + in sqrt example + +2014-01-23 Peter Stephenson <p.stephenson@samsung.com> + + * 32299: Doc/Zsh/arith.yo, Functions/Misc/zcalc, Src/math.c, + Src/params.c, Src/subst.c, Test/C01arith.ztst: add + ability to use "_" at the end of a [#] arithmetic expression + to get underscores to space numeric output. + +2014-01-22 Barton E. Schaefer <schaefer@zsh.org> + + * unposted: Src/mem.c: reformulate 32285 to lift the fheap->sp + test out of the loop, improve commentary + +2014-01-19 Barton E. Schaefer <schaefer@zsh.org> + + * 32294 (plus typo fix): Src/utils.c: prevent buffer overflow when + scanning very long directory paths for symbolic links + + * users/18335: Completion/Zsh/Command/_typeset: avoid passing to + "functions" those typeset options that it does not accept + +2014-01-18 Barton E. Schaefer <schaefer@zsh.org> + + * 32285: Src/mem.c (freeheap): when the last-arena-with-free-space + pointer (fheap) points to an arena that is going to be discarded + because it has become empty, loop back through the entire linked + list of arenas to find another partly-filled arena; fixes crash + wherein pushheap followed by freeheap could orphan the whole list + of arenas in some circumstances + + * 32283: Src/Zle/complist.c: avoid using a negative number for + available vertical space when the terminal has only a small number + of lines; fixes crash in menu selection + +2014-01-17 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Daniel Hahler: 32271: Doc/Zsh/compsys.yo: fix matcher list + example. + +2014-01-17 Peter Stephenson <p.stephenson@samsung.com> + + * sergio: 32267: Completion/Linux/Command/_modutils: modinfo may + not be in user's path, so use explicit path as already done for lsmod. + +2014-01-17 Frank Terbeck <ft@bewatermyfriend.org> + + * 32264: Functions/VCS_Info/Backends/VCS_INFO_detect_hg: vcs_info, + hg: Support detecting repos using ShareExtension + +2014-01-16 Barton E. Schaefer <schaefer@zsh.org> + + * Thomas Mitterfellner: 32265: Completion/openSUSE/Command/_zypper: + better handling of large lists of packages + +2014-01-16 Peter Stephenson <p.stephenson@samsung.com> + + * Holger Macht: 32257: Completion/openSUSE/Command/_zypper: + updates. + +2014-01-14 Peter Stephenson <p.stephenson@samsung.com> + + * 32255: Completion/Unix/Command/_python: complete for Python + with command names python2.4 ... python3.4. + +2014-01-11 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 32246: Doc/Zsh/builtins.yo, Src/builtin.c, Test/.distfiles, + Test/B08shift.ztst: add "shift -p" to pop arguments from the end + of arrays. + +2014-01-10 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Koen Wilde: 32245: Completion/Unix/Command/_mpc: complete more + arguments. + +2014-01-09 Peter Stephenson <p.stephenson@samsung.com> + + * users/18298 (tidied up): Doc/Zsh/expn.yo, Src/glob.c, + Test/D09brace.ztst: add {<char>..<char>} expansion. + +2014-01-07 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * Mark Oteiza: 32238: suppress error output completing after ip. + +2014-01-06 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * unposted: Config/version.mk: update to 5.0.5-dev-0 to avoid + installation clash with 5.0.5 release. + 2014-01-05 Peter Stephenson <p.w.stephenson@ntlworld.com> * unposted: Config/version.mk, Doc/Zsh/compsys.yo: update @@ -1265,7 +2159,7 @@ * users/17665: Doc/Zsh/options.yo, Src/math.c, Src/options.c, Src/zsh.h, Test/C01arith.ztst: add FORCE_FLOAT option. -2013-02-27 Oliver Kiddle <opk@zsh.org> +2013-02-27 Oliver Kiddle <opk@zsh.org> * 31076: Completion/Linux/Command/_yast, Completion/Unix/Type/_pids, Completion/Unix/Type/_pdf: @@ -1286,7 +2180,7 @@ * 31060: Src/builtin.c: "+" before a flag for "functions" or "autoload" should suppress display of function body. -2013-02-21 Oliver Kiddle <opk@zsh.org> +2013-02-21 Oliver Kiddle <opk@zsh.org> * 31058: Completion/Zsh/Command/_fc, Completion/Unix/Command/_cut, Completion/Unix/Command/_sed, Completion/Unix/Command/_wget, @@ -1298,7 +2192,7 @@ * 31055: Completion/compaudit: missing '$' in search of /proc file system. -2013-02-12 Oliver Kiddle <opk@zsh.org> +2013-02-12 Oliver Kiddle <opk@zsh.org> * 31041: Test/comptest, Test/X02zlevi.ztst: add support for testing line editor widgets from the test suite @@ -1306,7 +2200,7 @@ * unposted: Etc/zsh-development-guide: remove duplication in git guidelines -2013-02-09 Oliver Kiddle <opk@zsh.org> +2013-02-09 Oliver Kiddle <opk@zsh.org> * Morita Sho: 31038: Completion/Unix/Type/_terminals: add location of terminfo entries on Debian @@ -1363,7 +2257,7 @@ modifiers :wq operating on an empty string crashed the shell. The shell isn't supposed to crash. -2013-01-20 Oliver Kiddle <opk@zsh.org> +2013-01-20 Oliver Kiddle <opk@zsh.org> * 30987: Completion/X/Command/_xrandr: only call xrandr when necessary and use _call_program @@ -1421,7 +2315,7 @@ * unposted: Config/version.mk: zsh 5.0.1. -2012-12-18 Oliver Kiddle <opk@zsh.org> +2012-12-18 Oliver Kiddle <opk@zsh.org> * 30877: Etc/zsh-development-guide: document git workflow @@ -1455,7 +2349,7 @@ * users/17445: Src/math.c, Test/C01arith.ztst: fix handling of leading zeroes in floating point. -2012-11-20 Oliver Kiddle <opk@zsh.org> +2012-11-20 Oliver Kiddle <opk@zsh.org> * 30811: Completion/Linux/Command/_btrfs, Completion/Unix/Command/_mount: new completion for btrfs and @@ -1470,7 +2364,7 @@ * users/17042: Src/jobs.c: don't stomp the environment in "jobs -Z" unless we've first copied it to new memory. -2012-11-16 Oliver Kiddle <opk@zsh.org> +2012-11-16 Oliver Kiddle <opk@zsh.org> * 30802: Completion/Unix/Command/_find: add new command switches @@ -1488,7 +2382,7 @@ * 30800: Michal Halenka: Completion/Unix/Command/_arping: fix option. -2012-11-12 Oliver Kiddle <opk@zsh.org> +2012-11-12 Oliver Kiddle <opk@zsh.org> * 30795: Completion/Unix/Command/_xz, Completion/Unix/Command/_bzip2: new xz completion, new bzip2 options @@ -1496,7 +2390,7 @@ * 30794: Completion/Unix/Command/_irssi, Completion/Unix/Command/_mutt: update for new options -2012-11-11 Oliver Kiddle <opk@zsh.org> +2012-11-11 Oliver Kiddle <opk@zsh.org> * 30793: Completion/Unix/Command/_getent, Completion/Unix/Command/_iconv, Completion/Unix/Command/_ldd: @@ -1516,7 +2410,7 @@ * 30780: Doc/Zsh/builds.yo: document that set -o failures are hard but setopt failures are soft. -2012-11-07 Oliver Kiddle <opk@zsh.org> +2012-11-07 Oliver Kiddle <opk@zsh.org> * Benjamin R. Haskell: 30737: Completion/Unix/Command/_git: make custom completion functions for git aliases easier @@ -1585,7 +2479,7 @@ Test/C04funcdef.ztst: emulate command evaluations should apply sticky emulation to autoloads, too. -2012-10-07 Oliver Kiddle <opk@zsh.org> +2012-10-07 Oliver Kiddle <opk@zsh.org> * unposted: Completion/Unix/Command/_webbrowser, Completion/Unix/Type/_pspdf: add evince, zathura, dwb @@ -1639,7 +2533,7 @@ Functions/VCS_Info/Backends/VCS_INFO_detect_fossil: Fix fossil detection on unix -2012-09-28 Oliver Kiddle <opk@zsh.org> +2012-09-28 Oliver Kiddle <opk@zsh.org> * 30697: Completion/Unix/Command/_dbus: new completion definition diff --git a/Completion/Base/Completer/.distfiles b/Completion/Base/Completer/.distfiles index 3030142de..804c57990 100644 --- a/Completion/Base/Completer/.distfiles +++ b/Completion/Base/Completer/.distfiles @@ -6,6 +6,7 @@ _complete _correct _expand _expand_alias +_extensions _history _ignored _list diff --git a/Completion/Base/Completer/_expand_alias b/Completion/Base/Completer/_expand_alias index 8848e668d..8240e4162 100644 --- a/Completion/Base/Completer/_expand_alias +++ b/Completion/Base/Completer/_expand_alias @@ -1,7 +1,7 @@ #compdef -K _expand_alias complete-word \C-xa local word expl tmp pre sel what -local -a tmpa +local -a tmpa suf eval "$_comp_setup" @@ -58,7 +58,8 @@ if [[ -n $tmp ]]; then tmp="\\$tmp" fi fi - $pre _wanted aliases expl alias compadd -UQ -- ${tmp%%[[:blank:]]##} + zstyle -T ":completion:${curcontext}:" add-space || suf=( -S '' ) + $pre _wanted aliases expl alias compadd -UQ "$suf[@]" -- ${tmp%%[[:blank:]]##} elif (( $#pre )) && zstyle -t ":completion:${curcontext}:" complete; then $pre _aliases -s "$sel" -S '' else diff --git a/Completion/Base/Completer/_extensions b/Completion/Base/Completer/_extensions new file mode 100644 index 000000000..8b6c4fd6a --- /dev/null +++ b/Completion/Base/Completer/_extensions @@ -0,0 +1,33 @@ +#autoload + +# This completer completes filename extensions when completing +# after *. or ^*. It can be used anywhere in the completer list +# but if used after _expand, patterns that already match a file +# will be expanded before it is called. + +compset -P '(#b)([~$][^/]#/|)(*/|)(\^|)\*.' || return 1 + +local -aU files +local -a expl suf mfiles + +files=( ${(e)~match[1]}${match[2]}*.* ) || return 1 +eval set -A files '${(MSI:'{1..${#${(O)files//[^.]/}[1]}}':)files%%.[^/]##}' +files=( ${files:#.<->(.*|)} ) + +if zstyle -t ":completion:${curcontext}:extensions" prefix-hidden; then + files=( ${files#.} ) +else + PREFIX=".$PREFIX" + IPREFIX="${IPREFIX%.}" +fi + +zstyle -T ":completion:${curcontext}:extensions" add-space || + suf=( -S '' ) + +_description extensions expl 'file extension' + +# for an exact match, fail so as to give _expand or _match a chance. +compadd -O mfiles "$expl[@]" -a files +[[ $#mfiles -gt 1 || ${mfiles[1]} != $PREFIX ]] && + compadd "$expl[@]" "$suf[@]" -a files && + [[ -z $compstate[exact_string] ]] diff --git a/Completion/Base/Core/_description b/Completion/Base/Core/_description index 3d993271c..304c747a6 100644 --- a/Completion/Base/Core/_description +++ b/Completion/Base/Core/_description @@ -47,17 +47,19 @@ if [[ -z "$_comp_no_ignore" ]]; then zstyle -a ":completion:${curcontext}:$1" ignored-patterns _comp_ignore || _comp_ignore=() - zstyle -s ":completion:${curcontext}:$1" ignore-line hidden && + if zstyle -s ":completion:${curcontext}:$1" ignore-line hidden; then + local -a qwords + qwords=( ${words//(#m)[\[\]()\\*?#<>~\^\|]/\\$MATCH} ) case "$hidden" in - true|yes|on|1) _comp_ignore=( "$_comp_ignore[@]" ${(q)"${words[@]}"} );; - current) _comp_ignore=( "$_comp_ignore[@]" "${(q)words[CURRENT]}" );; + true|yes|on|1) _comp_ignore+=( $qwords );; + current) _comp_ignore+=( $qwords[CURRENT] );; current-shown) [[ "$compstate[old_list]" = *shown* ]] && - _comp_ignore=( "$_comp_ignore[@]" "${(q)words[CURRENT]}" );; - other) _comp_ignore=( "$_comp_ignore[@]" - "${(@q)words[1,CURRENT-1]}" - "${(@q)words[CURRENT+1,-1]}" );; + _comp_ignore+=( $qwords[CURRENT] );; + other) _comp_ignore+=( $qwords[1,CURRENT-1] + $qwords[CURRENT+1,-1] );; esac + fi # Ensure the ignore option is first so we can override it # for fake-always. diff --git a/Completion/Base/Core/_main_complete b/Completion/Base/Core/_main_complete index d6831b81b..e881ea6a1 100644 --- a/Completion/Base/Core/_main_complete +++ b/Completion/Base/Core/_main_complete @@ -126,6 +126,11 @@ fi _completer_num=1 +# We assume localtraps to be in effect here ... +integer SECONDS=0 +trap 'zle -M "Killed by signal in ${funcstack[0]} after ${SECONDS}s"; + zle -R; return 130' INT QUIT + # Call the pre-functions. funcs=( "$compprefuncs[@]" ) @@ -329,6 +334,14 @@ elif [[ nm -eq 0 && -z "$_comp_mesg" && compadd -x "$mesg" fi +if zstyle -s ":completion:${curcontext}:" show-ambiguity tmp; then + local prefix=${${compstate[unambiguous]}[1,${compstate[unambiguous_cursor]}-1]} + local toquote='[=\(\)\|~^?*[\]#<>]' + [[ $tmp = (yes|true|on) ]] && tmp=4 + [[ -n $prefix ]] && + _comp_colors+=( "=(#i)${prefix[1,-2]//?/(}${prefix[1,-2]//(#m)?/${MATCH/$~toquote/\\$MATCH}|)}${prefix[-1]//(#m)$~toquote/\\$MATCH}(#b)(?|)*==$tmp" ) +fi + [[ "$_comp_force_list" = always || ( "$_comp_force_list" = ?* && nm -ge _comp_force_list ) ]] && compstate[list]="${compstate[list]//messages} force" diff --git a/Completion/Darwin/Command/.distfiles b/Completion/Darwin/Command/.distfiles index e52f4a980..5756f542d 100644 --- a/Completion/Darwin/Command/.distfiles +++ b/Completion/Darwin/Command/.distfiles @@ -1,4 +1,10 @@ DISTFILES_SRC=' .distfiles -_defaults _fink _hdiutil _open _qtplay _softwareupdate +_defaults +_fink +_hdiutil +_open +_qtplay +_softwareupdate +_system_profiler ' diff --git a/Completion/Darwin/Command/_system_profiler b/Completion/Darwin/Command/_system_profiler new file mode 100644 index 000000000..fe197579d --- /dev/null +++ b/Completion/Darwin/Command/_system_profiler @@ -0,0 +1,20 @@ +#compdef system_profiler + +typeset -A opt_args +local context state state_descr line +local -a _data_types + +# TODO: Should this be static? Calling `system_profiler -listDataTypes` takes +# about 0.07-0.08 secs on my machine. Does this list ever change (between +# different versions of OS X)? +_data_types=( SP{AirPort,Applications,Audio,Bluetooth,Camera,CardReader,Component,ConfigurationProfile,DeveloperTools,Diagnostics,DisabledSoftware,DiscBurning,Displays,Ethernet,Extensions,FibreChannel,FireWire,Firewall,Fonts,Frameworks,Hardware,HardwareRAID,InstallHistory,Logs,ManagedClient,Memory,Network,NetworkLocation,NetworkVolume,PCI,ParallelATA,ParallelSCSI,Power,PrefPane,Printers,PrintersSoftware,SAS,SPI,SerialATA,Software,StartupItem,Storage,SyncServices,Thunderbolt,USB,UniversalAccess,WWAN}DataType ) +# the dynamic alternative is: +#_data_types=( ${${(f)"$(_call_program path system_profiler -listDataTypes 2>/dev/null)"}[2,-1]} ) + +_arguments \ + '(- *)-usage' \ + '(- *)-listDataTypes[lists the available datatypes]' \ + '(-listDataTypes -usage)-xml[generate xml output]' \ + '(-listDataTypes -usage)-detailLevel[level of detail for the report]:detail level:(mini basic full)' \ + '(-listDataTypes -usage)-timeout+[maximum time to wait in seconds]' \ + '(-listDataTypes -usage)*:data type:'"($_data_types)" diff --git a/Completion/Debian/Command/_apt b/Completion/Debian/Command/_apt index b51b2fc74..bf5343a94 100644 --- a/Completion/Debian/Command/_apt +++ b/Completion/Debian/Command/_apt @@ -1,11 +1,13 @@ -#compdef apt-get apt-cache apt-cdrom apt-config +#compdef apt apt-get apt-cache apt-cdrom apt-config apt-mark _apt () { case "$service" in + apt) _apt-cmd "$@";; apt-get) _apt-get "$@";; apt-cache) _apt-cache "$@";; apt-cdrom) _apt-cdrom "$@";; apt-config) _apt-config "$@";; + apt-mark) _apt-mark "$@";; *) _message "unknown command $service";; esac } @@ -389,6 +391,38 @@ _apt_consume_long () { return 0 } +_apt-cmd () { + _apt_arguments _apt-cmd_sm \ + -h,--help:bool \ + -v,--version:bool \ + -c,--config-file:configfile \ + -o,--option:arbitem \ + -t,--target-release:release \ + -- \ + /$'list\0'/ \| \ + /$'search\0'/ /$'[^\0]#\0'/ ':strings:pattern:' \| \ + /$'show\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" avail' \# \ + /$'update\0'/ \| \ + \( \ + /$'install\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" avail' \# \ + /$'[^\0/]#/'/ /$'[^\0/]#\0'/ ':release name::_apt_releases' \) \| \ + /$'remove\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ + /$'upgrade\0'/ \| \ + /$'full-upgrade\0'/ \| \ + /$'edit-sources\0'/ \| \ + /"[]"/ ':argument-1::compadd "$expl_action[@]" list search show update install remove upgrade full-upgrade edit-sources' + + _apt-cmd () { + local expl_action expl_packages + _description actions expl_action 'action' + _description packages expl_packages 'package' + + _apt-cmd_sm + } + + _apt-cmd "$@" +} + _apt-get () { _apt_arguments _apt-get_sm \ -h,--help:bool \ @@ -586,4 +620,34 @@ _apt_caching_policy () { /var/lib/dpkg/available -nt "$1" ]] } +_apt-mark () { + _apt_arguments _apt-mark_sm \ + -h,--help:bool \ + -v,--version:bool \ + -f,--file:configfile \ + -c,--config-file:configfile \ + -o,--option:arbitem \ + -qq:bool \ + -s:bool \ + -- \ + /$'auto\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ + /$'manual\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ + /$'hold\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ + /$'unhold\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ + /$'showauto\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ + /$'showmanual\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ + /$'showhold\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \ + /"[]"/ ':argument-1::compadd "$expl_action[@]" auto manual hold unhold showauto showmanual showhold' + + _apt-mark () { + local expl_action expl_packages + _description actions expl_action 'action' + _description packages expl_packages 'package' + + _apt-mark_sm + } + + _apt-mark "$@" +} + _apt "$@" diff --git a/Completion/Debian/Command/_aptitude b/Completion/Debian/Command/_aptitude index 2c462e462..2cb211149 100644 --- a/Completion/Debian/Command/_aptitude +++ b/Completion/Debian/Command/_aptitude @@ -70,6 +70,8 @@ _arguments -C \ '--schedule-only[schedule operations to be performed in the future]' \ '--purge-unused[purge unused packages instead of removing]' \ '--visual-preview[start up the visual interface and display its preview screen]' \ + '--full-resolver[attempts to resolve conflicts with a higher risk of breakage]' \ + '--safe-resolver[attempts to resolve conflicts with a lower risk of breakage]' \ '-S[load the extended state information from non-standard state file]:state file:_files' \ '-u[begin updating the package lists as soon as the program starts]' \ '-i[displays a download preview when the program starts]' \ diff --git a/Completion/Debian/Command/_axi-cache b/Completion/Debian/Command/_axi-cache index 0c137c700..bdefdd979 100644 --- a/Completion/Debian/Command/_axi-cache +++ b/Completion/Debian/Command/_axi-cache @@ -11,10 +11,11 @@ _arguments \ if (( CURRENT == 2 )); then _wanted tag expl 'axi-cache commands' \ - compadd help search more last show again + compadd help search more last show again info \ + rdetails depends madison policy showpkg showsrc else case "$words[2]" in - (search|show|again) + (search|show|again|rdetails|depends|madison|policy|showpkg|showsrc) _wanted tag expl 'terms/query' \ compadd -- $($service $words[2] --tabcomplete=plain -- $words[CURRENT]) ;; @@ -22,6 +23,9 @@ else _wanted tag expl 'count' \ compadd -- 1 2 3 4 5 6 7 8 9 0 ;; + (help|info) + # no args + ;; (*) _files ;; diff --git a/Completion/Debian/Command/_dpkg b/Completion/Debian/Command/_dpkg index e7184e7cc..3503d09b9 100644 --- a/Completion/Debian/Command/_dpkg +++ b/Completion/Debian/Command/_dpkg @@ -50,6 +50,9 @@ _dpkg_actions=( '--yet-to-unpack[list uninstalled]' '--print-architecture[print target architecture]' '--print-installation-architecture' + '--print-foreign-architectures[print list of extra architectures]' + '--add-architecture[add extra architecture]:architecture:->add_architecture' + '--remove-architecture[remove extra architecture]:architecture:->remove_architecture' '--compare-versions[compare version numbers]:*::expression:= ->compare_versions' ) @@ -179,4 +182,13 @@ case "$state" in _call_function ret _dpkg_$state && return ret _files ;; + add_architecture) + _call_function ret _dpkg_$state && return ret + _wanted architecture expl 'extra architecture' \ + compadd ${(f)"$(dpkg-architecture -L 2>/dev/null)"} + ;; + remove_architecture) + _call_function ret _dpkg_$state && return ret + _wanted architecture expl 'extra architecture' \ + compadd ${(f)"$(dpkg --print-foreign-architectures 2>/dev/null)"} esac diff --git a/Completion/Linux/Command/.distfiles b/Completion/Linux/Command/.distfiles index f6ee5b6c7..7ae5cf91e 100644 --- a/Completion/Linux/Command/.distfiles +++ b/Completion/Linux/Command/.distfiles @@ -23,8 +23,10 @@ _nmcli _pkgtool _rpmbuild _schedtool +_ss _sshfs _strace +_sysstat _tpb _tpconfig _tune2fs diff --git a/Completion/Linux/Command/_btrfs b/Completion/Linux/Command/_btrfs index da2514e99..c8f87ef70 100644 --- a/Completion/Linux/Command/_btrfs +++ b/Completion/Linux/Command/_btrfs @@ -1,15 +1,23 @@ #compdef btrfs +# based on Btrfs v3.12+20131125 local curcontext="$curcontext" curstate state line expl grp cmd ret=1 -local -a groups args cmds_1 cmds_2 cmds_3 cmds_4 cmds_5 cmds_6 +local -a cmds_1 cmds_2 cmds_3 cmds_4 cmds_5 cmds_6 cmds_7 cmds_8 cmds_9 cmds_10 +local -a groups args -groups=( subvolume filesystem device scrub balance inspect-internal help version ) -cmds_1=( create delete list snapshot get-default set-default find-new help ) +groups=( subvolume filesystem device scrub balance inspect-internal + quota qgroup replace rescue check restore send receive + help version ) +cmds_1=( create delete list snapshot get-default set-default find-new show help ) cmds_2=( df show sync defragment resize label balance help ) -cmds_3=( add delete scan help ) +cmds_3=( add delete ready scan stats help ) cmds_4=( start cancel resume status help ) cmds_5=( start pause cancel resume status ) -cmds_6=( inode-resolve logical-resolve help ) +cmds_6=( inode-resolve logical-resolve subvolid-resolve rootid help ) +cmds_7=( enable disable rescan help ) +cmds_8=( assign remove create destroy show limit help ) +cmds_9=( start status cancel help ) +cmds_10=( chunk-recover super-recover ) [[ $words[2] = h(|e(|l(|p))) ]] && args=( '--full[display detailed help]' ) @@ -31,88 +39,246 @@ while (( $#state )); do : $words local grp=${groups[(i)$words[2]*]} : $grp - (( grp && grp < 7 )) || return 1 + (( grp && grp <= 14 )) || return 1 curcontext="${curcontext%:*:*}:$service-${groups[grp]}:" - _wanted commands expl command compadd -a cmds_$grp && ret=0 + case $grp in + 11) + # btrfs check + args+=( + {-s,--support}'[specify superblock]:superblock: _message "superblock"' + '--repair[try to repair the filesystem]' + '--init-csum-tree[create a new CRC tree]' + '--init-extent-tree[create a new extent tree]' + '1:path:_files -/' + ) + ;| + 12) + # btrfs replace + args+=( + '-s[get snapshots]' + '-x[get extended attributes]' + '-v[verbose]' + '-i[ignore errors]' + '-o[overwrite]' + '-t[tree location]:tree:_message "tree location"' + '-f[filesystem location]:filesystem:_message "filesystem location"' + '-u[super mirror]:mirror:_message "super mirror"' + '-r[root objectid]:objectid:_message "root objectid"' + '-d[find dir]' + '-l[list tree roots]' + '--path-regex[restore matching filenames]:regex:_message "regex"' + '1:device:_files -/' + '2:path:_files -/' + ) + ;| + 13) + # btrfs send + args+=( + '*-v[verbose mode]' + '-p[send incremental stream]:parent:_files -/' + '*-c[use snapshot as clone source]:clone:_files -/' + '-f[output file]:file:_files' + '1:subvol:_files -/' + ) + ;| + 14) + # btrfs receive + args+=( + '*-v[verbose mode]' + '-f[input file]:file: _files' + '-e[terminate after <end cmd>]' + '1:mount:->mounts' + ) + ;| + <11-14>) + (( CURRENT-- )); shift words; curcontext="${curcontext%:*:*}:$service-${group[grp]}:" + _arguments -C "$args[@]" && ret=0 + ;; + <0-10>) + _wanted commands expl command compadd -a cmds_$grp && ret=0 + ;; + esac ;; args) : $words local grp=${groups[(i)$words[1]*]} - (( grp && grp < 7 )) || return 1 + (( grp && grp <= 15 )) || return 1 local group=cmds_$grp local cmd=${${(P)group}[(i)$words[2]*]} (( cmd )) || return 1 curcontext="${curcontext%:*:*}:$service-${groups[grp]}-${${(P)group}[cmd]}:" args=( '(-)--help[print help information]' ) case ${groups[grp]}:${${(P)group}[cmd]} in - filesystem:balance) - if (( CURRENT == 3 )); then - state+=cmds - else - shift words - (( CURRENT-- )) - state+=args - fi - continue - ;; - subvolume:create) args+=( '1:destination:->mounts' );; - subvolume:delete) args+=( '1:subvolume:_files -/' );; - subvolume:snapshot) args+=( '-r[readonly snapshot]' '1:snapshot:_files -/' );; - subvolume:list) args+=( '-p[include parent ID in output]' '1:path:->mounts' );; - subvolume:set-default) args+=( '1:id:_guard "[0-9]#" id' '2:path:->mounts' );; - filesystem:resize) args+=( '1:size:_guart "(|+|-)[0-9]#[GKM]"' '2:path:->mounts' );; - filesystem:defragment) - args+=( - '-v[verbose]' - '-c[compress files while defragmenting]' - '-f[flush after defragmenting]' - '-s[start position]:byte position' - '-l[defragment limited number of bytes]:length (bytes)' - '-t[defragment only files over a certain size]:minimum size (bytes)' - '*:file:_files' - ) - ;; - filesystem:label) args+=( '1:device:_files -g "*(d)"' '2:label' );; - filesystem:show) args+=( '(1 -)--all-devices[scan all devices in /dev]' '1: :_guard "^-*" uuid or label' );; - device:(add|delete)) args+=( '1:device:_files -g "*(d)"' '2:path:->mounts' );; - device:scan) args+=( '(1 -)--all-devices[scan all devices in /dev]' '1:device:_files -g "*(d)"' );; - scrub:(start|resume)) - args+=( - "-B[don't background and print statistics at end]" - '-d[print separate statistics for each device]' - '-q[omit error message and statistics]' - '-r[read only mode]' - '-u[scrub unused space too]' - '1:path or device:_files' - ) - ;; - scrub:cancel) args+=( '1:path or device' );; - scrub:status) args+=( '-d[separate statistics for each device]' '1:path or device:_files' );; - balance:start) - args+=( - '(-m -s)-d+[act on data chunks]:filter:->filters' - '(-d -s)-m+[act on metadata chunks]:filter:->filters' - '(-d -m)-s+[act on system chunks (only under -f)]:filters:->filters' - '-v[verbose mode]' - '-f[force reducing of metadata integrity]' - '1:path:_files -/' - ) - ;; - balance:status) args+=( '-v[verbose mode]' '2:path:_files -/' );; - balance:(pause|cancel|resume)) args+=( '2:path:_files -/' );; - inspect*:inode*) args+=( '-v[verbose mode]' '1:inode:_files' '2:path:_files -/' );; - inspect*:logical*) - args+=( - '-v[verbose mode]' - '-P[skip the path resolving and print the inodes instead]' - '1:logical address:_files' - '2:filesystem path:_files -/' - ) - ;; - subvolume:get-default) ;& - *:sync) ;& - *:df) args+=( '1:path:->mounts' );; - *) args+=( '*: :_default' );; # fallback for unknown subcommands + filesystem:balance) + if (( CURRENT == 3 )); then + state+=cmds + else + shift words + (( CURRENT-- )) + state+=args + fi + continue + ;; + subvolume:create) args+=( '1:destination:->mounts' );; + subvolume:delete) args+=( '1:subvolume:_files -/' );; + subvolume:snapshot) + args+=( + '-r[readonly snapshot]' + '*-i[assign to qgroup]:qgroup: _message "qgroup"' + '1:snapshot:_files -/' + ) + ;; + subvolume:list) + args+=( + '-p[include parent ID in output]' + '-a[include all subvolumes]' + '-c[include ogeneration of the subvolume]' + '-g[include generation of the subvolume]' + '-o[include only subvolumes below the path]' + '-u[include UUID of subvolume]' + '-q[include parent UUID of subvolume]' + '-t[print results as a table]' + '-s[list only snapshot subvolumes]' + '-r[list only readonly subvolumes]' + '-G[subvolume generation is more or less than]:gen: _guard "(|+|-)[0-9]#"' + '-C[subvolume ogeneration is more or less than]:ogen: _guard "(|+|-)[0-9]#"' + '--sort=-[list in order]:sort:_values -s "," sort rootid gen ogen path' + '1:path:->mounts' + ) + ;; + subvolume:set-default) args+=( '1:id:_guard "[0-9]#" id' '2:path:->mounts' );; + subvolume:get-default) args+=( '1:path:_files -/' );; + subvolume:find-new) args+=( '1:subvol:_files -/' '2:lastgen: _message "last gen"' );; + filesystem:resize) args+=( '1:size:_guard "(|+|-)[0-9]#[GKM]"' '2:path:->mounts' );; + filesystem:defragment) + args+=( + '-v[verbose]' + '-c[compress files while defragmenting]' + '-r[defragment files recursively]' + '-f[flush after defragmenting]' + '-s[start position]:byte position' + '-l[defragment limited number of bytes]:length (bytes)' + '-t[defragment only files over a certain size]:minimum size (bytes)' + '*:file:_files' + ) + ;; + filesystem:label) args+=( '1:device:_files -g "*(d)"' '2:label' );; + filesystem:show) + args+=( + '(1 -)'{-d,--all-devices}'[scan all devices in /dev]' + '(1 -)'{-m,--mounted}'[show only mounted filesystems]' + '1: :_guard "^-*" uuid or label' + ) + ;; + device:(add|delete)) + args+=( + '1:device:_files -g "*(d)"' + '2:path:->mounts' + ) + [[ ${${(P)group}[cmd]} == add ]] && + args+=( + {-K,--nodiscard}'[do not perform discard]' + {-f,--force}'[force overwrite of existing filesystem]' + ) + ;; + device:scan) args+=( '(1 -)--all-devices[scan all devices in /dev]' '1:device:_files -g "*(d)"' );; + device:stats) args+=( "1:device or mountpoint:_files -g '*(d,/)'" '-z[reset stats when done]' );; + device:ready) args+=( '1:device: _files -g "*(d)"' );; + scrub:(start|resume)) + args+=( + "-B[don't background and print statistics at end]" + '-d[print separate statistics for each device]' + '-q[omit error message and statistics]' + '-r[read only mode]' + '-R[raw print mode]' + '-c[set ioprio class]:class:(( 0\:none 1\:realtime 2\:best-effort 3\:idle))' + '-n[set ioprio classdata]:classdata:(0 1 2 3 4 5 6 7)' + '1:path or device:_files' + ) + [[ ${${(P)group}[cmd]} == start ]] && args+=( '-R[raw print mode]' ) + ;; + scrub:cancel) args+=( '1:path or device' );; + scrub:status) args+=( '-d[separate statistics for each device]' '1:path or device:_files' );; + balance:start) + args+=( + '(-m -s)-d+[act on data chunks]:filter:->filters' + '(-d -s)-m+[act on metadata chunks]:filter:->filters' + '(-d -m)-s+[act on system chunks (only under -f)]:filters:->filters' + '-v[verbose mode]' + '-f[force reducing of metadata integrity]' + '1:path:_files -/' + ) + ;; + balance:status) args+=( '-v[verbose mode]' '2:path:_files -/' );; + balance:(pause|cancel|resume)) args+=( '2:path:_files -/' );; + quota:(enable|disable)) args+=( '1:path:_files -/' );; + quota:rescan) + args+=( + '-s[show status of currently running rescan]' + '-w[wait for rescan to finish]' + '1:path:_files -/' + ) + ;; + qgroup:(assign|remove)) args+=( '1:source path:_files -/' + '2:destination path:_files -/' '3:path:_files -/' );; + qgroup:(create|destroy)) args+=( '1:qgroupid:' '2:path:_files -/' );; + qgroup:show) + args+=( + '-p[print parent qgroup id]' + '-c[print child qgroup id]' + '-r[print max referenced size of qgroup]' + '-e[print max exclusive size of qgroup]' + '-F[list impacted qgroups\(include ancestral qgroups\)]' + '-f[list impacted qgroups\(exclude ancestral qgroups\)]' + '--sort=-[sort qgroups]:sort:_values -s , sort \ + qgroupid rfer excl max_rfer max_excl' + '1:path:_files -/' + ) + ;; + qgroup:limit) + args+=( + '-c[limit amount of data after compression]' + '-e[limit space exclusively to qgroup]' + ':size or none: _message "size or none"' + ':qgroup id or path:_files -/' + ':path:_files -/' + ) + ;; + replace:start) + args+=( + '-r[read from <srcdev> only]:srcdev:_files' + '-f[force overwriting of target]' + '-B[do not background]' + ':srcdev or devid:_files' + ':target:_files' + ':path:->mounts' + ) + ;; + replace:status) args+=( '-1[print once]' ':path:->mounts' );; + replace:cancel) args+=( ':path:->mounts' );; + inspect*:inode*) args+=( '-v[verbose mode]' '1:inode:_files' '2:path:_files -/' );; + inspect*:subvol*) args+=( '-v[verbose mode]' '1:subvolid:_guard "[0-9]#" subvolume id' '2:path:_files -/' );; + inspect*:logical*) + args+=( + '-v[verbose mode]' + '-P[skip the path resolving and print the inodes instead]' + '-s[buffer size]:buffer size:' + '1:logical address:_files' + '2:filesystem path:_files -/' + ) + ;; + inspect*:rootid) args+=( '1:path:_files -/' );; + rescue:(chunk|super)-recover) + args+=( + '-y[assume yes to every question]' + '-v[verbose mode]' + ) + [[ ${${(P)group}[cmd]} == chunk-recover ]] && args+=('-h[display help]') + ;; + subvolume:get-default) ;& + *:sync) ;& + *:df) args+=( '1:path:->mounts' );; + *) args+=( '*: :_default' );; # fallback for unknown subcommands esac shift words (( CURRENT-- )) @@ -125,18 +291,18 @@ while (( $#state )); do filters) state=() _values -s , filter \ - 'profiles[balance only block groups in given replication profiles]:profile:->profiles' \ - 'usage[balance block groups with usage below percentage]:percentage' \ - 'devid[limit by device ID]:device ID' \ - 'drange[balance block groups overlapping byte range]:range' \ - 'vrange[balance block groups overlapping byte range in virtual address space]:range' \ - 'convert[convert block groups to given profile]:profile:->profiles' \ - 'soft[leave chunks that already have target profile]' && ret=0 + 'profiles[balance only block groups in given replication profiles]:profile:->profiles' \ + 'usage[balance block groups with usage below percentage]:percentage' \ + 'devid[limit by device ID]:device ID' \ + 'drange[balance block groups overlapping byte range]:range' \ + 'vrange[balance block groups overlapping byte range in virtual address space]:range' \ + 'convert[convert block groups to given profile]:profile:->profiles' \ + 'soft[leave chunks that already have target profile]' && ret=0 state=( $state ) ;; profiles) compset -P '*\|' - _values -s ',' profile raid0 raid1 raid10 dup single && ret=0 + _values -s ',' profile raid0 raid1 raid5 raid6 raid10 dup single && ret=0 ;; esac done diff --git a/Completion/Linux/Command/_modutils b/Completion/Linux/Command/_modutils index 39e00b4b0..66e65d32e 100644 --- a/Completion/Linux/Command/_modutils +++ b/Completion/Linux/Command/_modutils @@ -127,7 +127,7 @@ _modutils() { _message -e value 'parameter value' else local params - params=( ${${(M)${(f)"$(_call_program module_parameter modinfo "$words[2]" 2>/dev/null)"}:#parm:*}##parm:[[:space:]]##} ) + params=( ${${(M)${(f)"$(_call_program module_parameter /sbin/modinfo "$words[2]" 2>/dev/null)"}:#parm:*}##parm:[[:space:]]##} ) if [[ $#params -eq 0 ]]; then _message -e parameter "This modules doesn't have parameters" else diff --git a/Completion/Linux/Command/_ss b/Completion/Linux/Command/_ss new file mode 100644 index 000000000..95aa798db --- /dev/null +++ b/Completion/Linux/Command/_ss @@ -0,0 +1,98 @@ +#compdef ss + +local curcontext="$curcontext" suf ret=1 +local -a state line expl pref filt +local -A opt_args +local info="-h -V --help --version" +local sx="state exclude" + +_arguments -C -s \ + "(- *)"{-h,--help}'[show option summary]' \ + "(- *)"{-V,--version}'[show version information]' \ + "($info -n --numeric)"{-n,--numeric}"[don't resolve service names]" \ + "($info -r --resolve)"{-r,--resolve}'[resolve host addresses]' \ + "($info -a --all -l --listening)"{-a,--all}'[display all sockets]' \ + "($info -l --listening -a --all)"{-l,--listening}'[display listening sockets]' \ + "($info -o --options -e --extended)"{-o,--options}'[show timer information]' \ + "($info -e --extended -o --options)"{-e,--extended}'[show detailed information]' \ + "($info -m --memory)"{-m,--memory}'[show socket memory usage]' \ + "($info -p --processes)"{-p,--processes}'[show process using each socket]' \ + "($info -i --info)"{-i,--info}'[show internal TCP information]' \ + "($info -s --summary)"{-s,--summary}'[print summary statistics]' \ + "($info -4 --ipv4 -6 --ipv6)"{-4,--ipv4}'[display only IP version 4 sockets]' \ + "($info -4 --ipv4 -6 --ipv6)"{-6,--ipv6}'[display only IP version 6 sockets]' \ + "($info -0 --packet)"{-0,--packet}'[display PACKET sockets]' \ + "($info -t --tcp)"{-t,--tcp}'[display TCP sockets]' \ + "($info -u --udp)"{-u,--udp}'[display UDP sockets]' \ + "($info -d --dccp)"{-d,--dccp}'[display DCCP sockets]' \ + "($info -w --raw)"{-w,--raw}'[display RAW sockets]' \ + "($info -x --unix)"{-x,--unix}'[display Unix domain sockets]' \ + "($info -f --family)"{-f,--family}'[display sockets of specified type]:family:(unix inet inet6 link netlink)' \ + "($info -A --query --socket)"{-A,--query,--socket}'[specify socket tables to show]: :_values -s , socket\ table all inet tcp udp raw unix packet netlink unix_dgram unix_stream packet_raw packet_dgram' \ + "($info -D)"{-D,--diag=}'[dump raw info to file]:file:_files' \ + "($info -F)"{-F,--filter=}'[read filter information from a file]:file:_files' \ + "($info)*: :->filter" && ret=0 + +if [[ -n $state ]]; then + case $words[CURRENT-1] in + (d|s)port) + _wanted operators expl operator \ + compadd \< \> \= \>= \<= \== \!= eq ge gt lt le ne && ret=0 + ;; + dst|src) + if compset -P unix: || (( $+opt_args[-x] + $+opt_args[--unix] )) || [[ $opt_args[-f] = unix ]]; then + _files -g '*(=)' && ret=0 + elif compset -P nl:; then + if compset -P \*:; then + _pids && ret=0 + else + _message channel + fi + elif compset -P link:; then + compset -P \*: && _message ifindex || _message protocol + else + compset -P 'inet(6|):' + pref=$? + compset -S ':*' || suf="-qS:" + if compset -P \*:; then + _ports && ret=0 + elif compset -P \*/; then + _wanted netmasks expl netmask compadd $suf {1..31} && ret=0 + elif (( pref )); then + _alternative \ + "hosts:host:_hosts $suf" \ + "prefixes:prefix:compadd $suf nl link unix" && ret=0 + else + _hosts $suf && ret=0 + fi + fi + ;; + state|exclude) + _wanted states expl state compadd -M 'm:{a-zA-Z_}={A-Za-z-}' \ + ESTABLISHED SYN-SENT SYN-RECV FIN-WAIT-1 FIN-WAIT-2 TIME-WAIT \ + CLOSED CLOSE-WAIT LAST-ACK LISTEN CLOSING \ + all connected synchronized bucket big && ret=0 + ;; + *) + if [[ $words[CURRENT-2] = (d|s)port ]]; then + compset -P '*:' || pref=(-P :) + _ports $pref + return + else + (( $#line > 1 )) && [[ ${words[CURRENT-1]:Q} != (and|or|\() ]] && + filt=( "($sx)*"{and,or} ) + _values -w -s ' ' -S ' ' filter $filt \ + "*state[sockets in specified state]" \ + "*exclude[sockets not in specified state]" \ + "($sx)*src[local address/port of socket]" \ + "($sx)*dst[peer address/port of socket]" \ + "($sx)*dport[peer port]: :(lt gt ge)" \ + "($sx)*sport[local port]" \ + "($sx)*autobound[socket bound to ephemeral port]" \ + "($sx)*"{not,\(,\)} && ret=0 + fi + ;; + esac +fi + +return ret diff --git a/Completion/Unix/Command/.distfiles b/Completion/Unix/Command/.distfiles index 663c7c495..fe810e1c4 100644 --- a/Completion/Unix/Command/.distfiles +++ b/Completion/Unix/Command/.distfiles @@ -16,6 +16,7 @@ _baz _bison _bittorrent _bogofilter +_bpython _bzip2 _bzr _cal @@ -137,6 +138,7 @@ _mh _mkdir _module _monotone +_moosic _mosh _mount _mpc @@ -155,6 +157,7 @@ _nmap _notmuch _npm _nslookup +_od _pack _patch _pax diff --git a/Completion/Unix/Command/_bpython b/Completion/Unix/Command/_bpython new file mode 100644 index 000000000..c51cc8c3c --- /dev/null +++ b/Completion/Unix/Command/_bpython @@ -0,0 +1,46 @@ +#compdef bpython bpython-gtk bpython-urwid bpython2 bpython2-gtk bpython2-urwid bpython3 bpython3-gtk bpython3-urwid + +local -a all_opts urwid_opts gtk_opts + +all_opts=( + '--config[configuration file]:config file:_files' + '-h --help[show help message]' + '(-i --interactive)'{-i,--interactive}'[drop to bpython after running a file]' + '(-q --quiet)'{-q,--quiet}'[do not flush the output to stdout]' + '(-V --version)'{-V,--version}'[print version]' + '1:script:_files -g "*.u#py(-.)"' + '*:arguments:' +) + +urwid_opts=( + '(-r --reactor)'{-r,--reactor}'[use Twisted reactor instead of the event loop]:reactor:' + '--help-reactors[display list of available Twisted reactors]' + '(-p --plugin)'{-p,--plugin}'[exectue a twistd plugin]:plugin:' + '(-s --server)'{-s,--server}'[run an eval server on the given port]:port:' +) + +gtk_opts=( + '--socket-id[embed bpython]:socket id:' +) + +case "$service" in + bpython|bpython2|bpython3) + _arguments \ + "$all_opts[@]" && return 0 + ;; + + bpython-urwid|bpython2-urwid|bpython3-urwid) + _arguments \ + "$all_opts[@]" \ + "$urwid_opts[@]" && return 0 + ;; + + bpython-gtk|bpython2-gtk|bpython3-gtk) + _arguments \ + "$all_opts[@]" \ + "$gtk_opts[@]" && return 0 + ;; +esac + + +# vim:autoindent expandtab shiftwidth=2 tabstop=2 softtabstop=2 filetype=zsh diff --git a/Completion/Unix/Command/_bzr b/Completion/Unix/Command/_bzr index 23feb6f83..c28c2148e 100644 --- a/Completion/Unix/Command/_bzr +++ b/Completion/Unix/Command/_bzr @@ -25,7 +25,7 @@ curcontext="${curcontext%:*:*}:bzr-$cmd:" (( $+functions[_bzr_unknownFiles] )) || _bzr_unknownFiles() { local fileList - fileList=(${(ps:\0:)"$(bzr ls --null --unknown)"}) + fileList=(${(ps:\0:)"$(bzr ls --null --unknown -R)"}) compadd -af fileList return 0 } @@ -41,7 +41,15 @@ _bzr_unknownRoot() { (( $+functions[_bzr_versionedFiles] )) || _bzr_versionedFiles() { local fileList - fileList=(${(ps:\0:)"$(bzr ls --null --versioned)"}) + fileList=(${(ps:\0:)"$(bzr ls --null --versioned -R)"}) + compadd -af fileList + return 0 +} + +(( $+functions[_bzr_modifiedFiles] )) || +_bzr_modifiedFiles() { + local fileList + fileList=(${(ps:\0:)"$(bzr status . --versioned --short | cut -b 5- | tr '\n' '\0')"}) compadd -af fileList return 0 } @@ -214,7 +222,7 @@ case $cmd in '--unchanged[include unchanged files]' '(-q --quiet -v --verbose)'{--quiet,-q}'[be quiet]' '(-v --verbose -q --quiet)'{--verbose,-v}'[display more information]' - '*:modified files:_bzr_versionedFiles' + '*:modified files:_bzr_modifiedFiles' ) ;; @@ -300,7 +308,7 @@ case $cmd in args+=( '--no-backup[skip generation of backup~ files]' '(-r --revision)'{--revision=,-r}'[revision]:revision:' - '*:file:_bzr_versionedFiles' + '*:file:_bzr_modifiedFiles' ) ;; diff --git a/Completion/Unix/Command/_gcc b/Completion/Unix/Command/_gcc index b14c13334..c6bbabbe9 100644 --- a/Completion/Unix/Command/_gcc +++ b/Completion/Unix/Command/_gcc @@ -1,6 +1,6 @@ #compdef gcc g++ cc c++ llvm-gcc llvm-g++ clang clang++ -value-,LDFLAGS,-default- -value-,CFLAGS,-default- -value-,CPPFLAGS,-default- -local curcontext="$curcontext" state line ret=1 expl args args2 +local curcontext="$curcontext" state line ret=1 expl args args2 march typeset -A opt_args if [[ "$service" = -value-* ]]; then @@ -76,7 +76,7 @@ rs6000|powerpc*) -mpowerpc-gpopt -mno-powerpc-gpopt -mpowerpc-gfxopt -mno-powerpc-gfxopt -mnew-mnemonics -mno-new-mnemonics - -mfull-toc -mminimal-toc -mno-fop-in-toc -mno-sum-in-toc + -mfull-toc -mminimal-toc -mno-fop-in-toc -mno-sum-in-toc -msoft-float -mhard-float -mmultiple -mno-multiple -mstring -mno-string -mbit-align -mno-bit-align -mstrict-align -mno-strict-align -mrelocatable -mno-relocatable @@ -110,34 +110,118 @@ mips*) ) ;; i[3456]86|x86_64) + march="native i386 i486 i586 pentium pentium-mmx pentiumpro i686 pentium2 pentium3 pentium3m pentium-m pentium4 pentium4m prescott nocona core2 corei7 corei7-avx core-avx-i core-avx2 atom k6 k6-2 k6-3 athlon athlon-tbird athlon-4 athlon-xp athlon-mp k8 opteron athlon64 athlon-fx k8-sse3 opteron-sse3 athlon64-sse3 amdfam10 barcelona bdver1 bdver2 bdver3 btver1 btver2 winchip-c6 winchip2 c3 c3-2 geode" args=( - '-mtune=:CPU type:(i386 i486 i586 pentium pentium-mmx i686 pentiumpro pentium2 pentium3 pentium3m pentium-m pentium4 pentium4m prescott nocona k6 k6-2 k6-3 athlon athlon-tbird athlon-4 athlon-xp athlon-mp k8 opteron athlon64 athlon-fx winchip-c6 winchip2 c3 c3-2)' - '-march=:CPU type:(i386 i486 i586 pentium pentium-mmx i686 pentiumpro pentium2 pentium3 pentium3m pentium-m pentium4 pentium4m prescott nocona k6 k6-2 k6-3 athlon athlon-tbird athlon-4 athlon-xp athlon-mp k8 opteron athlon64 athlon-fx winchip-c6 winchip2 c3 c3-2)' - '-mfpmath=:FPU type:(387 sse sse,387)' - '-masm=:asm dialect:(att intel)' - -mieee-fp -mno-ieee-fp -msoft-float - -mno-fp-ret-in-387 -mno-fancy-math-387 - -malign-double -mno-align-double - -m128bit-long-double -m96bit-long-double - -msvr3-shlib -mno-svr3-shlib - -mrtd - '-mregparm=:number of integer argument registers:' - '-mpreferred-stack-boundary=:size of boundary:' - -mmmx -msse -msse2 -msse3 -m3dnow - -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow - -mpush-args -mno-push-args -maccumulate-outgoing-args + '-mtune=-[tune code for CPU type]:CPU type:('"$march"')' + '-march=-[generate instructions for CPU type]:CPU type:('"generic $march"')' -mthreads - -mno-align-stringops -minline-all-stringops - -momit-leaf-frame-pointer - -mtls-direct-seg-refs -mno-tls-direct-seg-refs - -m32 -m64 - -mno-red-zone - '-mcmodel=:memory model:(small kernel medium large)' - -mno-wide-multiply '-mreg-alloc=:default register allocation order:' - '-malign-jumps=: **2 base for jump goal alignment:' - '-malign-loops=: **2 base for loop alignment:' - '-malign-functions=: **2 base for function alignment:' + + # arguments with options + '-mabi=-[Generate code that conforms to the given ABI]:abi:(ms sysv)' + '-maddress-mode=-[Use given address mode]:address mode:(short long)' + '-malign-functions=-[Function starts are aligned to this power of 2]: **2 base for function alignment: ' + '-malign-jumps=-[Jump targets are aligned to this power of 2]: **2 base for jump goal alignment: ' + '-malign-loops=-[Loop code aligned to this power of 2]: **2 base for loop alignment: ' + '-masm=-[Use given assembler dialect]:asm dialect:(att intel)' + '-mbranch-cost=-[Branches are this expensive (1-5, arbitrary units)]:branch cost (1-5): ' + '-mcmodel=-[Use given x86-64 code model]:memory model:(32 small kernel medium large)' + '-mfpmath=-[Generate floating point mathematics using given instruction set]:FPU type:(387 sse sse,387 both)' + '-mincoming-stack-boundary=-[Assume incoming stack aligned to this power of 2]:assumed size of boundary: ' + '-mlarge-data-threshold=-[Data greater than given threshold will go into .ldata section in x86-64 medium model]:threshold: ' + '-mpreferred-stack-boundary=-[Attempt to keep stack aligned to this power of 2]:size of boundary: ' + '-mregparm=-[Number of registers used to pass integer arguments]:number of integer argument registers: ' + '-mstringop-strategy=-[Chose strategy to generate stringop using]:stringop strategy:(byte_loop libcall loop rep_4byte rep_8byte rep_byte unrolled_loop)' + '-mtls-dialect=-[Use given thread-local storage dialect]:TLS dialect:(gnu gnu2)' + '-mveclibabi=-[Vector library ABI to use]:vector library ABI:(acml svml)' + + # arguments without options + '-m3dnow[Support 3DNow! built-in functions]' + '-m8bit-idiv[Expand 32bit/64bit integer divide into 8bit unsigned integer divide with run-time check]' + '-m32[Generate 32bit i386 code]' + '-m64[Generate 64bit x86-64 code]' + '-m96bit-long-double[sizeof(long double) is 12]' + '-m128bit-long-double[sizeof(long double) is 16]' + '-m80387[Use hardware fp]' + '-mabm[Support code generation of Advanced Bit Manipulation (ABM) instructions]' + '-maccumulate-outgoing-args[Reserve space for outgoing arguments in the function prologue]' + '-madx[Support flag-preserving add-carry instructions]' + '-maes[Support AES built-in functions and code generation]' + '-malign-double[Align some doubles on dword boundary]' + '-malign-stringops[Align destination of the string operations]' + '-mandroid[Generate code for the Android platform]' + '-mavx2[Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and AVX2 built-in functions and code generation]' + '-mavx256-split-unaligned-load[Split 32-byte AVX unaligned load]' + '-mavx256-split-unaligned-store[Split 32-byte AVX unaligned store]' + '-mavx[Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2 and AVX built-in functions and code generation]' + '-mbionic[Use Bionic C library]' + '-mbmi2[Support BMI2 built-in functions and code generation]' + '-mbmi[Support BMI built-in functions and code generation]' + '-mcld[Generate cld instruction in the function prologue]' + '-mcrc32[Support code generation of crc32 instruction]' + '-mcx16[Support code generation of cmpxchg16b instruction]' + '-mdispatch-scheduler[Do dispatch scheduling if processor is bdver1 or bdver2 or bdver3 and Haifa scheduling is selected]' + '-mf16c[Support F16C built-in functions and code generation]' + '-mfancy-math-387[Generate sin, cos, sqrt for FPU]' + '-mfentry[Emit profiling counter call at function entry before prologue]' + '-mfma4[Support FMA4 built-in functions and code generation ]' + '-mfma[Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and FMA built-in functions and code generation]' + '-mforce-drap[Always use Dynamic Realigned Argument Pointer (DRAP) to realign stack]' + '-mfp-ret-in-387[Return values of functions in FPU registers]' + '-mfsgsbase[Support FSGSBASE built-in functions and code generation]' + '-mfxsr[Support FXSAVE and FXRSTOR instructions]' + '-mglibc[Use GNU C library]' + '-mhard-float[Use hardware fp]' + '-mhle[Support Hardware Lock Elision prefixes]' + '-mieee-fp[Use IEEE math for fp comparisons]' + '-minline-all-stringops[Inline all known string operations]' + '-minline-stringops-dynamically[Inline memset/memcpy string operations, but perform inline version only for small blocks]' + '-mlong-double-64[Use 64-bit long double]' + '-mlong-double-80[Use 80-bit long double]' + '-mlwp[Support LWP built-in functions and code generation ]' + '-mlzcnt[Support LZCNT built-in function and code generation]' + '-mmmx[Support MMX built-in functions]' + '-mmovbe[Support code generation of movbe instruction]' + '-mms-bitfields[Use native (MS) bitfield layout]' + '-mno-sse4[Do not support SSE4.1 and SSE4.2 built-in functions and code generation]' + '-momit-leaf-frame-pointer[Omit the frame pointer in leaf functions]' + '-mpc32[Set 80387 floating-point precision to 32-bit]' + '-mpc64[Set 80387 floating-point precision to 64-bit]' + '-mpc80[Set 80387 floating-point precision to 80-bit]' + '-mpclmul[Support PCLMUL built-in functions and code generation]' + '-mpopcnt[Support code generation of popcnt instruction]' + '-mprefer-avx128[Use 128-bit AVX instructions instead of 256-bit AVX instructions in the auto-vectorizer]' + '-mprfchw[Support PREFETCHW instruction]' + '-mpush-args[Use push instructions to save outgoing arguments]' + '-mrdrnd[Support RDRND built-in functions and code generation]' + '-mrdseed[Support RDSEED instruction]' + '-mrecip[Generate reciprocals instead of divss and sqrtss]' + '-mred-zone[Use red-zone in the x86-64 code]' + '-mrtd[Alternate calling convention]' + '-mrtm[Support RTM built-in functions and code generation]' + '-msahf[Support code generation of sahf instruction in 64bit x86-64 code]' + '-msoft-float[Do not use hardware fp]' + '-msse2[Support MMX, SSE and SSE2 built-in functions and code generation]' + '-msse2avx[Encode SSE instructions with VEX prefix]' + '-msse3[Support MMX, SSE, SSE2 and SSE3 built-in functions and code generation]' + '-msse4.1[Support MMX, SSE, SSE2, SSE3, SSSE3 and SSE4.1 built-in functions and code generation]' + '-msse4.2[Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 and SSE4.2 built-in functions and code generation]' + '-msse4[Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 and SSE4.2 built-in functions and code generation]' + '-msse4a[Support MMX, SSE, SSE2, SSE3 and SSE4A built-in functions and code generation]' + '-msse[Support MMX and SSE built-in functions and code generation]' + '-msseregparm[Use SSE register passing conventions for SF and DF mode]' + '-mssse3[Support MMX, SSE, SSE2, SSE3 and SSSE3 built-in functions and code generation]' + '-mstack-arg-probe[Enable stack probing]' + '-mstackrealign[Realign stack in prologue]' + '-mtbm[Support TBM built-in functions and code generation]' + '-mtls-direct-seg-refs[Use direct references against %gs when accessing tls data]' + '-muclibc[Use uClibc C library]' + '-mvect8-ret-in-mem[Return 8-byte vectors in memory]' + '-mvzeroupper[Generate vzeroupper instruction before a transfer of control flow out of the function]' + '-mx32[Generate 32bit x86-64 code]' + '-mxop[Support XOP built-in functions and code generation ]' + '-mxsave[Support XSAVE and XRSTOR instructions]' + '-mxsaveopt[Support XSAVEOPT instruction]' ) ;; hppa*) @@ -222,90 +306,635 @@ if [[ "$service" = clang* ]]; then ) fi +local -a languages +languages=( + c c-header cpp-output + c++ c++-header c++-cpp-output + objective-c objective-c-header objective-c-cpp-output + objective-c++ objective-c++-header objective-c++-cpp-output + assembler assembler-with-cpp + ada + f77 f77-cpp-input f95 f95-cpp-input + go + java +) + +# generic options (from --help) +args+=( + -a -C -H -P -s + '-###[print commands to run this compilation]' + '-o:output file:_files -g "^*.(c|h|cc|C|cxx)(-.)"' + '-x[Specify the language of the following input files]:input file language:('"$languages"')' + '+e-:virtual function definitions in classes:((0\:only\ interface 1\:generate\ code))' + '-d-:dump:->dump' + '-g-::debugging information type or level:(0 1 2 3 gdb coff stabs stabs+ dwarf dwarf+ dwarf-2 dwarf-3 dwarf-4 xcoff xcoff+)' + '-O-::optimization level:((0 1 2 3 g\:optimize\ for\ debugging\ experience s\:optimize\ for\ space fast\:optimize\ for\ speed\ disregarding\ exact\ standards\ compliance))' + '*-M-::output dependencies:((M\:only\ user\ header\ files MD\:output\ to\ file G\:treat\ missing\ header\ files\ as\ generated))' + '*-A-:define assertion:' + '*-D-:define macro:' + '*-U-:undefine macro:' + '-E[Preprocess only; do not compile, assemble or link]' + '-S[Compile only; do not assemble or link]' + '-c[Compile and assemble, but do not link]' + '*-Wp,-:preprocessor option:' + '*-Wl,-:linker option:' + '*-Xpreprocessor:preprocessor option:' + '*-Xlinker:linker option:' + '*-Xassembler:assembler option:' + '*-u:pretend symbol to be undefined:' + '*-Wa,-:assembler option:' + '*-l:library:->library' + '*-L-:library search path:_files -/' + '*-I-:header file search path:_files -/' + '-B-[Add <prefix> to the compiler'\''s search paths]:executable prefix:_files -/' + '-b:target machine:' + '-V:specify compiler version:' + '--version[Display compiler version information]' + '-print-file-name=-[Display the full path to library <library>]:library:->library' + '-print-prog-name=-[Display the full path to compiler component <program>]:program:' + '*-specs=-[Override built-in specs with the contents of <file>]:file:_files' + '-std=-[Assume that the input sources are for <standard>]:standard:(c90 c89 c99 c11 gnu90 gnu89 gnu99 gnu11 c++98 c++03 gnu++98 gnu++03 c++11 gnu++11 c++1y gnu++1y)' + '*-include:include file:_files -g \*.h\(-.\)' + '*-imacros:macro input file:_files -g \*.h\(-.\)' + '*-idirafter:second include path directory:_files -/' + '*-iprefix:prefix:_files' + '*-iwithprefix:second include path directory:_files -/' + '*-iwithprefixbefore:main include path directory:_files -/' + '*-isystem:second include path directory (system):_files -/' + '--sysroot=-[Use <directory> as the root directory for headers and libraries]:directory:_files -/' + '-pass-exit-codes[Exit with highest error code from a phase]' + '*--help=-[Display this information]:class:->help' + '--target-help[Display target specific command line options]' + '-dumpspecs[Display all of the built in spec strings]' + '-dumpversion[Display the version of the compiler]' + '-dumpmachine[Display the compiler'\''s target processor]' + '-print-search-dirs[Display the directories in the compiler'\''s search path]' + '-print-libgcc-file-name[Display the name of the compiler'\''s companion library]' + '-print-multiarch[Display the target'\''s normalized GNU triplet, used as a component in the library path]' + '-print-multi-directory[Display the root directory for versions of libgcc]' + '-print-multi-lib[Display the mapping between command line options and multiple library search directories]' + '-print-multi-os-directory[Display the relative path to OS libraries]' + '-print-sysroot[Display the target libraries directory]' + '-print-sysroot-headers-suffix[Display the sysroot suffix used to find headers]' + '-save-temps[Do not delete intermediate files]' + '-no-canonical-prefixes[Do not canonicalize paths when building relative prefixes to other gcc components]' + '-pipe[Use pipes rather than intermediate files]' + '-pie[Create a position independent executable]' + '-shared[Create a shared library]' + '-time[Time the execution of each subprocess]' +) + +# warnings (from --help=warnings), note some -W options are listed by --help=common instead +args+=( +# --help=warnings,^joined + '-W[This switch is deprecated; use -Wextra instead]' + '-Wabi-tag[Warn if a subobject has an abi_tag attribute that the complete object type does not have]' + '-Wabi[Warn about things that will change when compiling with an ABI-compliant compiler]' + '-Waddress[Warn about suspicious uses of memory addresses]' + '-Waggregate-return[Warn about returning structures, unions or arrays]' + '-Waggressive-loop-optimizations[Warn if a loop with constant number of iterations triggers undefined behavior]' + '-Waliasing[Warn about possible aliasing of dummy arguments]' + '-Walign-commons[Warn about alignment of COMMON blocks]' + '-Wall[Enable most warning messages]' + '-Wampersand[Warn about missing ampersand in continued character constants]' + '-Warray-bounds[Warn if an array is accessed out of bounds]' + '-Warray-temporaries[Warn about creation of array temporaries]' + '-Wassign-intercept[Warn whenever an Objective-C assignment is being intercepted by the garbage collector]' + '-Wattributes[Warn about inappropriate attribute usage]' + '-Wbad-function-cast[Warn about casting functions to incompatible types]' + '-Wbuiltin-macro-redefined[Warn when a built-in preprocessor macro is undefined or redefined]' + '-Wc++-compat[Warn about C constructs that are not in the common subset of C and C++]' + '-Wc++0x-compat[Deprecated in favor of -Wc++11-compat]' + '-Wc++11-compat[Warn about C++ constructs whose meaning differs between ISO C++ 1998 and ISO C++ 2011]' + '-Wc-binding-type[Warn if the type of a variable might be not interoperable with C]' + '-Wcast-align[Warn about pointer casts which increase alignment]' + '-Wcast-qual[Warn about casts which discard qualifiers]' + '-Wchar-subscripts[Warn about subscripts whose type is "char"]' + '-Wcharacter-truncation[Warn about truncated character expressions]' + '-Wclobbered[Warn about variables that might be changed by "longjmp" or "vfork"]' + '-Wcomment[Warn about possibly nested block comments, and C++ comments spanning more than one physical line]' + '-Wcomments[Synonym for -Wcomment]' + '-Wcompare-reals[Warn about equality comparisons involving REAL or COMPLEX expressions]' + '-Wconversion-extra[Warn about most implicit conversions]' + '-Wconversion-null[Warn for converting NULL from/to a non-pointer type]' + '-Wconversion[Warn for implicit type conversions that may change a value]' + '-Wcoverage-mismatch[Warn in case profiles in -fprofile-use do not match]' + '-Wcpp[Warn when a #warning directive is encountered]' + '-Wctor-dtor-privacy[Warn when all constructors and destructors are private]' + '-Wdeclaration-after-statement[Warn when a declaration is found after a statement]' + '-Wdelete-non-virtual-dtor[Warn about deleting polymorphic objects with non- virtual destructors]' + '-Wdeprecated-declarations[Warn about uses of __attribute__((deprecated)) declarations]' + '-Wdeprecated[Warn if a deprecated compiler feature, class, method, or field is used]' + '-Wdisabled-optimization[Warn when an optimization pass is disabled]' + '-Wdiv-by-zero[Warn about compile-time integer division by zero]' + '-Wdouble-promotion[Warn about implicit conversions from "float" to "double"]' + '-Weffc++[Warn about violations of Effective C++ style rules]' + '-Wempty-body[Warn about an empty body in an if or else statement]' + '-Wendif-labels[Warn about stray tokens after #elif and #endif]' + '-Wenum-compare[Warn about comparison of different enum types]' +#this still exists but makes completing -Werror= less convenient + #'-Werror-implicit-function-declaration[This switch is deprecated; use -Werror=implicit-function-declaration instead]' + '-Wextra[Print extra (possibly unwanted) warnings]' + '-Wfloat-equal[Warn if testing floating point numbers for equality]' + '-Wformat-contains-nul[Warn about format strings that contain NUL bytes]' + '-Wformat-extra-args[Warn if passing too many arguments to a function for its format string]' + '-Wformat-nonliteral[Warn about format strings that are not literals]' + '-Wformat-security[Warn about possible security problems with format functions]' + '-Wformat-y2k[Warn about strftime formats yielding 2-digit years]' + '-Wformat-zero-length[Warn about zero-length formats]' + '-Wformat[Warn about printf/scanf/strftime/strfmon format string anomalies]' + '-Wfree-nonheap-object[Warn when attempting to free a non-heap object]' + '-Wfunction-elimination[Warn about function call elimination]' + '-Wignored-qualifiers[Warn whenever type qualifiers are ignored]' + '-Wimplicit-function-declaration[Warn about implicit function declarations]' + '-Wimplicit-int[Warn when a declaration does not specify a type]' + '-Wimplicit-interface[Warn about calls with implicit interface]' + '-Wimplicit-procedure[Warn about called procedures not explicitly declared]' + '-Wimplicit[Warn about implicit declarations]' + '-Winherited-variadic-ctor[Warn about C++11 inheriting constructors when the base has a variadic constructor]' + '-Winit-self[Warn about variables which are initialized to themselves]' + '-Winline[Warn when an inlined function cannot be inlined]' + '-Wint-to-pointer-cast[Warn when there is a cast to a pointer from an integer of a different size]' + '-Wintrinsic-shadow[Warn if a user-procedure has the same name as an intrinsic]' + '-Wintrinsics-std[Warn on intrinsics not part of the selected standard]' + '-Winvalid-memory-model[Warn when an atomic memory model parameter is known to be outside the valid range]' + '-Winvalid-offsetof[Warn about invalid uses of the "offsetof" macro]' + '-Winvalid-pch[Warn about PCH files that are found but not used]' + '-Wjump-misses-init[Warn when a jump misses a variable initialization]' + '-Wline-truncation[Warn about truncated source lines]' + '-Wliteral-suffix[Warn when a string or character literal is followed by a ud-suffix which does not begin with an underscore]' + '-Wlogical-op[Warn when a logical operator is suspiciously always evaluating to true or false]' + '-Wlong-long[Do not warn about using "long long" when -pedantic]' + '-Wmain[Warn about suspicious declarations of "main"]' + '-Wmaybe-uninitialized[Warn about maybe uninitialized automatic variables]' + '-Wmissing-braces[Warn about possibly missing braces around initializers]' + '-Wmissing-declarations[Warn about global functions without previous declarations]' + '-Wmissing-field-initializers[Warn about missing fields in struct initializers]' + '-Wmissing-include-dirs[Warn about user-specified include directories that do not exist]' + '-Wmissing-parameter-type[Warn about function parameters declared without a type specifier in K&R-style functions]' + '-Wmissing-prototypes[Warn about global functions without prototypes]' + '-Wmudflap[Warn about constructs not instrumented by -fmudflap]' + '-Wmultichar[Warn about use of multi-character character constants]' + '-Wnarrowing[Warn about narrowing conversions within { } that are ill-formed in C++11]' + '-Wnested-externs[Warn about "extern" declarations not at file scope]' + '-Wnoexcept[Warn when a noexcept expression evaluates to false even though the expression can'\''t actually throw]' + '-Wnon-template-friend[Warn when non-templatized friend functions are declared within a template]' + '-Wnon-virtual-dtor[Warn about non-virtual destructors]' + '-Wnonnull[Warn about NULL being passed to argument slots marked as requiring non-NULL]' + '-Wold-style-cast[Warn if a C-style cast is used in a program]' + '-Wold-style-declaration[Warn for obsolescent usage in a declaration]' + '-Wold-style-definition[Warn if an old-style parameter definition is used]' + '-Woverflow[Warn about overflow in arithmetic expressions]' + '-Woverlength-strings[Warn if a string is longer than the maximum portable length specified by the standard]' + '-Woverloaded-virtual[Warn about overloaded virtual function names]' + '-Woverride-init[Warn about overriding initializers without side effects]' + '-Wpacked-bitfield-compat[Warn about packed bit-fields whose offset changed in GCC 4.4]' + '-Wpacked[Warn when the packed attribute has no effect on struct layout]' + '-Wpadded[Warn when padding is required to align structure members]' + '-Wparentheses[Warn about possibly missing parentheses]' + '-Wpedantic[Issue warnings needed for strict compliance to the standard]' + '-Wpmf-conversions[Warn when converting the type of pointers to member functions]' + '-Wpointer-arith[Warn about function pointer arithmetic]' + '-Wpointer-sign[Warn when a pointer differs in signedness in an assignment]' + '-Wpointer-to-int-cast[Warn when a pointer is cast to an integer of a different size]' + '-Wpoison-system-directories[Warn for -I and -L options using system directories if cross compiling]' + '-Wpragmas[Warn about misuses of pragmas]' + '-Wproperty-assign-default[Warn if a property for an Objective-C object has no assign semantics specified]' + '-Wprotocol[Warn if inherited methods are unimplemented]' + '-Wreal-q-constant[Warn about real-literal-constants with '\''q'\'' exponent-letter]' + '-Wrealloc-lhs-all[Warn when a left-hand-side variable is reallocated]' + '-Wrealloc-lhs[Warn when a left-hand-side array variable is reallocated]' + '-Wredundant-decls[Warn about multiple declarations of the same object]' + '-Wreorder[Warn when the compiler reorders code]' + '-Wreturn-local-addr[Warn about returning a pointer/reference to a local or temporary variable]' + '-Wreturn-type[Warn whenever a function'\''s return type defaults to "int" (C), or about inconsistent return types (C++)]' + '-Wselector[Warn if a selector has multiple methods]' + '-Wsequence-point[Warn about possible violations of sequence point rules]' + '-Wshadow[Warn when one local variable shadows another]' + '-Wsign-compare[Warn about signed-unsigned comparisons]' + '-Wsign-promo[Warn when overload promotes from unsigned to signed]' + '-Wstack-protector[Warn when not issuing stack smashing protection for some reason]' + '-Wstrict-null-sentinel[Warn about uncasted NULL used as sentinel]' + '-Wstrict-prototypes[Warn about unprototyped function declarations]' + '-Wstrict-selector-match[Warn if type signatures of candidate methods do not match exactly]' + '-Wsuggest-attribute=-[Warn about functions which might be candidates for __attribute__((const))]:const: ' + '-Wsurprising[Warn about "suspicious" constructs]' + '-Wswitch-default[Warn about enumerated switches missing a "default-" statement]' + '-Wswitch-enum[Warn about all enumerated switches missing a specific case]' + '-Wswitch[Warn about enumerated switches, with no default, missing a case]' + '-Wsync-nand[Warn when __sync_fetch_and_nand and __sync_nand_and_fetch built-in functions are used]' + '-Wsynth[Deprecated. This switch has no effect]' + '-Wsystem-headers[Do not suppress warnings from system headers]' + '-Wtabs[Permit nonconforming uses of the tab character]' + '-Wtarget-lifetime[Warn if the pointer in a pointer assignment might outlive its target]' + '-Wtraditional-conversion[Warn of prototypes causing type conversions different from what would happen in the absence of prototype]' + '-Wtraditional[Warn about features not present in traditional C]' + '-Wtrampolines[Warn whenever a trampoline is generated]' + '-Wtrigraphs[Warn if trigraphs are encountered that might affect the meaning of the program]' + '-Wtype-limits[Warn if a comparison is always true or always false due to the limited range of the data type]' + '-Wundeclared-selector[Warn about @selector()s without previously declared methods]' + '-Wundef[Warn if an undefined macro is used in an #if directive]' + '-Wunderflow[Warn about underflow of numerical constant expressions]' + '-Wuninitialized[Warn about uninitialized automatic variables]' + '-Wunknown-pragmas[Warn about unrecognized pragmas]' + '-Wunsafe-loop-optimizations[Warn if the loop cannot be optimized due to nontrivial assumptions]' + '-Wunsuffixed-float-constants[Warn about unsuffixed float constants]' + '-Wunused-but-set-parameter[Warn when a function parameter is only set, otherwise unused]' + '-Wunused-but-set-variable[Warn when a variable is only set, otherwise unused]' + '-Wunused-dummy-argument[Warn about unused dummy arguments]' + '-Wunused-function[Warn when a function is unused]' + '-Wunused-label[Warn when a label is unused]' + '-Wunused-local-typedefs[Warn when typedefs locally defined in a function are not used]' + '-Wunused-macros[Warn about macros defined in the main file that are not used]' + '-Wunused-parameter[Warn when a function parameter is unused]' + '-Wunused-result[Warn if a caller of a function, marked with attribute warn_unused_result, does not use its return value]' + '-Wunused-value[Warn when an expression value is unused]' + '-Wunused-variable[Warn when a variable is unused]' + '-Wunused[Enable all -Wunused- warnings]' + '-Wuseless-cast[Warn about useless casts]' + '-Wvarargs[Warn about questionable usage of the macros used to retrieve variable arguments]' + '-Wvariadic-macros[Warn about using variadic macros]' + '-Wvector-operation-performance[Warn when a vector operation is compiled outside the SIMD]' + '-Wvirtual-move-assign[Warn if a virtual base has a non-trivial move assignment operator]' + '-Wvla[Warn if a variable length array is used]' + '-Wvolatile-register-var[Warn when a register variable is declared volatile]' + '-Wwrite-strings[In C++, nonzero means warn about deprecated conversion from string literals to '\''char *'\''. In C, similar warning, except that the conversion is of course not deprecated by the ISO C standard]' + '-Wzero-as-null-pointer-constant[Warn when a literal '\''0'\'' is used as null pointer]' + '-frequire-return-statement[Functions which return values must end with return statements]' +# --help=warnings,joined + '-Wlarger-than=-[Warn if an object is larger than <number> bytes]:number: ' + '-Wnormalized=-[Warn about non-normalised Unicode strings]:normalization:((id\:allow\ some\ non-nfc\ characters\ that\ are\ valid\ identifiers nfc\:only\ allow\ NFC nfkc\:only\ allow\ NFKC none\:allow\ any\ normalization)): ' + '-Wstack-usage=-[Warn if stack usage might be larger than specified amount]:stack usage: ' + '-Wstrict-aliasing=-[Warn about code which might break strict aliasing rules]:level of checking (higher is more accurate):(1 2 3)' + '-Wstrict-overflow=-[Warn about optimizations that assume that signed overflow is undefined]:level of checking (higher finds more cases):(1 2 3 4 5)' +# -W options from --help=common + '-Werror=-[Treat specified warning as error (or all if none specified)]:warning:->werror' + '-Wfatal-errors[Exit on the first error occurred]' + '-Wframe-larger-than=-[Warn if a function'\'\''s stack frame requires more than <number> bytes]:number: ' +) +# optimizers (from --help=optimizers), except for -O +args+=( +# --help=optimizers,^joined + '-faggressive-loop-optimizations[Aggressively optimize loops using language constraints]' + '-falign-functions=-[Align the start of functions]:function alignment' + '-falign-jumps=-[Align labels which are only reached by jumping]:jump alignment' + '-falign-labels=-[Align all labels]:label alignment' + '-falign-loops=-[Align the start of loops]:loop alignment' + '-fasynchronous-unwind-tables[Generate unwind tables that are exact at each instruction boundary]' + '-fbranch-count-reg[Replace add, compare, branch with branch on count register]' + '-fbranch-probabilities[Use profiling information for branch probabilities]' + '-fbranch-target-load-optimize2[Perform branch target load optimization after prologue / epilogue threading]' + '-fbranch-target-load-optimize[Perform branch target load optimization before prologue / epilogue threading]' + '-fbtr-bb-exclusive[Restrict target load migration not to re-use registers in any basic block]' + '-fcaller-saves[Save registers around function calls]' + '-fcombine-stack-adjustments[Looks for opportunities to reduce stack adjustments and stack references]' + '-fcommon[Do not put uninitialized globals in the common section]' + '-fcompare-elim[Perform comparison elimination after register allocation has finished]' + '-fconserve-stack[Do not perform optimizations increasing noticeably stack usage]' + '-fcprop-registers[Perform a register copy-propagation optimization pass]' + '-fcrossjumping[Perform cross-jumping optimization]' + '-fcse-follow-jumps[When running CSE, follow jumps to their targets]' + '-fcx-fortran-rules[Complex multiplication and division follow Fortran rules]' + '-fcx-limited-range[Omit range reduction step when performing complex division]' + '-fdata-sections[Place data items into their own section]' + '-fdce[Use the RTL dead code elimination pass]' + '-fdefer-pop[Defer popping functions args from stack until later]' + '-fdelayed-branch[Attempt to fill delay slots of branch instructions]' + '-fdelete-null-pointer-checks[Delete useless null pointer checks]' + '-fdevirtualize[Try to convert virtual calls to direct ones]' + '-fdse[Use the RTL dead store elimination pass]' + '-fearly-inlining[Perform early inlining]' + '-fexceptions[Enable exception handling]' + '-fexpensive-optimizations[Perform a number of minor, expensive optimizations]' + '-ffinite-math-only[Assume no NaNs or infinities are generated]' + '-ffloat-store[Don'\''t allocate floats and doubles in extended- precision registers]' + '-fforward-propagate[Perform a forward propagation pass on RTL]' + '-fgcse-after-reload[Perform global common subexpression elimination after register allocation has finished]' + '-fgcse-las[Perform redundant load after store elimination in global common subexpression elimination]' + '-fgcse-lm[Perform enhanced load motion during global common subexpression elimination]' + '-fgcse-sm[Perform store motion after global common subexpression elimination]' + '-fgcse[Perform global common subexpression elimination]' + '-fgraphite-identity[Enable Graphite Identity transformation]' + '-fguess-branch-probability[Enable guessing of branch probabilities]' + '-fhandle-exceptions[This switch lacks documentation]' + '-fhoist-adjacent-loads[Enable hoisting adjacent loads to encourage generating conditional move instructions]' + '-fif-conversion2[Perform conversion of conditional jumps to conditional execution]' + '-fif-conversion[Perform conversion of conditional jumps to branchless equivalents]' + '-finline-atomics[Inline __atomic operations when a lock free instruction sequence is available]' + '-finline-functions-called-once[Integrate functions only required by their single caller]' + '-finline-functions[Integrate functions not declared "inline" into their callers when profitable]' + '-finline-small-functions[Integrate functions into their callers when code size is known not to grow]' + '-finline[Enable inlining of function declared "inline", disabling disables all inlining]' + '-fipa-cp-clone[Perform cloning to make Interprocedural constant propagation stronger]' + '-fipa-cp[Perform Interprocedural constant propagation]' + '-fipa-profile[Perform interprocedural profile propagation]' + '-fipa-pta[Perform interprocedural points-to analysis]' + '-fipa-pure-const[Discover pure and const functions]' + '-fipa-reference[Discover readonly and non addressable static variables]' + '-fipa-sra[Perform interprocedural reduction of aggregates]' + '-fira-hoist-pressure[Use IRA based register pressure calculation in RTL hoist optimizations]' + '-fivopts[Optimize induction variables on trees]' + '-fjump-tables[Use jump tables for sufficiently large switch statements]' + '-floop-block[Enable Loop Blocking transformation]' + '-floop-interchange[Enable Loop Interchange transformation]' + '-floop-nest-optimize[Enable the ISL based loop nest optimizer]' + '-floop-parallelize-all[Mark all loops as parallel]' + '-floop-strip-mine[Enable Loop Strip Mining transformation]' + '-fmath-errno[Set errno after built-in math functions]' + '-fmerge-all-constants[Attempt to merge identical constants and constant variables]' + '-fmerge-constants[Attempt to merge identical constants across compilation units]' + '-fmodulo-sched[Perform SMS based modulo scheduling before the first scheduling pass]' + '-fmove-loop-invariants[Move loop invariant computations out of loops]' + '-fno-threadsafe-statics[Do not generate thread-safe code for initializing local statics]' + '-fnon-call-exceptions[Support synchronous non-call exceptions]' + '-fnothrow-opt[Treat a throw() exception specification as noexcept to improve code size]' + '-fomit-frame-pointer[When possible do not generate stack frames]' + '-fopt-info[Enable all optimization info dumps on stderr]' + '-foptimize-register-move[Do the full register move optimization pass]' + '-foptimize-sibling-calls[Optimize sibling and tail recursive calls]' + '-foptimize-strlen[Enable string length optimizations on trees]' + '-fpack-struct[Pack structure members together without holes]' + '-fpeel-loops[Perform loop peeling]' + '-fpeephole2[Enable an RTL peephole pass before sched2]' + '-fpeephole[Enable machine specific peephole optimizations]' + '-fpredictive-commoning[Run predictive commoning optimization]' + '-fprefetch-loop-arrays[Generate prefetch instructions, if available, for arrays in loops]' + '-freg-struct-return[Return small aggregates in registers]' + '-fregmove[Enables a register move optimization]' + '-frename-registers[Perform a register renaming optimization pass]' + '-freorder-blocks-and-partition[Reorder basic blocks and partition into hot and cold sections]' + '-freorder-blocks[Reorder basic blocks to improve code placement]' + '-freorder-functions[Reorder functions to improve code placement]' + '-frerun-cse-after-loop[Add a common subexpression elimination pass after loop optimizations]' + '-freschedule-modulo-scheduled-loops[Enable/Disable the traditional scheduling in loops that already passed modulo scheduling]' + '-frounding-math[Disable optimizations that assume default FP rounding behavior]' + '-frtti[Generate run time type descriptor information]' + '-fsched-critical-path-heuristic[Enable the critical path heuristic in the scheduler]' + '-fsched-dep-count-heuristic[Enable the dependent count heuristic in the scheduler]' + '-fsched-group-heuristic[Enable the group heuristic in the scheduler]' + '-fsched-interblock[Enable scheduling across basic blocks]' + '-fsched-last-insn-heuristic[Enable the last instruction heuristic in the scheduler]' + '-fsched-pressure[Enable register pressure sensitive insn scheduling]' + '-fsched-rank-heuristic[Enable the rank heuristic in the scheduler]' + '-fsched-spec-insn-heuristic[Enable the speculative instruction heuristic in the scheduler]' + '-fsched-spec-load-dangerous[Allow speculative motion of more loads]' + '-fsched-spec-load[Allow speculative motion of some loads]' + '-fsched-spec[Allow speculative motion of non-loads]' + '-fsched2-use-superblocks[If scheduling post reload, do superblock scheduling]' + '-fschedule-insns2[Reschedule instructions after register allocation]' + '-fschedule-insns[Reschedule instructions before register allocation]' + '-fsection-anchors[Access data in the same section from shared anchor points]' + '-fsel-sched-pipelining-outer-loops[Perform software pipelining of outer loops during selective scheduling]' + '-fsel-sched-pipelining[Perform software pipelining of inner loops during selective scheduling]' + '-fsel-sched-reschedule-pipelined[Reschedule pipelined regions without pipelining]' + '-fselective-scheduling2[Run selective scheduling after reload]' + '-fselective-scheduling[Schedule instructions using selective scheduling algorithm]' + '-fshort-double[Use the same size for double as for float]' + '-fshort-enums[Use the narrowest integer type possible for enumeration types]' + '-fshort-wchar[Force the underlying type for "wchar_t" to be "unsigned short"]' + '-fshrink-wrap[Emit function prologues only before parts of the function that need it, rather than at the top of the function]' + '-fsignaling-nans[Disable optimizations observable by IEEE signaling NaNs]' + '-fsigned-zeros[Disable floating point optimizations that ignore the IEEE signedness of zero]' + '-fsingle-precision-constant[Convert floating point constants to single precision constants]' + '-fsplit-ivs-in-unroller[Split lifetimes of induction variables when loops are unrolled]' + '-fsplit-wide-types[Split wide types into independent registers]' + '-fstrict-aliasing[Assume strict aliasing rules apply]' + '-fstrict-enums[Assume that values of enumeration type are always within the minimum range of that type]' + '-fthread-jumps[Perform jump threading optimizations]' + '-ftoplevel-reorder[Reorder top level functions, variables, and asms]' + '-ftrapping-math[Assume floating-point operations can trap]' + '-ftrapv[Trap for signed overflow in addition, subtraction and multiplication]' + '-ftree-bit-ccp[Enable SSA-BIT-CCP optimization on trees]' + '-ftree-builtin-call-dce[Enable conditional dead code elimination for builtin calls]' + '-ftree-ccp[Enable SSA-CCP optimization on trees]' + '-ftree-ch[Enable loop header copying on trees]' + '-ftree-coalesce-inlined-vars[Enable coalescing of copy-related user variables that are inlined]' + '-ftree-coalesce-vars[Enable coalescing of all copy-related user variables]' + '-ftree-copy-prop[Enable copy propagation on trees]' + '-ftree-copyrename[Replace SSA temporaries with better names in copies]' + '-ftree-cselim[Transform condition stores into unconditional ones]' + '-ftree-dce[Enable SSA dead code elimination optimization on trees]' + '-ftree-dominator-opts[Enable dominator optimizations]' + '-ftree-dse[Enable dead store elimination]' + '-ftree-forwprop[Enable forward propagation on trees]' + '-ftree-fre[Enable Full Redundancy Elimination (FRE) on trees]' + '-ftree-loop-distribute-patterns[Enable loop distribution for patterns transformed into a library call]' + '-ftree-loop-distribution[Enable loop distribution on trees]' + '-ftree-loop-if-convert-stores[Also if-convert conditional jumps containing memory writes]' + '-ftree-loop-if-convert[Convert conditional jumps in innermost loops to branchless equivalents]' + '-ftree-loop-im[Enable loop invariant motion on trees]' + '-ftree-loop-ivcanon[Create canonical induction variables in loops]' + '-ftree-loop-optimize[Enable loop optimizations on tree level]' + '-ftree-lrs[Perform live range splitting during the SSA- >normal pass]' + '-ftree-partial-pre[In SSA-PRE optimization on trees, enable partial- partial redundancy elimination]' + '-ftree-phiprop[Enable hoisting loads from conditional pointers]' + '-ftree-pre[Enable SSA-PRE optimization on trees]' + '-ftree-pta[Perform function-local points-to analysis on trees]' + '-ftree-reassoc[Enable reassociation on tree level]' + '-ftree-scev-cprop[Enable copy propagation of scalar-evolution information]' + '-ftree-sink[Enable SSA code sinking on trees]' + '-ftree-slp-vectorize[Enable basic block vectorization (SLP) on trees]' + '-ftree-slsr[Perform straight-line strength reduction]' + '-ftree-sra[Perform scalar replacement of aggregates]' + '-ftree-switch-conversion[Perform conversions of switch initializations]' + '-ftree-tail-merge[Enable tail merging on trees]' + '-ftree-ter[Replace temporary expressions in the SSA->normal pass]' + '-ftree-vect-loop-version[Enable loop versioning when doing loop vectorization on trees]' + '-ftree-vectorize[Enable loop vectorization on trees]' + '-ftree-vrp[Perform Value Range Propagation on trees]' + '-funit-at-a-time[Compile whole compilation unit at a time]' + '-funroll-all-loops[Perform loop unrolling for all loops]' + '-funroll-loops[Perform loop unrolling when iteration count is known]' + '-funsafe-loop-optimizations[Allow loop optimizations to assume that the loops behave in normal way]' + '-funsafe-math-optimizations[Allow math optimizations that may violate IEEE or ISO standards]' + '-funswitch-loops[Perform loop unswitching]' + '-funwind-tables[Just generate unwind tables for exception handling]' + '-fvar-tracking-assignments-toggle[Toggle -fvar-tracking-assignments]' + '-fvar-tracking-assignments[Perform variable tracking by annotating assignments]' + '-fvar-tracking-uninit[Perform variable tracking and also tag variables that are uninitialized]' + '-fvar-tracking[Perform variable tracking]' + '-fvariable-expansion-in-unroller[Apply variable expansion when loops are unrolled]' + '-fvect-cost-model[Enable use of cost model in vectorization]' + '-fvpt[Use expression value profiles in optimizations]' + '-fweb[Construct webs and split unrelated uses of single variable]' + '-fwhole-program[Perform whole program optimizations]' + '-fwrapv[Assume signed arithmetic overflow wraps around]' +# --help=optimizers,joined + '-fpack-struct=-[Set initial maximum structure member alignment]:alignment: ' +) -_arguments -C -M 'L:|-{fW}no-=-{fW} r:|[_-]=* r:|=*' \ +# other common options, gcc --help=warnings --help=optimizers --help=common|sed 1,/language-independent/d +args+=( +# | grep -v :: + '--debug[This switch lacks documentation]' + '--dump[This switch lacks documentation]' + '--dumpbase[This switch lacks documentation]' + '--dumpdir[This switch lacks documentation]' + '--help[Display this information]' + '--no-warnings[This switch lacks documentation]' + '--optimize[This switch lacks documentation]' + '--output[This switch lacks documentation]' + '--param[Set parameter <param> to value. See manpage for a complete list of parameters]:name=value' + '--pedantic-errors[This switch lacks documentation]' + '--pedantic[This switch lacks documentation]' + '--profile[This switch lacks documentation]' + '--verbose[This switch lacks documentation]' + '--version[This switch lacks documentation]' + '-aux-info[Emit declaration information into <file>]:file:_files' + '-dumpbase[Set the file basename to be used for dumps]' + '-dumpdir[Set the directory name to be used for dumps]' + '-fPIC[Generate position-independent code if possible (large mode)]' + '-fPIE[Generate position-independent code for executables if possible (large mode)]' + '-fassociative-math[Allow optimization for floating-point arithmetic which may change the result of the operation due to rounding]' + '-fauto-inc-dec[Generate auto-inc/dec instructions]' + '-fbounds-check[Generate code to check bounds before indexing arrays]' + '-fcall-saved--[Mark <register> as being preserved across functions]:register' + '-fcall-used--[Mark <register> as being corrupted by function calls]:register' + '-fcheck-data-deps[Compare the results of several data dependence analyzers]' + '-fcompare-debug-second[Run only the second compilation of -fcompare-debug]' + '-fcompare-debug=[Compile with and without e.g. -gtoggle, and compare the final-insns dump]:opts:' #TODO: complete gcc options here + '-fdbg-cnt-list[List all available debugging counters with their limits and counts]' + '-fdbg-cnt=[,<counter>-<limit>,...) Set the debug counter limit]:counter\:limit,...: ' #TODO: gcc -fdbg-cnt-list -x c /dev/null -o /dev/null -c + '-fdebug-types-section[Output .debug_types section when using DWARF v4 debuginfo]' + '-fdelete-dead-exceptions[Delete dead instructions that may throw exceptions]' + '-fdiagnostics-show-caret[Show the source line with a caret indicating the column]' + '-fdiagnostics-show-location=-[How often to emit source location at the beginning of line-wrapped diagnostics]:source location:(once every-line)' + '-fdiagnostics-show-option[Amend appropriate diagnostic messages with the command line option that controls them]' + #not meant for end users + #'-fdisable--pass=[disables an optimization pass]:range1+range2: ' + #'-fdisable-[disables an optimization pass]' + #'-fenable--pass=[enables an optimization pass]:range1+range2: ' + #'-fenable-[enables an optimization pass]' + #'-fdump-<type>[Dump various compiler internals to a file]' + '-fdump-final-insns=-[Dump to filename the insns at the end of translation]:filename:_files' + '-fdump-go-spec=-[Write all declarations to file as Go code]:filename:_files' + '-fdump-noaddr[Suppress output of addresses in debugging dumps]' + '-fdump-passes[Dump optimization passes]' + '-fdump-unnumbered-links[Suppress output of previous and next insn numbers in debugging dumps]' + '-fdump-unnumbered[Suppress output of instruction numbers, line number notes and addresses in debugging dumps]' + '-fdwarf2-cfi-asm[Enable CFI tables via GAS assembler directives]' + '-feliminate-dwarf2-dups[Perform DWARF2 duplicate elimination]' + '-feliminate-unused-debug-symbols[Perform unused type elimination in debug info]' + '-feliminate-unused-debug-types[Perform unused type elimination in debug info]' + '-femit-class-debug-always[Do not suppress C++ class debug information]' + '-fexcess-precision=-[Specify handling of excess floating-point precision]:precision handling:(fast standard)' + '-ffast-math[Sets -fno-math-errno, -funsafe-math-optimizations, -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans and -fcx-limited-range]' + '-ffat-lto-objects[Output lto objects containing both the intermediate language and binary output]' + '-ffixed--[Mark <register> as being unavailable to the compiler]:register' + '-ffunction-cse[Allow function addresses to be held in registers]' + '-ffunction-sections[Place each function into its own section]' + '-fgnu-tm[Enable support for GNU transactional memory]' + '-fgraphite[Enable in and out of Graphite representation]' + '-fident[Process #ident directives]' + '-findirect-inlining[Perform indirect inlining]' + '-finhibit-size-directive[Do not generate .size directives]' + '-finline-limit=[Limit the size of inlined functions to <number>]:number: ' + '-finstrument-functions[Instrument function entry and exit with profiling calls]' + '-fira-loop-pressure[Use IRA based register pressure calculation in RTL loop optimizations]' + '-fira-share-save-slots[Share slots for saving different hard registers]' + '-fira-share-spill-slots[Share stack slots for spilled pseudo-registers]' + '-fira-verbose=[Control IRA'\''s level of diagnostic messages]:verbosity: ' + '-fkeep-inline-functions[Generate code for functions even if they are fully inlined]' + '-fkeep-static-consts[Emit static const variables even if they are not used]' + '-fleading-underscore[Give external symbols a leading underscore]' + '-flto-compression-level=[Use zlib compression level <number> for IL]:compression level: ' + '-flto-partition=[Partition symbols and vars at linktime based on object files they originate from]:partitioning algorithm:(1to1 balanced max)' + '-flto-report[Report various link-time optimization statistics]' + '-flto[Enable link-time optimization]' + '-fmax-errors=-[Maximum number of errors to report]:errors: ' + '-fmem-report-wpa[Report on permanent memory allocation in WPA only]' + '-fmem-report[Report on permanent memory allocation]' + '-fmerge-debug-strings[Attempt to merge identical debug strings across compilation units]' + '-fmessage-length=-[Limit diagnostics to <number> characters per line. 0 suppresses line-wrapping]:length: ' + '-fmodulo-sched-allow-regmoves[Perform SMS based modulo scheduling with register moves allowed]' + '-fopt-info-type=-[Dump compiler optimization details]:filename:_files' + '-fopt-info[Dump compiler optimization details]' + '-fpartial-inlining[Perform partial inlining]' + '-fpcc-struct-return[Return small aggregates in memory, not registers]' + '-fpic[Generate position-independent code if possible (small mode)]' + '-fpie[Generate position-independent code for executables if possible (small mode)]' + '-fplugin-arg--[Specify argument <key>=<value> for plugin <name>]:-fplugin-arg-name-key=value: ' #TODO + '-fpost-ipa-mem-report[Report on memory allocation before interprocedural optimization]' + '-fpre-ipa-mem-report[Report on memory allocation before interprocedural optimization]' + '-fprofile-arcs[Insert arc-based program profiling code]' + '-fprofile-correction[Enable correction of flow inconsistent profile data input]' + '-fprofile-generate[Enable common options for generating profile info for profile feedback directed optimizations]' + '-fprofile-report[Report on consistency of profile]' + '-fprofile-use[Enable common options for performing profile feedback directed optimizations]' + '-fprofile-values[Insert code to profile values of expressions]' + '-fprofile[Enable basic program profiling code]' + '-frandom-seed=-[Use <string> as random seed]:seed: ' + '-freciprocal-math[Same as -fassociative-math for expressions which include division]' + '-frecord-gcc-switches[Record gcc command line switches in the object file]' + '-free[Turn on Redundant Extensions Elimination pass]' + '-fsanitize=-[Enable AddressSanitizer, a memory error detector]:style:(address thread)' + '-fsched-stalled-insns-dep=-[Set dependence distance checking in premature scheduling of queued insns]:instructions: ' + '-fsched-stalled-insns=-[Set number of queued insns that can be prematurely scheduled]:instructions: ' + '-fsched-verbose=-[Set the verbosity level of the scheduler]:verbosity: ' + '-fshow-column[Show column numbers in diagnostics, when available]' + '-fsplit-stack[Generate discontiguous stack frames]' + '-fstack-check=-[Insert stack checking code into the program. -fstack-check=specific if to argument given]:type:(none generic specific)' + '-fstack-limit-register=-[Trap if the stack goes past <register>]:register: ' + '-fstack-limit-symbol=-[Trap if the stack goes past symbol <name>]:name: ' + '-fno-stack-limit' + '-fstack-protector-all[Use a stack protection method for every function]' + '-fstack-protector[Use propolice as a stack protection method]' + '-fstack-usage[Output stack usage information on a per-function basis]' + '-fstrict-overflow[Treat signed overflow as undefined]' + '-fstrict-volatile-bitfields[Force bitfield accesses to match their type width]' + '-fsync-libcalls[Implement __atomic operations via libcalls to legacy __sync functions]' + '-fsyntax-only[Check for syntax errors, then stop]' + '-ftest-coverage[Create data files needed by "gcov"]' + '-ftime-report[Report the time taken by each compiler pass]' + '-ftls-model=-[Set the default thread-local storage code generation model]:TLS model:(global-dynamic local-dynamic initial-exec local-exec)' + '-ftracer[Perform superblock formation via tail duplication]' + '-ftree-loop-linear[Enable loop interchange transforms. Same as -floop-interchange]' + '-fuse-ld=[Use the specified linker instead of the default linker]:linker:(bfd gold)' + '-fuse-linker-plugin[Use linker plugin during link-time optimization]' + '-fverbose-asm[Add extra commentary to assembler output]' + '-fvisibility=[Set the default symbol visibility]:visibility:(default internal hidden protected)' + '-fzero-initialized-in-bss[Put zero initialized data in the bss section]' + '-gno-pubnames[Don'\''t generate DWARF pubnames and pubtypes sections]' + '-gno-record-gcc-switches[Don'\''t record gcc command line switches in DWARF DW_AT_producer]' + '-gno-split-dwarf[Don'\''t generate debug information in separate .dwo files]' + '-gno-strict-dwarf[Emit DWARF additions beyond selected version]' + '-gpubnames[Generate DWARF pubnames and pubtypes sections]' + '-grecord-gcc-switches[Record gcc command line switches in DWARF DW_AT_producer]' + '-gsplit-dwarf[Generate debug information in separate .dwo files]' + '-gstrict-dwarf[Don'\''t emit DWARF additions beyond selected version]' + '-gtoggle[Toggle debug information generation]' + '-gvms[Generate debug information in VMS format]' + '-imultiarch[Set <dir> to be the multiarch include subdirectory]:directory:_files -/' #XXX not in manpage + '-iplugindir=[Set <dir> to be the default plugin directory]:directory:_files -/' + '(-pg)-p[Enable function profiling for prof]' + '(-p)-pg[Enable function profiling for gprof]' + '-pedantic-errors[Like -pedantic but issue them as errors]' + '-pedantic[Issue all mandatory diagnostics in the C standard]' + '-quiet[Do not display functions compiled or elapsed time]' + '-v[Enable verbose output]' + '-version[Display the compiler'\''s version]' + '-w[Suppress warnings]' +# | grep :: + '-fabi-version=-[Use version <n> of the C++ ABI (default: 2)]:ABI version:(1 2 3 4 5 6)' + '-fdebug-prefix-map=-[Map one directory name to another in debug information]:/old/dir=/new/dir:->dirtodir' + '-ffp-contract=-[Perform floating- point expression contraction (default: fast)]:style:(on off fast)' + '-finstrument-functions-exclude-file-list=-[Do not instrument functions listed in files]:comma-separated file list:->commafiles' + '-finstrument-functions-exclude-function-list=-[Do not instrument listed functions]:comma-separated list of syms: ' + '-fira-algorithm=-[Set the used IRA algorithm]:algorithm:(priority CB)' + '-fira-region=-[Set regions for IRA]:region:(all mixed one)' + '-fplugin=-[Specify a plugin to load]:plugin: ' # TODO: complete plugins? + '-fprofile-dir=-[Set the top-level directory for storing the profile data]:profile directory:_files -/' + '-fstack-reuse=-[Set stack reuse level for local variables]:reuse-level:(all named_vars none)' + '-ftree-parallelize-loops=-[Enable automatic parallelization of loops]:threads: ' +) + +# How to mostly autogenerate the above stuff: +# joinhelplines() { sed '$!N;s/^\( -.*\)\n \s*\([^-]\)/\1 \2/;P;D' } +# gcc-x86() { gcc --help=target,\^undocumented | joinhelplines | joinhelplines } +# compdef _gnu_generic gcc-x86 +# printf '%s\n' ${(onq-)_args_cache_gcc_x86} +_arguments -C -M 'L:|-{fWm}no-=-{fWm} r:|[_-]=* r:|=*' \ "$args[@]" \ - -c -S -E -v -a -w -C -H -P -s '(-pg)-p' '(-p)-pg' \ - '-###[print commands to run this compilation]' \ - '-o:output file:_files -g "^*.(c|h|cc|C|cxx)(-.)"' \ - '-x:input file language:(c objective-c c++ c-header cpp-output c++-cpp-output assembler assembler-with-cpp none)' \ - '+e-:virtual function definitions in classes:((0\:only\ interface 1\:generate\ code))' \ - '-d-:dump:->dump' \ - '-g-::debugging information type:(gdb coff stabs stabs+ dwarf dwarf+ xcoff xcoff+)' \ - '-O-::optimization level:(0 1 2 3)' \ - '*-M-::output dependencies:((M\:only\ user\ header\ files MD\:output\ to\ file G\:treat\ missing\ header\ files\ as\ generated))' \ - '*-A-:define assertion:' \ - '*-D-:define macro:' \ - '*-U-:undefine macro:' \ - '*-Wp,-:preprocessor option:' \ - '*-Wl,-:linker option:' \ - '*-Xpreprocessor:preprocessor option:' \ - '*-Xlinker:linker option:' \ - '*-u:pretend symbol to be undefined:' \ - '*-Wa,-:assembler option:' \ - '*-l:library:->library' \ - '*-L-:library search path:_files -/' \ - '*-I-:header file search path:_files -/' \ - '-B-:executable prefix:_files -/' \ - '-b:target machine:' \ - '-V:specify compiler version:' \ - '--version' \ - '-print-file-name=:library:->library' \ - '-print-prog-name=:program:' \ - '*-include:include file:_files -g \*.h\(-.\)' \ - '*-imacros:macro input file:_files -g \*.h\(-.\)' \ - '*-idirafter:second include path directory:_files -/' \ - '*-iprefix:prefix:_files' \ - '*-iwithprefix:second include path directory:_files -/' \ - '*-iwithprefixbefore:main include path directory:_files -/' \ - '*-isystem:second include path directory (system):_files -/' \ - -nostdinc -trigraphs -undef -pipe -ansi \ - -fallow-single-precision -fcond-mismatch -fasm \ - -fbuiltin -fsigned-bitfields -fsigned-char \ - -funsigned-bitfields -funsigned-char -fwritable-strings \ - -traditional -traditional-cpp -trigraphs \ - -fall-virtual -fdollars-in-identifiers -felide-constructors \ - -fenum-int-equiv -fexternal-templates -ffor-scope \ - -fhandle-signatures -fmemoize-lookups -fdefault-inline -fgnu-keywords \ - -fnonnull-objects -foperator-names -fstrict-prototype \ - -fthis-is-variable -nostdinc++ -traditional \ - -fsyntax-only -pedantic -pedantic-errors \ - -Wall -Waggregate-return -Wbad-function-cast \ - -Wcast-align -Wcast-qual -Wchar-subscript -Wcomment \ - -Wconversion -Wenum-clash -Werror -Wformat \ - '-Wid-clash--:minimum identifier difference length:' \ - -Wimplicit -Wimport -Winline \ - '-Wlarger-than--:maximum object length:' \ - -Wmissing-declarations \ - -Wmissing-prototypes -Wnested-externs \ - -Wimport -Woverloaded-virtual -Wparentheses \ - -Wpointer-arith -Wredundant-decls -Wreorder -Wreturn-type -Wshadow \ - -Wstrict-prototypes -Wswitch -Wsynth -Wtemplate-debugging \ - -Wtraditional -Wtrigraphs -Wuninitialized -Wunused \ - -Wwrite-strings \ - -fpretend-float \ - -print-libgcc-file-name \ - -print-search-dirs -save-temps \ - -fcaller-saves -fcse-follow-jumps -fcse-skip-blocks \ - -fdelayed-branch -fexpensive-optimizations \ - -ffast-math -ffloat-store -fforce-addr -fforce-mem \ - -finline-functions -fkeep-inline-functions \ - -fdefault-inline -fdefer-pop -ffunction-cse \ - -finline -fpeephole -fomit-frame-pointer \ - -frerun-cse-after-loop -fschedule-insns \ - -fschedule-insns2 -fstrength-reduce -fthread-jumps \ - -funroll-all-loops -funroll-loops \ - -nostartfiles -nodefaultlibs -nostdlib \ - -static -shared -symbolic \ - '*-fcall-saved--:register saved by function call:' \ - '*-fcall-used--:register clobbered by function call:' \ - '*-ffixed--:fixed register:' \ - -finhibit-size-directive \ - -fno-common -fno-ident -fno-gnu-linker \ - -fpcc-struct-return -fpic -fPIC \ - -freg-struct-return -fshared-data -fshort-enums \ - -fshort-double -fvolatile -fvolatile-global \ - -fverbose-asm -fpack-struct \ "$args2[@]" && ret=0 @@ -342,7 +971,22 @@ library) rundir) compset -P '*:' compset -S ':*' - _files -/ -S/ -r '\n\t\- /:' "$@" + _files -/ -S/ -r '\n\t\- /:' "$@" && ret=0 + ;; +help) + _values -s , 'help' \ + optimizers warnings target params common \ + c c++ objc objc++ lto ada adascil adawhy fortran go java \ + {\^,}undocumented {\^,}joined {\^,}separate \ + && ret=0 + ;; +dirtodir) + compset -P '*=' + _files -/ && ret=0 + ;; +commafiles) + compset -P '*,' + _files && ret=0 ;; esac diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 43a01d9ff..7cd3324a8 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -405,8 +405,9 @@ _git-check-ignore () { '(-q --quiet)'{-q,--quiet}'[do not output anything, just set exit status]' \ '(-v --verbose)'{-v,--verbose}'[output details about the matching pattern (if any) for each pathname]' \ '--stdin[read file names from stdin instead of from the command-line]' \ - '-z[make output format machine-parseable]' \ + '-z[make output format machine-parseable and treat input-paths as NUL-separated with --stdin]' \ '(-n --non-matching)'{-n,--non-matching}'[show given paths which do not match any pattern]' \ + '--no-index[do not look in the index when undertaking the checks]' \ '*:: :->file' && ret=0 } @@ -422,7 +423,7 @@ _git-checkout () { # and perhaps also allow all that just with ^{tree} and so on. Not quite sure # how to do that, though. local new_branch_reflog_opt - if (( words[(I)-b|-B] )); then + if (( words[(I)-b|-B|--orphan] )); then new_branch_reflog_opt="(--patch)-l[create the new branch's reflog]" fi @@ -434,12 +435,13 @@ _git-checkout () { '(-f --force -m --merge --conflict --patch)'{-f,--force}'[force branch switch/ignore unmerged entries]' \ '(-q --quiet --theirs --patch)--ours[check out stage #2 for unmerged paths]' \ '(-q --quiet --ours --patch)--theirs[check out stage #3 for unmerged paths]' \ - '( -B --orphan --ours --theirs --conflict --patch)-b[create a new branch based at given commit]: :__git_branch_names' \ - '(-b --orphan --ours --theirs --conflict --patch)-B[create or update branch based at given commit]: :__git_branch_names' \ - '(-t --track --orphan --patch)'{-t,--track}'[set up configuration so pull merges from the base commit]' \ + '( -B --orphan --ours --theirs --conflict --patch --detach)-b[create a new branch based at given commit]: :__git_branch_names' \ + '(-b --orphan --ours --theirs --conflict --patch --detach)-B[create or update branch based at given commit]: :__git_branch_names' \ + '(-t --track --orphan --patch --detach)'{-t,--track}'[set up configuration so pull merges from the base commit]' \ '(--patch)--no-track[override the branch.autosetupmerge configuration variable]' \ $new_branch_reflog_opt \ - '(-b -B -t --track --patch)--orphan[create a new orphan branch based at given commit]: :__git_branch_names' \ + '(-b -B -t --track --patch --orphan)--detach[detach the HEAD at named commit]' \ + '(-b -B -t --track --patch --detach)--orphan[create a new orphan branch based at given commit]: :__git_branch_names' \ '--ignore-skip-worktree-bits[ignores patterns and adds back any files in <paths>]' \ '(-q --quiet -f --force -m --merge --conflict --patch)'{-m,--merge}'[3way merge current branch, working tree and new branch]' \ '(-q --quiet -f --force -m --merge --patch)--conflict[same as --merge, using given merge style]:style:(merge diff3)' \ @@ -461,7 +463,7 @@ _git-checkout () { tree_ish_arg='tree-ishs::__git_tree_ishs' \ file_arg='modified-files::__git_modified_files' - if [[ -n ${opt_args[(I)-b|-B|--orphan]} ]]; then + if [[ -n ${opt_args[(I)-b|-B|--orphan|--detach]} ]]; then remote_branch_noprefix_arg= tree_ish_arg= file_arg= @@ -480,7 +482,7 @@ _git-checkout () { $remote_branch_noprefix_arg \ $tree_ish_arg \ $file_arg && ret=0 - elif [[ -n ${opt_args[(I)-b|-B|-t|--track|--orphan]} ]]; then + elif [[ -n ${opt_args[(I)-b|-B|-t|--track|--orphan|--detach]} ]]; then _nothing elif [[ -n $line[1] ]] && __git_is_treeish $line[1]; then __git_ignore_line __git_tree_files ${PREFIX:-.} $line[1] && ret=0 @@ -509,7 +511,7 @@ _git-cherry-pick () { '*'{-s,--strategy=}'[use given merge strategy]:merge strategy:__git_merge_strategies' \ '*'{-X,--strategy-option=}'[pass merge-strategy-specific option to merge strategy]' \ '(-e --edit -x -n --no-commit -s --signoff)--ff[fast forward, if possible]' \ - ': :__git_revisions' + ': :__git_commit_ranges' } (( $+functions[_git-citool] )) || @@ -722,63 +724,74 @@ _git-diff () { case $state in (from-to-file) + # If "--" is part of $opt_args, this means it was specified before any + # $words arguments. This means that no heads are specified in front, so + # we need to complete *changed* files only. + if [[ -n ${opt_args[(I)--]} ]]; then + if [[ -n ${opt_args[(I)--cached|--staged]} ]]; then + __git_changed-in-index_files && ret=0 + else + __git_changed-in-working-tree_files && ret=0 + fi + return ret + fi + + # Otherwise, more complex conditions need to be checked. case $CURRENT in (1) - if [[ -n ${opt_args[(I)--]} ]]; then - if [[ -n ${opt_args[(I)--cached|--staged]} ]]; then - __git_changed-in-index_files && ret=0 - else - __git_changed-in-working-tree_files && ret=0 - fi - else - local files_alt='files::__git_changed-in-working-tree_files' - - if [[ -n ${opt_args[(I)--cached|--staged]} ]]; then - files_alt='files::__git_changed-in-index_files' - fi - - _alternative \ - 'commit-ranges::__git_commit_ranges' \ - 'blobs-and-trees-in-treeish::__git_blobs_and_trees_in_treeish' \ - $files_alt \ - 'blobs::__git_blobs ' && ret=0 + local files_alt='files::__git_changed-in-working-tree_files' + if [[ -n ${opt_args[(I)--cached|--staged]} ]]; then + files_alt='files::__git_changed-in-index_files' fi + + _alternative \ + 'commit-ranges::__git_commit_ranges' \ + 'blobs-and-trees-in-treeish::__git_blobs_and_trees_in_treeish' \ + $files_alt \ + 'blobs::__git_blobs ' && ret=0 ;; (2) + # Check if first argument is something special. In case of committish ranges and committishs offer a full list compatible completions. if __git_is_committish_range $line[1]; then + # Example: git diff branch1..branch2 <tab> __git_tree_files ${PREFIX:-.} $(__git_committish_range_last $line[1]) && ret=0 elif __git_is_committish $line[1] || __git_is_treeish $line[1]; then - if [[ -n ${opt_args[(I)--]} ]]; then - __git_changed-in-working-tree_files && ret=0 - else - _alternative \ - 'commits::__git_commits' \ - 'blobs-and-trees-in-treeish::__git_blobs_and_trees_in_treeish' \ - 'files::__git_changed-in-working-tree_files' && ret=0 - fi + # Example: git diff branch1 <tab> + _alternative \ + 'commits::__git_commits' \ + 'blobs-and-trees-in-treeish::__git_blobs_and_trees_in_treeish' \ + 'files::__git_tree_files ${PREFIX:-.} HEAD' && ret=0 elif __git_is_blob $line[1]; then - if [[ -n ${opt_args[(I)--]} ]]; then - __git_cached_files && ret=0 - else - _alternative \ - 'files::__git_cached_files' \ - 'blobs::__git_blobs' && ret=0 - fi + _alternative \ + 'files::__git_cached_files' \ + 'blobs::__git_blobs' && ret=0 elif [[ -n ${opt_args[(I)--cached|--staged]} ]]; then + # Example: git diff --cached file1 <tab> __git_changed-in-index_files && ret=0 else + # Example: git diff file1 <tab> __git_changed-in-working-tree_files && ret=0 fi ;; (*) if __git_is_committish_range $line[1]; then + # Example: git diff branch1..branch2 file1 <tab> __git_tree_files ${PREFIX:-.} $(__git_committish_range_last $line[1]) && ret=0 elif { __git_is_committish $line[1] && __git_is_committish $line[2] } || __git_is_treeish $line[2]; then + # Example: git diff branch1 branch2 <tab> __git_tree_files ${PREFIX:-.} $line[2] && ret=0 + elif __git_is_committish $line[1] || __git_is_treeish $line[1]; then + # Example: git diff branch file1 <tab> + # Example: git diff branch -- f<tab> + __git_tree_files ${PREFIX:-.} HEAD && ret=0 elif __git_is_blob $line[1] && __git_is_blob $line[2]; then _nothing + elif [[ -n ${opt_args[(I)--cached|--staged]} ]]; then + # Example: git diff --cached file1 file2 <tab> + __git_changed-in-index_files && ret=0 else + # Example: git diff file1 file2 <tab> __git_changed-in-working-tree_files && ret=0 fi ;; @@ -911,6 +924,8 @@ _git-grep () { '(--no-exclude-standard)--exclude-standard[exclude files standard ignore mechanisms]' \ '--untracked[search in untracked files]' \ '(-a --text)'{-a,--text}'[process binary files as if they were text]' \ + '(--textconv --no-textconv)--textconv[honor textconv filter settings]' \ + '(--textconv --no-textconv)--no-textconv[do not honor textconv filter settings]' \ '(-i --ignore-case)'{-i,--ignore-case}'[ignore case when matching]' \ '-I[do not match pattern in binary files]' \ '--max-depth=[descend at most given levels of directories]: :__git_guard_number depth' \ @@ -1230,8 +1245,10 @@ _git-pull () { _arguments \ $merge_options \ - '( --no-rebase)--rebase[perform a rebase after fetching]' \ - '(--rebase )--no-rebase[do not perform a rebase after fetching]' \ + '(-r --rebase --no-rebase)'{-r=-,--rebase=-}'[perform a rebase after fetching]::rebase after fetching:((true\:"rebase after fetching" + false\:"merge after fetching" + preserve\:"rebase and preserve merges"))' \ + '(-r --rebase )--no-rebase[do not perform a rebase after fetching]' \ $fetch_options \ ': :__git_any_repositories' \ '*: :__git_ref_specs' @@ -1239,6 +1256,7 @@ _git-pull () { (( $+functions[_git-push] )) || _git-push () { + local ret=1 # NOTE: For --receive-pack we use _files to complete, even though this will # only complete files on the local end, not the remote end. Still, it may be # helpful to get some sort of completion going, perhaps modifying the path @@ -1253,9 +1271,11 @@ _git-push () { '--tags[all tags under refs/tags are pushed]' \ '--follow-tags[also push missing annotated tags reachable from the pushed refs]' \ '(--receive-pack --exec)'{--receive-pack=-,--exec=-}'[path to git-receive-pack on remote]:remote git-receive-pack:_files' \ + '(--force-with-lease --no-force-with-lease)*--force-with-lease=-[allow refs that are not ancestors to be updated if current ref matches expected value]::ref and expectation:->lease' \ + '(--force-with-lease --no-force-with-lease)--no-force-with-lease=-[cancel all previous force-with-lease specifications]' \ '(-f --force)'{-f,--force}'[allow refs that are not ancestors to be updated]' \ '(:)--repo=[default repository to use]:repository:__git_any_repositories' \ - '(-u --set-upstream-to)'{-u,--set-upstream-to}'[add upstream reference for each branch that is up to date or pushed]' \ + '(-u --set-upstream)'{-u,--set-upstream}'[add upstream reference for each branch that is up to date or pushed]' \ '( --no-thin)--thin[try to minimize number of objects to be sent]' \ '(--thin )--no-thin[do not try to minimize number of objects to be sent]' \ '(-q --quiet -v --verbose --progress)'{-q,--quiet}'[suppress all output]' \ @@ -1265,7 +1285,20 @@ _git-push () { '--recurse-submodules=[submodule handling]:submodule handling:((check\:"refuse pushing of supermodule if submodule commit cannot be found on the remote" on-demand\:"push all changed submodules"))' \ ':: :__git_any_repositories' \ - '*: :__git_ref_specs' + '*: :__git_ref_specs' && ret=0 + + case $state in + (lease) + compset -P '*:' + if [[ -n ${IPREFIX#*=} ]]; then + _guard '[[:xdigit:]]#' "expected value" && ret=0 + else + __git_remote_branch_names_noprefix && ret=0 + fi + ;; + esac + + return ret } (( $+functions[_git-rebase] )) || @@ -1300,6 +1333,8 @@ _git-rebase () { {-x,--exec}'[with -i\: append "exec <cmd>" after each line]:command' \ '(1)--root[rebase all reachable commits]' \ $autosquash_opts \ + '(--autostash --no-autostash)--autostash[stash uncommitted changes before rebasing and apply them afterwards]' \ + '(--autostash --no-autostash)--no-autostash[do not stash uncommitted changes before rebasing and apply them afterwards]' \ '--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' \ @@ -1501,7 +1536,7 @@ _git-stash () { '(--keep-index )--no-keep-index[all changes already added to the index are undone]' \ '(-q --quiet)'{-q,--quiet}'[suppress all output]' \ '(-u --include-untracked)'{-u,--include-untracked}'[include untracked files]' \ - '::message' && ret=0 + ':: :_guard "([^-]?#|)" message' && ret=0 ;; (list) local -a log_options revision_options @@ -1556,7 +1591,7 @@ _git-stash () { _git-status () { local -a branch_opts - if (( $words[(I)-s|--short] )); then + if (( $words[(I)-s|--short|--porcelain|-z] )); then branch_opts=('(-b --branch)'{-b,--branch}'[show branch and tracking info]') fi @@ -1889,13 +1924,13 @@ _git-config () { 'browser.*.cmd:browser command to use:browser:_path_commands' 'browser.*.path:path to use for the browser:absolute browser path:_files -g "*(*)"' clean.requireForce:'require --force for git clean to actually do something::->bool:true' - color.branch:'color output of git branch::->color-bool' + color.branch:'color output of git branch::->color-bool:false' color.branch.current:'color of the current branch::->color' color.branch.local:'color of a local branch::->color' color.branch.remote:'color of a remote branch::->color' color.branch.upstream:'color of upstream branches::->color' color.branch.plain:'color of other branches::->color' - color.diff:'color output of git diff::->color-bool' + color.diff:'color output of git diff::->color-bool:false' color.diff.plain:'color of context text::->color' color.diff.meta:'color of meta-information::->color' color.diff.frag:'color of hunk headers::->color' @@ -1909,7 +1944,7 @@ _git-config () { color.decorate.tag:'color of tags::->color' color.decorate.stash:'color of stashes::->color' color.decorate.HEAD:'color of HEAD::->color' - color.grep:'whether or not to color output of git grep::->color-bool' + color.grep:'whether or not to color output of git grep::->color-bool:false' color.grep.context:'color of non-matching text in context lines::->color' color.grep.filename:'color of filename prefix::->color' color.grep.function:'color of function name lines::->color' @@ -1917,14 +1952,14 @@ _git-config () { color.grep.match:'color of matching text::->color' color.grep.selected:'color of non-matching text in selected lines::->color' color.grep.separator:'color of separators between fields in a line::->color' - color.interactive:'whether or not to color in interactive mode::->color-bool' + color.interactive:'whether or not to color in interactive mode::->color-bool:false' color.interactive.prompt:'color of prompt::->color' color.interactive.header:'color of header::->color' color.interactive.help:'color of help::->color' color.interactive.error:'color of error::->color' color.pager:'feed colored output to pager::->bool:true' - color.showbranch:'color output of git show-branch::->color-bool' - color.status:'color output of git status::->color-bool' + color.showbranch:'color output of git show-branch::->color-bool:false' + color.status:'color output of git status::->color-bool:false' color.status.branch:'color of the current branch::->color' color.status.header:'color of header text::->color' color.status.added:'color of added, but not yet committed, files::->color' @@ -1932,7 +1967,7 @@ _git-config () { color.status.changed:'color of changed, but not yet added in the index, files::->color' color.status.untracked:'color of files not currently being tracked::->color' color.status.nobranch:'color of no-branch warning::->color' - color.ui:'color output of capable git commands::->color-bool' + color.ui:'color output of capable git commands::->color-bool:auto' commit.cleanup:'default --cleanup option::->commit.cleanup:default' commit.status:'include status information in commit message template::->bool:true' commit.template:'template file for commit messages:template:_files' @@ -1949,6 +1984,7 @@ _git-config () { diff.external:'command to generate diff with:diff command:_path_commands' diff.mnemonicprefix:'use mnemonic source and destination prefixes::->bool:false' diff.noprefix:'strip source and destination prefixes::->bool:false' + diff.orderfile:'file to read patch order glob patterns from:order file:_files' diff.renameLimit:'number of files to consider when detecting copy/renames:rename limit:->int' diff.renames:'try to detect renames::->diff.renames:true' diff.ignoreSubmodules:'ignore submodules::->bool:false' @@ -1961,6 +1997,7 @@ _git-config () { difftool.prompt:'prompt before each invocation of the diff tool::->bool:true' diff.wordRegex:'regex used to determine what a word is when performing word-by-word diff:regular expression:->string' diff.guitool:'diff tool with gui to use::__git_difftools' + fetch.prune:'remove any remote tracking branches that no longer exist remotely::->bool:false' fetch.unpackLimit:'maximum number of objects to unpack when fetching:unpack limit:->int' fetch.recurseSubmodules:'recurse into submodules (as needed) when fetching::->fetch.recurseSubmodules:on-demand' fetch.fsckObjects:'check all fetched objects::->bool:false' @@ -2043,13 +2080,14 @@ _git-config () { grep.lineNumber:'enable -n option by default::->bool:false' grep.patternType:'default matching pattern type::->grep.patternType:default' help.browser:'browser used to display help in web format::__git_browsers' - http.cookiefile:'file containing cookie lines which should be used in the Git http session::_files' help.htmlpath:'location of HTML help::->help.htmlpath' + http.cookiefile:'file containing cookie lines which should be used in the Git http session::_files' http.lowSpeedLimit:'limit controlling when to abort an HTTP transfer:speed limit:->int' http.lowSpeedTime:'limit controlling when to abort an HTTP transfer:time limit (seconds):->int' help.format:'default help format used by git help::->help.format' help.autocorrect:'execute corrected mistyped commands::->bool:false' http.proxy:'HTTP proxy to use:proxy:_urls' + http.savecookies:'save cookies to the cookie file::->bool:false' http.sslVerify:'verify the SSL certificate for HTTPS::->bool:true' http.sslCert:'file containing SSL certificates for HTTPS:SSL certificate file:_files' http.sslKey:'file containing the SSL private key for HTTPS:SSL private key file:_files' @@ -2067,6 +2105,30 @@ _git-config () { http.getanyfile:'allow clients to read any file within repository::->bool:true' http.uploadpack:'serve git fetch-pack and git ls-remote clients::->bool:true' http.receivepack:'serve git send-pack clients::->bool:true' + 'http.*.cookiefile:file containing cookie lines which should be used in the Git http session::_files' + 'http.*.lowSpeedLimit:limit controlling when to abort an HTTP transfer:speed limit:->int' + 'http.*.lowSpeedTime:limit controlling when to abort an HTTP transfer:time limit (seconds):->int' + 'help.*.format:default help format used by git help::->help.format' + 'help.*.autocorrect:execute corrected mistyped commands::->bool:false' + 'http.*.proxy:HTTP proxy to use:proxy:_urls' + 'http.*.savecookies:save cookies to the cookie file::->bool:false' + 'http.*.sslVerify:verify the SSL certificate for HTTPS::->bool:true' + 'http.*.sslCert:file containing SSL certificates for HTTPS:SSL certificate file:_files' + 'http.*.sslKey:file containing the SSL private key for HTTPS:SSL private key file:_files' + 'http.*.sslCertPasswordProtected:prompt for a password for the SSL certificate::->bool:false' + 'http.*.sslCAInfo:file containing CA certificates to verify against for HTTPS:CA certificates file:_files' + 'http.*.sslCAPath:directory containing files with CA certificates to verify against for HTTPS:CA certificates directory:_directories' + 'http.*.sslTry:attempt to use AUTH SSL/TLS and encrypted data transfers when connecting via regular FTP protocol::->bool:false' + 'http.*.maxRequests:how many HTTP requests to launch in parallel:maximum number of requests::->int:5' + 'http.*.minSessions:number of curl sessions to keep across requests:minimum number of sessions::->int:1' + 'http.*.postBuffer:maximum size of buffer used by smart HTTP transport when POSTing:maximum POST buffer size:->bytes:1m' + 'http.*.lowSpeedLimit:lower limit for HTTP transfer-speed:low transfer-speed limit:->int' + 'http.*.lowSpeedTime:duration for http.lowSpeedLimit:time:->int' + 'http.*.noEPSV:disable the use of the EPSV ftp-command::->bool:false' + 'http.*.useragent:user agent presented to HTTP server:user agent string:->string' + 'http.*.getanyfile:allow clients to read any file within repository::->bool:true' + 'http.*.uploadpack:serve git fetch-pack and git ls-remote clients::->bool:true' + 'http.*.receivepack:serve git send-pack clients::->bool:true' i18n.commitEncoding:'character encoding commit messages are stored in::->encoding' i18n.logOutputEncoding:'character encoding commit messages are output in::->encoding' imap.folder:'IMAP folder to use with git imap-send:IMAP folder name::_mailboxes' @@ -2131,11 +2193,12 @@ _git-config () { pack.indexVersion:'default pack index version:index version:->string' pack.packSizeLimit:'maximum size of packs:maximum size of packs:->bytes' pull.octopus:'default merge strategy to use when pulling multiple branches::__git_merge_strategies' - pull.rebase:'rebase branches on top of the fetched branch, instead of merging::->bool:false' + pull.rebase:'rebase branches on top of the fetched branch, instead of merging::->pull.rebase:false' pull.twohead:'default merge strategy to use when pulling a single branch::__git_merge_strategies' push.default:'action git push should take if no refspec is given::->push.default:matching' rebase.stat:'show a diffstat of what changed upstream since last rebase::->bool:false' rebase.autosquash:'autosquash by default::->bool:false' + rebase.autostash:'autostash by default::->bool:false' receive.autogc:'run git gc --auto after receiving data::->bool:true' receive.fsckObjects:'check all received objects::->bool:true' receive.hiderefs:'string(s) receive-pack uses to decide which refs to omit from its initial advertisement:hidden refs:->string' @@ -2149,6 +2212,7 @@ _git-config () { 'remote.*.url:URL of a remote repository::__git_any_repositories' 'remote.*.pushurl:push URL of a remote repository::__git_any_repositories' 'remote.*.proxy:URL of proxy to use for a remote repository::_urls' + 'remote.*.prune:remove any remote tracking branches that no longer exist remotely::->bool:false' 'remote.*.fetch:default set of refspecs for git fetch::__git_ref_specs' 'remote.*.push:default set of refspecs for git push::__git_ref_specs' 'remote.*.mirror:push with --mirror::->bool:false' @@ -2184,6 +2248,7 @@ _git-config () { sendemail.smtpserver:'SMTP server to connect to:smtp host:_hosts' sendemail.smtpserveroption:'specifies the outgoing SMTP server option to use:SMTP server option:->string' sendemail.smtpserverport:'port to connect to SMTP server on:smtp port:_ports' + sendemail.smtpsslcertpath:'path to ca-certificates (directory or file):ca certificates path:_files' sendemail.smtpuser:'user to use for SMTP-AUTH:smtp user:_users' sendemail.thread:'set In-Reply-To\: and References\: headers::->bool:true' sendemail.validate:'perform sanity checks on patches::->bool:true' @@ -2223,7 +2288,7 @@ _git-config () { 'submodule.*.fetchRecurseSubmodules:fetch commits of submodules::->bool' 'submodule.*.path:path within project:submodule directory:_directories -qS \:' 'submodule.*.url:URL to update from::__git_any_repositories' - 'submodule.*.update:update strategy to use::->submodule.update' + 'submodule.*.update:update strategy to use::->submodule.update:none' 'submodule.*.ignore:ignore modifications to submodules with git status and git diff-*::->submodule.ignore' svn.noMetadata:'disable git-svn-id: lines at end of commits::->bool:false' svn.useSvmProps:'use remappings of URLs and UUIDs from mirrors::->bool:false' @@ -2301,6 +2366,7 @@ _git-config () { 'gc.*.:${${line[1]#gc.}%.*}-specific gc option' 'gitcvs.*.:gitcvs ${${line[1]#gitcvs.}%.*}-specific option' 'guitool.*.:${${line[1]#guitool.}%.*}-specific option' + 'http.*.:${${line[1]#http.}%.*}-specific option' 'man.*.:${${line[1]#man.}%.*}-specific man option' 'merge.*.:${${line[1]#merge.}%.*}-specific merge option' 'mergetool.*.:${${line[1]#mergetool.}%.*}-specific option' @@ -2358,6 +2424,9 @@ _git-config () { (guitool.) __git_config_sections '^guitool\..+\.[^.]+$' guitools 'gui tool' -S . && ret=0 ;; + (http.) + __git_config_sections '^http\..+\.[^.]+$' bases base -S . && ret=0 + ;; (man.) __git_man_viewers -S . && ret=0 ;; @@ -2568,7 +2637,7 @@ _git-config () { esac ;; (color-bool) - __git_config_values -t booleans -l boolean -- "$current" false \ + __git_config_values -t booleans -l boolean -- "$current" "$parts[5]" \ {never,false,no,off}:"do not $parts[2]" \ always:"always $parts[2]" \ {auto,true,yes,on}:$parts[2] && ret=0 @@ -2749,6 +2818,12 @@ _git-config () { (permission) __git_repository_permissions && ret=0 ;; + (pull.rebase) + __git_config_values -- "$current" "$parts[5]" \ + {true,yes,on}:$parts[2] \ + {false,no,off}:"do not $parts[2]" \ + preserve:"rebase and preserve merges" && ret=0 + ;; (push.default) __git_config_values -- "$current" "$parts[5]" \ nothing:'do not push anything' \ @@ -2802,6 +2877,18 @@ _git-config () { _message "${parts[3]:-${parts[2]:-value}}" fi ;; + (submodule.update) + compset -P '*!' + if [[ -n $IPREFIX ]]; then + _command_names -e + else + __git_config_values -- "$current" "$parts[5]" \ + rebase:'rebase current branch onto commit recorded in superproject' \ + merge:'merge commit recorded in superproject into current branch of submodule' \ + none:'do not merge or rebase' \ + '!:specify command name that takes sha1 to update to as parameter' && ret=0 + fi + ;; (submodule.ignore) __git_config_values -- "$current" "$parts[5]" \ all:'never consider submodules modified' \ @@ -3155,7 +3242,7 @@ _git-blame () { '-b[show blank SHA-1 for boundary commits]' \ '--root[do not treat root commits as boundaries]' \ '--show-stats[include additional statistics at the end of blame output]' \ - '-L[annotate only the given line range]: :->line-range' \ + '*-L[annotate only the given line range]: :->line-range' \ '-l[show long rev]' \ '-t[show raw timestamp]' \ '-S[use revs from revs-file]:revs-file:_files' \ @@ -3353,6 +3440,7 @@ _git-rev-parse () { '(- *)'{-h,--help}'[display usage]' \ '--keep-dashdash[do not skip first -- option]' \ '--stop-at-non-option[stop parsing options at first non-option argument]' \ + '--stuck-long[output options in long form if available, and with their arguments stuck]' \ '*:option specification' && ret=0 fi elif (( words[(I)--sq-quote] )); then @@ -3580,6 +3668,7 @@ _git-send-email () { '--smtp-server=[specify SMTP server to connect to]:smtp server:_hosts' \ '--smtp-server-port=[specify port to connect to SMTP server on]:smtp port:_ports' \ '--smtp-server-option=[specify the outgoing SMTP server option to use]:SMPT server option' \ + '--smtp-ssl-cert-path=[path to ca-certificates (directory or file)]:ca certificates path:_files' \ '--smtp-user=[specify user to use for SMTP-AUTH]:smtp user:_users' \ '--smtp-debug=[enable or disable debug output]:smtp debug:((0\:"disable" 1\:"enable"))' \ '--cc-cmd=[specify command to generate Cc\: header with]:Cc\: command:_path_commands' \ @@ -4166,10 +4255,18 @@ _git-update-index () { (( $+functions[_git-update-ref] )) || _git-update-ref () { + local z_opt + + if (( words[(I)--stdin] )); then + z_opt='-z[values are separated with NUL character when reading from stdin]' + fi + _arguments -w -S -s \ '-m[update reflog for specified name with specified reason]:reason for update' \ '(:)-d[delete given reference after verifying its value]:symbolic reference:__git_revisions:old reference:__git_revisions' \ - '--no-deref[overwrite ref itself, not what it points to]' \ + '(-d --no-deref)--stdin[reads instructions from standard input]' \ + $z_opt \ + '(-d -z --stdin)--no-deref[overwrite ref itself, not what it points to]' \ ':symbolic reference:__git_revisions' \ ':new reference:__git_revisions' \ '::old reference:__git_revisions' @@ -4377,6 +4474,7 @@ _git-merge-base () { '--octopus[compute best common ancestors of all supplied commits]' \ '--is-ancestor[tell if A is ancestor of B (by exit status)]' \ '(-)--independent[display minimal subset of supplied commits with same ancestors]' \ + '--fork-point[find the point at which B forked from ref A (uses reflog)]' \ ': :__git_commits' \ '*: :__git_commits' } @@ -4445,9 +4543,9 @@ _git-show-index () { _git-show-ref () { _arguments -S \ - list \ - '(-h --head)'{-h,--head}'[show HEAD reference]' \ + '(-h --head)'{-h,--head}'[show the HEAD reference, even if it would normally be filtered out]' \ '--tags[show only refs/tags]' \ - '--heads[show only HEAD and refs under refs/heads]' \ + '--heads[show only refs/heads]' \ '(-d --dereference)'{-d,--dereference}'[dereference tags into object IDs as well]' \ '(-s --hash)'{-s+,--hash=-}'[only show the SHA-1 hash, not the reference name]:: :__git_guard_number length' \ '--verify[enable stricter reference checking]' \ @@ -4686,6 +4784,7 @@ _git-check-attr () { {-a,--all}'[list all attributes that are associated with the specified paths]' \ '--stdin[read file names from stdin instead of from command line]' \ '--cached[consider .gitattributes in the index only, ignoring the working tree.]' \ + '-z[make output format machine-parseable and treat input-paths as NUL-separated with --stdin]' \ $z_opt \ '(-)--[interpret preceding arguments as attributes and following arguments as path names]' \ '*:: :->attribute-or-file' && ret=0 @@ -4798,12 +4897,12 @@ __git_command_successful () { (( $+functions[__git_committish_range_first] )) || __git_committish_range_first () { - print -r -- ${1%..(.|)*} + print -r -- ${${${1%..*}%.}:-HEAD} } (( $+functions[__git_committish_range_last] )) || __git_committish_range_last () { - print -r -- ${1##*..(.|)} + print -r -- ${${${1#*..}#.}:-HEAD} } (( $+functions[__git_pattern_escape] )) || @@ -4832,12 +4931,12 @@ __git_is_treeish () { (( $+functions[__git_is_committish_range] )) || __git_is_committish_range () { - # TODO: This isn't quite right. We would like to do parts=${(~s:..(.|))}, - # but that doesn't work. (This would allow us to make sure that parts only - # contains two elements and then apply __git_is_committish on them. - [[ $1 == *..(.|)* ]] && - __git_is_committish $(__git_committish_range_first $1) && - __git_is_committish $(__git_committish_range_last $1) + [[ $1 == *..(.|)* ]] || return 1 + local first=$(__git_committish_range_first $1) + local last=$(__git_committish_range_last $1) + [[ $first != *..* && $last != *..* ]] && \ + __git_is_committish $first && \ + __git_is_committish $last } (( $+functions[__git_is_initial_commit] )) || @@ -5427,9 +5526,12 @@ __git_remote_branch_names_noprefix () { __git_commits () { # TODO: deal with things that __git_heads and __git_tags has in common (i.e., # if both exists, they need to be completed to heads/x and tags/x. + local -a sopts ropt + zparseopts -E -a sopts S: r:=ropt R: q + sopts+=( $ropt:q ) _alternative \ - 'heads::__git_heads' \ - 'commit-tags::__git_commit_tags' \ + "heads::__git_heads $sopts" \ + "commit-tags::__git_commit_tags $sopts" \ 'commit-objects::__git_commit_objects' } @@ -5496,10 +5598,12 @@ __git_commits2 () { (( $+functions[__git_commit_ranges] )) || __git_commit_ranges () { + local -a suf if compset -P '*..(.|)'; then __git_commits $* else - __git_commits $* -qS .. + compset -S '..*' || suf=( -S .. -r '.@~ ^:\t\n\-' ) + __git_commits $* $suf fi } @@ -5537,7 +5641,7 @@ __git_submodules () { local expl declare -a submodules - submodules=(${${(f)"$(_call_program submodules git submodule 2>/dev/null)"}#* }) + submodules=(${${${(f)"$(_call_program submodules git submodule 2>/dev/null)"}#?* }%% *}) __git_command_successful $pipestatus || return 1 _wanted submodules expl submodule compadd $* - $submodules @@ -5683,9 +5787,17 @@ __git_files () { # TODO: --directory should probably be added to $opts when --others is given. local pref=$gitcdup$gitprefix$PREFIX + + # First allow ls-files to pattern-match in case of remote repository files=(${(0)"$(_call_program files git ls-files -z --exclude-standard $opts -- ${pref:+$pref\\\*} 2>/dev/null)"}) __git_command_successful $pipestatus || return + # If ls-files succeeded but returned nothing, try again with no pattern + if [[ -z "$files" && -n "$pref" ]]; then + files=(${(0)"$(_call_program files git ls-files -z --exclude-standard $opts -- 2>/dev/null)"}) + __git_command_successful $pipestatus || return + fi + # _wanted $tag expl $description _files -g '{'${(j:,:)files}'}' $compadd_opts - _wanted $tag expl $description _multi_parts -f $compadd_opts - / files } @@ -5957,7 +6069,7 @@ __git_setup_diff_options () { '--find-copies-harder[try harder to find copies]' '(-D --irreversible-delete)'{-D,--irreversible-delete}'[omit the preimage for deletes]' '-l-[limit number of rename/copy targets to run]: :__git_guard_number' - '--diff-filter=-[select certain kinds of files for diff]: :_guard "[ACDMRTUXB*]#" kinds' + '--diff-filter=-[select certain kinds of files for diff]: :_guard "[AaCcDdMmRrTtUuXxBb*]#" kinds' '-S-[look for differences that add or remove the given string]:string' '-G-[look for differences whose added or removed line matches the given regex]:pattern' '--pickaxe-all[when -S finds a change, show all changes in that changeset]' @@ -6052,7 +6164,10 @@ __git_setup_revision_options () { '--tags=[-show all commits from refs/tags]::pattern' '--remotes=[-show all commits from refs/remotes]::pattern' '--glob=[show all commits from refs matching glob]:pattern' - '--stdin[read commit objects from standard input]' + '--exclude=[do not include refs matching glob]:pattern' + '--exclude=[do not include refs matching glob]:pattern' + '--ignore-missing[ignore invalid object an ref names on command line]' + '--bisect[pretend as if refs/bisect/bad --not refs/bisect/good-* was given on command line]' '(-g --walk-reflogs --reverse)'{-g,--walk-reflogs}'[walk reflog entries from most recent to oldest]' '--grep-reflog=[limit commits to ones whose reflog message matches the given pattern (with -g, --walk-reflogs)]:pattern' '--merge[after a failed merge, show refs that touch files having a conflict]' @@ -6262,15 +6377,22 @@ __git_browsers () { builtinbrowsers=( firefox iceweasel + seamonkey + iceape google-chrome + chrome chromium konquerer + opera w3m + elinks links lynx dillo open - start) + start + cygstart + xdg-open) _tags user-browsers builtin-browsers @@ -6469,6 +6591,7 @@ _git() { _arguments -C \ '(- :)--version[display version information]' \ '(- :)--help[display help message]' \ + '-C[run as if git was started in given path]: :_directories' \ '-c[pass configuration parameter to command]:parameter' \ '--exec-path=-[path containing core git-programs]:: :_directories' \ '(: -)--man-path[print the manpath for the man pages for this version of Git and exit]' \ diff --git a/Completion/Unix/Command/_gzip b/Completion/Unix/Command/_gzip index a90f23273..927d31d45 100644 --- a/Completion/Unix/Command/_gzip +++ b/Completion/Unix/Command/_gzip @@ -39,6 +39,7 @@ gzip) '(-q --quiet)--silent[suppress all warnings]' \ '(--recursive)-r[operate recursively on directories]' \ '(-r)--recursive[operate recursively on directories]' \ + '--rsyncable[make rsync-friendly archive]' \ '(--suffix)-S+[specify suffix for compressed files]:suffix:' \ '(-S)--suffix=[specify suffix for compressed files]:suffix:' \ '(--test)-t[test compressed file integrity]' \ diff --git a/Completion/Unix/Command/_hg b/Completion/Unix/Command/_hg index f48598278..c18500bcb 100644 --- a/Completion/Unix/Command/_hg +++ b/Completion/Unix/Command/_hg @@ -226,6 +226,16 @@ _hg_modified() { _wanted files expl 'modified files' _multi_parts / status_files } +_hg_committable() { + typeset -a status_files + # A file is a candidate for `hg commit` if it is: + # - modified (m), or + # - added (a), or + # - removed (r) + _hg_status mar + _wanted files expl 'committable files' _multi_parts / status_files +} + _hg_resolve() { local rstate rpath @@ -476,7 +486,7 @@ _hg_cmd_commit() { '(--logfile -l)'{-l+,--logfile}'[read commit message from specified file]:log file:_files' \ '(--date -d)'{-d+,--date}'[record datecode as commit date]:date code:' \ '(--user -u)'{-u+,--user}'[record user as commiter]:user:' \ - '*:file:_hg_files' + '*:file:_hg_committable' } _hg_cmd_copy() { diff --git a/Completion/Unix/Command/_ip b/Completion/Unix/Command/_ip index 0fc979cd3..f880f2683 100644 --- a/Completion/Unix/Command/_ip +++ b/Completion/Unix/Command/_ip @@ -40,7 +40,7 @@ subcmd_ipaddrs=( ) subcmd_prefix_label=( /$'(<->(.<->(.<->(.<->|)|)|)|[:[:xdigit]]#:[:[:xdigit:]]#)(|/<->)\0'/ - ":ipaddresslabel:IP addrlabel prefix currently set:( $(ip -6 addrlabel list | sed -n 's/^prefix \([0-9a-f\.:/]*\) .*$/\1/p') )" + ":ipaddresslabel:IP addrlabel prefix currently set:( $(ip -6 addrlabel list 2>/dev/null | sed -n 's/^prefix \([0-9a-f\.:/]*\) .*$/\1/p') )" ) diff --git a/Completion/Unix/Command/_man b/Completion/Unix/Command/_man index d1346f7cc..81ac40bc2 100644 --- a/Completion/Unix/Command/_man +++ b/Completion/Unix/Command/_man @@ -29,7 +29,7 @@ _man() { if (( index )); then local opt opt=$words[index+1] - _manpath=($_manpath $opt) + _manpath=($opt) fi # `sman' is the SGML manual directory for Solaris 7. diff --git a/Completion/Unix/Command/_moosic b/Completion/Unix/Command/_moosic new file mode 100644 index 000000000..f22fe16c5 --- /dev/null +++ b/Completion/Unix/Command/_moosic @@ -0,0 +1,487 @@ +#compdef moosic + +_moosic_add_cmds() { + + # querying for information + typeset -a queries + queries=( + "help:print brief description of command" + "current:print name of currently playing song" + "current-time:print the amount of time the current song has been playing" + "list:print the list of items in the current song queue" + "plainlist:print the current song queue without numbering each line" + "history:print a list of items that were recently played" + {status,state}":print the current state of the music daemon" + "length:print the number of items in the queue" + "ispaused:show whether the current song is paused or not" + "islooping:show whether the server is in loop mode" + "isadvancing:show whether the server is advancing through the song queue" + "version:print version information for client and server" + ) + + + # appending to song queue + typeset -a appending + appending=( + {append,add}":add the files to be played to the end of the song queue" + {pl-append,pl-add}":add the items listed in the given playlist files to end of queue" + "prepend:add the files to be played to the beginning of the song queue" + "pl-prepend:add the items in the given playlist files to beginning of queue" + "mixin:add the files to the song queue and reshuffle the entire queue" + "pl-mixin:add items in given playlist files to song queue and reshuffle the entire queue" + "replace:replace the current contents of the song queue with files listed" + "pl-replace:replace current contents of song queue with songs given in playlists" + "insert:insert the given items at a given point in the song queue" + "pl-insert:insert items from playlist files at specified point in queue" + "putback:reinsert current song at start of song queue" + "stagger-add:adds file list to end of queue after rearranging queue into staggered order" + "stagger-merge:adds given file list to queue in interleaved fashion" + "interval-add:inserts given songs with regular frequency specified by interval argument" + ) + + # removing + typeset -a removing + removing=( + {cut,del}":removes all song queue items in given range" + "crop:removes all song queue items that do not fall within given range" + "remove:remove all song queue items matching any one of given regexps" + "filter:remove all queue items not matching all given regexps" + "clear:clear song queue" + "wipe:clear song queue and stop current song" + ) + + # rearranging + typeset -a rearranging + rearranging=( + "move:move all items in given range to new position in song queue" + "move-pattern:moves all items matching the given regexp to new position" + "swap:trade places of songs in two specified ranges" + {shuffle,reshuffle}":reshuffle song queue within an optional range" + "sort:sort queue within optional range" + "reverse:reverse order of song queue" + "partial-sort:sort items matching each regexp" + "stagger:stagger items matching each regexp" + "sub:perform regular expression substitution on all items in queue" + "suball:like sub, but replace all occurrences of the pattern" + ) + + # general management + typeset -a general + general=( + "next:jumps ahead, number of songs optional" + "previous:retreats to previously played song" + "goto:jumps to next song matching regexp" + "gobackto:jumps back to most recent previous song matching regexp" + "noadvance:halt queue advancement" + "advance:resume queue advancement" + "toggle-advance:toggle queue advancement" + "stop:stop playing current song, stop processing queue, put current song back" + "pause:suspend current song to resume it later" + "unpause:unpause current song" + "play:resume playing" + "loop:turn loop mode on" + "noloop:turn loop mode off" + "toggle-loop:toggle loop mode" + "reconfigure:daemon reload configuration file" + "showconfig:show dameon filetype associations" + "start-server:starts new instance of daemon with given options" + {quit,exit,die}":quit daemon" + ) + + _describe queries queries -J queries + _describe appending appending -J appending + _describe removing removing -J removing + _describe rearranging rearranging -J rearranging + _describe general general -J general +} + +_moosic() { + typeset context state line + typeset -A opt_args + + typeset -a filelist_opts + filelist_opts=( + '(-g --shuffle-global)'{-g,--shuffle-global}'[shuffle filelist after directory expansion]' + '(-d --shuffle-dir)'{-d,--shuffle-dir}'[shuffle results of expanding the directories]' + '(-a --shuffle-args)'{-a,--shuffle-args}'[shuffle actual command line arguments]' + '(-o --inorder)'{-o,--inorder}'[do not shuffle filelist]' + '(-s --sort)'{-s,--sort}'[sort filelist lexicographically after expansion]' + '(-r --no-recurse)'{-r,--no-recurse}'[do not recurse through directories]' + '(-n --no-file-munge)'{-n,--no-file-munge}'[do not modify names in expanded filelist]' + '(-f --auto-find)'{-f,--auto-find}'[perform fuzzy search for music files]' + '(-F --auto-grep)'{-F,--auto-grep}'[like --auto-find but with regexp]' + '(-U --allow-unplayable)'{-U,--allow-unplayable}'[allow addition of unknown song types]' + ) + + typeset -a auto_opts + auto_opts=( + '(-m --music-dir)'{-m,--music-dir}'[directory used for auto-find, auto-grep]:directory:_files' + ) + + typeset -a main_opts + main_opts=( + '(-i --ignore-case)'{-i,--ignore-case}'[treat regexps as if they are case-insensitive]' + '(-S --showcommands)'{-S,--showcommands}'[show all moosic commands, then exit]' + '(-h --help)'{-h,--help}'[print help message then exit]' + '(-v --version)'{-v,--version}'[print version information, then exit]' + '(-c --config-dir)'{-c,--config-dir}'[configuration directory]:directory:_files' + '(-t --tcp)'{-t,--tcp}'[talk to server at specified host and port]:host\:port:' + '(-N --no-startserver)'{-N,--no-startserver}'[do not start moosicd server]' + ) + + typeset -a list_opts + list_opts=( + '(-C --current-in-list)'{-C,--current-in-list}'[print currently playing song in list]' + ) + + # GLOBAL ARGUMENTS + # do not use the -A option here. It will break the processing of + # positional arguments. + _arguments $main_opts $list_opts $auto_opts $filelist_opts \ + '1: :->cmd' \ + '*:: :->posarg' + + if [[ $state == cmd ]]; then + _moosic_add_cmds + elif [[ $state == posarg ]]; then + _moosic_cmd_${line[1]} + fi +} + +# Do something, but only if the current word is 2. +_do2() { + if (( CURRENT == 2 )); then + $@ + else + _message 'no more arguments' + fi +} + +### QUERY COMMANDS + +_moosic_cmd_help() { + _do2 '_moosic_add_cmds' +} + +_moosic_cmd_current() { + _message 'no arguments' +} + +_moosic_cmd_current-time() { + _do2 '_message' 'strftime string' +} + +_moosic_cmd_list() { + _do2 '_message' 'range' +} + +_moosic_cmd_plainlist() { + _do2 '_message' 'range' +} + +_moosic_cmd_history() { + _do2 '_message' 'maximum number of entries' +} + +_moosic_cmd_status() { + _message 'no arguments' +} + +_moosic_cmd_state() { + _message 'no arguments' +} + +_moosic_cmd_length() { + _message 'no arguments' +} + +_moosic_cmd_ispaused() { + _message 'no arguments' +} + +_moosic_cmd_islooping() { + _message 'no arguments' +} + +_moosic_cmd_isadvancing() { + _message 'no arguments' +} + +_moosic_cmd_version() { + _message 'no arguments' +} + +### APPENDING COMMANDS + +_moosic_song_files() +{ + _arguments -A '-*' $main_opts $filelist_opts $auto_opts \ + '*:song files:_files' +} + +_moosic_cmd_append() { + _moosic_song_files +} + +_moosic_cmd_add() { + _moosic_song_files +} + +_moosic_cmd_pl-append() { + _moosic_song_files +} + +_moosic_cmd_pl-add() { + _moosic_song_files +} + +_moosic_cmd_prepend() { + _moosic_song_files +} + +_moosic_cmd_pl-prepend() { + _moosic_song_files +} + +_moosic_cmd_mixin() { + _moosic_song_files +} + +_moosic_cmd_pl-mixin() { + _moosic_song_files +} + +_moosic_cmd_replace() { + _moosic_song_files +} + +_moosic_cmd_pl-replace() { + _moosic_song_files +} + +_moosic_cmd_insert() { + _moosic_song_files +} + +_moosic_cmd_pl-insert() { + _moosic_song_files +} + +_moosic_cmd_putback() { + _message 'no arguments' +} + +_moosic_cmd_stagger-add() { + _moosic_song_files +} + +_moosic_cmd_stagger-merge() { + _moosic_song_files +} + +_moosic_cmd_interval-add() { + _arguments -A '-*' $main_opts $filelist_opts \ + '1:interval:' \ + '*:song files:_files' +} + +### REMOVING COMMANDS + +_moosic_cmd_cut() { + _do2 '_message' 'range' +} + +_moosic_cmd_del() { + _do2 '_message' 'range' +} + +_moosic_cmd_crop() { + _do2 '_message' 'range' +} + +_moosic_cmd_remove() { + _do2 '_message' 'regex' +} + +_moosic_cmd_filter() { + _do2 '_message' 'regex' +} + +_moosic_cmd_clear() { + _message 'no arguments' +} + +_moosic_cmd_wipe() { + _message 'no arguments' +} + +### REARRANGING COMMANDS + +_moosic_cmd_move() { + _arguments -A '-*' $main_opts \ + '1:range:' \ + '2:index:' \ + '*:no more arguments:' +} + +_moosic_cmd_move-pattern() { + _arguments -A '-*' $main_opts \ + '1:regex:' \ + '2:index:' \ + '*:no more arguments:' +} + +_moosic_cmd_swap() { + _arguments -A '-*' $main_opts \ + '1:range:' \ + '2:range:' \ + '*:no more arguments:' +} + +_moosic_cmd_shuffle() { + _arguments -A '-*' $main_opts \ + '1:range (optional):' \ + '*:no more arguments:' +} + +_moosic_cmd_reshuffle() { + _arguments -A '-*' $main_opts \ + '1:range (optional):' \ + '*:no more arguments:' +} + +_moosic_cmd_sort() { + _arguments -A '-*' $main_opts \ + '1:range (optional):' \ + '*:no more arguments:' +} + +_moosic_cmd_reverse() { + _arguments -A '-*' $main_opts \ + '1:range (optional):' \ + '*:no more arguments:' +} + +_moosic_cmd_partial-sort() { + _do2 '_message' 'regex' +} + +_moosic_cmd_stagger() { + _do2 '_message' 'regex' +} + +_moosic_cmd_sub() { + _arguments -A '-*' $main_opts \ + '1:pattern:' \ + '2:replacement:' \ + '3:range (optional):' \ + '*:no more arguments:' +} + +_moosic_cmd_suball() { + _arguments -A '-*' $main_opts \ + '1:pattern:' \ + '2:replacement:' \ + '3:range (optional):' \ + '*:no more arguments:' +} + +### GENERAL COMMANDS + +_moosic_cmd_next() { + if (( CURRENT == 2 )); then + + typeset -a display display_cmd + if zstyle -a ":completion:${curcontext}:next" \ + 'command' display_cmd; then + $display_cmd + else + display=(${(f)"$(moosic list)"}) + fi + + typeset -a numbers + numbers=({1..${#display}}) + + compadd -V songs -d display -a numbers + else + _message 'no more arguments' + fi +} + +_moosic_cmd_previous() { + _do2 '_message' 'number to skip' +} + +_moosic_cmd_goto() { + _do2 '_message' 'regex' +} + +_moosic_cmd_gobackto() { + _do2 '_message' 'regex' +} + +_moosic_cmd_noadvance() { + _message 'no arguments' +} + +_moosic_cmd_advance() { + _message 'no arguments' +} + +_moosic_cmd_toggle-advance() { + _message 'no arguments' +} + +_moosic_cmd_stop() { + _message 'no arguments' +} + +_moosic_cmd_pause() { + _message 'no arguments' +} + +_moosic_cmd_unpause() { + _message 'no arguments' +} + +_moosic_cmd_play() { + _message 'no arguments' +} + +_moosic_cmd_loop() { + _message 'no arguments' +} + +_moosic_cmd_noloop() { + _message 'no arguments' +} + +_moosic_cmd_toggle-loop() { + _message 'no arguments' +} + +_moosic_cmd_reconfigure() { + _message 'no arguments' +} + +_moosic_cmd_showconfig() { + _message 'no arguments' +} + +_moosic_cmd_start-server() { + _message 'options' +} + +_moosic_cmd_quit() { + _message 'no arguments' +} + +_moosic_cmd_exit() { + _message 'no arguments' +} + +_moosic_cmd_die() { + _message 'no arguments' +} + +_moosic "$@" diff --git a/Completion/Unix/Command/_mpc b/Completion/Unix/Command/_mpc index 1ff9ad950..12707677f 100644 --- a/Completion/Unix/Command/_mpc +++ b/Completion/Unix/Command/_mpc @@ -25,7 +25,7 @@ _mpc_command() { local mpc_cmds mpc_cmds=( - add:"add a song to the current playlist" + add:"append a song to the end of the current playlist" clear:"clear the current playlist" crop:"remove all songs except for the currently playing song" current:"show the currently playing song" @@ -35,6 +35,7 @@ _mpc_command() { enable:"enable a output" idle:"wait until an event occurs" idleloop:"loop waiting for events" + insert:"insert a song after the currently playing song in the playlist" listall:"list all songs in the music directory" load:"load file as a playlist" ls:"list the contents of specified directory" @@ -253,7 +254,7 @@ _mpc_search() { local list expl list=(album artist title track name genre date composer performer comment disc filename any) - if [[ $#words -eq 2 ]]; then + if ! (( $#words % 2 )); then _wanted list expl table compadd $expl -a list else _message "pattern" diff --git a/Completion/Unix/Command/_nm b/Completion/Unix/Command/_nm index 5638014d6..3ceb8c932 100644 --- a/Completion/Unix/Command/_nm +++ b/Completion/Unix/Command/_nm @@ -21,7 +21,7 @@ case $state in _alternative \ "object-files:object file:_path_files -g '*.o'" \ "executable-files:executable file:_path_files -g '*(*)'" \ - "dynamic-libraries:dynamic library:_path_files -g '*.so'" \ + "dynamic-libraries:dynamic library:_path_files -g '*.so(.*)#'" \ "static-libraries:static library:_path_files -g '*.a'" \ "directories:directory:_path_files -g '*(/)'" && ret=0 ;; diff --git a/Completion/Unix/Command/_npm b/Completion/Unix/Command/_npm index 24b536188..f5493a321 100644 --- a/Completion/Unix/Command/_npm +++ b/Completion/Unix/Command/_npm @@ -1,19 +1,9 @@ #compdef npm -# Node Package Manager 0.3.15 completion, letting npm do all the completion work +# Node Package Manager completion, letting npm do all the completion work -_npm() { - compadd -- $(_npm_complete $words) -} +if type npm > /dev/null; then + eval "$(npm completion)" -# We want to show all errors of any substance, but never the "npm (not )ok" one. -# (Also doesn't consider "ERR! no match found" worth breaking the terminal for.) -_npm_complete() { - local ask_npm - ask_npm=(npm completion --color false --loglevel error -- $@) - { _call_program npm $ask_npm 2>&1 >&3 \ - | egrep -v '^(npm (not |)ok|ERR! no match found)$' >&2; \ - } 3>&1 -} - -_npm "$@" + _npm_completion "$@" +fi diff --git a/Completion/Unix/Command/_od b/Completion/Unix/Command/_od new file mode 100644 index 000000000..d542597e0 --- /dev/null +++ b/Completion/Unix/Command/_od @@ -0,0 +1,71 @@ +#compdef od + +local context state state_descr line args ret=1 +local -A opt_args + +args=( + '(-A --address-radix)'{-A+,--address-radix=}'[file offset base]:base:((d\:decimal o\:octal x\:hexadecimal n\:none))' + '(-j --skip-bytes)'{-j+,--skip-bytes=}'[skip specified bytes]:bytes' + '(-N --read-bytes)'{-N+,--read-bytes=}'[dump at most specified bytes]:bytes' + '*'{-t+,--format=}'[specify output format]:format string:->format' + '(-v --output-duplicates)'{-v,--output-duplicates}'[do not use * to mark line suppression]' + '-a[output named characters (-t a)]' + '-b[output octal bytes (-t o1)]' + '-c[output characters with C-style escape (-t c)]' + '-d[output unsigned decimal shorts (-t u2)]' + '-f[output single-precision floats (-t fF)]' + {-h,-x}'[output hexadecimal shorts (-t x2)]' + '-i[output decimal integers (-t dI)]' + {-l,-I,-L}'[output decimal longs (-t dL)]' + {-o,-B}'[output octal shorts (-t o2)]' + '-s[output decimal shorts (-t d2)]' + '*:files:_files' +) + +if _pick_variant gnu=GNU unix --version; then + # -h -B -I and -L are obsolescent and undocumented + args=( ${(R)args:#(|\*)(|\(*\))-[hBIL]*} ) + args+=( + {-S+,--strings=-}'[output strings of at least specfied bytes long]:length' + {-w-,--width=-}'[output specified bytes per line]:bytes' + '(- : *)--help[display help and exit]' + '(- : *)--version[output version information and exit]' + ) +else + args=( ${(R)args:#(|\*)(|\(*\))--*} ) # remove long options + case "$OSTYPE" in + (darwin*|freebsd*|dragonfly*|openbsd*) + args+=( + '-D[output unsigned decimal ints (-t u4)]' + {-e,-F}'[output double-precision floats (-t fD)]' + {-H,-X}'[output hexadecimal ints (-t x4)]' + '-O[output octal ints (-t o4)]' + ) + ;; + (*) + # POSIX options only + args=( ${(M)args:#(|\*)(|\(*\))-[AjNtvbcdosx]*} ) + ;; + esac +fi + +_arguments -s -S : "$args[@]" && return 0 + +case "$state" in + (format) + compset -P '*[acCSIL1248FDL]' + if compset -P '*[doux]'; then + args=( 'C:char' 'S:short' 'I:int' 'L:long' 1 2 4 8 ) + _describe -t integer-size 'size of integer' args && ret=0 + elif compset -P '*f'; then + args=( 'F:float' 'D:double' 'L:long double' ) + _describe -t float-size 'size of float' args && ret=0 + fi + args=( 'a:named character' 'c:character (C-style escape)' + 'd:decimal' 'o:octal' 'u:unsigned decimal' + 'x:hexadecimal' 'f:floating-point number' ) + _describe -t type-specifier 'type specifier' args && ret=0 + ;; +esac + +return ret diff --git a/Completion/Unix/Command/_perforce b/Completion/Unix/Command/_perforce index bcfe5229a..839870211 100644 --- a/Completion/Unix/Command/_perforce +++ b/Completion/Unix/Command/_perforce @@ -1203,9 +1203,11 @@ _perforce_files() { # probably ought to be optional (you can do it with tags if # you really want). if [[ $PREFIX = //[^/]# && $whole_path -eq 0 ]]; then - # Complete //clientname spec. Don't complete non-directories... + # Complete //clientname or //depot spec. + # Don't complete non-directories... # I don't actually know if they are valid here. - altfiles+=("clients:Perforce client:_perforce_clients") + altfiles+=("clients:Perforce client:_perforce_clients" + "depots:Perforce depot:_perforce_depots") else local donefiles=1 if [[ -z $dodirs ]]; then diff --git a/Completion/Unix/Command/_perl b/Completion/Unix/Command/_perl index b00baa6ed..52559b800 100644 --- a/Completion/Unix/Command/_perl +++ b/Completion/Unix/Command/_perl @@ -4,6 +4,7 @@ # Adam Spiers <adam@spiers.net> # # Completions currently based on Perl 5.14.1. +typeset -A opt_args _perl () { _arguments -s \ @@ -16,8 +17,8 @@ _perl () { '(-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: ' \ + '(1 -E)*-e+[run one line of program]:one line of program' \ + '(1 -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]' \ @@ -27,21 +28,29 @@ _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 (deprecated)]' \ "-s[enable some switch parsing for switches after script name]" \ "-S[look for the script using PATH environment variable]" \ '( -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 version, patchlevel and license]" \ "-V-[print perl configuration information]:configuration keys:_perl_config_vars" \ '( -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' + '-x-[ignore text before #!perl line and optionally cd to directory]:directory to cd to:_files -/' \ + '1:Perl script:_files -g "*.(p[ml]|PL|t)(-.)"' \ + '*::args:= _perl_normal' +} + +_perl_normal() { + local expl + if [[ -z "$opt_args[(I)-(e|E)]" ]]; then + shift words + (( CURRENT-- )) + fi + _normal && ret=0 } _perl_m_opt () { diff --git a/Completion/Unix/Command/_pgrep b/Completion/Unix/Command/_pgrep index e460202a1..3b180ab2d 100644 --- a/Completion/Unix/Command/_pgrep +++ b/Completion/Unix/Command/_pgrep @@ -1,32 +1,71 @@ -#compdef pgrep pkill +#compdef pgrep pkill 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:_groups' - '-s[match only session id]:session id:->sid' +arguments=('-P[parent process id]:parent process id:->ppid' + '-F[match only in process in pidfile]:files:_files' + '-g[match only in process group ids]:group:->pgid' + '-G[match only real group id]:group:_groups' + '-j[match only in processes inside jails]:jail id:->jid' + '-J[match only in project ids]:project id:->projid' + '-M[extract the name list from the specified core]:files:_files' + '-N[extract the name list from the specified system]:files:_files' + '-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') + '-T[match only in processes specified routing table in rtable]' + '-u[match only effective user id]:user:_users' + '-U[match only real user id]:user:_users' + '(-n)-o[oldest process]' + '(-o)-n[newest process]' + '-a[include process ancestors in the match list]' + '-c[print a count of matching processes]' + '-f[match against full command line]' + '-i[ignore case distinctions]' + '-I[confirmation before attempting to single each process]' + '-L[given pidfile must be locked]' + '-q[do not write anything to standard output]' + '-S[search also in system processes]' + '-v[negate matching]' + '-x[match exactly]' + '-z[match only in zones]:zone:_zones') -if [[ $service == 'pkill' ]] -then +if [[ $service == 'pkill' ]]; then arguments+=('-'${^signals}'[signal]') -elif [[ $service == 'pgrep' ]] -then +elif [[ $service == 'pgrep' ]]; then arguments+=('-d[output delimiter]:delimiter:compadd ${(s\:\:)IFS}' '-l[list name in addition to id]') fi +local optchars +case "$OSTYPE" in + linux*) + optchars="cflvxdnoPgsuUGt" + ;; + freebsd*) + optchars="LSafilnoqvxFGMNPUdgjstu" + ;; + openbsd*) + optchars="flnoqvxdGgPsTtUu" + ;; + darwin*) + optchars="LafilnoqvxFGPUdgtu" + ;; + solaris*) + optchars="flvxdnoPgsuUGJtTcz" + arguments=( ${arguments##-T*} ) + arguments=( ${arguments##-c*} ) + arguments+=( '-T[match only processes in task ids]:taskid:->task' ) + arguments+=( '-c[match only processes in contract ids]:taskid:->contract' ) + ;; + *) + optchars="flvxdnoPgsuUGt" + ;; +esac +arguments=( ${(M)arguments:#(|\*)(|\(*\))-[$optchars]*} + '*:process name:->pname') + _arguments -s -w $arguments && ret=0 case $state in @@ -39,23 +78,45 @@ case $state in ttys=( /dev/tty*(N) /dev/pts/*(N) ) _wanted tty expl 'terminal device' compadd -S ',' -q -F used ${ttys#/dev/} ;; - + (sid) + if [[ $OSTYPE == openbsd* ]]; then + break + fi + compset -P '*,' local -a used sid used=(${(s:,:)IPREFIX}) - sid=(${(uon)$(ps -A o sid=)}) + if [[ $OSTYPE == freebsd* ]]; then + sid=(${(uon)$(ps -ax -o sid=)}) + else + sid=(${(uon)$(ps -A -o sid=)}) + fi _wanted sid expl 'session id' compadd -S ',' -q -F used $sid ;; - + + (jid) + compset -P '*,' + + local -a used jid + used=(${(s:,:)IPREFIX}) + jid=(${(uon)$(ps -ax -o jid=)}) + + _wanted jid expl 'jail id' compadd -S ',' -q -F used $jid + ;; + (ppid) compset -P '*,' local -a used ppid used=(${(s:,:)IPREFIX}) - ppid=(${(uon)$(ps -A o ppid=)}) + if [[ $OSTYPE == (freebsd|openbsd|darwin)* ]]; then + ppid=(${(uon)$(ps -ax -o ppid=)}) + else + ppid=(${(uon)$(ps -A -o ppid=)}) + fi _wanted ppid expl 'parent process id' compadd -S ',' -q -F used $ppid ;; @@ -65,25 +126,77 @@ case $state in local -a used pgid used=(${(s:,:)IPREFIX}) - pgid=(${(uon)$(ps -A o pgid=)}) + if [[ $OSTYPE == (freebsd|openbsd|darwin)* ]]; then + pgid=(${(uon)$(ps -ax -o pgid=)}) + else + pgid=(${(uon)$(ps -A -o pgid=)}) + fi _wanted pgid expl 'process group id' compadd -S ',' -q -F used $pgid ;; - + + (projid) + compset -P '*,' + + local -a used projid + used=(${(s:,:)IPREFIX}) + projid=(${(uon)$(ps -A -o project=)}) + + _wanted projid expl 'project id' compadd -S ',' -q -F used $projid + ;; + + (contract) + compset -P '*,' + + local -a used ctid + used=(${(s:,:)IPREFIX}) + ctid=(${(uon)$(ps -A -o ctid=)}) + + _wanted ctid expl 'contract id' compadd -S ',' -q -F used $ctid + ;; + + (task) + compset -P '*,' + + local -a used taskid + used=(${(s:,:)IPREFIX}) + taskid=(${(uon)$(ps -A -o project=)}) + + _wanted taskid expl 'task id' compadd -S ',' -q -F used $taskid + ;; + (pname) local ispat="pattern matching " - if (( ${+opt_args[-x]} )) - then + 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=)"}} + + local command + if (( ${+opt_args[-f]} )); then + if [[ "$OSTYPE" == freebsd* ]] && (( ${+opt_args[-S]} )); then + command="$(ps -axH -o command=)" + elif [[ "$OSTYPE" == (freebsd|openbsd|darwin)* ]]; then + command="$(ps -ax -o command=)" + elif [[ "$OSTYPE" == solaris* ]]; then + command="$(ps -A -o args=)" + else + command="$(ps -A o cmd=)" + fi + _wanted pname expl $ispat'process command line' compadd ${(u)${(f)${command}}} else - _wanted pname expl $ispat'process name' compadd ${(u)${(f)"$(ps -A co cmd=)"}} + if [[ "$OSTYPE" == freebsd* ]] && (( ${+opt_args[-S]} )); then + command="$(ps -axcH -o command=)" + elif [[ "$OSTYPE" == (freebsd|openbsd|darwin)* ]]; then + command="$(ps -axc -o command=)" + elif [[ "$OSTYPE" == solaris* ]]; then + command="$(ps -A -o comm=)" + else + command="$(ps -A co cmd=)" + fi + _wanted pname expl $ispat'process name' compadd ${(u)${(f)${command}}} fi ;; - + esac && ret=0 return ret diff --git a/Completion/Unix/Command/_php b/Completion/Unix/Command/_php index bbb6a667b..5d7b84e28 100644 --- a/Completion/Unix/Command/_php +++ b/Completion/Unix/Command/_php @@ -7,7 +7,10 @@ local curcontext="$curcontext" line state expl typeset -A opt_args local -a args -local exclusions php_files=':PHP file:_files -g "*.php(-.)"' +local exclusions php_suffix + +zstyle -s ":completion:$curcontext" suffixes php_suffix '|' || php_suffix='php|phar' +local php_files=":PHP file:_files -g '*.($php_suffix)(-.)'" if _pick_variant php5=PHP\ 5 php4 --version; then exclusions="-B --process-begin -R --process-code -F --process-file -E --process-end" diff --git a/Completion/Unix/Command/_python b/Completion/Unix/Command/_python index ca1ed37fd..8e32bdf55 100644 --- a/Completion/Unix/Command/_python +++ b/Completion/Unix/Command/_python @@ -1,7 +1,7 @@ -#compdef python +#compdef python python2 python2.4 python2.5 python2.6 python2.7 python3.0 python3.1 python3.2 python3.3 python3.4 -# Python 2.6 -# Python 3.0 +# Python 2.7 +# Python 3.4 local curcontext="$curcontext" state line expl typeset -A opt_args @@ -12,9 +12,12 @@ if _pick_variant python3=Python\ 3 python2 --version; then args=( '(-bb)-b[issue warnings about str(bytes_instance), str(bytearray_instance) and comparing bytes/bytearray with str]' '(-b)-bb[issue errors about str(bytes_instance), str(bytearray_instance) and comparing bytes/bytearray with str]' + "-I[isolate Python from the user's environment]" + '-X[set implementation-specific option]:option' ) else args=( + '-R[use a pseudo-random salt to make hash values unpredeictable]' '-Q+[division options]:division option:(old warn warnall new)' '(-tt)-t[issue warnings about inconsistent tab usage]' '(-t)-tt[issue errors about inconsistent tab usage]' @@ -24,12 +27,12 @@ fi _arguments -C -s -S "$args[@]" \ "-B[don't write .py\[co\] files on import]" \ - '(1 -)-c+[program passed in as string (terminates option list)]:python command:' \ + '(1 -)-c+[program passed in as string (terminates option list)]:python command' \ '-d[debug output from parser]' \ '-E[ignore PYTHON* environment variables (such as PYTHONPATH)]' \ '(1 * -)-h[display help information]' \ '-i[inspect interactively after running script]' \ - '(1 * -)-m[run library module as a script (terminates option list)]:module:->modules' \ + '(1 -)-m[run library module as a script (terminates option list)]:module:->modules' \ '-O[optimize generated bytecode slightly]' \ '-OO[remove doc-strings in addition to the -O optimizations]' \ "-s[don't add user site directory to sys.path]" \ @@ -39,16 +42,25 @@ _arguments -C -s -S "$args[@]" \ '(1 * -)-V[display version information]' \ '-W+[warning control]:warning filter (action\:message\:category\:module\:lineno):(default always ignore module once error)' \ '-x[skip first line of source, allowing use of non-Unix forms of #!cmd]' \ - '(-)1:script file:_files -g "*.py(|c|o)(-.)"' \ - '*::script argument: _normal' && return + '(-)1:Python script:_files -g "*.py(|c|o)(-.)"' \ + '*::script argument:= ->normal' && return -if [[ "$state" = modules ]]; then - local -a modules - modules=( - ${${=${(f)"$(_call_program modules $words[1] -c \ - 'from\ pydoc\ import\ help\;\ help\(\"modules\"\)')"}[2,-3]}:#\(package\)} - ) - _wanted modules expl module compadd -a modules && return -fi +case "$state" in + modules) + local -a modules + modules=( + ${${=${(f)"$(_call_program modules $words[1] -c \ + 'from\ pydoc\ import\ help\;\ help\(\"modules\"\)')"}[2,-3]}:#\(package\)} + ) + _wanted modules expl module compadd -a modules && return + ;; + normal) + if [[ -z "$opt_args[(I)-(c|m)]" ]]; then + shift words + (( CURRENT-- )) + fi + _normal && return + ;; +esac return 1 diff --git a/Completion/Unix/Command/_qemu b/Completion/Unix/Command/_qemu index 8ba7140a1..db07eba33 100644 --- a/Completion/Unix/Command/_qemu +++ b/Completion/Unix/Command/_qemu @@ -47,7 +47,7 @@ _arguments \ '-S[do not start CPU at startup]' \ '-d[output log in /tmp/qemu.log]:log items:_qemu_log_items' \ '-hdachs[force hard disk 0 geometry (usually qemu can guess it)]:hd0 geometry c,h,s:' \ - '-std-vga[simulate standard VGA]' \ + '-vga[select video card type]:card type:(std cirrus vmware qxl xenfb none)' \ '-no-acpi[disable ACPI]' \ '-loadvm[start right away with a saved state]:file:_files' \ '-g[set initial graphic mode]:graphic mode:' \ diff --git a/Completion/Unix/Command/_rm b/Completion/Unix/Command/_rm index 20f44afc5..1f156c481 100644 --- a/Completion/Unix/Command/_rm +++ b/Completion/Unix/Command/_rm @@ -32,13 +32,9 @@ _arguments -C $opts \ case $state in (file) - declare -a ignored - ignored=() - ((CURRENT > 1)) && - ignored+=(${line[1,CURRENT-1]//(#m)[\[\]()\\*?#<>~\^]/\\$MATCH}) - ((CURRENT < $#line)) && - ignored+=(${line[CURRENT+1,-1]//(#m)[\[\]()\\*?#<>~\^]/\\$MATCH}) - _files -F ignored && ret=0 + line[CURRENT]=() + line=( ${line//(#m)[\[\]()\\*?#<>~\^\|]/\\$MATCH} ) + _files -F line && ret=0 ;; esac diff --git a/Completion/Unix/Command/_ruby b/Completion/Unix/Command/_ruby index 03f4e60c7..946ebe270 100644 --- a/Completion/Unix/Command/_ruby +++ b/Completion/Unix/Command/_ruby @@ -1,43 +1,78 @@ -#compdef ruby -P -value-,RUBY(LIB|OPT|PATH),-default- +#compdef ruby irb erb -P (ruby|[ei]rb)[0-9.]# -value-,RUBY(LIB|OPT|PATH),-default- -# ruby 1.8.2 (2004-12-25) [i686-linux] - -local curcontext="$curcontext" state line expl ret=1 +local curcontext="$curcontext" state line expl desc RUBY ret=1 typeset -A opt_args +local -a opts irb all common charsets suf -local -a args opts +all=( + '*-r+[require the library before executing your script]:library name:->library' + '(--internal-encoding)-U[set internal encoding to UTF-8]' + '(-E --encoding -K --external-encoding)'{-E+,--encoding=}'[specify default external and internal character encodings]:charset:->charsets' + '(1 * -)'{-h,--help}'[print help message]' + '(1 * -)--version[print the version]' +) -args=( - '(-)1:script file:_files' - '*::script argument: _normal' +common=( + '*-I+[specify $LOAD_PATH directory (may be used more than once)]:library directory:_files -/' + '-w[turn warnings on for your script]' + '-W-[set warning level]:warning level:((0\:silent 1\:medium 2\:verbose))' + '(-)1:ruby script:_files -g "*.rb(-.)"' + '*::script argument:= ->normal' ) opts=( - '-0-[specify record separator]:input record separator in octal (default \0):' + '-0-[specify record separator]:input record separator in octal [default \0]' '-a[autosplit mode with -n or -p (splits $_ into $F)]' '-c[check syntax only]' - '-C+[cd to directory, before executing your script]:directory:_files -/' + '-C+[cd to directory before executing your script]:directory:_files -/' '(-d --debug)'{-d,--debug}'[set debugging flags (set $DEBUG to true)]' - "(1)*-e+[one line of script (several -e's allowed, omit program file)]:one line of script:" + "(1)*-e+[one line script (several -e's allowed, omit program file)]:one line of script" '-F-[split() pattern for autosplit (-a)]:input field separator:' '-i-[edit ARGV files in place (make backup if extension supplied)]:suffix for in-place-edit mode:(.bak)' - '*-I+[specify $LOAD_PATH directory (may be used more than once)]:library directory:_files -/' '-K-[specifies KANJI (Japanese) code-set]:KANJI encoding:((e\:EUC-JP s\:Shift_JIS u\:UTF-8 N\:None))' "-l[assume 'while gets(); ... end' loop around your script]" "(-p)-n[assume 'while gets(); ... end' loop around your script]" '(-n)-p[assume loop like -n but print line also like sed]' - '*-r+[require the library, before executing your script]:library name:->library' '-s[enable some switch parsing for switches after script name]' '-S[look for the script using PATH environment variable]' - '-T-[turn on tainting checks]:taint level (default 0):((0\:strings\ from\ streams/environment/ARGV\ are\ tainted 1\:no\ dangerous\ operation\ by\ tainted\ value 2\:process/file\ operations\ prohibited 3\:all\ generated\ objects\ are\ tainted 4\:no\ global\ \(non-tainted\)\ variable\ modification/no\ direct\ output))' + '-T-[turn on tainting checks]:taint level:((0\:strings\ from\ streams/environment/ARGV\ are\ tainted 1\:no\ dangerous\ operation\ by\ tainted\ value 2\:process/file\ operations\ prohibited 3\:all\ generated\ objects\ are\ tainted 4\:no\ global\ \(non-tainted\)\ variable\ modification/no\ direct\ output))' '(-v --verbose)'{-v,--verbose}'[print version number, then turn on verbose mode]' - '-w[turn warnings on for your script]' - '-W-[set warning level]:warning level (default 2):((0\:silent 1\:medium 2\:verbose))' - '(-y --yydebug)'{-y,--yydebug}'[enable yacc debugging in the parser]' '-x-[strip off text before #!ruby line and perhaps cd to directory]:directory:_files -/' '(1 * -)--copyright[print the copyright]' - '(1 * -)'{-h,--help}'[print help message]' - '(1 * -)--version[print the version]' + --{en,dis}able-{gems,rubyopt,all} + --{external,internal}'-encoding=:charset:->charsets' + '!'{-y,--yydebug} + '!--dump=:target:(version copyright usage yydebug syntax parsetree parsetree_with_comment insns)' +) + +irb=( + '-f[suppress read of ~/.irbrc]' + '(--noinspect)-m[bc mode (load mathn, fraction, matrix)]' + $opts[(r)*-d\[*] + '(--noinspect)--inspect[use inspect for output]' + "(--inspect)--noinspect[don't use inspect for output]" + '(--noreadline)--readline[use readline extension]' + "(--readline)--noreadline[don't use readline extension]" + '(--prompt --prompt-mode --inf-ruby-mode --simple-prompt --noprompt)'{--prompt,--prompt-mode}'[switch prompt mode]:prompt mode:(default simple xmp inf-ruby)' + '(--prompt --prompt-mode --inf-ruby-mode --simple-prompt --noprompt)'{--inf-ruby-mode,--simple-prompt,--noprompt} + '--tracer[display trace for each command execution]' + '--back-trace-limit[set limit for backtraces]:limit [16]:' + '!--irb_debug:level' + '--context-mode:n' + '(--noecho)--echo[show result]' + "(--echo)--noecho[don't show result]" + '--single-irb[share self with sub-irb]' + '(--noverbose)--verbose[show details]' + "(--verbose)--noverbose[don't show details]" +) + +erb=( + "-P[don't evaluate lines which start with %]" + '-S[specify safe level for running script]:level:(1 2 3 4)' + '-T[specify trim mode]:mode [0]:((0\:EOL\ remains 1\:EOL\ removed\ if\ line\ ends\ with\ %\> 2\:EOL\ removed\ if\ line\ starts\ with\ \<%\ and\ ends\ with\ %\> -\:EOL\ is\ removed\ if\ line\ ends\ with\ -%\>,\ leading\ whitespace\ removed\ after\ \<%-))' + '(-d --debug)'{-d,--debug}'[set debugging flags (set $DEBUG to true)]' + '-n[used with -x, prepends line number to output]' + '-x[convert eRuby to Ruby]' ) case "$service" in @@ -49,22 +84,48 @@ case "$service" in words=( fake "$words[@]" ) (( CURRENT++ )) _arguments -C -s : "${(@M)opts:#*-[IdvwrK](|[-+])\[*}" && ret=0 + RUBY=ruby + ;; + ruby[0-9.]#) + RUBY=$words[1] + _arguments -C -s -S : $opts $all $common && ret=0 + ;; + irb[0-9.]#) + RUBY=${words[1]/irb/ruby} + _arguments -C -s : $irb $all $common && ret=0 ;; - ruby) - _arguments -C -s -S : "$opts[@]" "$args[@]" && ret=0 + erb[0-9.]#) + RUBY=${words[1]/irb/ruby} + _arguments -C -s : $erb $all \ + '*:erb file:_files -g "*.erb(-.)"' && ret=0 ;; esac case "$state" in + normal) + if (( ! $+opt_args[-e] )); then + shift words + (( CURRENT-- )) + fi + _normal && ret=0 + ;; + charsets) + charsets=( $(_call_program charsets $RUBY -e 'puts\ Encoding.list' 2>/dev/null) ) + # could also add Encoding.aliases.map(&:first) for aliases + desc='charset' + if [[ $curcontext = *option-E-1 ]]; then + if compset -P '*:'; then + desc='internal charset' + else + desc='external charset' + compset -S ':*' || suf=( -S: ) + fi + fi + _wanted charsets expl $desc compadd $suf -a charsets && ret=0 + ;; library) local -a dirs - local cmd - if [[ "$service" = *RUBYOPT* ]]; then - cmd=ruby - else - cmd=$words[1] - fi - dirs=( $(_call_program directories $cmd -e 'puts\ \$:' 2>/dev/null) ${(s.:.)opt_args[-I]} ) + dirs=( $(_call_program libraries $RUBY -e 'puts\ \$:' 2>/dev/null) ${(s.:.)opt_args[-I]} ) _wanted libraries expl library _path_files -W dirs && ret=0 ;; esac diff --git a/Completion/Unix/Command/_ssh b/Completion/Unix/Command/_ssh index 3e499b8d0..2be5672da 100644 --- a/Completion/Unix/Command/_ssh +++ b/Completion/Unix/Command/_ssh @@ -108,7 +108,7 @@ _ssh () { _arguments \ '-q[silence ssh-keygen]' \ "($cmds -P)-b[specify number of bits in key]:bits in key" \ - "($cmds -P)-t[specify the type of the key to create]:key type:(rsa1 rsa dsa ecdsa)" \ + "($cmds -P)-t[specify the type of the key to create]:key type:(rsa1 rsa dsa ecdsa ed25519)" \ "(${cmds#-p })-N[provide new passphrase]:new passphrase" \ "($cmds -b -t)-C[provide new comment]:new comment" \ '(-D)-f[key file]:key file:_files' \ @@ -223,6 +223,7 @@ _ssh () { 'ecdsa-sha2-nistp256-cert-v01@openssh.com' \ 'ecdsa-sha2-nistp384-cert-v01@openssh.com' \ 'ecdsa-sha2-nistp521-cert-v01@openssh.com' \ + 'ssh-ed25519-cert-v01@openssh.com' \ 'ssh-rsa-cert-v01@openssh.com' \ 'ssh-dss-cert-v01@openssh.com' \ 'ssh-rsa-cert-v00@openssh.com' \ @@ -230,6 +231,7 @@ _ssh () { 'ecdsa-sha2-nistp256' \ 'ecdsa-sha2-nistp384' \ 'ecdsa-sha2-nistp521' \ + 'ssh-ed25519' \ 'ssh-rsa' \ 'ssh-dss' && ret=0 ;; diff --git a/Completion/Unix/Command/_tmux b/Completion/Unix/Command/_tmux index a8f133295..5a4a2d71f 100644 --- a/Completion/Unix/Command/_tmux +++ b/Completion/Unix/Command/_tmux @@ -573,12 +573,13 @@ function _tmux-new-session() { local -a args args=( '-d[do not attach new session to current terminal]' + '-A[attach to existing session if it already exists]' '-n[name the initial window]:window name' - '-s[name the session]:session name' + '-s[name the session]:session name:__tmux-sessions' '-t[specify target session]:sessions:__tmux-sessions' '*:: :_command' ) - _arguments ${args} + _arguments -s ${args} } function _tmux-new-window() { diff --git a/Completion/Unix/Command/_zfs b/Completion/Unix/Command/_zfs index a9707ce36..cd5ad3edc 100644 --- a/Completion/Unix/Command/_zfs +++ b/Completion/Unix/Command/_zfs @@ -221,7 +221,7 @@ _zfs() { ("create") _arguments -A "-*" \ '-p[Create parent datasets]' \ - '-o[Set initial properties]:property:_values -s , "property" $create_properties' \ + '*-o[Set initial properties]:property:_values -s , "property" $create_properties' \ - set1 \ ':filesystem:_zfs_dataset -t fs -e "parent dataset"' \ - set2 \ @@ -246,7 +246,7 @@ _zfs() { ("snapshot") _arguments -A "-*" \ '-r[Recursively snapshot all descendant datasets]' \ - '-o[Set property]:property:_values -s , "property" $create_properties' \ + '*-o[Set property]:property:_values -s , "property" $create_properties' \ ':filesystem/volume:_zfs_dataset -t fs -t vol -S@' ;; @@ -263,7 +263,7 @@ _zfs() { _arguments -A "-*" \ '-p[Create parent datasets]' \ '-K[Create encryption key]' \ - '-o[Set property]:property:_values -s , "property" $create_properties' \ + '*-o[Set property]:property:_values -s , "property" $create_properties' \ ':snapshot:_zfs_dataset -t snap' \ ':filesystem/volume:_zfs_dataset -t fs -e "parent dataset"' ;; diff --git a/Completion/Unix/Type/_path_files b/Completion/Unix/Type/_path_files index aa58ea09b..85feae54c 100644 --- a/Completion/Unix/Type/_path_files +++ b/Completion/Unix/Type/_path_files @@ -564,9 +564,10 @@ for prepath in "$prepaths[@]"; do ( "$ignpar" != *dir* || "$pats" = '*(-/)' ) && ( "$ignpar" != *..* || "$tmp1[1]" = *../* ) ]]; then - compfiles -i tmp1 _comp_ignore "$ignpar" "$prepath$realpath$donepath" + compfiles -i tmp1 ignore "$ignpar" "$prepath$realpath$donepath" + _comp_ignore+=( ${(@)ignore#$prepath$realpath$donepath} ) - (( $#_comp_ignore && $mopts[(I)-F] )) || + (( $#_comp_ignore && ! $mopts[(I)-F] )) && mopts=( "$mopts[@]" -F _comp_ignore ) fi diff --git a/Completion/X/Command/_x_utils b/Completion/X/Command/_x_utils index 0ff0cf268..9448fd3df 100644 --- a/Completion/X/Command/_x_utils +++ b/Completion/X/Command/_x_utils @@ -69,7 +69,7 @@ xev) '-rv' ;; xhost) - local expl type ret=1 tmp match + local type tmp match if compset -P '-'; then tmp=(${(f)"$(xhost)"}) diff --git a/Completion/Zsh/Command/_typeset b/Completion/Zsh/Command/_typeset index 0920e3fb5..f876e1beb 100644 --- a/Completion/Zsh/Command/_typeset +++ b/Completion/Zsh/Command/_typeset @@ -91,13 +91,13 @@ if [[ "$state" = vars_eq ]]; then _wanted functions expl 'shell function' compadd -a args elif [[ -n $onopts$offopts ]]; then if [[ -n $offopts ]]; then - args=(${(f)"$(functions +$offopts)"}) + args=(${(f)"$(functions +${offopts//[^UXkmtTuz]/})"}) else args=(${(k)functions}) fi if [[ -n $onopts ]]; then local -a funckeys - funckeys=(${(f)"$(functions +$onopts)"}) + funckeys=(${(f)"$(functions +${onopts//[^UXkmtTuz]/})"}) args=(${args:|funckeys}) fi if zstyle -t ":completion:${curcontext}:functions" prefix-needed && diff --git a/Completion/Zsh/Command/_zstyle b/Completion/Zsh/Command/_zstyle index 708c0fddf..eb27117b2 100644 --- a/Completion/Zsh/Command/_zstyle +++ b/Completion/Zsh/Command/_zstyle @@ -182,6 +182,8 @@ styles=( disable v:vcs disable-patterns v: check-for-changes v:bool + check-for-staged-changes + v:bool stagedstr v: unstagedstr v: command v:_command_names diff --git a/Completion/Zsh/Context/_brace_parameter b/Completion/Zsh/Context/_brace_parameter index c0ecf251b..2aeb12bf4 100644 --- a/Completion/Zsh/Context/_brace_parameter +++ b/Completion/Zsh/Context/_brace_parameter @@ -185,6 +185,9 @@ if [[ $PREFIX = *'${('[^\)]# ]]; then ) _describe -t flags "parameter flag" flags -Q -S '' return +elif compset -P '*:'; then + _history_modifiers p + return fi _parameters -e diff --git a/Completion/Zsh/Type/_globquals b/Completion/Zsh/Type/_globquals index 9de7742ff..37db161d0 100644 --- a/Completion/Zsh/Type/_globquals +++ b/Completion/Zsh/Type/_globquals @@ -132,13 +132,13 @@ while [[ -n $PREFIX ]]; do (L) # complete/skip file size - if ! compset -P '([kKmMpP]|)([-+]|)<->'; then + if ! compset -P '([kKmMgGtTpP]|)([-+]|)<->'; then # complete/skip size spec alts=() - if ! compset -P '[kKmMpP]' && [[ -z $PREFIX ]]; then + if ! compset -P '[kKmMgGtTpP]' && [[ -z $PREFIX ]]; then alts+=( "size-specifiers:size specifier:\ -((k\:kb m\:mb p\:512-byte\ blocks))") +((k\:kb m\:mb g\:gb t\:tb p\:512-byte\ blocks))") fi if ! compset -P '[-+]' && [[ -z $PREFIX ]]; then alts+=("senses:sense:((-\:less\ than +\:more\ than))") @@ -251,6 +251,7 @@ case $state in "o:+ sort order, up" "O:+ sort order, down" "P:prepend word" + "Y:+ at most ARG matches" "[:+ range of files" "):end of qualifiers" "\::modifier" diff --git a/Completion/Zsh/Type/_parameters b/Completion/Zsh/Type/_parameters index 5156e3e2d..eaad3ca9d 100644 --- a/Completion/Zsh/Type/_parameters +++ b/Completion/Zsh/Type/_parameters @@ -8,6 +8,11 @@ local expl pattern fakes faked tmp pfilt +if compset -P '*:'; then + _history_modifiers p + return +fi + pattern=(-g \*) zparseopts -D -K -E g:=pattern diff --git a/Completion/openSUSE/Command/.distfiles b/Completion/openSUSE/Command/.distfiles index 301ef12b3..995d12e36 100644 --- a/Completion/openSUSE/Command/.distfiles +++ b/Completion/openSUSE/Command/.distfiles @@ -2,7 +2,7 @@ DISTFILES_SRC=' .distfiles _hwinfo _osc -_SuSEconfig +_SUSEconfig _yast2 _zypper ' diff --git a/Completion/openSUSE/Command/_SuSEconfig b/Completion/openSUSE/Command/_SUSEconfig index d50828529..d50828529 100644 --- a/Completion/openSUSE/Command/_SuSEconfig +++ b/Completion/openSUSE/Command/_SUSEconfig diff --git a/Completion/openSUSE/Command/_zypper b/Completion/openSUSE/Command/_zypper index 4f2477a41..25a32c3f1 100644 --- a/Completion/openSUSE/Command/_zypper +++ b/Completion/openSUSE/Command/_zypper @@ -1,6 +1,8 @@ #compdef zypper # # Copyright (C) 2009 Holger Macht <holger@homac.de> +# Copyright (C) 2014 Thomas Mitterfellner <thomas.mitterfellner@gmail.com> +# Copyright (C) 2014 Mariusz Fik <fisiu@opensuse.org> # # This file is released under the GPLv2. # @@ -9,60 +11,171 @@ # Toggle verbose completions: zstyle ':completion:*:zypper:*' verbose no # zstyle ':completion:*:zypper-subcommand:*' verbose no # -# version 0.1 +# version 0.3 # # Main dispatcher +function _zypper_caching_policy () { + # rebuild if zsh's cache is older than zypper's + if test /var/cache/zypp/raw -nt "$1"; then + return 0 + else + return 1 + fi +} + _zypper() { + typeset -A opt_args + local context curcontext="$curcontext" state line + if (( CURRENT > 2 )) && [[ ${words[2]} != "help" ]]; then # Remember the subcommand name - local cmd=${words[2]} + local cmd=${words[2]} # Set the context for the subcommand. - curcontext="${curcontext%:*:*}:zypper-subcommand" + curcontext="${curcontext%:*:*}:zypper-subcommand" # Narrow the range of words we are looking at to exclude `zypper' - (( CURRENT-- )) - shift words - - _zypper_cmd_do $cmd + (( CURRENT-- )) + shift words + + _zypper_cmd_do $cmd else - local hline - local -a cmdlist - local tag=0 - _call_program help-commands LANG=C zypper help | sed -e ':a;N;$!ba;s/\n\t\t\t\t/ /g' | while read -A hline; do - # start parsing with "Global Options:" - [[ $hline =~ "^Global Options:" ]] && tag=1 - [[ $tag = 0 ]] && continue - # all commands have to start with lower case letters - [[ $hline[1] =~ ^[A-Z] ]] && continue - (( ${#hline} < 2 )) && continue - - # cut comma at end of command - hline[1]=`echo $hline[1] | sed -e 's/\(^.*\),/\1/'` - - # ${hline[1]%,} truncates the last ',' - cmdlist=($cmdlist "${hline[1]%,}:${hline[2,-1]}") - done - _describe -t zypper-commands 'zypper command' cmdlist + local hline + local -a cmdlist + local tag=0 + _call_program help-commands LANG=C zypper help | sed -e ':a;N;$!ba;s/\n\t\t\t\t/ /g' | while read -A hline; do + # start parsing with "Global Options:" + [[ $hline =~ "^Global Options:" ]] && tag=1 + [[ $tag = 0 ]] && continue + # skip empty lines + [[ $hline =~ ^\s*$ ]] && continue + # all commands have to start with lower case letters + [[ $hline == [[:upper:]]* ]] && continue + (( ${#hline} < 2 )) && continue + + # cut comma at end of command + hline[1]=`echo $hline[1] | sed -e 's/\(^.*\),/\1/'` + + # ${hline[1]%,} truncates the last ',' + cmdlist=($cmdlist "${hline[1]%,}:${hline[2,-1]}") + done + _describe -t zypper-commands 'zypper command' cmdlist fi } +_all_repos() { + local -a repos + repos=( $(zypper -q lr | tail -n +3 | cut -d'|' -f 2) ) + _describe -t repos 'Available repositories' repos && return +} + +_enabled_repos() { + repos=( $(zypper -x lr | grep 'enabled="1"' | cut -d\" -f 2) ) + _describe -t repos 'Available repositories' repos && return +} + +_disabled_repos() { + repos=( $(zypper -x lr | grep 'enabled="0"' | cut -d\" -f 2) ) + _describe -t repos 'Available repositories' repos && return +} + _zypper_cmd_do() { + typeset -A opt_args + local context state line local hline local -a cmdlist local tag=0 + local curcontext="$curcontext" + + zstyle ":completion:${curcontext}:" use-cache on + zstyle ":completion:${curcontext}:" cache-policy _zypper_caching_policy + _call_program help-commands LANG=C zypper help $cmd | while read -A hline; do - # start parsing from "Options:" - [[ $hline =~ "^Command options:" ]] && tag=1 - [[ $tag = 0 ]] && continue - # Option has to start with a '-' - [[ $hline[1] =~ ^- ]] || continue - (( ${#hline} < 2 )) && continue - - cmdlist=($cmdlist "${hline[1]%,}:${hline[2,-1]}") + # start parsing from "Options:" + [[ $hline =~ "^Command options:" ]] && tag=1 + [[ $tag = 0 ]] && continue + # Option has to start with a '-' + [[ $hline[1] =~ ^- ]] || continue + (( ${#hline} < 2 )) && continue + + cmdlist=($cmdlist "${hline[1]%,}:${hline[2,-1]}") done if [ -n "$cmdlist" ]; then + local -a repos + + # special completion lists for certain options (mainly repos) + case ${words[CURRENT - 1]} in + --from) + repos=( $(zypper -x lr | grep 'enabled="1"' | cut -d\" -f 2) ) + _describe -t repos 'Available repositories' repos && return + ;; + (--enable|-e) + case $cmd in + (mr|modifyrepo) + _disabled_repos && return + ;; + esac + ;; + (--disable|-d) + case $cmd in + (mr|modifyrepo) + _enabled_repos && return + ;; + esac + ;; + (--type|-t) + local -a types + case $cmd in + (if|info|se|search|in|install) + types=( pattern srcpackage package patch ) + _describe -t types 'Package types' types && return + ;; + esac + ;; + esac + + # all options available for the active main command _describe -t zypper-commands 'zypper command' cmdlist + + case $cmd in + (lr|repos) + _all_repos + ;; + (in|install) + local expl + _description files expl 'RPM files' + _files "$expl[@]" -g '*.(#i)rpm(.)' + ;; + esac + + # only suggest packages if at least one character is given + if [[ ${words[CURRENT]} =~ "^[0-9a-zA-Z]" ]] ; then + local -a pkglist + + if ( [[ ${+_zypp_all_raw} -eq 0 ]] || _cache_invalid ZYPPER_ALL_RAW ) && ! _retrieve_cache ZYPPER_ALL_RAW; + then + _zypp_all_raw=$(zypper -x -q se | grep '<solvable' | cut -d \" -f 2,4) + _zypp_all=( $(echo $_zypp_all_raw | grep 'installed' | cut -d\" -f 2) ) + _zypp_not_installed=( $(echo $_zypp_all_raw | grep 'not-installed' | cut -d\" -f 2 ) ) + _zypp_installed=( $(echo $_zypp_all_raw | grep '^installed' | cut -d\" -f 2 ) ) + _store_cache ZYPPER_ALL_RAW _zypp_all_raw _zypp_all _zypp_not_installed _zypp_installed + fi + + case $cmd in + (in|install) + pkglist=( $_zypp_not_installed ) + compadd $pkglist && return + ;; + (rm|remove|up|update) + pkglist=( $_zypp_installed ) + compadd $pkglist && return + ;; + (if|info|se|search) + pkglist=( $_zypp_all ) + compadd $pkglist && return + ;; + esac + fi else _complete fi diff --git a/Config/defs.mk.in b/Config/defs.mk.in index 2c813a3b2..f6ea5c1cd 100644 --- a/Config/defs.mk.in +++ b/Config/defs.mk.in @@ -95,7 +95,7 @@ additionalfpath = @additionalfpath@ MAKEDEFS = \ prefix='$(prefix)' exec_prefix='$(exec_prefix)' bindir='$(bindir)' \ libdir='$(libdir)' MODDIR='$(MODDIR)' infodir='$(infodir)' mandir='$(mandir)' \ -datadir='$(datadir)' fndir='$(fndir)' htmldir='$(htmldir)' \ +datadir='$(datadir)' fndir='$(fndir)' htmldir='$(htmldir)' runhelpdir='$(runhelpdir)' \ CC='$(CC)' CPPFLAGS='$(CPPFLAGS)' DEFS='$(DEFS)' CFLAGS='$(CFLAGS)' \ LDFLAGS='$(LDFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \ DLCFLAGS='$(DLCFLAGS)' DLLDFLAGS='$(DLLDFLAGS)' \ diff --git a/Config/version.mk b/Config/version.mk index 7d49df4f6..f369c18e6 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=5.0.5 -VERSION_DATE='January 5, 2014' +VERSION=5.0.5-dev-1 +VERSION_DATE='August 10, 2014' diff --git a/Doc/Makefile.in b/Doc/Makefile.in index 50e210fcf..c86f34947 100644 --- a/Doc/Makefile.in +++ b/Doc/Makefile.in @@ -41,7 +41,8 @@ LN_S = @LN_S@ MAKEINFO = makeinfo TEXI2DVI = texi2dvi DVIPS = dvips -TEXI2HTML = @TEXI2HTML@ --output . --ifinfo --split=chapter --node-files +TEXI2HTML = @TEXI2HTML@ --output . --ifinfo --split=chapter --node-files \ + --init-file $(sdir)/texi2html.conf .SUFFIXES: .yo .1 @@ -159,7 +160,7 @@ zsh_a4.ps: zsh.dvi html: zsh_toc.html .PHONY: html -zsh_toc.html: $(sdir)/zsh.texi +zsh_toc.html: $(sdir)/zsh.texi $(sdir)/texi2html.conf $(TEXI2HTML) $(sdir)/zsh.texi zshall.1: zsh.yo @@ -191,7 +192,8 @@ help.txt: zshbuiltins.1 @-rm -f $(sdir)/help.txt $(sdir)/help/* perl $(sdir_top)/Util/helpfiles \ $(sdir)/zshbuiltins.1 $(sdir)/help $(sdir)/help.txt \ - || { rm -f $(sdir)/help.txt $(sdir)/help/*; false; } + || rm -f $(sdir)/help.txt $(sdir)/help/* + touch $(sdir)/$@ $(MAN): zmacros.yo zman.yo @@ -247,6 +249,10 @@ version.yo: $(sdir_top)/Config/version.mk echo 'IFDEF(DECWSLEVEL)(DECWSLEVEL())(ENDDEF())#' | tr '#' '\\'; \ ) > $(sdir)/version.yo +texi2html.conf: $(sdir_top)/Config/version.mk + echo '$$PRE_BODY_CLOSE = "<font size=\"-1\">Zsh version $(VERSION), released on $(VERSION_DATE).</font>";' \ + > $(sdir)/$@ + Zsh/modlist.yo: $(MODDOCSRC) ( \ echo "startitem()"; \ @@ -387,6 +393,7 @@ clean-here: rm -f *.aux *.cp *.cps *.fn *.fns *.ky *.log rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs rm -rf infodir + rm -f texi2html.conf .PHONY: clean-here distclean-here: clean-here diff --git a/Doc/Zsh/arith.yo b/Doc/Zsh/arith.yo index 2674c7817..96dc2dc68 100644 --- a/Doc/Zsh/arith.yo +++ b/Doc/Zsh/arith.yo @@ -76,6 +76,27 @@ have output base 16, while tt(x) (assuming it does not already exist) is implicitly typed by the arithmetic evaluation, where it acquires the output base 8. +The var(base) may be replaced or followed by an underscore, which may +itself be followed by a positive integer (if it is missing the value 3 +is used). This indicates that underscores should be inserted into the +output string, grouping the number for visual clarity. The following +integer specifies the number of digits to group together. For example: + +example(setopt cbases +print $(( [#16_4] 65536 ** 2 ))) + +outputs `tt(0x1_0000_0000)'. + +The feature can be used with floating +point numbers, in which case the base must be omitted; grouping +is away from the decimal point. For example, + +example(zmodload zsh/mathfunc +print $(( [#_] sqrt+LPAR()1e7+RPAR() ))) + +outputs `tt(3_162.277_660_168_379_5)' (the number of decimal places +shown may vary). + pindex(C_BASES, use of) pindex(OCTAL_ZEROES, use of) If the tt(C_BASES) option is set, hexadecimal numbers in the standard C diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 8c7bc85ea..f709f5020 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -3,8 +3,6 @@ chapter(Shell Builtin Commands) ifzman(\ sect(Shell Builtin Commands) )\ -cindex(builtin commands) -cindex(commands, builtin) def(prefix)(1)(\ item(tt(ARG1) var(simple command))( See noderef(Precommand Modifiers). @@ -29,6 +27,8 @@ ifnzman(noderef(Zle Builtins)). )\ )\ +cindex(builtin commands) +cindex(commands, builtin) Some shell builtin commands take options as described in individual entries; these are often referred to in the list below as `tt(flags)' to avoid confusion with shell options, which may also have an effect on the @@ -653,7 +653,7 @@ cindex(history, editing) cindex(editing history) xitem(tt(fc) [ tt(-e) var(ename) ] [ tt(-m) var(match) ] [ var(old)tt(=)var(new) ... ] [ var(first) [ var(last) ] ]) xitem(tt(fc) tt(-l) [ tt(-nrdfEiD) ] [ tt(-t) var(timefmt) ] [ tt(-m) var(match) ]) -xitem( [ var(old)tt(=)var(new) ... ] [ var(first) [ var(last) ] ]) +xitem(tt( )[ var(old)tt(=)var(new) ... ] [ var(first) [ var(last) ] ]) xitem(tt(fc) tt(-p) [ tt(-a) ] [ var(filename) [ var(histsize) [ var(savehistsize) ] ] ]) xitem(tt(fc) tt(-P)) item(tt(fc) tt(-ARWI) [ var(filename) ])( @@ -683,6 +683,9 @@ If var(first) is not specified, it will be set to -1 (the most recent event), or to -16 if the tt(-l) flag is given. If var(last) is not specified, it will be set to var(first), or to -1 if the tt(-l) flag is given. +However, if the current event has added entries to the history with +`tt(print -s)' or `tt(fc -R)', then the default var(last) for tt(-l) +includes all new history entries since the current event began. The flag tt(-r) reverses the order of the commands and the flag tt(-n) suppresses command numbers when listing. @@ -1285,8 +1288,7 @@ continuation and backslashes in the line don't quote the following character and are not removed. ) item(tt(-s))( -Don't echo back characters if reading from the terminal. Currently does -not work with the tt(-q) option. +Don't echo back characters if reading from the terminal. ) item(tt(-q))( Read only one character from the terminal and set var(name) to @@ -1500,12 +1502,15 @@ POSIX standard, but tt(setopt) is not. ) findex(shift) cindex(parameters, positional) -item(tt(shift) [ var(n) ] [ var(name) ... ])( +item(tt(shift) [ tt(-p) ] [ var(n) ] [ var(name) ... ])( The positional parameters tt(${)var(n)PLUS()1tt(}) ... are renamed to tt($1) ..., where var(n) is an arithmetic expression that defaults to 1. If any var(name)s are given then the arrays with these names are shifted instead of the positional parameters. + +If the option tt(-p) is given arguments are instead removed (popped) +from the end rather than the start of the array. ) findex(source) item(tt(source) var(file) [ var(arg) ... ])( @@ -1934,6 +1939,9 @@ sitem(tt(-m))(Kilobytes on the size of physical memory.) sitem(tt(-n))(open file descriptors.) sitem(tt(-p))(The number of pseudo-terminals.) sitem(tt(-q))(Bytes in POSIX message queues.) +sitem(tt(-r))(Maximum real time priority. On some systems where this +is not available, such as NetBSD, this has the same effect as tt(-T) +for compatibility with tt(sh).) sitem(tt(-s))(Kilobytes on the size of the stack.) sitem(tt(-T))(The number of simultaneous threads available to the user.) sitem(tt(-t))(CPU seconds to be used.) diff --git a/Doc/Zsh/calsys.yo b/Doc/Zsh/calsys.yo index 7dc51ab11..0d7abbf86 100644 --- a/Doc/Zsh/calsys.yo +++ b/Doc/Zsh/calsys.yo @@ -547,35 +547,36 @@ and status 2 if the wrong number of arguments were passed; it also sets the parameter tt(reply) to an empty associative array. Otherwise, it returns status 0 and sets elements of the associative array tt(reply) as follows: + startsitem() -sitem(time)(The time as a string of digits in the same units as +sitem(tt(time))(The time as a string of digits in the same units as tt($EPOCHSECONDS)) -sitem(schedtime)(The regularly scheduled time. This may differ from +sitem(tt(schedtime))(The regularly scheduled time. This may differ from the actual event time tt(time) if this is a recurring event and the next occurrence has been rescheduled. Then tt(time) gives the actual time and tt(schedtime) the time of the regular recurrence before modification.) -sitem(text1)(The text from the line not including the date and time of the +sitem(tt(text1))(The text from the line not including the date and time of the event, but including any tt(WARN) or tt(RPT) keywords and values.) -sitem(warntime)(Any warning time given by the tt(WARN) keyword as a string +sitem(tt(warntime))(Any warning time given by the tt(WARN) keyword as a string of digits containing the time at which to warn in the same units as tt($EPOCHSECONDS). (Note this is an absolute time, not the relative time passed down.) Not set no tt(WARN) keyword and value were matched.) -sitem(warnstr)(The raw string matched after the tt(WARN) keyword, else unset.) -sitem(rpttime)(Any recurrence time given by the tt(RPT) keyword as a string +sitem(tt(warnstr))(The raw string matched after the tt(WARN) keyword, else unset.) +sitem(tt(rpttime))(Any recurrence time given by the tt(RPT) keyword as a string of digits containing the time of the recurrence in the same units as tt($EPOCHSECONDS). (Note this is an absolute time.) Not set if no tt(RPT) keyword and value were matched.) -sitem(schedrpttime)(The next regularly scheduled occurrence of a recurring +sitem(tt(schedrpttime))(The next regularly scheduled occurrence of a recurring event before modification. This may differ from tt(rpttime), which is the actual time of the event that may have been rescheduled from the regular time.) -sitem(rptstr)(The raw string matched after the tt(RPT) keyword, else unset.) -sitem(text2)(The text from the line after removal of the date and any +sitem(tt(rptstr))(The raw string matched after the tt(RPT) keyword, else unset.) +sitem(tt(text2))(The text from the line after removal of the date and any keywords and values.) ) endsitem() -) + findex(calendar_showdate) item(tt(calendar_showdate) [ tt(-r) ] [ tt(-f) var(fmt) ] var(date-spec ...))( The given var(date-spec) is interpreted and the corresponding date and diff --git a/Doc/Zsh/compat.yo b/Doc/Zsh/compat.yo index bf97fe2ae..f1be15fee 100644 --- a/Doc/Zsh/compat.yo +++ b/Doc/Zsh/compat.yo @@ -6,7 +6,7 @@ cindex(ksh compatibility) Zsh tries to emulate bf(sh) or bf(ksh) when it is invoked as tt(sh) or tt(ksh) respectively; more precisely, it looks at the first letter of the name by which it was invoked, excluding any initial `tt(r)' -(assumed to stand for `restricted'), and if that is `tt(s)' or `tt(k)' it +(assumed to stand for `restricted'), and if that is `tt(b)', `tt(s)' or `tt(k)' it will emulate bf(sh) or bf(ksh). Furthermore, if invoked as tt(su) (which happens on certain systems when the shell is executed by the tt(su) command), the shell will try to find an alternative name from the tt(SHELL) diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index b9038cfa5..8a9f47db1 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -1995,11 +1995,11 @@ only be performed with the `tt(*)' inserted. kindex(matcher, completion style) item(tt(matcher))( This style is tested separately for each tag valid in the current -context. Its value is added to any match specifications given by the +context. Its value is tried before any match specifications given by the tt(matcher-list) style. It should be in the form described in ifzman(the section `Completion Matching Control' in zmanref(zshcompwid))\ ifnzman(noderef(Completion Matching Control))\ -. +. For examples of this, see the description of the tt(tag-order) style. ) kindex(matcher-list, completion style) item(tt(matcher-list))( @@ -2019,12 +2019,14 @@ specification is prefixed with tt(+), it is added to the existing list. Hence it is possible to create increasingly general specifications without repetition: -example(zstyle ':completion:*' matcher-list '' '+m{a-z}={A-Z}' '+m{A-Z}={a-z}') +example(zstyle ':completion:*' matcher-list '' '+m:{a-z}={A-Z}' '+m:{A-Z}={a-z}') It is possible to create match specifications valid for particular -completers by using the third field of the context. For example, to -use the completers tt(_complete) and tt(_prefix) but only allow -case-insensitive completion with tt(_complete): +completers by using the third field of the context. This applies only +to completers that override the global matcher-list, which as of this +writing includes only tt(_prefix) and tt(_ignored). For example, to +use the completers tt(_complete) and tt(_prefix) but allow +case-insensitive completion only with tt(_complete): example(zstyle ':completion:*' completer _complete _prefix zstyle ':completion:*:complete:*' matcher-list \ @@ -2344,7 +2346,7 @@ This is used by the tt(_history) completer and the tt(_history_complete_word) bindable command to decide which words should be completed. -If it is a singe number, only the last var(N) words from the history +If it is a single number, only the last var(N) words from the history will be completed. If it is a range of the form `var(max)tt(:)var(slice)', @@ -2440,6 +2442,15 @@ completing words for the dict command. It allows words from different dictionary databases to be added separately. The default for this style is `false'. ) +kindex(show-ambiguity, completion style) +item(tt(show-ambiguity))( +If the tt(zsh/complist) module is loaded, this style can be used to +highlight the first ambiguous character in completion lists. The +value is either a color indication such as those supported by the +tt(list-colors) style or, with a value of tt(true), a default of +underlining is selected. The highlighting is only applied if the +completion display strings correspond to the actual matches. +) kindex(show-completer, completion style) item(tt(show-completer))( Tested whenever a new completer is tried. If it is true, the completion @@ -3038,6 +3049,15 @@ This function is also a bindable command, see ifzman(the section `Bindable Commands' below)\ ifnzman(noderef(Bindable Commands)). ) +findex(_extensions) +item(tt(_extensions))( +If the cursor follows the string `tt(*.)', filename extensions are +completed. The extensions are taken from files in current directory or a +directory specified at the beginning of the current word. For exact matches, +completion continues to allow other completers such as tt(_expand) to +expand the pattern. The standard tt(add-space) and tt(prefix-hidden) +styles are observed. +) findex(_history) item(tt(_history))( Complete words from the shell's command history. This completer diff --git a/Doc/Zsh/cond.yo b/Doc/Zsh/cond.yo index 9f8a7d820..d04ceb258 100644 --- a/Doc/Zsh/cond.yo +++ b/Doc/Zsh/cond.yo @@ -186,11 +186,44 @@ true if either var(exp1) or var(exp2) is true. ) enditem() +For compatibility, if there is a single argument that is not +syntactically significant, typically a variable, the condition is +treated as a test for whether the expression expands as a string of +non-zero length. In other words, tt([[ $var ]]) is the same as tt([[ -n +$var ]]). It is recommended that the second, explicit, form be used +where possible. + 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. -Filename generation is not performed on any form of argument to conditions. -However, pattern metacharacters are active for the var(pattern) arguments; + +Filename generation is not performed on any form of argument to +conditions. However, it can be forced in any case where normal shell +expansion is valid and when the option tt(EXTENDED_GLOB) is in effect by +using an explicit glob qualifier of the form tt(LPAR()#q+RPAR()) at the +end of the string. A normal glob qualifier expression may appear +between the `tt(q)' and the closing parenthesis; if none appears the +expression has no effect beyond causing filename generation. The +results of filename generation are joined together to form a single +word, as with the results of other forms of expansion. + +This special use of filename generation is only available with the +tt([[) syntax. If the condition occurs within the tt([) or tt(test) +builtin commands then globbing occurs instead as part of normal command +line expansion before the condition is evaluated. In this case it may +generate multiple words which are likely to confuse the syntax of the +test command. + +For example, + +tt([[ -n file*(#qN) ]]) + +produces status zero if and only if there is at least one file in the +current directory beginning with the string `tt(file)'. The globbing +qualifier tt(N) ensures that the expression is empty if there is +no matching file. + +Pattern metacharacters are active for the var(pattern) arguments; the patterns are the same as those used for filename generation, see ifzman(\ zmanref(zshexpn)\ diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index bb6613ece..1c1a66a3b 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -45,9 +45,8 @@ shell features as well. The autoloadable tt(run-help) function, found in tt(Functions/Misc), searches for these helpfiles and performs several other tests to produce the most complete help possible for the command. -There may already be a directory of help files on your system; look in -tt(/usr/share/zsh) or tt(/usr/local/share/zsh) and subdirectories below -those, or ask your system administrator. +Help files are installed by default to a subdirectory of tt(/usr/share/zsh) +or tt(/usr/local/share/zsh). To create your own help files with tt(helpfiles), choose or create a directory where the individual command help files will reside. For @@ -55,22 +54,22 @@ example, you might choose tt(~/zsh_help). If you unpacked the zsh distribution in your home directory, you would use the commands: example(mkdir ~/zsh_help -cd ~/zsh_help -man zshall | colcrt - | \ -perl ~/zsh-version()/Util/helpfiles) +perl ~/zsh-version()/Util/helpfiles ~/zsh_help) + +vindex(HELPDIR) +The tt(HELPDIR) parameter tells tt(run-help) where to look for the help +files. When unset, it uses the default installation path. +To use your own set of help files, set this to the appropriate path +in one of your startup files: + +example(HELPDIR=~/zsh_help) findex(run-help, use of) -Next, to use the tt(run-help) function, you need to add lines something +To use the tt(run-help) function, you need to add lines something like the following to your tt(.zshrc) or equivalent startup file: example(unalias run-help -autoload run-help -HELPDIR=~/zsh_help) - -vindex(HELPDIR) -The tt(HELPDIR) parameter tells tt(run-help) where to look for the help -files. If your system already has a help file directory installed, set -tt(HELPDIR) to the path of that directory instead. +autoload run-help) Note that in order for `tt(autoload run-help)' to work, the tt(run-help) file must be in one of the directories named in your tt(fpath) array (see @@ -827,17 +826,32 @@ 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 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). +styles. The only backends that currently support this option are tt(git), +tt(hg), and tt(bzr) (the latter two only support unstaged). 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. +With the tt(bzr) backend, em(lightweight checkouts) only honor this style if +the tt(use-server) style is set. + Note, the actions taken if this style is enabled are potentially expensive (read: they may be slow, depending on how big the current repository is). Therefore, it is disabled by default. ) +kindex(check-for-staged-changes) +item(tt(check-for-staged-changes))( +This style is like tt(check-for-changes), but it never checks the worktree +files, only the metadata in the tt(.${vcs}) dir. Therefore, +this style initializes only the tt(%c) escape (with tt(stagedstr)) but +not the tt(%u) escape. This style is faster than tt(check-for-changes). + +In the tt(git) backend, this style checks for changes in the index. +Other backends do not currently implement this style. + +This style is disabled by default. +) kindex(stagedstr) item(tt(stagedstr))( This string will be used in the tt(%c) escape if there are staged changes in @@ -863,7 +877,7 @@ when this style is looked up. For example, this style can be used to use binaries from non-default installation directories. Assume, tt(git) is installed in /usr/bin but -your sysadmin installed a newer version in /usr/bin/local. Instead of +your sysadmin installed a newer version in /usr/local/bin. 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) ) @@ -881,6 +895,9 @@ backend is only usable if you have set the environment variable tt(P4CONFIG) to a file name and have corresponding files in the root directories of each Perforce client. See comments in the function tt(VCS_INFO_detect_p4) for more detail. + +The Bazaar backend (tt(bzr)) uses this to permit contacting the server +about lightweight checkouts, see the tt(check-for-changes) style. ) kindex(use-simple) item(tt(use-simple))( @@ -942,6 +959,7 @@ sitem(tt(enable))(ALL) sitem(tt(disable))((empty list)) sitem(tt(disable-patterns))((empty list)) sitem(tt(check-for-changes))(false) +sitem(tt(check-for-staged-changes))(false) sitem(tt(stagedstr))((string: "S")) sitem(tt(unstagedstr))((string: "U")) sitem(tt(command))((empty string)) @@ -1321,6 +1339,11 @@ This hooks is called when no version control system was detected. The `hook_com' parameter is not used. ) +item(tt(post-backend))( +Called as soon as the backend has finished collecting information. + +The `tt(hook_com)' keys available are as for the tt(set-message) hook. +) item(tt(post-quilt))( Called after the tt(quilt) support is done. The following information is passed as arguments to the hook: 1. the quilt-support mode (`addon' or @@ -1481,22 +1504,15 @@ function +vi-hgbookmarks+LPAR()RPAR() { # This makes the bookmarks string use only those # bookmarks. If there's more than one, it # concatenates them using commas. - local s i # The bookmarks returned by `hg' are available in - # the functions positional parameters. - (( $# == 0 )) && return 0 - for i in "$@"; do - if [[ $i == sh/* ]]; then - [[ -n $s ]] && s=$s, - s=${s}$i - fi - done + # the function's positional parameters. + local s="${(Mj:,:)@:#sh/*}" # Now, the communication with the code that calls # the hook functions is done via the hook_com[] - # hash. The key, at which the `gen-hg-bookmark-string' - # hook looks at is `hg-bookmark-string'. So: + # hash. The key at which the `gen-hg-bookmark-string' + # hook looks is `hg-bookmark-string'. So: hook_com[hg-bookmark-string]=$s - # And to signal, that we want to use the sting we + # And to signal that we want to use the string we # just generated, set the special variable `ret' to # something other than the default zero: ret=1 @@ -1874,6 +1890,12 @@ Edit the command line using your visual editor, as in tt(ksh). example(bindkey -M vicmd v edit-command-line) ) +tindex(expand-absolute-path) +item(tt(expand-absolute-path))( +Expand the file name under the cursor to an absolute path, resolving +symbolic links. Where possible, the initial path segment is turned +into a named directory or reference to a user's home directory. +) tindex(history-beginning-search-backward-end) tindex(history-beginning-search-forward-end) item(tt(history-search-end))( @@ -2306,6 +2328,32 @@ The name is a slight misnomer, as in fact the shell's own minibuffer is not used. Hence it is still possible to call tt(executed-named-cmd) and similar functions while reading a value. ) +tindex(replace-argument) +tindex(replace-argument-edit) +item(tt(replace-argument), tt(replace-argument-edit)) +( +The function tt(replace-argument) can be used to replace a command +line argument in the current command line or, if the current command +line is empty, in the last command line executed (the new command line +is not executed). Arguments are as delimited by standard shell syntax, + +If a numeric argument is given, that specifies the argument to be +replaced. 0 means the command name, as in history expansion. +A negative numeric argument counts backward from the last word. + +If no numeric argument is given, the current argument is replaced; +this is the last argument if the previous history line is being used. + +The function prompts for a replacement argument. + +If the widget contains the string tt(edit), for example is defined as + +example(zle -N replace-argument-edit replace-argument) + +then the function presents the current value of the argument for +editing, otherwise the editing buffer for the replacement is +initially empty. +) tindex(replace-string) tindex(replace-string-again) tindex(replace-pattern) @@ -2444,6 +2492,25 @@ The style tt(whence) is available in the context tt(:zle:$WIDGET); this may be set to an array to give the command and options that will be used to investigate the command word found. The default is tt(whence -c). ) +tindex(zcalc-auto-insert) +item(tt(zcalc-auto-insert))( +This function is useful together with the tt(zcalc) function described in +ifzman(the section Mathematical Functions)\ +ifnzman(noderef(Mathematical Functions)). +It should be bound to a key representing a binary operator such +as `tt(PLUS())', `tt(-)', `tt(*)' or `tt(/)'. When running in zcalc, +if the key occurs at the start of the line or immediately following +an open parenthesis, the text tt("ans ") is inserted before the +representation of the key itself. This allows easy use of the +answer from the previous calculation in the current line. The +text to be inserted before the symbol typed can be modified by setting +the variable tt(ZCALC_AUTO_INSERT_PREFIX). + +Hence, for example, typing `tt(PLUS()12)' followed by return adds 12 +to the previous result. + +When not in zcalc, the key simply inserts the symbol itself. +) enditem() subsect(Utility Functions) @@ -2899,7 +2966,7 @@ file name is matched against the pattern, regardless of how the file was passed to the handler. The file is resolved to a full path using the tt(:A) modifier described in ifzman(the subsection Modifers in zmanref(zshexpn))\ -ifnzman(noderef(Modifiers))); +ifnzman(noderef(Modifiers)); this means that symbolic links are resolved where possible, so that links into other file systems behave in the correct fashion. ) @@ -3370,21 +3437,22 @@ by the prompt theme system (ifzman(see above)\ ifnzman(noderef(Prompt Themes))). You seldom should need to run tt(colors) more than once. -The eight base colors are: black, red, green, yellow, blue, magenta, cyan, -and white. Each of these has codes for foreground and background. In -addition there are eight intensity attributes: bold, faint, standout, -underline, blink, reverse, and conceal. Finally, there are six codes used -to negate attributes: none (reset all attributes to the defaults), normal -(neither bold nor faint), no-standout, no-underline, no-blink, and -no-reverse. +The eight base colors are: tt(black), tt(red), tt(green), tt(yellow), +tt(blue), tt(magenta), tt(cyan), and tt(white). Each of these has codes for +foreground and background. In addition there are seven intensity attributes: +tt(bold), tt(faint), tt(standout), tt(underline), tt(blink), tt(reverse), +and tt(conceal). Finally, there are seven codes used to negate attributes: +tt(none) (reset all attributes to the defaults), tt(normal) +(neither bold nor faint), tt(no-standout), tt(no-underline), tt(no-blink), +tt(no-reverse), and tt(no-conceal). Some terminals do not support all combinations of colors and intensities. The associative arrays are: startitem() -xitem(color) -item(colour)( +xitem(tt(color)) +item(tt(colour))( Map all the color names to their integer codes, and integer codes to the color names. The eight base names map to the foreground color codes, as do names prefixed with `tt(fg-)', such as `tt(fg-red)'. Names prefixed @@ -3395,16 +3463,16 @@ and the tt(bg-) form for backgrounds. Although it is a misnomer to call them `colors', these arrays also map the other fourteen attributes from names to codes and codes to names. ) -xitem(fg) -xitem(fg_bold) -item(fg_no_bold)( +xitem(tt(fg)) +xitem(tt(fg_bold)) +item(tt(fg_no_bold))( Map the eight basic color names to ANSI terminal escape sequences that set the corresponding foreground text properties. The tt(fg) sequences change the color without changing the eight intensity attributes. ) -xitem(bg) -xitem(bg_bold) -item(bg_no_bold)( +xitem(tt(bg)) +xitem(tt(bg_bold)) +item(tt(bg_no_bold))( Map the eight basic color names to ANSI terminal escape sequences that set the corresponding background properties. The tt(bg) sequences change the color without changing the eight intensity attributes. diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 5ba3e21af..d01d804d2 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -1,7 +1,7 @@ texinode(Expansion)(Parameters)(Prompt Expansion)(Top) chapter(Expansion) -cindex(expansion) ifnztexi(sect(Description)) +cindex(expansion) The following types of expansions are performed in the indicated order in five steps: @@ -636,6 +636,30 @@ Similar to the preceding subsitution, but in the opposite sense, so that entries present in both the original substitution and as elements of var(arrayname) are retained and others removed. ) +xitem(tt(${)var(name)tt(:^)var(arrayname)tt(})) +item(tt(${)var(name)tt(:^^)var(arrayname)tt(}))( +Zips two arrays, such that the output array is twice as long as the +shortest (longest for `tt(:^^)') of tt(name) and tt(arrayname), with +the elements alternatingly being picked from them. For `tt(:^)', if one +of the input arrays is longer, the output will stop when the end of the +shorter array is reached. Thus, + +example(a=(1 2 3 4); b=(a b); print ${a:^b}) + +will output `tt(1 a 2 b)'. For `tt(:^^)', then the input is repeated +until all of the longer array has been used up and the above will output +`tt(1 a 2 b 3 a 4 b)'. + +Either or both inputs may be a scalar, they will be treated as an array +of length 1 with the scalar as the only element. If either array is empty, +the other array is output with no extra elements inserted. + +Currently the following code will output `tt(a b)' and `tt(1)' as two separate +elements, which can be unexpected. The second print provides a workaround which +should continue to work if this is changed. + +example(a=(a b); b=(1 2); print -l "${a:^b}"; print -l "${${a:^b}}") +) xitem(tt(${)var(name)tt(:)var(offset)tt(})) item(tt(${)var(name)tt(:)var(offset)tt(:)var(length)tt(}))( This syntax gives effects similar to parameter subscripting @@ -1407,16 +1431,21 @@ item(tt(19.) em(Ordering))( If the result is still an array and one of the `tt((o))' or `tt((O))' flags was present, the array is reordered. ) -item(tt(20.) em(Re-evaluation))( +item(tt(20.) tt(RC_EXPAND_PARAM))( +At this point the decision is made whether any resulting array elements +are to be combined element by element with surrounding text, as given +by either the tt(RC_EXPAND_PARAM) option or the `tt(^)' flag. +) +item(tt(21.) em(Re-evaluation))( Any `tt((e))' flag is applied to the value, forcing it to be re-examined for new parameter substitutions, but also for command and arithmetic substitutions. ) -item(tt(21.) em(Padding))( +item(tt(22.) em(Padding))( Any padding of the value by the `tt(LPAR()l.)var(fill)tt(.RPAR())' or `tt(LPAR()r.)var(fill)tt(.RPAR())' flags is applied. ) -item(tt(22.) em(Semantic joining))( +item(tt(23.) em(Semantic joining))( In contexts where expansion semantics requires a single word to result, all words are rejoined with the first character of tt(IFS) between. So in `tt(${LPAR()P)tt(RPAR()${LPAR()f)tt(RPAR()lines}})' @@ -1425,7 +1454,7 @@ joined again before the tt(P) flag can be applied. If a single word is not required, this rule is skipped. ) -item(tt(23.) em(Empty argument removal))( +item(tt(24.) em(Empty argument removal))( If the substitution does not appear in double quotes, any resulting zero-length argument, whether from a scalar or an element of an array, is elided from the list of arguments inserted into the command line. @@ -1539,6 +1568,16 @@ specified in any of the three numbers, specifying it in the third can be useful to pad for example `tt({-99..100..01})' which is not possible to specify by putting a 0 on either of the first two numbers (i.e. pad to two characters). +An expression of the form `tt({)var(c1)tt(..)var(c2)tt(})', where +var(c1) and var(c2) are single characters (which may be multibyte +characters), is expanded to every character in the range from var(c1) to +var(c2) in whatever character sequence is used internally. For +characters with code points below 128 this is US ASCII (this is the only +case most users will need). If any intervening character is not +printable, appropriate quotation is used to render it printable. +If the character sequence is reversed, the output is in reverse +order, e.g. `tt({d..a})' is substituted as `tt(d c b a)'. + If a brace expression matches none of the above forms, it is left unchanged, unless the option tt(BRACE_CCL) (an abbreviation for `brace character class') is set. @@ -1962,7 +2001,7 @@ except that recursive directory searching is not supported.) ) item(tt(PLUS()LPAR())...tt(RPAR()))( Match at least one occurrence. (Like `tt(LPAR())...tt(RPAR()##)', -except that recursive directory searching is not supported..) +except that recursive directory searching is not supported.) ) item(tt(?LPAR())...tt(RPAR()))( Match zero or one occurrence. (Like `tt(LPAR()|)...tt(RPAR())'.) @@ -2295,7 +2334,13 @@ contained within it are balanced; appearance of `tt(|)', `tt(LPAR())' or recognised in this form even if a bare glob qualifier exists at the end of the pattern, for example `tt(*(#q*)(.))' will recognise executable regular files if both options are set; however, mixed syntax should probably be -avoided for the sake of clarity. +avoided for the sake of clarity. Note that within conditions using the +`tt([[)' form the presence of a parenthesised expression +tt(LPAR()#q...+RPAR()) at the end of a string indicates that globbing +should be performed; the expression may include glob qualifiers, but +it is also valid if it is simply tt(LPAR()#q+RPAR()). This does +not apply to the right hand side of pattern match operators as the +syntax already has special significance. A qualifier may be any one of the following: @@ -2511,10 +2556,12 @@ item(tt(L)[tt(PLUS())|tt(-)]var(n))( files less than var(n) bytes (tt(-)), more than var(n) bytes (tt(PLUS())), or exactly var(n) bytes in length. -If this flag is directly followed by a `tt(k)' (`tt(K)'), `tt(m)' -(`tt(M)'), or `tt(p)' (`tt(P)') (e.g. `tt(Lk-50)') the check is performed -with kilobytes, megabytes, or blocks (of 512 bytes) instead. In this -case a file is regarded as "exactly" the size if the file size rounded up +If this flag is directly followed by a em(size specifier) `tt(k)' (`tt(K)'), +`tt(m)' (`tt(M)'), or `tt(p)' (`tt(P)') (e.g. `tt(Lk-50)') the check is +performed with kilobytes, megabytes, or blocks (of 512 bytes) instead. +(On some systems additional specifiers are available for gigabytes, +`tt(g)' or `tt(G)', and terabytes, `tt(t)' or `tt(T)'.) If a size specifier +is used a file is regarded as "exactly" the size if the file size rounded up to the next unit is equal to the test size. Hence `tt(*LPAR()Lm1+RPAR())' matches files from 1 byte up to 1 Megabyte inclusive. Note also that the set of files "less than" the test size only includes files that would @@ -2548,9 +2595,16 @@ item(tt(n))( sets the tt(NUMERIC_GLOB_SORT) option for the current pattern pindex(NUMERIC_GLOB_SORT, setting in pattern) ) +item(tt(Y)var(n))( +enables short-circuit mode: the pattern will expand to at most var(n) +filenames. If more than var(n) matches exist, only the first var(n) +matches in directory traversal order will be considered. + +Implies tt(oN) when no tt(o)var(c) qualifier is used. +) item(tt(o)var(c))( specifies how the names of the files should be sorted. If var(c) is -tt(n) they are sorted by name (the default); if it is tt(L) they +tt(n) they are sorted by name; if it is tt(L) they are sorted depending on the size (length) of the files; if tt(l) they are sorted by the number of links; if tt(a), tt(m), or tt(c) they are sorted by the time of the last access, modification, or @@ -2565,6 +2619,9 @@ so `tt(*(^-oL))' gives a list of all files sorted by file size in descending order, following any symbolic links. Unless tt(oN) is used, multiple order specifiers may occur to resolve ties. +The default sorting is tt(n) (by name) unless the tt(Y) glob qualifier is used, +in which case it is tt(N) (unsorted). + tt(oe) and tt(o+) are special cases; they are each followed by shell code, delimited as for the tt(e) glob qualifier and the tt(+) glob qualifier respectively (see above). The code is executed for each matched file with diff --git a/Doc/Zsh/grammar.yo b/Doc/Zsh/grammar.yo index b452e4cc9..77f0098e3 100644 --- a/Doc/Zsh/grammar.yo +++ b/Doc/Zsh/grammar.yo @@ -19,7 +19,11 @@ cindex(simple commands) cindex(commands, simple) A em(simple command) is a sequence of optional parameter assignments followed by blank-separated words, -with optional redirections interspersed. +with optional redirections interspersed. For a description +of assignment, see the beginning of +ifnzman(noderef(Parameters))\ +ifzman(zmanref(zshparam)). + The first word is the command to be executed, and the remaining words, if any, are arguments to the command. If a command name is given, the parameter assignments modify @@ -312,7 +316,7 @@ during the tt(try-list) is not useful (unless this forms part of an enclosing tt(always) block). Regardless of tt(TRY_BLOCK_ERROR), after the end of tt(always-list) the -normal shell status tt($?) is the value returned from tt(always-list). +normal shell status tt($?) is the value returned from tt(try-list). This will be non-zero if there was an error, even if tt(TRY_BLOCK_ERROR) was set to zero. @@ -465,37 +469,38 @@ shell constructs such as loops or conditions; this somewhat illogical behaviour can be recovered by setting the option tt(CONTINUE_ON_ERROR). Fatal errors found in non-interactive shells include: -startlist() -list(Failure to parse shell options passed when invoking the shell) -list(Failure to change options with the tt(set) builtin) -list(Parse errors of all sorts, including failures to parse + +startitemize() +itemiz(Failure to parse shell options passed when invoking the shell) +itemiz(Failure to change options with the tt(set) builtin) +itemiz(Parse errors of all sorts, including failures to parse mathematical expressions) -list(Failures to set or modify variable behaviour with tt(typeset), +itemiz(Failures to set or modify variable behaviour with tt(typeset), tt(local), tt(declare), tt(export), tt(integer), tt(float)) -list(Execution of incorrectly positioned loop control structures +itemiz(Execution of incorrectly positioned loop control structures (tt(continue), tt(break))) -list(Attempts to use regular expression with no regular expression +itemiz(Attempts to use regular expression with no regular expression module available) -list(Disallowed operations when the tt(RESTRICTED) options is set) -list(Failure to create a pipe needed for a pipeline) -list(Failure to create a multio) -list(Failure to autoload a module needed for a declared shell feature) -list(Errors creating command or process substitutions) -list(Syntax errors in glob qualifiers) -list(File generation errors where not caught by the option tt(BAD_PATTERN)) -list(All bad patterns used for matching within case statements) -list(File generation failures where not caused by tt(NO_MATCH) or -list(All file generation errors where the pattern was used to create a -multio) -list(Memory errors where detected by the shell) -list(Invalid subscripts to shell variables) -list(Attempts to assign read-only variables) -list(Logical errors with variables such as assignment to the wrong type) -list(Use of invalid variable names) -list(Errors in variable substitution syntax) -list(Failure to convert characters in tt($')...tt(') expressions) +itemiz(Disallowed operations when the tt(RESTRICTED) options is set) +itemiz(Failure to create a pipe needed for a pipeline) +itemiz(Failure to create a multio) +itemiz(Failure to autoload a module needed for a declared shell feature) +itemiz(Errors creating command or process substitutions) +itemiz(Syntax errors in glob qualifiers) +itemiz(File generation errors where not caught by the option tt(BAD_PATTERN)) +itemiz(All bad patterns used for matching within case statements) +itemiz(File generation failures where not caused by tt(NO_MATCH) or similar options) -endlist() +itemiz(All file generation errors where the pattern was used to create a +multio) +itemiz(Memory errors where detected by the shell) +itemiz(Invalid subscripts to shell variables) +itemiz(Attempts to assign read-only variables) +itemiz(Logical errors with variables such as assignment to the wrong type) +itemiz(Use of invalid variable names) +itemiz(Errors in variable substitution syntax) +itemiz(Failure to convert characters in tt($')...tt(') expressions) +enditemize() If the tt(POSIX_BUILTINS) option is set, more errors associated with shell builtin commands are treated as fatal, as specified by the POSIX diff --git a/Doc/Zsh/mod_pcre.yo b/Doc/Zsh/mod_pcre.yo index 9b8d9d6a7..faada28de 100644 --- a/Doc/Zsh/mod_pcre.yo +++ b/Doc/Zsh/mod_pcre.yo @@ -72,6 +72,7 @@ print -l $accum enditem() The tt(zsh/pcre) module makes available the following test condition: + startitem() findex(pcre-match) item(expr tt(-pcre-match) pcre)( @@ -79,6 +80,14 @@ Matches a string against a perl-compatible regular expression. For example, -[[ "$text" -pcre-match ^d+$ ]] && print text variable contains only "d's". +example([[ "$text" -pcre-match ^d+$ ]] && +print text variable contains only "d's".) + +pindex(REMATCH_PCRE) +pindex(NO_CASE_MATCH) +If the tt(REMATCH_PCRE) option is set, the tt(=~) operator is equivalent to +tt(-pcre-match), and the tt(NO_CASE_MATCH) option may be used. Note that +tt(NO_CASE_MATCH) never applies to the tt(pcre_match) builtin, instead use +the tt(-i) switch of tt(pcre_compile). ) enditem() diff --git a/Doc/Zsh/mod_regex.yo b/Doc/Zsh/mod_regex.yo index 4081810ed..f20451664 100644 --- a/Doc/Zsh/mod_regex.yo +++ b/Doc/Zsh/mod_regex.yo @@ -4,6 +4,7 @@ Interface to the POSIX regex library. cindex(regular expressions) cindex(regex) The tt(zsh/regex) module makes available the following test condition: + startitem() findex(regex-match) item(var(expr) tt(-regex-match) var(regex))( diff --git a/Doc/Zsh/mod_sched.yo b/Doc/Zsh/mod_sched.yo index 948001baf..2d8d77c7a 100644 --- a/Doc/Zsh/mod_sched.yo +++ b/Doc/Zsh/mod_sched.yo @@ -48,7 +48,7 @@ enditem() startitem() vindex(zsh_scheduled_events) -item(zsh_scheduled_events)( +item(tt(zsh_scheduled_events))( A readonly array corresponding to the events scheduled by the tt(sched) builtin. The indices of the array correspond to the numbers shown when tt(sched) is run with no arguments (provided that the diff --git a/Doc/Zsh/mod_zutil.yo b/Doc/Zsh/mod_zutil.yo index 726b0f055..ee9ec3adf 100644 --- a/Doc/Zsh/mod_zutil.yo +++ b/Doc/Zsh/mod_zutil.yo @@ -251,10 +251,12 @@ any not described by the var(specs). This is similar to using the tt(shift) builtin. ) item(tt(-K))( -With this option, the arrays specified with the tt(-a) and tt(-A) -options and with the `tt(=)var(array)' forms are kept unchanged when none -of the var(specs) for them is used. This allows assignment of default -values to them before calling tt(zparseopts). +With this option, the arrays specified with the tt(-a) option and with the +`tt(=)var(array)' forms are kept unchanged when none of the var(specs) for +them is used. Otherwise the entire array is replaced when any of the +var(specs) is used. Individual elements of associative arrays specified +with the tt(-A) option are preserved by tt(-K). This allows assignment of +default values to arrays before calling tt(zparseopts). ) item(tt(-M))( This changes the assignment rules to implement a map among equivalent diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index 3c6ea63b8..ec1f1645a 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -971,6 +971,23 @@ The file will still be periodically re-written to trim it when the number of lines grows 20% beyond the value specified by tt($SAVEHIST) (see also the HIST_SAVE_BY_COPY option). ) +pindex(INC_APPEND_HISTORY_TIME) +pindex(NO_INC_APPEND_HISTORY_TIME) +pindex(INCAPPENDHISTORYTIME) +pindex(NOINCAPPENDHISTORYTIME) +cindex(history, incremental appending to a file with time) +item(tt(INC_APPEND_HISTORY_TIME))( +This option is a variant of tt(INC_APPEND_HISTORY) in which, where +possible, the history entry is written out to the file after the +command is finished, so that the time taken by the command is recorded +correctly in the history file in tt(EXTENDED_HISTORY) format. This +means that the history entry will not be available immediately from +other instances of the shell that are using the same history file. + +This option is only useful if tt(INC_APPEND_HISTORY) and +tt(SHARE_HISTORY) are turned off. The three options should be +considered mutually exclusive. +) pindex(SHARE_HISTORY) pindex(NO_SHARE_HISTORY) pindex(SHAREHISTORY) @@ -981,10 +998,10 @@ item(tt(SHARE_HISTORY) <K>)( This option both imports new commands from the history file, and also causes your typed commands to be appended to the history file (the -latter is like specifying tt(INC_APPEND_HISTORY)). -The history lines are also output with timestamps ala -tt(EXTENDED_HISTORY) (which makes it easier to find the spot where -we left off reading the file after it gets re-written). +latter is like specifying tt(INC_APPEND_HISTORY), which should be turned +off if this option is in effect). The history lines are also output +with timestamps ala tt(EXTENDED_HISTORY) (which makes it easier to find +the spot where we left off reading the file after it gets re-written). By default, history movement commands visit the imported lines as well as the local lines, but you can toggle this on and off with the @@ -994,8 +1011,9 @@ some include them. If you find that you want more control over when commands get imported, you may wish to turn tt(SHARE_HISTORY) off, -tt(INC_APPEND_HISTORY) on, and then manually import -commands whenever you need them using `tt(fc -RI)'. +tt(INC_APPEND_HISTORY) or tt(INC_APPEND_HISTORY_TIME) (see above) on, +and then manually import commands whenever you need them using `tt(fc +-RI)'. ) enditem() @@ -1098,6 +1116,9 @@ pindex(CORRECTALL) pindex(NOCORRECTALL) item(tt(CORRECT_ALL) (tt(-O)))( Try to correct the spelling of all arguments in a line. + +The shell variable tt(CORRECT_IGNORE_FILE) may be set to a pattern to +match file names that will never be offered as corrections. ) pindex(DVORAK) pindex(NO_DVORAK) @@ -1174,7 +1195,7 @@ pindex(NOHASHEXECUTABLESONLY) cindex(hashing, of executables) cindex(executables, hashing) item(tt(HASH_EXECUTABLES_ONLY))( -When hashing commands because of tt(HASH_COMMANDS), check that the +When hashing commands because of tt(HASH_CMDS), check that the file to be hashed is actually an executable. This option is unset by default as if the path contains a large number of commands, or consists of many remote files, the additional tests can take @@ -1202,7 +1223,7 @@ Thus if `tt(/usr/local/bin)' is in the user's path, and he or she types (assuming it exists). Commands explicitly beginning with `tt(/)', `tt(./)' or `tt(../)' are not subject to the path search. -This also applies to the `tt(.)' builtin. +This also applies to the `tt(.)' and tt(source) builtins. Note that subdirectories of the current directory are always searched for executables specified in this form. This takes place before any search @@ -1605,7 +1626,25 @@ pindex(NOFUNCTIONARGZERO) cindex($0, setting) item(tt(FUNCTION_ARGZERO) <C> <Z>)( When executing a shell function or sourcing a script, set tt($0) -temporarily to the name of the function/script. +temporarily to the name of the function/script. Note that toggling +tt(FUNCTION_ARGZERO) from on to off (or off to on) does not change the +current value of tt($0). Only the state upon entry to the function or +script has an effect. Compare tt(POSIX_ARGZERO). +) +pindex(LOCAL_LOOPS) +pindex(NO_LOCAL_LOOPS) +pindex(LOCALLOOPS) +pindex(NOLOCALLOOPS) +cindex(break, inside function) +cindex(continue, inside function) +cindex(function, scope of break and continue) +item(tt(LOCAL_LOOPS))( +When this option is not set, the effect of tt(break) and tt(continue) +commands may propagate outside function scope, affecting loops in +calling functions. When the option is set in a calling function, a +tt(break) or a tt(continue) that is not caught within a called function +(regardless of the setting of the option within that function) +produces a warning and the effect is cancelled. ) pindex(LOCAL_OPTIONS) pindex(NO_LOCAL_OPTIONS) @@ -1615,10 +1654,10 @@ item(tt(LOCAL_OPTIONS) <K>)( If this option is set at the point of return from a shell function, most options (including this one) which were in force upon entry to the function are restored; options that are not restored are -tt(PRIVILEGED) and tt(RESTRICTED). Otherwise, only this option and the -tt(XTRACE) and tt(PRINT_EXIT_VALUE) options are restored. Hence -if this is explicitly unset by a shell function the other options in -force at the point of return will remain so. +tt(PRIVILEGED) and tt(RESTRICTED). Otherwise, only this option, +and the tt(LOCAL_LOOPS), tt(XTRACE) and tt(PRINT_EXIT_VALUE) options are +restored. Hence if this is explicitly unset by a shell function the +other options in force at the point of return will remain so. A shell function can also guarantee itself a known shell configuration with a formulation like `tt(emulate -L zsh)'; the tt(-L) activates tt(LOCAL_OPTIONS). @@ -1942,6 +1981,26 @@ as one unit, so aliases defined within the argument are not available even in later lines. If in doubt, avoid use of aliases in non-interactive code. ) +pindex(POSIX_ARGZERO) +pindex(NO_POSIX_ARGZERO) +pindex(POSIXARGZERO) +pindex(NOPOSIXARGZERO) +cindex($0, using) +item(tt(POSIX_ARGZERO))( +This option may be used to temporarily disable tt(FUNCTION_ARGZERO) and +thereby restore the value of tt($0) to the name used to invoke the shell +(or as set by the tt(-c) command line option). For compatibility with +previous versions of the shell, emulations use tt(NO_FUNCTION_ARGZERO) +instead of tt(POSIX_ARGZERO), which may result in unexpected scoping of +tt($0) if the emulation mode is changed inside a function or script. +To avoid this, explicitly enable tt(POSIX_ARGZERO) in the tt(emulate) +command: + +example(emulate sh -o POSIX_ARGZERO) + +Note that tt(NO_POSIX_ARGZERO) has no effect unless tt(FUNCTION_ARGZERO) +was already enabled upon entry to the function or script. +) pindex(POSIX_BUILTINS) pindex(NO_POSIX_BUILTINS) pindex(POSIXBUILTINS) @@ -2037,7 +2096,10 @@ When the is option is set, the usual zsh behaviour of executing traps for tt(EXIT) on exit from shell functions is suppressed. In that case, manipulating tt(EXIT) traps always alters the global trap for exiting the shell; the tt(LOCAL_TRAPS) option is -ignored for the tt(EXIT) trap. +ignored for the tt(EXIT) trap. Furthermore, a tt(return) statement +executed in a trap with no argument passes back from the function the +value from the surrounding context, not from code executed within the +trap. ) pindex(SH_FILE_EXPANSION) pindex(NO_SH_FILE_EXPANSION) diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 935fd5d86..dbac51182 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -21,14 +21,20 @@ indent(var(name)tt(=)var(value)) If the integer attribute, tt(-i), is set for var(name), the var(value) is subject to arithmetic evaluation. Furthermore, by replacing `tt(=)' -with `tt(+=)', a parameter can be added or appended to. See +with `tt(+=)', a parameter can be added or appended to. + +In scalar assignment, var(value) is expanded as a single string, in +which the elements of arrays are joined together; filename expansion is +not performed unless the option tt(GLOB_ASSIGN) is set. See noderef(Array Parameters) for additional forms of assignment. To refer to the value of a parameter, write `tt($)var(name)' or `tt(${)var(name)tt(})'. See ifzman(em(Parameter Expansion) in zmanref(zshexpn))\ ifnzman(noderef(Parameter Expansion)) -for complete details. +for complete details. This section also explains the effect +of the difference between scalar and array assignment on parameter +expansion. In the parameter lists that follow, the mark `<S>' indicates that the parameter is special. @@ -541,9 +547,11 @@ The exit status returned by the last command. ) vindex(0) item(tt(0) <S>)( -The name used to invoke the current shell. If the tt(FUNCTION_ARGZERO) option -is set, this is set temporarily within a shell function to the name of the -function, and within a sourced script to the name of the script. +The name used to invoke the current shell, or as set by the tt(-c) command +line option upon invocation. If the tt(FUNCTION_ARGZERO) option is set, +tt($0) is set upon entry to a shell function to the name of the function, +and upon entry to a sourced script to the name of the script, and reset to +its previous value when the function or script returns. ) vindex(status) item(tt(status) <S> <Z>)( @@ -599,9 +607,10 @@ group ID by `tt(LPAR()GID=)var(gid)tt(; command+RPAR())' ) vindex(HISTCMD) item(tt(HISTCMD))( -The current history line number in an interactive shell, in other -words the line number for the command that caused tt($HISTCMD) -to be read. +The current history event number in an interactive shell, in other +words the event number for the command that caused tt($HISTCMD) +to be read. If the current history event modifies the history, +tt(HISTCMD) changes to the new maximum history event number. ) vindex(HOST) item(tt(HOST))( @@ -620,7 +629,9 @@ item(tt(LOGNAME))( If the corresponding variable is not set in the environment of the shell, it is initialized to the login name corresponding to the current login session. This parameter is exported by default but -this can be disabled using the tt(typeset) builtin. +this can be disabled using the tt(typeset) builtin. The value +is set to the string returned by the manref(getlogin)(3) system call +if that is available. ) vindex(MACHTYPE) item(tt(MACHTYPE))( @@ -914,6 +925,14 @@ of file names, as applied by the tt(CORRECT_ALL) option (so with the example just given files beginning with `tt(_)' in the current directory would still be completed). ) +vindex(CORRECT_IGNORE_FILE) +item(tt(CORRECT_IGNORE_FILE))( +If set, is treated as a pattern during spelling correction of file names. +Any file name that matches the pattern is never offered as a correction. +For example, if the value is `tt(.*)' then dot file names will never be +offered as spelling corrections. This is useful with the +tt(CORRECT_ALL) option. +) vindex(DIRSTACKSIZE) item(tt(DIRSTACKSIZE))( The maximum size of the directory stack, by default there is no limit. If the diff --git a/Doc/Zsh/prompt.yo b/Doc/Zsh/prompt.yo index eab15d29d..0ed52b580 100644 --- a/Doc/Zsh/prompt.yo +++ b/Doc/Zsh/prompt.yo @@ -185,6 +185,13 @@ sitem(tt(%K))(the hour of the day on the 24-hour clock) sitem(tt(%L))(the hour of the day on the 12-hour clock) endsitem() +In addition, if the system supports the POSIX tt(gettimeofday) system +call, tt(%.) provides decimal fractions of a second since the epoch with +leading zeroes. By default three decimal places are provided, but a +number of digits up to 6 may be given following the tt(%); hence tt(%6.) +outputs microseconds. A typical example of this is the format +`tt(%D{%H:%M:%S.%.})'. + The GNU extension that a `tt(-)' between the tt(%) and the format character causes a leading zero or space to be stripped is handled directly by the shell for the format characters tt(d), tt(f), @@ -273,7 +280,8 @@ and var(false-text) may both contain arbitrarily-nested escape sequences, including further ternary expressions. The left parenthesis may be preceded or followed by a positive integer var(n), -which defaults to zero. A negative integer will be multiplied by -1. +which defaults to zero. A negative integer will be multiplied by -1, except +as noted below for `tt(l)'. The test character var(x) may be any of the following: startsitem() @@ -295,7 +303,9 @@ sitem(tt(g))(True if the effective gid of the current process is var(n).) sitem(tt(j))(True if the number of jobs is at least var(n).) sitem(tt(L))(True if the tt(SHLVL) parameter is at least var(n).) sitem(tt(l))(True if at least var(n) characters have already been -printed on the current line.) +printed on the current line. When var(n) is negative, true if at least +tt(abs)tt(LPAR())var(n)tt(RPAR()) characters remain before the opposite +margin (thus the left margin for tt(RPROMPT)).) sitem(tt(S))(True if the tt(SECONDS) parameter is at least var(n).) sitem(tt(T))(True if the time in hours is equal to var(n).) sitem(tt(t))(True if the time in minutes is equal to var(n).) @@ -311,13 +321,21 @@ item(tt(%[)var(xstring)tt(]))( Specifies truncation behaviour for the remainder of the prompt string. The third, deprecated, form is equivalent to `tt(%)var(xstringx)', i.e. var(x) may be `tt(<)' or `tt(>)'. -The numeric argument, which in the third form may appear immediately -after the `tt([)', specifies the maximum permitted length of -the various strings that can be displayed in the prompt. The var(string) will be displayed in place of the truncated portion of any string; note this does not undergo prompt expansion. +The numeric argument, which in the third form may appear immediately +after the `tt([)', specifies the maximum permitted length of +the various strings that can be displayed in the prompt. +In the first two forms, this numeric argument may be negative, in which +case the truncation length is determined by subtracting the absolute +value of the numeric argument from the number of character positions +remaining on the current prompt line. If this results in a zero or +negative length, a length of 1 is used. In other words, a negative +argument arranges that after truncation at least var(n) characters +remain before the right margin (left margin for tt(RPROMPT)). + The forms with `tt(<)' truncate at the left of the string, and the forms with `tt(>)' truncate at the right of the string. For example, if the current directory is `tt(/home/pike)', @@ -337,11 +355,19 @@ string, or to the end of the next enclosing group of the `tt(%LPAR())' construct, or to the next truncation encountered at the same grouping level (i.e. truncations inside a `tt(%LPAR())' are separate), which ever comes first. In particular, a truncation with argument zero -(e.g. `tt(%<<)') marks the end of the range of the string to be +(e.g., `tt(%<<)') marks the end of the range of the string to be truncated while turning off truncation from there on. For example, the prompt '%10<...<%~%<<%# ' will print a truncated representation of the current directory, followed by a `tt(%)' or `tt(#)', followed by a space. Without the `tt(%<<)', those two characters would be included -in the string to be truncated. +in the string to be truncated. Note that `tt(%-0<<)' is a distinct + +Truncation applies only within each individual line of the prompt, as +delimited by embedded newlines (if any). If the total length of any line +of the prompt after truncation is greater than the terminal width, or if +the part to be truncated contains embedded newlines, truncation behavior +is undefined and may change in a future version of the shell. Use +`tt(%-var(n)LPAR()l.var(true-text).var(false-text)RPAR())' to remove parts +of the prompt when the available space is less than var(n). ) enditem() diff --git a/Doc/Zsh/roadmap.yo b/Doc/Zsh/roadmap.yo index fd87c74ab..ba598e5ea 100644 --- a/Doc/Zsh/roadmap.yo +++ b/Doc/Zsh/roadmap.yo @@ -1,7 +1,6 @@ texinode(Roadmap)(Invocation)(Introduction)(Top) chapter(Roadmap) cindex(roadmap) - The Zsh Manual, like the shell itself, is large and often complicated. This section of the manual provides some pointers to areas of the shell that are likely to be of particular interest to new users, and indicates diff --git a/Doc/Zsh/tcpsys.yo b/Doc/Zsh/tcpsys.yo index 599335bc9..1e26054ce 100644 --- a/Doc/Zsh/tcpsys.yo +++ b/Doc/Zsh/tcpsys.yo @@ -666,6 +666,10 @@ expression `tt(%c)' expands to 1 if the session being read is the current session, else 0; this is most useful in ternary expressions such as `tt(%LPAR()c.-.PLUS()RPAR())' which outputs `tt(PLUS())' if the session is the current one, else `tt(-)'. + +If the prompt starts with tt(%P), this is stripped and the complete +result of the previous stage is passed through standard prompt tt(%)-style +formatting before being output. ) vindex(TCP_READ_DEBUG) item(tt(TCP_READ_DEBUG))( diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 2d7756859..2a907c52c 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -252,6 +252,9 @@ Bind each var(in-string) to each var(out-string). When var(in-string) is typed, var(out-string) will be pushed back and treated as input to the line editor. When tt(-R) is also used, interpret the var(in-string)s as ranges. + +Note that both var(in-string) and var(out-string) are subject to the same +form of interpretation, as described below. ) item(var(in-string command) ...)( Bind each var(in-string) to each var(command). @@ -492,26 +495,35 @@ Only available if your system supports one of the `poll' or `select' system calls; most modern systems do. Installs var(handler) (the name of a shell function) to handle input from -file descriptor var(fd). When zle is attempting to read data, it will -examine both the terminal and the list of handled var(fd)'s. If data -becomes available on a handled var(fd), zle will call var(handler) with -the fd which is ready for reading as the only argument. If the handler -produces output to the terminal, it should call `tt(zle -I)' before doing -so (see below). The handler should not attempt to read from the terminal. -Note that zle makes no attempt to check whether this fd is actually +file descriptor var(fd). Installing a handler for an var(fd) which is +already handled causes the existing handler to be replaced. Any number of +handlers for any number of readable file descriptors may be installed. +Note that zle makes no attempt to check whether this var(fd) is actually readable when installing the handler. The user must make their own arrangements for handling the file descriptor when zle is not active. -If the option tt(-w) is also given, the var(handler) is instead a -line editor widget, typically a shell function made into a widget using -tt(zle -N). In that case var(handler) can use all the facilities of -zle to update the current editing line. Note, however, that as handling -var(fd) takes place at a low level changes to the display will not -automatically appear; the widget should call tt(zle -R) to force redisplay. - -Any number of handlers for any number of readable file descriptors may be -installed. Installing a handler for an var(fd) which is already handled -causes the existing handler to be replaced. +When zle is attempting to read data, it will examine both the terminal and +the list of handled var(fd)'s. If data becomes available on a handled +var(fd), zle calls var(handler) with the fd which is ready for reading +as the first argument. Under normal circumstances this is the only +argument, but if an error was detected, a second argument provides +details: `tt(hup)' for a disconnect, `tt(nval)' for a closed or otherwise +invalid descriptor, or `tt(err)' for any other condition. Systems that +support only the `select' system call always use `tt(err)'. + +If the option tt(-w) is also given, the var(handler) is instead a line +editor widget, typically a shell function made into a widget using +`tt(zle -N)'. In that case var(handler) can use all the facilities of zle +to update the current editing line. Note, however, that as handling var(fd) +takes place at a low level changes to the display will not automatically +appear; the widget should call `tt(zle -R)' to force redisplay. As of this +writing, widget handlers only support a single argument and thus are never +passed a string for error state, so widgets must be prepared to test the +descriptor themselves. + +If either type of handler produces output to the terminal, it should call +`tt(zle -I)' before doing so (see below). Handlers should not attempt to +read from the terminal. If no var(handler) is given, but an var(fd) is present, any handler for that var(fd) is removed. If there is none, an error message is printed @@ -526,7 +538,8 @@ silently return status 1. Note that this feature should be used with care. Activity on one of the var(fd)'s which is not properly handled can cause the terminal to become -unusable. +unusable. Removing an var(fd) handler from within a signal trap may cause +unpredictable behavior. Here is a simple example of using this feature. A connection to a remote TCP port is created using the ztcp command; see @@ -536,6 +549,7 @@ which simply prints out any data which arrives on this connection. Note that `select' will indicate that the file descriptor needs handling if the remote side has closed the connection; we handle that by testing for a failed read. + example(if ztcp pwspc 2811; then tcpfd=$REPLY handler+LPAR()RPAR() { @@ -716,17 +730,18 @@ vindex(CONTEXT) item(tt(CONTEXT) (scalar))( The context in which zle was called to read a line; read-only. One of the values: + startitem() -item(start)( +item(tt(start))( The start of a command line (at prompt tt(PS1)). ) -item(cont)( +item(tt(cont))( A continuation to a command line (at prompt tt(PS2)). ) -item(select)( +item(tt(select))( In a tt(select) loop. ) -item(vared)( +item(tt(vared))( Editing a variable in tt(vared). ) enditem() @@ -863,21 +878,21 @@ is needed for character indexing to include tt(PREDISPLAY). Each string consists of the following parts: -startlist() -list(Optionally, a `tt(P)' to signify that the start and end offset that +startitemize() +itemiz(Optionally, a `tt(P)' to signify that the start and end offset that follow include any string set by the tt(PREDISPLAY) special parameter; this is needed if the predisplay string itself is to be highlighted. Whitespace may follow the `tt(P)'.) -list(A start offset in the same units as tt(CURSOR), terminated by +itemiz(A start offset in the same units as tt(CURSOR), terminated by whitespace.) -list(An end offset in the same units as tt(CURSOR), terminated by +itemiz(An end offset in the same units as tt(CURSOR), terminated by whitespace.) -list(A highlight specification in the same format as +itemiz(A highlight specification in the same format as used for contexts in the parameter tt(zle_highlight), ifnzman(noderef(Character Highlighting))\ ifzman(see Character Highlighting below); for example, tt(standout) or tt(fg=red,bold)). -endlist() +enditemize() For example, @@ -1293,8 +1308,11 @@ item(tt(redisplay))( Redisplay the command line, remaining in incremental search mode. ) item(tt(vi-cmd-mode))( -Toggle between the `tt(main)' and `tt(vicmd)' keymaps; +Select the `tt(vicmd)' keymap; the `tt(main)' keymap (insert mode) will be selected initially. + +In addition, the modifications that were made while in vi insert mode are +merged to form a single undo event. ) xitem(tt(vi-repeat-search)) item(tt(vi-rev-repeat-search))( @@ -2191,6 +2209,13 @@ tindex(spell-word) item(tt(spell-word) (ESC-$ ESC-S ESC-s) (unbound) (unbound))( Attempt spelling correction on the current word. ) +tindex(split-undo) +item(tt(split-undo))( +Breaks the undo sequence at the current change. This is useful in vi mode as +changes made in insert mode are coalesced on entering command mode. Similarly, +tt(undo) will normally revert as one all the changes made by a user-defined +widget. +) tindex(undefined-key) item(tt(undefined-key))( This command is executed when a key sequence that is not bound to any @@ -2202,6 +2227,10 @@ Incrementally undo the last text modification. When called from a user-defined widget, takes an optional argument indicating a previous state of the undo history as returned by the tt(UNDO_CHANGE_NO) variable; modifications are undone until that state is reached. + +Note that when invoked from vi command mode, the full prior change made in +insert mode is reverted, the changes having been merged when command mode was +selected. ) tindex(redo) item(tt(redo))( diff --git a/Doc/zman.yo b/Doc/zman.yo index 7aa0913cd..3329cb975 100644 --- a/Doc/zman.yo +++ b/Doc/zman.yo @@ -69,7 +69,7 @@ def(chapter)(1)(CMT()) COMMENT(--- the "" works around a yodl bug in versions before 2 ---) def(sect)(1)(\ IFDEF(INCWSLEVEL)(\ - NOTRANS(.SH )"UPPERCASE(ARG1)(0)"+NL()\ + NOTRANS(.SH )"UPPERCASE(NOTRANS(ARG1))(0)"+NL()\ )(\ NOTRANS(.SH )UPPERCASE(ARG1)(0)""+NL()\ )\ @@ -110,7 +110,7 @@ def(startitem)(0)(\ def(enditem)(0)(\ ENDITEM()\ STDPAR()\ - +redef(ENDITEM)(0)(NOTRANS(.RE)STDPAR())\ + +redef(ENDITEM)(0)(NOTRANS(.RE)STDPAR()redef(ENDITEM)(0)(CMT()))\ ) def(item)(2)(\ NOTRANS(.TP)+NL()\ @@ -121,7 +121,7 @@ def(item)(2)(\ +redef(PARAGRAPH)(0)(\ NL()NOTRANS(.RS)+NL()NOTRANS(.PP)+NL()\ STDPAR()\ - +redef(ENDITEM)(0)(NOTRANS(.RE)STDPAR())\ + +redef(ENDITEM)(0)(NOTRANS(.RE)STDPAR()redef(ENDITEM)(0)(CMT()))\ )\ ARG2\ +ENDITEM()\ diff --git a/Doc/zsh.yo b/Doc/zsh.yo index 0d815c2e0..7f6dbd2a3 100644 --- a/Doc/zsh.yo +++ b/Doc/zsh.yo @@ -41,6 +41,7 @@ permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions. texiendtitlepage() +NOTRANS(@contents) )\ ifnzman(includefile(Zsh/manual.yo)) includefile(Zsh/intro.yo) diff --git a/Doc/ztexi.yo b/Doc/ztexi.yo index e58ff3902..636896117 100644 --- a/Doc/ztexi.yo +++ b/Doc/ztexi.yo @@ -16,7 +16,6 @@ def(CMT)(0)(NOTRANS(@c)) ATEXIT(\ NL()\ - NOTRANS(@contents)+NL()\ NOTRANS(@bye)NL()\ ) diff --git a/Etc/.distfiles b/Etc/.distfiles index 2f9d7cd12..8c1218e72 100644 --- a/Etc/.distfiles +++ b/Etc/.distfiles @@ -26,3 +26,7 @@ relnote_4.3.12.txt relnote_5.0.0.txt zsh-development-guide ' + +DISTFILES_DOC=' +FAQ*.html +' diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo index 82053d003..ed703c68b 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 5.0.5 is the latest production version. For details of all the + Zsh 5.0.6 is the latest production version. For details of all the changes, see the NEWS file in the source distribution. A beta of the next version is sometimes available. Development of zsh is diff --git a/Functions/Misc/zcalc b/Functions/Misc/zcalc index 1f3392d92..63f67adb0 100644 --- a/Functions/Misc/zcalc +++ b/Functions/Misc/zcalc @@ -96,6 +96,9 @@ emulate -L zsh setopt extendedglob +# For testing in ZLE functions. +local ZCALC_ACTIVE=1 + # TODO: make local variables that shouldn't be visible in expressions # begin with _. local line ans base defbase forms match mbegin mend psvar optlist opt arg @@ -196,8 +199,8 @@ while (( expression_mode )) || # special cases # Set default base if `[#16]' or `[##16]' etc. on its own. # Unset it if `[#]' or `[##]'. - if [[ $line = (#b)[[:blank:]]#('[#'(\#|)(<->|)']')[[:blank:]]#(*) ]]; then - if [[ -z $match[4] ]]; then + if [[ $line = (#b)[[:blank:]]#('[#'(\#|)((<->|)(|_|_<->))']')[[:blank:]]#(*) ]]; then + if [[ -z $match[6] ]]; then if [[ -z $match[3] ]]; then defbase= else diff --git a/Functions/TCP/tcp_output b/Functions/TCP/tcp_output index 781c46c33..22e818e17 100644 --- a/Functions/TCP/tcp_output +++ b/Functions/TCP/tcp_output @@ -35,6 +35,9 @@ if [[ -n $tprompt ]]; then cursess="c:0" fi zformat -f REPLY $tprompt "s:$sess" "f:$read_fd" $cursess + if [[ $REPLY = %P* ]]; then + REPLY=${(%)${REPLY##%P}} + fi # We will pass this back up. REPLY="$REPLY$*" else diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_hg b/Functions/VCS_Info/Backends/VCS_INFO_detect_hg index a22c1ee0f..d7b1d0d36 100644 --- a/Functions/VCS_Info/Backends/VCS_INFO_detect_hg +++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_hg @@ -7,7 +7,7 @@ setopt localoptions NO_shwordsplit [[ $1 == '--flavours' ]] && { print -l hg-git hg-hgsubversion hg-hgsvn; return 0 } VCS_INFO_check_com ${vcs_comm[cmd]} || return 1 -vcs_comm[detect_need_file]="store data" +vcs_comm[detect_need_file]="store data sharedpath" VCS_INFO_bydir_detect '.hg' || return 1 if [[ -d ${vcs_comm[basedir]}/.hg/svn ]] ; then diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git index e6791cb7a..76ab92f33 100644 --- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git +++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git @@ -5,6 +5,7 @@ setopt localoptions extendedglob NO_shwordsplit local gitdir gitbase gitbranch gitaction gitunstaged gitstaged gitsha1 local stgitpatch stgitunapplied +local -i querystaged queryunstaged local -A hook_com VCS_INFO_git_getaction () { @@ -96,7 +97,7 @@ VCS_INFO_git_getbranch () { gitbranch="$(${(z)gitsymref} 2> /dev/null)" if [[ $? -ne 0 ]] ; then - gitbranch="refs/tags/$(${vcs_comm[cmd]} describe --exact-match HEAD 2>/dev/null)" + gitbranch="refs/tags/$(${vcs_comm[cmd]} describe --all --exact-match HEAD 2>/dev/null)" if [[ $? -ne 0 ]] ; then gitbranch="${${"$(< $gitdir/HEAD)"}[1,7]}..." @@ -120,14 +121,30 @@ if [[ -z ${gitdir} ]] || [[ -z ${gitbranch} ]] ; then return 1 fi -if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "check-for-changes" && \ - [[ "$(${vcs_comm[cmd]} rev-parse --is-inside-git-dir 2> /dev/null)" != 'true' ]] && \ - ${vcs_comm[cmd]} rev-parse --quiet --verify HEAD &> /dev/null ; then +if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "check-for-changes" ; then + querystaged=1 + queryunstaged=1 +elif zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" "check-for-staged-changes" ; then + querystaged=1 +fi +if (( querystaged || queryunstaged )) && \ + [[ "$(${vcs_comm[cmd]} rev-parse --is-inside-work-tree 2> /dev/null)" == 'true' ]] ; then # Default: off - these are potentially expensive on big repositories - ${vcs_comm[cmd]} diff --no-ext-diff --ignore-submodules --quiet --exit-code || - gitunstaged=1 - ${vcs_comm[cmd]} diff-index --cached --quiet --ignore-submodules HEAD 2> /dev/null - (( $? && $? != 128 )) && gitstaged=1 + if (( queryunstaged )) ; then + ${vcs_comm[cmd]} diff --no-ext-diff --ignore-submodules --quiet --exit-code || + gitunstaged=1 + fi + if (( querystaged )) ; then + if ${vcs_comm[cmd]} rev-parse --quiet --verify HEAD &> /dev/null ; then + ${vcs_comm[cmd]} diff-index --cached --quiet --ignore-submodules HEAD 2> /dev/null + (( $? && $? != 128 )) && gitstaged=1 + else + # empty repository (no commits yet) + # 4b825dc642cb6eb9a060e54bf8d69288fbee4904 is the git empty tree. + ${vcs_comm[cmd]} diff-index --cached --quiet --ignore-submodules 4b825dc642cb6eb9a060e54bf8d69288fbee4904 2>/dev/null + (( $? && $? != 128 )) && gitstaged=1 + fi + fi fi VCS_INFO_adjust diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn index 41cc3e783..e56afee02 100644 --- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn +++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn @@ -7,7 +7,7 @@ setopt localoptions noksharrays extendedglob NO_shwordsplit local svnbase svnbranch a b rrn local -i rc -local -A svninfo parentinfo +local -A svninfo parentinfo cwdinfo local -xA hook_com svnbase="."; @@ -28,24 +28,34 @@ done #rc=${pipestatus[1]} #(( rc != 0 )) && return 1 -while [[ -d "${svnbase}/../.svn" ]]; do - parentinfo=() - ${vcs_comm[cmd]} info --non-interactive "${svnbase}/.." | while IFS=: read a b; do parentinfo[${a// /_}]="${b## #}"; done - [[ ${parentinfo[Repository_UUID]} != ${svninfo[Repository_UUID]} ]] && break - svninfo=(${(kv)parentinfo}) - svnbase="${svnbase}/.." -done +cwdinfo=(${(kv)svninfo}) + +# Set svnbase to the wcroot path and svninfo to its `svn info`. +if (( ${+svninfo[Working_Copy_Root_Path]} )); then + # svn 1.7+ + svnbase=${svninfo[Working_Copy_Root_Path]} + ${vcs_comm[cmd]} info --non-interactive -- "${svnbase}" | while IFS=: read a b; do svninfo[${a// /_}]="${b## #}"; done +else + # svn 1.0-1.6 + while [[ -d "${svnbase}/../.svn" ]]; do + parentinfo=() + ${vcs_comm[cmd]} info --non-interactive -- "${svnbase}/.." | while IFS=: read a b; do parentinfo[${a// /_}]="${b## #}"; done + [[ ${parentinfo[Repository_UUID]} != ${svninfo[Repository_UUID]} ]] && break + svninfo=(${(kv)parentinfo}) + svnbase="${svnbase}/.." + done +fi svnbase="$(VCS_INFO_realpath ${svnbase})" rrn=${svnbase:t} zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" branchformat svnbranch || svnbranch="%b:%r" -hook_com=( branch "${svninfo[URL]##*/}" revision "${svninfo[Revision]}" ) +hook_com=( branch "${svninfo[URL]##*/}" revision "${cwdinfo[Revision]}" ) if VCS_INFO_hook 'set-branch-format' "${svnbranch}"; then zformat -f svnbranch "${svnbranch}" "b:${hook_com[branch]}" "r:${hook_com[revision]}" else svnbranch=${hook_com[branch-replace]} fi hook_com=() -VCS_INFO_formats '' "${svnbranch}" "${svnbase}" '' '' "${svninfo[Revision]}" '' +VCS_INFO_formats '' "${svnbranch}" "${svnbase}" '' '' "${cwdinfo[Revision]}" '' return 0 diff --git a/Functions/Zle/.distfiles b/Functions/Zle/.distfiles index 256044fa5..90a07690b 100644 --- a/Functions/Zle/.distfiles +++ b/Functions/Zle/.distfiles @@ -10,6 +10,7 @@ delete-whole-word-match down-case-word-match down-line-or-beginning-search edit-command-line +expand-absolute-path forward-word-match history-beginning-search-menu history-pattern-search @@ -31,6 +32,7 @@ narrow-to-region-invisible predict-on quote-and-complete-word read-from-minibuffer +replace-argument replace-string replace-string-again select-word-style @@ -43,5 +45,6 @@ up-case-word-match up-line-or-beginning-search url-quote-magic which-command +zcalc-auto-insert zed-set-file-name ' diff --git a/Functions/Zle/expand-absolute-path b/Functions/Zle/expand-absolute-path new file mode 100644 index 000000000..b85757600 --- /dev/null +++ b/Functions/Zle/expand-absolute-path @@ -0,0 +1,19 @@ +# expand-absolute-path +# This is a ZLE widget to expand the absolute path to a file, +# using directory naming to shorten the path where possible. + +emulate -L zsh +setopt extendedglob cbases + +autoload -Uz modify-current-argument + +if (( ! ${+functions[glob-expand-absolute-path]} )); then + glob-expand-absolute-path() { + local -a files + files=(${~1}(N:A)) + (( ${#files} )) || return + REPLY=${(D)files[1]} + } +fi + +modify-current-argument glob-expand-absolute-path diff --git a/Functions/Zle/read-from-minibuffer b/Functions/Zle/read-from-minibuffer index 57e926884..8fec1105e 100644 --- a/Functions/Zle/read-from-minibuffer +++ b/Functions/Zle/read-from-minibuffer @@ -20,7 +20,9 @@ done (( OPTIND > 1 )) && shift $(( OPTIND - 1 )) local readprompt="$1" lbuf_init="$2" rbuf_init="$3" +integer changeno=$UNDO_CHANGE_NO +{ # 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. @@ -39,10 +41,17 @@ local readprompt="$1" lbuf_init="$2" rbuf_init="$3" read -k $keys stat=$? else + local NUMERIC + unset NUMERIC zle recursive-edit -K main stat=$? (( stat )) || REPLY=$BUFFER fi } +} always { + # This removes the edits relating to the read from the undo history. + # These aren't useful once we get back to the main editing buffer. + zle undo $changeno +} return $stat diff --git a/Functions/Zle/replace-argument b/Functions/Zle/replace-argument new file mode 100644 index 000000000..0ef3de7b5 --- /dev/null +++ b/Functions/Zle/replace-argument @@ -0,0 +1,48 @@ +# Replace an argument to a command, delimited by normal shell syntax. +# Prompts for the replacement. +# With no numeric argument, replace the current argument. +# With a numeric argument, replace that argument: 0 = command word, +# as in history expansion. +# If editing buffer is empty, use previous history line. + +autoload -Uz split-shell-arguments read-from-minibuffer + +if (( ${#BUFFER} == 0 )); then + (( HISTNO-- )) + CURSOR=${#BUFFER} +fi + +local widget=$WIDGET numeric +integer cursor=CURSOR +if (( ${+NUMERIC} )); then + numeric=$NUMERIC +fi +local reply REPLY REPLY2 +integer index +split-shell-arguments + +if [[ -n $numeric ]]; then + if (( numeric < 0 )); then + (( index = ${#reply} - 1 + 2*(numeric+1) )) + else + (( index = 2 + 2*numeric )) + fi +else + (( index = REPLY & ~1 )) +fi + +local edit +if [[ $widget = *edit* ]]; then + edit=$reply[$index] +fi +read-from-minibuffer "Replace $reply[$index] with: " $edit || return 1 + +integer diff=$(( ${#REPLY} - ${#reply[$index]} )) +reply[$index]=$REPLY + +BUFFER=${(j..)reply} +if (( cursor > REPLY2 )); then + (( CURSOR = cursor + diff )) +else + (( CURSOR = REPLY2 )) +fi diff --git a/Functions/Zle/zcalc-auto-insert b/Functions/Zle/zcalc-auto-insert new file mode 100644 index 000000000..c9a5c8867 --- /dev/null +++ b/Functions/Zle/zcalc-auto-insert @@ -0,0 +1,8 @@ +# Bind to a binary operator keystroke for use with zcalc + +if [[ -n $ZCALC_ACTIVE ]]; then + if [[ $CURSOR -eq 0 || $LBUFFER[-1] = "(" ]]; then + LBUFFER+=${ZCALC_AUTO_INSERT_PREFIX:-"ans "} + fi +fi +zle .self-insert diff --git a/Misc/vcs_info-examples b/Misc/vcs_info-examples index b07bfc67c..5d8ff187e 100644 --- a/Misc/vcs_info-examples +++ b/Misc/vcs_info-examples @@ -266,6 +266,10 @@ autoload -Uz vcs_info zstyle ':vcs_info:*' check-for-changes true zstyle ':vcs_info:*' get-revision true +# Alternatively, the following would set only %c, but is faster: +#zstyle ':vcs_info:*' check-for-changes false +#zstyle ':vcs_info:*' check-for-staged-changes true + # Default to running vcs_info. If possible we prevent running it later for # speed reasons. If set to a non empty value vcs_info is run. @@ -58,6 +58,26 @@ between the right hand side of the screen (this causes problems with some terminals). It is not special and is not set by default; the effect in that case is as if it was 1, as in previous versions. +If the option EXTENDED_GLOB is in effect, it is possible to force +globbing within conditional code using the [[ ... ]] syntax by flagging +that a certain string is a glob using the (#q) glob qualifier syntax. +The resulting glob is treated as a single argument. For example, +[[ -n *.c(#qN) ]] tests whether there are any .c files in the current +directory. + +In prompt strings, the %N(l.true.false) conditional (line length) and +the %N<..< and %N>..> truncation operators now accept negative values +of N, which count the remaining space to the opposite margin (positive +values of N still count the space used since the start of the prompt). +In PS1 and PROMPT, this counts to the right margin, whereas in RPS1 and +RPROMPT, it counts to the left margin (not to the opposite prompt). + +Another new prompt feature is the %. escape within time strings, for +example %D{%H:%M:%S.%.}. It provides zero-padded decimal fractions of +second; by default milliseconds are shown, but the number of digits may +be indicated from 1 to 6, e.g. "%6.". (Note this is part of the +extensions to strftime() formats rather of basic prompt escapes.) + Changes between 4.2 and 5.0.0 ----------------------------- @@ -5,10 +5,8 @@ THE Z SHELL (ZSH) Version ------- -This is version 5.0.5 of the shell. This is a stable release. -There are minor new features as well as bug fixes since 5.0.2. -5.0.3 and 5.0.4 were short-lived releases with most of the features of -5.0.5 that were replaced owing to significant bugs. +This is version 5.0.6 of the shell. This is a stable release. +There are minor new features as well as bug fixes since 5.0.5. Installing Zsh -------------- diff --git a/Src/Builtins/rlimits.c b/Src/Builtins/rlimits.c index fd4c94aaa..9da31831d 100644 --- a/Src/Builtins/rlimits.c +++ b/Src/Builtins/rlimits.c @@ -32,12 +32,17 @@ #if defined(HAVE_GETRLIMIT) && defined(RLIM_INFINITY) -#ifdef RLIMIT_POSIXLOCKS +#if defined(HAVE_RLIMIT_POSIXLOCKS) && !defined(HAVE_RLIMIT_LOCKS) # define RLIMIT_LOCKS RLIMIT_POSIXLOCKS +# define HAVE_RLIMIT_LOCKS 1 #endif -#ifdef RLIMIT_NTHR +#if defined(HAVE_RLIMIT_NTHR) && !defined(HAVE_RLIMIT_PTHREAD) # define RLIMIT_PTHREAD RLIMIT_NTHR +# define HAVE_RLIMIT_PTHREAD 1 +# define THREAD_FMT "-T: threads " +#else +# define THREAD_FMT "-T: threads per process " #endif enum { @@ -367,13 +372,13 @@ printulimit(char *nam, int lim, int hard, int head) # ifdef HAVE_RLIMIT_SBSIZE case RLIMIT_SBSIZE: if (head) - printf("-b: socket buffer size (bytes) ", RLIMIT_SBSIZE); + printf("-b: socket buffer size (bytes) "); break; # endif /* HAVE_RLIMIT_SBSIZE */ # ifdef HAVE_RLIMIT_PTHREAD case RLIMIT_PTHREAD: if (head) - printf("-T: threads per process "); + printf("%s", THREAD_FMT); break; # endif /* HAVE_RLIMIT_PTHREAD */ # ifdef HAVE_RLIMIT_NICE @@ -860,6 +865,13 @@ bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) case 'r': res = RLIMIT_RTPRIO; break; +# else +# ifdef HAVE_RLIMIT_NTHR + /* For compatibility with sh on NetBSD */ + case 'r': + res = RLIMIT_NTHR; + break; +# endif /* HAVE_RLIMIT_NTHR */ # endif # ifdef HAVE_RLIMIT_NPTS case 'p': @@ -876,6 +888,11 @@ bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) res = RLIMIT_KQUEUES; break; # endif +# ifdef HAVE_RLIMIT_PTHREAD + case 'T': + res = RLIMIT_PTHREAD; + break; +# endif default: /* unrecognised limit */ zwarnnam(name, "bad option: -%c", *options); diff --git a/Src/Builtins/sched.c b/Src/Builtins/sched.c index 1ec3269bd..c1cc98354 100644 --- a/Src/Builtins/sched.c +++ b/Src/Builtins/sched.c @@ -211,7 +211,7 @@ bin_sched(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func)) t = sch->time; tmp = localtime(&t); - ztrftime(tbuf, 40, "%a %b %e %k:%M:%S", tmp); + ztrftime(tbuf, 40, "%a %b %e %k:%M:%S", tmp, 0L); if (sch->flags & SCHEDFLAG_TRASH_ZLE) flagstr = "-o "; else diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c index a4e7eca86..00ebd2b49 100644 --- a/Src/Modules/datetime.c +++ b/Src/Modules/datetime.c @@ -130,7 +130,7 @@ bin_strftime(char *nam, char **argv, Options ops, UNUSED(int func)) buffer = zalloc(bufsize); for (x=0; x < 4; x++) { - if (ztrftime(buffer, bufsize, argv[0], t) >= 0) + if (ztrftime(buffer, bufsize, argv[0], t, 0L) >= 0) break; buffer = zrealloc(buffer, bufsize *= 2); } diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c index 22148f991..0385a709e 100644 --- a/Src/Modules/parameter.c +++ b/Src/Modules/parameter.c @@ -106,7 +106,7 @@ getpmparameter(UNUSED(HashTable ht), const char *name) pm->u.str = paramtypestr(rpm); else { pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); } return &pm->node; } @@ -224,7 +224,7 @@ getpmcommand(UNUSED(HashTable ht), const char *name) } } else { pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); } return &pm->node; } @@ -410,7 +410,7 @@ getfunction(UNUSED(HashTable ht), const char *name, int dis) } } else { pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); } return &pm->node; } @@ -661,7 +661,7 @@ getbuiltin(UNUSED(HashTable ht), const char *name, int dis) pm->u.str = dupstring(t); } else { pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); } return &pm->node; } @@ -876,7 +876,7 @@ getpmoption(UNUSED(HashTable ht), const char *name) } else { pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); } return &pm->node; } @@ -934,7 +934,7 @@ getpmmodule(UNUSED(HashTable ht), const char *name) pm->u.str = dupstring(type); else { pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); } return &pm->node; } @@ -1048,7 +1048,7 @@ getpmhistory(UNUSED(HashTable ht), const char *name) pm->u.str = dupstring(he->node.nam); else { pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); } return &pm->node; } @@ -1158,7 +1158,7 @@ getpmjobtext(UNUSED(HashTable ht), const char *name) pm->u.str = pmjobtext(job); else { pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); } return &pm->node; } @@ -1259,7 +1259,7 @@ getpmjobstate(UNUSED(HashTable ht), const char *name) pm->u.str = pmjobstate(job); else { pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); } return &pm->node; } @@ -1325,7 +1325,7 @@ getpmjobdir(UNUSED(HashTable ht), const char *name) pm->u.str = pmjobdir(job); else { pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); } return &pm->node; } @@ -1451,7 +1451,7 @@ getpmnameddir(UNUSED(HashTable ht), const char *name) pm->u.str = dupstring(nd->dir); else { pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); } return &pm->node; } @@ -1502,7 +1502,7 @@ getpmuserdir(UNUSED(HashTable ht), const char *name) pm->u.str = dupstring(nd->dir); else { pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); } return &pm->node; } @@ -1754,7 +1754,7 @@ getalias(HashTable alht, UNUSED(HashTable ht), const char *name, int flags) pm->u.str = dupstring(al->text); else { pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); } return &pm->node; } @@ -1950,7 +1950,7 @@ getpmusergroups(UNUSED(HashTable ht), const char *name) if (!gs) { zerr("failed to retrieve groups for user: %e", errno); pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); return &pm->node; } @@ -1965,7 +1965,7 @@ getpmusergroups(UNUSED(HashTable ht), const char *name) } pm->u.str = dupstring(""); - pm->node.flags |= PM_UNSET; + pm->node.flags |= (PM_UNSET|PM_SPECIAL); return &pm->node; } diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c index cb9f8ef57..040a33f8e 100644 --- a/Src/Modules/pcre.c +++ b/Src/Modules/pcre.c @@ -289,14 +289,11 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) matched_portion = OPT_ARG(ops,c); } if(OPT_HASARG(ops,c='n')) { /* The offset position to start the search, in bytes. */ - offset_start = getposint(OPT_ARG(ops,c), nam); + if ((offset_start = getposint(OPT_ARG(ops,c), nam) < 0)) + return 1; } /* 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"); - } if ((ret = pcre_fullinfo(pcre_pattern, pcre_hints, PCRE_INFO_CAPTURECOUNT, &capcount))) { @@ -311,7 +308,7 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) unmetafy(plaintext, NULL); subject_len = (int)strlen(plaintext); - if (offset_start < 0 || offset_start >= subject_len) + if (offset_start > 0 && offset_start >= subject_len) ret = PCRE_ERROR_NOMATCH; else ret = pcre_exec(pcre_pattern, pcre_hints, plaintext, subject_len, offset_start, 0, ovec, ovecsize); @@ -345,6 +342,8 @@ cond_pcre_match(char **a, int id) if (zpcre_utf8_enabled()) pcre_opts |= PCRE_UTF8; + if (isset(REMATCHPCRE) && !isset(CASEMATCH)) + pcre_opts |= PCRE_CASELESS; lhstr = cond_str(a,0,0); rhre = cond_str(a,1,0); diff --git a/Src/Modules/stat.c b/Src/Modules/stat.c index edae0841e..6fc53894c 100644 --- a/Src/Modules/stat.c +++ b/Src/Modules/stat.c @@ -198,7 +198,7 @@ stattimeprint(time_t tim, char *outbuf, int flags) if (flags & STF_STRING) { char *oend = outbuf + strlen(outbuf); ztrftime(oend, 40, timefmt, (flags & STF_GMT) ? gmtime(&tim) : - localtime(&tim)); + localtime(&tim), 0L); if (flags & STF_RAW) strcat(oend, ")"); } diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index 399c45f46..1cca0c4b8 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -30,6 +30,55 @@ #include "zutil.mdh" #include "zutil.pro" +typedef struct { + char **match; + char **mbegin; + char **mend; +} MatchData; + +static void +savematch(MatchData *m) +{ + char **a; + + queue_signals(); + a = getaparam("match"); + m->match = a ? zarrdup(a) : NULL; + a = getaparam("mbegin"); + m->mbegin = a ? zarrdup(a) : NULL; + a = getaparam("mend"); + m->mend = a ? zarrdup(a) : NULL; + unqueue_signals(); +} + +static void +restorematch(MatchData *m) +{ + if (m->match) + setaparam("match", m->match); + else + unsetparam("match"); + if (m->mbegin) + setaparam("mbegin", m->mbegin); + else + unsetparam("mbegin"); + if (m->mend) + setaparam("mend", m->mend); + else + unsetparam("mend"); +} + +static void +freematch(MatchData *m) +{ + if (m->match) + freearray(m->match); + if (m->mbegin) + freearray(m->mbegin); + if (m->mend) + freearray(m->mend); +} + /* Style stuff. */ typedef struct stypat *Stypat; @@ -370,15 +419,21 @@ lookupstyle(char *ctxt, char *style) { Style s; Stypat p; + char **found = NULL; s = (Style)zstyletab->getnode2(zstyletab, style); - if (!s) - return NULL; - for (p = s->pats; p; p = p->next) - if (pattry(p->prog, ctxt)) - return (p->eval ? evalstyle(p) : p->vals); + if (s) { + MatchData match; + savematch(&match); + for (p = s->pats; p; p = p->next) + if (pattry(p->prog, ctxt)) { + found = (p->eval ? evalstyle(p) : p->vals); + break; + } + restorematch(&match); + } - return NULL; + return found; } static int @@ -915,55 +970,6 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) /* Zregexparse stuff. */ typedef struct { - char **match; - char **mbegin; - char **mend; -} MatchData; - -static void -savematch(MatchData *m) -{ - char **a; - - queue_signals(); - a = getaparam("match"); - m->match = a ? zarrdup(a) : NULL; - a = getaparam("mbegin"); - m->mbegin = a ? zarrdup(a) : NULL; - a = getaparam("mend"); - m->mend = a ? zarrdup(a) : NULL; - unqueue_signals(); -} - -static void -restorematch(MatchData *m) -{ - if (m->match) - setaparam("match", m->match); - else - unsetparam("match"); - if (m->mbegin) - setaparam("mbegin", m->mbegin); - else - unsetparam("mbegin"); - if (m->mend) - setaparam("mend", m->mend); - else - unsetparam("mend"); -} - -static void -freematch(MatchData *m) -{ - if (m->match) - freearray(m->match); - if (m->mbegin) - freearray(m->mbegin); - if (m->mend) - freearray(m->mend); -} - -typedef struct { int cutoff; char *pattern; Patprog patprog; @@ -1543,6 +1549,45 @@ add_opt_val(Zoptdesc d, char *arg) } } +/* + * For "zparseopts -K -A assoc ..." this function copies the keys and + * values from the default and allocates the extra space for any parsed + * values having the same keys. If there are no new values, creates an + * empty array. Returns a pointer to the NULL element marking the end. + * + * aval = pointer to the newly allocated array + * assoc = name of the default hash param to copy + * keep = whether we need to make the copy at all + * num = count of new values to add space for + */ +static char ** +zalloc_default_array(char ***aval, char *assoc, int keep, int num) +{ + char **ap = 0; + + *aval = 0; + if (keep && num) { + struct value vbuf; + Value v = fetchvalue(&vbuf, &assoc, 0, + SCANPM_WANTKEYS|SCANPM_WANTVALS|SCANPM_MATCHMANY); + if (v && v->isarr) { + char **dp, **dval = getarrvalue(v); + int dnum = (dval ? arrlen(dval) : 0) + 1; + *aval = (char **) zalloc(((num * 2) + dnum) * sizeof(char *)); + for (ap = *aval, dp = dval; dp && *dp; dp++) { + *ap = (char *) zalloc(strlen(*dp) + 1); + strcpy(*ap++, *dp); + } + *ap = NULL; + } + } + if (!ap) { + ap = *aval = (char **) zalloc(((num * 2) + 1) * sizeof(char *)); + *ap = NULL; + } + return ap; +} + static int bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) { @@ -1825,8 +1870,8 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) num++; if (!keep || num) { - aval = (char **) zalloc(((num * 2) + 1) * sizeof(char *)); - for (ap = aval, d = opt_descs; d; d = d->next) { + ap = zalloc_default_array(&aval, assoc, keep, num); + for (d = opt_descs; d; d = d->next) { if (d->vals) { *ap++ = n = (char *) zalloc(strlen(d->name) + 2); *n = '-'; diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 5c5628a8d..ac7785ab7 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -1260,6 +1260,20 @@ check_param(char *s, int set, int test) ispar = (br >= 2 ? 2 : 1); b[we-wb] = '\0'; return b; + } else if (offs > e - s && *e == ':') { + /* + * Guess whether we are in modifiers. + * If the name is followed by a : and the stuff after + * that is either colons or alphanumerics we probably are. + * This is a very rough guess. + */ + char *offsptr = s + offs; + for (; e < offsptr; e++) { + if (*e != ':' && !ialnum(*e)) + break; + } + ispar = (br >= 2 ? 2 : 1); + return NULL; } } return NULL; diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c index ab1857c0a..52b9e9c82 100644 --- a/Src/Zle/compctl.c +++ b/Src/Zle/compctl.c @@ -193,7 +193,7 @@ compctlread(char *name, char **args, Options ops, char *reply) /* only allowed to be called for completion */ if (!incompctlfunc) { - zwarnnam(name, "option valid only in functions called for completion"); + zwarnnam(name, "option valid only in functions called via compctl"); return 1; } @@ -3391,7 +3391,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) mflags |= CMF_FILE; for (n = firstnode(l); n; incnode(n)) addmatch(getdata(n), NULL); - mflags &= !CMF_FILE; + mflags &= ~CMF_FILE; } opts[NULLGLOB] = ng; } else { diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c index bcf356179..5e5ba9f20 100644 --- a/Src/Zle/complist.c +++ b/Src/Zle/complist.c @@ -383,12 +383,25 @@ getcoldef(char *s) } else if (*s == '=') { char *p = ++s, *t, *cols[MAX_POS]; int ncols = 0; + int nesting = 0; Patprog prog; /* This is for a pattern. */ - while (*s && *s != '=') - s++; + while (*s && (nesting || *s != '=')) { + switch (*s++) { + case '\\': + if (*s) + s++; + break; + case '(': + nesting++; + break; + case ')': + nesting--; + break; + } + } if (!*s) return s; *s++ = '\0'; @@ -2500,7 +2513,7 @@ domenuselect(Hookdef dummy, Chdata dat) mlbeg--; } } - if ((space = zterm_lines - pl - mhasstat)) + if ((space = zterm_lines - pl - mhasstat) > 0) while (mline >= mlbeg + space) if ((mlbeg += step) + space > mlines) mlbeg = mlines - space; diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c index c0e5ff3d8..fcceb670c 100644 --- a/Src/Zle/compresult.c +++ b/Src/Zle/compresult.c @@ -1131,7 +1131,7 @@ do_single(Cmatch m) /* If a suffix was added, and is removable, let * * `,' and `}' remove it. */ if (isset(AUTOPARAMKEYS)) - addsuffix(SUFTYP_POSSTR, 0, ZWS(",}"), 2, suffixnoinslen); + addsuffix(SUFTYP_POSSTR, 0, ZWS(",}"), 2, suffixlen); } else if (!menucmp) { /*{{*/ /* Otherwise, add a `,' suffix, and let `}' remove it. */ diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index f5e6ba195..b11c39f25 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -1500,9 +1500,11 @@ parse_cadef(char *nam, char **args) nodopts++; /* If this is for single-letter option we also store a - * pointer for the definition in the array for fast lookup. */ + * pointer for the definition in the array for fast lookup. + * But don't treat '--' as a single option called '-' */ - if (single && name[1] && !name[2]) + + if (single && name[1] && !name[2] && name[1] != '-') ret->single[STOUC(name[1])] = opt; if (again == 1) { @@ -2034,7 +2036,9 @@ ca_parse_line(Cadef d, int multi, int first) state.optbeg = state.argbeg = state.inopt = cur; state.argend = argend; state.singles = (d->single && (!pe || !*pe) && - state.curopt->name[1] && !state.curopt->name[2]); + state.curopt->name[1] && !state.curopt->name[2] && + /* Don't treat '--' as a single option called '-' */ + state.curopt->name[1] != '-'); if (!state.oargs[state.curopt->num]) state.oargs[state.curopt->num] = znewlinklist(); diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list index 4372fe36e..e3ffe3e8c 100644 --- a/Src/Zle/iwidgets.list +++ b/Src/Zle/iwidgets.list @@ -102,6 +102,7 @@ "self-insert-unmeta", selfinsertunmeta, ZLE_MENUCMP | ZLE_KEEPSUFFIX "send-break", sendbreak, 0 "set-mark-command", setmarkcommand, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL +"split-undo", splitundo, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_NOTCOMMAND "spell-word", spellword, 0 "set-local-history", setlocalhistory, 0 "transpose-chars", transposechars, 0 diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c index bd5bc36d5..44b39d186 100644 --- a/Src/Zle/zle_hist.c +++ b/Src/Zle/zle_hist.c @@ -890,6 +890,10 @@ zgetline(UNUSED(char **args)) free(s); free(lineadd); clearlist = 1; + if (stackhist != -1) { + histline = stackhist; + stackhist = -1; + } } return 0; } diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 040b7cb83..442c31995 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -157,10 +157,10 @@ mod_export char *statusline; /**/ int stackhist, stackcs; -/* != 0 if we are making undo records */ +/* position in undo stack from when the current vi change started */ /**/ -int undoing; +zlong vistartchange; /* current modifier status */ @@ -525,7 +525,8 @@ raw_getbyte(long do_keytmout, char *cptr) #endif #ifndef HAVE_POLL # ifdef HAVE_SELECT - fd_set foofd; + fd_set foofd, errfd; + FD_ZERO(&errfd); # endif #endif @@ -613,11 +614,14 @@ raw_getbyte(long do_keytmout, char *cptr) if (!errtry) { for (i = 0; i < nwatch; i++) { int fd = watch_fds[i].fd; + if (FD_ISSET(fd, &errfd)) + continue; FD_SET(fd, &foofd); if (fd > fdmax) fdmax = fd; } } + FD_ZERO(&errfd); if (tmout.tp != ZTM_NONE) { expire_tv.tv_sec = tmout.exp100ths / 100; @@ -732,9 +736,10 @@ raw_getbyte(long do_keytmout, char *cptr) Watch_fd lwatch_fd = lwatch_fds + i; if ( # ifdef HAVE_POLL - (fds[i+1].revents & POLLIN) + (fds[i+1].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL)) # else - FD_ISSET(lwatch_fd->fd, &foofd) + FD_ISSET(lwatch_fd->fd, &foofd) || + FD_ISSET(lwatch_fd->fd, &errfd) # endif ) { /* Handle the fd. */ @@ -765,6 +770,9 @@ raw_getbyte(long do_keytmout, char *cptr) if (fds[i+1].revents & POLLNVAL) zaddlinknode(funcargs, ztrdup("nval")); # endif +# else + if (FD_ISSET(lwatch_fd->fd, &errfd)) + zaddlinknode(funcargs, ztrdup("err")); # endif callhookfunc(lwatch_fd->func, funcargs, 0, NULL); freelinklist(funcargs, freestr); @@ -786,6 +794,31 @@ raw_getbyte(long do_keytmout, char *cptr) for (i = 0; i < lnwatch; i++) zsfree(lwatch_fds[i].func); zfree(lwatch_fds, lnwatch*sizeof(struct watch_fd)); + +# ifdef HAVE_POLL + /* Function may have added or removed handlers */ + nfds = 1 + nwatch; + if (nfds > 1) { + fds = zrealloc(fds, sizeof(struct pollfd) * nfds); + for (i = 0; i < nwatch; i++) { + /* + * This is imperfect because it assumes fds[] and + * watch_fds[] remain in sync, which may be false + * if handlers are shuffled. However, it should + * be harmless (e.g., produce one extra pass of + * the loop) in the event they fall out of sync. + */ + if (fds[i+1].fd == watch_fds[i].fd && + (fds[i+1].revents & (POLLERR|POLLHUP|POLLNVAL))) { + fds[i+1].events = 0; /* Don't poll this */ + } else { + fds[i+1].fd = watch_fds[i].fd; + fds[i+1].events = POLLIN; + } + fds[i+1].revents = 0; + } + } +# endif } } # ifdef HAVE_POLL @@ -1080,8 +1113,7 @@ zlecore(void) if (invicmdmode() && zlecs > findbol() && (zlecs == zlell || zleline[zlecs] == ZWC('\n'))) DECCS(); - if (undoing) - handleundo(); + handleundo(); } else { errflag = 1; break; @@ -1190,7 +1222,7 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish) zlereadflags = flags; zlecontext = context; histline = curhist; - undoing = 1; + vistartchange = -1; zleline = (ZLE_STRING_T)zalloc(((linesz = 256) + 2) * ZLE_CHAR_SIZE); *zleline = ZWC('\0'); virangeflag = lastcmd = done = zlecs = zlell = mark = 0; @@ -1198,14 +1230,7 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish) viinsbegin = 0; statusline = NULL; selectkeymap("main", 1); - /* - * If main is linked to the viins keymap, we need to register - * explicitly that we're now in vi insert mode as there's - * no user operation to indicate this. - */ - if (openkeymap("main") == openkeymap("viins")) - viinsert(NULL); - selectlocalmap(NULL); + initundo(); fixsuffix(); if ((s = getlinknode(bufstack))) { setline(s, ZSL_TOEND); @@ -1222,7 +1247,14 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish) stackhist = -1; } } - initundo(); + /* + * If main is linked to the viins keymap, we need to register + * explicitly that we're now in vi insert mode as there's + * no user operation to indicate this. + */ + if (openkeymap("main") == openkeymap("viins")) + viinsert_init(); + selectlocalmap(NULL); if (isset(PROMPTCR)) putc('\r', shout); if (tmout) diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index 7be0ebbd1..9bc1cf6f5 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -1249,10 +1249,14 @@ static char *suffixfunc; /* Length associated with the suffix function */ static int suffixfunclen; -/* Length associated with uninsertable characters */ +/* Whether to remove suffix on uninsertable characters */ +/**/ +int suffixnoinsrem; + +/* Length of the currently active, auto-removable suffix. */ /**/ mod_export int -suffixnoinslen; +suffixlen; /**/ mod_export void @@ -1309,7 +1313,8 @@ makesuffix(int n) if ((suffixchars = getsparam("ZLE_SPACE_SUFFIX_CHARS")) && *suffixchars) addsuffixstring(SUFTYP_POSSTR, SUFFLAGS_SPACE, suffixchars, n); - suffixnoinslen = n; + suffixlen = n; + suffixnoinsrem = 1; } /* Set up suffix for parameter names: the last n characters are a suffix * @@ -1358,15 +1363,10 @@ makesuffixstr(char *f, char *s, int n) s = metafy(s, i, META_USEHEAP); ws = stringaszleline(s, 0, &i, NULL, NULL); - if (z) - suffixnoinslen = inv ? 0 : n; - else if (inv) { - /* - * negative match, \- wasn't present, so it *should* - * have this suffix length - */ - suffixnoinslen = n; - } + /* Remove suffix on uninsertable characters if \- was given * + * and the character class wasn't negated -- or vice versa. */ + suffixnoinsrem = z ^ inv; + suffixlen = n; lasts = wptr = ws; while (i) { @@ -1444,7 +1444,7 @@ iremovesuffix(ZLE_INT_T c, int keep) struct suffixset *ss; if (c == NO_INSERT_CHAR) { - sl = suffixnoinslen; + sl = suffixnoinsrem ? suffixlen : 0; } else { ZLE_CHAR_T ch = c; /* @@ -1538,5 +1538,5 @@ fixsuffix(void) suffixlist = next; } - suffixfunclen = suffixnoinslen = 0; + suffixfunclen = suffixnoinsrem = suffixlen = 0; } diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c index a9bbf136a..5845207fa 100644 --- a/Src/Zle/zle_params.c +++ b/Src/Zle/zle_params.c @@ -363,7 +363,7 @@ get_prebuffer(UNUSED(Param pm)) static char * get_widget(UNUSED(Param pm)) { - return bindk->nam; + return bindk ? bindk->nam : ""; } /**/ diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index fd5485770..80be27f03 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -444,6 +444,7 @@ void set_region_highlight(UNUSED(Param pm), char **aval) { int len; + char **av = aval; struct region_highlight *rhp; len = aval ? arrlen(aval) : 0; @@ -490,6 +491,8 @@ set_region_highlight(UNUSED(Param pm), char **aval) match_highlight(strp, &rhp->atr); } + + freearray(av); } @@ -977,7 +980,7 @@ zrefresh(void) int tmpalloced; /* flag to free tmpline when finished */ int remetafy; /* flag that zle line is metafied */ int txtchange; /* attributes set after prompts */ - int rprompt_off; /* Offset of rprompt from right of screen */ + int rprompt_off = 1; /* Offset of rprompt from right of screen */ struct rparams rpms; #ifdef MULTIBYTE_SUPPORT int width; /* width of wide character */ @@ -1046,8 +1049,8 @@ zrefresh(void) region_highlights[1].start = region_highlights[1].end = -1; } /* check for an active completion suffix */ - if (suffixnoinslen) { - region_highlights[2].start = zlecs - suffixnoinslen; + if (suffixlen) { + region_highlights[2].start = zlecs - suffixlen; region_highlights[2].end = zlecs; } else { region_highlights[2].start = region_highlights[2].end = -1; diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 9d163ad9e..499c4ae77 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -611,8 +611,6 @@ docomplete(int lst) active = 1; comprecursive = 0; makecommaspecial(0); - if (undoing) - setlastline(); /* From the C-code's point of view, we can only use compctl as a default * type of completion. Load it if it hasn't been loaded already and @@ -1164,7 +1162,7 @@ get_comp_string(void) * being separated by tokens | & &! |& || &&). The loop stops when * * the end of the command containing the cursor is reached. What * * makes this messy is checking for things like redirections, loops * - * and whatnot. */ + * and whatnot. */ do { qsub = noword = 0; @@ -2797,6 +2795,7 @@ doexpandhist(void) if (!err) { zlemetacs = excs; if (strcmp(zlemetaline, ol)) { + zle_free_positions(); unmetafy_line(); /* For vi mode -- reset the beginning-of-insertion pointer * * to the beginning of the line. This seems a little silly, * diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index b82e54ce5..1089e274f 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -710,6 +710,27 @@ zle_restore_positions(void) } /* + * Discard positions previously saved, the line has been updated. + */ + +/**/ +mod_export void +zle_free_positions(void) +{ + struct zle_position *oldpos = zle_positions; + struct zle_region *oldrhp; + + zle_positions = oldpos->next; + oldrhp = oldpos->regions; + while (oldrhp) { + struct zle_region *nextrhp = oldrhp->next; + zfree(oldrhp, sizeof(*oldrhp)); + oldrhp = nextrhp; + } + zfree(oldpos, sizeof(*oldpos)); +} + +/* * Basic utility functions for adding to line or removing from line. * At this level the counts supplied are raw character counts, so * the calling code must be aware of combining characters where @@ -1354,7 +1375,10 @@ handlesuffix(UNUSED(char **args)) /* head of the undo list, and the current position */ -static struct change *changes, *curchange; +/**/ +struct change *curchange; + +static struct change *changes; /* list of pending changes, not yet in the undo system */ @@ -1629,6 +1653,32 @@ viundochange(char **args) return undo(args); } +/**/ +int +splitundo(char **args) +{ + if (vistartchange >= 0) { + mergeundo(); + vistartchange = (curchange && curchange->prev) ? + curchange->prev->changeno : 0; + } + handleundo(); + return 0; +} + +/**/ +void +mergeundo(void) +{ + struct change *current; + for (current = curchange->prev; + current && current->prev && current->changeno > vistartchange+1; + current = current->prev) { + current->flags |= CH_PREV; + current->prev->flags |= CH_NEXT; + } +} + /* * Call a ZLE hook: a user-defined widget called at a specific point * within the line editor. diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c index 173a49ef9..9e39143d0 100644 --- a/Src/Zle/zle_vi.c +++ b/Src/Zle/zle_vi.c @@ -67,15 +67,23 @@ int viinsbegin; static struct modifier lastmod; static int inrepeat, vichgrepeat; +/** + * im: >= 0: is an insertmode + * -1: skip setting insert mode + * -2: entering viins at start of editing from clean --- don't use + * inrepeat or lastchar, synthesise an i to enter insert mode. + */ + /**/ static void startvichange(int im) { if (im != -1) { - insmode = im; vichgflag = 1; + if (im > -1) + insmode = im; } - if (inrepeat) { + if (inrepeat && im != -2) { zmod = lastmod; inrepeat = vichgflag = 0; vichgrepeat = 1; @@ -84,7 +92,12 @@ startvichange(int im) if (vichgbuf) free(vichgbuf); vichgbuf = (char *)zalloc(vichgbufsz = 16); - vichgbuf[0] = lastchar; + if (im == -2) { + vichgbuf[0] = + zlell ? (insmode ? (zlecs < zlell ? 'i' : 'a') : 'R') : 'o'; + } else { + vichgbuf[0] = lastchar; + } vichgbufptr = 1; vichgrepeat = 0; } @@ -96,7 +109,7 @@ startvitext(int im) { startvichange(im); selectkeymap("main", 1); - undoing = 0; + vistartchange = (curchange && curchange->prev) ? curchange->prev->changeno : 0; viinsbegin = zlecs; } @@ -303,6 +316,18 @@ viinsert(UNUSED(char **args)) return 0; } +/* + * Go to vi insert mode when we first start the line editor. + * Iniialises some other stuff. + */ + +/**/ +void +viinsert_init(void) +{ + startvitext(-2); +} + /**/ int viinsertbol(UNUSED(char **args)) @@ -376,7 +401,7 @@ vichange(UNUSED(char **args)) forekill(c2 - zlecs, CUT_RAW); selectkeymap("main", 1); viinsbegin = zlecs; - undoing = 0; + vistartchange = (curchange && curchange->prev) ? curchange->prev->changeno : 0; } return ret; } @@ -561,7 +586,7 @@ vicmdmode(UNUSED(char **args)) { if (invicmdmode() || selectkeymap("vicmd", 0)) return 1; - undoing = 1; + mergeundo(); vichgflag = 0; if (zlecs != findbol()) DECCS(); diff --git a/Src/builtin.c b/Src/builtin.c index c3f0169c7..a2a3ad748 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -111,7 +111,7 @@ static struct builtin builtins[] = BUILTIN("return", BINF_PSPECIAL, bin_break, 0, 1, BIN_RETURN, NULL, NULL), BUILTIN("set", BINF_PSPECIAL | BINF_HANDLES_OPTS, bin_set, 0, -1, 0, NULL, NULL), BUILTIN("setopt", 0, bin_setopt, 0, -1, BIN_SETOPT, NULL, NULL), - BUILTIN("shift", BINF_PSPECIAL, bin_shift, 0, -1, 0, NULL, NULL), + BUILTIN("shift", BINF_PSPECIAL, bin_shift, 0, -1, 0, "p", NULL), BUILTIN("source", BINF_PSPECIAL, bin_dot, 1, -1, 0, NULL, NULL), BUILTIN("suspend", 0, bin_suspend, 0, 0, 0, "f", NULL), BUILTIN("test", BINF_HANDLES_OPTS, bin_test, 0, -1, BIN_TEST, NULL, NULL), @@ -1422,6 +1422,10 @@ bin_fc(char *nam, char **argv, Options ops, int func) unqueue_signals(); return 0; } + if (OPT_ISSET(ops,'I')) { + zwarnnam(nam, "-I requires one of -R/-W/-A"); + return 1; + } if (zleactive) { zwarnnam(nam, "no interactive history within ZLE"); @@ -1727,7 +1731,7 @@ fclist(FILE *f, Options ops, zlong first, zlong last, if (tdfmt != NULL) { struct tm *ltm; ltm = localtime(&ent->stim); - if (ztrftime(timebuf, 256, tdfmt, ltm)) + if (ztrftime(timebuf, 256, tdfmt, ltm, 0L)) fprintf(f, "%s ", timebuf); } /* display the time taken by the command, if required */ @@ -4509,7 +4513,7 @@ bin_print(char *name, char **args, Options ops, int func) /**/ int -bin_shift(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) +bin_shift(char *name, char **argv, Options ops, UNUSED(int func)) { int num = 1, l, ret = 0; char **s; @@ -4533,7 +4537,19 @@ bin_shift(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) ret++; continue; } - s = zarrdup(s + num); + if (OPT_ISSET(ops,'p')) { + char **s2, **src, **dst; + int count; + l = arrlen(s); + src = s; + dst = s2 = (char **)zalloc((l - num + 1) * sizeof(char *)); + for (count = l - num; count; count--) + *dst++ = ztrdup(*src++); + *dst = NULL; + s = s2; + } else { + s = zarrdup(s + num); + } setaparam(*argv, s); } } else { @@ -4542,9 +4558,16 @@ bin_shift(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) ret = 1; } else { s = zalloc((l - num + 1) * sizeof(char *)); - memcpy(s, pparams + num, (l - num + 1) * sizeof(char *)); - while (num--) - zsfree(pparams[num]); + if (OPT_ISSET(ops,'p')) { + memcpy(s, pparams, (l - num) * sizeof(char *)); + s[l-num] = NULL; + while (num--) + zsfree(pparams[l-1-num]); + } else { + memcpy(s, pparams + num, (l - num + 1) * sizeof(char *)); + while (num--) + zsfree(pparams[num]); + } zfree(pparams, (l + 1) * sizeof(char *)); pparams = s; } @@ -4669,9 +4692,10 @@ exit_pending; int bin_break(char *name, char **argv, UNUSED(Options ops), int func) { - int num = lastval, nump = 0; + int num = lastval, nump = 0, implicit; /* handle one optional numeric argument */ + implicit = !*argv; if (*argv) { num = mathevali(*argv++); nump = 1; @@ -4702,7 +4726,13 @@ bin_break(char *name, char **argv, UNUSED(Options ops), int func) retflag = 1; breaks = loops; lastval = num; - if (trap_state == TRAP_STATE_PRIMED && trap_return == -2) { + if (trap_state == TRAP_STATE_PRIMED && trap_return == -2 + /* + * With POSIX, "return" on its own in a trap doesn't + * update $? --- we keep the status from before the + * trap. + */ + && !(isset(POSIXTRAPS) && implicit)) { trap_state = TRAP_STATE_FORCE_RETURN; trap_return = lastval; } @@ -6069,8 +6099,9 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func) } /* display a time, provided in units of 1/60s, as minutes and seconds */ -#define pttime(X) printf("%ldm%ld.%02lds",((long) (X))/3600,\ - ((long) (X))/60%60,((long) (X))*100/60%100) +#define pttime(X) printf("%ldm%ld.%02lds",((long) (X))/(60 * clktck),\ + ((long) (X))/clktck%clktck,\ + ((long) (X))*100/clktck%100) /* times: display, in a two-line format, the times provided by times(3) */ @@ -6079,6 +6110,7 @@ int bin_times(UNUSED(char *name), UNUSED(char **argv), UNUSED(Options ops), UNUSED(int func)) { struct tms buf; + long clktck = get_clktck(); /* get time accounting information */ if (times(&buf) == -1) diff --git a/Src/compat.c b/Src/compat.c index cc4e876da..b0bcb6265 100644 --- a/Src/compat.c +++ b/Src/compat.c @@ -37,7 +37,7 @@ char * strstr(const char *s, const char *t) { - char *p1, *p2; + const char *p1, *p2; for (; *s; s++) { for (p1 = s, p2 = t; *p2; p1++, p2++) diff --git a/Src/cond.c b/Src/cond.c index c67354297..df9065660 100644 --- a/Src/cond.c +++ b/Src/cond.c @@ -37,6 +37,21 @@ static char *condstr[COND_MOD] = { "-ne", "-lt", "-gt", "-le", "-ge", "=~" }; +static void cond_subst(char **strp, int glob_ok) +{ + if (glob_ok && + checkglobqual(*strp, strlen(*strp), 1, NULL)) { + LinkList args = newlinklist(); + addlinknode(args, *strp); + prefork(args, 0); + while (!errflag && args && nonempty(args) && + has_token((char *)peekfirst(args))) + zglob(args, firstnode(args), 0); + *strp = sepjoin(hlinklist2array(args, 0), NULL, 1); + } else + singsub(strp); +} + /* * Evaluate a conditional expression given the arguments. * If fromtest is set, the caller is the test or [ builtin; @@ -177,13 +192,13 @@ evalcond(Estate state, char *fromtest) } left = ecgetstr(state, EC_DUPTOK, &htok); if (htok) { - singsub(&left); + cond_subst(&left, !fromtest); untokenize(left); } if (ctype <= COND_GE && ctype != COND_STREQ && ctype != COND_STRNEQ) { right = ecgetstr(state, EC_DUPTOK, &htok); if (htok) { - singsub(&right); + cond_subst(&right, !fromtest); untokenize(right); } } @@ -194,7 +209,7 @@ evalcond(Estate state, char *fromtest) fprintf(xtrerr, " %s ", condstr[ctype]); if (ctype == COND_STREQ || ctype == COND_STRNEQ) { char *rt = dupstring(ecrawstr(state->prog, state->pc, NULL)); - singsub(&rt); + cond_subst(&rt, !fromtest); quote_tokenized_output(rt, xtrerr); } else @@ -282,8 +297,7 @@ evalcond(Estate state, char *fromtest) right = dupstring(opat = ecrawstr(state->prog, state->pc, &htok)); - if (htok) - singsub(&right); + singsub(&right); save = (!(state->prog->flags & EF_HEAP) && !strcmp(opat, right) && pprog != dummy_patprog2); diff --git a/Src/exec.c b/Src/exec.c index f16cfd391..5ad957f98 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2346,7 +2346,7 @@ execsubst(LinkList strs) { if (strs) { prefork(strs, esprefork); - if (esglob) { + if (esglob && !errflag) { LinkList ostrs = strs; globlist(strs, 0); strs = ostrs; @@ -3867,8 +3867,10 @@ getoutputfile(char *cmd, char **eptr) int fd; char *s; - if (thisjob == -1) + if (thisjob == -1){ + zerr("process substitution %s cannot be used here", cmd); return NULL; + } if (!(prog = parsecmd(cmd, eptr))) return NULL; if (!(nam = gettempname(NULL, 0))) @@ -3939,11 +3941,13 @@ namedpipe(void) char *tnam = gettempname(NULL, 1); # ifdef HAVE_MKFIFO - if (mkfifo(tnam, 0600) < 0) + if (mkfifo(tnam, 0600) < 0){ # else - if (mknod(tnam, 0010600, 0) < 0) + if (mknod(tnam, 0010600, 0) < 0){ # endif + zerr("failed to create named pipe: %s, %e", tnam, errno); return NULL; + } return tnam; } #endif /* ! PATH_DEV_FD && HAVE_FIFOS */ @@ -3966,9 +3970,10 @@ getproc(char *cmd, char **eptr) #ifndef PATH_DEV_FD int fd; - - if (thisjob == -1) + if (thisjob == -1) { + zerr("process substitution %s cannot be used here", cmd); return NULL; + } if (!(pnam = namedpipe())) return NULL; if (!(prog = parsecmd(cmd, eptr))) @@ -3993,8 +3998,10 @@ getproc(char *cmd, char **eptr) #else /* PATH_DEV_FD */ int pipes[2], fd; - if (thisjob == -1) + if (thisjob == -1) { + zerr("process substitution %s cannot be used here", cmd); return NULL; + } pnam = hcalloc(strlen(PATH_DEV_FD) + 6); if (!(prog = parsecmd(cmd, eptr))) return NULL; @@ -4234,8 +4241,13 @@ execfuncdef(Estate state, UNUSED(int do_exec)) plen = nprg * sizeof(wordcode); len = plen + (npats * sizeof(Patprog)) + nstrs; - if (htok && names) + if (htok && names) { execsubst(names); + if (errflag) { + state->pc = end; + return 1; + } + } while (!names || (s = (char *) ugetnode(names))) { if (!names) { @@ -4291,8 +4303,13 @@ execfuncdef(Estate state, UNUSED(int do_exec)) end += *state->pc++; args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok); - if (htok && args) + if (htok && args) { execsubst(args); + if (errflag) { + state->pc = end; + return 1; + } + } if (!args) args = newlinklist(); @@ -4597,7 +4614,7 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) char *name = shfunc->node.nam; int flags = shfunc->node.flags, ooflags; char *fname = dupstring(name); - int obreaks, saveemulation, restore_sticky; + int obreaks, ocontflag, oloops, saveemulation, restore_sticky; Eprog prog; struct funcstack fstack; static int oflags; @@ -4609,7 +4626,9 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) pushheap(); oargv0 = NULL; - obreaks = breaks;; + obreaks = breaks; + ocontflag = contflag; + oloops = loops; if (trap_state == TRAP_STATE_PRIMED) trap_return--; oldlastval = lastval; @@ -4797,6 +4816,17 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) opts[XTRACE] = saveopts[XTRACE]; opts[PRINTEXITVALUE] = saveopts[PRINTEXITVALUE]; opts[LOCALOPTIONS] = saveopts[LOCALOPTIONS]; + opts[LOCALLOOPS] = saveopts[LOCALLOOPS]; + } + + if (opts[LOCALLOOPS]) { + if (contflag) + zwarn("`continue' active at end of function scope"); + if (breaks) + zwarn("`break' active at end of function scope"); + breaks = obreaks; + contflag = ocontflag; + loops = oloops; } endtrapscope(); diff --git a/Src/glob.c b/Src/glob.c index e0d0cf68e..627166c7a 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -120,6 +120,8 @@ typedef struct stat *Statptr; /* This makes the Ultrix compiler happy. Go figu #define TT_POSIX_BLOCKS 1 #define TT_KILOBYTES 2 #define TT_MEGABYTES 3 +#define TT_GIGABYTES 4 +#define TT_TERABYTES 5 typedef int (*TestMatchFunc) _((char *, struct stat *, off_t, char *)); @@ -443,6 +445,7 @@ insert(char *s, int checked) break; } unqueue_signals(); + return; } /* Do the globbing: scanner is called recursively * @@ -451,7 +454,7 @@ insert(char *s, int checked) /**/ static void -scanner(Complist q) +scanner(Complist q, int shortcircuit) { Patprog p; int closure; @@ -459,16 +462,19 @@ scanner(Complist q) int errssofar = errsfound; struct dirsav ds; - init_dirsav(&ds); if (!q) return; + init_dirsav(&ds); if ((closure = q->closure)) { /* (foo/)# - match zero or more dirs */ if (q->closure == 2) /* (foo/)## - match one or more dirs */ q->closure = 1; - else - scanner(q->next); + else { + scanner(q->next, shortcircuit); + if (shortcircuit && shortcircuit == matchct) + return; + } } p = q->pat; /* Now the actual matching for the current path section. */ @@ -513,8 +519,11 @@ scanner(Complist q) } if (add) { addpath(str, l); - if (!closure || !statfullpath("", NULL, 1)) - scanner((q->closure) ? q : q->next); + if (!closure || !statfullpath("", NULL, 1)) { + scanner((q->closure) ? q : q->next, shortcircuit); + if (shortcircuit && shortcircuit == matchct) + return; + } pathbuf[pathpos = oppos] = '\0'; } } @@ -522,6 +531,8 @@ scanner(Complist q) if (str[l]) str = dupstrpfx(str, l); insert(str, 0); + if (shortcircuit && shortcircuit == matchct) + return; } } else { /* Do pattern matching on current path section. */ @@ -609,9 +620,12 @@ scanner(Complist q) memcpy(subdirs + subdirlen, (char *)&errsfound, sizeof(int)); subdirlen += sizeof(int); - } else + } else { /* if the last filename component, just add it */ insert(fn, 1); + if (shortcircuit && shortcircuit == matchct) + return; + } } } closedir(lock); @@ -624,7 +638,10 @@ scanner(Complist q) fn += l + 1; memcpy((char *)&errsfound, fn, sizeof(int)); fn += sizeof(int); - scanner((q->closure) ? q : q->next); /* scan next level */ + /* scan next level */ + scanner((q->closure) ? q : q->next, shortcircuit); + if (shortcircuit && shortcircuit == matchct) + return; pathbuf[pathpos = oppos] = '\0'; } hrealloc(subdirs, subdirlen, 0); @@ -638,6 +655,7 @@ scanner(Complist q) close(ds.dirfd); pathbufcwd = pbcwdsav; } + return; } /* This function tokenizes a zsh glob pattern */ @@ -1059,6 +1077,67 @@ insert_glob_match(LinkList list, LinkNode next, char *data) insertlinknode(list, next, data); } +/* + * Return + * 1 if str ends in bare glob qualifiers + * 2 if str ends in non-bare glob qualifiers (#q) + * 0 otherwise. + * + * str is the string to check. + * sl is its length (to avoid recalculation). + * nobareglob is 1 if bare glob qualifiers are not allowed. + * *sp, if sp is not null, will be a pointer to the opening parenthesis. + */ + +/**/ +int +checkglobqual(char *str, int sl, int nobareglob, char **sp) +{ + char *s; + int paren, ret = 1; + + if (str[sl - 1] != Outpar) + return 0; + + /* Check these are really qualifiers, not a set of * + * alternatives or exclusions. We can be more * + * lenient with an explicit (#q) than with a bare * + * set of qualifiers. */ + paren = 0; + for (s = str + sl - 2; *s && (*s != Inpar || paren); s--) { + switch (*s) { + case Outpar: + paren++; /*FALLTHROUGH*/ + case Bar: + if (!zpc_disables[ZPC_BAR]) + nobareglob = 1; + break; + case Tilde: + if (isset(EXTENDEDGLOB) && !zpc_disables[ZPC_TILDE]) + nobareglob = 1; + break; + case Inpar: + paren--; + break; + } + if (s == str) + break; + } + if (*s != Inpar) + return 0; + if (isset(EXTENDEDGLOB) && !zpc_disables[ZPC_HASH] && s[1] == Pound) { + if (s[2] != 'q') + return 0; + ret = 2; + } else if (nobareglob) + return 0; + + if (sp) + *sp = s; + + return ret; +} + /* Main entry point to the globbing code for filename globbing. * * np points to a node in the list list which will be expanded * * into a series of nodes. */ @@ -1078,6 +1157,8 @@ zglob(LinkList list, LinkNode np, int nountok) /* and index+1 of the last match */ struct globdata saved; /* saved glob state */ int nobareglob = !isset(BAREGLOBQUAL); + int shortcircuit = 0; /* How many files to match; */ + /* 0 means no limit */ if (unset(GLOBOPT) || !haswilds(ostr) || unset(EXECOPT)) { if (!nountok) @@ -1116,7 +1197,7 @@ zglob(LinkList list, LinkNode np, int nountok) (isset(EXTENDEDGLOB) && !zpc_disables[ZPC_HASH])) { struct qual *newquals; char *s; - int sense, paren; + int sense, qualsfound; off_t data; char *sdata, *newcolonmod; int (*func) _((char *, Statptr, off_t, char *)); @@ -1146,40 +1227,7 @@ zglob(LinkList list, LinkNode np, int nountok) newquals = qo = qn = ql = NULL; sl = strlen(str); - if (str[sl - 1] != Outpar) - break; - - /* Check these are really qualifiers, not a set of * - * alternatives or exclusions. We can be more * - * lenient with an explicit (#q) than with a bare * - * set of qualifiers. */ - paren = 0; - for (s = str + sl - 2; *s && (*s != Inpar || paren); s--) { - switch (*s) { - case Outpar: - paren++; /*FALLTHROUGH*/ - case Bar: - if (!zpc_disables[ZPC_BAR]) - nobareglob = 1; - break; - case Tilde: - if (isset(EXTENDEDGLOB) && !zpc_disables[ZPC_TILDE]) - nobareglob = 1; - break; - case Inpar: - paren--; - break; - } - } - if (*s != Inpar) - break; - if (isset(EXTENDEDGLOB) && !zpc_disables[ZPC_HASH] && s[1] == Pound) { - if (s[2] == 'q') { - *s = 0; - s += 2; - } else - break; - } else if (nobareglob) + if (!(qualsfound = checkglobqual(str, sl, nobareglob, &s))) break; /* Real qualifiers found. */ @@ -1192,6 +1240,8 @@ zglob(LinkList list, LinkNode np, int nountok) str[sl-1] = 0; *s++ = 0; + if (qualsfound == 2) + s += 2; while (*s && !newcolonmod) { func = (int (*) _((char *, Statptr, off_t, char *)))0; if (idigit(*s)) { @@ -1362,7 +1412,7 @@ zglob(LinkList list, LinkNode np, int nountok) /* Find matching delimiters */ tt = get_strarg(s, &arglen); if (!*tt) { - zerr("missing end of name"); + zerr("missing delimiter for 'u' glob qualifier"); data = 0; } else { #ifdef USE_GETPWNAM @@ -1402,7 +1452,7 @@ zglob(LinkList list, LinkNode np, int nountok) tt = get_strarg(s, &arglen); if (!*tt) { - zerr("missing end of name"); + zerr("missing delimiter for 'g' glob qualifier"); data = 0; } else { #ifdef USE_GETGRNAM @@ -1459,6 +1509,23 @@ zglob(LinkList list, LinkNode np, int nountok) /* Numeric glob sort */ gf_numsort = !(sense & 1); break; + case 'Y': + { + /* Short circuit: limit number of matches */ + const char *s_saved = s; + shortcircuit = !(sense & 1); + if (shortcircuit) { + /* Parse the argument. */ + data = qgetnum(&s); + if ((shortcircuit = data) != data) { + /* Integer overflow */ + zerr("value too big: Y%s", s_saved); + restore_globstate(saved); + return; + } + } + break; + } case 'a': /* Access time in given range */ g_amc = 0; @@ -1486,6 +1553,12 @@ zglob(LinkList list, LinkNode np, int nountok) g_units = TT_KILOBYTES, ++s; else if (*s == 'm' || *s == 'M') g_units = TT_MEGABYTES, ++s; +#if defined(ZSH_64_BIT_TYPE) || defined(LONG_IS_64_BIT) + else if (*s == 'g' || *s == 'G') + g_units = TT_GIGABYTES, ++s; + else if (*s == 't' || *s == 'T') + g_units = TT_TERABYTES, ++s; +#endif getrange: /* Get time multiplier */ if (g_amc >= 0) { @@ -1549,9 +1622,10 @@ zglob(LinkList list, LinkNode np, int nountok) restore_globstate(saved); return; } + if ((sense & 2) && + (t & (GS_SIZE|GS_ATIME|GS_MTIME|GS_CTIME|GS_LINKS))) + t <<= GS_SHIFT; /* HERE: GS_EXEC? */ if (t != GS_EXEC) { - if ((sense & 2) && !(t & (GS_NAME|GS_DEPTH))) - t <<= GS_SHIFT; /* HERE: GS_EXEC? */ if (gf_sorts & t) { zerr("doubled sort specifier"); restore_globstate(saved); @@ -1709,7 +1783,7 @@ zglob(LinkList list, LinkNode np, int nountok) return; } if (!gf_nsorts) { - gf_sortlist[0].tp = gf_sorts = GS_NAME; + gf_sortlist[0].tp = gf_sorts = (shortcircuit ? GS_NONE : GS_NAME); gf_nsorts = 1; } /* Initialise receptacle for matched files, * @@ -1721,7 +1795,7 @@ zglob(LinkList list, LinkNode np, int nountok) /* The actual processing takes place here: matches go into * * matchbuf. This is the only top-level call to scanner(). */ - scanner(q); + scanner(q, shortcircuit); /* Deal with failures to match depending on options */ if (matchct) @@ -1832,6 +1906,8 @@ zglob(LinkList list, LinkNode np, int nountok) matchptr++; } } + } else if (!badcshglob && !isset(NOMATCH) && matchct == 1) { + insert_glob_match(list, node, (--matchptr)->name); } free(matchbuf); @@ -1895,6 +1971,8 @@ hasbraces(char *str) switch (*str++) { case Inbrace: if (!lbr) { + if (bracechardots(str-1, NULL, NULL)) + return 1; lbr = str - 1; if (*str == '-') str++; @@ -2027,6 +2105,68 @@ xpandredir(struct redir *fn, LinkList redirtab) return ret; } +/* + * Check for a brace expansion of the form {<char>..<char>}. + * On input str must be positioned at an Inbrace, but the sequence + * of characters beyond that has not necessarily been checked. + * Return 1 if found else 0. + * + * The other parameters are optionaland if the function returns 1 are + * used to return: + * - *c1p: the first character in the expansion. + * - *c2p: the final character in the expansion. + */ + +/**/ +static int +bracechardots(char *str, convchar_t *c1p, convchar_t *c2p) +{ + convchar_t cstart, cend; + char *pnext = str + 1, *pconv, convstr[2]; + if (itok(*pnext)) { + if (*pnext == Inbrace) + return 0; + convstr[0] = ztokens[*pnext - Pound]; + convstr[1] = '\0'; + pconv = convstr; + } else + pconv = pnext; + MB_METACHARINIT(); + pnext += MB_METACHARLENCONV(pconv, &cstart); + if ( +#ifdef MULTIBYTE_SUPPORT + cstart == WEOF || +#else + !cstart || +#endif + pnext[0] != '.' || pnext[1] != '.') + return 0; + pnext += 2; + if (itok(*pnext)) { + if (*pnext == Inbrace) + return 0; + convstr[0] = ztokens[*pnext - Pound]; + convstr[1] = '\0'; + pconv = convstr; + } else + pconv = pnext; + MB_METACHARINIT(); + pnext += MB_METACHARLENCONV(pconv, &cend); + if ( +#ifdef MULTIBYTE_SUPPORT + cend == WEOF || +#else + !cend || +#endif + *pnext != Outbrace) + return 0; + if (c1p) + *c1p = cstart; + if (c2p) + *c2p = cend; + return 1; +} + /* brace expansion */ /**/ @@ -2060,10 +2200,57 @@ xpandbraces(LinkList list, LinkNode *np) char *dots, *p, *dots2 = NULL; LinkNode olast = last; /* Get the first number of the range */ - zlong rstart = zstrtol(str+1,&dots,10), rend = 0; + zlong rstart, rend; int err = 0, rev = 0, rincr = 1; - int wid1 = (dots - str) - 1, wid2 = (str2 - dots) - 2, wid3 = 0; - int strp = str - str3; + int wid1, wid2, wid3, strp; + convchar_t cstart, cend; + + if (bracechardots(str, &cstart, &cend)) { + int lenalloc; + /* + * This is a character range. + */ + if (cend < cstart) { + convchar_t ctmp = cend; + cend = cstart; + cstart = ctmp; + rev = 1; + } + uremnode(list, node); + strp = str - str3; + lenalloc = strp + strlen(str2+1) + 1; + for (; cend >= cstart; cend--) { +#ifdef MULTIBYTE_SUPPORT + char *ncptr; + int nclen; + mb_metacharinit(); + ncptr = wcs_nicechar(cend, NULL, NULL); + nclen = strlen(ncptr); + p = zhalloc(lenalloc + nclen); + memcpy(p, str3, strp); + memcpy(p + strp, ncptr, nclen); + strcpy(p + strp + nclen, str2 + 1); +#else + p = zhalloc(lenalloc + 1); + memcpy(p, str3, strp); + sprintf(p + strp, "%c", cend); + strcat(p + strp, str2 + 1); +#endif + insertlinknode(list, last, p); + if (rev) /* decreasing: add in reverse order. */ + last = nextnode(last); + } + *np = nextnode(olast); + return; + } + + /* Get the first number of the range */ + rstart = zstrtol(str+1,&dots,10); + rend = 0; + wid1 = (dots - str) - 1; + wid2 = (str2 - dots) - 2; + wid3 = 0; + strp = str - str3; if (dots == str + 1 || *dots != '.' || dots[1] != '.') err++; @@ -3443,9 +3630,9 @@ qualiscom(UNUSED(char *name), struct stat *buf, UNUSED(off_t mod), UNUSED(char * static int qualsize(UNUSED(char *name), struct stat *buf, off_t size, UNUSED(char *dummy)) { -#if defined(LONG_IS_64_BIT) || defined(OFF_T_IS_64_BIT) +#if defined(ZSH_64_BIT_TYPE) || defined(LONG_IS_64_BIT) # define QS_CAST_SIZE() - off_t scaled = buf->st_size; + zlong scaled = buf->st_size; #else # define QS_CAST_SIZE() (unsigned long) unsigned long scaled = (unsigned long)buf->st_size; @@ -3464,6 +3651,16 @@ qualsize(UNUSED(char *name), struct stat *buf, off_t size, UNUSED(char *dummy)) scaled += 1048575l; scaled /= 1048576l; break; +#if defined(ZSH_64_BIT_TYPE) || defined(LONG_IS_64_BIT) + case TT_GIGABYTES: + scaled += ZLONG_CONST(1073741823); + scaled /= ZLONG_CONST(1073741824); + break; + case TT_TERABYTES: + scaled += ZLONG_CONST(1099511627775); + scaled /= ZLONG_CONST(1099511627776); + break; +#endif } return (g_range < 0 ? scaled < QS_CAST_SIZE() size : diff --git a/Src/hist.c b/Src/hist.c index 1845bd8ad..770d559b1 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -935,9 +935,11 @@ hbegin(int dohist) hf = getsparam("HISTFILE"); /* - * For INCAPPENDHISTORY, when interactive, save the history here + * For INCAPPENDHISTORYTIME, when interactive, save the history here * as it gives a better estimate of the times of commands. * + * If INCAPPENDHISTORY is also set we've already done it. + * * If SHAREHISTORY is also set continue to do so in the * standard place, because that's safer about reading and * rewriting history atomically. @@ -950,7 +952,8 @@ hbegin(int dohist) * so that (correctly) nothing happens here. But it shows * I thought about it. */ - if (isset(INCAPPENDHISTORY) && !isset(SHAREHISTORY) && + if (isset(INCAPPENDHISTORYTIME) && !isset(SHAREHISTORY) && + !isset(INCAPPENDHISTORY) && !(histactive & HA_NOINC) && !strin && histsave_stack_pos == 0) savehistfile(hf, 0, HFILE_USE_OPTIONS | HFILE_FAST); } @@ -1378,7 +1381,8 @@ hend(Eprog prog) * For normal INCAPPENDHISTORY case and reasoning, see hbegin(). */ if (isset(SHAREHISTORY) ? histfileIsLocked() : - (isset(INCAPPENDHISTORY) && histsave_stack_pos != 0)) + (isset(INCAPPENDHISTORY) || (isset(INCAPPENDHISTORYTIME) && + histsave_stack_pos != 0))) savehistfile(hf, 0, HFILE_USE_OPTIONS | HFILE_FAST); unlockhistfile(hf); /* It's OK to call this even if we aren't locked */ /* @@ -1764,7 +1768,8 @@ chrealpath(char **junkptr) str++; } - *junkptr = metafy(bicat(real, nonreal), -1, META_HEAPDUP); + *junkptr = metafy(str = bicat(real, nonreal), -1, META_HEAPDUP); + zsfree(str); #ifdef HAVE_CANONICALIZE_FILE_NAME free(real); #endif @@ -2303,8 +2308,7 @@ readhistline(int start, char **bufp, int *bufsiz, FILE *in) } else { buf[len - 1] = '\0'; - if (len > 1 && buf[len - 2] == '\\' && - (len < 3 || buf[len - 3] != '\\')) { + if (len > 1 && buf[len - 2] == '\\') { buf[--len - 1] = '\n'; if (!feof(in)) return readhistline(len, bufp, bufsiz, in); @@ -2541,7 +2545,7 @@ savehistfile(char *fn, int err, int writeflags) } if (writeflags & HFILE_USE_OPTIONS) { if (isset(APPENDHISTORY) || isset(INCAPPENDHISTORY) - || isset(SHAREHISTORY)) + || isset(INCAPPENDHISTORYTIME) || isset(SHAREHISTORY)) writeflags |= HFILE_APPEND | HFILE_SKIPOLD; else histfile_linect = 0; @@ -2577,7 +2581,7 @@ savehistfile(char *fn, int err, int writeflags) tmpfile = NULL; if (err) { if (isset(APPENDHISTORY) || isset(INCAPPENDHISTORY) - || isset(SHAREHISTORY)) + || isset(INCAPPENDHISTORYTIME) || isset(SHAREHISTORY)) zerr("rewriting %s would change its ownership -- skipped", fn); else zerr("rewriting %s would change its ownership -- history not saved", fn); @@ -2613,6 +2617,8 @@ savehistfile(char *fn, int err, int writeflags) ret = 0; for (; he && he->histnum <= xcurhist; he = down_histent(he)) { + int count_backslashes = 0; + if ((writeflags & HFILE_SKIPDUPS && he->node.flags & HIST_DUP) || (writeflags & HFILE_SKIPFOREIGN && he->node.flags & HIST_FOREIGN) || he->node.flags & HIST_TMPSTORE) @@ -2644,9 +2650,18 @@ savehistfile(char *fn, int err, int writeflags) if (*t == '\n') if ((ret = fputc('\\', out)) < 0) break; + if (*t == '\\') + count_backslashes++; + else + count_backslashes = 0; if ((ret = fputc(*t, out)) < 0) break; } + if (ret < 0) + break; + if (count_backslashes && (count_backslashes % 2 == 0)) + if ((ret = fputc(' ', out)) < 0) + break; if (ret < 0 || (ret = fputc('\n', out)) < 0) break; } @@ -2719,6 +2734,25 @@ savehistfile(char *fn, int err, int writeflags) static int lockhistct; +static int +checklocktime(char *lockfile, time_t then) +{ + time_t now = time(NULL); + + if (now + 10 < then) { + /* File is more than 10 seconds in the future? */ + errno = EEXIST; + return -1; + } + + if (now - then < 10) + sleep(1); + else + unlink(lockfile); + + return 0; +} + /* * Lock history file. Return 0 on success, 1 on failure to lock this * time, 2 on permanent failure (e.g. permission). @@ -2736,9 +2770,7 @@ lockhistfile(char *fn, int keep_trying) #ifdef HAVE_FCNTL_H if (isset(HISTFCNTLLOCK) && flock_fd < 0) { - ret = flockhistfile(fn, keep_trying); - if (ret) - return ret; + return flockhistfile(fn, keep_trying); } #endif @@ -2775,10 +2807,10 @@ lockhistfile(char *fn, int keep_trying) continue; break; } - if (time(NULL) - sb.st_mtime < 10) - sleep(1); - else - unlink(lockfile); + if (checklocktime(lockfile, sb.st_mtime) < 0) { + ret = 1; + break; + } } if (fd < 0) lockhistct--; @@ -2803,10 +2835,10 @@ lockhistfile(char *fn, int keep_trying) continue; ret = 2; } else { - if (time(NULL) - sb.st_mtime < 10) - sleep(1); - else - unlink(lockfile); + if (checklocktime(lockfile, sb.st_mtime) < 0) { + ret = 1; + break; + } continue; } lockhistct--; @@ -2831,10 +2863,10 @@ lockhistfile(char *fn, int keep_trying) ret = 2; break; } - if (time(NULL) - sb.st_mtime < 10) - sleep(1); - else - unlink(lockfile); + if (checklocktime(lockfile, sb.st_mtime) < 0) { + ret = 1; + break; + } } if (fd < 0) lockhistct--; diff --git a/Src/init.c b/Src/init.c index f5aae71f2..5e92f59df 100644 --- a/Src/init.c +++ b/Src/init.c @@ -77,7 +77,7 @@ mod_export int tclen[TC_COUNT]; /**/ int tclines, tccolumns; /**/ -mod_export int hasam, hasxn, hasye; +mod_export int hasam, hasbw, hasxn, hasye; /* Value of the Co (max_colors) entry: may not be set */ @@ -226,7 +226,7 @@ parseargs(char **argv, char **runscript) char **x; LinkList paramlist; - argzero = *argv++; + argzero = posixzero = *argv++; SHIN = 0; /* There's a bit of trickery with opts[INTERACTIVE] here. It starts * @@ -253,7 +253,7 @@ parseargs(char **argv, char **runscript) if (*argv) { if (unset(SHINSTDIN)) { if (cmd) - argzero = *argv; + argzero = posixzero = *argv; else *runscript = *argv; opts[INTERACTIVE] &= 1; @@ -275,6 +275,7 @@ parseargs(char **argv, char **runscript) while ((*x++ = (char *)getlinknode(paramlist))); free(paramlist); argzero = ztrdup(argzero); + posixzero = ztrdup(posixzero); } /* Insert into list in order of pointer value */ @@ -698,6 +699,7 @@ init_term(void) /* check whether terminal has automargin (wraparound) capability */ hasam = tgetflag("am"); + hasbw = tgetflag("bw"); hasxn = tgetflag("xn"); /* also check for newline wraparound glitch */ hasye = tgetflag("YE"); /* print in last column does carriage return */ @@ -749,9 +751,8 @@ init_term(void) tcstr[TCCLEARSCREEN] = ztrdup("\14"); tclen[TCCLEARSCREEN] = 1; } -#if 0 /* This might work, but there may be more to it */ - rprompt_indent = (hasye || !tccan(TCLEFT)) ? 1 : 0; -#endif + /* This might work, but there may be more to it */ + rprompt_indent = ((hasam && !hasbw) || hasye || !tccan(TCLEFT)); } return 1; } @@ -1003,15 +1004,6 @@ setupvals(void) setiparam("COLUMNS", zterm_columns); setiparam("LINES", zterm_lines); #endif - { - /* Import from environment, overrides init_term() */ - struct value vbuf; - char *name = "ZLE_RPROMPT_INDENT"; - if (getvalue(&vbuf, &name, 1) && !(vbuf.flags & PM_UNSET)) - rprompt_indent = getintvalue(&vbuf); - else - rprompt_indent = 1; - } #ifdef HAVE_GETRLIMIT for (i = 0; i != RLIM_NLIMITS; i++) { @@ -1535,7 +1527,7 @@ mod_export CompctlReadFn compctlreadptr = fallback_compctlread; mod_export int fallback_compctlread(char *name, UNUSED(char **args), UNUSED(Options ops), UNUSED(char *reply)) { - zwarnnam(name, "option valid only in functions called from completion"); + zwarnnam(name, "no loaded module provides read for completion context"); return 1; } diff --git a/Src/jobs.c b/Src/jobs.c index 871946598..c4a0707d4 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -618,13 +618,11 @@ setprevjob(void) } /**/ -#ifndef HAVE_GETRUSAGE -static long clktck = 0; - -/**/ -static void -set_clktck(void) +long +get_clktck(void) { + static long clktck; + #ifdef _SC_CLK_TCK if (!clktck) /* fetch clock ticks per second from * @@ -646,9 +644,9 @@ set_clktck(void) # endif # endif #endif + + return clktck; } -/**/ -#endif /**/ static void @@ -698,11 +696,13 @@ printtime(struct timeval *real, child_times_t *ti, char *desc) percent = 100.0 * total_time / (real->tv_sec + real->tv_usec / 1000000.0); #else - set_clktck(); - user_time = ti->ut / (double) clktck; - system_time = ti->st / (double) clktck; - percent = 100.0 * (ti->ut + ti->st) - / (clktck * real->tv_sec + clktck * real->tv_usec / 1000000.0); + { + long clktck = get_clktck(); + user_time = ti->ut / (double) clktck; + system_time = ti->st / (double) clktck; + percent = 100.0 * (ti->ut + ti->st) + / (clktck * real->tv_sec + clktck * real->tv_usec / 1000000.0); + } #endif queue_signals(); @@ -910,8 +910,10 @@ should_report_time(Job j) reporttime--; return reporttime <= 0; #else - set_clktck(); - return ((j->procs->ti.ut + j->procs->ti.st) / clktck >= reporttime); + { + clktck = get_clktck(); + return ((j->procs->ti.ut + j->procs->ti.st) / clktck >= reporttime); + } #endif } @@ -30,6 +30,8 @@ #include "zsh.mdh" #include "lex.pro" +#define LEX_HEAP_SIZE (32) + /* tokens */ /**/ @@ -721,7 +723,7 @@ gettok(void) /* word includes the last character read and possibly \ before ! */ if (dbparens) { len = 0; - bptr = tokstr = (char *) hcalloc(bsiz = 32); + bptr = tokstr = (char *) hcalloc(bsiz = LEX_HEAP_SIZE); hungetc(c); cmdpush(CS_MATH); c = dquote_parse(infor ? ';' : ')', 0); @@ -775,7 +777,7 @@ gettok(void) if (lexflags & LEXFLAGS_COMMENTS_KEEP) { len = 0; - bptr = tokstr = (char *)hcalloc(bsiz = 32); + bptr = tokstr = (char *)hcalloc(bsiz = LEX_HEAP_SIZE); add(c); } hwend(); @@ -877,7 +879,7 @@ gettok(void) } if (incmdpos || (isset(SHGLOB) && !isset(KSHGLOB))) { len = 0; - bptr = tokstr = (char *) hcalloc(bsiz = 32); + bptr = tokstr = (char *) hcalloc(bsiz = LEX_HEAP_SIZE); switch (cmd_or_math(CS_MATH)) { case 1: return DINPAR; @@ -1027,7 +1029,7 @@ gettokstr(int c, int sub) peek = STRING; if (!sub) { len = 0; - bptr = tokstr = (char *) hcalloc(bsiz = 32); + bptr = tokstr = (char *) hcalloc(bsiz = LEX_HEAP_SIZE); } for (;;) { int act; diff --git a/Src/loop.c b/Src/loop.c index 90a0761b3..2f639fd5a 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -73,7 +73,7 @@ execfor(Estate state, int do_exec) matheval(str); if (errflag) { state->pc = end; - return lastval = errflag; + return 1; } cond = ecgetstr(state, EC_NODUP, &ctok); advance = ecgetstr(state, EC_NODUP, &atok); @@ -87,8 +87,13 @@ execfor(Estate state, int do_exec) state->pc = end; return 0; } - if (htok) + if (htok) { execsubst(args); + if (errflag) { + state->pc = end; + return 1; + } + } } else { char **x; @@ -97,7 +102,7 @@ execfor(Estate state, int do_exec) addlinknode(args, dupstring(*x)); } } - lastval = 0; + /* lastval = 0; */ loops++; pushheap(); cmdpush(CS_FOR); @@ -223,15 +228,20 @@ execselect(Estate state, UNUSED(int do_exec)) state->pc = end; return 0; } - if (htok) + if (htok) { execsubst(args); + if (errflag) { + state->pc = end; + return 1; + } + } } if (!args || empty(args)) { state->pc = end; return 1; } loops++; - lastval = 0; + /* lastval = 0; */ pushheap(); cmdpush(CS_SELECT); usezle = interact && SHTTY != -1 && isset(USEZLE); diff --git a/Src/math.c b/Src/math.c index 42355f885..266569827 100644 --- a/Src/math.c +++ b/Src/math.c @@ -556,6 +556,9 @@ lexconstant(void) int outputradix; /**/ +int outputunderscore; + +/**/ static int zzlex(void) { @@ -713,7 +716,7 @@ zzlex(void) return EOI; case '[': { - int n; + int n, checkradix = 0; if (idigit(*ptr)) { n = zstrtol(ptr, &ptr, 10); @@ -730,9 +733,19 @@ zzlex(void) n = -1; ptr++; } - if (!idigit(*ptr)) + if (!idigit(*ptr) && *ptr != '_') goto bofs; - outputradix = n * zstrtol(ptr, &ptr, 10); + if (idigit(*ptr)) { + outputradix = n * zstrtol(ptr, &ptr, 10); + checkradix = 1; + } + if (*ptr == '_') { + ptr++; + if (idigit(*ptr)) + outputunderscore = zstrtol(ptr, &ptr, 10); + else + outputunderscore = 3; + } } else { bofs: zerr("bad output format specification"); @@ -740,11 +753,13 @@ zzlex(void) } if(*ptr != ']') goto bofs; - n = (outputradix < 0) ? -outputradix : outputradix; - if (n < 2 || n > 36) { - zerr("invalid base (must be 2 to 36 inclusive): %d", - outputradix); - return EOI; + if (checkradix) { + n = (outputradix < 0) ? -outputradix : outputradix; + if (n < 2 || n > 36) { + zerr("invalid base (must be 2 to 36 inclusive): %d", + outputradix); + return EOI; + } } ptr++; break; @@ -1337,9 +1352,9 @@ matheval(char *s) char *junk; mnumber x; int xmtok = mtok; - /* maintain outputradix across levels of evaluation */ + /* maintain outputradix and outputunderscore across levels of evaluation */ if (!mlevel) - outputradix = 0; + outputradix = outputunderscore = 0; if (!*s) { x.type = MN_INTEGER; @@ -226,6 +226,9 @@ old_heaps(Heap old) #else zfree(h, HEAPSIZE); #endif +#ifdef ZSH_VALGRIND + VALGRIND_DESTROY_MEMPOOL((char *)h); +#endif } heaps = old; #ifdef ZSH_HEAP_DEBUG @@ -319,23 +322,26 @@ freeheap(void) h_free++; #endif - /* At this point we used to do: - fheap = NULL; - * + /* * When pushheap() is called, it sweeps over the entire heaps list of * arenas and marks every one of them with the amount of free space in * that arena at that moment. zhalloc() is then allowed to grab bits * out of any of those arenas that have free space. * - * With the above reset of fheap, the loop below sweeps back over the + * Whenever fheap is NULL here, the loop below sweeps back over the * entire heap list again, resetting the free space in every arena to * the amount stashed by pushheap() and finding the first arena with * free space to optimize zhalloc()'s next search. When there's a lot * of stuff already on the heap, this is an enormous amount of work, * and performance goes to hell. * - * However, there doesn't seem to be any reason to reset fheap before - * beginning this loop. Either it's already correct, or it has never + * However, if the arena to which fheap points is unused, we want to + * free it, so we have no choice but to do the sweep for a new fheap. + */ + if (fheap && !fheap->sp) + fheap = NULL; /* We used to do this unconditionally */ + /* + * In other cases, either fheap is already correct, or it has never * been set and this loop will do it, or it'll be reset from scratch * on the next popheap(). So all that's needed here is to pick up * the scan wherever the last pass [or the last popheap()] left off. @@ -344,6 +350,10 @@ freeheap(void) hn = h->next; if (h->sp) { #ifdef ZSH_MEM_DEBUG +#ifdef ZSH_VALGRIND + VALGRIND_MAKE_MEM_UNDEFINED((char *)arena(h) + h->sp->used, + h->used - h->sp->used); +#endif memset(arena(h) + h->sp->used, 0xff, h->used - h->sp->used); #endif h->used = h->sp->used; @@ -366,12 +376,18 @@ freeheap(void) h->heap_id = new_id; } #endif +#ifdef ZSH_VALGRIND + VALGRIND_MEMPOOL_TRIM((char *)h, (char *)arena(h), h->used); +#endif } else { #ifdef USE_MMAP munmap((void *) h, h->size); #else zfree(h, HEAPSIZE); #endif +#ifdef ZSH_VALGRIND + VALGRIND_DESTROY_MEMPOOL((char *)h); +#endif } } if (hl) @@ -403,6 +419,10 @@ popheap(void) if ((hs = h->sp)) { h->sp = hs->next; #ifdef ZSH_MEM_DEBUG +#ifdef ZSH_VALGRIND + VALGRIND_MAKE_MEM_UNDEFINED((char *)arena(h) + hs->used, + h->used - hs->used); +#endif memset(arena(h) + hs->used, 0xff, h->used - hs->used); #endif h->used = hs->used; @@ -414,6 +434,9 @@ popheap(void) } h->heap_id = hs->heap_id; #endif +#ifdef ZSH_VALGRIND + VALGRIND_MEMPOOL_TRIM((char *)h, (char *)arena(h), h->used); +#endif if (!fheap && h->used < ARENA_SIZEOF(h)) fheap = h; zfree(hs, sizeof(*hs)); @@ -425,6 +448,9 @@ popheap(void) #else zfree(h, HEAPSIZE); #endif +#ifdef ZSH_VALGRIND + VALGRIND_DESTROY_MEMPOOL((char *)h); +#endif } } if (hl) @@ -496,6 +522,12 @@ zhalloc(size_t size) { Heap h; size_t n; +#ifdef ZSH_VALGRIND + size_t req_size = size; + + if (size == 0) + return NULL; +#endif size = (size + H_ISIZE - 1) & ~(H_ISIZE - 1); @@ -523,6 +555,9 @@ zhalloc(size_t size) HEAPID_FMT ".\n", h->heap_id); } #endif +#ifdef ZSH_VALGRIND + VALGRIND_MEMPOOL_ALLOC((char *)h, (char *)ret, req_size); +#endif return ret; } } @@ -561,6 +596,12 @@ zhalloc(size_t size) h->heap_id); } #endif +#ifdef ZSH_VALGRIND + VALGRIND_CREATE_MEMPOOL((char *)h, 0, 0); + VALGRIND_MAKE_MEM_NOACCESS((char *)arena(h), + n - ((char *)arena(h)-(char *)h)); + VALGRIND_MEMPOOL_ALLOC((char *)h, (char *)arena(h), req_size); +#endif if (hp) hp->next = h; @@ -586,13 +627,21 @@ hrealloc(char *p, size_t old, size_t new) { Heap h, ph; +#ifdef ZSH_VALGRIND + size_t new_req = new; +#endif + old = (old + H_ISIZE - 1) & ~(H_ISIZE - 1); new = (new + H_ISIZE - 1) & ~(H_ISIZE - 1); if (old == new) return p; if (!old && !p) +#ifdef ZSH_VALGRIND + return zhalloc(new_req); +#else return zhalloc(new); +#endif /* find the heap with p */ @@ -615,14 +664,33 @@ hrealloc(char *p, size_t old, size_t new) */ if (p + old < arena(h) + h->used) { if (new > old) { +#ifdef ZSH_VALGRIND + char *ptr = (char *) zhalloc(new_req); +#else char *ptr = (char *) zhalloc(new); +#endif memcpy(ptr, p, old); #ifdef ZSH_MEM_DEBUG memset(p, 0xff, old); #endif +#ifdef ZSH_VALGRIND + VALGRIND_MEMPOOL_FREE((char *)h, (char *)p); + /* + * zhalloc() marked h,ptr,new as an allocation so we don't + * need to do that here. + */ +#endif unqueue_signals(); return ptr; } else { +#ifdef ZSH_VALGRIND + VALGRIND_MEMPOOL_FREE((char *)h, (char *)p); + if (p) { + VALGRIND_MEMPOOL_ALLOC((char *)h, (char *)p, + new_req); + VALGRIND_MAKE_MEM_DEFINED((char *)h, (char *)p); + } +#endif unqueue_signals(); return new ? p : NULL; } @@ -657,10 +725,14 @@ hrealloc(char *p, size_t old, size_t new) #else zfree(h, HEAPSIZE); #endif +#ifdef ZSH_VALGRIND + VALGRIND_DESTROY_MEMPOOL((char *)h); +#endif unqueue_signals(); return NULL; } if (new > ARENA_SIZEOF(h)) { + Heap hnew; /* * Not enough memory in this heap. Allocate a new * one of sufficient size. @@ -682,17 +754,23 @@ hrealloc(char *p, size_t old, size_t new) * a mmap'd segment be extended, so simply allocate * a new one and copy. */ - Heap hnew; - hnew = mmap_heap_alloc(&n); /* Copy the entire heap, header (with next pointer) included */ memcpy(hnew, h, h->size); munmap((void *)h, h->size); - h = hnew; } #else - h = (Heap) realloc(h, n); + hnew = (Heap) realloc(h, n); #endif +#ifdef ZSH_VALGRIND + VALGRIND_MEMPOOL_FREE((char *)h, p); + VALGRIND_DESTROY_MEMPOOL((char *)h); + VALGRIND_CREATE_MEMPOOL((char *)hnew, 0, 0); + VALGRIND_MEMPOOL_ALLOC((char *)hnew, (char *)arena(hnew), + new_req); + VALGRIND_MAKE_MEM_DEFINED((char *)hnew, (char *)arena(hnew)); +#endif + h = hnew; h->size = n; if (ph) @@ -700,6 +778,13 @@ hrealloc(char *p, size_t old, size_t new) else heaps = h; } +#ifdef ZSH_VALGRIND + else { + VALGRIND_MEMPOOL_FREE((char *)h, (char *)p); + VALGRIND_MEMPOOL_ALLOC((char *)h, (char *)p, new_req); + VALGRIND_MAKE_MEM_DEFINED((char *)h, (char *)p); + } +#endif h->used = new; #ifdef ZSH_HEAP_DEBUG h->heap_id = heap_id; @@ -713,6 +798,11 @@ hrealloc(char *p, size_t old, size_t new) if (h->used + (new - old) <= ARENA_SIZEOF(h)) { h->used += new - old; unqueue_signals(); +#ifdef ZSH_VALGRIND + VALGRIND_MEMPOOL_FREE((char *)h, (char *)p); + VALGRIND_MEMPOOL_ALLOC((char *)h, (char *)p, new_req); + VALGRIND_MAKE_MEM_DEFINED((char *)h, (char *)p); +#endif return p; } else { char *t = zhalloc(new); @@ -721,6 +811,10 @@ hrealloc(char *p, size_t old, size_t new) #ifdef ZSH_MEM_DEBUG memset(p, 0xff, old); #endif +#ifdef ZSH_VALGRIND + VALGRIND_MEMPOOL_FREE((char *)h, (char *)p); + /* t already marked as allocated by zhalloc() */ +#endif unqueue_signals(); return t; } @@ -856,7 +950,10 @@ zrealloc(void *ptr, size_t size) ptr = NULL; } else { /* If ptr is NULL, then behave like malloc */ - ptr = malloc(size); + if (!(ptr = (void *) malloc(size))) { + zerr("fatal error: out of memory"); + exit(1); + } } unqueue_signals(); @@ -1505,7 +1602,7 @@ zsfree(char *p) MALLOC_RET_T realloc(MALLOC_RET_T p, MALLOC_ARG_T size) { - struct m_hdr *m = (struct m_hdr *)(((char *)p) - M_ISIZE), *mp, *mt; + struct m_hdr *m = (struct m_hdr *)(((char *)p) - M_ISIZE), *mt; char *r; int i, l = 0; @@ -1521,10 +1618,10 @@ realloc(MALLOC_RET_T p, MALLOC_ARG_T size) /* check if we are reallocating a small block, if we do, we have to compute the size of the block from the sort of block it is in */ for (i = 0; i < M_NSMALL; i++) { - for (mp = NULL, mt = m_small[i]; + for (mt = m_small[i]; mt && (((char *)mt) > ((char *)p) || (((char *)mt) + mt->len) < ((char *)p)); - mp = mt, mt = mt->next); + mt = mt->next); if (mt) { l = M_BSLEN(mt->len); diff --git a/Src/mkmakemod.sh b/Src/mkmakemod.sh index 2633c27d4..002160910 100644 --- a/Src/mkmakemod.sh +++ b/Src/mkmakemod.sh @@ -307,10 +307,10 @@ if $first_stage; then echo "\$(SYMS_${mddname}): \$(PROTODEPS)" echo echo "${mddname}.export: \$(SYMS_${mddname})" - echo " ( echo '#!'; cat \$(SYMS_${mddname}) | sed -n '/^X/{s/^X//;p;}' | sort -u ) > \$@" + echo " @( echo '#!'; cat \$(SYMS_${mddname}) | sed -n '/^X/{s/^X//;p;}' | sort -u ) > \$@" echo echo "modobjs.${mddname}: \$(MODOBJS_${mddname})" - echo " echo '' \$(MODOBJS_${mddname}) $modobjs_sed>> \$(dir_src)/stamp-modobjs.tmp" + echo " @echo '' \$(MODOBJS_${mddname}) $modobjs_sed>> \$(dir_src)/stamp-modobjs.tmp" echo if test -z "$alwayslink"; then case " $all_modules" in *" ${mddname}."*) diff --git a/Src/options.c b/Src/options.c index ce73d9901..6e4e7b911 100644 --- a/Src/options.c +++ b/Src/options.c @@ -165,6 +165,7 @@ static struct optname optns[] = { {{NULL, "ignoreclosebraces", OPT_EMULATE}, IGNORECLOSEBRACES}, {{NULL, "ignoreeof", 0}, IGNOREEOF}, {{NULL, "incappendhistory", 0}, INCAPPENDHISTORY}, +{{NULL, "incappendhistorytime", 0}, INCAPPENDHISTORYTIME}, {{NULL, "interactive", OPT_SPECIAL}, INTERACTIVE}, {{NULL, "interactivecomments",OPT_BOURNE}, INTERACTIVECOMMENTS}, {{NULL, "ksharrays", OPT_EMULATE|OPT_BOURNE}, KSHARRAYS}, @@ -179,6 +180,7 @@ static struct optname optns[] = { {{NULL, "listrowsfirst", 0}, LISTROWSFIRST}, {{NULL, "listtypes", OPT_ALL}, LISTTYPES}, {{NULL, "localoptions", OPT_EMULATE|OPT_KSH}, LOCALOPTIONS}, +{{NULL, "localloops", OPT_EMULATE}, LOCALLOOPS}, {{NULL, "localpatterns", OPT_EMULATE}, LOCALPATTERNS}, {{NULL, "localtraps", OPT_EMULATE|OPT_KSH}, LOCALTRAPS}, {{NULL, "login", OPT_SPECIAL}, LOGINSHELL}, @@ -207,6 +209,7 @@ static struct optname optns[] = { {{NULL, "pathscript", OPT_EMULATE|OPT_BOURNE}, PATHSCRIPT}, {{NULL, "pipefail", OPT_EMULATE}, PIPEFAIL}, {{NULL, "posixaliases", OPT_EMULATE|OPT_BOURNE}, POSIXALIASES}, +{{NULL, "posixargzero", OPT_EMULATE}, POSIXARGZERO}, {{NULL, "posixbuiltins", OPT_EMULATE|OPT_BOURNE}, POSIXBUILTINS}, {{NULL, "posixcd", OPT_EMULATE|OPT_BOURNE}, POSIXCD}, {{NULL, "posixidentifiers", OPT_EMULATE|OPT_BOURNE}, POSIXIDENTIFIERS}, diff --git a/Src/params.c b/Src/params.c index ad9e3470b..0699ead85 100644 --- a/Src/params.c +++ b/Src/params.c @@ -67,6 +67,7 @@ char **path, /* $path */ /**/ mod_export char *argzero, /* $0 */ + *posixzero, /* $0 */ *home, /* $HOME */ *nullcmd, /* $NULLCMD */ *oldpwd, /* $OLDPWD */ @@ -194,6 +195,8 @@ static const struct gsu_integer euid_gsu = static const struct gsu_integer ttyidle_gsu = { ttyidlegetfn, nullintsetfn, stdunsetfn }; +static const struct gsu_scalar argzero_gsu = +{ argzerogetfn, nullstrsetfn, nullunsetfn }; static const struct gsu_scalar username_gsu = { usernamegetfn, usernamesetfn, stdunsetfn }; static const struct gsu_scalar dash_gsu = @@ -263,7 +266,7 @@ static initparam special_params[] ={ #define NULL_GSU BR((GsuScalar)(void *)NULL) #define IPDEF1(A,B,C) {{NULL,A,PM_INTEGER|PM_SPECIAL|C},BR(NULL),GSU(B),10,0,NULL,NULL,NULL,0} IPDEF1("#", pound_gsu, PM_READONLY), -IPDEF1("ERRNO", errno_gsu, 0), +IPDEF1("ERRNO", errno_gsu, PM_UNSET), IPDEF1("GID", gid_gsu, PM_DONTIMPORT | PM_RESTRICTED), IPDEF1("EGID", egid_gsu, PM_DONTIMPORT | PM_RESTRICTED), IPDEF1("HISTSIZE", histsize_gsu, PM_RESTRICTED), @@ -279,12 +282,13 @@ IPDEF2("USERNAME", username_gsu, PM_DONTIMPORT|PM_RESTRICTED), IPDEF2("-", dash_gsu, PM_READONLY), IPDEF2("histchars", histchars_gsu, PM_DONTIMPORT), IPDEF2("HOME", home_gsu, PM_UNSET), -IPDEF2("TERM", term_gsu, 0), +IPDEF2("TERM", term_gsu, PM_UNSET), IPDEF2("TERMINFO", terminfo_gsu, PM_UNSET), IPDEF2("WORDCHARS", wordchars_gsu, 0), IPDEF2("IFS", ifs_gsu, PM_DONTIMPORT), -IPDEF2("_", underscore_gsu, PM_READONLY), +IPDEF2("_", underscore_gsu, PM_DONTIMPORT), IPDEF2("KEYBOARD_HACK", keyboard_hack_gsu, PM_DONTIMPORT), +IPDEF2("0", argzero_gsu, 0), #ifdef USE_LOCALE # define LCIPDEF(name) IPDEF2(name, lc_blah_gsu, PM_UNSET) @@ -326,20 +330,20 @@ IPDEF5("SHLVL", &shlvl, varinteger_gsu), IPDEF5("TRY_BLOCK_ERROR", &try_errflag, varinteger_gsu), #define IPDEF7(A,B) {{NULL,A,PM_SCALAR|PM_SPECIAL},BR((void *)B),GSU(varscalar_gsu),0,0,NULL,NULL,NULL,0} +#define IPDEF7U(A,B) {{NULL,A,PM_SCALAR|PM_SPECIAL|PM_UNSET},BR((void *)B),GSU(varscalar_gsu),0,0,NULL,NULL,NULL,0} IPDEF7("OPTARG", &zoptarg), IPDEF7("NULLCMD", &nullcmd), -IPDEF7("POSTEDIT", &postedit), +IPDEF7U("POSTEDIT", &postedit), IPDEF7("READNULLCMD", &readnullcmd), IPDEF7("PS1", &prompt), -IPDEF7("RPS1", &rprompt), -IPDEF7("RPROMPT", &rprompt), +IPDEF7U("RPS1", &rprompt), +IPDEF7U("RPROMPT", &rprompt), IPDEF7("PS2", &prompt2), -IPDEF7("RPS2", &rprompt2), -IPDEF7("RPROMPT2", &rprompt2), +IPDEF7U("RPS2", &rprompt2), +IPDEF7U("RPROMPT2", &rprompt2), IPDEF7("PS3", &prompt3), IPDEF7("PS4", &prompt4), IPDEF7("SPROMPT", &sprompt), -IPDEF7("0", &argzero), #define IPDEF8(A,B,C,D) {{NULL,A,D|PM_SCALAR|PM_SPECIAL},BR((void *)B),GSU(colonarr_gsu),0,0,NULL,C,NULL,0} IPDEF8("CDPATH", &cdpath, "cdpath", 0), @@ -2416,9 +2420,10 @@ setnumvalue(Value v, mnumber val) if ((val.type & MN_INTEGER) || outputradix) { if (!(val.type & MN_INTEGER)) val.u.l = (zlong) val.u.d; - convbase(p = buf, val.u.l, outputradix); + p = convbase_underscore(buf, val.u.l, outputradix, + outputunderscore); } else - p = convfloat(val.u.d, 0, 0, NULL); + p = convfloat_underscore(val.u.d, outputunderscore); setstrvalue(v, ztrdup(p)); break; case PM_INTEGER: @@ -3979,6 +3984,17 @@ lcsetfn(Param pm, char *x) } #endif /* USE_LOCALE */ +/* Function to get value for special parameter `0' */ + +/**/ +static char * +argzerogetfn(UNUSED(Param pm)) +{ + if (isset(POSIXARGZERO)) + return posixzero; + return argzero; +} + /* Function to get value for special parameter `HISTSIZE' */ /**/ @@ -4245,7 +4261,7 @@ static char ** pipestatgetfn(UNUSED(Param pm)) { char **x = (char **) zhalloc((numpipestats + 1) * sizeof(char *)); - char buf[20], **p; + char buf[DIGBUFSIZE], **p; int *q, i; for (p = x, q = pipestats, i = numpipestats; i--; p++, q++) { @@ -4555,9 +4571,14 @@ delenv(Param pm) */ } +/* + * Guts of convbase: this version can return the number of digits + * sans any base discriminator. + */ + /**/ -mod_export void -convbase(char *s, zlong v, int base) +void +convbase_ptr(char *s, zlong v, int base, int *ndigits) { int digs = 0; zulong x; @@ -4583,6 +4604,8 @@ convbase(char *s, zlong v, int base) x /= base; if (!digs) digs = 1; + if (ndigits) + *ndigits = digs; s[digs--] = '\0'; x = v; while (digs >= 0) { @@ -4594,6 +4617,64 @@ convbase(char *s, zlong v, int base) } /* + * Basic conversion of integer to a string given a base. + * If 0 base is 10. + * If negative no base discriminator is output. + */ + +/**/ +mod_export void +convbase(char *s, zlong v, int base) +{ + convbase_ptr(s, v, base, NULL); +} + +/* + * Add underscores to converted integer for readability with given spacing. + * s is as for convbase: at least BDIGBUFSIZE. + * If underscores were added, returned value with underscores comes from + * heap, else the returned value is s. + */ + +/**/ +char * +convbase_underscore(char *s, zlong v, int base, int underscore) +{ + char *retptr, *sptr, *dptr; + int ndigits, nunderscore, mod, len; + + convbase_ptr(s, v, base, &ndigits); + + if (underscore <= 0) + return s; + + nunderscore = (ndigits - 1) / underscore; + if (!nunderscore) + return s; + len = strlen(s); + retptr = zhalloc(len + nunderscore + 1); + mod = 0; + memcpy(retptr, s, len - ndigits); + sptr = s + len; + dptr = retptr + len + nunderscore; + /* copy the null */ + *dptr-- = *sptr--; + for (;;) { + *dptr = *sptr; + if (!--ndigits) + break; + dptr--; + sptr--; + if (++mod == underscore) { + mod = 0; + *dptr-- = '_'; + } + } + + return retptr; +} + +/* * Convert a floating point value for output. * Unlike convbase(), this has its own internal storage and returns * a value from the heap. @@ -4659,6 +4740,83 @@ convfloat(double dval, int digits, int flags, FILE *fout) return ret; } +/* + * convert float to string with basic options but inserting underscores + * for readability. + */ + +/**/ +char *convfloat_underscore(double dval, int underscore) +{ + int ndigits_int = 0, ndigits_frac = 0, nunderscore, len; + char *s, *retptr, *sptr, *dptr; + + s = convfloat(dval, 0, 0, NULL); + if (underscore <= 0) + return s; + + /* + * Count the number of digits before and after the decimal point, if any. + */ + sptr = s; + if (*sptr == '-') + sptr++; + while (idigit(*sptr)) { + ndigits_int++; + sptr++; + } + if (*sptr == '.') { + sptr++; + while (idigit(*sptr)) { + ndigits_frac++; + sptr++; + } + } + + /* + * Work out how many underscores to insert --- remember we + * put them in integer and fractional parts separately. + */ + nunderscore = (ndigits_int-1) / underscore + (ndigits_frac-1) / underscore; + if (!nunderscore) + return s; + len = strlen(s); + dptr = retptr = zhalloc(len + nunderscore + 1); + + /* + * Insert underscores in integer part. + * Grouping starts from the point in both directions. + */ + sptr = s; + if (*sptr == '-') + *dptr++ = *sptr++; + while (ndigits_int) { + *dptr++ = *sptr++; + if (--ndigits_int && !(ndigits_int % underscore)) + *dptr++ = '_'; + } + if (ndigits_frac) { + /* + * Insert underscores in the fractional part. + */ + int mod = 0; + /* decimal point, we already checked */ + *dptr++ = *sptr++; + while (ndigits_frac) { + *dptr++ = *sptr++; + mod++; + if (--ndigits_frac && mod == underscore) { + *dptr++ = '_'; + mod = 0; + } + } + } + /* Copy exponent and anything else up to null */ + while ((*dptr++ = *sptr++)) + ; + return retptr; +} + /* Start a parameter scope */ /**/ diff --git a/Src/parse.c b/Src/parse.c index f0d0855d3..5f1303f1c 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -1471,7 +1471,6 @@ par_funcdef(int *complex) if (num == 0) { /* Anonymous function, possibly with arguments */ incmdpos = 0; - *complex = 1; } zshlex(); } else if (unset(SHORTLOOPS)) { @@ -1503,6 +1502,7 @@ par_funcdef(int *complex) num++; zshlex(); } + *complex = (num > 0); ecbuf[parg] = ecused - parg; /*?*/ ecbuf[parg+1] = num; } @@ -1736,7 +1736,6 @@ par_simple(int *complex, int nr) if (argc == 0) { /* Anonymous function, possibly with arguments */ incmdpos = 0; - *complex = 1; } zshlex(); } else { @@ -1776,6 +1775,7 @@ par_simple(int *complex, int nr) argc++; zshlex(); } + *complex = (argc > 0); ecbuf[parg] = ecused - parg; /*?*/ ecbuf[parg+1] = argc; } @@ -2068,6 +2068,9 @@ par_cond_2(void) /* one argument: [ foo ] is equivalent to [ -n foo ] */ s1 = tokstr; condlex(); + /* ksh behavior: [ -t ] means [ -t 1 ]; bash disagrees */ + if (unset(POSIXBUILTINS) && !strcmp(s1, "-t")) + return par_cond_double(s1, dupstring("1")); return par_cond_double(dupstring("-n"), s1); } if (testargs[1]) { @@ -2086,6 +2089,10 @@ par_cond_2(void) return par_cond_triple(s1, s2, s3); } } + /* + * We fall through here on any non-numeric infix operator + * or any other time there are at least two arguments. + */ } if (tok == BANG) { /* @@ -2114,18 +2121,20 @@ par_cond_2(void) condlex(); return r; } + s1 = tokstr; + dble = (s1 && *s1 == '-' + && (condlex != testlex + || strspn(s1+1, "abcdefghknoprstuwxzLONGS") == 1) + && !s1[2]); if (tok != STRING) { - if (tok && tok != LEXERR && condlex == testlex) { - s1 = tokstr; + /* Check first argument for [[ STRING ]] re-interpretation */ + if (s1 /* tok != DOUTBRACK && tok != DAMPER && tok != DBAR */ + && tok != LEXERR && (!dble || condlex == testlex)) { condlex(); - return par_cond_double("-n", s1); + return par_cond_double(dupstring("-n"), s1); } else YYERROR(ecused); } - s1 = tokstr; - if (condlex == testlex) - dble = (*s1 == '-' && strspn(s1+1, "abcdefghknoprstuwxzLONGS") == 1 - && !s1[2]); condlex(); if (tok == INANG || tok == OUTANG) { enum lextok xtok = tok; @@ -2140,15 +2149,21 @@ par_cond_2(void) return 1; } if (tok != STRING) { - if (tok != LEXERR && condlex == testlex) { - if (!dble) - return par_cond_double("-n", s1); - else if (!strcmp(s1, "-t")) - return par_cond_double(s1, "1"); + /* + * Check second argument in case semantics e.g. [ = -a = ] + * mean we have to go back and fix up the first one + */ + if (tok != LEXERR) { + if (!dble || condlex == testlex) + return par_cond_double(dupstring("-n"), s1); + else + return par_cond_multi(s1, newlinklist()); } else YYERROR(ecused); } - s2 = tokstr; + s2 = tokstr; + if (condlex != testlex) + dble = (s2 && *s2 == '-' && !s2[2]); incond++; /* parentheses do globbing */ condlex(); incond--; /* parentheses do grouping */ diff --git a/Src/pattern.c b/Src/pattern.c index b79c3b444..94a299ebb 100644 --- a/Src/pattern.c +++ b/Src/pattern.c @@ -2223,6 +2223,8 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalen, return ret; } else { + int q = queue_signal_level(); + /* * Test for a `must match' string, unless we're scanning for a match * in which case we don't need to do this each time. @@ -2270,6 +2272,8 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalen, patinput = patinstart; + dont_queue_signals(); + if (patmatch((Upat)progstr)) { /* * we were lazy and didn't save the globflags if an exclusion @@ -2406,6 +2410,8 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalen, } else ret = 0; + restore_queue_signals(q); + if (tryalloced) zfree(tryalloced, unmetalen + unmetalenp); @@ -2485,7 +2491,7 @@ patmatch(Upat prog) zrange_t from, to, comp; patint_t nextch; - while (scan) { + while (scan && !errflag) { next = PATNEXT(scan); if (!globdots && P_NOTDOT(scan) && patinput == patinstart && diff --git a/Src/prompt.c b/Src/prompt.c index 95a7d4969..328ae3c66 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -270,6 +270,8 @@ putpromptchar(int doprint, int endchar, unsigned int *txtchangep) char *ss, *hostnam; int t0, arg, test, sep, j, numjobs; struct tm *tm; + struct timezone dummy_tz; + struct timeval tv; time_t timet; Nameddir nd; @@ -365,6 +367,8 @@ putpromptchar(int doprint, int endchar, unsigned int *txtchangep) case 'l': *bv->bp = '\0'; countprompt(bv->bufline, &t0, 0, 0); + if (minus) + t0 = zterm_columns - t0; if (t0 >= arg) test = 1; break; @@ -558,6 +562,14 @@ putpromptchar(int doprint, int endchar, unsigned int *txtchangep) break; case '<': case '>': + /* Test (minus) here so -0 means "at the right margin" */ + if (minus) { + *bv->bp = '\0'; + countprompt(bv->bufline, &t0, 0, 0); + arg = zterm_columns - t0 + arg; + if (arg <= 0) + arg = 1; + } if (!prompttrunc(arg, *bv->fm, doprint, endchar, txtchangep)) return *bv->fm; break; @@ -636,8 +648,8 @@ putpromptchar(int doprint, int endchar, unsigned int *txtchangep) tmfmt = "%l:%M%p"; break; } - timet = time(NULL); - tm = localtime(&timet); + gettimeofday(&tv, &dummy_tz); + tm = localtime(&tv.tv_sec); /* * Hack because strftime won't say how * much space it actually needs. Try to add it @@ -647,7 +659,7 @@ putpromptchar(int doprint, int endchar, unsigned int *txtchangep) */ for(j = 0, t0 = strlen(tmfmt)*8; j < 3; j++, t0*=2) { addbufspc(t0); - if (ztrftime(bv->bp, t0, tmfmt, tm) >= 0) + if (ztrftime(bv->bp, t0, tmfmt, tm, tv.tv_usec) >= 0) break; } /* There is enough room for this because addbufspc(t0) @@ -1172,7 +1184,7 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar, addbufspc(1); *bv->bp++ = '<'; } - ptr = bv->buf + w; /* addbv->bufspc() may have realloc()'d bv->buf */ + ptr = bv->buf + w; /* addbufspc() may have realloc()'d bv->buf */ /* * Now: * bv->buf is the start of the output prompt buffer @@ -1187,7 +1199,7 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar, bv->trunccount = bv->dontcount; putpromptchar(doprint, endchar, txtchangep); bv->trunccount = 0; - ptr = bv->buf + w; /* putpromptchar() may have realloc()'d */ + ptr = bv->buf + w; /* putpromptchar() may have realloc()'d */ *bv->bp = '\0'; /* * Now: @@ -1473,7 +1485,7 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar, /* Now we have to trick it into matching endchar again */ bv->fm--; } else { - if (*bv->fm != ']') + if (*bv->fm != endchar) bv->fm++; while(*bv->fm && *bv->fm != truncchar) { if (*bv->fm == '\\' && bv->fm[1]) diff --git a/Src/prototypes.h b/Src/prototypes.h index 00988ac4c..e3db4f5ee 100644 --- a/Src/prototypes.h +++ b/Src/prototypes.h @@ -130,5 +130,5 @@ extern char *strerror _((int errnum)); /***************************************************/ #ifndef HAVE_MEMMOVE -extern void bcopy _((const void *, void *, int)); +extern void bcopy _((const void *, void *, size_t)); #endif diff --git a/Src/signals.c b/Src/signals.c index c8f5fbcca..cb2b58161 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -369,7 +369,7 @@ signal_suspend(UNUSED(int sig), int wait_cmd) #ifdef POSIX_SIGNALS # ifdef BROKEN_POSIX_SIGSUSPEND sigprocmask(SIG_SETMASK, &set, &oset); - pause(); + ret = pause(); sigprocmask(SIG_SETMASK, &oset, NULL); # else /* not BROKEN_POSIX_SIGSUSPEND */ ret = sigsuspend(&set); @@ -1155,6 +1155,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn) char *name, num[4]; int obreaks = breaks; int oretflag = retflag; + int olastval = lastval; int isfunc; int traperr, new_trap_state, new_trap_return; @@ -1261,6 +1262,13 @@ dotrapargs(int sig, int *sigtr, void *sigfn) } else { if (traperr && !EMULATION(EMULATE_SH)) lastval = 1; + else { + /* + * With no explicit forced return, we keep the + * lastval from before the trap ran. + */ + lastval = olastval; + } if (try_tryflag) errflag = traperr; breaks += obreaks; diff --git a/Src/subst.c b/Src/subst.c index 1059508ef..4a5fe3a3c 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -169,7 +169,7 @@ stringsubst(LinkList list, LinkNode node, int pf_flags, int asssub) if (errflag) return NULL; if (!subst) - subst = ""; + rest = subst = ""; sublen = strlen(subst); restlen = strlen(rest); @@ -2878,6 +2878,67 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags) } break; } + } else if (inbrace && (*s == '^' || *s == Hat)) { + char **zip; + int shortest = 1; + ++s; + if (*s == '^' || *s == Hat) { + shortest = 0; + ++s; + } + if (*itype_end(s, IIDENT, 0)) { + untokenize(s); + zerr("not an identifier: %s", s); + return NULL; + } + if (vunset) { + if (unset(UNSET)) { + *idend = '\0'; + zerr("%s: parameter not set", idbeg); + return NULL; + } + val = dupstring(""); + } else { + char *sval; + zip = getaparam(s); + if (!zip) { + sval = getsparam(s); + if (sval) + zip = hmkarray(sval); + } + if (!isarr) aval = mkarray(val); + if (zip) { + char **out; + int alen, ziplen, outlen, i = 0; + alen = arrlen(aval); + ziplen = arrlen(zip); + outlen = shortest ^ (alen > ziplen) ? alen : ziplen; + if (!shortest && (alen == 0 || ziplen == 0)) { + if (ziplen) + aval = arrdup(zip); + } else { + out = zhalloc(sizeof(char *) * (2 * outlen + 1)); + while (i < outlen) { + if (copied) + out[i*2] = aval[i % alen]; + else + out[i*2] = dupstring(aval[i % alen]); + out[i*2+1] = dupstring(zip[i % ziplen]); + i++; + } + out[i*2] = NULL; + aval = out; + copied = 1; + isarr = 1; + } + } else { + if (unset(UNSET)) { + zerr("%s: parameter not set", s); + return NULL; + } + val = dupstring(""); + } + } } else if (inbrace && (*s == '|' || *s == Bar || *s == '*' || *s == Star)) { int intersect = (*s == '*' || *s == Star); @@ -2935,7 +2996,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags) */ if (!vunset) { if (isarr) { - aval = mkarray(NULL); + aval = hmkarray(NULL); } else { val = dupstring(""); } @@ -3754,19 +3815,19 @@ static char * arithsubst(char *a, char **bptr, char *rest) { char *s = *bptr, *t; - char buf[BDIGBUFSIZE], *b = buf; + char buf[BDIGBUFSIZE], *b; mnumber v; singsub(&a); v = matheval(a); if ((v.type & MN_FLOAT) && !outputradix) - b = convfloat(v.u.d, 0, 0, NULL); + b = convfloat_underscore(v.u.d, outputunderscore); else { if (v.type & MN_FLOAT) v.u.l = (zlong) v.u.d; - convbase(buf, v.u.l, outputradix); + b = convbase_underscore(buf, v.u.l, outputradix, outputunderscore); } - t = *bptr = (char *) hcalloc(strlen(*bptr) + strlen(b) + + t = *bptr = (char *) hcalloc(strlen(*bptr) + strlen(b) + strlen(rest) + 1); t--; while ((*++t = *s++)); diff --git a/Src/utils.c b/Src/utils.c index c6d178ce2..998e46a36 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -725,32 +725,36 @@ xsymlinks(char *s) char **pp, **opp; char xbuf2[PATH_MAX*2], xbuf3[PATH_MAX*2]; int t0, ret = 0; + zulong xbuflen = strlen(xbuf); opp = pp = slashsplit(s); - for (; *pp; pp++) { - if (!strcmp(*pp, ".")) { - zsfree(*pp); + for (; xbuflen < sizeof(xbuf) && *pp; pp++) { + if (!strcmp(*pp, ".")) continue; - } if (!strcmp(*pp, "..")) { char *p; - zsfree(*pp); if (!strcmp(xbuf, "/")) continue; if (!*xbuf) continue; - p = xbuf + strlen(xbuf); - while (*--p != '/'); + p = xbuf + xbuflen; + while (*--p != '/') + xbuflen--; *p = '\0'; continue; } sprintf(xbuf2, "%s/%s", xbuf, *pp); t0 = readlink(unmeta(xbuf2), xbuf3, PATH_MAX); if (t0 == -1) { - strcat(xbuf, "/"); - strcat(xbuf, *pp); - zsfree(*pp); + zulong pplen = strlen(*pp) + 1; + if ((xbuflen += pplen) < sizeof(xbuf)) { + strcat(xbuf, "/"); + strcat(xbuf, *pp); + } else { + *xbuf = 0; + break; + } } else { ret = 1; metafy(xbuf3, t0, META_NOALLOC); @@ -759,10 +763,9 @@ xsymlinks(char *s) xsymlinks(xbuf3 + 1); } else xsymlinks(xbuf3); - zsfree(*pp); } } - free(opp); + freearray(opp); return ret; } @@ -779,8 +782,10 @@ xsymlink(char *s) return NULL; *xbuf = '\0'; xsymlinks(s + 1); - if (!*xbuf) + if (!*xbuf) { + zwarn("path expansion failed, using root directory"); return ztrdup("/"); + } return ztrdup(xbuf); } @@ -2486,7 +2491,7 @@ getquery(char *valid_chars, int purge) static int d; static char *guess, *best; -static Patprog spckpat; +static Patprog spckpat, spnamepat; /**/ static void @@ -2557,6 +2562,13 @@ spckword(char **s, int hist, int cmd, int ask) } else spckpat = NULL; + if ((correct_ignore = getsparam("CORRECT_IGNORE_FILE")) != NULL) { + tokenize(correct_ignore = dupstring(correct_ignore)); + remnulargs(correct_ignore); + spnamepat = patcompile(correct_ignore, 0, NULL); + } else + spnamepat = NULL; + if (**s == String && !*t) { guess = *s + 1; if (itype_end(guess, IIDENT, 1) == guess) @@ -2698,10 +2710,13 @@ ztrftimebuf(int *bufsizeptr, int decr) /**/ mod_export int -ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm) +ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm, long usec) { - int hr12, decr; -#ifndef HAVE_STRFTIME + int hr12; +#ifdef HAVE_STRFTIME + int decr; + char tmp[4]; +#else static char *astr[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; static char *estr[] = @@ -2709,12 +2724,12 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm) "Aug", "Sep", "Oct", "Nov", "Dec"}; #endif char *origbuf = buf; - char tmp[4]; while (*fmt) if (*fmt == '%') { int strip; + int digs = 3; fmt++; if (*fmt == '-') { @@ -2722,6 +2737,17 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm) fmt++; } else strip = 0; + if (idigit(*fmt)) { + /* Digit --- only useful with . */ + char *dstart = fmt; + char *dend = fmt+1; + while (idigit(*dend)) + dend++; + if (*dend == '.') { + fmt = dend; + digs = atoi(dstart); + } + } /* * Assume this format will take up at least two * characters. Not always true, but if that matters @@ -2731,6 +2757,20 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm) if (ztrftimebuf(&bufsize, 2)) return -1; switch (*fmt++) { + case '.': + if (ztrftimebuf(&bufsize, digs)) + return -1; + if (digs > 6) + digs = 6; + if (digs < 6) { + int trunc; + for (trunc = 5 - digs; trunc; trunc--) + usec /= 10; + usec = (usec + 5) / 10; + } + sprintf(buf, "%0*ld", digs, usec); + buf += digs; + break; case 'd': if (tm->tm_mday > 9 || !strip) *buf++ = '0' + tm->tm_mday / 10; @@ -3332,6 +3372,17 @@ mkarray(char *s) } /**/ +mod_export char ** +hmkarray(char *s) +{ + char **t = (char **) zhalloc((s) ? (2 * sizeof s) : (sizeof s)); + + if ((*t = s)) + t[1] = NULL; + return t; +} + +/**/ mod_export void zbeep(void) { @@ -3778,6 +3829,8 @@ mindist(char *dir, char *mindistguess, char *mindistbest) if (!(dd = opendir(unmeta(dir)))) return mindistd; while ((fn = zreaddir(dd, 0))) { + if (spnamepat && pattry(spnamepat, fn)) + continue; nd = spdist(fn, mindistguess, (int)strlen(mindistguess) / 4 + 1); if (nd <= mindistd) { @@ -4256,6 +4309,12 @@ mod_export char * zreaddir(DIR *dir, int ignoredots) { struct dirent *de; +#if defined(HAVE_ICONV) && defined(__APPLE__) + static iconv_t conv_ds = (iconv_t)0; + static char *conv_name = 0; + char *conv_name_ptr, *orig_name_ptr; + size_t conv_name_len, orig_name_len; +#endif do { de = readdir(dir); @@ -4264,6 +4323,30 @@ zreaddir(DIR *dir, int ignoredots) } while(ignoredots && de->d_name[0] == '.' && (!de->d_name[1] || (de->d_name[1] == '.' && !de->d_name[2]))); +#if defined(HAVE_ICONV) && defined(__APPLE__) + if (!conv_ds) + conv_ds = iconv_open("UTF-8", "UTF-8-MAC"); + if (conv_ds != (iconv_t)(-1)) { + /* Force initial state in case re-using conv_ds */ + (void) iconv(conv_ds, 0, &orig_name_len, 0, &conv_name_len); + + orig_name_ptr = de->d_name; + orig_name_len = strlen(de->d_name); + conv_name = zrealloc(conv_name, orig_name_len+1); + conv_name_ptr = conv_name; + conv_name_len = orig_name_len; + if (iconv(conv_ds, + &orig_name_ptr, &orig_name_len, + &conv_name_ptr, &conv_name_len) != (size_t)(-1) && + orig_name_len == 0) { + /* Completely converted, metafy and return */ + *conv_name_ptr = '\0'; + return metafy(conv_name, -1, META_STATIC); + } + /* Error, or conversion incomplete, keep the original name */ + } +#endif + return metafy(de->d_name, -1, META_STATIC); } diff --git a/Src/watch.c b/Src/watch.c index 5231579f8..8dea0b495 100644 --- a/Src/watch.c +++ b/Src/watch.c @@ -330,7 +330,7 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) } timet = getlogtime(u, inout); tm = localtime(&timet); - ztrftime(buf, 40, fm2, tm); + ztrftime(buf, 40, fm2, tm, 0L); printf("%s", (*buf == ' ') ? buf + 1 : buf); break; case '%': @@ -33,9 +33,6 @@ /* * Our longest integer type: will be a 64 bit either if long already is, * or if we found some alternative such as long long. - * Currently we only define this to be longer than a long if - * --enable-largefile * was given. That enables internal use of 64-bit - * types even if no actual large file support is present. */ #ifdef ZSH_64_BIT_TYPE typedef ZSH_64_BIT_TYPE zlong; @@ -50,6 +47,32 @@ typedef unsigned long zulong; #endif /* + * Work out how to define large integer constants that will fit + * in a zlong. + */ +#if defined(ZSH_64_BIT_TYPE) || defined(LONG_IS_64_BIT) +/* We have some 64-bit type */ +#ifdef LONG_IS_64_BIT +/* It's long */ +#define ZLONG_CONST(x) x ## l +#else +/* It's long long */ +#ifdef ZLONG_IS_LONG_LONG +#define ZLONG_CONST(x) x ## ll +#else +/* + * There's some 64-bit type, but we don't know what it is. + * We'll just cast it and hope the compiler does the right thing. + */ +#define ZLONG_CONST(x) ((zlong)x) +#endif +#endif +#else +/* We're stuck with long */ +#define ZLONG_CONST(x) (x ## l) +#endif + +/* * Double float support requires 64-bit alignment, so if longs and * pointers are less we need to pad out. */ @@ -2092,6 +2115,7 @@ enum { IGNORECLOSEBRACES, IGNOREEOF, INCAPPENDHISTORY, + INCAPPENDHISTORYTIME, INTERACTIVE, INTERACTIVECOMMENTS, KSHARRAYS, @@ -2105,6 +2129,7 @@ enum { LISTPACKED, LISTROWSFIRST, LISTTYPES, + LOCALLOOPS, LOCALOPTIONS, LOCALPATTERNS, LOCALTRAPS, @@ -2128,6 +2153,7 @@ enum { PATHSCRIPT, PIPEFAIL, POSIXALIASES, + POSIXARGZERO, POSIXBUILTINS, POSIXCD, POSIXIDENTIFIERS, diff --git a/Src/zsh.mdd b/Src/zsh.mdd index d77fc4336..cec3edab7 100644 --- a/Src/zsh.mdd +++ b/Src/zsh.mdd @@ -44,7 +44,7 @@ patchlevel.h: FORCE cp -f $(sdir)/$@.release $@; \ else \ echo '#define ZSH_PATCHLEVEL "'`cd $(sdir) && git describe --tags --long`'"' > $@.tmp; \ - cmp $@ $@.tmp 2>/dev/null && rm -f $@.tmp || mv $@.tmp $@; \ + cmp $@ $@.tmp >/dev/null 2>&1 && rm -f $@.tmp || mv $@.tmp $@; \ fi FORCE: diff --git a/Src/zsh_system.h b/Src/zsh_system.h index e68fd62f9..811340d42 100644 --- a/Src/zsh_system.h +++ b/Src/zsh_system.h @@ -286,11 +286,15 @@ struct timezone { # include <limits.h> #endif +#ifdef USE_STACK_ALLOCATION #ifdef HAVE_VARIABLE_LENGTH_ARRAYS # define VARARR(X,Y,Z) X (Y)[Z] #else # define VARARR(X,Y,Z) X *(Y) = (X *) alloca(sizeof(X) * (Z)) #endif +#else +# define VARARR(X,Y,Z) X *(Y) = (X *) zhalloc(sizeof(X) * (Z)) +#endif /* we should handle unlimited sizes from pathconf(_PC_PATH_MAX) */ /* but this is too much trouble */ @@ -708,7 +712,10 @@ struct timezone { #endif #ifndef HAVE_MEMMOVE -# define memmove(dest, src, len) bcopy((src), (dest), (len)) +# ifndef memmove +static char *zmmv; +# define memmove(dest, src, len) (bcopy((src), zmmv = (dest), (len)), zmmv) +# endif #endif #ifndef offsetof @@ -874,3 +881,8 @@ extern short ospeed; # endif # endif #endif + +#ifdef ZSH_VALGRIND +# include "valgrind/valgrind.h" +# include "valgrind/memcheck.h" +#endif diff --git a/Test/.distfiles b/Test/.distfiles index 1c0102818..5826e7574 100644 --- a/Test/.distfiles +++ b/Test/.distfiles @@ -15,6 +15,7 @@ B04read.ztst B05eval.ztst B06fc.ztst B07emulate.ztst +B08shift.ztst C01arith.ztst C02cond.ztst C03traps.ztst diff --git a/Test/A07control.ztst b/Test/A07control.ztst index b9b89b588..397a821f1 100644 --- a/Test/A07control.ztst +++ b/Test/A07control.ztst @@ -23,12 +23,12 @@ >start 255 >255 - fn() { + $ZTST_testdir/../Src/zsh -fc 'fn() { continue } - fn + fn' 1:continue outside loop -?fn:continue:1 not in while, until, select, or repeat loop +?fn:continue:1: not in while, until, select, or repeat loop for outer in 0 1 2 3; do print outer $outer diff --git a/Test/B08shift.ztst b/Test/B08shift.ztst new file mode 100644 index 000000000..0aa922673 --- /dev/null +++ b/Test/B08shift.ztst @@ -0,0 +1,33 @@ +# Test the shift builtin. + +%test + + set -- one two three four five six seven eight nine ten + shift + print $* + shift 2 + print $* + shift -p 3 + print $* + shift -p + print $* +0:shifting positional parameters +>two three four five six seven eight nine ten +>four five six seven eight nine ten +>four five six seven +>four five six + + array=(yan tan tether mether pip azer sezar akker conter dick) + shift 2 array + print $array + shift array + print $array + shift -p 3 array + print $array + shift -p array + print $array +0:shifting array +>tether mether pip azer sezar akker conter dick +>mether pip azer sezar akker conter dick +>mether pip azer sezar +>mether pip azer diff --git a/Test/C01arith.ztst b/Test/C01arith.ztst index 7b005c2ab..25cd8b83a 100644 --- a/Test/C01arith.ztst +++ b/Test/C01arith.ztst @@ -266,3 +266,19 @@ >48.5 >77.5 >63.5 + + underscore_integer() { + setopt cbases localoptions + print $(( [#_] 1000000 )) + print $(( [#16_] 65536 )) + print $(( [#16_4] 65536 * 32768 )) + } + underscore_integer +0:Grouping output with underscores: integers +>1_000_000 +>0x10_000 +>0x8000_0000 + + print $(( [#_] (5. ** 10) / 16. )) +0:Grouping output with underscores: floating point +>610_351.562_5 diff --git a/Test/C02cond.ztst b/Test/C02cond.ztst index 94fca8b68..69001476c 100644 --- a/Test/C02cond.ztst +++ b/Test/C02cond.ztst @@ -349,6 +349,14 @@ F:Failures in these cases do not indicate a problem in the shell. >0 >1 + foo='' + [[ $foo ]] || print foo is empty + foo=full + [[ $foo ]] && print foo is full +0:bash compatibility with single [[ ... ]] argument +>foo is empty +>foo is full + %clean # This works around a bug in rm -f in some versions of Cygwin chmod 644 unmodish diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst index 706aa28c2..a2660315f 100644 --- a/Test/C04funcdef.ztst +++ b/Test/C04funcdef.ztst @@ -208,6 +208,11 @@ >Da de da >Do be do + () (cat $1 $2) <(print process expanded) =(print expanded to file) +0:Process substitution with anonymous functions +>process expanded +>expanded to file + () { 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 diff --git a/Test/D02glob.ztst b/Test/D02glob.ztst index 1f8f65286..4697ca414 100644 --- a/Test/D02glob.ztst +++ b/Test/D02glob.ztst @@ -431,6 +431,7 @@ mkdir glob.tmp/dir5 touch glob.tmp/dir5/N123 print glob.tmp/dir5/N<->(N) + rm -rf glob.tmp/dir5 0:Numeric glob is not usurped by process substitution. >glob.tmp/dir5/N123 @@ -526,3 +527,41 @@ >+bus+bus matches +(+bus|-car) >@sinhats matches @(@sinhats|wrensinfens) >!kerror matches !(!somethingelse) + + ( + setopt extendedglob + cd glob.tmp + [[ -n a*(#qN) ]] && print File beginning with a + [[ -z z*(#qN) ]] && print No file beginning with z + setopt nonomatch + [[ -n z*(#q) ]] && print Normal string if nullglob not set + ) +0:Force glob expansion in conditions using (#q) +>File beginning with a +>No file beginning with z +>Normal string if nullglob not set + + (){ print $#@ } glob.tmp/dir*(Y1) + (){ print $#@ } glob.tmp/file*(NY1) + (){ [[ "$*" == */dir?\ */dir? ]] && print Returns matching filenames } glob.tmp/dir*(Y2) + (){ print "Limit is upper bound:" ${(o)@:t} } glob.tmp/dir*(Y5) + (){ print "Negated:" $@:t } glob.tmp/dir*(Y1^Y) + (){ print "Sorting:" $@:t } glob.tmp/dir*(Y4On) + (){ [[ $#@ -eq 1 ]] && print Globs before last path component } glob.tmp/dir?/subdir(NY1) + (){ [[ $#@ -eq 0 ]] && print Respects qualifiers } glob.tmp/dir*(NY1.) + (print -- *(Y)) 2>/dev/null || print "Argument required" +0:short-circuit modifier +>1 +>0 +>Returns matching filenames +>Limit is upper bound: dir1 dir2 dir3 dir4 +>Negated: dir1 dir2 dir3 dir4 +>Sorting: dir4 dir3 dir2 dir1 +>Globs before last path component +>Respects qualifiers +>Argument required + + [[ "ce fichier n'existe pas" = (#b)ce\ (f[^ ]#)\ *s(#q./) ]] + print $match[1] +0:(#q) is ignored completely in conditional pattern matching +>fichier diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index a8cc93a12..49dcea901 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -1560,3 +1560,79 @@ 0:Intersection and disjunction with empty parameters >0 >0 + + foo=(a b c) + bar=(1 2 3) + print ${foo:^bar} + print ${foo:^^bar} + foo=(a b c d) + bar=(1 2) + print ${foo:^bar} + print ${foo:^^bar} + foo=('a a' b) + bar=(1 '2 2') + print -l "${foo:^bar}" + print -l "${(@)foo:^bar}" +0:Zipping arrays, correct output +>a 1 b 2 c 3 +>a 1 b 2 c 3 +>a 1 b 2 +>a 1 b 2 c 1 d 2 +# maybe this should be changed to output "a a b 1" +>a a b +>1 +>a a +>1 +>b +>2 2 + + foo=(a b c) + bar=() + print ${foo:^bar} + print ${foo:^^bar} + print ${bar:^foo} + print ${bar:^^foo} + print ${bar:^bar} + print ${bar:^^bar} +0:Zipping arrays, one or both inputs empty +> +>a b c +> +>a b c +> +> + + foo=text + bar=() + print ${foo:^bar} + print ${bar:^^foo} + bar=other + print ${foo:^bar} + bar=(array elements) + print ${foo:^bar} + print ${foo:^^bar} + print ${bar:^foo} + print ${bar:^^foo} +0:Zipping arrays, scalar input +> +>text +>text other +>text array +>text array text elements +>array text +>array text elements text + + foo=(a b c) + print ${foo:^^^bar} +1:Zipping arrays, parsing +?(eval):2: not an identifier: ^bar + + (setopt nounset + print ${foo:^noexist}) +1:Zipping arrays, NO_UNSET part 1 +?(eval):2: noexist: parameter not set + + (setopt nounset + print ${noexist:^foo}) +1:Zipping arrays, NO_UNSET part 2 +?(eval):2: noexist: parameter not set diff --git a/Test/D09brace.ztst b/Test/D09brace.ztst index d0ec93cd3..3e667a8d1 100644 --- a/Test/D09brace.ztst +++ b/Test/D09brace.ztst @@ -97,3 +97,18 @@ 0:BRACE_CCL off >X{za-q521}Y + print -r hey{a..j}there +0:{char..char} ranges, simple case +>heyathere heybthere heycthere heydthere heyethere heyfthere heygthere heyhthere heyithere heyjthere + + print -r gosh{1,{Z..a},2}cripes +0:{char..char} ranges, ASCII ordering +>gosh1cripes goshZcripes gosh[cripes gosh\cripes gosh]cripes gosh^cripes gosh_cripes gosh`cripes goshacripes gosh2cripes + + print -r crumbs{y..p}ooh +0:{char..char} ranges, reverse +>crumbsyooh crumbsxooh crumbswooh crumbsvooh crumbsuooh crumbstooh crumbssooh crumbsrooh crumbsqooh crumbspooh + + print -r left{[..]}right +0:{char..char} ranges with tokenized characters +>left[right left\right left]right diff --git a/Test/E01options.ztst b/Test/E01options.ztst index d9f219115..46b183776 100644 --- a/Test/E01options.ztst +++ b/Test/E01options.ztst @@ -430,7 +430,7 @@ foo unfunction foo 0:FUNCTION_ARGZERO option ->My name is ZTST_execchunk +>My name is (anon) >My name is foo setopt _NO_glob_ @@ -1114,3 +1114,45 @@ >1 >1 >2 + + for (( i = 0; i < 10; i++ )); do + () { + print $i + break + } + done +0:NO_LOCAL_LOOPS +>0 + + () { + emulate -L zsh + setopt localloops + for (( i = 0; i < 10; i++ )); do + () { + setopt nolocalloops # ignored in parent + print $i + break + } + done + } +0:LOCAL_LOOPS +>0 +>1 +>2 +>3 +>4 +>5 +>6 +>7 +>8 +>9 +?(anon):4: `break' active at end of function scope +?(anon):4: `break' active at end of function scope +?(anon):4: `break' active at end of function scope +?(anon):4: `break' active at end of function scope +?(anon):4: `break' active at end of function scope +?(anon):4: `break' active at end of function scope +?(anon):4: `break' active at end of function scope +?(anon):4: `break' active at end of function scope +?(anon):4: `break' active at end of function scope +?(anon):4: `break' active at end of function scope diff --git a/Test/X02zlevi.ztst b/Test/X02zlevi.ztst index d4a125f21..19188dfb7 100644 --- a/Test/X02zlevi.ztst +++ b/Test/X02zlevi.ztst @@ -10,6 +10,63 @@ %test + zletest $'word\euaend' +0:undo initial change +>BUFFER: end +>CURSOR: 3 + + zletest $'text\e.' +0:repeat initial edit +>BUFFER: text +>text +>CURSOR: 8 + + zpty_run 'print -z before' + zletest $'after\e.' +0:repeat initial edit with non-blank starting line +>BUFFER: beforeafterafter +>CURSOR: 15 + + zpty_run 'setopt overstrike;print -z bung' + zletest $'ing\e2|.' +0:repeat initial edit with overstrike set +>BUFFER: binging +>CURSOR: 3 + + zpty_run 'bindkey "^_" undo' + zletest $'undoc\037e' +0:use of undo in vi insert mode +>BUFFER: undoe +>CURSOR: 5 + + zletest $'one\euatwo\e0clthree' +0:vi mode undo of initial and subsequent change +>BUFFER: threewo +>CURSOR: 5 + + zletest $'xxx\euiyyy\euAz' +0:undo invoked twice +>BUFFER: z +>CURSOR: 1 + + zpty_run 'bindkey -a "^K" redo' + zletest $'123\C-_\e\C-k' +0:undo in insert mode, redo in command +>BUFFER: 123 +>CURSOR: 2 + + zpty_run 'bindkey "^Y" redo' + zletest $'pre\eA123\C-_\C-y\eu' +0:undo and redo in insert mode, undo in command +>BUFFER: pre +>CURSOR: 2 + + zpty_run 'bindkey "^Gu" split-undo' + zletest $'one\C-gutwo\eu' +0:split the undo sequence +>BUFFER: one +>CURSOR: 2 + zletest $'one two\ebmt3|`tx``' 0:setting mark and returning to original position >BUFFER: one wo diff --git a/Test/comptest b/Test/comptest index 10814d635..4655f3b2b 100644 --- a/Test/comptest +++ b/Test/comptest @@ -69,12 +69,15 @@ comp-finish () { zle -R } zle-finish () { - print -lr "<WIDGET><finish>" "BUFFER: $BUFFER" "CURSOR: $CURSOR" - (( region_active )) && print -lr "MARK: $MARK" - zle -K main - zle kill-whole-line + local buffer="$BUFFER" cursor="$CURSOR" mark="$MARK" + (( region_active)) || unset mark + BUFFER="" + zle -I zle clear-screen - zle -R + zle redisplay + print -lr "<WIDGET><finish>" "BUFFER: $buffer" "CURSOR: $cursor" + (( $+mark )) && print -lr "MARK: $mark" + zle accept-line } zle -N expand-or-complete-with-report zle -N list-choices-with-report @@ -83,20 +86,41 @@ zle -N zle-finish bindkey "^I" expand-or-complete-with-report bindkey "^D" list-choices-with-report bindkey "^Z" comp-finish -bindkey "^M" zle-finish -bindkey -a "^M" zle-finish +bindkey "^X" zle-finish +bindkey -a "^X" zle-finish ' } +zpty_flush() { + local junk + if zpty -r -t zsh junk \*; then + (( ZTST_verbose > 2 )) && print -n -u $ZTST_fd "$*: ${(V)junk}" + while zpty -r -t zsh junk \* ; do + (( ZTST_verbose > 2 )) && print -n -u $ZTST_fd "${(V)junk}" + done + (( ZTST_verbose > 2 )) && print -u $ZTST_fd '' + fi +} + +zpty_run() { + zpty -w zsh "$*" + zpty -r -m zsh log "*<PROMPT>*" || { + print "prompt hasn't appeared." + return 1 + } +} + comptesteval () { local tmp=/tmp/comptest.$$ print -lr - "$@" > $tmp + # zpty_flush Before comptesteval zpty -w zsh ". $tmp" zpty -r -m zsh log_eval "*<PROMPT>*" || { print "prompt hasn't appeared." return 1 } + zpty_flush After comptesteval rm $tmp } @@ -136,10 +160,12 @@ comptest () { zletest () { input="$*" - zpty -n -w zsh "$input"$'\C-M' + # zpty_flush Before zletest + zpty -n -w zsh "$input"$'\C-X' zpty -r -m zsh log "*<WIDGET><finish>*<PROMPT>*" || { print "failed to invoke finish widget." return 1 } + # zpty_flush After zletest print -lr "${(@)${(ps:\r\n:)log##*<WIDGET><finish>}[1,-2]}" } diff --git a/Test/ztst.zsh b/Test/ztst.zsh index 745a13cff..74111f6cc 100755 --- a/Test/ztst.zsh +++ b/Test/ztst.zsh @@ -260,8 +260,12 @@ $ZTST_redir" # Execute an indented chunk. Redirections will already have # been set up, but we need to handle the options. ZTST_execchunk() { + setopt localloops # don't let continue & break propagate out options=($ZTST_testopts) - eval "$ZTST_code" + () { + unsetopt localloops + eval "$ZTST_code" + } ZTST_status=$? # careful... ksh_arrays may be in effect. ZTST_testopts=(${(kv)options[*]}) diff --git a/Util/helpfiles b/Util/helpfiles index 900564842..699ca8321 100755 --- a/Util/helpfiles +++ b/Util/helpfiles @@ -1,4 +1,4 @@ -#!/usr/local/bin/perl -- -*-perl-*- +#!/usr/bin/env perl # helpfiles: make help files for Z-shell builtins from the manual entries. @@ -16,24 +16,10 @@ # If a third arg is given, the symlink is not created, but a # list of symlinks is put into the file specified by that arg. -# Example usage: -# cd ~/zsh-4.0.1 # or wherever -# mkdir Help -# cd Help -# man zshbuiltins | colcrt - | helpfiles -# run-help() { -# typeset zhelp=~/zsh-4.0.1/Help # or wherever -# [[ $1 = . ]] && 1=dot -# [[ $1 = : ]] && 1=colon -# if [[ $1 = compctl ]]; then -# man zshcompctl -# elif [[ -f $zhelp/$1 ]]; then -# ${=PAGER:-more} $zhelp/$1 -# else -# man $1 -# fi -# } -# now <Esc>-h works for shell builtins. +# This script is called automatically during `make install' +# unless specified otherwise. + +# For usage and and more information see zshcontrib(1). sub Usage { print(STDERR "Usage: helpfiles zshbuiltins.1 dest-dir [link-file]\n"); @@ -81,17 +67,17 @@ if(system('man ' . $args) || !(-s $mantmp)) { } $args = "$mantmp >$coltmp"; unlink($coltmp); -&Info('attempting colcrt ', $args); -if(system('colcrt ' . $args) || !(-s $coltmp)) { - unlink($coltmp); - &Info('attempting col -bx <', $args); +&Info('attempting col -bx <', $args); # The x is necessary so that spaces don't turn into tabs, which messes # up the calculations of indentation on machines which randomly wrap lines # round to the previous line (so you see what we're up against). - if(system('col -bx <' . $args) || !(-s $coltmp)) { +if(system('col -bx <' . $args) || !(-s $coltmp)) { + unlink($coltmp); + &Info('attempting colcrt - ', $args); + if(system('colcrt - ' . $args) || !(-s $coltmp)) { unlink($mantmp); unlink($coltmp); - &Die('colcrt and col -bx both failed'); + &Die('col -bx and colcrt - both failed'); } } unlink($mantmp) || &Die('cannot remove tempfile ', $mantmp); diff --git a/configure.ac b/configure.ac index 776b90828..37f35858f 100644 --- a/configure.ac +++ b/configure.ac @@ -117,6 +117,17 @@ AC_HELP_STRING([--enable-zsh-heap-debug], AC_DEFINE(ZSH_HEAP_DEBUG) fi]) +dnl Do you want to allow Valgrind to debug heap allocation? +ifdef([zsh-valgrind],[undefine([zsh-valgrind])])dnl +AH_TEMPLATE([ZSH_VALGRIND], +[Define to 1 if you want to add code for valgrind to debug heap memory.]) +AC_ARG_ENABLE(zsh-valgrind, +AC_HELP_STRING([--enable-zsh-valgrind], +[turn on support for valgrind debugging of heap memory]), +[if test x$enableval = xyes; then + AC_DEFINE(ZSH_VALGRIND) +fi]) + dnl Do you want debugging information on internal hash tables. dnl This turns on the `hashinfo' builtin command. ifdef([zsh-hash-debug],[undefine([zsh-hash-debug])])dnl @@ -129,6 +140,16 @@ AC_HELP_STRING([--enable-zsh-hash-debug], [turn on debugging of internal hash ta AC_DEFINE(ZSH_HASH_DEBUG) fi]) +dnl Do you want to dynamically allocate memory on the stack where possible? +ifdef([stack-allocation],[undefine([stack-allocation])])dnl +AH_TEMPLATE([USE_STACK_ALLOCATION], +[Define to 1 if you want to allocate stack memory e.g. with `alloca'.]) +AC_ARG_ENABLE(stack-allocation, +AC_HELP_STRING([--enable-stack-allocation], [allocate stack memory e.g. with `alloca']), +[if test x$enableval = xyes; then + AC_DEFINE(USE_STACK_ALLOCATION) +fi]) + dnl Pathnames for global zsh scripts ifdef([etcdir],[undefine([etcdir])])dnl AC_ARG_ENABLE(etcdir, @@ -756,7 +777,7 @@ AH_TEMPLATE([ZSH_NO_XOPEN], AC_CACHE_CHECK(if _XOPEN_SOURCE_EXTENDED should not be defined, zsh_cv_no_xopen, [[case "$host_os" in - *openbsd*|*freebsd5*|*freebsd6.[012]*|*aix*) + *freebsd5*|*freebsd6.[012]*|*aix*) zsh_cv_no_xopen=yes ;; *) |