File Name Cache in Emacs 28.1: Add Automatic Invalidation on External Changes?
0 reputation · 26 Nov 2023, 08:59 UTC
0 reputation · 26 Nov 2023, 08:59 UTC
Ensure that Emacs accurately reflects changes made to files outside the editor by keeping the file-name-cache up‑to‑date.
In Emacs 28.1 the cache is cleared only manually via clear-file-name-cache or when file-name-cache-size is exceeded. There is no hook that automatically removes stale entries when a file is modified on disk.
Should an advisory be added to file‑system change hooks to clear relevant cache entries, or should the entire cache be purged? The trade‑off between correctness and performance remains undecided in the documentation.
file-attributes or related file‑system hooks reliably invalidate only the affected cache entries without causing noticeable slowdown?file-name-cache on any external modification, or to target specific entries to preserve cache benefits?31775 reputation · 26 Nov 2023, 17:07 UTC
In Emacs 28.1, the file-name-cache is a performance optimization that prevents redundant system calls for functions like file-attributes and fileexists. However, because the cache lacks a native link to file-system events, it can become stale when files are modified by external processes (build tools, git, or other editors).
To ensure accuracy without sacrificing performance, the most effective approach is to use a targeted invalidation rather than a global cache purge. Clearing the entire cache via clear-file-name-cache forces Emacs to re-query every cached file on next access, which can cause noticeable lag in large projects or over network drives.
To implement this, you should utilize file-notify-add to monitor specific directories. When a modification event is detected, you should remove only the affected entry from the cache.
;; Example logic for targeted invalidation
(defun my-invalidate-cache-entry (path)
""Remove a specific path from the file-name-cache."
(let ((entry (hash-file-name-cache path))
(put file-name-cache entry nil)))
(defun my-file-changed-handler (event)
""Callback for file-notify-event."
(when (eq (event-type event) 'modified)
(my-invalidate-cache-entry (event-name event))))
hash-file-name-cache is highly efficient. Since file-name-cache is a hash table, removing a single key is O(1) compared to rebuilding the entire structure.file-notify listeners. If you use multiple Emacs instances, you would need a mechanism to broadcast invalidation signals, which adds complexity.file-attributes itself is not possible as it is a consumer of the cache, not the provider. The logic must reside at the file-system level (via file-notify).Are you monitoring a high-frequency directory (like a node_modules or build folder), or primarily static source files? This will determine if you need to debounce the invalidation hook to prevent CPU thrashing.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.