mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-01 05:16:05 +01:00
38929: new vim style text object using match-words-by-style mechanism
This commit is contained in:
parent
dfd8b1da4f
commit
932ff2b6f8
3 changed files with 132 additions and 4 deletions
|
@ -1,5 +1,8 @@
|
|||
2016-07-24 Oliver Kiddle <opk@zsh.org>
|
||||
|
||||
* 38929: Doc/Zsh/contrib.yo, Functions/Zle/select-word-match:
|
||||
new vim style text object using match-words-by-style mechanism
|
||||
|
||||
* 38935: Matthew Martin: Completion/Unix/Command/_tcpdump:
|
||||
update for Free and Open BSD
|
||||
|
||||
|
|
|
@ -1940,6 +1940,8 @@ tindex(transpose-words-match)
|
|||
tindex(capitalize-word-match)
|
||||
tindex(up-case-word-match)
|
||||
tindex(down-case-word-match)
|
||||
tindex(delete-whole-word-match)
|
||||
tindex(select-word-match)
|
||||
tindex(select-word-style)
|
||||
tindex(match-word-context)
|
||||
tindex(match-words-by-style)
|
||||
|
@ -1947,12 +1949,14 @@ xitem(tt(forward-word-match), tt(backward-word-match))
|
|||
xitem(tt(kill-word-match), tt(backward-kill-word-match))
|
||||
xitem(tt(transpose-words-match), tt(capitalize-word-match))
|
||||
xitem(tt(up-case-word-match), tt(down-case-word-match))
|
||||
xitem(tt(delete-whole-word-match), tt(select-word-match))
|
||||
item(tt(select-word-style), tt(match-word-context), tt(match-words-by-style))(
|
||||
The eight `tt(-match)' functions are drop-in replacements for the
|
||||
The first eight `tt(-match)' functions are drop-in replacements for the
|
||||
builtin widgets without the suffix. By default they behave in a similar
|
||||
way. However, by the use of styles and the function tt(select-word-style),
|
||||
the way words are matched can be altered. For comparison, the widgets
|
||||
described in ifzman(zmanref(zshzle) under Text Objects)\
|
||||
the way words are matched can be altered. tt(select-word-match) is intended
|
||||
to be used as a text object in vi mode but with custom word styles. For
|
||||
comparison, the widgets described in ifzman(zmanref(zshzle) under Text Objects)\
|
||||
ifnzman(noderef(Text Objects)) use fixed definitions of words, compatible
|
||||
with the tt(vim) editor.
|
||||
|
||||
|
@ -1960,7 +1964,7 @@ The simplest way of configuring the functions is to use
|
|||
tt(select-word-style), which can either be called as a normal function with
|
||||
the appropriate argument, or invoked as a user-defined widget that will
|
||||
prompt for the first character of the word style to be used. The first
|
||||
time it is invoked, the eight tt(-match) functions will automatically
|
||||
time it is invoked, the first eight tt(-match) functions will automatically
|
||||
replace the builtin versions, so they do not need to be loaded explicitly.
|
||||
|
||||
The word styles available are as follows. Only the first character
|
||||
|
|
121
Functions/Zle/select-word-match
Normal file
121
Functions/Zle/select-word-match
Normal file
|
@ -0,0 +1,121 @@
|
|||
# Select the entire word around the cursor. Intended for use as
|
||||
# a vim-style text object in vi mode but with customisable
|
||||
# word boundaries.
|
||||
#
|
||||
# For example:
|
||||
# autoload -U select-word-match
|
||||
# zle -N select-in-camel select-word-match
|
||||
# bindkey -M viopp ic select-in-camel
|
||||
# zstyle ':zle:*-camel' word-style normal-subword
|
||||
|
||||
emulate -L zsh
|
||||
setopt extendedglob
|
||||
|
||||
local curcontext=:zle:$WIDGET
|
||||
local -a matched_words
|
||||
# Start and end of range of characters
|
||||
integer pos1 pos2 num=${NUMERIC:-1}
|
||||
local style word
|
||||
|
||||
# choose between inner word or a word style of widget
|
||||
for style in $1 ${${WIDGET#*-}[1]} $KEYS[1] "i"; do
|
||||
[[ $style = [ai] ]] && break
|
||||
done
|
||||
|
||||
autoload -Uz match-words-by-style
|
||||
|
||||
while (( num-- )); do
|
||||
if (( MARK > CURSOR )); then
|
||||
# if cursor is at the start of the selection, just move back a word
|
||||
match-words-by-style
|
||||
if [[ $style = i && -n $matched_words[3] ]]; then
|
||||
word=$matched_words[3]
|
||||
else
|
||||
word=$matched_words[2]$matched_words[3]
|
||||
fi
|
||||
if [[ -n $word ]]; then
|
||||
(( CURSOR -= ${#word} ))
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
elif (( MARK >= 0 && MARK < CURSOR )); then
|
||||
# cursor at the end, move forward a word
|
||||
(( CURSOR+1 == $#BUFFER )) && return 1
|
||||
(( CURSOR++ ))
|
||||
match-words-by-style
|
||||
if [[ -n $matched_words[4] ]]; then
|
||||
if [[ $style = i ]]; then
|
||||
# just skip the whitespace
|
||||
word=$matched_words[4]
|
||||
else
|
||||
# skip the whitespace plus word
|
||||
word=$matched_words[4]$matched_words[5]
|
||||
fi
|
||||
else
|
||||
if [[ $style = i ]]; then
|
||||
# skip the word
|
||||
word=$matched_words[5]
|
||||
else
|
||||
# skip word and following whitespace
|
||||
word=$matched_words[5]$matched_words[6]
|
||||
fi
|
||||
fi
|
||||
(( CURSOR += ${#word} - 1 ))
|
||||
else
|
||||
match-words-by-style
|
||||
|
||||
if [[ -n "${matched_words[3]}" ]]; then
|
||||
# There's whitespace before the cursor, so the word we are selecting
|
||||
# starts at the cursor position.
|
||||
pos1=$CURSOR
|
||||
else
|
||||
# No whitespace before us, so select any wordcharacters there.
|
||||
pos1="${#matched_words[1]}"
|
||||
fi
|
||||
|
||||
if [[ -n "${matched_words[4]}" ]]; then
|
||||
if [[ -n "${matched_words[3]}" ]] || (( CURSOR == 0 )); then
|
||||
# whitespace either side, select it
|
||||
(( pos1 = CURSOR - ${#matched_words[3]} ))
|
||||
(( pos2 = CURSOR + ${#matched_words[4]} ))
|
||||
else
|
||||
# There's whitespace at the cursor position, so only select
|
||||
# up to the cursor position.
|
||||
(( pos2 = CURSOR + 1 ))
|
||||
fi
|
||||
else
|
||||
# No whitespace at the cursor position, so select the
|
||||
# current character and any following wordcharacters.
|
||||
(( pos2 = CURSOR + ${#matched_words[5]} ))
|
||||
fi
|
||||
|
||||
if [[ $style = a ]]; then
|
||||
if [[ -n "${matched_words[4]}" && ( -n "${matched_words[3]}" || CURSOR -eq 0 ) ]]; then
|
||||
# in the middle of whitespace so grab a word
|
||||
if [[ -n "${matched_words[5]}" ]]; then
|
||||
(( pos2 += ${#matched_words[5]} )) # preferably the one after
|
||||
else
|
||||
(( pos1 -= ${#matched_words[2]} )) # otherwise the one before
|
||||
fi
|
||||
elif [[ -n "${matched_words[6]}" ]]; then
|
||||
(( pos2 += ${#matched_words[6]} ))
|
||||
elif [[ -n "${matched_words[3]}" ]]; then
|
||||
# couldn't grab whitespace forwards so try backwards
|
||||
(( pos1 -= ${#matched_words[3]} ))
|
||||
elif (( pos1 > 0 )); then
|
||||
# There might have been whitespace before the word
|
||||
(( CURSOR = pos1 ))
|
||||
match-words-by-style
|
||||
if [[ -n "${matched_words[3]}" ]]; then
|
||||
(( pos1 -= ${#matched_words[3]} ))
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
(( MARK = pos1, CURSOR = pos2-1 ))
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $KEYMAP == vicmd ]] && (( !REGION_ACTIVE )); then
|
||||
(( CURSOR++ )) # Need to include cursor position for operators
|
||||
fi
|
Loading…
Reference in a new issue