Я использую простой виджет zle print-current-word
чтобы проиллюстрировать, как можно извлечь текущее слово в командной строке в простых случаях, то есть предположить, что пробелы всегда являются разделителями слов. (Таким образом, это терпит неудачу, когда цитирование или экранированные пробелы входят в игру):
print-current-word() {
CURRENTWORD="${LBUFFER/* /}${RBUFFER/ */}"
print; print "The current word is: $CURRENTWORD"
}
zle -N print-current-word
$LBUFFER
и $RBUFFER
содержат командную строку слева и справа от курсора, соответственно.
${name/pattern/repl}
возвращает имя переменной с шаблоном, замененным на repl. Так что в этом случае это обрезает в $LBUFFER
все до последнего пробела, оставляя часть слева от курсора текущего слова. Аналог для $RBUFFER
.
Более сложный подход будет:
print-current-word () {
local words i beginword
i=0
beginword=0
words=("${(z)BUFFER}")
while (( beginword <= CURSOR )); do
(( i++ ))
(( beginword += ${#words[$i]}+1 ))
done
CURRENTWORD="$words[$i]"
print; print "The current word is: $CURRENTWORD"
}
Однако это также не свободно от предположений, так как предполагается, что каждое слово отделено ровно одним пробелом (добавление +1 к beginword
).
Несколько слов о некоторых особых вещах:
words=("${(z)BUFFER}")
разбивает $BUFFER
, то есть полную командную строку, на слова оболочки, используя правила синтаксического анализа оболочки с помощью флага расширения (z)
и помещает его в массив
(( ... ))
активирует математический режим Zsh
${#name}
задает длину имени переменной