vim操作指引(Vim为我编写书和课程省下了大把时间)(1)

vim操作指引(Vim为我编写书和课程省下了大把时间)(2)

在写一本书或课程时,你需要处理成百上千的字而Vim能够帮助你有效地管理这些内容.

当我就快要完成我正在忙的一门课程时,我会尝试想出方法来改善我的工作流为了能更容易地创建下一个课程。

这意味着要评价从音频和视频硬件到代码编辑器甚至操作系统的几乎所有东西。

这篇文章专注于大量文本的组织和处理.这可适用于书籍,课程,笔记或者实际上可以是任何东西。

过去的两周在Windows 的 Linux 子系统中配合使用了终端 Vim tumux 之后,我已经比之前的 VSCode 配置更有生产力了。

tmux 对于任何想要玩转多个项目的用户尤其有用。我总是在自由作家与开发工作,博客,开源项目,业余项目,课程间不停转换。能够点击一个tmux热键翻到任何一个给定的项目并让所有的东西都立即被加载和准备好开始工作是非常棒的。

我之前是通过 tmux 和 VSCode 来完成工作,但是打开并将 VSCode 移动到正确的尺寸总是需要我去手动完成。

那也许听起来很平凡,但是实际上并不是。每次你做的时候,它会将你置于一个负面情绪中,你会想"唉,现在我必须要手动再组织一遍"。

对于 Windows 来说最大的缺点就是,要去管理窗口 (windows) 布局是非常冗杂的,有趣的是这个操作系统居然也被称为 Windows。自从我在 Linux 上尝试过使用 i3 作为窗口管理器以后,我就再也不能够回到其它任何工具上了。

因此,在过去的几周里我一边为我的课程写作一边寻找能够在 Windows 中尽可能复制 i3 的方法,我发现在 WSL 中使用终端 Vim 和 tmux 使得我接近于可以在一个终端中做任何事情。

为此那也是我选择尝试 Vim 的一个主要原因。其并不一定是由于 VSCode 作为一个编辑器太过于局限,尽管在考虑改善我的课程创作工作流后我最终发现它的确是不合适的。

创作课程会涉及到什么?

它是一个可以与写一本书相比的几个月的投入,而且还会有额外的复杂度,因为你不仅仅要写下人们将要读的内容。

例如,对于一本书,你需要有一个目录,章节以及属于每个章节的内容。你可以以任何你喜欢的格式来写作一本书并在你将完成时将其导出为PDF格式。你仅仅需要关心PDF是什么样的。

一个课程与其很相似。 它有一个目录,小节和课程内容。小节只是一个组织课程内容的方式,而课程内容是你计划在视频上发表的内容的文本手稿。

例如,我当前忙于的课程具有24个小节以及158个课程内容。每个课程内容具有大约2000个字。粗略算共有300000个字的文本而这门课程还没有完成。

每个课程内容最后都将被转换为介于2到20分钟长的视频,具体时间实际上取决于该门课程字数的多少。

因此,现在让我们来谈一些我在组织课程内容时遇到过的一些问题。

下面的所有问题都是我在开始使用Vim之前的情况下遇到的的问题,而在最后我将重温我如何使用Vim来处理它们。

处理文件名

当时我针对这些问题的解决方式是为一个特定的课程创建一个 scripts文件夹并在那个文件夹内为每一个小节创建一个单独的文件夹,在小节文件夹内每一个课程都有其独立的文件。

它看起来像这样:

vim操作指引(Vim为我编写书和课程省下了大把时间)(3)

换句话说,我用一个数字对每个小节的课程内容进行排序,而对于每一个小节课程内容号码不会进行清零。它会从1开始编号,一直到最后一个课程内容。

有趣的是,我还有一个含有被编号的文件夹且能与特定的课程内容匹配的单独的git仓库。真正重要的是课程内容编号和git仓库文件夹编号最后会在一起编号。

但是,正如你可能已经发现,这个方式对于你需要在课程中途添加一个课程内容的情形来说是非常糟糕的。想象一下你在编号50后需要加入一个编号为51的课程。这意味着你需要为新添的51号后的所有课程内容编号手动增加1,而这是非常糟糕的。

