Vim:核心思想和基本操做

The Missing Semester —— 学校不教的 CS 基础

最近在看一个 MIT 发布的系列课程视频:The Missing Semeter Of Your Computer Science Education,课程涵盖了不少咱们在日常开发中遇到过的、可是课程体系中不多涉及到的话题,并介绍了相关的基础知识和最佳实践。这一系列视频中,其中一节是关于 Vim 的,介绍了 Vim 背后的思想和一些基本操做。python

虽然以前在捣鼓云服务器的时候用过 VIm 编辑过一些文件,可是那时候对命令行环境还比较陌生,有一些基本的操做还不够熟练,也就不肯意去深刻学习 Vim,致使一直没有入门。平时也主要用 VS Code 这样的现代编辑器,因此也没有太强的动力去学习 Vim。shell

最近在一些项目中,开始愈来愈多地和终端、shell 脚本打交道,愈发感受须要学习一些进阶的操做,来提升生产力。这一系列课程视频刚好为我打开了新世界的大门。另外,在写代码的时候,确实发如今键盘和鼠标之间来回切换至关费时间。编程

正好如今借着这一系列视频,开始从新学习 Vim 的操做。如今断断续续已经用了两个礼拜、四五个小时了,基本的操做逐渐熟悉,编辑速度直线上升。甚至发现即便是在现代编辑器中,不少操做使用 Vim 也会更快一些。因而连 VS Code、Chrome 浏览器什么的全都配置了 Vim,尽可能避免使用鼠标或者触控板。vim

在进入正题以前,向你们推荐一下这一系列的课程。若是你想系统地了解一下命令行界面、Vim 等各类工具,想要提高本身的生产力,或者简单地想学一些“高端”操做,均可以去看一下这一系列视频,相信你不会后悔的。浏览器

接下来,我会简单介绍一下 Vim 及其背后的思想,并经过一些简单的使用场景,介绍 Vim 入门级别的一些命令。服务器

Vim 的基本思想

Vim 认为,开发者大部分时间花在阅读代码、对代码进行小幅编辑上,而非花在编写大量代码上。因而,Vim 就有了各类模式:在 普通(NORMAL) 模式下阅读代码、跳转位置、快速编辑,在 编辑(INSERT) 模式下编写代码,在 可视(VISUAL) 模式下选择代码,等等。app

Vim 是可编程的,能够经过 Vimscript 或者 Python 编写控制 Vim 的程序。甚至连 Vim 的界面自己也是一种“编程语言”——每个按键对应一个命令,而且多个命令能够组合在一块儿。编程语言

Vim 帮助你脱离对鼠标的依赖。在键盘和鼠标中频繁切换太慢了。甚至,在键盘和方向键之间切换也很慢,因此它连方向键也不须要。编辑器

基于这些思想,Vim 可以跟上咱们思考的速度,使用熟练之后,会大大提升咱们的效率。ide

Vim 的基本操做

模式切换

  • 当使用 Vim 命令打开一个文件时,会默认进入普通模式。
  • 使用 i (insert) 进入编辑模式,在当前光标以前插入文本。(还有另外的命令能够进入编辑模式,在以后会详细列出)
  • 使用 v (visual) 进入可视模式
  • 在非普通模式下,使用 ESC 回到普通模式
    • 在使用 Vim 时,会频繁使用到 ESC。所以,建议将大写锁定键绑定为 ESC,来减小手的移动幅度。

普通模式

正如在基本思想中所说,开发者很大一部分时间是在阅读代码。并且阅读并不是老是线性的,须要在同一文件的不一样部分来回跳转切换,或者须要查看多个文件。所以,在阅读模式下快速移动光标到本身想要查看的位置尤其重要。

Vim 不须要方向键,而是由 hjkl 代替,分别对应左、下、上、右四个方向键。虽然其实用方向键也能够移动,可是为了可以尽可能避免手的位移,仍是习惯一下 hjkl 为好。在 Vim 的配置文件中,也能够设置禁用方向键,这个以后会给出相应的配置。

可是这仅仅只是实现了方向键。咱们仍是只能一点点的上下左右移动。因而,又有了不少别的操做,让咱们更快地移动

行间移动:

  • w 向后移动一个词。
  • b 向前移动一个词
  • e 向后移动到当前词的末尾字符
  • {number}w/b/e 移动规定词数,好比 3w 会向后移动三个词
  • $ / ^ 光标移动至行尾/行首

