[@Deprecated]让Alfred支持拼音搜索

感谢@小心大熊猫@007752277662友情提醒,目前Alfred是支持拼音搜索的,操作手法如下:

按空格,出现符号';然后输入需要拼音搜索的程序或者文件即可。

此文已经没有任何意义,@Deprecated。

Alfred是个好东西,不过检索程序的时候不支持拼音搜索;我在论坛看到有人给作者反馈过,无奈作者说支持中文,他不知道拼音是什么,于是就不了了之了。举个例子:我想打开网易云音乐,可是当我输入wangyiyunyinyue的时候却是这样的结果:

要么我知道这个App的名字叫做NeteaseMusic,要么我就需要用中文输入网易云音乐打开了;如果恰巧输入法是英文输入状态,那么就会遇到上图的情况;这时候再把已经输入的删除然后切换输入法打开,效率无疑大大折扣。

就算这里搜索这个App可以使用英文名字解决,可是对于某些系统程序比如邮件可能还知道是Mail,那么备忘录呢?便签呢?还有一些别的中文程序没有英文名的比如马克飞象?如果Alfred能支持拼音搜索,这些问题全部都没了!而且,Alfred可以强制使用英文输入,直接使用字母检索,不用切换输入法了。

原理

经过简单的观察之后,发现Alfred检索程序不仅仅是检索名字,还收集了一些额外的信息;在Alfred作者的帮助下,知道它利用了Mac文件系统的一个拓展信息的字段;如果你发现某些目录后面有@那么就是有拓展信息了:

drwxr-xr-x+  3 root    wheel  102  9 10  2014 Stickies.app/
drwxr-xr-x@  3 weishu  admin  102  3 26  2015 Sublime Text.app/

可以借助命令行工具xattr进行操作;具体使用可以man xattr.

所以,我们可以通过把拼音信息添加到文件的拓展信息里面去,这样Alfred就能借助这些信息帮助拼音检索了。

实现

获取程序名

程序名不仅仅是一个文件名这么简单,Mac软件有一个叫做localization的概念,大致就是国际化吧;程序结构把国际化的字段存放在不同的文件里面,在程序本地化之后自动load.

我们要使用的那个字段是CFBundleName;存放在/<App>/Contents/Resources/<language>/InfoPlist.strings这个文件里面;我们把这个名字读取出来即可。

尝试过使用objc的接口NSBundle.localizedInfoDiction来获取本地化的字段,无奈拿到的永远是英文字段;只好手工解析中文字段了(不会Objc );使用的命令行工具plutil:

def _get_localized_name(abs_path):
    '''get the localized name of given app'''
    bundle = NSBundle.new()
    bundle.initWithPath_(abs_path)
    localizations = bundle.localizations()
    chinese = ('zh_CN', 'zh_Hans')

    b = any(map(lambda x: x in localizations, chinese))
    if not b: return 

    for ch in chinese:
        path = bundle.pathForResource_ofType_inDirectory_forLanguage_('InfoPlist', 'strings', None, ch)
        if not path: continue
        # the path must surround with "", there may be space characters
        json_str = subprocess.check_output(u'plutil -convert json -o - "%s"' % path, shell=True)
        # print json_str
        json_res = json.loads(json_str, encoding='utf8')
        name = json_res.get('CFBundleName')
        if name: return name

转换为拼音

可以直接使用python的拼音转换库[pypinyin][1],借助这个工具,一行代码搞定:

def _get_app_pinyin_name(app_name):
    reduce(lambda x, y: x + y, lazy_pinyin(app_name, errors='ignore'))

添加拼音信息

拼音信息被添加到文件的拓展信息里面,直接使用xattr添加即可:

def _add_meta_data(app_pinyin_name, app_path):
    ''' add meta data(comments) to the app, which can help Alfred or SpotLight find it'''
    subprocess.check_call('xattr -w com.apple.metadata:kMDItemFinderComment %s %s' % (app_pinyin_name, app_path), shell=True)

好了,把这些代码整合起来,就能得到最终的结果了,完整的代码在[这里][2]。

def main():
    pattern = re.compile(r'^[\\w\\s.]+$')

    workspace = NSWorkspace.sharedWorkspace()

    for app_dir in APP_DIRECTORYS:
        if not os.path.exists(app_dir): continue

        for root, dirs, files in os.walk(app_dir, topdown=True):
            remove_list = []
            for directory in dirs:
                # print type(directory), root, directory
                full_path = os.path.join(root, directory)
                if not _is_application(workspace, full_path): continue

                remove_list.append(directory)
                
                localized_name =  _get_localized_name(full_path)
                app_name = localized_name if localized_name else directory.rsplit(r'.')[0]

                if pattern.match(app_name): 
                    continue
                
                _add_meta_data(_get_app_pinyin_name(app_name), full_path)

            # if this directory is already a Application
            # do not traverse this; some app may be very large 
            # and there won't be any other app inside it
            dirs[:] = [d for d in dirs if d not in remove_list]

最后,我们执行这一段脚本即可sudo python main.py。之所以需要sudo是因为某些系统程序(比如家计算器),直接使用是没有权限的。

完整代码见原文:http://www.tianweishu.com/2015/12/07/make-alfred-support-pinyinyin-search

最后看效果:


[1]: https://github.com/mozillazg/python-pinyin
[2]: https://gist.github.com/tiann/35fb758c18036d7f8640

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容