The code below should be closer to doing what you want (in place of the plugin outlined above).
The code in set_modification_time()
will determine the last modification time of the file associated with the view
passed in (if that view is associated with a file on disk and that file actually exists) and add it to the status bar with the format defined at the top (as defined here you will get something like [Tue 03 Oct 2023, 02:36PM]
)
The function is executed:
- Whenever a new file is loaded
- A file that has previously been loaded is reloaded (e.g. its content changed on disk and Sublime noticed)
- The file was saved by you or on your behalf
- You make a clone of an existing file, say when doing a split
In addition, the on_init()
will make the function execute across all views that exist at the point at which the plugin was originally loaded. In your case, that means that when you quit and restart Sublime, all of the files in all of the windows that are open at startup will have their modification times applied.
The on_load_project_async()
will trigger whenever a new window is created as a result of loading a project file from disk, and will scan over all of the views in that window and update their status bars as well.
Note that due to the usage of Pathlib
and the f""
string formats (and the use of on_init
and on_load_project_async
) this will only work in ST4 and up since those features require the 3.8 plugin host. This could be modified to work in earlier versions if strictly needed.
Note also that your User
package always runs in the 3.8 plugin host in ST4, but if you want to move this out to its own separate package folder, you would need to include a .python-version
file as outlined in the documentation on API environments
import sublime
import sublime_plugin
from pathlib import Path
from datetime import datetime
# The icon/text to appear prior to modification date of the file; set to be
# empty if you want no such text.
ICON = "⏰"
# The status key to use; keys in the status bar are ordered by key, so you can
# use this to juggle the relative order of the key in the status bar as needed.
STATUS_KEY = "0-clock"
# The format string to use to format the modification time of the file in the
# status bar. See this URL for details on codes that are available:
# https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes
TIME_FORMAT = "[%a %d %b %Y, %I:%M%p]"
class StatusBarEvents(sublime_plugin.EventListener):
"""
Listen for files being loaded, reloaded, saved and cloned and update the
status bar for that file to track the last modification time of the file as
it appears on disk.
This will track any file as it is originally opened, and will update all
views in all windows
"""
def set_modification_time(self, view):
"""
Given a view, check to see if it has a file associated with it on disk.
If it does, then determine the last modification time of the file and
add or update a status key in the status bar to display that data.
"""
if view.file_name() is not None:
file = Path(view.file_name())
if file.exists():
time = datetime.fromtimestamp(file.stat().st_mtime)
view.set_status(STATUS_KEY, f"{ICON} {time.strftime(TIME_FORMAT)}")
# Update the last modification time in a file whenever a file loads, is
# reloaded from disk, saved to disk by the user, or a new clone of the
# view is created (e.g. `File > Split View` and similar.)
on_load = on_reload = on_post_save = on_clone = set_modification_time
def on_init(self, views):
"""
When the event listener is instantiated, scan over all files that are
currently open and update their modification times in the status bar.
"""
for view in views:
self.set_modification_time(view)
def on_load_project_async(self, window):
"""
Whenever a new project is loaded from disk, scan over all of files that
may be open inside of the window and update their status bars.
"""
for view in window.views():
self.set_modification_time(view)