I’m tired of having tabs hang around when they are removed from the filesystem. Eventually I do a find and replace everywhere, save all, and suddenly a bunch of untracked files appear in my repo. I’d love if there were an option to not leave files open in this case, but if there isn’t I’d like to take a stab at making a plugin to make that behavior. I’m not seeing anything too promising in the API docs so if I’m missing something please let me know.
There’s no direct event that tells you that a file is missing because it was deleted.
That said, view.file_name() tells you the file name that’s associated with any particular view. This is None for files that haven’t been saved yet, and the name of the file that was loaded in the buffer, which includes if the file didn’t actually exist at the time that it was created.
This post shows a version of the save_all command that only saves files that have a file name associated with them, which means that they were actually loaded (or the user tried to load them). skipping over trying to save any files that haven’t been given a name yet.
Taking that one step further, this might give you ideas on how to do what you want:
import sublime
import sublime_plugin
import os
class SaveAllUnmissingCommand(sublime_plugin.WindowCommand):
def run(self, close_missing=False):
for view in self.window.views():
if view.file_name() is not None:
exists = os.path.exists(view.file_name())
if view.is_dirty() and exists:
view.run_command("save")
if not exists and close_missing:
view.set_scratch(True)
view.close()
The save_all_unmissing command that this implements will iterate over all of the views in the current window. If it finds a view that’s dirty and also backed by a file that currently exists on disk, it will be saved, and any files that haven’t been saved yet will be skipped, pending you saving them and giving them a name.
Additionally, if you pass True to the close_missing argument, any view that has a file name already associated with it but for which no such file exists on disk will be closed. The view is set to a scratch buffer so that you’re not asked to confirm the close; you could remove that if you want to be prompted to close such views.
Note however that as I mentioned above, if you did something like subl -n sample.txt, a view with a file_name() of sample.txt will be created even if the file doesn’t exist. As such this command would close such a buffer as well, which may or may not be what you want.
Depending on how you wanted to proceed, you could keep the linked version of the command to only save files that still exist and then use the standard close all command to close everything that’s still open, which would prompt you per file, or do something similar to what’s happening here.
Thank you, this is pretty close to what I want. I really wish there were some event that was fired when a file is deleted, otherwise I think I’ll just try and pick a cadence for running this command so that it happens frequently enough that files being deleted don’t become a bother anymore.
I ended up just running the command on window activation. I only delete views that have no file at the path they are associated with, are not dirty, and have at least 1 character in them. So far so good.