vim handbook

差那么点意思啊

参考教程
参考教程

记个终端的

1
2
ctrl + b 前移光标
ctrl + f 后移光标

词移动

w

“w” 移动到下一个单词的词首

    This is a line with example text 
      x-->-->->----------------->
       w  w  w    3w

b

“b” 命令向后移动到前一个词的词首

    This is a line with example text 
    <----<--<-<---------<--x
       b   b b    2b      b

e, ge

“e” 命令可以移到下一个单词的词末
“ge” 则移动到前一个单词的末尾

    This is a line with example text 
       <----<----x---->------------>
       2ge   ge     e       2e

移动到行首或行尾

“$” 命令把光标移动到当前行行尾

“^” 命令把光标移动到一行的第一个非空字符

“0” 命令 (零) 移到一行的第一个字符

移动到一个指定的字符

“f” 代表 “Find” (寻找)

“F” 命令用于向左查找

    To err is human.  To really foul up you need a computer. 
    ---------->--------------->
        fh           fy

    To err is human.  To really foul up you need a computer. 
              --------------------->
                       3fl

“t” 表示 “To” (到达)

“Tx” 是这个命令的反向版本

    To err is human.  To really foul up you need a computer. 
               <------------  ------------->
                    Th              tn

这四个命令可以通过 “;” 命令重复,”,” 命令则用于反向重复。无论用哪个命令,光标
永远都不会移出当前行,哪怕这两行是连续的一个句子。

括号匹配

“%” 它能匹配一对括号

