原文地址:http://code-tech.diandian.com/post/2012-11-16/40042306130php
Sublime插件的開發,能夠首先參考How to Create a Sublime Text 2 Plugin 和html
如何開發Sublime插件 還有Sublime中文手冊 ,還有個非官方的文檔,沒有翻譯完,但願有志之士發揚開源精神,繼續完成,地址https://github.com/yangweijie/sublime-text-unofficial-documentation--cnpython
雖然看了前面兩篇文章,可是對於沒有任何python基礎的人仍是有點困難,本人主攻語言php,看了2星期的python電子書。隔了幾個月又基本還回去了,推薦一個網站能夠將經常使用php函數找到對應python版,提及來還真的很像的: http://www.php2python.com PS:Ruby和python都能跨界,何時出個php的就行了O(∩_∩)O~git
廢話很少說了,先說一下開發插件流程:github
1.按照上面的文章開發出Example插件web
2.在此插件上添加本身的功能thinkphp
3.完善菜單、快捷鍵和配置文件等json
注意點:善用調試面板 ctrl+~,多讀其餘插件的源碼,他山之石能夠攻玉,藉助度娘和谷姐的力量 sublime-text
先粘上本插件的源碼api
# -*- coding: utf-8 -*- import sublime, sublime_plugin import os,httplib,urllib,urllib2,json,webbrowser,codecs def fs_reader(path): return codecs.open(path, mode='r', encoding='utf8').read() def fs_writer(path, raw): codecs.open(path, mode='w', encoding='utf8').write(raw) def out_tpl(new,sub=''): if sub == '': return tpl.replace('{%s}',new) else: return tpl2.replace('{%s}',new) def get_tpl_fullpath(filename,parent_dir=''): return packages_path + '\\manual\\' + parent_dir + filename+'.html' def write_tpl(filename,content,parent_dir=''): if not os.path.isfile(get_tpl_fullpath(filename,parent_dir)): fs_writer(get_tpl_fullpath(filename,parent_dir),content) def open_tab(url): webbrowser.open_new_tab(url) def get_content(id,parent_dir=0): conn = httplib.HTTPConnection("doc.thinkphp.cn") conn.request("GET", "/api/view/"+id) r1 = conn.getresponse() data1 = r1.read() data1 = json.loads(data1) data = data1['data'] content = '' for i in data: content= content + i['content'] if parent_dir == 0: return out_tpl(content) else: return out_tpl(content,1) settings = sublime.load_settings('Thinkphp.sublime-settings') packages_path = sublime.packages_path() + '\\Thinkphp' manual_dir = settings.get('manual_dir') tpl = fs_reader(os.path.join(packages_path + '\\'+ manual_dir +'\\public', 'book.tpl')) tpl2 = fs_reader(os.path.join(packages_path + '\\'+ manual_dir +'\\public', 'book_sub.tpl')) class ThinkphpCommand(sublime_plugin.TextCommand): def see(self,id,name,parent_dir=''): #url = 'http://doc.thinkphp.cn/manual/' + self.data[arg]['name'] content = get_content(id,parent_dir) write_tpl(name,content,parent_dir) url = 'file://'+get_tpl_fullpath(name,parent_dir) open_tab(url) def build(self,id,name,parent_dir=''): content = get_content(id,parent_dir) write_tpl(name,content,parent_dir) def run(self, edit): data = self._init() self.data = data chapter = [] tree = [] sort_data = [] k = 0 for i in data: chapter.insert(int(i['id']),i['title']) sort_data.insert(k,i['name']) state = i.get('_child', None) if state: tree.insert(k,i['_child']) else: tree.insert(k,None) k = k+1 # print chapter self.chapter = chapter self.sort_data = sort_data self.tree = tree self.view.window().show_quick_panel(chapter, self.panel_done) def panel_done(self,arg): if arg == -1: pass else: self.tree_key = arg if self.tree[arg] == None: self.see(self.data[arg]['id'],self.data[arg]['name']) else: if not os.path.isdir(packages_path + '\\'+ manual_dir +'\\'+self.sort_data[arg]): os.mkdir(packages_path + '\\'+ manual_dir +'\\'+self.sort_data[arg]) child =[] k = 0 for i in self.tree[arg]: child.insert(k,i['title']) k +=1 self.view.window().show_quick_panel(child, self.child_done) def child_done(self,arg): if arg == -1: self.view.window().show_quick_panel(self.chapter, self.panel_done) else: self.see(self.tree[self.tree_key][arg]['id'],self.tree[self.tree_key][arg]['name'],self.sort_data[self.tree_key]+'\\') def _init(self): conn = httplib.HTTPConnection("doc.thinkphp.cn") conn.request("GET", "/api") r1 = conn.getresponse() data1 = r1.read() data1 = json.loads(data1) return data1['data'] def update_manual(self): data = self._init() for j in data: if not j.get('_child', None): self.build(j['id'], j['name']) else: parent_dir = j['name'] if not os.path.isdir(packages_path + '\\'+ manual_dir +'\\'+j['name']): os.mkdir(packages_path + '\\'+ manual_dir +'\\'+j['name']) for t in j['_child']: sublime.set_timeout(self.build(t['id'],t['name'],parent_dir+'\\'),100) sublime.status_message('the manual has been generated') def search_panel(self): self.view.window().show_input_panel('search in thinkphp manual?', '', self.search_done, self.search_change, self.search_cancel) def search_done(self,arg): data = {'keywords' : arg} f = urllib2.urlopen(url = 'http://doc.thinkphp.cn/api/search',data = urllib.urlencode(data)) data = f.read() data = json.loads(data) if data['data'] == []: sublime.error_message('No Search result !') else: chapter = [] data = data['data'] self.search_list = data for i in data: chapter.insert(int(i['id']),i['title']) self.view.window().show_quick_panel(chapter, self.manual_search_done) def manual_search_done(self,arg): if arg == -1: pass else: choose = self.search_list[arg] data = self._init() for i in data: if i['id'] == choose['id']: self.see(choose['id'], choose['name']) else: state = i.get('_child', None) if state: for j in i['_child']: if j['id'] == choose['id']: if not os.path.isdir(packages_path + '\\'+ manual_dir +'\\'+i['name']): os.mkdir(packages_path + '\\'+ manual_dir +'\\'+i['name']) self.see(choose['id'], choose['name'], i['name']+'\\') def search_change(self,arg): pass def search_cancel(self): pass class update_thinkphp_manual(ThinkphpCommand,sublime_plugin.TextCommand): def run(self, edit): self.update_manual() class search_word_thinkphp_manual(ThinkphpCommand,sublime_plugin.TextCommand): def run(self, edit): region = self.view.sel()[0] if region.begin() != region.end(): self.search_done(self.view.substr(region)) else: self.search_panel() class search_thinkphp_manual(ThinkphpCommand,sublime_plugin.TextCommand): def run(self, edit): self.search_panel()
# -*- coding: utf-8 -*-
這行註釋防止代碼有中文致使的亂碼顯示
self
.view.window().show_quick_panel
這行裏的self.view.window()得到window類,以後就能夠調用window類的全部方法了,好比show_quick_panel顯示下拉列表
sublime.packages_path()
這個是獲取當前插件包的路徑,根據安裝版和綠色版返回的地址不一樣,前者win的是在用戶文檔目錄下,後者是在Sublime軟件安裝的Data\Packages裏
class
ThinkphpCommand(sublime_plugin.TextCommand):
這個纔是開始插件命令的定義,注意Thinkphp必定要和插件目錄名一致,當咱們保存插件py文件時,st會從新加載全部插件一次,這時在終端面板裏能夠經過view.runCommand('thinkphp')來運行它看效果,命令名要用小寫了
sublime.error_message()
Sublime類的方法能夠直接調用
class
update_thinkphp_manual(ThinkphpCommand,sublime_plugin.TextCommand):
def
run(
self
, edit):
self
.update_manual()
這個是前面2篇文檔沒講的,我是在gist插件的源碼裏看到的,如何在一個插件裏擴展多條命令,而且可使用當前插件的方法
settings = sublime.load_settings('Thinkphp.sublime-settings')
manual_dir = settings.get('manual_dir')
這兩句是讀取配置和獲取配置的值,固然還有本身去更新配置
region = self.view.sel()[0] if region.begin() != region.end(): self.search_done(self.view.substr(region))
這個是最簡單的獲取選區的判斷後使用的例子
接下來時菜單Main.sublime-menu:
[ { "id": "tools", "children": [ { "caption": "ThinkPHP manual", "id": "ThinkPHP manual", "command": "thinkphp" }, { "caption": "ThinkPHP manual: search", "id": "ThinkPHP manual: search", "command": "search_thinkphp_manual" }, { "caption": "ThinkPHP manual: build book", "id": "ThinkPHP manual: build book", "command": "update_thinkphp_manual" } ] }, { "caption": "Preferences", "mnemonic": "n", "id": "preferences", "children": [ { "caption": "Package Settings", "mnemonic": "P", "id": "package-settings", "children": [ { "caption": "ThinkPHP", "children": [ { "command": "open_file", "args": {"file": "${packages}/Gist/ThinkPHP.sublime-settings"}, "caption": "Settings – Default" }, { "command": "open_file", "args": {"file": "${packages}/User/ThinkPHP.sublime-settings"}, "caption": "Settings – User" }, { "command": "open_file", "args": { "file": "${packages}/ThinkPHP/Default (Windows).sublime-keymap", "platform": "Windows" }, "caption": "Key Bindings – Default" }, { "command": "open_file", "args": { "file": "${packages}/User/Default (Windows).sublime-keymap", "platform": "Windows" }, "caption": "Key Bindings – User" }, { "caption": "-" } ] } ] } ] } ]
這裏注意的是"${packages}
"表明當前插件目錄,還有就是順序,tools在preferences
前面,放到後面可能不起做用了
Thinkphp.sublime-commands
[ { "caption": "ThinkPHP manual: view list", "command": "thinkphp" }, { "caption": "ThinkPHP manual: build book", "command": "update_thinkphp_manual" }, { "caption": "ThinkPHP manual: search", "command": "search_thinkphp_manual" } ]
只有在命令文件裏寫過的命令纔會在ctrl+shift+p的命令列表中顯示
右鍵 Context.sublime-menu:
[ { "command": "search_word_thinkphp_manual", "caption": "search_thinkphp_manual here" } ]
菜單文件配了選項在菜單中會出現,可是隻有在對應命令存在可執行,方會顯示可點擊的狀態,而不是灰色
插件命名最好使用首字母大寫的駝峯法命名如Thinkphp,最好不要帶_ 空格等。
但願你們能從這篇文章中獲得一些幫助,而後投入到轟轟烈烈的Sublime插件開發隊伍中去。。