How to effectively work with multiple files in Vim?
我已经开始使用vim开发Perl脚本,并开始发现它非常强大。
我喜欢的一件事是能够同时打开多个文件,例如,
1 2 | :n :prev |
查看打开的文件
1 | :args |
要添加文件,我可以说:
1 | :n test.pl |
我希望它会被添加到我的文件列表中,但是它会删除我当前的文件列表,当我键入
那么如何向args列表添加和删除文件呢?
为什么不使用标签(在VIM 7中引入)?您可以在带有
如果没有那么多文件,或者没有VIM 7,您也可以将屏幕拆分为多个文件:
上市
要查看当前缓冲区的列表,我使用:
1 | :ls |
开口
要打开新文件,我使用
1 | :e ../myFile.pl |
使用增强的选项卡完成(将
注意:您也可以使用
要在所有打开的文件之间切换,我使用
1 | :b myfile |
具有增强的选项卡完成功能(仍为
注:
使用
有了这些,我不需要在Vim中使用制表符,我的手指可以找到缓冲区,而不是我的眼睛。
注意:如果您希望所有文件都转到同一个vim实例,请使用
1 | :ls |
打开的缓冲区列表
:bp 上一个缓冲区:bn 下一个缓冲区:bn 移动到第n个缓冲区- 带制表键的
:b 提供自动完成功能(太棒了!!)
在一些版本的vim中,
或者在正常模式下,使用
另外,您还可以保存vim的会话
1 | :mksession! ~/today.ses |
上述命令将当前打开的文件缓冲区和设置保存到
1 | vim -S ~/today.ses |
记不起你昨天离开的地方了。;)
添加到
1 | :argadd |
从
1 | :argdelete |
在您的示例中,可以使用
我使用缓冲区命令-
我认为您可能使用了错误的命令来查看已打开的文件列表。
尝试执行
1 2 3 4 | 1 %a "./checkin.pl" line 1 2 # "./grabakamailogs.pl" line 1 3 "./grabwmlogs.pl" line 0 etc. |
然后,您可以通过按列出的数字引用这些文件,例如3B
或者你可以通过输入数字而不是只输入b来分割你的屏幕。
作为旁白,%表示当前可见的文件,表示备用文件。
通过按ctrl shift 6,可以轻松地在这两个文件之间切换。
编辑:和
Vim(但不是最初的Vi!)我发现(在许多情况下)选项卡优于缓冲区。您可以说
这里有很多答案!我所使用的没有重新设计轮子-最著名的插件(不会很快死亡,很多人都会使用)是超快速和极客。
- ctrlp vim/ctrlp.vim-按名称查找文件,按位置或仅按名称进行模糊搜索
- jlanzarotta/bufexplorer-浏览打开的缓冲区(当您不记得最近打开和修改了多少个文件,并且不记得它们在哪里时,可能是因为您使用ag搜索了它们)
- rking/ag.vim搜索关于gitignore的文件
- scooloose/nerdtree查看目录结构、查找、添加/删除/修改文件
更新:最近我使用dyng/ctrlsf.vim搜索上下文视图(比如sublime search),并将引擎从ag切换到ripgrep。表演很出色。
像
1 2 3 | :e foo.txt bar.txt :e /foo/bar/*.txt :badd /foo/bar/* |
如果要从VIM中添加多个文件,请使用
1 2 3 | :arga foo.txt bar.txt :arga /foo/bar/*.txt :argadd /foo/bar/* |
本文中的一些答案建议使用制表符,另一些则建议使用缓冲区来完成相同的事情。选项卡和缓冲区是不同的。我强烈建议您阅读本文vim tab madness-buffers vs tab这是我从文章中得到的一个很好的总结:总结:
- 缓冲区是文件的内存文本。
- 窗口是缓冲区上的一个视区。
- 选项卡页是Windows的集合。
在VIM中使用多个文件时,我主要使用这些命令(打开大约350个文件):
:b (跳到缓冲区):bw (缓冲区擦除,移除缓冲区):e (编辑,打开新的缓冲区>pltags 启用跳转到子程序/方法定义
您可能需要使用VIM全局标记。
这样,您就可以在文件之间快速跳转,甚至可以跳转到文件中标记的位置。此外,键命令也很短:
更改位置时,重置标记也很快:
我对gvim和命令行vim使用相同的.vimrc文件。我倾向于在gvim中使用制表符,在命令行vim中使用缓冲区,因此我设置了.vimrc以使使用这两个制表符更容易:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | " Movement between tabs OR buffers nnoremap L :call MyNext()<CR> nnoremap H :call MyPrev()<CR> " MyNext() and MyPrev(): Movement between tabs OR buffers function! MyNext() if exists( '*tabpagenr' ) && tabpagenr('$') != 1 " Tab support && tabs open normal gt else " No tab support, or no tabs open execute":bnext" endif endfunction function! MyPrev() if exists( '*tabpagenr' ) && tabpagenr('$') != '1' " Tab support && tabs open normal gT else " No tab support, or no tabs open execute":bprev" endif endfunction |
这会破坏现有的H和L映射,但它使文件之间的切换非常快速和容易。只需按"H"键进入下一个,按"L"键进入上一个;无论您使用的是制表符还是缓冲区,都会得到预期的结果。
如果要使用多个缓冲区,我认为最重要的是设置隐藏这样它就可以让您切换缓冲区,即使您要离开的缓冲区中有未保存的更改。
添加另一个答案,因为这不包含在任何答案中
将所有缓冲区更改为
1 | :tab sball |
将打开所有缓冲区到选项卡视图。然后我们可以使用任何与选项卡相关的命令
1 2 | gt or :tabn " go to next tab gT or :tabp or :tabN " go to previous tab |
详细信息见
我们可以指示vim以选项卡视图的形式,通过
1 | au VimEnter * if !&diff | tab all | tabfirst | endif |
无论如何,要回答这个问题:添加到arg列表中:
从arg列表中删除:
更多关于
我有效地处理多个文件的方法是使用tmux。
它允许您垂直和水平拆分窗口,如:
我让它在我的Mac和Linux机器上都以这种方式工作,我发现它比(在Mac上)提供的本机窗口窗格切换机制更好。我发现切换更容易,只有使用tmux,我才能在我的Mac上运行"当前目录下的新页面"(尽管在同一目录下似乎有打开新窗格的选项),这是一个非常关键的部分。当前位置的即时新窗格非常有用。一种为两个操作系统使用相同的键组合来创建新窗格的方法对我来说非常重要,而且对于将来的个人兼容性来说,这也是一种奖励。除了多个tmux窗格外,我还尝试使用多个选项卡,例如和多个新窗口,例如,最终我发现多个tmux窗格对我最有用。我非常"视觉化",喜欢把各种各样的上下文放在我面前,作为窗格连接在一起。
tmux还支持水平和垂直窗格,而旧的
如果只使用VIM内置命令,我见过在多个缓冲区之间切换的最佳命令是:
1 | nnoremap <Leader>f :set nomore<Bar>:ls<Bar>:set more<CR>:b<Space> |
它完美地结合了
在vimrc中给出了上面的映射,一旦您键入
- 显示所有打开的缓冲区
- 你可以:
23 型转到缓冲器23,- 键入
# 转到替代/mru缓冲区, - 键入文件的部分名称,然后键入
或 以自动完成, - 或者只是
或 保持在当前缓冲区
上述键映射的输出快照为:
1 2 3 4 5 6 7 | :set nomore|:ls|:set more 1 h "script.py" line 1 2 #h +"file1.txt" line 6 -- '#' for alternative buffer 3 %a "README.md" line 17 -- '%' for current buffer 4 "file3.txt" line 0 -- line 0 for hasn't switched to 5 +"/etc/passwd" line 42 -- '+' for modified :b '<Cursor> here' |
在上面的快照中:
- 第二列:
%a 表示当前,h 表示隐藏,# 表示以前,空表示尚未切换到。 - 第三栏:
+ 修改。
另外,我强烈建议
我使用下面的内容,这为您提供了许多您希望在其他编辑器中具有的功能,如Sublime文本/textmate
我使用在我的
mini buffer explorer脚本也很好,可以获得一个很好的缓冲区压缩列表。然后是
我经常使用命令行和git,所以在我的bashrc中有这个别名:
1 | alias gvim="gvim --servername \$(git rev-parse --show-toplevel || echo 'default') --remote-tab" |
这将在现有窗口的新选项卡中打开每个新文件,并为每个Git存储库创建一个窗口。因此,如果您从repo a打开两个文件,从repo b打开三个文件,您将得到两个窗口,一个用于repo a,两个选项卡,一个用于repo b,三个选项卡。
如果要打开的文件不包含在git repo中,它将转到默认窗口。
要在选项卡之间跳转,我使用以下映射:
1 2 | nmap <C-p> :tabprevious<CR> nmap <C-n> :tabnext<CR> |
要一次打开多个文件,您应该将其与其他解决方案之一结合起来。
为方便编辑多个文件,请尝试以下映射
"拆分窗口"
"四处走动"
我制作了一个非常简单的视频,显示我使用的工作流。基本上,我使用了ctrl-pvim插件,并将缓冲区导航映射到enter键。
这样,我可以在正常模式下按Enter键,查看打开的文件列表(显示在屏幕底部的一个新窗口中),选择要编辑的文件,然后再次按Enter键。要快速搜索多个打开的文件,只需键入部分文件名,选择文件并按Enter。
我没有在视频中打开很多文件,但是当你开始有很多文件时,它会变得非常有用。
由于插件使用MRU排序对缓冲区进行排序,所以您只需按两次Enter键并跳转到正在编辑的最新文件。
安装插件后,您需要的唯一配置是:
1 | nmap <CR> :CtrlPBuffer<CR> |
当然,您可以将其映射到不同的键,但我发现要输入的映射非常方便。
我建议使用这个插件
NERDtree
这是带有说明的Github链接。
神经树
我使用VIM插件作为插件管理器,但您也可以使用Vundle。
VIM插头
冯德尔
当我开始使用VIM时,我没有意识到标签应该被用作不同的窗口布局,而buffer则充当了相互之间多个文件编辑/切换的角色。实际上,在V7.0之前,标签还没有出现,我只是在一个终端标签中打开了一个VIM(当时我正在使用GNOME终端),然后使用alt+数字在标签之间切换,因为我认为使用诸如:buffers、:bn和:bp之类的命令对我来说太多了。当vim 7.0发布时,我发现管理许多文件并切换到它更容易,但是最近我才意识到缓冲区应该一直是前进的道路,除非有一件事:您需要配置它以使其正常工作。
所以我尝试了VIM航空公司,并启用了顶部标签式缓冲条的视觉效果,但是我的ITerm2出现了问题,所以我尝试了其他一些方法,看起来MBE最适合我。我还将shift+h/l设置为快捷方式,因为原始的快捷方式(移动到当前页面的头/尾)对我不太有用。
它似乎比gt和gt更容易,并且:e也比:tabnew更容易。我发现:bd并不像:q那么方便(MBE有点问题),但是我可以在缓冲区中处理所有的文件。
你可以是一个绝对的疯子,在你的
alias vim="vim -p"
这将导致在选项卡中从shell打开多个文件,而不必随后在vim中调用
这个线程中的大多数答案都是使用普通的vim命令,这当然很好,但我认为我将使用插件和我认为特别有用的功能(至少其中一些技巧来自Gary Bernhardt的文件导航技巧)提供广泛的答案:
要在最后两个文件之间切换,只需按两次
1 | nnoremap <leader><leader> <c-^> |
对于快速移动一个项目,答案是一个模糊匹配解决方案,如ctrlp。我把它绑定到
在这种情况下,我希望看到当前打开的缓冲区的可视化表示,我使用bufexplorer插件。简单但有效。
如果我想浏览文件系统,我会使用命令行或外部实用程序(quicklsilver、afred等),但查看当前的项目结构nerd树是一个经典。但不要用它代替
这些应该足以找到和打开文件。从那里当然可以使用水平和垂直分割。关于分裂,我发现这些函数特别有用:
当空间不足时,在较小的区域打开新的拆分,并在导航中展开它们。有关这些功能的具体操作,请参阅此处的注释:
1 2 3 4 5 6 7 8 | set winwidth=84 set winheight=5 set winminheight=5 set winheight=999 nnoremap <C-w>v :111vs<CR> nnoremap <C-w>s :rightbelow split<CR> set splitright |
轻松地从拆分移动到拆分:
1 2 3 4 | nnoremap <C-J> <C-W><C-J> nnoremap <C-K> <C-W><C-K> nnoremap <C-L> <C-W><C-L> nnoremap <C-H> <C-W><C-H> |
如果你在OSX上并且想点击你的标签,可以使用mouseterm和simbl(从这里获取)。另外,请查看此相关讨论。