目的
本文旨在介绍VIM的基本使用方法,以方便新学者学习和使用VIM。
什么是VIM
Vim是一个类似于Vi的著名的功能强大、高度可定制的文本编辑器,在Vi的基础上改进和增加了很多特性。VIM是自由软件。Vim普遍被推崇为类Vi编辑器中最好的一个,事实上真正的劲敌来自Emacs的不同变体。1999 年Emacs被选为Linuxworld文本编辑分类的优胜者,Vim屈居第二。但在2000年2月Vim赢得了Slashdot Beanie的最佳开放源代码文本编辑器大奖,又将Emacs推至二线, 总的来看, Vim和Emacs在文本编辑方面都是非常优秀的。
节选自 Vim 百度百科
官方网站:https://www.vim.org/ 文档网站:http://vimdoc.sourceforge.net/
Ubuntu 上安装VIM
Vim在Ubuntu上安装是非常友善的。默认的系统里也会自带一个Vim的版本,但一般不会是最新的版本,所以安装好Ubuntu后,应更新一下Vim的版本。执行命令如下:
sudo apt-get update
sudo apt-get install vim
VIM的两种基本模式
Vim是一个模式编辑器。这意味着编辑器处于不同的模式下行为不同。两种基本模式是普通模式 或插入模式 。在普通模式 下,您输入的字符是命令;而在插入模式 下,字符作为文本插入。
节选自:http://vimdoc.sourceforge.net/htmldoc/usr_02.html#02.2 The Vim editor is a modal editor. That means that the editor behaves differently, depending on which mode you are in. The two basic modes are called Normal mode and Insert mode. In Normal mode the characters you type are commands. In Insert mode the characters are inserted as text.
友情提示:Vim还有一些其它的模式,像可视模式(Visual mode)、替换模式(Replace mode)等请自行查阅相关文档即可。建议初学者先掌握好两种基本模式。
这两种模式示例图所下所示:
| | 普通模式 | 插入模式 |
一般地,在终端上打下Vim后,下方会有两行当前状态信息展示出来。普通模式 与插入模式 的区别在于最一个行一个不显示内容,一个显示为 -- INSTERT -- ;而上一行显示内容格式是 [文件名][文件类型][读写权限] [Line:当前光标行号/当前光标列号][光标位置占总文件字符位置百分比] 。 默认打开时Vim处于普通模式 (这种设计能有效防止打开文件阅读时不小心把内容给修改了而不自知的情况发生);按下 i 、I 、o 、O 、a 、A 、s 、S 中任一个键,都能切换到插入模式 。 当在插入模式 下按下ESC 键后,又可以回到普通模式 来。
小白提问:为啥进入插入模式 这么多种方法,而退回普通模式 却只有一种呢? 答:进入姿势的不同,决定了不同的体验。为了更方便程序员对代码进行上(O )、下(o )、左(I )、右(A )全方位插入代码,才设计了这么多方法的。这些都是非常常用的姿势,能有效提高开发的效率,可以从这些方法的含义上看到姿势的不同: i : 光标指向那里,就在那里插入 I : 光标在那一行,就插入这一行的头部(行首) o : 光标指向那一行,就在此行后新增一行插入 O : 光标指向那一行,就在此行前新增一行插入 a : 光标指向那里,就在些字符的下一个字符插入 A : 光标在那一行,就插入这一行的尾部(行末) 而退出时,只是回到最初状态,所有设计一个键就行了。其实在Vim中任何场景下都可以按ESC 来回退到普通模式 ,如果按一次不行,那就请按两次(两次代表强制退出到普通模式 )。就像对于吃货来讲,有什么烦恼是一顿火锅解决不了的呢?如果一顿不够,那就来两顿。
要提升开发效率,普通模式 的快捷键或命令行功能是必需要熟悉的。这里列举一些常用的,大家使用过程中多用就能慢慢提升开发效率了。
打开文件
以下命令是Shell中执行的命令。
vim filename
vim filename +97
普通模式下的快捷键
这里只列举经常用的快捷键,更新的请自行百度。
快捷键 | 功能描述 |
---|
jkhl | 上下左右 | gg | 光标移到到文档首行 | G | 光标移到到文档尾行 | gg | 光标移到到文档首行 | 数字+G | 光标移到文档指定数字行 | % | 如果光标处于括号位置,即跳到该括号对应的括号位置 | [[ | 上一个函数的定义的{ 处 | ]] | 下一个函数的定义的{ 处 | v | 进入字符选中模式,通过左移和右移来选中字符 | y | 复制已选中的文本到剪贴板 | yy | 复制光标所在的一行 | 数字+yy | 复制光标所在行往下开始的规定数字行 | dd | 删除光标所在的一行 | 数字+dd | 删除光标所在行往下开始的规定数字行 | dgg | 删除光标所在行到文件首的所有内容 | dG | 删除光标所在行到文件末的所有内容 | cw | 删除光标所在位置往后的单词,并切换到插入模式 | ctrl+w | 在插入模式下,删除光标所在位置往前的单词 | p | 将剪贴板中的内容粘贴到光标后 | P | 将剪贴板中的内容粘贴到光标前 | x | 删除光标所在位置的字符 | X | 删除光标前一个字符 | u | 向前撤销 | U | 向前撤销所有编程 | ctrl+r | 向后恢复 | gUw | 光标往后的单词变成大写 | guw | 光标往后的单词变成小写 | :wq | 退出并保存文件 | :wq! | 强制退出并保存文件 | :q! | 强制退出 | :q | 退出 | :w | 保存文件 | :w! | 强制保存文件 | ZZ | 直接退出Vim编译器 | ctrl+* | 向下开始搜索光标所在位置单词 | ctrl+# | 向上开始搜索光标所在位置单词 | /关键字 | 向下开始搜索关键字 | ?关键字 | 向上开始搜索关键字 | n | 跳转到下一个搜索到的字符上 |
替换功能
替换功能命令格式如下:
:s/字符串/替换字符串/选项
一般地,选项常用的就是g,代表全部替换,或者不写,只替换一个。字符串也可能被写成正则表达式。无论是查找或者是替换都是支持正则表达式的。 关于更多正则表达式内容,请自行百度学习。初学者建议先不关注。
VIM的插件
Vim是有丰富的插件提供给开发者使用的。这里只介绍插件的功能,至于插件的安装,请参考https://download.csdn.net/download/tangta789/86401186 的一键式脚本安装即可。
ctags
ctags是用于生成代码依赖关系的,以方便开发者查找或者跳转函数。 友情提示:在使用此功能前,应该在你的项目源代码目录执行以下命令:
ctags -R .
taglist
对源代码生成函数列表功能。
autocomplpop
写代码时的自动补全功能。
VIM的配置
将下面的内容复制到 ~/.vimrc 里就行了。
" 设置支持字体集
set fencs=utf-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936
set termencoding=utf-8
set encoding=utf-8
set fileencodings=ucs-bom,utf-8,cp936
set fileencoding=utf-8
" 设置显示行号
set nu
" 设置搜索结果高亮
set hls
set backspace=indent,eol,start
" 设置缩进和TAB键为4个空格
set sw=4
set ts=4
set expandtab
%retab!
syntax on
map <F5> <Esc>:e!<CR>
imap <F5> <Esc>:e!<CR>i
" 设置函数列表显示快捷键
map tl :Tlist<CR>
" 打开make编译日志
let g:copenflag=0
map co :if copenflag==0<CR>copen<CR>let g:copenflag=1<CR>else<CR>cclose<CR>let g:copenflag=0<CR>endif<CR><CR>
map make :make<CR>
map push :make && make push<CR>
map q %
"mouse=a,不能使用复制功能,用快搜键进行mouse模式切换. "
map `q :if &mouse=='a'<CR>set nonu<CR>set mouse=i<CR>else<CR>set nu<CR>set mouse=a<CR>endif<CR><CR>
" 自动缩进
set autoindent
set cindent
"禁止生成临时文件
set nobackup
set noswapfile
" 为特定文件类型载入相关缩进文件
filetype indent on
" 带有如下符号的单词不要被换行分割
set iskeyword+=_,$,@,%,#,-
" 可以在buffer的任何地方使用鼠标(类似office中在工作区双击鼠标定位)
set mouse=a
" 允许在有未保存的修改时切换缓冲区,此时的修改由 vim 负责保存
set hidden
let Tlist_File_Fold_Auto_Close = 0
let Tlist_GainFocus_On_ToggleOpen = 0
" 如果taglist窗口是最后一个窗口,则退出vim
let Tlist_Exit_OnlyWindow = 1
let Tlist_Auto_Update = 1
let Tlist_Close_On_Select = 0
let Tlist_Compact_Format = 0
let Tlist_Display_Prototype = 0
let Tlist_Display_Tag_Scope = 1
let Tlist_Enable_Fold_Column = 0
let Tlist_File_Fold_Auto_Close = 0
let Tlist_GainFocus_On_ToggleOpen = 1
let Tlist_Hightlight_Tag_On_BufEnter = 1
let Tlist_Inc_Winwidth = 0
let Tlist_Max_Submenu_Items = 1
let Tlist_Max_Tag_Length = 30
let Tlist_Process_File_Always = 0
let Tlist_Show_Menu = 0
let Tlist_Sort_Type = "order"
let Tlist_Use_Horiz_Window = 0
let Tlist_WinWidth = 31
"map <C-a> ggvG==<CR>``
"让vim记忆上次编辑的位置
autocmd BufReadPost *
\ if line("'\"")>0&&line("'\"")<=line("$") |
\ exe "normal g'\"" |
\ endif
let g:myvim=0
map <F3> <Esc>:if myvim==1<CR>e #2<CR>let g:myvim=0<CR>else<CR>:e #1<CR>let g:myvim=1<CR>endif<CR><CR>
imap <F3> <Esc>:if myvim==1<CR>e #2<CR>let g:myvim=0<CR>else<CR>:e #1<CR>let g:myvim=1<CR>endif<CR><CR>
"map <LeftMouse><LeftMouse> <2-LeftMouse>y<2-LeftMouse><CR>
"多文本编辑时,来回换文件
set completeopt=menu,menuone
" 关掉智能补全时的预览窗口
let OmniCpp_MayCompleteDot = 1
" autocomplete with .
let OmniCpp_MayCompleteArrow = 1
" autocomplete with ->
let OmniCpp_MayCompleteScope = 1
" autocomplete with ::
let OmniCpp_SelectFirstItem = 2
" select first item (but don't insert)
let OmniCpp_NamespaceSearch = 1
" search namespaces in this and included files
let OmniCpp_ShowPrototypeInAbbr = 1
" show function prototype in popup window
let OmniCpp_GlobalScopeSearch=1
" enable the global scope search
let OmniCpp_DisplayMode=1
" Class scope completion mode: always show all members
let OmniCpp_DefaultNamespaces=["std"]
let OmniCpp_ShowScopeInAbbr=1
" show scope in abbreviation and remove the last column
let OmniCpp_ShowAccess=1
set omnifunc=ccomplete#Complete
"call Tlist_Window_Openss()
"ctags
set tags=./tags,./.tags,./TAGS,tags;~,.tags;~,TAGS;
|