我的任务管理系统

本文参与「少数派2017年度征文」活动

Many a finger has attempted an expedition to No Hand’s Land, but none have returned successful.

这是著名的相机应用Halide的设计者Sebastiaan在How to Design for iPhone X (without an iPhone X)这篇文章中用来吐槽iPhone X屏幕过大的配图。从Halide滑动调节曝光参数、对焦滚轮置于屏幕底部等设计理念中可以看出这种「Reachable」理念的贯彻。
说起来,平常屏幕上最Reachable的区域还是键盘。自从学会双拼以后,我就发现自己对键盘(实体与虚拟)产生了一点依赖性。原先用图形界面能完成的事情,我如今更喜欢用键盘来完成。为此我想分享一下在过去的2017年中我总结出来的一套用键盘输入代替图形界面操作的工作流,主要涉及Drafts和Workflow这两大效率软件。效率这件事情本身是很主观的定义——所以我这套东西是否适合各位读者,也就仁者见仁智者见智了。

何谓键盘效率

在开始谈这套工作流之前,我想先聊聊它的目的,也就是创造效率。
「效率」这件事本身是一个很复杂的目标,带有强烈的主观性,柯林斯词典对于efficiency这个词的定义是「不浪费时间和精力地完成一件任务的能力」。当代各种自动化的应用、工作流的意义在于替用户去完成复杂但具有一定规律的工作,它们因此具有节省时间和精力的作用。在谈效率之前,无可避免地要牵涉到效率的意义。如果具体说这个话题,完全可以就此再写一篇文章,因此我只想简短地说说我的看法。
在实践了一年多的GTD并长期折腾Workflow、Drafts等应用后,我得出的结论是:应当辩证地看待效率这件事情。追寻效率不是养成分秒必争的习惯,而是掌握自己能掌握的时间。举例来说,使用GTD应用没有必要事无巨细地把全部能做的事情都写进inbox,而是注重把重要的或是易忘的事情放进去。同样,对待这套工作流,也没必要把所有需求全部放到键盘上,正确的打开方式应该是——用键盘把真正的「痛点」解决掉。
接下来我们来看看键盘效率。作为一种追寻效率的途径,评价键盘的意义离不开节省时间和节省精力这两方面。

键盘效率之于节省时间

综合来看,时间这个指标是最容易量化和比较的。Markdown的发明者John Gruber就曾经谈到过,用键盘完成重复的操作必然快于鼠标,就算寻找快捷键会花费时间,重复的操作也能省下更多的时间。推广地考虑,假如用户对于快捷键有足够的熟练度(常见的Ctrl-C、Ctrl-V、Ctrl-Z等就是很好的例子),就可以很大程度上减少寻找快捷键花费的时间。而放在iOS上来看,虚拟键盘本身不再起到Shortcut的作用,取而代之的是自动化时代的标配——键盘扩展条。这个键盘扩展区域可以同时包含快捷键、快速短语等功能,并且往往能够做到更多。但是我认为这些东西可以一并归入「键盘」的范畴,因为这两者在屏幕上的位置是相邻的,键盘扩展可以看作键盘的一个延伸。而鉴于点击扩展条上的一个快捷键不需要过多地思考(或Bruce Tognazzini所谓的「experience amnesia」),加之键盘扩展往往与各种能够节省时间的脚本与自动化流程相结合,从某种程度上来说这一自动化时代的产物在iOS平台上的效果更胜于旧时代的键盘操作——这是键盘效率在节省时间方面的体现。

键盘效率之于节省精力

除去不浪费时间,不浪费精力这一点也必然要受到评价。这个「精力」到底是指什么?笼统地讲,它是用户在完成操作过程的时候对于操作是否繁杂的感受。从某种意义上来说,移动鼠标并点击会消耗精力;操作图形界面会消耗精力;在键盘上按下按键同样也会消耗精力。回想上次使用Word的情景,你不小心误删除了一整段内容,这时是鼠标移到屏幕上方的工具栏点击撤销更快还是直接按下Ctrl-Z更快?由此可见,对于熟练的使用者,键盘的确能在大部分时间更省力,因为手在键盘上移动的距离往往比在鼠标或在图形界面上移动的距离要短很多。事实上,即使在iOS这个移动平台上,这件事情也不例外;就算iPhone6以后的机型有Reachability辅助,单手跨越半个屏幕去操作图形界面依然是挺麻烦的事情。相反,操作虚拟键盘时,我们的手停留在屏幕的下半部分,也即最容易触及的位置。
曾经有个网站叫 onetapless,专门收录各种自动化效率方案(可惜已经停止更新很久了),它的名字大约就是对「效率」最好的定义:节省精力,就是用更少的点击取代更多的点击;用Reachable的点击取代Unreachable的点击,以达成效率的目标。这样看来在iOS上寻求效率的一种方法就是键盘与快捷键和脚本的组合了,而这是键盘效率在节省精力方面的体现。

