VIM智能退出宏

3

多年来,我的手“记住”了F2是保存,F3是退出(这还是我使用IBM编辑器的遗留习惯)。因此,我首先将vim键映射设置为让F2和F3执行它们本该执行的功能。特别是对于F3:

:map <F3> :q<CR>
:map! <ESC>:q<CR>

如果我退出一个已经编辑过的文件,仍会得到 `E37: No write since last change (add ! to override)`。我更喜欢的是,它应该发出一个函数来发出 `E37: No write since last change. Press F3 again to really quit.`
我该如何编写代码呢?
更新的解决方案建议 有人指出我可以使用 `confirm` 来完成这个任务。我“知道”之前看到过一些内置的解决方案,但我记不起来了。然而,请注意,`confirm` 的意义与宏的意义相反,即它提供“是,保留更改”,而宏提供“是,放弃更改”。 如果早些时候提出了 `confirm`,我就会满足。
实际操作 首先,感谢 @Jamie Schembri 提供的示例。在学习新的脚本语言时,始终需要一个示例。
这是我最终使用的宏。是的,它并不完全符合要求。我用一个 Yes|No|Write 选项替换了第二个 F3,这感觉更好。我还必须添加一个 nr2char(),以使字母的测试起作用。我还必须从 :map 中删除一个 CR。 更新请参阅此问题,以获取使用此宏的解决方案,添加了处理 tagstack 文件的附加功能。如果您从 tagstack 文件中退出,vim 将关闭所有文件。
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
      call feedkeys('\<ESC>')
    endif
  endtry
endfunction

从多年的“手指记忆”中,我的手知道F2是保存,F3是退出。该死。我想我可以感受到那个记忆隆起。ISPF/PDF仍然可以向Unix工具包教授一些东西。一些。 - jthill
Xedit、ZED、Redit、E、E/PM。我希望有一个很好的 Linux 克隆版本的 E/PM,可以使用 Rexx 进行宏编写。THE 是一个相当不错的 Xedit 克隆版本,但在 Linux 上使用时会遇到一些问题。 - Wes Miller
我正在尝试找到如何进行下一个键拦截的方法,以便让您完全忽略该消息(因此,如果您不按F3键,则无论您按什么键都会正常工作)。 - jthill
我会放弃下一个键,除非它是F3。你知道我会按ESC键。对于VI编辑器来说,ESC键就像Windows系统的重启一样重要。 - Wes Miller
2个回答

3

参考pandubear的答案,我编写了一个奇怪但似乎符合你要求的小函数。

function! QuitF3()
  try
    quit
  catch /E37:/
    " Unwritten changes.
    echo "E37: No write since last change. Press F3 again to really quit."
    if getchar() == "\<F3>"
      quit!
    else
      " Close prompt.
      call feedkeys('\<ESC>')
    endif
  endtry
endfunction

map <F3> :call QuitF3()<CR><CR>

在这里。你能解释一下是什么导致了你跳过提示吗? - jthill
嗯,它并不能很好地工作。看起来似乎从某个地方得到一个13,<CR>,被getchar()吃掉了,然后发现这不是F3。将if getchar()之前加上echo getchar()似乎可以解决问题,但会在屏幕上产生乱码。echo getchar() > /dev/nill也没有用。 - Wes Miller
哦,顺便问一下,getdhar() 调用后不需要加上 nr2char() 进行 ASCII 到字符的转化吗? - Wes Miller
@jthill 我不确定,但如果有人能解释一下,我会很感激。那是个有趣的点。 @WesMiller 如果我正确理解了:help getchar() ,它不应该需要nr2char()。我只有OS X终端和iTerm2可以测试,但两者都可以使用,所以这可能与您的终端有关? - Jamie Schembri
好的。我比你晚了大约五分钟才明白,希望我能像你一样想到直接给它所需的东西,我觉得我的实践技巧需要润滑。嘿,你可以保存getchar的结果并将其附加到feedkeys参数中。 - jthill
@jthill,它需要额外的<CR>确实让我感到烦恼,所以我真的很想弄清楚为什么会这样!无论如何,我确实尝试了传递getchar()结果,但它导致了奇怪的行为——可能是由于expr-quote - Jamie Schembri

1

我认为您可以将F3映射到执行以下操作的函数:(伪代码)

try:
    quit
catch error 37:
    intercept next keystroke
    if it's F3:
        force quit
    else:
        send key back to vim

我不知道所有细节,但我相当确定您可以使用:try:catchgetchar()(对于像F3这样的特殊键是否有效还不确定)和feedkeys()来完成所有这些事情。请参阅每个内容的:help
不过这似乎有点麻烦。为什么不为:q!创建一个单独的映射呢?

类似我的想法。我以前见过这种行为,所以我知道它是可以完成的。而添加额外的映射会破坏手指记忆的作用。 - Wes Miller
请查看附加到问题的“实际操作”。抱歉它无法适应此处。请注意,我遇到了第二个<CR>的问题,不得不将其删除。 - Wes Miller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接