我经常试图去学习Emac编辑器/IDE/OS. 我最后一次尝试时,我花了一些时间去适应,直到我想去配置一个自己的.emacs文件
在我用vi打开.emacs文件那一刻,我意识到我做了什么,vim早已经赢得了我的青睐.
所以,我将vim作为我的首选编辑器[注1]
另一个动机是,我发现我最喜欢的shell(ZSH)有很酷的 vi-mode 包含命令模式(使得,你可以在命令和插入模式之间切换)
Vim有一系列给力的特性,并且学习它们需要花费一些时间.当然,现在有很多在线指南和技巧文章,但是帮助文档同样很优秀!有概览页面,总结页面和一些注释
我开始使用官网的指南和帮助系统学习(输入 :help 可以从命令模式获取帮助), 我喜欢在测试文件中测试命令,并且对重要的命令写下简短的说明
另一个我使用Vim的原因是,使用Vim比Emacs更加健康(使用默认键映射).健康?很多命令可以简单地通过一次敲击完成 - 模式编辑器的优点,不需要使用由很多修改关键字组成的长命令串.即使你有一个正常的键盘,敲击Ctrl,Alt等键很显然不是那么正常
只需要记住:Vim的命令都非常简单,但是简单命令组合起来将变得十分强大
Vim有3种模式:
1.命令行模式:所有键盘输入都是命令
2.插入模式:大部分键盘输入作为文本插入(出了少部分特殊键)
3.可视模式:用于帮助选中文本,可以看做是命令行模式的子模式
从插入模式或可视模式切换到命令模式,按
从命令模式切换到插入模式:
* i 在当前位置之前插入
* a 在当前位置之后插入(追加)
* I 调到当前行第一个非空白字符之前插入
* A 调到当前行最后一个字符之后插入
从命令模式到可视模式:
* v 切换到可视模式(字符级别)
* V 切换到可视模式(行级别)
* ctrl-v 切换到块可视模式(块级别的)
所有操作,比如替换,删除,拷贝或排版,在可视模式下同样适用
简单的移动命令
* h 左移
* l 右移
* k 上移
* j 下移
很显然,这几个命令只在命令模式下可用,当然,你可以用方向键(在所有模式下适用)
Vim有很多移动命令,我只是学习了一部分,但是如果你需要一些特殊的移动方式,可以看看帮助,我确定你会找到有用的方法
Vim distinguishes between screen-lines (those shown on the monitor) and real lines (those ended with a new-line). Vim区分逻辑行(频幕上展示的)和物理行(实际以\n结尾的)
以下是一些重要的命令
0 当前行第一列
^ 当前行第一个非空白字符
w 移到下一个单词
W 移到下一个单词,忽略标点
e 移动到单词尾部
E 移动到单词尾部,忽略标点
b 移动到单词开头
B 移动到单词开头,忽略标点
ge 移动到前一个词尾部
gE 移动到前一个词尾部,忽略标点
g_ 移动到最后一个非空白字符
$ 移动到最后一列
如果你记住一部分,你将学会如何快速从A移动到B!另一个重要的事实是,这些命令说明了基本命令的定义方式
在Vim中,插入文本是很简单的事情,只需要敲i并且开始输入.但是vim提供了相当丰富的文本编辑命令
d 删除当前光标位置到下一个命令哪个提供位置之间的字符(例如: d$删除当前行光标位置到最后一列的所有字符)
c 修改
x 删除光标位置字符
X 删除光标之前的字符(相当于回退)
y 拷贝
p 在当前光标之后黏贴拷贝的内容
P 在当前光标之前黏贴拷贝的内容
r 替换当前字符
s 用输入替换当前位置到下一个命令给出位置的字符
. 重复上一个命令
dd, cc 或yy 将操作整行,例如yy拷贝当前行
需要注意的是,很多命令比我在这里描述的额更为强大.例如你可以 输入"ayy 拷贝当前行道一个寄存器a,可以使用 "ap 黏贴a中的内容. Vim自动保存最后几个复制或删除的内容,要查看寄存器的内容,输入:registers, 你可以使用它们去黏贴一些老的文本
可视块使得能够在选中文本每一行某个位置插入一个字符
假设你选中了一块代码(Ctrl-v),你可以键入I,在代码块之前插入文本(切换到插入模式).当你离开插入模式时,输入的文本将作用于选中的每一行.使用A在代码块之后进行插入
另一个有用的特性是,你可以用新文本替换整个代码块.选中代码块,输入s,vim进入插入模式,然后输入内容.离开插入模式时,vim将输入的内容插入到剩余行
如果你想追加文本到某些行后边,使用Ctrl-v$选中需要修改的行选中需要修改的行. 这个和上一个命令不同的是,$表示"行尾",ctrl-v选中行的行尾,忽略文本
使用 Ctrl-v:
This is a testNEWLY INSERTED
This is a NEWLY INSERTED
This is NEWLY INSERTED
使用 Ctrl-v$:
This is a testNEWLY INSERTED
This is aNEWLY INSERTED
This isNEWLY INSERTED
Vim命令操作文本对象(字符,单词,括号分割的字符,句子等等)
对我来说,最重要的一个是 在单词中: iw. 要选中当前的单词,只需要键入 viw (v可视模式,iw选中光标所在词),同样的,删除: diw
inner-word/block和a-word/block的区别在于,前者只选中单词的字符(不包括空白字符) 或者括号中的内容(不包括括号本身).后者包括括号本身或者单词后的空白字符
iw 单词
aw 单词+后面空白
iW …inner WORD
aW …a WORD
is 句子
as 句子+后面空白
ip 段落
ap 段落+段落后空白
i( or i) 括号中
a( or a) 括号中+括号
i< or i>
a< or i>
i{ or i}
a{ or a}
i" 引号中
a" 引号中+引号
i`
a`
下面是命令命令的展示,[]表示选中的文本:
iw This is a [test] sentence.
aw This is a [test ]sentence.
iW This is a […test…] sentence.
aW This is a […test… ]sentence.
is …sentence. [This is a sentence.] This…
as …sentence. [This is a sentence. ]This…
ip End of previous paragraph.
[This is a paragraph. It has two sentences.]
The next.
ap End of previous paragraph.
[This is a paragraph. It has two sentences.
]The next.
i( or i) 1 * ([2 + 3])
a( or a) 1 * [(2 + 3)]
i< or i> The <[tag]>
a< or i> The [<tag>]
i{ or i} some {[ code block ]}
a{ or a} some [{ code block }]
i" The "[best]"
a" The[ “best”]
i` The `[best]`
a` The[ `best`]
可以尝试使用,熟悉并记住(对我而言,iw和i() 真正地节省了时间)
不要害怕使用一系列命令,你可以在命令模式下撤销,用u - 甚至用ctrl-r撤销刚才的撤销操作
Vim7.0 介绍了撤销分支,但我没有时间去深入了解
Vim很容易加入外部命令的输出,或者通过外部过滤器过滤整行或部分
使用外部命令 :!command 输出将会展现出来
通过外部命令过滤文本,可以使用 :!sort %
将外部命令的输出插入到当前文件 :r!command (例如 :r!which ls)
查看更多关于filter的信息 :h filter
在Vim中搜索非常简单,在命令模式下输入 / ,然后填入你要搜索的词,然后vim会搜索这个文件(当前位置向前)
使用? 进行向后搜索
在搜索结果中,使用n或N进行重复搜索(和前一个搜索同一个方向)
如果设置了"incsearch", Vim会立刻跳到匹配文本位置,如果设置了"hlsearch", 将会高亮所有匹配文本. 要去除高亮,:nohl
替换同样不是很难,但是你需要对正则表达式有所了解
使用正则替换某些文本,输入 :%s/old/new/gc 这个命令将会遍历整个文件%, 用单词"new"替换所有"old". g代表替换行中所有匹配文本,c代表替换前询问
如果只需要替换选中区域中的某些文本,选中区域,输入 :s/old/new/g.
这个就像
:'<,'>s/old/new/g
在标签一节之后,你将会知道 '<'和'>'的意思
在你输入时,反复输入同一个词是很正常的事情. 使用Ctrl-p,vim会反向搜索最近输入过的拥有相同开头的词, ctrl-x ctrl-l补全整个词
如果你不确定如何拼写某个词,并且你设置了拼写检查(:set spell),你可以使用 Ctrl-x Ctrl-k 到字典中查询已经输入的词.Vim自动补全系统在7.0后得到了很大的改善.
注意,自动补全命令仅在插入模式下有效,在命令模式有其他的作用
你可以在文档中设置标签,实现在文档中不同位置的快速跳转
vim自动设置的标签
{0-9} 关闭文件的最近10个位置(0 最后一个, 1 倒数第二个)
< and > 标记文本左边/右边的位置
( and ) 当前句子的开始/结束
{ and } 当前段落的开始/结束
[ and ] 拷贝或修改文本的第一/最后一个字符的位置
. 最后修改点位置
' or ` 上次跳转点位置
" 退出文件前的最后一个位置
^ 最后插入/修改位置
要设置自定义标签,使用 m{a-zA-Z} (例如 ma ), 如果要跳转到某个标签(自定义或预定义),可以使用 ' 和 `
' 将光标移到标记行首个非空字符位置
` 移到设置标签时得准确位置
大写和小写标记之间有些区别
{a-z} 文件维度
{A-Z} 会话维度,和文件关联,可以跨文件跳转
例如,可以使用 L 标记work-log 使用T标记time-table ,然后进行快速跳转
例如,你可以键入 '" 跳转到文件关闭前光标所在位置(Vim可以通过配置实现)
列出标签列表 :marks
删除 :delmarks a b c
删除所有 :delmarks!
Vim 7.0介绍过tabs. 我们都知道并喜欢tabs,所以这里不多提. (注意: vim中的tabs和其他程序中的tabs略有不同.不同点在于,每个tab页可以拥有自己的布局, 例如我可以在第一个tab中切分窗口,在第二个tab中不切分)
命令行中用vim一次性打开多个tab vim -p *.txt
切换tab, 可以使用鼠标(gVim) 或者输入 gt
创建一个新的空tab,输入 :tabnew
或者在一个新tab中打开文件 :tabe xyz
buffer和window有些不好理解,window是打开vim时你看到的,当你打开帮助(:help bufers), 你将会得到两个window.并非真正的窗口,是vim提供的展示视图
你可以打开一个window,切分成水平两个 :sp 或者竖直两个 :vsp. 通过这个方法,vim将同一个buffer放在两个不同的window. 你可以打开文件, :sp filea 或者 :vsp fileb. 在窗口之间跳转,命令模式下使用 Ctrl-w {hjkl}
buffer大多数情况下是一个文件,但是不要求可见. 所以通常一个window中有多个buffer, 要在当前window中展现不同的buffer , 使用 :b NUMBER, 可以使用 :buffers查看对应buffer的编号,通常情况下,vim要求你在切换到另一个buffer之前,保存当前buffer, 所以切换报错时不要太过惊讶(可以 :set hidden 使未保存buffer生效,但需谨慎使用)
下面是我的笔记:
:b N 切换到buffer N
:buffers 展示buffer列表, 字符含义
% 当前window
# 替换buffer (使用 :e# or :b#切换)
a 活动的(加载并可见)
h 隐藏的(加载但不可见)
+ 修改的
:bd 关闭buffer并从buffer列表移除(不关闭vim,即使最后一个buffer关闭)
:bun 关闭buffer但留存在bufferlist
:sp #N 分屏并编辑buffer N
:w 保存当前buffer
:e 重新加载当前文件
:q 退出
:new 新的空window
:on 关闭除当前活动window之外的所有window(Ctrl-W o)
Ctrl-W {h,j,k,l} 窗口之间切换
设置'hidden'后,允许修改未保存的buffer隐藏,buffer会自动保存如果未设置'hidden',设置了'autowrite'
Vim允许使用点. 重复某些命令,当存在多个命令时,使用宏
你可以开始 录制宏, 使用 q和{0-9a-zA-Z}, 例如 qq 录制用于buffer"q"的宏,完成录制后,键入q退出
现在你可以使用 @q 在任何时候调用宏
我希望可以帮助你开始学习vim. 我可以做的最后一件事是,提供我的vim配置文件. 使用 :help ... 去学习vim更强大的功能并在后续写一篇指南
可以将vimrc文件放入你的home目录(~/.vimrc),但是要先确定这个目录下还没有这个文件
注解1: Vim是一个编辑器,不是IDE 或者操作系统. 不要通过其试图创建一个IDE,如果你喜欢IDE,挑一个来用!当然,vim可以将很多任务自动化,例如编译,跳转到编译错误处,要实现这些,关注下vim的插件
Emacs is a good operating system, but it lacks a good editor. — Old saying.