键盘效率的缺陷

任何事物都具有两面性,我并不想故意去掩盖键盘「不那么效率」的地方。
首先,键盘输入对于准确度有一定要求。图形界面只需要用户去点击一块区域即可触发反馈,而键盘输入的指令则不能有偏差。换而言之,键盘具有更低的容错率。其次,键盘输入对熟练度也有要求。如果输入速度不够快,那么这件事情并没有达到节省时间的效果,或许甚至会更消耗精力。
但是瑕不掩瑜,这些缺陷并不是我们弃用键盘的理由。进一步发掘键盘的潜力,就是要用现代化的方法规避这两大问题,使效率最大化。对于输入的准确性,通过键盘扩展条快速插入短语的方式可以减少输入错误的情况;而双拼和现代输入法的联想则可以使输入更快速。

综合来讲,键盘这一诞生远早于图形界面的交互方式在现今的时代并未过时。或许会有很多人倾向于语音、体感等新兴的交互方式,但对于熟练的用户来说,键盘永远是最快的。过去的命令行是用键盘进行全部的操作和控制,而如今键盘不再是控制系统的主力,但由它启动的自动化流程却带来了更多的生产力。

工作流总览

这套工作流的原理概括来说其实很简单:用Drafts输入内容,然后通过Drafts的Action运行Workflow,并将合适的内容作为参数传递给Workflow。而对应的Workflow动作的类型设置为Action Extention,这样就可以接收来自Drafts的文本作进一步处理。有了这个逻辑的指导,我们实际上可以弄出非常多的花样。
最终这个工作流实现的效果是:通过键盘在Drafts内输入一段文本,文本本身可能包含一些用于区分其处理方式的指令,然后按下键盘扩展条上的某个指向一个Action的按钮;这个Action随后触发一个Workflow;Workflow对接收的文本进行处理后进一步分发。如此,我们可以只使用键盘及扩展条,对应到屏幕上也就是开篇图片中的「REACHABLE PLAINS」来完成输入工作,达成上一节提到的效率。

为什么选择Drafts和Workflow?

除去使用键盘的便利性,作为iOS最有名的文本编辑器之一,Drafts自然有它的独到之处。
第一是Drafts本身的收集和分发特性。Drafts打开即写的形式很适合用来作为输入终端使用。理论上任何文字输入应用(例如原生备忘录)都可以代替Drafts在这个工作流中的位置,只需要输入文字然后在分享菜单中运行Workflow即可。但是Drafts还有一重特性:运行一个动作后可以直接将当前的文档存档或删除。假如我想直接把文档内容发送到另一处,我显然会希望运行动作后直接删除我输入的东西,这时Drafts的优势就体现出来了:它能够以一个文本编辑器的强大功能和扩展来支持这种「终端」式的操作行为,不是终端却又胜过终端。第二在于Drafts的键盘扩展对文字处理的能力支持很好,用键盘扩展可以快速插入很多东西,实现类似自动补全的输入效果。
而Workflow更是被誉为「带着镣铐跳舞」的效率应用,在iOS平台上率先打破了应用与应用之间的界限。理论上Pythonista也能完成Workflow的工作,但是Workflow胜在学习成本低、简短的动作制作快速——这也是「效率」的体现。有一种观点认为如果花费在为达成效率而制作的工作流上的时间多于这个工作流能节省的时间,那这种方法就是不具效率(inefficient)的。这种观点没有考虑到精力这一方面的节省,不过大体上还是可以拿来参考的。对于没有花费大量时间学习Python的人来说,显然还是用Workflow更效率——只要掌握方法。

用Workflow分发文字的几个方法论

Workflow作为这个键盘工作流中的信息分发枢纽,其重要性不言而喻。不过显而易见的是,各人的对于分发的目的地需求是不同的,因此我想先介绍几个介乎「术」和「器」之间的指导方法。

执行多行任务

自动化处理流程往往是对大量信息处理的过程,包含对多个项目的操作。但是Drafts或是任何等位的文字编辑应用导出的文本都是一个整体,所以需要对这段文本先进行处理。Workflow内置的Split Text动作可以按照指定分行符(通常用换行)将输入的文字分离,然后合成一个列表作为输出,随后接一个Repeat With Each即可对每一行文字单独执行处理流程。
用 Workflow 执行多行任务
大体上这个思路就是如图所示的结构,在Repeat的循环中再包含具体的处理流程。这样在Drafts中只需输入完每一个待处理的内容单位后换行(假如Split Text选择New Lines,那就只需换行而无需按照Markdown换行那样按Tab),再执行该Workflow,那么每一行的内容单位就会分别被执行相同的操作流程。

