Vi/Vim

1. 概述

vi 编辑器有三种模式:

  • 正常模式:查看文本,可转换到输入模式或命令模式,在这两个模式下按 Esc 键可以回到正常模式。
  • 输入模式:正常模式下,使用 ia 等进入输入模式,可以修改文本内容。详解:
    • i:在当前光标处进入输入模式,
    • A:将光标移动至当前行行末并进入输入模式,
    • o:在当前行的下面插入新行,光标移动至新行并进入输入模式,
    • O:在当前行的上面插入新行,光标移动至新行并进入输入模式,
    • cecw :删除当前光标后单词的部分,并进入输入模式,
    • c$:删除当前光标到行尾的部分,并进入输入模式,
    • c^:删除当前光标到行首的部分,并进入输入模式,
  • 命令模式:正常模式下,使用 : 进入命令模式,可以执行保存退出等命令。
    输入模式的进入可能很多人只知道i,其实是有很多快捷键可以进入输入模式

常见用法:

  • Esc 键可以回到正常模式,或终止按了一半的命令。
  • 在正常模式下,输入 :q! 退出编辑器并放弃所有的改动。q 表示退出,!表示不保存。
  • 在正常模式下,输入 :qw 退出编辑器并保存所有的改动。q 表示退出,w表示保存。
  • 通过命令 vim 文件名 <回车> 进入 vim 编辑器,如果文件不存在则创建这个文件。
  • u 撤消最后执行的命令
  • U 撤消对整行的修改。

2. vimtutor 教程

Linux 发行版通常自带 Vim 教程命令 vimtutor,直接在终端输入这个命令即可进入教程。

2.1 基础

1. 移动光标

可以通过方向键移动光标,也可以通过下面四个字母键来移动:

  • h 或左箭头 :左移
  • j 或下箭头 :下移
  • k 或上箭头 :上移
  • l 或右箭头 :右移
             ^
             k              提示: h 的键位于左边,每次按下就会向左移动。
       < h       l >               l 的键位于右边,每次按下就会向右移动。
             j                     j 键看起来很象一支尖端方向朝下的箭头。
             v

快速跳转光标

0:光标跳转到行首。
^:光标跳转到行首,跳过所有空白字符。
$:光标跳转到行尾。
w:光标跳转到后一个单词首字母位置上,一定是下一个单词。
b:光标跳转到前一个单词首字母位置上,一定是下一个单词。
e:光标跳转到后一个单词尾字母位置上,可能是当前单词或下一个单词。
1Ggg:光标跳到文件首行。
G:光标跳到文件末行。
数字 G:光标跳到文件中指定的行数。

显示和取消行号

:set nu:显示行号。
:set nonu:取消行号显示。

2. 翻页

Ctrl + f 或 PgDn:向下翻页
Ctrl + b 或 PgUp:向上翻页
Ctrl + u:向上翻半页
Ctrl + d:向下翻半页

3. 文本删除 x

正常(Normal)模式下,x 键删除光标所在位置的字符,相当于 Delete 键。
注意,删除时如果遇到换行符,则改变删除方向,删除前面的字符。

4. 文本插入 i

正常(Normal)模式下,按 i 键(表示 Insert)进入插入(Insert)模式,插入文本到光标所在位置。
此时,hjkl 四个按键无法用于移动光标,只能用箭头。

5. 文本插入 a

正常(Normal)模式下,按 a 键(表示 append)进入插入(Insert)模式,插入文本到光标所在位置的后面。
此时,hjkl 四个按键无法用于移动光标,只能用箭头。

2.2 删除类命令

1. 删除单词 dw

输入 dw 可以从光标处删除至一个单词的末尾,包括空格。
对于中文,直接删除至句子后的第一个标点。

2. 从光标处删除至行末 d$

输入 d$ 可以从光标处删除至行末。

3. 关于命令和对象

许多改变文本的命令都由一个操作符和一个动作构成。

使用删除操作符 d 的删除命令的格式如下:

    d   motion

其中:
d - 删除操作符。
motion - 操作符的操作对象(在下面列出)。

动作列表:

  • w - 从当前光标当前位置直到下一个单词起始处,不包括它的第一个字符。
  • e - 从当前光标当前位置直到单词末尾,包括最后一个字符。
  • $ - 从当前光标当前位置直到当前行末。

    因此输入 de 会从当前光标位置删除到单词末尾。

4. 使用计数指定动作

输入 2w 使光标向前移动两个单词。
输入 3e 使光标向前移动到第三个单词的末尾。
输入 0 (数字零) 移动光标到行首。
输入 $ 移动光标到行尾。

5. 使用计数器删除更多

上面已经提到过删除操作符和动作的组合,可以在组合中动作之前插入一个数字以删除更多:

    d   number(数字)   motion

例如,对于“this is a test”,光标在行首时,

  • 输入 dw 会删除“this ”成为“is a test”;输入 d2w 会删除“this a ”成为“a test”
  • 输入 de 会删除“this”成为“ is a test”(注意不会删除空格);输入 d2e 会删除“this a”成为“ a test”

6. 整行操作

  • 删除整行 dd
  • 删除多行 ndd,例如 3dd 删除 3 行
  • 复制整行 yy
  • 复制多行 nyy

不管是删除还是复制,都会讲对应文本放入 Vim 自带的粘贴板,通过 p 可以在光标所在行的下一行粘贴,通过 P 可以在光标所在行的上一行粘贴。

7. 撤销 u U 以及重做 Ctrl + r

  • u 撤消最后执行的命令
  • U 撤消对整行的修改。

输入 u 可以撤消 U 以及更前的命令。
Ctrl + r 可以撤销之前的撤销操作,恢复更改过的内容。

2.3 文本粘贴,替换

1. 粘贴 p

删除数据后,会存入 vim 的寄存器中。输入 p 可以将最后一次删除的内容粘贴到光标之后。例如:

  1. 输入 dd 将该行删除,这会将该行保存到 Vim 的一个寄存器中。
  2. 接着将光标移动到其他行,即准备粘贴的位置的上方。光标的具体位置不重要。
  3. 然后在正常模式下(键进入)输入 p 将该行粘贴。

2. 替换单个字符 r

rx 会替换光标所在位置的字符为 x

3. 替换至单词末尾或行尾 c

    c [number] motion
  • cecw :删除当前光标后单词的部分,并进入输入模式,
  • c2ec2w :删除当前光标后 2 个单词的部分,并进入输入模式,
  • c$:删除当前光标到行尾的部分,并进入输入模式,
  • c^:删除当前光标到行首的部分,并进入输入模式。

2.4 定位,搜索

1. 定位 g

CTRL + g 查看文件总行数,光标所在行列。G 可以跳转到某一行。

  • G:跳转到文件最后一行。
  • gg:跳转到文件第一行。
  • 20G:跳转到文件第 20 行。

2. 搜索 /

输入 / 后,可以输入要查找的字符串,回车即可开始查找并将光标定位的匹配到的字符串的第一个字符。

  • /error:回车后,开始查找 error 字符串。
  • ?error:回车后,开始反方向查找 error 字符串。
  • n:再次执行查找操作。
  • N:反方向再次执行查找操作。
  • CTRL + o:光标回到前一个位置。比如我在第 20 行执行搜索并跳转到第一个匹配到的 40 行,按下 CTRL + o 后光标回到第 20 行。
  • CTRL + i:光标回到下一个位置。

3. 搜索匹配的括号 %

经常需要在文本中找对应的另一半括号,在正常模式下,将光标定位到左括号或右括号并输入 %,光标会自动跳转到另一半对应的括号。支持小括号、中括号、大括号:( [ {``) ] }

4. 替换字符串 s substitute

:s/old/new/g 命令可以将“old”字符串替换为“new”。

  • :s/old/new:将光标所在行的第一个“old”字符串替换为“new”。
  • :s/old/new/g:将光标所在行的所有的“old”字符串替换为“new”。
  • :#,#s/old/new/g:#,# 表示两个行号,在这两行之间的“old”字符串都会被替换为“new”。
  • :%s/old/new/g:将整个文件中的“old”字符串替换为“new”。
  • :%s/old/new/gc:找出整个文件中的“old”字符串,并提示是否替换为“new”。

2.5 执行命令、操作文件

1. 执行外部命令 :! command

  • :!ls 可以执行 ls 命令。
  • :!ls -al 可以执行 ls 命令,同时指定参数。

