(cl-defmethod xref-backend-references :around ((_backend (eql 'elisp)) identifier)
(let* ((pos (get-text-property 0 'pos identifier))
- (enable-local-variables nil))
- (or (elisp-make-xrefs (elisp-local-references pos))
+ (enable-local-variables nil)
+ (gc-cons-threshold (* 1024 1024 1024)))
+ (or (elisp-make-xrefs (and pos (elisp-local-references pos)))
(let (res
(types
(case (elisp--xref-infer-namespace-1 pos)
(project-files (project-current))))
"Scanning for references"
(with-current-buffer (find-file-noselect file)
- (let (all)
- (save-excursion
- (goto-char (point-min))
- (condition-case e
- (while t
- (scope
- (lambda (type beg len &rest _)
- (and (or (null types) (memq type types))
- (string= identifier (buffer-substring-no-properties beg (+ beg len)))
- (push (cons beg len) all)))))
- (end-of-file
- (setq res (nconc (elisp-make-xrefs all) res)))
- (error (message "Encountered error while scanning %s: %S" file e) nil))))))
- res)
+ (pcase-dolist (`(,type ,beg ,len . ,_) (elisp-symbols-index))
+ (and (or (null types) (memq type types))
+ (string= identifier (buffer-substring-no-properties beg (+ beg len)))
+ (push (elisp-make-xref beg len) res)))))
+ (nreverse res))
;; (cl-call-next-method backend identifier)
)))
+(defun elisp-make-xref (beg len)
+ (let* ((beg-end (save-excursion
+ (goto-char beg)
+ (cons (pos-bol) (pos-eol))))
+ (begg (car beg-end))
+ (end (cdr beg-end))
+ (line (buffer-substring begg end))
+ (cur (- beg begg)))
+ (add-face-text-property cur (+ len cur) 'xref-match t line)
+ (xref-make line (xref-make-buffer-location (current-buffer) beg))))
+
(defun elisp-make-xrefs (all)
(let (res)
- (pcase-dolist (`(,sym . ,len) all)
- (let* ((beg-end (save-excursion
- (goto-char sym)
- (cons (pos-bol) (pos-eol))))
- (beg (car beg-end))
- (end (cdr beg-end))
- (line (buffer-substring-no-properties beg end))
- (cur (- sym beg)))
- (add-face-text-property cur (+ len cur) 'xref-match t line)
- (push (xref-make line (xref-make-buffer-location
- (current-buffer) sym))
- res)))
+ (dolist (ent all) (push (elisp-make-xref (car ent) (cdr ent)) res))
res))
(defun elisp--xref-filter-definitions (definitions namespace symbol)
\f
(put 'read-symbol-shorthands 'safe-local-variable #'consp)
+(defvar-local elisp-symbols-index-cache nil)
+
+(defun elisp-symbols-index ()
+ (cdr (if (<= (buffer-chars-modified-tick)
+ (or (car elisp-symbols-index-cache) 0))
+ elisp-symbols-index-cache
+ (setq elisp-symbols-index-cache
+ (cons (buffer-chars-modified-tick)
+ (elisp-symbols-index-1))))))
+
+(defun elisp-symbols-index-1 ()
+ (let (all)
+ (save-excursion
+ (goto-char (point-min))
+ (condition-case e
+ (while t (scope (lambda (&rest args) (push args all))))
+ (end-of-file (nreverse all))
+ (error (message "Encountered error while scanning %s: %S" buffer-file-name e) nil)))))
+
(provide 'elisp-mode)
;;; elisp-mode.el ends here