mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-27 04:40:59 +01:00
zsh-3.1.5-pws-24
This commit is contained in:
parent
a2159285e8
commit
346825df86
100 changed files with 4530 additions and 1578 deletions
288
ChangeLog
288
ChangeLog
|
|
@ -1,5 +1,293 @@
|
|||
1999-06-25 Peter Stephenson <pws@ibmth.difi.unipi.it>
|
||||
|
||||
* pws: 6857: Completion/Core/compinit,
|
||||
Completion/Core/compinstall, Doc/Zsh/compsys.yo: compinit and
|
||||
compinstall are now functions which unfunction and autoload
|
||||
themselves. _compdir is used by compinstall to record where
|
||||
it found the completion directories. compinit is now otherwise
|
||||
stuck with fpath.
|
||||
|
||||
* pws: 6851, 6853: typeset -g doesn't locallize parameters; bug
|
||||
that unset parameters were recreated global instead of at
|
||||
some higher local level; handle PM_AUTOLOAD consistent with other
|
||||
flags.
|
||||
|
||||
* Sven: 6850: Src/init.c: always generate a new pgrp for the
|
||||
shell, since the parent (e.g. xterm) may not have done that
|
||||
and zsh now runs programs in its own pgrp.
|
||||
|
||||
* Sven: 6848: Src/exec.c: don't suspend if the shell is the
|
||||
only thing to suspend (or something like that).
|
||||
|
||||
* Sven: 6841: Src/loop.c: %_ in else branches for PS4
|
||||
|
||||
1999-06-24 Peter Stephenson <pws@ibmth.difi.unipi.it>
|
||||
|
||||
* pws: 6834: Src/glob.c, Src/hashtable.c: dyncat() changed always
|
||||
to use heap memory (as it erroneously claimed); hashtable element
|
||||
tablename (used for debugging) freed.
|
||||
|
||||
* Bart: 6830: Src/params.c: don't create the hashtable for an
|
||||
assoc array on assignment unless there is something to put in it.
|
||||
|
||||
* Sven: 6825: Src/Zle_tricky.c: make sure path prefix and suffix
|
||||
are quoted in filename completion; recalculate length of match
|
||||
string.
|
||||
|
||||
* Sven: 6824: Src/exec.c, Src/signals.c: functions got deleted
|
||||
from the process table too early for job control.
|
||||
|
||||
* pws: 6823: Src/exec.c, Src/utils.c: names and line numbers
|
||||
of functions printed for errors during execution.
|
||||
|
||||
* Sven: 6822: Src/Zle/complist.c, Src/Zle/zle_tricky.c: assorted
|
||||
completion fixes: crash with old completion; too many spaces
|
||||
with menu inserting; too many beeps with LISTBEEP.
|
||||
|
||||
* Sven: 6819: Src/exec.c, Src/jobs.c, Src/signals.c: Run
|
||||
jobs inside shell constructs in the same process group as the
|
||||
shell itself.
|
||||
|
||||
* Sven: 6817: Src/Zle/comp.h, Src/Zle/complist.c,
|
||||
Src/Zle/zle_tricky.c: Change ZLS_SELECT to SELECTMIN;
|
||||
don't automatically switch on select widget until there are
|
||||
$SELECTMIN choices.
|
||||
|
||||
1999-06-23 Peter Stephenson <pws@ibmth.difi.unipi.it>
|
||||
|
||||
* pws: 6816: Doc/Zsh/params.yo, Src/utils.c: ZBEEP parameter
|
||||
gives string to output instead of beeping.
|
||||
|
||||
* Sven: 6815: Src/Zle/complist.c: switch off menu-select for
|
||||
hidden matches.
|
||||
|
||||
* pws: 6814: Doc/Zsh/mod_zle.yo, Doc/Zsh/options.yo,
|
||||
Doc/Zsh/zle.yo, Src/Zle/deltochar.c, Src/Zle/iwidgets.list,
|
||||
Src/Zle/zle_hist.c, Src/Zle/zle_main.c, Src/Zle/zle_misc.c,
|
||||
Src/Zle/zle_move.c, Src/Zle/zle_thingy.c, Src/Zle/zle_tricky.c,
|
||||
Src/Zle/zle_utils.c, Src/Zle/zle_vi.c, Src/Zle/zle_word.c:
|
||||
Zle determines whether to feep by the return status (except
|
||||
for some inner code loops); completion widgets return 1 if
|
||||
something failed in the hierarchy outside the widget function;
|
||||
the -n and -N options work properly.
|
||||
|
||||
* pws: 6812: Src/subst.c: ${(AA)foo=}, or anything that gives
|
||||
a null string after the =, creates an empty assoc array.
|
||||
|
||||
* pws: 6806: Completion/Core/compdump, Completion/Core/compinit,
|
||||
Completion/Core/compinstall, Doc/Zsh/compsys.yo: compdump is now
|
||||
a function which unfunctions itself; default dumpfile location
|
||||
is now ${ZDOTDIR:-$HOME}/.zcompdump
|
||||
|
||||
* Sven: 6807: Src/Zle/complist.c: accept-and-menu-complete
|
||||
advances the menu-select selection too.
|
||||
|
||||
* Sven: 6802: Src/Zle/complist.c: change some default colours
|
||||
|
||||
* pws: 6801: Doc/Zsh/builtins.yo, Src/builtin.c: Make emulate -L
|
||||
turn on LOCAL_TRAPS, too.
|
||||
|
||||
* Sven: 6796: Src/Zle/zle_main.c, Src/Zle/zle_thingy.c,
|
||||
Doc/Zsh/mod_zle.yo, Completion/Core/compinit: zle -la lists
|
||||
all widgets, just the name; zle -la <NAME> tests if <NAME> is
|
||||
defined.
|
||||
|
||||
* Sven: 6793: Src/Zle/complist.c, Src/Zle/zle_keymap.c,
|
||||
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>
|
||||
|
||||
* Sven: 6786: Src/Zle/zle_tricky.c, Doc/Zsh/compctl.yo: only use
|
||||
a range when you are after the first pattern in it.
|
||||
|
||||
* Sven: 6780: Src/Zle/complist.c: wasn't showinglist when it
|
||||
thought it was.
|
||||
|
||||
* Sven: 6778: don't delete function from job tables
|
||||
|
||||
* pws: 6776: Doc/Makefile.in, Doc/Zsh/compsys.yo,
|
||||
Doc/Zsh/mod_complist.yo: Tweakchen for menu-select patch;
|
||||
also (unposted) changed name collist to complist wherever it
|
||||
occurs.
|
||||
|
||||
* Sven: 6774, 6775: Src/Zle/collist.c, Src/Zle/comp.h,
|
||||
Src/Zle/zle.h, Src/Zle/zle_main.c, Src/Zle/zle_tricky.c,
|
||||
Doc/Zsh/compsys.yo, Doc/Zsh/mod_collist.yo,
|
||||
Doc/Zsh/mod_compctl.yo, Doc/Zsh/mod_deltochar.yo,
|
||||
Doc/Zsh/modules.yo, Completion/Core/_path_files: Improvements
|
||||
for menu-select widget; ZLS_SELECT turns menu-completion
|
||||
into menu-selection; key bindings more natural; highlighting
|
||||
more useful
|
||||
|
||||
* 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>
|
||||
|
||||
* Sven: 6760: Src/Zle/zle_tricky.c: menucompletion displaying new
|
||||
list of matches sometimes got confused.
|
||||
|
||||
* Sven: 6755: Src/jobs.c: status of restarted job including
|
||||
current shell processes was wrong.
|
||||
|
||||
* Sven: 6753: Src/Zle/collist.c, Src/xmods.conf:
|
||||
load collist
|
||||
|
||||
* Sven: 6747: Src/Zle/collist.c, Src/Zle/zle_main.c,
|
||||
Src/Zle/zle_tricky.c: menu-select allows you to move
|
||||
cursor to select completions; uses ma list colouring
|
||||
capability.
|
||||
|
||||
* Sven: 6742: Src/Zle/collist.c, Src/Zle/collist.mdd,
|
||||
Src/Zle/zle_main.c, Src/Zle/zle_tricky.c, Src/module.c,
|
||||
Src/zsh.h, Doc/Zsh/mod_collist.yo, Doc/Zsh/mod_compctly.yo,
|
||||
Doc/Zsh/mod_deltochar.yo, Doc/Zsh/modules.yo,
|
||||
Util/zsh-development-guide: collist module: colour completion
|
||||
lists by setting ZLS_COLOURS (or even ZLS_COLORS) variables.
|
||||
|
||||
* pws: 6737: Doc/Zsh/builtins.yo, Doc/Zsh/zle.yo: simplifications
|
||||
suggested by Bart.
|
||||
|
||||
* Bart: 6732: Doc/Zsh/compsys.yo: restore missing bits of Sven's
|
||||
patches (not the zle_tricky.c hunk).
|
||||
|
||||
* Bart: 6731: Doc/Zsh/compctl.yo: spelling correction
|
||||
|
||||
1999-06-20 Peter Stephenson <pws@ibmth.difi.unipi.it>
|
||||
|
||||
* zsh-3.1.5-pws-23 made available
|
||||
|
||||
* Sven/pws: 6616, 6609, 6726 (merged): `zle [ -N ] [ -n num ]
|
||||
widget args'; internal widgets handle arguments and return
|
||||
values; search commands use arguments; read -[kq] can use
|
||||
zle's key mechanism; zle -R [msg] redisplays line editor;
|
||||
digit-argument feeps if the keypress wasn't a digit;
|
||||
universal-argument handles argument as numeric.
|
||||
|
||||
* pws: 6725: Src/signals.c: more local traps: now don't add trap
|
||||
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>
|
||||
|
||||
* pws: 6718: Completion/Core/compinit, Completion/Core/compdump,
|
||||
Doc/Zsh/compsys.yo: rebind existing completion widgets for new
|
||||
completion instead of defining new ones.
|
||||
|
||||
* pws: 6717: Doc/Zsh/options.yo, Src/exec.c, Src/options.c,
|
||||
Src/signals.c, Src/zsh.h: Option LOCAL_TRAPS saves and restores
|
||||
traps on exit from functions; set for ksh emulation.
|
||||
|
||||
* Tanaka Akira: 6716: Completion/User/_chown: some systems use `:'
|
||||
as separator in chown.
|
||||
|
||||
* Oliver/Sven: 6709, 6710: Completion files Base/_subscript,
|
||||
User/_chown, User/_groups, User/_x_options: _subscript shows
|
||||
listing for ordinary arrays; new chown and chgrp completions;
|
||||
example _x_options can complete displays.
|
||||
|
||||
* Sven: 6707: Src/exec.c: Shell structures not at the end
|
||||
of a pipeline are suspendable. This is the only way
|
||||
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>
|
||||
|
||||
* pws: 6705: Doc/Zsh/builtins.yo, Src/builtin.c, Src/exec.c,
|
||||
Src/init.c, Src/input.c, Src/parse.c: some more LINENO
|
||||
subtleties: embedded function definitions have correct line
|
||||
number; all lines, not just ones with new PS1, are counted
|
||||
interactively; traps with trap builtin use line no. of
|
||||
surrounding environment.
|
||||
|
||||
* Sven: 6693: Src/Modules/parameter.c, Src/builtin.c, Src/exec.c,
|
||||
Src/input.c, Src/zsh.h: update LINENO properly when parsing a
|
||||
string.
|
||||
|
||||
* Sven: 6692: Src/Zle/comp.h, Src/Zle/compctl.c,
|
||||
Src/Zle/zle_tricky.c, Doc/Zsh/compwid.yo,
|
||||
Completion/Builtins/_kill, Completion/Builtins/_wait,
|
||||
Completion/User/_gdb: allow the -y option to compadd for
|
||||
specifying an array to use when listing.
|
||||
|
||||
* Sven: 6689: Src/Zle/zle_tricky.c, Completion/Base/_subscript:
|
||||
test for closing bracket in get_comp_string().
|
||||
|
||||
* Oliver: 6688: Zsh/compsys.yo, Zsh/func.yo, Zsh/mod_zle.yo,
|
||||
Zsh/params.yo, Zsh/zftpsys.yo: spelling changes.
|
||||
|
||||
* Wayne: 6682: Src/hist.c: Uniquified history commands are limited
|
||||
to size $SAVEHIST, so that the last $((HISTSIZE-SAVEHIST))
|
||||
commands are always available even with HIST_EXPIRE_DUPS_FIRST.
|
||||
|
||||
* Sven: 6686: Completion/Core/_match, Completion/Core/_path_files,
|
||||
Doc/Zsh/compsys.yo: New configuration keys path_cursor,
|
||||
match_insert.
|
||||
|
||||
* Sven: 6685: Src/Zle/compctl.c, Src/Zle/zle_params.c,
|
||||
Doc/Zsh/zle.yo, Completion/Base/_first,
|
||||
Completion/Commands/_correct_filename,
|
||||
Completion/Commands/_most_recent_file,
|
||||
Completion/Core/_approximate, Completion/Core/_expand,
|
||||
Completion/Core/_list: NUMERIC is unset if no prefix was given;
|
||||
it may be unset explicitly, and if set again will be restored in
|
||||
the expected way.
|
||||
|
||||
* Wayne: 6683: Src/exec.c: ambiguous brace
|
||||
|
||||
* Wayne: 6681: Src/builtin.c: start-of-loop check for history -r
|
||||
was wrong.
|
||||
|
||||
1999-06-16 Peter Stephenson <pws@ibmth.difi.unipi.it>
|
||||
|
||||
* pws: 6679: Src/Zle/zle_thingy.c, Doc/Zsh/compwid.yo: always
|
||||
use .complete-word etc. as widget type in zle -C.
|
||||
|
||||
* pws: 6677: Doc/Zsh/guide.yo: avoid TeX overfull hbox problem.
|
||||
|
||||
* Andrej: 6674: Doc/zsh.yo, Doc/ztexi.yo: change order of initial
|
||||
formatting instructions to make interaction with system
|
||||
configuration files better.
|
||||
|
||||
* pws: 6660: Doc/Zsh/compctl.yo: pointer to new completion system
|
||||
at top of compctl documentation.
|
||||
|
||||
* pws: 6659: Src/Zle/zle_tricky.c: a couple of NULL's should be 0's
|
||||
|
||||
* pws: 6658: Doc/Zsh/options.yo, Src/init.c: options strings at
|
||||
shell startup can end with whitespace (for #!), but anything
|
||||
after the whitespace causes an error.
|
||||
|
||||
* Sven: 6657: Completion files Base/_subscript,
|
||||
Builtins/_autoload, Builtins/_bindkey, Builtins/_echotc,
|
||||
Builtins/_kill, Builtins/_limits, Builtins/_wait,
|
||||
Builtins/_zmodload, User/_dd, User/_find, User/_gdb, User/_make,
|
||||
User/_mh, User/_rlogin, User/_x_options: New gdb completion;
|
||||
improved make completion; use compadd in preference to compgen
|
||||
-[sk]; configuration keys ps_args, ps_listsargs.
|
||||
|
||||
* Sven: 6654: Src/Zle/zle_tricky.c: empty display list after -y.
|
||||
|
||||
* Bart: 6652: Src/exec.c: trailing spaces confused #! emulation.
|
||||
|
||||
* Sven: 6649: Src/Zle/zle_tricky.c: behaviour of compctl -l.
|
||||
|
||||
* 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>
|
||||
|
||||
* Tanaka Akira: 6642: Completion/Base/_tilde: complete directory
|
||||
stack elements after ~+ or ~-.
|
||||
|
||||
* Tanaka Akira: 6641: Src/subst.c: treat ~-0 like ~0
|
||||
|
||||
* pws: 6639: configure.in: don't try type of $enable_val if empty
|
||||
(needed when off_t/ino_t are 64-bit without explicit enabling).
|
||||
|
||||
* zsh-3.1.5-pws-22 made available
|
||||
|
||||
* Oliver: 6636: Completion/Builtins/_limits: wasn't working
|
||||
|
||||
* Bart: 6617 + minor changes: Src/utils.c: Be more careful keeping
|
||||
|
|
|
|||
|
|
@ -40,9 +40,9 @@
|
|||
# PREFIX="$PREFIX[1,-2]"
|
||||
# # If a numeric prefix is given, we use it as the number of
|
||||
# # lines (multiplied by ten below) in the history to search.
|
||||
# if [[ NUMERIC -gt 1 ]]; then
|
||||
# if [[ ${NUMERIC:-1} -gt 1 ]]; then
|
||||
# max=$NUMERIC
|
||||
# NUMERIC=1
|
||||
# unset NUMERIC
|
||||
# else
|
||||
# # The default is to search the last 100 lines.
|
||||
# max=10
|
||||
|
|
|
|||
|
|
@ -1,7 +1,27 @@
|
|||
#compdef -subscript-
|
||||
|
||||
if [[ ${(Pt)${compstate[parameter]}} = assoc* ]]; then
|
||||
compgen -S ']' -k "( ${(kP)${compstate[parameter]}} )"
|
||||
if [[ "$RBUFFER" = \]* ]]; then
|
||||
compadd -S '' - "${(@kP)${compstate[parameter]}}"
|
||||
else
|
||||
compadd -S ']' - "${(@kP)${compstate[parameter]}}"
|
||||
fi
|
||||
elif [[ ${(Pt)${compstate[parameter]}} = array* ]]; then
|
||||
local list i j
|
||||
|
||||
ind=( {1..${#${(P)${compstate[parameter]}}}} )
|
||||
list=()
|
||||
for i in "$ind[@]"; do
|
||||
[[ "$i" = ${PREFIX}*${SUFFIX} ]] &&
|
||||
list=( "$list[@]"
|
||||
"${(r:4:: ::):)i} $(print -D ${(P)${compstate[parameter]}[$i]})" )
|
||||
done
|
||||
|
||||
if [[ "$RBUFFER" = \]* ]]; then
|
||||
compadd -S '' -V default -y list - "$ind[@]"
|
||||
else
|
||||
compadd -S ']' -V default -y list - "$ind[@]"
|
||||
fi
|
||||
else
|
||||
_compalso -math-
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -7,10 +7,32 @@
|
|||
# `(( compstate[nmatches] )) || compgen -nu -qS/'
|
||||
# below that.
|
||||
|
||||
local c s dirs list
|
||||
|
||||
if [[ "$SUFFIX" = */* ]]; then
|
||||
ISUFFIX="/${SUFFIX#*/}$ISUFFIX"
|
||||
SUFFIX="${SUFFIX%%/*}"
|
||||
compgen -nu -S ''
|
||||
s=(-S '')
|
||||
else
|
||||
compgen -nu -qS/
|
||||
s=(-qS/)
|
||||
fi
|
||||
|
||||
if compset -P +; then
|
||||
dirs="$(dirs -v)"
|
||||
list=("${(f)dirs}")
|
||||
[[ -o pushdminus ]] && dirs="$(awk '{ $1 = '$#list' - $1 - 1;
|
||||
printf("%s\t%s\n", $1, $2); }' <<<$dirs)"
|
||||
list=("${(@)list% *}")
|
||||
c=(-y '$dirs' -k "($list)")
|
||||
elif compset -P -; then
|
||||
dirs="$(dirs -v)"
|
||||
list=("${(f)dirs}")
|
||||
[[ ! -o pushdminus ]] && dirs="$(awk '{ $1 = '$#list' - $1 - 1;
|
||||
printf("%s\t%s\n", $1, $2); }' <<<$dirs)"
|
||||
list=("${(@)list% *}")
|
||||
c=(-y '$dirs' -k "($list)")
|
||||
else
|
||||
c=(-nu)
|
||||
fi
|
||||
|
||||
compgen "$c[@]" "$s[@]"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
#compdef autoload
|
||||
|
||||
compgen -s '${^fpath}/*(N:t)'
|
||||
compadd - ${^fpath}/*(N:t)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
# Where appropriate, will complete keymaps instead of widgets.
|
||||
|
||||
if [[ "$words[2]" = -*[DAN]* || "$words[CURRENT-1]" = -*M ]]; then
|
||||
compgen -s '$(bindkey -l)'
|
||||
compadd - $(bindkey -l)
|
||||
else
|
||||
compgen -b -M 'r:|-=* r:|=*'
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
#compdef echotc
|
||||
|
||||
compgen -k '(al dc dl do le up al bl cd ce cl cr dc dl do ho is le ma nd nl se so up)'
|
||||
compadd al dc dl do le up al bl cd ce cl cr dc dl do ho is le ma nd nl se so up
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@
|
|||
local list
|
||||
|
||||
if compset -P 1 -; then
|
||||
compgen -k "($signals[1,-3])"
|
||||
compadd $signals[1,-3]
|
||||
else
|
||||
local ret=1
|
||||
|
||||
compgen -P '%' -j && ret=0
|
||||
list=("$(ps 2>/dev/null)")
|
||||
compgen -y '$list' -s '${${${(f)"$(ps 2>/dev/null)"}[2,-1]## #}%% *}' &&
|
||||
list=("${(@Mr:COLUMNS-1:)${(f)$(ps ${compconfig[ps_listargs]:-$compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ ]#${PREFIX}[0-9]#${SUFFIX}[ ]*}")
|
||||
compadd -y list - ${${${(f)"$(ps $compconfig[ps_args] 2>/dev/null)"}[2,-1]## #}%% *} &&
|
||||
ret=0
|
||||
|
||||
return ret
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
#compdef limit unlimit
|
||||
|
||||
compgen -s '${${(f)"$(limit)"}%% *}'
|
||||
compadd ${${(f)"$(limit)"}%% *}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,20 @@
|
|||
#compdef wait
|
||||
|
||||
# This uses two configuration keys:
|
||||
#
|
||||
# ps_args
|
||||
# This can be set to options of the ps(1) command that should be
|
||||
# used when invoking it to get the pids to complete.
|
||||
#
|
||||
# ps_listargs
|
||||
# This defaults to the value of the `ps_args' key and defines
|
||||
# options for the ps command that are to be used when creating
|
||||
# the list to display during completion.
|
||||
|
||||
local list ret=1
|
||||
|
||||
compgen -P '%' -j && ret=0
|
||||
list=("$(ps 2>/dev/null)")
|
||||
compgen -y '$list' -s '${${${(f)"$(ps 2>/dev/null)"}[2,-1]## #}%% *}' && ret=0
|
||||
list=("${(@Mr:COLUMNS-1:)${(f)$(ps ${compconfig[ps_listargs]:-$compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ ]#${PREFIX}[0-9]#${SUFFIX}[ ]*}")
|
||||
compadd -y list - ${${${(f)"$(ps $compconfig[ps_args] 2>/dev/null)"}[2,-1]## #}%% *} && ret=0
|
||||
|
||||
return ret
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ local fl="$words[2]"
|
|||
if [[ "$fl" = -*(a*u|u*a)* || "$fl" = -*a* && CURRENT -ge 4 ]]; then
|
||||
compgen -B
|
||||
elif [[ "$fl" = -*u* ]]; then
|
||||
compgen -s '$(zmodload)'
|
||||
compadd - $(zmodload)
|
||||
else
|
||||
compgen -s '${^module_path}/*(N:t:r)'
|
||||
compadd - ${^module_path}/*(N:t:r)
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
DISTFILES_SRC='
|
||||
.distfiles _correct_filename _correct_word _most_recent_file
|
||||
.distfiles _correct_filename _most_recent_file
|
||||
'
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ if [[ -z $WIDGET ]]; then
|
|||
file=$1
|
||||
local IPREFIX
|
||||
else
|
||||
(( NUMERIC > 1 )) && max_approx=$NUMERIC
|
||||
(( ${NUMERIC:-1} > 1 )) && max_approx=$NUMERIC
|
||||
fi
|
||||
|
||||
if [[ $file = \~*/* ]]; then
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ local file tilde etilde
|
|||
if [[ $PREFIX = \~*/* ]]; then
|
||||
tilde=${PREFIX%%/*}
|
||||
etilde=${~tilde}
|
||||
file=($~PREFIX*$~SUFFIX(om[$NUMERIC]N))
|
||||
file=($~PREFIX*$~SUFFIX(om[${NUMERIC:-1}]N))
|
||||
file=(${file/#$etilde/$tilde})
|
||||
else
|
||||
file=($~PREFIX*$~SUFFIX(om[$NUMERIC]N))
|
||||
file=($~PREFIX*$~SUFFIX(om[${NUMERIC:-1}]N))
|
||||
fi
|
||||
(( $#file )) && compadd -U -i "$IPREFIX" -I "$ISUFFIX" -f -Q $file
|
||||
|
|
|
|||
|
|
@ -89,14 +89,14 @@ fi
|
|||
|
||||
# Get the number of errors to accept.
|
||||
|
||||
if [[ "$cfgacc" = *[nN]* && NUMERIC -ne 1 ]]; then
|
||||
if [[ "$cfgacc" = *[nN]* && ${NUMERIC:-1} -ne 1 ]]; then
|
||||
# Stop if we also have a `!'.
|
||||
|
||||
[[ "$cfgacc" = *\!* ]] && return 1
|
||||
|
||||
# Prefer the numeric argument if that has a sensible value.
|
||||
|
||||
comax="$NUMERIC"
|
||||
comax="${NUMERIC:-1}"
|
||||
else
|
||||
comax="${cfgacc//[^0-9]}"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
# In this case, expansion of substitutions will be done if the
|
||||
# expression evaluates to `1'. For example, with
|
||||
#
|
||||
# compconf expand_substitute='NUMERIC != 1'
|
||||
# compconf expand_substitute='${NUMERIC:-1} != 1'
|
||||
#
|
||||
# substitution will be performed only if given an explicit numeric
|
||||
# argument other than `1', as by typing ESC 2 TAB.
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
# will be done if the expression evaluates to `1'.
|
||||
# For example, with
|
||||
#
|
||||
# compconf list_condition='NUMERIC != 1'
|
||||
# compconf list_condition='${NUMERIC:-1} != 1'
|
||||
#
|
||||
# delaying will be done only if given an explicit numeric argument
|
||||
# other than `1'.
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
# expand-or-complete function because otherwise the pattern will
|
||||
# be expanded using globbing.
|
||||
#
|
||||
# Configuration key used:
|
||||
# Configuration keys used:
|
||||
#
|
||||
# match_original
|
||||
# If this is set to a `only', pattern matching will only be tried
|
||||
|
|
@ -18,6 +18,11 @@
|
|||
# no completions, matching will be tried again with a `*' inserted
|
||||
# at the cursor position. If this key is not set or set to an empty
|
||||
# string, matching will only be attempted with the `*' inserted.
|
||||
#
|
||||
# match_insert
|
||||
# If this is set to a string starting with `unambig', menucompletion
|
||||
# will only be turned on if no unambiguous string could be built
|
||||
# that is at least as long as the original string.
|
||||
|
||||
local tmp opm="$compstate[pattern_match]" ret=0
|
||||
|
||||
|
|
@ -37,7 +42,12 @@ if [[ -n "$compconfig[match_original]" ]]; then
|
|||
compstate[pattern_match]="$opm"
|
||||
compstate[matcher]="$compstate[total_matchers]"
|
||||
|
||||
(( ret )) && return 0
|
||||
if (( ret )); then
|
||||
[[ "$compconfig[match_insert]" = unambig* &&
|
||||
$#compstate[unambiguous] -ge ${#:-${PREFIX}${SUFFIX}} ]] &&
|
||||
compstate[pattern_insert]=unambiguous
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# No completion with inserting `*'?
|
||||
|
|
@ -50,4 +60,10 @@ _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
|
||||
|
||||
return 1-ret
|
||||
|
|
|
|||
|
|
@ -11,12 +11,17 @@
|
|||
# with one of the suffixes thus given are treated like files with one
|
||||
# of the suffixes in the `fignore' array in normal completion.
|
||||
#
|
||||
# This function supports one configuration key:
|
||||
# This function supports two configuration keys:
|
||||
#
|
||||
# path_expand
|
||||
# If this is set to a non-empty string, the partially typed path
|
||||
# from the line will be expanded as far as possible even if trailing
|
||||
# pathname components can not be completed.
|
||||
#
|
||||
# path_cursor
|
||||
# If this is set to an non-empty string, the cursor will be placed
|
||||
# in the path after the ambiguous pathname component even when using
|
||||
# menucompletion.
|
||||
|
||||
local linepath realpath donepath prepath testpath exppath
|
||||
local tmp1 tmp2 tmp3 tmp4 i orig pre suf tpre tsuf
|
||||
|
|
@ -304,10 +309,11 @@ for prepath in "$prepaths[@]"; do
|
|||
# it as far as possible.
|
||||
|
||||
if [[ -n $menu ]]; then
|
||||
[[ -n "$compconfig[path_cursor]" ]] && compstate[to_end]=''
|
||||
if [[ "$tmp3" = */* ]]; then
|
||||
compadd -Uf -p "$linepath$testpath" -s "/${tmp3#*/}" \
|
||||
-W "$prepath$realpath$testpath" "$ignore[@]" \
|
||||
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" \
|
||||
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" -M 'r:|/=* r:|=*' \
|
||||
"$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
|
||||
- "${(@)tmp1%%/*}"
|
||||
else
|
||||
|
|
@ -371,9 +377,9 @@ done
|
|||
exppaths=( "${(@)exppaths:#$orig}" )
|
||||
|
||||
if [[ -n "$compconfig[path_expand]" &&
|
||||
$#exppaths -ne 0 && nm -eq compstate[nmatches] ]]; then
|
||||
compadd -U -S '' "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
|
||||
-p "$linepath" - "${(@)exppaths}"
|
||||
$#exppaths -eq 0 && 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] ]]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# This is a file to be sourced to dump the definitions for new-style
|
||||
# This is a function to dump the definitions for new-style
|
||||
# completion defined by 'compinit' in the same directory. The output
|
||||
# should be directed into the "compinit.dump" in the same directory as
|
||||
# compinit. If you rename init, just stick .dump onto the end of whatever
|
||||
|
|
@ -9,12 +9,14 @@
|
|||
# To do this, simply remove the .dump file, start a new shell, and
|
||||
# create the .dump file as before. Again, compinit -d handles this
|
||||
# automatically.
|
||||
#
|
||||
# It relies on KSH_ARRAYS not being set.
|
||||
|
||||
# Print the number of files used for completion. This is used in compinit
|
||||
# to see if auto-dump should re-dump the dump-file.
|
||||
|
||||
emulate -L zsh
|
||||
|
||||
typeset _d_file _d_f _d_bks _d_line _d_als
|
||||
|
||||
_d_file=${compconfig[dumpfile]-${0:h}/compinit.dump}
|
||||
|
||||
typeset -U _d_files
|
||||
|
|
@ -22,8 +24,6 @@ _d_files=( ${^~fpath}/_(|*[^~])(N:t) )
|
|||
|
||||
print "#files: $#_d_files" > $_d_file
|
||||
|
||||
unset _d_files
|
||||
|
||||
# First dump the arrays _comps and _patcomps. The quoting hieroglyphyics
|
||||
# ensure that a single quote inside a variable is itself correctly quoted.
|
||||
|
||||
|
|
@ -44,11 +44,13 @@ print >> $_d_file
|
|||
# Now dump the key bindings. We dump all bindings for zle widgets
|
||||
# whose names start with a underscore.
|
||||
# We need both the zle -C's and the bindkey's to recreate.
|
||||
# We can ignore any zle -C which rebinds a standard widget (second
|
||||
# argument to zle does not begin with a `_').
|
||||
|
||||
_d_bks=()
|
||||
zle -lL |
|
||||
while read -rA _d_line; do
|
||||
if [[ ${_d_line[5]} = _* ]]; then
|
||||
if [[ ${_d_line[3]} = _* && ${_d_line[5]} = _* ]]; then
|
||||
print -r - ${_d_line}
|
||||
_d_bks=($_d_bks ${_d_line[3]})
|
||||
fi
|
||||
|
|
@ -86,4 +88,5 @@ done >> $_d_file
|
|||
|
||||
print >> $_d_file
|
||||
|
||||
unset _d_line _d_zle _d_bks _d_als _d_f _f_file
|
||||
unfunction compdump
|
||||
autoload -U compdump
|
||||
|
|
|
|||
|
|
@ -41,15 +41,13 @@
|
|||
# See the file `compdump' for how to speed up initialisation.
|
||||
|
||||
# If we got the `-d'-flag, we will automatically dump the new state (at
|
||||
# the end).
|
||||
# `-f dir' is used to pass down the directory where this file was
|
||||
# found. This is necessary if functionargzero is not set.
|
||||
# If we were given an argument, this will be taken as the name of the
|
||||
# file in which to store the dump.
|
||||
# the end). This takes the dumpfile as an argument.
|
||||
|
||||
emulate -L zsh
|
||||
|
||||
typeset _i_dumpfile _i_files _i_line _i_done _i_dir _i_autodump=0
|
||||
typeset _i_tag _i_file
|
||||
|
||||
_i_fdir=''
|
||||
_i_dumpfile=''
|
||||
_i_autodump=0
|
||||
while [[ $# -gt 0 && $1 = -[df] ]]; do
|
||||
if [[ "$1" = -d ]]; then
|
||||
_i_autodump=1
|
||||
|
|
@ -59,56 +57,27 @@ while [[ $# -gt 0 && $1 = -[df] ]]; do
|
|||
shift
|
||||
fi
|
||||
elif [[ "$1" = -f ]]; then
|
||||
# Used by compinstall to pass down directory where compinit was found
|
||||
# Not used any more; use _compdir
|
||||
shift
|
||||
_i_fdir="$1"
|
||||
shift
|
||||
fi
|
||||
done
|
||||
# Get the directory if we don't have it already and we can
|
||||
if [[ -z "$_i_fdir" && -o functionargzero && $0 = */* ]]; then
|
||||
_i_fdir=${0:h}
|
||||
fi
|
||||
|
||||
# The associative array containing the definitions for the commands.
|
||||
# Definitions for patterns will be stored in the normal array `_patcomps'.
|
||||
|
||||
typeset -A _comps
|
||||
typeset -gA _comps
|
||||
_patcomps=()
|
||||
|
||||
# This is the associative array used for configuration.
|
||||
|
||||
typeset -A compconfig
|
||||
typeset -gA compconfig
|
||||
|
||||
# Standard initialisation for `compconfig'.
|
||||
if [[ -n $_i_dumpfile ]]; then
|
||||
# Explicitly supplied dumpfile.
|
||||
compconfig[dumpfile]="$_i_dumpfile"
|
||||
elif [[ -o functionargzero ]]; then
|
||||
# We can deduce it from the name of this script
|
||||
compconfig[dumpfile]="$0.dump"
|
||||
elif [[ -n $_i_fdir ]]; then
|
||||
# We were told what directory to use.
|
||||
compconfig[dumpfile]="$_i_fdir/compinit.dump"
|
||||
else
|
||||
compconfig[dumpfile]=''
|
||||
fi
|
||||
|
||||
if [[ -n $compconfig[dumpfile] ]]; then
|
||||
# Check the file is writeable. If it doesn't exist, the
|
||||
# only safe way is to try and create it.
|
||||
if [[ -f $compconfig[dumpfile] ]]; then
|
||||
[[ -w $compconfig[dumpfile] ]] || compconfig[dumpfile]=''
|
||||
elif touch $compconfig[dumpfile] >& /dev/null; then
|
||||
rm -f $compconfig[dumpfile]
|
||||
else
|
||||
compconfig[dumpfile]=''
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z $compconfig[dumpfile] ]]; then
|
||||
# If no dumpfile given, or it was not writeable, then use
|
||||
# user's ZDOTDIR.
|
||||
compconfig[dumpfile]="${ZDOTDIR:-$HOME}/.zcompdump"
|
||||
fi
|
||||
|
||||
|
|
@ -215,7 +184,11 @@ compdef() {
|
|||
fi
|
||||
|
||||
# Define the widget.
|
||||
if [[ $1 = .* ]]; then
|
||||
zle -C "$func" "$1" "$func"
|
||||
else
|
||||
zle -C "$func" ".$1" "$func"
|
||||
fi
|
||||
shift
|
||||
|
||||
# And bind the keys...
|
||||
|
|
@ -321,22 +294,32 @@ _i_files=( ${^~fpath:/.}/_(|*[^~])(N:t) )
|
|||
if [[ $#_i_files -lt 20 ]]; then
|
||||
# Too few files: we need some more directories
|
||||
# Assume that we need to add the compinit directory to fpath.
|
||||
if [[ -n $_i_fdir ]]; then
|
||||
if [[ $_i_fdir = */Core ]]; then
|
||||
if [[ -n $_compdir ]]; then
|
||||
if [[ $_compdir = */Core ]]; then
|
||||
# Add all the Completion subdirectories
|
||||
fpath=(${_i_fdir:h}/*(/) $fpath)
|
||||
elif [[ -d $_i_fdir/Core ]]; then
|
||||
fpath=(${_compdir:h}/*(/) $fpath)
|
||||
elif [[ -d $_compdir/Core ]]; then
|
||||
# Likewise
|
||||
fpath=(${_i_fdir}/*(/) $fpath)
|
||||
else
|
||||
fpath=($_i_fdir $fpath)
|
||||
fpath=(${_compdir}/*(/) $fpath)
|
||||
fi
|
||||
_i_files=( ${^~fpath:/.}/_(|*[^~])(N:t) )
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# Rebind the standard widgets
|
||||
for _i_line in complete-word delete-char-or-list expand-or-complete \
|
||||
expand-or-complete-prefix list-choices menu-complete \
|
||||
menu-expand-or-complete reverse-menu-complete; do
|
||||
zle -C $_i_line .$_i_line _main_complete
|
||||
done
|
||||
zle -la menu-select && zle -C menu-select .menu-select _main_complete
|
||||
|
||||
_i_done=''
|
||||
|
||||
# Make sure compdump is available, even if we aren't going to use it.
|
||||
autoload -U compdump compinstall
|
||||
|
||||
# If we have a dump file, load it.
|
||||
|
||||
if [[ -f "$compconfig[dumpfile]" ]]; then
|
||||
|
|
@ -345,7 +328,6 @@ if [[ -f "$compconfig[dumpfile]" ]]; then
|
|||
builtin . "$compconfig[dumpfile]"
|
||||
_i_done=yes
|
||||
fi
|
||||
unset _i_line
|
||||
fi
|
||||
if [[ -z "$_i_done" ]]; then
|
||||
for _i_dir in $fpath; do
|
||||
|
|
@ -369,30 +351,12 @@ if [[ -z "$_i_done" ]]; then
|
|||
done
|
||||
done
|
||||
|
||||
bindkey |
|
||||
while read -rA _i_line; do
|
||||
case "$_i_line[2]" in
|
||||
(complete-word) ;&
|
||||
(delete-char-or-list) ;&
|
||||
(expand-or-complete) ;&
|
||||
(expand-or-complete-prefix) ;&
|
||||
(list-choices) ;&
|
||||
(menu-complete) ;&
|
||||
(menu-expand-or-complete) ;&
|
||||
(reverse-menu-complete)
|
||||
zle -C _complete_$_i_line[2] $_i_line[2] _main_complete
|
||||
bindkey "${_i_line[1][2,-2]}" _complete_$_i_line[2]
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
unset _i_dir _i_line _i_file _i_tag
|
||||
|
||||
# If autodumping was requested, do it now.
|
||||
|
||||
if [[ -n ${_i_fdir} && $_i_autodump = 1 ]]; then
|
||||
builtin . ${_i_fdir}/compdump
|
||||
if [[ $_i_autodump = 1 ]]; then
|
||||
compdump
|
||||
fi
|
||||
fi
|
||||
|
||||
unset _i_files _i_initname _i_done _i_autodump _i_fdir _i_dumpfile
|
||||
unfunction compinit
|
||||
autoload -U compinit
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# available in some directory; they should have been installed with the
|
||||
# the shell (except we haven't written that yet).
|
||||
#
|
||||
# Source this script (e.g. `. /path/compinstall') and answer the questions.
|
||||
# Run this script as a function and answer the questions.
|
||||
#
|
||||
# Normally, this will alter ~/.zshrc (or wherever ZDOTDIR puts it), but you
|
||||
# can make that unwritable and it will leave the lines in a temporary file
|
||||
|
|
@ -23,33 +23,13 @@
|
|||
# - Could add code for setting other completers and options.
|
||||
# - Could add keys for context-sensitive help.
|
||||
|
||||
# Save the options. We will need to trap ^C to make sure they get
|
||||
# restored properly.
|
||||
typeset -A _ci_options
|
||||
_ci_options=($(setopt kshoptionprint;setopt))
|
||||
[[ -o kshoptionprint ]] || _ci_options[kshoptionprint]=off
|
||||
[[ -o monitor ]] && _ci_options[monitor]=on
|
||||
[[ -o zle ]] && _ci_options[zle]=on
|
||||
|
||||
emulate zsh
|
||||
|
||||
TRAPINT() {
|
||||
unsetopt ${(k)_ci_options[(R)off]}
|
||||
setopt ${(k)_ci_options[(R)on]}
|
||||
|
||||
unset _ci_options _ci_f _ci_fdir _ci_files _ci_dumpfile _ci_lines
|
||||
unset _ci_type _ci_completer _ci_accept _ci_cprompt _ci_startline
|
||||
unset _ci_endline _ci_ifile _ci_tmpf _ci_defaults _ci_compconf _ci_warn
|
||||
unset _ci_dtype _ci_existing _ci_line
|
||||
|
||||
if (( $1 )); then
|
||||
print Aborted.
|
||||
unfunction TRAPINT
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
emulate -L zsh
|
||||
|
||||
typeset _ci_options _ci_f _ci_fdir _ci_files _ci_dumpfile _ci_lines
|
||||
typeset _ci_type _ci_completer _ci_accept _ci_cprompt _ci_startline
|
||||
typeset _ci_endline _ci_ifile _ci_tmpf _ci_compconf _ci_warn
|
||||
typeset _ci_dtype _ci_existing _ci_line
|
||||
|
||||
# Look for the defaults.
|
||||
_ci_startline='# The following lines were added by compinstall'
|
||||
|
|
@ -60,6 +40,7 @@ _ci_lines=''
|
|||
_ci_existing=''
|
||||
|
||||
typeset -A _ci_defaults
|
||||
|
||||
if [[ -f $_ci_ifile ]]; then
|
||||
# This assumes the lines haven't been altered by the user too much
|
||||
# after they were added.
|
||||
|
|
@ -83,10 +64,12 @@ if [[ -f $_ci_ifile ]]; then
|
|||
fi
|
||||
_ci_existing="${_ci_existing} $_ci_line
|
||||
"
|
||||
elif [[ $_ci_line[1] = . && $_ci_line[2] = */compinit ]]; then
|
||||
# parse the line sourcing compinit
|
||||
[[ $_ci_line[3] = -f ]] && _ci_fdir=$_ci_line[4]
|
||||
elif [[ $_ci_line[1] = compinit ]]; then
|
||||
# parse the line running compinit
|
||||
[[ $_ci_line[2] = -f ]] && _ci_fdir=$_ci_line[3]
|
||||
[[ $_ci_line[-2] = -d ]] && _ci_dumpfile=$_ci_line[-1]
|
||||
elif [[ $_ci_line[1] = _compdir=* ]]; then
|
||||
_ci_fdir=${_ci_line[1]##_compdir=}
|
||||
elif [[ $_ci_line[1] = compconf ]]; then
|
||||
# parse a compconf component as second argument (should be completer)
|
||||
[[ $_ci_line[2] = completer=* ]] &&
|
||||
|
|
@ -94,7 +77,7 @@ if [[ -f $_ci_ifile ]]; then
|
|||
[[ $_ci_line[-1] == \\ ]] && _ci_compconf=1
|
||||
_ci_existing="${_ci_existing}$_ci_line
|
||||
"
|
||||
elif [[ $_ci_line[1] != \#* ]]; then
|
||||
elif [[ $_ci_line[1] != \#* && $_ci_line[1] != (autoload|\[\[) ]]; then
|
||||
if [[ -z $_ci_warn ]]; then
|
||||
_ci_warn=1
|
||||
print "Warning: existing lines in compinstall setup not understood:"
|
||||
|
|
@ -166,7 +149,7 @@ fi
|
|||
# Set up the dumpfile
|
||||
_ci_dtype=existing
|
||||
if [[ -z $_ci_dumpfile ]]; then
|
||||
_ci_dumpfile="${_ci_fdir}/compinit.dump"
|
||||
_ci_dumpfile="${ZDOTDIR:-$HOME}/.zcompdump"
|
||||
_ci_dtype=standard
|
||||
fi
|
||||
|
||||
|
|
@ -184,7 +167,6 @@ else
|
|||
I will force completion to dump its status, which will speed up the shell's
|
||||
start-up considerably. However, I can't write the file I'd like to, namely
|
||||
${_ci_dumpfile}. Please edit a replacement."
|
||||
_ci_dumpfile='~/.compinit.dump'
|
||||
vared _ci_dumpfile
|
||||
while ! touch ${~_ci_dumpfile} >& /dev/null; do
|
||||
print "Sorry, I can't write that either. Try again."
|
||||
|
|
@ -193,7 +175,10 @@ ${_ci_dumpfile}. Please edit a replacement."
|
|||
[[ -s $_ci_dumpfile ]] || rm -f $_ci_dumpfile
|
||||
fi
|
||||
|
||||
_ci_lines="${_ci_lines}. $_ci_fdir/compinit -f $_ci_fdir -d"
|
||||
_ci_lines="${_ci_lines}_compdir=$_ci_fdir
|
||||
[[ -z \$fpath[(r)\$_compdir] ]] && fpath=(\$_compdir \$fpath)
|
||||
autoload -U compinit
|
||||
compinit -d"
|
||||
[[ $_ci_dtype != standard ]] && _ci_lines="${_ci_lines} $_ci_dumpfile"
|
||||
_ci_lines="${_ci_lines}
|
||||
"
|
||||
|
|
@ -363,6 +348,7 @@ $_ci_lines$_ci_endline" >>$_ci_ifile &&
|
|||
print "\nSuccessfully appended lines to $_ci_ifile."
|
||||
fi
|
||||
|
||||
TRAPINT 0
|
||||
unfunction compinstall
|
||||
autoload -U compinstall
|
||||
|
||||
return 0
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
DISTFILES_SRC='
|
||||
.distfiles
|
||||
_a2ps _compress _configure _dd _dvi _find _gunzip _gzip _hosts
|
||||
_make _man _mh _pdf _ps _rcs _rlogin _strip _stty _tar _tar_archive
|
||||
_tex _uncompress _x_options _xfig
|
||||
_a2ps _chown _compress _configure _dd _dvi _find _groups _gunzip _gzip
|
||||
_hosts _make _man _mh _pdf _ps _rcs _rlogin _strip _stty
|
||||
_tar _tar_archive _tex _uncompress _x_options _xfig
|
||||
'
|
||||
|
|
|
|||
15
Completion/User/_chown
Normal file
15
Completion/User/_chown
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#compdef chown chgrp
|
||||
|
||||
if [[ CURRENT -eq 2 || CURRENT -eq 3 && $words[CURRENT-1] = -* ]]; then
|
||||
if [[ $words[1] = chgrp ]] || compset -P '*[:.]'; then
|
||||
_groups
|
||||
else
|
||||
if [[ $OSTYPE = (solaris*|hpux*) ]]; then
|
||||
compgen -u -S ':' -q
|
||||
else
|
||||
compgen -u -S '.' -q
|
||||
fi
|
||||
fi
|
||||
else
|
||||
_files
|
||||
fi
|
||||
|
|
@ -4,10 +4,9 @@ if compset -P 1 'conv\='; then
|
|||
# If there's a comma present, ignore up to the last one. The
|
||||
# test alone will have that effect.
|
||||
compset -p '*,'
|
||||
compgen -S, -q \
|
||||
-k '(ascii ebcdic ibm block unblock lcase ucase swab noerror sync)'
|
||||
compadd -qS, -q ascii ebcdic ibm block unblock lcase ucase swab noerror sync
|
||||
elif compset -P 1 '[io]f\='; then
|
||||
_files
|
||||
else
|
||||
compgen -S '=' -k '(if of ibs obs bs cbs skip files seek count conv)'
|
||||
compadd -S '=' if of ibs obs bs cbs skip files seek count conv
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ local prev="$words[CURRENT-1]"
|
|||
if compset -N '-(ok|exec)' '\;'; then
|
||||
_normal
|
||||
elif compset -P 1 -; then
|
||||
compgen -s 'daystart {max,min,}depth follow noleaf version xdev \
|
||||
compadd daystart {max,min,}depth follow noleaf version xdev \
|
||||
{a,c,}newer {a,c,m}{min,time} empty false {fs,x,}type gid inum links \
|
||||
{i,}{l,}name {no,}{user,group} path perm regex size true uid used \
|
||||
exec {f,}print{f,0,} ok prune ls'
|
||||
exec {f,}print{f,0,} ok prune ls
|
||||
elif [[ CURRENT -eq 2 ]]; then
|
||||
local ret=1
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ elif [[ CURRENT -eq 2 ]]; then
|
|||
elif [[ "$prev" = -((a|c|)newer|fprint(|0|f)) ]]; then
|
||||
_files
|
||||
elif [[ "$prev" = -fstype ]]; then
|
||||
compgen -k '(ufs 4.2 4.3 nfs tmp mfs S51K S52K)'
|
||||
compadd ufs 4.2 4.3 nfs tmp mfs S51K S52K
|
||||
elif [[ "$prev" = -group ]]; then
|
||||
compgen -k groups
|
||||
elif [[ "$prev" = -user ]]; then
|
||||
|
|
|
|||
6
Completion/User/_groups
Normal file
6
Completion/User/_groups
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#compdef newgrp
|
||||
|
||||
: ${(A)groups:=${${(s: :)$(</etc/group)}%%:*}}
|
||||
# : ${(A)groups:=${${(s: :)$(ypcat group.byname)}%%:*}} # If you use NIS
|
||||
|
||||
compadd $groups
|
||||
|
|
@ -1,4 +1,24 @@
|
|||
#compdef make gmake pmake
|
||||
|
||||
compgen -s "\$(awk '/^[a-zA-Z0-9][^\/ ]+:/ {print \$1}' FS=: [mM]akefile /dev/null)" ||
|
||||
_files
|
||||
local prev="$words[CURRENT-1]" file ret=1
|
||||
|
||||
if [[ "$prev" = -[CI] ]]; then
|
||||
_files -/
|
||||
elif [[ "$prev" = -[foW] ]]; then
|
||||
_files
|
||||
else
|
||||
file="$words[(I)-f]"
|
||||
if (( file )); then
|
||||
file="$words[file+1]"
|
||||
elif [[ -e Makefile ]]; then
|
||||
file=Makefile
|
||||
elif [[ -e makefile ]]; then
|
||||
file=makefile
|
||||
else
|
||||
file=''
|
||||
fi
|
||||
|
||||
[[ -n "$file" ]] &&
|
||||
compadd - $(awk '/^[a-zA-Z0-9][^/ ]+:/ {print $1}' FS=: $file) && ret=0
|
||||
(( ret )) && _files
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ if compset -P 1 -; then
|
|||
print $n =~ s/^\[([a-z]+)\]// ? "$n\n$1$n\n" : "$n\n";
|
||||
}')
|
||||
return
|
||||
elif compset -P 1 '[+@] || [ "$prev" = -draftfolder ]]; then
|
||||
elif compset -P 1 '[+@]' || [[ "$prev" = -draftfolder ]]; then
|
||||
# Complete folder names.
|
||||
local mhpath
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ elif compset -P 1 '[+@] || [ "$prev" = -draftfolder ]]; then
|
|||
elif [[ "$prev" = -(editor|(whatnow|rmm|show|more)proc) ]]; then
|
||||
compgen -c
|
||||
elif [[ "$prev" = -file ]]; then
|
||||
compgen -f
|
||||
_files
|
||||
elif [[ "$prev" = -(form|audit|filter) ]]; then
|
||||
# Need some MH template file, which may be in our own MH directory
|
||||
# or with the standard library.
|
||||
|
|
@ -69,7 +69,7 @@ else
|
|||
# leaving foldnam empty works here
|
||||
fi
|
||||
|
||||
compgen -s '$(mark $foldnam 2>/dev/null | awk -F: '\''{ print $1 }'\'')' &&
|
||||
compadd $(mark $foldnam 2>/dev/null | awk -F: '{ print $1 }') &&
|
||||
ret=0
|
||||
compadd reply next cur prev first last all unseen && ret=0
|
||||
compgen -W folddir -g '<->' && ret=0
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
if [[ CURRENT -eq 2 ]]; then
|
||||
compgen -k hosts
|
||||
elif [[ CURRENT -eq 3 ]]; then
|
||||
compgen -k '(-l)'
|
||||
compadd - -l
|
||||
else
|
||||
compgen -u
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -2,4 +2,8 @@
|
|||
|
||||
# A simple pattern completion, just as an example.
|
||||
|
||||
compgen -J options -k '(-display -name -xrm)'
|
||||
if [ "$words[CURRENT-1]" = "-display" ]; then
|
||||
compgen -k hosts -S':0'
|
||||
else
|
||||
compadd -J options - -display -name -xrm
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
defs.mk
|
||||
|
|
@ -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-22
|
||||
VERSION_DATE='June 13, 1999'
|
||||
VERSION=3.1.5-pws-24
|
||||
VERSION_DATE='June 26, 1999'
|
||||
|
|
|
|||
|
|
@ -2,13 +2,11 @@ DISTFILES_SRC='
|
|||
.cvsignore .distfiles Makefile.in
|
||||
META-FAQ.yo intro.ms
|
||||
version.yo zmacros.yo zman.yo ztexi.yo
|
||||
zsh.yo zshbuiltins.yo zshcompctl.yo zshcompsys.yo zshcompwid.yo
|
||||
zshexpn.yo zshmisc.yo zshmodules.yo zshoptions.yo zshparam.yo
|
||||
zshzftpsys.yo zshzle.yo
|
||||
zsh.yo zshbuiltins.yo zshcompctl.yo zshexpn.yo zshmisc.yo
|
||||
zshmodules.yo zshoptions.yo zshparam.yo zshzle.yo
|
||||
zsh.texi
|
||||
zsh.1 zshbuiltins.1 zshcompctl.1 zshcompsys.1 zshcompwid.1
|
||||
zshexpn.1 zshmisc.1 zshmodules.1 zshoptions.1 zshparam.1
|
||||
zshzftpsys.1 zshzle.1 zshall.1
|
||||
zsh.1 zshbuiltins.1 zshcompctl.1 zshexpn.1 zshmisc.1 zshmodules.1
|
||||
zshoptions.1 zshparam.1 zshzle.1 zshall.1
|
||||
'
|
||||
|
||||
DISTFILES_DOC='
|
||||
|
|
|
|||
|
|
@ -56,9 +56,9 @@ Zsh/compat.yo Zsh/compctl.yo Zsh/cond.yo Zsh/exec.yo Zsh/expn.yo \
|
|||
Zsh/filelist.yo Zsh/files.yo Zsh/func.yo Zsh/grammar.yo Zsh/guide.yo \
|
||||
Zsh/index.yo Zsh/intro.yo Zsh/invoke.yo Zsh/jobs.yo Zsh/metafaq.yo \
|
||||
Zsh/modules.yo Zsh/mod_cap.yo Zsh/compwid.yo Zsh/compsys.yo \
|
||||
Zsh/mod_clone.yo Zsh/mod_comp1.yo Zsh/mod_compctl.yo Zsh/mod_deltochar.yo \
|
||||
Zsh/mod_example.yo Zsh/mod_files.yo Zsh/mod_mapfile.yo Zsh/mod_stat.yo \
|
||||
Zsh/mod_zle.yo Zsh/options.yo \
|
||||
Zsh/mod_clone.yo Zsh/mod_comp1.yo Zsh/mod_compctl.yo Zsh/mod_complist.yo \
|
||||
Zsh/mod_deltochar.yo Zsh/mod_example.yo Zsh/mod_files.yo \
|
||||
Zsh/mod_mapfile.yo Zsh/mod_stat.yo Zsh/mod_zle.yo Zsh/options.yo \
|
||||
Zsh/params.yo Zsh/prompt.yo Zsh/redirect.yo Zsh/restricted.yo \
|
||||
Zsh/seealso.yo Zsh/zftpsys.yo Zsh/zle.yo
|
||||
|
||||
|
|
@ -131,9 +131,10 @@ zshmisc.1: Zsh/grammar.yo Zsh/redirect.yo Zsh/exec.yo Zsh/func.yo \
|
|||
Zsh/prompt.yo Zsh/restricted.yo
|
||||
|
||||
zshmodules.1: Zsh/modules.yo Zsh/mod_cap.yo Zsh/mod_clone.yo \
|
||||
Zsh/mod_comp1.yo Zsh/mod_compctl.yo Zsh/mod_deltochar.yo \
|
||||
Zsh/mod_example.yo Zsh/mod_files.yo Zsh/mod_mapfile.yo \
|
||||
Zsh/mod_sched.yo Zsh/mod_stat.yo Zsh/mod_zftp.yo Zsh/mod_zle.yo
|
||||
Zsh/mod_comp1.yo Zsh/mod_complist.yo Zsh/mod_compctl.yo \
|
||||
Zsh/mod_deltochar.yo Zsh/mod_example.yo Zsh/mod_files.yo \
|
||||
Zsh/mod_mapfile.yo Zsh/mod_sched.yo Zsh/mod_stat.yo \
|
||||
Zsh/mod_zftp.yo Zsh/mod_zle.yo
|
||||
|
||||
zshoptions.1: Zsh/options.yo
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ DISTFILES_SRC='
|
|||
arith.yo builtins.yo compat.yo compctl.yo compsys.yo compwid.yo
|
||||
cond.yo exec.yo expn.yo filelist.yo files.yo func.yo grammar.yo
|
||||
guide.yo index.yo intro.yo invoke.yo jobs.yo metafaq.yo
|
||||
mod_cap.yo mod_clone.yo mod_comp1.yo
|
||||
mod_cap.yo mod_clone.yo mod_comp1.yo mod_complist.yo
|
||||
mod_compctl.yo mod_deltochar.yo mod_example.yo mod_files.yo
|
||||
mod_mapfile.yo mod_parameter.yo mod_sched.yo mod_stat.yo
|
||||
mod_zftp.yo mod_zle.yo
|
||||
|
|
|
|||
|
|
@ -224,10 +224,11 @@ are reset to their default value corresponding to the specified emulation
|
|||
mode, except for certain options describing the interactive
|
||||
environment; otherwise, only those options likely to cause portability
|
||||
problems in scripts and functions are altered. If the tt(-L) option
|
||||
is given, the option tt(LOCAL_OPTIONS) will be set as well, causing
|
||||
the effect of the tt(emulate) command to be local to the immediately
|
||||
surrounding shell function, if any; normally this is turned off in all
|
||||
emulation modes except tt(ksh).
|
||||
is given, the options tt(LOCAL_OPTIONS) and tt(LOCAL_TRAPS) will be set as
|
||||
well, causing the effects of the tt(emulate) command and any tt(setopt) and
|
||||
tt(trap) commands to be local to the immediately surrounding shell
|
||||
function, if any; normally these options are turned off in all emulation
|
||||
modes except tt(ksh).
|
||||
)
|
||||
findex(enable)
|
||||
cindex(enabling commands)
|
||||
|
|
@ -263,8 +264,7 @@ findex(export)
|
|||
item(tt(export) [ var(name)[tt(=)var(value)] ... ])(
|
||||
The specified var(name)s are marked for automatic export
|
||||
to the environment of subsequently executed commands.
|
||||
Equivalent to tt(typeset -x), except that no parameter will be created
|
||||
to hide an existing one in an outer scope.
|
||||
Equivalent to tt(typeset -gx).
|
||||
If a parameter specified does not
|
||||
already exist, it is created in the global scope.
|
||||
)
|
||||
|
|
@ -428,7 +428,7 @@ added by explicit specification. If has no effect if used with tt(-f).
|
|||
)
|
||||
alias(history)(fc -l)
|
||||
findex(integer)
|
||||
item(tt(integer) [ {tt(PLUS())|tt(-)}tt(lrtux) ] [ var(name)[tt(=)var(value)] ... ])(
|
||||
item(tt(integer) [ {tt(PLUS())|tt(-)}tt(glrtux) ] [ var(name)[tt(=)var(value)] ... ])(
|
||||
Equivalent to tt(typeset -i), except that options irrelevant to
|
||||
integers are not permitted.
|
||||
)
|
||||
|
|
@ -522,7 +522,7 @@ endsitem()
|
|||
)
|
||||
findex(local)
|
||||
item(tt(local) [ {tt(PLUS())|tt(-)}tt(ALRUZailrtu) [var(n)]] [ var(name)[tt(=)var(value)] ] ...)(
|
||||
Same as tt(typeset), except that the options tt(-x) and
|
||||
Same as tt(typeset), except that the options tt(-g), tt(-x) and
|
||||
tt(-f) are not permitted.
|
||||
)
|
||||
findex(log)
|
||||
|
|
@ -682,12 +682,13 @@ Read only one character from the terminal and set var(name) to
|
|||
With this flag set the return value is zero only if the character was
|
||||
`tt(y)' or `tt(Y)'. Note that this always reads from the terminal, even
|
||||
if used with the tt(-p) or tt(-u) or tt(-z) flags or with redirected input.
|
||||
This option may also be used within zle widgets.
|
||||
)
|
||||
item(tt(-k) [ var(num) ])(
|
||||
Read only one (or var(num)) characters. All are assigned to the first
|
||||
var(name), without word splitting. This flag is ignored when tt(-q) is
|
||||
present. Input is read from the terminal unless one of tt(-u) or tt(-p)
|
||||
is present.
|
||||
is present. This option may also be used within zle widgets.
|
||||
)
|
||||
item(tt(-z))(
|
||||
Read one entry from the editor buffer stack and assign it to the first
|
||||
|
|
@ -842,7 +843,8 @@ findex(trap)
|
|||
cindex(signals, trapping)
|
||||
cindex(trapping signals)
|
||||
item(tt(trap) [ var(arg) [ var(sig) ... ] ])(
|
||||
var(arg) is a command to be read and executed when the shell
|
||||
var(arg) is a series of commands (usually quoted to protect it from
|
||||
immediate evaluation by the shell) to be read and executed when the shell
|
||||
receives var(sig). Each var(sig) can be given as a number
|
||||
or as the name of a signal.
|
||||
If var(arg) is `tt(-)', then all traps var(sig) are reset to their
|
||||
|
|
@ -862,6 +864,20 @@ then the command var(arg) is executed when the shell terminates.
|
|||
|
||||
The tt(trap) command with no arguments prints a list of commands
|
||||
associated with each signal.
|
||||
|
||||
Note that traps defined with the tt(trap) builtin are slightly different
|
||||
from those defined as `tt(TRAP)var(NAL) () { ... }', as the latter have
|
||||
their own function environment (line numbers, local variables, etc.) while
|
||||
the former use the environment of the command in which they were called.
|
||||
For example,
|
||||
|
||||
example(trap 'print $LINENO' DEBUG)
|
||||
|
||||
will print the line number of command executed after it has run, while
|
||||
|
||||
example(TRAPDEBUG() { print $LINENO; })
|
||||
|
||||
will always print the number zero.
|
||||
)
|
||||
findex(true)
|
||||
cindex(doing nothing, successfully)
|
||||
|
|
@ -887,7 +903,7 @@ Equivalent to tt(whence -v).
|
|||
findex(typeset)
|
||||
cindex(parameters, setting)
|
||||
cindex(parameters, declaring)
|
||||
xitem(tt(typeset) [ {tt(PLUS())|tt(-)}tt(ALRUZafilrtuxm) [var(n)]] [ \
|
||||
xitem(tt(typeset) [ {tt(PLUS())|tt(-)}tt(ALRUZafgilrtuxm) [var(n)]] [ \
|
||||
var(name)[tt(=)var(value)] ... ])
|
||||
item(tt(typeset) -T [ {tt(PLUS()|tt(-))}tt(LRUZrux) ] \
|
||||
var(SCALAR)[tt(=)var(value)] var(array))(
|
||||
|
|
@ -926,6 +942,14 @@ to var(array) sets it to be a single-element array. Note that
|
|||
both tt(typeset -xT ...) and tt(export -T ...) work, but only the
|
||||
scalar will be marked for export.
|
||||
|
||||
The flag tt(-g) (global) flag is treated specially: it means that any
|
||||
resulting parameter will not be restricted to local scope. Note that this
|
||||
does not necessarily mean that the parameter will be global, as the flag
|
||||
will apply to any existing parameter (even if unset) from an enclosing
|
||||
function. This flag does not affect the parameter after creation, hence it
|
||||
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
|
||||
|
|
@ -1174,6 +1198,7 @@ findex(zmodload)
|
|||
cindex(modules, loading)
|
||||
cindex(loading modules)
|
||||
xitem(tt(zmodload) [ tt(-dL) ] [ ... ])
|
||||
xitem(tt(zmodload -e) [ ... ])
|
||||
xitem(tt(zmodload) [ tt(-a) [ tt(-bcp) [ tt(-I) ] ] ] [ tt(-iL) ] ...)
|
||||
item(tt(zmodload) tt(-u) [ tt(-abcdp) [ tt(-I) ] ] [ tt(-iL) ] ...)(
|
||||
tt(zmodload) performs operations relating to zsh's loadable modules.
|
||||
|
|
@ -1269,6 +1294,21 @@ xitem(tt(zmodload) tt(-a) [ tt(-i) ] var(name) [ var(builtin) ... ])
|
|||
item(tt(zmodload) tt(-ua) [ tt(-i) ] var(builtin) ...)(
|
||||
Equivalent to tt(-ab) and tt(-ub).
|
||||
)
|
||||
enditem()
|
||||
item(tt(zmodload -e) [ var(string) ... ])(
|
||||
The tt(-e) option without arguments lists all modules loaded or linked
|
||||
into the shell. With arguments only the return status is set to zero
|
||||
if all var(string)s given as arguments are names of modules loaded or
|
||||
linked in and to one if at least on var(string) is not the name of a
|
||||
module loaded or linked. This can be used to test for the availability
|
||||
of things implemented by modules.
|
||||
)
|
||||
enditem()
|
||||
|
||||
In a shell without dynamic loading only the tt(-e) option is
|
||||
supported. In such a shell the return status of tt(zmodload) without
|
||||
arguments or options is one whereas in a shell with dynamic loading
|
||||
the return status without arguments or options is always zero. This
|
||||
can be used to test if the shell supports dynamic loading of modules
|
||||
or not.
|
||||
)
|
||||
enditem()
|
||||
|
|
|
|||
|
|
@ -2,6 +2,24 @@ texinode(Programmable Completion Using compctl)(Completion Widgets)(Zsh Line Edi
|
|||
chapter(Programmable Completion Using compctl)
|
||||
cindex(completion, programmable)
|
||||
cindex(completion, controlling)
|
||||
ifzman(\
|
||||
sect(Synopsis)
|
||||
This version of zsh has two ways of performing completion of words on the
|
||||
command line. New users of the shell may prefer to use the newer
|
||||
and more powerful system based on shell functions; this is described in
|
||||
zmanref(zshcompsys), and the basic shell mechanisms which support it are
|
||||
described in zmanref(zshcompwid). This manual entry describes the older
|
||||
tt(compctl) command.
|
||||
)\
|
||||
ifnzman(\
|
||||
sect(Types of completion)
|
||||
This version of zsh has two ways of performing completion of words on the
|
||||
command line. New users of the shell may prefer to use the newer
|
||||
and more powerful system based on shell functions; this is described
|
||||
in noderef(Completion System), and the basic shell mechanisms which support
|
||||
it are described in noderef(Completion Widgets). This chapter describes
|
||||
the older tt(compctl) command.
|
||||
)\
|
||||
findex(compctl)
|
||||
sect(Description)
|
||||
startlist()
|
||||
|
|
@ -615,7 +633,8 @@ var(max) inclusive.
|
|||
)
|
||||
item(tt(r[)var(str1)tt(,)var(str2)tt(])...)(
|
||||
Matches if the cursor is after a word with prefix var(str1). If there
|
||||
is also a word with prefix var(str2) on the command line it matches
|
||||
is also a word with prefix var(str2) on the command line after the one
|
||||
matched by var(str1) it matches
|
||||
only if the cursor is before this word. If the comma and var(str2) are
|
||||
omitted, it matches if the cursor is after a word with prefix var(str1).
|
||||
)
|
||||
|
|
|
|||
|
|
@ -41,15 +41,15 @@ directory (or multiple directories) of your own which should appear in your
|
|||
tt($fpath) variable so that the functions can be autoloaded.
|
||||
|
||||
startmenu()
|
||||
menu(Initialisation)
|
||||
menu(Initialization)
|
||||
menu(Control Functions)
|
||||
menu(Completion Functions)
|
||||
endmenu()
|
||||
|
||||
texinode(Initialisation)(Control Functions)()(Completion System)
|
||||
sect(Initialisation)
|
||||
texinode(Initialization)(Control Functions)()(Completion System)
|
||||
sect(Initialization)
|
||||
|
||||
The script tt(compinstall) can be run by a user to set up the completion
|
||||
The function tt(compinstall) can be run by a user to set up the completion
|
||||
system for use. It will usually insert code into tt(.zshrc), although if
|
||||
that is not writable it will save it in another file and tell you that
|
||||
file's locations. Note that it is up to you to make sure that the lines
|
||||
|
|
@ -59,13 +59,15 @@ So long as you keep them all together (including the comment lines at the
|
|||
start and finish), you can rerun tt(compinstall) and it will correctly
|
||||
locate and modify these lines. Note, however, that any code you add to
|
||||
this section by hand is likely to be lost if you rerun tt(compinstall).
|
||||
The new code will take effect next time you start the shell, or run
|
||||
tt(.zshrc) by hand.
|
||||
|
||||
You can run it as `tt(source )var(<path>)tt(/compinstall)' or
|
||||
`tt(. )var(<path>)tt(/compinstall)', where var(<path>) is where the
|
||||
completion functions are stored. It will ask you various questions about
|
||||
how you would like completion set up. It is in two parts; the basic part
|
||||
To run it, you will need to make sure it is in a directory mentioned in your
|
||||
tt($fpath) parameter, and that it is autoloaded (`tt(autoload -U
|
||||
compinstall)' is recommended). It will ask you various questions about how
|
||||
you would like completion set up. It is in two parts; the basic part
|
||||
locates the completion files and decides where to put your personal
|
||||
dumpfile, used to speed up initialisation after the first time. After
|
||||
dumpfile, used to speed up initialization after the first time. After
|
||||
that, you will be asked if you wish to go on to the advanced set-up; if you
|
||||
answer tt(n), you can rerun tt(compinstall) later without having to
|
||||
re-enter any of the basic settings.
|
||||
|
|
@ -73,36 +75,35 @@ re-enter any of the basic settings.
|
|||
You can abort the installation any time you are being prompted for
|
||||
information, and your tt(.zshrc) will not be altered at all.
|
||||
|
||||
After initialization all the builtin completion widgets such as
|
||||
tt(expand-or-complete) will be redefined to use the new completion system.
|
||||
Should you need to, you can still bind keys to the old functions by putting
|
||||
a `tt(.)' in front, e.g. `tt(.expand-or-complete)'.
|
||||
|
||||
subsect(Use of compinit)
|
||||
|
||||
This section describes the use of tt(compinit) to initialize completion for
|
||||
the current session when run directly by the user; if you have run
|
||||
tt(compinstall) it will be called automatically from your tt(.zshrc).
|
||||
|
||||
To initialise the system, the script tt(compinit) should be sourced with
|
||||
`tt(source )var(<path>)tt(/compinit)' or
|
||||
`tt(. )var(<path>)tt(/compinit)'. This will define a few utility functions,
|
||||
arrange for all the necessary shell functions to be autoloaded, and will
|
||||
then re-bind all keys that do completion to use the new system.
|
||||
To initialize the system, the function tt(compinit) should be in a
|
||||
directory mentioned in the tt($fpath) variable, and should be autoloaded
|
||||
(`tt(autoload -U compinit)' is recommended). When run, it will define a
|
||||
few utility functions, arrange for all the necessary shell functions to be
|
||||
autoloaded, and will then re-bind all keys that do completion to use the
|
||||
new system.
|
||||
|
||||
To speed up the running of tt(compinit), it can be made to produce a dumped
|
||||
configuration which will be read in on future invocations. The easiest way
|
||||
to do this is by adding the option tt(-d) whenever tt(compinit) is sourced.
|
||||
In this case the dumped file will have the same name as the sourced file,
|
||||
but with tt(.dump) appended to the end, or, if that is not writable by the
|
||||
user, the file tt(.zcompdump) in the same directory as the startup files
|
||||
(i.e. tt($ZDOTDIR) or tt($HOME)); alternatively, an explicit file name can
|
||||
be given following the tt(-d). On the next call to tt(compinit -d), the
|
||||
dumped file will be read instead.
|
||||
to do this is by adding the option tt(-d) whenever tt(compinit) is run.
|
||||
In this case the dumped file is tt(.zcompdump) in the same directory as the
|
||||
startup files (i.e. tt($ZDOTDIR) or tt($HOME)); alternatively, an explicit
|
||||
file name can be given following the tt(-d). On the next call to
|
||||
tt(compinit -d), the dumped file will be read instead.
|
||||
|
||||
The other option accepted by tt(compinit) is tt(-f )var(dir), which gives
|
||||
the directory in which tt(compinit) resides. If you source tt(compinit) by
|
||||
its full pathname, and the option tt(FUNCTION_ARGZERO) is set, as it is by
|
||||
default unless tt(zsh) is emulating tt(sh) or tt(ksh), this is unnecessary
|
||||
as tt(compinit) can deduce the directory for itself. It is used in two
|
||||
ways: to find the program tt(compdump) used by the tt(-d) option, and to
|
||||
check if the directory should be added to the function search path to find
|
||||
the completion functions (see below).
|
||||
If the parameter tt(_compdir) is set, tt(compinit) uses it has a directory
|
||||
where completion functions can be found; this is only necessary if they are
|
||||
not already in the function search path.
|
||||
|
||||
If the number of completion files changes, tt(compinit) will recognise this
|
||||
and produce a new dump file. However, if the name of a function or the
|
||||
|
|
@ -110,27 +111,30 @@ arguments in the first line of a tt(#compdef) function (as described below)
|
|||
change, it is easiest to delete the dump file by hand so that the next time
|
||||
tt(compinit) will re-create it.
|
||||
|
||||
The dumping is actually done by another script, tt(compdump), but you will
|
||||
only need to source this yourself if you change the configuration
|
||||
The dumping is actually done by another function, tt(compdump), but you
|
||||
will only need to run this yourself if you change the configuration
|
||||
(e.g. using tt(compdef)) and then want to dump the new one. The name of
|
||||
the old dumped file will be remembered for this.
|
||||
the old dumped file will be remembered for this purpose.
|
||||
|
||||
subsect(Autoloaded files)
|
||||
|
||||
The convention for autoloaded functions used in completion is that they
|
||||
start with an underscore; as already mentioned, the tt(fpath/FPATH)
|
||||
parameter must contain the directory in which they are stored. If
|
||||
tt(compinit) does not find enough files beginning with an underscore (fewer
|
||||
than twenty) in the search path, it will try to find more by adding its own
|
||||
directory to the search path. If you keep all the completion files in this
|
||||
directory, this means you never have to alter tt(fpath/FPATH) yourself.
|
||||
parameter must contain the directory in which they are stored. If tt(zsh)
|
||||
was properly installed on your system, then tt(fpath/FPATH) automatically
|
||||
contains the required directories.
|
||||
|
||||
For incomplete installations, if tt(compinit) does not find enough files
|
||||
beginning with an underscore (fewer than twenty) in the search path, it
|
||||
will try to find more by adding the directory tt(_compdir) to the search
|
||||
path; if you have run tt(compinstall), this will be set automatically.
|
||||
Furthermore, if the directory in question ends in the path segment
|
||||
tt(Core), or has a subdirectory named tt(Core), tt(compinit) will add all
|
||||
subdirectories of the directory where tt(Core) is to the path: this allows
|
||||
the functions to be in the same format as in the tt(zsh) source
|
||||
distribution.
|
||||
|
||||
When tt(compinit) is sourced, it searches all such files accessible via
|
||||
When tt(compinit) is run, it searches all such files accessible via
|
||||
tt(fpath/FPATH) and reads the first line of each of them. This line should
|
||||
contain one of the tags described below. Files whose first line does not
|
||||
start with one of these tags are not considered to be part of the
|
||||
|
|
@ -158,7 +162,11 @@ var(key-sequences). It creates a widget behaving like the builtin widget
|
|||
var(style), which must be one of those that perform completion, namely
|
||||
tt(complete-word), tt(delete-char-or-list), tt(expand-or-complete),
|
||||
tt(expand-or-complete-prefix), tt(list-choices), tt(menu-complete),
|
||||
tt(menu-expand-or-complete), or tt(reverse-menu-complete).
|
||||
tt(menu-expand-or-complete), or tt(reverse-menu-complete). If the
|
||||
tt(complist) module is loaded (see
|
||||
ifzman(zmanref(zshmodules))\
|
||||
ifnzman(noderef(The complist Module))\
|
||||
), the tt(menu-select) widget can be used, too.
|
||||
|
||||
The widget is then bound to all the var(key-sequences) given, if any: when
|
||||
one of the var(key-sequences) is typed, the function in the file will
|
||||
|
|
@ -238,10 +246,10 @@ function, usable to be put in a setup script.
|
|||
)
|
||||
enditem()
|
||||
|
||||
texinode(Control Functions)(Completion Functions)(Initialisation)(Completion System)
|
||||
texinode(Control Functions)(Completion Functions)(Initialization)(Completion System)
|
||||
sect(Control Functions)
|
||||
|
||||
The initialisation script tt(compinit) re-binds all the keys which perform
|
||||
The initialization script tt(compinit) re-binds all the keys which perform
|
||||
completion to newly created widgets that all call the supplied widget
|
||||
function tt(_main_complete). This function acts as a wrapper calling
|
||||
the so-called `completer' functions that generate matches. If
|
||||
|
|
@ -382,7 +390,7 @@ with a numeric argument of six (as in `tt(ESC-6 TAB)'), up to six
|
|||
errors are accepted. Hence with a value of `tt(0n)', no correcting
|
||||
completion will be attempted unless a numeric argument is given.
|
||||
|
||||
If the value contains `tt(n)' or `tt(N)' and a exclamation mark
|
||||
If the value contains `tt(n)' or `tt(N)' and an exclamation mark
|
||||
(`tt(!)'), tt(_approximate) will var(not) try to generate corrected
|
||||
completions when given a numeric argument, so in this case the number given
|
||||
should be greater than zero. For example, `tt(2n!)' specifies that
|
||||
|
|
@ -467,6 +475,12 @@ configuration key tt(match_original) has a value of `tt(only)', no
|
|||
`tt(*)' will be inserted. If tt(match_original) has any other non-empty
|
||||
string as its value, this completer will first try to generate matches
|
||||
without, then with a `tt(*)' inserted at the cursor position.
|
||||
|
||||
The generated matches will be offered in a menucompletion unless the
|
||||
tt(match_insert) configuration key is set to a string starting with
|
||||
`tt(unambig)'. In this case menucompletion will only be started if no
|
||||
unambiguous string could be generated that is at least as long as the
|
||||
original string.
|
||||
)
|
||||
item(tt(_expand))(
|
||||
This completer function does not really do completion, but instead
|
||||
|
|
@ -652,7 +666,7 @@ one can write a pattern completion function that keeps other functions
|
|||
from being tried simply by setting this parameter to any value.
|
||||
)
|
||||
item(tt(_multi_parts))(
|
||||
This functions gets two arguments: a separator character and an
|
||||
This function gets two arguments: a separator character and an
|
||||
array. As usual, the array may be either the
|
||||
name of an array parameter or a literal array in the form
|
||||
`tt(LPAR()foo bar)tt(RPAR())' (i.e. a list of words separated by white
|
||||
|
|
@ -700,10 +714,13 @@ These functions also accept the `tt(-J)', `tt(-V)', `tt(-X)', `tt(-P)',
|
|||
`tt(-S)', `tt(-q)', `tt(-r)', and `tt(-R)' options from the
|
||||
tt(compadd) builtin.
|
||||
|
||||
Finally, the tt(_path_files) function supports one configuration key:
|
||||
tt(path_expand). If this is set to any non-empty string, the partially
|
||||
Finally, the tt(_path_files) function supports two configuration keys.
|
||||
If tt(path_expand) is set to any non-empty string, the partially
|
||||
typed path from the line will be expanded as far as possible even if
|
||||
trailing pathname components can not be completed.
|
||||
trailing pathname components can not be completed. And if
|
||||
tt(path_cursor) is set to a non-empty string, the cursor will be left
|
||||
after the first ambiguous pathname component even when menucompletion
|
||||
is used.
|
||||
)
|
||||
item(tt(_parameters))(
|
||||
This should be used to complete parameter names if you need some of the
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ of the builtin widgets that handle completions can be given:
|
|||
tt(complete-word), tt(expand-or-complete),
|
||||
tt(expand-or-complete-prefix), tt(menu-complete),
|
||||
tt(menu-expand-or-complete), tt(reverse-menu-complete),
|
||||
tt(list-choices), or tt(delete-char-or-list).
|
||||
tt(list-choices), or tt(delete-char-or-list). Note that this will still
|
||||
work even if the widget in question has been rebound.
|
||||
|
||||
startmenu()
|
||||
menu(Special Parameters)
|
||||
|
|
@ -346,7 +347,7 @@ xitem(tt(compadd) [ tt(-qQfnUam) ] [ tt(-F) var(array) ])
|
|||
xitem([ tt(-P) var(prefix) ] [ tt(-S) var(suffix) ])
|
||||
xitem([ tt(-p) var(hidden-prefix) ] [ tt(-s) var(hidden-suffix) ])
|
||||
xitem([ tt(-i) var(ignored-prefix) ] [ tt(-I) var(ignored-suffix) ])
|
||||
xitem([ tt(-W) var(file-prefix) ])
|
||||
xitem([ tt(-W) var(file-prefix) ] [ tt(-y) var(array) ])
|
||||
xitem([ tt(-J) var(name) ] [ tt(-V) var(name) ] [ tt(-X) var(explanation) ])
|
||||
xitem([ tt(-r) var(remove-chars) ] [ tt(-R) var(remove-func) ])
|
||||
xitem([ tt(-M) var(match-spec) ] [ tt(-O) var(array) ] [ tt(-A) var(array) ])
|
||||
|
|
@ -406,6 +407,12 @@ match.
|
|||
item(tt(-I) var(ignored-suffix))(
|
||||
Like tt(-i), but gives an ignored suffix.
|
||||
)
|
||||
item(tt(-y) var(array))(
|
||||
This gives a number of string to display instead of the matches. This
|
||||
is like the tt(-y) option of the tt(compctl) builtin command but the
|
||||
var(array) argument may only be the name of an array parameter or a
|
||||
literal array in parentheses containing the strings to display.
|
||||
)
|
||||
item(tt(-J) var(name))(
|
||||
As for tt(compctl) and tt(compgen), this gives the name of the group
|
||||
of matches the words should be stored in.
|
||||
|
|
|
|||
|
|
@ -41,16 +41,16 @@ pindex(KSH_AUTOLOAD, use of)
|
|||
If the tt(KSH_AUTOLOAD) option is set, or the file contains only a simple
|
||||
definition of the function, the file's contents will be
|
||||
executed. It would normally define the function in question, but may
|
||||
also perform initialisation.
|
||||
also perform initialization.
|
||||
It is executed in the context of the function
|
||||
execution, and may therefore define local parameters.
|
||||
|
||||
Otherwise, the function is defined such that its body is the
|
||||
complete contents of the file. This form allows the file to be
|
||||
used directly as an executable shell script.
|
||||
Initialisation code can be executed, but only as part of the first
|
||||
Initialization code can be executed, but only as part of the first
|
||||
function execution, so the function would have to redefine itself to
|
||||
avoid reinitialising on the next execution.
|
||||
avoid reinitializing on the next execution.
|
||||
|
||||
If this processing of the file results in the function being
|
||||
fully defined, the function itself is then executed.
|
||||
|
|
|
|||
|
|
@ -146,8 +146,10 @@ then be processed with bf(dvips) and optionally bf(gs) (Ghostscript) to
|
|||
produce a nicely formatted printed guide.
|
||||
)
|
||||
item(The HTML guide)(
|
||||
An HTML version of this guide is available at the Zsh web site via
|
||||
An HTML version of this guide is available at the Zsh web site via:
|
||||
|
||||
tt(http://sunsite.auc.dk/zsh/Doc/index.html).
|
||||
|
||||
(The HTML version is produced with bf(texi2html), which may be obtained
|
||||
from tt(http://wwwcn.cern.ch/dci/texi2html/). The command is
|
||||
`tt(texi2html -split_chapter -expandinfo zsh.texi)'.)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
texinode(The compctl Module)(The deltochar Module)(The comp1 Module)(Zsh Modules)
|
||||
texinode(The compctl Module)(The complist Module)(The comp1 Module)(Zsh Modules)
|
||||
sect(The compctl Module)
|
||||
The tt(compctl) module makes available several builtin commands. tt(compctl),
|
||||
is the standard way to control completions for ZLE. See
|
||||
|
|
|
|||
119
Doc/Zsh/mod_complist.yo
Normal file
119
Doc/Zsh/mod_complist.yo
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
texinode(The complist Module)(The deltochar Module)(The compctl Module)(Zsh Modules)
|
||||
sect(The complist Module)
|
||||
cindex(completion, listing)
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
strings and their default values are:
|
||||
|
||||
startitem()
|
||||
item(tt(no 0))(
|
||||
for normal text (not the string displayed for a match)
|
||||
)
|
||||
item(tt(fi 0))(
|
||||
for regular files
|
||||
)
|
||||
item(tt(di 32))(
|
||||
for directories
|
||||
)
|
||||
item(tt(ln 36))(
|
||||
for symbolic links
|
||||
)
|
||||
item(tt(pi 31))(
|
||||
for named pipes (FIFOs)
|
||||
)
|
||||
item(tt(so 33))(
|
||||
for sockets
|
||||
)
|
||||
item(tt(bd 44;37))(
|
||||
for block devices
|
||||
)
|
||||
item(tt(cd 44;37))(
|
||||
for character devices
|
||||
)
|
||||
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))
|
||||
)
|
||||
item(tt(lc \e[))(
|
||||
for the left code (see below)
|
||||
)
|
||||
item(tt(rc m))(
|
||||
for the right code
|
||||
)
|
||||
item(tt(ec) var(none))(
|
||||
for the end code
|
||||
)
|
||||
enditem()
|
||||
|
||||
Apart from these strings, the var(name) may also be an asterisk
|
||||
(`tt(*)') followed by any string. The var(value) given for such a
|
||||
string will be used for all files whose name ends with the string.
|
||||
|
||||
When printing a match, the code prints the value of tt(lc), the value
|
||||
for the file-type or the last matching specification with a `tt(*)',
|
||||
the value of tt(rc), the string to display for the match itself, and
|
||||
then the value of tt(ec) if that is defined or the values of tt(lc),
|
||||
tt(no), and tt(rc) if tt(ec) is not defined.
|
||||
|
||||
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 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
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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. 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
|
||||
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.
|
||||
|
||||
During this selection the widget uses the keymap tt(menuselect). Any
|
||||
key that is not defined in this keymap or that is bound to
|
||||
tt(undefined-key) is looked up in the keymap currently selected. This
|
||||
is used to ensure that the most important keys used during selection
|
||||
have sensible default (namely the cursor keys, return, and TAB). However,
|
||||
keys in the the tt(menuselect) keymap can be modified directly using the
|
||||
tt(bindkey) builtin command (see
|
||||
ifzman(zmanref(zshmodules))\
|
||||
ifnzman(noderef(The zle Module))\
|
||||
).
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
texinode(The deltochar Module)(The example Module)(The compctl Module)(Zsh Modules)
|
||||
texinode(The deltochar Module)(The example Module)(The complist Module)(Zsh Modules)
|
||||
sect(The deltochar Module)
|
||||
The tt(deltochar) module makes available one ZLE function:
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ with the var(new-keymap) name, it is deleted.
|
|||
item(tt(-N) var(new-keymap) [ var(old-keymap) ])(
|
||||
Create a new keymap, named var(new-keymap). If a keymap already has that
|
||||
name, it is deleted. If an var(old-keymap) name is given, the new keymap
|
||||
is initialised to be a duplicate of it, otherwise the new keymap will
|
||||
is initialized to be a duplicate of it, otherwise the new keymap will
|
||||
be empty.
|
||||
)
|
||||
enditem()
|
||||
|
|
@ -161,12 +161,13 @@ cindex(widgets, calling)
|
|||
cindex(calling widgets)
|
||||
cindex(widgets, defining)
|
||||
cindex(defining widgets)
|
||||
xitem(tt(zle) tt(-l) [ tt(-L) ])
|
||||
xitem(tt(zle) tt(-l) [ tt(-L) ] [ tt(-a) ] [ var(string) ... ])
|
||||
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))
|
||||
item(tt(zle) var(widget))(
|
||||
xitem(tt(zle) tt(-R) [ var(display-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:
|
||||
|
||||
|
|
@ -175,7 +176,15 @@ item(tt(-l) [ tt(-L) ])(
|
|||
List all existing user-defined widgets. If the tt(-L)
|
||||
option is used, list in the form of tt(zle)
|
||||
commands to create the widgets.
|
||||
Built-in widgets are not listed.
|
||||
|
||||
When combined with the tt(-a) option, all widget names are listed,
|
||||
including the builtin ones. In this case the tt(-L) option is ignored.
|
||||
|
||||
If at least one var(string) is given, nothing will be printed but the
|
||||
return status will be zero if all var(string)s are names of existing
|
||||
widgets (or of user-defined widgets if the tt(-a) flag is not given)
|
||||
and non-zero if at least one var(string) is not a name of an defined
|
||||
widget.
|
||||
)
|
||||
item(tt(-D) var(widget) ...)(
|
||||
Delete the named var(widget)s.
|
||||
|
|
@ -191,7 +200,11 @@ Create a user-defined widget. If there is already a widget with the
|
|||
specified name, it is overwritten. When the new
|
||||
widget is invoked from within the editor, the specified shell var(function)
|
||||
is called. If no function name is specified, it defaults to
|
||||
the same name as the widget.
|
||||
the same name as the widget. For further information, see the section
|
||||
em(Widgets) in
|
||||
ifzman(zmanref(zshzle))\
|
||||
ifnzman(noderef(Zsh Line Editor))\
|
||||
.
|
||||
)
|
||||
item(tt(-C) var(widget) var(completion-widget) var(function))(
|
||||
Create a user-defined completion widget names var(widget). The
|
||||
|
|
@ -203,9 +216,38 @@ ifzman(zmanref(zshcompwid))\
|
|||
ifnzman(noderef(Completion Widgets))\
|
||||
.
|
||||
)
|
||||
item(var(widget))(
|
||||
item(tt(-R) [ var(display-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).
|
||||
)
|
||||
item(var(widget) tt([ -n) var(num) tt(]) tt([ -N ]) var(args) ...)(
|
||||
Invoke the specified widget. This can only be done when ZLE is
|
||||
active; normally this will be within a user-defined widget.
|
||||
|
||||
With the options tt(-n) and tt(-N), the current numerical argument will be
|
||||
saved and then restored after the call to tt(widget); `tt(-n) var(num)'
|
||||
sets the numerical argument temporarily to var(num), while `tt(-N)' sets it
|
||||
to the default, i.e. as if there were none.
|
||||
|
||||
Any further arguments will be passed to the widget. If it is a shell
|
||||
function, these are passed down as postional parameters; for builtin
|
||||
widgets it is up to the widget in question what it does with them.
|
||||
Currently arguments are only handled by the incremental-search commands,
|
||||
the tt(history-search-forward) and tt(-backward) and the corresponding
|
||||
functions prefixed by tt(vi-), and by tt(universal-argument). No error is
|
||||
flagged if the command does not use the arguments, or only uses some of
|
||||
them.
|
||||
|
||||
The return status reflects the success or failure of the operation carried
|
||||
out by the widget, or if it is a user-defined widget the return status of
|
||||
the shell function.
|
||||
|
||||
A non-zero return status causes the shell to beep when the widget exits,
|
||||
unless the tt(BEEP) options was unset or the widget was called via the
|
||||
tt(zle) command. Thus if a user defined widget requires an immediate beep,
|
||||
it should call the tt(beep) widget directly.
|
||||
)
|
||||
enditem()
|
||||
)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ item(tt(compctl))(
|
|||
The tt(compctl) builtin for controlling completion and the builtins for
|
||||
completion widgets.
|
||||
)
|
||||
item(tt(complist))(
|
||||
Completion listing extensions.
|
||||
)
|
||||
item(tt(deltochar))(
|
||||
A ZLE function duplicating EMACS' tt(zap-to-char).
|
||||
)
|
||||
|
|
@ -55,6 +58,7 @@ menu(The cap Module)
|
|||
menu(The clone Module)
|
||||
menu(The comp1 Module)
|
||||
menu(The compctl Module)
|
||||
menu(The complist Module)
|
||||
menu(The deltochar Module)
|
||||
menu(The example Module)
|
||||
menu(The files Module)
|
||||
|
|
@ -69,6 +73,7 @@ includefile(Zsh/mod_cap.yo)
|
|||
includefile(Zsh/mod_clone.yo)
|
||||
includefile(Zsh/mod_comp1.yo)
|
||||
includefile(Zsh/mod_compctl.yo)
|
||||
includefile(Zsh/mod_complist.yo)
|
||||
includefile(Zsh/mod_deltochar.yo)
|
||||
includefile(Zsh/mod_example.yo)
|
||||
includefile(Zsh/mod_files.yo)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,12 @@ Some of the single letter option names refer to an option being off,
|
|||
in which case the inversion of that name refers to the option being on.
|
||||
For example, `tt(PLUS()n)' is the short name of `tt(exec)', and
|
||||
`tt(-n)' is the short name of its inversion, `tt(noexec)'.
|
||||
|
||||
In strings of single letter options supplied to the shell at startup,
|
||||
trailing whitespace will be ignored; for example the string `tt(-f )'
|
||||
will be treated just as `tt(-f)', but the string `tt(-f i)' is an error.
|
||||
This is because many systems which implement the `tt(#!)' mechanism for
|
||||
calling scripts do not strip trailing whitespace.
|
||||
texinode(Description of Options)(Option Aliases)(Specifying Options)(Options)
|
||||
sect(Description of Options)
|
||||
cindex(options, description)
|
||||
|
|
@ -551,7 +557,10 @@ pindex(LIST_BEEP)
|
|||
cindex(beep, ambiguous completion)
|
||||
cindex(completion, beep on ambiguous)
|
||||
item(tt(LIST_BEEP))(
|
||||
Beep on an ambiguous completion.
|
||||
Beep on an ambiguous completion. More accurately, this forces the
|
||||
completion widgets to return status 1 on an ambiguous completion, which
|
||||
causes the shell to beep if the option tt(BEEP) is also set; this may
|
||||
be modified if completion is called from a user-defined widget.
|
||||
)
|
||||
pindex(LIST_TYPES)
|
||||
cindex(marking file types)
|
||||
|
|
@ -572,6 +581,22 @@ A shell function can also guarantee itself a known shell configuration
|
|||
with a formulation like `tt(emulate -L zsh)'; the tt(-L) activates
|
||||
tt(LOCAL_OPTIONS).
|
||||
)
|
||||
pindex(LOCAL_TRAPS)
|
||||
item(tt(LOCAL_TRAPS))(
|
||||
If this option is set when a signal trap is set inside a function, then the
|
||||
previous status of the trap for that signal will be restored when the
|
||||
function exits. Note that this option must be set em(prior) to altering the
|
||||
trap behaviour in a function; unlike tt(LOCAL_OPTIONS), the value on exit
|
||||
from the function is irrelevant. However, it does not need to be set
|
||||
before any global trap for that to be correctly restored by a function.
|
||||
For example,
|
||||
|
||||
example(unsetopt localtraps
|
||||
trap - INT
|
||||
fn() { setopt localtraps; trap '' INT; sleep 3; })
|
||||
|
||||
will restore normally handling of tt(SIGINT) after the function exits.
|
||||
)
|
||||
pindex(LOGIN)
|
||||
item(tt(LOGIN) (tt(-l), ksh: tt(-l)))(
|
||||
This is a login shell.
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ In the parameter lists that follow, the mark `<S>' indicates that the
|
|||
parameter is special.
|
||||
Special parameters cannot have their type changed, and they stay special even
|
||||
if unset. `<Z>' indicates that the parameter does not exist when the shell
|
||||
initialises in tt(sh) or tt(ksh) emulation mode.
|
||||
initializes in tt(sh) or tt(ksh) emulation mode.
|
||||
startmenu()
|
||||
menu(Array Parameters)
|
||||
menu(Positional Parameters)
|
||||
|
|
@ -316,7 +316,7 @@ as determined at compile time.
|
|||
)
|
||||
vindex(OLDPWD)
|
||||
item(tt(OLDPWD))(
|
||||
The previous working directory. This is set when the shell initialises
|
||||
The previous working directory. This is set when the shell initializes
|
||||
and whenever the directory changes.
|
||||
)
|
||||
vindex(OPTARG)
|
||||
|
|
@ -339,7 +339,7 @@ The process ID of the parent of the shell.
|
|||
)
|
||||
vindex(PWD)
|
||||
item(tt(PWD))(
|
||||
The present working directory. This is set when the shell initialises
|
||||
The present working directory. This is set when the shell initializes
|
||||
and whenever the directory changes.
|
||||
)
|
||||
vindex(RANDOM)
|
||||
|
|
@ -592,7 +592,7 @@ item(tt(module_path) <S> <Z> (tt(MODULE_PATH) <S>))(
|
|||
An array (colon-separated list)
|
||||
of directories that tt(zmodload)
|
||||
searches for dynamically loadable modules.
|
||||
This is initialised to a standard pathname,
|
||||
This is initialized to a standard pathname,
|
||||
usually `tt(/usr/local/lib/zsh/$ZSH_VERSION)'.
|
||||
(The `tt(/usr/local/lib)' part varies from installation to installation.)
|
||||
For security reasons, any value set in the environment when the shell
|
||||
|
|
@ -858,6 +858,19 @@ item(tt(WORDCHARS) <S>)(
|
|||
A list of non-alphanumeric characters considered part of a word
|
||||
by the line editor.
|
||||
)
|
||||
vindex(ZBEEP)
|
||||
item(tt(ZBEEP))(
|
||||
If set, this gives a string of characters, which can use all the same codes
|
||||
as the tt(bindkey) command as described in
|
||||
ifzman(zmanref(zshzle))\
|
||||
ifnzman(noderef(Zsh Line Editor))\
|
||||
, that will be output to the terminal
|
||||
instead of beeping. This may have a visible instead of an audible effect;
|
||||
for example, the string `tt(\e[?5h\e[?5l)' on a vt100 or xterm will have
|
||||
the effect of flashing reverse video on and off (if you usually use reverse
|
||||
video, you should use the string `tt(\e[?5l\e[?5h)' instead). This takes
|
||||
precedence over the tt(NOBEEP) option.
|
||||
)
|
||||
vindex(ZDOTDIR)
|
||||
item(tt(ZDOTDIR))(
|
||||
The directory to search for shell startup files (.zshrc, etc),
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ two letters `tt(zf)'. They may already have been installed on your system;
|
|||
otherwise, you will need to find them and copy them. The directory should
|
||||
appear as one of the elements of the tt($fpath) array (this should already
|
||||
be the case if they were installed), and at least the function tt(zfinit)
|
||||
should be autoloaded; it will autoload the rest. Finally, to initialise
|
||||
should be autoloaded; it will autoload the rest. Finally, to initialize
|
||||
the use of the system you need to call the tt(zfinit) function. The
|
||||
following code in your tt(.zshrc) will arrange for this; assume the
|
||||
functions are stored in the directory tt(~/myfns):
|
||||
|
|
@ -59,7 +59,7 @@ zfinit)
|
|||
Note that tt(zfinit) assumes you are using the tt(zmodload) method to
|
||||
load the tt(zftp) command. If it is already built into the shell, change
|
||||
tt(zfinit) to tt(zfinit -n). It is helpful (though not essential) if the
|
||||
call to tt(zfinit) appears after any code to initialise the new completion
|
||||
call to tt(zfinit) appears after any code to initialize the new completion
|
||||
system, else unnecessary tt(compctl) commands will be given.
|
||||
|
||||
texinode(Zftp Functions)(Miscellaneous Features)(Installation)(Zftp Function System)
|
||||
|
|
@ -324,7 +324,7 @@ alter tt(zftp_chpwd) and tt(zftp_progress), in particular.
|
|||
|
||||
startitem()
|
||||
item(tt(zfinit [ -n ]))(
|
||||
As described above, this is used to initialise the zftp function system.
|
||||
As described above, this is used to initialize the zftp function system.
|
||||
The tt(-n) option should be used if the zftp command is already built into
|
||||
the shell.
|
||||
)
|
||||
|
|
|
|||
|
|
@ -102,7 +102,8 @@ cindex(widgets, user-defined)
|
|||
User-defined widgets, being implemented as shell functions,
|
||||
can execute any normal shell command. They can also run other widgets
|
||||
(whether built-in or user-defined) using the tt(zle) builtin command.
|
||||
Finally, they can examine and edit the ZLE buffer being edited by
|
||||
They can use tt(read -k) or tt(read -q) to read characters from standard
|
||||
input. Finally, they can examine and edit the ZLE buffer being edited by
|
||||
reading and setting the special parameters described below.
|
||||
|
||||
cindex(parameters, editor)
|
||||
|
|
@ -162,7 +163,11 @@ and meta-keys are reported with a leading `tt(M-)', as in `tt(M-a)' and
|
|||
)
|
||||
vindex(NUMERIC)
|
||||
item(tt(NUMERIC) (integer))(
|
||||
The numeric argument.
|
||||
The numeric argument. If no numeric argument was given, this parameter
|
||||
is unset. When this is set inside a widget function, builtin widgets
|
||||
called with the tt(zle) builtin command will use the value
|
||||
assigned. If it is unset inside awidget function, builtin widgets
|
||||
called behave as if no numeric argument was given.
|
||||
)
|
||||
vindex(HISTNO)
|
||||
item(tt(HISTNO) (integer))(
|
||||
|
|
@ -346,6 +351,10 @@ item(tt(down-line-or-search))(
|
|||
Move down a line in the buffer, or if already at the bottom line,
|
||||
search forward in the history for a line beginning with the first
|
||||
word in the buffer.
|
||||
|
||||
If called from a function by the tt(zle) command with arguments, the first
|
||||
argument is taken as the string for which to search, rather than the
|
||||
first word in the buffer.
|
||||
)
|
||||
tindex(down-history)
|
||||
item(tt(down-history) (unbound) (^N) (unbound))(
|
||||
|
|
@ -414,6 +423,17 @@ search, leaving the last found line in the buffer. Any single character that
|
|||
is not bound to one of the above functions, or tt(self-insert) or
|
||||
tt(self-insert-unmeta), will have the same effect but the function will be
|
||||
executed.
|
||||
|
||||
When called from a widget function by the tt(zle) command, the incremental
|
||||
search commands can take a string argument. This will be treated as a
|
||||
string of keys, as for arguments to the tt(bindkey) command, and used as
|
||||
initial input for the command. Any characters in the string which are
|
||||
unused by the incremental search will be silently ignored. For example,
|
||||
|
||||
example(zle history-incremental-search-backward forceps)
|
||||
|
||||
will search backwards for tt(forceps), leaving the minibuffer containing
|
||||
the string `tt(forceps)'.
|
||||
)
|
||||
tindex(history-incremental-search-forward)
|
||||
item(tt(history-incremental-search-forward) (^S ^Xs) (unbound) (unbound))(
|
||||
|
|
@ -427,6 +447,10 @@ tindex(history-search-backward)
|
|||
item(tt(history-search-backward) (ESC-P ESC-p) (unbound) (unbound))(
|
||||
Search backward in the history for a line beginning with the first
|
||||
word in the buffer.
|
||||
|
||||
If called from a function by the tt(zle) command with arguments, the first
|
||||
argument is taken as the string for which to search, rather than the
|
||||
first word in the buffer.
|
||||
)
|
||||
tindex(vi-history-search-backward)
|
||||
item(tt(vi-history-search-backward) (unbound) (/) (unbound))(
|
||||
|
|
@ -454,18 +478,27 @@ tt(magic-space) is treated as a space.
|
|||
Any other character that is not bound to self-insert or
|
||||
self-insert-unmeta will beep and be ignored. If the function is called from vi
|
||||
command mode, the bindings of the current insert mode will be used.
|
||||
|
||||
If called from a function by the tt(zle) command with arguments, the first
|
||||
argument is taken as the string for which to search, rather than the
|
||||
first word in the buffer.
|
||||
)
|
||||
tindex(history-search-forward)
|
||||
item(tt(history-search-forward) (ESC-N ESC-n) (unbound) (unbound))(
|
||||
Search forward in the history for a line beginning with the first
|
||||
word in the buffer.
|
||||
|
||||
If called from a function by the tt(zle) command with arguments, the first
|
||||
argument is taken as the string for which to search, rather than the
|
||||
first word in the buffer.
|
||||
)
|
||||
tindex(vi-history-search-forward)
|
||||
item(tt(vi-history-search-forward) (unbound) (?) (unbound))(
|
||||
Search forward in the history for a specified string.
|
||||
The string may begin with `tt(^)' to anchor the search to the
|
||||
beginning of the line. The functions available in the mini-buffer are the same
|
||||
as for tt(vi-history-search-backward).
|
||||
as for tt(vi-history-search-backward). Argument handling is also the same
|
||||
as for that command.
|
||||
)
|
||||
tindex(infer-next-history)
|
||||
item(tt(infer-next-history) (^X^N) (unbound) (unbound))(
|
||||
|
|
@ -504,6 +537,10 @@ item(tt(up-line-or-search))(
|
|||
Move up a line in the buffer, or if already at the top line,
|
||||
search backward in the history for a line beginning with the
|
||||
first word in the buffer.
|
||||
|
||||
If called from a function by the tt(zle) command with arguments, the first
|
||||
argument is taken as the string for which to search, rather than the
|
||||
first word in the buffer.
|
||||
)
|
||||
tindex(up-history)
|
||||
item(tt(up-history) (unbound) (^P) (unbound))(
|
||||
|
|
@ -800,7 +837,11 @@ startitem()
|
|||
tindex(digit-argument)
|
||||
item(tt(digit-argument) (ESC-0..ESC-9) (1-9) (unbound))(
|
||||
Start a new numeric argument, or add to the current one.
|
||||
See also tt(vi-digit-or-beginning-of-line).
|
||||
See also tt(vi-digit-or-beginning-of-line). This only works if bound to a
|
||||
key sequence ending in a decimal digit.
|
||||
|
||||
Inside a widget function, a call to this function treats the last key of
|
||||
the key sequence which called the widget as the digit.
|
||||
)
|
||||
tindex(neg-argument)
|
||||
item(tt(neg-argument) (ESC--) (unbound) (unbound))(
|
||||
|
|
@ -815,6 +856,10 @@ repeated using this command. For example, if this command occurs
|
|||
twice, followed immediately by tt(forward-char), move forward sixteen
|
||||
spaces; if instead it is followed by tt(-2), then tt(forward-char),
|
||||
move backward two spaces.
|
||||
|
||||
Inside a widget function, if passed an argument, i.e. `tt(zle
|
||||
universal-argument) var(num)', the numerical argument will be set to
|
||||
var(num); this is equivalent to `tt(NUMERIC=)var(num)'.
|
||||
)
|
||||
enditem()
|
||||
texinode(Completion)(Miscellaneous)(Arguments)(Zsh Line Editor)
|
||||
|
|
@ -911,6 +956,10 @@ item(tt(accept-line-and-down-history) (^O) (unbound) (unbound))(
|
|||
Execute the current line, and push the next history
|
||||
event on the the buffer stack.
|
||||
)
|
||||
tindex(beep)
|
||||
item(tt(beep))(
|
||||
Beep, unless the tt(BEEP) option is unset.
|
||||
)
|
||||
tindex(vi-cmd-mode)
|
||||
item(tt(vi-cmd-mode) (^X^V) (unbound) (^[))(
|
||||
Enter command mode; that is, select the `tt(vicmd)' keymap.
|
||||
|
|
|
|||
|
|
@ -15,12 +15,10 @@ ifnzman(\
|
|||
def(ifzshone)(1)()\
|
||||
def(ifzshall)(1)()\
|
||||
)\
|
||||
ifztexi(\
|
||||
ifztexi(
|
||||
texinfo(zsh.info)(zsh)
|
||||
NOTRANS(@setchapternewpage off
|
||||
@iftex
|
||||
NOTRANS(@iftex
|
||||
@finalout
|
||||
@afourpaper
|
||||
@end iftex)
|
||||
texititlepage()
|
||||
texititle(The Z Shell Guide)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ def(CMT)(0)(NOTRANS(@c))
|
|||
|
||||
ATEXIT(\
|
||||
NL()\
|
||||
NOTRANS(@setchapternewpage off)NL()\
|
||||
NOTRANS(@contents)NL()\
|
||||
NOTRANS(@bye)NL()\
|
||||
)
|
||||
|
|
@ -47,6 +46,10 @@ def(texinfo)(2)(\
|
|||
STDPAR()\
|
||||
NOTRANS(\input texinfo.tex)NL()\
|
||||
NOTRANS(@c %**start of header)NL()\
|
||||
NOTRANS(@iftex)NL()\
|
||||
NOTRANS(@afourpaper)NL()\
|
||||
NOTRANS(@setchapternewpage off)NL()\
|
||||
NOTRANS(@end iftex)NL()\
|
||||
NOTRANS(@setfilename )ARG1NL()\
|
||||
NOTRANS(@settitle )ARG2NL()\
|
||||
NOTRANS(@c %**end of header)NL()\
|
||||
|
|
|
|||
145
Etc/FAQ.yo
145
Etc/FAQ.yo
|
|
@ -49,22 +49,11 @@ description(
|
|||
mydit(Archive-Name:) unix-faq/shell/zsh
|
||||
mydit(Last-Modified:) 1999/05/24
|
||||
mydit(Submitted-By:) email(pws@ibmth.df.unipi.it (Peter Stephenson))
|
||||
mydit(Version:) $Id: FAQ.yo,v 1.1.1.4 1999/05/31 17:10:29 akr Exp $
|
||||
mydit(Version:) $Id: FAQ.yo,v 1.1.1.5 1999/06/27 05:33:49 akr Exp $
|
||||
mydit(Posting-Frequency:) Monthly
|
||||
mydit(Copyright:) (C) P.W. Stephenson, 1995--1999 (see end of document)
|
||||
)
|
||||
|
||||
bf(Changes since issue posted April 1999:)
|
||||
description(
|
||||
mydit(*.*) Orthography for option names standardised.
|
||||
mydit(1.4) don't change config.h.in, change acconfig.h
|
||||
mydit(1.6) email zefram@zsh.org
|
||||
mydit(2.4) new widget version of tcsh run-fg-editor
|
||||
mydit(3.7) should have mentioned tt(PRINT_EIGHT_BIT) is new in 3.1
|
||||
mydit(3.23) new: describe tt(PROMPT_CR) option.
|
||||
mydit(5.1) Description of tt(LIST_AMBIGUOUS) corrected.
|
||||
)
|
||||
|
||||
This document contains a list of frequently-asked (or otherwise
|
||||
significant) questions concerning the Z-shell, a command interpreter
|
||||
for many UNIX systems which is freely available to anyone with FTP
|
||||
|
|
@ -125,6 +114,7 @@ Chapter 3: How to get various things to work
|
|||
3.21. Why is my history not being saved?
|
||||
3.22. How do I get a variable's value to be evaluated as another variable?
|
||||
3.23. How do I prevent the prompt overwriting output when there is no newline?
|
||||
3.24. What's wrong with cut and paste on my xterm?
|
||||
|
||||
Chapter 4: The mysteries of completion
|
||||
4.1. What is completion?
|
||||
|
|
@ -309,11 +299,11 @@ sect(What's the latest version?)
|
|||
list of incompatibilities at the end of link(5.1)(51). This is longer
|
||||
than usual due to enhanced sh, ksh and POSIX compatibility.
|
||||
|
||||
The beta version 3.1.5 is also available. Development of zsh is
|
||||
usually patch by patch, with each intermediate version publicly
|
||||
available. Note that this `open' development system does mean bugs
|
||||
are sometimes introduced into the most recent archived version.
|
||||
These are usually fixed quickly.
|
||||
The beta version 3.1.5 is also available, and 3.1.6 should appear over
|
||||
the summer. Development of zsh is usually patch by patch, with each
|
||||
intermediate version publicly available. Note that this `open'
|
||||
development system does mean bugs are sometimes introduced into the most
|
||||
recent archived version. These are usually fixed quickly.
|
||||
|
||||
Note also that as the shell changes, it may become incompatible with
|
||||
older versions; see the end of question link(5.1)(51) for a partial list.
|
||||
|
|
@ -326,17 +316,20 @@ sect(What's the latest version?)
|
|||
sect(Where do I get it?)
|
||||
label(16)
|
||||
|
||||
The archive is now run by email(Andrew Main <zefram@zsh.org>).
|
||||
The following are known mirrors (kept frequently up to date); the
|
||||
The coordinator of development is currently me; the alias
|
||||
email(coordinator@zsh.org) can be used to contact whoever is in the hot
|
||||
seat. The following are known mirrors (kept frequently up to date); the
|
||||
first is the official archive site, currently in Australia. All are
|
||||
available by anonymous FTP. The major sites keep test versions in
|
||||
the 'testing' subdirectory: such up-to-the-minute development
|
||||
versions should only be retrieved if you actually plan to help test
|
||||
the latest version of the shell. The following list also appears
|
||||
on the WWW at url(http://www.zsh.org)(http://www.zsh.org) .
|
||||
available by anonymous FTP. The major sites keep test versions in the
|
||||
`testing' subdirectory: such up-to-the-minute development versions should
|
||||
only be retrieved if you actually plan to help test the latest version of
|
||||
the shell. The following list also appears on the WWW at
|
||||
url(http://www.zsh.org)(http://www.zsh.org) .
|
||||
|
||||
description(
|
||||
mydit(Home site) url(ftp://ftp.zsh.org)(ftp://ftp.zsh.org)
|
||||
mydit() url(http://www.zsh.org/pub/zsh/)
|
||||
(http://www.zsh.org/pub/zsh/)
|
||||
mydit(Australia) url(ftp://ftp.ips.gov.au/mirror/zsh/)
|
||||
(ftp://ftp.ips.gov.au/mirror/zsh/)
|
||||
mydit(Denmark) url(ftp://sunsite.auc.dk/pub/unix/shells/zsh)
|
||||
|
|
@ -354,7 +347,9 @@ label(16)
|
|||
mydit(Hungary) url(ftp://ftp.cs.elte.hu/pub/zsh/)
|
||||
(ftp://ftp.cs.elte.hu/pub/zsh/)
|
||||
mydit() (also url(http://www.cs.elte.hu/pub/zsh/)
|
||||
(http://www.cs.elte.hu/pub/zsh/) )
|
||||
(http://www.cs.elte.hu/pub/zsh/) )
|
||||
mydit() url(ftp://ftp.kfki.hu/pub/packages/zsh/)
|
||||
(ftp://ftp.kfki.hu/pub/packages/zsh/)
|
||||
mydit(Israel) \
|
||||
url(ftp://ftp.math.technion.ac.il/mirror/ftp.zsh.org/pub/zsh/)
|
||||
(ftp://ftp.math.technion.ac.il/mirror/ftp.zsh.org/pub/zsh/)
|
||||
|
|
@ -363,7 +358,7 @@ url(http://www.math.technion.ac.il/mirror/ftp.zsh.org/pub/zsh/)
|
|||
(http://www.math.technion.ac.il/mirror/ftp.zsh.org/pub/zsh/)
|
||||
mydit(Japan) url(ftp://ftp.tohoku.ac.jp/mirror/zsh/)
|
||||
(ftp://ftp.tohoku.ac.jp/mirror/zsh/)
|
||||
mydit() url(ftp://ftp.nis.co.jp/pub/shells/zsh/)
|
||||
mydit() url(ftp://ftp.nisiq.net/pub/shells/zsh/)
|
||||
(ftp://ftp.nis.co.jp/pub/shells/zsh/)
|
||||
mydit() url(ftp://ftp.win.ne.jp/pub/shell/zsh/)
|
||||
(ftp://ftp.win.ne.jp/pub/shell/zsh/)
|
||||
|
|
@ -378,8 +373,8 @@ url(http://www.math.technion.ac.il/mirror/ftp.zsh.org/pub/zsh/)
|
|||
mydit(UK) url(ftp://ftp.net.lut.ac.uk/zsh/)
|
||||
(ftp://ftp.net.lut.ac.uk/zsh/)
|
||||
mydit() (also by FSP at port 21)
|
||||
mydit() url(ftp://src.doc.ic.ac.uk/packages/unix/shells/zsh/)
|
||||
(ftp://src.doc.ic.ac.uk/packages/unix/shells/zsh/)
|
||||
mydit() url(ftp://sunsite.org.uk/packages/zsh/)
|
||||
(ftp://sunsite.org.uk/packages/zsh/)
|
||||
mydit(USA) url(ftp://ftp.math.gatech.edu/pub/zsh/)
|
||||
(ftp://ftp.math.gatech.edu/pub/zsh/)
|
||||
mydit() url(ftp://uiarchive.uiuc.edu/pub/packages/shells/zsh/)
|
||||
|
|
@ -388,6 +383,10 @@ url(http://www.math.technion.ac.il/mirror/ftp.zsh.org/pub/zsh/)
|
|||
(ftp://ftp.sterling.com/zsh/)
|
||||
mydit() url(ftp://ftp.rge.com/pub/shells/zsh/)
|
||||
(ftp://ftp.rge.com/pub/shells/zsh/)
|
||||
mydit() url(ftp://foad.org/pub/zsh/)
|
||||
(ftp://foad.org/pub/zsh/)
|
||||
mydit() url(http://foad.org/zsh/)
|
||||
(http://foad.org/zsh/)
|
||||
)
|
||||
|
||||
The Windows port mentioned above is maintained separately by email(Amol
|
||||
|
|
@ -464,7 +463,6 @@ sect(I don't have root access: how do I make zsh my login shell?)
|
|||
endif
|
||||
)
|
||||
|
||||
|
||||
It's not a good idea to put this (even without the -l) into .cshrc,
|
||||
at least without some tests on what the csh is supposed to be doing,
|
||||
as that will cause _every_ instance of csh to turn into a zsh and
|
||||
|
|
@ -577,10 +575,6 @@ tt(SH_OPTION_LETTERS),
|
|||
it()* The results of parameter substitutions are treated as plain text:
|
||||
mytt(foo="*"; print $foo) prints all files in ksh but mytt(*) in zsh
|
||||
(uset tt(GLOB_SUBST)).
|
||||
it() The backslash in tt($(echo '\$x')) is treated differently: in \
|
||||
ksh, it
|
||||
is not stripped, in zsh it is. (The tt(`...`) form gives the same in
|
||||
both shells.)
|
||||
it()* tt($PSn) do not do parameter substitution by default (use \
|
||||
PROMPT_SUBST).
|
||||
it()* Standard globbing does not allow ksh-style `pattern-lists'.
|
||||
|
|
@ -641,11 +635,11 @@ link(2.3)(23).
|
|||
it()* Options are not local to functions (use LOCAL_OPTIONS; note this
|
||||
may always be unset locally to propagate options settings from a
|
||||
function to the calling level).
|
||||
it() Function definitions themselves are not local to functions.
|
||||
)
|
||||
it() Traps and signals:
|
||||
itemize(
|
||||
it() Traps are not local to functions.
|
||||
it()* Traps are not local to functions. The option LOCAL_TRAPS will
|
||||
be available from 3.1.6.
|
||||
it() TRAPERR has become TRAPZERR (this was forced by UNICOS which
|
||||
has SIGERR).
|
||||
)
|
||||
|
|
@ -660,6 +654,8 @@ link(2.3)(23).
|
|||
release either.)
|
||||
it() Management of histories in multiple shells is different:
|
||||
the history list is not saved and restored after each command.
|
||||
(The option tt(SHARE_HISTORY) will appear in 3.1.6 and will be
|
||||
set in ksh compatibility mode to remedy this.)
|
||||
it() mytt(\) does not escape editing chars (use mytt(^V)).
|
||||
it() Not all ksh bindings are set (e.g. mytt(<ESC>#); try mytt(<ESC>q)).
|
||||
it()* mytt(#) in an interactive shell is not treated as a comment by
|
||||
|
|
@ -1155,15 +1151,16 @@ sect(How do I automatically display the directory in my xterm title bar?)
|
|||
|
||||
sect(How do I make the completion list use eight bit characters?)
|
||||
|
||||
If you are sure your terminal handles this, the easiest way from version
|
||||
3.1 of the shell is to set the option tt(PRINT_EIGHT_BIT). In principle,
|
||||
this will work automatically if your computer uses the `locale' system
|
||||
and your locale variables are set properly, as zsh understands this.
|
||||
However, it is quite complicated, so if it isn't already set up, trying
|
||||
the option is a lot easier. For 3.0, you are stuck with trying to
|
||||
understand locales, see the tt(setlocale(3)) and tt(zshparam(1)) manual
|
||||
pages: the simplest possibility may be to set tt(LC_ALL=en_US). For older
|
||||
versions of the shell, there is no easy way out.
|
||||
If you are sure your terminal handles this, the easiest way from versions
|
||||
3.0.6 and 3.1 of the shell is to set the option tt(PRINT_EIGHT_BIT). In
|
||||
principle, this will work automatically if your computer uses the
|
||||
`locale' system and your locale variables are set properly, as zsh
|
||||
understands this. However, it is quite complicated, so if it isn't
|
||||
already set up, trying the option is a lot easier. For earlier versions
|
||||
of zsh 3, you are stuck with trying to understand locales, see the
|
||||
tt(setlocale(3)) and tt(zshparam(1)) manual pages: the simplest
|
||||
possibility may be to set tt(LC_ALL=en_US). For older versions of the
|
||||
shell, there is no easy way out.
|
||||
|
||||
|
||||
sect(Why do the cursor (arrow) keys not work?)
|
||||
|
|
@ -1538,8 +1535,8 @@ sect(How do I get a variable's value to be evaluated as another variable?)
|
|||
)
|
||||
produces the same result.
|
||||
|
||||
Future versions of zsh will probably allow you to do this directly,
|
||||
with a new flag; mytt(${(P)E}).
|
||||
Versions 3.1.6 of zsh will allow you to do this directly with a new flag;
|
||||
mytt(${(P)E}).
|
||||
|
||||
As a slight aside, sometimes people note that the syntax mytt(${${E}})
|
||||
is valid and expect it to have this effect. It probably ought to, but
|
||||
|
|
@ -1569,6 +1566,39 @@ sect(How do I prevent the prompt overwriting output when there is no newline?)
|
|||
prompt (see question link(3.13)(313) for that).
|
||||
|
||||
|
||||
sect(What's wrong with cut and paste on my xterm?)
|
||||
|
||||
On the majority of modern UNIX systems, cutting text from one window and
|
||||
pasting it into another should work fine. On a few, however, there are
|
||||
problems due to issues about how the terminal is handled: most programs
|
||||
expect the terminal to be in `canonical input mode', which means that the
|
||||
program is passed a whole line of input at a time, while for editing
|
||||
the shell needs a single character at a time and must be in
|
||||
`non-canonical input mode'. On the systems in question, input can be
|
||||
lost or re-ordered when the mode changes. There are actually two
|
||||
slightly different problems:
|
||||
enumerate(
|
||||
myeit() When you paste something in while a programme is running, so that
|
||||
the shell only retrieves it later. Traditionally, there was a test
|
||||
which was used only on systems where the problem was known to exist,
|
||||
so it is possible some other systems were not handled (for example,
|
||||
certain versions of IRIX, it appears); also, continuation lines were
|
||||
not handled properly. A more reliable approach will appear in
|
||||
versions 3.0.6 and 3.1.6.
|
||||
myeit() When the shell is waiting for input, and you paste in a chunk of
|
||||
text consisting of more than one complete set of commands.
|
||||
Unfortunately, this is a much harder problem: the line editor is
|
||||
already active, and needs to be turned off when the first command is
|
||||
executed. The shell doesn't even know if the remaining text is input
|
||||
to a command or for the shell, so there's simply nothing it can do.
|
||||
However, if you have problems you can trick it: type `tt({)' on a line
|
||||
by itself, then paste the input, then type `tt(})' on a line by
|
||||
itself. The shell will not execute anything until the final brace is
|
||||
read; all input is read as continuation lines (this may require the
|
||||
fixes referred to above in order to be reliable).
|
||||
)
|
||||
|
||||
|
||||
chapter(The mysteries of completion)
|
||||
|
||||
Programmable completion using the `compctl' command is one of the most
|
||||
|
|
@ -1673,7 +1703,7 @@ sect(How does zsh deal with ambiguous completions?)
|
|||
flexibility for what it does here via its options. The default is
|
||||
for it to beep and completion to stop until you type another
|
||||
character. You can type tt(\C-D) to see all the possible completions.
|
||||
(That's assuming your at the end of the line, otherwise tt(\C-D) will
|
||||
(That's assuming you're at the end of the line, otherwise tt(\C-D) will
|
||||
delete the next character and you have to use tt(ESC-\C-D).) This can be
|
||||
changed by the following options, among others:
|
||||
itemize(
|
||||
|
|
@ -1887,13 +1917,15 @@ this applies
|
|||
|
||||
itemize(
|
||||
it() mytt(time) is ignored with builtins and can't be used with mytt({...}).
|
||||
it() mytt(set -x) (mytt(setopt xtrace)) still has a few glitches.
|
||||
it() mytt(set -x) (mytt(setopt xtrace)) still has a few glitches; these
|
||||
are mostly fixed in 3.1.6.
|
||||
it() Zsh's notion of the current line number (via tt($LINENO)) is
|
||||
sometimes not well handled, particularly when using functions and traps.
|
||||
This should also work reliably from 3.1.6.
|
||||
it() In vi mode, mytt(u) can go past the original modification point.
|
||||
it() The singlelinezle option has problems with prompts containing escapes.
|
||||
it() The mytt(r) command does not work inside mytt($(...)) or mytt(`...`)
|
||||
expansions. (This is fixed in 3.1.)
|
||||
expansions. This is fixed in 3.1.
|
||||
it() mytt(typeset) handling is non-optimal, particularly with regard to
|
||||
flags, and is ksh-incompatible in unpredictable ways.
|
||||
it() Nested closures in extended globbing and pattern matching, such as
|
||||
|
|
@ -1901,8 +1933,8 @@ this applies
|
|||
[[ fofo = (fo#)# ]]
|
||||
)
|
||||
were not correctly handled, and there were problems with
|
||||
complicated exclusions using mytt(^) or mytt(~). (These
|
||||
are fixed in version 3.1.3.)
|
||||
complicated exclusions using mytt(^) or mytt(~). These
|
||||
are fixed in version 3.1.3.
|
||||
)
|
||||
|
||||
Note that a few recent changes introduce incompatibilities (these
|
||||
|
|
@ -1918,7 +1950,7 @@ this applies
|
|||
zsh features are never noticed by many users. To turn them off,
|
||||
just put mytt(unsetopt alwayslastprompt listambiguous) in your
|
||||
tt(.zshrc) file.
|
||||
it() tt(history-search-{forward,backward}) now only find previous
|
||||
it() In 3.1.5, tt(history-search-{forward,backward}) only find previous
|
||||
lines where the first word is the same as the current one. For
|
||||
example,
|
||||
verb(
|
||||
|
|
@ -2051,11 +2083,7 @@ label(52)
|
|||
email(zsh-workers-owner@sunsite.auc.dk). The list maintainer's
|
||||
real name is email(Karsten Thygesen <karthy@kom.auc.dk>).
|
||||
|
||||
The list from May 1992 to May 1995 is archived in
|
||||
url(ftp://ftp.sterling.com/zsh/zsh-list/YY-MM)
|
||||
(ftp://ftp.sterling.com/zsh/zsh-list/YY-MM)
|
||||
where YY-MM are the year and month in digits. More recent
|
||||
mailings up to date are to be found at
|
||||
An archive of mailings for the last few years can be found at
|
||||
url(http://www.zsh.org/mla/)(http://www.zsh.org/mla/)
|
||||
at the main zsh archive in Australia.
|
||||
|
||||
|
|
@ -2089,7 +2117,8 @@ sect(What's on the wish-list?)
|
|||
case-insensitive matching and wild card anchors, e.g. mytt(z_t<TAB>)
|
||||
can allow a wildcard before the mytt(_) so that this will expand
|
||||
to mytt(zle_tricky.c) --- all under user control; completions can
|
||||
be grouped.
|
||||
be grouped; a new completion command, menu-select, allows real menu
|
||||
selection --- you can move the cursor around to choose a completion.
|
||||
it() Case-insensitive and approximate matching in the globbing code:
|
||||
for example, mytt((#ia2)readme) matches the string mytt(readme)
|
||||
case-insensitively with up to two errors, such as tt(README),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
# zfgoto bname
|
||||
# Go to bookmark bname, a location on a remote FTP host. Unless
|
||||
# this was the last session or is for anonymous FTP, prompt for
|
||||
# the user's password.
|
||||
|
||||
emulate -L zsh
|
||||
setopt extendedglob
|
||||
|
||||
# Set ZFTP_BMFILE if not already set. This should agree with
|
||||
# the corresponding line in zfmark.
|
||||
: ${ZFTP_BMFILE:=${ZFDOTDIR:-$HOME}/.zfbkmarks}
|
||||
|
||||
typeset -A bkmarks
|
||||
local line ncftp opt optlist
|
||||
|
||||
while [[ $1 == -* ]]; do
|
||||
if [[ $1 == - || $1 == -- ]]; then
|
||||
shift;
|
||||
break;
|
||||
fi
|
||||
optlist=${1#-}
|
||||
for (( i = 1; i <= $#optlist; i++)); do
|
||||
opt=$optlist[$i]
|
||||
case $opt in
|
||||
n) ncftp=1
|
||||
;;
|
||||
*) print option $opt not recognised >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift
|
||||
done
|
||||
|
||||
if (( $# != 1 )); then
|
||||
print "Usage: zfgoto bookmark" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ -n $ncftp && -f ~/.ncftp/bookmarks ]]; then
|
||||
local oldifs=$IFS
|
||||
IFS=,
|
||||
while read -rA line; do
|
||||
bkmarks[$line[1]]="${line[3]:-anonymous}@${line[2]}:${line[6]}"
|
||||
done < ~/.ncftp/bookmarks
|
||||
IFS=$oldifs
|
||||
elif [[ -f $ZFTP_BMFILE ]]; then
|
||||
# read in file: could optimise this by recording last read time
|
||||
# comparing with file
|
||||
while read -r line; do
|
||||
# ignore blank and comment lines
|
||||
[[ $line = [[:blank:]]# || $line = [[:blank:]]#'#'* ]] && continue
|
||||
bkmarks[${line%% *}]="${line#* }"
|
||||
done <$ZFTP_BMFILE
|
||||
fi
|
||||
|
||||
line=${bkmarks[$1]}
|
||||
|
||||
if [[ -z $line ]]; then
|
||||
print "Bookmark \`$1' not found" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
local user host dir
|
||||
user=${line%%@*}
|
||||
line=${line#*@}
|
||||
host=${line%%:*}
|
||||
dir=${line#*:}
|
||||
|
||||
if [[ $user = ftp || $user = anonymous ]]; then
|
||||
# Anonymous ftp, so we don't need password etc.
|
||||
zfanon $host && [[ -n $dir ]] && zfcd $dir
|
||||
elif [[ $zflastsession = ${host}:* && $user = $zflastuser ]]; then
|
||||
# This was the last session, so assume it's still setup in the
|
||||
# open parameters
|
||||
zfopen && [[ -n $dir ]] && zfcd $dir
|
||||
else
|
||||
# Last try: see if it's in the parameters.
|
||||
local params
|
||||
params=($(zftp params))
|
||||
if [[ $host = $params[1] && $user = $params[2] ]]; then
|
||||
zfopen && [[ -n $dir ]] && zfcd $dir
|
||||
else
|
||||
zfopen $host $user && [[ -n $dir ]] && zfcd $dir
|
||||
fi
|
||||
fi
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
# zfmark [bname]
|
||||
# Set a bookmark for the current zftp connection, or use the
|
||||
# information about the last session if there isn't one.
|
||||
# A bookmark includes both the host *and* the directory on that host.
|
||||
#
|
||||
# Without bname, list the current bookmarks and their locations.
|
||||
|
||||
emulate -L zsh
|
||||
setopt extendedglob
|
||||
|
||||
# Set ZFTP_BMFILE if not already set. This should agree with
|
||||
# the corresponding line in zfgoto.
|
||||
: ${ZFTP_BMFILE:=${ZDOTDIR:-$HOME}/.zfbkmarks}
|
||||
|
||||
typeset -A bkmarks
|
||||
local line
|
||||
|
||||
if [[ -f $ZFTP_BMFILE ]]; then
|
||||
# read in file: could optimise this by recording last read time
|
||||
# comparing with file
|
||||
while read -r line; do
|
||||
# ignore blank and comment lines
|
||||
[[ $line = [[:blank:]]# || $line = [[:blank:]]#'#'* ]] && continue
|
||||
bkmarks[${line%% *}]="${line#* }"
|
||||
done <$ZFTP_BMFILE
|
||||
fi
|
||||
|
||||
if (( $# == 0 )); then
|
||||
for line in ${(ko)bkmarks}; do
|
||||
print -r- "$line ${bkmarks[$line]}"
|
||||
done
|
||||
return 0
|
||||
elif (( $# > 1 )); then
|
||||
print "Usage: zfmark [bookmark]" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ -n $ZFTP_HOST ]]; then
|
||||
bkmarks[$1]="${ZFTP_USER}@${ZFTP_HOST}:${ZFTP_PWD}"
|
||||
elif [[ -n $zflastsession ]]; then
|
||||
bkmarks[$1]="${zflastuser}@${zflastsession}"
|
||||
else
|
||||
print "No current or recent ZFTP session to bookmark." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
for line in ${(ko)bkmarks}; do
|
||||
print -r- "$line ${bkmarks[$line]}"
|
||||
done >$ZFTP_BMFILE
|
||||
|
|
@ -326,7 +326,7 @@ setfunction(char *name, char *val)
|
|||
val = metafy(val, strlen(val), META_REALLOC);
|
||||
|
||||
HEAPALLOC {
|
||||
list = parse_string(val);
|
||||
list = parse_string(val, 1);
|
||||
} LASTALLOC;
|
||||
|
||||
if (!list || list == &dummy_list) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ DISTFILES_SRC='
|
|||
.cvsignore .distfiles .exrc
|
||||
comp1.mdd comp.h comp1.c comp1.export
|
||||
compctl.mdd compctl.c
|
||||
complist.mdd complist.c
|
||||
deltochar.mdd deltochar.c
|
||||
zle.mdd iwidgets.list zle.h zle_bindings.c zle_hist.c
|
||||
zle_keymap.c zle_main.c zle_misc.c zle_move.c zle_params.c
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ typedef struct patcomp *Patcomp;
|
|||
typedef struct cmatcher *Cmatcher;
|
||||
typedef struct cmlist *Cmlist;
|
||||
typedef struct cpattern *Cpattern;
|
||||
typedef struct menuinfo *Menuinfo;
|
||||
|
||||
/* node for compctl hash table (compctltab) */
|
||||
|
||||
|
|
@ -266,6 +267,19 @@ struct cpattern {
|
|||
#define CFN_FIRST 1
|
||||
#define CFN_DEFAULT 2
|
||||
|
||||
/* Information about menucompletion stuff. */
|
||||
|
||||
struct menuinfo {
|
||||
Cmgroup group; /* position in the group list */
|
||||
Cmatch *cur; /* match currently inserted */
|
||||
int pos; /* begin on line */
|
||||
int len; /* length of inserted string */
|
||||
int end; /* end on the line */
|
||||
int we; /* non-zero if the cursor was at the end */
|
||||
int insc; /* length of suffix inserted */
|
||||
int asked; /* we asked if the list should be shown */
|
||||
};
|
||||
|
||||
/* Flags for compadd and addmatches(). */
|
||||
|
||||
#define CAF_QUOTE 1
|
||||
|
|
@ -286,6 +300,7 @@ struct cadata {
|
|||
char *pre; /* prefix to insert (-P) */
|
||||
char *suf; /* suffix to insert (-S) */
|
||||
char *group; /* name of the group (-[JV]) */
|
||||
char *ylist; /* display list (-y) */
|
||||
char *rems; /* remove suffix on chars... (-r) */
|
||||
char *remf; /* function to remove suffix (-R) */
|
||||
char *ign; /* ignored suffixes (-F) */
|
||||
|
|
@ -298,6 +313,16 @@ struct cadata {
|
|||
char *dpar; /* array to delete non-matches in (-D) */
|
||||
};
|
||||
|
||||
/* Data given to hooks. */
|
||||
|
||||
typedef struct chdata *Chdata;
|
||||
|
||||
struct chdata {
|
||||
Cmgroup matches; /* the matches generated */
|
||||
int num; /* the number of matches */
|
||||
Cmatch cur; /* current match or NULL */
|
||||
};
|
||||
|
||||
/* Flags for special parameters. */
|
||||
|
||||
#define CPN_WORDS 0
|
||||
|
|
|
|||
|
|
@ -1727,7 +1727,7 @@ bin_compadd(char *name, char **argv, char *ops, int func)
|
|||
}
|
||||
dat.ipre = dat.isuf = dat.ppre = dat.psuf = dat.prpre =
|
||||
dat.pre = dat.suf = dat.group = dat.rems = dat.remf =
|
||||
dat.ign = dat.exp = dat.apar = dat.opar = dat.dpar = NULL;
|
||||
dat.ign = dat.exp = dat.apar = dat.opar = dat.dpar = dat.ylist = NULL;
|
||||
dat.match = NULL;
|
||||
dat.flags = 0;
|
||||
dat.aflags = CAF_MATCH;
|
||||
|
|
@ -1779,6 +1779,10 @@ bin_compadd(char *name, char **argv, char *ops, int func)
|
|||
sp = &(dat.group);
|
||||
e = "group name expected after -%c";
|
||||
break;
|
||||
case 'y':
|
||||
sp = &(dat.ylist);
|
||||
e = "string expected after -%c";
|
||||
break;
|
||||
case 'i':
|
||||
sp = &(dat.ipre);
|
||||
e = "string expected after -%c";
|
||||
|
|
@ -2217,13 +2221,14 @@ static void
|
|||
addcompparams(struct compparam *cp, Param *pp)
|
||||
{
|
||||
for (; cp->name; cp++, pp++) {
|
||||
Param pm = createparam(cp->name, cp->type | PM_SPECIAL | PM_REMOVABLE);
|
||||
Param pm = createparam(cp->name,
|
||||
cp->type |PM_SPECIAL|PM_REMOVABLE|PM_LOCAL);
|
||||
if (!pm)
|
||||
pm = (Param) paramtab->getnode(paramtab, cp->name);
|
||||
DPUTS(!pm, "param not set in addcompparams");
|
||||
|
||||
*pp = pm;
|
||||
pm->level = locallevel;
|
||||
pm->level = locallevel + 1;
|
||||
if ((pm->u.data = cp->var)) {
|
||||
switch(PM_TYPE(cp->type)) {
|
||||
case PM_SCALAR:
|
||||
|
|
@ -2257,7 +2262,8 @@ makecompparams(void)
|
|||
|
||||
addcompparams(comprparams, comprpms);
|
||||
|
||||
if (!(cpm = createparam(COMPSTATENAME, PM_SPECIAL|PM_REMOVABLE|PM_HASHED)))
|
||||
if (!(cpm = createparam(COMPSTATENAME,
|
||||
PM_SPECIAL|PM_REMOVABLE|PM_LOCAL|PM_HASHED)))
|
||||
cpm = (Param) paramtab->getnode(paramtab, COMPSTATENAME);
|
||||
DPUTS(!cpm, "param not set in makecompparams");
|
||||
|
||||
|
|
|
|||
918
Src/Zle/complist.c
Normal file
918
Src/Zle/complist.c
Normal file
|
|
@ -0,0 +1,918 @@
|
|||
/*
|
||||
* complist.c - completion listing enhancements
|
||||
*
|
||||
* This file is part of zsh, the Z shell.
|
||||
*
|
||||
* Copyright (c) 1999 Sven Wischnowsky
|
||||
* 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 Sven Wischnowsky 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 Sven Wischnowsky and the Zsh Development Group have been advised of
|
||||
* the possibility of such damage.
|
||||
*
|
||||
* Sven Wischnowsky 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 Sven Wischnowsky and the
|
||||
* Zsh Development Group have no obligation to provide maintenance,
|
||||
* support, updates, enhancements, or modifications.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "complist.mdh"
|
||||
#include "complist.pro"
|
||||
|
||||
|
||||
/* We use the parameters ZLS_COLORS and ZLS_COLOURS in the same way as
|
||||
* the color ls does. It's just that we don't support the `or' file
|
||||
* type. */
|
||||
|
||||
|
||||
static Widget w_menuselect;
|
||||
static Keymap mskeymap;
|
||||
|
||||
/* Indixes into the terminal string arrays. */
|
||||
|
||||
#define COL_NO 0
|
||||
#define COL_FI 1
|
||||
#define COL_DI 2
|
||||
#define COL_LN 3
|
||||
#define COL_PI 4
|
||||
#define COL_SO 5
|
||||
#define COL_BD 6
|
||||
#define COL_CD 7
|
||||
#define COL_EX 8
|
||||
#define COL_MI 9
|
||||
#define COL_LC 10
|
||||
#define COL_RC 11
|
||||
#define COL_EC 12
|
||||
#define COL_MA 13
|
||||
|
||||
#define NUM_COLS 14
|
||||
|
||||
/* Names of the terminal strings. */
|
||||
|
||||
static char *colnames[] = {
|
||||
"no", "fi", "di", "ln", "pi", "so", "bd", "cd", "ex", "mi",
|
||||
"lc", "rc", "ec", "ma", NULL
|
||||
};
|
||||
|
||||
/* Default values. */
|
||||
|
||||
static char *defcols[] = {
|
||||
"0", "0", "1;34", "1;36", "33", "1;35", "1;33", "1;33", "1;32", NULL,
|
||||
"\033[", "m", NULL, "7"
|
||||
};
|
||||
|
||||
/* This describes a terminal string for a filename extension. */
|
||||
|
||||
typedef struct extcol *Extcol;
|
||||
|
||||
struct extcol {
|
||||
char *ext; /* the extension */
|
||||
char *col; /* the terminal color string */
|
||||
Extcol next; /* the next one in the list */
|
||||
};
|
||||
|
||||
/* This holds all terminal strings. */
|
||||
|
||||
typedef struct listcols *Listcols;
|
||||
|
||||
struct listcols {
|
||||
char *cols[NUM_COLS]; /* strings for file types */
|
||||
Extcol exts; /* strings for extensions */
|
||||
};
|
||||
|
||||
/* This parses the value of a definition (the part after the `=').
|
||||
* The return value is a pointer to the character after it. */
|
||||
|
||||
static char *
|
||||
getcolval(char *s)
|
||||
{
|
||||
char *p;
|
||||
|
||||
for (p = s; *s && *s != ':'; p++, s++) {
|
||||
if (*s == '\\' && s[1]) {
|
||||
switch (*++s) {
|
||||
case 'a': *p = '\007'; break;
|
||||
case 'n': *p = '\n'; break;
|
||||
case 'b': *p = '\b'; break;
|
||||
case 't': *p = '\t'; break;
|
||||
case 'v': *p = '\v'; break;
|
||||
case 'f': *p = '\f'; break;
|
||||
case 'r': *p = '\r'; break;
|
||||
case 'e': *p = '\033'; break;
|
||||
case '_': *p = ' '; break;
|
||||
case '?': *p = '\177'; break;
|
||||
default:
|
||||
if (*s >= '0' && *s <= '7') {
|
||||
int i = STOUC(*s);
|
||||
|
||||
if (*++s >= '0' && *s <= '7') {
|
||||
i = (i * 8) + STOUC(*s);
|
||||
if (*++s >= '0' && *s <= '7')
|
||||
i = (i * 8) + STOUC(*s);
|
||||
}
|
||||
*p = (char) i;
|
||||
} else
|
||||
*p = *s;
|
||||
}
|
||||
} else if (*s == '^') {
|
||||
if ((s[1] >= '@' && s[1] <= '_') ||
|
||||
(s[1] >= 'a' && s[1] <= 'z'))
|
||||
*p = (char) (STOUC(*s) & ~0x60);
|
||||
else if (s[1] == '?')
|
||||
*p = '\177';
|
||||
else {
|
||||
*p++ = *s;
|
||||
*p = s[1];
|
||||
}
|
||||
s++;
|
||||
} else
|
||||
*p = *s;
|
||||
}
|
||||
if (p != s)
|
||||
*p = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
/* This parses one definition. Return value is a pointer to the
|
||||
* character after it. */
|
||||
|
||||
static char *
|
||||
getcoldef(Listcols c, char *s)
|
||||
{
|
||||
if (*s == '*') {
|
||||
Extcol ec;
|
||||
char *n, *p;
|
||||
|
||||
/* This is for an extension. */
|
||||
|
||||
n = ++s;
|
||||
while (*s && *s != '=')
|
||||
s++;
|
||||
if (!*s )
|
||||
return s;
|
||||
*s++ = '\0';
|
||||
p = getcolval(s);
|
||||
if (*n) {
|
||||
ec = (Extcol) zhalloc(sizeof(*ec));
|
||||
ec->ext = n;
|
||||
ec->col = s;
|
||||
ec->next = c->exts;
|
||||
c->exts = ec;
|
||||
}
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
return p;
|
||||
} else {
|
||||
char *n = s, *p, **nn;
|
||||
int i;
|
||||
|
||||
/* This is for a file type. */
|
||||
|
||||
while (*s && *s != '=')
|
||||
s++;
|
||||
if (!*s)
|
||||
return s;
|
||||
*s++ = '\0';
|
||||
for (i = 0, nn = colnames; *nn; i++, nn++)
|
||||
if (!strcmp(n ,*nn))
|
||||
break;
|
||||
p = getcolval(s);
|
||||
if (*nn)
|
||||
c->cols[i] = s;
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
/* This initializes the given terminal color structure. */
|
||||
|
||||
static int
|
||||
getcols(Listcols c)
|
||||
{
|
||||
char *s;
|
||||
int i;
|
||||
|
||||
if (!(s = getsparam("ZLS_COLORS")) &&
|
||||
!(s = getsparam("ZLS_COLOURS"))) {
|
||||
if (!c)
|
||||
return 1;
|
||||
for (i = 0; i < NUM_COLS; i++)
|
||||
c->cols[i] = "";
|
||||
|
||||
c->exts = NULL;
|
||||
return 1;
|
||||
}
|
||||
if (!c)
|
||||
return 0;
|
||||
/* We have one of the parameters, use it. */
|
||||
memset(c, 0, sizeof(*c));
|
||||
s = dupstring(s);
|
||||
while (*s)
|
||||
s = getcoldef(c, s);
|
||||
|
||||
/* Use default values for those that aren't set explicitly. */
|
||||
for (i = 0; i < NUM_COLS; i++)
|
||||
if (!c->cols[i])
|
||||
c->cols[i] = defcols[i];
|
||||
/* Default for missing files. */
|
||||
if (!c->cols[COL_MI])
|
||||
c->cols[COL_MI] = c->cols[COL_FI];
|
||||
|
||||
if (!c->cols[COL_EC]) {
|
||||
char *e = (char *) zhalloc(strlen(c->cols[COL_LC]) +
|
||||
strlen(c->cols[COL_NO]) +
|
||||
strlen(c->cols[COL_RC]) + 1);
|
||||
|
||||
/* If no `ec' was given, we is `<lc><no><rc>' as the default. */
|
||||
strcpy(e, c->cols[COL_LC]);
|
||||
strcat(e, c->cols[COL_NO]);
|
||||
strcat(e, c->cols[COL_RC]);
|
||||
c->cols[COL_EC] = e;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the terminal color string for the file with the given name and
|
||||
* file modes. */
|
||||
|
||||
static char *
|
||||
getcolstr(Listcols c, char *n, mode_t m)
|
||||
{
|
||||
Extcol e;
|
||||
|
||||
for (e = c->exts; e; e = e->next)
|
||||
if (strsfx(e->ext, n))
|
||||
return e->col;
|
||||
|
||||
if (S_ISDIR(m))
|
||||
return c->cols[COL_DI];
|
||||
else if (S_ISLNK(m))
|
||||
return c->cols[COL_LN];
|
||||
else if (S_ISFIFO(m))
|
||||
return c->cols[COL_PI];
|
||||
else if (S_ISSOCK(m))
|
||||
return c->cols[COL_SO];
|
||||
else if (S_ISBLK(m))
|
||||
return c->cols[COL_BD];
|
||||
else if (S_ISCHR(m))
|
||||
return c->cols[COL_CD];
|
||||
else if (S_ISREG(m) && (m & S_IXUGO))
|
||||
return c->cols[COL_EX];
|
||||
|
||||
return c->cols[COL_FI];
|
||||
}
|
||||
|
||||
/* Information about the list shown. */
|
||||
|
||||
static int noselect, mselect, inselect, mcol, mline, mcols, mlines;
|
||||
static Cmatch *mmatch, **mtab;
|
||||
static Cmgroup mgroup, *mgtab;
|
||||
|
||||
/* List the matches. Most of this is just taken from ilistmatches(),
|
||||
* of course. */
|
||||
|
||||
static int
|
||||
complistmatches(Hookdef dummy, Chdata dat)
|
||||
{
|
||||
Cmgroup amatches = dat->matches, g;
|
||||
Cmatch *p, m;
|
||||
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;
|
||||
struct listcols col;
|
||||
|
||||
if (minfo.asked == 2) {
|
||||
showinglist = 0;
|
||||
return (noselect = 1);
|
||||
}
|
||||
getcols(&col);
|
||||
|
||||
/* Set the cursor below the prompt. */
|
||||
if (inselect)
|
||||
clearflag = 0;
|
||||
trashzle();
|
||||
showinglist = listshown = 0;
|
||||
|
||||
clearflag = (isset(USEZLE) && !termflags &&
|
||||
complastprompt && *complastprompt);
|
||||
|
||||
for (g = amatches; g; g = g->next) {
|
||||
char **pp = g->ylist;
|
||||
int nl = 0, l;
|
||||
|
||||
if (pp) {
|
||||
/* We have an ylist, lets see, if it contains newlines. */
|
||||
while (!nl && *pp)
|
||||
nl = !!strchr(*pp++, '\n');
|
||||
|
||||
pp = g->ylist;
|
||||
if (nl) {
|
||||
/* Yup, there are newlines, count lines. */
|
||||
char *nlptr, *sptr;
|
||||
|
||||
g->flags |= CGF_LINES;
|
||||
noselect = 1;
|
||||
while ((sptr = *pp)) {
|
||||
while (sptr && *sptr) {
|
||||
nlines += (nlptr = strchr(sptr, '\n'))
|
||||
? 1 + (nlptr-sptr)/columns
|
||||
: strlen(sptr)/columns;
|
||||
sptr = nlptr ? nlptr+1 : NULL;
|
||||
}
|
||||
nlines++;
|
||||
pp++;
|
||||
}
|
||||
nlines--;
|
||||
} else {
|
||||
while (*pp) {
|
||||
if ((l = strlen(*pp)) > longest)
|
||||
longest = l;
|
||||
nlist++;
|
||||
pp++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (p = g->matches; (m = *p); p++) {
|
||||
if (!(m->flags & CMF_NOLIST)) {
|
||||
if ((l = niceztrlen(m->str)) > longest)
|
||||
longest = l;
|
||||
nlist++;
|
||||
} else
|
||||
noselect = 1;
|
||||
}
|
||||
}
|
||||
if ((e = g->expls)) {
|
||||
while (*e) {
|
||||
if ((*e)->count)
|
||||
nlines += 1 + printfmt((*e)->str, (*e)->count, 0);
|
||||
e++;
|
||||
}
|
||||
}
|
||||
}
|
||||
longest += 2 + of;
|
||||
if ((ncols = (columns + 1) / longest)) {
|
||||
for (g = amatches; g; g = g->next)
|
||||
nlines += (g->lcount + ncols - 1) / ncols;
|
||||
} else {
|
||||
ncols = 1;
|
||||
opl = 1;
|
||||
for (g = amatches; g; g = g->next) {
|
||||
char **pp = g->ylist;
|
||||
|
||||
if (pp) {
|
||||
if (!(g->flags & CGF_LINES)) {
|
||||
while (*pp) {
|
||||
nlines += 1 + (strlen(*pp) / columns);
|
||||
pp++;
|
||||
}
|
||||
}
|
||||
} else
|
||||
for (p = g->matches; (m = *p); p++)
|
||||
if (!(m->flags & CMF_NOLIST))
|
||||
nlines += 1 + ((1 + niceztrlen(m->str)) / columns);
|
||||
}
|
||||
}
|
||||
|
||||
/* Maybe we have to ask if the user wants to see the list. */
|
||||
if ((!minfo.cur || !minfo.asked) &&
|
||||
((complistmax && nlist > complistmax) ||
|
||||
(!complistmax && nlines >= lines))) {
|
||||
int qup;
|
||||
zsetterm();
|
||||
qup = printfmt("zsh: do you wish to see all %n possibilities? ", nlist, 1);
|
||||
fflush(shout);
|
||||
if (getzlequery() != 'y') {
|
||||
if (clearflag) {
|
||||
putc('\r', shout);
|
||||
tcmultout(TCUP, TCMULTUP, qup);
|
||||
if (tccan(TCCLEAREOD))
|
||||
tcout(TCCLEAREOD);
|
||||
tcmultout(TCUP, TCMULTUP, nlnct);
|
||||
} else
|
||||
putc('\n', shout);
|
||||
noselect = 1;
|
||||
if (minfo.cur)
|
||||
minfo.asked = 2;
|
||||
return 1;
|
||||
}
|
||||
if (clearflag) {
|
||||
putc('\r', shout);
|
||||
tcmultout(TCUP, TCMULTUP, qup);
|
||||
if (tccan(TCCLEAREOD))
|
||||
tcout(TCCLEAREOD);
|
||||
} else
|
||||
putc('\n', shout);
|
||||
settyinfo(&shttyinfo);
|
||||
if (minfo.cur)
|
||||
minfo.asked = 1;
|
||||
}
|
||||
if (mselect >= 0) {
|
||||
int i;
|
||||
|
||||
i = ncols * nlines;
|
||||
free(mtab);
|
||||
mtab = (Cmatch **) zalloc(i * sizeof(Cmatch **));
|
||||
memset(mtab, 0, i * sizeof(Cmatch **));
|
||||
free(mgtab);
|
||||
mgtab = (Cmgroup *) zalloc(i * sizeof(Cmgroup));
|
||||
memset(mgtab, 0, i * sizeof(Cmgroup));
|
||||
mcols = ncols;
|
||||
mlines = nlines;
|
||||
}
|
||||
/* Now print the matches. */
|
||||
g = amatches;
|
||||
while (g) {
|
||||
char **pp = g->ylist;
|
||||
|
||||
if ((e = g->expls)) {
|
||||
while (*e) {
|
||||
if ((*e)->count) {
|
||||
if (pnl) {
|
||||
putc('\n', shout);
|
||||
pnl = 0;
|
||||
ml++;
|
||||
}
|
||||
ml += printfmt((*e)->str, (*e)->count, 1);
|
||||
pnl = 1;
|
||||
}
|
||||
e++;
|
||||
}
|
||||
}
|
||||
if (pp && *pp) {
|
||||
if (pnl) {
|
||||
putc('\n', shout);
|
||||
pnl = 0;
|
||||
ml++;
|
||||
}
|
||||
if (g->flags & CGF_LINES) {
|
||||
while (*pp) {
|
||||
zputs(*pp, shout);
|
||||
if (*++pp)
|
||||
putc('\n', shout);
|
||||
}
|
||||
} else {
|
||||
int n = g->lcount, nl = (n + ncols - 1) / ncols, nc = nl, i, a;
|
||||
char **pq;
|
||||
|
||||
while (n && nl--) {
|
||||
i = ncols;
|
||||
mc = 0;
|
||||
pq = pp;
|
||||
while (n && i--) {
|
||||
if (pq - g->ylist >= g->lcount)
|
||||
break;
|
||||
zputs(*pq, shout);
|
||||
if (i) {
|
||||
a = longest - strlen(*pq);
|
||||
while (a--)
|
||||
putc(' ', shout);
|
||||
}
|
||||
pq += nc;
|
||||
n--;
|
||||
}
|
||||
if (n) {
|
||||
putc('\n', shout);
|
||||
ml++;
|
||||
}
|
||||
pp++;
|
||||
}
|
||||
}
|
||||
} else if (g->lcount) {
|
||||
int n = g->lcount, nl = (n + ncols - 1) / ncols, nc = nl, i, j, a = 0;
|
||||
int zt;
|
||||
Cmatch *q;
|
||||
|
||||
if (n && pnl) {
|
||||
putc('\n', shout);
|
||||
pnl = 0;
|
||||
ml++;
|
||||
}
|
||||
for (p = skipnolist(g->matches); n && nl--;) {
|
||||
i = ncols;
|
||||
mc = 0;
|
||||
q = p;
|
||||
while (n && i--) {
|
||||
fputs(col.cols[COL_LC], shout);
|
||||
if (!(m = *q)) {
|
||||
fputs(col.cols[COL_MI], shout);
|
||||
fputs(col.cols[COL_RC], shout);
|
||||
a = longest - 2;
|
||||
while (a--)
|
||||
putc(' ', shout);
|
||||
fputs(col.cols[COL_EC], shout);
|
||||
break;
|
||||
}
|
||||
hasm = 1;
|
||||
if (mselect >= 0) {
|
||||
mtab[mc + (ncols * ml)] = q;
|
||||
mgtab[mc + (ncols * ml)] = g;
|
||||
}
|
||||
if (m->gnum == mselect) {
|
||||
mcol = mc;
|
||||
mline = ml;
|
||||
mmatch = q;
|
||||
mgroup = g;
|
||||
cc = COL_MA;
|
||||
} else
|
||||
cc = -1;
|
||||
if (m->flags & CMF_FILE) {
|
||||
struct stat buf;
|
||||
char *pb;
|
||||
|
||||
pb = (char *) zhalloc((m->prpre ? strlen(m->prpre) : 0) +
|
||||
3 + strlen(m->str));
|
||||
sprintf(pb, "%s%s", (m->prpre ? m->prpre : "./"),
|
||||
m->str);
|
||||
|
||||
zt = ztat(pb, &buf, 1);
|
||||
if (cc >= 0)
|
||||
fputs(col.cols[cc], shout);
|
||||
else if (zt)
|
||||
fputs(col.cols[COL_NO], shout);
|
||||
else
|
||||
fputs(getcolstr(&col, pb, buf.st_mode), shout);
|
||||
fputs(col.cols[COL_RC], shout);
|
||||
nicezputs(m->str, shout);
|
||||
if (zt)
|
||||
putc(' ', shout);
|
||||
else
|
||||
putc(file_type(buf.st_mode), shout);
|
||||
} else {
|
||||
fputs(col.cols[cc >= 0 ? cc : COL_NO], shout);
|
||||
fputs(col.cols[COL_RC], shout);
|
||||
nicezputs(m->str, shout);
|
||||
if (of)
|
||||
putc(' ', shout);
|
||||
}
|
||||
a = longest - niceztrlen(m->str) - 2 - of;
|
||||
while (a--)
|
||||
putc(' ', shout);
|
||||
fputs(col.cols[COL_EC], shout);
|
||||
if (i) {
|
||||
fputs(col.cols[COL_LC], shout);
|
||||
fputs(col.cols[COL_NO], shout);
|
||||
fputs(col.cols[COL_RC], shout);
|
||||
fputs(" ", shout);
|
||||
fputs(col.cols[COL_EC], shout);
|
||||
}
|
||||
if (--n)
|
||||
for (j = nc; j && *q; j--)
|
||||
q = skipnolist(q + 1);
|
||||
mc++;
|
||||
}
|
||||
if (i > 0) {
|
||||
fputs(col.cols[COL_LC], shout);
|
||||
fputs(col.cols[COL_MI], shout);
|
||||
fputs(col.cols[COL_RC], shout);
|
||||
a = longest - 2;
|
||||
while (a--)
|
||||
putc(' ', shout);
|
||||
fputs(col.cols[COL_EC], shout);
|
||||
}
|
||||
if (n) {
|
||||
putc('\n', shout);
|
||||
ml++;
|
||||
if (n && nl)
|
||||
p = skipnolist(p + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (g->lcount)
|
||||
pnl = 1;
|
||||
g = g->next;
|
||||
}
|
||||
|
||||
if (clearflag) {
|
||||
/* Move the cursor up to the prompt, if always_last_prompt *
|
||||
* is set and all that... */
|
||||
if ((nlines += nlnct - 1) < lines) {
|
||||
tcmultout(TCUP, TCMULTUP, nlines);
|
||||
showinglist = -1;
|
||||
listshown = 1;
|
||||
} else
|
||||
clearflag = 0, putc('\n', shout);
|
||||
} else
|
||||
putc('\n', shout);
|
||||
if (!hasm || nlines >= lines)
|
||||
noselect = 1;
|
||||
return noselect;
|
||||
}
|
||||
|
||||
typedef struct menustack *Menustack;
|
||||
|
||||
struct menustack {
|
||||
Menustack prev;
|
||||
char *line;
|
||||
int cs;
|
||||
struct menuinfo info;
|
||||
};
|
||||
|
||||
static int
|
||||
domenuselect(Hookdef dummy, Chdata dat)
|
||||
{
|
||||
Cmatch **p;
|
||||
Cmgroup *pg;
|
||||
Thingy cmd;
|
||||
Menustack u = NULL;
|
||||
int i = 0;
|
||||
char *s;
|
||||
|
||||
if (getcols(NULL) || (dummy && (!(s = getsparam("SELECTMIN")) ||
|
||||
(dat && dat->num < atoi(s)))))
|
||||
return 1;
|
||||
|
||||
selectlocalmap(mskeymap);
|
||||
noselect = 0;
|
||||
mselect = (*(minfo.cur))->gnum;
|
||||
for (;;) {
|
||||
showinglist = -2;
|
||||
zrefresh();
|
||||
inselect = 1;
|
||||
if (noselect)
|
||||
break;
|
||||
if (!i) {
|
||||
i = mcols * mlines;
|
||||
while (i--)
|
||||
if (mtab[i])
|
||||
break;
|
||||
if (!i)
|
||||
break;
|
||||
i = 1;
|
||||
}
|
||||
p = mtab + mcol + (mline * mcols);
|
||||
pg = mgtab + mcol + (mline * mcols);
|
||||
minfo.cur = *p;
|
||||
minfo.group = *pg;
|
||||
|
||||
getk:
|
||||
|
||||
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak) ||
|
||||
cmd == Th(z_acceptline))
|
||||
break;
|
||||
else if (cmd == Th(z_acceptandhold) ||
|
||||
cmd == Th(z_acceptandmenucomplete)) {
|
||||
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));
|
||||
acceptlast();
|
||||
do_menucmp(0);
|
||||
mselect = (*(minfo.cur))->gnum;
|
||||
continue;
|
||||
} else if (cmd == Th(z_undo)) {
|
||||
int l;
|
||||
|
||||
if (!u)
|
||||
goto getk;
|
||||
|
||||
cs = 0;
|
||||
foredel(ll);
|
||||
spaceinline(l = strlen(u->line));
|
||||
strncpy((char *) line, u->line, l);
|
||||
cs = u->cs;
|
||||
memcpy(&minfo, &(u->info), sizeof(struct menuinfo));
|
||||
p = &(minfo.cur);
|
||||
u = u->prev;
|
||||
} else if (cmd == Th(z_redisplay)) {
|
||||
redisplay(zlenoargs);
|
||||
continue;
|
||||
} else if (cmd == Th(z_clearscreen)) {
|
||||
clearscreen(zlenoargs);
|
||||
continue;
|
||||
} else if (cmd == Th(z_downhistory) ||
|
||||
cmd == Th(z_downlineorhistory) ||
|
||||
cmd == Th(z_downlineorsearch) ||
|
||||
cmd == Th(z_vidownlineorhistory)) {
|
||||
do {
|
||||
if (mline == mlines - 1) {
|
||||
p -= mline * mcols;
|
||||
mline = 0;
|
||||
} else {
|
||||
mline++;
|
||||
p += mcols;
|
||||
}
|
||||
} while (!*p);
|
||||
} else if (cmd == Th(z_uphistory) ||
|
||||
cmd == Th(z_uplineorhistory) ||
|
||||
cmd == Th(z_uplineorsearch) ||
|
||||
cmd == Th(z_viuplineorhistory)) {
|
||||
do {
|
||||
if (!mline) {
|
||||
mline = mlines - 1;
|
||||
p += mline * mcols;
|
||||
} else {
|
||||
mline--;
|
||||
p -= mcols;
|
||||
}
|
||||
} while (!*p);
|
||||
} else if (cmd == Th(z_forwardchar) || cmd == Th(z_viforwardchar)) {
|
||||
do {
|
||||
if (mcol == mcols - 1) {
|
||||
p -= mcol;
|
||||
mcol = 0;
|
||||
} else {
|
||||
mcol++;
|
||||
p++;
|
||||
}
|
||||
} while (!*p);
|
||||
} else if (cmd == Th(z_backwardchar) || cmd == Th(z_vibackwardchar)) {
|
||||
do {
|
||||
if (!mcol) {
|
||||
mcol = mcols - 1;
|
||||
p += mcol;
|
||||
} else {
|
||||
mcol--;
|
||||
p--;
|
||||
}
|
||||
} while (!*p);
|
||||
} else if (cmd == Th(z_beginningofbufferorhistory) ||
|
||||
cmd == Th(z_beginningofline) ||
|
||||
cmd == Th(z_beginningoflinehist) ||
|
||||
cmd == Th(z_vibeginningofline)) {
|
||||
p -= mcol;
|
||||
mcol = 0;
|
||||
while (!*p) {
|
||||
mcol++;
|
||||
p++;
|
||||
}
|
||||
} else if (cmd == Th(z_endofbufferorhistory) ||
|
||||
cmd == Th(z_endofline) ||
|
||||
cmd == Th(z_endoflinehist) ||
|
||||
cmd == Th(z_viendofline)) {
|
||||
p += mcols - mcol - 1;
|
||||
mcol = mcols - 1;
|
||||
while (!*p) {
|
||||
mcol--;
|
||||
p--;
|
||||
}
|
||||
} else if (cmd == Th(z_forwardword) ||
|
||||
cmd == Th(z_emacsforwardword) ||
|
||||
cmd == Th(z_viforwardword) ||
|
||||
cmd == Th(z_viforwardwordend)) {
|
||||
Cmgroup g = *pg;
|
||||
int ol = mline;
|
||||
|
||||
do {
|
||||
if (mline == mlines - 1) {
|
||||
p -= mline * mcols;
|
||||
pg -= mline * mcols;
|
||||
mline = 0;
|
||||
} else {
|
||||
mline++;
|
||||
p += mcols;
|
||||
pg += mcols;
|
||||
}
|
||||
} while (ol != mline && (*pg == g || !*pg));
|
||||
} else if (cmd == Th(z_backwardword) ||
|
||||
cmd == Th(z_emacsbackwardword) ||
|
||||
cmd == Th(z_vibackwardword)) {
|
||||
Cmgroup g = *pg;
|
||||
int ol = mline;
|
||||
|
||||
do {
|
||||
if (!mline) {
|
||||
mline = mlines - 1;
|
||||
p += mline * mcols;
|
||||
pg += mline * mcols;
|
||||
} else {
|
||||
mline--;
|
||||
p -= mcols;
|
||||
pg -= mcols;
|
||||
}
|
||||
} while (ol != mline && (*pg == g || !*pg));
|
||||
} else if (cmd == Th(z_completeword) ||
|
||||
cmd == Th(z_expandorcomplete) ||
|
||||
cmd == Th(z_expandorcompleteprefix) ||
|
||||
cmd == Th(z_menucomplete) ||
|
||||
cmd == Th(z_menuexpandorcomplete) ||
|
||||
!strcmp(cmd->nam, "menu-select") ||
|
||||
!strcmp(cmd->nam, "complete-word") ||
|
||||
!strcmp(cmd->nam, "expand-or-complete") ||
|
||||
!strcmp(cmd->nam, "expand-or-complete-prefix") ||
|
||||
!strcmp(cmd->nam, "menu-complete") ||
|
||||
!strcmp(cmd->nam, "menu-expand-or-complete")) {
|
||||
do_menucmp(0);
|
||||
mselect = (*(minfo.cur))->gnum;
|
||||
continue;
|
||||
} else if (cmd == Th(z_reversemenucomplete) ||
|
||||
!strcmp(cmd->nam, "reverse-menu-complete")) {
|
||||
reversemenucomplete(zlenoargs);
|
||||
mselect = (*(minfo.cur))->gnum;
|
||||
continue;
|
||||
} else {
|
||||
ungetkeycmd();
|
||||
break;
|
||||
}
|
||||
do_single(**p);
|
||||
mselect = (**p)->gnum;
|
||||
}
|
||||
selectlocalmap(NULL);
|
||||
mselect = -1;
|
||||
inselect = 0;
|
||||
if (!noselect) {
|
||||
showinglist = -2;
|
||||
zrefresh();
|
||||
}
|
||||
return noselect;
|
||||
}
|
||||
|
||||
/* The widget function. */
|
||||
|
||||
static int
|
||||
menuselect(char **args)
|
||||
{
|
||||
int d = 0;
|
||||
|
||||
if (!minfo.cur) {
|
||||
menucomplete(args);
|
||||
if ((minfo.cur && minfo.asked == 2) || getsparam("ZLS_SELECT"))
|
||||
return 0;
|
||||
d = 1;
|
||||
}
|
||||
if (minfo.cur && (minfo.asked == 2 || domenuselect(NULL, NULL)) && !d)
|
||||
menucomplete(args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
setup_complist(Module m)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
boot_complist(Module m)
|
||||
{
|
||||
mtab = NULL;
|
||||
mgtab = NULL;
|
||||
mselect = -1;
|
||||
inselect = 0;
|
||||
|
||||
w_menuselect = addzlefunction("menu-select", menuselect,
|
||||
ZLE_MENUCMP|ZLE_KEEPSUFFIX|ZLE_ISCOMP);
|
||||
if (!w_menuselect) {
|
||||
zwarnnam(m->nam, "name clash when adding ZLE function `menu-select'",
|
||||
NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
addhookfunc("list_matches", (Hookfn) complistmatches);
|
||||
addhookfunc("menu_start", (Hookfn) domenuselect);
|
||||
mskeymap = newkeymap(NULL, "menuselect");
|
||||
linkkeymap(mskeymap, "menuselect", 1);
|
||||
bindkey(mskeymap, "\t", refthingy(t_completeword), NULL);
|
||||
bindkey(mskeymap, "\n", refthingy(t_acceptline), NULL);
|
||||
bindkey(mskeymap, "\r", refthingy(t_acceptline), NULL);
|
||||
bindkey(mskeymap, "\33[A", refthingy(t_uplineorhistory), NULL);
|
||||
bindkey(mskeymap, "\33[B", refthingy(t_downlineorhistory), NULL);
|
||||
bindkey(mskeymap, "\33[C", refthingy(t_forwardchar), NULL);
|
||||
bindkey(mskeymap, "\33[D", refthingy(t_backwardchar), NULL);
|
||||
bindkey(mskeymap, "\33OA", refthingy(t_uplineorhistory), NULL);
|
||||
bindkey(mskeymap, "\33OB", refthingy(t_downlineorhistory), NULL);
|
||||
bindkey(mskeymap, "\33OC", refthingy(t_forwardchar), NULL);
|
||||
bindkey(mskeymap, "\33OD", refthingy(t_backwardchar), NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef MODULE
|
||||
|
||||
/**/
|
||||
int
|
||||
cleanup_complist(Module m)
|
||||
{
|
||||
free(mtab);
|
||||
free(mgtab);
|
||||
|
||||
deletezlefunction(w_menuselect);
|
||||
deletehookfunc("list_matches", (Hookfn) complistmatches);
|
||||
deletehookfunc("menu_start", (Hookfn) domenuselect);
|
||||
unlinkkeymap("menuselect", 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
finish_complist(Module m)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
3
Src/Zle/complist.mdd
Normal file
3
Src/Zle/complist.mdd
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
moddeps="comp1 zle"
|
||||
|
||||
objects="complist.o"
|
||||
|
|
@ -33,8 +33,8 @@
|
|||
static Widget w_deletetochar;
|
||||
|
||||
/**/
|
||||
static void
|
||||
deltochar(void)
|
||||
static int
|
||||
deltochar(char **args)
|
||||
{
|
||||
int c = getkey(0), dest = cs, ok = 0, n = zmult;
|
||||
|
||||
|
|
@ -67,8 +67,7 @@ deltochar(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!ok)
|
||||
feep();
|
||||
return !ok;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
"backward-kill-line", backwardkillline, ZLE_KILL | ZLE_KEEPSUFFIX
|
||||
"backward-kill-word", backwardkillword, ZLE_KILL | ZLE_KEEPSUFFIX
|
||||
"backward-word", backwardword, 0
|
||||
"beep", handlefeep, 0
|
||||
"beginning-of-buffer-or-history", beginningofbufferorhistory, 0
|
||||
"beginning-of-history", beginningofhistory, 0
|
||||
"beginning-of-line", beginningofline, 0
|
||||
|
|
|
|||
|
|
@ -1,10 +1,44 @@
|
|||
#!
|
||||
acceptlast
|
||||
addzlefunction
|
||||
backdel
|
||||
backkill
|
||||
bindkey
|
||||
clearflag
|
||||
clearscreen
|
||||
deletezlefunction
|
||||
do_menucmp
|
||||
do_single
|
||||
feep
|
||||
foredel
|
||||
forekill
|
||||
getkey
|
||||
getkeycmd
|
||||
getzlequery
|
||||
linkkeymap
|
||||
listshown
|
||||
menucomplete
|
||||
menucur
|
||||
menugrp
|
||||
minfo
|
||||
newkeymap
|
||||
nlnct
|
||||
printfmt
|
||||
redisplay
|
||||
refthingy
|
||||
reversemenucomplete
|
||||
selectlocalmap
|
||||
showinglist
|
||||
skipnolist
|
||||
spaceinline
|
||||
tcmultout
|
||||
tcout
|
||||
thingies
|
||||
trashzle
|
||||
ungetkeycmd
|
||||
unlinkkeymap
|
||||
zlenoargs
|
||||
zmod
|
||||
zrefresh
|
||||
zsetterm
|
||||
ztat
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ typedef struct thingy *Thingy;
|
|||
|
||||
/* widgets (ZLE functions) */
|
||||
|
||||
typedef void (*ZleIntFunc) _((void));
|
||||
typedef int (*ZleIntFunc) _((char **));
|
||||
|
||||
struct widget {
|
||||
int flags; /* flags (see below) */
|
||||
|
|
@ -64,6 +64,7 @@ struct widget {
|
|||
#define ZLE_KEEPSUFFIX (1<<7) /* DON'T remove added suffix */
|
||||
#define ZLE_NOTCOMMAND (1<<8) /* widget should not alter lastcmd */
|
||||
#define ZLE_ISCOMP (1<<9) /* usable for new style completion */
|
||||
|
||||
/* thingies */
|
||||
|
||||
struct thingy {
|
||||
|
|
@ -142,3 +143,9 @@ typedef struct cutbuffer *Cutbuffer;
|
|||
#define CUTBUFFER_LINE 1 /* for vi: buffer contains whole lines of data */
|
||||
|
||||
#define KRINGCT 8 /* number of buffers in the kill ring */
|
||||
|
||||
/* Convenience macros for the hooks */
|
||||
|
||||
#define LISTMATCHESHOOK (zlehooks + 0)
|
||||
#define INSERTMATCHHOOK (zlehooks + 1)
|
||||
#define MENUSTARTHOOK (zlehooks + 2)
|
||||
|
|
|
|||
|
|
@ -73,12 +73,13 @@ forget_edits(void)
|
|||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
uphistory(void)
|
||||
int
|
||||
uphistory(char **args)
|
||||
{
|
||||
int nodups = isset(HISTIGNOREDUPS);
|
||||
if (!zle_goto_hist(histline, -zmult, nodups) && isset(HISTBEEP))
|
||||
feep();
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
@ -116,53 +117,53 @@ upline(void)
|
|||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
uplineorhistory(void)
|
||||
int
|
||||
uplineorhistory(char **args)
|
||||
{
|
||||
int ocs = cs;
|
||||
int n = upline();
|
||||
if (n) {
|
||||
int m = zmult;
|
||||
int m = zmult, ret;
|
||||
|
||||
cs = ocs;
|
||||
if (virangeflag || !histallowed) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (virangeflag || !histallowed)
|
||||
return 1;
|
||||
zmult = n;
|
||||
uphistory();
|
||||
ret = uphistory(args);
|
||||
zmult = m;
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viuplineorhistory(void)
|
||||
int
|
||||
viuplineorhistory(char **args)
|
||||
{
|
||||
int col = lastcol;
|
||||
uplineorhistory();
|
||||
uplineorhistory(args);
|
||||
lastcol = col;
|
||||
vifirstnonblank();
|
||||
return vifirstnonblank(args);
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
uplineorsearch(void)
|
||||
int
|
||||
uplineorsearch(char **args)
|
||||
{
|
||||
int ocs = cs;
|
||||
int n = upline();
|
||||
if (n) {
|
||||
int m = zmult;
|
||||
int m = zmult, ret;
|
||||
|
||||
cs = ocs;
|
||||
if (virangeflag || !histallowed) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (virangeflag || !histallowed)
|
||||
return 1;
|
||||
zmult = n;
|
||||
historysearchbackward();
|
||||
ret = historysearchbackward(args);
|
||||
zmult = m;
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
@ -200,98 +201,102 @@ downline(void)
|
|||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
downlineorhistory(void)
|
||||
int
|
||||
downlineorhistory(char **args)
|
||||
{
|
||||
int ocs = cs;
|
||||
int n = downline();
|
||||
if (n) {
|
||||
int m = zmult;
|
||||
int m = zmult, ret;
|
||||
|
||||
cs = ocs;
|
||||
if (virangeflag || !histallowed) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (virangeflag || !histallowed)
|
||||
return 1;
|
||||
zmult = n;
|
||||
downhistory();
|
||||
ret = downhistory(args);
|
||||
zmult = m;
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vidownlineorhistory(void)
|
||||
int
|
||||
vidownlineorhistory(char **args)
|
||||
{
|
||||
int col = lastcol;
|
||||
downlineorhistory();
|
||||
downlineorhistory(args);
|
||||
lastcol = col;
|
||||
vifirstnonblank();
|
||||
return vifirstnonblank(zlenoargs);
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
downlineorsearch(void)
|
||||
int
|
||||
downlineorsearch(char **args)
|
||||
{
|
||||
int ocs = cs;
|
||||
int n = downline();
|
||||
if (n) {
|
||||
int m = zmult;
|
||||
int m = zmult, ret;
|
||||
|
||||
cs = ocs;
|
||||
if (virangeflag || !histallowed) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (virangeflag || !histallowed)
|
||||
return 1;
|
||||
zmult = n;
|
||||
historysearchforward();
|
||||
ret = historysearchforward(args);
|
||||
zmult = m;
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
acceptlineanddownhistory(void)
|
||||
int
|
||||
acceptlineanddownhistory(char **args)
|
||||
{
|
||||
Histent he;
|
||||
|
||||
if (!(he = movehistent(quietgethist(histline), 1, HIST_FOREIGN))) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (!(he = movehistent(quietgethist(histline), 1, HIST_FOREIGN)))
|
||||
return 1;
|
||||
pushnode(bufstack, ztrdup(ZLETEXT(he)));
|
||||
done = 1;
|
||||
stackhist = he->histnum;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
downhistory(void)
|
||||
int
|
||||
downhistory(char **args)
|
||||
{
|
||||
int nodups = isset(HISTIGNOREDUPS);
|
||||
if (!zle_goto_hist(histline, zmult, nodups) && isset(HISTBEEP))
|
||||
feep();
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int histpos, srch_hl, srch_cs = -1;
|
||||
static char *srch_str;
|
||||
|
||||
/**/
|
||||
void
|
||||
historysearchbackward(void)
|
||||
int
|
||||
historysearchbackward(char **args)
|
||||
{
|
||||
Histent he;
|
||||
int n = zmult;
|
||||
char *s;
|
||||
int n = zmult, hp;
|
||||
char *s, *str;
|
||||
|
||||
if (zmult < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
historysearchforward();
|
||||
ret = historysearchforward(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
if (histline == curhist || histline != srch_hl || cs != srch_cs || mark != 0
|
||||
|| memcmp(srch_str, line, histpos) != 0) {
|
||||
if ((str = *args))
|
||||
hp = strlen(str);
|
||||
else {
|
||||
if (histline == curhist || histline != srch_hl || cs != srch_cs ||
|
||||
mark != 0 || memcmp(srch_str, line, histpos) != 0) {
|
||||
zfree(srch_str, histpos);
|
||||
for (histpos = 0; histpos < ll && !iblank(line[histpos]); histpos++) ;
|
||||
if (histpos < ll)
|
||||
|
|
@ -299,40 +304,47 @@ historysearchbackward(void)
|
|||
srch_str = zalloc(histpos);
|
||||
memcpy(srch_str, line, histpos);
|
||||
}
|
||||
str = srch_str;
|
||||
hp = histpos;
|
||||
}
|
||||
he = quietgethist(histline);
|
||||
while ((he = movehistent(he, -1, hist_skip_flags))) {
|
||||
if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
|
||||
continue;
|
||||
s = ZLETEXT(he);
|
||||
if (metadiffer(s, srch_str, histpos) < 0 &&
|
||||
metadiffer(s, srch_str, ll)) {
|
||||
if (metadiffer(s, str, hp) < 0 &&
|
||||
(*args || metadiffer(s, str, ll))) {
|
||||
if (--n <= 0) {
|
||||
zle_setline(he);
|
||||
srch_hl = histline;
|
||||
srch_cs = cs;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
feep();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
historysearchforward(void)
|
||||
int
|
||||
historysearchforward(char **args)
|
||||
{
|
||||
Histent he;
|
||||
int n = zmult;
|
||||
char *s;
|
||||
int n = zmult, hp;
|
||||
char *s, *str;
|
||||
|
||||
if (zmult < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
historysearchbackward();
|
||||
ret = historysearchbackward(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
if (histline == curhist || histline != srch_hl || cs != srch_cs || mark != 0
|
||||
|| memcmp(srch_str, line, histpos) != 0) {
|
||||
if ((str = *args))
|
||||
hp = strlen(str);
|
||||
else {
|
||||
if (histline == curhist || histline != srch_hl || cs != srch_cs ||
|
||||
mark != 0 || memcmp(srch_str, line, histpos) != 0) {
|
||||
zfree(srch_str, histpos);
|
||||
for (histpos = 0; histpos < ll && !iblank(line[histpos]); histpos++) ;
|
||||
if (histpos < ll)
|
||||
|
|
@ -340,62 +352,69 @@ historysearchforward(void)
|
|||
srch_str = zalloc(histpos);
|
||||
memcpy(srch_str, line, histpos);
|
||||
}
|
||||
str = srch_str;
|
||||
hp = histpos;
|
||||
}
|
||||
he = quietgethist(histline);
|
||||
while ((he = movehistent(he, 1, hist_skip_flags))) {
|
||||
if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
|
||||
continue;
|
||||
s = ZLETEXT(he);
|
||||
if (metadiffer(s, srch_str, histpos) < (he->histnum == curhist) &&
|
||||
metadiffer(s, srch_str, ll)) {
|
||||
if (metadiffer(s, str, hp) < (he->histnum == curhist) &&
|
||||
(*args || metadiffer(s, str, ll))) {
|
||||
if (--n <= 0) {
|
||||
zle_setline(he);
|
||||
srch_hl = histline;
|
||||
srch_cs = cs;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
feep();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
beginningofbufferorhistory(void)
|
||||
int
|
||||
beginningofbufferorhistory(char **args)
|
||||
{
|
||||
if (findbol())
|
||||
cs = 0;
|
||||
else
|
||||
beginningofhistory();
|
||||
return beginningofhistory(args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
beginningofhistory(void)
|
||||
int
|
||||
beginningofhistory(char **args)
|
||||
{
|
||||
if (!zle_goto_hist(firsthist(), 0, 0) && isset(HISTBEEP))
|
||||
feep();
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
endofbufferorhistory(void)
|
||||
int
|
||||
endofbufferorhistory(char **args)
|
||||
{
|
||||
if (findeol() != ll)
|
||||
cs = ll;
|
||||
else
|
||||
endofhistory();
|
||||
return endofhistory(args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
endofhistory(void)
|
||||
int
|
||||
endofhistory(char **args)
|
||||
{
|
||||
zle_goto_hist(curhist, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
insertlastword(void)
|
||||
int
|
||||
insertlastword(char **args)
|
||||
{
|
||||
int n;
|
||||
char *s, *t;
|
||||
|
|
@ -420,19 +439,15 @@ insertlastword(void)
|
|||
zsfree(lastinsert);
|
||||
lastinsert = NULL;
|
||||
}
|
||||
if (!(he = quietgethist(evhist)) || !he->nwords) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (!(he = quietgethist(evhist)) || !he->nwords)
|
||||
return 1;
|
||||
if (zmult > 0) {
|
||||
n = he->nwords - (zmult - 1);
|
||||
} else {
|
||||
n = 1 - zmult;
|
||||
}
|
||||
if (n < 1 || n > he->nwords) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (n < 1 || n > he->nwords)
|
||||
return 1;
|
||||
s = he->text + he->words[2*n-2];
|
||||
t = he->text + he->words[2*n-1];
|
||||
save = *t;
|
||||
|
|
@ -446,6 +461,7 @@ insertlastword(void)
|
|||
doinsert(s);
|
||||
zmult = n;
|
||||
*t = save;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
@ -461,15 +477,15 @@ zle_setline(Histent he)
|
|||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
setlocalhistory(void)
|
||||
int
|
||||
setlocalhistory(char **args)
|
||||
{
|
||||
if (zmod.flags & MOD_MULT) {
|
||||
hist_skip_flags = zmult? HIST_FOREIGN : 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
hist_skip_flags ^= HIST_FOREIGN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
@ -489,13 +505,13 @@ zle_goto_hist(int ev, int n, int skipdups)
|
|||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
pushline(void)
|
||||
int
|
||||
pushline(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0)
|
||||
return;
|
||||
return 1;
|
||||
pushnode(bufstack, metafy((char *) line, ll, META_DUP));
|
||||
while (--n)
|
||||
pushnode(bufstack, ztrdup(""));
|
||||
|
|
@ -503,18 +519,19 @@ pushline(void)
|
|||
*line = '\0';
|
||||
ll = cs = 0;
|
||||
clearlist = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
pushlineoredit(void)
|
||||
int
|
||||
pushlineoredit(char **args)
|
||||
{
|
||||
int ics;
|
||||
int ics, ret;
|
||||
unsigned char *s;
|
||||
char *hline = hgetline();
|
||||
|
||||
if (zmult < 0)
|
||||
return;
|
||||
return 1;
|
||||
if (hline && *hline) {
|
||||
ics = ztrlen(hline);
|
||||
sizeline(ics + ll + 1);
|
||||
|
|
@ -524,34 +541,36 @@ pushlineoredit(void)
|
|||
ll += ics;
|
||||
cs += ics;
|
||||
}
|
||||
pushline();
|
||||
ret = pushline(args);
|
||||
if (!isfirstln)
|
||||
errflag = done = 1;
|
||||
clearlist = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
pushinput(void)
|
||||
int
|
||||
pushinput(char **args)
|
||||
{
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
if (zmult < 0)
|
||||
return;
|
||||
return 1;
|
||||
zmult += i = !isfirstln;
|
||||
pushlineoredit();
|
||||
ret = pushlineoredit(args);
|
||||
zmult -= i;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
getline(void)
|
||||
int
|
||||
getline(char **args)
|
||||
{
|
||||
char *s = (char *)getlinknode(bufstack);
|
||||
|
||||
if (!s)
|
||||
feep();
|
||||
else {
|
||||
if (!s) {
|
||||
return 1;
|
||||
} else {
|
||||
int cc;
|
||||
|
||||
unmetafy(s, &cc);
|
||||
|
|
@ -561,20 +580,23 @@ getline(void)
|
|||
free(s);
|
||||
clearlist = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
historyincrementalsearchbackward(void)
|
||||
int
|
||||
historyincrementalsearchbackward(char **args)
|
||||
{
|
||||
doisearch(-1);
|
||||
doisearch(args, -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
historyincrementalsearchforward(void)
|
||||
int
|
||||
historyincrementalsearchforward(char **args)
|
||||
{
|
||||
doisearch(1);
|
||||
doisearch(args, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct isrch_spot {
|
||||
|
|
@ -642,13 +664,13 @@ get_isrch_spot(int num, int *hlp, int *posp, int *csp, int *lenp, int *dirp, int
|
|||
|
||||
/**/
|
||||
static void
|
||||
doisearch(int dir)
|
||||
doisearch(char **args, int dir)
|
||||
{
|
||||
char *s, *ibuf = zhalloc(80), *sbuf = ibuf + FIRST_SEARCH_CHAR;
|
||||
int sbptr = 0, top_spot = 0, pos, sibuf = 80;
|
||||
int nomatch = 0, skip_line = 0, skip_pos = 0;
|
||||
int odir = dir, sens = zmult == 1 ? 3 : 1;
|
||||
int hl = histline;
|
||||
int hl = histline, savekeys = -1, feep = 0;
|
||||
Thingy cmd;
|
||||
char *okeymap = curkeymapname;
|
||||
static char *previous_search = NULL;
|
||||
|
|
@ -657,6 +679,14 @@ doisearch(int dir)
|
|||
|
||||
clearlist = 1;
|
||||
|
||||
if (*args) {
|
||||
int len;
|
||||
char *arg;
|
||||
savekeys = kungetct;
|
||||
arg = getkeystring(*args, &len, 2, NULL);
|
||||
ungetkeys(arg, len);
|
||||
}
|
||||
|
||||
strcpy(ibuf, ISEARCH_PROMPT);
|
||||
memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? "fwd" : "bck", 3);
|
||||
remember_edits();
|
||||
|
|
@ -709,7 +739,7 @@ doisearch(int dir)
|
|||
get_isrch_spot(top_spot, &hl, &pos, &cs, &sbptr,
|
||||
&dir, &nomatch);
|
||||
if (!nomatch) {
|
||||
feep();
|
||||
feep = 1;
|
||||
nomatch = 1;
|
||||
}
|
||||
he = quietgethist(hl);
|
||||
|
|
@ -743,14 +773,14 @@ doisearch(int dir)
|
|||
break;
|
||||
}
|
||||
if(cmd == Th(z_clearscreen)) {
|
||||
clearscreen();
|
||||
clearscreen(zlenoargs);
|
||||
goto ref;
|
||||
} else if(cmd == Th(z_redisplay)) {
|
||||
redisplay();
|
||||
redisplay(zlenoargs);
|
||||
goto ref;
|
||||
} else if(cmd == Th(z_vicmdmode)) {
|
||||
if(selectkeymap(invicmdmode() ? "main" : "vicmd", 0))
|
||||
feep();
|
||||
feep = 1;
|
||||
goto ref;
|
||||
} else if(cmd == Th(z_vibackwarddeletechar) ||
|
||||
cmd == Th(z_backwarddeletechar)) {
|
||||
|
|
@ -758,7 +788,7 @@ doisearch(int dir)
|
|||
get_isrch_spot(--top_spot, &hl, &pos, &cs, &sbptr,
|
||||
&dir, &nomatch);
|
||||
else
|
||||
feep();
|
||||
feep = 1;
|
||||
if (nomatch) {
|
||||
statusline = ibuf;
|
||||
skip_pos = 1;
|
||||
|
|
@ -773,16 +803,16 @@ doisearch(int dir)
|
|||
memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? "fwd" : "bck", 3);
|
||||
continue;
|
||||
} else if(cmd == Th(z_acceptandhold)) {
|
||||
acceptandhold();
|
||||
acceptandhold(zlenoargs);
|
||||
break;
|
||||
} else if(cmd == Th(z_acceptandinfernexthistory)) {
|
||||
acceptandinfernexthistory();
|
||||
acceptandinfernexthistory(zlenoargs);
|
||||
break;
|
||||
} else if(cmd == Th(z_acceptlineanddownhistory)) {
|
||||
acceptlineanddownhistory();
|
||||
acceptlineanddownhistory(zlenoargs);
|
||||
break;
|
||||
} else if(cmd == Th(z_acceptline)) {
|
||||
acceptline();
|
||||
acceptline(zlenoargs);
|
||||
break;
|
||||
} else if(cmd == Th(z_historyincrementalsearchbackward)) {
|
||||
set_isrch_spot(top_spot++, hl, pos, cs, sbptr, dir, nomatch);
|
||||
|
|
@ -825,7 +855,7 @@ doisearch(int dir)
|
|||
zrefresh();
|
||||
}
|
||||
if ((c = getkey(0)) == EOF)
|
||||
feep();
|
||||
feep = 1;
|
||||
else
|
||||
goto ins;
|
||||
} else {
|
||||
|
|
@ -843,7 +873,7 @@ doisearch(int dir)
|
|||
}
|
||||
ins:
|
||||
if (sbptr == PATH_MAX) {
|
||||
feep();
|
||||
feep = 1;
|
||||
continue;
|
||||
}
|
||||
set_isrch_spot(top_spot++, hl, pos, cs, sbptr, dir, nomatch);
|
||||
|
|
@ -854,7 +884,9 @@ doisearch(int dir)
|
|||
}
|
||||
sbuf[sbptr++] = c;
|
||||
}
|
||||
handlefeep();
|
||||
if (feep)
|
||||
handlefeep(zlenoargs);
|
||||
feep = 0;
|
||||
}
|
||||
if (sbptr) {
|
||||
zfree(previous_search, previous_search_len);
|
||||
|
|
@ -863,11 +895,17 @@ doisearch(int dir)
|
|||
}
|
||||
statusline = NULL;
|
||||
selectkeymap(okeymap, 1);
|
||||
/*
|
||||
* Don't allow unused characters provided as a string to the
|
||||
* widget to overflow and be used as separated commands.
|
||||
*/
|
||||
if (savekeys >= 0 && kungetct > savekeys)
|
||||
kungetct = savekeys;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
acceptandinfernexthistory(void)
|
||||
int
|
||||
acceptandinfernexthistory(char **args)
|
||||
{
|
||||
Histent he;
|
||||
|
||||
|
|
@ -878,14 +916,15 @@ acceptandinfernexthistory(void)
|
|||
he = movehistent(he, 1, HIST_FOREIGN);
|
||||
pushnode(bufstack, ztrdup(ZLETEXT(he)));
|
||||
stackhist = he->histnum;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
infernexthistory(void)
|
||||
int
|
||||
infernexthistory(char **args)
|
||||
{
|
||||
Histent he;
|
||||
|
||||
|
|
@ -894,28 +933,30 @@ infernexthistory(void)
|
|||
if (!metadiffer(ZLETEXT(he), (char *) line, ll)) {
|
||||
he = movehistent(he, 1, HIST_FOREIGN);
|
||||
zle_setline(he);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
feep();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vifetchhistory(void)
|
||||
int
|
||||
vifetchhistory(char **args)
|
||||
{
|
||||
if (zmult < 0)
|
||||
return;
|
||||
return 1;
|
||||
if (histline == curhist) {
|
||||
if (!(zmod.flags & MOD_MULT)) {
|
||||
cs = ll;
|
||||
cs = findbol();
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (!zle_goto_hist((zmod.flags & MOD_MULT) ? zmult : curhist, 0, 0) &&
|
||||
isset(HISTBEEP))
|
||||
feep();
|
||||
isset(HISTBEEP)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the last vi search */
|
||||
|
|
@ -928,7 +969,7 @@ static int
|
|||
getvisrchstr(void)
|
||||
{
|
||||
char *sbuf = zhalloc(80);
|
||||
int sptr = 1, ret = 0, ssbuf = 80;
|
||||
int sptr = 1, ret = 0, ssbuf = 80, feep = 0;
|
||||
Thingy cmd;
|
||||
char *okeymap = curkeymapname;
|
||||
|
||||
|
|
@ -953,9 +994,9 @@ getvisrchstr(void)
|
|||
cmd = Th(z_selfinsert);
|
||||
}
|
||||
if(cmd == Th(z_redisplay)) {
|
||||
redisplay();
|
||||
redisplay(zlenoargs);
|
||||
} else if(cmd == Th(z_clearscreen)) {
|
||||
clearscreen();
|
||||
clearscreen(zlenoargs);
|
||||
} else if(cmd == Th(z_acceptline) ||
|
||||
cmd == Th(z_vicmdmode)) {
|
||||
sbuf[sptr] = 0;
|
||||
|
|
@ -981,7 +1022,7 @@ getvisrchstr(void)
|
|||
zrefresh();
|
||||
}
|
||||
if ((c = getkey(0)) == EOF)
|
||||
feep();
|
||||
feep = 1;
|
||||
else
|
||||
goto ins;
|
||||
} else if(cmd == Th(z_selfinsertunmeta) || cmd == Th(z_selfinsert)) {
|
||||
|
|
@ -998,9 +1039,11 @@ getvisrchstr(void)
|
|||
}
|
||||
sbuf[sptr++] = c;
|
||||
} else {
|
||||
feep();
|
||||
feep = 1;
|
||||
}
|
||||
handlefeep();
|
||||
if (feep)
|
||||
handlefeep(zlenoargs);
|
||||
feep = 0;
|
||||
}
|
||||
statusline = NULL;
|
||||
selectkeymap(okeymap, 1);
|
||||
|
|
@ -1008,36 +1051,58 @@ getvisrchstr(void)
|
|||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vihistorysearchforward(void)
|
||||
int
|
||||
vihistorysearchforward(char **args)
|
||||
{
|
||||
if (*args) {
|
||||
int ose = visrchsense, ret;
|
||||
char *ost = visrchstr;
|
||||
|
||||
visrchsense = 1;
|
||||
visrchstr = *args;
|
||||
ret = virepeatsearch(zlenoargs);
|
||||
visrchsense = ose;
|
||||
visrchstr = ost;
|
||||
return ret;
|
||||
}
|
||||
visrchsense = 1;
|
||||
if (getvisrchstr())
|
||||
virepeatsearch();
|
||||
return virepeatsearch(zlenoargs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vihistorysearchbackward(void)
|
||||
int
|
||||
vihistorysearchbackward(char **args)
|
||||
{
|
||||
if (*args) {
|
||||
int ose = visrchsense, ret;
|
||||
char *ost = visrchstr;
|
||||
|
||||
visrchsense = -1;
|
||||
visrchstr = *args;
|
||||
ret = virepeatsearch(zlenoargs);
|
||||
visrchsense = ose;
|
||||
visrchstr = ost;
|
||||
return ret;
|
||||
}
|
||||
visrchsense = -1;
|
||||
if (getvisrchstr())
|
||||
virepeatsearch();
|
||||
return virepeatsearch(zlenoargs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
virepeatsearch(void)
|
||||
int
|
||||
virepeatsearch(char **args)
|
||||
{
|
||||
Histent he;
|
||||
int t0;
|
||||
int n = zmult;
|
||||
char *s;
|
||||
|
||||
if (!visrchstr) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (!visrchstr)
|
||||
return 1;
|
||||
if (zmult < 0) {
|
||||
n = -n;
|
||||
visrchsense = -visrchsense;
|
||||
|
|
@ -1053,20 +1118,22 @@ virepeatsearch(void)
|
|||
: hstrnstr(s, 0, visrchstr, t0, 1, 1) != 0)) {
|
||||
if (--n <= 0) {
|
||||
zle_setline(he);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
feep();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
virevrepeatsearch(void)
|
||||
int
|
||||
virevrepeatsearch(char **args)
|
||||
{
|
||||
int ret;
|
||||
visrchsense = -visrchsense;
|
||||
virepeatsearch();
|
||||
ret = virepeatsearch(args);
|
||||
visrchsense = -visrchsense;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Extra function added by A.R. Iano-Fletcher. */
|
||||
|
|
@ -1074,8 +1141,8 @@ virevrepeatsearch(void)
|
|||
/* history-beginning-search-backward */
|
||||
|
||||
/**/
|
||||
void
|
||||
historybeginningsearchbackward(void)
|
||||
int
|
||||
historybeginningsearchbackward(char **args)
|
||||
{
|
||||
Histent he;
|
||||
int cpos = cs; /* save cursor position */
|
||||
|
|
@ -1083,10 +1150,11 @@ historybeginningsearchbackward(void)
|
|||
char *s;
|
||||
|
||||
if (zmult < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
historybeginningsearchforward();
|
||||
ret = historybeginningsearchforward(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
he = quietgethist(histline);
|
||||
while ((he = movehistent(he, -1, hist_skip_flags))) {
|
||||
|
|
@ -1098,19 +1166,19 @@ historybeginningsearchbackward(void)
|
|||
if (--n <= 0) {
|
||||
zle_setline(he);
|
||||
cs = cpos;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
feep();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Extra function added by A.R. Iano-Fletcher. */
|
||||
|
||||
/* history-beginning-search-forward */
|
||||
/**/
|
||||
void
|
||||
historybeginningsearchforward(void)
|
||||
int
|
||||
historybeginningsearchforward(char **args)
|
||||
{
|
||||
Histent he;
|
||||
int cpos = cs; /* save cursor position */
|
||||
|
|
@ -1118,10 +1186,11 @@ historybeginningsearchforward(void)
|
|||
char *s;
|
||||
|
||||
if (zmult < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
historybeginningsearchbackward();
|
||||
ret = historybeginningsearchbackward(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
he = quietgethist(histline);
|
||||
while ((he = movehistent(he, 1, hist_skip_flags))) {
|
||||
|
|
@ -1133,9 +1202,9 @@ historybeginningsearchforward(void)
|
|||
if (--n <= 0) {
|
||||
zle_setline(he);
|
||||
cs = cpos;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
feep();
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ struct bindstate {
|
|||
/* currently selected keymap, and its name */
|
||||
|
||||
/**/
|
||||
Keymap curkeymap;
|
||||
Keymap curkeymap, localkeymap;
|
||||
/**/
|
||||
char *curkeymapname;
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ freekeynode(HashNode hn)
|
|||
static HashTable copyto;
|
||||
|
||||
/**/
|
||||
static Keymap
|
||||
Keymap
|
||||
newkeymap(Keymap tocopy, char *kmname)
|
||||
{
|
||||
Keymap km = zcalloc(sizeof(*km));
|
||||
|
|
@ -250,7 +250,7 @@ scancopykeys(HashNode hn, int flags)
|
|||
}
|
||||
|
||||
/**/
|
||||
static void
|
||||
void
|
||||
deletekeymap(Keymap km)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -322,21 +322,21 @@ openkeymap(char *name)
|
|||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
unlinkkeymap(char *name)
|
||||
int
|
||||
unlinkkeymap(char *name, int ignm)
|
||||
{
|
||||
KeymapName n = (KeymapName) keymapnamtab->getnode(keymapnamtab, name);
|
||||
if(!n)
|
||||
return 2;
|
||||
if(n->flags & KMN_IMMORTAL)
|
||||
if(!ignm && (n->flags & KMN_IMMORTAL))
|
||||
return 1;
|
||||
keymapnamtab->freenode(keymapnamtab->removenode(keymapnamtab, name));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
linkkeymap(Keymap km, char *name)
|
||||
int
|
||||
linkkeymap(Keymap km, char *name, int imm)
|
||||
{
|
||||
KeymapName n = (KeymapName) keymapnamtab->getnode(keymapnamtab, name);
|
||||
if(n) {
|
||||
|
|
@ -347,9 +347,12 @@ linkkeymap(Keymap km, char *name)
|
|||
if(!--n->keymap->rc)
|
||||
deletekeymap(n->keymap);
|
||||
n->keymap = km;
|
||||
} else
|
||||
keymapnamtab->addnode(keymapnamtab, ztrdup(name),
|
||||
makekeymapnamnode(km));
|
||||
} else {
|
||||
n = makekeymapnamnode(km);
|
||||
if (imm)
|
||||
n->flags |= KMN_IMMORTAL;
|
||||
keymapnamtab->addnode(keymapnamtab, ztrdup(name), n);
|
||||
}
|
||||
km->rc++;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -379,6 +382,15 @@ selectkeymap(char *name, int fb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Select a local key map. */
|
||||
|
||||
/**/
|
||||
void
|
||||
selectlocalmap(Keymap m)
|
||||
{
|
||||
localkeymap = m;
|
||||
}
|
||||
|
||||
/* Reopen the currently selected keymap, in case it got deleted. This *
|
||||
* should be called after doing anything that might have run an *
|
||||
* arbitrary user-specified command. */
|
||||
|
|
@ -642,7 +654,7 @@ bin_bindkey(char *name, char **argv, char *ops, int func)
|
|||
return 1;
|
||||
}
|
||||
if(ops['e'] || ops['v'])
|
||||
linkkeymap(km, "main");
|
||||
linkkeymap(km, "main", 0);
|
||||
} else {
|
||||
kmname = NULL;
|
||||
km = NULL;
|
||||
|
|
@ -715,7 +727,7 @@ bin_bindkey_del(char *name, char *kmname, Keymap km, char **argv, char *ops, cha
|
|||
int ret = 0;
|
||||
|
||||
do {
|
||||
int r = unlinkkeymap(*argv);
|
||||
int r = unlinkkeymap(*argv, 0);
|
||||
if(r == 1)
|
||||
zwarnnam(name, "keymap name `%s' is protected", *argv, 0);
|
||||
else if(r == 2)
|
||||
|
|
@ -735,7 +747,7 @@ bin_bindkey_link(char *name, char *kmname, Keymap km, char **argv, char *ops, ch
|
|||
if(!km) {
|
||||
zwarnnam(name, "no such keymap `%s'", argv[0], 0);
|
||||
return 1;
|
||||
} else if(linkkeymap(km, argv[1])) {
|
||||
} else if(linkkeymap(km, argv[1], 0)) {
|
||||
zwarnnam(name, "keymap name `%s' is protected", argv[1], 0);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -762,7 +774,7 @@ bin_bindkey_new(char *name, char *kmname, Keymap km, char **argv, char *ops, cha
|
|||
}
|
||||
} else
|
||||
km = NULL;
|
||||
linkkeymap(newkeymap(km, argv[0]), argv[0]);
|
||||
linkkeymap(newkeymap(km, argv[0]), argv[0], 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1108,20 +1120,18 @@ default_bindings(void)
|
|||
* will be linked to the "emacs" keymap, except that if VISUAL *
|
||||
* or EDITOR contain the string "vi" then it will be linked to *
|
||||
* the "viins" keymap. */
|
||||
linkkeymap(vmap, "viins");
|
||||
linkkeymap(emap, "emacs");
|
||||
linkkeymap(amap, "vicmd");
|
||||
linkkeymap(smap, ".safe");
|
||||
linkkeymap(vmap, "viins", 0);
|
||||
linkkeymap(emap, "emacs", 0);
|
||||
linkkeymap(amap, "vicmd", 0);
|
||||
linkkeymap(smap, ".safe", 1);
|
||||
if (((ed = zgetenv("VISUAL")) && strstr(ed, "vi")) ||
|
||||
((ed = zgetenv("EDITOR")) && strstr(ed, "vi")))
|
||||
linkkeymap(vmap, "main");
|
||||
linkkeymap(vmap, "main", 0);
|
||||
else
|
||||
linkkeymap(emap, "main");
|
||||
linkkeymap(emap, "main", 0);
|
||||
|
||||
/* the .safe map cannot be modified or deleted */
|
||||
smap->flags |= KM_IMMUTABLE;
|
||||
((KeymapName) keymapnamtab->getnode(keymapnamtab, ".safe"))->flags
|
||||
|= KMN_IMMORTAL;
|
||||
}
|
||||
|
||||
/*************************/
|
||||
|
|
@ -1142,7 +1152,12 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
|
|||
keybuf[0] = 0;
|
||||
while((c = getkeybuf(!!lastlen)) != EOF) {
|
||||
char *s;
|
||||
Thingy f = keybind(km, keybuf, &s);
|
||||
Thingy f;
|
||||
int loc = 1;
|
||||
|
||||
if (!localkeymap ||
|
||||
(f = keybind(localkeymap, keybuf, &s)) == t_undefinedkey)
|
||||
loc = 0, f = keybind(km, keybuf, &s);
|
||||
|
||||
if(f != t_undefinedkey) {
|
||||
lastlen = keybuflen;
|
||||
|
|
@ -1150,7 +1165,7 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
|
|||
str = s;
|
||||
lastc = c;
|
||||
}
|
||||
if(!keyisprefix(km, keybuf))
|
||||
if(!keyisprefix((loc ? localkeymap : km), keybuf))
|
||||
break;
|
||||
}
|
||||
if(!lastlen && keybuflen)
|
||||
|
|
|
|||
|
|
@ -106,10 +106,12 @@ struct modifier zmod;
|
|||
/**/
|
||||
int prefixflag;
|
||||
|
||||
/* != 0 if there is a pending beep (usually indicating an error) */
|
||||
/* Number of characters waiting to be read by the ungetkeys mechanism */
|
||||
/**/
|
||||
int kungetct;
|
||||
|
||||
/**/
|
||||
int feepflag;
|
||||
char *zlenoargs[1] = { NULL };
|
||||
|
||||
#ifdef FIONREAD
|
||||
static int delayzsetterm;
|
||||
|
|
@ -262,7 +264,7 @@ zsetterm(void)
|
|||
}
|
||||
|
||||
static char *kungetbuf;
|
||||
static int kungetct, kungetsz;
|
||||
static int kungetsz;
|
||||
|
||||
/**/
|
||||
void
|
||||
|
|
@ -499,6 +501,7 @@ zleread(char *lp, char *rp, int flags)
|
|||
viinsbegin = 0;
|
||||
statusline = NULL;
|
||||
selectkeymap("main", 1);
|
||||
selectlocalmap(NULL);
|
||||
fixsuffix();
|
||||
if ((s = (unsigned char *)getlinknode(bufstack))) {
|
||||
setline((char *)s);
|
||||
|
|
@ -527,20 +530,21 @@ zleread(char *lp, char *rp, int flags)
|
|||
lastcol = -1;
|
||||
initmodifier(&zmod);
|
||||
prefixflag = 0;
|
||||
feepflag = 0;
|
||||
zrefresh();
|
||||
while (!done && !errflag) {
|
||||
|
||||
statusline = NULL;
|
||||
vilinerange = 0;
|
||||
reselectkeymap();
|
||||
selectlocalmap(NULL);
|
||||
bindk = getkeycmd();
|
||||
if (!ll && isfirstln && c == eofchar) {
|
||||
eofsent = 1;
|
||||
break;
|
||||
}
|
||||
if (bindk) {
|
||||
execzlefunc(bindk);
|
||||
if (execzlefunc(bindk, zlenoargs))
|
||||
handlefeep(zlenoargs);
|
||||
handleprefixes();
|
||||
/* for vi mode, make sure the cursor isn't somewhere illegal */
|
||||
if (invicmdmode() && cs > findbol() &&
|
||||
|
|
@ -565,7 +569,6 @@ zleread(char *lp, char *rp, int flags)
|
|||
#endif
|
||||
if (!kungetct)
|
||||
zrefresh();
|
||||
handlefeep();
|
||||
}
|
||||
statusline = NULL;
|
||||
invalidatelist();
|
||||
|
|
@ -591,10 +594,10 @@ zleread(char *lp, char *rp, int flags)
|
|||
/* execute a widget */
|
||||
|
||||
/**/
|
||||
void
|
||||
execzlefunc(Thingy func)
|
||||
int
|
||||
execzlefunc(Thingy func, char **args)
|
||||
{
|
||||
int r = 0;
|
||||
int r = 0, ret = 0;
|
||||
Widget w;
|
||||
|
||||
if(func->flags & DISABLED) {
|
||||
|
|
@ -605,7 +608,7 @@ execzlefunc(Thingy func)
|
|||
zsfree(nm);
|
||||
showmsg(msg);
|
||||
zsfree(msg);
|
||||
feep();
|
||||
ret = 1;
|
||||
} else if((w = func->widget)->flags & (WIDGET_INT|WIDGET_NCOMP)) {
|
||||
int wflags = w->flags;
|
||||
|
||||
|
|
@ -621,9 +624,9 @@ execzlefunc(Thingy func)
|
|||
lastcol = -1;
|
||||
if (wflags & WIDGET_NCOMP) {
|
||||
compwidget = w;
|
||||
completecall();
|
||||
ret = completecall(args);
|
||||
} else
|
||||
w->u.fn();
|
||||
ret = w->u.fn(args);
|
||||
if (!(wflags & ZLE_NOTCOMMAND))
|
||||
lastcmd = wflags;
|
||||
r = 1;
|
||||
|
|
@ -638,14 +641,23 @@ execzlefunc(Thingy func)
|
|||
zsfree(nm);
|
||||
showmsg(msg);
|
||||
zsfree(msg);
|
||||
feep();
|
||||
ret = 1;
|
||||
} else {
|
||||
int osc = sfcontext, osi = movefd(0);
|
||||
int osc = sfcontext, osi = movefd(0), olv = lastval;
|
||||
LinkList largs = NULL;
|
||||
|
||||
if (*args) {
|
||||
largs = newlinklist();
|
||||
addlinknode(largs, dupstring(w->u.fnnam));
|
||||
while (*args)
|
||||
addlinknode(largs, dupstring(*args++));
|
||||
}
|
||||
startparamscope();
|
||||
makezleparams(0);
|
||||
sfcontext = SFC_WIDGET;
|
||||
doshfunc(w->u.fnnam, l, NULL, 0, 1);
|
||||
doshfunc(w->u.fnnam, l, largs, 0, 0);
|
||||
ret = lastval;
|
||||
lastval = olv;
|
||||
sfcontext = osc;
|
||||
endparamscope();
|
||||
lastcmd = 0;
|
||||
|
|
@ -658,6 +670,7 @@ execzlefunc(Thingy func)
|
|||
refthingy(func);
|
||||
lbindk = func;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* initialise command modifiers */
|
||||
|
|
@ -826,14 +839,14 @@ bin_vared(char *name, char **args, char *ops, int func)
|
|||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
describekeybriefly(void)
|
||||
int
|
||||
describekeybriefly(char **args)
|
||||
{
|
||||
char *seq, *str, *msg, *is;
|
||||
Thingy func;
|
||||
|
||||
if (statusline)
|
||||
return;
|
||||
return 1;
|
||||
clearlist = 1;
|
||||
statusline = "Describe key briefly: _";
|
||||
statusll = strlen(statusline);
|
||||
|
|
@ -841,7 +854,7 @@ describekeybriefly(void)
|
|||
seq = getkeymapcmd(curkeymap, &func, &str);
|
||||
statusline = NULL;
|
||||
if(!*seq)
|
||||
return;
|
||||
return 1;
|
||||
msg = bindztrdup(seq);
|
||||
msg = appstr(msg, " is ");
|
||||
if (!func)
|
||||
|
|
@ -852,6 +865,7 @@ describekeybriefly(void)
|
|||
zsfree(is);
|
||||
showmsg(msg);
|
||||
zsfree(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAXFOUND 4
|
||||
|
|
@ -882,13 +896,13 @@ scanfindfunc(char *seq, Thingy func, char *str, void *magic)
|
|||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
whereis(void)
|
||||
int
|
||||
whereis(char **args)
|
||||
{
|
||||
struct findfunc ff;
|
||||
|
||||
if (!(ff.func = executenamedcommand("Where is: ")))
|
||||
return;
|
||||
return 1;
|
||||
ff.found = 0;
|
||||
ff.msg = niceztrdup(ff.func->nam);
|
||||
scankeymap(curkeymap, 1, scanfindfunc, &ff);
|
||||
|
|
@ -898,6 +912,7 @@ whereis(void)
|
|||
ff.msg = appstr(ff.msg, " et al");
|
||||
showmsg(ff.msg);
|
||||
zsfree(ff.msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
@ -933,7 +948,17 @@ 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, "lDANCLmMgGc", NULL),
|
||||
BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANCLmMgGcRa", NULL),
|
||||
};
|
||||
|
||||
/* The order of the entries in this table has to match the *HOOK
|
||||
* macros in zle.h */
|
||||
|
||||
/**/
|
||||
struct hookdef zlehooks[] = {
|
||||
HOOKDEF("list_matches", ilistmatches, 0),
|
||||
HOOKDEF("insert_match", NULL, HOOKF_ALL),
|
||||
HOOKDEF("menu_start", NULL, HOOKF_ALL),
|
||||
};
|
||||
|
||||
/**/
|
||||
|
|
@ -955,6 +980,8 @@ setup_zle(Module m)
|
|||
unambig_dataptr = unambig_data;
|
||||
set_comp_sepptr = set_comp_sep;
|
||||
|
||||
getkeyptr = getkey;
|
||||
|
||||
/* initialise the thingies */
|
||||
init_thingies();
|
||||
lbindk = NULL;
|
||||
|
|
@ -977,6 +1004,7 @@ int
|
|||
boot_zle(Module m)
|
||||
{
|
||||
addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
|
||||
addhookdefs(m->nam, zlehooks, sizeof(zlehooks)/sizeof(*zlehooks));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -992,6 +1020,7 @@ cleanup_zle(Module m)
|
|||
return 1;
|
||||
}
|
||||
deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
|
||||
deletehookdefs(m->nam, zlehooks, sizeof(zlehooks)/sizeof(*zlehooks));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1031,6 +1060,8 @@ finish_zle(Module m)
|
|||
unambig_dataptr = NULL;
|
||||
set_comp_sepptr = NULL;
|
||||
|
||||
getkeyptr = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ doinsert(char *str)
|
|||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
selfinsert(void)
|
||||
int
|
||||
selfinsert(char **args)
|
||||
{
|
||||
char s[3], *p = s;
|
||||
|
||||
|
|
@ -69,56 +69,61 @@ selfinsert(void)
|
|||
*p++ = c;
|
||||
*p = 0;
|
||||
doinsert(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
selfinsertunmeta(void)
|
||||
int
|
||||
selfinsertunmeta(char **args)
|
||||
{
|
||||
c &= 0x7f;
|
||||
if (c == '\r')
|
||||
c = '\n';
|
||||
selfinsert();
|
||||
return selfinsert(args);
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
deletechar(void)
|
||||
int
|
||||
deletechar(char **args)
|
||||
{
|
||||
if (zmult < 0) {
|
||||
int ret;
|
||||
zmult = -zmult;
|
||||
backwarddeletechar();
|
||||
ret = backwarddeletechar(args);
|
||||
zmult = -zmult;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
if (cs + zmult <= ll) {
|
||||
cs += zmult;
|
||||
backdel(zmult);
|
||||
} else
|
||||
feep();
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
backwarddeletechar(void)
|
||||
int
|
||||
backwarddeletechar(char **args)
|
||||
{
|
||||
if (zmult < 0) {
|
||||
int ret;
|
||||
zmult = -zmult;
|
||||
deletechar();
|
||||
ret = deletechar(args);
|
||||
zmult = -zmult;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
backdel(zmult > cs ? cs : zmult);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
killwholeline(void)
|
||||
int
|
||||
killwholeline(char **args)
|
||||
{
|
||||
int i, fg, n = zmult;
|
||||
|
||||
if (n < 0)
|
||||
return;
|
||||
return 1;
|
||||
while (n--) {
|
||||
if ((fg = (cs && cs == ll)))
|
||||
cs--;
|
||||
|
|
@ -128,28 +133,31 @@ killwholeline(void)
|
|||
forekill(i - cs + (i != ll), fg);
|
||||
}
|
||||
clearlist = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
killbuffer(void)
|
||||
int
|
||||
killbuffer(char **args)
|
||||
{
|
||||
cs = 0;
|
||||
forekill(ll, 0);
|
||||
clearlist = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
backwardkillline(void)
|
||||
int
|
||||
backwardkillline(char **args)
|
||||
{
|
||||
int i = 0, n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
killline();
|
||||
ret = killline(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
if (cs && line[cs - 1] == '\n')
|
||||
|
|
@ -160,11 +168,12 @@ backwardkillline(void)
|
|||
}
|
||||
forekill(i, 1);
|
||||
clearlist = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
gosmacstransposechars(void)
|
||||
int
|
||||
gosmacstransposechars(char **args)
|
||||
{
|
||||
int cc;
|
||||
|
||||
|
|
@ -172,19 +181,19 @@ gosmacstransposechars(void)
|
|||
if (cs == ll || line[cs] == '\n' ||
|
||||
((cs + 1 == ll || line[cs + 1] == '\n') &&
|
||||
(!cs || line[cs - 1] == '\n'))) {
|
||||
feep();
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
cs += (cs == 0 || line[cs - 1] == '\n') ? 2 : 1;
|
||||
}
|
||||
cc = line[cs - 2];
|
||||
line[cs - 2] = line[cs - 1];
|
||||
line[cs - 1] = cc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
transposechars(void)
|
||||
int
|
||||
transposechars(char **args)
|
||||
{
|
||||
int cc, ct;
|
||||
int n = zmult;
|
||||
|
|
@ -194,10 +203,8 @@ transposechars(void)
|
|||
n = -n;
|
||||
while (n--) {
|
||||
if (!(ct = cs) || line[cs - 1] == '\n') {
|
||||
if (ll == cs || line[cs] == '\n') {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (ll == cs || line[cs] == '\n')
|
||||
return 1;
|
||||
if (!neg)
|
||||
cs++;
|
||||
ct++;
|
||||
|
|
@ -214,29 +221,28 @@ transposechars(void)
|
|||
}
|
||||
if (ct == ll || line[ct] == '\n')
|
||||
ct--;
|
||||
if (ct < 1 || line[ct - 1] == '\n') {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (ct < 1 || line[ct - 1] == '\n')
|
||||
return 1;
|
||||
cc = line[ct - 1];
|
||||
line[ct - 1] = line[ct];
|
||||
line[ct] = cc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
poundinsert(void)
|
||||
int
|
||||
poundinsert(char **args)
|
||||
{
|
||||
cs = 0;
|
||||
vifirstnonblank();
|
||||
vifirstnonblank(zlenoargs);
|
||||
if (line[cs] != '#') {
|
||||
spaceinline(1);
|
||||
line[cs] = '#';
|
||||
cs = findeol();
|
||||
while(cs != ll) {
|
||||
cs++;
|
||||
vifirstnonblank();
|
||||
vifirstnonblank(zlenoargs);
|
||||
spaceinline(1);
|
||||
line[cs] = '#';
|
||||
cs = findeol();
|
||||
|
|
@ -246,42 +252,46 @@ poundinsert(void)
|
|||
cs = findeol();
|
||||
while(cs != ll) {
|
||||
cs++;
|
||||
vifirstnonblank();
|
||||
vifirstnonblank(zlenoargs);
|
||||
if(line[cs] == '#')
|
||||
foredel(1);
|
||||
cs = findeol();
|
||||
}
|
||||
}
|
||||
done = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
acceptline(void)
|
||||
int
|
||||
acceptline(char **args)
|
||||
{
|
||||
done = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
acceptandhold(void)
|
||||
int
|
||||
acceptandhold(char **args)
|
||||
{
|
||||
pushnode(bufstack, metafy((char *)line, ll, META_DUP));
|
||||
stackcs = cs;
|
||||
done = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
killline(void)
|
||||
int
|
||||
killline(char **args)
|
||||
{
|
||||
int i = 0, n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
backwardkillline();
|
||||
ret = backwardkillline(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
if (line[cs] == '\n')
|
||||
|
|
@ -292,11 +302,12 @@ killline(void)
|
|||
}
|
||||
backkill(i, 0);
|
||||
clearlist = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
killregion(void)
|
||||
int
|
||||
killregion(char **args)
|
||||
{
|
||||
if (mark > ll)
|
||||
mark = ll;
|
||||
|
|
@ -304,11 +315,12 @@ killregion(void)
|
|||
forekill(mark - cs, 0);
|
||||
else
|
||||
backkill(cs - mark, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
copyregionaskill(void)
|
||||
int
|
||||
copyregionaskill(char **args)
|
||||
{
|
||||
if (mark > ll)
|
||||
mark = ll;
|
||||
|
|
@ -316,25 +328,24 @@ copyregionaskill(void)
|
|||
cut(cs, mark - cs, 0);
|
||||
else
|
||||
cut(mark, cs - mark, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kct, yankb, yanke;
|
||||
|
||||
/**/
|
||||
void
|
||||
yank(void)
|
||||
int
|
||||
yank(char **args)
|
||||
{
|
||||
Cutbuffer buf = &cutbuf;
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0)
|
||||
return;
|
||||
return 1;
|
||||
if (zmod.flags & MOD_VIBUF)
|
||||
buf = &vibuf[zmod.vibuf];
|
||||
if (!buf->buf) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (!buf->buf)
|
||||
return 1;
|
||||
mark = cs;
|
||||
yankb = cs;
|
||||
while (n--) {
|
||||
|
|
@ -344,18 +355,17 @@ yank(void)
|
|||
cs += buf->len;
|
||||
yanke = cs;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
yankpop(void)
|
||||
int
|
||||
yankpop(char **args)
|
||||
{
|
||||
int cc;
|
||||
|
||||
if (!(lastcmd & ZLE_YANK) || !kring[kct].buf) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (!(lastcmd & ZLE_YANK) || !kring[kct].buf)
|
||||
return 1;
|
||||
cs = yankb;
|
||||
foredel(yanke - yankb);
|
||||
cc = kring[kct].len;
|
||||
|
|
@ -364,17 +374,20 @@ yankpop(void)
|
|||
cs += cc;
|
||||
yanke = cs;
|
||||
kct = (kct + KRINGCT - 1) % KRINGCT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
overwritemode(void)
|
||||
int
|
||||
overwritemode(char **args)
|
||||
{
|
||||
insmode ^= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
whatcursorposition(void)
|
||||
int
|
||||
whatcursorposition(char **args)
|
||||
{
|
||||
char msg[100];
|
||||
char *s = msg;
|
||||
|
|
@ -408,18 +421,19 @@ whatcursorposition(void)
|
|||
sprintf(s, " point %d of %d(%d%%) column %d", cs+1, ll+1,
|
||||
ll ? 100 * cs / ll : 0, cs - bol);
|
||||
showmsg(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
undefinedkey(void)
|
||||
int
|
||||
undefinedkey(char **args)
|
||||
{
|
||||
feep();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
quotedinsert(void)
|
||||
int
|
||||
quotedinsert(char **args)
|
||||
{
|
||||
#ifndef HAS_TIO
|
||||
struct sgttyb sob;
|
||||
|
|
@ -433,17 +447,20 @@ quotedinsert(void)
|
|||
zsetterm();
|
||||
#endif
|
||||
if (c < 0)
|
||||
feep();
|
||||
return 1;
|
||||
else
|
||||
selfinsert();
|
||||
return selfinsert(args);
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
digitargument(void)
|
||||
int
|
||||
digitargument(char **args)
|
||||
{
|
||||
int sign = (zmult < 0) ? -1 : 1;
|
||||
|
||||
if (c < '0' || c > '9')
|
||||
return 1;
|
||||
|
||||
if (!(zmod.flags & MOD_TMULT))
|
||||
zmod.tmult = 0;
|
||||
if (zmod.flags & MOD_NEG) {
|
||||
|
|
@ -455,26 +472,31 @@ digitargument(void)
|
|||
zmod.tmult = zmod.tmult * 10 + sign * (c & 0xf);
|
||||
zmod.flags |= MOD_TMULT;
|
||||
prefixflag = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
negargument(void)
|
||||
int
|
||||
negargument(char **args)
|
||||
{
|
||||
if(zmod.flags & MOD_TMULT) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (zmod.flags & MOD_TMULT)
|
||||
return 1;
|
||||
zmod.tmult = -1;
|
||||
zmod.flags |= MOD_TMULT|MOD_NEG;
|
||||
prefixflag = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
universalargument(void)
|
||||
int
|
||||
universalargument(char **args)
|
||||
{
|
||||
int digcnt = 0, pref = 0, minus = 1, gotk;
|
||||
if (*args) {
|
||||
zmod.mult = atoi(*args);
|
||||
zmod.flags |= MOD_MULT;
|
||||
return 0;
|
||||
}
|
||||
while ((gotk = getkey(0)) != EOF) {
|
||||
if (gotk == '-' && !digcnt) {
|
||||
minus = -1;
|
||||
|
|
@ -493,11 +515,12 @@ universalargument(void)
|
|||
zmod.tmult *= 4;
|
||||
zmod.flags |= MOD_TMULT;
|
||||
prefixflag = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
copyprevword(void)
|
||||
int
|
||||
copyprevword(char **args)
|
||||
{
|
||||
int len, t0;
|
||||
|
||||
|
|
@ -513,18 +536,20 @@ copyprevword(void)
|
|||
spaceinline(len);
|
||||
memcpy((char *)&line[cs], (char *)&line[t0], len);
|
||||
cs += len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
sendbreak(void)
|
||||
int
|
||||
sendbreak(char **args)
|
||||
{
|
||||
errflag = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
quoteregion(void)
|
||||
int
|
||||
quoteregion(char **args)
|
||||
{
|
||||
char *str;
|
||||
size_t len;
|
||||
|
|
@ -544,11 +569,12 @@ quoteregion(void)
|
|||
memcpy((char *)&line[cs], str, len);
|
||||
mark = cs;
|
||||
cs += len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
quoteline(void)
|
||||
int
|
||||
quoteline(char **args)
|
||||
{
|
||||
char *str;
|
||||
size_t len = ll;
|
||||
|
|
@ -557,6 +583,7 @@ quoteline(void)
|
|||
sizeline(len);
|
||||
memcpy(line, str, len);
|
||||
cs = ll = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
@ -612,7 +639,7 @@ Thingy
|
|||
executenamedcommand(char *prmt)
|
||||
{
|
||||
Thingy cmd;
|
||||
int len, l = strlen(prmt), ols = listshown;
|
||||
int len, l = strlen(prmt), ols = listshown, feep = 0;
|
||||
char *ptr;
|
||||
char *okeymap = curkeymapname;
|
||||
|
||||
|
|
@ -637,20 +664,20 @@ executenamedcommand(char *prmt)
|
|||
return NULL;
|
||||
}
|
||||
if(cmd == Th(z_clearscreen)) {
|
||||
clearscreen();
|
||||
clearscreen(zlenoargs);
|
||||
} else if(cmd == Th(z_redisplay)) {
|
||||
redisplay();
|
||||
redisplay(zlenoargs);
|
||||
} else if(cmd == Th(z_viquotedinsert)) {
|
||||
*ptr = '^';
|
||||
zrefresh();
|
||||
c = getkey(0);
|
||||
if(c == EOF || !c || len == NAMLEN)
|
||||
feep();
|
||||
feep = 1;
|
||||
else
|
||||
*ptr++ = c, len++;
|
||||
} else if(cmd == Th(z_quotedinsert)) {
|
||||
if((c = getkey(0)) == EOF || !c || len == NAMLEN)
|
||||
feep();
|
||||
feep = 1;
|
||||
else
|
||||
*ptr++ = c, len++;
|
||||
} else if(cmd == Th(z_backwarddeletechar) ||
|
||||
|
|
@ -701,7 +728,7 @@ executenamedcommand(char *prmt)
|
|||
scanhashtable(thingytab, 1, 0, DISABLED, scancompcmd, 0);
|
||||
} LASTALLOC;
|
||||
if (empty(cmdll))
|
||||
feep();
|
||||
feep = 1;
|
||||
else if (cmd == Th(z_listchoices) ||
|
||||
cmd == Th(z_deletecharorlist)) {
|
||||
int zmultsav = zmult;
|
||||
|
|
@ -723,7 +750,7 @@ executenamedcommand(char *prmt)
|
|||
!(isset(LISTAMBIGUOUS) && cmdambig > len)) {
|
||||
int zmultsav = zmult;
|
||||
if (isset(LISTBEEP))
|
||||
feep();
|
||||
feep = 1;
|
||||
statusll = l + cmdambig + 1;
|
||||
zmult = 1;
|
||||
listlist(cmdll);
|
||||
|
|
@ -733,12 +760,14 @@ executenamedcommand(char *prmt)
|
|||
}
|
||||
} else {
|
||||
if (len == NAMLEN || icntrl(c) || cmd != Th(z_selfinsert))
|
||||
feep();
|
||||
feep = 1;
|
||||
else
|
||||
*ptr++ = c, len++;
|
||||
}
|
||||
}
|
||||
handlefeep();
|
||||
if (feep)
|
||||
handlefeep(zlenoargs);
|
||||
feep = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,64 +33,69 @@
|
|||
static int vimarkcs[27], vimarkline[27];
|
||||
|
||||
/**/
|
||||
void
|
||||
beginningofline(void)
|
||||
int
|
||||
beginningofline(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
endofline();
|
||||
ret = endofline(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
if (cs == 0)
|
||||
return;
|
||||
return 0;
|
||||
if (line[cs - 1] == '\n')
|
||||
if (!--cs)
|
||||
return;
|
||||
return 0;
|
||||
while (cs && line[cs - 1] != '\n')
|
||||
cs--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
endofline(void)
|
||||
int
|
||||
endofline(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
beginningofline();
|
||||
ret = beginningofline(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
if (cs >= ll) {
|
||||
cs = ll;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (line[cs] == '\n')
|
||||
if (++cs == ll)
|
||||
return;
|
||||
return 0;
|
||||
while (cs != ll && line[cs] != '\n')
|
||||
cs++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
beginningoflinehist(void)
|
||||
int
|
||||
beginningoflinehist(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
endoflinehist();
|
||||
ret = endoflinehist(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n) {
|
||||
if (cs == 0)
|
||||
|
|
@ -103,26 +108,29 @@ beginningoflinehist(void)
|
|||
n--;
|
||||
}
|
||||
if (n) {
|
||||
int m = zmult;
|
||||
int m = zmult, ret;
|
||||
|
||||
zmult = n;
|
||||
uphistory();
|
||||
ret = uphistory(args);
|
||||
zmult = m;
|
||||
cs = 0;
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
endoflinehist(void)
|
||||
int
|
||||
endoflinehist(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
beginningoflinehist();
|
||||
ret = beginningoflinehist(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n) {
|
||||
if (cs >= ll) {
|
||||
|
|
@ -137,46 +145,51 @@ endoflinehist(void)
|
|||
n--;
|
||||
}
|
||||
if (n) {
|
||||
int m = zmult;
|
||||
int m = zmult, ret;
|
||||
|
||||
zmult = n;
|
||||
downhistory();
|
||||
ret = downhistory(args);
|
||||
zmult = m;
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
forwardchar(void)
|
||||
int
|
||||
forwardchar(char **args)
|
||||
{
|
||||
cs += zmult;
|
||||
if (cs > ll)
|
||||
cs = ll;
|
||||
if (cs < 0)
|
||||
cs = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
backwardchar(void)
|
||||
int
|
||||
backwardchar(char **args)
|
||||
{
|
||||
cs -= zmult;
|
||||
if (cs > ll)
|
||||
cs = ll;
|
||||
if (cs < 0)
|
||||
cs = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
setmarkcommand(void)
|
||||
int
|
||||
setmarkcommand(char **args)
|
||||
{
|
||||
mark = cs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
exchangepointandmark(void)
|
||||
int
|
||||
exchangepointandmark(char **args)
|
||||
{
|
||||
int x;
|
||||
|
||||
|
|
@ -185,11 +198,12 @@ exchangepointandmark(void)
|
|||
cs = x;
|
||||
if (cs > ll)
|
||||
cs = ll;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vigotocolumn(void)
|
||||
int
|
||||
vigotocolumn(char **args)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
|
|
@ -202,20 +216,20 @@ vigotocolumn(void)
|
|||
cs = y;
|
||||
if (cs < x)
|
||||
cs = x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vimatchbracket(void)
|
||||
int
|
||||
vimatchbracket(char **args)
|
||||
{
|
||||
int ocs = cs, dir, ct;
|
||||
unsigned char oth, me;
|
||||
|
||||
otog:
|
||||
if (cs == ll || line[cs] == '\n') {
|
||||
feep();
|
||||
cs = ocs;
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
switch (me = line[cs]) {
|
||||
case '{':
|
||||
|
|
@ -258,49 +272,49 @@ vimatchbracket(void)
|
|||
ct++;
|
||||
}
|
||||
if (cs < 0 || cs >= ll) {
|
||||
feep();
|
||||
cs = ocs;
|
||||
return 1;
|
||||
} else if(dir > 0 && virangeflag)
|
||||
cs++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viforwardchar(void)
|
||||
int
|
||||
viforwardchar(char **args)
|
||||
{
|
||||
int lim = findeol() - invicmdmode();
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
vibackwardchar();
|
||||
ret = vibackwardchar(args);
|
||||
zmult = n;
|
||||
return;
|
||||
}
|
||||
if (cs >= lim) {
|
||||
feep();
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
if (cs >= lim)
|
||||
return 1;
|
||||
while (n-- && cs < lim)
|
||||
cs++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vibackwardchar(void)
|
||||
int
|
||||
vibackwardchar(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
viforwardchar();
|
||||
ret = viforwardchar(args);
|
||||
zmult = n;
|
||||
return;
|
||||
}
|
||||
if (cs == findbol()) {
|
||||
feep();
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
if (cs == findbol())
|
||||
return 1;
|
||||
while (n--) {
|
||||
cs--;
|
||||
if (cs < 0 || line[cs] == '\n') {
|
||||
|
|
@ -308,157 +322,163 @@ vibackwardchar(void)
|
|||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viendofline(void)
|
||||
int
|
||||
viendofline(char **args)
|
||||
{
|
||||
int oldcs = cs, n = zmult;
|
||||
|
||||
if (n < 1) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (n < 1)
|
||||
return 1;
|
||||
while(n--) {
|
||||
if (cs > ll) {
|
||||
cs = oldcs;
|
||||
feep();
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
cs = findeol() + 1;
|
||||
}
|
||||
cs--;
|
||||
lastcol = 1<<30;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vibeginningofline(void)
|
||||
int
|
||||
vibeginningofline(char **args)
|
||||
{
|
||||
cs = findbol();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vfindchar, vfinddir, tailadd;
|
||||
|
||||
/**/
|
||||
void
|
||||
vifindnextchar(void)
|
||||
int
|
||||
vifindnextchar(char **args)
|
||||
{
|
||||
if ((vfindchar = vigetkey()) != -1) {
|
||||
vfinddir = 1;
|
||||
tailadd = 0;
|
||||
virepeatfind();
|
||||
return virepeatfind(args);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vifindprevchar(void)
|
||||
int
|
||||
vifindprevchar(char **args)
|
||||
{
|
||||
if ((vfindchar = vigetkey()) != -1) {
|
||||
vfinddir = -1;
|
||||
tailadd = 0;
|
||||
virepeatfind();
|
||||
return virepeatfind(args);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vifindnextcharskip(void)
|
||||
int
|
||||
vifindnextcharskip(char **args)
|
||||
{
|
||||
if ((vfindchar = vigetkey()) != -1) {
|
||||
vfinddir = 1;
|
||||
tailadd = -1;
|
||||
virepeatfind();
|
||||
return virepeatfind(args);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vifindprevcharskip(void)
|
||||
int
|
||||
vifindprevcharskip(char **args)
|
||||
{
|
||||
if ((vfindchar = vigetkey()) != -1) {
|
||||
vfinddir = -1;
|
||||
tailadd = 1;
|
||||
virepeatfind();
|
||||
return virepeatfind(args);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
virepeatfind(void)
|
||||
int
|
||||
virepeatfind(char **args)
|
||||
{
|
||||
int ocs = cs, n = zmult;
|
||||
|
||||
if (!vfinddir) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (!vfinddir)
|
||||
return 1;
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
virevrepeatfind();
|
||||
ret = virevrepeatfind(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
do
|
||||
cs += vfinddir;
|
||||
while (cs >= 0 && cs < ll && line[cs] != vfindchar && line[cs] != '\n');
|
||||
if (cs < 0 || cs >= ll || line[cs] == '\n') {
|
||||
feep();
|
||||
cs = ocs;
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
cs += tailadd;
|
||||
if (vfinddir == 1 && virangeflag)
|
||||
cs++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
virevrepeatfind(void)
|
||||
int
|
||||
virevrepeatfind(char **args)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (zmult < 0) {
|
||||
zmult = -zmult;
|
||||
virepeatfind();
|
||||
ret = virepeatfind(args);
|
||||
zmult = -zmult;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
vfinddir = -vfinddir;
|
||||
virepeatfind();
|
||||
ret = virepeatfind(args);
|
||||
vfinddir = -vfinddir;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vifirstnonblank(void)
|
||||
int
|
||||
vifirstnonblank(char **args)
|
||||
{
|
||||
cs = findbol();
|
||||
while (cs != ll && iblank(line[cs]))
|
||||
cs++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
visetmark(void)
|
||||
int
|
||||
visetmark(char **args)
|
||||
{
|
||||
int ch;
|
||||
|
||||
ch = getkey(0);
|
||||
if (ch < 'a' || ch > 'z') {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (ch < 'a' || ch > 'z')
|
||||
return 1;
|
||||
ch -= 'a';
|
||||
vimarkcs[ch] = cs;
|
||||
vimarkline[ch] = histline;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vigotomark(void)
|
||||
int
|
||||
vigotomark(char **args)
|
||||
{
|
||||
int ch;
|
||||
|
||||
|
|
@ -466,30 +486,26 @@ vigotomark(void)
|
|||
if (ch == c)
|
||||
ch = 26;
|
||||
else {
|
||||
if (ch < 'a' || ch > 'z') {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (ch < 'a' || ch > 'z')
|
||||
return 1;
|
||||
ch -= 'a';
|
||||
}
|
||||
if (!vimarkline[ch]) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (!vimarkline[ch])
|
||||
return 1;
|
||||
if (curhist != vimarkline[ch] && !zle_goto_hist(vimarkline[ch], 0, 0)) {
|
||||
vimarkline[ch] = 0;
|
||||
feep();
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
cs = vimarkcs[ch];
|
||||
if (cs > ll)
|
||||
cs = ll;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vigotomarkline(void)
|
||||
int
|
||||
vigotomarkline(char **args)
|
||||
{
|
||||
vigotomark();
|
||||
vifirstnonblank();
|
||||
vigotomark(args);
|
||||
return vifirstnonblank(zlenoargs);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ static struct zleparam {
|
|||
zleunsetfn, NULL },
|
||||
{ "keys", PM_ARRAY | PM_READONLY, NULL, FN(get_keys),
|
||||
zleunsetfn, NULL },
|
||||
{ "NUMERIC", PM_INTEGER, FN(set_numeric), FN(get_numeric),
|
||||
zleunsetfn, NULL },
|
||||
{ "NUMERIC", PM_INTEGER | PM_UNSET, FN(set_numeric), FN(get_numeric),
|
||||
unset_numeric, NULL },
|
||||
{ "HISTNO", PM_INTEGER | PM_READONLY, NULL, FN(get_histno),
|
||||
zleunsetfn, NULL },
|
||||
{ NULL, 0, NULL, NULL, NULL, NULL }
|
||||
|
|
@ -84,12 +84,12 @@ makezleparams(int ro)
|
|||
|
||||
for(zp = zleparams; zp->name; zp++) {
|
||||
Param pm = createparam(zp->name, (zp->type |PM_SPECIAL|PM_REMOVABLE|
|
||||
(ro ? PM_READONLY : 0)));
|
||||
PM_LOCAL|(ro ? PM_READONLY : 0)));
|
||||
if (!pm)
|
||||
pm = (Param) paramtab->getnode(paramtab, zp->name);
|
||||
DPUTS(!pm, "param not set in makezleparams");
|
||||
|
||||
pm->level = locallevel;
|
||||
pm->level = locallevel + 1;
|
||||
pm->u.data = zp->data;
|
||||
switch(PM_TYPE(zp->type)) {
|
||||
case PM_SCALAR:
|
||||
|
|
@ -107,6 +107,8 @@ makezleparams(int ro)
|
|||
break;
|
||||
}
|
||||
pm->unsetfn = zp->unsetfn;
|
||||
if ((zp->type & PM_UNSET) && (zmod.flags & MOD_MULT))
|
||||
pm->flags &= ~PM_UNSET;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -267,6 +269,7 @@ static void
|
|||
set_numeric(Param pm, zlong x)
|
||||
{
|
||||
zmult = x;
|
||||
zmod.flags = MOD_MULT;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
@ -276,6 +279,17 @@ get_numeric(Param pm)
|
|||
return zmult;
|
||||
}
|
||||
|
||||
/**/
|
||||
static void
|
||||
unset_numeric(Param pm, int exp)
|
||||
{
|
||||
if (exp) {
|
||||
stdunsetfn(pm, exp);
|
||||
zmod.flags = 0;
|
||||
zmult = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
static zlong
|
||||
get_histno(Param pm)
|
||||
|
|
|
|||
|
|
@ -1004,23 +1004,25 @@ tcoutarg(int cap, int arg)
|
|||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
clearscreen(void)
|
||||
int
|
||||
clearscreen(char **args)
|
||||
{
|
||||
tcout(TCCLEARSCREEN);
|
||||
resetneeded = 1;
|
||||
clearflag = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
redisplay(void)
|
||||
int
|
||||
redisplay(char **args)
|
||||
{
|
||||
moveto(0, 0);
|
||||
zputc('\r', shout); /* extra care */
|
||||
tc_upcurs(lprompth - 1);
|
||||
resetneeded = 1;
|
||||
clearflag = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
|
|||
|
|
@ -318,9 +318,10 @@ deletezlefunction(Widget w)
|
|||
/*
|
||||
* The available operations are:
|
||||
*
|
||||
* -l list user-defined widgets (no arguments)
|
||||
* -l list widgets/test for existence
|
||||
* -D delete widget names
|
||||
* -A link the two named widgets (2 arguments)
|
||||
* -C create completion widget (3 arguments)
|
||||
* -N create new user-defined widget (1 or 2 arguments)
|
||||
* invoke a widget (1 argument)
|
||||
*/
|
||||
|
|
@ -334,12 +335,12 @@ bin_zle(char *name, char **args, char *ops, int func)
|
|||
int (*func) _((char *, char **, char *, char));
|
||||
int min, max;
|
||||
} const opns[] = {
|
||||
{ 'l', bin_zle_list, 0, 0 },
|
||||
{ 'l', bin_zle_list, 0, -1 },
|
||||
{ 'D', bin_zle_del, 1, -1 },
|
||||
{ 'A', bin_zle_link, 2, 2 },
|
||||
{ 'N', bin_zle_new, 1, 2 },
|
||||
{ 'C', bin_zle_complete, 3, 3 },
|
||||
{ 'c', bin_zle_complete, 3, 3 },
|
||||
{ 'R', bin_zle_refresh, 0, 1 },
|
||||
{ 0, bin_zle_call, 0, -1 },
|
||||
};
|
||||
struct opn const *op, *opp;
|
||||
|
|
@ -357,10 +358,6 @@ bin_zle(char *name, char **args, char *ops, int func)
|
|||
|
||||
/* check number of arguments */
|
||||
for(n = 0; args[n]; n++) ;
|
||||
if(!op->o && n != 1 && n != 2) {
|
||||
zerrnam(name, "wrong number of arguments", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if(n < op->min) {
|
||||
zerrnam(name, "not enough arguments for -%c", NULL, op->o);
|
||||
return 1;
|
||||
|
|
@ -377,7 +374,41 @@ bin_zle(char *name, char **args, char *ops, int func)
|
|||
static int
|
||||
bin_zle_list(char *name, char **args, char *ops, char func)
|
||||
{
|
||||
scanhashtable(thingytab, 1, 0, DISABLED, scanlistwidgets, ops['L']);
|
||||
if (!*args) {
|
||||
scanhashtable(thingytab, 1, 0, DISABLED, scanlistwidgets,
|
||||
(ops['a'] ? -1 : ops['L']));
|
||||
return 0;
|
||||
} else {
|
||||
int ret = 0;
|
||||
Thingy t;
|
||||
|
||||
for (; *args && !ret; args++) {
|
||||
if (!(t = (Thingy) thingytab->getnode2(thingytab, *args)) ||
|
||||
(!ops['a'] && (t->widget->flags & WIDGET_INT)))
|
||||
ret = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
bin_zle_refresh(char *name, char **args, char *ops, char func)
|
||||
{
|
||||
char *s = statusline;
|
||||
int sl = statusll;
|
||||
|
||||
if (*args) {
|
||||
statusline = *args;
|
||||
statusll = strlen(statusline);
|
||||
} else {
|
||||
statusline = NULL;
|
||||
statusll = 0;
|
||||
}
|
||||
zrefresh();
|
||||
|
||||
statusline = s;
|
||||
statusll = sl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -388,6 +419,10 @@ scanlistwidgets(HashNode hn, int list)
|
|||
Thingy t = (Thingy) hn;
|
||||
Widget w = t->widget;
|
||||
|
||||
if(list < 0) {
|
||||
printf("%s\n", hn->nam);
|
||||
return;
|
||||
}
|
||||
if(w->flags & WIDGET_INT)
|
||||
return;
|
||||
if(list) {
|
||||
|
|
@ -490,7 +525,8 @@ bin_zle_complete(char *name, char **args, char *ops, char func)
|
|||
return 1;
|
||||
}
|
||||
#endif
|
||||
t = rthingy(args[1]);
|
||||
|
||||
t = rthingy((args[1][0] == '.') ? args[1] : dyncat(".", args[1]));
|
||||
cw = t->widget;
|
||||
unrefthingy(t);
|
||||
if (!cw || !(cw->flags & ZLE_ISCOMP)) {
|
||||
|
|
@ -517,31 +553,64 @@ bin_zle_call(char *name, char **args, char *ops, char func)
|
|||
{
|
||||
Thingy t;
|
||||
struct modifier modsave;
|
||||
int ret, saveflag = 0;
|
||||
char *wname = *args++;
|
||||
|
||||
if(!zleactive || incompctlfunc || incompfunc) {
|
||||
zerrnam(name, "widgets can only be called when ZLE is active",
|
||||
NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (args[1]) {
|
||||
modsave = zmod;
|
||||
if (isdigit(*args[1])) {
|
||||
zmod.mult = atoi(args[1]);
|
||||
zmod.flags |= MOD_MULT;
|
||||
|
||||
if (!wname) {
|
||||
zwarnnam(name, "wrong number of arguments", NULL, 0);
|
||||
if (saveflag)
|
||||
zmod = modsave;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
while (*args && **args == '-') {
|
||||
char *num;
|
||||
if (!args[0][1] || args[0][1] == '-') {
|
||||
args++;
|
||||
break;
|
||||
}
|
||||
while (*++(*args)) {
|
||||
switch (**args) {
|
||||
case 'n':
|
||||
num = args[0][1] ? args[0]+1 : args[1];
|
||||
if (!num) {
|
||||
zwarnnam(name, "number expected after -%c", NULL, **args);
|
||||
return 1;
|
||||
}
|
||||
if (!args[0][1])
|
||||
args++;
|
||||
modsave = zmod;
|
||||
saveflag = 1;
|
||||
zmod.mult = atoi(num);
|
||||
zmod.flags |= MOD_MULT;
|
||||
break;
|
||||
case 'N':
|
||||
modsave = zmod;
|
||||
saveflag = 1;
|
||||
zmod.mult = 1;
|
||||
zmod.flags &= ~MOD_MULT;
|
||||
break;
|
||||
default:
|
||||
zwarnnam(name, "unknown option: %s", *args, 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
t = rthingy(args[0]);
|
||||
args++;
|
||||
}
|
||||
|
||||
t = rthingy(wname);
|
||||
PERMALLOC {
|
||||
execzlefunc(t);
|
||||
ret = execzlefunc(t, args);
|
||||
} LASTALLOC;
|
||||
unrefthingy(t);
|
||||
if (args[1])
|
||||
if (saveflag)
|
||||
zmod = modsave;
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************/
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -409,19 +409,11 @@ showmsg(char const *msg)
|
|||
/* handle the error flag */
|
||||
|
||||
/**/
|
||||
void
|
||||
feep(void)
|
||||
int
|
||||
handlefeep(char **args)
|
||||
{
|
||||
feepflag = 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
handlefeep(void)
|
||||
{
|
||||
if(feepflag)
|
||||
zbeep();
|
||||
feepflag = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************/
|
||||
|
|
@ -554,18 +546,17 @@ setlastline(void)
|
|||
/* move backwards through the change list */
|
||||
|
||||
/**/
|
||||
void
|
||||
undo(void)
|
||||
int
|
||||
undo(char **args)
|
||||
{
|
||||
handleundo();
|
||||
do {
|
||||
if(!curchange->prev) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if(!curchange->prev)
|
||||
return 1;
|
||||
unapplychange(curchange = curchange->prev);
|
||||
} while(curchange->flags & CH_PREV);
|
||||
setlastline();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
@ -592,19 +583,18 @@ unapplychange(struct change *ch)
|
|||
/* move forwards through the change list */
|
||||
|
||||
/**/
|
||||
void
|
||||
redo(void)
|
||||
int
|
||||
redo(char **args)
|
||||
{
|
||||
handleundo();
|
||||
do {
|
||||
if(!curchange->next) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if(!curchange->next)
|
||||
return 1;
|
||||
applychange(curchange);
|
||||
curchange = curchange->next;
|
||||
} while(curchange->prev->flags & CH_NEXT);
|
||||
setlastline();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
@ -631,8 +621,8 @@ applychange(struct change *ch)
|
|||
/* vi undo: toggle between the end of the undo list and the preceding point */
|
||||
|
||||
/**/
|
||||
void
|
||||
viundochange(void)
|
||||
int
|
||||
viundochange(char **args)
|
||||
{
|
||||
handleundo();
|
||||
if(curchange->next) {
|
||||
|
|
@ -641,6 +631,7 @@ viundochange(void)
|
|||
curchange = curchange->next;
|
||||
} while(curchange->next);
|
||||
setlastline();
|
||||
return 0;
|
||||
} else
|
||||
undo();
|
||||
return undo(args);
|
||||
}
|
||||
|
|
|
|||
371
Src/Zle/zle_vi.c
371
Src/Zle/zle_vi.c
|
|
@ -102,10 +102,8 @@ vigetkey(void)
|
|||
char m[3], *str;
|
||||
Thingy cmd;
|
||||
|
||||
if((c = getkey(0)) == EOF) {
|
||||
feep();
|
||||
if((c = getkey(0)) == EOF)
|
||||
return -1;
|
||||
}
|
||||
|
||||
m[0] = c;
|
||||
metafy(m, 1, META_NOALLOC);
|
||||
|
|
@ -115,13 +113,10 @@ vigetkey(void)
|
|||
cmd = t_undefinedkey;
|
||||
|
||||
if (!cmd || cmd == Th(z_sendbreak)) {
|
||||
feep();
|
||||
return -1;
|
||||
} else if (cmd == Th(z_quotedinsert)) {
|
||||
if ((c = getkey(0)) == EOF) {
|
||||
feep();
|
||||
if ((c = getkey(0)) == EOF)
|
||||
return -1;
|
||||
}
|
||||
} else if(cmd == Th(z_viquotedinsert)) {
|
||||
char sav = line[cs];
|
||||
|
||||
|
|
@ -129,10 +124,8 @@ vigetkey(void)
|
|||
zrefresh();
|
||||
c = getkey(0);
|
||||
line[cs] = sav;
|
||||
if(c == EOF) {
|
||||
feep();
|
||||
if(c == EOF)
|
||||
return -1;
|
||||
}
|
||||
} else if (cmd == Th(z_vicmdmode))
|
||||
return -1;
|
||||
return c;
|
||||
|
|
@ -142,7 +135,7 @@ vigetkey(void)
|
|||
static int
|
||||
getvirange(int wf)
|
||||
{
|
||||
int pos = cs;
|
||||
int pos = cs, ret = 0;
|
||||
int mult1 = zmult, hist1 = histline;
|
||||
Thingy k2;
|
||||
|
||||
|
|
@ -168,39 +161,37 @@ getvirange(int wf)
|
|||
k2 == Th(z_sendbreak)) {
|
||||
wordflag = 0;
|
||||
virangeflag = 0;
|
||||
feep();
|
||||
return -1;
|
||||
}
|
||||
if(k2 == bindk)
|
||||
/* The command key is repeated: a number of lines is used. */
|
||||
dovilinerange();
|
||||
else
|
||||
execzlefunc(k2);
|
||||
/*
|
||||
* With k2 == bindk, the command key is repeated:
|
||||
* a number of lines is used. If the function used
|
||||
* returns 1, we fail.
|
||||
*/
|
||||
if ((k2 == bindk) ? dovilinerange() : execzlefunc(k2, zlenoargs))
|
||||
ret = -1;
|
||||
if(vichgrepeat)
|
||||
zmult = mult1;
|
||||
else
|
||||
zmult = mult1 * zmod.tmult;
|
||||
} while(prefixflag);
|
||||
} while(prefixflag && !ret);
|
||||
wordflag = 0;
|
||||
virangeflag = 0;
|
||||
|
||||
/* It is an error to use a non-movement command to delimit the *
|
||||
* range. We here reject the case where the command modified *
|
||||
* the line, or selected a different history line. */
|
||||
if(histline != hist1 || ll != lastll || memcmp(line, lastline, ll)) {
|
||||
if (histline != hist1 || ll != lastll || memcmp(line, lastline, ll)) {
|
||||
histline = hist1;
|
||||
memcpy(line, lastline, ll = lastll);
|
||||
cs = pos;
|
||||
feep();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Can't handle an empty file. Also, if the movement command *
|
||||
* failed, or didn't move, it is an error. */
|
||||
if (!ll || (cs == pos && virangeflag != 2)) {
|
||||
feep();
|
||||
if (!ll || (cs == pos && virangeflag != 2) || ret == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* vi-match-bracket changes the value of virangeflag when *
|
||||
* moving to the opening bracket, meaning that we need to *
|
||||
|
|
@ -233,7 +224,7 @@ getvirange(int wf)
|
|||
}
|
||||
|
||||
/**/
|
||||
static void
|
||||
static int
|
||||
dovilinerange(void)
|
||||
{
|
||||
int pos = cs, n = zmult;
|
||||
|
|
@ -243,17 +234,14 @@ dovilinerange(void)
|
|||
* downward, otherwise upward. The repeat count gives the *
|
||||
* number of lines. */
|
||||
vilinerange = 1;
|
||||
if (!n) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (!n)
|
||||
return 1;
|
||||
if (n > 0) {
|
||||
while(n-- && cs <= ll)
|
||||
cs = findeol() + 1;
|
||||
if (n != -1) {
|
||||
cs = pos;
|
||||
feep();
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
cs--;
|
||||
} else {
|
||||
|
|
@ -261,123 +249,127 @@ dovilinerange(void)
|
|||
cs = findbol() - 1;
|
||||
if (n != 1) {
|
||||
cs = pos;
|
||||
feep();
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
cs++;
|
||||
}
|
||||
virangeflag = 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viaddnext(void)
|
||||
int
|
||||
viaddnext(char **args)
|
||||
{
|
||||
if (cs != findeol())
|
||||
cs++;
|
||||
startvitext(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viaddeol(void)
|
||||
int
|
||||
viaddeol(char **args)
|
||||
{
|
||||
cs = findeol();
|
||||
startvitext(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viinsert(void)
|
||||
int
|
||||
viinsert(char **args)
|
||||
{
|
||||
startvitext(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viinsertbol(void)
|
||||
int
|
||||
viinsertbol(char **args)
|
||||
{
|
||||
vifirstnonblank();
|
||||
vifirstnonblank(zlenoargs);
|
||||
startvitext(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
videlete(void)
|
||||
int
|
||||
videlete(char **args)
|
||||
{
|
||||
int c2;
|
||||
int c2, ret = 1;
|
||||
|
||||
startvichange(1);
|
||||
if ((c2 = getvirange(0)) != -1) {
|
||||
forekill(c2 - cs, 0);
|
||||
ret = 0;
|
||||
if (vilinerange && ll) {
|
||||
if (cs == ll)
|
||||
cs--;
|
||||
foredel(1);
|
||||
vifirstnonblank();
|
||||
vifirstnonblank(zlenoargs);
|
||||
}
|
||||
}
|
||||
vichgflag = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
videletechar(void)
|
||||
int
|
||||
videletechar(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
startvichange(-1);
|
||||
/* handle negative argument */
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
vibackwarddeletechar();
|
||||
ret = vibackwarddeletechar(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
/* it is an error to be on the end of line */
|
||||
if (cs == ll || line[cs] == '\n') {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (cs == ll || line[cs] == '\n')
|
||||
return 1;
|
||||
/* Put argument into the acceptable range -- it is not an error to *
|
||||
* specify a greater count than the number of available characters. */
|
||||
if (n > findeol() - cs)
|
||||
n = findeol() - cs;
|
||||
/* do the deletion */
|
||||
forekill(n, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vichange(void)
|
||||
int
|
||||
vichange(char **args)
|
||||
{
|
||||
int c2;
|
||||
int c2, ret = 1;
|
||||
|
||||
startvichange(1);
|
||||
if ((c2 = getvirange(1)) != -1) {
|
||||
ret = 0;
|
||||
forekill(c2 - cs, 0);
|
||||
selectkeymap("main", 1);
|
||||
viinsbegin = cs;
|
||||
undoing = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
visubstitute(void)
|
||||
int
|
||||
visubstitute(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
startvichange(1);
|
||||
if (n < 0) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (n < 0)
|
||||
return 1;
|
||||
/* it is an error to be on the end of line */
|
||||
if (cs == ll || line[cs] == '\n') {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (cs == ll || line[cs] == '\n')
|
||||
return 1;
|
||||
/* Put argument into the acceptable range -- it is not an error to *
|
||||
* specify a greater count than the number of available characters. */
|
||||
if (n > findeol() - cs)
|
||||
|
|
@ -385,79 +377,84 @@ visubstitute(void)
|
|||
/* do the substitution */
|
||||
forekill(n, 0);
|
||||
startvitext(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vichangeeol(void)
|
||||
int
|
||||
vichangeeol(char **args)
|
||||
{
|
||||
forekill(findeol() - cs, 0);
|
||||
startvitext(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vichangewholeline(void)
|
||||
int
|
||||
vichangewholeline(char **args)
|
||||
{
|
||||
vifirstnonblank();
|
||||
vichangeeol();
|
||||
vifirstnonblank(args);
|
||||
return vichangeeol(zlenoargs);
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viyank(void)
|
||||
int
|
||||
viyank(char **args)
|
||||
{
|
||||
int oldcs = cs, c2;
|
||||
int oldcs = cs, c2, ret = 1;
|
||||
|
||||
startvichange(1);
|
||||
if ((c2 = getvirange(0)) != -1)
|
||||
if ((c2 = getvirange(0)) != -1) {
|
||||
cut(cs, c2 - cs, 0);
|
||||
ret = 0;
|
||||
}
|
||||
vichgflag = 0;
|
||||
cs = oldcs;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viyankeol(void)
|
||||
int
|
||||
viyankeol(char **args)
|
||||
{
|
||||
int x = findeol();
|
||||
|
||||
startvichange(-1);
|
||||
if (x == cs) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (x == cs)
|
||||
return 1;
|
||||
cut(cs, x - cs, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viyankwholeline(void)
|
||||
int
|
||||
viyankwholeline(char **args)
|
||||
{
|
||||
int bol = findbol(), oldcs = cs;
|
||||
int n = zmult;
|
||||
|
||||
startvichange(-1);
|
||||
if (n < 1)
|
||||
return;
|
||||
return 1;
|
||||
while(n--) {
|
||||
if (cs > ll) {
|
||||
feep();
|
||||
cs = oldcs;
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
cs = findeol() + 1;
|
||||
}
|
||||
vilinerange = 1;
|
||||
cut(bol, cs - bol - 1, 0);
|
||||
cs = oldcs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vireplace(void)
|
||||
int
|
||||
vireplace(char **args)
|
||||
{
|
||||
startvitext(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vi-replace-chars has some oddities relating to vi-repeat-change. In *
|
||||
|
|
@ -474,32 +471,27 @@ vireplace(void)
|
|||
* without a rewrite of the repeat code. */
|
||||
|
||||
/**/
|
||||
void
|
||||
vireplacechars(void)
|
||||
int
|
||||
vireplacechars(char **args)
|
||||
{
|
||||
int ch, n = zmult;
|
||||
|
||||
startvichange(1);
|
||||
/* check argument range */
|
||||
if (n < 1 || n + cs > findeol()) {
|
||||
if(vichgrepeat) {
|
||||
int ofeep = feepflag;
|
||||
if(vichgrepeat)
|
||||
vigetkey();
|
||||
feepflag = ofeep;
|
||||
}
|
||||
if(vichgflag) {
|
||||
free(vichgbuf);
|
||||
vichgbuf = NULL;
|
||||
vichgflag = 0;
|
||||
}
|
||||
feep();
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
/* get key */
|
||||
if((ch = vigetkey()) == -1) {
|
||||
vichgflag = 0;
|
||||
feep();
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
/* do change */
|
||||
if (ch == '\r' || ch == '\n') {
|
||||
|
|
@ -513,47 +505,51 @@ vireplacechars(void)
|
|||
cs--;
|
||||
}
|
||||
vichgflag = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vicmdmode(void)
|
||||
int
|
||||
vicmdmode(char **args)
|
||||
{
|
||||
if (invicmdmode() || selectkeymap("vicmd", 0))
|
||||
feep();
|
||||
return 1;
|
||||
undoing = 1;
|
||||
vichgflag = 0;
|
||||
if (cs != findbol())
|
||||
cs--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viopenlinebelow(void)
|
||||
int
|
||||
viopenlinebelow(char **args)
|
||||
{
|
||||
cs = findeol();
|
||||
spaceinline(1);
|
||||
line[cs++] = '\n';
|
||||
startvitext(1);
|
||||
clearlist = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viopenlineabove(void)
|
||||
int
|
||||
viopenlineabove(char **args)
|
||||
{
|
||||
cs = findbol();
|
||||
spaceinline(1);
|
||||
line[cs] = '\n';
|
||||
startvitext(1);
|
||||
clearlist = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vioperswapcase(void)
|
||||
int
|
||||
vioperswapcase(char **args)
|
||||
{
|
||||
int oldcs, c2;
|
||||
int oldcs, c2, ret = 1;
|
||||
|
||||
/* get the range */
|
||||
startvichange(1);
|
||||
|
|
@ -569,22 +565,22 @@ vioperswapcase(void)
|
|||
}
|
||||
/* go back to the first line of the range */
|
||||
cs = oldcs;
|
||||
ret = 0;
|
||||
#if 0
|
||||
vifirstnonblank();
|
||||
#endif
|
||||
}
|
||||
vichgflag = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
virepeatchange(void)
|
||||
int
|
||||
virepeatchange(char **args)
|
||||
{
|
||||
/* make sure we have a change to repeat */
|
||||
if (!vichgbuf || vichgflag) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (!vichgbuf || vichgflag)
|
||||
return 1;
|
||||
/* restore or update the saved count and buffer */
|
||||
if (zmod.flags & MOD_MULT) {
|
||||
lastmod.mult = zmod.mult;
|
||||
|
|
@ -598,11 +594,12 @@ virepeatchange(void)
|
|||
/* repeat the command */
|
||||
inrepeat = 1;
|
||||
ungetkeys(vichgbuf, vichgbufptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viindent(void)
|
||||
int
|
||||
viindent(char **args)
|
||||
{
|
||||
int oldcs = cs, c2;
|
||||
|
||||
|
|
@ -610,14 +607,13 @@ viindent(void)
|
|||
startvichange(1);
|
||||
if ((c2 = getvirange(0)) == -1) {
|
||||
vichgflag = 0;
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
vichgflag = 0;
|
||||
/* must be a line range */
|
||||
if (!vilinerange) {
|
||||
feep();
|
||||
cs = oldcs;
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
oldcs = cs;
|
||||
/* add a tab to the beginning of each line within range */
|
||||
|
|
@ -628,12 +624,13 @@ viindent(void)
|
|||
}
|
||||
/* go back to the first line of the range */
|
||||
cs = oldcs;
|
||||
vifirstnonblank();
|
||||
vifirstnonblank(zlenoargs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viunindent(void)
|
||||
int
|
||||
viunindent(char **args)
|
||||
{
|
||||
int oldcs = cs, c2;
|
||||
|
||||
|
|
@ -641,14 +638,13 @@ viunindent(void)
|
|||
startvichange(1);
|
||||
if ((c2 = getvirange(0)) == -1) {
|
||||
vichgflag = 0;
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
vichgflag = 0;
|
||||
/* must be a line range */
|
||||
if (!vilinerange) {
|
||||
feep();
|
||||
cs = oldcs;
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
oldcs = cs;
|
||||
/* remove a tab from the beginning of each line within range */
|
||||
|
|
@ -659,12 +655,13 @@ viunindent(void)
|
|||
}
|
||||
/* go back to the first line of the range */
|
||||
cs = oldcs;
|
||||
vifirstnonblank();
|
||||
vifirstnonblank(zlenoargs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vibackwarddeletechar(void)
|
||||
int
|
||||
vibackwarddeletechar(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
|
|
@ -672,16 +669,16 @@ vibackwarddeletechar(void)
|
|||
startvichange(-1);
|
||||
/* handle negative argument */
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
videletechar();
|
||||
ret = videletechar(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
/* It is an error to be at the beginning of the line, or (in *
|
||||
* insert mode) to delete past the beginning of insertion. */
|
||||
if ((!invicmdmode() && cs - n < viinsbegin) || cs == findbol()) {
|
||||
feep();
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
/* Put argument into the acceptable range -- it is not an error to *
|
||||
* specify a greater count than the number of available characters. */
|
||||
|
|
@ -689,41 +686,39 @@ vibackwarddeletechar(void)
|
|||
n = cs - findbol();
|
||||
/* do the deletion */
|
||||
backkill(n, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vikillline(void)
|
||||
int
|
||||
vikillline(char **args)
|
||||
{
|
||||
if (viinsbegin > cs) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (viinsbegin > cs)
|
||||
return 1;
|
||||
backdel(cs - viinsbegin);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viputbefore(void)
|
||||
int
|
||||
viputbefore(char **args)
|
||||
{
|
||||
Cutbuffer buf = &cutbuf;
|
||||
int n = zmult;
|
||||
|
||||
startvichange(-1);
|
||||
if (n < 0)
|
||||
return;
|
||||
return 1;
|
||||
if (zmod.flags & MOD_VIBUF)
|
||||
buf = &vibuf[zmod.vibuf];
|
||||
if (!buf->buf) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (!buf->buf)
|
||||
return 1;
|
||||
if(buf->flags & CUTBUFFER_LINE) {
|
||||
cs = findbol();
|
||||
spaceinline(buf->len + 1);
|
||||
memcpy((char *)line + cs, buf->buf, buf->len);
|
||||
line[cs + buf->len] = '\n';
|
||||
vifirstnonblank();
|
||||
vifirstnonblank(zlenoargs);
|
||||
} else {
|
||||
while (n--) {
|
||||
spaceinline(buf->len);
|
||||
|
|
@ -733,30 +728,29 @@ viputbefore(void)
|
|||
if (cs)
|
||||
cs--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viputafter(void)
|
||||
int
|
||||
viputafter(char **args)
|
||||
{
|
||||
Cutbuffer buf = &cutbuf;
|
||||
int n = zmult;
|
||||
|
||||
startvichange(-1);
|
||||
if (n < 0)
|
||||
return;
|
||||
return 1;
|
||||
if (zmod.flags & MOD_VIBUF)
|
||||
buf = &vibuf[zmod.vibuf];
|
||||
if (!buf->buf) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (!buf->buf)
|
||||
return 1;
|
||||
if(buf->flags & CUTBUFFER_LINE) {
|
||||
cs = findeol();
|
||||
spaceinline(buf->len + 1);
|
||||
line[cs++] = '\n';
|
||||
memcpy((char *)line + cs, buf->buf, buf->len);
|
||||
vifirstnonblank();
|
||||
vifirstnonblank(zlenoargs);
|
||||
} else {
|
||||
if (cs != findeol())
|
||||
cs++;
|
||||
|
|
@ -768,20 +762,18 @@ viputafter(void)
|
|||
if (cs)
|
||||
cs--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vijoin(void)
|
||||
int
|
||||
vijoin(char **args)
|
||||
{
|
||||
int x;
|
||||
|
||||
startvichange(-1);
|
||||
if ((x = findeol()) == ll) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if ((x = findeol()) == ll)
|
||||
return 1;
|
||||
cs = x + 1;
|
||||
for (x = 1; cs != ll && iblank(line[cs]); cs++, x++);
|
||||
backdel(x);
|
||||
|
|
@ -791,17 +783,18 @@ vijoin(void)
|
|||
spaceinline(1);
|
||||
line[cs] = ' ';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viswapcase(void)
|
||||
int
|
||||
viswapcase(char **args)
|
||||
{
|
||||
int eol, n = zmult;
|
||||
|
||||
startvichange(-1);
|
||||
if (n < 1)
|
||||
return;
|
||||
return 1;
|
||||
eol = findeol();
|
||||
while (cs < eol && n--) {
|
||||
if (islower(line[cs]))
|
||||
|
|
@ -812,11 +805,12 @@ viswapcase(void)
|
|||
}
|
||||
if (cs && cs == eol)
|
||||
cs--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vicapslockpanic(void)
|
||||
int
|
||||
vicapslockpanic(char **args)
|
||||
{
|
||||
clearlist = 1;
|
||||
zbeep();
|
||||
|
|
@ -825,20 +819,19 @@ vicapslockpanic(void)
|
|||
zrefresh();
|
||||
while (!islower(getkey(0)));
|
||||
statusline = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
visetbuffer(void)
|
||||
int
|
||||
visetbuffer(char **args)
|
||||
{
|
||||
int ch;
|
||||
|
||||
if ((zmod.flags & MOD_VIBUF) ||
|
||||
(((ch = getkey(0)) < '1' || ch > '9') &&
|
||||
(ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z'))) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
(ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z')))
|
||||
return 1;
|
||||
if (ch >= 'A' && ch <= 'Z') /* needed in cut() */
|
||||
zmod.flags |= MOD_VIAPP;
|
||||
else
|
||||
|
|
@ -846,32 +839,33 @@ visetbuffer(void)
|
|||
zmod.vibuf = tulower(ch) + (idigit(ch) ? -'1' + 26 : -'a');
|
||||
zmod.flags |= MOD_VIBUF;
|
||||
prefixflag = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vikilleol(void)
|
||||
int
|
||||
vikilleol(char **args)
|
||||
{
|
||||
int n = findeol() - cs;
|
||||
|
||||
startvichange(-1);
|
||||
if (!n) {
|
||||
/* error -- line already empty */
|
||||
feep();
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
/* delete to end of line */
|
||||
forekill(findeol() - cs, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vipoundinsert(void)
|
||||
int
|
||||
vipoundinsert(char **args)
|
||||
{
|
||||
int oldcs = cs;
|
||||
|
||||
startvichange(-1);
|
||||
vifirstnonblank();
|
||||
vifirstnonblank(zlenoargs);
|
||||
if(line[cs] != '#') {
|
||||
spaceinline(1);
|
||||
line[cs] = '#';
|
||||
|
|
@ -884,11 +878,12 @@ vipoundinsert(void)
|
|||
viinsbegin--;
|
||||
cs = oldcs - (cs < oldcs);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viquotedinsert(void)
|
||||
int
|
||||
viquotedinsert(char **args)
|
||||
{
|
||||
#ifndef HAS_TIO
|
||||
struct sgttyb sob;
|
||||
|
|
@ -908,23 +903,23 @@ viquotedinsert(void)
|
|||
#endif
|
||||
foredel(1);
|
||||
if(c < 0)
|
||||
feep();
|
||||
return 1;
|
||||
else
|
||||
selfinsert();
|
||||
return selfinsert(args);
|
||||
}
|
||||
|
||||
/* the 0 key in vi: continue a repeat count in the manner of *
|
||||
* digit-argument if possible, otherwise do vi-beginning-of-line. */
|
||||
|
||||
/**/
|
||||
void
|
||||
vidigitorbeginningofline(void)
|
||||
int
|
||||
vidigitorbeginningofline(char **args)
|
||||
{
|
||||
if(zmod.flags & MOD_TMULT)
|
||||
digitargument();
|
||||
return digitargument(args);
|
||||
else {
|
||||
removesuffix();
|
||||
invalidatelist();
|
||||
vibeginningofline();
|
||||
return vibeginningofline(args);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,38 +31,41 @@
|
|||
#include "zle_word.pro"
|
||||
|
||||
/**/
|
||||
void
|
||||
forwardword(void)
|
||||
int
|
||||
forwardword(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
backwardword();
|
||||
ret = backwardword(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
while (cs != ll && iword(line[cs]))
|
||||
cs++;
|
||||
if (wordflag && !n)
|
||||
return;
|
||||
return 0;
|
||||
while (cs != ll && !iword(line[cs]))
|
||||
cs++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viforwardword(void)
|
||||
int
|
||||
viforwardword(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
backwardword();
|
||||
ret = backwardword(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
if (iident(line[cs]))
|
||||
|
|
@ -72,64 +75,69 @@ viforwardword(void)
|
|||
while (cs != ll && !iident(line[cs]) && !iblank(line[cs]))
|
||||
cs++;
|
||||
if (wordflag && !n)
|
||||
return;
|
||||
return 0;
|
||||
while (cs != ll && (iblank(line[cs]) || line[cs] == '\n'))
|
||||
cs++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viforwardblankword(void)
|
||||
int
|
||||
viforwardblankword(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
vibackwardblankword();
|
||||
ret = vibackwardblankword(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
while (cs != ll && !iblank(line[cs]))
|
||||
cs++;
|
||||
if (wordflag && !n)
|
||||
return;
|
||||
return 0;
|
||||
while (cs != ll && iblank(line[cs]))
|
||||
cs++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
emacsforwardword(void)
|
||||
int
|
||||
emacsforwardword(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
emacsbackwardword();
|
||||
ret = emacsbackwardword(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
while (cs != ll && !iword(line[cs]))
|
||||
cs++;
|
||||
if (wordflag && !n)
|
||||
return;
|
||||
return 0;
|
||||
while (cs != ll && iword(line[cs]))
|
||||
cs++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viforwardblankwordend(void)
|
||||
int
|
||||
viforwardblankwordend(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0)
|
||||
return;
|
||||
return 1;
|
||||
while (n--) {
|
||||
while (cs != ll && iblank(line[cs + 1]))
|
||||
cs++;
|
||||
|
|
@ -138,19 +146,21 @@ viforwardblankwordend(void)
|
|||
}
|
||||
if (cs != ll && virangeflag)
|
||||
cs++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
viforwardwordend(void)
|
||||
int
|
||||
viforwardwordend(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
backwardword();
|
||||
ret = backwardword(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
if (iblank(line[cs + 1]))
|
||||
|
|
@ -165,19 +175,21 @@ viforwardwordend(void)
|
|||
}
|
||||
if (cs != ll && virangeflag)
|
||||
cs++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
backwardword(void)
|
||||
int
|
||||
backwardword(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
forwardword();
|
||||
ret = forwardword(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
while (cs && !iword(line[cs - 1]))
|
||||
|
|
@ -185,19 +197,21 @@ backwardword(void)
|
|||
while (cs && iword(line[cs - 1]))
|
||||
cs--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vibackwardword(void)
|
||||
int
|
||||
vibackwardword(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
backwardword();
|
||||
ret = backwardword(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
while (cs && iblank(line[cs - 1]))
|
||||
|
|
@ -209,19 +223,21 @@ vibackwardword(void)
|
|||
while (cs && !iident(line[cs - 1]) && !iblank(line[cs - 1]))
|
||||
cs--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vibackwardblankword(void)
|
||||
int
|
||||
vibackwardblankword(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
viforwardblankword();
|
||||
ret = viforwardblankword(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
while (cs && iblank(line[cs - 1]))
|
||||
|
|
@ -229,19 +245,21 @@ vibackwardblankword(void)
|
|||
while (cs && !iblank(line[cs - 1]))
|
||||
cs--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
emacsbackwardword(void)
|
||||
int
|
||||
emacsbackwardword(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
emacsforwardword();
|
||||
ret = emacsforwardword(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
while (cs && !iword(line[cs - 1]))
|
||||
|
|
@ -249,19 +267,21 @@ emacsbackwardword(void)
|
|||
while (cs && iword(line[cs - 1]))
|
||||
cs--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
backwarddeleteword(void)
|
||||
int
|
||||
backwarddeleteword(char **args)
|
||||
{
|
||||
int x = cs, n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
deleteword();
|
||||
ret = deleteword(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
while (x && !iword(line[x - 1]))
|
||||
|
|
@ -270,19 +290,18 @@ backwarddeleteword(void)
|
|||
x--;
|
||||
}
|
||||
backdel(cs - x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
vibackwardkillword(void)
|
||||
int
|
||||
vibackwardkillword(char **args)
|
||||
{
|
||||
int x = cs, lim = (viinsbegin > findbol()) ? viinsbegin : findbol();
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (n < 0)
|
||||
return 1;
|
||||
/* this taken from "vibackwardword" */
|
||||
while (n--) {
|
||||
while ((x > lim) && iblank(line[x - 1]))
|
||||
|
|
@ -295,20 +314,22 @@ vibackwardkillword(void)
|
|||
x--;
|
||||
}
|
||||
backkill(cs - x, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
backwardkillword(void)
|
||||
int
|
||||
backwardkillword(char **args)
|
||||
{
|
||||
int x = cs;
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
killword();
|
||||
ret = killword(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
while (x && !iword(line[x - 1]))
|
||||
|
|
@ -317,11 +338,12 @@ backwardkillword(void)
|
|||
x--;
|
||||
}
|
||||
backkill(cs - x, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
upcaseword(void)
|
||||
int
|
||||
upcaseword(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
int neg = n < 0, ocs = cs;
|
||||
|
|
@ -338,11 +360,12 @@ upcaseword(void)
|
|||
}
|
||||
if (neg)
|
||||
cs = ocs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
downcaseword(void)
|
||||
int
|
||||
downcaseword(char **args)
|
||||
{
|
||||
int n = zmult;
|
||||
int neg = n < 0, ocs = cs;
|
||||
|
|
@ -359,11 +382,12 @@ downcaseword(void)
|
|||
}
|
||||
if (neg)
|
||||
cs = ocs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
capitalizeword(void)
|
||||
int
|
||||
capitalizeword(char **args)
|
||||
{
|
||||
int first, n = zmult;
|
||||
int neg = n < 0, ocs = cs;
|
||||
|
|
@ -384,20 +408,22 @@ capitalizeword(void)
|
|||
}
|
||||
if (neg)
|
||||
cs = ocs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
deleteword(void)
|
||||
int
|
||||
deleteword(char **args)
|
||||
{
|
||||
int x = cs;
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
backwarddeleteword();
|
||||
ret = backwarddeleteword(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
while (x != ll && !iword(line[x]))
|
||||
|
|
@ -406,20 +432,22 @@ deleteword(void)
|
|||
x++;
|
||||
}
|
||||
foredel(x - cs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
killword(void)
|
||||
int
|
||||
killword(char **args)
|
||||
{
|
||||
int x = cs;
|
||||
int n = zmult;
|
||||
|
||||
if (n < 0) {
|
||||
int ret;
|
||||
zmult = -n;
|
||||
backwardkillword();
|
||||
ret = backwardkillword(args);
|
||||
zmult = n;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
while (n--) {
|
||||
while (x != ll && !iword(line[x]))
|
||||
|
|
@ -428,11 +456,12 @@ killword(void)
|
|||
x++;
|
||||
}
|
||||
forekill(x - cs, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
transposewords(void)
|
||||
int
|
||||
transposewords(char **args)
|
||||
{
|
||||
int p1, p2, p3, p4, x = cs;
|
||||
char *temp, *pp;
|
||||
|
|
@ -448,22 +477,16 @@ transposewords(void)
|
|||
x = cs;
|
||||
while (x && line[x - 1] != '\n' && !iword(line[x]))
|
||||
x--;
|
||||
if (!x || line[x - 1] == '\n') {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (!x || line[x - 1] == '\n')
|
||||
return 1;
|
||||
}
|
||||
for (p4 = x; p4 != ll && iword(line[p4]); p4++);
|
||||
for (p3 = p4; p3 && iword(line[p3 - 1]); p3--);
|
||||
if (!p3) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (!p3)
|
||||
return 1;
|
||||
for (p2 = p3; p2 && !iword(line[p2 - 1]); p2--);
|
||||
if (!p2) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (!p2)
|
||||
return 1;
|
||||
for (p1 = p2; p1 && iword(line[p1 - 1]); p1--);
|
||||
pp = temp = (char *)zhalloc(p4 - p1 + 1);
|
||||
struncpy(&pp, (char *) line + p3, p4 - p3);
|
||||
|
|
@ -474,4 +497,5 @@ transposewords(void)
|
|||
}
|
||||
if (neg)
|
||||
cs = ocs;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ static struct builtin builtins[] =
|
|||
BUILTIN("cd", 0, bin_cd, 0, 2, BIN_CD, NULL, NULL),
|
||||
BUILTIN("chdir", 0, bin_cd, 0, 2, BIN_CD, NULL, NULL),
|
||||
BUILTIN("continue", BINF_PSPECIAL, bin_break, 0, 1, BIN_CONTINUE, NULL, NULL),
|
||||
BUILTIN("declare", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "ALRTUZafilrtux", NULL),
|
||||
BUILTIN("declare", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "ALRTUZafgilrtux", NULL),
|
||||
BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "v", NULL),
|
||||
BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmr", NULL),
|
||||
BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL),
|
||||
|
|
@ -60,7 +60,7 @@ static struct builtin builtins[] =
|
|||
BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmr", NULL),
|
||||
BUILTIN("eval", BINF_PSPECIAL, bin_eval, 0, -1, BIN_EVAL, NULL, NULL),
|
||||
BUILTIN("exit", BINF_PSPECIAL, bin_break, 0, 1, BIN_EXIT, NULL, NULL),
|
||||
BUILTIN("export", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, BIN_EXPORT, "LRTUZafilrtu", "x"),
|
||||
BUILTIN("export", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, BIN_EXPORT, "LRTUZafilrtu", "xg"),
|
||||
BUILTIN("false", 0, bin_false, 0, -1, 0, NULL, NULL),
|
||||
BUILTIN("fc", BINF_FCOPTS, bin_fc, 0, -1, BIN_FC, "nlreIRWAdDfEim", NULL),
|
||||
BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL),
|
||||
|
|
@ -74,7 +74,7 @@ static struct builtin builtins[] =
|
|||
#endif
|
||||
|
||||
BUILTIN("history", 0, bin_fc, 0, -1, BIN_FC, "nrdDfEim", "l"),
|
||||
BUILTIN("integer", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "lrtux", "i"),
|
||||
BUILTIN("integer", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "glrtux", "i"),
|
||||
BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL),
|
||||
BUILTIN("kill", 0, bin_kill, 0, -1, 0, NULL, NULL),
|
||||
BUILTIN("let", 0, bin_let, 1, -1, 0, NULL, NULL),
|
||||
|
|
@ -93,7 +93,7 @@ static struct builtin builtins[] =
|
|||
BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
|
||||
BUILTIN("r", BINF_R, bin_fc, 0, -1, BIN_FC, "nrl", NULL),
|
||||
BUILTIN("read", 0, bin_read, 0, -1, 0, "rzu0123456789pkqecnAlE", NULL),
|
||||
BUILTIN("readonly", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "ALRTUZafiltux", "r"),
|
||||
BUILTIN("readonly", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "ALRTUZafgiltux", "r"),
|
||||
BUILTIN("rehash", 0, bin_hash, 0, 0, 0, "dfv", "r"),
|
||||
BUILTIN("return", BINF_PSPECIAL, bin_break, 0, 1, BIN_RETURN, NULL, NULL),
|
||||
BUILTIN("set", BINF_PSPECIAL, bin_set, 0, -1, 0, NULL, NULL),
|
||||
|
|
@ -107,7 +107,7 @@ static struct builtin builtins[] =
|
|||
BUILTIN("trap", BINF_PSPECIAL, bin_trap, 0, -1, 0, NULL, NULL),
|
||||
BUILTIN("true", 0, bin_true, 0, -1, 0, NULL, NULL),
|
||||
BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsw", "v"),
|
||||
BUILTIN("typeset", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "ALRTUZafilrtuxm", NULL),
|
||||
BUILTIN("typeset", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "ALRTUZafgilrtuxm", NULL),
|
||||
BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL),
|
||||
BUILTIN("unalias", 0, bin_unhash, 1, -1, 0, "m", "a"),
|
||||
BUILTIN("unfunction", 0, bin_unhash, 1, -1, 0, "m", "f"),
|
||||
|
|
@ -120,7 +120,9 @@ static struct builtin builtins[] =
|
|||
BUILTIN("which", 0, bin_whence, 0, -1, 0, "ampsw", "c"),
|
||||
|
||||
#ifdef DYNAMIC
|
||||
BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "ILabcdipu", NULL),
|
||||
BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "ILabcdipue", NULL),
|
||||
#else
|
||||
BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "e", NULL),
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -351,7 +353,8 @@ execbuiltin(LinkList args, Builtin bn)
|
|||
|
||||
/* display execution trace information, if required */
|
||||
if (xtr) {
|
||||
fprintf(stderr, "%s%s", (prompt4) ? prompt4 : "", name);
|
||||
printprompt4();
|
||||
fprintf(stderr, "%s", name);
|
||||
if (xarg)
|
||||
fprintf(stderr, " %s", xarg);
|
||||
while (*oargv)
|
||||
|
|
@ -1349,7 +1352,7 @@ fclist(FILE *f, int n, int r, int D, int d, int first, int last, struct asgment
|
|||
fclistdone = 1;
|
||||
|
||||
ent = gethistent(first, first < last? GETHIST_DOWNWARD : GETHIST_UPWARD);
|
||||
if (!ent || ent->histnum < first || ent->histnum > last) {
|
||||
if (!ent || (first < last? ent->histnum > last : ent->histnum < last)) {
|
||||
if (first == last)
|
||||
zwarnnam("fc", "no such event: %d", NULL, first);
|
||||
else
|
||||
|
|
@ -1491,8 +1494,14 @@ typeset_single(char *cname, char *pname, Param pm, int func,
|
|||
{
|
||||
int usepm, tc, keeplocal = 0;
|
||||
|
||||
/* use the existing pm? */
|
||||
usepm = pm && !(pm->flags & (PM_UNSET | PM_AUTOLOAD));
|
||||
/*
|
||||
* Do we use the existing pm? Note that this isn't the end of the
|
||||
* story, because if we try and create a new pm at the same
|
||||
* locallevel as an unset one we use the pm struct anyway: that's
|
||||
* handled in createparam(). Here we just avoid using it for the
|
||||
* present tests if it's unset.
|
||||
*/
|
||||
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)
|
||||
|
|
@ -1501,15 +1510,15 @@ typeset_single(char *cname, char *pname, Param pm, int func,
|
|||
/*
|
||||
* Don't use a non-special existing param if
|
||||
* - the local level has changed, and
|
||||
* - the function is not `export'.
|
||||
* - we are really locallizing the parameter
|
||||
*/
|
||||
if (usepm && !(pm->flags & PM_SPECIAL) &&
|
||||
locallevel != pm->level && func != BIN_EXPORT)
|
||||
locallevel != pm->level && (on & PM_LOCAL))
|
||||
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_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",
|
||||
|
|
@ -1518,6 +1527,7 @@ typeset_single(char *cname, char *pname, Param pm, int func,
|
|||
}
|
||||
|
||||
if (usepm) {
|
||||
on &= ~PM_LOCAL;
|
||||
if (!on && !roff && !value) {
|
||||
paramtab->printnode((HashNode)pm, 0);
|
||||
return pm;
|
||||
|
|
@ -1604,7 +1614,7 @@ typeset_single(char *cname, char *pname, Param pm, int func,
|
|||
|
||||
if (keeplocal)
|
||||
pm->level = keeplocal;
|
||||
else if (func != BIN_EXPORT)
|
||||
else if (on & PM_LOCAL)
|
||||
pm->level = locallevel;
|
||||
if (value && !(pm->flags & (PM_ARRAY|PM_HASHED)))
|
||||
setsparam(pname, ztrdup(value));
|
||||
|
|
@ -1677,6 +1687,9 @@ bin_typeset(char *name, char **argv, char *ops, int func)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!ops['g'])
|
||||
on |= PM_LOCAL;
|
||||
|
||||
if (on & PM_TIED) {
|
||||
Param apm;
|
||||
struct asgment asg0;
|
||||
|
|
@ -3073,7 +3086,7 @@ bin_emulate(char *nam, char **argv, char *ops, int func)
|
|||
{
|
||||
emulate(*argv, ops['R']);
|
||||
if (ops['L'])
|
||||
dosetopt(LOCALOPTIONS, 1, 0);
|
||||
opts[LOCALOPTIONS] = opts[LOCALTRAPS] = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3121,7 +3134,7 @@ bin_read(char *name, char **args, char *ops, int func)
|
|||
char *reply, *readpmpt;
|
||||
int bsiz, c = 0, gotnl = 0, al = 0, first, nchars = 1, bslash;
|
||||
int haso = 0; /* true if /dev/tty has been opened specially */
|
||||
int isem = !strcmp(term, "emacs");
|
||||
int isem = !strcmp(term, "emacs"), izle = zleactive && getkeyptr;
|
||||
char *buf, *bptr, *firstarg, *zbuforig;
|
||||
LinkList readll = newlinklist();
|
||||
|
||||
|
|
@ -3146,6 +3159,7 @@ bin_read(char *name, char **args, char *ops, int func)
|
|||
return compctlread(name, args, ops, reply);
|
||||
|
||||
if ((ops['k'] && !ops['u'] && !ops['p']) || ops['q']) {
|
||||
if (!zleactive) {
|
||||
if (SHTTY == -1) {
|
||||
/* need to open /dev/tty specially */
|
||||
SHTTY = open("/dev/tty", O_RDWR|O_NOCTTY);
|
||||
|
|
@ -3165,14 +3179,17 @@ bin_read(char *name, char **args, char *ops, int func)
|
|||
if (!isem && ops['k'])
|
||||
setcbreak();
|
||||
readfd = SHTTY;
|
||||
}
|
||||
} else if (ops['u'] && !ops['p']) {
|
||||
/* -u means take input from the specified file descriptor. *
|
||||
* -up means take input from the coprocess. */
|
||||
for (readfd = 9; readfd && !ops[readfd + '0']; --readfd);
|
||||
} else if (ops['p'])
|
||||
izle = 0;
|
||||
} else if (ops['p']) {
|
||||
readfd = coprocin;
|
||||
else
|
||||
readfd = 0;
|
||||
izle = 0;
|
||||
} else
|
||||
readfd = izle = 0;
|
||||
|
||||
/* handle prompt */
|
||||
if (firstarg) {
|
||||
|
|
@ -3196,6 +3213,12 @@ bin_read(char *name, char **args, char *ops, int func)
|
|||
bptr = buf = (char *)zalloc(nchars+1);
|
||||
|
||||
do {
|
||||
if (izle) {
|
||||
if ((val = getkeyptr(0)) < 0)
|
||||
break;
|
||||
*bptr++ = (char) val;
|
||||
nchars--;
|
||||
} else {
|
||||
/* If read returns 0, is end of file */
|
||||
if ((val = read(readfd, bptr, nchars)) <= 0)
|
||||
break;
|
||||
|
|
@ -3205,9 +3228,10 @@ bin_read(char *name, char **args, char *ops, int func)
|
|||
|
||||
/* increment pointer past read characters */
|
||||
bptr += val;
|
||||
}
|
||||
} while (nchars > 0);
|
||||
|
||||
if (!ops['u'] && !ops['p']) {
|
||||
if (!izle && !ops['u'] && !ops['p']) {
|
||||
/* dispose of result appropriately, etc. */
|
||||
if (isem)
|
||||
while (val > 0 && read(SHTTY, &d, 1) == 1 && d != '\n');
|
||||
|
|
@ -3236,6 +3260,11 @@ bin_read(char *name, char **args, char *ops, int func)
|
|||
readbuf[1] = '\0';
|
||||
|
||||
/* get, and store, reply */
|
||||
if (izle) {
|
||||
int key = getkeyptr(0);
|
||||
|
||||
readbuf[0] = (key == 'y' ? 'y' : 'n');
|
||||
} else {
|
||||
readbuf[0] = ((char)getquery(NULL, 0)) == 'y' ? 'y' : 'n';
|
||||
|
||||
/* dispose of result appropriately, etc. */
|
||||
|
|
@ -3243,7 +3272,7 @@ bin_read(char *name, char **args, char *ops, int func)
|
|||
close(SHTTY);
|
||||
SHTTY = -1;
|
||||
}
|
||||
|
||||
}
|
||||
if (ops['e'] || ops['E'])
|
||||
printf("%s\n", readbuf);
|
||||
if (!ops['e'])
|
||||
|
|
@ -3265,7 +3294,7 @@ bin_read(char *name, char **args, char *ops, int func)
|
|||
buf = bptr = (char *)zalloc(bsiz = 64);
|
||||
/* get input, a character at a time */
|
||||
while (!gotnl) {
|
||||
c = zread();
|
||||
c = zread(izle);
|
||||
/* \ at the end of a line indicates a continuation *
|
||||
* line, except in raw mode (-r option) */
|
||||
if (bslash && c == '\n') {
|
||||
|
|
@ -3355,7 +3384,7 @@ bin_read(char *name, char **args, char *ops, int func)
|
|||
bslash = 0;
|
||||
if (!gotnl)
|
||||
for (;;) {
|
||||
c = zread();
|
||||
c = zread(izle);
|
||||
/* \ at the end of a line introduces a continuation line, except in
|
||||
raw mode (-r option) */
|
||||
if (bslash && c == '\n') {
|
||||
|
|
@ -3419,10 +3448,15 @@ bin_read(char *name, char **args, char *ops, int func)
|
|||
|
||||
/**/
|
||||
static int
|
||||
zread(void)
|
||||
zread(int izle)
|
||||
{
|
||||
char cc, retry = 0;
|
||||
|
||||
if (izle) {
|
||||
int c = getkeyptr(0);
|
||||
|
||||
return (c < 0 ? EOF : c);
|
||||
}
|
||||
/* use zbuf if possible */
|
||||
if (zbuf) {
|
||||
/* If zbuf points to anything, it points to the next character in the
|
||||
|
|
@ -3618,7 +3652,7 @@ bin_trap(char *name, char **argv, char *ops, int func)
|
|||
arg = *argv++;
|
||||
if (!*arg)
|
||||
l = NULL;
|
||||
else if (!(l = parse_string(arg))) {
|
||||
else if (!(l = parse_string(arg, 0))) {
|
||||
zwarnnam(name, "couldn't parse trap command", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
140
Src/exec.c
140
Src/exec.c
|
|
@ -133,14 +133,17 @@ static int doneps4;
|
|||
|
||||
/**/
|
||||
List
|
||||
parse_string(char *s)
|
||||
parse_string(char *s, int ln)
|
||||
{
|
||||
List l;
|
||||
int oldlineno = lineno;
|
||||
|
||||
lexsave();
|
||||
inpush(s, 0, NULL);
|
||||
inpush(s, (ln ? INP_LINENO : 0), NULL);
|
||||
strinbeg(0);
|
||||
lineno = ln ? 1 : -1;
|
||||
l = parse_list();
|
||||
lineno = oldlineno;
|
||||
strinend();
|
||||
inpop();
|
||||
lexrestore();
|
||||
|
|
@ -301,7 +304,9 @@ execcursh(Cmd cmd, LinkList args, int flags)
|
|||
{
|
||||
if (!list_pipe)
|
||||
deletejob(jobtab + thisjob);
|
||||
cmdpush(CS_CURSH);
|
||||
execlist(cmd->u.list, 1, flags & CFLAG_EXEC);
|
||||
cmdpop();
|
||||
|
||||
return lastval;
|
||||
}
|
||||
|
|
@ -354,7 +359,9 @@ zexecve(char *pth, char **argv)
|
|||
if (execvebuf[1] == '!') {
|
||||
for (t0 = 0; t0 != ct; t0++)
|
||||
if (execvebuf[t0] == '\n')
|
||||
execvebuf[t0] = '\0';
|
||||
break;
|
||||
while (inblank(execvebuf[t0]))
|
||||
execvebuf[t0--] = '\0';
|
||||
execvebuf[POUNDBANGLIMIT] = '\0';
|
||||
for (ptr = execvebuf + 2; *ptr && *ptr == ' '; ptr++);
|
||||
for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++);
|
||||
|
|
@ -676,7 +683,7 @@ execstring(char *s, int dont_change_job, int exiting)
|
|||
List list;
|
||||
|
||||
pushheap();
|
||||
if ((list = parse_string(s)))
|
||||
if ((list = parse_string(s, 0)))
|
||||
execlist(list, dont_change_job, exiting);
|
||||
popheap();
|
||||
}
|
||||
|
|
@ -694,8 +701,8 @@ execlist(List list, int dont_change_job, int exiting)
|
|||
{
|
||||
Sublist slist;
|
||||
static int donetrap;
|
||||
int ret, cj;
|
||||
int old_pline_level, old_list_pipe;
|
||||
int ret, cj, csp;
|
||||
int old_pline_level, old_list_pipe, oldlineno;
|
||||
/*
|
||||
* ERREXIT only forces the shell to exit if the last command in a &&
|
||||
* or || fails. This is the case even if an earlier command is a
|
||||
|
|
@ -707,6 +714,7 @@ execlist(List list, int dont_change_job, int exiting)
|
|||
cj = thisjob;
|
||||
old_pline_level = pline_level;
|
||||
old_list_pipe = list_pipe;
|
||||
oldlineno = lineno;
|
||||
|
||||
if (sourcelevel && unset(SHINSTDIN))
|
||||
pline_level = list_pipe = 0;
|
||||
|
|
@ -718,6 +726,7 @@ execlist(List list, int dont_change_job, int exiting)
|
|||
* called once for each sublist that fails. */
|
||||
donetrap = 0;
|
||||
slist = list->left;
|
||||
csp = cmdsp;
|
||||
|
||||
/* Loop through code followed by &&, ||, or end of sublist. */
|
||||
while (slist) {
|
||||
|
|
@ -744,6 +753,7 @@ execlist(List list, int dont_change_job, int exiting)
|
|||
goto sublist_done;
|
||||
}
|
||||
}
|
||||
cmdpush(CS_CMDAND);
|
||||
break;
|
||||
case ORNEXT:
|
||||
/* If the return code is zero, we skip pipelines until *
|
||||
|
|
@ -760,12 +770,14 @@ execlist(List list, int dont_change_job, int exiting)
|
|||
goto sublist_done;
|
||||
}
|
||||
}
|
||||
cmdpush(CS_CMDOR);
|
||||
break;
|
||||
}
|
||||
slist = slist->right;
|
||||
}
|
||||
sublist_done:
|
||||
|
||||
cmdsp = csp;
|
||||
noerrexit = oldnoerrexit;
|
||||
|
||||
if (sigtrapped[SIGDEBUG])
|
||||
|
|
@ -794,6 +806,7 @@ sublist_done:
|
|||
|
||||
pline_level = old_pline_level;
|
||||
list_pipe = old_list_pipe;
|
||||
lineno = oldlineno;
|
||||
if (dont_change_job)
|
||||
thisjob = cj;
|
||||
}
|
||||
|
|
@ -888,6 +901,9 @@ execpline(Sublist l, int how, int last1)
|
|||
DPUTS(!list_pipe_pid, "invalid list_pipe_pid");
|
||||
addproc(list_pipe_pid, list_pipe_text);
|
||||
|
||||
if (!jn->procs->next)
|
||||
jn->gleader = mypgrp;
|
||||
|
||||
for (pn = jobtab[jn->other].procs; pn; pn = pn->next)
|
||||
if (WIFSTOPPED(pn->status))
|
||||
break;
|
||||
|
|
@ -901,12 +917,14 @@ execpline(Sublist l, int how, int last1)
|
|||
jn->stat |= STAT_STOPPED | STAT_CHANGED;
|
||||
printjob(jn, !!isset(LONGLISTJOBS), 1);
|
||||
}
|
||||
else
|
||||
else if (newjob != list_pipe_job)
|
||||
deletejob(jn);
|
||||
else
|
||||
lastwj = -1;
|
||||
}
|
||||
|
||||
for (; !nowait;) {
|
||||
if (list_pipe_child) {
|
||||
if (list_pipe_child || pline_level) {
|
||||
jn->stat |= STAT_NOPRINT;
|
||||
makerunning(jn);
|
||||
}
|
||||
|
|
@ -917,8 +935,11 @@ execpline(Sublist l, int how, int last1)
|
|||
jn->stat & STAT_DONE &&
|
||||
lastval2 & 0200)
|
||||
killpg(mypgrp, lastval2 & ~0200);
|
||||
if ((list_pipe || last1) && !list_pipe_child &&
|
||||
jn->stat & STAT_STOPPED) {
|
||||
if ((list_pipe || last1 || pline_level) &&
|
||||
!list_pipe_child &&
|
||||
((jn->stat & STAT_STOPPED) ||
|
||||
(list_pipe_job && pline_level &&
|
||||
(jobtab[list_pipe_job].stat & STAT_STOPPED)))) {
|
||||
pid_t pid;
|
||||
int synch[2];
|
||||
|
||||
|
|
@ -944,21 +965,28 @@ execpline(Sublist l, int how, int last1)
|
|||
close(synch[1]);
|
||||
read(synch[0], &dummy, 1);
|
||||
close(synch[0]);
|
||||
/* If this job has finished, we leave it as a
|
||||
* normal (non-super-) job. */
|
||||
if (!(jn->stat & STAT_DONE)) {
|
||||
jobtab[list_pipe_job].other = newjob;
|
||||
jobtab[list_pipe_job].stat |= STAT_SUPERJOB;
|
||||
jn->stat |= STAT_SUBJOB | STAT_NOPRINT;
|
||||
jn->other = pid;
|
||||
}
|
||||
if ((list_pipe || last1) && jobtab[list_pipe_job].procs)
|
||||
killpg(jobtab[list_pipe_job].gleader, SIGSTOP);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
close(synch[0]);
|
||||
entersubsh(Z_ASYNC, 0, 0);
|
||||
if (jobtab[list_pipe_job].procs)
|
||||
setpgrp(0L, mypgrp = jobtab[list_pipe_job].gleader);
|
||||
close(synch[1]);
|
||||
kill(getpid(), SIGSTOP);
|
||||
list_pipe = 0;
|
||||
list_pipe_child = 1;
|
||||
opts[INTERACTIVE] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -975,7 +1003,8 @@ execpline(Sublist l, int how, int last1)
|
|||
jn->stat |= STAT_NOPRINT;
|
||||
killjb(jobtab + pj, lastval & ~0200);
|
||||
}
|
||||
if (list_pipe_child || (list_pipe && (jn->stat & STAT_DONE)))
|
||||
if (list_pipe_child || ((list_pipe || pline_level) &&
|
||||
(jn->stat & STAT_DONE)))
|
||||
deletejob(jn);
|
||||
thisjob = pj;
|
||||
|
||||
|
|
@ -998,19 +1027,19 @@ execpline2(Pline pline, int how, int input, int output, int last1)
|
|||
{
|
||||
pid_t pid;
|
||||
int pipes[2];
|
||||
int oldlineno;
|
||||
|
||||
if (breaks || retflag)
|
||||
return;
|
||||
|
||||
oldlineno = lineno;
|
||||
if (pline->left->lineno >= 0)
|
||||
lineno = pline->left->lineno;
|
||||
|
||||
if (pline_level == 1)
|
||||
if (pline_level == 1) {
|
||||
if (!sfcontext)
|
||||
strcpy(list_pipe_text, getjobtext((void *) pline->left));
|
||||
else
|
||||
list_pipe_text[0] = '\0';
|
||||
}
|
||||
if (pline->type == END)
|
||||
execcmd(pline->left, input, output, how, last1 ? 1 : 2);
|
||||
else {
|
||||
|
|
@ -1054,15 +1083,15 @@ execpline2(Pline pline, int how, int input, int output, int last1)
|
|||
if (pline->right) {
|
||||
/* if another execpline() is invoked because the command is *
|
||||
* a list it must know that we're already in a pipeline */
|
||||
cmdpush(CS_PIPE);
|
||||
list_pipe = 1;
|
||||
execpline2(pline->right, how, pipes[0], output, last1);
|
||||
list_pipe = old_list_pipe;
|
||||
cmdpop();
|
||||
zclose(pipes[0]);
|
||||
subsh_close = -1;
|
||||
}
|
||||
}
|
||||
|
||||
lineno = oldlineno;
|
||||
}
|
||||
|
||||
/* make the argv array */
|
||||
|
|
@ -1079,7 +1108,7 @@ makecline(LinkList list)
|
|||
argv = 2 + (char **) ncalloc((countlinknodes(list) + 4) * sizeof(char *));
|
||||
if (isset(XTRACE)) {
|
||||
if (!doneps4)
|
||||
fprintf(stderr, "%s", (prompt4) ? prompt4 : "");
|
||||
printprompt4();
|
||||
|
||||
for (node = firstnode(list); node; incnode(node)) {
|
||||
*ptr++ = (char *)getdata(node);
|
||||
|
|
@ -1283,7 +1312,7 @@ addvars(LinkList l, int export)
|
|||
|
||||
xtr = isset(XTRACE);
|
||||
if (xtr && nonempty(l)) {
|
||||
fprintf(stderr, "%s", prompt4 ? prompt4 : "");
|
||||
printprompt4();
|
||||
doneps4 = 1;
|
||||
}
|
||||
|
||||
|
|
@ -2179,8 +2208,9 @@ entersubsh(int how, int cl, int fake)
|
|||
attachtty(jobtab[thisjob].gleader);
|
||||
}
|
||||
}
|
||||
else if (!jobtab[thisjob].gleader ||
|
||||
(setpgrp(0L, jobtab[thisjob].gleader) == -1)) {
|
||||
else if (!(list_pipe || list_pipe_child || pline_level > 1) &&
|
||||
(!jobtab[thisjob].gleader ||
|
||||
setpgrp(0L, jobtab[thisjob].gleader) == -1)) {
|
||||
jobtab[thisjob].gleader = getpid();
|
||||
if (list_pipe_job != thisjob &&
|
||||
!jobtab[list_pipe_job].gleader)
|
||||
|
|
@ -2322,7 +2352,7 @@ getoutput(char *cmd, int qt)
|
|||
Cmd c;
|
||||
Redir r;
|
||||
|
||||
if (!(list = parse_string(cmd)))
|
||||
if (!(list = parse_string(cmd, 0)))
|
||||
return NULL;
|
||||
if (list != &dummy_list && !list->right && !list->left->flags &&
|
||||
list->left->type == END && list->left->left->type == END &&
|
||||
|
|
@ -2451,7 +2481,7 @@ parsecmd(char *cmd)
|
|||
return NULL;
|
||||
}
|
||||
*str = '\0';
|
||||
if (str[1] || !(list = parse_string(cmd + 2))) {
|
||||
if (str[1] || !(list = parse_string(cmd + 2, 0))) {
|
||||
zerr("parse error in process substitution", NULL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -2661,7 +2691,8 @@ execcond(Cmd cmd, LinkList args, int flags)
|
|||
{
|
||||
int stat;
|
||||
if (isset(XTRACE)) {
|
||||
fprintf(stderr, "%s[[", prompt4 ? prompt4 : "");
|
||||
printprompt4();
|
||||
fprintf(stderr, "[[");
|
||||
tracingcond++;
|
||||
}
|
||||
stat = !evalcond(cmd->u.cond);
|
||||
|
|
@ -2682,8 +2713,10 @@ execarith(Cmd cmd, LinkList args, int flags)
|
|||
char *e;
|
||||
zlong val = 0;
|
||||
|
||||
if (isset(XTRACE))
|
||||
fprintf(stderr, "%s((", prompt4 ? prompt4 : "");
|
||||
if (isset(XTRACE)) {
|
||||
printprompt4();
|
||||
fprintf(stderr, "((");
|
||||
}
|
||||
if (args)
|
||||
while ((e = (char *) ugetnode(args))) {
|
||||
if (isset(XTRACE))
|
||||
|
|
@ -2759,21 +2792,22 @@ static void
|
|||
execshfunc(Cmd cmd, Shfunc shf, LinkList args)
|
||||
{
|
||||
LinkList last_file_list = NULL;
|
||||
unsigned char *ocs;
|
||||
int ocsp;
|
||||
|
||||
if (errflag)
|
||||
return;
|
||||
|
||||
if (!list_pipe) {
|
||||
if (!list_pipe && thisjob != list_pipe_job) {
|
||||
/* Without this deletejob the process table *
|
||||
* would be filled by a recursive function. */
|
||||
last_file_list = jobtab[thisjob].filelist;
|
||||
jobtab[thisjob].filelist = NULL;
|
||||
deletejob(jobtab + thisjob);
|
||||
}
|
||||
|
||||
if (isset(XTRACE)) {
|
||||
LinkNode lptr;
|
||||
fprintf(stderr, "%s", prompt4 ? prompt4 : prompt4);
|
||||
printprompt4();
|
||||
if (args)
|
||||
for (lptr = firstnode(args); lptr; incnode(lptr)) {
|
||||
if (lptr != firstnode(args))
|
||||
|
|
@ -2783,8 +2817,14 @@ execshfunc(Cmd cmd, Shfunc shf, LinkList args)
|
|||
fputc('\n', stderr);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
ocs = cmdstack;
|
||||
ocsp = cmdsp;
|
||||
cmdstack = (unsigned char *) zalloc(CMDSTACKSZ);
|
||||
cmdsp = 0;
|
||||
doshfunc(shf->nam, shf->funcdef, args, shf->flags, 0);
|
||||
free(cmdstack);
|
||||
cmdstack = ocs;
|
||||
cmdsp = ocsp;
|
||||
|
||||
if (!list_pipe)
|
||||
deletefilelist(last_file_list);
|
||||
|
|
@ -2842,9 +2882,8 @@ doshfunc(char *name, List list, LinkList doshargs, int flags, int noreturnval)
|
|||
* was executed. */
|
||||
{
|
||||
char **tab, **x, *oargv0 = NULL;
|
||||
int xexittr, newexittr, oldzoptind, oldlastval;
|
||||
void *xexitfn, *newexitfn;
|
||||
char saveopts[OPT_SIZE];
|
||||
int oldzoptind, oldlastval;
|
||||
char saveopts[OPT_SIZE], *oldscriptname;
|
||||
int obreaks = breaks;
|
||||
|
||||
HEAPALLOC {
|
||||
|
|
@ -2852,14 +2891,12 @@ doshfunc(char *name, List list, LinkList doshargs, int flags, int noreturnval)
|
|||
if (trapreturn < 0)
|
||||
trapreturn--;
|
||||
oldlastval = lastval;
|
||||
xexittr = sigtrapped[SIGEXIT];
|
||||
if (xexittr & ZSIG_FUNC)
|
||||
xexitfn = shfunctab->removenode(shfunctab, "TRAPEXIT");
|
||||
else
|
||||
xexitfn = sigfuncs[SIGEXIT];
|
||||
sigtrapped[SIGEXIT] = 0;
|
||||
sigfuncs[SIGEXIT] = NULL;
|
||||
|
||||
starttrapscope();
|
||||
|
||||
tab = pparams;
|
||||
oldscriptname = scriptname;
|
||||
scriptname = name;
|
||||
oldzoptind = zoptind;
|
||||
zoptind = 1;
|
||||
|
||||
|
|
@ -2902,6 +2939,7 @@ doshfunc(char *name, List list, LinkList doshargs, int flags, int noreturnval)
|
|||
argzero = oargv0;
|
||||
}
|
||||
zoptind = oldzoptind;
|
||||
scriptname = oldscriptname;
|
||||
pparams = tab;
|
||||
|
||||
if (isset(LOCALOPTIONS)) {
|
||||
|
|
@ -2916,27 +2954,7 @@ doshfunc(char *name, List list, LinkList doshargs, int flags, int noreturnval)
|
|||
opts[LOCALOPTIONS] = saveopts[LOCALOPTIONS];
|
||||
}
|
||||
|
||||
/*
|
||||
* The trap '...' EXIT runs in the environment of the caller,
|
||||
* so remember it here but run it after resetting the
|
||||
* traps for the parent.
|
||||
*/
|
||||
newexittr = sigtrapped[SIGEXIT];
|
||||
newexitfn = sigfuncs[SIGEXIT];
|
||||
if (newexittr & ZSIG_FUNC)
|
||||
shfunctab->removenode(shfunctab, "TRAPEXIT");
|
||||
|
||||
sigtrapped[SIGEXIT] = xexittr;
|
||||
if (xexittr & ZSIG_FUNC) {
|
||||
shfunctab->addnode(shfunctab, ztrdup("TRAPEXIT"), xexitfn);
|
||||
sigfuncs[SIGEXIT] = ((Shfunc) xexitfn)->funcdef;
|
||||
} else
|
||||
sigfuncs[SIGEXIT] = (List) xexitfn;
|
||||
|
||||
if (newexitfn) {
|
||||
dotrapargs(SIGEXIT, &newexittr, newexitfn);
|
||||
freestruct(newexitfn);
|
||||
}
|
||||
endtrapscope();
|
||||
|
||||
if (trapreturn < -1)
|
||||
trapreturn++;
|
||||
|
|
@ -3008,7 +3026,7 @@ getfpfunc(char *s)
|
|||
d[len] = '\0';
|
||||
d = metafy(d, len, META_REALLOC);
|
||||
HEAPALLOC {
|
||||
r = parse_string(d);
|
||||
r = parse_string(d, 1);
|
||||
} LASTALLOC;
|
||||
return r;
|
||||
} else
|
||||
|
|
|
|||
|
|
@ -1993,7 +1993,7 @@ dyncat(char *s1, char *s2)
|
|||
char *ptr;
|
||||
int l1 = strlen(s1);
|
||||
|
||||
ptr = (char *)ncalloc(l1 + strlen(s2) + 1);
|
||||
ptr = (char *)zhalloc(l1 + strlen(s2) + 1);
|
||||
strcpy(ptr, s1);
|
||||
strcpy(ptr + l1, s2);
|
||||
return ptr;
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ deletehashtable(HashTable ht)
|
|||
ht->last->next = ht->next;
|
||||
else
|
||||
firstht = ht->next;
|
||||
zsfree(ht->tablename);
|
||||
#endif /* ZSH_HASH_DEBUG */
|
||||
zfree(ht->nodes, ht->hsize * sizeof(HashNode));
|
||||
zfree(ht, sizeof(*ht));
|
||||
|
|
|
|||
|
|
@ -888,9 +888,14 @@ prepnexthistent(int histnum)
|
|||
else {
|
||||
he = hist_ring->down;
|
||||
if (isset(HISTEXPIREDUPSFIRST) && !(he->flags & HIST_DUP)) {
|
||||
int max_unique_ct = getiparam("SAVEHIST");
|
||||
do {
|
||||
if (max_unique_ct-- <= 0) {
|
||||
he = hist_ring->down;
|
||||
break;
|
||||
}
|
||||
he = he->down;
|
||||
} while (he != hist_ring->down && !(he->flags & HIST_DUP)) ;
|
||||
} while (he != hist_ring->down && !(he->flags & HIST_DUP));
|
||||
if (he != hist_ring->down) {
|
||||
he->up->down = he->down;
|
||||
he->down->up = he->up;
|
||||
|
|
@ -989,7 +994,7 @@ hend(void)
|
|||
}
|
||||
#endif
|
||||
/* get rid of pesky \n which we've already nulled out */
|
||||
if (!chline[chwords[chwordpos-2]])
|
||||
if (chwordpos > 1 && !chline[chwords[chwordpos-2]])
|
||||
chwordpos -= 2;
|
||||
/* strip superfluous blanks, if desired */
|
||||
if (isset(HISTREDUCEBLANKS))
|
||||
|
|
|
|||
32
Src/init.c
32
Src/init.c
|
|
@ -75,6 +75,11 @@ int tclen[TC_COUNT];
|
|||
/**/
|
||||
int tclines, tccolumns, hasam;
|
||||
|
||||
/* Pointer to read-key function from zle */
|
||||
|
||||
/**/
|
||||
int (*getkeyptr) _((int));
|
||||
|
||||
#ifdef DEBUG
|
||||
/* depth of allocation type stack */
|
||||
|
||||
|
|
@ -194,6 +199,7 @@ parseargs(char **argv)
|
|||
|
||||
/* loop through command line options (begins with "-" or "+") */
|
||||
while (*argv && (**argv == '-' || **argv == '+')) {
|
||||
char *args = *argv;
|
||||
action = (**argv == '-');
|
||||
if(!argv[0][1])
|
||||
*argv = "--";
|
||||
|
|
@ -229,6 +235,14 @@ parseargs(char **argv)
|
|||
else
|
||||
dosetopt(optno, action, 1);
|
||||
break;
|
||||
} else if (isspace(**argv)) {
|
||||
/* zsh's typtab not yet set, have to use ctype */
|
||||
while (*++*argv)
|
||||
if (!isspace(**argv)) {
|
||||
zerr("bad option string: `%s'", args, 0);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
if (!(optno = optlookupc(**argv))) {
|
||||
zerr("bad option: -%c", NULL, **argv);
|
||||
|
|
@ -376,7 +390,16 @@ init_io(void)
|
|||
#ifdef JOB_CONTROL
|
||||
/* If interactive, make the shell the foreground process */
|
||||
if (opts[MONITOR] && interact && (SHTTY != -1)) {
|
||||
attachtty(GETPGRP());
|
||||
/* Since we now sometimes execute programs in the process group
|
||||
* of the parent shell even when using job-control, we have to
|
||||
* make sure that we run in our own process group. Otherwise if
|
||||
* we are called from a program that doesn't put us in our own
|
||||
* group a SIGTSTP that we ignore might stop our parent process.
|
||||
* Instead of the two calls below we once had:
|
||||
* attachtty(GETPGRP());
|
||||
*/
|
||||
attachtty(getpid());
|
||||
setpgrp(0L, 0L);
|
||||
if ((mypgrp = GETPGRP()) > 0) {
|
||||
while ((ttpgrp = gettygrp()) != -1 && ttpgrp != mypgrp) {
|
||||
sleep(1);
|
||||
|
|
@ -530,12 +553,15 @@ setupvals(void)
|
|||
int i;
|
||||
#endif
|
||||
|
||||
getkeyptr = NULL;
|
||||
|
||||
lineno = 1;
|
||||
noeval = 0;
|
||||
curhist = 0;
|
||||
histsiz = DEFAULT_HISTSIZE;
|
||||
inithist();
|
||||
|
||||
cmdstack = (unsigned char *) zalloc(256);
|
||||
cmdstack = (unsigned char *) zalloc(CMDSTACKSZ);
|
||||
cmdsp = 0;
|
||||
|
||||
bangchar = '!';
|
||||
|
|
@ -869,7 +895,7 @@ source(char *s)
|
|||
SHIN = tempfd;
|
||||
bshin = fdopen(SHIN, "r");
|
||||
subsh = 0;
|
||||
lineno = 0;
|
||||
lineno = 1;
|
||||
loops = 0;
|
||||
dosetopt(SHINSTDIN, 0, 1);
|
||||
scriptname = s;
|
||||
|
|
|
|||
11
Src/input.c
11
Src/input.c
|
|
@ -186,6 +186,8 @@ ingetc(void)
|
|||
inbufct--;
|
||||
if (itok(lastc = STOUC(*inbufptr++)))
|
||||
continue;
|
||||
if (((inbufflags & INP_LINENO) || !strin) && lastc == '\n')
|
||||
lineno++;
|
||||
return lastc;
|
||||
}
|
||||
|
||||
|
|
@ -279,10 +281,8 @@ inputline(void)
|
|||
zputs(ingetcline, stderr);
|
||||
fflush(stderr);
|
||||
}
|
||||
if (*ingetcline && ingetcline[strlen(ingetcline) - 1] == '\n') {
|
||||
/* We've now read a complete line. */
|
||||
lineno++;
|
||||
if (interact && isset(SUNKEYBOARDHACK) && isset(SHINSTDIN) &&
|
||||
if (*ingetcline && ingetcline[strlen(ingetcline) - 1] == '\n' &&
|
||||
interact && isset(SUNKEYBOARDHACK) && isset(SHINSTDIN) &&
|
||||
SHTTY != -1 && *ingetcline && ingetcline[1] &&
|
||||
ingetcline[strlen(ingetcline) - 2] == '`') {
|
||||
/* Junk an unmatched "`" at the end of the line. */
|
||||
|
|
@ -297,7 +297,6 @@ inputline(void)
|
|||
ptr[-1] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
isfirstch = 1;
|
||||
/* Put this into the input channel. */
|
||||
inputsetline(ingetcline, INP_FREE);
|
||||
|
|
@ -359,6 +358,8 @@ inungetc(int c)
|
|||
inbufptr--;
|
||||
inbufct++;
|
||||
inbufleft++;
|
||||
if (((inbufflags & INP_LINENO) || !strin) && c == '\n')
|
||||
lineno--;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else if (!(inbufflags & INP_CONT)) {
|
||||
|
|
|
|||
|
|
@ -92,9 +92,13 @@ makerunning(Job jn)
|
|||
|
||||
jn->stat &= ~STAT_STOPPED;
|
||||
for (pn = jn->procs; pn; pn = pn->next)
|
||||
#if 0
|
||||
if (WIFSTOPPED(pn->status) &&
|
||||
(!(jn->stat & STAT_SUPERJOB) || pn->next))
|
||||
pn->status = SP_RUNNING;
|
||||
#endif
|
||||
if (WIFSTOPPED(pn->status))
|
||||
pn->status = SP_RUNNING;
|
||||
|
||||
if (jn->stat & STAT_SUPERJOB)
|
||||
makerunning(jobtab + jn->other);
|
||||
|
|
@ -181,8 +185,9 @@ update_job(Job jn)
|
|||
|
||||
for (i = 1; i < MAXJOB; i++)
|
||||
if ((jobtab[i].stat & STAT_SUPERJOB) &&
|
||||
jobtab[i].other == job) {
|
||||
killpg(jobtab[i].gleader, SIGSTOP);
|
||||
jobtab[i].other == job &&
|
||||
jobtab[i].gleader) {
|
||||
killpg(jobtab[i].gleader, SIGTSTP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ lexsave(void)
|
|||
ls->hlinesz = hlinesz;
|
||||
ls->cstack = cmdstack;
|
||||
ls->csp = cmdsp;
|
||||
cmdstack = (unsigned char *)zalloc(256);
|
||||
cmdstack = (unsigned char *)zalloc(CMDSTACKSZ);
|
||||
ls->tok = tok;
|
||||
ls->isnewlin = isnewlin;
|
||||
ls->tokstr = tokstr;
|
||||
|
|
@ -1150,7 +1150,7 @@ gettokstr(int c, int sub)
|
|||
cmdpush(CS_BQUOTE);
|
||||
SETPARBEGIN
|
||||
inquote = 0;
|
||||
while ((c = hgetc()) != '`' && !lexstop)
|
||||
while ((c = hgetc()) != '`' && !lexstop) {
|
||||
if (c == '\\') {
|
||||
c = hgetc();
|
||||
if (c != '\n') {
|
||||
|
|
@ -1171,6 +1171,7 @@ gettokstr(int c, int sub)
|
|||
ALLOWHIST
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inquote)
|
||||
ALLOWHIST
|
||||
cmdpop();
|
||||
|
|
|
|||
21
Src/loop.c
21
Src/loop.c
|
|
@ -71,6 +71,7 @@ execfor(Cmd cmd, LinkList args, int flags)
|
|||
lastval = 0;
|
||||
loops++;
|
||||
pushheap();
|
||||
cmdpush(CS_FOR);
|
||||
for (;;) {
|
||||
if (node->condition) {
|
||||
str = dupstring(node->condition);
|
||||
|
|
@ -119,6 +120,7 @@ execfor(Cmd cmd, LinkList args, int flags)
|
|||
freeheap();
|
||||
}
|
||||
popheap();
|
||||
cmdpop();
|
||||
loops--;
|
||||
return lastval;
|
||||
}
|
||||
|
|
@ -147,6 +149,7 @@ execselect(Cmd cmd, LinkList args, int flags)
|
|||
loops++;
|
||||
lastval = 0;
|
||||
pushheap();
|
||||
cmdpush(CS_SELECT);
|
||||
inp = fdopen(dup((SHTTY == -1) ? 0 : SHTTY), "r");
|
||||
more = selectlist(args, 0);
|
||||
for (;;) {
|
||||
|
|
@ -201,6 +204,7 @@ execselect(Cmd cmd, LinkList args, int flags)
|
|||
break;
|
||||
}
|
||||
done:
|
||||
cmdpop();
|
||||
popheap();
|
||||
fclose(inp);
|
||||
loops--;
|
||||
|
|
@ -279,6 +283,7 @@ execwhile(Cmd cmd, LinkList args, int flags)
|
|||
node = cmd->u.whilecmd;
|
||||
oldval = 0;
|
||||
pushheap();
|
||||
cmdpush(node->cond ? CS_UNTIL : CS_WHILE);
|
||||
loops++;
|
||||
for (;;) {
|
||||
noerrexit = 1;
|
||||
|
|
@ -304,6 +309,7 @@ execwhile(Cmd cmd, LinkList args, int flags)
|
|||
}
|
||||
oldval = lastval;
|
||||
}
|
||||
cmdpop();
|
||||
popheap();
|
||||
loops--;
|
||||
return lastval;
|
||||
|
|
@ -322,6 +328,7 @@ execrepeat(Cmd cmd, LinkList args, int flags)
|
|||
}
|
||||
count = atoi(peekfirst(args));
|
||||
pushheap();
|
||||
cmdpush(CS_REPEAT);
|
||||
loops++;
|
||||
while (count--) {
|
||||
execlist(cmd->u.list, 1, 0);
|
||||
|
|
@ -337,6 +344,7 @@ execrepeat(Cmd cmd, LinkList args, int flags)
|
|||
break;
|
||||
}
|
||||
}
|
||||
cmdpop();
|
||||
popheap();
|
||||
loops--;
|
||||
return lastval;
|
||||
|
|
@ -347,7 +355,7 @@ int
|
|||
execif(Cmd cmd, LinkList args, int flags)
|
||||
{
|
||||
struct ifcmd *node;
|
||||
int olderrexit;
|
||||
int olderrexit, s = 0;
|
||||
List *i, *t;
|
||||
|
||||
olderrexit = noerrexit;
|
||||
|
|
@ -358,17 +366,22 @@ execif(Cmd cmd, LinkList args, int flags)
|
|||
if (!noerrexit)
|
||||
noerrexit = 1;
|
||||
while (*i) {
|
||||
cmdpush(s ? CS_ELIF : CS_IF);
|
||||
execlist(*i, 1, 0);
|
||||
cmdpop();
|
||||
if (!lastval)
|
||||
break;
|
||||
s = 1;
|
||||
i++;
|
||||
t++;
|
||||
}
|
||||
noerrexit = olderrexit;
|
||||
|
||||
if (*t)
|
||||
if (*t) {
|
||||
cmdpush(*i ? (s ? CS_ELIFTHEN : CS_IFTHEN) : CS_ELSE);
|
||||
execlist(*t, 1, flags & CFLAG_EXEC);
|
||||
else
|
||||
cmdpop();
|
||||
} else
|
||||
lastval = 0;
|
||||
|
||||
return lastval;
|
||||
|
|
@ -393,6 +406,7 @@ execcase(Cmd cmd, LinkList args, int flags)
|
|||
lastval = 0;
|
||||
|
||||
if (node) {
|
||||
cmdpush(CS_CASE);
|
||||
while (*p) {
|
||||
char *pat = dupstring(*p + 1);
|
||||
singsub(&pat);
|
||||
|
|
@ -405,6 +419,7 @@ execcase(Cmd cmd, LinkList args, int flags)
|
|||
p++;
|
||||
l++;
|
||||
}
|
||||
cmdpop();
|
||||
}
|
||||
return lastval;
|
||||
}
|
||||
|
|
|
|||
254
Src/module.c
254
Src/module.c
|
|
@ -709,7 +709,14 @@ bin_zmodload(char *nam, char **args, char *ops, int func)
|
|||
zwarnnam(nam, "what do you want to unload?", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (ops['d'])
|
||||
if (ops['e'] && (ops['I'] || ops['L'] || ops['a'] || ops['d'] ||
|
||||
ops['i'] || ops['u'])) {
|
||||
zwarnnam(nam, "-e cannot be combined with other options", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (ops['e'])
|
||||
return bin_zmodload_exist(nam, args, ops);
|
||||
else if (ops['d'])
|
||||
return bin_zmodload_dep(nam, args, ops);
|
||||
else if ((ops['a'] || ops['b']) && !(ops['c'] || ops['p']))
|
||||
return bin_zmodload_auto(nam, args, ops);
|
||||
|
|
@ -725,6 +732,46 @@ bin_zmodload(char *nam, char **args, char *ops, int func)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
bin_zmodload_exist(char *nam, char **args, char *ops)
|
||||
{
|
||||
LinkNode node;
|
||||
Module m;
|
||||
|
||||
if (!*args) {
|
||||
for (node = firstnode(bltinmodules); node; incnode(node)) {
|
||||
nicezputs((char *) getdata(node), stdout);
|
||||
putchar('\n');
|
||||
}
|
||||
for (node = firstnode(modules); node; incnode(node)) {
|
||||
m = (Module) getdata(node);
|
||||
if (m->handle && !(m->flags & MOD_UNLOAD)) {
|
||||
nicezputs(m->nam, stdout);
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
int ret = 0, f;
|
||||
|
||||
for (; !ret && *args; args++) {
|
||||
f = 0;
|
||||
for (node = firstnode(bltinmodules);
|
||||
!f && node; incnode(node))
|
||||
f = !strcmp(*args, (char *) getdata(node));
|
||||
for (node = firstnode(modules);
|
||||
!f && node; incnode(node)) {
|
||||
m = (Module) getdata(node);
|
||||
if (m->handle && !(m->flags & MOD_UNLOAD))
|
||||
f = !strcmp(*args, m->nam);
|
||||
}
|
||||
ret = !f;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
bin_zmodload_dep(char *nam, char **args, char *ops)
|
||||
|
|
@ -1115,6 +1162,37 @@ bin_zmodload_load(char *nam, char **args, char *ops)
|
|||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
#else /* DYNAMIC */
|
||||
|
||||
/* This is the version for shells without dynamic linking. */
|
||||
|
||||
/**/
|
||||
int
|
||||
bin_zmodload(char *nam, char **args, char *ops, int func)
|
||||
{
|
||||
/* We understand only the -e option. */
|
||||
|
||||
if (ops['e']) {
|
||||
LinkNode node;
|
||||
|
||||
if (!*args) {
|
||||
for (node = firstnode(bltinmodules); node; incnode(node)) {
|
||||
nicezputs((char *) getdata(node), stdout);
|
||||
putchar('\n');
|
||||
}
|
||||
} else {
|
||||
for (; *args; args++)
|
||||
for (node = firstnode(bltinmodules); node; incnode(node))
|
||||
if (strcmp(*args, (char *) getdata(node)))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* Otherwise we return 1 -- different from the dynamic version. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
#endif /* DYNAMIC */
|
||||
|
||||
|
|
@ -1206,6 +1284,180 @@ addconddefs(char const *nam, Conddef c, int size)
|
|||
return hadf ? hads : 1;
|
||||
}
|
||||
|
||||
/* This list of hook functions defined. */
|
||||
|
||||
/**/
|
||||
Hookdef hooktab;
|
||||
|
||||
/* Find a hook definition given the name. */
|
||||
|
||||
/**/
|
||||
Hookdef
|
||||
gethookdef(char *n)
|
||||
{
|
||||
Hookdef p;
|
||||
|
||||
for (p = hooktab; p; p = p->next)
|
||||
if (!strcmp(n, p->name))
|
||||
return p;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This adds the given hook definition. The return value is zero on *
|
||||
* success and 1 on failure. */
|
||||
|
||||
/**/
|
||||
int
|
||||
addhookdef(Hookdef h)
|
||||
{
|
||||
if (gethookdef(h->name))
|
||||
return 1;
|
||||
|
||||
h->next = hooktab;
|
||||
hooktab = h;
|
||||
PERMALLOC {
|
||||
h->funcs = newlinklist();
|
||||
} LASTALLOC;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This adds multiple hook definitions. This is like addbuiltins(). */
|
||||
|
||||
/**/
|
||||
int
|
||||
addhookdefs(char const *nam, Hookdef h, int size)
|
||||
{
|
||||
int hads = 0, hadf = 0;
|
||||
|
||||
while (size--) {
|
||||
if (addhookdef(h)) {
|
||||
zwarnnam(nam, "name clash when adding condition `%s'", h->name, 0);
|
||||
hadf = 1;
|
||||
} else
|
||||
hads = 2;
|
||||
h++;
|
||||
}
|
||||
return hadf ? hads : 1;
|
||||
}
|
||||
|
||||
/* Delete hook definitions. */
|
||||
|
||||
/**/
|
||||
int
|
||||
deletehookdef(Hookdef h)
|
||||
{
|
||||
Hookdef p, q;
|
||||
|
||||
for (p = hooktab, q = NULL; p && p != h; q = p, p = p->next);
|
||||
|
||||
if (!p)
|
||||
return 1;
|
||||
|
||||
if (q)
|
||||
q->next = p->next;
|
||||
else
|
||||
hooktab = p->next;
|
||||
freelinklist(p->funcs, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
deletehookdefs(char const *nam, Hookdef h, int size)
|
||||
{
|
||||
while (size--) {
|
||||
deletehookdef(h);
|
||||
h++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Add a function to a hook. */
|
||||
|
||||
/**/
|
||||
int
|
||||
addhookdeffunc(Hookdef h, Hookfn f)
|
||||
{
|
||||
PERMALLOC {
|
||||
addlinknode(h->funcs, (void *) f);
|
||||
} LASTALLOC;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
addhookfunc(char *n, Hookfn f)
|
||||
{
|
||||
Hookdef h = gethookdef(n);
|
||||
|
||||
if (h)
|
||||
return addhookdeffunc(h, f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Delete a function from a hook. */
|
||||
|
||||
/**/
|
||||
int
|
||||
deletehookdeffunc(Hookdef h, Hookfn f)
|
||||
{
|
||||
LinkNode p;
|
||||
|
||||
for (p = firstnode(h->funcs); p; incnode(p))
|
||||
if (f == (Hookfn) getdata(p)) {
|
||||
remnode(h->funcs, p);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
deletehookfunc(char *n, Hookfn f)
|
||||
{
|
||||
Hookdef h = gethookdef(n);
|
||||
|
||||
if (h)
|
||||
return deletehookdeffunc(h, f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Run the function(s) for a hook. */
|
||||
|
||||
/**/
|
||||
int
|
||||
runhookdef(Hookdef h, void *d)
|
||||
{
|
||||
if (empty(h->funcs)) {
|
||||
if (h->def)
|
||||
return h->def(h, d);
|
||||
return 0;
|
||||
} else if (h->flags & HOOKF_ALL) {
|
||||
LinkNode p;
|
||||
int r;
|
||||
|
||||
for (p = firstnode(h->funcs); p; incnode(p))
|
||||
if ((r = ((Hookfn) getdata(p))(h, d)))
|
||||
return r;
|
||||
if (h->def)
|
||||
return h->def(h, d);
|
||||
return 0;
|
||||
} else
|
||||
return ((Hookfn) getdata(lastnode(h->funcs)))(h, d);
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
runhook(char *n, void *d)
|
||||
{
|
||||
Hookdef h = gethookdef(n);
|
||||
|
||||
if (h)
|
||||
return runhookdef(h, d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This adds the given parameter definition. The return value is zero on *
|
||||
* success and 1 on failure. */
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ static struct optname optns[] = {
|
|||
{NULL, "listbeep", OPT_ALL, LISTBEEP},
|
||||
{NULL, "listtypes", OPT_ALL, LISTTYPES},
|
||||
{NULL, "localoptions", OPT_EMULATE|OPT_KSH, LOCALOPTIONS},
|
||||
{NULL, "localtraps", OPT_EMULATE|OPT_KSH, LOCALTRAPS},
|
||||
{NULL, "login", OPT_SPECIAL, LOGINSHELL},
|
||||
{NULL, "longlistjobs", 0, LONGLISTJOBS},
|
||||
{NULL, "magicequalsubst", 0, MAGICEQUALSUBST},
|
||||
|
|
|
|||
|
|
@ -588,7 +588,7 @@ createparam(char *name, int flags)
|
|||
|
||||
DPUTS(oldpm && oldpm->level > locallevel,
|
||||
"BUG: old local parameter not deleteed");
|
||||
if (oldpm && oldpm->level == locallevel) {
|
||||
if (oldpm && (oldpm->level == locallevel || !(flags & PM_LOCAL))) {
|
||||
if (!(oldpm->flags & PM_UNSET) || (oldpm->flags & PM_SPECIAL)) {
|
||||
oldpm->flags &= ~PM_UNSET;
|
||||
return NULL;
|
||||
|
|
@ -616,7 +616,7 @@ createparam(char *name, int flags)
|
|||
pm = (Param) alloc(sizeof *pm);
|
||||
pm->nam = nulstring;
|
||||
}
|
||||
pm->flags = flags;
|
||||
pm->flags = flags & ~PM_LOCAL;
|
||||
|
||||
if(!(pm->flags & PM_SPECIAL))
|
||||
assigngetset(pm);
|
||||
|
|
@ -1898,7 +1898,7 @@ arrhashsetfn(Param pm, char **val)
|
|||
* since that could cause trouble for special hashes. This way, *
|
||||
* it's up to pm->sets.hfn() what to do. */
|
||||
int alen = arrlen(val);
|
||||
HashTable opmtab = paramtab, ht;
|
||||
HashTable opmtab = paramtab, ht = 0;
|
||||
char **aptr = val;
|
||||
Value v = (Value) hcalloc(sizeof *v);
|
||||
v->b = -1;
|
||||
|
|
@ -1909,6 +1909,7 @@ arrhashsetfn(Param pm, char **val)
|
|||
NULL, 0);
|
||||
return;
|
||||
}
|
||||
if (alen)
|
||||
ht = paramtab = newparamtable(17, pm->nam);
|
||||
while (*aptr) {
|
||||
/* The parameter name is ztrdup'd... */
|
||||
|
|
|
|||
12
Src/parse.c
12
Src/parse.c
|
|
@ -890,6 +890,8 @@ par_subsh(Cmd c)
|
|||
static void
|
||||
par_funcdef(Cmd c)
|
||||
{
|
||||
int oldlineno = lineno;
|
||||
lineno = 0;
|
||||
nocorrect = 1;
|
||||
incmdpos = 0;
|
||||
yylex();
|
||||
|
|
@ -912,13 +914,17 @@ par_funcdef(Cmd c)
|
|||
if (tok == INBRACE) {
|
||||
yylex();
|
||||
c->u.list = par_list();
|
||||
if (tok != OUTBRACE)
|
||||
if (tok != OUTBRACE) {
|
||||
lineno += oldlineno;
|
||||
YYERRORV;
|
||||
}
|
||||
yylex();
|
||||
} else if (unset(SHORTLOOPS)) {
|
||||
lineno += oldlineno;
|
||||
YYERRORV;
|
||||
} else
|
||||
c->u.list = par_list1();
|
||||
lineno += oldlineno;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1023,6 +1029,8 @@ par_simple(Cmd c)
|
|||
c->redir = newlinklist();
|
||||
par_redir(c->redir);
|
||||
} else if (tok == INOUTPAR) {
|
||||
int oldlineno = lineno;
|
||||
lineno = 0;
|
||||
incmdpos = 1;
|
||||
cmdpush(CS_FUNCDEF);
|
||||
yylex();
|
||||
|
|
@ -1033,6 +1041,7 @@ par_simple(Cmd c)
|
|||
c->u.list = par_list();
|
||||
if (tok != OUTBRACE) {
|
||||
cmdpop();
|
||||
lineno += oldlineno;
|
||||
YYERROR;
|
||||
}
|
||||
yylex();
|
||||
|
|
@ -1051,6 +1060,7 @@ par_simple(Cmd c)
|
|||
}
|
||||
cmdpop();
|
||||
c->type = FUNCDEF;
|
||||
lineno += oldlineno;
|
||||
} else
|
||||
break;
|
||||
isnull = 0;
|
||||
|
|
|
|||
159
Src/signals.c
159
Src/signals.c
|
|
@ -602,6 +602,57 @@ killjb(Job jn, int sig)
|
|||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* List for saving traps. We don't usually have that many traps
|
||||
* at once, so just use a linked list.
|
||||
*/
|
||||
struct savetrap {
|
||||
int sig, flags, local;
|
||||
void *list;
|
||||
};
|
||||
|
||||
static LinkList savetraps;
|
||||
|
||||
/* Flag to unsettrap not to free the structs, which we're keeping */
|
||||
|
||||
/**/
|
||||
int notrapfree;
|
||||
|
||||
/*
|
||||
* Save the current trap and unset it.
|
||||
*/
|
||||
|
||||
static void
|
||||
dosavetrap(int sig, int level)
|
||||
{
|
||||
struct savetrap *st;
|
||||
st = (struct savetrap *)zalloc(sizeof(*st));
|
||||
st->sig = sig;
|
||||
st->local = level;
|
||||
notrapfree++;
|
||||
if ((st->flags = sigtrapped[sig]) & ZSIG_FUNC) {
|
||||
/*
|
||||
* Get the old function: this assumes we haven't added
|
||||
* the new one yet.
|
||||
*/
|
||||
char func[20];
|
||||
sprintf(func, "TRAP%s", sigs[sig]);
|
||||
st->list = shfunctab->removenode(shfunctab, func);
|
||||
} else {
|
||||
st->list = sigfuncs[sig];
|
||||
unsettrap(sig);
|
||||
}
|
||||
notrapfree--;
|
||||
PERMALLOC {
|
||||
if (!savetraps)
|
||||
savetraps = newlinklist();
|
||||
/*
|
||||
* Put this at the front of the list
|
||||
*/
|
||||
insertlinknode(savetraps, (LinkNode)savetraps, st);
|
||||
} LASTALLOC;
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
settrap(int sig, List l)
|
||||
|
|
@ -612,7 +663,15 @@ settrap(int sig, List l)
|
|||
zerr("can't trap SIG%s in interactive shells", sigs[sig], 0);
|
||||
return 1;
|
||||
}
|
||||
if (sigfuncs[sig])
|
||||
/*
|
||||
* Note that we save the trap here even if there isn't an existing
|
||||
* one, to aid in removing this one. However, if there's
|
||||
* already one at the current locallevel we just overwrite it.
|
||||
*/
|
||||
if (isset(LOCALTRAPS) && locallevel &&
|
||||
(!sigtrapped[sig] || locallevel > (sigtrapped[sig] >> ZSIG_SHIFT))) {
|
||||
dosavetrap(sig, locallevel);
|
||||
} else if (sigfuncs[sig])
|
||||
unsettrap(sig);
|
||||
sigfuncs[sig] = l;
|
||||
if (!l) {
|
||||
|
|
@ -632,6 +691,12 @@ settrap(int sig, List l)
|
|||
sig != SIGCHLD)
|
||||
install_handler(sig);
|
||||
}
|
||||
/*
|
||||
* Note that introducing the locallevel does not affect whether
|
||||
* sigtrapped[sig] is zero or not, i.e. a test without a mask
|
||||
* works just the same.
|
||||
*/
|
||||
sigtrapped[sig] |= (locallevel << ZSIG_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -645,6 +710,19 @@ unsettrap(int sig)
|
|||
(jobbing && (sig == SIGTTOU || sig == SIGTSTP || sig == SIGTTIN))) {
|
||||
return;
|
||||
}
|
||||
if (isset(LOCALTRAPS) && locallevel &&
|
||||
sigtrapped[sig] && locallevel > (sigtrapped[sig] >> ZSIG_SHIFT)) {
|
||||
/*
|
||||
* This calls unsettrap recursively to do any dirty work, so
|
||||
* make sure this bit doesn't happen: a bit messy, but hard
|
||||
* to avoid.
|
||||
*/
|
||||
int oldlt = opts[LOCALTRAPS];
|
||||
opts[LOCALTRAPS] = 0;
|
||||
dosavetrap(sig, locallevel);
|
||||
opts[LOCALTRAPS] = oldlt;
|
||||
return;
|
||||
}
|
||||
sigtrapped[sig] = 0;
|
||||
if (sig == SIGINT && interact) {
|
||||
/* PWS 1995/05/16: added test for interactive, also noholdintr() *
|
||||
|
|
@ -659,6 +737,8 @@ unsettrap(int sig)
|
|||
#endif
|
||||
sig != SIGCHLD)
|
||||
signal_default(sig);
|
||||
if (notrapfree)
|
||||
return;
|
||||
if (trapped & ZSIG_FUNC) {
|
||||
char func[20];
|
||||
HashNode hn;
|
||||
|
|
@ -672,6 +752,83 @@ unsettrap(int sig)
|
|||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
starttrapscope(void)
|
||||
{
|
||||
/*
|
||||
* SIGEXIT needs to be restored at the current locallevel,
|
||||
* so give it the next higher one.
|
||||
*/
|
||||
if (sigtrapped[SIGEXIT])
|
||||
dosavetrap(SIGEXIT, locallevel+1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset traps after the end of a function: must be called after
|
||||
* endparamscope() so that the locallevel has been decremented.
|
||||
*/
|
||||
|
||||
/**/
|
||||
void
|
||||
endtrapscope(void)
|
||||
{
|
||||
LinkNode ln;
|
||||
struct savetrap *st;
|
||||
int exittr;
|
||||
void *exitfn = NULL;
|
||||
|
||||
/*
|
||||
* Remember the exit trap, but don't run it until
|
||||
* after all the other traps have been put back.
|
||||
*/
|
||||
if ((exittr = sigtrapped[SIGEXIT])) {
|
||||
notrapfree++;
|
||||
if (exittr & ZSIG_FUNC) {
|
||||
exitfn = shfunctab->removenode(shfunctab, "TRAPEXIT");
|
||||
} else {
|
||||
exitfn = sigfuncs[SIGEXIT];
|
||||
unsettrap(SIGEXIT);
|
||||
}
|
||||
notrapfree--;
|
||||
}
|
||||
|
||||
if (savetraps) {
|
||||
while ((ln = firstnode(savetraps)) &&
|
||||
(st = (struct savetrap *) ln->dat) &&
|
||||
st->local > locallevel) {
|
||||
int sig = st->sig;
|
||||
|
||||
remnode(savetraps, ln);
|
||||
|
||||
if (sigtrapped[sig])
|
||||
unsettrap(sig);
|
||||
if (st->flags) {
|
||||
List list = (st->flags & ZSIG_FUNC) ?
|
||||
((Shfunc) st->list)->funcdef : (List) st->list;
|
||||
/* prevent settrap from saving this */
|
||||
int oldlt = opts[LOCALTRAPS];
|
||||
opts[LOCALTRAPS] = 0;
|
||||
settrap(sig, list);
|
||||
opts[LOCALTRAPS] = oldlt;
|
||||
if ((sigtrapped[sig] = st->flags) & ZSIG_FUNC)
|
||||
shfunctab->addnode(shfunctab, ((Shfunc)st->list)->nam,
|
||||
(Shfunc) st->list);
|
||||
}
|
||||
zfree(st, sizeof(*st));
|
||||
}
|
||||
}
|
||||
|
||||
if (exittr) {
|
||||
dotrapargs(SIGEXIT, &exittr, (exittr & ZSIG_FUNC) ?
|
||||
((Shfunc)exitfn)->funcdef : (List) exitfn);
|
||||
if (exittr & ZSIG_FUNC)
|
||||
shfunctab->freenode((HashNode)exitfn);
|
||||
else
|
||||
freestruct(exitfn);
|
||||
}
|
||||
}
|
||||
|
||||
/* Execute a trap function for a given signal, possibly
|
||||
* with non-standard sigtrapped & sigfuncs values
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1328,10 +1328,15 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
|||
else
|
||||
t = aval;
|
||||
} else if (!isarr) {
|
||||
if (!*val && arrasg > 1) {
|
||||
arr[0] = NULL;
|
||||
l = 0;
|
||||
} else {
|
||||
arr[0] = val;
|
||||
arr[1] = NULL;
|
||||
t = aval = arr;
|
||||
l = 1;
|
||||
}
|
||||
t = aval = arr;
|
||||
} else
|
||||
l = arrlen(aval), t = aval;
|
||||
p = a = zalloc(sizeof(char *) * (l + 1));
|
||||
|
|
@ -1944,6 +1949,8 @@ dstackent(char ch, int val)
|
|||
else
|
||||
for (end=NULL, n=firstnode(dirstack); n && val; val--, n=nextnode(n));
|
||||
if (n == end) {
|
||||
if (backwards && !val)
|
||||
return pwd;
|
||||
if (isset(NOMATCH))
|
||||
zerr("not enough directory stack entries.", NULL, 0);
|
||||
return NULL;
|
||||
|
|
|
|||
49
Src/utils.c
49
Src/utils.c
|
|
@ -62,9 +62,10 @@ zerr(const char *fmt, const char *str, int num)
|
|||
/*
|
||||
* scriptname is set when sourcing scripts, so that we get the
|
||||
* correct name instead of the generic name of whatever
|
||||
* program/script is running.
|
||||
* program/script is running. It's also set in shell functions,
|
||||
* so test locallevel, too.
|
||||
*/
|
||||
nicezputs(isset(SHINSTDIN) ? "zsh" :
|
||||
nicezputs((isset(SHINSTDIN) && !locallevel) ? "zsh" :
|
||||
scriptname ? scriptname : argzero, stderr);
|
||||
fputs(": ", stderr);
|
||||
zerrnam(NULL, fmt, str, num);
|
||||
|
|
@ -79,7 +80,7 @@ zerrnam(const char *cmd, const char *fmt, const char *str, int num)
|
|||
return;
|
||||
errflag = 1;
|
||||
trashzle();
|
||||
if(unset(SHINSTDIN)) {
|
||||
if (unset(SHINSTDIN) || locallevel) {
|
||||
nicezputs(scriptname ? scriptname : argzero, stderr);
|
||||
fputs(": ", stderr);
|
||||
}
|
||||
|
|
@ -133,7 +134,7 @@ zerrnam(const char *cmd, const char *fmt, const char *str, int num)
|
|||
putc(*fmt == Meta ? *++fmt ^ 32 : *fmt, stderr);
|
||||
fmt++;
|
||||
}
|
||||
if (unset(SHINSTDIN) && lineno)
|
||||
if ((unset(SHINSTDIN) || locallevel) && lineno)
|
||||
fprintf(stderr, " [%ld]\n", (long)lineno);
|
||||
else
|
||||
putc('\n', stderr);
|
||||
|
|
@ -774,6 +775,23 @@ checkmailpath(char **s)
|
|||
}
|
||||
}
|
||||
|
||||
/* This prints the XTRACE prompt. */
|
||||
|
||||
/**/
|
||||
void
|
||||
printprompt4(void)
|
||||
{
|
||||
if (prompt4) {
|
||||
int l;
|
||||
char *s = dupstring(prompt4);
|
||||
|
||||
unmetafy(s, &l);
|
||||
s = unmetafy(promptexpand(metafy(s, l, META_NOALLOC), 0, NULL, NULL), &l);
|
||||
|
||||
fprintf(stderr, "%s", s);
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
freestr(void *a)
|
||||
|
|
@ -2116,7 +2134,12 @@ mkarray(char *s)
|
|||
void
|
||||
zbeep(void)
|
||||
{
|
||||
if (isset(BEEP))
|
||||
char *vb;
|
||||
if ((vb = getsparam("ZBEEP"))) {
|
||||
int len;
|
||||
vb = getkeystring(vb, &len, 2, NULL);
|
||||
write(SHTTY, vb, len);
|
||||
} else if (isset(BEEP))
|
||||
write(SHTTY, "\07", 1);
|
||||
}
|
||||
|
||||
|
|
@ -3150,6 +3173,22 @@ dquotedzputs(char const *s, FILE *stream)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Decode a key string, turning it into the literal characters.
|
||||
* The length is returned in len.
|
||||
* fromwhere determines how the processing works.
|
||||
* 0: Don't handle keystring, just print-like escapes.
|
||||
* Expects misc to be present.
|
||||
* 1: Handle Emacs-like \C-X arguments etc., but not ^X
|
||||
* Expects misc to be present.
|
||||
* 2: Handle ^X as well as emacs-like keys; don't handle \c
|
||||
* for no newlines.
|
||||
* 3: As 1, but don't handle \c.
|
||||
* 4: Do $'...' quoting. Overwrites the existing string instead of
|
||||
* zhalloc'ing
|
||||
* 5: As 2, but \- is special. Expects misc to be defined.
|
||||
*/
|
||||
|
||||
/**/
|
||||
char *
|
||||
getkeystring(char *s, int *len, int fromwhere, int *misc)
|
||||
|
|
|
|||
|
|
@ -3,3 +3,4 @@ comp1
|
|||
zle
|
||||
compctl
|
||||
sched
|
||||
complist
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ addconddefs
|
|||
addedx
|
||||
addhashnode
|
||||
addhistnum
|
||||
addhookdefs
|
||||
addhookfunc
|
||||
addparamdefs
|
||||
addwrapper
|
||||
arrvargetfn
|
||||
|
|
@ -43,6 +45,8 @@ current_limits
|
|||
deletebuiltins
|
||||
deleteconddefs
|
||||
deletehashtable
|
||||
deletehookdefs
|
||||
deletehookfunc
|
||||
deleteparamdefs
|
||||
deleteparamtable
|
||||
deletewrapper
|
||||
|
|
@ -83,6 +87,7 @@ gethashnode2
|
|||
gethparam
|
||||
getintvalue
|
||||
getiparam
|
||||
getkeyptr
|
||||
getkeystring
|
||||
getlinknode
|
||||
getpermtext
|
||||
|
|
@ -206,6 +211,7 @@ resetneeded
|
|||
restoredir
|
||||
reswdtab
|
||||
retflag
|
||||
runhookdef
|
||||
runshfunc
|
||||
scancountparams
|
||||
scanhashtable
|
||||
|
|
|
|||
45
Src/zsh.h
45
Src/zsh.h
|
|
@ -226,6 +226,7 @@ enum {
|
|||
#define INP_HIST (1<<2) /* expanding history */
|
||||
#define INP_CONT (1<<3) /* continue onto previously stacked input */
|
||||
#define INP_ALCONT (1<<4) /* stack is continued from alias expn. */
|
||||
#define INP_LINENO (1<<5) /* update line number */
|
||||
|
||||
/* Flags for metafy */
|
||||
#define META_REALLOC 0
|
||||
|
|
@ -277,6 +278,7 @@ typedef struct heapstack *Heapstack;
|
|||
typedef struct histent *Histent;
|
||||
typedef struct forcmd *Forcmd;
|
||||
typedef struct autofn *AutoFn;
|
||||
typedef struct hookdef *Hookdef;
|
||||
|
||||
typedef struct asgment *Asgment;
|
||||
|
||||
|
|
@ -886,6 +888,22 @@ struct module {
|
|||
#define MOD_UNLOAD (1<<1)
|
||||
#define MOD_SETUP (1<<2)
|
||||
|
||||
/* C-function hooks */
|
||||
|
||||
typedef int (*Hookfn) _((Hookdef, void *));
|
||||
|
||||
struct hookdef {
|
||||
Hookdef next;
|
||||
char *name;
|
||||
Hookfn def;
|
||||
int flags;
|
||||
LinkList funcs;
|
||||
};
|
||||
|
||||
#define HOOKF_ALL 1
|
||||
|
||||
#define HOOKDEF(name, func, flags) { NULL, name, (Hookfn) func, flags, NULL }
|
||||
|
||||
/* node used in parameter hash table (paramtab) */
|
||||
|
||||
struct param {
|
||||
|
|
@ -958,12 +976,13 @@ struct param {
|
|||
#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_SPECIAL (1<<13) /* special builtin parameter */
|
||||
#define PM_DONTIMPORT (1<<14) /* do not import this variable */
|
||||
#define PM_RESTRICTED (1<<15) /* cannot be changed in restricted mode */
|
||||
#define PM_UNSET (1<<16) /* has null value */
|
||||
#define PM_REMOVABLE (1<<17) /* special can be removed from paramtab */
|
||||
#define PM_AUTOLOAD (1<<18) /* autoloaded from module */
|
||||
#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 */
|
||||
|
||||
/* Flags for extracting elements of arrays and associative arrays */
|
||||
#define SCANPM_WANTVALS (1<<0)
|
||||
|
|
@ -1201,6 +1220,7 @@ enum {
|
|||
LISTBEEP,
|
||||
LISTTYPES,
|
||||
LOCALOPTIONS,
|
||||
LOCALTRAPS,
|
||||
LOGINSHELL,
|
||||
LONGLISTJOBS,
|
||||
MAGICEQUALSUBST,
|
||||
|
|
@ -1358,7 +1378,8 @@ struct ttyinfo {
|
|||
/* Definitions for the %_ prompt escape */
|
||||
/****************************************/
|
||||
|
||||
#define cmdpush(X) if (!(cmdsp >= 0 && cmdsp < 256)) {;} else cmdstack[cmdsp++]=(X)
|
||||
#define CMDSTACKSZ 256
|
||||
#define cmdpush(X) if (!(cmdsp >= 0 && cmdsp < CMDSTACKSZ)) {;} else cmdstack[cmdsp++]=(X)
|
||||
#ifdef DEBUG
|
||||
# define cmdpop() if (cmdsp <= 0) { \
|
||||
fputs("BUG: cmdstack empty\n", stderr); \
|
||||
|
|
@ -1491,9 +1512,13 @@ struct heap {
|
|||
|
||||
/* These used in the sigtrapped[] array */
|
||||
|
||||
#define ZSIG_TRAPPED (1<<0)
|
||||
#define ZSIG_IGNORED (1<<1)
|
||||
#define ZSIG_FUNC (1<<2)
|
||||
#define ZSIG_TRAPPED (1<<0) /* Signal is trapped */
|
||||
#define ZSIG_IGNORED (1<<1) /* Signal is ignored */
|
||||
#define ZSIG_FUNC (1<<2) /* Trap is a function, not an eval list */
|
||||
/* Mask to get the above flags */
|
||||
#define ZSIG_MASK (ZSIG_TRAPPED|ZSIG_IGNORED|ZSIG_FUNC)
|
||||
/* No. of bits to shift local level when storing in sigtrapped */
|
||||
#define ZSIG_SHIFT 3
|
||||
|
||||
/**********************************/
|
||||
/* Flags to third argument of zle */
|
||||
|
|
|
|||
|
|
@ -397,6 +397,154 @@ builtins and condition codes:
|
|||
...
|
||||
}
|
||||
|
||||
Modules can also define function hooks. Other modules can then add
|
||||
functions to these hooks to make the first module call these functions
|
||||
instead of the default.
|
||||
|
||||
Again, an array is used to define hooks:
|
||||
|
||||
static struct hookdef foohooks[] = {
|
||||
HOOKDEF("foo", foofunc, 0),
|
||||
};
|
||||
|
||||
The first argument of the macro is the name of the hook. This name
|
||||
is used whenever the hook is used. The second argument is the default
|
||||
function for the hook or NULL if no default function exists. The
|
||||
last argument is used to define flags for the hook. Currently only one
|
||||
such flag is defined: `HOOKF_ALL'. If this flag is given and more than
|
||||
one function was added to the hook, all functions will be called
|
||||
(including the default function). Otherwise only the last function
|
||||
added will be called.
|
||||
|
||||
The functions that can be used as default functions or that can be
|
||||
added to a hook have to be defined like:
|
||||
|
||||
/**/
|
||||
static int
|
||||
foofunc(Hookdef h, void *data)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
The first argument is a pointer to the struct defining the hook. The
|
||||
second argument is an arbitrary pointer that is given to the function
|
||||
used to invoke hooks (see below).
|
||||
|
||||
The functions to register and de-register hooks look like those for
|
||||
the other things that can be defined by modules:
|
||||
|
||||
/**/
|
||||
int
|
||||
boot_foo(Module m)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = addhookdefs(m->nam, foohooks, sizeof(foohooks)/sizeof(*foohooks))
|
||||
...
|
||||
}
|
||||
...
|
||||
/**/
|
||||
int
|
||||
cleanup_foo(Module m)
|
||||
{
|
||||
deletehookdefs(m->nam, foohooks, sizeof(foohooks)/sizeof(*foohooks));
|
||||
...
|
||||
}
|
||||
|
||||
Modules that define hooks can invoke the function(s) registered for
|
||||
them by calling the function `runhook(name, data)'. The first argument
|
||||
is the name of the hook and the second one is the pointer given to the
|
||||
hook functions as their second argument. Hooks that have the `HOOKF_ALL'
|
||||
flag call all function defined for them until one returns non-zero.
|
||||
The return value of `runhook()' is the return value of the last hook
|
||||
function called or zero if none was called.
|
||||
|
||||
To add a function to a hook, the function `addhookfunc(name, func)' is
|
||||
called with the name of the hook and a hook function as arguments.
|
||||
Deleting them is done by calling `deletehookfunc(name, func)' with the
|
||||
same arguments as for the corresponding call to `addhookfunc()'.
|
||||
|
||||
Alternative forms of the last three function are provided for hooks
|
||||
that are changed or called very often. These functions,
|
||||
`runhookdef(def, data)', `addhookdeffunc(def, func)', and
|
||||
`deletehookdeffunc(def, func)' get a pointer to the `hookdef'
|
||||
structure defining the hook instead of the name and otherwise behave
|
||||
like their counterparts.
|
||||
|
||||
Modules can also define function hooks. Other modules can then add
|
||||
functions to these hooks to make the first module call these functions
|
||||
instead of the default.
|
||||
|
||||
Again, an array is used to define hooks:
|
||||
|
||||
static struct hookdef foohooks[] = {
|
||||
HOOKDEF("foo", foofunc, 0),
|
||||
};
|
||||
|
||||
The first argument of the macro is the name of the hook. This name
|
||||
is used whenever the hook is used. The second argument is the default
|
||||
function for the hook or NULL if no default function exists. The
|
||||
last argument is used to define flags for the hook. Currently only one
|
||||
such flag is defined: `HOOKF_ALL'. If this flag is given and more than
|
||||
one function was added to the hook, all functions will be called
|
||||
(including the default function). Otherwise only the last function
|
||||
added will be called.
|
||||
|
||||
The functions that can be used as default functions or that can be
|
||||
added to a hook have to be defined like:
|
||||
|
||||
/**/
|
||||
static int
|
||||
foofunc(Hookdef h, void *data)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
The first argument is a pointer to the struct defining the hook. The
|
||||
second argument is an arbitrary pointer that is given to the function
|
||||
used to invoke hooks (see below).
|
||||
|
||||
The functions to register and de-register hooks look like those for
|
||||
the other things that can be defined by modules:
|
||||
|
||||
/**/
|
||||
int
|
||||
boot_foo(Module m)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = addhookdefs(m->nam, foohooks, sizeof(foohooks)/sizeof(*foohooks))
|
||||
...
|
||||
}
|
||||
...
|
||||
/**/
|
||||
int
|
||||
cleanup_foo(Module m)
|
||||
{
|
||||
deletehookdefs(m->nam, foohooks, sizeof(foohooks)/sizeof(*foohooks));
|
||||
...
|
||||
}
|
||||
|
||||
Modules that define hooks can invoke the function(s) registered for
|
||||
them by calling the function `runhook(name, data)'. The first argument
|
||||
is the name of the hook and the second one is the pointer given to the
|
||||
hook functions as their second argument. Hooks that have the `HOOKF_ALL'
|
||||
flag call all function defined for them until one returns non-zero.
|
||||
The return value of `runhook()' is the return value of the last hook
|
||||
function called or zero if none was called.
|
||||
|
||||
To add a function to a hook, the function `addhookfunc(name, func)' is
|
||||
called with the name of the hook and a hook function as arguments.
|
||||
Deleting them is done by calling `deletehookfunc(name, func)' with the
|
||||
same arguments as for the corresponding call to `addhookfunc()'.
|
||||
|
||||
Alternative forms of the last three function are provided for hooks
|
||||
that are changed or called very often. These functions,
|
||||
`runhookdef(def, data)', `addhookdeffunc(def, func)', and
|
||||
`deletehookdeffunc(def, func)' get a pointer to the `hookdef'
|
||||
structure defining the hook instead of the name and otherwise behave
|
||||
like their counterparts.
|
||||
|
||||
Finally, modules can define wrapper functions. These functions are
|
||||
called whenever a shell function is to be executed.
|
||||
|
||||
|
|
|
|||
|
|
@ -598,7 +598,8 @@ main() { return sizeof(ino_t) < 8; }
|
|||
if test "x$enable_lfs" != xno -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" != xyes -a "x$enable_lfs" != xno; then
|
||||
[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)
|
||||
else
|
||||
zsh_64_BIT_TYPE(long long, zsh_cv_64_bit_type)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue