diff --git a/lisp/treesit.el b/lisp/treesit.el index 962a6fc3cf8..f5d30be52bb 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -1075,17 +1075,56 @@ treesit-font-lock-fontify-region face (treesit-node-type node)))))))))))) `(jit-lock-bounds ,start . ,end)) +(defvar treesit--notifier-ranges nil) +(defvar treesit--notifier-context 'direct) + (defun treesit--font-lock-notifier (ranges parser) "Ensures updated parts of the parse-tree are refontified. +And re-syntax-propertized. RANGES is a list of (BEG . END) ranges, PARSER is the tree-sitter parser notifying of the change." (with-current-buffer (treesit-parser-buffer parser) - (dolist (range ranges) - (when treesit--font-lock-verbose - (message "Notifier received range: %s-%s" - (car range) (cdr range))) - (with-silent-modifications - (put-text-property (car range) (cdr range) 'fontified nil))))) + (unless (eq treesit--notifier-context 'direct) + (setq treesit--notifier-ranges (append treesit--notifier-ranges ranges))) + (message "notifier context %s ranges %s" treesit--notifier-context ranges) + (when ranges + (unless (eq treesit--notifier-context 'font-lock) + (when treesit-font-lock-settings + (with-silent-modifications + (dolist (range ranges) + (when treesit--font-lock-verbose + (message "Notifier received range: %s-%s" + (car range) (cdr range))) + ;; (backtrace) + (put-text-property (car range) (cdr range) 'fontified nil))))) + (unless (eq treesit--notifier-context 'syntax) + (when syntax-propertize-function + (syntax-ppss-flush-cache (cl-loop for r in ranges + minimize (car r)))))))) + +(defun treesit--syntax-extend-region (beg end &optional font-lock-p) + (let (treesit--notifier-ranges + (treesit--notifier-context (if font-lock-p 'font-lock 'syntax))) + (treesit-buffer-root-node (treesit-language-at (point))) + (when treesit--notifier-ranges + ;; (message "some ranges received %S while beg end %s %s" treesit--notifier-ranges beg end) + ;; Some updates received from `treesit_ensure_parsed'. + (cl-loop for range in treesit--notifier-ranges + if (or (<= (car range) beg (cdr range)) + (<= (car range) end (cdr range))) + return (cons (min (car range) beg) + (max (cdr range) end)))))) + +(defun treesit--font-lock-extend-region () + (defvar font-lock-beg) + (defvar font-lock-end) + ;; (message "called treesit--font-lock-extend-region") + (let ((new (treesit--syntax-extend-region font-lock-beg font-lock-end t))) + (when new + ;; (message "eeextended to %S" new) + (setq font-lock-beg (car new)) + (setq font-lock-end (cdr new)) + t))) ;;; Indent @@ -2391,7 +2430,9 @@ treesit-major-mode-setup (treesit-font-lock-recompute-features) (dolist (parser (treesit-parser-list)) (treesit-parser-add-notifier - parser #'treesit--font-lock-notifier))) + parser #'treesit--font-lock-notifier)) + (push #'treesit--font-lock-extend-region font-lock-extend-region-functions) + (push #'treesit--syntax-extend-region syntax-propertize-extend-region-functions)) ;; Indent. (when treesit-simple-indent-rules (setq-local treesit-simple-indent-rules