vimscript管理窗口需要一些审查

sigwle7e  于 9个月前  发布在  其他
关注(0)|答案(2)|浏览(99)

有人能检查一下我下面的vimscript吗?我试着做了一个键Map:

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

字符串
对于一个有文件内容的窗口,这个键Map可以很好的工作。只有对于一个没有文件内容的窗口(这种窗口可以由n创建),这个代码可以工作,但是nerdtree和tagbar不会重新出现。
恢复这些插件窗口的作用是函数RecoverThe2().我不能调试这个脚本.我只能想象是怎么回事在我的大脑.但我不能弄清楚.
1.关于这个问题,我想听听你的意见。
1.我想得到一些关于全局变量g:nerdtree_open和g:tagbar_open的用法的建议。我不确定vimscript中全局变量的正确用法。我是否正确使用了全局变量?

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>


F.Y.I.我在Ubuntu 22.04 Gnome终端上测试了这个
你可以找到我的vimrc here

qhhrdooz

qhhrdooz1#

Map的右侧是一个宏,因此是一系列命令。在您的情况下,RHS可以细分为4个正常模式命令:

:call CloseThe2()<cr><C-W>H :call RecoverThe2()<cr>
AAAAAAAAAAAAAAAAAAAAA
                     BBBBBB
                           C
                            DDDDDDDDDDDDDDDDDDDDDDD

字符串
在宏中,当其中一个命令引发错误时,其余的命令将不会执行。因此,如果您绝对希望执行所有命令,则确保没有任何命令引发错误是很重要的。
现在,让我们看看这四个命令的作用:

  • 命令A调用函数。
  • 命令B移动当前窗口。
  • 命令C将光标向右移动一个字符。
  • 命令D调用函数。

你的问题就在这里你在命令B和D之间添加的空格被解释为一个合法的正常模式命令C::help <space>。当光标右边有一些文本时,<Space>工作,但当不是这种情况时,它抛出一个错误。由于你的缓冲区是空的,命令C抛出一个错误,并阻止命令D的执行。
因此,一个简单解决方法是删除空格:

:call CloseThe2()<cr><C-W>H:call RecoverThe2()<cr>


请注意,您问题中的示例也有很多尾随空格。您应该确保它们不在您的vimrc中。
现在,由于这两个函数总是以相同的方式调用,将窗口移动夹在中间,您可能可以将整个过程 Package 到一个函数中,以保持Map简单:

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

snz8szmq

snz8szmq2#

感谢romainl,我能够编写工作脚本,如下所示:

"The keymap below can be implemented with the help of stackoverflow and it's        
"member romainl (https://stackoverflow.com/users/546861/romainl)                 
"https://stackoverflow.com/questions/77578019/vimscript-for-managing-windows-need-some-review
function! MoveTheWindowAllTheWayTo(direction)                                    
  "Detect which plugins are open                                                 
  if exists('t:NERDTreeBufName')                                                 
    let l:nerdtree_open = bufwinnr(t:NERDTreeBufName) != -1                      
  else                                                                           
    let l:nerdtree_open = 0                                                      
  endif                                                                          
  let l:tagbar_open = bufwinnr('__Tagbar__') != -1                               
                                                                                 
  "Close any open one                                                            
  if l:nerdtree_open                                                             
    NERDTreeClose                                                                
  endif                                                                          
  if l:tagbar_open                                                               
    TagbarClose                                                                  
  endif                                                                          
                                                                                 
  "Move the Window the cursor is in                                              
  exe "wincmd " .. a:direction                                                   
                                                                                 
  "Reopen any temporarily closed one                                             
  if l:nerdtree_open                                                             
    NERDTree                                                                     
  endif                                                                          
  if l:tagbar_open                                                               
    TagbarOpen                                                                   
  endif                                                                          
endfunction                                                                      
                                                                                 
noremap <C-W>HH :call MoveTheWindowAllTheWayTo('H')<CR>                          
noremap <C-W>JJ :call MoveTheWindowAllTheWayTo('J')<CR>                          
noremap <C-W>KK :call MoveTheWindowAllTheWayTo('K')<CR>                          
noremap <C-W>LL :call MoveTheWindowAllTheWayTo('L')<CR>

字符串
这也有帮助:https://vimdoc.sourceforge.net/htmldoc/windows.html#:wincmd

相关问题