vim从入门到丝滑学习笔记

353 阅读7分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

入门

vim模式:(界面左下角有显示)

在这里插入图片描述

普通模式 (Normal-mode)  默认模式,进入方式:esc、C-[ 、C-c
插入模式 (Insert-mode) i、a、o、I、A、O
命令模式 (Command-mode) /、?、!
可视模式 (Visual-mode)  v 选择字符
可视模式 (Visual-Line-mode)  V 选择整行
可视模式 (Visual-Block-mode)  C-v 块选择模式,可以列选择
替换模式(Replace-mode) R
普通-插入模式(Normal-Insert-mode) C-o 切换到该模式。执行一次普通模式后,自动回到插入模式

api帮助文档

Vim帮助文档使用方法 :help xxx

如::help diw

"dl"    delete character (alias: "x")           dl
"diw"   delete inner word                       diw
"daw"   delete a word                           daw
"diW"   delete inner WORD (see WORD)            diW
"daW"   delete a WORD (see WORD)                daW
"dgn"   delete the next search pattern match    dgn
"dd"    delete one line                         dd
"dis"   delete inner sentence                   dis
"das"   delete a sentence                       das
"dib"   delete inner '(' ')' block              dib
"dab"   delete a '(' ')' block                  dab
"dip"   delete inner paragraph                  dip
"dap"   delete a paragraph                      dap
"diB"   delete inner '{' '}' block              diB
"daB"   delete a '{' '}' block                  daB    

再如: :help keycodes

notation	meaning		    	equivalent	decimal 	value(s)	~
-----------------------------------------------------------------------
<BS>		backspace			CTRL-H	  8				*backspace*
<Tab>		tab					CTRL-I	  9				*tab* *Tab*
<CR>		carriage return		CTRL-M	 13				*carriage-return*
<Return>	same as <CR>								*<Return>*
<Enter>		same as <CR>								*<Enter>*
<Esc>		escape				CTRL-[	 27				*escape* *<Esc>*
<Space>		space						 32				*space*

Ctrl+S造成vim假卡死

Ctrl + S 只是停止向终端输出而已 Ctrl + Q 恢复

基本指令

count operator count motion 3 dycv 5 iw

  • operator:干什么
  • count:干多少次
  • motion: 在哪干

The motion commands can be used after an operator command, to have the command operate on the text that was moved over. That is the text between the cursor position before and after the motion. Operators are generally used to delete or change text.

:h operator 查看操作符 :h motion 查看动作。一个移动光标的命令

hjkl 左下上右
wb 下、上个词

u 撤销操作undo
C-r (Ctrl + r) 重做redo

operator操作符

符号含义
delete删除
change修改(删除并进入插入模式
yank复制
visual选中并进入visual模式

motion动作

  • i/a 区别:inner / around

  • iw / aw : 选中单词 (普通模式),如diw/daw 删除单词

    ia例子例子
    "foo""foo"di" : ""
    (foo)(foo)di(di)dib()da(da)dab :
    {foo}{foo}di{di}dib{}da{da}daB :

    其他符号,如 ' <[ 等同理。

移动

水平移动(行内)

normal模式的操作

w/W 词头
b/B 上个词头,反向跳到词头
e/E 词尾
ge/gE 上个词尾
f字母 跳到字母
t字母:跳到字母前
F字母:向前跳到字母
T字母:向前跳到字母后的字母
; 重复操作上个命令
, 撤销上个操作回退
0 行首
^ 非空行首
g_ 非空行尾
$ 行尾
# 跳到当前光标所在单词上一个词
* 跳到当前光标所在单词下一个词

垂直移动(行间)

gg 跳到全文开头(相当于1G,首行)
G 跳到全文结尾行首非空(尾行)
	% 当前文件所有行(:%d<CR> 删除所有行)
	空 当前行
n+/n- 光标下、上移n行
C-d/C-f 向下翻半/1页
C-u/C-b 向上翻半/1:10/10G 跳到第10:%<CR> /:$<CR> 跳到文件最后一行行首
zz 将当前行设为屏幕居中
/正则字符串+回车 正向跳到匹配字符串,追加n,正向下一个;追加N,反向下一个
?正则字符串+回车 反向跳到匹配字符串,追加n,正向下一个;追加N,反向下一个
	:noh[lsearch] 移除搜索高亮
# 跳到当前光标所在单词上一个词
* 跳到当前光标所在单词下一个词

编辑

基础命令

dd 删除一行
yy 复制一行 yank即为copy
cc 删除一行并进入插入模式

di{或di}或diB 删除{}中所有内容
diw 删除当前词,无论光标位置在词的哪个位置
dw 删除一个单词
dt) 删除当前到)前字符
d$ 删除当前字符到行尾字符
D 删除当前字符到行尾字符
vf) 向右高亮直到),含)
vt) 向右高亮直到)前一字符
cw 删除词当前字母之后部分并进入插入模式
ciw 删除当前词并进入插入模式
ct字母  删除到字母前的字符,不删除字母,并进入插入模式
C 删除当前字符到行尾字符,并进入插入模式
x 删除单个字符
r字符 替换当前字符,相当于删除+插入+返回normal模式
R字符串 替换字符串,需要返回normal模式结束替换
s 删除单个字符并进入插入模式
S 删除整行,并进入插入模式
o 向下一行插入空行,回车换行<CR>,尽量使用<Esc>o替换
O 向上插入空行
p 光标后粘贴
P 光标前粘贴
:w 保存
:q 退出
:q! 强制退出
:wq/ZZ/:x 保存并退出

