diff options
Diffstat (limited to 'lisp/emacs-lisp/lisp-mode.el')
-rw-r--r-- | lisp/emacs-lisp/lisp-mode.el | 219 |
1 files changed, 120 insertions, 99 deletions
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 0b1e5abd1ad..9bed4374dff 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -94,68 +94,68 @@ (defvar lisp-imenu-generic-expression (list (list nil - (purecopy (concat "^\\s-*(" - (regexp-opt - '("defun" "defmacro" - ;; Elisp. - "defun*" "defsubst" "define-inline" - "define-advice" "defadvice" "define-skeleton" - "define-compilation-mode" "define-minor-mode" - "define-global-minor-mode" - "define-globalized-minor-mode" - "define-derived-mode" "define-generic-mode" - "ert-deftest" - "cl-defun" "cl-defsubst" "cl-defmacro" - "cl-define-compiler-macro" "cl-defgeneric" - "cl-defmethod" - ;; CL. - "define-compiler-macro" "define-modify-macro" - "defsetf" "define-setf-expander" - "define-method-combination" - ;; CLOS and EIEIO - "defgeneric" "defmethod") - t) - "\\s-+\\(" (rx lisp-mode-symbol) "\\)")) + (concat "^\\s-*(" + (regexp-opt + '("defun" "defmacro" + ;; Elisp. + "defun*" "defsubst" "define-inline" + "define-advice" "defadvice" "define-skeleton" + "define-compilation-mode" "define-minor-mode" + "define-global-minor-mode" + "define-globalized-minor-mode" + "define-derived-mode" "define-generic-mode" + "ert-deftest" + "cl-defun" "cl-defsubst" "cl-defmacro" + "cl-define-compiler-macro" "cl-defgeneric" + "cl-defmethod" + ;; CL. + "define-compiler-macro" "define-modify-macro" + "defsetf" "define-setf-expander" + "define-method-combination" + ;; CLOS and EIEIO + "defgeneric" "defmethod") + t) + "\\s-+\\(" (rx lisp-mode-symbol) "\\)") 2) ;; Like the previous, but uses a quoted symbol as the name. (list nil - (purecopy (concat "^\\s-*(" - (regexp-opt - '("defalias" "define-obsolete-function-alias") - t) - "\\s-+'\\(" (rx lisp-mode-symbol) "\\)")) + (concat "^\\s-*(" + (regexp-opt + '("defalias" "define-obsolete-function-alias") + t) + "\\s-+'\\(" (rx lisp-mode-symbol) "\\)") 2) - (list (purecopy "Variables") - (purecopy (concat "^\\s-*(" - (regexp-opt - '(;; Elisp - "defconst" "defcustom" "defvar-keymap" - ;; CL - "defconstant" - "defparameter" "define-symbol-macro") - t) - "\\s-+\\(" (rx lisp-mode-symbol) "\\)")) + (list "Variables" + (concat "^\\s-*(" + (regexp-opt + '(;; Elisp + "defconst" "defcustom" "defvar-keymap" + ;; CL + "defconstant" + "defparameter" "define-symbol-macro") + t) + "\\s-+\\(" (rx lisp-mode-symbol) "\\)") 2) ;; For `defvar'/`defvar-local', we ignore (defvar FOO) constructs. - (list (purecopy "Variables") - (purecopy (concat "^\\s-*(defvar\\(?:-local\\)?\\s-+\\(" - (rx lisp-mode-symbol) "\\)" - "[[:space:]\n]+[^)]")) + (list "Variables" + (concat "^\\s-*(defvar\\(?:-local\\)?\\s-+\\(" + (rx lisp-mode-symbol) "\\)" + "[[:space:]\n]+[^)]") 1) - (list (purecopy "Types") - (purecopy (concat "^\\s-*(" - (regexp-opt - '(;; Elisp - "defgroup" "deftheme" - "define-widget" "define-error" - "defface" "cl-deftype" "cl-defstruct" - ;; CL - "deftype" "defstruct" - "define-condition" "defpackage" - ;; CLOS and EIEIO - "defclass") - t) - "\\s-+'?\\(" (rx lisp-mode-symbol) "\\)")) + (list "Types" + (concat "^\\s-*(" + (regexp-opt + '(;; Elisp + "defgroup" "deftheme" + "define-widget" "define-error" + "defface" "cl-deftype" "cl-defstruct" + ;; CL + "deftype" "defstruct" + "define-condition" "defpackage" + ;; CLOS and EIEIO + "defclass") + t) + "\\s-+'?\\(" (rx lisp-mode-symbol) "\\)") 2)) "Imenu generic expression for Lisp mode. See `imenu-generic-expression'.") @@ -308,7 +308,7 @@ This will generate compile-time constants from BINDINGS." (buffer-substring-no-properties beg0 end0))))) (buffer-substring-no-properties (1+ beg0) end0)) - `(face ,font-lock-warning-face + '(face font-lock-warning-face help-echo "This \\ has no effect")))) (defun lisp--match-confusable-symbol-character (limit) @@ -490,14 +490,17 @@ This will generate compile-time constants from BINDINGS." (2 font-lock-constant-face nil t)) ;; Words inside \\[], \\<>, \\{} or \\`' tend to be for ;; `substitute-command-keys'. - (,(rx "\\\\" (or (seq "[" (group-n 1 lisp-mode-symbol) "]") + (,(rx "\\\\" (or (seq "[" + (group-n 1 (seq lisp-mode-symbol (not "\\"))) "]") (seq "`" (group-n 1 ;; allow multiple words, e.g. "C-x a" lisp-mode-symbol (* " " lisp-mode-symbol)) "'"))) (1 font-lock-constant-face prepend)) - (,(rx "\\\\" (or (seq "<" (group-n 1 lisp-mode-symbol) ">") - (seq "{" (group-n 1 lisp-mode-symbol) "}"))) + (,(rx "\\\\" (or (seq "<" + (group-n 1 (seq lisp-mode-symbol (not "\\"))) ">") + (seq "{" + (group-n 1 (seq lisp-mode-symbol (not "\\"))) "}"))) (1 font-lock-variable-name-face prepend)) ;; Ineffective backslashes (typically in need of doubling). ("\\(\\\\\\)\\([^\"\\]\\)" @@ -556,7 +559,9 @@ This will generate compile-time constants from BINDINGS." (,(concat "(" cl-errs-re "\\_>") (1 font-lock-warning-face)) ;; Words inside ‘’ and `' tend to be symbol names. - (,(concat "[`‘]\\(" (rx lisp-mode-symbol) "\\)['’]") + (,(concat "[`‘]\\(" + (rx (* lisp-mode-symbol (+ space)) lisp-mode-symbol) + "\\)['’]") (1 font-lock-constant-face prepend)) ;; Uninterned symbols, e.g., (defpackage #:my-package ...) ;; must come before keywords below to have effect @@ -657,9 +662,9 @@ Lisp font lock syntactic face function." (let ((listbeg (nth 1 state))) (if (or (lisp-string-in-doc-position-p listbeg startpos) (lisp-string-after-doc-keyword-p listbeg startpos)) - font-lock-doc-face - font-lock-string-face)))) - font-lock-comment-face)) + 'font-lock-doc-face + 'font-lock-string-face)))) + 'font-lock-comment-face)) (defun lisp-adaptive-fill () "Return fill prefix found at point. @@ -1153,7 +1158,7 @@ is the buffer position of the start of the containing expression." (defun lisp--local-defform-body-p (state) "Return non-nil when at local definition body according to STATE. STATE is the `parse-partial-sexp' state for current position." - (when-let ((start-of-innermost-containing-list (nth 1 state))) + (when-let* ((start-of-innermost-containing-list (nth 1 state))) (let* ((parents (nth 9 state)) (first-cons-after (cdr parents)) (second-cons-after (cdr first-cons-after)) @@ -1171,11 +1176,11 @@ STATE is the `parse-partial-sexp' state for current position." (let (local-definitions-starting-point) (and (save-excursion (goto-char (1+ second-order-parent)) - (when-let ((head (ignore-errors - ;; FIXME: This does not distinguish - ;; between reading nil and a read error. - ;; We don't care but still, better fix this. - (read (current-buffer))))) + (when-let* ((head (ignore-errors + ;; FIXME: This does not distinguish + ;; between reading nil and a read error. + ;; We don't care but still, better fix this. + (read (current-buffer))))) (when (memq head '( cl-flet cl-labels cl-macrolet cl-flet* cl-symbol-macrolet)) ;; In what follows, we rely on (point) returning non-nil. @@ -1428,6 +1433,20 @@ Any non-integer value means do not use a different value of :group 'lisp :version "30.1") +(defvar lisp-fill-paragraphs-as-doc-string t + "Whether `lisp-fill-paragraph' should fill strings as ELisp doc strings. +The default behavior of `lisp-fill-paragraph' is tuned for filling Emacs +Lisp doc strings, with their special treatment for the first line. +Specifically, strings are filled in a narrowed context to avoid filling +surrounding code, which means any leading indent is disregarded, which +can cause the filled string to extend passed the configured +`fill-column' variable value. If you would rather fill the string in +its original context, disregarding the special conventions of ELisp doc +strings, and want to ensure the `fill-column' value is more strictly +respected, set this variable to nil. Doing so makes +`lisp-fill-paragraph' behave as it used to in Emacs 27 and prior +versions.") + (defun lisp-fill-paragraph (&optional justify) "Like \\[fill-paragraph], but handle Emacs Lisp comments and docstrings. If any of the current line is a comment, fill the comment or the @@ -1477,42 +1496,44 @@ and initial semicolons." (derived-mode-p 'emacs-lisp-mode)) emacs-lisp-docstring-fill-column fill-column))) - (let ((ppss (syntax-ppss)) - (start (point)) - ;; Avoid recursion if we're being called directly with - ;; `M-x lisp-fill-paragraph' in an `emacs-lisp-mode' buffer. - (fill-paragraph-function t)) + (let* ((ppss (syntax-ppss)) + (start (point)) + ;; Avoid recursion if we're being called directly with + ;; `M-x lisp-fill-paragraph' in an `emacs-lisp-mode' buffer. + (fill-paragraph-function t) + (string-start (ppss-comment-or-string-start ppss))) (save-excursion (save-restriction ;; If we're not inside a string, then do very basic ;; filling. This avoids corrupting embedded strings in ;; code. - (if (not (ppss-comment-or-string-start ppss)) + (if (not string-start) (lisp--fill-line-simple) - ;; If we're in a string, then narrow (roughly) to that - ;; string before filling. This avoids filling Lisp - ;; statements that follow the string. - (when (ppss-string-terminator ppss) - (goto-char (ppss-comment-or-string-start ppss)) - ;; The string may be unterminated -- in that case, don't - ;; narrow. - (when (ignore-errors - (progn - (forward-sexp 1) - t)) - (narrow-to-region (1+ (ppss-comment-or-string-start ppss)) - (1- (point))))) - ;; Move back to where we were. - (goto-char start) - ;; We should fill the first line of a string - ;; separately (since it's usually a doc string). - (if (= (line-number-at-pos) 1) - (narrow-to-region (line-beginning-position) - (line-beginning-position 2)) - (save-excursion - (goto-char (point-min)) - (forward-line 1) - (narrow-to-region (point) (point-max)))) + (when lisp-fill-paragraphs-as-doc-string + ;; If we're in a string, then narrow (roughly) to that + ;; string before filling. This avoids filling Lisp + ;; statements that follow the string. + (when (ppss-string-terminator ppss) + (goto-char string-start) + ;; The string may be unterminated -- in that case, don't + ;; narrow. + (when (ignore-errors + (progn + (forward-sexp 1) + t)) + (narrow-to-region (1+ string-start) + (1- (point))))) + ;; Move back to where we were. + (goto-char start) + ;; We should fill the first line of a string + ;; separately (since it's usually a doc string). + (if (= (line-number-at-pos) 1) + (narrow-to-region (line-beginning-position) + (line-beginning-position 2)) + (save-excursion + (goto-char (point-min)) + (forward-line 1) + (narrow-to-region (point) (point-max))))) (fill-paragraph justify))))))) ;; Never return nil. t) |