VIM:如何确定当前文件是否在tagstack上?

时间:2014-01-06 22:14:16

标签: vim

在其他SO-ers的帮助下,我为vim放了一个smart quit macro,询问你是否真的想要退出一个带有变化的文件。我将这个宏绑定到F3,因为我30年前在大型机上学习了编辑器而F3对我来说永远是Quit。

当我使用标签并且正在查看tagstack上的文件时,我经常通过按F3而不是ctrl-T来关闭该文件。这将关闭所有未更改的文件标记文件或其他。

所以,我想改进我的智能退出宏,让它检测到当前文件在tagstack上,我的意思是:pop,not:quit。

有办法做到这一点吗?

" Smart Quit Function ----------------------                                                                             
function! QuitF3()

  try
    quit
  catch /E37:/
    " Unwritten changes.
    echo "E37: Discard changes?  Y|y = Yes, N|n = No, W|w = Write"

    let ans = nr2char( getchar() )

    if      ans == "y" || ans == "Y"
      quit!
    elseif  ans == "w" || ans == "W"
      write
    else
      " Close prompt.
      call feedkeys('\<ESC>')
    endif
  endtry
endfunction

2 个答案:

答案 0 :(得分:1)

这可以通过对用于跳转到标记的键的映射来实现,以便在跳转到全局变量之后保存文件名或缓冲区编号。然后,您可以根据退出函数上保存的值检查当前文件名/缓冲区编号。

这是可能的开始:

nnoremap <silent> <c-]> :call JumpTag()<CR>
let g:lastTagBuffer = -1
function! JumpTag()
   let w = expand("<cword>")        " get the word under cursor
   if w =~ '\a'                  " if the word contains a letter
      try
         exe "tag " . w
         let g:lastTagBuffer = bufnr("%")
      catch
         return
      endtry
   endif
endfunction

您可以在:h CursorHold-example找到更多信息。

如果您愿意,可以使用列表而不是单个var来保存所有标记跳转并在 Ctrl + t 上包含一个地图以删除最后一个element,然后你可以镜像tagstack的内容。

答案 1 :(得分:1)

我被要求在@kazark的帖子位置移动这个答案,这是原始问题的附录。

男孩我错过了显而易见的事。

在我下面的解决方案中,我使用了与原始逻辑相反的方法。也就是说,始终try使用pop关闭当前文件。如果有效,我就完成了。如果它失败了,我会产生一些错误,可能是E555,我可以catch。但是,如果我发现任何错误,pop失败,我知道try关闭文件,然后按照原始脚本。这是最终结果:

" Smart Quit Function ----------------------                                                                             
function! QuitF3()
   try
      pop
   catch 
      try
        quit
      catch /E37:/
         " Unwritten changes.
         echo "E37: Discard changes?  Y|y = Yes, N|n = No, W|w = Write"

         let ans = nr2char( getchar() )

         if      ans == "y" || ans == "Y"
           quit!
         elseif  ans == "w" || ans == "W"
           write
         else
           " Close prompt.
           call feedkeys('\<ESC>')
         endif
        return 0
      endtry
   endtry
endfunction