-
-
Notifications
You must be signed in to change notification settings - Fork 197
Open
Description
Issue description
Took me a bit to track this one down, ended up using "kill -USR2 {emacs-pid}" to get the lisp stacktrace.
The issue is that treesit-language-available-p seems to have gotten much slower in emacs-plus 30.2 (although it's possible it's a macOS change). Granted, one can turn global-treesit-auto-mode off as a work-around. Because treesit-available-p gets called on every file open when global-treesit-auto-mode is enabled, it makes emacs feel very slow, and affects various other commands that generate buffers that set a mode that treesit might support.
I (with LLM) hacked around it by adding a two level cache (one for per-session mtimes of library files, another for enabled and source mtimes.
(defvar my/treesit-available-cache (make-hash-table :test #'equal)
"Persistent cache mapping language symbols to t/nil.")
(defvar my/treesit-libfile-mtime-cache (make-hash-table :test #'equal)
"Ephemeral cache mapping language symbols to last-known grammar mtime.")
(defvar my/treesit-available-persist-file
(expand-file-name "treesit-available-cache.el" user-emacs-directory)
"File to persist Tree-sitter availability cache.")
(defun my/load-treesit-cache ()
"Load persistent Tree-sitter availability cache from disk."
(when (file-readable-p my/treesit-available-persist-file)
(with-temp-buffer
(insert-file-contents my/treesit-available-persist-file)
(let ((data (read (current-buffer))))
(when (hash-table-p data)
(setq my/treesit-available-cache data))))))
(defun my/save-treesit-cache ()
"Save the Tree-sitter availability cache to disk."
(with-temp-file my/treesit-available-persist-file
(let ((print-length nil)
(print-level nil))
(prin1 my/treesit-available-cache (current-buffer)))))
(defun my/treesit-get-libfile-mtime (lang)
"Return the mtime of the Tree-sitter grammar file for LANG, or nil if not found."
(let ((libfile (ignore-errors (treesit--lib-file lang))))
(when (and libfile (file-exists-p libfile))
(nth 5 (file-attributes libfile))))) ;; mtime
(advice-add 'treesit-language-available-p :around
(lambda (orig-fn &rest args)
(let* ((lang (car args))
(current-mtime (my/treesit-get-libfile-mtime lang))
(cached-mtime (gethash lang my/treesit-libfile-mtime-cache))
(cached-result (gethash lang my/treesit-available-cache)))
;; Check if mtime changed during this session
(if (and cached-result
(equal cached-mtime current-mtime))
cached-result
(let ((result (apply orig-fn args)))
(when current-mtime
(puthash lang current-mtime my/treesit-libfile-mtime-cache))
(puthash lang result my/treesit-available-cache)
result)))))
(add-hook 'emacs-startup-hook #'my/load-treesit-cache)
(add-hook 'kill-emacs-hook #'my/save-treesit-cache)
Metadata
Metadata
Assignees
Labels
No labels