1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-01-16 10:01:16 +01:00

zsh-3.1.6-test-1

This commit is contained in:
Tanaka Akira 1999-07-12 17:02:40 +00:00
parent 7c670f1e6a
commit 1f6786ef7a
65 changed files with 1858 additions and 505 deletions

244
ChangeLog
View file

@ -1,12 +1,204 @@
1999-07-03 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-07-12 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: version 3.1.6-test-1
* Sven: 7099: Completion/Core/_main_complete, Doc/Zsh/compsys.yo:
config key last_prompt means don't turn off alwayslastprompt on
prefix.
* Sven: 7097: Completion/Core/_oldlist: keeps old command line.
1999-07-09 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 7091: configure.in, INSTALL: change defaults for
dynamic and large file support to be enabled.
* Sven: 7083: Src/Zle/compctl.c, Src/Zle/zle_tricky.c,
Doc/Zsh/compwid.yo: compset -q unconditionally splits
the current word.
* Sven: 7082: Completion/Base/_parameter: use _parameters
* pws: 7076: Completion/Base/_command_names,
Completion/Base/_first, Completion/User/_su: %resume should be
in _command_names; _su should check $SHELL.
* pws: 7075, 7080, 7092: Completion/Core/compinit,
Config/funcinst.mk, Config/installfns.sh,
Config/uninstallfns.sh, INSTALL: Yet another attempt to install
shell functions in a sensible way; compinit adds to the end of
$fpath; fixed typo that it didn't check existing fpath properly.
* Oliver: 7067: Completion/Base/_first, Completion/User/_su,
Completion/User/_sh: check for %resume on command line;
new completions for _su and _sh.
* pws: 7066: configure.in: function install makefile in
source, not build, hierarchy.
* Sven: 7062: Src/Zle/complist.c, Src/Zle/zle_tricky.c,
Doc/Zsh/compsys.yo, Doc/Zsh/mod_complist.yo: undo works
inside menu-selection for items completed by
accept-and-infer-next-history; display is more reliable.
* Sven: 7058: Src/Zle/zle_params.c: turn off menu completion
if the command line gets altered by a zle function.
1999-07-08 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 7049: Src/builtin.c: eval didn't save/restore lexical
state.
* pws: 7046: Src/loop.c: xtrace for case and for statements.
* Sven: 7043: Completion/Core/_oldlist: Extra sophistication
when using _oldlist with a particular completer.
* pws: 7042: Etc/BUGS, Etc/CONTRIBUTORS, Etc/NEWS,
Doc/Zsh/builtins.yo, Doc/Zsh/expn.yo, Doc/Zsh/mod_complist.yo,
Doc/Zsh/params.yo: Changes to admin files for 3.1.6; some minor
documentation changes.
* Sven: 7039: Completion/Commands/_read_comp: trapping SIGINT
no longer necessary after 7038.
* pws: 7038: Src/Zle/zle_main.c: restore breaks whenever errflag
is restored as SIGINT handler sets both.
* Sven: 7036: Src/Zle/complist.c: make sure old list is thrown
away when doing accept-and-infer-next-history in menu-completion.
* Sven: 7028: Src/Zle/zle_tricky.c,
Functions/Zle/incremental-complete-word: problems when BUFFER
changes, %u in i-c-w prompt, config key for showing list.
* Sven: 7026: Completion/Core/_main_complete,
Completion/Core/_match, Completion/Core/_oldlist,
Completion/Core/compinit: More information stored in assoc array
_lastcomp about the previous completion.
* Sven: 7025: Src/Zle/complist.c: remove list when accepting
and retrying completion when unambiguous.
1999-07-07 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 7021: Src/utils.c: error message in findsep() was
erroneous.
* pws: 7020: Src/params.c: error message for whole assoc array
assignment.
* Oliver: 7005: Src/builtin.c, Doc/Zsh/builtins.yo: alias
takes +g and + flags.
* Sven: 7004: Src/Zle/zle_refresh.c: reset showinglist on
clearlist.
* pws: 7002: Completion/Commands/_read_comp: does completion
lists; handle errors better.
* pws: 7001: Src/hist.c: line numbers were wrong in some error
messages (e.g. conditions) when reading from a string
(e.g. autoloaded functions).
* pws: 6998: Src/Zle/zle_bindings.c: restore history-search
bindings \M-n, \M-p.
* Sven: 6996: Src/Zle/complist.c, Src/Zle/zle_tricky.c,
Doc/Zsh/mod_complist.yo: accept-and-infer-next-history
in menu-select accepts a match, then restarts menu selection.
* Sven: 6995, 7000: Src/math.c, Src/utils.c, Doc/Zsh/arith.yo:
allow bindkey strings in after #\ in math mode. Also
incremental-complete-word and insert-files, added by hand
to directory Functions/Zle, with appropriate changes to
configure.in and INSTALL.
* Sven: 6992: Src/Zle/zle_main.c, Src/Zle/zle_misc.c,
Src/Zle/zle_thingy.c, Src/Zle/zle_tricky.c, Doc/Zsh/mod_zle.yo:
zle -R can take list arguments; zle -cR clears the list;
zle -U puts keys in the unget queue.
* Geoff: 6991: configure.in: NetBSD can use both ELF and a.out.
1999-07-06 Peter Stephenson <pws@ibmth.df.unipi.it>
* Andrej: 6990: Completion/Builtins/_cd,
Completion/Core/_path_files: some local variable fixes.
* pws: 6987: Src/builtin.c: `typeset +f' and `functions +'
should just print the function name.
* pws: 6986: Doc/Zsh/builtins.yo, Doc/Zsh/params.yo,
Src/builtin.c, Src/params.c, Src/zsh.h: special parameters
can become local, remaining special; be more careful that
only the most global parameter can appear in the environment.
* pws: 6984: Doc/Zsh/compsys.yo: typo in 6973 docs
1999-07-05 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6982: Src/exec.c: variable assignment with redirection is
interpreted as variable assignment with redirection, not
nullcmd.
* pws: 6981: Completion/Commands/_read_comp: -n should be -z.
* Sven: 6979: Completion/Core/_path_files: compconfig[path_expand]
fix.
* Sven: 6977: Completion/Core/_match: cosmetic `if' change.
* Sven: 6975: Src/Zle/zle_tricky.c: fix quoting of tildes at
the start of file names.
* Sven: 6974: Src/exec.c: mark superjob as locked as soon
as started.
* pws: 6973: Completion/Commands/_read_comp, Doc/Zsh/compsys.yo:
_read_comp allows function arguments and ^U but won't add
non-printables; document Completion/Commands widgets.
* Sven: 6971: Src/exec.c, Src/jobs.c: backgrounding jobs forked
from current shell works again; job table not filled up by
current shell subjobs; current/previous job not lost.
1999-07-04 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6970: Completion/Base/_default, Completion/Builtins/_cd,
Completion/Commands/_read_comp: handle magicequalsubst and
cdablevars optios; _read_comp can read and execute a completion
function (_*) or compgen argument (-*) on the fly.
* pws: 6969: Doc/Zsh/builtins.yo, Src/builtin.c: print -b
uses full bindkey string possibilities.
* Tanaka Akira: 6968: Completion/Core/compinit: compinit -D
didn't actually work.
* pws: 6967: Completion/Core/_path_files: final return status
inverted.
* pws: 6966: Completion/Makefile.in, Functions/Makefile.in,
Config/funcinst.mk, configure.in, INSTALL: prevent overwriting
of changed shell functions on installation; move function
installation code to funcinst.mk; clear up INSTALL a bit.
1999-07-03 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6962: Doc/Zsh/prompt.yo, Src/prompt.c: %/ and %~ take
numbers for trailing path segments like %c and %C, %N can too;
function promptpath() to implement this.
* pws: 6957: 3.1.5-pws-25 made available
* pws: 6955, 6956: Completion/Core/compinit,
Completion/Core/compinstall, Doc/Zsh/compsys.yo: better handling
of subdirectory structure for completion functions; -d is default
for compinit, -D turns it off; documentation updated for installed
files; bugfix for compinstall re-using compconf arguments.
1999-07-02 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-07-02 Peter Stephenson <pws@ibmth.df.unipi.it>
* Tanaka Akira: 6953: Completion/Builtins/_cd: use pushd code for cd
@ -22,7 +214,7 @@
send-break to exit menu selection and return to normal menu
completion.
1999-07-01 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-07-01 Peter Stephenson <pws@ibmth.df.unipi.it>
* Sven: 6936: Src/jobs.c: time builtin was broken.
@ -30,7 +222,7 @@
control fixes: running external command after loop in function;
function on left hand side of pipeline with loop on right.
1999-06-29 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-29 Peter Stephenson <pws@ibmth.df.unipi.it>
* Sven: 6908, 6926: Src/exec.c, Src/jobs.c, Src/zsh.h: more job
control fixes: functions with programs that send strange
@ -50,7 +242,7 @@
some (but not all) recent job handling patches to avoid more
serious problems with recalcitrant programs.
1999-06-28 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-28 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6899: Doc/Zsh/params.yo, Doc/Zsh/prompt.yo, Src/init.c:
default PS4 is now "+%N:%i> ", except in [k]sh emulation.
@ -67,7 +259,7 @@
* Geoff: 6884: Src/Zle/zle_refresh.c: bug when redisplaying line
one shorter than terminal width
1999-06-27 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-27 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6881: Doc/Zsh/mod_zle.yo: explain keymap linking
@ -83,11 +275,11 @@
* pws: 6866: Src/exec.c, Src/init.c: signed/unsigned character
problems; one was causing SunOS 4.1.3_U1 with gcc 2.7.0 to hang.
1999-06-26 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-26 Peter Stephenson <pws@ibmth.df.unipi.it>
* 3.1.5-pws-24 made available
1999-06-25 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-25 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6857: Completion/Core/compinit,
Completion/Core/compinstall, Doc/Zsh/compsys.yo: compinit and
@ -110,7 +302,7 @@
* Sven: 6841: Src/loop.c: %_ in else branches for PS4
1999-06-24 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-24 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6834: Src/glob.c, Src/hashtable.c: dyncat() changed always
to use heap memory (as it erroneously claimed); hashtable element
@ -142,7 +334,7 @@
don't automatically switch on select widget until there are
$SELECTMIN choices.
1999-06-23 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-23 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6816: Doc/Zsh/params.yo, Src/utils.c: ZBEEP parameter
gives string to output instead of beeping.
@ -185,7 +377,7 @@
Src/Zle/zle_main.c, Doc/Zsh/mod_complist.yo: Local keymaps can be
defined, currently only used with menu-select.
1999-06-22 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-22 Peter Stephenson <pws@ibmth.df.unipi.it>
* Sven: 6786: Src/Zle/zle_tricky.c, Doc/Zsh/compctl.yo: only use
a range when you are after the first pattern in it.
@ -212,7 +404,7 @@
* Oliver: 6772: Src/Zle/zle_tricky.c: use the whole
command text for job completion.
1999-06-21 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-21 Peter Stephenson <pws@ibmth.df.unipi.it>
* Sven: 6760: Src/Zle/zle_tricky.c: menucompletion displaying new
list of matches sometimes got confused.
@ -243,7 +435,7 @@
* Bart: 6731: Doc/Zsh/compctl.yo: spelling correction
1999-06-20 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-20 Peter Stephenson <pws@ibmth.df.unipi.it>
* zsh-3.1.5-pws-23 made available
@ -258,7 +450,7 @@
to list to restore when outside a function, but do if the function
simply unsets a trap which was set outside.
1999-06-18 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-18 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6718: Completion/Core/compinit, Completion/Core/compdump,
Doc/Zsh/compsys.yo: rebind existing completion widgets for new
@ -281,7 +473,7 @@
of stopping a command in such a structure where the command
handles interruptions in such a way that zsh doesn't see them.
1999-06-17 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-17 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6705: Doc/Zsh/builtins.yo, Src/builtin.c, Src/exec.c,
Src/init.c, Src/input.c, Src/parse.c: some more LINENO
@ -328,7 +520,7 @@
* Wayne: 6681: Src/builtin.c: start-of-loop check for history -r
was wrong.
1999-06-16 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-16 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6679: Src/Zle/zle_thingy.c, Doc/Zsh/compwid.yo: always
use .complete-word etc. as widget type in zle -C.
@ -365,7 +557,7 @@
* Bart: 6646: Src/lex.c: extra braces to enhance beauty of code
which appeared in 3.0.5.
1999-06-15 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-15 Peter Stephenson <pws@ibmth.df.unipi.it>
* Tanaka Akira: 6642: Completion/Base/_tilde: complete directory
stack elements after ~+ or ~-.
@ -388,7 +580,7 @@
* Bart: 6628: Src/params.c: setting slices of unset array
caused a crash.
1999-06-14 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-14 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6626: Src/mem.c: in zsh's malloc, try to make sure when
sbrk'ing that it's sufficiently well aligned.
@ -419,7 +611,7 @@
expn.yo, files.yo, mod_mapfile.yo, mod_zftp.yo, params.yo,
zftpsys.yo, zle.yo: spelling corrections
1999-06-12 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-12 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6601: Src/Makefile.in: don't remake Makemod just
to clean up files
@ -439,7 +631,7 @@
* Wayne: 6599: Src/Zle/zle_tricky.c: unitialised variable warnings
from gcc
1999-06-11 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-11 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6598: Doc/Zsh/zftpsys.yo, Functions/Zftp/zfinit,
Functions/Zftp/zfgoto, Functions/Zftp/zfmark,
@ -461,7 +653,7 @@
struct cmd to insert cmd args and flags, always pass those
separately
1999-06-10 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-10 Peter Stephenson <pws@ibmth.df.unipi.it>
* Andrej: 6581: Doc/Makefile: dependencies for manuals
@ -497,7 +689,7 @@
* Sven: 6557: Doc/zsh/compsys.yo: a few typos
1999-06-09 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-09 Peter Stephenson <pws@ibmth.df.unipi.it>
* Andrej: 6556: aczsh.m4: don't disable setting variables
for --enable-lfs just because some other variables were set
@ -543,7 +735,7 @@
on Solaris 2.7, despite previous reports; Sven says on Digital
UNIX 4.0, you need special DLLD and LDFLAGS.
1999-06-08 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-08 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 6525: Src/lex.c (gettokstr): allow parentheses after
first character in command word
@ -560,7 +752,7 @@
* Wayne: 6510: Completion/Core/compinit: another nounset problem
1999-06-07 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-07 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: configure.in, Config/defs.mk.in, Functions/Makefile.in,
Completion/Makefile.in, rearrangement of Functions
@ -613,12 +805,12 @@
* Tanaka Akira: 6478: Completion/User/_make: complete files
as fallback (but use _files instead of compgen -f)
1999-06-06 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-06 Peter Stephenson <pws@ibmth.df.unipi.it>
* Naoki Wakamatsu <naoki-w@ht-net21.ne.jp>: 6477: configure.in:
undefine etcdir, not zshenv
1999-06-05 Peter Stephenson <pws@ibmth.difi.unipi.it>
1999-06-05 Peter Stephenson <pws@ibmth.df.unipi.it>
* Merge ChangeLog entry from patchlist.txt in 3.1.5-pws-20
These are briefer than normal ChangeLog entries, but upgrading

View file

@ -2,6 +2,13 @@
local nm=$compstate[nmatches] ret=1
# Complete jobs in implicit fg and bg
if [[ "$PREFIX[1]" = "%" ]]; then
compgen -j -P '%'
[[ nm -ne compstate[nmatches] ]] && return
fi
compgen -c && ret=0
if [[ nm -eq compstate[nmatches] ]]; then

View file

@ -11,4 +11,11 @@
compcall || return 0
_files
_files && return
# magicequalsubst allows arguments like <any-old-stuff>=~/foo to do
# file name expansion after the =. In that case, it's natural to
# allow completion to handle file names after any equals sign.
if [[ -o magicequalsubst ]] && compset -P 1 '*='; then
_files
fi

View file

@ -1,3 +1,3 @@
#compdef -parameter-
compgen -v
_parameters -S ' ' -r '['

View file

@ -11,11 +11,8 @@
# it's not a lot of use. If you don't type the + or - it will
# complete directories as normal.
local pushdminus
[[ -o pushdminus ]] && pushdminus=1
emulate -LR zsh
setopt extendedglob
emulate -L zsh
setopt extendedglob nonomatch
if [[ CURRENT -eq 3 ]]; then
# cd old new: look for old in $PWD and see what can replace it
@ -40,8 +37,8 @@ elif [[ $PREFIX = [-+]* ]]; then
lines="$(dirs -v)"
# turn the lines into an array, removing the current directory
list=(${${(f)lines}##0*})
if [[ ( $IPREFIX = - && -z $pushdminus ) ||
( $IPREFIX = + && -n $pushdminus ) ]]; then
if [[ ( $IPREFIX = - && ! -o pushdminus ) ||
( $IPREFIX = + && -o pushdminus ) ]]; then
# reverse the numbering: it counts the last one as -0, which
# is a little strange.
integer tot i
@ -59,7 +56,19 @@ elif [[ $PREFIX = [-+]* ]]; then
return ret
elif [[ $PREFIX != (\~|/|./|../)* && $#cdpath -ne 0 ]]; then
_path_files -W "(. $cdpath)" -/
local tdir tdir2
# With cdablevars, we can convert foo/bar/... to ~foo/bar/... if
# there is no directory foo. In that case we could also complete
# variable names, but it hardly seems worth it.
# Note we need a tilde because cdablevars also allows user home
# directories, hence we also need nonomatch to suppress error messages.
if [[ -o cdablevars && ! -d ${tdir::=${PREFIX%%/*}} &&
-d ${~tdir2::="~$tdir"} ]]; then
PREFIX="~$PREFIX"
_path_files -/
else
_path_files -W "(. $cdpath)" -/
fi
else
_path_files -/
fi

View file

@ -1,3 +1,4 @@
DISTFILES_SRC='
.distfiles _correct_filename _correct_word _expand_word _most_recent_file
.distfiles _correct_filename _correct_word _expand_word
_history_complete_word _read_comp _most_recent_file
'

View file

@ -0,0 +1,2 @@
#compdef -k complete-word \e/
compgen -Q -H 0 ''

View file

@ -0,0 +1,158 @@
#compdef -k complete-word \C-x\C-r
# This allows an on-the-fly choice of completions. On typing the key
# sequence given above, you will be prompted for a string of arguments. If
# this string begins with `_', it will be taken as the name of a function to
# evaluate to generate the completions; unambiguous strings in the function
# name are automatically completed.
#
# Else it is taken to be a set of arguments for compgen to generate a list
# of choices. The possibilities are the same as the flags for generating
# completions given in the zshcompctl manual page. Note the arguments are
# verbatim: include minus signs, spaces, quotes, etc.
#
# On subsequent calls, the same completion will be re-performed. To
# force a new type of completion to be read, supply a numeric argument.
#
# For example,
# % bindkey | grep rever<C-xC-r>
# Completion: -b<RET>
# % bindkey | grep reverse-menu-complete _
#
# Global variables used:
# _read_comp Last completion string read from user
emulate -L zsh
setopt extendedglob nobadpattern # xtrace promptsubst
# local PS4='%N:%i:$((#key))> '
# Took me ages to work this out. If we're not on the first global
# matcher specification, we mustn't do any I/O.
if [[ compstate[matcher] -gt 1 && -z $_read_comp ]]; then
return 1
fi
if [[ compstate[matcher] -gt 1 ||
( ${+NUMERIC} = 0 && -n $_read_comp ) ]]; then
if [[ $_read_comp = _* ]]; then
eval $_read_comp
else
eval "compgen $_read_comp"
fi
return
fi
_read_comp=
local key search str str2 newch funcs funcs2 exact msg list
integer pos
msg="Completion: "
zle -R $msg
if ! read -k key; then
zle -cR ''
return 1
fi
while [[ '#key' -ne 10 && '#key' -ne 13 ]]; do
if [[ '#key' -eq 0 && '#key' -eq 3 || '#key' -eq 7 ]]; then
zle -cR ''
return 1
fi
if [[ ( '#key' -eq 8 || '#key' -eq 127 ) && -n $str ]]; then
# delete character
str="$str[1,-2]"
exact=
list=()
elif [[ '#key' -eq 21 ]]; then
# ^U: delete line
str=
exact=
list=()
elif [[ '#key' -eq 4 && $str = _[^\ ]# && $str != *' '* ]]; then
# ^D: list completions
list=(${$(whence -m "$str*" 2>/dev/null)%: function})
elif [[ ( -n $exact && $key != ' ' ) || '#key & 127' -lt 32 ]]; then
# If we've got an exact function, only allow a space after it.
# Don't try to insert non-printing characters.
if [[ -n $ZBEEP ]]; then
print -nb $ZBEEP
elif [[ -o beep ]]; then
print -n "\a"
fi
list=()
else
str="$str$key"
if [[ $str = _[^\ ]# ]]; then
# Rudimentary completion for function names.
# Allow arguments, i.e. don't do this after we've got a space.
funcs=(${$(whence -m "$str*" 2>/dev/null)%: function})
if [[ -o autolist && $#str -gt 1 ]]; then
list=($funcs)
else
list=()
fi
if (( $#funcs == 1 )); then
# Exact match; prompt the user for a newline to confirm
str=$funcs[1]
exact=" (Confirm)"
elif (( $#funcs == 0 )); then
# We can't call zle beep, because this isn't a zle widget.
if [[ -n $ZBEEP ]]; then
print -nb $ZBEEP
elif [[ -o beep ]]; then
print -n "\a"
fi
str="$str[1,-2]"
list=()
else
# Add characters to the string until a name doesn't
# match any more, then backtrack one character to get
# the longest unambiguous match.
str2=$str
pos=$#str2
while true; do
(( pos++ ))
newch=${funcs[1][pos]}
[[ -z $newch ]] && break
str2=$str2$newch
funcs2=(${funcs##$str2*})
(( $#funcs2 )) && break
str=$str2
done
fi
else
exact=
fi
fi
if (( $#list )); then
zle -R "$msg$str$exact" $list
else
zle -cR "$msg$str$exact"
fi
if ! read -k key; then
zle -cR ''
return 1
fi
done
if [[ -z $str ]]; then
# string must be non-zero
return 1
elif [[ $str = _* ]] && ! whence ${str%% *} >& /dev/null; then
# a function must be known to the shell
return 1
else
# remember the string for re-use
_read_comp=$str
fi
zle -cR ''
if [[ $str = _* ]]; then
eval $str
else
eval "compgen $str"
fi

View file

@ -15,9 +15,13 @@
# any matches, correction is tried and if that doesn't yield
# anything either, correcting completion is attempted.
#
# These completer functions are only used when this function is called
# without arguments. If arguments are given, they should be names of
# completer functions which will then be called.
# These completer functions are only used when this function is called
# without arguments. If arguments are given, they should be names of
# completer functions which will then be called.
#
# last_prompt
# If this is set to `always' the cursor is moved up to the last prompt
# after printing a list even if a numeric argument was given.
# If you want to complete only set or unset options for the unsetopt
@ -33,7 +37,7 @@
# state than the global one for which you are completing.
local comp
local comp ret=1
setopt localoptions nullglob rcexpandparam
unsetopt markdirs globsubst shwordsplit nounset ksharrays
@ -54,5 +58,21 @@ fi
# And now just call the completer functions defined.
for comp; do
"$comp" && return
if "$comp"; then
ret=0
break;
fi
done
[[ "$compconfig[last_prompt]" = always ]] && compstate[last_prompt]=yes
_lastcomp=( "${(@kv)compstate}" )
_lastcomp[completer]="$comp"
_lastcomp[prefix]="$PREFIX"
_lastcomp[suffix]="$SUFFIX"
_lastcomp[iprefix]="$IPREFIX"
_lastcomp[isuffix]="$ISUFFIX"
_lastcomp[qiprefix]="$QIPREFIX"
_lastcomp[qisuffix]="$QISUFFIX"
return ret

View file

@ -60,10 +60,8 @@ _complete && ret=1
compstate[pattern_match]="$opm"
compstate[matcher]="$compstate[total_matchers]"
if (( ! ret )); then
[[ "$compconfig[match_insert]" = unambig* &&
$#compstate[unambiguous] -ge ${#:-${PREFIX}${SUFFIX}} ]] &&
compstate[pattern_insert]=unambiguous
fi
[[ ret -eq 1 && "$compconfig[match_insert]" = unambig* &&
$#compstate[unambiguous] -ge ${#:-${PREFIX}${SUFFIX}} ]] &&
compstate[pattern_insert]=unambiguous
return 1-ret

View file

@ -4,12 +4,24 @@
# and either the compconfig key oldlist_list is `always', or it is not `never'
# and the list is not already shown, then use the existing list for listing
# (even if it was generated by another widget).
if [[ -n $compstate[old_list] && $compconfig[oldlist_list] != never &&
$WIDGET = *list* &&
( $compconfig[oldlist_list] = always || $compstate[old_list] != shown ) ]]
then
compstate[old_list]=keep
return 0
# Do this also if there is an old list and it was generated by the
# completer named by the oldlist_list key.
if [[ -n $compstate[old_list] && $compconfig[oldlist_list] != never ]]; then
if [[ $WIDGET = *list* &&
( $compconfig[oldlist_list] = always ||
$compstate[old_list] != shown ) ]]; then
compstate[old_list]=keep
return 0
elif [[ $compconfig[oldlist_list] = *${_lastcomp[completer]}* ]]; then
[[ "$_lastcomp[insert]" = unambig* ]] && compstate[to_end]=single
compstate[old_list]=keep
if [[ -o automenu ]]; then
compstate[insert]=menu
else
compadd -Qs "$SUFFIX" - "$PREFIX"
fi
return 0
fi
fi
# If this is a completion widget, and we have a completion inserted already,

View file

@ -33,12 +33,11 @@ typeset -U prepaths exppaths
setopt localoptions nullglob rcexpandparam extendedglob
unsetopt markdirs globsubst shwordsplit nounset
local sopt='-' gopt='' opt
exppaths=()
prepaths=('')
ignore=()
group=()
sopt='-'
gopt=''
pats=()
addpfx=()
addsfx=()
@ -377,9 +376,9 @@ done
exppaths=( "${(@)exppaths:#$orig}" )
if [[ -n "$compconfig[path_expand]" &&
$#exppaths -eq 0 && nm -eq compstate[nmatches] ]]; then
$#exppaths -eq 1 && nm -eq compstate[nmatches] ]]; then
compadd -QU -S '' "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
-M 'r:|/=* r:|=*' -p "$linepath" - "${(@)exppaths}"
fi
[[ nm -eq compstate[nmatches] ]]
[[ nm -ne compstate[nmatches] ]]

View file

@ -49,7 +49,7 @@ emulate -L zsh
typeset _i_dumpfile _i_files _i_line _i_done _i_dir _i_autodump=1
typeset _i_tag _i_file _i_addfiles
while [[ $# -gt 0 && $1 = -[df] ]]; do
while [[ $# -gt 0 && $1 = -[dDf] ]]; do
if [[ "$1" = -d ]]; then
_i_autodump=1
shift
@ -59,6 +59,7 @@ while [[ $# -gt 0 && $1 = -[df] ]]; do
fi
elif [[ "$1" = -D ]]; then
_i_autodump=0
shift
elif [[ "$1" = -f ]]; then
# Not used any more; use _compdir
shift
@ -72,6 +73,11 @@ done
typeset -gA _comps
_patcomps=()
# The associative array use to report information about the last
# cmpletion to the outside.
typeset -gA _lastcomp
# This is the associative array used for configuration.
typeset -gA compconfig
@ -308,10 +314,10 @@ if [[ $#_i_files -lt 20 || $_compdir = */Core || -d $_compdir/Core ]]; then
fi
for _i_line in {1..$#i_addfiles}; do
_i_file=${_i_addfiles[$_i_line]}
[[ -d $_i_file && -z ${fpath[(r)$_i_$file]} ]] ||
[[ -d $_i_file && -z ${fpath[(r)$_i_file]} ]] ||
_i_addfiles[$_i_line]=
done
fpath=($_i_addfiles $fpath)
fpath=($fpath $_i_addfiles)
_i_files=( ${^~fpath:/.}/_(|*[^~])(N:t) )
fi
fi

View file

@ -136,7 +136,7 @@ fi
# Check if this is in fpath already, else put it there (with ~'s expanded).
_ci_f=${~_ci_fdir}
[[ -z ${fpath[(r)$_ci_f]} ]] && fpath=($_ci_f $fpath)
[[ -z ${fpath[(r)$_ci_f]} ]] && fpath=($fpath $_ci_f)
# Contract $HOME to ~ in the parameter to be used for writing.
_ci_fdir=${_ci_fdir/#$HOME/\~}
@ -183,7 +183,7 @@ ${_ci_dumpfile}. Please edit a replacement."
fi
_ci_lines="${_ci_lines}_compdir=$_ci_fdir
[[ -z \$fpath[(r)\$_compdir] ]] && fpath=(\$_compdir \$fpath)
[[ -z \$fpath[(r)\$_compdir] ]] && fpath=(\$fpath \$_compdir)
autoload -U compinit
compinit"
[[ $_ci_dtype != standard ]] && _ci_lines="${_ci_lines} $_ci_dumpfile"

View file

@ -48,40 +48,7 @@ install: install.fns
uninstall: uninstall.fns
# install functions, including those in subdirectories, creating
# install directory if necessary
install.fns:
if test x$(fndir) != x && test x$(fndir) != xno; then \
$(sdir_top)/mkinstalldirs $(fndir) || exit 1; \
for file in $(FUNCTIONS_INSTALL); do \
if test -f $$file; then \
if test x$(FUNCTIONS_SUBDIRS) != x -a \
x$(FUNCTIONS_SUBDIRS) != xno; then \
subdir="`echo $$file | sed -e 's%/.*%%'`"; \
$(sdir_top)/mkinstalldirs $(fndir)/$$subdir || exit 1; \
$(INSTALL_DATA) $$file $(fndir)/$$subdir || exit 1; \
else \
$(INSTALL_DATA) $$file $(fndir) || exit 1; \
fi; \
fi; \
done; \
fi; \
exit 0
uninstall.fns:
if test x$(fndir) != x && test x$(fndir) != xno; then \
for file in $(FUNCTIONS_INSTALL); do \
if test -f $$file; then \
if test x$(FUNCTIONS_SUBDIRS) != x -a \
x$(FUNCTIONS_SUBDIRS) != xno; then \
rm -f $(fndir)/$$file; \
else \
rm -f "$(fndir)/`echo $$file | sed -e 's%^.*/%%'`"; \
fi; \
fi; \
done; \
fi; \
exit 0
@FUNCINST_MK@
# ========== DEPENDENCIES FOR CLEANUP ==========

View file

@ -1,6 +1,6 @@
DISTFILES_SRC='
.distfiles
_a2ps _chown _compress _configure _dd _dvi _find _groups _gunzip _gzip
_hosts _make _man _mh _pdf _ps _rcs _rlogin _strip _stty
_hosts _use_lo _make _man _mh _pdf _ps _rcs _rlogin _strip _stty
_tar _tar_archive _tex _uncompress _x_options _xfig
'

View file

@ -1,3 +1,3 @@
#compdef gs ghostview gview psnup psselect pswrap pstops pstruct lpr
#compdef gs ghostview gv gview psnup psselect pswrap pstops pstruct lpr lp
_files -g '*([pP][sS]|eps)'

View file

@ -75,6 +75,7 @@ if [[ "$PREFIX" = --* ]]; then
_long_options '--owner*' "_tilde" \
'*=(PROG|COMMAND)*' "_command_names" \
'*=ARCHIVE*' "_tar_archive" \
'*=NAME*' "_files" \
'*=CONTROL*' "[t numbered nil existing never simple]"
elif [[ ( CURRENT -gt 2 && "$words[CURRENT-1]" = -*f* &&

10
Completion/User/_use_lo Normal file
View file

@ -0,0 +1,10 @@
#compdef gls gdiff
# This is for GNU-like commands which understand the --help option,
# but which do not otherwise require special completion handling.
if [[ $PREFIX = --* ]]; then
_long_options
else
_default
fi

View file

@ -1,4 +1,5 @@
DISTFILES_SRC='
.distfiles .cvsignore
clean.mk config.mk defs.mk.in version.mk
clean.mk config.mk defs.mk.in funcinst.mk version.mk
installfns.sh uninstallfns.sh
'

47
Config/funcinst.mk Normal file
View file

@ -0,0 +1,47 @@
#
# Makefile definitions for installing shell functions
#
# Copyright (c) 1999 Peter Stephenson
# All rights reserved.
#
# Permission is hereby granted, without written agreement and without
# license or royalty fees, to use, copy, modify, and distribute this
# software and to distribute modified versions of this software for any
# purpose, provided that the above copyright notice and the following
# two paragraphs appear in all copies of this software.
#
# In no event shall Peter Stephenson or the Zsh Development Group be liable
# to any party for direct, indirect, special, incidental, or consequential
# damages arising out of the use of this software and its documentation,
# even if Peter Stephenson and the Zsh Development Group have been advised of
# the possibility of such damage.
#
# Peter Stephenson and the Zsh Development Group specifically disclaim any
# warranties, including, but not limited to, the implied warranties of
# merchantability and fitness for a particular purpose. The software
# provided hereunder is on an "as is" basis, and Peter Stephenson and the
# Zsh Development Group have no obligation to provide maintenance,
# support, updates, enhancements, or modifications.
#
# install functions, including those in subdirectories, creating
# install directory if necessary
install.fns:
if test x$(fndir) != x && test x$(fndir) != xno; then \
sdir_top="$(sdir_top)" fndir="$(fndir)" sdir="$(sdir)" \
FUNCTIONS_INSTALL="$(FUNCTIONS_INSTALL)" \
FUNCTIONS_SUBDIRS="$(FUNCTIONS_SUBDIRS)" \
INSTALL_DATA="$(INSTALL_DATA)" \
$(SHELL) $(sdir_top)/Config/installfns.sh || exit 1; \
fi; \
exit 0
uninstall.fns:
if test x$(fndir) != x && test x$(fndir) != xno; then \
fndir="$(fndir)" sdir="$(sdir)" \
FUNCTIONS_INSTALL="$(FUNCTIONS_INSTALL)" \
FUNCTIONS_SUBDIRS="$(FUNCTIONS_SUBDIRS)" \
$(SHELL) $(sdir_top)/Config/uninstallfns.sh || exit 1; \
fi; \
exit 0

48
Config/installfns.sh Executable file
View file

@ -0,0 +1,48 @@
#!/bin/sh
if test -d $fndir.old; then
add_old=1
fi
$sdir_top/mkinstalldirs $fndir || exit 1;
# If the source directory is somewhere else, we need to force
# the shell to expand it in that directory, then strip it off.
install=
for file in $FUNCTIONS_INSTALL; do
if test -f "$sdir/$file"; then
install="$install $file"
else
install="$install `echo $sdir/$file | sed -e \"s%$sdir/%%g\"`"
fi
done
for file in $install; do
if test -f $sdir/$file; then
if test x$FUNCTIONS_SUBDIRS != x -a x$FUNCTIONS_SUBDIRS != xno; then
subfile="$file"
subdir="`echo $file | sed -e 's%/[^/]*$%%'`"
olddir="$fndir.old/$subdir"
instdir="$fndir/$subdir"
else
subfile="`echo $file | sed -e 's%^.*/%%'`"
olddir="$fndir.old"
instdir="$fndir"
fi
if test -f $fndir/$subfile; then
if cmp $fndir/$subfile $sdir/$file >/dev/null; then :; else
$sdir_top/mkinstalldirs $olddir
mv $fndir/$subfile $olddir
: ${add_old:=1}
fi
fi
$sdir_top/mkinstalldirs $instdir || exit 1
$INSTALL_DATA $sdir/$file $instdir || exit 1
fi
done
if test x$add_old != x1; then
rm -rf $fndir.old
fi
exit 0

31
Config/uninstallfns.sh Executable file
View file

@ -0,0 +1,31 @@
#!/bin/sh
# If the source directory is somewhere else, we need to force
# the shell to expand it in that directory, then strip it off.
install=
for file in $FUNCTIONS_INSTALL; do
if test -f "$sdir/$file"; then
install="$install $file"
else
install="$install `echo $sdir/$file | sed -e \"s%$sdir/%%g\"`"
fi
done
for file in $install; do
if test -f $sdir/$file; then
if test x$FUNCTIONS_SUBDIRS != x -a x$FUNCTIONS_SUBDIRS != xno; then
rm -f $fndir/$file;
if test -f $fndir.old/$file; then
mv $fndir.old/$file $fndir/$file
fi
else
bfile="`echo $file | sed -e 's%^.*/%%'`"
rm -f "$fndir/$bfile"; \
if test -f $fndir.old/$bfile; then
mv $fndir.old/$bfile $fndir/$bfile
fi
fi
fi
done
exit 0

View file

@ -27,5 +27,5 @@
# This must also serve as a shell script, so do not add spaces around the
# `=' signs.
VERSION=3.1.5-pws-25
VERSION_DATE='July 3, 1999'
VERSION=3.1.6-test-1
VERSION_DATE='July 9, 1999'

View file

@ -74,11 +74,12 @@ is evaluated. Note the precedence of the bitwise AND, OR,
and XOR operators.
An expression of the form `tt(#\)var(x)' where var(x) is any character
gives the ascii value of this character and an expression of the form
`tt(#)var(foo)' gives the ascii value of the first character of the value
of the parameter var(foo). Note that this is different from the expression
`tt($#)var(foo)', a standard parameter substitution which gives the length
of the parameter var(foo).
sequence such as `tt(a)', `tt(^A)', or `tt(\M-\C-x)' gives the ascii
value of this character and an expression of the form `tt(#)var(foo)'
gives the ascii value of the first character of the value of the
parameter var(foo). Note that this is different from the expression
`tt($#)var(foo)', a standard parameter substitution which gives the
length of the parameter var(foo).
Named parameters and subscripted arrays can be referenced by name within an
arithmetic expression without using the parameter expansion syntax. For

View file

@ -44,7 +44,7 @@ This command only expands parameters. A zero exit code is returned.
findex(alias)
cindex(aliases, defining)
cindex(aliases, listing)
item(tt(alias) [ tt(-gmrL) ] [ var(name)[tt(=)var(value)] ... ])(
item(tt(alias) [ {tt(PLUS()|tt(-))}tt(gmrL) ] [ var(name)[tt(=)var(value)] ... ])(
For each var(name) with a corresponding var(value), define an alias
with that value. A trailing space in var(value) causes the next word
to be checked for alias expansion. If the tt(-g) flag is present,
@ -58,7 +58,9 @@ are taken as patterns (they should be quoted to preserve them from being
interpreted as glob patterns), and the aliases matching these patterns
are printed. When printing aliases and the tt(-g) or tt(-r) flags
are present, then restrict the printing to global or regular
aliases, respectively.
aliases, respectively. Using `tt(PLUS())' instead of `tt(-)', or ending
the option list with a single `tt(PLUS())', prevents the values of the
aliases from being printed.
If the tt(-L) flag is present, then print each
alias in a manner suitable for putting in a startup script. The exit
@ -550,7 +552,7 @@ If the tt(PUSHD_MINUS) option is set, the meanings of `tt(PLUS())' and
`tt(-)' in this context are swapped.
)
findex(print)
item(tt(print) [ tt(-nrslzpNDPoOicm) ] [ tt(-u)var(n) ] [ tt(-R) [ tt(-en) ]] [ var(arg) ... ])(
item(tt(print) [ tt(-bnrslzpNDPoOicm) ] [ tt(-u)var(n) ] [ tt(-R) [ tt(-en) ]] [ var(arg) ... ])(
With no flags or with flag `tt(-)', the arguments are printed on
the standard output as described by tt(echo), with the following differences:
the escape sequence `tt(\M-)var(x)' metafies the character
@ -570,6 +572,13 @@ unless the tt(-e) flag is given. The tt(-n) flag suppresses the trailing
newline. Only the tt(-e) and tt(-n) flags are recognized after
tt(-R); all other arguments and options are printed.
)
item(tt(-b))(
Recognize all the escape sequences defined for the tt(bindkey) command,
see
ifzman(zmanref(zshmodules))\
ifnzman(noderef(The zle Module))\
.
)
item(tt(-m))(
Take the first argument as a pattern (should be quoted), and remove
it from the argument list together with subsequent arguments that
@ -917,15 +926,18 @@ ifzman(`Local Parameters' in zmanref(zshparam))\
ifnzman(noderef(Local Parameters))\
. Local parameters are not exported unless tt(ALL_EXPORT) is set, in
which case the parameter is exported em(only) when var(name) does not
already appear in the environment.
already exist. The same rules apply to special shell parameters, which
retain their special attributes when made local.
For each var(name)tt(=)var(value) assignment, the parameter
var(name) set to var(value). Note that arrays currently cannot be
assigned in tt(typeset) expressions; scalars and integers only.
For each remaining var(name) that refers to a parameter that is set,
the name and value of the parameter are printed in the form of an
assignment. Nothing is printed for newly-created parameters.
For each remaining var(name) that refers to a parameter that is set, the
name and value of the parameter are printed in the form of an assignment.
Nothing is printed for newly-created parameters, or if any attribute flags
listed below are given. Using `tt(PLUS())' instead of minus to introduce
an attribute turns it off.
If the tt(-T) option is given, exactly two (or zero) var(name)
arguments must be present. They represent a scalar and an array (in
@ -951,13 +963,16 @@ has no effect when listing existing parameters, nor does the flag tt(+g)
have any effect.
If no var(name) is present, the names and values of all parameters are
printed. In this case the attribute flags restrict the display to
only those parameters that have the specified attributes. Using
`tt(PLUS())' rather than `tt(-)' to introduce the flag causes the
attribute to be turned off, and suppresses printing of the names and
values. If only the tt(-m) flag is given the arguments are taken as
patterns (should be quoted) and all parameters (or functions with the
tt(-f) flag) with matching names are printed.
printed. In this case the attribute flags restrict the display to only
those parameters that have the specified attributes, and using `tt(PLUS())'
rather than `tt(-)' to introduce the flag suppresses printing of the values
of parameters when there is no parameter name. Also, if the option list
ends with `tt(PLUS())', values will not be printed. If only the tt(-m)
flag is given the arguments are taken as patterns (should be quoted) and
all parameters (or functions with the tt(-f) flag) with matching names are
printed. If no attribute flags and no tt(-m) flag is present, the
parameter names will be preceded by a list of any attributes (tt(array),
tt(association), tt(exported), tt(integer), tt(readonly)).
The following attribute flags may be specified:

View file

@ -17,6 +17,7 @@ menu(Initialization)
menu(Control Functions)
menu(Completion Functions)
menu(Completion Directories)
menu(Bindable Commands)
endmenu()
texinode(Initialization)(Control Functions)()(Completion System)
@ -248,6 +249,11 @@ of the completer functions to decide if other completers should be
called. If the return value is zero, no other completers are tried and the
tt(_main_complete) function returns.
The widget function tt(_main_complete) also uses the configuration key
tt(last_prompt). If this is set to tt(always), the cursor is moved up
to the last prompt after printing a list of matches even if a numeric
argument was given.
The following completer functions are contained in the distribution (users
may write their own):
@ -578,7 +584,10 @@ it is set to tt(never), this will not be done (the behaviour without the
tt(_oldlist) completer). If it is unset, or any other value, then the
existing list of completions will be displayed if it is not already;
otherwise, the standard completion list will be generated: this is the
default behaviour of tt(_oldlist).
default behaviour of tt(_oldlist). However, if there is an old list
and this key contains the name of the completer function that
generated the list, then the old list will be used even if it was
generated by a widget which does not listing.
For example, suppose you type tt(^Xc) to use the tt(_correct_word)
widget, which generates a list of corrections for the word under the
@ -586,6 +595,14 @@ cursor. Usually, typing tt(^D) would generate a standard list of
completions for the word on the command line, and show that. With
tt(_oldlist), it will instead show the list of corrections already
generated.
As another example consider the tt(_match) completer: with the
tt(match_insert) key set to tt(unambig) it inserts only an
unambiguous prefix string if there is any. But since this may remove
parts of the original pattern, attempting completion again may result
in more matches than on the first attempt. But by using the
tt(_oldlist) completer and setting this key to tt(_match), the list of
matches generated on the first attempt will be used again.
)
item(tt(oldlist_menu))(
Controls how menu completion behaves when a completion has already been
@ -769,7 +786,7 @@ on words starting with two hyphens.
)
enditem()
texinode(Completion Directories)()(Completion Functions)(Completion System)
texinode(Completion Directories)(Bindable Commands)(Completion Functions)(Completion System)
sect(Completion Directories)
In the source distribution, the files are contained in various
@ -802,3 +819,63 @@ Functions which implement special types of completion to be bound to
keystrokes rather than called by context.
)
enditem()
texinode(Bindable Commands)()(Completion Directories)(Completion System)
sect(Bindable Commands)
In addition to the context-dependent completions provided, which are
expected to work in an intuitively obvious way, there are a few widgets
implementing special behaviour which can be bound separately to keys. The
following is a list of these and their default bindings.
startitem()
item(tt(_correct_filename (^XC)))(
Correct the filename path at the cursor position. Allows up to six errors
in the name. Can also be correctly called with an argument to correct
a filepath, independently of zle.
)
item(tt(_correct_word) (^Xc))(
Performs correction of the current argument using the usual contextual
completions as possible choices.
)
item(tt(_expand_word (^Xe)))(
Performs expansion on the current word: equivalent to the standard
tt(expand-word) command, but using all the `tt(expand_*)' configuration
keys described previously. In addition, each such key can be overridden by
a key starting with the string `tt(expandword_)'; for example, the
tt(expandword_substitute) key if defined overrides the
tt(expand_substitute) key.
)
item(tt(_history_complete_word) (\e/))(
Complete words from the shell's command history.
)
item(tt(_most_recent_file (^Xm)))(
Complete the name of the most recently modified file matching the pattern
on the command line (which may be blank). If given a numeric argument
var(N), complete the var(N)th most recently modified file. Note the
completion, if any, is always unique.
)
item(tt(_read_comp (^X^R)))(
Prompt the user for a string, and use that to perform completion on the
current word. There are two possibilities for the string. First, it can
be a set of words beginning `tt(_)', for example `tt(_files -/)', in which
case the function with any arguments will be called to generate the
completions. Unambiguous parts of the function name will be completed
automatically (normal completion is not available at this point) until a
space is typed.
Otherwise, any other string, for example `tt(-b)', will be passed as
arguments to tt(compgen) and should hence be a set of flags specifying the
type of completion.
A very restricted set of editing commands is available when reading the
string: `tt(DEL)' and `tt(^H)' delete the last character; `tt(^U)' deletes
the line, and `tt(^C)' and `tt(^G)' abort the function, while `tt(RET)'
accepts the completion. Note the string is used verbatim as a command
line, so arguments must be quoted in accordance with standard shell rules.
Once a string has been read, the next call to tt(_read_comp) will use the
existing string instead of reading a new one. To force a new string to be
read, call tt(_read_comp) with a numeric argument.
)
enditem()

View file

@ -620,7 +620,7 @@ array. If tt(words) contains no word matching var(end-pat), the
testing and modification is performed as if it were not given.
)
item(tt(-q))(
If the cursor is currently inside single or double quotes, the word
The word
currently being completed is split in separate words at the spaces. The
resulting words are stored in the tt(words) array, and tt(PREFIX),
tt(SUFFIX), tt(QIPREFIX), and tt(QISUFFIX) are modified to reflect the

View file

@ -248,6 +248,9 @@ reference on the command line, then they refer to the previous command.
The character sequence `tt(^)var(foo)tt(^)var(bar)'
repeats the last command, replacing the string var(foo) with var(bar).
More precisely, the sequence `tt(^)var(foo)tt(^)var(bar)tt(^)' is
synonymous with `tt(!!:s)tt(^)var(foo)tt(^)var(bar)tt(^)', hence other
modifiers may follow the final `tt(^)'.
If the shell encounters the character sequence `tt(!")'
in the input, the history mechanism is temporarily disabled until
@ -855,10 +858,10 @@ texinode(Command Substitution)(Arithmetic Expansion)(Parameter Expansion)(Expans
sect(Command Substitution)
cindex(command substitution)
cindex(substitution, command)
A command enclosed in parentheses
preceded by a dollar sign, like `tt($LPAR())...tt(RPAR())', or quoted with grave
accents, like `tt(`)...tt(`)', is replaced with its standard output, with any
trailing newlines deleted.
A command enclosed in parentheses preceded by a dollar sign, like
`tt($LPAR())...tt(RPAR())', or quoted with grave
accents, like `tt(`)...tt(`)', is replaced with its standard output, with
any trailing newlines deleted.
If the substitution is not enclosed in double quotes, the
output is broken into words using the tt(IFS) parameter.
vindex(IFS, use of)

View file

@ -5,6 +5,12 @@ The tt(complist) module offers two extensions to completion listings:
the ability to highlight matches in such a list and a different
style of menu-completion.
Whenever one of the parameters tt(ZLS_COLORS) or tt(ZLS_COLOURS) is set
and the tt(complist) module is loaded or linked into the shell,
completion lists will be colored. Note, however, that tt(complist) will
not automatically be loaded if it is not linked in: on systems with
dynamic loading, `tt(zmodload complist)' is required.
subsect(Parameters)
For both extensions one of the parameters tt(ZLS_COLORS) or tt(ZLS_COLOURS)
must be set, even if the value is empty (which uses all the default values
@ -12,12 +18,12 @@ given below). These describe how matches are highlighted. The format of the
value of these parameters is the same as used by the GNU version of the
tt(ls) command: a colon-separated list of specifications of the form
`var(name)=var(value)'. The var(name) may be one of the following strings,
most of which specify file-types for which the var(value) will be used. The
most of which specify file types for which the var(value) will be used. The
strings and their default values are:
startitem()
item(tt(no 0))(
for normal text (not the string displayed for a match)
for normal text (i.e. when displaying something other than a matched file)
)
item(tt(fi 0))(
for regular files
@ -44,7 +50,7 @@ item(tt(ex 35))(
for executable files
)
item(tt(mi) var(none))(
for names not naming a file (default is the value defined for tt(fi))
for non-existent file (default is the value defined for tt(fi))
)
item(tt(lc \e[))(
for the left code (see below)
@ -71,46 +77,51 @@ The default values are ISO 6429 (ANSI) compliant and can be used on
vt100 compatible terminals such as tt(xterm)s. On monochrome terminals
the default values will have no visual effect.
Whenever one of the parameters tt(ZLS_COLORS) or tt(ZLS_COLOURS) is set
and the tt(complist) module is loaded or linked into the shell,
completion lists will be colored.
subsect(Menu selection)
The tt(complist) module also offers a different style of selecting
matches from a list called menu-selection. It can be invoked directly by
The tt(complist) module also offers an alternative style of selecting
matches from a list, called menu-selection. It can be invoked directly by
the widget tt(menu-select) defined by the module. Alternatively,
the parameter tt(SELECTMIN) can be set to an integer giving the minimum
number of matches which must be present before menu selection is
the parameter tt(SELECTMIN) can be set to an integer, which give the
minimum number of matches that must be present before menu selection is
automatically turned on. This second method requires that menu completion
be started, either directly from a widget such as tt(menu-complete), or due
to one of the options tt(MENU_COMPLETE) or tt(AUTO_MENU) being set. If
tt(SELECTMIN) is set, but is 0, 1 or empty, menu selection will always be
started during menu completion if the completion is ambiguous.
started during an ambiguous menu completion.
After menu-selection is started, the matches will be listed. The
matches to insert into the command line can be selected from this
list. In the list one match is highlighted using the value for tt(ma)
from the tt(ZLS_COLORS) or tt(ZLS_COLOURS) parameter. The default
value for this it `tt(7)' which forces the selected match to be
highlighted using standout mode on a vt100 compatible terminal. If
highlighted using standout mode on a vt100-compatible terminal. If
neither tt(ZLS_COLORS) nor tt(ZLS_COLOURS) is set, the same terminal
control sequence is used as for the `tt(%S)' escape in prompts.
control sequence as for the `tt(%S)' escape in prompts is used.
Selecting matches is done by moving the mark around using the zle movement
functions. The zle functions tt(send-break) and tt(accept-line) can be used
to leave menu-selection, leaving the match currently inserted into the line
in place. In the case of tt(accept-line), the match currently inserted
will be accepted and the immediatly trying completion again will
complete after it. Using tt(send-break) leaves menu-selection and
continues with normal menu-completion. The functions tt(accept-and-hold) and
in place. In the case of tt(accept-line), the match currently inserted
will be accepted and a new completion may be attempted.
Using tt(send-break) leaves menu-selection and continues with normal
menu-completion. The functions tt(accept-and-hold) and
tt(accept-and-menu-complete) can be used to accept the match currently
inserted and continue inserting matches after that. Matches inserted this
way can be removed by invoking the tt(undo) function. Keys bound to one of
inserted and continue inserting matches from the same list. The
function tt(accept-and-infer-next-history) accepts the current match and
then tries completion with menu-selection again. In the case of
files this allows one to select a directory and immediately attempt to
complete files in it. Matches inserted in one of these ways can be removed
by invoking the tt(undo) function. Keys bound to one of
the completion functions will cycle to the next (or, in case of
tt(reverse-menu-complete), the previous) match, and the tt(redisplay) and
tt(clear-screen) functions work as usual without leaving
menu-selection. Any other zle function leaves menu-selection and executes
that function.
menu-selection.
Any other zle function leaves menu-selection and executes that function.
It is possible to make widgets in the above list do the same by using the
form of the widget with a `tt(.)' in front. For example, the widget
`tt(.accept-line)' has the effect of leaving menu selection and accepting
the entire command line.
During this selection the widget uses the keymap tt(menuselect). Any
key that is not defined in this keymap or that is bound to
@ -124,6 +135,6 @@ ifnzman(noderef(The zle Module))\
). For example, to make the return key leave menu-selection and
continue with normal menu-completion one can call
indent(tt(bindkey -M menuselect '^J' send-break))
indent(tt(bindkey -M menuselect '^M' send-break))
after loading the tt(complist) module.

View file

@ -177,7 +177,8 @@ xitem(tt(zle) tt(-D) var(widget) ...)
xitem(tt(zle) tt(-A) var(old-widget) var(new-widget))
xitem(tt(zle) tt(-N) var(widget) [ var(function) ])
xitem(tt(zle) tt(-C) var(widget) var(completion-widget) var(function))
xitem(tt(zle) tt(-R) [ var(display-string) ])
xitem(tt(zle) tt(-R) [ tt(-c) ] [ var(display-string) ] [ var(string) ... ])
xitem(tt(zle) tt(-U) var(string))
item(tt(zle) var(widget) tt([ -n) var(num) tt(]) tt([ -N ]) var(args) ...)(
The tt(zle) builtin performs a number of different actions concerning
ZLE. Which operation it performs depends on its options:
@ -227,11 +228,21 @@ ifzman(zmanref(zshcompwid))\
ifnzman(noderef(Completion Widgets))\
.
)
item(tt(-R) [ var(display-string) ])(
item(tt(-R) [ tt(-c) ] [ var(display-string) ] [ var(string) ... ])(
Redisplay the command line; this is to be called from within a user-defined
widget to allow changes to become visible. If a var(display-string) is
given, this is shown in the status line (immediately below the line being
edited).
given and not empty, this is shown in the status line (immediately
below the line being edited).
If the optional var(string)s are given they are listed below the
prompt in the same way as completion lists are printed. If no
var(string)s are given but the tt(-c) option is used such a list is
cleared.
)
item(tt(-U) var(string))(
This puts the characters in the var(string) in the input queue of
ZLE. After the widget currently executed finishes ZLE will behave as
if the characters in the var(string) were typed by the user.
)
item(var(widget) tt([ -n) var(num) tt(]) tt([ -N ]) var(args) ...)(
Invoke the specified widget. This can only be done when ZLE is

View file

@ -108,14 +108,15 @@ be a list of flags. The flags currently understood are:
startitem()
item(tt(e))(
this option has no effect and retained for backward compatibility only.
This option has no effect and retained for backward compatibility only.
)
item(tt(w))(
if the parameter subscripted is a scalar than this flag makes
subscription work on a per-word basis instead of characters.
If the parameter subscripted is a scalar than this flag makes
subscripting work on words instead of characters. The default word
separator is whitespace.
)
item(tt(s:)var(string)tt(:))(
this gives the var(string) that separates words (for use with the
This gives the var(string) that separates words (for use with the
tt(w) flag).
)
item(tt(p))(
@ -123,21 +124,22 @@ Recognize the same escape sequences as the tt(print) builtin in
the string argument of a subsequent `tt(s)' flag.
)
item(tt(f))(
if the parameter subscripted is a scalar than this flag makes
subscription work on a per-line basis instead of characters.
This is a shorthand for `tt(pws:\n:)'.
If the parameter subscripted is a scalar than this flag makes
subscripting work on lines instead of characters, i.e. with elements
separated by newlines. This is a shorthand for `tt(pws:\n:)'.
)
item(tt(r))(
if this flag is given the var(exp) is taken as a pattern and the
result is the first matching array element, substring or word (if the
parameter is an array, if it is a scalar, or if it is a scalar and the
`tt(w)' flag is given, respectively); note that this is like giving a
number: `tt($foo[(r))var(??)tt(,3])' and `tt($foo[(r))var(??)tt(,(r)f*])' work.
If the parameter is an associative array, only the value part of each pair
is compared to the pattern.
Reverse subscripting: if this flag is given, the var(exp) is taken as a
pattern and the result is the first matching array element, substring or
word (if the parameter is an array, if it is a scalar, or if it is a scalar
and the `tt(w)' flag is given, respectively). The subscript used is the
number of the matching element, so that pairs of subscripts such as
`tt($foo[(r))var(??)tt(,3])' and `tt($foo[(r))var(??)tt(,(r)f*])'
are possible. If the parameter is an associative array, only the value part
of each pair is compared to the pattern.
)
item(tt(R))(
like `tt(r)', but gives the last match. For associative arrays, gives
Like `tt(r)', but gives the last match. For associative arrays, gives
all possible matches.
)
item(tt(i))(
@ -188,8 +190,7 @@ Shell function executions delimit scopes for shell parameters.
(Parameters are dynamically scoped.) The tt(typeset) builtin, and its
alternative forms tt(declare), tt(integer), tt(local) and tt(readonly)
(but not tt(export)), can be used to declare a parameter as being local
to the innermost scope. Note that em(special) parameters cannot be made
local.
to the innermost scope.
When a parameter is read or assigned to, the
innermost existing parameter of that name is used. (That is, the
@ -200,6 +201,23 @@ causes it to be created in the em(outer)most scope.
Local parameters disappear when their scope ends.
tt(unset) can be used to delete a parameter while it is still in scope;
any outer parameter of the same name remains hidden.
Special parameters may also be made local; they retain their special
attributes. This may have unexpected effects. Firstly, there is no
default value, so if there is no assigment at the point the variable is
made local, it will be set to an empty value (or zero in the case of
integers). Secondly, special parameters which are made local will not be
exported (as with other parameters), so that the global value of the
parameter remains present in the environment if it is already there. This
should be particularly noted in the case of tt(PATH): the shell will use
the local version of tt(PATH) for finding programmes, but programmes using
the shell's environment will inherit the global version. The following:
example(typeset PATH=/new/directory:$PATH)
is valid for temporarily allowing the shell to find the programs in
tt(/new/directory) inside a function.
texinode(Parameters Set By The Shell)(Parameters Used By The Shell)(Local Parameters)(Parameters)
sect(Parameters Set By The Shell)
The following parameters are automatically set by the shell:
@ -715,12 +733,12 @@ set up the terminal before executing the command. The modes apply only to the
command, and are reset when it finishes or is suspended. If the command is
suspended and continued later with the tt(fg) or tt(wait) builtins it will
see the modes specified by tt(STTY), as if it were not suspended. This
(intentionally) does not apply if the command is continued via `tt(kill -CONT)'.
tt(STTY) is ignored if the command is run in the background, or if it is in the
environment of the shell but not explicitly assigned to in the input line. This
avoids running stty at every external command by accidentally exporting it.
Also note that tt(STTY) should not be used for window size specifications; these
will not be local to the command.
(intentionally) does not apply if the command is continued via `tt(kill
-CONT)'. tt(STTY) is ignored if the command is run in the background, or
if it is in the environment of the shell but not explicitly assigned to in
the input line. This avoids running stty at every external command by
accidentally exporting it. Also note that tt(STTY) should not be used for
window size specifications; these will not be local to the command.
)
vindex(TERM)
item(tt(TERM) <S>)(

View file

@ -42,21 +42,14 @@ A `tt(RPAR())'.
)
xitem(tt(%d))
item(tt(%/))(
Present working directory (tt($PWD)).
Present working directory (tt($PWD)). If an integer follows the `tt(%)',
it specifies a number of trailing components of tt($PWD) to show; zero
means the whole path.
)
item(tt(%~))(
tt($PWD).
If it has a named directory as its prefix, that part is replaced
by a `tt(~)' followed by the name of the directory.
If it starts with tt($HOME), that part is
replaced by a `tt(~)'.
)
xitem(tt(%c))
xitem(tt(%.))
item(tt(%C))(
Trailing component of tt($PWD).
An integer may follow the `tt(%)' to get more than one component.
Unless `tt(%C)' is used, tilde contraction is performed first.
As tt(%d) and tt(%/), but if tt($PWD) has a named directory as its prefix,
that part is replaced by a `tt(~)' followed by the name of the directory.
If it starts with tt($HOME), that part is replaced by a `tt(~)'.
)
xitem(tt(%h))
item(tt(%!))(
@ -98,7 +91,9 @@ tt($USERNAME).
item(tt(%N))(
The name of the script, sourced file, or shell function that zsh is
currently executing, whichever was started most recently. If there is
none, this is equivalent to the parameter tt($0).
none, this is equivalent to the parameter tt($0). An integer may follow
the `tt(%)' to specify a number of trailing path components to show; zero
means the full path.
)
item(tt(%i))(
The line number currently being executed in the script, sourced file, or
@ -235,4 +230,14 @@ 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.
)
xitem(tt(%c))
xitem(tt(%.))
item(tt(%C))(
Trailing component of tt($PWD).
An integer may follow the `tt(%)' to get more than one component.
Unless `tt(%C)' is used, tilde contraction is performed first. These are
deprecated as tt(%c) and tt(%C) are equivalent to tt(%1~) and tt(%1/),
respectively, while explicit positive integers have the same effect as for
the latter two sequences.
)
enditem()

View file

@ -2,9 +2,20 @@
KNOWN BUGS IN ZSH
-----------------
On some terminals, display of lines with exactly 80 characters is
problematic. zsh assumes that the terminal does not print an extra
newline in this case, but some terminals (e.g. aixterm) do.
------------------------------------------------------------------------
Completion has a habit of doing the wrong thing after a
backslash/newline.
When interrupting code like the following with ^C:
while true; do
sh -c '...'
done
if the `sh' is executing, zsh does not know that the sh received a ^C and
continues with the next iteration. This happens for any program which
handles the interrupt, then exits after tidying up; it does not happen for
zsh, which exits directly from the signal handler. The workaround is to
use ^Z which forks the shell and makes the loop a separate job, then kill
the suspended loop.
------------------------------------------------------------------------
If you suspend "man", zle seems to get into cooked mode. It works ok
for plain "less".
@ -26,12 +37,6 @@ Then if you suspend
% foo less something
from zsh/bash, zle/readline gets into cooked mode.
------------------------------------------------------------------------
% zsh -c 'cat a_long_file | less ; :'
can be interrupted with ^C. The prompt comes back and less is orphaned.
If you go to the end of the file with less and cat terminates, ^C
will not terminate less. The `; :' after less forces zsh to fork before
executing less.
------------------------------------------------------------------------
The pattern %?* matches names beginning with %? instead of names with at
least two characters beginning with %. This is a hack to allow %?foo job
substitution without quoting. This behaviour is incompatible with sh

View file

@ -4,8 +4,8 @@ ZSH CONTRIBUTORS
Zsh was originally written by Paul Falstad <pf@zsh.org>. Zsh is
now maintained by the members of the zsh-workers mailing list
<zsh-workers@math.gatech.edu>. The development is currently coordinated
by Andrew Main (Zefram) <zefram@zsh.org>.
<zsh-workers@sunsite.auc.dk>. The development is currently coordinated
by Peter Stephenson <pws@zsh.org>.
This file credits only the major contributors to the current release.
See the ChangeLog files for a complete list of people who have submitted
@ -15,6 +15,40 @@ to be currently accurate. If you feel that you or someone else have
been unfairly omitted from this list please mail the current maintainer
at <coordinator@zsh.org>.
Version 3.1.6
-------------
* Sven Wishnowsky <wischnow@informatik.hu-berlin.de>: completion code,
major rewrite and enhancements, including matching control, completion
widgets and function system, complist module; zle code additions; job
control code changes; parameters code changes; parameter module;
additional autoloading code; general code changes for extra efficiency;
subscripting and ordering of globbing lists.
* Peter Stephenson <pws@ibmth.df.unipi.it>: zftp and mapfile modules and
zf* functions; local parameters and typeset changes; changes in autoconf
system; case-independent and approximate pattern matching; various
options; a few completion modules; some zle changes; FAQ.
* Bart Schaefer <schaefer@candle.brasslantern.com>: associative array
implementation; other parameter changes; keeping track of missing
patches; function autoloading changes.
* Wayne Davison <wayne@clari.net>: History code novelties and improvements
with new options.
* Geoff Wing <mason@primenet.com.au>: Zle display code fixes, mailing
list and patch archive.
* Zoltán Hidvégi <hzoli@cs.elte.hu>: AIX dynamic loading code.
* Matt Armstrong: cygwin configuration changes.
Other improvements, bug fixes and design suggestions from all the above
plus Andrej Borsenkow, Oliver Kiddle, Tanaka Akira, Naoki Wakamatsu, Tatuso
Furukawa, Ville Herva, Will Day, Lehti Rahmi, Larry P. Schrof, Helmut
Jarausch, Phil Pennock, Wilfredo Sanchez, Bruce Stephens.
Version 3.0
-----------

View file

@ -87,6 +87,9 @@ SGI: IRIX 5.1.1.1, 5.2, 5.3, 6.2, 6.3, 6.5
full optimization (cc -O3 -OPT:Olimit=0) causes problems.
Sun: SunOS 4.1.*
Dynamic loading does not work under SunOS 4.1. Sometimes,
you may need to turn it off explicitly with --disable-dynamic.
Under 4.1.3 if yellow pages is used, username completion may cause
segmentation violation. This is a bug in the shared library not
in zsh. Some libc.so.1.9.* has this bug (it fails in yp_all).

View file

@ -2,6 +2,92 @@
CHANGES FROM PREVIOUS VERSIONS OF ZSH
-------------------------------------
New features in zsh version 3.1.6 (beta version)
------------------------------------------------
New completion system via shell functions; massive degree of
programmability and configurability:
- ready-made function suite to use, see zshcompsys(1)
- approximate completion and spelling correction via completion
- control over matching for case-independence, partial word completion, etc.
- menu selection: choose a completion by moving the cursor
- coloured completion lists
Other editing changes:
- enhancements to function/editing interface: new parameters, numeric
arguments, string argument passing, reading keys from widgets.
- the old history-search-{back,for}ward behaviour and bindings have
returned (up to minor details).
- BASH_AUTO_LIST option to show completion list only on second key press.
- the ZBEEP parameter gives a string to output instead of beeping,
allowing you to have a visual bell.
History changes: new options HIST_NO_FUNCTIONS, HIST_EXPIRE_DUPS_FIRST,
HIST_FIND_NO_DUPS, HIST_IGNORE_ALL_DUPS, INC_APPEND_HISTORY,
HIST_SAVE_NO_DUPS, SHARE_HISTORY, allow better control of when history is
read and written and how duplicates are handled.
Associative arrays plus enhanced parameter substitutions to retrieve keys
and values.
Globbing changes:
- Case-insensitive and approximate globbing.
- Ordering and indexing of globbing matches, e.g. *(om[1]) picks
most recently modified file.
New loadable modules:
- zftp, plus associated function suite, for turning your zsh session
into an FTP session too
- parameter, for examining and altering shell hash tables via an
associative array interface.
- mapfile, for reading and writing external files via an associative
array interface.
Debugging and prompt enhancements:
- LINENO is now very much more useful in scripts and functions and has
corresponding prompt escape %i
- $PS4 can contain %i as well as %N for script or function names
(default PS4 changed), also %_ for current shell structure executing;
- Prompt truncation %<...< is now more flexible: it applies to a
whole section of the prompt, not just one escape. You need to put
%<< after the truncated escape to get the old behaviour.
- %20(l.yes.no) in prompts prints yes if at least 20 characters have
been output, else no (e.g. for outputting extra newlines).
Parameter and expansion changes
- typeset -t MYPATH mypath creates tied path/PATH-like variables
- typeset -g allows operations on parameters without making them local
- New expansions
- ${(t)param} prints type information for $param
- ${(P)param} treats value of $param as the name of a param to
substitute
- ${foo:q} can quote replaced parameter text from expansion
- ${foo/old/new} substitution, like bash; also (S) flag for shortest
match
- $foo[(b.2.i)bar] starts searching $foo for bar starting at 2nd match
- more logical behaviour of nested parameters, now properly documented
- quote only nested expansion, e.g. ${(f)"$(<file)"} reads complete
`file', then splits lines into array.
Builtin and function changes
- stat module: `stat -H hash foo' gives you e.g. $hash[mtime]
- autoload -U autoloads functions without alias expansion.
Other new options:
- LOCAL_TRAPS allows signal traps to be local to functions (as in ksh).
- NO_RCS can now be turned on at any point in initialization files.
- NO_GLOBAL_RCS can force /etc/z* files after /etc/zshenv to be skipped.
(Please don't use this as an excuse to stuff more into /etc/zshenv!)
- existing MAGIC_EQUAL_SUBST option is more useful; any argument containing
...=~...:~... will perform filename expansion on the ~.
Configuration changes:
- Large file and 64-bit integers on 32-bit machines supported where
provided by OS.
- generation of signal names should be more reliable
- Customizable installation of shell functions from distribution.
New features in zsh version 3.1 (beta version)
----------------------------------------------

View file

@ -48,40 +48,7 @@ install: install.fns
uninstall: uninstall.fns
# install functions, including those in subdirectories, creating
# install directory if necessary
install.fns:
if test x$(fndir) != x && test x$(fndir) != xno; then \
$(sdir_top)/mkinstalldirs $(fndir) || exit 1; \
for file in $(FUNCTIONS_INSTALL); do \
if test -f $$file; then \
if test x$(FUNCTIONS_SUBDIRS) != x -a \
x$(FUNCTIONS_SUBDIRS) != xno; then \
subdir="`echo $$file | sed -e 's%/.*%%'`"; \
$(sdir_top)/mkinstalldirs $(fndir)/$$subdir || exit 1; \
$(INSTALL_DATA) $$file $(fndir)/$$subdir || exit 1; \
else \
$(INSTALL_DATA) $$file $(fndir) || exit 1; \
fi; \
fi; \
done; \
fi; \
exit 0
uninstall.fns:
if test x$(fndir) != x && test x$(fndir) != xno; then \
for file in $(FUNCTIONS_INSTALL); do \
if test -f $$file; then \
if test x$(FUNCTIONS_SUBDIRS) != x -a \
x$(FUNCTIONS_SUBDIRS) != xno; then \
rm -f $(fndir)/$$file; \
else \
rm -f "$(fndir)/`echo $$file | sed -e 's%^.*/%%'`"; \
fi; \
fi; \
done; \
fi; \
exit 0
@FUNCINST_MK@
# ========== DEPENDENCIES FOR CLEANUP ==========

3
Functions/Zle/.distfiles Normal file
View file

@ -0,0 +1,3 @@
DISTFILES_SRC='
.distfiles incremental-complete-word insert-files
'

View file

@ -0,0 +1,89 @@
# incremental-complete-word() {
# Autoload this function, run `zle -N <func-name>' and bind <func-name>
# to a key.
# This allows incremental completion of a word. After starting this
# command, a list of completion choices is shown after every character you
# type, which you can delete with ^h or DEL. RET will accept the
# completion so far. You can hit TAB to do normal completion and ^g to
# abort back to the state when you started.
#
# Completion keys:
# incremental_prompt Prompt to show in status line during icompletion;
# the sequence `%u' is replaced by the unambiguous
# part of all matches if there is any and it is
# different from the word on the line
# incremental_stop Pattern matching keys which will cause icompletion
# to stop and the key to be re-executed
# incremental_break Pattern matching keys which will cause icompletion
# to stop and the key to be discarded
# incremental_completer Set of completers, like the `completer' key
# incremental_list If set to a non-empty string, the matches will be
# listed on every key-press
emulate -L zsh
unsetopt autolist menucomplete automenu # doesn't work well
local key lbuf="$LBUFFER" rbuf="$RBUFFER" pmpt word lastl lastr wid twid
[[ -n "$compconfig[incremental_completer]" ]] &&
set ${(s.:.)compconfig[incremental_completer]}
pmpt="${compconfig[incremental_prompt]-incremental completion...}"
if [[ -n "$compconfig[incremental_list]" ]]; then
wid=list-choices
else
wid=complete-word
fi
zle $wid "$@"
LBUFFER="$lbuf"
RBUFFER="$rbuf"
if [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
word=''
else
word="${_lastcomp[unambiguous]}"
fi
zle -R "${pmpt//\\%u/$word}"
read -k key
while [[ '#key' -ne '#\\r' && '#key' -ne '#\\n' &&
'#key' -ne '#\\C-g' ]]; do
twid=$wid
if [[ "$key" = ${~compconfig[incremental_stop]} ]]; then
zle -U "$key"
return
elif [[ "$key" = ${~compconfig[incremental_break]} ]]; then
return
elif [[ '#key' -eq '#\\C-h' || '#key' -eq '#\\C-?' ]]; then
[[ $#LBUFFER -gt $#l ]] && LBUFFER="$LBUFFER[1,-2]"
elif [[ '#key' -eq '#\\t' ]]; then
zle complete-word "$@"
lbuf="$LBUFFER"
rbuf="$RBUFFER"
elif [[ '#key' -eq '#\\C-d' ]]; then
twid=list-choices
else
LBUFFER="$LBUFFER$key"
fi
lastl="$LBUFFER"
lastr="$RBUFFER"
zle $twid "$@"
LBUFFER="$lastl"
RBUFFER="$lastr"
if [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
word=''
else
word="${_lastcomp[unambiguous]}"
fi
zle -R "${pmpt//\\%u/$word}"
read -k key
done
if [[ '#key' -eq '#\\C-g' ]]; then
LBUFFER="$lbuf"
RBUFFER="$rbuf"
fi
zle -Rc
# }

View file

@ -0,0 +1,42 @@
# insert-files() {
# Autoload this function, run `zle -N <func-name>' and bind <func-name>
# to a key.
# This function allows you type a file pattern, and see the results of the
# expansion at each step. When you hit return, they will be inserted into
# the command line.
emulate -L zsh
setopt nobadpattern
local key str files
files=( *(N) )
if (( $#files )); then
zle -R "files: ${str}_" "$files[@]"
else
zle -R "files: ${str}_ (failed)"
fi
read -k key
while [[ '#key' -ne '#\\r' && '#key' -ne '#\\n' &&
'#key' -ne '#\\C-g' ]]; do
if [[ '#key' -eq '#\\C-h' || '#key' -eq '#\\C-?' ]]; then
[[ -n "$str" ]] && str="$str[1,-2]"
else
str="$str$key"
fi
eval "files=( \${~str}*(N) )"
if (( $#files )); then
zle -R "files: ${str}_" "$files[@]"
else
zle -R "files: ${str}_ (failed)"
fi
read -k key
done
zle -Rc
if [[ '#key' -ne '#\\C-g' && $#files -gt 0 ]]; then
[[ "$LBUFFER[-1]" = ' ' ]] || files=('' "$files[@]")
LBUFFER="$LBUFFER$files "
fi
# }

82
INSTALL
View file

@ -1,6 +1,15 @@
--------------
INSTALLING ZSH
--------------
++++++++++++++
INSTALLING ZSH
++++++++++++++
This file is divided into two parts: making and installing the shell, and
a description of various additional configuration options. You should
have a look at the items in the second part before following the
instructions in the first.
=====================
MAKING AND INSTALLING
=====================
Check MACHINES File
-------------------
@ -27,15 +36,18 @@ top level Makefile.
Dynamic loading
---------------
Zsh-3.1 has support for dynamically loadable modules. To enable this run
configure with the --enable-dynamic option. Note that dynamic loading
does not work on all systems. On these systems this option will have no
effect, so it is always safe to use --enable-dynamic. When dynamic
loading is enabled, major parts of zsh (including the Zsh Line Editor) are
compiled into modules and not included into the main zsh binary. Zsh
autoloads these modules when they are required. This means that you have
to execute make install.modules before you try the newly compiled zsh
executable.
Zsh-3.1 has support for dynamically loadable modules. This is now enabled
by default; to disable it, run configure with the --disable-dynamic option.
Note that dynamic loading does not work on all systems. On these systems
this option will have no effect. When dynamic loading is enabled, major
parts of zsh (including the Zsh Line Editor) are compiled into modules and
not included into the main zsh binary. Zsh autoloads these modules when
they are required. This means that you have to execute make
install.modules before you try the newly compiled zsh executable, and hence
also the install paths must be correct. The installation path for modules
is EPREFIX/lib/zsh/<zsh-version-number>, where EPREFIX defaults to PREFIX
unless given explicitly, and PREFIX defaults to /usr/local. See the end of
this file for options to configure to change these.
Adding more modules
-------------------
@ -156,6 +168,11 @@ source code in the directory that "configure" is in. For example,
/usr/local/src/zsh-3.0/configure
make
=====================
CONFIGURATION OPTIONS
=====================
Memory Routines
---------------
@ -225,31 +242,44 @@ FUNCTIONS_INSTALL, either when running configure (e.g.
`make install.fns'. It includes a list of files relative to either the
Completion or Functions subdirectories. By default, all the functions for
the Completion system will be installed (see the zshcompsys manual page),
i.e.
FUNCTIONS_INSTALL='Core/* Base/* Builtins/* User/* Commands/*'
plus those provide functions for the line editor, i.e.
FUNCTIONS_INSTALL='Core/* Base/* Builtins/* User/* Commands/* Zle/*'
and if the --enable-dynamic option was given, the functions in
Functions/Zftp, which require the zftp module to be available (see the
zshzftpsys manual page), will be included as well. There are also some
miscellaneous functions with documentation in comments; the complete set
of functions can be installed with
FUNCTIONS_INSTALL='Core/* Base/* Builtins/* User/* Commands/* Misc/* Zftp/*'
FUNCTIONS_INSTALL='Core/* Base/* Builtins/* User/* Commands/* \
Misc/* Zftp/* Zle/*'
Note you should set this by hand to include `Zftp/*' if you have zftp
compiled into a statically linked shell.
You can also set --enable-function-subdirs to allow shell
functions to be installed into subdirectories of the function directory,
i.e. `Core/*' files will be installed into `FNDIR/Core', and so on.
This also initialises $fpath/$FPATH appropriately.
You can also use the configure option --enable-function-subdirs to allow
shell functions to be installed into subdirectories of the function
directory, i.e. `Core/*' files will be installed into `FNDIR/Core', and so
on. This also initialises $fpath/$FPATH appropriately.
On installation, any completion function which already exists but is
different from the new version will be moved to a corresponding place in
FNDIR.old; for example, if a different version of User/_rcs exists when
installing into /usr/local/share/zsh/functions/User, the old one will be
moved into /usr/local/share/zsh/functions.old/User. The installer is
responsible for recovering or deleting old functions which have been moved
in this way. On uninstallation, any newly installed functions (including
those which existed before but were unchanged) will be deleted and the
files in the FNDIR.old hierarchy moved back into FNDIR. To preserve the
entire old hierarchy, you should move or copy it before installation.
Support for large files and integers
------------------------------------
Some 32-bit systems allow special compilation modes to get around the 2GB
file size barrier; the zsh support for this is still experimental, and
feedback is particularly appreciated. The option --enable-lfs turns on the
configure check for support for large files. Not all systems recognize the
test used by zsh (via the getconf command), so flags may need to be set by
hand, but --enable-lfs should be used in any case to compile in the code
for using 64 bit integers. On HP-UX 10.20, zsh has been successfully
compiled with large file support by configuring with
file size barrier. The option --enable-lfs turns on the configure check
for support for large files. This is now enabled by default; use
--disable-lfs to turn it off. Not all systems recognize the test used by
zsh (via the getconf command), so flags may need to be set by hand. On
HP-UX 10.20, zsh has been successfully compiled with large file support by
configuring with
CC="cc -Ae" CPPFLAGS="-D_LARGEFILE_SOURCE -D_FILE64" configure \
--enable-lfs ...
You can also give a value to --enable-lfs, which will be interpreted as the

View file

@ -1,4 +1,5 @@
DISTFILES_SRC='
.distfiles
c2z compctl-examples globtests globtests.ksh lete2ctl
c2z compctl-examples globtests globtests.ksh
job-control-tests lete2ctl
'

31
Misc/job-control-tests Normal file
View file

@ -0,0 +1,31 @@
# These are some tests for the job control code. The code chunks
# have to be run interactively. Some use files in the zsh distribution.
# Try
# ^Z
# fg
if true; then cat Src/builtin.c | less; fi
# Try
# ^Z
# fg
fn() {
if true; then cat Src/builtin.c | less; fi
}
fn
# Try
# ^Z
# fg
# ^C
# then
# ^Z
# bg
# kill
while true; do sed -e 's/foo/bar/' Src/builtin.c >/dev/null; done
# Try
# ^C
# ignoring the error messages from sed.
# ^Z is more of a problem since you have to catch the sed.
while true; do sed -e 's/foo/bar/' non-existent-file >/dev/null; done

View file

@ -2096,9 +2096,7 @@ bin_compset(char *name, char **argv, char *ops, int func)
case 'P': test = CVT_PREPAT; break;
case 's': test = CVT_SUFNUM; break;
case 'S': test = CVT_SUFPAT; break;
case 'q': return !(compquote && *compquote &&
(*compquote == '\'' || *compquote == '"') &&
!set_comp_sepptr());
case 'q': return set_comp_sepptr();
default:
zerrnam(name, "bad option -%c", NULL, argv[0][1]);
return 1;

View file

@ -309,7 +309,7 @@ complistmatches(Hookdef dummy, Chdata dat)
Cexpl *e;
int nlines = 0, ncols, nlist = 0, longest = 1, pnl = 0, opl = 0;
int of = isset(LISTTYPES);
int mc, ml = 0, cc, hasm = 0;
int mc, ml = 0, cc, hasm = 0, cl;
struct listcols col;
if (minfo.asked == 2) {
@ -448,7 +448,12 @@ complistmatches(Hookdef dummy, Chdata dat)
mgtab = (Cmgroup *) zalloc(i * sizeof(Cmgroup));
memset(mgtab, 0, i * sizeof(Cmgroup));
mcols = ncols;
mlines = nlines;
mlines = cl = nlines;
if (cl < 2) {
cl = -1;
if (tccan(TCCLEAREOD))
tcout(TCCLEAREOD);
}
}
/* Now print the matches. */
g = amatches;
@ -456,14 +461,27 @@ complistmatches(Hookdef dummy, Chdata dat)
char **pp = g->ylist;
if ((e = g->expls)) {
int l;
while (*e) {
if ((*e)->count) {
if (pnl) {
putc('\n', shout);
pnl = 0;
ml++;
if (cl >= 0 && --cl <= 1) {
cl = -1;
if (tccan(TCCLEAREOD))
tcout(TCCLEAREOD);
}
}
l = printfmt((*e)->str, (*e)->count, 1);
ml += l;
if (cl >= 0 && (cl -= l) <= 1) {
cl = -1;
if (tccan(TCCLEAREOD))
tcout(TCCLEAREOD);
}
ml += printfmt((*e)->str, (*e)->count, 1);
pnl = 1;
}
e++;
@ -474,6 +492,11 @@ complistmatches(Hookdef dummy, Chdata dat)
putc('\n', shout);
pnl = 0;
ml++;
if (cl >= 0 && --cl <= 1) {
cl = -1;
if (tccan(TCCLEAREOD))
tcout(TCCLEAREOD);
}
}
if (g->flags & CGF_LINES) {
while (*pp) {
@ -504,6 +527,11 @@ complistmatches(Hookdef dummy, Chdata dat)
if (n) {
putc('\n', shout);
ml++;
if (cl >= 0 && --cl <= 1) {
cl = -1;
if (tccan(TCCLEAREOD))
tcout(TCCLEAREOD);
}
}
pp++;
}
@ -517,6 +545,11 @@ complistmatches(Hookdef dummy, Chdata dat)
putc('\n', shout);
pnl = 0;
ml++;
if (cl >= 0 && --cl <= 1) {
cl = -1;
if (tccan(TCCLEAREOD))
tcout(TCCLEAREOD);
}
}
for (p = skipnolist(g->matches); n && nl--;) {
i = ncols;
@ -607,6 +640,11 @@ complistmatches(Hookdef dummy, Chdata dat)
if (n) {
putc('\n', shout);
ml++;
if (cl >= 0 && --cl <= 1) {
cl = -1;
if (tccan(TCCLEAREOD))
tcout(TCCLEAREOD);
}
if (n && nl)
p = skipnolist(p + 1);
}
@ -640,11 +678,13 @@ struct menustack {
char *line;
int cs;
struct menuinfo info;
Cmgroup amatches, pmatches, lmatches;
};
static int
domenuselect(Hookdef dummy, Chdata dat)
{
static Chdata fdat = NULL;
Cmatch **p;
Cmgroup *pg;
Thingy cmd;
@ -652,10 +692,15 @@ domenuselect(Hookdef dummy, Chdata dat)
int i = 0, acc = 0;
char *s;
if (dummy && (!(s = getsparam("SELECTMIN")) ||
(dat && dat->num < atoi(s))))
if (fdat || (dummy && (!(s = getsparam("SELECTMIN")) ||
(dat && dat->num < atoi(s))))) {
if (fdat) {
fdat->matches = dat->matches;
fdat->num = dat->num;
}
return 0;
}
fdat = dat;
selectlocalmap(mskeymap);
noselect = 0;
mselect = (*(minfo.cur))->gnum;
@ -686,6 +731,32 @@ domenuselect(Hookdef dummy, Chdata dat)
else if (cmd == Th(z_acceptline)) {
acc = 1;
break;
} else if (cmd == Th(z_acceptandinfernexthistory)) {
Menustack s = (Menustack) zhalloc(sizeof(*s));
s->prev = u;
u = s;
s->line = dupstring((char *) line);
s->cs = cs;
memcpy(&(s->info), &minfo, sizeof(struct menuinfo));
s->amatches = amatches;
s->pmatches = pmatches;
s->lmatches = lmatches;
menucmp = 0;
fixsuffix();
validlist = 0;
pmatches = NULL;
invalidatelist();
menucomplete(zlenoargs);
if (dat->num < 2 || !minfo.cur || !*(minfo.cur)) {
noselect = 1;
clearlist = 1;
zrefresh();
break;
}
clearlist = 1;
mselect = (*(minfo.cur))->gnum;
continue;
} else if (cmd == Th(z_acceptandhold) ||
cmd == Th(z_acceptandmenucomplete)) {
Menustack s = (Menustack) zhalloc(sizeof(*s));
@ -695,6 +766,7 @@ domenuselect(Hookdef dummy, Chdata dat)
s->line = dupstring((char *) line);
s->cs = cs;
memcpy(&(s->info), &minfo, sizeof(struct menuinfo));
s->amatches = s->pmatches = s->lmatches = NULL;
acceptlast();
do_menucmp(0);
mselect = (*(minfo.cur))->gnum;
@ -712,7 +784,15 @@ domenuselect(Hookdef dummy, Chdata dat)
cs = u->cs;
memcpy(&minfo, &(u->info), sizeof(struct menuinfo));
p = &(minfo.cur);
if (u->pmatches && pmatches != u->pmatches) {
freematches();
amatches = u->amatches;
pmatches = u->pmatches;
lmatches = u->lmatches;
hasperm = 1;
}
u = u->prev;
clearlist = 1;
} else if (cmd == Th(z_redisplay)) {
redisplay(zlenoargs);
continue;
@ -846,6 +926,19 @@ domenuselect(Hookdef dummy, Chdata dat)
do_single(**p);
mselect = (**p)->gnum;
}
if (u) {
int hp = hasperm;
Cmgroup m = pmatches;
for (; u; u = u->prev) {
if (u->pmatches != m) {
pmatches = u->pmatches;
freematches();
}
}
pmatches = m;
hasperm = hp;
}
selectlocalmap(NULL);
mselect = -1;
inselect = 0;
@ -858,6 +951,7 @@ domenuselect(Hookdef dummy, Chdata dat)
showinglist = -2;
zrefresh();
}
fdat = NULL;
return (!noselect ^ acc);
}

View file

@ -1,23 +1,29 @@
#!
acceptlast
addzlefunction
amatches
backdel
backkill
bindkey
clearflag
clearlist
clearscreen
deletezlefunction
do_menucmp
do_single
feep
fixsuffix
foredel
forekill
freematches
getkey
getkeycmd
getzlequery
hasperm
invalidatelist
lastambig
linkkeymap
listshown
lmatches
menucmp
menucomplete
menucur
@ -25,6 +31,7 @@ menugrp
minfo
newkeymap
nlnct
pmatches
printfmt
redisplay
refthingy
@ -39,6 +46,7 @@ thingies
trashzle
ungetkeycmd
unlinkkeymap
validlist
zlenoargs
zmod
zrefresh

View file

@ -200,9 +200,9 @@ int metabind[128] = {
/* M-K */ z_undefinedkey,
/* M-L */ z_downcaseword,
/* M-M */ z_undefinedkey,
/* M-N */ z_historybeginningsearchforward,
/* M-N */ z_historysearchforward,
/* M-O */ z_undefinedkey,
/* M-P */ z_historybeginningsearchbackward,
/* M-P */ z_historysearchbackward,
/* M-Q */ z_pushline,
/* M-R */ z_undefinedkey,
/* M-S */ z_spellword,
@ -232,9 +232,9 @@ int metabind[128] = {
/* M-k */ z_undefinedkey,
/* M-l */ z_downcaseword,
/* M-m */ z_undefinedkey,
/* M-n */ z_historybeginningsearchforward,
/* M-n */ z_historysearchforward,
/* M-o */ z_undefinedkey,
/* M-p */ z_historybeginningsearchbackward,
/* M-p */ z_historysearchbackward,
/* M-q */ z_pushline,
/* M-r */ z_undefinedkey,
/* M-s */ z_spellword,

View file

@ -307,7 +307,7 @@ getkey(int keytmout)
unsigned int ret;
long exp100ths;
int die = 0, r, icnt = 0;
int old_errno = errno;
int old_errno = errno, obreaks = breaks;
#ifdef HAVE_SELECT
fd_set foofd;
@ -397,6 +397,7 @@ getkey(int keytmout)
if (!errflag && !retflag && !breaks)
continue;
errflag = 0;
breaks = obreaks;
errno = old_errno;
return EOF;
} else if (errno == EWOULDBLOCK) {
@ -717,7 +718,7 @@ bin_vared(char *name, char **args, char *ops, int func)
Value v;
Param pm = 0;
int create = 0;
int type = PM_SCALAR;
int type = PM_SCALAR, obreaks = breaks;
char *p1 = NULL, *p2 = NULL;
if (zleactive) {
@ -809,6 +810,7 @@ bin_vared(char *name, char **args, char *ops, int func)
if (!t || errflag) {
/* error in editing */
errflag = 0;
breaks = obreaks;
return 1;
}
/* strip off trailing newline, if any */
@ -948,7 +950,7 @@ trashzle(void)
static struct builtin bintab[] = {
BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaMldDANmrsLR", NULL),
BUILTIN("vared", 0, bin_vared, 1, 7, 0, NULL, NULL),
BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANCLmMgGcRa", NULL),
BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANCLmMgGcRaU", NULL),
};
/* The order of the entries in this table has to match the *HOOK

View file

@ -736,6 +736,7 @@ executenamedcommand(char *prmt)
statusll = l + len + 1;
zmult = 1;
listlist(cmdll);
showinglist = 0;
zmult = zmultsav;
} else if (!nextnode(firstnode(cmdll))) {
strcpy(ptr = cmdbuf, peekfirst(cmdll));
@ -754,6 +755,7 @@ executenamedcommand(char *prmt)
statusll = l + cmdambig + 1;
zmult = 1;
listlist(cmdll);
showinglist = 0;
zmult = zmultsav;
}
len = cmdambig;

View file

@ -137,6 +137,8 @@ set_buffer(Param pm, char *x)
cs = ll;
} else
cs = ll = 0;
fixsuffix();
menucmp = 0;
}
/**/
@ -156,6 +158,8 @@ set_cursor(Param pm, zlong x)
cs = ll;
else
cs = x;
fixsuffix();
menucmp = 0;
}
/**/
@ -182,6 +186,8 @@ set_lbuffer(Param pm, char *x)
ll = ll - cs + len;
cs = len;
zsfree(x);
fixsuffix();
menucmp = 0;
}
/**/
@ -205,6 +211,8 @@ set_rbuffer(Param pm, char *x)
sizeline(ll = cs + len);
memcpy(line + cs, y, len);
zsfree(x);
fixsuffix();
menucmp = 0;
}
/**/

View file

@ -281,7 +281,9 @@ zrefresh(void)
clearflag = 0;
resetneeded = 1;
}
listshown = showinglist = 0;
listshown = 0;
if (showinglist != -2)
showinglist = 0;
}
clearlist = 0;

View file

@ -340,7 +340,8 @@ bin_zle(char *name, char **args, char *ops, int func)
{ 'A', bin_zle_link, 2, 2 },
{ 'N', bin_zle_new, 1, 2 },
{ 'C', bin_zle_complete, 3, 3 },
{ 'R', bin_zle_refresh, 0, 1 },
{ 'R', bin_zle_refresh, 0, -1 },
{ 'U', bin_zle_unget, 1, 1 },
{ 0, bin_zle_call, 0, -1 },
};
struct opn const *op, *opp;
@ -396,22 +397,49 @@ static int
bin_zle_refresh(char *name, char **args, char *ops, char func)
{
char *s = statusline;
int sl = statusll;
int sl = statusll, ocl = clearlist;
statusline = NULL;
statusll = 0;
if (*args) {
statusline = *args;
statusll = strlen(statusline);
} else {
statusline = NULL;
statusll = 0;
}
if (**args) {
statusline = *args;
statusll = strlen(statusline);
}
if (*++args) {
LinkList l = newlinklist();
int zmultsav = zmult;
for (; *args; args++)
addlinknode(l, *args);
zmult = 1;
listlist(l);
showinglist = clearlist = 0;
zmult = zmultsav;
} else if (ops['c'])
clearlist = 1;
} else if (ops['c'])
clearlist = 1;
zrefresh();
clearlist = ocl;
statusline = s;
statusll = sl;
return 0;
}
/**/
static int
bin_zle_unget(char *name, char **args, char *ops, char func)
{
char *p = *args;
while (*p)
ungetkey((int) *p++);
return 0;
}
/**/
static void
scanlistwidgets(HashNode hn, int list)

View file

@ -133,7 +133,8 @@ static LinkList matches, fmatches;
/* This holds the list of matches-groups. lmatches is a pointer to the *
* last element in this list. */
static Cmgroup pmatches, amatches, lmatches;
/**/
Cmgroup pmatches, amatches, lmatches;
/* Non-zero if we have permanently allocated matches. */
@ -150,7 +151,8 @@ static int nmatches, smatches;
/* !=0 if we have a valid completion list. */
static int validlist;
/**/
int validlist;
/* This flag is non-zero if we are completing a pattern (with globcomplete) */
@ -818,7 +820,8 @@ docomplete(int lst)
* string inserted by the last completion. */
if (fromcomp & FC_INWORD)
cs = lastend;
if ((cs = lastend) > ll)
cs = ll;
/* Check if we have to start a menu-completion (via automenu). */
@ -1773,6 +1776,7 @@ doexpansion(char *s, int lst, int olst, int explincmd)
if (lst == COMP_LIST_EXPAND) {
/* Only the list of expansions was requested. */
listlist(vl);
showinglist = 0;
goto end;
}
/* Remove the current word and put the expansions there. */
@ -2577,7 +2581,8 @@ comp_match(char *pfx, char *sfx, char *w, Comp cp,
return NULL;
r = (qu ? quotename(r, NULL) : dupstring(r));
if (qu == 2 && r[0] == '\\' && r[1] == '~')
chuck(r);
/* We still break it into parts here, trying to build a sensible
* cline list for these matches, too. */
wl = strlen(w);
@ -2590,6 +2595,8 @@ comp_match(char *pfx, char *sfx, char *w, Comp cp,
int mpl, rpl, wl;
w = (qu ? quotename(w, NULL) : dupstring(w));
if (qu == 2 && w[0] == '\\' && w[1] == '~')
chuck(w);
wl = strlen(w);
@ -3814,15 +3821,20 @@ addmatches(Cadata dat, char **argv)
dat->rems = dupstring(dat->rems);
/* Probably quote the prefix and suffix for testing. */
if (!cp && (dat->aflags & CAF_MATCH) &&
!(dat->aflags & CAF_QUOTE)) {
lpre = quotename(lpre, NULL);
lsuf = quotename(lsuf, NULL);
if (!(dat->aflags & CAF_QUOTE)) {
if (!cp && (dat->aflags & CAF_MATCH)) {
lpre = quotename(lpre, NULL);
lsuf = quotename(lsuf, NULL);
}
if (dat->ppre) {
dat->ppre = quotename(dat->ppre, NULL);
if ((dat->flags & CMF_FILE) &&
dat->ppre[0] == '\\' && dat->ppre[1] == '~')
chuck(dat->ppre);
}
if (dat->psuf)
dat->psuf = quotename(dat->psuf, NULL);
}
if (dat->ppre)
dat->ppre = quotename(dat->ppre, NULL);
if (dat->psuf)
dat->psuf = quotename(dat->psuf, NULL);
}
/* Walk through the matches given. */
for (; (s = *argv); argv++) {
@ -3855,7 +3867,9 @@ addmatches(Cadata dat, char **argv)
lc = bld_parts(ms, sl, -1, NULL);
isexact = 0;
} else if (!(ms = comp_match(lpre, lsuf, s, cp, &lc,
!(dat->aflags & CAF_QUOTE),
(!(dat->aflags & CAF_QUOTE) ?
((dat->ppre && dat->ppre) ||
!(dat->flags & CMF_FILE) ? 1 : 2) : 0),
&bpl, &bsl, &isexact))) {
if (dparr && !*++dparr)
dparr = NULL;
@ -3962,7 +3976,7 @@ addmatch(char *s, char *t)
}
ms = ((addwhat == CC_FILES || addwhat == -6 ||
addwhat == -5 || addwhat == -8) ?
comp_match(qfpre, qfsuf, s, filecomp, &lc, 1,
comp_match(qfpre, qfsuf, s, filecomp, &lc, (ppre && *ppre ? 1 : 2),
&bpl, &bsl, &isexact) :
comp_match(fpre, fsuf, s, filecomp, &lc, 0,
&bpl, &bsl, &isexact));
@ -4361,6 +4375,7 @@ docompletion(char *s, int lst, int incmd)
cs = origcs;
clearlist = 1;
ret = 1;
minfo.cur = NULL;
goto compend;
}
if (comppatmatch && *comppatmatch && comppatmatch != opm)
@ -5156,10 +5171,16 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
zsfree(compisuffix);
compisuffix = ztrdup("");
zsfree(compqiprefix);
compqiprefix = qp;
zsfree(compqisuffix);
compqisuffix = qs;
if (instring) {
compqiprefix = qp;
compqisuffix = qs;
} else {
compqiprefix = ztrdup(quotename(qp, NULL));
zsfree(qp);
compqisuffix = ztrdup(quotename(qs, NULL));
zsfree(qs);
}
freearray(compwords);
i = countlinknodes(foo);
compwords = (char **) zalloc((i + 1) * sizeof(char *));
@ -7028,7 +7049,7 @@ freematch(Cmatch m)
/* This frees the groups of matches. */
/**/
static void
void
freematches(void)
{
Cmgroup g = pmatches, n;

View file

@ -42,7 +42,7 @@ static struct builtin builtins[] =
BUILTIN("[", 0, bin_test, 0, -1, BIN_BRACKET, NULL, NULL),
BUILTIN(".", BINF_PSPECIAL, bin_dot, 1, -1, 0, NULL, NULL),
BUILTIN(":", BINF_PSPECIAL, bin_true, 0, -1, 0, NULL, NULL),
BUILTIN("alias", BINF_MAGICEQUALS, bin_alias, 0, -1, 0, "Lgmr", NULL),
BUILTIN("alias", BINF_MAGICEQUALS | BINF_PLUSOPTS, bin_alias, 0, -1, 0, "Lgmr", NULL),
BUILTIN("autoload", BINF_TYPEOPTS, bin_functions, 0, -1, 0, "tU", "u"),
BUILTIN("bg", 0, bin_fg, 0, -1, BIN_BG, NULL, NULL),
BUILTIN("break", BINF_PSPECIAL, bin_break, 0, 1, BIN_BREAK, NULL, NULL),
@ -87,7 +87,7 @@ static struct builtin builtins[] =
#endif
BUILTIN("popd", 0, bin_cd, 0, 2, BIN_POPD, NULL, NULL),
BUILTIN("print", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, "RDPnrslzNu0123456789pioOcm-", NULL),
BUILTIN("print", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, "RDPbnrslzNu0123456789pioOcm-", NULL),
BUILTIN("pushd", 0, bin_cd, 0, 2, BIN_PUSHD, NULL, NULL),
BUILTIN("pushln", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, NULL, "-nz"),
BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
@ -645,12 +645,14 @@ set_pwd_env(void)
setsparam("OLDPWD", ztrdup(oldpwd));
pm = (Param) paramtab->getnode(paramtab, "PWD");
if (!(pm->flags & PM_EXPORTED)) {
if (!(pm->flags & PM_EXPORTED) &&
(!pm->level || (isset(ALLEXPORT) && !pm->old))) {
pm->flags |= PM_EXPORTED;
pm->env = addenv("PWD", pwd);
}
pm = (Param) paramtab->getnode(paramtab, "OLDPWD");
if (!(pm->flags & PM_EXPORTED)) {
if (!(pm->flags & PM_EXPORTED) &&
(!pm->level || (isset(ALLEXPORT) && !pm->old))) {
pm->flags |= PM_EXPORTED;
pm->env = addenv("OLDPWD", oldpwd);
}
@ -1492,7 +1494,7 @@ Param
typeset_single(char *cname, char *pname, Param pm, int func,
int on, int off, int roff, char *value, Param altpm)
{
int usepm, tc, keeplocal = 0;
int usepm, tc, keeplocal = 0, newspecial = 0;
/*
* Do we use the existing pm? Note that this isn't the end of the
@ -1503,22 +1505,31 @@ typeset_single(char *cname, char *pname, Param pm, int func,
*/
usepm = pm && !(pm->flags & PM_UNSET);
/* Always use an existing pm if special at current locallevel */
if (pm && (pm->flags & PM_SPECIAL) && pm->level == locallevel)
/*
* We need to compare types with an existing pm if special,
* even if that's unset
*/
if (pm && (pm->flags & PM_SPECIAL))
usepm = 1;
/*
* Don't use a non-special existing param if
* Don't use an existing param if
* - the local level has changed, and
* - we are really locallizing the parameter
*/
if (usepm && !(pm->flags & PM_SPECIAL) &&
locallevel != pm->level && (on & PM_LOCAL))
if (usepm && locallevel != pm->level && (on & PM_LOCAL)) {
/*
* If the original parameter was special and we're creating
* a new one, we need to keep it special.
*/
newspecial = (pm->flags & PM_SPECIAL);
usepm = 0;
}
/* attempting a type conversion, or making a tied colonarray? */
if ((tc = usepm && (((off & pm->flags) | (on & ~pm->flags)) &
(PM_INTEGER|PM_HASHED|PM_ARRAY|PM_TIED|PM_AUTOLOAD))))
if ((tc = (usepm || newspecial)
&& (((off & pm->flags) | (on & ~pm->flags)) &
(PM_INTEGER|PM_HASHED|PM_ARRAY|PM_TIED|PM_AUTOLOAD))))
usepm = 0;
if (tc && (pm->flags & PM_SPECIAL)) {
zerrnam(cname, "%s: can't change type of a special parameter",
@ -1526,13 +1537,27 @@ typeset_single(char *cname, char *pname, Param pm, int func,
return NULL;
}
/*
* According to the manual, local parameters don't get exported.
* A parameter will be local if
* 1. we are re-using an existing local parameter
* or
* 2. we are not using an existing parameter, but
* i. there is already a parameter, which will be hidden
* or
* ii. we are creating a new local parameter
*/
if ((usepm && pm->level) ||
(!usepm && (pm || (locallevel && (on & PM_LOCAL)))))
on &= ~PM_EXPORTED;
if (usepm) {
on &= ~PM_LOCAL;
if (!on && !roff && !value) {
paramtab->printnode((HashNode)pm, 0);
return pm;
}
if ((pm->flags & PM_RESTRICTED && isset(RESTRICTED))) {
if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED)) {
zerrnam(cname, "%s: restricted", pname, 0);
return pm;
}
@ -1553,7 +1578,8 @@ typeset_single(char *cname, char *pname, Param pm, int func,
if (pm->flags & PM_EXPORTED) {
if (!(pm->flags & PM_UNSET) && !pm->env && !value)
pm->env = addenv(pname, getsparam(pname));
} else if (pm->env) {
} else if (pm->env &&
(!pm->level || (isset(ALLEXPORT) && !pm->old))) {
delenv(pm->env);
zsfree(pm->env);
pm->env = NULL;
@ -1593,13 +1619,68 @@ typeset_single(char *cname, char *pname, Param pm, int func,
pname = dupstring(pname);
unsetparam_pm(pm, 0, 1);
}
/*
* Create a new node for a parameter with the flags in `on' minus the
* readonly flag
*/
pm = createparam(pname, on & ~PM_READONLY);
DPUTS(!pm, "BUG: parameter not created");
pm->ct = auxlen;
if (newspecial) {
Param tpm, pm2;
if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED)) {
zerrnam(cname, "%s: restricted", pname, 0);
return pm;
}
/*
* For specials, we keep the same struct but zero everything.
* Maybe it would be easier to create a new struct but copy
* the get/set methods.
*/
tpm = (Param) zalloc(sizeof *tpm);
tpm->nam = pm->nam;
if (pm->ename &&
(pm2 = (Param) paramtab->getnode(paramtab, pm->ename)) &&
pm2->level == locallevel) {
/* This is getting silly, but anyway: if one of a path/PATH
* pair has already been made local at the current level, we
* have to make sure that the other one does not have its value
* saved: since that comes from an internal variable it will
* already reflect the local value, so restoring it on exit
* would be wrong.
*
* This problem is also why we make sure we have a copy
* of the environment entry in tpm->env, rather than relying
* on the restored value to provide it.
*/
tpm->flags = pm->flags | PM_NORESTORE;
} else {
copyparam(tpm, pm, 1);
}
tpm->old = pm->old;
tpm->level = pm->level;
tpm->ct = pm->ct;
tpm->env = pm->env;
pm->old = tpm;
/*
* The remaining on/off flags should be harmless to use,
* because we've checked for unpleasant surprises above.
*/
pm->flags = (PM_TYPE(pm->flags) | on | PM_SPECIAL) & ~off;
/*
* Final tweak: if we've turned on one of the flags with
* numbers, we should use the appropriate integer.
*/
if (on & (PM_LEFT|PM_RIGHT_B|PM_RIGHT_Z|PM_INTEGER))
pm->ct = auxlen;
else
pm->ct = 0;
pm->env = NULL;
} else {
/*
* Create a new node for a parameter with the flags in `on' minus the
* readonly flag
*/
pm = createparam(pname, on & ~PM_READONLY);
DPUTS(!pm, "BUG: parameter not created");
pm->ct = auxlen;
}
if (altpm && PM_TYPE(pm->flags) == PM_SCALAR) {
/*
@ -1618,6 +1699,28 @@ typeset_single(char *cname, char *pname, Param pm, int func,
pm->level = locallevel;
if (value && !(pm->flags & (PM_ARRAY|PM_HASHED)))
setsparam(pname, ztrdup(value));
else if (newspecial && !(pm->old->flags & PM_NORESTORE)) {
/*
* We need to use the special setting function to re-initialise
* the special parameter to empty.
*/
HEAPALLOC {
switch (PM_TYPE(pm->flags)) {
case PM_SCALAR:
pm->sets.cfn(pm, ztrdup(""));
break;
case PM_INTEGER:
pm->sets.ifn(pm, 0);
break;
case PM_ARRAY:
pm->sets.afn(pm, mkarray(NULL));
break;
case PM_HASHED:
pm->sets.hfn(pm, newparamtable(17, pm->nam));
break;
}
} LASTALLOC;
}
pm->flags |= (on & PM_READONLY);
if (value && (pm->flags & (PM_ARRAY|PM_HASHED))) {
zerrnam(cname, "%s: can't assign initial value for array", pname, 0);
@ -1839,7 +1942,7 @@ bin_functions(char *name, char **argv, char *ops, int func)
Comp com;
Shfunc shf;
int i, returnval = 0;
int on = 0, off = 0;
int on = 0, off = 0, pflags = 0;
/* Do we have any flags defined? */
if (ops['u'] == 1)
@ -1860,13 +1963,17 @@ bin_functions(char *name, char **argv, char *ops, int func)
return 1;
}
if (ops['f'] == 2 || ops['+'])
pflags |= PRINT_NAMEONLY;
/* If no arguments given, we will print functions. If flags *
* are given, we will print only functions containing these *
* flags, else we'll print them all. */
if (!*argv) {
if (ops['U'] && !ops['u'])
on &= ~PM_UNDEFINED;
scanhashtable(shfunctab, 1, on|off, DISABLED, shfunctab->printnode, 0);
scanhashtable(shfunctab, 1, on|off, DISABLED, shfunctab->printnode,
pflags);
return 0;
}
@ -1879,7 +1986,8 @@ bin_functions(char *name, char **argv, char *ops, int func)
if ((com = parsereg(*argv))) {
/* with no options, just print all functions matching the glob pattern */
if (!(on|off)) {
scanmatchtable(shfunctab, com, 0, DISABLED, shfunctab->printnode, 0);
scanmatchtable(shfunctab, com, 0, DISABLED,
shfunctab->printnode, pflags);
} else {
/* apply the options to all functions matching the glob pattern */
for (i = 0; i < shfunctab->hsize; i++) {
@ -1906,7 +2014,7 @@ bin_functions(char *name, char **argv, char *ops, int func)
shf->flags = (shf->flags | (on & ~PM_UNDEFINED)) & ~off;
else
/* no flags, so just print */
shfunctab->printnode((HashNode) shf, 0);
shfunctab->printnode((HashNode) shf, pflags);
} else if (on & PM_UNDEFINED) {
/* Add a new undefined (autoloaded) function to the *
* hash table with the corresponding flags set. */
@ -2407,6 +2515,8 @@ bin_alias(char *name, char **argv, char *ops, int func)
if (ops['L'])
printflags |= PRINT_LIST;
else if (ops['r'] == 2 || ops['g'] == 2 || ops['m'] == 2 || ops['+'])
printflags |= PRINT_NAMEONLY;
/* In the absence of arguments, list all aliases. If a command *
* line flag is specified, list only those of that type. */
@ -2512,8 +2622,8 @@ bin_print(char *name, char **args, char *ops, int func)
if (!ops['e'] && (ops['R'] || ops['r'] || ops['E']))
unmetafy(args[n], &len[n]);
else
args[n] = getkeystring(args[n], &len[n],
func != BIN_ECHO && !ops['e'], &nnl);
args[n] = getkeystring(args[n], &len[n], ops['b'] ? 2 :
(func != BIN_ECHO && !ops['e']), &nnl);
/* -P option -- interpret as a prompt sequence */
if(ops['P']) {
/*
@ -3098,11 +3208,7 @@ bin_eval(char *nam, char **argv, char *ops, int func)
{
List list;
inpush(zjoin(argv, ' '), 0, NULL);
strinbeg(0);
list = parse_list();
strinend();
inpop();
list = parse_string(zjoin(argv, ' '), 0);
if (!list) {
errflag = 0;
return 1;

View file

@ -916,7 +916,7 @@ execpline(Sublist l, int how, int last1)
}
jn->stat &= ~(STAT_DONE | STAT_NOPRINT);
jn->stat |= STAT_STOPPED | STAT_CHANGED;
jn->stat |= STAT_STOPPED | STAT_CHANGED | STAT_LOCKED;
printjob(jn, !!isset(LONGLISTJOBS), 1);
}
else if (newjob != list_pipe_job)
@ -1012,7 +1012,9 @@ execpline(Sublist l, int how, int last1)
jn = jobtab + pj;
killjb(jn, lastval & ~0200);
}
if (list_pipe_child || (list_pipe && (jn->stat & STAT_DONE)))
if (list_pipe_child ||
((jn->stat & STAT_DONE) &&
(list_pipe || (pline_level && !(jn->stat & STAT_SUBJOB)))))
deletejob(jn);
thisjob = pj;
@ -1530,6 +1532,9 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
/* Was this "exec < foobar"? */
nullexec = 1;
break;
} else if (vars && nonempty(vars)) {
nullexec = 2;
break;
} else if (!nullcmd || !*nullcmd ||
(cflags & BINF_PREFIX)) {
zerr("redirection with no command", NULL, 0);
@ -1869,7 +1874,8 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
addfd(forked, save, mfds, fn->fd1, fil, 0);
/* If this is 'exec < file', read from stdin, *
* not terminal, unless `file' is a terminal. */
if (nullexec && fn->fd1 == 0 && isset(SHINSTDIN) && interact)
if (nullexec == 1 && fn->fd1 == 0 &&
isset(SHINSTDIN) && interact)
init_io();
break;
case CLOSE:
@ -1929,17 +1935,28 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
closemn(mfds, i);
if (nullexec) {
for (i = 0; i < 10; i++)
if (save[i] != -2)
zclose(save[i]);
if (nullexec == 1) {
/*
* If nullexec is 1 we specifically *don't* restore the original
* fd's before returning.
*/
for (i = 0; i < 10; i++)
if (save[i] != -2)
zclose(save[i]);
return;
}
/*
* Here we specifically *don't* restore the original fd's
* before returning.
* If nullexec is 2, we have variables to add with the redirections
* in place.
*/
return;
}
if (isset(EXECOPT) && !errflag) {
if (vars)
addvars(vars, 0);
lastval = errflag ? errflag : cmdoutval;
if (isset(XTRACE)) {
fputc('\n', stderr);
fflush(stderr);
}
} else if (isset(EXECOPT) && !errflag) {
/*
* We delay the entersubsh() to here when we are exec'ing
* the current shell (including a fake exec to run a builtin then

View file

@ -291,7 +291,7 @@ safeinungetc(int c)
void
herrflush(void)
{
while (!lexstop && inbufct)
while (!lexstop && inbufct && !strin)
hwaddc(ingetc());
}

View file

@ -125,6 +125,86 @@ findproc(pid_t pid, Job *jptr, Process *pptr)
return 0;
}
/* Find the super-job of a sub-job. */
/**/
static int
super_job(int sub)
{
int i;
for (i = 1; i < MAXJOB; i++)
if ((jobtab[i].stat & STAT_SUPERJOB) &&
jobtab[i].other == sub &&
jobtab[i].gleader)
return i;
return 0;
}
/**/
static int
handle_sub(int job, int fg)
{
Job jn = jobtab + job, sj = jobtab + jn->other;
if ((sj->stat & STAT_DONE) || !sj->procs) {
struct process *p;
for (p = sj->procs; p; p = p->next)
if (WIFSIGNALED(p->status)) {
if (jn->gleader != mypgrp && jn->procs->next)
killpg(jn->gleader, WTERMSIG(p->status));
else
kill(jn->procs->pid, WTERMSIG(p->status));
kill(sj->other, SIGCONT);
kill(sj->other, WTERMSIG(p->status));
break;
}
if (!p) {
int cp;
jn->stat &= ~STAT_SUPERJOB;
jn->stat |= STAT_WASSUPER;
if ((cp = ((WIFEXITED(jn->procs->status) ||
WIFSIGNALED(jn->procs->status)) &&
killpg(jn->gleader, 0) == -1))) {
Process p;
for (p = jn->procs; p->next; p = p->next);
jn->gleader = p->pid;
}
/* This deleted the job too early if the parent
shell waited for a command in a list that will
be executed by the sub-shell (e.g.: if we have
`ls|if true;then sleep 20;cat;fi' and ^Z the
sleep, the rest will be executed by a sub-shell,
but the parent shell gets notified for the
sleep.
deletejob(sj); */
/* If this super-job contains only the sub-shell,
we have to attach the tty to its process group
now. */
if ((fg || thisjob == job) &&
(!jn->procs->next || cp || jn->procs->pid != jn->gleader))
attachtty(jn->gleader);
kill(sj->other, SIGCONT);
}
curjob = jn - jobtab;
} else if (sj->stat & STAT_STOPPED) {
struct process *p;
jn->stat |= STAT_STOPPED;
for (p = jn->procs; p; p = p->next)
if (p->status == SP_RUNNING ||
(!WIFEXITED(p->status) && !WIFSIGNALED(p->status)))
p->status = sj->procs->status;
curjob = jn - jobtab;
printjob(jn, !!isset(LONGLISTJOBS), 1);
return 1;
}
return 0;
}
/* Update status of process that we have just WAIT'ed for */
/**/
@ -183,13 +263,8 @@ update_job(Job jn)
* or to exit. So we have to send it a SIGTSTP. */
int i;
for (i = 1; i < MAXJOB; i++)
if ((jobtab[i].stat & STAT_SUPERJOB) &&
jobtab[i].other == job &&
jobtab[i].gleader) {
killpg(jobtab[i].gleader, SIGTSTP);
break;
}
if ((i = super_job(job)))
killpg(jobtab[i].gleader, SIGTSTP);
}
return;
}
@ -254,6 +329,13 @@ update_job(Job jn)
return;
jn->stat |= (somestopped) ? STAT_CHANGED | STAT_STOPPED :
STAT_CHANGED | STAT_DONE;
if (!inforeground &&
(jn->stat & (STAT_SUBJOB | STAT_DONE)) == (STAT_SUBJOB | STAT_DONE)) {
int su;
if ((su = super_job(jn - jobtab)))
handle_sub(su, 0);
}
if ((jn->stat & (STAT_DONE | STAT_STOPPED)) == STAT_STOPPED) {
prevjob = curjob;
curjob = job;
@ -303,13 +385,14 @@ setprevjob(void)
for (i = MAXJOB - 1; i; i--)
if ((jobtab[i].stat & STAT_INUSE) && (jobtab[i].stat & STAT_STOPPED) &&
i != curjob && i != thisjob) {
!(jobtab[i].stat & STAT_SUBJOB) && i != curjob && i != thisjob) {
prevjob = i;
return;
}
for (i = MAXJOB - 1; i; i--)
if ((jobtab[i].stat & STAT_INUSE) && i != curjob && i != thisjob) {
if ((jobtab[i].stat & STAT_INUSE) && !(jobtab[i].stat & STAT_SUBJOB) &&
i != curjob && i != thisjob) {
prevjob = i;
return;
}
@ -791,64 +874,9 @@ waitjob(int job, int sig)
killjb(jn, SIGCONT);
jn->stat &= ~STAT_STOPPED;
}
if (jn->stat & STAT_SUPERJOB) {
Job sj = jobtab + jn->other;
if ((sj->stat & STAT_DONE) || !sj->procs) {
struct process *p;
for (p = sj->procs; p; p = p->next)
if (WIFSIGNALED(p->status)) {
if (jn->gleader != mypgrp && jn->procs->next)
killpg(jn->gleader, WTERMSIG(p->status));
else
kill(jn->procs->pid, WTERMSIG(p->status));
kill(sj->other, SIGCONT);
kill(sj->other, WTERMSIG(p->status));
break;
}
if (!p) {
int cp;
jn->stat &= ~STAT_SUPERJOB;
jn->stat |= STAT_WASSUPER;
if ((cp = ((WIFEXITED(jn->procs->status) ||
WIFSIGNALED(jn->procs->status)) &&
killpg(jn->gleader, 0) == -1))) {
Process p;
for (p = jn->procs; p->next; p = p->next);
jn->gleader = p->pid;
}
/* This deleted the job too early if the parent
shell waited for a command in a list that will
be executed by the sub-shell (e.g.: if we have
`ls|if true;then sleep 20;cat;fi' and ^Z the
sleep, the rest will be executed by a sub-shell,
but the parent shell gets notified for the
sleep.
deletejob(sj); */
/* If this super-job contains only the sub-shell,
we have to attach the tty to our process group
(which is shared by the sub-shell) now. */
if (!jn->procs->next || cp || jn->procs->pid != jn->gleader)
attachtty(jn->gleader);
kill(sj->other, SIGCONT);
}
curjob = jn - jobtab;
}
else if (sj->stat & STAT_STOPPED) {
struct process *p;
jn->stat |= STAT_STOPPED;
for (p = jn->procs; p; p = p->next)
if (p->status == SP_RUNNING ||
(!WIFEXITED(p->status) && !WIFSIGNALED(p->status)))
p->status = sj->procs->status;
curjob = jn - jobtab;
printjob(jn, !!isset(LONGLISTJOBS), 1);
if (jn->stat & STAT_SUPERJOB)
if (handle_sub(jn - jobtab, 1))
break;
}
}
child_block();
}
} else

View file

@ -57,6 +57,13 @@ execfor(Cmd cmd, LinkList args, int flags)
if (node->condition) {
str = dupstring(node->name);
singsub(&str);
if (isset(XTRACE)) {
char *str2 = dupstring(str);
untokenize(str2);
printprompt4();
fprintf(stderr, "%s\n", str2);
fflush(stderr);
}
if (!errflag)
matheval(str);
if (errflag)
@ -79,9 +86,14 @@ execfor(Cmd cmd, LinkList args, int flags)
if (!errflag) {
while (iblank(*str))
str++;
if (*str)
if (*str) {
if (isset(XTRACE)) {
printprompt4();
fprintf(stderr, "%s\n", str);
fflush(stderr);
}
val = matheval(str);
else
} else
val = 1;
}
if (errflag) {
@ -95,6 +107,11 @@ execfor(Cmd cmd, LinkList args, int flags)
} else {
if (!args || !(str = (char *) ugetnode(args)))
break;
if (isset(XTRACE)) {
printprompt4();
fprintf(stderr, "%s=%s\n", node->name, str);
fflush(stderr);
}
setsparam(node->name, ztrdup(str));
}
execlist(node->list, 1,
@ -107,6 +124,11 @@ execfor(Cmd cmd, LinkList args, int flags)
}
if (node->condition && !errflag) {
str = dupstring(node->advance);
if (isset(XTRACE)) {
printprompt4();
fprintf(stderr, "%s\n", str);
fflush(stderr);
}
singsub(&str);
if (!errflag)
matheval(str);
@ -410,6 +432,13 @@ execcase(Cmd cmd, LinkList args, int flags)
while (*p) {
char *pat = dupstring(*p + 1);
singsub(&pat);
if (isset(XTRACE)) {
char *pat2 = dupstring(pat);
untokenize(pat2);
printprompt4();
fprintf(stderr, "case %s (%s)\n", word, pat2);
fflush(stderr);
}
if (matchpat(word, pat)) {
do {
execlist(*l++, 1, **p == ';' && (flags & CFLAG_EXEC));

View file

@ -357,9 +357,11 @@ zzlex(void)
}
if (*ptr == '#') {
if (*++ptr == '\\') {
int v;
ptr++;
yyval = *ptr == Meta ? *++ptr ^ 32 : *ptr;
ptr++;
ptr = getkeystring(ptr, NULL, 6, &v);
yyval = v;
unary = 0;
return NUM;
}

View file

@ -1905,7 +1905,7 @@ arrhashsetfn(Param pm, char **val)
if (alen % 2) {
freearray(val);
zerr("bad set of key/value pairs for associative array\n",
zerr("bad set of key/value pairs for associative array",
NULL, 0);
return;
}
@ -2500,11 +2500,17 @@ arrfixenv(char *s, char **t)
Param pm;
MUSTUSEHEAP("arrfixenv");
pm = (Param) paramtab->getnode(paramtab, s);
/*
* Only one level of a parameter can be exported. Unless
* ALLEXPORT is set, this must be global.
*/
if (t == path)
cmdnamtab->emptytable(cmdnamtab);
if (isset(ALLEXPORT) ? !!pm->old : pm->level)
return;
u = t ? zjoin(t, ':') : "";
len_s = strlen(s);
pm = (Param) paramtab->getnode(paramtab, s);
for (ep = environ; *ep; ep++)
if (!strncmp(*ep, s, len_s) && (*ep)[len_s] == '=') {
pm->env = replenv(*ep, u);
@ -2685,8 +2691,46 @@ static void
scanendscope(HashNode hn, int flags)
{
Param pm = (Param)hn;
if(pm->level > locallevel)
unsetparam_pm(pm, 0, 0);
if (pm->level > locallevel) {
if ((pm->flags & (PM_SPECIAL|PM_REMOVABLE)) == PM_SPECIAL) {
/*
* Removable specials are normal in that they can be removed
* to reveal an ordinary parameter beneath. Here we handle
* non-removable specials, which were made local by stealth
* (see newspecial code in typeset_single()). In fact the
* visible pm is always the same struct; the pm->old is
* just a place holder for old data and flags.
*/
Param tpm = pm->old;
DPUTS(!tpm || PM_TYPE(pm->flags) != PM_TYPE(tpm->flags) ||
!(tpm->flags & PM_SPECIAL),
"BUG: in restoring scope of special parameter");
pm->old = tpm->old;
pm->flags = (tpm->flags & ~PM_NORESTORE);
pm->level = tpm->level;
pm->ct = tpm->ct;
pm->env = tpm->env;
if (!(tpm->flags & PM_NORESTORE))
switch (PM_TYPE(pm->flags)) {
case PM_SCALAR:
pm->sets.cfn(pm, tpm->u.str);
break;
case PM_INTEGER:
pm->sets.ifn(pm, tpm->u.val);
break;
case PM_ARRAY:
pm->sets.afn(pm, tpm->u.arr);
break;
case PM_HASHED:
pm->sets.hfn(pm, tpm->u.hash);
break;
}
zfree(tpm, sizeof(*tpm));
} else
unsetparam_pm(pm, 0, 0);
}
}

View file

@ -97,6 +97,38 @@ static int dontcount;
static char *rstring, *Rstring;
/*
* Expand path p; maximum is npath segments where 0 means the whole path.
* If tilde is 1, try and find a named directory to use.
*/
static void
promptpath(char *p, int npath, int tilde)
{
char *modp = p;
Nameddir nd;
if (tilde && ((nd = finddir(p))))
modp = tricat("~", nd->nam, p + strlen(nd->dir));
if (npath) {
char *sptr;
for (sptr = modp + strlen(modp); sptr > modp; sptr--) {
if (*sptr == '/' && !--npath) {
sptr++;
break;
}
}
if (*sptr == '/' && sptr[1] && sptr != modp)
sptr++;
stradd(sptr);
} else
stradd(modp);
if (p != modp)
zsfree(modp);
}
/* Perform prompt expansion on a string, putting the result in a *
* permanently-allocated string. If ns is non-zero, this string *
* may have embedded Inpar and Outpar, which indicate a toggling *
@ -293,49 +325,21 @@ putpromptchar(int doprint, int endchar)
}
switch (*fm) {
case '~':
if ((nd = finddir(pwd))) {
char *t = tricat("~", nd->nam, pwd + strlen(nd->dir));
stradd(t);
zsfree(t);
break;
}
promptpath(pwd, arg, 1);
break;
case 'd':
case '/':
stradd(pwd);
promptpath(pwd, arg, 0);
break;
case 'c':
case '.':
{
char *t;
if ((nd = finddir(pwd)))
t = tricat("~", nd->nam, pwd + strlen(nd->dir));
else
t = ztrdup(pwd);
if (!arg)
arg++;
for (ss = t + strlen(t); ss > t; ss--)
if (*ss == '/' && !--arg) {
ss++;
break;
}
if(*ss == '/' && ss[1] && ss != t)
ss++;
stradd(ss);
zsfree(t);
break;
}
promptpath(pwd, arg ? arg : 1, 1);
break;
case 'C':
if (!arg)
arg++;
for (ss = pwd + strlen(pwd); ss > pwd; ss--)
if (*ss == '/' && !--arg) {
ss++;
break;
}
if (*ss == '/' && ss[1] && (ss != pwd))
ss++;
stradd(ss);
promptpath(pwd, arg ? arg : 1, 0);
break;
case 'N':
promptpath(scriptname ? scriptname : argzero, arg, 0);
break;
case 'h':
case '!':
@ -536,9 +540,6 @@ putpromptchar(int doprint, int endchar)
sprintf(bp, "%ld", (long)lineno);
bp += strlen(bp);
break;
case 'N':
stradd(scriptname ? scriptname : argzero);
break;
case '\0':
return 0;
case Meta:

View file

@ -1735,10 +1735,11 @@ findsep(char **s, char *sep)
if (!*t)
return i;
if (*(*s)++ == Meta) {
(*s)++;
#ifdef DEBUG
if (! **s)
if (! *(*s)++)
fprintf(stderr, "BUG: unexpected end of string in findsep()\n");
#else
(*s)++;
#endif
}
}
@ -3187,24 +3188,28 @@ dquotedzputs(char const *s, FILE *stream)
* 4: Do $'...' quoting. Overwrites the existing string instead of
* zhalloc'ing
* 5: As 2, but \- is special. Expects misc to be defined.
* 6: As 2, but parses only one character and returns end-pointer
* and parsed character in *misc
*/
/**/
char *
getkeystring(char *s, int *len, int fromwhere, int *misc)
{
char *buf;
char *buf, tmp[1];
char *t, *u = NULL;
char svchar = '\0';
int meta = 0, control = 0;
if (fromwhere != 4)
buf = zhalloc(strlen(s) + 1);
if (fromwhere == 6)
t = tmp;
else if (fromwhere != 4)
t = buf = zhalloc(strlen(s) + 1);
else {
buf = s;
t = buf = s;
s += 2;
}
for (t = buf; *s; s++) {
for (; *s; s++) {
if (*s == '\\' && s[1]) {
switch (*++s) {
case 'a':
@ -3303,7 +3308,8 @@ getkeystring(char *s, int *len, int fromwhere, int *misc)
} else if (fromwhere == 4 && *s == Snull) {
for (u = t; (*u++ = *s++););
return t + 1;
} else if (*s == '^' && (fromwhere == 2 || fromwhere == 5)) {
} else if (*s == '^' &&
(fromwhere == 2 || fromwhere == 5 || fromwhere == 6)) {
control = 1;
continue;
} else if (*s == Meta)
@ -3330,6 +3336,10 @@ getkeystring(char *s, int *len, int fromwhere, int *misc)
t[-1] = Meta;
t++;
}
if (fromwhere == 6 && t != tmp) {
*misc = (int) tmp[0];
return s + 1;
}
}
DPUTS(fromwhere == 4, "BUG: unterminated $' substitution");
*t = '\0';

View file

@ -951,40 +951,41 @@ struct param {
/* flags for parameters */
/* parameter types */
#define PM_SCALAR 0 /* scalar */
#define PM_ARRAY (1<<0) /* array */
#define PM_INTEGER (1<<1) /* integer */
#define PM_HASHED (1<<2) /* association */
#define PM_SCALAR 0 /* scalar */
#define PM_ARRAY (1<<0) /* array */
#define PM_INTEGER (1<<1) /* integer */
#define PM_HASHED (1<<2) /* association */
#define PM_TYPE(X) (X & (PM_SCALAR|PM_INTEGER|PM_ARRAY|PM_HASHED))
#define PM_LEFT (1<<3) /* left justify and remove leading blanks */
#define PM_RIGHT_B (1<<4) /* right justify and fill with leading blanks */
#define PM_RIGHT_Z (1<<5) /* right justify and fill with leading zeros */
#define PM_LOWER (1<<6) /* all lower case */
#define PM_LEFT (1<<3) /* left justify, remove leading blanks */
#define PM_RIGHT_B (1<<4) /* right justify, fill with leading blanks */
#define PM_RIGHT_Z (1<<5) /* right justify, fill with leading zeros */
#define PM_LOWER (1<<6) /* all lower case */
/* The following are the same since they *
* both represent -u option to typeset */
#define PM_UPPER (1<<7) /* all upper case */
#define PM_UNDEFINED (1<<7) /* undefined (autoloaded) shell function */
#define PM_UPPER (1<<7) /* all upper case */
#define PM_UNDEFINED (1<<7) /* undefined (autoloaded) shell function */
#define PM_READONLY (1<<8) /* readonly */
#define PM_TAGGED (1<<9) /* tagged */
#define PM_EXPORTED (1<<10) /* exported */
#define PM_READONLY (1<<8) /* readonly */
#define PM_TAGGED (1<<9) /* tagged */
#define PM_EXPORTED (1<<10) /* exported */
/* The following are the same since they *
* both represent -U option to typeset */
#define PM_UNIQUE (1<<11) /* remove duplicates */
#define PM_UNALIASED (1<<11) /* do not expand aliases when autoloading */
#define PM_UNIQUE (1<<11) /* remove duplicates */
#define PM_UNALIASED (1<<11) /* do not expand aliases when autoloading */
#define PM_TIED (1<<12) /* array tied to colon-path or v.v. */
#define PM_LOCAL (1<<13) /* this parameter will be made local */
#define PM_SPECIAL (1<<14) /* special builtin parameter */
#define PM_DONTIMPORT (1<<15) /* do not import this variable */
#define PM_RESTRICTED (1<<16) /* cannot be changed in restricted mode */
#define PM_UNSET (1<<17) /* has null value */
#define PM_REMOVABLE (1<<18) /* special can be removed from paramtab */
#define PM_AUTOLOAD (1<<19) /* autoloaded from module */
#define PM_TIED (1<<12) /* array tied to colon-path or v.v. */
#define PM_LOCAL (1<<13) /* this parameter will be made local */
#define PM_SPECIAL (1<<14) /* special builtin parameter */
#define PM_DONTIMPORT (1<<15) /* do not import this variable */
#define PM_RESTRICTED (1<<16) /* cannot be changed in restricted mode */
#define PM_UNSET (1<<17) /* has null value */
#define PM_REMOVABLE (1<<18) /* special can be removed from paramtab */
#define PM_AUTOLOAD (1<<19) /* autoloaded from module */
#define PM_NORESTORE (1<<20) /* do not restore value of local special */
/* Flags for extracting elements of arrays and associative arrays */
#define SCANPM_WANTVALS (1<<0)

View file

@ -100,7 +100,8 @@ fi])
dnl Do you want large file support, if available?
undefine([lfs])dnl
AC_ARG_ENABLE(lfs,
[ --enable-lfs turn on support for large files])
[ --enable-lfs turn on support for large files],
[lfs="$enableval"], [lfs=yes])
dnl Pathnames for global zsh scripts
undefine([etcdir])dnl
@ -183,7 +184,7 @@ dnl Do you want dynamically loaded binary modules.
undefine([dynamic])dnl
AC_ARG_ENABLE(dynamic,
[ --enable-dynamic allow dynamically loaded binary modules],
[dynamic="$enableval"], [dynamic=no])
[dynamic="$enableval"], [dynamic=yes])
dnl Do you want to compile as K&R C.
AC_ARG_ENABLE(ansi2knr,
@ -214,7 +215,7 @@ AC_ARG_ENABLE(function-subdirs,
[ --enable-function-subdirs install functions in subdirectories])
if test "x${FUNCTIONS_INSTALL+set}" != xset; then
FUNCTIONS_INSTALL="Core/* Base/* Builtins/* User/* Commands/*"
FUNCTIONS_INSTALL="Core/* Base/* Builtins/* User/* Commands/* Zle/*"
if test $dynamic != no; then
FUNCTIONS_INSTALL="${FUNCTIONS_INSTALL} Zftp/*"
fi
@ -243,7 +244,7 @@ AC_PROG_CC
dnl Check for large file support.
dnl This needs to be done early to get the stuff into the flags.
if test "x$enable_lfs" != x; then
if test $lfs != no; then
zsh_LARGE_FILE_SUPPORT
fi
@ -595,12 +596,11 @@ main() { return sizeof(ino_t) < 8; }
AC_DEFINE(INO_T_IS_64_BIT)
fi
if test "x$enable_lfs" != xno -o $zsh_cv_off_t_is_64_bit = yes \
if test $lfs != no -o $zsh_cv_off_t_is_64_bit = yes \
-o $zsh_cv_ino_t_is_64_bit = yes; then
AC_CACHE_CHECK(if compiler has a 64 bit type, zsh_cv_64_bit_type,
[if test "x$enable_lfs" != x -a "x$enable_lfs" != xyes \
-a "x$enable_lfs" != xno; then
zsh_64_BIT_TYPE(${enable_lfs}, zsh_cv_64_bit_type, force)
[if test $lfs != xyes -a $lfs != xno; then
zsh_64_BIT_TYPE(${lfs}, zsh_cv_64_bit_type, force)
else
zsh_64_BIT_TYPE(long long, zsh_cv_64_bit_type)
if test "$zsh_cv_64_bit_type" = no; then
@ -1171,8 +1171,10 @@ char *argv[];
DL_EXT="${DL_EXT=so}"
if test $zsh_cv_sys_elf = yes; then
DLLD="${DLLD=$CC}"
DLLDARG="${LDARG}"
else
DLLD="${DLLD=ld}"
DLLDARG=""
fi
if test -n "$GCC"; then
DLCFLAGS="${DLCFLAGS=-fpic}"
@ -1188,7 +1190,7 @@ char *argv[];
linux*|irix*|osf*) DLLDFLAGS="${DLLDFLAGS=-shared}" ;;
sunos*) DLLDFLAGS="${DLLDFLAGS=-assert nodefinitions}" ;;
sysv4*|esix*) DLLDFLAGS="${DLLDFLAGS=-G $ldflags}" ;;
netbsd*) DLLDFLAGS="${DLLDFLAGS=-x -shared --whole-archive}" ;;
netbsd*) DLLDFLAGS="${DLLDFLAGS=${DLLDARG}-x -shared --whole-archive}" ;;
aix*) DLLDFLAGS="${DLLDFLAGS=-G -bexpall -lc}" ;;
solaris*|sysv4*|esix*) DLLDFLAGS="${DLLDFLAGS=-G}" ;;
esac
@ -1340,11 +1342,13 @@ CLEAN_MK="${srcdir}/Config/clean.mk"
CONFIG_MK="${srcdir}/Config/config.mk"
dnl defs.mk is in the build tree, not the source tree
DEFS_MK="Config/defs.mk"
FUNCINST_MK="${srcdir}/Config/funcinst.mk"
VERSION_MK="${srcdir}/Config/version.mk"
AC_SUBST_FILE(CLEAN_MK)dnl
AC_SUBST_FILE(CONFIG_MK)dnl
AC_SUBST_FILE(DEFS_MK)dnl
AC_SUBST_FILE(FUNCINST_MK)dnl
AC_SUBST_FILE(VERSION_MK)dnl
real_no_create=$no_create