Vim

来自 ArchWiki

Vim 是一个终端文本编辑器。它是 vi 的扩展版本,具有额外的功能,包括语法高亮、全面的帮助系统、原生脚本 (Vim script)、用于文本选择的可视模式、文件比较 (vimdiff(1)),以及功能受限的工具,例如 rview(1)rvim(1)

安装

安装以下软件包之一

  • vim — 支持 PythonLuaRubyPerl 解释器,但不包含 GTK/X 支持。
  • gvim — 除了提供上述 vim 软件包的功能外,还包含 GTK/X 支持。
注意
  • vim 软件包构建时没有 Xorg 支持;具体来说,缺少 +clipboard 功能,因此 Vim 将无法与 primaryclipboard 选择缓冲区一起使用。gvim 软件包也提供了带有 +clipboard 功能的 Vim 的 CLI 版本。
  • 非官方仓库 herecura 还提供了许多 Vim/gVim 变体:vim-clivim-gvim-commonvim-gvim-gtk3vim-rtvim-tiny

用法

有关如何使用 Vim 的基本概述,请运行 vimtutor(终端版本)或 gvimtutor(图形版本)来学习 Vim 教程

Vim 包含广泛的帮助系统,可以使用 :h 主题 命令访问。主题包括命令、配置选项、快捷键绑定、插件等。使用 :h 命令(不带任何主题)获取有关帮助系统和主题之间跳转的信息。

配置

Vim 的用户特定配置文件位于主目录中:~/.vimrc,当前用户的 Vim 文件位于 ~/.vim/ 中。全局配置文件位于 /etc/vimrc。全局 Vim 文件(如 defaults.vimarchlinux.vim)位于 /usr/share/vim/ 中。

从版本 9.1.0327 开始,Vim 采用了 freedesktop XDG Base Directory Specification:这意味着,您现在可以将配置文件放在 ~/.config/vim/ 下,这样 Vim 将不再使您的主目录显得杂乱。

对于 gVim,用户特定的配置文件位于 ~/.gvimrc,全局配置文件位于 /etc/gvimrc

注意
  • 通常期望的行为(如语法高亮)在 defaults.vim 中启用,当不存在 ~/.vimrc 时加载。将 let skip_defaults_vim=1 添加到 /etc/vimrc 以完全禁用 defaults.vim 的加载。[1]。或者,要在存在 ~/.vimrc 时也启用 defaults.vim,请参阅 vim 中的 :h defaults
  • gVim 同时加载 VimgVim 的配置文件,而 Vim 仅加载 Vim 的配置文件。

剪贴板

Vim 命令(如 :yank:put)通常与未命名寄存器 "" 一起使用。如果 +clipboard 功能可用,并且其值包含 unnamed,那么通常会转到未命名寄存器的 Vim yank、delete、change 和 put 操作将使用剪贴板寄存器 "*,它是 X 中的 PRIMARY 缓冲区。

