Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

view.is_dirty() out of sync when file is deleted #6490

Closed
titoBouzout opened this issue Sep 19, 2024 · 3 comments
Closed

view.is_dirty() out of sync when file is deleted #6490

titoBouzout opened this issue Sep 19, 2024 · 3 comments

Comments

@titoBouzout
Copy link
Collaborator

titoBouzout commented Sep 19, 2024

Description of the bug

view.is_dirty() out of sync when file is deleted, it returns False when it should return True nvm Im wrong, but there's an issue

  1. install the command quoted bellow
  2. drag a drop a file from desktop to ST
  3. focus a new view in ST
  4. delete the file from desktop
  5. add the following command to the tab context menu, and run it on the empty view
  6. it will prompt for saving instead of being closed
//  Tab Context.sublime-menu
[{
	"command": "close_all_other_dirty_tabs",
	"caption": "Close Others Dirty"
}]
# user/is_dirty.py
class close_all_other_dirty_tabs(sublime_plugin.WindowCommand):
    def run(self):
        window = sublime.active_window()
        _view = window.active_view()
        for view in window.views():
            if view != _view:
                if view.is_dirty():
                    print("is dirty")
                    view.set_scratch(True)
                    view.run_command("set_scratch", True)
                view.close()

Steps to reproduce

above

Expected behavior

My use case was to "close other tabs even if dirty", so one could say that my view.is_dirty() check was useless, but I still expected it to work, so that put me off for a while.

In any case, if I want to create the command "close others dirty tabs", leaving open non-dirty tabs, then I won't be able todo so with this bug.

Actual behavior

already described

Sublime Text build number

4178

Operating system & version

Windows 10

(Linux) Desktop environment and/or window manager

No response

Additional information

Additionally, there's some sort of race condition, if files open, get deleted and recreated in rapid succession, it will remain dirty, even if the file contents it's the same.

  1. file is open and saved
  2. file gets deleted
  3. file gets created with same content
  4. file is marked as dirty and remains dirty

OpenGL context information

No response

@titoBouzout
Copy link
Collaborator Author

Uh, now that I think, the value is right. If the file was deleted, and recreated with the same content, then is not dirty.

The issue is somewhere else, ST thinks the file has unsaved changes, the UI shows hints (like the tab icons changing color) its unsaved, and when trying to close it, it asks for saving.

I can't tell where the problem is, but something is not right.

@deathaxe
Copy link
Collaborator

deathaxe commented Oct 4, 2024

Related with #6503

You are probably confused by deleted and modified files being displayed with the same close button icon.

Technically "deleted" and "modified" states are independent. The real file state is a combination of both.

deleted dirty description
0 0 unmodified content of an existing file
1 0 unmodified content of a deleted file
0 1 modified content of an existing file
1 1 modified content of a deleted file

That's also expressed by the "Save As..." dialog's message.

grafik

To suppress the dialog for unmodified deleted files, a check for valid view.file_name() and not os.path.exists(view.file_name()) is required in addition to view.is_dirty()

Following modification to your plugin is required

# user/is_dirty.py
import os
import sublime
import sublime_plugin

class close_all_other_dirty_tabs(sublime_plugin.WindowCommand):
    """Close all deleted or modified views without confirmation."""
    def run(self):
        window = sublime.active_window()
        _view = window.active_view()
        for view in window.views():
            if view != _view:
                if view.file_name() and not os.path.exists(view.file_name()):
                    print("is deleted")
                    view.set_scratch(True)
                elif view.is_dirty():
                    print("is dirty")
                    view.set_scratch(True)
                view.close()

Note: A related solution can be found at https://forum.sublimetext.com/t/do-not-prompt-to-save-deleted-files/72990/3, which can be commanded to save or not save closed views via arguments.

Conclusion

The view.is_dirty() function is working as expected.

@titoBouzout
Copy link
Collaborator Author

Thanks @deathaxe for the explanation, indeed view.is_dirty() was/is working as expected.

My confusion came from that after the file being restored, the UI(not the api) still showed the file as being "dirty". Such as asking for saving, that was in 4178, I can't seem to reproduce that behavior anymore with 4183. So something must have changed.

I suppose we are good to close the issue?

@deathaxe deathaxe closed this as completed Oct 4, 2024
@deathaxe deathaxe closed this as not planned Won't fix, can't repro, duplicate, stale Oct 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants