lex-hl

git clone git://jamzattack.xyz/lex-hl.git
Log | Files | Refs

commit 33013aea5e172be5781ed8fb81d61e4a4ebc59c0
parent e1e2076bf817942a827cf562dd3ca644be8b71b7
Author: Jamie Beardslee <jdb@jamzattack.xyz>
Date:   Fri, 11 Sep 2020 18:58:15 +1200

Split `highlight-lexical-variables' into a few separate functions

It was a big messy function, so I added a couple of internal functions
- generate-regexp: generates a regexp based on `forms'
- sexp-at-point: now the function that does all the work wrt figuring
  out and evaluating the highlight function.

Because of this refactoring, it was simple to add a couple of new
commands:
- top-level: highlight top-level form (usually defun)
- prompt: prompt user for which form to highlight
- nearest (was highlight-lexical-variables): highlight the nearest
  form before point.

Diffstat:
Mlex-hl.el | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 54 insertions(+), 20 deletions(-)

diff --git a/lex-hl.el b/lex-hl.el @@ -95,33 +95,67 @@ If FUNCTION is omitted or nil, `lex-hl--SYMBOL' will be used." (lex-hl-highlight-symbol symbol))) (lex-hl-add-form 'dolist) + +(defun lex-hl-generate-regexp () + "Generate a regexp based on `lex-hl-forms'." + (eval + `(rx "(" (group (or ,@lex-hl-forms))))) + +(defun lex-hl-sexp-at-point () + "Highlight variables bound in the sexp at point." + (let* ((sexp (read (thing-at-point 'sexp))) + (symbol (car sexp))) + (funcall (or (get symbol 'lex-hl) + (error "`%s' not supported by `lex-hl'" symbol)) + sexp))) + ;;; User-facing commands +;;;###autoload +(defun lex-hl-top-level () + "Highlight variables bound in the top-level form at point. +See the variable `lex-hl-forms' for a list of supported forms." + (interactive) + (save-excursion + (beginning-of-defun) + (lex-hl-sexp-at-point))) + +;;;###autoload +(defun lex-hl-prompt (bounds) + "Highlight variables bound in the form chosen from the minibuffer. +This is limited to the region specified by BOUNDS. Interactively, +this is the top-level form at point, or the active region with a +prefix argument." + (interactive (if current-prefix-arg + (region-bounds) + (list (bounds-of-thing-at-point 'defun)))) + (let ((beg (car bounds)) + (end (cdr bounds)) + list) + (goto-char beg) + (save-excursion + (while (re-search-forward (lex-hl-generate-regexp) end :noerror) + (let ((match (match-beginning 0))) + (push (cons (buffer-substring match (line-end-position)) match) + list))) + (goto-char (cdr (assoc (completing-read "Highlight variables in: " list) + list))) + (lex-hl-sexp-at-point)))) ;;;###autoload -(defun lex-hl-highlight-lexical-variables (arg) +(defun lex-hl-nearest (n) + "Highlight variables bound in the Nth nearest form. +See the variable `lex-hl-forms' for a list of supported forms." (interactive "p") - (if (<= arg 0) + (if (<= n 0) (hi-lock-unface-buffer t) - (let* ((bounds (bounds-of-thing-at-point 'defun)) - (beg (car bounds)) - (end (cdr bounds))) - (save-restriction - ;; TODO: figure out a way to highlight only within a region. - ;; When narrowed, hi-lock still highlights other occurences when - ;; point gets close. - (narrow-to-region beg end) - (save-excursion - (re-search-backward (eval - `(rx "(" (group (or ,@lex-hl-forms)))) - beg :noerror arg) - (goto-char (match-beginning 0)) - (let* ((sexp (read (thing-at-point 'sexp))) - (symbol (car sexp))) - (funcall (get symbol 'lex-hl) sexp))))))) - -;; (define-key emacs-lisp-mode-map (kbd "C-c .") #'lex-hl-highlight-lexical-variables) + (let ((beg (car (bounds-of-thing-at-point 'defun)))) + (save-excursion + (re-search-backward (lex-hl-generate-regexp) + beg :noerror n) + (goto-char (match-beginning 0)) + (lex-hl-sexp-at-point))))) (provide 'lex-hl) ;;; lex-hl.el ends here