Sublime Text is my favorite code editor, It's very fast and lightweight and I find it very useful for web development.
Sublime Text has a nice API to create sublime packages (plugins) and today I'm going to show you step by step how to do so.
For more information, please visit the Sublime Text API documentation.
MySignature Plugin
The Sublime Text editor comes with default auto-complete feature which contains the words in your current file.
you cannot auto-complete words from another file and if you have methods in your code (of course you have), it contains only the method names.
MySignature plugin solves this problem and add to the auto-complete pop-up box methods from all your project files with their signature:
When you choose a method from the pop-up box, It pastes the method with its signature and all you have to do is to replace the method parameters.
Step By Step AutoComplete Plugin Tutorial
Plugins in Sublime Text are written in Python.
You can view my full plugin code on MySignature gihub.
Create the plugin folder
Create your plugin folder inside the sublime plugins folder:
usually:
\Users\<username>\AppData\Roaming\Sublime Text 2\Packages - on windows
/Users/<username>/Library/Application Support/Sublime Text 2/Packages - on mac
Create a new python file inside your plugin directory.
Example:
mysign.py
Listen to Sublime Text events
This plugin needs to listen to two Sublime Text events:
- When file is saved - to load all the methods from all files into the memory.
- When auto-complete pop-up box appears - to display the relevant methods inside.
Create a new class which inherit from sublime_plugin.EventListener (see API):
class MyPlugin(MySign, sublime_plugin.EventListener): def on_post_save(self, view): def on_query_completions(self, view, prefix, locations):
When the plugin is loaded into the memory, on_post_save becomes a callback to file save event and the on_query_completions becomes a callback to auto-complete events. (when you type ctrl+space or type an exists string)
ON_POST_SAVE(self, view) Method
First, I get all the opened folders in the Sublime Text editor.
open_folder_array = view.window().folders() // view represents the sublime current view object. (see API)
The next step is to scan all the files inside and load the methods into the memory.
Note that this is a heavy task and the editor may stuck so I uses python thread to do it:
- Import python thread library: import threading
- Create a new thread class: class MySignCollectorThread(threading.Thread):
- Create constructor, send the open_folder_array as a parameter and save it as a class data member.
def __init__(self, collector, open_folder_arr, timeout_seconds): self.collector = collector self.timeout = timeout_seconds self.open_folder_arr = open_folder_arr threading.Thread.__init__(self)
- Implement the 'run' method which is called when the thread is started:
def run(self): for folder in self.open_folder_arr: jsfiles = self.get_javascript_files(folder) for file_name in jsfiles: self.save_method_signature(file_name)- Implement the recursive method get_javascript_files to get all files inside the folder:
def get_javascript_files(self, dir_name, *args): fileList = [] for file in os.listdir(dir_name): dirfile = os.path.join(dir_name, file) if os.path.isfile(dirfile): fileName, fileExtension = os.path.splitext(dirfile) if fileExtension == ".js" and ".min." not in fileName: // ignore minified files fileList.append(dirfile) elif os.path.isdir(dirfile): fileList += self.get_javascript_files(dirfile, *args) return fileList- Implement the method save_method_signature which search the javascript methods inside a specific file and store it inside an array:
def save_method_signature(self, file_name): file_lines = open(file_name, 'rU') for line in file_lines: if "function" in line: matches = re.search('(\w+)\s*[:|=]\s*function\s*\((.*)\)', line) if matches != None: // store the method somewhere ... ...- Create the thread and run it
if self._collector_thread != None: self._collector_thread.stop() self._collector_thread = MySignCollectorThread(self, open_folder_arr, 30) self._collector_thread.start()
This method is called when auto-complete pop-up box is displayed and this method returns an array with tuples:
[
('<label>', '<text-to-paste>'),
...
...
]
The '<label>' represents the label which will be displayed inside the pop-up box.
This label will be separated with tab ('\t') when the first string is the method signature and the second string is the description (method file in my plugin).
The method description will be displayed in italic font.
- Implements the on_query_completions:
def on_query_completions(self, view, prefix, locations): current_file = view.file_name() completions = [] if self.get_lang(current_file) == 'javascript': completions = // get the saved methods from the memory which contains the prefix string // remove duplicate lines completions = list(set(completions)) completions.sort() // return the array return (completions,sublime.INHIBIT_EXPLICIT_COMPLETIONS)- Implements the method get_autocomplete_list
def get_autocomplete_list(self, word): autocomplete_list = [] for method_obj in self._functions: if word in method_obj.name(): method_str_to_append = method_obj.name() + '(' + method_obj.signature()+ ')' method_file_location = method_obj.filename(); autocomplete_list.append((method_str_to_append + '\t' + method_file_location,method_str_to_append)) return autocomplete_list
Publish Sublime Text Plugin
Sublime Package Control is a repository of Sublime Text plugins.
You can activate it with Ctrl+Shift+P shortcut in the Sublime Text editor, type 'package install' and you get a list of plugins to install with just one click.
To publish your plugin to the Sublime Package Manager you must store it as a project inside Gihub.
These are the steps to publish your plugin:
- Push your plugin source code to Github as an open source project.
- Fork the 'Sublime Package Manager' project from: https://github.com/wbond/package_control_channel
- Add your plugin url from github to the repositories.json file:
{ "schema_version": "1.2", "repositories": [ ...
"https://github.com/eibbors/Bubububububad", "https://github.com/eladyarkoni/MySignaturePlugin", "https://github.com/EleazarCrusader/nexus-theme", ... "package_name_map": { ...
"modx-sublimetext-2": "MODx Revolution Snippets", "MySignaturePlugin": "Autocomplete Javascript with Method Signature", "Nette-package-for-Sublime-Text-2": "Nette", ... }Then, make a pull request with your changes.
Wait for your pull request to be approved by wbond.
That's It, You are now a Sublime Text Plugin Expert :)
Very simple, very useful and you can do whatever you want to make your perfect code editor!