Sublime Forum

Checking success of run_command("save") after using retarget(path)

#1

In a plugin I’m working on I’m using the (undocumented) View class retarget() method to set a buffer’s path and then using run_command() to save the buffer, like this:

new_buffer = self.active_window.new_file()
new_buffer.retarget(path)
new_buffer.run_command("save")

Since the user may not have permission to write path I’d like to be able to check if run_command("save") succeeded or not. Unfortunately run_command() does not return a value, is there some other way that I can see if run_command("save") succeeded from within the plugin?

ST does show a dialog box saying the save failed but my plugin needs to determine whether to proceed or not.

ST also logs the failed save in the console “error: unable to save [path]” along with the specific error message, e.g. “Error: Permission denied”. Perhaps this can be examined somehow?

Thanks.

0 Likes

Re-open file without close the window
#2

I don’t know if you can get at the contents of the console from within a plugin, although I would guess that it’s feasible if you could also get at the contents of other panels (I’ve never tried that either, though). It seems like attempting to parse the output of the console would be rather brittle, however.

A more robust solution may be to use os.path.isfile before and after the save so that you can see if the file appears after you’ve tried to save it. In the case where the file exists beforehand, you would also have to use something like os.stat to capture the last modification time and then do the same again afterwards so that you could verify that the file was actually touched by the save.

1 Like

#3

how about using the is_dirty method of the view? unless there is no such thing and I just made it up… I’m on mobile atm and cba to check :wink:

2 Likes

#4

Yeah, or that method, which is much shorter and cleaner and definitely exists on the view method (although I would do some tests to ensure it still works the way you expect if you’re using an undocumented method, because I am extremely paranoid regarding undocumented stuff).

In fact I’m so paranoid that I even checked to determine if that method returns the correct value on a save error due to invalid permissions (it does, naturally) and discovered that it uses pkexec to try and perform the save so that it is theoretically possible to edit another user’s files (at least on Linux), which I was previously unaware of, so that’s neat.

1 Like

#5

I thought of using is_dirty() before posting and tried it, unfortunately it only reports on whether a file has unsaved modifications in it. I need a solution that will work with both a newly created empty buffer (so no unsaved modifications) and as a save-as for an existing buffer, so is_dirty() is a no go.

The isfile() and stat() approach looks promising - I’ll give it a try tomorrow.

I did run some tests with retarget(path) and it seemed fine, as did close() another undocumented View class method which my code uses to close a buffer it created. Updating documentation seems to be a low priority for JPS, so I had taken the view that the undocumented methods in the API were only so because he hadn’t got around to documenting them yet, or had forgotten to, and not because they’re unsafe. Am I being foolhardy? Why would JPS add an unsafe method to sublime.py when he could simply leave it alone? Have there been cases of undocumented methods in the API causing problems?

Thanks.

0 Likes

#6

No, I wouldn’t think so. Probably a lot of that for me is projecting what I might have done in a similar case onto someone else, i.e. “I wrote this thing but I’m not going to say yet exactly what it does because there are some edge cases I haven’t ironed out yet”. As a result I tend to be a little paranoid about that sort of thing initially,.

I think in the Sublime ecosystem it’s more like, as you mentioned, documentation being not as high a priority. I know I’m certainly guilty of that as well. My take on the situation is that since the official API page tells you to go look at bundled plugins for examples it’s sort of a “blessing” that you should peruse the available code to glean what you can from it.

There’s a fair amount of stuff that you can do that’s not documented anywhere and you’d only know if you looked at that code, but it’s there and doing stuff so it’s probably safe (for example, default_dir and default_extension being settings you can set on a view to control how the file saves by default, unless that’s actually documented and I just haven’t noticed it).

I don’t personally recall seeing or hearing anything about undocumented features causing problems, although that’s not very definitive. :wink:

1 Like

#7

Modify the buffer before running retarget and save. Then is_dirty is guaranteed to be set before saving and will be unset when saving was successful. Insert some character and then remove it, for example. Don’t use undo though.

Note that on Linux St can make use of sudo to request permission for saving a file the user would usually not have permission for. This dialog can take a while to close, so you’ll have to consider this delay (for example by listening to any other event).

2 Likes