@@ -155,6 +155,15 @@ terminal output redraw."
155155(defvar-local ai-code-session-link--pending-tail-width 0
156156 " Pending tail width to rescan when delayed session linkification runs." )
157157
158+ (defvar-local ai-code-session-link--buffer-project-files-cache nil
159+ " Buffer-local project file cache reused across session relinkify passes." )
160+
161+ (defvar-local ai-code-session-link--last-region-bounds nil
162+ " Last relinkified region bounds used to skip unchanged property churn." )
163+
164+ (defvar-local ai-code-session-link--last-region-text nil
165+ " Last relinkified region text used to skip unchanged property churn." )
166+
158167(defvar ai-code-session-link--project-files-cache nil
159168 " Dynamic cache of project file lists used during one linkify pass." )
160169
@@ -184,6 +193,17 @@ terminal output redraw."
184193 cached))
185194 (funcall compute)))
186195
196+ (defun ai-code-session-link--buffer-project-files-cache ()
197+ " Return the buffer-local cache of enumerated project files."
198+ (or ai-code-session-link--buffer-project-files-cache
199+ (setq ai-code-session-link--buffer-project-files-cache
200+ (make-hash-table :test 'equal ))))
201+
202+ (defun ai-code-session-link--unchanged-region-p (bounds region-text )
203+ " Return non-nil when BOUNDS and REGION-TEXT match the last relinkified region."
204+ (and (equal ai-code-session-link--last-region-bounds bounds)
205+ (equal ai-code-session-link--last-region-text region-text)))
206+
187207(defun ai-code-session-link--project-files (root )
188208 " Return absolute project files for ROOT."
189209 (when (file-directory-p root)
@@ -468,7 +488,8 @@ terminal output redraw."
468488
469489(defun ai-code-session-link--linkify-file-region (start end )
470490 " Apply file session links between START and END."
471- (let ((ai-code-session-link--project-files-cache (make-hash-table :test 'equal ))
491+ (let ((ai-code-session-link--project-files-cache
492+ (ai-code-session-link--buffer-project-files-cache))
472493 (ai-code-session-link--resolved-path-cache (make-hash-table :test 'equal )))
473494 (let ((file-links (ai-code-session-link--collect-file-links start end)))
474495 (while file-links
@@ -586,26 +607,31 @@ terminal output redraw."
586607 (widen )
587608 (setq start (max (point-min ) start)
588609 end (min (point-max ) end))
589- (let ((pos start))
590- (while (< pos end)
591- (let ((next (or (next-single-property-change
592- pos 'ai-code-session-link nil end)
593- end)))
594- (when (get-text-property pos 'ai-code-session-link )
595- (remove-text-properties
596- pos next
597- '(ai-code-session-link nil
598- ai-code-session-symbol-link nil
599- ai-code-session-symbol-file nil
600- mouse-face nil
601- help-echo nil
602- keymap nil
603- follow-link nil
604- font-lock-face nil
605- face nil )))
606- (setq pos next))))
607- (ai-code-session-link--linkify-url-region start end)
608- (ai-code-session-link--linkify-file-region start end))))))
610+ (let ((bounds (cons start end))
611+ (region-text (buffer-substring-no-properties start end)))
612+ (unless (ai-code-session-link--unchanged-region-p bounds region-text)
613+ (let ((pos start))
614+ (while (< pos end)
615+ (let ((next (or (next-single-property-change
616+ pos 'ai-code-session-link nil end)
617+ end)))
618+ (when (get-text-property pos 'ai-code-session-link )
619+ (remove-text-properties
620+ pos next
621+ '(ai-code-session-link nil
622+ ai-code-session-symbol-link nil
623+ ai-code-session-symbol-file nil
624+ mouse-face nil
625+ help-echo nil
626+ keymap nil
627+ follow-link nil
628+ font-lock-face nil
629+ face nil )))
630+ (setq pos next))))
631+ (ai-code-session-link--linkify-url-region start end)
632+ (ai-code-session-link--linkify-file-region start end)
633+ (setq ai-code-session-link--last-region-bounds bounds
634+ ai-code-session-link--last-region-text region-text))))))))
609635
610636(defun ai-code-session-link--recent-output-tail-width (output )
611637 " Return the tail width to rescan after OUTPUT."
0 commit comments