Linux-Vim/Vi命令使用技巧

在linux的世界观有这么一句话“万物皆文件”,意思是在Linux系统中所见到任何东西都是文件,都可以理解为文件,同样即可理解为你在Linux系统中看到的任务带有名称的东西,不管其是什么格式的,你都可以像对待纯文本文件一下打开它,当然打开后看到的内容肯定是会不同格式而不同的。打开文件当然需要能打开文件的命令来操作,Vim或者vi就是打开文件的命令。

Vim是从vi发展出来的一个文本编辑器。其代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。和Emacs并列成为类Unix系统用户最喜欢的编辑器。Vim的第一个版本由布莱姆·米勒在1991年发布。最初的简称是VIMitation,随着功能的不断增加,正式名称改成了VIMproved。现在是在开放源代码方式下发行的自由软件

wiki上对Vim的基本介绍

1、主要基本模式

  • 命令(Normal)模式:默认模式,移动光标,剪切/粘贴文本—-查看文件内容
  • 插入(Insert)或编辑模式: 修改文本
  • 扩展命令(extended command )模式: 保存,退出等

2、在 Vim 中设置 Tab

为什么要设置vim的tab缩进,这个主要还是一些语言自身的格式要求(如python),还有就是为了视觉美观。缩进用 tab 制表符还是空格,这不是个问题,就像 python 用四个空格来缩进一样,这是要看个人喜好的。在 Vim 中可以很方便的根据不同的文件类型来设置使用 tab 制表符或者空格,还可以设置长度,非常灵活。

登录linux系统后,在光标闪动的地方输入: cd , 然后回车; 然后输入命令 vim ~/.vimrc

首先来看如何设定 tab 的宽度以及如何确定用 tab 制表符还是空格来表示一个缩进:

set tabstop=4
set softtabstop=4
set shiftwidth=4
set noexpandtab / expandtab

说明: 
其中 tabstop 表示一个 tab 显示出来是多少个空格的长度,默认 8。softtabstop 表示在编辑模式的时候按退格键的时候退回缩进的长度,当使用 expandtab 时特别有用。shiftwidth 表示每一级缩进的长度,一般设置成跟 softtabstop 一样。当设置成 expandtab 时,缩进用空格来表示,noexpandtab 则是用制表符表示一个缩进。

当然,除了基本的配置还有很多比较进阶配置,比如自动代码补全,换行缩进等

vim 小进阶配置
set nu
set tabstop=4
set ruler
set autoindent
set cindent
set smartindent
set laststatus=2
set softtabstop=4
set shiftwidth=4
syntax enable

set tags+=~/.vim/tags/cpp_src/tags ” 设置tags搜索路径

map <C-n> :NERDTree<CR>
map <C-t> :TlistToggle<CR>

” pathongen
execute pathogen#infect()
syntax on
filetype plugin indent on

” taglist
let Tlist_Show_One_File=1
let Tlist_Exit_OnlyWindow=1
let Tlist_Use_Right_Window=1
let Tlist_Sort_Type=”name”
set completeopt=longest,menu

“youcompleteme
“回车即选择当前项
inoremap <expr> <CR> pumvisible() ? “\<C-y>” : “\<CR>”
” 跳转到定义处
let mapleader =”\<space>”
nnoremap <leader>jj :YcmCompleter GoToDefinitionElseDeclaration<CR>

let g:miniBufExplMapWindowNavVim = 1
let g:ycm_global_ycm_extra_conf=’~/.vim/bundle/youcompleteme/.ycm_extra_conf.py’
let g:ycm_error_symbol = ‘>>’
let g:ycm_warning_symbol = ‘>*’
“” 不显示开启vim时检查ycm_extra_conf文件的信息
let g:ycm_confirm_extra_conf=0
“开启基于tag的补全,可以在这之后添加需要的标签路径
let g:ycm_collect_identifiers_from_tags_files= 1
“”注释和字符串中的文字也会被收入补全
let g:ycm_collect_identifiers_from_comments_and_strings = 0
” 输入第 2 个字符开始补全
let g:ycm_min_num_of_chars_for_completion= 2
” 禁止缓存匹配项,每次都重新生成匹配项
let g:ycm_cache_omnifunc=1
“” 开启语义补全
let g:ycm_seed_identifiers_with_syntax= 1
“在注释输入中也能补全
let g:ycm_complete_in_comments = 1
“”在字符串输入中也能补全
let g:ycm_complete_in_strings = 1
” 设置在下面几种格式的文件上屏蔽ycm
let g:ycm_filetype_blacklist = {‘tagbar’ : 1,’nerdtree’ : 1,}
“youcompleteme 默认tab s-tab 和 ultisnips 冲突
let g:ycm_key_list_select_completion = [ ‘<Down>’ ]
let g:ycm_key_list_previous_completion = [ ‘<Up>’ ]
“修改对C函数的补全快捷键,默认是CTRL + space,修改为ALT + ;
let g:ycm_key_invoke_completion = ‘<C-Space>’
vim 代码补全,换行缩进配置