要更改默认寄存器,您可以 :set clipboard=unnamedplus 以使用 "+ 寄存器代替。"+ 剪贴板寄存器对应于 X 中的 CLIPBOARD 缓冲区。应该注意的是,clipboard 选项可以设置为逗号分隔的值。如果您 :set clipboard=unnamedplus,unnamed,那么除了 "+ 寄存器之外,yank 操作还会将 yank 的文本复制到 "* 寄存器(但是,delete、change 和 put 操作仍然只会对 "+ 寄存器进行操作)。

有关更多信息,请参阅 :help 'clipboard'clipboard 功能可以设置其他值。您可以使用 :help clipboard-unnamed 来转到可以为此功能设置的第一个有效值的帮助主题,然后是所有其他有效值的帮助。

提示
  • 可以为复制和粘贴操作创建自定义快捷方式。例如,请参阅 [2],了解如何绑定 Ctrl+cCtrl+vCtrl+x
  • Vim 退出时,X 剪贴板会被刷新。要使 Vim 选择在 X 剪贴板中持久存在,您需要一个 剪贴板管理器。或者,您可以将 autocmd VimLeave * call system("echo -n $'" . escape(getreg(), "'") . "' | xsel --input --clipboard") 添加到您的 .vimrc(需要 xsel 软件包)。

语法高亮

要为多种编程语言启用语法高亮

:filetype plugin on
:syntax on

缩进

此条目或章节需要扩充。

原因: 描述 autoindentsmartindent 选项。(在 Talk:Vim 中讨论)

可以使用以下命令加载特定文件类型的缩进文件

:filetype indent on

可视化换行

默认情况下,wrap 选项处于启用状态,它指示 Vim 换行超过窗口宽度的行,以便行的其余部分显示在下一行。wrap 选项仅影响文本的显示方式,文本本身不会被修改。

换行通常发生在最后一个适合窗口的字符之后,即使它在一个单词的中间。更智能的换行可以使用 linebreak 选项控制。当使用 set linebreak 启用它时,换行发生在 breakat 字符串选项中列出的字符之后,默认情况下,该选项包含一个空格和一些标点符号(请参阅 :help breakat)。

换行通常显示在下一行的开头,而与任何缩进无关。breakindent 选项指示 Vim 在换行长行时考虑缩进,以便换行后的行保持与先前显示的行相同的缩进。breakindent 的行为可以使用 breakindentopt 选项进行微调,例如,将换行后的行向右移动四个空格以用于 Python 文件(有关详细信息,请参阅 :help breakindentopt

autocmd FileType python set breakindentopt=shift:4

使用鼠标

Vim 能够使用鼠标,但它仅适用于某些终端

要启用此功能,请将此行添加到 ~/.vimrc

set mouse=a

mouse=a 选项在 defaults.vim 中设置。

注意: 如果可以访问 X 服务器,复制/粘贴将使用 "* 寄存器,请参阅 #剪贴板 章节。按住 shift 键 仍然可以使用 xterm 鼠标按钮处理。

使用方向键在行之间跳转

默认情况下,在行首按 Left 键,或在行尾按 Right 键,光标不会跳转到上一行或下一行。

可以通过将 set whichwrap=b,s,<,>,[,] 添加到您的 ~/.vimrc 文件来更改默认行为。

合并文件

Vim 包含一个 diff 编辑器(一个显示两个或多个文件之间的差异并帮助方便地合并它们的程序)。使用 vimdiff 运行 diff 编辑器 — 只需向其指定一些文件:vimdiff 文件1 文件2。以下是 vimdiff 特定的命令列表。

操作 快捷键
下一个更改 ]c
上一个更改 [c
diff 获取 do
diff 放置 dp
展开折叠 zo
折叠 zc
重新扫描文件 :diffupdate

技巧和窍门

行号

要显示行号列,请使用 :set number。默认情况下显示绝对行号,可以使用 :set relativenumber 启用相对行号。同时设置两者会启用混合行号——当前行是绝对的,而其他行是相对的。

可以使用 :行号行号gg 跳转到特定行。跳转记录在跳转列表中,有关详细信息,请参阅 :h jump-motions

拼写检查

Vim 具有拼写检查功能,输入以下命令启用:

set spell

默认情况下,仅安装英语语言词典(在 /usr/share/vim/vim82/spell/ 中)。可以在 官方软件仓库 中通过搜索 vim-spell 找到更多词典。其他词典可以放在 ~/.vim/spell/ 文件夹中,并使用以下命令启用::setlocal spell spelllang=en_us(将 en_us 替换为所需词典的名称)。

操作 快捷键
下一个拼写错误 ]s
上一个拼写错误 [s
拼写建议 z=
拼写正确,添加 zg
拼写正确,会话 zG
拼写错误,添加 zw
拼写错误,会话 zW
重复检查文件中所有拼写错误 :spellr
提示
  • 要在两种语言(例如英语和德语)中启用拼写检查,请将 set spelllang=en,de 添加到您的 ~/.vimrc/etc/vimrc 中,然后重启 Vim
  • 您可以使用 FileType 插件和文件类型检测的自定义规则,为任意文件类型(例如 .txt)启用拼写检查。要为任何以 .txt 结尾的文件启用拼写检查,请创建文件 /usr/share/vim/vimfiles/ftdetect/plaintext.vim,并将行 autocmd BufRead,BufNewFile *.txt set filetype=plaintext 插入该文件。接下来,将行 autocmd FileType plaintext setlocal spell spelllang=en_us 插入到您的 ~/.vimrc/etc/vimrc 中,然后重启 Vim。或者,可以简单地将行 autocmd BufRead,BufNewFile *.txt setlocal spell 插入到他们的 ~/.vimrc/etc/vimrc 中,然后重启 Vim。请务必编辑此行(特别是 *.txt)以包含用于拼写检查的文件类型。
  • 要仅为 LaTeX (或 TeX) 文档启用拼写检查,请将 autocmd FileType tex setlocal spell spelllang=en_us 添加到您的 ~/.vimrc/etc/vimrc 中,然后重启 Vim

保存运行时状态

通常,退出 vim 会丢弃所有不重要的信息,例如打开的文件、命令行历史记录、yank 的文本等。可以通过以下方式配置保留此信息。

viminfo 文件

viminfo 文件也可用于存储命令行历史记录、搜索字符串历史记录、输入行历史记录、寄存器内容、文件标记、文件中的位置标记、上次搜索/替换模式(在会话中与 n& 一起在搜索模式中使用)、缓冲区列表以及您可能已定义的任何全局变量。要使 viminfo 模式可用,您安装的 vim 版本必须已使用 +viminfo 功能编译。

通过将(例如)以下内容添加到您的 ~/.vimrc 文件中,配置在 viminfo 文件中保留哪些内容

set viminfo='10,<100,:100,%,n~/.vim/.viminfo

其中每个参数前面都有一个标识符

'q  : q, number of edited file remembered
<m  : m, number of lines saved for each register
:p  : p, number of history cmd lines remembered
%   : saves and restores the buffer list
n...: fully qualified path to the viminfo files (note that this is a literal "n")

有关预先存在的 viminfo 文件如何在更新以包含当前会话信息(例如来自您正在退出的当前会话中的多个缓冲区)时被修改的详细信息,请参阅官方 viminfo 文档

会话文件

会话文件可用于随时间推移保存任意数量的特定会话的状态。每个会话或项目可以使用一个不同的会话文件。要使该模式可用,您安装的 vim 版本必须已使用 +mksession 功能编译。

在会话中,:mksession[!] [my_session_name.vim] 会将 vim 脚本写入当前目录中的 my_session_name.vim,如果您选择提供文件名,则默认写入 Session.vim。可选的 ! 将覆盖具有相同名称和路径的预先存在的会话文件。

可以在从终端启动 Vim 时恢复 Vim 会话

$ vim -S [my_session_name.vim]

或通过运行 Vim 命令在已打开的会话缓冲区中恢复

:source my_session_name.vim

有关会话文件中保存的内容以及其他详细信息,请参阅 Vim 文档 中的广泛介绍。注释示例可以在 此处 找到。

保存光标位置

请参阅 Vim wiki 上的 恢复到上一次编辑会话中的文件位置的光标

用 Vim 替换 vi 命令

vi 创建一个指向 vim别名

或者,如果您希望能够键入 sudo vi 并获得 vim,请安装 vi-vim-symlinkAUR,它将删除 vi 并将其替换为指向 vim 的符号链接。您也可以自己创建此符号链接,并将其放置在路径中高于 /usr/bin 的某个位置,以使其优先。

DOS/Windows 回车符

如果每行末尾都有 ^M,则表示您正在编辑在 MS-DOS 或 Windows 中创建的文本文件。这是因为在 Linux 中,仅使用单个换行符 (LF) 进行换行,但在 Windows/MS DOS 系统中,它们使用回车符 (CR) 和换行符 (LF) 的序列来实现相同的目的。这些回车符显示为 ^M

要删除文件中的所有回车符,请执行以下操作

:%s/^M//g

请注意,这里 ^ 是一个控制字符。要输入控制序列 ^M,请按 Ctrl+v,Ctrl+m

或者,安装软件包 dos2unix 并运行 dos2unix 文件 来修复文件。

注意: 另一种简单的方法是更改 fileformat 设置。set ff=unix 将具有 DOS/Windows 行尾的文件转换为 Unix 行尾。要反过来做,只需发出 set ff=dos 将具有 Unix 行尾的文件转换为 DOS/Windows 行尾。

gVim 窗口底部的空白

当使用配置为忽略窗口大小提示的 窗口管理器 时,gVim 将使用 GTK 主题背景颜色填充非功能区域。

解决方案是调整 gVim 在窗口底部保留多少空间。将以下行放在 ~/.vimrc

set guiheadroom=0
注意: 如果您将其设置为零,您将看不到底部的水平滚动条。

Vim 作为分页器

脚本允许将 Vim 用作终端分页器,并具有各种 vim 功能(如配色方案)的优点。要更改默认分页器,请导出 PAGER 环境变量。

Vim 附带 /usr/share/vim/vim91/macros/less.sh 脚本,您可以为其创建别名。请注意,此脚本不支持 less(1) § OPTIONS 中提到的任何命令行标志。

或者,还有 vimpager Vim 脚本。请注意,并非所有命令行标志都受支持;支持的标志列表在 GitHub 上可用

分页器和编辑器之间的折衷方案是 [g]vim -R (gvim -R 等同于 gview)。这将导致编辑器以 readonly 模式打开文件。每个不涉及修改文件的编辑器功能都可以像往常一样使用。实际上,readonly 模式可以显式覆盖,以启用修改。

高亮搜索结果

为了在键入搜索内容时高亮显示搜索中将匹配的第一个字符串,请将以下行添加到您的 ~/.vimrc

set incsearch

为了在键入搜索内容时以及在执行搜索后高亮显示搜索中将匹配的所有字符串,请将以下行添加到您的 ~/.vimrc

set hlsearch
注意
  • 设置 hlsearch 将使所有匹配项保持高亮显示,直到进行进一步搜索。这种行为可能不受欢迎,因此要暂时禁用高亮显示,直到下一次搜索,请运行 :nohlsearch。如果您发现自己经常运行此命令,请考虑将其绑定到某个键。
  • 当在其他涉及正则表达式的命令(如 sg)期间匹配正则表达式时,也会观察到此行为。

XDG Base Directory 规范的解决方法

此条目或章节已过时。

原因:[3] 提交以来,$XDG_CONFIG_HOME 已被支持。(在 Talk:Vim 中讨论)

7.3.1178 起,如果未找到 ~/.vimrcVim 将搜索 ~/.vim/vimrc

"$XDG_CONFIG_HOME"/vim/vimrc
set runtimepath^=$XDG_CONFIG_HOME/vim
set runtimepath+=$XDG_DATA_HOME/vim
set runtimepath+=$XDG_CONFIG_HOME/vim/after

set packpath^=$XDG_DATA_HOME/vim,$XDG_CONFIG_HOME/vim
set packpath+=$XDG_CONFIG_HOME/vim/after,$XDG_DATA_HOME/vim/after

let g:netrw_home = $XDG_DATA_HOME."/vim"
call mkdir($XDG_DATA_HOME."/vim/spell", 'p')

set backupdir=$XDG_STATE_HOME/vim/backup | call mkdir(&backupdir, 'p')
set directory=$XDG_STATE_HOME/vim/swap   | call mkdir(&directory, 'p')
set undodir=$XDG_STATE_HOME/vim/undo     | call mkdir(&undodir,   'p')
set viewdir=$XDG_STATE_HOME/vim/view     | call mkdir(&viewdir,   'p')

if !has('nvim') | set viminfofile=$XDG_STATE_HOME/vim/viminfo | endif
~/.profile
export GVIMINIT='let $MYGVIMRC="$XDG_CONFIG_HOME/vim/gvimrc" | source $MYGVIMRC'
export VIMINIT='let $MYVIMRC="$XDG_CONFIG_HOME/vim/vimrc" | source $MYVIMRC'

[G]VIMINIT 环境变量也会影响 Neovim。如果需要 VimNeovim 的单独配置,则以下将是更好的选择

export GVIMINIT='let $MYGVIMRC = !has("nvim") ? "$XDG_CONFIG_HOME/vim/gvimrc" : "$XDG_CONFIG_HOME/nvim/init.gvim" | so $MYGVIMRC'
export VIMINIT='let $MYVIMRC = !has("nvim") ? "$XDG_CONFIG_HOME/vim/vimrc" : "$XDG_CONFIG_HOME/nvim/init.vim" | so $MYVIMRC'

插件

Vim 添加插件可以通过扩展 Vim 功能来提高您的工作效率。插件可以更改 Vim UI,添加新命令,启用代码补全支持,将其他程序和实用程序与 Vim 集成,添加对其他语言的支持等等。

提示: 有关常用插件的列表,请参阅 Vim Awesome

安装

使用内置的包管理器

Vim 可以原生加载第三方插件。可以通过将第三方软件包存储在 ~/.vim/pack 文件夹中使用此功能。此文件夹的结构与典型的插件管理器略有不同,后者通常每个插件都有一个目录。以下是典型的安装过程和目录结构(以 Tim Pope 的 vim-surround 插件为例)

$ mkdir -p ~/.vim/pack/tpope/start

重要的是要注意,~/.vim/pack/tpope 是一个软件包目录,在 Vim 文档 中被松散地定义为包含一个或多个插件的目录。但是,不应将插件存储库下载到此目录。软件包目录的名称也是任意的。您可以选择将所有插件保存在单个软件包目录中,或者像我们的示例中一样,使用作者的 GitHub 名称 tpope

软件包目录可以包含以下子文件夹

  • start - 来自此子文件夹的插件将在 Vim 启动时自动加载。这是最常用的位置。
  • opt - 可以通过在 Vim 中发出 :packadd 命令按需加载来自此子文件夹的插件。

现在更改为 start 文件夹并检出插件存储库

$ cd ~/.vim/pack/tpope/start
$ git clone https://tpope.io/vim/surround.git

这将创建一个额外的子文件夹 ~/.vim/pack/tpope/start/surround,插件文件放置在该文件夹中。

接下来,如果插件包含帮助文件,则更新帮助索引

$ vim -u NONE -c "helptags surround/doc" -c q

现在,插件将在启动 Vim 时自动加载。无需更改 ~/.vimrc,插件特定的选项除外。

使用插件管理器

插件管理器是一个插件,用于安装、管理和更新 Vim 插件。如果您还在 Arch Linux 以外的平台上使用 Vim,并且想要一种一致的插件更新方法,这将非常有用。

从 Arch 软件仓库

vim-plugins 组提供了各种插件。使用 pacman -Sg vim-plugins 命令列出可用的软件包,然后可以使用 pacman 安装 它们。

值得注意的插件

cscope

Cscope 是一个用于浏览项目的工具。通过导航到单词/符号/函数并调用 cscope(通常使用快捷键),它可以找到:调用该函数的函数、函数定义以及更多内容。

安装 cscope 软件包。

复制 cscope 默认文件,Vim 将自动读取它

mkdir -p ~/.vim/plugin
wget -P ~/.vim/plugin https://cscope.sourceforge.net/cscope_maps.vim

创建一个文件,其中包含您希望 cscope 索引的文件列表(cscope 可以处理多种语言,但此示例查找 .c.cpp.h 文件,特定于 C/C++ 项目)

$ cd /path/to/project/dir
$ find . -type f -print | grep -E '\.(c(pp)?|h)$' > cscope.files

创建 cscope 将读取的数据库文件

$ cscope -bq
注意: 您必须从此位置浏览您的项目文件,或者设置并导出 $CSCOPE_DB 变量,将其指向 cscope.out 文件。

默认键盘快捷键

 Ctrl-\ and
      c: Find functions calling this function
      d: Find functions called by this function
      e: Find this egrep pattern
      f: Find this file
      g: Find this definition
      i: Find files #including this file
      s: Find this C symbol
      t: Find assignments to

您可以随意更改快捷键。

#Maps ctrl-c to find functions calling the function
nnoremap <C-c> :cs find c <C-R>=expand("<cword>")<CR><CR>

Taglist

Taglist 提供了源代码文件结构的概览,并允许您有效地浏览不同编程语言的源代码文件。

安装 vim-taglistAUR 软件包。

~/.vimrc 中要放入的有用选项

let Tlist_Compact_Format = 1
let Tlist_GainFocus_On_ToggleOpen = 1
let Tlist_Close_On_Select = 1
nnoremap <C-l> :TlistToggle<CR>

故障排除

gVim 速度慢

Vim 的 GTK 3 GUI 可能比 GTK 2 版本慢(参见 FS#51366)。gvim-gtk2AUR 可以作为一种解决方法安装。

双向支持

Vim 仍然缺乏完整的双向支持,并且这取决于终端。

使用 :rightleft 强制文本对齐。可以使用以下方式将其分配给一个快捷键

inoremap <C-X> <C-O>:silent if &rl <Bar> set rl! <Bar> else <Bar> set rl <Bar> endif<CR>

Vim 有其自己的字母整形功能。尽管存在一些 渲染问题,但这在没有字母整形支持的终端上(如 alacrittyst)也能工作。整形取决于 阿拉伯文表示形式-B (U+FE70–FEFF),因此请确保您的字体包含对这些字符的支持。由于没有已知的完全支持这些字符的等宽字体,您需要有一个额外的后备字体(例如:vazir-code-fontsAUR,后备到 ttf-dejavu)。请参阅 St#阿拉伯文整形支持 以获得终端字体设置示例。

但是,如果终端支持字母整形(如 gnome-terminal 和其他基于 libvte 的终端),那么 Vim 和终端字母整形可能会冲突,从而导致阿拉伯文本乱码。目前,Vim 无法检测 终端是否具有字母整形功能。因此,解决方法是手动告诉 Vim 将字母整形留给终端处理,方法是 :set notbidi。请注意,由于 限制,当 :set rightleft 时,这将导致文本反向。有关更多信息,请参阅 :set arabic

参见

官方

教程

视频

速查表

游戏

配置

颜色