跨行移动:

  • {number}j/k 向下/向上移动相应行数,好比 5k 向上移动 5 行
    • 这样移动时,行号很重要。Vim 不只支持显示当前行数,还能够在配置文件中设置显示相对行号,这样很方便就能看出须要向上或者向下移动几行。详细配置会在后面一并给出。
  • {number}G 移动到该行
  • H 移动到窗口顶端,M 移动至窗口中间,L 移动到窗口底部
  • Ctrl-u 向上滚动半个窗口,Ctrl-d 向下滚动半个窗口
  • gg 移至文件顶端,G 文件移至底端

搜索:

  • f{character} F{character},在当前行,向后/向前查找某一字符,光标移动到该字符
    • 使用 ,; 跳至下一处或者上一处
  • t{character}, T{character},在当前行,向后/向前查找某一字符,光标移动到该字符以前
    • 一样,使用 ,; 跳至下一处或者上一处
  • /{regex} 搜索文件,n / N 跳转到下一处/上一处

编辑模式

在普通模式下,除了上面提到的用 i 进入编辑模式,还有其余的命令:

  • I (shift + i) 在当前行的第一个非空字符以前进入编辑模式
  • a (append) 在光标以后进入编辑模式
  • A 在行尾进入编辑模式
  • o 在当前行下新插入一行,光标移动至行首,进入编辑模式
  • O 在当前行上面新插入一行,光标移动至行首,进入编辑模式

这几个操做对应了几个不一样的场景。在实际的开发过程当中很常见。好比行尾少了冒号或者分号,好比须要新开一行,不须要先移动光标到行尾,而能够直接使用对应的指令在相应位置开始编写代码。

还有一些常见的命令,能够对应其余的编辑场景:

  • d{motion} 删除,好比 dw 是删除当前词,d$ 删除光标至行尾的全部字符,d^ 删除光标至行首的全部字符
  • c{motion} 修改,cw 是修改当前词,效果是删除当前词,并进入编辑模式,等同于 dw + i
  • x 删除当前字符,至关于 dl
  • s 替换当前字符,至关于 xi

进入可视模式后,能够选中文本,再进行操做:

  • 可视模式下经过前面介绍过的移动命令能够选中特定文本
  • 选中后,d 删除,c 修改
  • y 复制(英文是 yank),d 也会复制,p 粘贴

Vim 中也有对应的撤销、重作:

  • 在普通模式下,u 撤销 ctrl + r 重作

计数与修饰

在前面咱们见过了 {number}k 这样的操做,能够经过计数来执行特定次数相同的操做。更多的例子有:3w 向后移动 3 个词,7dw 删除 7 个词

