- 每次需要输入时等要通过额外的操作,频繁切换聚焦的窗口来获取这些信息。
这些问题虽然各自都占用了我们为数不多的时间和精力,但因为场景小而频繁,当乘以次数后,这些消耗也变得非常可观,并且非常影响我们的工作体验。
思考
让我们思考一下当我们想要使用 alias 的时候我们实际想要的是什么?我以个人的经验来总结,大概是以下几点:
-
用一个很短的短词来替代一个需要高频输入的很长的句子。
-
用一个更好记的词替代一个难记易忘的句。
-
配置的成本可控,使用的成本很低。
我们品一品1、2两点,其本质就是一个字典,由短语为key,长句为value。这个是我们程序员的好朋友了,我们可以简单的通过一个文件就能实现这份配置。事实上,我们使用记事本记录,其实本质也是在使用字典的特性。而第三点,让我瞬间想到使用 Alfred 的 Workflow 这个Mac上的神器。关于 Alfred 此处不做介绍,不知道或者想要了解的同学可以移步官网 (https://www.alfredapp.com/?spm=ata.13261165.0.0.5082c0d41D4sSf)。
设计
其实针对我们已经给出的需求,我们非常容易就可以得出一个设计思路。我们可以固定一个文件路径保存一个文件,这个文件以一种简单的格式或方式保存一个字典。编写一个 alfred 的 workflow 来解析这个文件形成一个 Map ,并通过搜索和匹配 key 来快速的获取 value ,而获取 value 最有效的方式就是把 value 输出到系统的剪切板中。
考虑到 Mac 和 Alfred 的使用用户并不全是工程师,我们选择记录字典的格式最好越简单越好。所以我计划以普通的文本格式,每一行为一个键值对,第一个空格前的短词为 key ,第一个空格后的内容为 value 。直接让用户新建指定路径的文件并通过编辑文件的方式来管理的形式确实可以被一部分用户所接受,但是为了能面对更多用户,我认为以 workflow 的方式在增删字典的内容也同时是需要支持的。这样不想关心具体实现、不愿接触文本文件的用户同样可以无感使用。
最后我给这个 workflow 取名为 EasyAlias。
实现
来看一下 workflow 的排版:
通过三个关键字的Alfred命令,分别实现设置alias(sal, set alias),删除alias(dal, delete alias),查找(gal, get alias)。
其中sal和dal使用简单的keyword输入,而gal为了使用Alfred通过的展示候选列表和搜索匹配的能力,而使用了Script Filter作为输入。三者都通过shell调用了一个实现主要功能的python脚本easy_alias.py,通过传入不同的action参数来区分行为。
sal:
python easy_alias.py set {query}
dal:
python easy_alias.py del {query}
gal:
python easy_alias.py show {query}cat filter.output
easy_alias.py
coding=utf8
import sys
import json
from os import listdir, makedirs
from os.path import isfile, join, exists, expanduser
base_path = expanduser(“~/.easy_alias”)
file_name = “alias_conf”
file_path = join(base_path, file_name)
alias_map = dict()
def init():
if not exists(base_path):
makedirs(base_path)
if not exists(file_path):
open(file_path, ‘w’).close()
def get_key_and_value(text):
seqs = text.strip().split(’ ')
if len(seqs) < 2:
return None, None
key = seqs[0];
value = reduce(lambda x, y: x.strip() + ’ ’ + y.strip(), seqs[1:])
return key, value
def get_alias_map():
with open(file_path, ‘r’) as f:
for line in f.readlines():
k, v = get_key_and_value(line)
if k == None or v == None:
continue
alias_map[k] = v
def set_alias():
if len(sys.argv) < 3:
return
text = sys.argv[2].strip()
k, v = get_key_and_value(text)
if k == None or v == None:
return
alias_map[k] = v
def del_alias():
if len(sys.argv) < 3:
return
key = sys.argv[2].strip()
new_content = “”
if key in alias_map:
alias_map.pop(key)
def show_alias():
items = list()
for k, v in alias_map.iteritems():
d = {
“uid”: k,
“type”: “default”,
“title”: k,
“subtitle”: v,
“arg”: v,
“autocomplete”: k,
“icon”: {
“type”: “fileticon”,
“path”: “icon.png”
}
}
items.append(d)
show = {“items”: items}
with open(‘filter.output’, ‘w’) as f:
f.write(json.dumps(show))
def write_map_to_file():
file_content = ‘’
for k, v in alias_map.iteritems():
file_content += k + ’ ’ + v + ‘\n’
with open(file_path, ‘w’) as f:
f.write(file_content)
if name == ‘main’:
init()
get_alias_map()
action = sys.argv[1]
with open(join(base_path, ‘logs’), ‘a’) as f:
f.write(str(sys.argv) + ‘\n’)
if (action == ‘set’):
set_alias()
if (action == ‘del’):
del_alias()
if (action == ‘show’):
show_alias()
write_map_to_file()
效果
设置一个alias
查找一个alias
删除一个alias
如果觉得通过sal设置和dal删除的方式太麻烦,也可以直接编辑~/.easy_alias/alias_conf
分享
1、算法大厂——字节跳动面试题
2、2000页互联网Java面试题大全
3、高阶必备,算法学习
HM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy8zM1AyRmRBbmp1OE9UbkRyelJSREpNMXF3SmM3aWN0bFUzZGlhcUxpYlBBRE9CZ0prdWtRa0E3NUlHSDZPa2FEVGdvVTdYeHUwS3RjclZJN3hJMUl6bEhYZy82NDA?x-oss-process=image/format,png “image.png”)
分享
1、算法大厂——字节跳动面试题
[外链图片转存中…(img-yDmVxbxr-1721146872889)]
2、2000页互联网Java面试题大全
[外链图片转存中…(img-u3S4ihJW-1721146872889)]
3、高阶必备,算法学习
[外链图片转存中…(img-okcIRRn2-1721146872889)]