sublime text 3插件改造之添加从模版新增文件到指定目录
Posted 随记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sublime text 3插件改造之添加从模版新增文件到指定目录相关的知识,希望对你有一定的参考价值。
简介:以前使用ST2里面的Sublime NFFT插件比较顺手,最近安装了ST3,但是Sublime NFFT插件不支持ST3,就下载了SublimeTmpl从模版新建文件插件。在使用时,习惯在侧边栏右击目录-新建模版文件,然后保存在右击的目录下。但是SublimeTmpl插件不支持这功能,非常蛋疼。花了一点时间研究Sublime NFFT插件源码,对SublimeTmpl进行了改造,详情如下:
SublimeTmpl插件安装之后,首选项>浏览程序包>SublimeTmpl>sublime-tmpl.py,该文件修改如下(左侧是原来代码,右侧红色部分是修改之处):
修改之后完整代码:
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # + Python 3 support 4 # + sublime text 3 support 5 6 import sublime 7 import sublime_plugin 8 # import sys 9 import os 10 import glob 11 import datetime 12 import zipfile 13 import re 14 15 PACKAGE_NAME = \'SublimeTmpl\' 16 TMLP_DIR = \'templates\' 17 KEY_SYNTAX = \'syntax\' 18 KEY_FILE_EXT = \'extension\' 19 20 # st3: Installed Packages/xx.sublime-package 21 BASE_PATH = os.path.abspath(os.path.dirname(__file__)) 22 PACKAGES_PATH = sublime.packages_path() # for ST2 23 24 # sys.path += [BASE_PATH] 25 # sys.path.append(BASE_PATH) 26 # import sys;print(sys.path) 27 28 IS_GTE_ST3 = int(sublime.version()[0]) >= 3 29 DISABLE_KEYMAP = None 30 31 class SublimeTmplCommand(sublime_plugin.TextCommand): 32 33 def run(self, edit, type=\'html\', dirs=[]): 34 view = self.view 35 opts = self.get_settings(type) 36 tmpl = self.get_code(type) 37 38 # print(\'global\', DISABLE_KEYMAP, IS_GTE_ST3); 39 if DISABLE_KEYMAP: 40 return False 41 42 # print(KEY_SYNTAX in opts) 43 self.tab = self.creat_tab(view) 44 45 self.set_syntax(opts) 46 self.set_code(tmpl, type, dirs) 47 48 def get_settings(self, type=None): 49 settings = sublime.load_settings(PACKAGE_NAME + \'.sublime-settings\') 50 51 if not type: 52 return settings 53 54 # print(settings.get(\'html\')[\'syntax\']) 55 opts = settings.get(type, []) 56 # print(opts) 57 return opts 58 59 def open_file(self, path, mode=\'r\'): 60 fp = open(path, mode) 61 code = fp.read() 62 fp.close() 63 return code 64 65 def get_code(self, type): 66 code = \'\' 67 file_name = "%s.tmpl" % type 68 isIOError = False 69 70 if IS_GTE_ST3: 71 tmpl_dir = \'Packages/\' + PACKAGE_NAME + \'/\' + TMLP_DIR + \'/\' 72 user_tmpl_dir = \'Packages/User/\' + \\ 73 PACKAGE_NAME + \'/\' + TMLP_DIR + \'/\' 74 # tmpl_dir = os.path.join(\'Packages\', PACKAGE_NAME , TMLP_DIR) 75 else: 76 tmpl_dir = os.path.join(PACKAGES_PATH, PACKAGE_NAME, TMLP_DIR) 77 user_tmpl_dir = os.path.join( 78 PACKAGES_PATH, \'User\', PACKAGE_NAME, TMLP_DIR) 79 80 self.user_tmpl_path = os.path.join(user_tmpl_dir, file_name) 81 self.tmpl_path = os.path.join(tmpl_dir, file_name) 82 83 if IS_GTE_ST3: 84 try: 85 code = sublime.load_resource(self.user_tmpl_path) 86 except IOError: 87 try: 88 code = sublime.load_resource(self.tmpl_path) 89 except IOError: 90 isIOError = True 91 else: 92 if os.path.isfile(self.user_tmpl_path): 93 code = self.open_file(self.user_tmpl_path) 94 elif os.path.isfile(self.tmpl_path): 95 code = self.open_file(self.tmpl_path) 96 else: 97 isIOError = True 98 99 # print(self.tmpl_path) 100 if isIOError: 101 sublime.message_dialog(\'[Warning] No such file: \' + self.tmpl_path 102 + \' or \' + self.user_tmpl_path) 103 104 return self.format_tag(code) 105 106 def format_tag(self, code): 107 code = code.replace(\'\\r\', \'\') # replace \\r\\n -> \\n 108 # format 109 settings = self.get_settings() 110 format = settings.get(\'date_format\', \'%Y-%m-%d\') 111 date = datetime.datetime.now().strftime(format) 112 if not IS_GTE_ST3: 113 code = code.decode(\'utf8\') # for st2 && Chinese characters 114 code = code.replace(\'${date}\', date) 115 116 attr = settings.get(\'attr\', {}) 117 for key in attr: 118 code = code.replace(\'${%s}\' % key, attr.get(key, \'\')) 119 return code 120 121 def creat_tab(self, view): 122 win = view.window() 123 tab = win.new_file() 124 return tab 125 126 def set_code(self, code, type, dirs): 127 tab = self.tab 128 tab.set_name(\'untitled.\' + type) 129 # insert codes 130 tab.run_command(\'insert_snippet\', {\'contents\': code}) 131 if len(dirs) == 1: 132 tab.settings().set(\'default_dir\', dirs[0]) 133 134 def set_syntax(self, opts): 135 v = self.tab 136 # syntax = self.view.settings().get(\'syntax\') # from current file 137 syntax = opts[KEY_SYNTAX] if KEY_SYNTAX in opts else \'\' 138 # print(syntax) # tab.set_syntax_file(\'Packages/Diff/Diff.tmLanguage\') 139 v.set_syntax_file(syntax) 140 141 # print(opts[KEY_FILE_EXT]) 142 if KEY_FILE_EXT in opts: 143 v.settings().set(\'default_extension\', opts[KEY_FILE_EXT]) 144 145 class SublimeTmplEventListener(sublime_plugin.EventListener): 146 def on_query_context(self, view, key, operator, operand, match_all): 147 settings = sublime.load_settings(PACKAGE_NAME + \'.sublime-settings\') 148 disable_keymap_actions = settings.get(\'disable_keymap_actions\', \'\') 149 # print ("key1: %s, %s" % (key, disable_keymap_actions)) 150 global DISABLE_KEYMAP 151 DISABLE_KEYMAP = False; 152 if not key.startswith(\'sublime_tmpl.\'): 153 return None 154 if not disable_keymap_actions: # no disabled actions 155 return True 156 elif disable_keymap_actions == \'all\' or disable_keymap_actions == True: # disable all actions 157 DISABLE_KEYMAP = True; 158 return False 159 prefix, name = key.split(\'.\') 160 ret = name not in re.split(r\'\\s*,\\s*\', disable_keymap_actions.strip()) 161 # print(name, ret) 162 DISABLE_KEYMAP = True if not ret else False; 163 return ret 164 165 def plugin_loaded(): # for ST3 >= 3016 166 # global PACKAGES_PATH 167 PACKAGES_PATH = sublime.packages_path() 168 TARGET_PATH = os.path.join(PACKAGES_PATH, PACKAGE_NAME) 169 # print(BASE_PATH, os.path.dirname(BASE_PATH)) 170 # print(TARGET_PATH) 171 172 # auto create custom_path 173 custom_path = os.path.join(PACKAGES_PATH, \'User\', PACKAGE_NAME, TMLP_DIR) 174 # print(custom_path, os.path.isdir(custom_path)) 175 if not os.path.isdir(custom_path): 176 os.makedirs(custom_path) 177 178 # first run 179 if not os.path.isdir(TARGET_PATH): 180 os.makedirs(os.path.join(TARGET_PATH, TMLP_DIR)) 181 # copy user files 182 tmpl_dir = TMLP_DIR + \'/\' 183 file_list = [ 184 \'Default.sublime-commands\', \'Main.sublime-menu\', 185 # if don\'t copy .py, ST3 throw: ImportError: No module named 186 \'sublime-tmpl.py\', 187 \'README.md\', 188 tmpl_dir + \'css.tmpl\', tmpl_dir + \'html.tmpl\', 189 tmpl_dir + \'js.tmpl\', tmpl_dir + \'php.tmpl\', 190 tmpl_dir + \'python.tmpl\', tmpl_dir + \'ruby.tmpl\', 191 tmpl_dir + \'xml.tmpl\' 192 ] 193 try: 194 extract_zip_resource(BASE_PATH, file_list, TARGET_PATH) 195 except Exception as e: 196 print(e) 197 198 # old: *.user.tmpl compatible fix 199 files = glob.iglob(os.path.join(os.path.join(TARGET_PATH, TMLP_DIR), \'*.user.tmpl\')) 200 for file in files: 201 filename = os.path.basename(file).replace(\'.user.tmpl\', \'.tmpl\') 202 # print(file, \'=>\', os.path.join(custom_path, filename)); 203 os.rename(file, os.path.join(custom_path, filename)) 204 205 # old: settings-custom_path compatible fix 206 settings = sublime.load_settings(PACKAGE_NAME + \'.sublime-settings\') 207 old_custom_path = settings.get(\'custom_path\', \'\') 208 if old_custom_path and os.path.isdir(old_custom_path): 209 # print(old_custom_path) 210 files = glob.iglob(os.path.join(old_custom_path, \'*.tmpl\')) 211 for file in files: 212 filename = os.path.basename(file).replace(\'.user.tmpl\', \'.tmpl\') 213 # print(file, \'=>\', os.path.join(custom_path, filename)) 214 os.rename(file, os.path.join(custom_path, filename)) 215 216 if not IS_GTE_ST3: 217 sublime.set_timeout(plugin_loaded, 0) 218 219 def extract_zip_resource(path_to_zip, file_list, extract_dir=None): 220 if extract_dir is None: 221 return 222 # print(extract_dir) 223 if os.path.exists(path_to_zip): 224 z = zipfile.ZipFile(path_to_zip, \'r\') 225 for f in z.namelist(): 226 # if f.endswith(\'.tmpl\'): 227 if f in file_list: 228 # print(f) 229 z.extract(f, extract_dir) 230 z.close()
增加侧边栏右键新增模版文件功能:
- 首选项>浏览程序包,在打开的目录新建跟插件名称一样的目录,这里是新建"SideBarEnhancements"。
- 选择当前目录上一级(Sublime Text 3)>Installed Packages找到"SideBarEnhancements.sublime-package",复制一份该文件到任意目录,修改文件后缀为.zip,用软件解压。
- 找到解压目录中以".sublime-menu"为结尾的文件,这里是"Side Bar.sublime-menu",复制一份到第一步新建的目录SideBarEnhancements中。
- 修改复制的"Side Bar.sublime-menu"文件,添加如下内容:
1 { 2 "caption": "New File (SublimeTmpl)", 3 "id": "side-bar-new-file-SublimeTmpl", 4 "children": [ 5 { 6 "caption": "HTML", 7 "command": "sublime_tmpl", 8 "args": { 9 "type": "html", 10 "dirs": [] 11 } 12 }, 13 { 14 "caption": "javascript", 15 "command": "sublime_tmpl", 16 "args": { 17 "type": "js", 18 "dirs": [] 19 } 20 }, 21 { 22 "caption": "CSS", 23 "command": "sublime_tmpl", 24 "args": { 25 "type": "css", 26 "dirs": [] 27 } 28 }, 29 { 30 "caption": "PHP", 31 "command": "sublime_tmpl", 32 "args": { 33 "type": "php", 34 "dirs": [] 35 } 36 }, 37 { 38 "caption": "python", 39 "command": "sublime_tmpl", 40 "args": { 41 "type": "py", 42 "dirs": [] 43 } 44 }, 45 { 46 "caption": "ruby", 47 "command": "sublime_tmpl", 48 "args": { 49 "type": "rb", 50 "dirs": [] 51 } 52 }, 53 {"caption": "-"}, 54 { 55 "command": "open_file", 56 "args": {"file": "${packages}/SublimeTmpl/Main.sublime-menu"}, 57 "caption": "Menu" 58 } 59 ] 60 },
修改之后完成代码:
[ { "caption": "aaaaa_side_bar", "id": "aaaaa_side_bar", "command": "aaaaa_side_bar", "args": { "paths": [] } }, { "caption": "-", "id": "side-bar-start-separator" }, { "caption": "New File…", "id": "side-bar-new-file", "command": "side_bar_new_file", "args": { "paths": [] } }, { "caption": "New Folder…", "id": "side-bar-new-directory", "command": "side_bar_new_directory", "args": { "paths": [] } }, { "caption": "-", "id": "side-bar-start-separator" }, { "caption": "New File (SublimeTmpl)", "id": "side-bar-new-file-SublimeTmpl", "children": [ { "caption": "HTML", "command": "sublime_tmpl", "args": { "type": "html", "dirs": [] } }, { "caption": "Javascript", "command": "sublime_tmpl", "args": { "type": "js", "dirs": [] } }, { "caption": "CSS", "command": "sublime_tmpl", "args": { "type": "css", "dirs": [] } }, { "caption": "PHP", "command": "sublime_tmpl", "args": { "type": "php", "dirs": [] } }, { "caption": "python", "command": "sublime_tmpl", "args": { "type": "py", "dirs": [] } }, { "caption": "ruby", "command": "sublime_tmpl", "args": { "type": "rb", "dirs": [] } }, {"caption": "-"}, { "command": "open_file", "args": {"file": "${packages}/SublimeTmpl/Main.sublime-menu"}, "caption": "Menu" } ] }, { "caption": "-", "id": "side-bar-new-separator" }, { "caption": "Edit", "id": "side-bar-edit", "command": "side_bar_edit", "args": { "paths": [] } }, { "caption": "Edit to Right", "id": "side-bar-edit-to-right", "command": "side_bar_edit_to_right", "args": { "paths": [] } }, { "caption": "Open / Run", "id": "side-bar-open", "command": "side_bar_open", "args": { "paths": [] } }, { "caption": "Open In Browser", "id": "side-bar-open-in-browser", "children": [ { "caption": "Default", "command": "side_bar_open_in_browser", "args": { "paths": [] } }, { "caption": "-" }, { "caption": "Firefox", "command": "side_bar_open_in_browser", "args": { "paths": [], "type": "testing", "browser": "firefox" } }, { "caption": "-" }, { "caption": "Chromium", "command": "side_bar_open_in_browser", "args": { "paths": [], "type": "testing", "browser": "chromium" } }, { "caption": "Chrome", "command": "side_bar_open_in_browser", "args": { "paths": [], "type": "testing", "browser": "chrome" } }, { "caption": "Canary", "command": "side_bar_open_in_browser", "args": { "paths": [], "type": "testing", "browser": "canary" } }, { "caption": "-" }, { "caption": "Opera", "command": "side_bar_open_in_browser", "args": { "paths": [], "type": "testing", "browser": "opera" } }, { "caption": "Safari", "command": "side_bar_open_in_browser", "args": { "paths": [], "type": "testing", "browser": "safari" } }, { "caption": "-" }, { "caption": "Internet Explorer", "command": "side_bar_open_in_browser", "args": { "paths": [], "type": "testing", "browser": "ie" } }, { "caption": "Edge", "command": "side_bar_open_in_br以上是关于sublime text 3插件改造之添加从模版新增文件到指定目录的主要内容,如果未能解决你的问题,请参考以下文章
Sublime Text插件之SublimeHighlight
Sublime Text 编辑器 插件 之 "Sublime Alignment" 详解