"C-c C-f" #'elisp-byte-compile-file
"C-c C-b" #'elisp-byte-compile-buffer
"C-M-q" #'indent-pp-sexp
- "C-c M-e" #'macrostep-expand)
+ "C-c M-e" #'macrostep-expand
+ "C-c C-n" #'elisp-next-occurrence
+ "C-c C-p" #'elisp-prev-occurrence)
(easy-menu-define emacs-lisp-mode-menu emacs-lisp-mode-map
"Menu for Emacs Lisp mode."
(elisp--xref-filter-definitions defs 'any sym))
(elisp--xref-filter-definitions defs namespace sym))))))))
+(defun elisp-local-references (pos)
+ "Return references to local variable at POS as (BEG . LEN) cons cells."
+ (let (all cur)
+ (save-excursion
+ (goto-char pos)
+ (beginning-of-defun)
+ (scope (lambda (_type beg len bin)
+ (when (<= beg pos (+ beg len))
+ (setq cur bin))
+ (when bin (setf (alist-get beg all) (list len bin))))
+ (current-buffer)))
+ (seq-keep
+ (pcase-lambda (`(,sym ,len ,bin)) (when (equal bin cur) (cons sym len)))
+ all)))
+
(cl-defmethod xref-backend-references :around ((backend (eql 'elisp)) identifier)
(let* ((pos (get-text-property 0 'pos identifier))
- all dec)
- (when pos
- (save-excursion
- (goto-char pos)
- (beginning-of-defun)
- (scope (lambda (_type beg len bin)
- (when (<= beg pos (+ beg len))
- (setq dec bin))
- (when bin (setf (alist-get beg all) (list len bin))))
- (current-buffer))))
- (if dec
+ (all (elisp-local-references pos)))
+ (if all
(let (res)
- (pcase-dolist (`(,sym ,len ,bin) all)
- (when (equal bin dec)
- (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))))
+ (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)))
res)
(cl-call-next-method backend identifier))))
"Byte compile the file the current buffer is visiting.
If LOAD is non-nil, load the resulting .elc file. When called
interactively, this is the prefix argument."
- (interactive "P")
+ (interactive "P" elisp-mode)
(unless buffer-file-name
(error "This buffer is not visiting a file"))
(byte-compile-file buffer-file-name)
"Byte compile the current buffer, but don't write a file.
If LOAD is non-nil, load byte-compiled data. When called
interactively, this is the prefix argument."
- (interactive "P")
+ (interactive "P" elisp-mode)
(let ((bfn buffer-file-name)
file elc)
(require 'bytecomp)
(byte-compile-log-warning-function
(lambda (string position &optional fill level)
(if bfn
- ;; Massage the warnings to that they point to
+ ;; Massage the warnings so that they point to
;; this file, not the one in /tmp.
(let ((byte-compile-current-file bfn)
(byte-compile-root-dir (file-name-directory bfn)))
(when (file-exists-p elc)
(delete-file elc))))))
+(defun elisp-prev-occurrence (n)
+ "Go to previous Nth occurrence of local variable at point."
+ (interactive "p" emacs-lisp-mode)
+ (elisp-next-occurrence (- n)))
+
+(defun elisp-next-occurrence (n)
+ "Go to next Nth occurrence of local variable at point."
+ (interactive "p" emacs-lisp-mode)
+ (if-let ((pos (point))
+ (next (nth (1- (abs n))
+ (sort (seq-filter (pcase-lambda (`(,beg . ,_))
+ (and (eq (< pos beg) (< 0 n))
+ (not (= pos beg))))
+ (or (elisp-local-references pos)
+ (user-error "No local variable at point")))
+ :reverse (< n 0))))
+ (beg (car next))
+ (end (+ beg (cdr next))))
+ (progn
+ (goto-char beg)
+ (pulse-momentary-highlight-region beg end 'highlight)
+ (when elisp-next-occurrence-repeat-map
+ (set-transient-map elisp-next-occurrence-repeat-map)))
+ (user-error "No next occurrence")))
+
+(defvar-keymap elisp-next-occurrence-repeat-map
+ :doc "Repeat keymap for `elisp-next-occurrence' and `elisp-prev-occurrence'."
+ "C-n" #'elisp-next-occurrence
+ "C-p" #'elisp-prev-occurrence)
+
\f
(put 'read-symbol-shorthands 'safe-local-variable #'consp)