关于这一点,要去预先为一个课程想出最终的目录编排几乎是不可能的,因为你不大可能去提前预测所有的课程内容。

我需要编写脚本并且在过程中使用它。我甚至可能写作完成后才想出课程内容的名称,而且由于视频的时长非常重要,课程内容的字数实际上决定了什么时候一个课程内容需要分割为下一个课程。

现在为了与该问题进行斗争,我所做的就是为每个小节创建一个文件,并为该小节写出所有的课程内容脚本,而在我很高兴时才会将其分解为手动编号的文件。

那是我现在的处理方式。我会手动对它们进行编号并试图减少在之后不得不添入课程内容的可能性。如果我不得不添入(这在这个课程中目前发生了两次),我就像吞下一个子弹一样感到急躁,然后还是得手动重命名所有的东西。

这种方式的另一个痛点是,如果我想要改变一个课程内容名称,我需要进入文件系统并手动改变文件名。这似乎看起来是一个小事情,但是它会为写作过程添加阻力。它真的会!

最后,有一个规则是,我总是要确保一个课程内容很漂亮的过渡到下一个课程内容,因此如果我正工作于课程内容5,我通常会打开课程内容4,滑到文件的底部,阅读我过去写的内容来确保我以一个自然过渡的方式开启课程内容5。这会涉及到许多在文件之间的跳跃。

利用我现有的工具解决这些问题的潜在的方法

我尝试不对课程内容进行编号而是准备好一个分开的YAML目录。那么我就可以编写一个小的Python脚本来读入该目录文件并在课程完成后以编程的方式为小节和课程编号。

我确认那能够工作,但是现在我需要保存一个与实际文件同步的单独的目录文件。处理文件名字本身就足够烦人了而这个解决方案并没有真正解决它。它就像在火上浇油一样。

然而值得提到的是,不像一本书,一个课程不仅仅是一个单独的导出的PDF文件。我想要人们能够在我的网站中进入课程,这意味着需要在课程平台后端创建一个目录。

最终要与其交互的是人类,而不仅仅是这些脚本文件,因此实际上在我的开发盒子里面的这些小节文件夹和课程内容文件是没必要存在的。它们的存在仅仅是为了我能够在一个git仓库中将它们与文件夹编号关联在一起。

完美世界中的理想解决方案

如果我不需要考虑小节和课程内容在代码编辑器中出现的顺序外的排序将会非常棒。

基本上,如果我有一个如下的课程内容列表:

  1. Welcome

  2. Downloading the Starter Files

  3. Tooling Setup

我仅仅想要以一个人类可读的方式来处理课程内容名字而不是去处理数字。如果我想要重命名一个课程内容,它仅仅在那个部位被重命名,而如果我想要将一个课程内容往下移,我仅需要进行下移而课程内容号会同时被自动更新。

关于这一点,如果在某处中间添加一个课程内容,所有其后的其它课程内容将会使他们的编码自动调整。这对于节编码同样适用。但是记住,课程内容编码将会在所有小节中进行检索。每个小节都会有起自己的单独的课程内容检索。

我也不愿意去手动处理创建 tooling-setup.txt文件。

另一个重要的事情是课程内容的分离。如果我点击进入或者展开Tooling Setup课程,我仅仅想要看见该课程内容的文本,但同时,为了能够快速查看它们如何开始和结束,我有时也许想要查看之前或者下一个课程内容的文本。

实际上,不仅仅只有课程内容的分离可以帮助我保持专注。能够跳跃到课程内容的开头,中部或者尾部并不将其应用于整个小节或者课程也是非常棒的。尤其是在搜索文本时。

但是关于那一点,有时能够在整个课程文本上进行操作是超级便利的。例如,我能够搜寻像"for example"这样的短语来看我说过它多少次,并尝试使用可替代的其它词来使得它听起来不过于系统化。

事实上我不会在发布视频的时候逐字地读这些脚本。他们主要是为了帮助我组织我的思绪,但是我的确需要在录制视频时用它们作为指导。

用Vim解决这个问题

