From 59c3d242d546059cad473f1155ad0e350fe45260 Mon Sep 17 00:00:00 2001 From: Tanaka Akira Date: Mon, 12 Jul 1999 17:02:52 +0000 Subject: Initial revision --- Completion/Commands/_history_complete_word | 2 + Completion/Commands/_read_comp | 158 +++++++++++++++++++++++++++++ Completion/User/_use_lo | 10 ++ Config/funcinst.mk | 47 +++++++++ Config/installfns.sh | 48 +++++++++ Config/uninstallfns.sh | 31 ++++++ Functions/Zle/.distfiles | 3 + Functions/Zle/incremental-complete-word | 89 ++++++++++++++++ Functions/Zle/insert-files | 42 ++++++++ Misc/job-control-tests | 31 ++++++ 10 files changed, 461 insertions(+) create mode 100644 Completion/Commands/_history_complete_word create mode 100644 Completion/Commands/_read_comp create mode 100644 Completion/User/_use_lo create mode 100644 Config/funcinst.mk create mode 100755 Config/installfns.sh create mode 100755 Config/uninstallfns.sh create mode 100644 Functions/Zle/.distfiles create mode 100644 Functions/Zle/incremental-complete-word create mode 100644 Functions/Zle/insert-files create mode 100644 Misc/job-control-tests diff --git a/Completion/Commands/_history_complete_word b/Completion/Commands/_history_complete_word new file mode 100644 index 000000000..fc67c0f14 --- /dev/null +++ b/Completion/Commands/_history_complete_word @@ -0,0 +1,2 @@ +#compdef -k complete-word \e/ +compgen -Q -H 0 '' diff --git a/Completion/Commands/_read_comp b/Completion/Commands/_read_comp new file mode 100644 index 000000000..a32879b56 --- /dev/null +++ b/Completion/Commands/_read_comp @@ -0,0 +1,158 @@ +#compdef -k complete-word \C-x\C-r + +# This allows an on-the-fly choice of completions. On typing the key +# sequence given above, you will be prompted for a string of arguments. If +# this string begins with `_', it will be taken as the name of a function to +# evaluate to generate the completions; unambiguous strings in the function +# name are automatically completed. +# +# Else it is taken to be a set of arguments for compgen to generate a list +# of choices. The possibilities are the same as the flags for generating +# completions given in the zshcompctl manual page. Note the arguments are +# verbatim: include minus signs, spaces, quotes, etc. +# +# On subsequent calls, the same completion will be re-performed. To +# force a new type of completion to be read, supply a numeric argument. +# +# For example, +# % bindkey | grep rever +# Completion: -b +# % bindkey | grep reverse-menu-complete _ +# +# Global variables used: +# _read_comp Last completion string read from user + +emulate -L zsh +setopt extendedglob nobadpattern # xtrace promptsubst +# local PS4='%N:%i:$((#key))> ' + +# Took me ages to work this out. If we're not on the first global +# matcher specification, we mustn't do any I/O. +if [[ compstate[matcher] -gt 1 && -z $_read_comp ]]; then + return 1 +fi + +if [[ compstate[matcher] -gt 1 || + ( ${+NUMERIC} = 0 && -n $_read_comp ) ]]; then + if [[ $_read_comp = _* ]]; then + eval $_read_comp + else + eval "compgen $_read_comp" + fi + return +fi + +_read_comp= + +local key search str str2 newch funcs funcs2 exact msg list +integer pos + +msg="Completion: " + +zle -R $msg + +if ! read -k key; then + zle -cR '' + return 1 +fi + +while [[ '#key' -ne 10 && '#key' -ne 13 ]]; do + if [[ '#key' -eq 0 && '#key' -eq 3 || '#key' -eq 7 ]]; then + zle -cR '' + return 1 + fi + if [[ ( '#key' -eq 8 || '#key' -eq 127 ) && -n $str ]]; then + # delete character + str="$str[1,-2]" + exact= + list=() + elif [[ '#key' -eq 21 ]]; then + # ^U: delete line + str= + exact= + list=() + elif [[ '#key' -eq 4 && $str = _[^\ ]# && $str != *' '* ]]; then + # ^D: list completions + list=(${$(whence -m "$str*" 2>/dev/null)%: function}) + elif [[ ( -n $exact && $key != ' ' ) || '#key & 127' -lt 32 ]]; then + # If we've got an exact function, only allow a space after it. + # Don't try to insert non-printing characters. + if [[ -n $ZBEEP ]]; then + print -nb $ZBEEP + elif [[ -o beep ]]; then + print -n "\a" + fi + list=() + else + str="$str$key" + if [[ $str = _[^\ ]# ]]; then + # Rudimentary completion for function names. + # Allow arguments, i.e. don't do this after we've got a space. + funcs=(${$(whence -m "$str*" 2>/dev/null)%: function}) + if [[ -o autolist && $#str -gt 1 ]]; then + list=($funcs) + else + list=() + fi + if (( $#funcs == 1 )); then + # Exact match; prompt the user for a newline to confirm + str=$funcs[1] + exact=" (Confirm)" + elif (( $#funcs == 0 )); then + # We can't call zle beep, because this isn't a zle widget. + if [[ -n $ZBEEP ]]; then + print -nb $ZBEEP + elif [[ -o beep ]]; then + print -n "\a" + fi + str="$str[1,-2]" + list=() + else + # Add characters to the string until a name doesn't + # match any more, then backtrack one character to get + # the longest unambiguous match. + str2=$str + pos=$#str2 + while true; do + (( pos++ )) + newch=${funcs[1][pos]} + [[ -z $newch ]] && break + str2=$str2$newch + funcs2=(${funcs##$str2*}) + (( $#funcs2 )) && break + str=$str2 + done + fi + else + exact= + fi + fi + if (( $#list )); then + zle -R "$msg$str$exact" $list + else + zle -cR "$msg$str$exact" + fi + if ! read -k key; then + zle -cR '' + return 1 + fi +done + +if [[ -z $str ]]; then + # string must be non-zero + return 1 +elif [[ $str = _* ]] && ! whence ${str%% *} >& /dev/null; then + # a function must be known to the shell + return 1 +else + # remember the string for re-use + _read_comp=$str +fi + +zle -cR '' + +if [[ $str = _* ]]; then + eval $str +else + eval "compgen $str" +fi diff --git a/Completion/User/_use_lo b/Completion/User/_use_lo new file mode 100644 index 000000000..e469154ea --- /dev/null +++ b/Completion/User/_use_lo @@ -0,0 +1,10 @@ +#compdef gls gdiff + +# This is for GNU-like commands which understand the --help option, +# but which do not otherwise require special completion handling. + +if [[ $PREFIX = --* ]]; then + _long_options +else + _default +fi diff --git a/Config/funcinst.mk b/Config/funcinst.mk new file mode 100644 index 000000000..e473eb351 --- /dev/null +++ b/Config/funcinst.mk @@ -0,0 +1,47 @@ +# +# Makefile definitions for installing shell functions +# +# Copyright (c) 1999 Peter Stephenson +# All rights reserved. +# +# Permission is hereby granted, without written agreement and without +# license or royalty fees, to use, copy, modify, and distribute this +# software and to distribute modified versions of this software for any +# purpose, provided that the above copyright notice and the following +# two paragraphs appear in all copies of this software. +# +# In no event shall Peter Stephenson or the Zsh Development Group be liable +# to any party for direct, indirect, special, incidental, or consequential +# damages arising out of the use of this software and its documentation, +# even if Peter Stephenson and the Zsh Development Group have been advised of +# the possibility of such damage. +# +# Peter Stephenson and the Zsh Development Group specifically disclaim any +# warranties, including, but not limited to, the implied warranties of +# merchantability and fitness for a particular purpose. The software +# provided hereunder is on an "as is" basis, and Peter Stephenson and the +# Zsh Development Group have no obligation to provide maintenance, +# support, updates, enhancements, or modifications. +# + +# install functions, including those in subdirectories, creating +# install directory if necessary + +install.fns: + if test x$(fndir) != x && test x$(fndir) != xno; then \ + sdir_top="$(sdir_top)" fndir="$(fndir)" sdir="$(sdir)" \ + FUNCTIONS_INSTALL="$(FUNCTIONS_INSTALL)" \ + FUNCTIONS_SUBDIRS="$(FUNCTIONS_SUBDIRS)" \ + INSTALL_DATA="$(INSTALL_DATA)" \ + $(SHELL) $(sdir_top)/Config/installfns.sh || exit 1; \ + fi; \ + exit 0 + +uninstall.fns: + if test x$(fndir) != x && test x$(fndir) != xno; then \ + fndir="$(fndir)" sdir="$(sdir)" \ + FUNCTIONS_INSTALL="$(FUNCTIONS_INSTALL)" \ + FUNCTIONS_SUBDIRS="$(FUNCTIONS_SUBDIRS)" \ + $(SHELL) $(sdir_top)/Config/uninstallfns.sh || exit 1; \ + fi; \ + exit 0 diff --git a/Config/installfns.sh b/Config/installfns.sh new file mode 100755 index 000000000..de7a52bce --- /dev/null +++ b/Config/installfns.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +if test -d $fndir.old; then + add_old=1 +fi + +$sdir_top/mkinstalldirs $fndir || exit 1; + +# If the source directory is somewhere else, we need to force +# the shell to expand it in that directory, then strip it off. +install= +for file in $FUNCTIONS_INSTALL; do + if test -f "$sdir/$file"; then + install="$install $file" + else + install="$install `echo $sdir/$file | sed -e \"s%$sdir/%%g\"`" + fi +done + +for file in $install; do + if test -f $sdir/$file; then + if test x$FUNCTIONS_SUBDIRS != x -a x$FUNCTIONS_SUBDIRS != xno; then + subfile="$file" + subdir="`echo $file | sed -e 's%/[^/]*$%%'`" + olddir="$fndir.old/$subdir" + instdir="$fndir/$subdir" + else + subfile="`echo $file | sed -e 's%^.*/%%'`" + olddir="$fndir.old" + instdir="$fndir" + fi + if test -f $fndir/$subfile; then + if cmp $fndir/$subfile $sdir/$file >/dev/null; then :; else + $sdir_top/mkinstalldirs $olddir + mv $fndir/$subfile $olddir + : ${add_old:=1} + fi + fi + $sdir_top/mkinstalldirs $instdir || exit 1 + $INSTALL_DATA $sdir/$file $instdir || exit 1 + fi +done + +if test x$add_old != x1; then + rm -rf $fndir.old +fi + +exit 0 diff --git a/Config/uninstallfns.sh b/Config/uninstallfns.sh new file mode 100755 index 000000000..ae1b4fef5 --- /dev/null +++ b/Config/uninstallfns.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +# If the source directory is somewhere else, we need to force +# the shell to expand it in that directory, then strip it off. +install= +for file in $FUNCTIONS_INSTALL; do + if test -f "$sdir/$file"; then + install="$install $file" + else + install="$install `echo $sdir/$file | sed -e \"s%$sdir/%%g\"`" + fi +done + +for file in $install; do + if test -f $sdir/$file; then + if test x$FUNCTIONS_SUBDIRS != x -a x$FUNCTIONS_SUBDIRS != xno; then + rm -f $fndir/$file; + if test -f $fndir.old/$file; then + mv $fndir.old/$file $fndir/$file + fi + else + bfile="`echo $file | sed -e 's%^.*/%%'`" + rm -f "$fndir/$bfile"; \ + if test -f $fndir.old/$bfile; then + mv $fndir.old/$bfile $fndir/$bfile + fi + fi + fi +done + +exit 0 diff --git a/Functions/Zle/.distfiles b/Functions/Zle/.distfiles new file mode 100644 index 000000000..429c133a0 --- /dev/null +++ b/Functions/Zle/.distfiles @@ -0,0 +1,3 @@ +DISTFILES_SRC=' + .distfiles incremental-complete-word insert-files +' diff --git a/Functions/Zle/incremental-complete-word b/Functions/Zle/incremental-complete-word new file mode 100644 index 000000000..2a9c1aff2 --- /dev/null +++ b/Functions/Zle/incremental-complete-word @@ -0,0 +1,89 @@ +# incremental-complete-word() { + +# Autoload this function, run `zle -N ' and bind +# to a key. + +# This allows incremental completion of a word. After starting this +# command, a list of completion choices is shown after every character you +# type, which you can delete with ^h or DEL. RET will accept the +# completion so far. You can hit TAB to do normal completion and ^g to +# abort back to the state when you started. +# +# Completion keys: +# incremental_prompt Prompt to show in status line during icompletion; +# the sequence `%u' is replaced by the unambiguous +# part of all matches if there is any and it is +# different from the word on the line +# incremental_stop Pattern matching keys which will cause icompletion +# to stop and the key to be re-executed +# incremental_break Pattern matching keys which will cause icompletion +# to stop and the key to be discarded +# incremental_completer Set of completers, like the `completer' key +# incremental_list If set to a non-empty string, the matches will be +# listed on every key-press + +emulate -L zsh +unsetopt autolist menucomplete automenu # doesn't work well + +local key lbuf="$LBUFFER" rbuf="$RBUFFER" pmpt word lastl lastr wid twid + +[[ -n "$compconfig[incremental_completer]" ]] && +set ${(s.:.)compconfig[incremental_completer]} +pmpt="${compconfig[incremental_prompt]-incremental completion...}" + +if [[ -n "$compconfig[incremental_list]" ]]; then + wid=list-choices +else + wid=complete-word +fi + +zle $wid "$@" +LBUFFER="$lbuf" +RBUFFER="$rbuf" +if [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then + word='' +else + word="${_lastcomp[unambiguous]}" +fi +zle -R "${pmpt//\\%u/$word}" +read -k key + +while [[ '#key' -ne '#\\r' && '#key' -ne '#\\n' && + '#key' -ne '#\\C-g' ]]; do + twid=$wid + if [[ "$key" = ${~compconfig[incremental_stop]} ]]; then + zle -U "$key" + return + elif [[ "$key" = ${~compconfig[incremental_break]} ]]; then + return + elif [[ '#key' -eq '#\\C-h' || '#key' -eq '#\\C-?' ]]; then + [[ $#LBUFFER -gt $#l ]] && LBUFFER="$LBUFFER[1,-2]" + elif [[ '#key' -eq '#\\t' ]]; then + zle complete-word "$@" + lbuf="$LBUFFER" + rbuf="$RBUFFER" + elif [[ '#key' -eq '#\\C-d' ]]; then + twid=list-choices + else + LBUFFER="$LBUFFER$key" + fi + lastl="$LBUFFER" + lastr="$RBUFFER" + zle $twid "$@" + LBUFFER="$lastl" + RBUFFER="$lastr" + if [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then + word='' + else + word="${_lastcomp[unambiguous]}" + fi + zle -R "${pmpt//\\%u/$word}" + read -k key +done + +if [[ '#key' -eq '#\\C-g' ]]; then + LBUFFER="$lbuf" + RBUFFER="$rbuf" +fi +zle -Rc +# } diff --git a/Functions/Zle/insert-files b/Functions/Zle/insert-files new file mode 100644 index 000000000..10f90ed4a --- /dev/null +++ b/Functions/Zle/insert-files @@ -0,0 +1,42 @@ +# insert-files() { + +# Autoload this function, run `zle -N ' and bind +# to a key. + +# This function allows you type a file pattern, and see the results of the +# expansion at each step. When you hit return, they will be inserted into +# the command line. + +emulate -L zsh +setopt nobadpattern + +local key str files + +files=( *(N) ) +if (( $#files )); then + zle -R "files: ${str}_" "$files[@]" +else + zle -R "files: ${str}_ (failed)" +fi +read -k key +while [[ '#key' -ne '#\\r' && '#key' -ne '#\\n' && + '#key' -ne '#\\C-g' ]]; do + if [[ '#key' -eq '#\\C-h' || '#key' -eq '#\\C-?' ]]; then + [[ -n "$str" ]] && str="$str[1,-2]" + else + str="$str$key" + fi + eval "files=( \${~str}*(N) )" + if (( $#files )); then + zle -R "files: ${str}_" "$files[@]" + else + zle -R "files: ${str}_ (failed)" + fi + read -k key +done +zle -Rc +if [[ '#key' -ne '#\\C-g' && $#files -gt 0 ]]; then + [[ "$LBUFFER[-1]" = ' ' ]] || files=('' "$files[@]") + LBUFFER="$LBUFFER$files " +fi +# } diff --git a/Misc/job-control-tests b/Misc/job-control-tests new file mode 100644 index 000000000..7e35fba0b --- /dev/null +++ b/Misc/job-control-tests @@ -0,0 +1,31 @@ +# These are some tests for the job control code. The code chunks +# have to be run interactively. Some use files in the zsh distribution. + +# Try +# ^Z +# fg +if true; then cat Src/builtin.c | less; fi + +# Try +# ^Z +# fg +fn() { + if true; then cat Src/builtin.c | less; fi +} +fn + +# Try +# ^Z +# fg +# ^C +# then +# ^Z +# bg +# kill +while true; do sed -e 's/foo/bar/' Src/builtin.c >/dev/null; done + +# Try +# ^C +# ignoring the error messages from sed. +# ^Z is more of a problem since you have to catch the sed. +while true; do sed -e 's/foo/bar/' non-existent-file >/dev/null; done -- cgit 1.4.1