识别不同指令

多行同时处理的缺陷在于每一行都是经过同一个Workflow流程,因此经过的处理流程是一样的。但假如我们的预期中每一行受到的处理略有差别,例如某一行的内容最终被送往到GTD应用的Inbox列表,而另一行则被送到Works这个列表,那又该怎么办呢?
在依靠键盘完成所有事情的思路指导下,方法很显然:对于不同的操作,在制作Workflow时就自我约定好几个有效的指令,然后用正则表达式来识别指令。
识别指令
Workflow中内置的Match Text就是通过正则表达式来识别输入的文本,从中提取出符合特征的文本段的。例如默认的[0-9a-zA-Z]匹配的就是单个数字或字母,所有符合结果的内容会被编组成一个列表作为输出。当然你也可以直接输入一段内容来匹配,例如输入abcd,这个动作便会匹配所有的「abcd」。有关于具体如何使用正则表达式的语法,你可以在这个页面查看。
我个人的习惯是用一个符号加上内容来代表指令,例如@inbox这样的格式。特殊符号的意义是便于识别出整段文字中代表指令的部分。此外,在第一次匹配后,可以再接一个Match Text匹配\w*(表示除符号以外的任意字符串)来去除特殊符号,这样匹配出来的最终结果就可以直接作为魔法变量拿来用了。

使用缩写指令

由于前面识别出来的指令最终直接用于Workflow的动作,因此必须要输入完整。但是我的Todoist中有一个Project叫「Books&Movies」,如果想向它添加内容,每次都打一遍那个and符号是不现实的,更为合理的使用方法显然是打一个类似于@bm这样的缩写。为此我决定再引入一个Dictionary用来存放缩写-全称的组合。Dictionary是一种数据格式,由多组键值(key)对应数据值(value)的组合构成,键值是必须唯一的。在用上一节的匹配方法找到缩写的指令后,把这个指令和Dictionary中的所有键值匹配一遍,如果有任何相等的,则输出那个键值对应的数据值。由于流程图过长,你可以点击这里查看。
而只需将这个流程图中的Set Variable改为Add to Variable,我们就可以匹配连续多个指令并合成一个列表作为输出。

几个例子

参考以上几个方法,我做了几条Workflow来改善日常的输入效率。

Todoist——非自然语义处理

众所周知的是Todoist的任务输入功能是有自然语义处理功能的,能够识别出一些日期和重复等内容。尽管如此,我还是觉得添加任务有时候是一件不那么愉快的事情——问题出在Todoist对于已添加的任务的编辑入口藏得太深,而图形界面在输入的时候又并不总是很方便(更何况我还用了一段时间的浏览器版)。这也就是我为何开始尝试用Workflow来添加任务。
我并不想就这个Workflow的技术细节再花费篇幅,所有有关于它的信息可以点击此处来查看。我更希望在这里谈谈这个Workflow背后的逻辑,也就是我的GTD收集理念:可回顾的输入过程。GTD的收集往往是思路整理的过程,在这个过程中任何已写下的东西都有可能会重新被修改。这也就是为什么Todoist输入完一条就按下回车确认的输入方式让我觉得略微不适,而在Drafts里有条理地整理完所有思绪再一次性创建任务才是符合逻辑的输入方式。诚然,这样输入就等于抛弃了Todoist自带的自然语义处理,但是可自定义的灵活缩写和键盘扩展支持的快速插入功能足以弥补这一缺陷。

Quizlet——更流畅的添加体验

Quizlet的应用在学习集内添加单词的入口很深,算来从主界面到开始添加单词合计需要点按4次,其中还有一次在屏幕的右上角,这样的体验可想而知是很差的。
幸好Quizlet提供了完善的API供我们调用,少数派曾有一篇利用 Workflow和API 快速添加 Flashcards 背单词就提及了用API添加单词的方法,参考这篇文章的思路,我们只需打开Drafts,输入生词,运行Workflow即可快速添加单词,而不会打断阅读的思维过程。

类似这样的例子还有很多,这样的一个组合实际上可以做到很多事情,我这里的两个例子也仅仅是起到抛砖引玉的作用。

结语

面对同一条的道路,不同的人会造出不同的轮子。这篇文章仅是我对于我心目中的轮子的阐述和解释,这个轮子未必对所有人都是最完美的,但是其背后的逻辑是我认为最适合这条道路的。如果你有与我不同的看法,欢迎在此提出,理性讨论。


题图来自Freepik