经过修饰,能够修更名词的意思,实现不一样的编辑效果。好比,ci( 能够修改当前括号内的内容,它会删除当前括号内的内容,并进入编辑模式。da' 则会删除引号以及引号内部的内容。这里 i 的意思是 inside,a 则是 around

Vim 命令行

在普通模式下,使用 : 进入命令行,进行文件的读取、写入等操做:

  • :w 保存
  • :q 退出。 :wq 保存 + 退出
  • :q! 放弃修改的内容强行退出
  • :e {file name} 打开某一文件
  • :ls 显示打开的文件(缓冲)
  • :help {topic} 打开帮助界面
    • :help :w 打开 :w 命令的帮助
    • :help w 打开 w 移动操做的帮助

Vim 实例演示

介绍了一些基本操做,能够经过一个例子来看看如何使用这些命令来编辑一个文件:

The Missing Semester 提供了一个例子,里面是一段有问题的 Python 程序:

def fizz_buzz(limit):
    for i in range(limit):
        if i % 3 == 0:
            print('fizz')
        if i % 5 == 0:
            print('fizz')
        if i % 3 and i % 5:
            print(i)

def main():
    fizz_buzz(10)
复制代码

该程序存在一些问题:

  • main 函数不会执行,须要在文件末尾添加一些语句
  • 循环会从 0 开始,而不是从 1 开始,须要修改 range 中的内容
  • 当数字是 3 的倍数 或者是 5 的倍数的时候,打印的是同一个词, 须要修改其中一个引号内的词为别的什么以区分
  • main 函数中使用的是写死的参数,而非命令行参数或者是用户的输入

下面的几个动图,显示了如何经过 Vim 来修改这个程序。按键操做显示在了动图中

添加 if __name__ == 'main': 语句,涉及到行数跳转:

add main

修改其中一个 'fizz''buzz'

modify range

修改 range 范围:

modify word

添加命令行参数:

Vim 基本配置

前面提到了一些须要配置的功能。在上面的动图中你也看到了相对行号显示、自动缩进等,这些在最开始打开 Vim 的时候并非默认开启的,须要在 Vim 的配置文件中进行配置。

在 macOS 和 Linux 系统中,Vim 的配置文件位于 '~/' 目录下,文件名为 .vimrc。Vim 在每次启动时都会默认读取该文件的配置。

这里是一个比较简单的配置文件,建议你阅读注释的描述,判断本身是否须要这一设置,再手动配置你的 '~/.vimrc` 文件,仅仅加入你须要的配置项。这样可以避免你在不清楚设置的具体内容是什么的状况下,盲目拷贝别人的配置,致使引入一些你不习惯的操做。

配置文件来自于 The Missing Semester,翻译了注释

" 双引号为注释标记.

" 若是在 Vim 中打开这个文件,则会看到语法高亮

" Vim 是基于 Vi 开发的。设置 `nocompatible` 会取消默认的 Vi 兼容模式,并启用一些有用的 Vim 功能
" 这项配置在 ~/.vimrc 中其实不必,由于若是用户有 `~/.vimrc` 文件,Vim 会自动使用非兼容模式。
" 写在这以防配置文件是经过其余方式引入的(好比文件另存为了 foo,并经过 `vim -u foo` 命令启动了 Vim
set nocompatible

" 打开语法高亮
syntax on

" 禁用默认的开启提示文字
set shortmess+=I

" 显示行号
set number

" 启用相对行号。当前行所显示的数字是实际行号,上面和下面的行都会显示相对的行号,便于跳转
set relativenumber

" 在窗口底部显示状态栏
set laststatus=2

" 若是搜索的关键词所有为小写,则搜索忽略大小写。若是关键词中含有大写字母,则搜索变为大小写敏感
set ignorecase
set smartcase

" 即时显示搜索结果,而非等待按回车以后再显示
set incsearch

" 启用鼠标。虽然你应该尽可能避免使用鼠标,可是某些状况下仍是鼠标比较方便 
set mouse+=a

" 当使用方向键跳转行数时发出提示
" Do this in normal mode...
nnoremap <Left>  :echoe "Use h"<CR>
nnoremap <Right> :echoe "Use l"<CR>
nnoremap <Up>    :echoe "Use k"<CR>
nnoremap <Down>  :echoe "Use j"<CR>
" ...and in insert mode
inoremap <Left>  <ESC>:echoe "Use h"<CR>
inoremap <Right> <ESC>:echoe "Use l"<CR>
inoremap <Up>    <ESC>:echoe "Use k"<CR>
inoremap <Down>  <ESC>:echoe "Use j"<CR>

" 将缩进符显示为 4 个空格 
set tabstop=4
" 当使用 '>' 缩进时, 使用 4 个空格
set shiftwidth=4
" 按 Tab 键时,插入 4 个空格
set expandtab
" 设置自动缩进,根据文件类型缩进 
set autoindent
filetype plugin indent on
复制代码

小结

本篇文章介绍了 Vim 的基本思想,入门 Vim 须要了解的基本操做,以及基本的配置项。这篇文章也是在 VS Code 中 启用了 Vim 插件以后编写的。

我本身也是刚用了没几个小时,虽然大部分操做已经比较熟悉,可是仍是有些地方会卡住一小会。不过,用得越多,就能发现卡壳儿的地方愈来愈少,写代码的速度愈来愈快了。

Vim 是一个很是强大的编辑器,还有不少的功能、插件和配置没有探索到。后续当我用得再多一些,总结出一些高级用法以后,再来分享。

网上也有很多资源能够学习 Vim,好比 Vim Tutor 在命令行学习 Vim 操做。还有人建了一个网页,你们互相比拼谁能用最少的命令修改完一段文本。另外,当你以为在编辑什么文件时,有些操做过于繁琐,那颇有可能确实存在一个更好的方式,这时不妨上网查一下,看看前人有没有相应的解决方法。

入门 Vim 确实是一个按部就班的过程,一开始很不习惯。可是当你逼着本身用一段时间之后,就会越用越顺手。固然,仍是在业余时间偷偷练习吧,熟悉 Vim 操做以前,在搬砖修福报的时候仍是保持效率更重要。。

参考连接:

missing.csail.mit.edu/2020/editor…

文章同步发布于博客:点击查看

相关文章
相关标签/搜索