2. 保存文件 :w

  • :w TEST:如果 TEST 文件不存在,则新建文件 TEST,并将当前 vi 编辑器中的内容保存到 TEST。如果文件已经存在则保存失败。
  • :w! TEST:将当前 vi 编辑器中的内容保存到 TEST。如果 TEST 文件不存在则新建,已经存在则覆盖。

3. 选择部分文本并另存为新文件 v

按下 v 后,进入 Visual 模式,类似按下鼠标左键,可以前后移动光标自由选择文本。步骤如下:

  • 光标移动到起始位置后,按下 v 键,进入 Visual 模式
  • 移动光标选择一部分文本后,按下 : 字符,屏幕底部会自动出现 :'<,'> 提示字符
  • :'<,'> 提示字符后面输入 w TEST ,TEST 表示一个不存在的文件名
  • 回车,这部分文本会保存到新创建的 TEST 文件中。可以通过 :!ls -al 来验证。

文本选中后,可以执行多种操作:
- d:删除所选文本。

4. 检索和合并文件 :r FILENAME

:r FILENAME 会在光标位置插入新行,放入文件中的内容。步骤如下:

  • 光标移动到合适位置
  • 输入 :r FILENAME 插入文件内容,例如 :r TEST

也可以读取外部命令的输出,例如 :r !ls 会读取 ls 命令的输出并放入光标所在位置。

5. 总结

  • :! command 执行外部命令::!ls:!rm TEST
  • :w 文件存盘
  • v 动作可以选择部分文本。选中后可以通过 :w 文件存盘,或 d删除所选文本
  • :r FILENAME 读取磁盘文件并放入光标所在位置
  • :r !ls 读取 ls 命令的输出并放入光标所在位置

2.6 高级用法

ioOaA 都会进入 Insert 插入模式,只是位置不同。

1. open 命令

  • o 在光标所在行下面插入一行并进入插入模式
  • O 在光标所在行上面插入一行并进入插入模式

2. append 命令

  • a 在光标所在位置的下一个字符进入插入模式
  • A 在光标所在行的行尾进入插入模式

3. 另一种替换方式

  • r 替换光标所在位置的一个
  • R 从光标所在位置开始进入 Replace 替换模式,顺序替换字符,直到 Esc 退出替换模式

Replace 模式类似 Insert 模式,但是每次插入字符都会替换原位置的已有字符。

4. 复制粘贴文本

通过 v 进入 Visual 模式选中文本后,按 y 复制文本,移动光标到合适位置按 p 粘贴文本。例如对于下面文本:

--->  a) this is the first item.
      b)
  • 光标移动到第一行的 this 前的空格
  • 通过 v 进入 Visual 模式,选中文本到 first 前的空格
  • y 复制高亮选中的文本
  • 移动光标到第二行末尾
  • p 粘贴文本

5. 设置一个选项,以便搜索或替换可以忽略大小写

  • :set ic 忽略大小写 Ignore Case。通过 /xx\c 搜索字符串时也忽略大小写
  • :set noic 区分大小写
  • :set hls is 高亮所有匹配项 hlsearch,动态匹配输入 incsearch
  • :set nohls nois 停止高亮所有匹配项

通过 /xx 搜索字符串时,默认区分大小写,

  • incsearch 每输入一个字符就实时重新匹配一次并显示匹配的位置
  • hlsearch 高亮显示匹配项
  • ignorecase 忽略大小写

2.7 帮助、启动脚本、自动补全

1. 获取帮助

Vim 有一个在线帮助系统,启动后会以上下两部分分屏显示帮助文档和当前打开的文档。具体的用法在帮助系统开始部分有详细说明。常用操作有:

  • 进入帮助系统:启动 Vim 后按 F1 或输入 :help 即可进入
  • 退出:确定光标在帮助系统视窗之内,通过 :q:quit:exit 都可以退出
  • 切换视窗:连续两次 Ctrl + w
  • 查看指定主题的帮助:

2. 创建启动脚本

Vim 的许多特性默认关闭,要启用这些特性,需要编写 vimrc 脚本文件。可以通过 Vim 自带的示例创建这个脚本:

  • 编辑 ~/.vimrc 文件,可以通过 vim ~/.vimrc 直接进入,或 vim 进入 Vim 后通过 :e ~/.vimrc 进入
  • 读取示例文件 :r $VIMRUNTIME/vimrc_example.vim
  • 保存 :w

