Thread View: comp.unix.shell
2 messages
2 total messages
Started by Cyrille Lefevre
Thu, 22 Feb 2007 00:05
emacs style completion in ksh93
Author: Cyrille Lefevre
Date: Thu, 22 Feb 2007 00:05
Date: Thu, 22 Feb 2007 00:05
162 lines
5625 bytes
5625 bytes
hi,
this should be rewritten using a state machine, but, for instance, this
satisfy my needs...
handle tab => complete => list [=> esc # => select]
handle esc [ # ~ and esc [[ # as key binding
handle esc # as numeric prefix
ksh93 d (dtksh) vs. ksh93 q/s :
* esc [ # ~ is received as esc [, then #, then ~ under ksh93 d (dtksh)
while it is received as esc [ # ~ under ksh93 q/s
* .sh.edtext is always empty under ksh93 d (dtksh)
so hitting DEL (^D) at first pos does nothing
* esc [[ # is received as esc [[, then # under both ksh93 d/q/s
* cd /path/to esc = esc # esc = is buggy under ksh93 d
admit that the first esc = propose 1) lib/ 2) lib, then
esc 2 esc = replace /path/to by lib/ instead of /path/to/lib/
#!/bin/echo error: only source
#ident @(#) $Header:
/package/cvs/exploitation/util/san/libksh/Attic/ksh93rc,v 1.1.2.4
2007/02/19 17:29:50 cle Exp $
# [[ ${SECONDS} = *[.,]* ]] && . ./.ksh93rc
comp=(
ff=$'\f'
tab=$'\t'
list=$'\E='
comp=$'\E\E'
integer count=0
esc=$'\E'
ednum=
tilde='~'
esc2=$'\E\[\['
edchar=
eof=$'\004'
map=( []= )
)
function comp_emacs {
#printf "<%q-%q:%q:%q>" "${.sh.edchar}" "${.sh.edcol}"
"${#.sh.edtext}" "${.sh.edtext}"
if [[ ${.sh.edchar} == ${comp.tab} ]]; then
if [[ -n ${comp.ednum} ]]; then
comp.count=1
fi
if (( ++comp.count == 1 )); then
.sh.edchar=${comp.comp}; return
elif (( comp.count > 1 )); then
.sh.edchar=${comp.ednum}${comp.list}
comp.ednum=; return
fi
# notreached
elif [[ ${.sh.edchar} != ${comp.ff} ]]
comp.count=0
# fallthrough
fi
if [[ ${.sh.edchar} == ${comp.esc}[0-9] ]]; then
typeset ednum=${comp.ednum}
comp.ednum=${.sh.edchar}
.sh.edchar=${ednum}${comp.edchar}
comp.edchar=; return
elif [[ ${.sh.edchar} == [0-9] ]]; then
# dtksh hack
if [[ -n ${comp.edchar} ]]; then
comp.edchar=${comp.edchar}${.sh.edchar}
.sh.edchar=; return
elif [[ -n ${comp.ednum} ]]; then
comp.ednum=${comp.ednum}${.sh.edchar}
.sh.edchar=; return
fi
# fallthrough
elif [[ ${.sh.edchar} = [A-E] ]]; then
# cygwin hack
if [[ -n ${comp.edchar} ]]; then
.sh.edchar=${comp.edchar}${.sh.edchar}
# fallthrough
fi
fi
# dtksh hack
if [[ ${.sh.edchar} == ${comp.tilde} ]]; then
if [[ -n ${comp.edchar} ]]; then
typeset edmap=${comp.map[${comp.edchar}${comp.tilde}]}
if [[ ${edmap} != ${comp.eof} ]] || \
(( .sh.edcol || ( ! .sh.edcol && ${#.sh.edtext} ) )); then
.sh.edchar=${comp.ednum}${edmap}
comp.ednum= comp.edchar=; return
elif [[ ${edmap} == ${comp.eof} ]] && (( ! .sh.edcol )); then
.sh.edchar=
comp.ednum= comp.edchar=; return
fi
# fallthrough
fi
# cygwin hack
elif [[ ${.sh.edchar} == "${comp.esc2}" ]]; then
comp.edchar=${.sh.edchar}
.sh.edchar=; return
elif [[ -n ${comp.map[${.sh.edchar}]} ]]; then
typeset edmap=${comp.map[${.sh.edchar}]}
if [[ ${edmap} != ${comp.eof} ]] || \
(( .sh.edcol || ( ! .sh.edcol && ${#.sh.edtext} ) )); then
.sh.edchar=${comp.ednum}${edmap}
comp.ednum=; return
elif [[ ${edmap} == ${comp.eof} ]] && (( ! .sh.edcol )); then
.sh.edchar=
comp.ednum=; return
fi
# fallthrough
# dtksh hack
elif [[ -n ${comp.map[${.sh.edchar}${comp.tilde}]} ]]; then
comp.edchar=${.sh.edchar}
.sh.edchar=; return
fi
.sh.edchar=${comp.ednum}${.sh.edchar}
comp.ednum=; return
}
trap comp_emacs KEYBD
function keybind {
typeset c= act=a
while getopts pu c; do act=${c}; done
shift OPTIND-1
case ${act} in
a)
while (( $# > 1 )); do
comp.map[$(printf "$1")]=$(printf "$2")
shift 2
done
;;
p)
for c in ${!comp.map[@]}; do
printf "%-8q => %q\n" "${c}" "${comp.map[${c}]}"
done
;;
u)
if (( $# > 0 )); then
for c; do
unset ${comp.map[$(printf "${c}")]}
done
else
unset comp.map
comp.map=( []= )
fi
;;
esac
}
keybind "\E[A" "\020" "\E[B" "\016" "\E[C" "\006" "\E[D" "\002"
keybind "\EOA" "\020" "\EOB" "\016" "\EOC" "\006" "\EOD" "\002"
keybind "\E[2~" " " "\E[3~" "\004" "\E[1~" "\001" "\E[4~" "\005"
keybind "\E[L" " " "\177" "\004" "\E[H" "\001" "\E[F" "\005"
keybind "\E[5~" "\Eb" "\E[6~" "\Ef" "\E[I" "\Eb" "\E[G" "\Ef"
keybind "\E[11~" "\001man " "\E[[A" "\001man " "\EOP" "\001man "
#keybind -p
Regards, Cordialement,
Cyrille Lefevre.
--
mailto:Cyrille.Lefevre-news%nospam@laposte.net.invalid
supprimer "%nospam% et ".invalid" pour me repondre.
remove "%nospam" and ".invalid" to answer me.
Re: emacs style completion in ksh93
Author: bsh
Date: Fri, 23 Feb 2007 01:50
Date: Fri, 23 Feb 2007 01:50
39 lines
2761 bytes
2761 bytes
Cyrille Lefevre wrote:
> this should be rewritten using a state machine...
Oh no you shouldn't! Or perhaps I should instead say that,
having had much experience in writing state machines, they
are always problematic to debug and maintain. Their use is
almost always a case of having not used the appropriate
software tool, or justified by the primacy of execution speed.
> function comp_emacs {
Thank you! I wish that I could show you my own keybind
example implementing generalized autocompletion, but it's
stuck on another machine's harddrive. It's almost as
complex, and (if I understand your code sufficiently) shows
a design variation that allows binding of (multiple) keystrokes
to the output of a user-specified function. I've attempted a
different algorithm to map character sequences utilizing
hashes with a base 64 numerical radix, instead of the usual
associative array technique, which has limitations, but is
very fast.
I wonder, was this code written in regard to the issue
described in:
https://mailman.research.att.com/pipermail/ast-users/2004q1/000457.html
Obviously, you have seen DGK's keybind example, but
for those in C.U.S. who wish a demonstration example,
see:
http://www.kornshell.com/examples/keybind
A question: have you done GUI coding on dtksh?
Once again, thanks for submitting your code to C.U.S.
I thought _someone_ should respond to this contribution,
but I wanted to resolve the problem of the above keybind
URL being temporarily unavailable, before I posted.
=Brian
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads