Pi Store
更多

将 VS Code 打造成跨平台 Markdown「草稿本」

2023 年 09 月 13 日

借助配置文件、任务、代码片段和快捷键映射等功能,就能把 VS Code 变成一个跨平台、全功能的 Markdown「草稿本」,同时不影响它发挥代码编辑器的本职功能。


需求讨论

在电脑上工作时,经常会需要一个暂存文本的空间,用来放置一闪而过的想法、起草相对重要的消息回复,或者汇总来自多处的摘录——相当于案头备着的草稿纸所起的功能。

诚然,可选解决方案不可谓不多,既有 nvALTTotDrafts 等将此作为主要功能的软件,也可以用各类笔记软件、甚至剪贴板管理工具兼任。

Tot (MacWorld)

但是,我对这些方案一直不很满意。打草稿追求的是快进快出、随身携带,但上述工具中很少见到能兼顾收集快捷、导出方便和跨平台(特别是跨 macOS 和 Windows)同步的。将「草稿」和普通笔记混同在一起,也不便于管理。

更重要的是,越是草稿和临时性质的内容,越意味着需要大量编辑,包括调整顺序、提取信息、整理格式等等;笔记软件通常不会对此做特别优化,导致操作起来颇为麻烦。

经过多番尝试和比较后,我开始意识到,文本编辑器其实就是一种特别适合做「草稿本」的工具:由于基于朴素的目录和文本文件,很容易通过终端命令实现自动化,搭车通用的云盘实现跨平台同步;编辑器的定位使然,查找替换、快捷键操作、自动补全和高亮等功能也是必然内置的。

不过,要让文本编辑器真正成为方便好用的「草稿本」,还需要具有以下功能:

  • 支持自动保存。这是「草稿本」让人能放心使用的信任基础,又可以具体细分为自动保存更改和自动保存会话:前者是指自动保存对现有文件的编辑,后者是指在关闭窗口或退出软件时,即使没有保存到文件的临时内容也会被暂存下来,并在下次启动时重现。
  • 支持新文件名模板。没有人会想在打草稿的时候费脑筋起文件名。「草稿本」最好能为每个新建的文件按一定规则拟一个不会重复的文件名,例如通过时间戳或 UUID。
  • 支持 Markdown 语法。对于文本笔记,Markdown 支持几乎是必须的。理想的「草稿本」应该支持 Markdown 语法高亮、常见格式的快捷键,以及同步预览。
  • 支持区隔不同场景下的设置。「草稿本」的上述功能需求与一般的文件查看和代码编辑是非常不同的;如果编辑器只支持一套配置,按此设置也就意味着它几乎不能再用于别的任务了,显得有些小题大做。

调研下来,如果以「出厂状态」为标准,只有 BBEdit 最接近这样的要求。事实上,它的 Notebook 功能完全就是为了这个需求开发的。

BBEdit 的 Notebook 功能(Bare Bones Software)

遗憾的是,BBEdit 只支持 macOS 平台;作为三十年历史的经典软件,有些设计和操作在今天看来略显古旧,对 Markdown 和中文的支持都不完美;Notebook 也不属于其免费功能范围,50 美元的门票有些昂贵了。

于是,我又打起了自己另一个常用软件 VS Code 的主意。经过一番尝试,竟然完全符合需求:

  • VS Code 本身是跨平台、开源的代码编辑器,基础的编辑功能自然不在话下,而且具有特别丰富的插件生态。这使得 VS Code 可能是代码编辑器里最擅长写 Markdown 的,Markdown 工具里编辑功能最强的。
  • 支持多套配置的灵活切换。特别是一月更新的 1.75 版加入了一个非常实用的「配置文件」(profile)功能,可以为各个使用场景选择不同的设置、插件、界面布局和快捷键等,比以往基于工作区(workspace)的方式更灵活,而且支持云端同步。
  • 自动化方便,可以将任何终端命令保存为「任务」;还有完善的命令行界面,方便对接其他自动化工具。

下面,本文将具体介绍怎样将 VS Code 打造成一个跨平台的 Markdown「草稿本」,同时不影响它发挥代码编辑器的本职功能。如果有类似需求,你可以依样操作,也可以挑选适合自己的部分变通采纳。

搭建基本框架

首先,确定一个「草稿本」的存放目录。具体位置按个人习惯即可,但如果有同步需求,可以选择一个云盘中的位置;如果本来就用纯文本方式做笔记,还可以取现有路径的下级目录,方便统一管理。

例如,我的「草稿本」位于 ~/flashes(取「闪念」之意)。这个目录实际上是指向我 Obsidian 笔记库同名子目录的符号链接,本身 (1) 位于 iCloud 云盘中,(2) 通过 Syncthing 与非苹果设备同步,并且 (3) 自动定期提交到一个私人 GitHub 仓库。

这样,无论在 Mac、Android 手机还是 VPS 服务器上,我都可以随时访问到这些「草稿」;在 Obsidian 中整理笔记时,还可以直接引用或链接到「草稿本」中的内容。

创建完成后,在 VS Code 中通过命令面板(Command/Ctrl+Shift+P)运行 File: Open Folder,将这个笔记目录作为工作区打开。(由于 VS Code 的中文本地化翻译质量不高,本文中提及的命令和操作名称以英文版为准。)

接着,创建一个「草稿本」专用配置文件。 为此,通过命令面板运行 Profiles: Create Profile

在显示的选项中:

  • 配置文件名称:按喜好填写即可,尽量简洁,方便后面自动化。例如我这里起了一个 flashes,意指「闪念」。
  • 是否复制现有配置或模板的内容:这可以根据你之前的使用情况决定——
    • 如果你从事开发工作,已经对 VS Code 做了开发环境的重度配置,那么显然不适合照搬到「草稿本」中,最好选择「无」,从头开始。
    • 相反,如果你像我一样,主要用 VS Code 码字,配置比较轻量,那么不妨选择「默认」来沿用熟悉的环境。
    • 还有一种选择是 Doc Writer,这是 VS Code 提供的模板之一,内置了一系列为码字优化的设置项和流行插件;如果想偷懒或者没什么思路,它是一个比较好的起点。
  • 配置文件范围:这里列举了配置文件可以独立容纳的内容,如果取消勾选,新的配置文件会直接沿用默认配置的相应部分。如后文将会表明,这几项对于配置「草稿本」都是有用的,保持全选的默认状态即可。

做好设置后,点击 Create 即可完成创建。你可以从 Acticity Bar 上设置按钮的角标判断当前生效的配置文件。此外,工作区会记住上一次切换到的配置文件,因此以后打开「草稿本」文件夹时,都会自动使用刚才新创建的配置文件。

优化「草稿本」的内部环境

如开头提到,配置文件功能的一大优点就是实现了设置、插件的相互隔离。因此,我们可以随意将这个「草稿本」专用的新配置向着最适合 Markdown 随手记的环境改造,而不用担心干扰更适合编辑代码的默认配置,或者因为插件装得太多影响启动速度和性能。

至于具体怎么改造,则是萝卜青菜的问题,读者可以自由发挥。官方帮助中的「Markdown 编辑」一节是很好的起点(读完你很可能会意识到很多功能现在已经不需要装插件)。我之前还介绍过 AutoCorrect(自动添加中英文间的空格)和 markdownlint(自动检测和修复 Markdown 格式)两个实用 Markdown 写作插件,有兴趣的朋友可以回顾

下面只重点介绍一些我认为特别适合本文场景、需要一些注解的配置方式。

精简界面布局

VS Code 默认布局显得比较聒噪,很多功能对于 Markdown 笔记场景也并不适用。因为配置文件也会隔离界面布局,可以放心做些「大刀阔斧」的精简。例如:

  • 将侧边栏的 Explorer、Search 等高频使用的面板放到底栏中(通过拖拽,或者在标题上点击右键,选择 Panel Position > Bottom),然后隐藏 Source Control、Problems 等无关面板(在标题上点击右键选择 Hide Panel)。这样,就可以隐藏左右边栏节约空间了。
  • 点击窗口右上角的「自定义布局」按钮,打开 Zen Mode(但同时关闭 Centered Layout),隐藏无关的界面元素。

这样,界面看起来就清爽多了。

设置自动保存

好的「草稿本」应该尽量让人忘掉「保存」这回事,自己默默保存更改就好,不要用「是否保存」的弹窗来骚扰用户。为此,相关的设置是:

  • files.autoSave: 设为 afterDelay,即每隔一段时间自动保存,具体间隔通过 files.autoSaveDelay 指定(单位为毫秒),例如 5000 即为每 5 秒保存一次。
  • files.hotExit: 设为 onExitAndWindowClose,即在关闭窗口或退出应用时均不额外提醒,下次打开时自动恢复未保存内容。

一键插入格式模版

很多第三方笔记工具会提供快速插入 Markdown 模板的菜单项和快捷键,而这在 VS Code 中也很好实现,并且用自带的「代码片段」(snippet)和快捷键映射功能即可,不需要任何插件。

下面以自制插入 Markdown 任务列表(- [ ])的模板并绑定快捷键为例演示,配置好的效果如下图所示。

首先,将任务列表的语法创建为一个代码片段。 为此,用命令面板运行 Snippets: Configure User Snippets,然后选择 markdown。将打开的 markdown.json 文件修改如下:

{
    // omitted
    "Insert task list": {
        "prefix": "task",
        "body": [
            "- [${1| ,x|}] $2",
            "$0"
        ],
        "description": "Insert task list"
    },
    // omitted
}

由此,我们创建了一个名为 Insert task list,简称为 task 的代码片段,其格式定义位于 body 键。其中:

  • $1$2……$n 称为 tabstop,是模板中待填写的「空档」,在插入后可以按 Tab 键快速跳到下一个。
  • ${1| ,x|} 是指在光标位于这个空档时,用列表提供空格和 x 两个选项供用户选择,对应任务列表的两种状态。
  • $0 是填完所有空档后,光标最后停在的位置,这里设置为下一行的行首。

这时,就可以用命令面板运行 Snippets: Insert Snippet,然后选择 task 来调用这个模板了。

接着,我们为它指定一个快捷键,以便更快调用。 用命令面板运行 Preferences: Open Keyboard Shortcuts (JSON),将打开的 keybindings.json 文件修改如下:

[
    // omitted
    {
        "when": "editorTextFocus && isMac",
        "key": "cmd+k t",
        "command": "editor.action.insertSnippet",
        "args": {
            "name": "Insert task list",
            "langId": "markdown"
        }
    },
    {
        "when": "editorTextFocus && !isMac",
        "key": "ctrl+k t",
        "command": "editor.action.insertSnippet",
        "args": {
            "name": "Insert task list",
            "langId": "markdown"
        }
    },
    // omitted
]

这里:

  • key 键用于指定快捷键,可以是组合式、两段式或其混合(完整语法见官方帮助)。例如 cmd+k t 指先按 Command + K,然后再按 T
  • when 键用于指定启用快捷键的环境,可用条件包括操作状态、操作系统等,且支持逻辑运算(完整列举见官方帮助)。例如 editorTextFocus && !isMac 表示仅在输入焦点位于编辑区域,且当前系统不是 macOS 时才启用。由于 VS Code 是一个跨平台编辑器,这特别适合针对 macOS 和 Windows 设置不同的修饰键。
  • commandargs 键用于指定快捷键要执行的命令。对于代码片段而言,命令总是 editor.action.insertSnippetargs.nameargs.langId 则分别是之前在创建代码片段时设置的名称和适用语言。

通过同样的方法,你可以创建其他自己常用的 Markdown 格式模板并绑定快捷键。和配置文件中的其他设置一样,这都不会和默认配置相冲突,并且可以通过设置同步功能跨端同步。

这里再附一个「插入 Markdown 表格模板」的代码片段供参考:

{
    // omitted
    "Insert 3x2 table": {
        "prefix": "table",
        "body": [
            "| ${1:Column1}  | ${2:Column2}   | ${3:Column3}   |",
            "|-------------- | -------------- | -------------- |",
            "| ${4:Item1}    | ${5:Item1}     | ${6:Item1}     |",
            "${0}"
        ],
        "description": "Insert table with 2 rows and 3 columns."
    },
    // omitted
}

让新建文件名附带时间戳

默认设置下,VS Code 的 Command+N(或 Windows 上的 Ctrl+N)快捷键会新建一个名字毫无新意的 Untitled-1.txt,并且在手动保存之前都是临时文件。对于「草稿本」的场景而言,这既不直观也不方便。

联想到很多采用「卡片笔记」方法的软件都支持自动在文件名中加入时间戳(例如 Obsidian 的「ZK 卡片」按钮),既不会重复,又方便事后检索。这能否在 VS Code 中实现呢?

当然可以,方法是挪用 VS Code 的「任务」(task)功能。任务原本是针对开发场景的自动化功能,每项任务其实就是一条预先定义的命令,可以通过命令面板或快捷键调用,实现代码检查、编译等功能。

会员专属文章,欢迎加入少数派会员。
优质内容
权益周边
会员社群
power+
评论区
精彩评论0
成为少数派会员方可评论,立即加入 。若已是少数派会员,点击登录
还没有评论,来发表第一个评论吧
精彩评论
还没有评论,来发表第一个评论吧
成为少数派会员方可评论,立即加入 。若已是少数派会员,点击登录
会员新功能
内容侧边栏
点击这里拉开侧边栏,即可查看会员内容列表,快速切换内容。