要在启动 Vim 时默认开启 incsearch 选项,只需要在 vimrc 脚本中添加一句:

    set incsearch

更多资料可以通过 :help vimrc-intro 命令查看。示例文件如下:

" An example for a vimrc file.
"
" Maintainer:   Bram Moolenaar <Bram@vim.org>
" Last change:  2011 Apr 15
"
" To use it, copy it to
"     for Unix and OS/2:  ~/.vimrc
"         for Amiga:  s:.vimrc
"  for MS-DOS and Win32:  $VIM\_vimrc
"       for OpenVMS:  sys$login:.vimrc

" When started as "evim", evim.vim will already have done these settings.
if v:progname =~? "evim"
  finish
endif

" Use Vim settings, rather than Vi settings (much better!).
" This must be first, because it changes other options as a side effect.
set nocompatible

" allow backspacing over everything in insert mode
set backspace=indent,eol,start

if has("vms")
  set nobackup      " do not keep a backup file, use versions instead
else
  set backup        " keep a backup file
endif
set history=50      " keep 50 lines of command line history
set ruler       " show the cursor position all the time
set showcmd     " display incomplete commands
set incsearch       " do incremental searching

" For Win32 GUI: remove 't' flag from 'guioptions': no tearoff menu entries
" let &guioptions = substitute(&guioptions, "t", "", "g")

" Don't use Ex mode, use Q for formatting
map Q gq

" CTRL-U in insert mode deletes a lot.  Use CTRL-G u to first break undo,
" so that you can undo CTRL-U after inserting a line break.
inoremap <C-U> <C-G>u<C-U>

" In many terminal emulators the mouse works just fine, thus enable it.
if has('mouse')
  set mouse=a
endif

" Switch syntax highlighting on, when the terminal has colors
" Also switch on highlighting the last used search pattern.
if &t_Co > 2 || has("gui_running")
  syntax on
  set hlsearch
endif

" Only do this part when compiled with support for autocommands.
if has("autocmd")

  " Enable file type detection.
  " Use the default filetype settings, so that mail gets 'tw' set to 72,
  " 'cindent' is on in C files, etc.
  " Also load indent files, to automatically do language-dependent indenting.
  filetype plugin indent on

  " Put these in an autocmd group, so that we can delete them easily.
  augroup vimrcEx
  au!

  " For all text files set 'textwidth' to 78 characters.
  autocmd FileType text setlocal textwidth=78

  " When editing a file, always jump to the last known cursor position.
  " Don't do it when the position is invalid or when inside an event handler
  " (happens when dropping a file on gvim).
  " Also don't do it when the mark is in the first line, that is the default
  " position when opening a file.
  autocmd BufReadPost *
    \ if line("'\"") > 1 && line("'\"") <= line("$") |
    \   exe "normal! g`\"" |
    \ endif

  augroup END

else

  set autoindent        " always set autoindenting on

endif " has("autocmd")

" Convenient command to see the difference between the current buffer and the
" file it was loaded from, thus the changes you made.
" Only define it when not defined already.
if !exists(":DiffOrig")
  command DiffOrig vert new | set bt=nofile | r ++edit # | 0d_ | diffthis
          \ | wincmd p | diffthis
endif

3. 自动补全

  • 确保 Vim 关闭 compatible 兼容模式 :set nocp
  • 查看目录中的文件 :!ls
  • 输入命令的开头部分 :e
  • 按下 Ctrl + D,Vim 会列出所有可用的 e 开头的命令
  • 按 TAB 键,Vim 会顺序切换匹配的命令
  • :edit 命令时,输入空格,再输入当前目录中要编辑文件的开头部分
  • 按 TAB 键,Vim 会自动补全文件名

很多命令都可以使用自动补全功能,通过 Ctrl + D 和 TAB 尝试即可。这对于 :help 命令尤其有用。

2.8 总结

Vim 可用的命令太多了,可以通过 :help user-manual 来查看。如果还想深入学习,就需要去读几本专门的书籍了。推荐 Steve Oualline 的 Vim - Vi Improved。

posted on 2018-05-05 12:17  kikajack  阅读(173)  评论(0编辑  收藏  举报