Mastering_vim

目录:

bilibili居然有配套“Mastering Vim: Understanding Vim's Lesser-Known Features for More Effective Editing”的视频,作者Damain Conway。

1. Preface

2. Chapter 1: Getting Started

2.1. Technical requirements

2.2. Let’s start a conversation (about modal interfaces)

2.3. Installation

2.3.1. Setting up on Linux

其实作者用的是Vim8,而公司32号机是Vim7.4,有无必要跟从特定版本。若需跟从,就不能用公司32号机了,无安装权限。

对了,其上介绍了对应不同的linux版本该怎么安装最新的Vim。

书上更新命令似乎无用,换用网上搜索的命令:

sudo add-apt-repository ppa:jonathonf/vim
sudo apt-get update
sudo apt-get install vim

2.3.2. Setting up on MacOS

2.3.2.1. Using Homebrew

2.3.2.2. Downloading a .dmg image

2.3.3. Setting up on Windows

似乎作者说在Windows系统可使用Cygwin和gVim实现Vim的功能,当然,似乎也因操作系统差异有些小问题。

2.3.3.1. Unix-like experience with Cygwin

2.3.3.1.1. Installing Cygwin
2.3.3.1.2. Using Cygwin

2.3.3.2. Visual Vim with gVim

2.3.4. Verifying and troubleshooting the installation

作者说到,也许Vim默认支持python2而非3,他介绍了解决这个问题的办法。

2.4. Vanilla Vim vs gVim

2.5. Configuring Vim with your .vimrc

2.6. Common operations (or how to exit Vim)

2.6.1. Opening files

不管文件存在与否,有则直接打开,无则创建并打开:

vim animal_farm.py

若已打开Vim程序,想在Vim程序中打开文件如animal_farm.py,可:

:e animal_farm.py

注::e代表edit。

2.6.2. Changing text

进入Vim之后默认在普通模式,此模式下任何键入对应特定某条命令。输入i可进入插入模式。模式可看底部状态行,如插入模式显示--INSERT--,普通模式无特别提示。

在插入模式输入以下内容:

#!/usr/bin/python3
"""Our own little animal farm."""

import sys

def add_animal(farm, animal):
    farm.add(animal)
    return farm

def main(animals):
    farm = set()
    for animal in animals:
        farm = add_animal(farm, animal)
    print("We've got some animals on the farm:", ','.join(farm) + '.')
    
if __name__ == '__main__':
    if len(sys.argv) == 1:
        print('Pass at least one animal type!')
        sys.exit(1)
    main(sys.argv[1:])

敲击ESC键回到普通模式。

2.6.3. Saving and closing files

普通模式执行如下命令,可保存文件:

:w

注:

  1. :w代表write。
  2. 别忘了在输入命令后敲击ENTER键。
  3. 也可保存到新的文件,如:w animal_farm_2.py代表将animal_farm.py当前内容保存至animal_farm_2.py

接下来你应该是要退出文件,可输入:

:q

注::q代表quit。

也可同时保存并退出,即:

:wq

如文件有更改却想不保存更改直接退出,要使用如下命令强制退出:

:q!

注:

  1. Vim中许多命令有长短两个版本。例如,:e:w:q:edit:write:quit的短版本。在Vim手册中,命令的可选部分通常用方括号([])标注,例如:w[rite]:e[dit]

2.6.3.1. A word about swap files

默认情况下,Vim在交换文件中跟踪对文件所做的更改。交换文件是在编辑文件时创建的,用于在Vim、SSH会话或机器崩溃时恢复文件内容。如不清楚退出Vim,屏幕将出现:

...
Swap file ".animal_farm.py.swp" already exits!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:

可敲击r来恢复交换文件内容,或敲击d删除交换文件并驳回改变。如果您决定恢复交换文件,您可以通过重新打开一个文件并运行:e,并按d删除交换文件,来防止下次在Vim中打开文件时出现相同的消息。

默认情况下,Vim在与原始文件相同的目录中创建类似于<filename>.swp的文件。如果您不希望您的文件系统被交换文件打乱,您可以通过告诉Vim将所有交换文件放在一个目录中来改变这种行为。为此,在.vimrc中添加以下内容:

set directory=$HOME/.vim/swap//

注:

  1. Windows系统应设置:

    directory=%USERDATA%\.vim\swap//
    

    注意最后两斜线方向必须如上所示。

  2. 甚至可通过set noswapfile完全关闭交换文件。

  3. 很可能home目录无此文件,可创建并加入此条。

  4. 配置时候你可能会写注释,但Vim的注释不能用#,而要在需注释行首用"(英文双引号)。