拓展命令

gd 跳到定义 goto definition
C-] 跳到定义
gf 打开光标处所指的文件
:delmark a 删除a标签
[` /]` 跳到上一个、下一个小写字符标签 (vscode不支持)
mM 创建全局标签MA-Z 大写字母为全局标签、唯一、可跨文件跳转,a-z 为局部标签、不唯一,仅当前文件内)
`M 跳到标签M (技巧:浏览代码前,先打个全局标签,好回来)
`. 跳到上次修改位置
'. 跳到上次修改位置所在非空行首(vscode中是跳到精确上次修改位置)
`^ 跳到最后一次插入插入位置 (vscode不支持)
gi 跳到最后一次插入模式位置 go to the last place you left insert mode
g; 上次修改位置,再执行则逃到上上词修改位置
g, 下次修改位置
C-o 跳到上次光标位置
C-i 跳到下次光标位置
[[ 跳到当前函数开头(cpp ok, java不可以)]] 跳到下一个函数开头(cpp ok, java不可以)
H/M/L 屏幕不动,光标动,跳到屏幕顶部、中间、底部
zz/zt/zb 光标不动,屏幕移动,使当前行处于屏幕中间、顶部、底部
( /) 跳到上/下一句
{ /} 跳到上/下一段
% 跳到匹配符号处,{}、()、[] 等,当前光标在一处,跳到匹配处
g~~ 切换行所有字符大小写
xp 交换两字符
:qa! 关闭所有文件且不保存 quit all
:%d<CR>或ggdGggVGd 删除所有行,清空全文
:%y<CR>或ggvG$yggVGy 拷贝全文
J 把下一行与当前行连接成一行

:marks 查看标签列表
:changes 查看修改列表
:jumps 查看跳转列表

<< shift line left 左移
>> shift line right 右移
== 格式化当前行

C-h 删除上一个字符
C-w 删除上一个词
C-u 删除上一行
	
@: repeat last ex command
@@ after repeating it once, you can continue repeating with this

大小写

~ 将光标下的字母切换大小写
3~ 将后面3个字母切换大小写
g~~ 将当前行的所有字母切换大小写
gUU/guu 将当前行切为大/小写
guiw/guaw 将当前词改为小写
gUiw/gUaw 将当前词改为大写

加a减x

C-a 将本行光标或之后的首数字+1
C-x 将本行光标或之后的首数字-1
180<C-x>   "0px" -> "-180px"

进阶篇

寄存器register

" 无名寄存器(unnamed register)。""p 等价于 p命令,粘贴无名寄存器内容
0 复制专用寄存器(yank register)。"0,只保存y{motion}复制的内容,即上次复制的内容。而无名寄存器还会保存c、x、s、d操作数据。
1-9 delete registers
a-z 有名寄存器。named registers
_ 黑洞寄存器。"_d{motion}会执行真正的删除操作
+ 系统寄存器
* 系统寄存器

"ay{motion} copy to register a 拷贝到寄存器a,小写会替换掉原寄存器内容
"Ay{motion} copy and append to register a 拷贝并追加到寄存器a,大写会追加内容
"ap paste from register a 粘贴寄存器a的内容
"add 删除当前行存到寄存器a
C-ra 插入模式时,从寄存器a粘贴内容
C-r0 从复制专用寄存器中粘贴内容
C-r% 插入当前文件名

宏macro

q{register} 开始录制 Start recording a new macro in {register}
q 停止录制 Stop recording macro
@{register} 应用宏 Replay macro in {register}
@@ 再次应用上次应用的宏 Replay the last macro that you executed
命令行模式执行宏a :'<,'>normal @a

编辑

. 重复上次操作(从插入模式到normal模),也称为 “.范式”,可认为是最简单的宏
	案例:一次复制,多次替换:1. yiw 2.viw"0p 3..(点范式) 4..
	案例:交换两个词:1. yiw 2.mm 3. viwp 4. `m 5. vwp
