如何在Vim窗口内打开Shell?

142

我可以使用Vim的:shell命令打开一个终端,但是我不能同时编辑文件和使用终端。

有没有办法将Vim分成多个窗口(或标签),并在其中一个窗口中打开一个终端?


1
以前有一个针对vim的shell补丁,但据我所知它现在已经无法编译了。最接近真正shell的东西是使用screen或tmux。这是我在vim中最想念的东西。 - Randy Morris
2
看起来是一个重复的问题,与https://dev59.com/03M_5IYBdhLWcg3ww2Kb相同。 - Brad Cupit
11个回答

149

Neovim 和 Vim 8.2 可以通过 :ter[minal] 命令原生地支持此功能。

有关详细信息,请参见文档中的 terminal-window 部分。


它可以工作,但我想将其添加为底部的小面板(就像VS一样)。 - FractalSpace

47

这取决于你所使用的操作系统 - 实际上我没有在Windows上测试过 - 但是Conque是最好的插件之一。

实际上,它可以变得更好,但已经能够正常工作。


4
如果您正在使用Vundle管理插件,可以将"Bundle 'jewes/Conque-Shell'"添加到您的".vimrc"文件中,并运行":BundleInstall"进行安装。 - Mingjiang Shi
需要注意的一件事是:在某些工作环境中,vi 的 +python 或 +python3 要求可能会成为一个致命因素。 - cfi
这是更新后的URL(附有截图):https://github.com/wkentaro/conque.vim - Walty Yeung

19

:vsp 或者 :sp - 将vim分割成两个实例,但是你不能只在其中一个实例中使用:shell

为什么不显示终端的另一个标签页而不是vim的另一个标签页呢?如果你喜欢这个想法,你可以尝试一下:Ctrl-shift-t,然后用Ctrl - pageupCtrl - pagedown来在它们之间移动。

如果你只想要运行一些 shell 命令,你可以在vim中使用!来执行任何 shell 命令。

例如::!./a.out


2
要运行当前打开的可执行文件,您可以使用 vim 路径魔法,如下所示::!./% - cprn
1
为什么不显示终端的另一个选项卡 - 并非每个人都在GUI上方使用vim终端仿真器...从“Ctrl”-无论如何,我想你的答案假定gnome-terminal或类似的仿真器。 - törzsmókus

8
您可以使用tmuxscreen(后者仅能水平分割而无需修补程序)来分割终端。但我不知道如何在两个窗格中同时运行一个Vim实例。

4
如果你从 git 上构建屏幕,它可以进行垂直分割。 - Randy Morris

8
如果你还没有发现,你可以使用令人惊叹的screen插件Conque也很出色,但我觉得screen更加实用(例如,它不会“污染”你的缓冲区,你可以在编辑后只发送你真正想要的命令)。

8
我猜这是一个相当老的问题,但现在在2017年。我们有neovim,它是vim的一个分支,添加了终端支持。
因此调用:term会打开一个终端窗口。与使用tmux(终端复用器)相比,这种解决方案的优点在于您将拥有与vim设置相同的窗口绑定。neovim与vim兼容,因此您可以基本上复制并粘贴您的.vimrc,它就能正常工作。
更多的优点是您可以切换到打开的终端的普通模式,以及进行基本的复制和编辑。对于git提交来说也非常有用,因为你可以在缓冲区中使用自动完成的所有内容。
我会更新这个答案,因为vim也计划发布终端支持,可能在vim 8.1中。您可以在此处跟进进展: https://groups.google.com/forum/#!topic/vim_dev/Q9gUWGCeTXM 一旦发布,我确信这比使用tmux更优越。

6
我想它是在Vim 8.0中发布的。 - LangeHaare

3

Shougo的VimShell是与neocomplcache一起使用的,可以自动完成文件名。


1

虽然不完全符合您的要求,但您可能会对我的插件vim-notebook感兴趣,它可以使用户保持后台进程的活动状态,并让其评估当前文档的一部分(并将输出写入文档)。 它旨在用于包含要评估的代码片段的笔记本风格文档。


1

使用 Vim 8.0 或更高版本,您可以通过使用 terminal 功能在 vim 窗口中运行终端仿真器。另外,如果您想在 gVim 或 MacVim 中模拟现代 IDE 终端(如 VSCode 集成终端),可以将以下配置放入您的 vimrc 文件中。

set shell=/path/to/shell

" Make sure to replace `sh.exe` in BufNr("sh.exe") with your shell executable.
nnoremap <expr> <space> BufNr("sh.exe") > 0 ? (&buftype == 'terminal' ? '<c-^>' : ':b '. BufNr("sh.exe") . '<cr>') : ':terminal ++curwin<cr>'

function! BufNr(pattern)
  let bufcount = bufnr("$")
  let currbufnr = 1
  let nummatches = 0
  let firstmatchingbufnr = 0
  while currbufnr <= bufcount
    if(bufexists(currbufnr))
      let currbufname = bufname(currbufnr)
      if(match(currbufname, a:pattern) > -1)
        let nummatches += 1
        let firstmatchingbufnr = currbufnr
      endif
    endif
    let currbufnr = currbufnr + 1
  endwhile
  return firstmatchingbufnr
endf

现在您可以在正常模式(或您选择的任何映射)中使用space来执行以下操作:
  1. 如果终端尚不存在,则在当前窗口中打开终端。
  2. 如果当前缓冲区不是终端类型,则切换到终端缓冲区。
  3. 如果当前缓冲区是终端缓冲区,则切换到上一个缓冲区。

0
你可能想打开一个 "screen" 程序,分屏,一个屏幕上打开 shell,另一个屏幕上打开 vim。这对我很有效。

取消了-1,因为没有解释。 此外,我测试了vim屏幕插件的解决方案,与mrcybul的解决方案并没有太大区别。@mrcybul:感谢您的尝试帮助。为了避免被投票否决,请仔细阅读其他答案,并只在您认为自己的答案有所创新时才添加自己的答案。同时请说明您的解决方案在某些情况下可能更好。 - Titou

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