我是在我知道我将要使用什么编辑器和工具前写下的上面的理想的解决方案。我认为这不仅是一个很棒的发现问题是什么的方法,也是一个如何解决它的方式。

我仅有的曾阅读过的技术书籍是SICP(Structure and Interpretation of Computer ProgRAMs)。在该书中他们谈论了一个叫做"wishful thinking"的概念。

在书的内容中,他们谈论了在假设已经有特定的库或者函数存在的情况下设计你自己的软件的场景。这使得你能够专注于设计你的应用的API并在之后填入细节。

那是我这里所做的,但是是一个不同的场景。

创建一个巨大的300000字的文件:

我开始参考我的理想解决方案并考虑这个问题。总的来说,问题的一个大的部分是关于处理单独的文件名字。

所以为什么不首先消除文件并使用一个大文件呢?

我没有一个巨大的文件来对其进行测试,但是只需要几秒钟就可以基于我已有的文件来创建一个。我只需要在WSL中打开一个Bash命令提示符并运行cat */*.txt > all.md

现在我有一个300000字的markdown文件,其大小大约是1.5MB。我决定尝试用我现有的VSCode设置和Vim来打开它。在两种情形下我都保证启用插件且两个编辑器都有处理markdown的插件。

令人足够吃惊的是VSCode非常快地打开了文件。其只花了3秒,而且往文件中输入时就像在一个小文件中输入一样快。

然而,仅仅在没有做任何事情的情况下,打开文件就占用了我的3.2GHZ四核i5 CPU的50%,并且在输入的时候跳跃到了65%.

这并不能解决问题。这是一个我将要在几个月内每天都要打开的文件。它不能占据我的整个CPU资源。同时,它也使用了800MB的RAM,虽然坦白地说由于我有16GB的RAM我并不介意那个。

因此我在Vim中打开了同样的文件。Vim花了大约一样的时间来打开文件,但是它使用了少于10MB的RAM以及在打开时占用0%的额外的CPU,在文件中部输入时额外的CPU占用仅仅跳至3-4%。

我感到就像我在一个更小的文件中进行输入一样轻快。它甚至会处理输入 ** 来开始使用markdown加粗文本并且是即时的,甚至它在对300000个字进行加粗时也是这样。

那是一个我能够寻求的更好的结果,尤其是当Vim是直接在被认为是非常慢的WSL中直接运行。我认为在原生Linux系统上其肯定会运行地更快。

设置一个显示的最差的情景:

如果我有一个900000字的文件会怎么样? 实际上在我一个课程中有500000个字是不大可能的,但是我认为看看会发生什么是一个好主意。

900000个字Vim花了10秒来打开,但是一旦完成后,就像操作只有300000个字的文件一样棒。在进出插入模式间大约有半秒的延迟,但那是仅有的差异。RAM和CPU占用几乎是一样的。

如果你很好奇,我告诉你VSCode在处理300k字的时候也会表现如此良好。在这种情况下,VSCode实际上比Vim更快地打开文件,但是,再一次地强调,这肯定是由于Vim是运行于WSL中,而VSCode是直接在Windows中运行。

在一个单独大文件的小节和课程内容之间导航:

由于我不将使用VSCode,所以去比较它是没有意义的,这将会专门专注于Vim。

vim-markdown 插件绝对是超级棒,并使得所有这一切都可以进行。

我是一个典型的不喜欢代码折叠的人,但是代码折叠被证明是有史以来的最好的东西对于这种方式来说,而且vim-markdown插件具有对基于markdown的标题处理折叠的一流支持。

这意味着我能够保证在打开文件时所有的折叠都是关闭的,然后跳跃到某一个我想要在上面进行工作的课程内容,并在几秒内它就展开。它工作得非常完美。

这个插件也支持使用[[]]在标题间跳跃,因此我可以很容易地跳跃到之前的或者下一个课程内容。

Vim也意识到了如何使代码折叠工作,你可以仅为那些打开的折叠执行文本搜索和操作。这给了我理想的解决方案中想要的所有的功能。因为如果我想要在整个文件上进行工作,我可以敲击一个热键来展开所有内容。

此外,还有fzf.vim插件,它可以让你模糊搜索缓冲区中的行。它是一个极佳的用于寻找短语的选择。严格地说,junegunn是一个令人吃惊的开发生产工具的作者。他制作了FZF和一些其它的工具。

为小节和课程内容编号:

vim-markdown插件碰巧也有一个手动命令叫做:Toc,它能够为你的标题创建整个目录。这个TOC是在一个分离的缓冲区中创建的,而且你甚至可以点击标题来跳至markdown文件中的对应区域。

这个行为完全是我所需要的。我不需要总是知道课程内容编号。只是在我想要知道计数或者想要在Vim外将一个课程内容编号关联到一个git文件夹号码的时候才需要。

目前这个插件没有支持在TOC输出中对标题编号,因此我在GitHub上打开了一个issue。但是这个问题目前是可解决的,就是一点点进行集成的工作就可以了。

例如,我所有的小节都使用#,而我所有的课程内容都使用##,因此所有需要做的就是一个小的Bash魔法来解析这个文件。例如,你可以在文件中进行grep并取出所有的以#开始的行然后你就有了一个所有小节的列表,等等...

我还没有想出一个完美的脚本,但是我100%确认那是可能实现的,而且那是我现在所有需要担心的。在我完成了我当前的课程以后,也许vim-markdown的作者就将这个功能构建到他的插件了。谁知道呢!

改善大文件中的滑动速度:

在WSL中,我注意到甚至在具有100行的小文件中滑动时的相对行数更新也是非常缓慢的。我们在滑动中花了几秒的延迟才看见光标移动。

结果是相对行数是最常被谴责的糟点,但是我并不想因此放弃。在应用了下面的设置以后,滑动再次变得迅速了,甚至是在一个具有900000字的文件中。查看一个超过100000行的文件是非常有趣的。

vim操作指引(Vim为我编写书和课程省下了大把时间)(4)

加速代码折叠:

在300000字文件中,默认的代码折叠是难以忍受的慢。甚至仅仅打开这个文件也使得它很难使用,但是经过一点研究后,我找到了一个可以完美地工作的插件。

添加FastFold插件到我的vimrc中立刻解决了这个问题。它从无法使用变为非常的棒。当折叠被更新的时候它就基本上跟着变化了。

为截屏视频添加润色而不用编辑视频

当我录制的时候,我通常会使用一个非常大的字体和一个显著的光标,因此去紧跟我正讲到的内容会更加容易。但是我最近开始做的的一件事情是在录制完视频以后通过添加特效来强调文本。

vim操作指引(Vim为我编写书和课程省下了大把时间)(5)

例如,在我录制视频以后,在编辑阶段我将经常经常使屏幕的大部分变得暗淡并突出代码的某一个特定区域,这是为了使我正在讲的内容更加清晰。

我听到许多人说他们真的很喜欢这个效果,并且一些人说我的深入Docker课程是他们所见过的产品质量最高的课程。

然而,产品质量的提升也是有代价的。它花费了非常长的时间来遍历视频并手动高亮我想要高亮的区域。

碰巧的是有一个叫做limelight.vim的插件,它可以让你实时地做这个事情。它是由创造FZF的同一个作者编写的。

vim操作指引(Vim为我编写书和课程省下了大把时间)(6)

它会自动高亮你的光标所在的区域,而且你可以调整诸如颜色暗淡和不透明度等参数。因此你可以使用任何颜色主题让它看起来非常棒。

这意味着我能够打开灰光灯,并且不需要在后期产品编辑中手动添加暗淡和高亮屏幕。只是这个功能就能够省下几个小时。目前VSCode没有提供类似的功能,但是我认为这是可以被完成的。我知道它有一个Emacs的接口。

我将会在我录制下一个课程的时候尝试一下它。

最后,我真的非常高兴给了Vim第二个机会。我很久以前忽视了它,但是现在它成为了我用于写代码和创建课程的工具链中最重要的工具。期待将来能有更多的Vim帖子产生。

英文原文:https://nickjanetakis.com/blog/vim-is-saving-me-hours-of-work-when-writing-books-and-courses 译者:青蒿素,