2.7. Moving around: talk to your editor

Vim允许您比大多数传统编辑器更有效地浏览内容。让我们从基础开始。

你可以使用方向键或字母hjkl来移动光标。这是最低效和最精确的移动方式:

key Alternative Action
h Left arrow
左箭头
Move cursor left
光标左移
j Down arrow
右箭头
Move cursor down
光标右移
k Up arrow
上箭头
Move cursor up
光标上移
l Right arrow
下箭头
Move cursor right
光标下移

Vi (Vim的前身)是在旧的ADM-3A终端(看其键盘布局无箭头键)上创建的,该终端没有箭头键。键hjkl用作箭头。

试一试!习惯hjkl的移动有很大的价值:你的手停留在键盘的主行上。这样你就不需要移动你的手,它会帮助你保持流状态。此外,许多应用程序将hjkl视为箭头键—您会惊讶于有这么多工具响应这些键。

现在,您可能倾向于多次点击方向键来达到想要的位置,但是有一个更好的方法!您可以在每个命令前面加上一个数字,这将重复该命令的次数。例如,按5j将光标向下移动5行,而按14l将光标向左移动14个字符。这适用于您在本书中遇到的大多数命令。

计算您想要移动的确切字符数是相当困难的(而且没有人愿意这样做),所以有一种方法可以通过单词移动。使用w移动到下一个单词的开头,使用e移动到最近单词的结尾。要回到单词开头,按b键。

空格隔断的任何字符,包括大写字母,均应视为文字(word)。这允许您区分希望遍历的内容。