如果光标在 “(“ 上,它移动到对应的 “)” 上,反之,如果它在 “)”
上,它移动到 “(“ 上

                        %
                     <----->
            if (a == (b * c) / d) 
               <---------------->
                        %

移动到指定的行

“G” 命令加上一个计数前缀这个命令可以把你送到指定的行

   |   first line of a file   ^
        |   text text text text    |
        |   text text text text    |  gg
    7G  |   text text text text    |
        |   text text text text
        |   text text text text
        V   text text text text    |
            text text text text    |  G
            text text text text    |
            last line of a file    V

“%” 命令, “50%” 移动到文件的中间,”90%” 移到差不多结尾的位置

移动到视野之内的一行,”H” 表示 Home (头),”M” 表示 Middle (中) 而 “L” 表示 Last (尾)

                    +---------------------------+
            H -->   | text sample text          |
                    | sample text               |
                    | text sample text          |
                    | sample text               |
            M -->   | text sample text          |
                    | sample text               |
                    | text sample text          |
                    | sample text               |
            L -->   | text sample text          |
                    +---------------------------+

滚屏

CTRL-U 命令向下滚动半屏

CTRL-D 命令把视窗向下移动半屏

                               +----------------+
                                   | some text      |
                                   | some text      |
                                   | some text      |
    +---------------+              | some text      |
    | some text     |  CTRL-U  --> |                |
    |               |              | 123456         |
    | 123456        |              +----------------+
    | 7890          |
    |               |              +----------------+
    | example       |  CTRL-D -->  | 7890           |
    +---------------+              |                |
                                   | example        |
                                   | example        |
                                   | example        |
                                   | example        |
                                   +----------------+

每次滚一行的命令是 CTRL-E (上滚) 和 CTRL-Y (下滚)

“zz” 命令,光标所在行处于屏幕的中间

“zt” 把光标所在行移动到屏幕的顶部

“zb” 则移动到屏幕的底部

简单查找

查找命令是 “/String”

要查找单词 “include”,使用如下命令:

    /include

要查找下一个匹配可以使用 “n” 命令

查找光标后的第一个 #include:

    /#include

“?” 命令功能与 “/“ 的功能类似,但进行反方向查找:

    ?word

“N” 命令在反方向重复前一次查找,因此,在 “/“ 命令后执行 “N” 命令是反向查找,在
“?” 命令后执行 “N” 命令是正向查找。

历 史 记 录

假设你执行了三个查找命令:

    /one
    /two
    /three

现在,让我们输入 “/“ 启动一次查找,但先不按下回车键。现在按 (上箭头),Vim
把 “/three” 放到你的命令行上。回车就会从当前位置查找 “three”。如果你不回车,继
续按 ,Vim 转而显示 “/two”,而下一次 变成 “/one”。
你还可以用 命令在历史记录中反向查找。

在 文 本 中 查 找 一 个 单 词

把光标移到那个单词下面使用 “*” 命令。Vim 会取得光标上的
单词并把它作为被查找的字符串

“#” 命令在反向完成相同的功能。你可以在命令前加一个计数: “3*” 查找光标下单
词第三次出现的地方。

查 找 整 个 单 词

找到以 “the” 结尾的单词

/the\>

“>“ 是一个特殊的记号,表示只匹配单词末尾。类似地,”<“ 只匹配单词的开头。
这样,要匹配一个完整的单词 “the”,只需:

/\<the\>

高 亮 匹 配

变量 “nr”。你可以把光标移到 “nr” 下用 “*” 命令,然后用 n 命令一个个遍历

:set hlsearch

:set nohlsearch

使用标记

当你用 “G” 命令跳到另一个地方,Vim 会记住你从什么地方跳过去的。这个位置成为一
个标记,要回到原来的地方,使用如下命令:

    ``

有 名 字 的 标 记

命令 “ma” 用 a 标记当前的光标位置

你可以在文本中使用 26 个标记 (a 到 z)

要跳到一个你定义的标记,可以使用命令 `{mark},这里 {mark} 是指定义标记的那
个字母。所以,移到标记 a 的命令是:

    `a

取得所有的标记的列表
:marks

你会注意到有一些特殊的标记,包括:

    '       跳转前的光标位置
    "       最后编辑的光标位置
    [       最后修改的开始位置
    ]       最后修改的结束位置

快 捷 键

有些操作符 - 动作命令由于经常被使用,所以被设置为单字符命令:

    x  表示  dl  (删除当前光标下的字符)
    X  表示  dh  (删除光标左边的字符)
    D  表示  d$  (删除到行尾)
    C  表示  c$  (修改到行尾)
    s  表示  cl  (修改一个字符)
    S  表示  cc  (修改一整行)

替 换 单 个 字 符

“r” 命令不是操作符。它只是等你输入一个字符然后用这个字符替换当前光标上的字符

你可以用 “cl” 命令或者 “s” 命令完成相同的功能,但 “r” 命令不需要使用 退
出插入状态:
there is somerhing grong here
rT rt rw

    There is something wrong here 

可视模式

用 “v” 命令启动可视模式

如果你想对整行做操作,可以使用 “V” 命令来启动可视模式

如果你在可视模式下选中了一些文字,然后你又发现你需要改变被选择的文字的另一端,
用 “o” 命令即可 (提示: “o” 表示 other end),光标会移动到被选中文字的另一端,现
在你可以移动光标去改变选中文字的开始点了。再按 “o” 光标还会回到另一端。

当使用列块可视模式的时候,你会有四个角,”o” 只是把你移到对角上。而用 “O” 则能
移到同一行的另一个角上。

daw

“daw” 的 “d” 是删除操作符。”aw” 是一个文本对象。提示: “aw” 表示 “A Word” (一个
单词),这样,”daw” 就是 “Delete A Word” (删除一个单词)。确切地说,该单词后的空
格字符也被删除掉了 (或者如果在行尾的话,单词前的空格字符)。

编辑另一个文件

:edit foo.txt

文件列表

你可以在启动 Vim 的时候指定一堆文件。例如:

    vim one.c two.c three.c

这个命令启动 Vim 并告诉它你要编辑三个文件。Vim 只显示第一个。等你编辑完第一个
以后,用如下命令可以编辑第二个:

    :next

如果你在当前文件中有未保存的修改,你会得到一个错误信息而无法编辑下一个文件。这
个问题与前一节执行 “:edit” 命令的问题相同。要放弃当前修改:

    :next!

但大多数情况下,你需要保存当前文件再进入下一个。这里有一个特殊的命令:

    :wnext

这相当于执行了两个命令:

    :write
    :next

从一个文件跳到另一个文件

要在两个文件间快速跳转,按 CTRL-^ (美式英语键盘中 ^ 6 的上面)

文件标记

在 03.10 一节,我们介绍过使用 “mx” 命令在文件中增加标记,那只在一个文件中有
效。如果你编辑另一个文件并在那里加了标记,这些标记都是这个文件专用的。这样,每
个文件都有一个自己的标记集,并只能在该文件中使用。
到此为止,我们都用小写字母的标记。实际上还可以使用大写字母标记,这种标记是
全局的,它们可以在任何文件中使用。例如,你在编辑一个文件 “foo.txt”。在文件的中
间 (50%) 并建立一个 J 标记 (J 表示甲):

    50%mJ

现在编辑文件 “bar.txt” 并在文件的最后一行放一个标记 Y (Y 表示乙):

    GmY

现在你可以使用 “J" 命令跳回到 foo.txt 的中间。或者在另一个文件中输入 "Y” 跳
回到 bar.txt 的末尾。

文件标记会被一直记住直到被重新定义。这样,你可以在一个文件中留下一个标记,然后
任意做一段时间的编辑,最后用这个标记跳回去。
让文件标记符和对应的位置建立一些关系常常是很有用的。例如,用 H 表示头文件
(Head File),M 表示 Makefile 而 C 表示 C 的代码文件。

要知道一个标记在什么地方,在 “:marks” 命令中加上标记名作为参数即可:

    :marks M

你还可以带多个参数:

    :marks MCP

别忘了你还可以 CTRL-O 和 CTRL-I 在整个跳转序列中前后跳转。

分割窗口

水平分割

:split命令把屏幕分解成两个窗口并把光标置于上面的窗口中:

    +----------------------------------+
    |/* file one.c */                  |
    |~                                 |
    |~                                 |
     one.c============================= 
    |/* file one.c */                  |
    |~                                 |
     one.c============================= 
    |                                  |
    +----------------------------------+

CTRL-W w 命令可以用于在窗口间跳转

垂直分割

要在窗口左边打开新窗口,用这个命令:

    :vsplit

或者

    :vsplit two.c

这个命令的结果如下:

    +--------------------------------------+
    |/* file two.c */   |/* file one.c */  |
    |~                  |~                 |
    |~                  |~                 |
    |~                  |~                 |
     two.c===============one.c============= 
    |                                      |
    +--------------------------------------+

还有一个 “vnew” 命令,用于打开一个垂直分割的新窗口。还有一种方法是:

    :vertical new

用另一个文件分割窗口

:split two.c

要打开窗口编辑一个新文件,可以使用如下命令:

    :new

你可以重复使用 “:split” 和 “:new” 命令建立任意多的窗口。

关 闭 窗 口

以下命令用于关闭窗口:

    :close

关 闭 所 有 其 它 窗 口

如果你已经打开了一整套窗口,但现在只想编辑其中一个,如下命令可以完成这个功能:

    :only

窗口大小

要扩大窗口:

    CTRL-W +

要缩小窗口:

    CTRL-W -

要把一个窗口设置为指定的高度,可以用这个命令:

    {height}CTRL-W _

窗 口 间 跳 转

    CTRL-W h        跳转到左边的窗口
    CTRL-W j        跳转到下面的窗口
    CTRL-W k        跳转到上面的窗口
    CTRL-W l        跳转到右边的窗口

    CTRL-W t        跳转到最顶上的窗口
    CTRL-W b        跳转到最底下的窗口

移动窗口

    CTRL-W K
    CTRL-W H        把当前窗口移到最左边
    CTRL-W J        把当前窗口移到最下边
    CTRL-W L        把当前窗口移到最右边

对所有窗口执行命令

    :qall

这表示 “quit all” (全部退出)。如果任何一个窗口没有存盘,Vim 都不会退出。同时光
标会自动跳到那个窗口,你可以用 “:write” 命令保存该文件或者 “:quit!” 放弃修改。

如果你知道有窗口被改了,而你想全部保存,则执行如下命令:

    :wall

这表示 “write all” (全部保存)。但实际上,它只会保存修改过的文件。Vim 知道保存
一个没有修改过的文件是没有意义的。
另外,还有 “:qall” 和 “wall” 的组合命令:

    :wqall

这会保存所有修改过的文件并退出 Vim 。
最后,下面的命令由于退出 Vim 并放弃所有修改:

    :qall!

用 vimdiff 显示文件差异

在命令行中输入如下命令: (不是在 Vim 中)

    vimdiff main.c~ main.c

Vim 会用垂直分割的方式打开两个文件。你只能看到你修改过的地方和上下几行的地方。

     VV                   VV
    +-----------------------------------------+
    |+ +--123 lines: /* a|+ +--123 lines: /* a|  <- 折叠
    |  text              |  text              |
    |  text              |  text              |
    |  text              |  text              |
    |  text              |  changed text      |  <- 修改过的行
    |  text              |  text              |
    |  text              |  ------------------|  <- 删除的行
    |  text              |  text              |
    |  text              |  text              |
    |  text              |  text              |
    |+ +--432 lines: text|+ +--432 lines: text|  <- 折叠
    |  ~                 |  ~                 |
    |  ~                 |  ~                 |
     main.c~==============main.c============== 
    |                                         |
    +-----------------------------------------+

改变大小写

~ 改变当前字母

你手头有一个分节标题全部是小写的。你想把全部 “section” 改成大写的。这可以用
“gU” 操作符。先在第一列执行:

                         gUw
    section header      ---->      SECTION header

“gu” 的作用正好相反:

                         guw
    SECTION header      ---->      section header

你还可以用 “g“ 来交换大小写。所有这些命令都是操作符,所以它们可以用于 “动作”
命令,文本对象和可视模式。
要让一个操作符作用于当前行,可以执行这个操作符两次。例如,”d” 是删除操作
符,所以删除一行就是 “dd”。相似地,”gugu” 使整一行变成小写。这可以缩成 “guu”。
“gUgU” 可以缩成 “gUU” 而 “g
g~” 则是 “g~~”。例如:

                            g~~
    Some GIRLS have Fun    ---->   sOME girls HAVE fUN 

单词替换

替换命令可以在全文中用一个单词替换另一个单词:

    :%s/four/4/g

“%” 范围前缀表示在所有行中执行替换。最后的 “g” 标记表示替换行中的所有匹配点。
如果你有一个像 “thirtyfour” 这样的单词,上面的命令会出错。这种情况下,这
个单词会被替换成 “thirty4”。要解决这个问题,用 “<“ 来指定匹配单词开头:

    :%s/\<four/4/g

显然,这样在处理 “fourteen” 的时候还是会出错。用 “>“ 来解决这个问题:

    :%s/\<four\>/4/g

如果你在编码,你可能只想替换注释中的 “four”,而保留代码中的。由于这很难指定,
可以在替换命令中加一个 “c” 标记,这样,Vim 会在每次替换前提示你:

    :%s/\<four\>/4/gc

j k h l
命令 操作
ddp 交换上下行
yyp 复制当前行
gd 跳到定义
/def 跳到下个函数开始的地方
cf. 直接修改到下个 .

常用设置

设置 syntax on

设置 行号 set nu

设置自动缩进 set autoindent

:e! 重新加载并且不保存文件

移动

基于单词的移动

1
2
w (word) 下一个单词
b (back word) 移动回上一个单词

行移动

1
2
3
4
5
6
:18 移动光标到 18
14G 移动到 14
0 移动光标到行首
^ 移动到第一个非空白字符
$ 移动光标到行尾
g_ 移动到行尾非空白字符

行间搜索移动

  • 使用 f{char} 可以移动到 char 字符上, t 移动到 char 前一个字符
  • 使用 ; 或 , 继续搜索下一个或上一个

单词移动

word: 以非空白符分割的单词

WORD: 以空白符分割的单词

  • w/W 移动到下一个 word/WORD 开头, e/E 下一个 word/WORD 尾
  • b/B 回到上一个 word/WORD 开头

翻页

  • gg 移动到文件开头
  • G 移动到文件结尾
  • ctrl + O 返回到刚刚移动的位置
  • H/M/L 跳转到屏幕的开头, 中间和 结尾
  • ctrl + f, ctrl+u 上下翻页,
  • zz 把屏幕放在中间

1
2
3
a/A (append)
i/I (insert)
o/O (open a line)

a 会在当前字母的后面插入

i 会在当前字母的前面插入

o 会打开一个新行

A 在行末添加

I 在行首插入

O 在当前行的上方插入

删除

1
2
3
4
5
6
7
8
9
d (delete)
dw (del word)
dd (del line)
x (删除一个字符)
diw (del inner word) 删除不包含空格的单词
daw (del around word)
ctrl + h 删除上一个字符
ctrl + w 删除上一个单词
ctrl + u 删除当前行

d,x 都可以搭配数字执行多次

  • 2dd/2x 删除两行/删除两个字符

  • dt] del to ], 删除到 ] 的所有内容

  • d0/d& 快速删除行首和行尾

  • r replace
  • c change
  • s substitue

normal 模式下使用 r 替换一个字符, s 替换并进入插入模式

使用 c 配合文本对象, 可以进行快速修改

1
2
3
4
c (change)
ciw (change inner word) 自动删除单词并进入插入模式
ct) (chang to ) )?? 修改到右括号
ci" 删除双引号的内容并进入插入模式

1
2
3
4
5
f find
fs 查找当前行一个出现的 s, 使用 ; 查找下一个
/keyword 查找单词
?keyword 向前查找

使用 n/N 跳转到下一个或者上一个匹配

翻页

1
2
ctrl + f (forward)
ctrl + u (upward)

粘贴复制

1
2
y yank
p paste

分屏

1
2
vs vertical split
sp split

搜索和替换

1
% s/foo/bar/g

其它常用命令

设置行号

:set nu

visual 模式

一般用来块状选择文本

normal 模式下使用 v 进入 visual 模式

1
2
3
4
V  选中行
ctrl + v 进行块选择
viw 选中单词
vaw 选中单词带空格

快速切换 insert normal 模式

  • ctrl + c (可能会中断插件) 或者 ctrl + [
  • gi 快速跳转到最后一次编辑的地方并进入 insert 模式

多文件

buffer windows tab

buffer 指打开的文件的一个内存缓冲区

窗口是 buffer 可视化的分割区

tab 是窗口的工作区

文本对象操作方式

[number] <command> [text object]
`[次数] <命令 (delete change yank)>[文本对象 (单词 w, 句子 s, 段落 p)]

复制粘贴和寄存器的使用

Vim 里面剪切 (cut) 复制 (copy) 粘贴 (paste) 分别是 delete/yank/put

normal 模式

normal 模式下复制粘贴分别使用 y(yank) 和 p(put), 剪贴 d 和 p

可以使用 v(visual) 命令选中要复制的地方, 然后使用 p 粘贴

配合文本对象使用:

  • yiw 复制一个单词
  • yy 复制一行

insert 模式下的复制粘贴

很多人会使用鼠标进行选中, 然后使用 ctrl + v 进行粘贴, 这里和其它编辑器差不多, 但是粘贴代码的时候会有个坑

当设置了 autoindent, 粘贴代码时缩进会混乱

这个时候需要使用 set: pasteset: nopaste 解决

寄存器

Vim 操作的是寄存器, 不是系统剪贴板

默认我们使用 d 删除 或者 y 复制的内容都会放到这个 寄存器

使用 x 删除一个字符放到寄存器, 然后使用 p 粘贴, 可以调换两个字符

指定寄存器

通过 “{register}” 前缀可以指定寄存器, 不指定则默认使用无名寄存器

比如, 使用 "ayiw 复制一个单词到寄存器 a 中, "bdd 删除当前行到寄存器 b 中

Vim 中 "" 表示无名寄存器, 缺省使用. ""p 等同于 p

其它一些寄存器

复制专用寄存器 `”0 使用 y 复制文本同时会被拷贝到复制寄存器 0

系统剪贴板 “+ 可以在复制前加上 “+ 复制到系统剪贴板, 可以使用系统剪贴板粘贴到其它地方

"% 当前文件名, “. 上次插入的文本

设置系统剪贴板为默认无名寄存器

set clipboard=unnamed

vim 宏(macro)

什么是宏

宏 是一系列命令的集合

我们可以使用宏 [录制] 一系列操作, 然后用于 [回放]

使用宏

宏的使用分为录制和回放

normal 模式下使用 q 来录制, 同时也是 q 来结束录制

使用 q{register} 选择要保存的寄存器, 把录制的命令保存其中

使用 @{register} 回放寄存器中保存的一系列命令

vim 中的补全

使用 ctrl + n 和 ctrl + p 补全单词

使用 ctrl + x 和 ctrl + f 补全文件名

使用 ctrl + x ctrl + o 补全代码, 需要开启文件类型检查, 安装插件

使用 ctrl + xf 补全文件路径

vim 换色

使用 :colorscheme 显示当前的主题配色, 默认 default

使用 :colorscheme <ctrl + d> 可以显示所有的配色

使用 :colorscheme 配色名可以修改配色

vim 配置

配置文件 ~/.vimrc, 常用设置

idea 和 vscode 输入法自动切换

idea

使用 ideavim_extension

vscode

使用 im-select

配置 vscode , 在 setting.json 中添加

1
2
3
4
"vim.autoSwitchInputMethod.enable": true,
"vim.autoSwitchInputMethod.defaultIM": "com.apple.keylayout.ABC",
"vim.autoSwitchInputMethod.obtainIMCmd": "/usr/local/bin/im-select",
"vim.autoSwitchInputMethod.switchIMCmd": "/usr/local/bin/im-select {im}"