Sublime Forum

File has been modified, save changes?

#1

I am using ST with WinSCP which creates a temporary folder for editing a file, then deletes the folder when I am done.

If I do not FIRST close the Sublime Text window before closing WinSCP, the next time I open Sublime Text, I see the old file contents. Other editors just don’t show non-existent files on re-opening.

On closing that tab or the window, I get the message that “… has been modified, save changes?”

First of all, this is misleading. The text has not been modified since it was last saved. What has happened is that the folder and file are no longer there. So the correct message would indicate that the file is no longer at the location it was when it was loaded - if any message is necessary at all.

Personally, as long as no editing has occurred, I would prefer that the file just close when I close the tab and not reappear if it doesn’t exist next time I run ST.

Is there an option to change this behavior? I haven’t found one.

I am new to ST, but mostly like its features so far.

Thanks.

0 Likes

#2

I’m not aware of a setting that changes that particular behavior overall except through turning off hot_exit, which stops Sublime from saving any state at all. In that case when you quit you’re prompted to save any unsaved changes, all files are closed, and on restart you end up with an empty window.

That said, generally when Sublime restarts and restores the session, the tabs for any open files that no longer exist are closed unless they have unsaved changes. In that case you don’t get a prompt that the file was modified (that I can reproduce anyway) but saving the file will resurrect the missing file if the path is still valid.

For example if I save a text file named crunk.txt on my desktop, quit Sublime and then restart it after deleting the file, the session restores but that tab is no longer present. If I modify the file and quit Sublime without saving, then remove the file and restart Sublime, the tab is still there showing the edits, but the file is no longer on disk. In that case there’s no warning that’s popped up telling me there are unsaved changes.

What version of Sublime are you running? Have you tried reproducing this with a portable copy of Sublime to see if it recurs without any third party packages installed?

0 Likes

#3

Thank you for the quick response.

I tried the following sequence.

Create a file in ST.
Save it.
Delete the file.
Tab back to ST - where it now shows that the file has been edited (although it has not). This is the unexpected (IMHO) behavior.

So the behavior after that would be correct because ST believes the file has been edited when in reality it has disappeared on disk.

Closing and reopening ST leaves the “edited” file visible.

Interesting: deleting the file immediately changes the icon to edited.
Restoring the file from the recycle bin changes it back. (Even with ST not in the foreground).

Renaming the file has the same effect.

These are all “file changed on disk” events, not the same as “File has been modified…” which implies I have typed something that is about to be lost. Only worrisome when hours have elapsed since the file was looked at.

Actually editing the file in another editor results in ST showing the new text and the icon showing up-to-date.

3.2.1 v 3207 portable

0 Likes

#4

Once there’s a filename associated with a tab (there won’t be before you save a brand new file, for example), the state of the tab tracks that file. So as you’ve seen if you remove the file in any way, the response from Sublime is to tell you that the file has been edited and putting it back will make it think it hasn’t changed.

In some weird loose technical way, that’s somewhat true; the file changed from existing to not existing and vice versa, though that’s not what you’d expect the modified state of the buffer to tell you.

On the other hand, the plugin API has an on_modified event which doesn’t trigger when a file is removed, even though it’s marking the file as being modified for the purposes of the tab bar and such, so that seems like a bit of a disconnect.

This is controlled by the always_prompt_for_file_reload setting:

    // Always prompt before reloading a file, even if the file hasn't been
    // modified. The default behavior is to automatically reload a file if it
    // hasn't been edited. If a file has unsaved changes, a prompt will always
    // be shown.
    "always_prompt_for_file_reload": false,

The default value is false, so if the underlying file changes and you haven’t modified it, it will silently reload without asking you. You can flip the state of that if you want to know when this happens. This can be semi-problematic in cases where you’re for example using source control and check out an old version while you have files open, which may give you an excess of prompts to respond to, though.

In regards to having views close when the underlying file is missing, there’s not a setting for that but something like the plugin below may be of help (see this video if you are unfamiliar with using plugins).

When the plugin is loaded (whenever you modify it or when Sublime starts) it will check every open window to see if there are any views that have a filename associated with them but for which the file on disk is no longer present and forcibly close them. For our case here, that would be files that had active modifications to them at the point where Sublime was quit, since Sublime will close unmodified tabs for missing files on it’s own.

As defined here, the tab will be closed without prompting to save any changes, which has the potential for data loss in cases where you might actually want to have kept such a buffer around, so this is sort of a Danger Will Robinson kind of operation.

import sublime
import sublime_plugin

import os


def plugin_loaded():
    """
    At plugin load time, check every view in every window looking for views
    represented by files which are no longer on disk and forcibly clobber 
    them. 
    """
    for window in sublime.windows():
        for view in window.views():
            if view_file_missing(view):
                clobber_view(view)


def view_file_missing(view):
    """
    Return an indication on whether the view provided represents a file that
    is missing on disk. Files with no name assigned and files opened by
    "View Package Files" and similar commands will report False here.
    """
    name = view.file_name()
    if name is None or view.is_read_only():
        return False

    return not os.path.isfile(name) 


def clobber_view(view):
    """
    Unconditionally close the provided view, discarding all changes present
    in it without asking for confirmation.
    """
    view.set_scratch(True)
    view.close()
2 Likes

#5

Excellent!

Thank you for the help on this level of customization. It is a good leg up for when I want more “features” that match my personal mind-set, which is not always the generally accepted way :smile:

I’ll get there…

0 Likes