有人可以检查一下我下面的 vim 脚本吗? 我尝试制作一个键映射来执行以下操作:
1. Closes tagbar and/or nerdtree if exist
2. Do <C-W>H or <C-W>J or <C-W>K or <C-W>L
3. Recover tagbar and/or nerdtree if originally exited
对于其中包含文件内容的窗口,此键映射效果很好。
仅对于其中没有文件内容的窗口(此类窗口可以通过
恢复那些插件窗口就是函数RecoverThe2()的作用。 我无法调试这个脚本。我只能想象我的大脑中正在发生什么。但我无法弄清楚。
let g:nerdtree_open = 0
let g:tagbar_open = 0
function! CloseThe2()
" Detect which plugins are open
if exists('t:NERDTreeBufName')
let g:nerdtree_open = bufwinnr(t:NERDTreeBufName) != -1
else
let g:nerdtree_open = 0
endif
let g:tagbar_open = bufwinnr('__Tagbar__') != -1
" Perform the appropriate action
if g:nerdtree_open
NERDTreeClose
endif
if g:tagbar_open
TagbarClose
endif
endfunction
function! RecoverThe2()
" Perform the appropriate action
if g:nerdtree_open
NERDTree
let g:nerdtree_open = 0
endif
if g:tagbar_open
TagbarOpen
let g:tagbar_open = 0
endif
endfunction
noremap <C-W>HH :call CloseThe2()<cr><C-W>H :call RecoverThe2()<cr>
noremap <C-W>JJ :call CloseThe2()<cr><C-W>J :call RecoverThe2()<cr>
noremap <C-W>KK :call CloseThe2()<cr><C-W>K :call RecoverThe2()<cr>
noremap <C-W>LL :call CloseThe2()<cr><C-W>L :call RecoverThe2()<cr>
仅供参考我在 Ubuntu 22.04 Gnome 终端上测试了这个
映射的右侧是宏,因此是一系列命令。在您的情况下,RHS 可以细分为 N 个正常模式命令:
:call CloseThe2()<cr><C-W>H :call RecoverThe2()<cr>
AAAAAAAAAAAAAAAAAAAAA
BBBBBB
C
DDDDDDDDDDDDDDDDDDDDDDD
在宏中,当其中一个命令抛出错误时,其余命令不会执行。因此,如果您绝对希望执行所有命令,请务必确保所有命令都不会抛出错误。
现在,让我们看看这四个命令的作用:
您的问题就在这里:您在命令 B 和 D 之间添加的空格被解释为合法的正常模式命令 C:
:help <space>
。当光标右侧有一些文本时,<Space>
可以工作,但如果不是这种情况,它会抛出错误。由于缓冲区为空,命令 C 会抛出错误并阻止命令 D 的执行。
因此,一个简单的解决方法是删除该空间:
:call CloseThe2()<cr><C-W>H:call RecoverThe2()<cr>
请注意,您问题中的示例也有很多尾随空格。您应该确保它们不在您的
vimrc
中。
现在,由于这两个函数总是以相同的方式调用,夹着窗口移动,您可能可以将整个函数包装到一个函数中,以保持映射简单:
function! Whatever(direction)
call CloseThe2()
execute "wincmd " .. a:direction
call RecoverThe2()
endfunction
nnoremap <C-W>HH <Cmd>call Whatever("H")<cr>
或者甚至丢弃这两个函数,这两个函数在该上下文之外并没有真正的用处,并将所有内容放在一个函数中。请注意,它具有将所有内容保留在本地的额外好处,从而防止全局范围内不必要的污染:
function! Whatever(direction)
" the setup
let l:nerdtree_open = 0
let l:tagbar_open = 0
" the first step
if exists('t:NERDTreeBufName')
[…]
" the second step
execute "wincmd " .. a:direction
" the third step
if l:nerdtree_open
[…]
endfunction
nnoremap <C-W>HH <Cmd>call Whatever("H")<cr>
FWIW,请参阅
:help get()
了解从范围获取值的便捷方法,在本例中为 l:
,不会引发错误,并且具有默认值。
参见
:help :wincmd
。