sublime插件gist源码分析(1)
缘由
最近学习sublime插件开发,准备给leanote写一个插件。
这样可以发挥sublime编辑器的优势,也可以让leanote把笔记管理起来。
学习插件开发,最快的就是看别人怎么做的。
于是找了一个类似的插件,学习下里面的源码。
可以快速了解下api的使用,也顺便巩固下python
学习源码的注意事项
- 要有目地性。
- 先从跟踪一个简单功能来,边看边查边实现,查的过程就是学习的过程。
- 看代码只看关注的功能主线,扩展功能或异常分支都暂时可以略过。
- 能调试的话,可以把中间结果打印出来,可以更加了解其中机制
- 对一点有些疑问,不用死磕,可以先记录下来,跳过,回头再来看。
- 对复杂的逻辑要多看几次,理顺关系。
准备工作
看代码之前,应该是要用这过个插件,了解它的功能和配置。
要在sublime上安装gist插件就不用说了。
再则对插件开发有一定了解,起码要写过hello world。
然后再是下载源代码:git clone https://github.com/condemil/Gist
文件概览
文件不多,可以把每个文件每简单查看下,确定每个文件都是干嘛的。
- sublime-menu 菜单配置文件
- sublime-keymap 快捷键文件
- gist.py 功能实现的主体,主要关注的
- helpers.py 辅助函数
- request.py 网络操作相关的内容
- setting.py 配置文件
先从快捷键入手,在文件Default (Windows).sublime-keymap
中{ "keys": ["ctrl+k", "ctrl+o"], "command": "gist_list" }
分析源码先找一条主线分析,这里选先看gist_list
逻辑。
主要功能:
- 列出你的gist上有哪些代码片段
- 选择之后,会在sublime中打开。
列出代码片段功能分析
先是发现 GistListCommandBase, GistListCommand这两个类。
GistListCommandBase中有run方法,插件入口,但和example中的run不一样。
先向下看,在 run 的结尾有self.get_window().show_quick_panel(gist_names, on_gist_num)
通过查sublime 插件的 api知道这就是弹选择框的操作,说明找对地方了。
on_gist_num是回调函数,就是等用户选完,会调用这个函数。
再看他是怎么生成gist_names的。
向上面找,gist_name由 filtered生成,filtered由gists_filter(api_request(settings.GISTS_URL))
拿到
然后去找api_request的代码,发现在 request.py中
经过解读,就是从配置中拿到token,然后用 gist的 api拿到数据。
(api 说明https://developer.github.com/v3/gists/)
run后面include_users与include_orgs是分支代码可以先不看。
on_gist_num这个回调中,offOrgs与offUsers都是0,所以直接走最后的分支,就是self.handle_gist(self.gists[num - offUsers])
这个handle_gist就是子类的实现
GistListCommand的实现就是open_gist
综上分析,主要流程为
- GistListCommandBase.run入口
- api_request拿到gist的列表json,进行过滤,生成gist_names
- self.get_window().show_quick_panel 显示选择框
- on_gist_num处理结果,并由子类去调用open_gist
然后自己写了一个简化版。
没有做参数验查,异常处理,只处理简单的情况
做了从gist的api拿到gist的列表,并显示在sublime上,让用户选哪个。
token为gist的 参考 https://github.com/condemil/Gist#generating-access-token
1 |
|
示显代码片段功能
现在拿到了gist相关信息,怎么何把它显示在sublime上呢
继续读open_gist代码。
因为这里只对api的调用。
没有做过多的解读
于是写了一个简化版
实现新建文件,在文件中插入内容,存在临时目录中,并保存
1 |
|
上面用到的组件总结
sublime plugin api
- sublime.status_message
- view.window().show_quick_panel
- sublime.active_window().new_file()
- view.set_name()
- view.run_command(‘append’, {‘characters’:’xx’})
- view.retarget()
- view.run_command(‘save’)
库
- json
- urllib
- contextlib
参考
https://developer.github.com/v3/gists/
https://www.sublimetext.com/docs/3/api_reference.htm