Sublime Forum

EventListener, Views, and Edit Objects

#1

So, as part of my ongoing project, I decided I wanted a little routine that would wait for the “on_pre_save” event and update a field in the header named "Last updated: ". I did fine with finding and altering the string, however I realized that the on_pre_save method doesn’t receive an edit object. It receives the current view object, but not the edit object that you normally get with a TextCommand plugin.

And then I found a paragraph in the Unofficial Documentation that states “Plugin creators must ensure that all modifying operations occur inside the .run method of new text commands.”

Am I correct in thinking that 1) I cannot directly get an edit object for the view that I’m receiving and do the editing in the event method but 2) can create a command that does this, and then inside of “on_pre_save” I issue the view.run_command(“name”)? I will try the latter, but I’m asking the question in case I’m missing out on an easier method for obtaining an edit object for the view and can just do it all in the listener method.

0 Likes

#2

Yes, this is the way to do it.

0 Likes

#3

Just ran into sort of a major problem. “on_pre_save” fires for every view. This has the somewhat problematic result that it replaces the text string in the actual source code that looks for the field name. Is there a way to restrict to only my language files? I will start searching for scope commands. Perhaps if I can extract the scope for the view I can tell whether or not to run the command.

0 Likes

#4

You can use view.settings().get("syntax") to get to the syntax file, or you could even use view.match_selector(point, "source.mylanguage") to see if the scope at a particular point in the view matches "source.mylanguage".

0 Likes

#5

Yeah, I haven’t quite figured out selectors and keys. They are mentioned in the API page, but since I haven’t found much that defined what they actually are, I haven’t messed with them.

That being said, I found that view.scope_name(0) would return the syntax scope of the first character, and the first field was “source.vhdl” so I wrote myself a utility method that just checks if the file is a VHDL language file using that.

So, now my header last updated field is saving each time I hit save with the new time. This is perfect.

I also wonder if what I’ve done might have been facilitated by selectors and keys now. Maybe I can dig around for examples that use those functions and see what comes up.

0 Likes

#6

If you want to account for multiple selections, you could try something like this in your text command:

import sublime_plugin
class TestCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        if all(self.view.match_selector(r.a, "source.vhdl") for r in self.view.sel()):
            print("OK: all selections start with the source.vhdl scope")
        else:
            print("not all selections start with the source.vhdl scope :-(")
0 Likes

#7

Well, I believe the “source” portion of the scope is the same for an entire file, correct? Or is it possible to have multiple language scopes in the same file?

I’m probably alright though because even if Sublime permits it, for a normal VHDL file, it’s all or nothing really. I don’t think the compilers have any way of coping with a partially VHDL-partially something else file.

0 Likes

#8

It is indeed possible to have multiple top level scope names in the same file, although it is used only sparingly. Usually, you would go with the base scope name of the entire file, which is then going to be at every point in the file. If it’s not, you usually know what you are doing.

0 Likes

#9

Very good. That’s what I thought and it works out alright now.

Trying to talk my coworker into being an alpha tester now :slight_smile:. I’m sure there are a few things that should be altered prior to release, but it is definitely getting harder to find them.

0 Likes