我开发了一个zsh插件,它是vi仿真模式下zsh的vim-easymotion移植。由于zsh的行编辑器具有多行支持,因此我增加了对行运动(j
和k
)的支持。该插件还应该在vi操作符挂起模式下工作(例如,在删除模式下),因此我使用zsh的MARK
andCURSOR
变量将用户选择范围扩展到整行(因此,行运动将始终删除或更改整行,而不仅仅是部分行)其中的)。这是vim用户期望的行为。但是,更改/删除操作后的光标位置错误。光标应在已删除的行块之后的下一行的第一个单词上。相反,光标在最后一行的末尾之前线段。我看不到在操作员挂起模式后更改光标的可能性,因为任何光标更改都将成为所选操作员区域的一部分。
所以我的问题是:有人知道执行vi运算符后如何在zsh自定义小部件中更改光标位置吗?
更新:
为了使问题易于理解,我尝试创建一个最小的问题示例:
这个小的zsh脚本可以通过以下方式获得:
function test-widget () {
MARK=3
CURSOR=6
}
zle -N test-widget
bindkey -M vicmd ' ' test-widget
如果您处于zsh的vicmd / normal模式(bindkey -v
激活vi仿真并<esc>
进入命令模式),现在可以按<space>
将光标设置为当前编辑缓冲区中的第六个字符。如果输入vi操作符(如d
后接)<space>
,则从第三个字符到第六个字符的所有内容都将被删除(由于MARK
变量的设置)。
删除示例:考虑您的编辑缓冲区是(标有的光标位置[]
):
[a]bc def ghi
然后按d<space>
,您将得到:
abc[f] ghi
但是,我想在相同的小部件调用中执行删除操作后更改光标的位置,例如:
abcf [g]hi
我不知道这怎么可能,因为所有更改CURSOR
都会影响已删除文本的范围。
如何实现删除操作+光标定位?
这听起来我你将不得不重新定义采取动作,如绑定到那些小部件d
,c
,y
,gu
,gU
,g~
...
就像是:
test-widget () {
MARK=3
CURSOR=6
MOVE_AFTER_MOTION=2
}
zle -N test-widget
bindkey -M vicmd ' ' test-widget
for widget in vi-{delete,change,yank,{down,oper-swap,up}-case}; do
$widget () {
local ret
zle ".$WIDGET"; ret=$?
if (($+MOVE_AFTER_MOTION)); then
(( CURSOR += MOVE_AFTER_MOTION ))
unset MOVE_AFTER_MOTION
fi
return "$ret"
}
zle -N $widget
done
您可能还必须考虑$NUMERIC
不在1时该怎么办。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句