A 跳到行末并进入插入模式
	案例:对每行末尾都加上分号。1. A;<Esc>  2. j. 3. j. 4... (来自《Vim实用技巧》)
C 等价c$ 删除当前字符到行尾的所有字符并进入插入模式
s 等价cl 删除当前字符并进入插入模式
I 等价^i 跳到非空行首并进入插入模式
/正则表达式<CR> 正向查找匹配项,n查下一处,N查上一处。<CR> 即<Enter>回车键。
?正则<CR> 反向查
n/ N 正向/反向执行最后一次查找

:sort 或 :%sort 全文排序
:'<,'>sort 对选区行排序
:sort u 去除重复行排序
:sort i 忽略大小写对所有行排序
:.,.+3sort 对当前行到下3行共4行数据进行排序
:sort n 对全文每行按照数字排序
:sort! 倒序

C-h 插入模式时删除前一个字符
C-w 插入模式时删除前一个字
C-u 插入模式时删除到非空行首
命令行模式执行普通模式命令,如执行宏a:'<,'>normal @a  ,再如行尾插入分号 :'<,'>normal A"
命令行模式执行上一次命令行命令 :C-p
命令行模式执行下一次命令行命令 :C-n
C-o 普通-插入模式,1次普通模式操作后自动进入插入模式,插入模式时修改很有用 :h i_CTRL-O
C-r{register} 插入模式时粘贴指定寄存器数据,如C-r0。[:h i_CTRL-R] Insert the contents of a register.
C-r% 插入模式时插入当前文件名 

C-n或C-p 代码提示,再次按C-n或C-p选择提示

