我可以重复上一个UI命令吗?


17

我知道我可以.用来重复上一个编辑命令。

有没有办法重复上一个UI操作命令?例如,我可以写成10<C-W>-将窗口缩小十行。如果我想进一步缩小命令范围,可以按⟨ 一些键 easily轻松地重复此命令,将是很好的选择。


相关阅读:stackoverflow.com/q/6952636/2072269(未给出答案你以后可以使用已经做了调整大小)。
muru

@muru:很好,但这是针对这种情况的。如果我做了类似的事情fz然后10;呢?那:tabm +1呢 这些都必须是特殊情况的吗?
wchargin

我想你误会了我。我是说链接的帖子没有用的答案(在其他人提出并提出建议之前)。
muru

哦!好的,那么我们在同一页面上@muru :)
wchargin

Answers:


12

点命令.之所以有效,是因为Vim会“保持跟踪”更改缓冲区内容的命令。如果运行:echo b:changedtick,则每次对当前缓冲区的更改都会使它递增。

但是Vim不会“跟踪”非编辑命令。因此,不,您的要求无法完成。


8

在vim中,默认情况下无法执行此操作,因为vim不会跟踪先前执行的wincmd。但是,可以通过一些巧妙的映射来做到这一点:

function! s:Wincmd(count, key)
    " If count is not zero, use the original count.  If otherwise, don't
    " include a count.
    let if_count = a:count ? a:count : ""
    " This builds a wincmd from the given key, and saves it so
    " it can be repeated.
    let g:last_wincmd = "wincmd " . nr2char(a:key)
    " Execute the built wincmd
    execute if_count . g:last_wincmd
endfunction

function! s:WincmdRepeat(count)
    " If no wincmd has been executed yet, don't do anything
    if !exists('g:last_wincmd') | return | endif
    " If a count is given, repeat the last wincmd that amount of times.
    " If otherwise, just repeat once.
    let if_count = a:count ? a:count : ""
    execute if_count . g:last_wincmd
endfunction

" Overwrite the default <C-w> mapping so that the last wincmd can be kept
" track of.  The getchar function is what captures the key pressed
" directly afterwards.  The <C-u> is to remove any cmdline range that vim
" automatically inserted.
nnoremap <silent> <C-w> :<C-u>call <SID>Wincmd(v:count, getchar())<CR>

" This just calls the function which repeats the previous wincmd.  It
" does accept a count, which is the number of times it should repeat the
" previous wincmd.  You can also replace Q with whatever key you want. 
nnoremap <silent> Q :<C-u> call <SID>WincmdRepeat(v:count)<CR>

请注意,如果有任何使用的映射,<C-w>则只有在它们不相同时才可以重复nore。使用发出的任何wincmds :wincmd将不会重复。另外,不能执行任何包含多个字符的wincmds (例如<C-w>gf

相关帮助主题

  • :help v:count
  • :help getchar()
  • :help nr2char()
  • :help expr1
  • :help :wincmd
  • :help :execute
  • :help :for
  • :help :map-<silent>
  • :help c_CTRL-U
  • :help <SID>

1
这很棒,并且是编写良好的VimScript的绝佳示例!一些次要的(可能是挑剔的)反馈:此重复命令的行为与内置.计数行为不同。向提供.计数时,将忽略先前的计数。因此,2dd接下来3.将删除2行,然后删除3行;相反,对于您的映射,2<C-w>-其次是3Q将窗口缩小2行,然后缩小6(= 2x3)行。这种行为很好,但是在选择自定义命令的行为方式时,最好从类似的内置Vim命令中提取。
tommcdo

谢谢!另外,我明白了您对计数的含义。我可能会更改它,以便它可以那样工作。
EvergreenTree

4

子模式插件可以帮助这一点。您可以输入来定义输入的“子模式” <C-W>-,其中您已经定义了-(也许是+)继续调整窗口的大小。


2

还有另一个名为repmo.vim的插件(“ repeat motions”),可以执行您想要的操作。

但是您需要指定要重复的动作(或一般动作)。我的当前配置如下:

let g:repmo_mapmotions = "j|k h|l zh|zl g;|g, <C-w>w|<C-w>W"
let g:repmo_mapmotions .= " <C-w>+|<C-w>- <C-w>>|<C-w><"
let g:repmo_key = ";" 
let g:repmo_revkey = "," 

因此,完成后,5 CTRL-W +我可以;重复多次。

该插件通过为指定的每个键创建映射来工作。

使用f或时t;,映射将被清除回其默认行为。

我发现映射对于g;返回先前的编辑点特别有用。 g; ; ; ;


@albfan我不确定我是否理解您的问题,但是对我而言,,立即采取行动并能5,按预期工作。您可能已将其设置mapleader,吗?
joeytwiddle
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.