首页 > 解决方案 > 点可重复映射从正常模式插入空格并沿移动光标

问题描述

我有一个nnoremap <leader>l i<space><esc>在正常模式下插入空格的映射,并且该映射是点可重复的。但是,光标停留在原来的位置,并且空间“扩展”到光标右侧。

我想要一个做同样但移动光标的映射,例如

nnoremap <leader>h i<space><esc>l

我喜欢在正常模式下用空格打破字符序列,我想随意决定光标应该停留还是移动(使用h移动光标或l将文本向左移动,同时将光标留在原处) .

ior aor or的所有技巧<C-o>似乎都不起作用,这是预期的行为。

是否有任何巧妙的技巧可以nnoremap仅使用来实现点重复性?如果我排在最后,它也应该起作用。

我可能可以这样重新表述它:我希望具有类似于Xand的功能,x它在光标之前或光标处删除单个字符,而不是删除一个字符,我想在光标<space> 之前或光标插入一个字符(而不是在光标之后与a)一样。它应该是点可重复的并且可以计数。最好是在 中使用的映射不超过一行,.vimrc并且不需要任何插件。而且我不想改变将光标向左移动一个字符的行为<esc>(或者i,在离开插入模式时负责移动光标的任何一个)。

编辑1: 点重复nnoremap <leader>l i<space><esc>这样做:

<leader>l...

AAAAAAAAAA[B]BBBBBBBB
AAAAAAAAAA[ ]BBBBBBBBB
AAAAAAAAAA[ ] BBBBBBBBB
AAAAAAAAAA[ ]  BBBBBBBBBB

我想要一个可重复的点<leader>h来做到这一点:

<leader>h...

AAAAAAAAAA[B]BBBBBBBB
AAAAAAAAAA [B]BBBBBBBB
AAAAAAAAAA  [B]BBBBBBBB
AAAAAAAAAA   [B]BBBBBBBBB

编辑2:

@romainl 在回复中提到的解决方法可以解决问题:

function! s:insspace(...)
    if a:0
      " perform operation
      execute 'normal' v:count1.'i '."\<esc>".'l'
    else
      " set up
      let &operatorfunc = matchstr(expand('<sfile>'), '[^. ]*$')
      return "g@\<space>"
    endif
endfunction

nnoremap <silent><expr> <leader>h <sid>insspace()

有人可以解释它是如何工作的吗?我是vim的初学者...

标签: vim

解决方案


给定下面的字符串并假设光标在-

lorem-ipsum
     ^

有多种简单且可重复的方法可以在 之后插入空格-并将光标留在空格上:

a <Esc>
s<C-r>" <Esc>

lorem- ipsum
      ^

上面的两个宏……</p>

  • 是“点可重复的”,因为不涉及运动,
  • 将光标留在空格上,因为在插入之后,Vim 将光标放在最后插入的字符上。

但这正是后一种行为,它阻止我们在插入之前或之后没有运动的情况下在另一个方向上做同样的事情。

没有运动,操作是“点可重复的”,但光标留在-

i <Esc>
a <Esc>
s <C-r>"<Esc>

lorem -ipsum
      ^

随着运动,光标留在空间上,但操作不是“点可重复的”:

i <Esc><Left>
<Left>a <Esc>
s <C-r>"<Esc><Left>

lorem -ipsum
     ^

解决方法有点做作但很漂亮。


推荐阅读