:t 复制行(如 :2,5t8 将25行复制到第8行下一行)
:.,.+5d 删除当前行到后5行(vscode支持)
:m 移动行 (如 :2,5m8,将25行剪切到第8行下一行,vscode不支持)
:copy(简写形式为 :co,等价缩写 :t)  拷贝(vscode不支持)
:2,5t. 将第25行拷贝到当前行下一行 (vscode不支持t点,可以为具体行号或标签)
:t6 将当前行拷贝到第6行下一行 (常用,vscode支持,:2,5t8 支持)
:t. 等价 yyp	(vscode不支持)
:t$ 把当前行复制到文件最后一行(vscode不支持)
:'<,'>t0 将高亮选中的开始到结束部分拷贝到文档开头
:move(简写 :m) 移动(剪切+粘贴)
:[range]move{address}
案例:对所有行尾加上分号:1. A ;<ESC> 2. jVG 3. :'<,'>normal .对高亮选区的每一行执行normal模式下的点命令
或上述3步改为1步完成:1. :%normal A ; 对全文按照普通模式,每行尾都增加分号// (vscode不支持)
或采用选择模式方案,选择所有行,然后A; 即 ggVGA;
或依然采用命令行模式方案,正则替换::1,$s/$/;/g 或 :%s/$/;/g 含义:范围1到最后一行每行都将行尾正则替换为分号 (vscode支持)
案例:对3到10行注释掉:1. :3,10 normal I// 3到10行执行普通模式I// (vscode不支持)
或 1. :3,10s/^/\/\//g (vscode支持)
:2,10s/hello/world/g  将2-10行内的hello全部都改为world(绝对行号)
:%s/hello/world/g 将全文的hello都改为world
:2,5s/aaa/bbb	将25行所有aaa都改为bbb
:.,.+5s/a/b	将当前行到下面第6行,共6行中所有a改为b
:5s/.*/-/g 将第5行所有字符都改为-
:%s/\<aa\>/AA/g 将单词aa改为AA,包含aa的单词不会替换
地址范围符号及含义:
	1 第一行
	$ 最后一行
	. 当前行
	% 所有行,即 :1,$
	'm 标签m所在行
	'< 选区开始
	'> 选区结束
flags替换标志位:
	g(global) 全局
	c(confirm) 替换前需确认
	n(number) 统计匹配次数而不进行替换
. 重复上次普通模式命令
@: 重复上次Ex命令
@@ 回放最近调用的宏

<C-r><C-w> 命令模式时,快速拷贝光标下文本到命令行

o 选择模式时,切换高亮选区端点
gv 重选上次的高亮选区
Vr- 将当前行字符改为横杠

buffer、window、tab

