V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
skywind3000
V2EX  ›  Vim

Vim/NeoVim 内置终端调教记

  •  3
     
  •   skywind3000 · 2020-01-11 17:37:22 +08:00 · 7146 次点击
    这是一个创建于 1538 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Vim/NeoVim 的内置终端都发布了差不多两年了,但是大家还是习惯用 vim+tmux 的组合,宁肯在 tmux 里分割 split 也不肯使用 vim 的内置终端?

    有没有办法让内嵌终端变得更好用一些呢?让它真的能帮到我们优化自己的工作流,提高操作的效率呢?学习了一圈 emacs / vscode 等编辑器的内嵌终端,我写了个 200 行的小脚本,对 vim/nvim 的内嵌终端进行一些简单的调教:

    https://github.com/skywind3000/vim-terminal-help

    这个小脚本对三个小地方进行了一些改进:

    第一:提供一个 ALT+= 的快捷键可以像 vscode 的 CTRL+backtick 一样用来打开 /关闭终端窗口,不用每次输入 :terminal,同时新终端会把 shell 的工作目录初始化成你上面正在编辑的文件所在的目录,因为你大部分时候临时想搞点什么一般都是针对你当前正在编辑的文件来操作,那么初始化成当前文件的目录就避免了你每次打开终端再 cd 一半天:

    (按 ALT+= 在正下方打开终端,路径自动帮你定位到上面文件所在目录)

    所以工作流程就是你编辑着当前文档,突然想搞点啥然后 ALT+= 在正下方打开终端,敲几行命令,运行完了就再 ALT+= 把它收起来,整个流程十分顺畅。多次 ALT+= 不会无止境的打开新终端,只会复用已有的,而如果你再终端里输入了 exit 结束了 shell 进程,那么再次按 ALT+= 才会创建一个新的终端。

    第二:初始化了一组快捷键 ALT+SHIFT+hjkl 用来在终端窗口和其他窗口之间跳转,很多 vim 用户过去都习惯设置 CTRL+hjkl 来做窗口跳转,普通窗口没问题,但是终端窗口下面,CTRL+hjkl 本身就是各种终端程序高频使用的组合键,你外面 tnoremap 覆盖掉了,里面你想运行个 fzf 都没有办法用 CTRL+j/k 在 fzf 里面上下移动光标了。因此这个小脚本鼓励大家使用新的 ALT+SHIFT+hjkl 来做窗口切换,这几个键在终端内相对用的少一些。

    第三:在终端内提供一个名叫 drop 的命令,当你在终端中突然想编辑某个文件,直接 drop xxx 命令就能通知到外层的 vim 来打开该文件了,因为 vim 的当前目录和终端内 shell 的当前目录经常不一致,你在内嵌终端里 cd 到了 xcode 种很深的一层目录,这时想让外层的 vim 打开一个文件有多麻烦?先要切换会终端的 normal 模式去,然后在 vim 种输入常常的::e .... 后面接长长的一串路径名(因为二者当前路径不同)。所以这个 drop 命令(兼容 win/linux, vim/neovim )存在的意义就是让你能在终端内以最快捷的方式让 vim 打开一个文件。

    --

    我平时会用 vscode 来编辑 markdown,vscode 的 CTRL+backtick 切换内嵌终端的功能确实很顺手,我用的很多,用来运行命令行工具编译 /发布 markdown。而同样终端下的 emacs 的用户也基本都在用内置的各种终端,而很少用外面的 tmux。 所以从道理上来讲 vim/nvim 的内嵌终端应该是可以更好用一点的,不至于像现在这样很少被人用。

    就像苹果的 airpod 耳机,其实无线耳机,其实技术上并没有什么新的东西,无线耳机好多年前就有了,但是用的人真的不多,而 airpod 做的其实也很简单,就是持续在不同的细节地方改进用户体验,然后把续航时间大大增长,最终量变积累形程质变,今天 airpod 如此受人欢迎。基于前面的经验,我想,或许,我们可以通过不断的改进内置终端的各处体验,最终真的让他帮助到大家。

    我自己用了一段时间后发现,当然不能完替 tmux 操作,但代替了不少之前需要 vim+tmux 协同的工作,的确感觉到比以前的方便。就像以前我在 Windows 下从来不用 GVim 内置终端的,现在也开始用了,比如正在写 python 代码,发现需要安装个包,以前是要打开 windows 菜单,然后运行 cmd,然后再 pip install,打断太多了。现在同样的事情我就倾向于 ALT+= 打开内置终端(我配置的是 powershell ),然后 pip install 一个包,完事就 ALT+= 收起来,比以前顺畅太多,全键盘操作,工作流根本不会中断。

    所以用了一段时间,又根据朋友的反馈做了一些调整优化,归纳成个小脚本共享出来,希望大家工作效率得到提升:

    https://github.com/skywind3000/vim-terminal-help

    --

    第 1 条附言  ·  2020-01-11 18:58:28 +08:00

    补充:有人说不知道内置终端如何滚屏,原来很多人还不知道内置终端也分 normal/insert 两种模式,正常终端操作,输入文字是 insert 模式,在 insert 模式中按 <c-\><c-N> 就可以切换到终端 normal 模式了,然后你可以像 vim buffer 一样正常的 hjkl 漫游,正常的滚屏,复制内容。弄完了以后再按 i/a 回到 insert 模式中接着输入终端命令。

    另外从 vim 寄存器到 终端粘贴内容的操作因为 vim/nvim 不一样,vim 的终端粘贴是在终端 insert 模式下按 termkey + " + 寄存器termkey 在这个脚本里是 <c-_> ,而 neovim 的终端是可以直接在 normal 模式下像普通 vim buffer 一样粘贴。

    为了方便,所以最新版的脚本中我增加了一个 ALT+- 的映射,可以让你再终端里按 ALT 和减号就粘贴 0 号寄存器了,vim/nvim 兼容。

    第 2 条附言  ·  2020-01-20 02:39:12 +08:00

    vim-terminal-help 再次更新:

    • 允许通过 g:terminal_key 配置默认的切换 terminal 的热键,不是写死的 ALT+等于号。
    • 可以通过 g:terminal_cwd 配置 shell 启动时候的目录

    g:terminal_cwd 可以有三个值:

    • 0 是 vim 当前目录
    • 1 是当前编辑文件的所在目录
    • 2 是当前文件的项目目录(包含 .git/.svn 的父目录)
    10 条回复    2020-02-03 15:27:40 +08:00
    ech0x
        1
    ech0x  
       2020-01-11 18:18:52 +08:00 via iPhone
    刚刚在知乎上看完😂
    dongqihong
        2
    dongqihong  
       2020-01-11 18:26:14 +08:00
    赞!刚使用了下,挺不错的,不过有个问题,我发现这个终端复用貌似只是在同一个 tab 下,如果我在另一个 tab 下运行 alt + = 会打开一个新的 terminal。
    jdhao
        3
    jdhao  
       2020-01-11 18:26:19 +08:00
    资瓷!
    skywind3000
        4
    skywind3000  
    OP
       2020-01-11 18:59:08 +08:00
    @dongqihong , 对的,每个 tabpage 一个,故意做成这样的。
    yfixx
        5
    yfixx  
       2020-01-12 18:13:06 +08:00
    资瓷一下
    ensonmj
        6
    ensonmj  
       2020-01-16 13:14:12 +08:00
    最大的问题,是远程使用无法保持会话。tmux 最大的优势是这个
    skywind3000
        7
    skywind3000  
    OP
       2020-01-16 18:26:11 +08:00
    @ensonmj 你说的没错,这玩意儿不是用来代替 tmux 的,是补充不足,我现在为了断线重新和多 window,我也会套一个 tmux,但是启动了 vim 后,大部分活计我用 vim 内嵌终端来完成了。
    MrUser
        8
    MrUser  
       2020-01-25 21:08:12 +08:00
    使用 Alt + = 隐藏终端后,在使用 :q 退出 vim 时提示:
    E947: Job still running in buffer "!/usr/local/bin/fish"
    Press ENTER or type command to continue

    按回车后显示的是用 Alt + = 打开的那个内置终端。
    ----
    不能随 vim 一起退出么?
    skywind3000
        9
    skywind3000  
    OP
       2020-02-02 04:27:56 +08:00   ❤️ 1
    @MrUser Emacs 进程没结束完退出也会有这个提示,提醒你安全退出罢了。你不喜欢可以用:

    let g:terminal_kill = "term"

    来设置一个信号,退出 vim 时用 term 信号杀死所有后台 terminal 进程。
    MrUser
        10
    MrUser  
       2020-02-03 15:27:40 +08:00
    @skywind3000
    感谢感谢,让大神见笑了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3218 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 11:39 · PVG 19:39 · LAX 04:39 · JFK 07:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.