1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-23 07:19:15 +00:00

Font-lock shorthands in elisp-mode for quick visual recognition (bug#50959)

Only the shorthanded prefix is font-locked.  This allows the remainder
of the font-lock logic to subsist (e.g. for macro-defining symbols).

* lisp/shorthands.el (cl-lib): Require it when compiling.
(elisp-shorthand-font-lock-face): New face.
(shorthands--mismatch-from-end): New helper.
(shorthands-font-lock-shorthands): New helper.

* test/lisp/progmodes/elisp-mode-resources/simple-shorthand-test.el:
Add some dummy test code.
This commit is contained in:
João Távora 2021-10-03 11:56:16 +01:00
parent 17e6f3bee5
commit e6fbc45b7b
2 changed files with 47 additions and 0 deletions

View File

@ -26,6 +26,7 @@
;;; Code:
(require 'files)
(eval-when-compile (require 'cl-lib))
(defun hack-elisp-shorthands (fullname)
"Return value of `elisp-shorthands' file-local variable in FULLNAME.
@ -57,4 +58,42 @@ value of `elisp-shorthands', when it processes that file's Elisp code."
(let ((elisp-shorthands (hack-elisp-shorthands fullname)))
(load-with-code-conversion fullname file noerror nomessage)))
;; FIXME: move this all to progmodes/elisp-mode.el? OTOH it'd make
;; more sense there, OTOH all the elisp font-lock stuff is actually in
;; lisp/emacs-lisp/lisp-mode.el, which isn't right either. So
;; shorthand font-locking logic is probably better here for now.
(defface elisp-shorthand-font-lock-face
'((t :inherit font-lock-keyword-face :foreground "cyan"))
"Face for highlighting shorthands in Emacs Lisp."
:version "28.1"
:group 'font-lock-faces)
(defun shorthands--mismatch-from-end (str1 str2)
(cl-loop with l1 = (length str1) with l2 = (length str2)
for i from 1
for i1 = (- l1 i) for i2 = (- l2 i)
while (and (>= i1 0) (>= i2 0) (eq (aref str1 i1) (aref str2 i2)))
finally (return (1- i))))
(defun shorthands-font-lock-shorthands (limit)
(when elisp-shorthands
(while (re-search-forward
(eval-when-compile
(concat "\\_<\\(" lisp-mode-symbol-regexp "\\)\\_>"))
limit t)
(let* ((existing (get-text-property (match-beginning 1) 'face))
(probe (and (not (memq existing '(font-lock-comment-face
font-lock-string-face)))
(intern-soft (match-string 1))))
(sname (and probe (symbol-name probe)))
(mm (and sname (shorthands--mismatch-from-end
(match-string 1) sname))))
(unless (or (null mm) (= mm (length sname)))
(add-face-text-property (match-beginning 1) (1+ (- (match-end 1) mm))
'elisp-shorthand-font-lock-face))))))
(font-lock-add-keywords 'emacs-lisp-mode '((shorthands-font-lock-shorthands)) t)
;;; shorthands.el ends here

View File

@ -16,8 +16,16 @@
(defvar f-test-complete-me 42)
(elisp--foo-test3)
(defun #_f-test4--- () 84)
(defmacro f-define-test-5 ())
;; should be font locked with both shorthand
;; highlighting _and_ macro highlighting.
(f-define-test-5)
(when nil
(f-test3)
(f-test2)