-
-
Save kkiernan/bc562611cbc8bb3c9b62 to your computer and use it in GitHub Desktop.
import sublime, sublime_plugin, re | |
class CreateCommand(sublime_plugin.TextCommand): | |
# Runs the plugin | |
def run(self, edit, stub, offset): | |
self.view.insert(edit, offset, stub) |
import sublime, sublime_plugin | |
class ImplementCommand(sublime_plugin.TextCommand): | |
# Gets the currently selected symbol | |
# | |
def get_selected_symbol(self): | |
point = self.view.sel()[0] | |
region = self.view.word(point) | |
return self.view.substr(region) | |
# Gets files with names that match the currently selected symbol | |
# | |
def get_matching_files(self): | |
window = self.view.window() | |
selected_symbol = self.get_selected_symbol() | |
locations = window.lookup_symbol_in_index(selected_symbol) | |
files = [] | |
for location in locations: | |
files.append(location[0]) | |
return files | |
# Handles the selection of a quick panel item | |
# | |
def on_done(self, index): | |
if index == -1: | |
return | |
self.view.run_command("parse", {"path": self.files[index]}) | |
# Runs the plugin | |
# | |
def run(self, edit): | |
self.files = self.get_matching_files() | |
if (len(self.files) == 1): | |
self.view.run_command("parse", {"path": self.files[0]}) | |
if (len(self.files) > 1): | |
self.view.window().show_quick_panel(self.files, self.on_done) |
import sublime, sublime_plugin, re | |
class ParseCommand(sublime_plugin.TextCommand): | |
# Normalizes a given path to the current system style | |
# -- This method is from the PHP Companion utils file | |
# | |
def normalize_to_system_style_path(self, path): | |
if sublime.platform() == "windows": | |
path = re.sub(r"/([A-Za-z])/(.+)", r"\1:/\2", path) | |
path = re.sub(r"/", r"\\", path) | |
return path | |
# Runs the plugin | |
# | |
def run(self, edit, path): | |
# Get the contents of the file at the given path | |
with open(self.normalize_to_system_style_path(path), "r") as f: | |
content = f.read() | |
# Get the methods from the content | |
self.methods = re.findall("(?<!\* )(?:abstract )?(?:public|protected|private)(?: static)? function [A-z0-9]*\([A-z0-9$=, ]*\)[A-z :]*", content) | |
self.methods.insert(0, 'Insert all methods') | |
# Show the available methods in the quick panel | |
if (len(self.methods) > 0): | |
self.view.window().show_quick_panel(self.methods, self.on_done) | |
# Handles selection of a quick panel item | |
# | |
def on_done(self, index): | |
if index == -1: | |
return | |
# Find the closing brackets. We'll place the method | |
# stubs just before the last closing bracket. | |
closing_brackets = self.view.find_all("[}]") | |
# Add the method stub(s) to the current file | |
region = closing_brackets[-1] | |
point = region.end() - 1 | |
template = "\n\t{0}\n\t{{\n\t\tthrow new \Exception('Method not implemented');\n\t}}\n" | |
# Better way to handle add all selection? | |
if index == 0: | |
for method in self.methods[1:]: | |
method_stub = template.format(method) | |
self.view.run_command("create", {"stub": method_stub, "offset": point}) | |
else: | |
method_stub = template.format(self.methods[index]) | |
self.view.run_command("create", {"stub": method_stub, "offset": point}) |
Looks awesome! I like being able to select the methods. That works better for abstract classes anyway, which I forgot about at first. I'll play around with a better regex too.
Also, this one doesn't do anything if more than one file is found. I'll tinker around on your fork and share it then.
Here is a long winded regex that does a bit better: https://regex101.com/r/yD6nY7/7.
Edit (newer version with unit tests): https://regex101.com/r/yD6nY7/12
Take a look at the updated gist when you have some time. It now supports multiple files, like if you are working with a lot of packages that have some overlapping names.
I also tweaked the regex and it seems to be working pretty nicely. It accommodates a mix of abstract, static, and other methods with various visibility. I also tested it with type hinting and return type declarations since I think that has been approved for PHP7.
Updated: Also just added an "Insert all methods" option as well. For interfaces, this would be useful if you have an empty class that you are just starting to work on.
What keybinding do you use ?
I am using f1 at the moment. It runs implement.py to kick everything off.
{ "keys": ["f1"], "command": "implement" }
This seems like a really useful script, could you turn it into a plugin and upload it to package control? It would be much easier to install then and easier for people to find.
Glad you think it looks useful, thanks for the feedback! I was hoping we could add this to PHP Companion (erichard's awesome plugin) instead of making a standalone plugin.
Right now I use it by downloading a zip of this gist and dropping it into my packages folder. I'm on Windows so the directory is C:\Users\USERNAME\AppData\Roaming\Sublime Text 3\Packages. Not sure what it is on OS X or Linux. Then you need to add a keybinding like the one I mentioned in the comment above to run the command.
Checkout my fork. Instead of inserting all methods I let the user choose the method he wants. Also I think the
findall
method on line 40 a bit too simple.It doesn't match theses methods :
public static function myStaticMethod()
protected function myProtectedMethod()
But will match function statement in comments :
Not sure we can do all with regexes but I will try...