用 VIM 写 Markdown

前言

这是第 n 次写这篇博客了。前面都是写了几次之后又删掉,因为主题不明,终于也有觉得自己写作主题不明的那天了。其实这篇文章也不全是关于 VIM,因为我确实不好定性。

以前自己使用的 Markdown 编辑器是 Typora[1],不得不说,Typora 是真的优雅。虽然自己不再使用,但尝试过其他编辑器后,总是觉得没有一款可以比得上 Typora。

Typora 收费后各种替代品涌现,打算占据这片高地,比较有名的是 MarkText[2]。可惜有些东西还真
替代不了,虽然 MarkText 真的很简洁,走了 Typora 风格,但是使用起来总觉得不够丝
滑。

我还使用过 Zettlr[3],主要用于论文写作,因为
Typora 不支持文献引用。后面 Zettlr 出现小 bug,导致表格录入的数据都无法保存。这个问题很快就被修复了,但是当时我正在赶论文,根本没有时间等待,直接使用 VIM
写。

俺是万万没想到,原来 VIM 写 Markdown 一样可以很顺手。当时不知道Better BibTex[4]可以直接在 VIM 内调用 Zotero 的引用框,为了完成文献的插入,我用 vimscript,VIM
的脚本语言,写了一个引用文献的脚本,然后完成了自己的论文。

事后想想,好像没有使用 Zettlr 的道理了:原本它的优势是文献引用,现在自己写了一
个小脚本也解决问题了。此外,当时为了交叉引用引入新语法,Zettlr 也渲染不了,于是我就彻底抛弃 Zettlr 扎根 VIM。

使用 VIM 写作还是碰到了很多问题,很多都是自己并不完全了解 VIM 导致的,但有些问
题 VIM 到现在还是没有解决。这也是我写这篇博客的原因:把自己碰到的一些问题总结
到一起。

用 VIM 写 Markdown

|物理行和逻辑行

物理行指的是没有回车符断开的一行,或者叫做“段落”,逻辑行指的是段落内部可以分成
的行。这很抽象,下面一张图解释一下物理行和逻辑行:

用 VIM 写 Markdown
物理行和逻辑行

上图中,第 50、54 行属于物理行,一般只占一(逻辑)行。第 46、48 行也是物理行,
但是由于字数太多进行了段内分行,所以出现了逻辑行。简而言之,图片中标有行号的就是物理行。

逻辑行的行数是随着窗口大小改变的,比如我把窗口变大之后,逻辑行就变少了,因为一
行可以容纳的字符变多了。

用 VIM 写 Markdown
逻辑行变少了

一般的编辑器不区分物理行和逻辑行,也就是光标或者鼠标把肉眼能见到的行,都算作一
行,不幸的是 VIM 不这样。

VIM 的 j 和 k 是物理行的移动,逻辑行使用 gjgk。写文章的时候,一行包含
的字符太多是没法用 jk 进行逻辑行移动的。

举个例子:上面第一张图,想要从第 46 行的“镜像之后”移动到下面的“但是可以”。其他编辑器最笨也可以使用方向键往下移动,但是 VIM 使用方向键或者 j 就会直接跳到第
47 行,要移动到下一逻辑行必须使用 gj 或者 g,否则就需要使用l 键一直往右移动,直到碰到自己想到的位置。

使用 gj 也不是不行,只是需要敲两次按键,对我们来说太麻烦了。解决办法是使用
VIM 的按键映射(map)。在 VIM 配置文件 ~/.vimrc 添加:

nnoremap  j gj
nnoremap  k gk
nnoremap  g
nnoremap  g
nnoremap  gj j
nnoremap  gk k
nnoremap  g
nnoremap  g
用 VIM 写 Markdown
重新映射按键

上面是把两种按键对换了:物理行使用 gjgkgg 进行移动,逻辑行使用 jk 或者方向键即可。

至于为什么使用的是 nnoremap 而不是简单的 map,这得涉及到 VIM 的一些语法,
一两句话说不清。nnoremapnormal not recursively map 的缩写,表示普通模式下对按键进行非递归映射。

|长段落

第一个问题,物理行和逻辑行解决了,但是没有彻底解决:它只是解决了如何在物理行和
逻辑行直接移动,没有解决逻辑行和物理行的问题。

物理行指的是一个段落,为方便叙述统一使用“段落”替代,请看下面的物理行:

用 VIM 写 Markdown
长长的物理行

在段落里移动只能使用 hl,因为 VIM 最引以为豪的文本对象(text-object)
对东亚文字不起作用。英语或者说拉丁字母的词是通过空格来区分的,但是中文、韩文、
日文、喃字、字生(中日韩越壮字符)是没有空格的。

VIM 可以使用 w 进行字词的移动,或者 f 快速跳转,那是借助了拉丁文字的空格判
断。中文没有空格,这些文本操作只能识别标点符号。所以上面那些长长的段落,在 VIM
中只能非常笨拙地一个字符一个字符移动。

至于解决办法,没有,VIM 到现在都没有解决这个问题。

不过使用 Markdown 就有点好处了。Markdown 有一条规则:回车符不是分段的标志,空行才是段落的标志。举个例子:

不过使用 Markdown 就有点好处了。Markdown 有一条规则:回车符不是分段的标志,空
行才是段落的标志。举个例子:

看起来是两行,毕竟有一个回车嘛,在“空”之后。但 Markdown 中,这被当作一行看待,
Markdown 会把这两行合成一个段落,然后在两行之间添加一个空格,对于拉丁文字来说很方便。渲染后成为:

不过使用 Markdown 就有点好处了。Markdown 有一条规则:回车符不是分段的标志,空 行才是段落的标志。举个例子:

那 Markdown 如何插入一个真正的段落?使用一个空行就行:

不过使用 Markdown 就有点好处了。Markdown 有一条规则:回车符不是分段的标志,空

行才是段落的标志。举个例子:

正是 Markdown 的特性,我们不用让 VIM 的段落太长,可以在自己想要断开的地方断开,
反正渲染之后都会被当作一行对待。

用 VIM 写 Markdown
直接在一定字数后断开,不必一行内全写整个段落

那应该在哪里断开?写代码一般都会有个不成文的规定:一行代码的字符数不多于 78
个。所以我们可以限定自己的一段只有 78 个字符。写文章的时候不可能去数自己一行到底写了多少字符,可以用 VIM 的功能辅助:colorcolumn

colorcolumn 可以高亮特定的列。如果我们希望自己的字符数不超过 78 这个列,可以
~/.vimrc 配置文件中添加 set colorcolumn=79

用 VIM 写 Markdown
高亮第 79 列,字数超过这列就断行

这样,只要写到这一列就可以换行了。上面的配色有点难看,但只是为了演示。

上面说了,Markdown 会把回车断开的行拼成一个段落,然后在它们之间添加一个空格。问题就出在这里了:添加一个空格。对拉丁文字来说好处多多,毕竟这样就不用在分段的
地方添加空格,但是对中文来说就多了一个不必要的空格。例如在 之后分段,下一
个字符是 ,合并成一行后成为 回 家

这个解决办法还算简单:使用 Pandoc 的功能。Pandoc 扩展里有一个east_asian_line_breaks 功能,可以自动判断如果是东亚字符就不添加空格。

用 VIM 写 Markdown
东亚文字断行

想要使用这个功能需要如此:

pandoc -f markdown+east_asian_line_breaks -t docx paper.md

或者在 YAML 配置中输入:

from: markdown+east_asian_line_breaks
# 或者
reader: markdown+east_asian_line_breaks

下面是使用这个扩展和不使用的效果展示:

用 VIM 写 Markdown
原始文件,一个段落分两行
用 VIM 写 Markdown
不使用 east_asian_line_breaks 扩展,可以看到“一”和“点”之间有空格
用 VIM 写 Markdown
使用 east_asian_line_breaks 扩展,“一”和“点”之间的空格没有了

至此,好像解决了逻辑行和物理行的问题了

用 VIM 写 Markdown
看看这篇文章的效果

|空格

写作的时候经常会碰到中英文混合输入。一般而言,如果碰到这种情况,应该在中英文之
间保留一个空格 — 中文、英文和阿拉伯数字之间应该有空格。

不过一般是看不到这些控制符号的。有些时候写的太快忘了在中英文之间放空格,回头检
查就很麻烦。可以给空格、制表符等这类控制符一个标识,这样检查时就能一眼看出。比
如下图使用一个点号(·)代替空格(可视化),检查的时候可以一眼看出空格在哪里:

用 VIM 写 Markdown
空格使用一个点号替代

上图中出现了一个中文句号后接英文(nnoremap),它们之间是没有空格的,那里出现
空白只是因为中文句号是全角符号,占用两格。如果不让空格可视化,我们可能以为是一
个英文标点加一个空格 — 没错,我改论文的时候被这东西害惨了。

可视化的方式是在 ~/.virmc 配置文件添加:

set listchars=space:·

同理还可以设置其他的控制符,例如 Tabular 这类,可以在 VIM 中输入:help listchars 回车查看。

用 VIM 写 Markdown
listchars 可以设置的部分

|平滑滚动

还是物理行和逻辑行的衍生问题:因为 VIM 只认物理行,所以滚动的时候会出现这种问
题:如果一行很长,例如 JavaScript、JSON 文件,那滚动非常难受。

