Sublime Forum

Saving a file before and after running my task

#1

Hey everyone.

Here’s what I want to achieve:

  • Have an app let’s call this /bin/wr, that does some operations. I want the output of this to replace the contents of the currently open file.
  • Before calling /bin/wr, I want the file to saved, and afterwards once I replace the contents, saved again.

Unfortunately I couldn’t get the saving part working with the run_command, exec, etc. tried both async and sync. The file is always left dirty and never saved before calling the process.

Here’s a simplified version of my code. Ignore syntax/indentation errors if there are any, I’m not used to this forum input.

import sublime
import sublime_plugin
import subprocess

class RunBinaryCommand(sublime_plugin.TextCommand):

def run(self, edit, name):
    p = subprocess.Popen("/bin/wr " + name, stdout=subprocess.PIPE, bufsize=1, text=True)
    out, err = p.communicate()
    self.view.replace(edit, sublime.Region(0, self.view.size()), out)
    sublime.set_timeout(lambda: sublime.run_command('save', {"async": false}))

I’ve simplified the code a bit, the plugin is working as intended without the saving part. The real version is slightly more meaningful with more parameters passed in, in this simplified example there’s no need to do any of this, so just assume I have a meaningful reason behind all this please :slight_smile:

Also, do I need to use something else other than a text command plugin?

0 Likes

#2

Sounds like you could simply write a WR.sublime-build file, which could directly run against the file itself. ST saves content before build is performed and would reload the content as content changes on disk.

2 Likes

#3

the way use this, the “name” parameter often takes different values(the wr binary is a monolith that can do different kinds of calculations/operations), so a single build doesn’t seem like the ideal case for me, i’d rather make sure the file is saved before and after. Thanks for the suggestion, it’s a solution i’ll use if I can’t solve this the way I’d like, thanks a lot. :slight_smile:
I have some keybindings like the following for the operations I support. is there a way to bind different builds like so, perhaps without creating lots of files(although i’m fine with creating lots of files too, since I can .gitignore them)?
{
“keys”: [“ctrl+key”],
“command”: “cmd”,
“args”: { “name”: “value” }
},

0 Likes

#4

I should mention I’m also binding this to emacs as well, and both editors are fast enough it doesn’t do anything I can see(no flickering or any operation >10ms even though I’m rewriting entire files at once) so while I could create a bunch of small .py files to do all this, I’d like to keep the binary around if possible to keep it usable across editors with a simple wrapper.

0 Likes

#5

Yes; sublime-build files allow you to specify a named variant of the build that allow you to do things like override the command while inheriting everything else; you can also do the same in build systems stored in sublime-project files.

In addition, the build command can be told to execute a specific build or a specific variant of a build as well (see video below for a demonstration of all of these things).

1 Like

#6

thanks a lot, that solves everything. that said, is there really no way to reliably save a file within a plugin on sublime?

0 Likes

#7

view.run_command('save') from within a command should in fact trigger the save of the file, yes. A common pitfall here is to save the file and then immediately modify the content from within the same command (or a command called from it).

Although the save will happen in such a case, Sublime doesn’t mark the buffer as clean until after the whole chain of commands finishes, and it does so by checking the modification count of the buffer from prior to all of the command executing to after they’re done.

So, in a case where the command saves and also modifies the file, by the time the commands are finished the modification count is different and the file looks dirty still despite the fact that the version on disk is in fact saved.

All that said, if trim_trailing_white_space_on_save is turned on, the save will save the file and trim the whitespace, but then mark the file as dirty (presumably for the same reasoning as above) despite the fact that this does not happen if you just invoke the save command directly.

My guess would be that the core has special logic in it to know how to handle this situation when save is invoked directly that doesn’t trigger if another command is what executes save.

0 Likes