Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I modify a sublime text 3 document via the in-app python console?

I want to apply some function to the text of a document. Like for example run a regexp replacement and then convert the resulting text to lowercase (or some more complicated example that cannot be easily done with the provided tools).

I know how to do this using python, so I could just run a simple script from a python interpreter to load, modify, and save the data back. This can however be quite annoying, and given the existence of a python API for sublime text there should be a way to directly run a script to modify the open document.

I would also prefer to avoid macros because those would require me to save a .sublime-macro file, but alternative solutions of this sort are equally welcome.

How can I achieve this?

like image 711
glS Avatar asked Oct 19 '25 01:10

glS


1 Answers

In the sublime console, the symbol view represents the currently focused view (file) while window represents the current window.

So you can use the plugin API method sublime.View.substr() to collect the contents of the currently selected view as a string for further manipulation:

content = view.substr(sublime.Region(0, view.size()))

Or if you wanted, you could select some text first and then grab the contents of the selection. This example grabs only the content of the first selection; modify as needed if you wanted to grab the contents of multiple selections at once.

content = view.substr(view.sel()[0])

From here you can do whatever you want to content. Your issue is in putting the contents back into the buffer when you're done.

All edit operations need to be tracked to allow Sublime the ability to undo the change. For this reason the underlying API requires all calls that would modify the buffer (inserting, appending, or replacing text, etc) to provide an edit object. However these objects are strictly controlled; only Sublime can create one on your behalf.

So the only way to modify the buffer is to either implement your own TextCommand that does it for you, or utilize an existing command via the sublime.View.run_command() method.

content = view.substr(sublime.Region(0, view.size()))
content = content.replace("Hello", "Bonjour")
content = content.replace("Goodbye", "Au Revoir")
view.run_command("select_all")
view.run_command("insert", {"characters": content})

Here I've pulled the text out of the buffer, done some replacements, and then put the entire modified string back into the buffer by first selecting everything and then inserting the new content back.

Note that if you were doing this from a TextCommand, you would need to use self.view everywhere and not just view.

like image 125
OdatNurd Avatar answered Oct 20 '25 14:10

OdatNurd