比如下面的演示:长段落滚动直接整段消失,重新绘制,太变态了。

用 VIM 写 Markdown

不设置平滑滚动

同样是上面的例子,这次看下图。这种时候,长段落不会整段消失,而是尽量铺满屏幕,
表示和上面的文字是一个段落。

用 VIM 写 Markdown
平滑滚动

这就是“平滑滚动”,在 ~/.vimrc 中添加 set smoothscroll 即可。

|使用 VIM 的过滤功能 (Filter)

过滤功能(Filter)其实翻译不是很准确,本质上就是文本和外部命令的交互。VIM 中可
以通过 ! 与调用外部命令。举个例子,在命令行模式输入 :!ls 就可以列出当前文
件所在目录下的所有文件了:

用 VIM 写 Markdown
使用过滤功能列出当前文件所在目录的所有文件

然后 VIM 还可以把文件的文本传出去,调用外部命令处理。例如我要在下面随机生成 10
个 100 以内的整数,然后再从小到大排序。可以写下 Python 代码,再传给外部 Python
处理:

用 VIM 写 Markdown
生成随机数

这个示例调用了 Python 和 Linux 的 sort 命令。选择范围我做了两次演示:第一次
是使用行数范围,从第 257 到第 259 行;第二次是使用可视(块)模式,直接选定区域。

不过对于很多人来说,这可能没什么用,毕竟写代码的人才会意淫这种用法,是吧?其实
不然,举个例子,我现在要画一个图,只需要在 Markdown 内写下这个图的流程,然后调
用外部命令处理即可:

用 VIM 写 Markdown
演示画图

上面使用的命令是 {range}w !{command}:想看自己写的画图代码如何,只需要传出代
码,不需要读入,所以使用 w !{comamnd}(write),如果只是读入则使用r !{command}(read),传出又读入使用 !{command}

觉得画得不错,可以在当前目录直接生成图片 test.png,然后引用:

用 VIM 写 Markdown
生成并引用图片
用 VIM 写 Markdown
生成的图片

何如?这其实有点像 VS Code 的 Code Runner (好像是这个名字,忘了),但是更灵
活。

没办法,字数有点多了,下次再写。

后语

其实之前我想写写自己写的 Zotero 引用插件,但是那时候使用 vimscript 比较年轻,
有点迷信 Lambda 表达式,导致自己的代码充斥着大量的 Lambda 表达式,后面自己都看不懂。

下面可以看看我之前写的 Lambda,都要走火入魔了。因为自己也看不懂代码,所以就一直没写。主要是那时候以我的知识知道,调用函数其实会拖慢速度,觉得 Lambda 可能快
一点,其实也不然。最近用 vim9script 对自己的插件进行了重构(高大上的词),可能
会真的写一篇文章讲讲 VIM 的插件怎么写。

用 VIM 写 Markdown
上古时代还年轻,大量使用 Lambda 表达式

相关网站

[1]

Typora: https://typoraio.cn

[2]

MarkText: https://github.com/marktext/marktext

[3]

Zettlr: https://zettlr.org

[4]

Better BibTex: https://retorque.re/zotero-better-bibtex/

本内容由作者或发布人投稿发表,只做展示阅览使用。发布者:欣IT,转转请注明出处:https://www.xinenw.com/4945

(1)
打赏 微信扫一扫 微信扫一扫
欣IT欣IT作者
上一篇 2023年 6月 4日 上午8:34
下一篇 2023年 6月 4日 上午8:35

相关推荐

  • 保姆级开通ChatGPT Plus教程,极速体验GPT-4

    点击蓝字 关注我们 如果你需要一个长期稳定的私人生产力工具,建议按照本文操作自充,首次订阅的后续付费会简单很多;如果你只是想尝个鲜,可以直接淘宝买号,或者短期代充,立马就能玩。 0. 注册chatGPT账号 登录 https://chat.openai.com/chat,选择  sign up 注册账号。(需要VPN) 手机号验证使用软件 SMS Activ…

    2023年 6月 3日
    40200
  • 使用 Linux 作为主力机一年后

    前言 一年前,当我把自己的电脑系统改成 Linux 时,我就想着一年快过去、快过去,我要写一篇文章讲讲自己用 Linux 系统如何了!然后真到了一年后,我却懒得写了。现在抽出时间,恰好可以圆一下去年的梦。作为一个总结,我会聊聊两个问题,一个说说自己的感受,一个说说使用 Linux 作为主力机需要的 Windows 替代品。 使用 Linux 作为主力机感觉如…

    2023年 6月 3日
    5.9K00

发表回复

登录后才能评论
欣文网全新升级中,拥抱WP,开启新次元,尽请期待!