注:

  1. Vim有两种文字(word)对象:小写“word”和大写“WORD”。在Vim世界中,word是由空格分隔的字母、数字和下划线组成的序列。WORD是由空格分隔的任何非空白字符组成的序列。
  2. 让我们来看看下面这行代码:

    farm = add_animal(farm, animal)
    

    代码此时光标位置在a。按w键会把光标移到(;而按W键会转到animal的开头。按e键会把光标移到add_animal的末尾;而按E键会转到animal的开头。

大写的WEB将把任何被空格分隔在一起的字符作为本WORD。如下表所示:

Key Action
w Move forward by word
向前移动一个word
e Move forward until the end of the word
向前移动到本word末尾
W Move forward by WORD
向前移动一个WORD
E Move forward until the end of the WORD
向前移动到本WORD末尾
b Move backwards to the beginning of the word
后移到本word的开头
B Move backwards to the beginning of the WORD
后移到本WORD的开头

下面的表格显示了更多关于每个命令行为的例子:

Key Initial cursor position Resulting cursor position
w farm = <a>dd_animal(farm, animal) farm = add_animal<(>farm, animal)
e farm = add_an<i>mal(farm, animal) farm = add_anima<l>(farm, animal)
b farm = add_an<i>mal(farm, animal) farm = <a>dd_animal(farm, animal)
W farm = add_an<i>mal(farm, animal) farm = add_animal(farm, <a>nimal)
E farm = add_an<i>mal(farm, animal) farm = add_animal(farm<,> animal)
B farm = add_animal(f<a>rm, animal) farm = <a>dd_animal(farm, animal)

注:

  1. <>标注光标位置。

将显示的(通过文字移动)动作与您先前学习的方向动作相结合,以减少按键次数!

在段落中移动也很有用。任何被至少两行隔开的代码都被认为是一个段落,这也意味着每个代码块都是一个段落,如下面的例子所示:

def add_animal(farm, animal):
    farm.add(animal)
    return farm

def main(animals):
    farm = set()
    for animal in animals:
        farm = add_animal(farm, animal)
    print("We've got some animals on the farm:", ', '.join(farm) + '.')

函数add_animalmain是两个独立的段落。使用右花括号向前移动,使用左花括号向后移动,具体如下表所示:

Command Action
{ Move back by one paragraph
向后移动一段落
} Move forward by one paragraph
向前移动一段落

注:

  1. 区隔段落仅需首尾各一空行。
  2. 这里空行指除换行符之外的其它字符,空格符也不行。
  3. 通过{}在段落间移动,你会好奇光标落脚处。若段落之间区隔为两空行,{将首先移到本段落的段首,即本段落紧前一空行的行首,之后再{将移到下一段落的段首。}将首先移到本段落的段尾,即本段落的紧后一空行的行首,之后再}将移到下一段落的段尾。若段落之间区隔为一空行,则本段落的段尾即下一段落的段首。

如果你需要移动一个以上的段落,不要忘记把这两个和数字结合起来。

有更多的移动方式,但这些是最重要的基础。我们将在第二章“高级编辑和导航”中介绍更复杂的导航方法。

2.8. Making simple edits in insert mode

在使用Vim时,您通常希望在插入模式上花费尽可能少的时间(除非您正在编写而不是编辑)。由于大多数文本操作都涉及编辑,所以我们将重点讨论编辑。

您已经学会了按i键进入插入模式。有更多的方法可以进入插入模式。通常情况下,你会想要为另一篇文章修改一段文字,而且有一个针对该的命令cchange命令允许您删除部分文本并立即进入插入模式。Change是一个复合命令,这意味着它后面需要有一个命令告诉Vim需要更改什么。你可以把它和你以前学过的任何动作命令结合起来。以下是一些例子:

Command Before After
cw farm = add_animal(<f>arm, animal) farm = add_animal(<,> animal)
c3e (comma counts as a word) farm = add_animal(fa<r>m, animal) farm = add_animal(fa<)>
cb farm = add_animal(farm, ani<m>al) farm = add_animal(farm, <m>al)
c4l farm = add_animal(farm, <a>nimal) farm = add_animal(farm, <a>l)
cW farm = add_animal(farm, <a>nimal) farm = add_animal(farm,<>

注:

  1. c后面跟移动的命令,代表删除到移动结束的位置。如cw指向前移动一个单词并删除,实现表格第一行。
  2. farm,animal算3个word。
  3. 紧上表格我试验了,确实如此。
  4. 作为一个奇怪的例外,cw表现得像ce。这是Vim的前身Vi遗留下来的。

当您学习更复杂的动作命令时,您可以将这些命令与快速无缝编辑的更改组合在一起。我们还将介绍一些插件,这些插件将对更改命令进行加速,从而允许进行更强大的编辑,比如更改大括号中的文本,或者替换正在运行的引号类型。

注:

  1. 所有这些示例都遵循<command> <number> <movement or a text object>结构。您可以在<command>之前或之后放置一个数字。

例如,如果您希望将farm = add_animal(farm, animal)更改为farm = add_animal(farm, creatures),您可以执行以下命令集:

Contents of the line Action
<f>arm = add_animal(farm, animal) Start with a cursor in the beginning of the line
开始时光标位于行首
farm = add_animal(farm, <a>nimal) Hit 3W to move the cursor three WORDs forward to the beginning of animal
敲击3W以使光标移动3个WORD到“animal”的开头
farm = add_animal(farm, <)> Press cw to delete the word animal and enter the insert mode
按下cw以删除属于一个word的“animal”并进入插入模式
farm = add_animal(farm, creature<)> Type creature
输入“creature”
farm = add_animal(farm, creatur<e>) Hit the Esc key to return to NORMAL mode
敲击ESC键回到普通模式

有时我们只想切东西,不放任何东西,d就是这样做的。它代表删除。它的行为与c相似,只是we的行为更标准一些,如下例所示:

Command Before After
dw farm = add_animal(<f>arm, animal) farm = add_animal(<,> animal)
d3e (comma counts as a word) farm = add_animal(fa<r>m, animal) farm = add_animal(fa<)>
db farm = add_animal(farm, ani<m>al) farm = add_animal(farm, <m>al)
d4l farm = add_animal(farm, <a>nimal) farm = add_animal(farm, <a>l)
dW farm = add_animal(farm, <a>nimal) farm = add_animal(farm,<>

还有两个更漂亮的快捷方式,可以让你改变或删除一整行:

Command What it does
cc Clears the whole line and enters insert mode. Preserves current indentation level, which is useful when coding.
清除整行并进入插入模式。保持当前缩进级别,这在编码时很有用。
dd Deletes an entire line.
删除整行。

注:

  1. ccdd的差异。cc将进入插入模式dd则否。cc将保持此行之前的缩进状态,而dd将删除整行并换行符,即被删除行甚至不留下空行。
  2. 如果在选择正确的移动命令时遇到困难,还可以使用可视化模式选择要修改的文本。按v键进入可视模式,使用常用的移动命令来调整选择。一旦您对选择满意,就运行所需的命令(如c更改或d删除)。可视化模式可显示选择了什么文本。

2.9. Persistent undo and repeat

与任何编辑器一样,Vim跟踪每个操作。按u撤消最后一个操作,并按Ctrl + r重做。

注:

  1. 要了解更多关于Vim的撤消树(Vim的撤消历史不是线性的!)以及如何导航它,请参阅第4章,高级工作流。

Vim还允许持久化会话之间的撤消历史记录,如果您希望撤消(或记住)几天前完成的某些操作,这是非常好的!

您可以通过在.vimrc中添加以下代码来启用持久撤销:

set undofile 

但是,这将为您正在编辑的每个文件添加一个undo文件。您可以将撤销文件合并到一个目录中,如下面的示例所示:

" Set up persistent undo across all files. 
set undofile 
if !isdirectory("$HOME/.vim/undodir")  
    call mkdir("$HOME/.vim/undodir", "p") 
endif 
set undodir="$HOME/.vim/undodir"

注:

  1. 如果您使用的是Windows,请将目录替换为%USERPROFILE%\_vim\undodir(您将更改_vimrc而不是.vimrc)。
  2. 不知为何,会遇到E303错误,所以并未实际完成vim配置,既然.vimrc之前是不存在的,那么删除此文件。

现在,您将能够跨会话撤消和重做更改。

2.10. Read the Vim manual using :help

Vim提供的最好的学习工具当然是:help命令,如下面的截图所示:

help.txt        For Vim version 8.1.  Last change: 2019 Jul 21

                        VIM - main help file
                                                                         k
      Move around:  Use the cursor keys, or "h" to go left,            h   l
                    "j" to go down, "k" to go up, "l" to go right.       j
Close this window:  Use ":q<Enter>".
   Get out of Vim:  Use ":qa!<Enter>" (careful, all changes are lost!).

Jump to a subject:  Position the cursor on a tag (e.g. bars) and hit CTRL-].
   With the mouse:  ":set mouse=a" to enable the mouse (in xterm or GUI).
                    Double-click the left mouse button on a tag, e.g. bars.
        Jump back:  Type CTRL-O.  Repeat to go further back.

Get specific help:  It is possible to go directly to whatever you want help
                    on, by giving an argument to the :help command.
                    Prepend something to specify the context:  help-context

                          WHAT                  PREPEND    EXAMPLE
                      Normal mode command                  :help x
help.txt [Help][RO]

它是一个随Vim安装的巨大的资源和教程的集合。通过使用页面向上和向下键(也可分别使用Ctrl + bCtrl + f)滚动,有很多有用的信息。

当您遇到问题,或者想要了解更多关于某个特定命令的信息时,请尝试使用:help(您可以将其缩短为:h)进行搜索。让我们来搜索一下我们学过的cc命令:

:h cc

显示为:

                        "c" command always starts insert mode, even if there
                        is no text to delete.

                                                        cc
["x]cc                  Delete [count] lines [into register x] and start
                        insert linewise.  If 'autoindent' is on, preserve
                        the indent of the first line.

                                                        C
["x]C                   Delete from the cursor position to the end of the
                        line and [count]-1 more lines [into register x], and
                        start insert.  Synonym for c$ (not linewise).

                                                        s
["x]s                   Delete [count] characters [into register x] and start
                        insert (s stands for Substitute).  Synonym for "cl"
                        (not linewise).

                                                        S
["x]S                   Delete [count] lines [into register x] and start
                        insert.  Synonym for "cc" linewise.
change.txt [Help][RO]

帮助告诉我们命令的工作方式,以及不同的选项和设置如何影响命令(例如自动缩进(autoindent)设置保留缩进)。

:help是一个导航一组帮助文件的命令。当您查看帮助文件时,您会注意到某些单词是用颜色高亮显示的。这些都是标记,可以使用:help命令进行搜索。不幸的是,并非每个标签名称都是直观的。例如,如果我们想学习如何在Vim中搜索字符串,我们可以尝试使用以下方法:

:h search

然而,看起来这个命令把我们带到表达式求值的入口,这并不是我们要找的,如下面的截图所示:

                Returns an empty String when row or col is out of range.

                Can also be used as a method:
                        GetRow()->screenstring(col)

search({pattern} [, {flags} [, {stopline} [, {timeout}]]])      search()
                Search for regexp pattern {pattern}.  The search starts at the
                cursor position (you can use cursor() to set it).

                When a match has been found its line number is returned.
                If there is no match a 0 is returned and the cursor doesn't
                move.  No error message is given.

                {flags} is a String, which can contain these character flags:
                'b'     search Backward instead of forward
                'c'     accept a match at the Cursor position
                'e'     move to the End of the match
                'n'     do Not move the cursor
                'p'     return number of matching sub-Pattern (see below)
                's'     Set the ' mark at the previous location of the cursor
                'w'     Wrap around the end of the file
eval.txt [Help][RO]

要找到正确的条目,输入:h search(不要回车),然后按Ctrl + D。这将为您提供包含子字符串search的帮助标记列表。其中一个选项是search-commands,这是我们要找的。完成您的命令,以下列方式进入我们正在寻找的入口:

:h search-commands 

下面的显示显示了搜索的正确帮助条目:

8. Composing characters         patterns-composing
9. Compare with Perl patterns   perl-patterns
10. Highlighting matches        match-highlight

==============================================================================
1. Search commands                              search-commands

                                                        /
/{pattern}[/]<CR>       Search forward for the [count]'th occurrence of
                        {pattern} exclusive.

/{pattern}/{offset}<CR> Search forward for the [count]'th occurrence of
                        {pattern} and go {offset} lines up or down.
                        linewise.

                                                        /<CR>
/<CR>                   Search forward for the [count]'th occurrence of the
                        latest used pattern last-pattern with latest used
                        {offset}.

//{offset}<CR>          Search forward for the [count]'th occurrence of the
                        latest used pattern last-pattern with new
                        {offset}.  If {offset} is empty no offset is used.

pattern.txt [Help][RO]

注:

  1. 说到搜索功能,您可以使用/search term从游标向前搜索,或者使用?search term向后搜索帮助页面(或Vim中打开的任何文件)。有关如何执行搜索操作的更多信息,请参见第2章高级编辑和导航。

当您有问题或想更好地理解Vim的行为方式时,不要忘记使用Vim的帮助系统。

2.11. Summary

最初的Vi是为了在带宽和速度有限的情况下通过远程终端工作而开发的。这些限制引导Vi建立一个高效的、深思熟虑的编辑过程,这是当今Vi改进的核心。

在本章中,您学习了如何在每个主要平台上安装和更新Vim及其图形化对应的GVim(以比您需要的更多的方式)。

您已经学会了通过修改.vimrc来配置Vim,当您根据自己的需要定制编辑器时,您常常会回到这个步骤。

您已经掌握了处理文件、移动Vim和进行更改的基础知识。Vim的文本对象(字母、单词、段落)和复合命令(如d2w-删除两个word)的概念为精确的文本操作提供了支持。

如果你能从这一章中学到一件事,那就是:help。Vim的内部帮助系统非常详细,它可以回答您可能遇到的大多数问题(如果不是所有问题的话),只要您知道自己在寻找什么。

在下一章中,我们将研究如何从Vim中获得更多信息。您将学习如何导航文件和更好地编辑文本。

3. Chapter 2: Advanced Editing and Navigation

在本章中,您将更轻松地在日常任务中使用Vim。您将使用Python代码库,它应该为您提供一组使用代码的真实场景。如果你有自己的项目,你可以选择使用自己的项目文件来尝试本章的课程;但是,您可能会发现并不是所有的场景都适用于您的代码库。

本章将涉及以下主题:

3.1. Technical requirements

本章将介绍如何使用Python代码库。你可以通过https:/​/​github.​com/​PacktPublishing/​MasteringVim/​blob/​master/​Chapter02获取本章将要编辑的代码。

3.2. Installing plugins

本章将首先介绍Vim插件。插件管理是一个相当广泛的主题(在第3章,也跟随领导者-插件管理),但我们开始只有几个插件,所以我们暂不必自己担心那个主题。

首先,让我们来看看一次性设置:

  1. 您需要创建一个目录来存储插件。在命令行执行以下操作:

    $ mkdir -p ~/.vim/pack/plugins/start
    

    如果你在Windows下使用GVim,你必须在目录用户文件夹下创建vimfiles(通常C:\Users\<username>),然后在其中创建pack\plugins\start

  2. 您需要告诉Vim为每个插件加载文档,因为它不会自动加载文档。为此,在~/.vimrc中添加以下行:

    packloadall           " Load all plugins.    
    silent! helptags ALL  " Load help files for all plugins. 
    

现在,每次你想添加一个插件,你必须:

  1. 在GitHub上找到你的插件。例如,让我们安装https:/​/​github.​com/1. scrooloose/​nerdtree。如果已经安装了Git,请找到Git存储库URL(在本例中是https:/​/​github.​com/​scrooloose/​nerdtree.​git)并运行以下命令:

    $ git clone https://github.com/scrooloose/nerdtree.git ~/.vim/pack/plugins/start/nerdtree 
    

    如果您没有安装Git,或者安装着Windows下的GVim插件,请导航到插件的GitHub页面,找到一个Clonedownload按钮。下载ZIP文件并将其解压缩到Linux的.vim/pack/plugins/start/nerdtree,或Windows的vimfiles/pack/plugins/start/nerdtree

  2. 重新启动Vim,插件应该可以使用。

3.3. Organizing workspace

到目前为止,我们只处理了Vim中的一个文件。在处理代码时,您通常必须同时处理多个文件,来回切换,在多个文件之间进行编辑,并在其他地方查找某些数据。幸运的是,Vim提供了一种广泛的方式来处理许多文件:

下面是一个截图来说明以上几点:


注:

  1. 暂不知怎么实现如书上两个文档左右排列

让我们来看看截图中的内容:

本节将详细讨论窗口、选项卡和折叠,您将能够轻松地处理所需的任何文件。

3.3.1. Buffers

缓冲区是文件的内部表示。您打开的每个文件都有一个相应的缓冲区。让我们从命令行打开一个文件vim animal_farm.py。现在,让我们看看现有的缓冲区列表:

:ls

注:

  1. 许多命令都有同义词,:ls也是这样,:buffers:files将有同样效果。

以下是:ls命令输出的情况(看底部三行):

...                                                                                                                                                                                                            
~                                                                                                                                                                                                            
:ls
  1 %a   "animal_farm.py"               line 23
Press ENTER or type command to continue

状态栏显示了一些关于我们已经打开的缓冲区的信息(我们现在只有一个):

让我们打开另一个文件:

:e animals/cat.py

您可以看到,我们最初打开的文件不见了,已经被当前文件替换。但是,animal_farm.py仍然存储在一个缓冲区中。再次列出所有缓冲区:

:ls

你可以看到两个文件名列出:

...                                                                                                                                                                                                           
~                                                                                                                                                                                                            
:ls
  1 #    "animal_farm.py"               line 23
  2 %a   "animals/cat.py"               line 4
Press ENTER or type command to continue

那么,我们怎样才能得到文件呢?

Vim通过一个数字和一个名称引用缓冲区,并且在单个会话中这两者都是惟一的(直到您退出Vim)。要切换到一个不同的缓冲区,使用:b命令,后面跟着缓冲区的数字:

:b 1

注:

  1. 您可以通过省略:b和缓冲区编号之间的空格来缩短命令。

瞧,你又回到了原始文件!由于缓冲区也由文件名标识,所以可以使用部分文件名在它们之间进行切换。下面将打开包含animals/cat.py的缓冲区:

:b cat

但是,如果有多个匹配项,则会出现错误。尝试寻找一个文件名包含py的缓冲区:

:b py

如下面的截图所示,状态栏显示了一个错误:

:ls
  1 #    "animal_farm.py"               line 23
  2 %a   "animals/cat.py"               line 4
E93: More than one match for py
Press ENTER or type command to continue

这时就可以使用tab补全来遍历可用选项。输入:b py(不需要回车),然后按Tab键循环查看可用的结果。

您还可以使用:bn:bnext)和:bp:bprevious)在缓冲区循环。

一旦你完成了缓冲区(的使用),你可以删除它,也就是从开放缓冲区的列表中删除它而不退出Vim:

:bd

如果没有保存当前缓冲区,将返回一个错误。因此,您将有机会保存文件而不会意外删除缓冲区。

3.3.2. Plugin spotlight – unimpaired

Tim Pope的vim-unimpaired是一个插件,它为现有的Vim命令(以及一些新命令)添加了大量方便的映射。我每天都使用它,因为我发现映射更直观——]b[b在打开的缓冲区循环,]f[f在一个路径下的文件循环,等等。可从Github地址https:/​/​github.​com/​tpope/​vim-​unimpaired 得到(参阅本章之前章节安装插件以获得安装指导。)

以下是vim-unimpaired提供的一些映射:

这个插件也允许你通过几个按键来切换某些选项,比如切换拼写检查或者切换光标高亮显示。

参见:help unimpaired完整列表的映射和功能,vim-unimpaired提供。

3.3.3. Windows

Vim将缓冲区加载到windows中。您可以同时在屏幕上打开多个窗口,允许分屏功能。

3.3.3.1. Creating, deleting, and navigating windows

让我们尝试一下使用windows。打开animal_farm.py(从命令行运行$ vim animal_farm.py或从vim运行:e animal_farm.py)。

在一个分割窗口打开我们的一个文件:

split animals/cat.py

注:

  1. 也可将:split简化为:sp

你可以看到animals/cat.py被打开在当前文件的上方,你的光标被放在那里:

class Cat(animal.Animal):

    def __init__(self):
        self.kind = 'cat'
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
~                                                                                                                                                                                                            
animals/cat.py                                                                                                                                                                             4,25           All
#!/usr/bin/python3
"""Our own little animal farm."""

import sys


def add_animal(farm, animal):
    farm.add(animal)
    return farm


def main(animals):
    farm = set()
    for animal in animals:
        farm = add_animal(farm, animal)
    print("We've got some animals on the farm:", ', '.join(farm) + '.')


if __name__ == '__main__':
    if len(sys.argv) == 1:
        print('Pass at least one animal type!')
        sys.exit(1)
    main(sys.argv[1:])
~                                                                                                                                                                                                            
animal_farm.py                                                                                                                                                                             23,5           All
"animals/cat.py" 4L, 77C

你可以通过运行以下代码来垂直分割窗口:

:vsplit farm.py

注:

  1. :vs:vsplit命令的简化。

您可以将:split:vsplit命令无限地组合在一起,以创建您需要的任意数量的窗口。

到目前为止,您学到的所有命令在这个窗口中都将正常工作,包括更改缓冲区。要在窗口之间移动,请使用Ctrl+w,然后按方向键:hjkl。箭头键也可以。

注:

  1. 如果你经常使用windows,你可以通过绑定Ctrl+h到左边的拆分,Ctrl+j到底部的拆分,等等。在.vimrc文件中添加以下内容:

    " Fast split navigation with <Ctrl> + hjkl. 
    noremap <c-h> <c-w><c-h> 
    noremap <c-j> <c-w><c-j> 
    noremap <c-k> <c-w><c-k> 
    noremap <c-l> <c-w><c-l>
    

尝试一下Ctrl+w接着j会把你移到下面的窗口,然后Ctrl+w接着k会把光标移回来。

你可以通过以下方式之一关闭分割窗口:

Ctrl+w接着q将关闭当前窗口 :q将关闭窗口并释放缓冲区,然而,如果只有打开的一个窗口,也将关闭vim bd将删除当前缓冲区并关闭当前窗口。 Ctrl+w接着o将关闭除当前外的其它窗口

注:

  1. 当打开了多个窗口,可执行:qa来关闭全部窗口并退出vim,可结合:w来保存所有打开了的文件,也就是:wqa

如果你想关闭一个缓冲区而不关闭它所在的窗口,你可以添加以下命令到你的.vimrc文件:

command! Bd :bp | :sp | :bn | :bd  " Close buffer without closing window. 

您将能够使用:Bd关闭缓冲区,同时保持拆分窗口打开。

3.3.3.2. Moving windows

3.3.3.3. Resizing windows

3.3.4. Tabs

3.3.5. Folds

3.3.5.1. Folding Python code

3.3.5.2. Types of folds

3.4. Navigating file trees

3.4.1. Netrw

3.4.2. :e with wildmenu enabled

3.4.3. Plugin spotlight – NERDTree

3.4.4. Plugin spotlight – Vinegar

3.4.5. Plugin spotlight – CtrlP

3.5. Navigating text

3.5.1. Jumping into insert mode

3.5.2. Searching with / and ?

3.5.2.1. Searching across files

3.5.2.2. ack

3.5.3. Utilizing text objects

3.5.4. Plugin spotlight – EasyMotion

3.6. Copying and pasting with registers

3.6.1. Where do the registers come in?

3.6.2. Copying from outside of Vim

3.7. Summary

4. Chapter 3: Follow the Leader - Plugin Management

4.1. Technical requirements

4.2. Managing plugins

4.2.1. vim-plug

4.2.2. Honorable mentions

4.2.2.1. Vundle

4.2.2.2. Do it yourself

4.2.2.3. Pathogen

4.2.3. Profiling slow plugins

4.2.3.1. Profiling startup

4.2.3.2. Profiling specific actions

4.3. Deeper dive into modes

4.3.1. Normal mode

4.3.2. Command-line and ex modes

4.3.3. Insert mode

4.3.4. Visual and select mode

4.3.5. Replace and virtual replace mode

4.3.6. Terminal mode

4.4. Remapping commands

4.4.1. Mode – aware remapping

4.5. The leader key

4.6. Configuring plugins

4.7. Summary

5. Chapter 4: Understanding the Text

5.1. Technical requirements

5.2. Code autocomplete

5.2.1. Built-in autocomplete

5.2.2. YouCompleteMe

5.2.2.1. Installation

5.2.2.2. Using YouCompleteMe

5.3. Navigating the code base with tags

5.3.1. Exuberant Ctags

5.3.2. Automatically updating the tags

5.4. Undo tree and Gundo

5.5. Summary

6. Chapter 5: Build, Test, and Execute

6.1. Technical requirements

6.2. Working with version control

6.2.1. Quick-and-dirty version control and Git introduction

6.2.1.1. Concepts

6.2.1.2. Setting up a new project

6.2.1.3. Cloning an existing repository

6.2.1.4. Working with Git

6.2.1.4.1. Adding files, committing, and pushing
6.2.1.4.2. Creating and merging branches

6.2.2. Integrating Git with Vim (vim-fugitive)

6.3. Resolving conflicts with vimdiff

6.3.1. Comparing two files

6.3.2. vimdiff and Git

6.3.2.1. git config

6.3.2.2. Creating merge conflict

6.3.2.3. Resolving a merge conflict

6.4. tmux, screen, and Vim terminal mode

6.4.1. tmux

6.4.1.1. Panes are just like splits

6.4.1.2. Windows are just like tabs

6.4.1.3. Sessions are invaluable

6.4.1.4. tmux and Vim splits

6.4.2. Screen

6.4.3. Terminal mode

6.5. Building and testing

6.5.1. Quickfix list

6.5.2. Location list

6.5.3. Building code

6.5.3.1. Plugin spotlight: vim-dispatch

6.5.4. Testing code

6.5.4.1. Plugin spotlight – vim-test

6.5.5. Syntax checking code with linters

6.5.5.1. Using linters with Vim

6.5.5.2. Plugin spotlight – Syntastic

6.5.5.3. Plugin spotlight – ALE

6.6. Summary

7. Chapter 6: Refactoring Code with Regex and Macros

7.1. Technical requirements

7.2. Search or replace with regular expressions

7.2.1. Search and replace

7.2.2. Operations across files using arglist

7.2.3. Regex basics

7.2.3.1. Special regex characters

7.2.3.2. Alternation and grouping

7.2.3.3. Quantifiers or multis

7.2.4. More about magic

7.2.4.1. Magic

7.2.4.2. No magic

7.2.4.3. Very magic

7.2.5. Applying the knowledge in practice

7.2.5.1. Renaming a variable, a method, or a class

7.2.5.2. Reordering function arguments

7.3. Recording and playing macros

7.3.1. Editing macros

7.3.2. Recursive macros

7.3.3. Running macros across multiple files

7.4. Using plugins to do the job

7.5. Summary

8. Chapter 7: Making Vim Your Own

8.1. Technical requirements

8.2. Playing with the Vim UI

8.2.1. Color schemes

8.2.1.1. Browsing the color schemes

8.2.1.2. Common issues

8.2.2. The status line

8.2.2.1. Powerline

8.2.2.2. Airline

8.2.3. gVim-specific configuration

8.3. Keeping track of configuration files

8.4. Healthy Vim customization habits

8.4.1. Optimizing your workflow

8.4.2. Keeping .vimrc organized

8.5. Summary

9. Chapter 8: Transcending the Mundane with Vimscript

9.1. Technical requirements

9.2. Why Vimscript?

9.3. How to execute Vimscript

9.4. Learning the syntax

9.4.1. Setting variables

9.4.2. Surfacing output

9.4.3. Conditional statements

9.4.4. Lists

9.4.5. Dictionaries

9.4.6. Loops

9.4.7. Functions

9.4.8. Classes

9.4.9. Lambda expressions

9.4.10. Map and filter

9.4.11. Interacting with Vim

9.4.12. File-related commands

9.4.13. Prompts

9.4.14. Using Help

9.5. A word about style guides

9.6. Let's build a plugin

9.6.1. Plugin layout

9.6.2. The basics

9.6.3. Housekeeping

9.6.4. Improving our plugin

9.6.5. Distributing the plugin

9.6.6. Where to take the plugin from here

9.7. Further reading

9.8. Summary

10. Chapter 9: Neovim

10.1. Technical requirements

10.2. Why make another Vim?

10.3. Installing and configuring Neovim

10.3.1. Checking health

10.3.2. Sane defaults

10.4. Oni

10.5. Neovim plugin highlights

10.6. Summary

11. Chapter 10: Where to Go from Here

11.1. Seven habits of effective text editing

11.2. Modal interfaces everywhere

11.2.1. A Vim-like web browsing experience

11.2.1.1. Vimium and Vimium-FF

11.2.1.2. Alternatives

11.2.2. Vim everywhere else

11.2.2.1. vim-anywhere for Linux and macOS

11.2.2.2. Text Editor Anywhere for Windows

11.3. Recommended reading and communities

11.3.1. Mailing lists

11.3.2. IRC

11.3.3. Other communities

11.4. Summary

12. Other Books You May Enjoy

13. Index