Sublime Forum

Writting an Identation plugin for ST3 for Python

#1

Having had a look at this topic how would I go about writing an identer for python, which seems terrible in ST3. (I know that looks like a critism, I understand the devs had a lot to do and writing a great indenter was prob the last thing on the list of things to do…)

The identer works really well for C++ and C but I do realise that python not having curly brackets makes the problem a lot harder, but I feel my regex and python might be just enough to give it a go. (ha ha)

Could someone point me in the direction of some approprate resources i.e. what ST3 api’s I’m going need to access (I know all about keybindings, the basic implementation of python plugins) , some other general ideas pls…

Or is it just a case of passing in a selection of text ( or all of it ) to the plugin and then working some python magic (the hard part) and just spitting it back out reformatted?

Looking at @OdatNurd 's great code here (I think, apols if I’ve wrongly attributed this) :-


import sublime
import sublime_plugin


class FindReplaceCommand(sublime_plugin.TextCommand):
    """The implementation of 'find_replace' text command.

    Example: import

        view.run_command(
            "find_replace", {
                "pattern": "the",
                "replace_by": "THE",
                "start_pt": 100,
                "flags": ["LITERAL"]
            }
        ) import
    """

    FLAGS = {
        "LITERAL": sublime.LITERAL,
        "IGNORECASE": sublime.IGNORECASE
    }

    def run(self, edit, pattern, replace_by, flags=[]):
        """Find and replace all patterns.

        Arguments:
            edit (sublime.Edit):
                The edit token used to undo this command.
            pattern (string):
                The regex pattern to use for finding.
            replace_by (string):
                The text to replace all found words by.
            flags (list):
                The flags to pass to view.find()
                ["LITERAL", "IGNORECASE"]
        """
        found = self.view.find_all(pattern, self._flags(flags))
        if not found:
            return
        for idx, region in enumerate(found):
            if idx == 0:
                self.view.replace(edit, region, replace_by)
            else:
                difference = len(replace_by) - len(pattern)
                if difference != 0:
                    modified_region = sublime.Region(region.begin() + (idx * difference), 
                                                        region.end() + (idx * difference))
                    self.view.replace(edit, modified_region, replace_by)
                else:
                    self.view.replace(edit, region, replace_by)

    def _flags(self, flags):
        """Translate list of flags."""
        result = 0
        for flag in flags:
            result |= self.FLAGS.get(flag, 0)
        return result

this essentially gives me the framework (Very approximately) it’s just a case of modding that (I know not simple) and applying to a keybinding ?

Or am I ‘barking up the wrong tree’ entirely ?. Or does one exist already ?

Thanks, any thoughts appreciated.

0 Likes

#2

There are quite likely plugins that are already available that do this (the Python servers to LSP for example might, or some sort of format-on-save plugin).

That said, generally what you want if you’re going to take a crack at it yourself (which I do frequently) is grab text out of the buffer, edit it, then put it back. You can do that in a TextCommand so that you can reformat on a keypress, or you can create an event listener that listens for on_pre_save and modify the buffer before a save happens.

In addition to the above, the following video is the result of someone asking a similar question, which you may find useful as well as it goes over exactly how this process works (though much like this answer, it entirely glosses over the interesting part, which is the complications of examining the code to determine how you want to modify it in the first place).

1 Like

#3

For ST 3, I recommend https://packagecontrol.io/packages/sublack

3 Likes

#4

@jfcherng I can’t accept two solutions, however thank you both

0 Likes