3、常用快捷键

1、最基本命令
空格键 向右移动一格
x 删除后面的字符 X 删除前一个字符  删除3个字符就是3x  
dd:删除一行   D 删除到行尾 
caw:改写单词  c 相当于 d 变为编辑模式
J:删除换行符,使下一行并上来。     nJ:连接后面的n行
u:撤销上一次操作      U:撤销当前行的所有修改
ctrl+r:对撤消的撤消
i 在光标前插入
I 在行首插入 
a 在光标后插入
A 在行末插入
o:在当前行的下面另起一行,并变为插入模式
O:在当前行上面另起一行,变为插入模式
Ctrl+o:临时变成命令模式(一次而已)
:e!:放弃更改,然后相当于重新打开
:help:帮助,可用ZZ退出帮助窗口
基本命令
2、复制命令
vim中Nyy可以复制光标后的N行。有时我们不容易得出行数,这时可以用做标记的方法来制定复制范围: 
  1. 在开始行上输入ma作一个标记a 
  2. 移动到结束行,输入y’a会复制当前行到标记a之间的文本。d’a会删除。 
或者是v进入可视模式,再13G跳转到相应行,y即可。
:10,20y    回车即可,相应的删除也是如此     :10,20d     (此方法比上面两种方法更简单)
:10,20 m 30    把10行到20行的内容,剪切到30行之后
:10,20 co 30   把10行到20行的内容,复制到30行之后
将光标放在 { 处,然后输入v%就可以把大括号中内容选定
如果光标放在第一个s上,想删除到“(”为止,则输入dt(就可以了,t(的作用是跳到下一个”(“前。
ctrl +n 自动补全 ctrl + p 也一样
:ab hw hello world  用一个缩写字符串代替一个长的字符串,此处用 hw 代替 hello world
%: 移动到与制匹配的括号上去(),{},[],<>等
‘ 移动到上一次的修改行
fx 向右跳到本行字符x处(x可以是任何字符)
Fx 向左跳到本行字符x处(x可以是任何字符)
tx 和fx相同,区别是跳到字符x前
Tx 和Fx相同,区别是跳到字符x后
# 到与当前单词相同的上一个单词上, * 到与当前单词相同的下一个单词上
如果你要重复键入一个短语或一个句子, 也有一种快捷的方法。Vim有一种记录宏的机制。你键入”qa”开始把一段宏记录入寄存器变量`a’中。
按下来你可以象平常一样键入你要的操作, 只是这些操作都会被Vim记录进它命名为`a’的宏中, 再次再下”q”键, 就结束了宏`a’的录制。当你要重复执行你刚才记录的那些操作时只要使用”@a”命令。共有26个可用的寄存器供你记录宏。 使用宏你可以重复多个不同的操作。而不仅仅是插入文本了。如果你要进行某种重复的操作, 记着要用这一招呀。
:abbr hte the
:abbr hw Hello World
输入先面的单词时,自动用后面的替换。
复制命令
3、移动命令
b、3b、w、3w:向前\后移动几个单词,标点也算一个单词。相应的大写状态为不含标点,即只把空格和换行符作为单词间隔符。
$:移动到行尾  3$:移动到3行后的行尾
^:移动到行首,0也是
+:移到下一行的行首
-: 移到上一行的行首
f:搜索命令,小写时向后搜索(用来定位)如 fx:定位到下一个x上。   Fx:定位到上一个x上,重复时,可用;或,  不过 , 表示反方向
%:跳到相对应的括号上,编程时常用
33G:跳转到33行   此时按“可以返回到原来行
gg:文件头   G: 文件尾
30%:跳转到文件的30%处
“H”意为Home, “M”为Middle, “L”为Last.  当前屏幕的上中下位置,大小写皆可
Ctrl+G:显示当前位置
set number:设置显示行号,set nonumber:关闭显示
:set ruler 设置在窗口右下角显示行号,与上面的好处是,节省空间
ctrl+u\d  向上\下滚动半屏
ctrl+e\y  向上\下滚动一行
ctrl+b\f  向上\下滚动一屏  这个比较实用,记住。
zz:将当前行滚动于屏幕中间,方便查看上下文  zt置顶,zb置尾
/string  查找string,回车后,按n键可以跳到下一个,N上一个,另外按/键后,按上下键可以找到以前查找的记录,同样的 :也有记录
?/string 同上,默认向上查找
:set ignorecase 大小写无关
:set noignorecase 大小写敏感
* :查找下一个光标所在单词  #是查找上一个
:set hlsearch  高亮显示查找结果
:set nohlsearch  取消高亮
:nohlsearch  去掉当前显示的高完(一次性)
 “ 上次光标停靠的行
% 匹配到相应括号处
>>   向右移动本行一段距离     <<   向左移动本行一段距离    3<<    把下面3行(包括本行),向左移动一段距离     :20,30>>  把20行到30行向右移动一段距离
移动命令
4、小幅改动命令
:%s/str1/str2/g   替换每一行的 str1为 str2
:10,20s/str1/str2/g   替换从行10到行20之间的 str1为 str2
:10,$s/str1/str2/g   替换从行10到最后一行之间的 str1为 str2
:s/str1/str2/g   替换当前行的 str1为 str2
.  重复执行命令 
:10,$ w test2.cpp     取行10到最后一行内容,保存到test2.cpp
:r class/User.hpp    读取文件中的内容,插入到当前行的后面
dw:删除一个单词(光标后部分)  不如:daw实用    d4w:删除4个单词    d$:删除当前光标到行尾    d^:删除当前光标至行首       d换成c效果是一样的,只是操作完会变成insert模式   dnw: 删除N个单词   dnj: 向下删除n行      dnk: 向上删除n行 
X:删除左边的字符,相当于<-键,x删除当前字符  D:相当于d$  C:相当于c$  s:相当于c1  S:相当于cc
r:替换当前字符,但不会进入insert模式    3r:把后面3个字符替换掉    R:替换模式
.:重复上一次操作
v:进入Visual模式    V:进入可视行模式,比如 Vjjd 删除3行  Ctrl+v:可视块模式
P:粘贴至光标前    p:粘贴至光标后    3P:粘贴3次      “2p     粘贴最后第二次的删除的内容
yy:复制一行  yaw: 复制一个单词,光标在单词任意位置    ynw: 复制N个单词       ynj: 向下复制n行          ynk: 向上复制n行  
自动缩进:
:set cindent(所有的set都可以简写为se,虽然只节省了一个字符, 译者注) 需要注意的是cindent控制缩进量是通过shiftwidth选项的值, 而不是通过tabstop 的值, shiftwidth的默认值是8(也就是说, 一个缩进为8个空格, 译者注), 要改变默认的设置, 可以使用”:set shiftwidth=x”命令, 其中x是你希望一个缩进量代表的空格的数目.
 { = 到前一个空行上
} = 到下一个空行上
小幅改动命令
5、滚屏和移动
^f:向前(下)一整屏
^b:向后(上)一整屏
^d:向前(下)一半屏
^u:向后(上)一半屏
z,Enter:将光标所在行移动到屏幕顶部(同于zz)
z.:将光标所在行移动到屏幕中间
z-:将光标所在行移动到屏幕尾部
nz,Enter:将第n行移动到屏幕顶部,同样的,z. 与 z- 前也可以加数字。
 
在屏幕中移动:
H、M、L分别移动到屏幕的顶部、中间和尾部。
nH、nL 移动到距离屏幕顶部和顶部n行的位置。
滚屏和移动