:e a.txt 打开a.txt
:ls 或 :buffers 或 :files 查看缓冲区,显示出缓冲区编号、状态(%当前缓冲区 a激活缓冲区 +已更改缓冲区 -不可改缓冲区 #交换缓冲区 )、名称(同文件名)、光标所在行号
:b n 跳到第n个缓冲区
:b buffer_name 加上tab补全跳转到指定缓冲区
:bp[revious] /:bn[ext] /:bf[irst] /:bl[ast] 跳转到上一个/下一个/第一个/最后一个缓冲区,也可按tab补全,如:bp<TAB> 会自动补全为:bprevious,简写也可以
:ball 打开所有缓冲区
:wall! 强制保存所有缓冲区
:qall! 强制退出所有缓冲区
:badd xx 添加缓冲区xx

<C-w>s 或 :sp[lit] 水平分割窗口
<C-w>v 或 :vs[plit](vertical split) 垂直分割窗口

<C-w>w 循环切换窗口
<C-w>h/j/k/l 切换到←/↓/↑/→窗口 
<C-w>H/J/K/L 移动当前窗口向←/↓/↑/→
 
<C-w>+ 增加窗口高度
<C-w>- 减少窗口高度
<C-w>= 所有窗口等宽等高
<C-w>_ 最大化当前窗口高度
<C-w>| 最大化当前窗口宽度
[N]<C-w>_ 当前窗口高度设置为[N]行
[N]<C-w>| 当前窗口宽度设置为[N]列
:h window-resize 查看文档

:tabs 查看所有打开的tab,有 > 箭头的是当前tab,有 + 说明有修改未保存,并显示tab页编号供tabp/tabn使用
:tabnew 新建标签页
:tabe a.txt 在新标签页打开a.txt
:tabc 关闭当前的tab
:tabo 关闭所有其他的tab
:tabp[revious] 或 gT 上一个tab
:tabn[ext] 或 gt 下一个tab
:tabn[ext] [num] 或 [num]gt 切换到编号为[num]的标签页
<C-w>T 将当前窗口移动到新标签页

vim 目录结构

参考:blog.csdn.net/u014805066/…

.vimrc配置文件

linux: ~/.vimrc windows: C:\Users\cuncaojin\.vimrc

:h option-list 查看所有设置选项 a-good-vimrc .vimrc实用配置 github.com/wklken/k-vi… vim 配置 比较全

" 修改leader键
let mapleader = ' '

" 文档可编辑
set modifiable

" 与windows共享剪贴板
set clipboard+=unnamed

" 命令行行数
set cmdheight=1

" 编码
set encoding=utf-8
set fileencodings=ucs-bom,utf-8,gbk,gb2312,utf-16,big5
set fenc=utf-8
set fencs=utf-8,gbk,gb2312

" history文件中需要记录的行数
set history=2000

" 不设置则在插入模式时无法用退格键和 Delete 键删除回车符
set backspace=indent,eol,start

" 行号
set number
set nowrap
" set relativenumber

" 取消文件备份
set nobackup
set nowritebackup
set noswapfile

" 设置缩进
set cindent
set smartindent
set autoindent
set smarttab
set expandtab
set tabstop=4
set shiftwidth=4
set softtabstop=4
filetype indent on

" 00x增减数字时使用十进制
set nrformats=

" 按TAB键时命令行自动补全
set wildmenu
" 文件在Vim之外修改过,自动重新读入
set autoread
" 设置自动保存内容
set autowrite
" 状态栏显示命令
set showcmd
" 移动到buffer的顶部和底部时保留行距
set scrolloff=3
" 懒渲染
set lazyredraw
" 当前行高亮
set cursorline
" 高亮括号匹配
set showmatch

" 搜索
set incsearch
set hlsearch
set ignorecase
set smartcase
noremap <ESC> <ESC>:nohlsearch<CR>

" 语法高亮
syntax enable
" 自动补全
set completeopt=longest,menu
" 侦测文件类型
filetype on
" 载入文件类型插件
filetype plugin on

" 将默认实际行移动映射改为屏幕行移动,k原本为实际行,gk为屏幕行,实际一行文本过长可能有多屏幕行
nnoremap k gk
nnoremap gk k
nnoremap j gj
nnoremap gj j

" 命令行模式时快速移动光标位置
cnoremap <C-a> <Home>
cnoremap <C-e> <End>

" 交换 ' `
nnoremap ' `
nnoremap ` '

" normal/ visual/ insert no Recursive map 非递归映射
inoremap jj <ESC>'^

" 为了可以多次粘贴
nnoremap <Leader>p "0p
nnoremap <Leader>P "0P
vnoremap <Leader>p "0p
vnoremap <Leader>P "0P

" 切换buffer(:ls :bf[irst] :bl[ast] :bp[revious] :bn[ext])
nnoremap <slient> [b :bprevious<CR>
nnoremap <slient> [n :bnext<CR>

" 切换window (<C-W>w)
nnoremap <C-j> <C-W>j
nnoremap <C-k> <C-W>k
nnoremap <C-h> <C-W>h
nnoremap <C-l> <C-W>l

" 切换Tab
nnoremap <C-TAB> :tabnext<CR>
nnoremap <C-S-TAB> :tabprev<CR>

" 允许在有未保存的修改时切换缓冲区,此时的修改由 vim 负责保存,如果不设置可能文本编辑失败
set hidden

" 更新时间毫秒数
set updatetime=300

" /////////////////// call plug#begin('~/.vim/plugged') /////////////////////
" 使用方法:
" 1. :source ~/.vimrc
" 2. :PlugInstall
call plug#begin('~/.vim/plugged')

Plug 'mhinz/vim-startify'
Plug 'tpope/vim-surround'
Plug 'easymotion/vim-easymotion'
Plug 'preservim/nerdtree'

call plug#end()
" /////////////////// call plug#end() /////////////////////

" ========== nerdtree ==========
nnoremap <leader>n :NERDTreeFocus<CR>
nnoremap <C-n> :NERDTree<CR>
nnoremap <C-t> :NERDTreeToggle<CR>
" 在文件树中定位到当前文件,配合 C-wp 再从文件树切回之前文件窗口
nnoremap <C-f> :NERDTreeFind<CR>
" 显示隐藏文件
" let NERDTreeShowHidden=1
let NERDTreeIgnore = [
        \'\.git$','\.svn$','\.svn%', '\.swp%'
        \ ]

" ========== easymotion ==========
" 搜索时忽略大小写
let g:EasyMotion_smartcase = 1

vim插件管理器

vim插件管理器中佼佼者:vim-plug

vim插件

vim 插件网站

  • 小奶牛 vim-startify

  • spacevim

      配置插件
    
  • easymotion

      <leader><leader>s{char} search character everywhere
      <leader><leader>w start of words
      <leader><leader>b start of words backwards
      <leader><leader>bdw start of words everywhere. The bd stands for bidirectional
      <leader><leader>e end of words
      <leader><leader>ge end of words backwards
      <leader><leader>bdw end of words everywhere
      <leader><leader>j beginning of lines
      <leader><leader>k beginning of lines backwards
      <leader><leader>f{char} find character
      <leader><leader>F{char} find character backwards
      <leader><leader>t{char} until character
      <leader><leader>T{char} until character backwards
    
  • vim-sneak

    官方图:在这里插入图片描述

  • vim-surround

      Press cs"' inside
    
      "Hello world!"
      to change it to
    
      'Hello world!'
      Now press cs'<q> to change it to
    
      <q>Hello world!</q>
      To go full circle, press cst" to get
    
      "Hello world!"
      To remove the delimiters entirely, press ds".
    
      Hello world!
      Now with the cursor on "Hello", press ysiw] (iw is a text object).
    
      [Hello] world!
      Let's make that braces and add some space (use } instead of { for no space): cs]{
    
      { Hello } world!
      Now wrap the entire line in parentheses with yssb or yss).
    
      ({ Hello } world!)
      Revert to the original text: ds{ds)
    
      Hello world!
      Emphasize hello: ysiw<em>
    
      <em>Hello</em> world!
    

vim实战练习

游戏

工具

  • windows版vim

  • Unix/Linux (推荐,vscode、idea可作为过渡期使用)

  • vscode

    安装插件 Vim、Learn Vim(推荐) vim插件 Learn Vim插件

  • IDEA系列 在这里插入图片描述

neovim

SpaceVim

开箱即用的模块化 Vim IDE

linux 命令

C-a 跳到行首
C-e 跳到行尾
C-h 向前删除一个字符
C-w 向前删除一个词
C-u 清空命令行
C-r 进入历史命令查找窗口,输入要查找的命令可快速选择历史命令
C-L 清屏
cd - 将当前目录切换到上一次所在目录
Shift-Insert 粘贴

ubuntu

vim辅记图

参考

  1. SpaceVim
  2. vim 教程网
  3. Vim 中文社区
  4. 《Vim实用技巧(第2版)》
  5. Vim 有什么奇技淫巧
  6. 笨方法学Vimscript中文译文w3cschool
  7. 优雅玩转Vim
  8. 玩转Vim 从放弃到爱不释手
  9. 史上最全Vim快捷键键位图(入门到进阶)
  10. 史上最全Vim快捷键键位图 -- 入门到进阶
  11. 键位图--原版
  12. jrmiii.com/
  13. Ubuntu更换软件源
  14. a-good-vimrc
  15. 寓教于乐!一款游戏让你成为 Vim 高手!
  16. fatal error: curses.h: No such file or directory的解决办法
  17. VIM训练游戏
  18. Vim Cheat Sheet
  19. 如何让 vim 成为我们的神器——推荐
  20. 最佳 vim 配色方案

致谢

  1. Jaime González García