mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-01 05:16:05 +01:00
users/17608: use function to modify currrent command line argument
This commit is contained in:
parent
44757a653c
commit
6265394d6b
3 changed files with 51 additions and 17 deletions
|
@ -1,3 +1,9 @@
|
|||
2013-01-24 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* users/17608: Doc/Zsh/contrib.yo,
|
||||
Functions/Zle/modify-current-argument: use function to modify
|
||||
current command line argument.
|
||||
|
||||
2013-01-22 Peter Stephenson <p.stephenson@samsung.com>
|
||||
|
||||
* 30993: Src/subst.c, Test/D04parameter.ztst: parameter
|
||||
|
@ -461,5 +467,5 @@
|
|||
|
||||
*****************************************************
|
||||
* This is used by the shell to define $ZSH_PATCHLEVEL
|
||||
* $Revision: 1.5788 $
|
||||
* $Revision: 1.5789 $
|
||||
*****************************************************
|
||||
|
|
|
@ -2477,15 +2477,22 @@ See the function tt(modify-current-argument), described below, for
|
|||
an example of how to call this function.
|
||||
)
|
||||
tindex(modify-current-argument)
|
||||
item(tt(modify-current-argument) var(expr-using-)tt($ARG))(
|
||||
item(tt(modify-current-argument) [ var(expr-using-)tt($ARG) | var(func) ])(
|
||||
This function provides a simple method of allowing user-defined widgets
|
||||
to modify the command line argument under the cursor (or immediately to the
|
||||
left of the cursor if the cursor is between arguments). The argument
|
||||
should be an expression which when evaluated operates on the shell
|
||||
left of the cursor if the cursor is between arguments).
|
||||
|
||||
The argument can be an expression which when evaluated operates on the shell
|
||||
parameter tt(ARG), which will have been set to the command line argument
|
||||
under the cursor. The expression should be suitably quoted to prevent
|
||||
it being evaluated too early.
|
||||
|
||||
Alternatively, if the argument does not contain the string tt(ARG), it
|
||||
is assumed to be a shell function, to which the current command line
|
||||
argument is passed as the only argument. The function should set the
|
||||
variable tt(REPLY) to the new value for the command line argument.
|
||||
If the function returns non-zero status, so does the calling function.
|
||||
|
||||
For example, a user-defined widget containing the following code
|
||||
converts the characters in the argument under the cursor into all upper
|
||||
case:
|
||||
|
@ -2497,6 +2504,18 @@ or one of the styles of quotes), and replaces it with single quoting
|
|||
throughout:
|
||||
|
||||
example(modify-current-argument '${(qq)${(Q)ARG}}')
|
||||
|
||||
The following performs directory expansion on the command line
|
||||
argument and replaces it by the absolute path:
|
||||
|
||||
example(expand-dir() {
|
||||
REPLY=${~1}
|
||||
REPLY=${REPLY:a}
|
||||
}
|
||||
modify-current-argument expand-dir)
|
||||
|
||||
In practice the function tt(expand-dir) would probably not be defined
|
||||
within the widget where tt(modify-current-argument) is called.
|
||||
)
|
||||
enditem()
|
||||
|
||||
|
|
|
@ -14,24 +14,27 @@
|
|||
setopt localoptions noksharrays multibyte
|
||||
|
||||
local -a reply
|
||||
integer REPLY REPLY2 fromend endoffset
|
||||
integer posword poschar fromend endoffset
|
||||
local REPLY REPLY2
|
||||
|
||||
autoload -Uz split-shell-arguments
|
||||
split-shell-arguments
|
||||
|
||||
(( posword = REPLY, poschar = REPLY2 ))
|
||||
|
||||
# Can't do this unless there's some text under or left of us.
|
||||
(( REPLY < 2 )) && return 1
|
||||
(( posword < 2 )) && return 1
|
||||
|
||||
# Get the index of the word we want.
|
||||
if (( REPLY & 1 )); then
|
||||
if (( posword & 1 )); then
|
||||
# Odd position; need previous word.
|
||||
(( REPLY-- ))
|
||||
(( posword-- ))
|
||||
# Pretend position was just after the end of it.
|
||||
(( REPLY2 = ${#reply[REPLY]} + 1 ))
|
||||
(( poschar = ${#reply[posword]} + 1 ))
|
||||
fi
|
||||
|
||||
# Work out offset from end of string
|
||||
(( fromend = $REPLY2 - ${#reply[REPLY]} - 1 ))
|
||||
(( fromend = $poschar - ${#reply[posword]} - 1 ))
|
||||
if (( fromend >= -1 )); then
|
||||
# Cursor is near the end of the word, we'll try to keep it there.
|
||||
endoffset=1
|
||||
|
@ -39,11 +42,17 @@ fi
|
|||
|
||||
# Length of all characters before current.
|
||||
# Force use of character (not index) counting and join without IFS.
|
||||
integer wordoff="${(cj..)#reply[1,REPLY-1]}"
|
||||
integer wordoff="${(cj..)#reply[1,posword-1]}"
|
||||
|
||||
# Replacement for current word. This could do anything to ${reply[REPLY]}.
|
||||
local ARG="${reply[REPLY]}" repl
|
||||
eval repl=\"$1\"
|
||||
# Replacement for current word. This could do anything to ${reply[posword]}.
|
||||
local ARG="${reply[posword]}" repl
|
||||
if [[ $1 != *ARG* ]]; then
|
||||
REPLY=
|
||||
$1 $ARG || return 1
|
||||
repl=$REPLY
|
||||
else
|
||||
eval repl=\"$1\"
|
||||
fi
|
||||
|
||||
if (( !endoffset )) && [[ ${repl[fromend,-1]} = ${ARG[fromend,-1]} ]]; then
|
||||
# If the part of the string from here to the end hasn't changed,
|
||||
|
@ -54,8 +63,8 @@ fi
|
|||
# New line: all words before and after current word, with
|
||||
# no additional spaces since we've already got the whitespace
|
||||
# and the replacement word in the middle.
|
||||
local left="${(j..)reply[1,REPLY-1]}${repl}"
|
||||
local right="${(j..)reply[REPLY+1,-1]}"
|
||||
local left="${(j..)reply[1,posword-1]}${repl}"
|
||||
local right="${(j..)reply[posword+1,-1]}"
|
||||
|
||||
if [[ endoffset -ne 0 && ${#repl} -ne 0 ]]; then
|
||||
# Place cursor relative to end.
|
||||
|
@ -71,5 +80,5 @@ else
|
|||
integer repmax=$(( ${#repl} + 1 ))
|
||||
# Remember CURSOR starts from offset 0 for some reason, so
|
||||
# subtract 1 from positions.
|
||||
(( CURSOR = wordoff + (REPLY2 > repmax ? repmax : REPLY2) - 1 ))
|
||||
(( CURSOR = wordoff + (poschar > repmax ? repmax : poschar) - 1 ))
|
||||
fi
|
||||
|
|
Loading…
Reference in a new issue