diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 052a10e3797..4c40f414ca0 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -3679,10 +3679,20 @@ in C. @vindex font-lock-function-name-face for the name of a function being defined or declared. +@item font-lock-function-call-face +@vindex font-lock-function-call-face +for the name of a function being called. This face inherits, by +default, from @code{font-lock-function-name-face}. + @item font-lock-variable-name-face @vindex font-lock-variable-name-face for the name of a variable being defined or declared. +@item font-lock-variable-ref-face +@vindex font-lock-variable-ref-face +for the name of a variable being referenced. This face inherits, by +default, from @code{font-lock-variable-name-face}. + @item font-lock-keyword-face @vindex font-lock-keyword-face for a keyword with special syntactic significance, like @samp{for} and @@ -3756,11 +3766,16 @@ for numbers. @vindex font-lock-operator-face for operators. -@item font-lock-property-face -@vindex font-lock-property-face -for properties of an object, such as the declaration and use of fields -in a struct. -This face inherits, by default, from @code{font-lock-variable-name-face}. +@item font-lock-property-name-face +@vindex font-lock-property-name-face +for properties of an object, such as the declaration of fields in a +struct. This face inherits, by default, from +@code{font-lock-variable-name-face}. + +@item font-lock-property-ref-face +@vindex font-lock-property-ref-face +for properties of an object, such as use of fields in a struct. This +face inherits, by default, from @code{font-lock-property-name-face}. For example, diff --git a/etc/NEWS.29 b/etc/NEWS.29 index 7f84d548149..b6c6f2c6362 100644 --- a/etc/NEWS.29 +++ b/etc/NEWS.29 @@ -828,11 +828,12 @@ filter/sentinel error has been handled. +++ ** New faces for font-lock. These faces are primarily meant for use with tree-sitter. They are: +'font-lock-function-call-face', 'font-lock-variable-ref-face', 'font-lock-bracket-face', 'font-lock-delimiter-face', 'font-lock-escape-face', 'font-lock-misc-punctuation-face', 'font-lock-number-face', 'font-lock-operator-face', -'font-lock-property-face', and 'font-lock-punctuation-face', -'font-lock-regexp-face'. +'font-lock-property-name-face', 'font-lock-property-ref-face', +'font-lock-punctuation-face', and 'font-lock-regexp-face'. +++ ** New face 'variable-pitch-text'. diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index dea5dbe9410..46e41dd046c 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -68,13 +68,16 @@ Do not call this mode function yourself. It is meant for internal use." font-lock-comment-delimiter-face font-lock-comment-face font-lock-constant-face font-lock-delimiter-face font-lock-doc-face font-lock-doc-markup-face - font-lock-escape-face font-lock-function-name-face + font-lock-escape-face font-lock-function-call-face + font-lock-function-name-face font-lock-keyword-face font-lock-negation-char-face font-lock-number-face font-lock-misc-punctuation-face font-lock-operator-face font-lock-preprocessor-face - font-lock-property-face font-lock-punctuation-face + font-lock-property-name-face font-lock-property-ref-face + font-lock-punctuation-face font-lock-regexp-grouping-backslash font-lock-regexp-grouping-construct font-lock-string-face font-lock-type-face font-lock-variable-name-face + font-lock-variable-ref-face font-lock-warning-face button link link-visited fringe header-line tooltip mode-line mode-line-buffer-id mode-line-emphasis mode-line-highlight mode-line-inactive diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 456ec06a141..d60e3a9dae7 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -272,6 +272,14 @@ for speeding up processing.") . ,(cdr case))) cases))) +(defsubst byte-opt--fget (f prop) + "Simpler and faster version of `function-get'." + (let ((val nil)) + (while (and (symbolp f) f + (null (setq val (get f prop)))) + (setq f (symbol-function f))) + val)) + (defun byte-optimize-form-code-walker (form for-effect) ;; ;; For normal function calls, We can just mapcar the optimizer the cdr. But @@ -497,7 +505,7 @@ for speeding up processing.") form) ((guard (when for-effect - (if-let ((tmp (get fn 'side-effect-free))) + (if-let ((tmp (byte-opt--fget fn 'side-effect-free))) (or byte-compile-delete-errors (eq tmp 'error-free) (progn @@ -516,7 +524,7 @@ for speeding up processing.") ;; even if the called function is for-effect, because we ;; don't know anything about that function. (let ((form (cons fn (mapcar #'byte-optimize-form (cdr form))))) - (if (get fn 'pure) + (if (byte-opt--fget fn 'pure) (byte-optimize-constant-args form) form)))))) @@ -538,7 +546,7 @@ for speeding up processing.") ;; until a fixpoint has been reached. (and (consp form) (symbolp (car form)) - (let ((opt (function-get (car form) 'byte-optimizer))) + (let ((opt (byte-opt--fget (car form) 'byte-optimizer))) (and opt (let ((old form) (new (funcall opt form))) @@ -1661,7 +1669,7 @@ See Info node `(elisp) Integer Basics'." frame-visible-p fround ftruncate get gethash get-buffer get-buffer-window get-file-buffer hash-table-count - int-to-string intern-soft isnan + intern-soft isnan keymap-parent ldexp length length< length> length= @@ -1675,23 +1683,22 @@ See Info node `(elisp) Integer Basics'." prefix-numeric-value previous-window prin1-to-string propertize rassq rassoc read-from-string regexp-quote region-beginning region-end reverse round - sin sqrt string string< string= string-equal string-lessp - string> + sin sqrt string string-equal string-lessp string-search string-to-char string-to-number string-to-syntax substring - sxhash sxhash-equal sxhash-eq sxhash-eql - symbol-function symbol-name symbol-plist symbol-value string-make-unibyte + sxhash-equal sxhash-eq sxhash-eql + symbol-function symbol-name symbol-plist symbol-value + string-make-unibyte string-make-multibyte string-as-multibyte string-as-unibyte string-to-multibyte take tan time-convert truncate unibyte-char-to-multibyte upcase user-full-name - user-login-name user-original-login-name + user-login-name vconcat window-at window-body-height window-body-width window-buffer window-dedicated-p window-display-table window-combination-limit window-frame window-fringes - window-height window-hscroll window-inside-edges - window-inside-absolute-pixel-edges window-inside-pixel-edges + window-hscroll window-left-child window-left-column window-margins window-minibuffer-p window-next-buffers window-next-sibling window-new-normal window-new-total window-normal-size window-parameter window-parameters @@ -1699,7 +1706,7 @@ See Info node `(elisp) Integer Basics'." window-prev-sibling window-scroll-bars window-start window-text-height window-top-child window-top-line window-total-height window-total-width window-use-time window-vscroll - window-width)) + )) (side-effect-and-error-free-fns '(arrayp atom bobp bolp bool-vector-p @@ -1716,7 +1723,7 @@ See Info node `(elisp) Integer Basics'." keymapp keywordp list listp make-marker mark-marker markerp max-char - natnump nlistp not null number-or-marker-p numberp + natnump nlistp null number-or-marker-p numberp overlayp point point-marker point-min point-max preceding-char processp proper-list-p @@ -1763,11 +1770,11 @@ See Info node `(elisp) Integer Basics'." copysign isnan ldexp float logb floor ceiling round truncate ffloor fceiling fround ftruncate - string= string-equal string< string-lessp string> + string-equal string-lessp string-search consp atom listp nlistp proper-list-p sequencep arrayp vectorp stringp bool-vector-p hash-table-p - null not + null numberp integerp floatp natnump characterp integer-or-marker-p number-or-marker-p char-or-string-p symbolp keywordp diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index b0c9667dc19..095468ad978 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -5079,7 +5079,10 @@ binding slots have been popped." (defun byte-compile-suppressed-warnings (form) (let ((byte-compile--suppressed-warnings (append (cadadr form) byte-compile--suppressed-warnings))) - (byte-compile-form (macroexp-progn (cddr form))))) + ;; Propagate the for-effect mode explicitly so that warnings about + ;; ignored return values can be detected and suppressed correctly. + (byte-compile-form (macroexp-progn (cddr form)) byte-compile--for-effect) + (setq byte-compile--for-effect nil))) ;; Warn about misuses of make-variable-buffer-local. (byte-defop-compiler-1 make-variable-buffer-local diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el index b753adcb8a0..ea2766b8dc4 100644 --- a/lisp/emacs-lisp/package-vc.el +++ b/lisp/emacs-lisp/package-vc.el @@ -309,7 +309,6 @@ asynchronously." (directory (file-name-concat (or (package-desc-dir pkg-desc) (expand-file-name name package-user-dir)) - (plist-get pkg-spec :lisp-dir) (and-let* ((extras (package-desc-extras pkg-desc))) (alist-get :lisp-dir extras)))) (file (or (plist-get pkg-spec :main-file) @@ -615,6 +614,10 @@ PKG-SPEC is a package specification, a property list describing how to fetch and build the package. See `package-vc--archive-spec-alist' for details. The optional argument REV specifies a specific revision to checkout. This overrides the `:branch' attribute in PKG-SPEC." + (unless (eq (package-desc-kind pkg-desc) 'vc) + (let ((copy (copy-package-desc pkg-desc))) + (setf (package-desc-kind copy) 'vc + pkg-desc copy))) (pcase-let* (((map :lisp-dir) pkg-spec) (name (package-desc-name pkg-desc)) (dirname (package-desc-full-name pkg-desc)) @@ -826,9 +829,7 @@ regular package, but it will not remove a VC package. rev))) ((and-let* ((desc (assoc package package-archive-contents #'string=))) (package-vc--unpack - (let ((copy (copy-package-desc (cadr desc)))) - (setf (package-desc-kind copy) 'vc) - copy) + (cadr desc) (or (package-vc--desc->spec (cadr desc)) (and-let* ((extras (package-desc-extras (cadr desc))) (url (alist-get :url extras)) diff --git a/lisp/emacs-lisp/unsafep.el b/lisp/emacs-lisp/unsafep.el index 1d3cde69392..e722cbc52dd 100644 --- a/lisp/emacs-lisp/unsafep.el +++ b/lisp/emacs-lisp/unsafep.el @@ -237,7 +237,7 @@ Otherwise result is a reason code." ((eq (car-safe fun) 'lambda) (unsafep fun unsafep-vars)) ((not (and (symbolp fun) - (or (get fun 'side-effect-free) + (or (function-get fun 'side-effect-free) (eq (get fun 'safe-function) t) (eq safe-functions t) (memq fun safe-functions)))) diff --git a/lisp/font-lock.el b/lisp/font-lock.el index 9e944fe188a..b82b7648797 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -2026,6 +2026,12 @@ as the constructs of Haddock, Javadoc and similar systems." "Font Lock mode face used to highlight function names." :group 'font-lock-faces) +(defface font-lock-function-call-face + '((t :inherit font-lock-function-name-face)) + "Font Lock mode face used to highlight function calls." + :group 'font-lock-faces + :version "29.1") + (defface font-lock-variable-name-face '((((class grayscale) (background light)) :foreground "Gray90" :weight bold :slant italic) @@ -2040,6 +2046,12 @@ as the constructs of Haddock, Javadoc and similar systems." "Font Lock mode face used to highlight variable names." :group 'font-lock-faces) +(defface font-lock-variable-ref-face + '((t :inherit font-lock-variable-name-face)) + "Font Lock mode face used to highlight variable references." + :group 'font-lock-faces + :version "29.1") + (defface font-lock-type-face '((((class grayscale) (background light)) :foreground "Gray90" :weight bold) (((class grayscale) (background dark)) :foreground "DimGray" :weight bold) @@ -2115,10 +2127,17 @@ as the constructs of Haddock, Javadoc and similar systems." :group 'font-lock-faces :version "29.1") -(defface font-lock-property-face +(defface font-lock-property-name-face '((t :inherit font-lock-variable-name-face)) "Font Lock mode face used to highlight properties of an object. -For example, the declaration and use of fields in a struct." +For example, the declaration of fields in a struct." + :group 'font-lock-faces + :version "29.1") + +(defface font-lock-property-ref-face + '((t :inherit font-lock-property-name-face)) + "Font Lock mode face used to highlight property references. +For example, property lookup of fields in a struct." :group 'font-lock-faces :version "29.1") diff --git a/lisp/kmacro.el b/lisp/kmacro.el index 94d8794bd23..64aa7a27bde 100644 --- a/lisp/kmacro.el +++ b/lisp/kmacro.el @@ -376,11 +376,23 @@ and `kmacro-counter-format'.") (defvar kmacro-view-last-item nil) (defvar kmacro-view-item-no 0) +(defun kmacro--to-vector (object) + "Normalize an old-style key sequence to the vector form." + (if (not (stringp object)) + object + (let ((vec (string-to-vector object))) + (unless (multibyte-string-p object) + (dotimes (i (length vec)) + (let ((k (aref vec i))) + (when (> k 127) + (setf (aref vec i) (+ k ?\M-\C-@ -128)))))) + vec))) (defun kmacro-ring-head () "Return pseudo head element in macro ring." (and last-kbd-macro - (kmacro last-kbd-macro kmacro-counter kmacro-counter-format-start))) + (kmacro (kmacro--to-vector last-kbd-macro) + kmacro-counter kmacro-counter-format-start))) (defun kmacro-push-ring (&optional elt) @@ -839,12 +851,8 @@ KEYS should be a vector or a string that obeys `key-valid-p'." (setq format (nth 2 mac)) (setq counter (nth 1 mac)) (setq mac (nth 0 mac))) - (when (stringp mac) - ;; `kmacro' interprets a string according to `key-parse'. - (require 'macros) - (declare-function macro--string-to-vector "macros") - (setq mac (macro--string-to-vector mac))) - (kmacro mac counter format))) + ;; `kmacro' interprets a string according to `key-parse'. + (kmacro (kmacro--to-vector mac) counter format))) (defun kmacro-extract-lambda (mac) "Extract kmacro from a kmacro lambda form." @@ -860,8 +868,6 @@ KEYS should be a vector or a string that obeys `key-valid-p'." (cl-defmethod cl-print-object ((object kmacro) stream) (princ "#f(kmacro " stream) - (require 'macros) - (declare-function macros--insert-vector-macro "macros" (definition)) (let ((vecdef (kmacro--keys object)) (counter (kmacro--counter object)) (format (kmacro--format object))) @@ -943,20 +949,15 @@ Such a \"function\" cannot be called from Lisp, but it is a valid editor command (put symbol 'kmacro t)) -(cl-defstruct (kmacro-register - (:constructor nil) - (:constructor kmacro-make-register (macro))) - macro) +(cl-defmethod register-val-jump-to ((km kmacro) arg) + (funcall km arg)) ;FIXME: η-reduce? -(cl-defmethod register-val-jump-to ((data kmacro-register) _arg) - (kmacro-call-macro current-prefix-arg nil nil (kmacro-register-macro data))) +(cl-defmethod register-val-describe ((km kmacro) _verbose) + (princ (format "a keyboard macro:\n %s" + (key-description (kmacro--keys km))))) -(cl-defmethod register-val-describe ((data kmacro-register) _verbose) - (princ (format "a keyboard macro:\n %s" - (key-description (kmacro-register-macro data))))) - -(cl-defmethod register-val-insert ((data kmacro-register)) - (insert (format-kbd-macro (kmacro-register-macro data)))) +(cl-defmethod register-val-insert ((km kmacro)) + (insert (key-description (kmacro--keys km)))) (defun kmacro-to-register (r) "Store the last keyboard macro in register R. @@ -966,7 +967,7 @@ Interactively, reads the register using `register-read-with-preview'." (progn (or last-kbd-macro (error "No keyboard macro defined")) (list (register-read-with-preview "Save to register: ")))) - (set-register r (kmacro-make-register last-kbd-macro))) + (set-register r (kmacro-ring-head))) (defun kmacro-view-macro (&optional _arg) diff --git a/lisp/macros.el b/lisp/macros.el index 59c7796551f..98ee3dc52f9 100644 --- a/lisp/macros.el +++ b/lisp/macros.el @@ -46,16 +46,6 @@ " ") ?\])) -(defun macro--string-to-vector (str) - "Convert an old-style string key sequence to the vector form." - (let ((vec (string-to-vector str))) - (unless (multibyte-string-p str) - (dotimes (i (length vec)) - (let ((k (aref vec i))) - (when (> k 127) - (setf (aref vec i) (+ k ?\M-\C-@ -128)))))) - vec)) - ;;;###autoload (defun insert-kbd-macro (macroname &optional keys) "Insert in buffer the definition of kbd macro MACRONAME, as Lisp code. @@ -88,10 +78,8 @@ use this command, and then save the file." (insert "(defalias '")) (prin1 macroname (current-buffer)) (insert "\n ") - (when (stringp definition) - (setq definition (macro--string-to-vector definition))) - (if (vectorp definition) - (setq definition (kmacro definition))) + (when (or (stringp definition) (vectorp definition)) + (setq definition (kmacro (kmacro--to-vector definition)))) (if (kmacro-p definition) (let ((vecdef (kmacro--keys definition)) (counter (kmacro--counter definition)) diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index 02ceb2979f7..b9639c1e7f7 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -2467,16 +2467,17 @@ This uses \"avahi-browse\" in case D-Bus is not enabled in Avahi." (delete-dups (mapcar (lambda (x) - (let* ((list (split-string x ";")) - (host (nth 6 list)) - (text (split-string (nth 9 list) "\" \"" 'omit "\"")) - user) - ;; A user is marked in a TXT field like "u=guest". - (while text - (when (string-match (rx "u=" (group (+ nonl)) eol) (car text)) - (setq user (match-string 1 (car text)))) - (setq text (cdr text))) - (list user host))) + (ignore-errors + (let* ((list (split-string x ";")) + (host (nth 6 list)) + (text (split-string (nth 9 list) "\" \"" 'omit "\"")) + user) + ;; A user is marked in a TXT field like "u=guest". + (while text + (when (string-match (rx "u=" (group (+ nonl)) eol) (car text)) + (setq user (match-string 1 (car text)))) + (setq text (cdr text))) + (list user host)))) result)))) (when tramp-gvfs-enabled diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el index 9b271a7cfbd..ad7bf94cdcd 100644 --- a/lisp/net/trampver.el +++ b/lisp/net/trampver.el @@ -102,7 +102,7 @@ ("2.3.3" . "26.1") ("2.3.3.26.1" . "26.1") ("2.3.5.26.2" . "26.2") ("2.3.5.26.3" . "26.3") ("2.4.3.27.1" . "27.1") ("2.4.5.27.2" . "27.2") - ("2.5.2.28.1" . "28.1") ("2.5.3.28.2" . "28.2") + ("2.5.2.28.1" . "28.1") ("2.5.3.28.2" . "28.2") ("2.5.4" . "28.3") ("2.6.0.29.1" . "29.1"))) (add-hook 'tramp-unload-hook diff --git a/lisp/progmodes/c-ts-common.el b/lisp/progmodes/c-ts-common.el index 72df65a2287..85db39aaeae 100644 --- a/lisp/progmodes/c-ts-common.el +++ b/lisp/progmodes/c-ts-common.el @@ -305,6 +305,7 @@ If NODE is nil, return nil." (and parent (string-match-p (car regexp) (treesit-node-type parent)) + (treesit-node-field-name node) (string-match-p (cdr regexp) (treesit-node-field-name node))) @@ -313,7 +314,9 @@ If NODE is nil, return nil." nil)) (defun c-ts-common-statement-offset (node parent &rest _) - "This anchor is used for children of a statement inside a block. + "Return an indent offset for a statement inside a block. + +Assumes the anchor is (point-min), i.e., the 0th column. This function basically counts the number of block nodes (i.e., brackets) (defined by `c-ts-common-indent-block-type-regexp') @@ -324,6 +327,9 @@ To support GNU style, on each block level, this function also checks whether the opening bracket { is on its own line, if so, it adds an extra level, except for the top-level. +It also has special handling for bracketless statements and +else-if statements, which see. + PARENT is NODE's parent, BOL is the beginning of non-whitespace characters on the current line." (let ((level 0)) @@ -363,7 +369,13 @@ characters on the current line." (cl-incf level)) ;; Flatten "else if" statements. (when (and (c-ts-common--node-is node 'else) - (c-ts-common--node-is node 'if)) + (c-ts-common--node-is node 'if) + ;; But if the "if" is on it's own line, still + ;; indent a level. + (not (save-excursion + (goto-char (treesit-node-start node)) + (looking-back (rx bol (* whitespace)) + (line-beginning-position))))) (cl-decf level))) ;; Go up the tree. (setq node (treesit-node-parent node))) diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index b7a487687a8..035df909eb2 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -252,6 +252,33 @@ is actually the parent of point at the moment of indentation." 0 c-ts-mode-indent-offset))) +(defun c-ts-mode--anchor-prev-sibling (node &rest _) + "Return the start of the previous named sibling of NODE. + +This anchor handles the special case where the previous sibling +is a labeled_statement, in that case, return the child of the +labeled statement instead. (Actually, recursively go down until +the node isn't a labeled_statement.) Eg, + +label: + int x = 1; + int y = 2; + +The anchor of \"int y = 2;\" should be \"int x = 1;\" rather than +the labeled_statement. + +Return nil if a) there is no prev-sibling, or 2) prev-sibling +doesn't have a child." + (when-let ((prev-sibling (treesit-node-prev-sibling node t))) + (while (and prev-sibling + (equal "labeled_statement" + (treesit-node-type prev-sibling))) + ;; The 0th child is the label, the 1th the colon. + (setq prev-sibling (treesit-node-child prev-sibling 2))) + ;; This could be nil if a) there is no prev-sibling or b) + ;; prev-sibling doesn't have a child. + (treesit-node-start prev-sibling))) + (defun c-ts-mode--indent-styles (mode) "Indent rules supported by `c-ts-mode'. MODE is either `c' or `cpp'." @@ -277,13 +304,6 @@ MODE is either `c' or `cpp'." ((parent-is "labeled_statement") point-min c-ts-common-statement-offset) - ;; Bracketless statement matchers. - ((match nil "while_statement" "condition") parent-bol c-ts-mode-indent-offset) - ((match nil "if_statement" "consequence") parent-bol c-ts-mode-indent-offset) - ((match nil "if_statement" "alternative") parent-bol c-ts-mode-indent-offset) - ((match nil "do_statement" "body") parent-bol c-ts-mode-indent-offset) - ((match nil "for_statement" "body") parent-bol c-ts-mode-indent-offset) - ((node-is "preproc") point-min 0) ((node-is "#endif") point-min 0) ((match "preproc_call" "compound_statement") point-min 0) @@ -318,14 +338,18 @@ MODE is either `c' or `cpp'." ;; int[5] a = { 0, 0, 0, 0 }; - ((parent-is "initializer_list") parent-bol c-ts-mode-indent-offset) + ((match nil "initializer_list" nil 1 1) parent-bol c-ts-mode-indent-offset) + ((match nil "initializer_list" nil 2) c-ts-mode--anchor-prev-sibling 0) ;; Statement in enum. - ((parent-is "enumerator_list") point-min c-ts-common-statement-offset) + ((match nil "enumerator_list" nil 1 1) point-min c-ts-common-statement-offset) + ((match nil "enumerator_list" nil 2) c-ts-mode--anchor-prev-sibling 0) ;; Statement in struct and union. - ((parent-is "field_declaration_list") point-min c-ts-common-statement-offset) + ((match nil "field_declaration_list" nil 1 1) point-min c-ts-common-statement-offset) + ((match nil "field_declaration_list" nil 2) c-ts-mode--anchor-prev-sibling 0) ;; Statement in {} blocks. - ((parent-is "compound_statement") point-min c-ts-common-statement-offset) + ((match nil "compound_statement" nil 1 1) point-min c-ts-common-statement-offset) + ((match nil "compound_statement" nil 2) c-ts-mode--anchor-prev-sibling 0) ;; Opening bracket. ((node-is "compound_statement") point-min c-ts-common-statement-offset) ;; Bug#61291. @@ -506,7 +530,10 @@ MODE is either `c' or `cpp'." declarator: (_) @c-ts-mode--fontify-declarator) (parameter_declaration - declarator: (_) @c-ts-mode--fontify-declarator)) + declarator: (_) @c-ts-mode--fontify-declarator) + + (enumerator + name: (identifier) @font-lock-property-name-face)) :language mode :feature 'assignment @@ -516,7 +543,7 @@ MODE is either `c' or `cpp'." '((assignment_expression left: (identifier) @font-lock-variable-name-face) (assignment_expression - left: (field_expression field: (_) @font-lock-property-face)) + left: (field_expression field: (_) @font-lock-property-ref-face)) (assignment_expression left: (pointer_expression (identifier) @font-lock-variable-name-face)) @@ -529,8 +556,8 @@ MODE is either `c' or `cpp'." :feature 'function '((call_expression function: - [(identifier) @font-lock-function-name-face - (field_expression field: (field_identifier) @font-lock-function-name-face)])) + [(identifier) @font-lock-function-call-face + (field_expression field: (field_identifier) @font-lock-function-call-face)])) :language mode :feature 'variable @@ -552,9 +579,7 @@ MODE is either `c' or `cpp'." :language mode :feature 'property - '((field_identifier) @font-lock-property-face - (enumerator - name: (identifier) @font-lock-property-face)) + '((field_identifier) @font-lock-property-ref-face) :language mode :feature 'bracket @@ -614,6 +639,7 @@ For NODE, OVERRIDE, START, END, and ARGS, see (face (pcase (treesit-node-type (treesit-node-parent (or qualified-root identifier))) + ("field_declaration" 'font-lock-property-name-face) ("function_declarator" 'font-lock-function-name-face) (_ 'font-lock-variable-name-face)))) (when identifier @@ -630,7 +656,7 @@ OVERRIDE, START, END, and ARGS, see `treesit-font-lock-rules'." "call_expression")) (treesit-fontify-with-override (treesit-node-start node) (treesit-node-end node) - 'font-lock-variable-name-face override start end))) + 'font-lock-variable-ref-face override start end))) (defun c-ts-mode--fontify-defun (node override start end &rest _) "Correctly fontify the DEFUN macro. diff --git a/lisp/progmodes/cmake-ts-mode.el b/lisp/progmodes/cmake-ts-mode.el index 04f5d6bdac8..a3f9279ec1c 100644 --- a/lisp/progmodes/cmake-ts-mode.el +++ b/lisp/progmodes/cmake-ts-mode.el @@ -125,7 +125,7 @@ :language 'cmake :feature 'function - '((normal_command (identifier) @font-lock-function-name-face)) + '((normal_command (identifier) @font-lock-function-call-face)) :language 'cmake :feature 'keyword @@ -154,7 +154,7 @@ :language 'cmake :feature 'variable :override t - '((variable) @font-lock-variable-name-face) + '((variable) @font-lock-variable-ref-face) :language 'cmake :feature 'error diff --git a/lisp/progmodes/csharp-mode.el b/lisp/progmodes/csharp-mode.el index 239c85ce25f..4ed8b0368b5 100644 --- a/lisp/progmodes/csharp-mode.el +++ b/lisp/progmodes/csharp-mode.el @@ -708,9 +708,9 @@ compilation and evaluation time conflicts." (treesit-font-lock-rules :language 'c-sharp :feature 'expression - '((conditional_expression (identifier) @font-lock-variable-name-face) - (postfix_unary_expression (identifier)* @font-lock-variable-name-face) - (initializer_expression (assignment_expression left: (identifier) @font-lock-variable-name-face))) + '((conditional_expression (identifier) @font-lock-variable-ref-face) + (postfix_unary_expression (identifier)* @font-lock-variable-ref-face) + (initializer_expression (assignment_expression left: (identifier) @font-lock-variable-ref-face))) :language 'c-sharp :feature 'bracket @@ -739,8 +739,8 @@ compilation and evaluation time conflicts." :language 'c-sharp :override t :feature 'property - `((attribute (identifier) @font-lock-property-face (attribute_argument_list)) - (attribute (identifier) @font-lock-property-face)) + `((attribute (identifier) @font-lock-property-ref-face (attribute_argument_list)) + (attribute (identifier) @font-lock-property-ref-face)) :language 'c-sharp :override t @@ -859,14 +859,14 @@ compilation and evaluation time conflicts." :feature 'function '((invocation_expression function: (member_access_expression - name: (identifier) @font-lock-function-name-face)) + name: (identifier) @font-lock-function-call-face)) (invocation_expression - function: (identifier) @font-lock-function-name-face) + function: (identifier) @font-lock-function-call-face) (invocation_expression function: (member_access_expression - name: (generic_name (identifier) @font-lock-function-name-face))) + name: (generic_name (identifier) @font-lock-function-call-face))) (invocation_expression - function: (generic_name (identifier) @font-lock-function-name-face))) + function: (generic_name (identifier) @font-lock-function-call-face))) :language 'c-sharp :feature 'escape-sequence @@ -878,23 +878,23 @@ compilation and evaluation time conflicts." :override t '((if_directive "if" @font-lock-preprocessor-face - (identifier) @font-lock-variable-name-face) + (identifier) @font-lock-variable-ref-face) (elif_directive "elif" @font-lock-preprocessor-face - (identifier) @font-lock-variable-name-face) + (identifier) @font-lock-variable-ref-face) (else_directive) @font-lock-preprocessor-face (endif_directive) @font-lock-preprocessor-face (define_directive "define" @font-lock-preprocessor-face - (identifier) @font-lock-variable-name-face) + (identifier) @font-lock-variable-ref-face) (nullable_directive) @font-lock-preprocessor-face (pragma_directive) @font-lock-preprocessor-face (region_directive) @font-lock-preprocessor-face (endregion_directive) @font-lock-preprocessor-face (region_directive - (preproc_message) @font-lock-variable-name-face) + (preproc_message) @font-lock-variable-ref-face) (endregion_directive - (preproc_message) @font-lock-variable-name-face)))) + (preproc_message) @font-lock-variable-ref-face)))) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-mode)) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 4a09da65e53..d0e899cbed5 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -3492,12 +3492,15 @@ If NOERROR, return predicate, else erroring function." (defvar-local eglot--outstanding-inlay-hints-region (cons nil nil) "Jit-lock-calculated (FROM . TO) region with potentially outdated hints") +(defvar-local eglot--outstanding-inlay-hints-last-region nil) + (defvar-local eglot--outstanding-inlay-regions-timer nil "Helper timer for `eglot--update-hints'") (defun eglot--update-hints (from to) "Jit-lock function for Eglot inlay hints." (cl-symbol-macrolet ((region eglot--outstanding-inlay-hints-region) + (last-region eglot--outstanding-inlay-hints-last-region) (timer eglot--outstanding-inlay-regions-timer)) (setcar region (min (or (car region) (point-max)) from)) (setcdr region (max (or (cdr region) (point-min)) to)) @@ -3513,12 +3516,28 @@ If NOERROR, return predicate, else erroring function." ;; not introducing any more delay over jit-lock's timers. (when (= jit-lock-context-unfontify-pos (point-max)) (if timer (cancel-timer timer)) - (setq timer (run-at-time - 0 nil - (lambda () - (eglot--update-hints-1 (max (car region) (point-min)) - (min (cdr region) (point-max))) - (setq region (cons nil nil) timer nil))))))) + (let ((buf (current-buffer))) + (setq timer (run-at-time + 0 nil + (lambda () + (eglot--when-live-buffer buf + ;; HACK: In some pathological situations + ;; (Emacs's own coding.c, for example), + ;; jit-lock is calling `eglot--update-hints' + ;; repeatedly with same sequence of + ;; arguments, which leads to + ;; `eglot--update-hints-1' being called with + ;; the same region repeatedly. This happens + ;; even if the hint-painting code does + ;; nothing else other than widen, narrow, + ;; move point then restore these things. + ;; Possible Emacs bug, but this fixes it. + (unless (equal last-region region) + (eglot--update-hints-1 (max (car region) (point-min)) + (min (cdr region) (point-max))) + (setq last-region region)) + (setq region (cons nil nil) + timer nil))))))))) (defun eglot--update-hints-1 (from to) "Do most work for `eglot--update-hints', including LSP request." @@ -3529,7 +3548,8 @@ If NOERROR, return predicate, else erroring function." (let ((ov (make-overlay (point) (point))) (left-pad (and paddingLeft (not (memq (char-before) '(32 9))))) (right-pad (and paddingRight (not (memq (char-after) '(32 9))))) - (text (if (stringp label) label (plist-get label :value)))) + (text (if (stringp label) + label (plist-get (elt label 0) :value)))) (overlay-put ov 'before-string (propertize (concat (and left-pad " ") text (and right-pad " ")) diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el index 2a2783f45f6..0e019f5bad9 100644 --- a/lisp/progmodes/go-ts-mode.el +++ b/lisp/progmodes/go-ts-mode.el @@ -134,7 +134,7 @@ (method_spec name: (field_identifier) @font-lock-function-name-face) (field_declaration - name: (field_identifier) @font-lock-property-face) + name: (field_identifier) @font-lock-property-name-face) (parameter_declaration name: (identifier) @font-lock-variable-name-face) (short_var_declaration @@ -147,10 +147,10 @@ :language 'go :feature 'function '((call_expression - function: (identifier) @font-lock-function-name-face) + function: (identifier) @font-lock-function-call-face) (call_expression function: (selector_expression - field: (field_identifier) @font-lock-function-name-face))) + field: (field_identifier) @font-lock-function-call-face))) :language 'go :feature 'keyword @@ -178,12 +178,12 @@ :language 'go :feature 'property - '((field_identifier) @font-lock-property-face - (keyed_element (_ (identifier) @font-lock-property-face))) + '((selector_expression field: (field_identifier) @font-lock-property-ref-face) + (keyed_element (_ (identifier) @font-lock-property-ref-face))) :language 'go :feature 'variable - '((identifier) @font-lock-variable-name-face) + '((identifier) @font-lock-variable-ref-face) :language 'go :feature 'escape-sequence diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el index 0560cc33244..54ed8b4277d 100644 --- a/lisp/progmodes/java-ts-mode.el +++ b/lisp/progmodes/java-ts-mode.el @@ -220,7 +220,7 @@ (method_reference (identifier) @font-lock-type-face) - (scoped_identifier (identifier) @font-lock-variable-name-face) + (scoped_identifier (identifier) @font-lock-constant-face) ((scoped_identifier name: (identifier) @font-lock-type-face) (:match "^[A-Z]" @font-lock-type-face)) @@ -244,7 +244,7 @@ name: (identifier) @font-lock-variable-name-face) (element_value_pair - key: (identifier) @font-lock-property-face) + key: (identifier) @font-lock-property-ref-face) (formal_parameter name: (identifier) @font-lock-variable-name-face) @@ -255,14 +255,14 @@ :override t :feature 'expression '((method_invocation - object: (identifier) @font-lock-variable-name-face) + object: (identifier) @font-lock-variable-ref-face) (method_invocation - name: (identifier) @font-lock-function-name-face) + name: (identifier) @font-lock-function-call-face) (argument_list (identifier) @font-lock-variable-name-face) - (expression_statement (identifier) @font-lock-variable-name-face)) + (expression_statement (identifier) @font-lock-variable-ref-face)) :language 'java :feature 'bracket diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index dc49d7e818c..93298f4fb6e 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -3544,11 +3544,10 @@ This function is intended for use in `after-change-functions'." value: [(function) (arrow_function)]) (variable_declarator - name: (array_pattern - (identifier) - (identifier) - @font-lock-function-name-face) - value: (array (number) (function))) + name: [(array_pattern (identifier) @font-lock-variable-name-face) + (object_pattern + (shorthand_property_identifier_pattern) @font-lock-variable-name-face)]) + ;; full module imports (import_clause (identifier) @font-lock-variable-name-face) ;; named imports with aliasing @@ -3564,15 +3563,13 @@ This function is intended for use in `after-change-functions'." :language 'javascript :feature 'property - '(((property_identifier) @font-lock-property-face + '(((property_identifier) @font-lock-property-ref-face (:pred js--treesit-property-not-function-p - @font-lock-property-face)) + @font-lock-property-ref-face)) - (pair value: (identifier) @font-lock-variable-name-face) + (pair value: (identifier) @font-lock-variable-ref-face) - ((shorthand_property_identifier) @font-lock-property-face) - - ((shorthand_property_identifier_pattern) @font-lock-property-face)) + ((shorthand_property_identifier) @font-lock-property-ref-face)) :language 'javascript :feature 'assignment @@ -3582,14 +3579,14 @@ This function is intended for use in `after-change-functions'." :language 'javascript :feature 'function '((call_expression - function: [(identifier) @font-lock-function-name-face + function: [(identifier) @font-lock-function-call-face (member_expression property: - (property_identifier) @font-lock-function-name-face)]) + (property_identifier) @font-lock-function-call-face)]) (method_definition name: (property_identifier) @font-lock-function-name-face) (function_declaration - name: (identifier) @font-lock-function-name-face) + name: (identifier) @font-lock-function-call-face) (function name: (identifier) @font-lock-function-name-face)) @@ -3597,15 +3594,15 @@ This function is intended for use in `after-change-functions'." :feature 'jsx '((jsx_opening_element [(nested_identifier (identifier)) (identifier)] - @font-lock-function-name-face) + @font-lock-function-call-face) (jsx_closing_element [(nested_identifier (identifier)) (identifier)] - @font-lock-function-name-face) + @font-lock-function-call-face) (jsx_self_closing_element [(nested_identifier (identifier)) (identifier)] - @font-lock-function-name-face) + @font-lock-function-call-face) (jsx_attribute (property_identifier) @@ -3684,8 +3681,8 @@ For OVERRIDE, START, END, see `treesit-font-lock-rules'." (treesit-fontify-with-override (treesit-node-start node) (treesit-node-end node) (pcase (treesit-node-type node) - ("identifier" 'font-lock-variable-name-face) - ("property_identifier" 'font-lock-property-face)) + ("identifier" 'font-lock-variable-ref-face) + ("property_identifier" 'font-lock-property-ref-face)) override start end))) (defun js--treesit-defun-name (node) diff --git a/lisp/progmodes/json-ts-mode.el b/lisp/progmodes/json-ts-mode.el index 6bd9d30328e..c5979b9a14c 100644 --- a/lisp/progmodes/json-ts-mode.el +++ b/lisp/progmodes/json-ts-mode.el @@ -101,7 +101,7 @@ :language 'json :feature 'pair :override t ; Needed for overriding string face on keys. - '((pair key: (_) @font-lock-variable-name-face)) + '((pair key: (_) @font-lock-property-ref-face)) :language 'json :feature 'error :override t diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index eab5e70af33..8220e3086fd 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1106,25 +1106,26 @@ fontified." :language 'python '((interpolation) @python--treesit-fontify-string-interpolation) - :feature 'definition - :language 'python - '((function_definition - name: (identifier) @font-lock-function-name-face) - (class_definition - name: (identifier) @font-lock-type-face)) - - :feature 'function - :language 'python - '((call function: (identifier) @font-lock-function-name-face) - (call function: (attribute - attribute: (identifier) @font-lock-function-name-face))) - :feature 'keyword :language 'python `([,@python--treesit-keywords] @font-lock-keyword-face ((identifier) @font-lock-keyword-face (:match "^self$" @font-lock-keyword-face))) + :feature 'definition + :language 'python + '((function_definition + name: (identifier) @font-lock-function-name-face) + (class_definition + name: (identifier) @font-lock-type-face) + (parameters (identifier) @font-lock-variable-name-face)) + + :feature 'function + :language 'python + '((call function: (identifier) @font-lock-function-call-face) + (call function: (attribute + attribute: (identifier) @font-lock-function-call-face))) + :feature 'builtin :language 'python `(((identifier) @font-lock-builtin-face @@ -1146,7 +1147,7 @@ fontified." @font-lock-variable-name-face) (assignment left: (attribute attribute: (identifier) - @font-lock-property-face)) + @font-lock-property-ref-face)) (pattern_list (identifier) @font-lock-variable-name-face) (tuple_pattern (identifier) @@ -1183,12 +1184,12 @@ fontified." :feature 'property :language 'python '((attribute - attribute: (identifier) @font-lock-property-face) + attribute: (identifier) @font-lock-property-ref-face) (class_definition body: (block (expression_statement (assignment left: - (identifier) @font-lock-property-face))))) + (identifier) @font-lock-property-ref-face))))) :feature 'operator :language 'python @@ -1211,10 +1212,10 @@ fontified." "Check whether NODE is a variable. NODE's type should be \"identifier\"." ;; An identifier can be a function/class name, a property, or a - ;; variables. This function filters out function/class names and - ;; properties. + ;; variables. This function filters out function/class names, + ;; properties and method parameters. (pcase (treesit-node-type (treesit-node-parent node)) - ((or "function_definition" "class_definition") nil) + ((or "function_definition" "class_definition" "parameters") nil) ("attribute" (pcase (treesit-node-field-name node) ("object" t) diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el index f15387c91bc..f70c0279d3d 100644 --- a/lisp/progmodes/ruby-ts-mode.el +++ b/lisp/progmodes/ruby-ts-mode.el @@ -292,11 +292,11 @@ values of OVERRIDE" :language language :feature 'global - '((global_variable) @font-lock-variable-name-face) + '((global_variable) @font-lock-variable-ref-face) :language language :feature 'instance - '((instance_variable) @font-lock-variable-name-face) + '((instance_variable) @font-lock-variable-ref-face) :language language :feature 'method-definition @@ -350,7 +350,7 @@ values of OVERRIDE" :language language :feature 'function '((call - method: (identifier) @font-lock-function-name-face)) + method: (identifier) @font-lock-function-call-face)) :language language :feature 'assignment diff --git a/lisp/progmodes/rust-ts-mode.el b/lisp/progmodes/rust-ts-mode.el index ee73ebf7a9f..a46d442a0e5 100644 --- a/lisp/progmodes/rust-ts-mode.el +++ b/lisp/progmodes/rust-ts-mode.el @@ -157,7 +157,7 @@ '((function_item name: (identifier) @font-lock-function-name-face) (macro_definition "macro_rules!" @font-lock-constant-face) (macro_definition (identifier) @font-lock-preprocessor-face) - (field_declaration name: (field_identifier) @font-lock-property-face) + (field_declaration name: (field_identifier) @font-lock-property-name-face) (parameter pattern: (_) @rust-ts-mode--fontify-pattern) (closure_parameters (_) @rust-ts-mode--fontify-pattern) (let_declaration pattern: (_) @rust-ts-mode--fontify-pattern) @@ -174,17 +174,17 @@ :feature 'function '((call_expression function: - [(identifier) @font-lock-function-name-face + [(identifier) @font-lock-function-call-face (field_expression - field: (field_identifier) @font-lock-function-name-face) + field: (field_identifier) @font-lock-function-call-face) (scoped_identifier - name: (identifier) @font-lock-function-name-face)]) + name: (identifier) @font-lock-function-call-face)]) (generic_function - function: [(identifier) @font-lock-function-name-face + function: [(identifier) @font-lock-function-call-face (field_expression - field: (field_identifier) @font-lock-function-name-face) + field: (field_identifier) @font-lock-function-call-face) (scoped_identifier - name: (identifier) @font-lock-function-name-face)]) + name: (identifier) @font-lock-function-call-face)]) (macro_invocation macro: (identifier) @font-lock-preprocessor-face)) :language 'rust @@ -239,8 +239,8 @@ :language 'rust :feature 'property - '((field_identifier) @font-lock-property-face - (shorthand_field_initializer (identifier) @font-lock-property-face)) + '((field_identifier) @font-lock-property-ref-face + (shorthand_field_initializer (identifier) @font-lock-property-ref-face)) ;; Must be under type, otherwise some imports can be highlighted as constants. :language 'rust @@ -251,25 +251,25 @@ :language 'rust :feature 'variable - '((arguments (identifier) @font-lock-variable-name-face) - (array_expression (identifier) @font-lock-variable-name-face) - (assignment_expression right: (identifier) @font-lock-variable-name-face) - (binary_expression left: (identifier) @font-lock-variable-name-face) - (binary_expression right: (identifier) @font-lock-variable-name-face) - (block (identifier) @font-lock-variable-name-face) - (compound_assignment_expr right: (identifier) @font-lock-variable-name-face) - (field_expression value: (identifier) @font-lock-variable-name-face) - (field_initializer value: (identifier) @font-lock-variable-name-face) - (if_expression condition: (identifier) @font-lock-variable-name-face) - (let_condition value: (identifier) @font-lock-variable-name-face) - (let_declaration value: (identifier) @font-lock-variable-name-face) - (match_arm value: (identifier) @font-lock-variable-name-face) - (match_expression value: (identifier) @font-lock-variable-name-face) - (reference_expression value: (identifier) @font-lock-variable-name-face) - (return_expression (identifier) @font-lock-variable-name-face) - (tuple_expression (identifier) @font-lock-variable-name-face) - (unary_expression (identifier) @font-lock-variable-name-face) - (while_expression condition: (identifier) @font-lock-variable-name-face)) + '((arguments (identifier) @font-lock-variable-ref-face) + (array_expression (identifier) @font-lock-variable-ref-face) + (assignment_expression right: (identifier) @font-lock-variable-ref-face) + (binary_expression left: (identifier) @font-lock-variable-ref-face) + (binary_expression right: (identifier) @font-lock-variable-ref-face) + (block (identifier) @font-lock-variable-ref-face) + (compound_assignment_expr right: (identifier) @font-lock-variable-ref-face) + (field_expression value: (identifier) @font-lock-variable-ref-face) + (field_initializer value: (identifier) @font-lock-variable-ref-face) + (if_expression condition: (identifier) @font-lock-variable-ref-face) + (let_condition value: (identifier) @font-lock-variable-ref-face) + (let_declaration value: (identifier) @font-lock-variable-ref-face) + (match_arm value: (identifier) @font-lock-variable-ref-face) + (match_expression value: (identifier) @font-lock-variable-ref-face) + (reference_expression value: (identifier) @font-lock-variable-ref-face) + (return_expression (identifier) @font-lock-variable-ref-face) + (tuple_expression (identifier) @font-lock-variable-ref-face) + (unary_expression (identifier) @font-lock-variable-ref-face) + (while_expression condition: (identifier) @font-lock-variable-ref-face)) :language 'rust :feature 'escape-sequence diff --git a/lisp/progmodes/typescript-ts-mode.el b/lisp/progmodes/typescript-ts-mode.el index 1646776ce95..d907608d0db 100644 --- a/lisp/progmodes/typescript-ts-mode.el +++ b/lisp/progmodes/typescript-ts-mode.el @@ -245,16 +245,13 @@ Argument LANGUAGE is either `typescript' or `tsx'." :language language :feature 'property `((property_signature - name: (property_identifier) @font-lock-property-face) + name: (property_identifier) @font-lock-property-name-face) (public_field_definition - name: (property_identifier) @font-lock-property-face) + name: (property_identifier) @font-lock-property-name-face) - (pair key: (property_identifier) @font-lock-variable-name-face) + (pair key: (property_identifier) @font-lock-property-ref-face) - ((shorthand_property_identifier) @font-lock-property-face) - - ((shorthand_property_identifier_pattern) - @font-lock-property-face)) + ((shorthand_property_identifier) @font-lock-property-ref-face)) :language language :feature 'expression @@ -268,30 +265,34 @@ Argument LANGUAGE is either `typescript' or `tsx'." :feature 'function '((call_expression function: - [(identifier) @font-lock-function-name-face + [(identifier) @font-lock-function-call-face (member_expression - property: (property_identifier) @font-lock-function-name-face)])) + property: (property_identifier) @font-lock-function-call-face)])) :language language :feature 'pattern `((pair_pattern - key: (property_identifier) @font-lock-property-face) + key: (property_identifier) @font-lock-property-ref-face + value: [(identifier) @font-lock-variable-name-face + (assignment_pattern left: (identifier) @font-lock-variable-name-face)]) - (array_pattern (identifier) @font-lock-variable-name-face)) + (array_pattern (identifier) @font-lock-variable-name-face) + + ((shorthand_property_identifier_pattern) @font-lock-variable-name-face)) :language language :feature 'jsx `((jsx_opening_element [(nested_identifier (identifier)) (identifier)] - @font-lock-function-name-face) + @font-lock-function-call-face) (jsx_closing_element [(nested_identifier (identifier)) (identifier)] - @font-lock-function-name-face) + @font-lock-function-call-face) (jsx_self_closing_element [(nested_identifier (identifier)) (identifier)] - @font-lock-function-name-face) + @font-lock-function-call-face) (jsx_attribute (property_identifier) @font-lock-constant-face)) diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index a1d7d4bbbec..39e38179359 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -1399,9 +1399,8 @@ for determining whether point is within a selector." :feature 'query :language 'css - '((keyword_query) @font-lock-property-face - (feature_name) @font-lock-property-face) - + '((keyword_query) @font-lock-property-ref-face + (feature_name) @font-lock-property-ref-face) :feature 'bracket :language 'css diff --git a/lisp/textmodes/toml-ts-mode.el b/lisp/textmodes/toml-ts-mode.el index 416542084f1..2ff9d07d13b 100644 --- a/lisp/textmodes/toml-ts-mode.el +++ b/lisp/textmodes/toml-ts-mode.el @@ -92,8 +92,8 @@ :language 'toml :feature 'pair :override t ; Needed for overriding string face on keys. - '((bare_key) @font-lock-property-face - (quoted_key) @font-lock-property-face + '((bare_key) @font-lock-property-ref-face + (quoted_key) @font-lock-property-ref-face (table ("[" @font-lock-bracket-face (_) @font-lock-type-face "]" @font-lock-bracket-face)) diff --git a/lisp/textmodes/yaml-ts-mode.el b/lisp/textmodes/yaml-ts-mode.el index a25230e6e61..dc0fa00df27 100644 --- a/lisp/textmodes/yaml-ts-mode.el +++ b/lisp/textmodes/yaml-ts-mode.el @@ -94,22 +94,22 @@ :feature 'property :override t '((block_mapping_pair - key: (flow_node (plain_scalar (string_scalar) @font-lock-property-face))) + key: (flow_node (plain_scalar (string_scalar) @font-lock-property-ref-face))) (block_mapping_pair key: (flow_node - [(double_quote_scalar) (single_quote_scalar)] @font-lock-property-face)) + [(double_quote_scalar) (single_quote_scalar)] @font-lock-property-ref-face)) (flow_mapping - (_ key: (flow_node (plain_scalar (string_scalar) @font-lock-property-face)))) + (_ key: (flow_node (plain_scalar (string_scalar) @font-lock-property-ref-face)))) (flow_mapping (_ key: (flow_node - [(double_quote_scalar) (single_quote_scalar)] @font-lock-property-face))) + [(double_quote_scalar) (single_quote_scalar)] @font-lock-property-ref-face))) (flow_sequence - (_ key: (flow_node (plain_scalar (string_scalar) @font-lock-property-face)))) + (_ key: (flow_node (plain_scalar (string_scalar) @font-lock-property-ref-face)))) (flow_sequence (_ key: (flow_node - [(double_quote_scalar) (single_quote_scalar)] @font-lock-property-face)))) + [(double_quote_scalar) (single_quote_scalar)] @font-lock-property-ref-face)))) :language 'yaml :feature 'error diff --git a/lisp/treesit.el b/lisp/treesit.el index 644a8018ad2..a413311e824 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -1533,7 +1533,7 @@ Similar to `treesit-indent', but indent a region instead." (dotimes (jdx idx) (let ((anchor (aref meta-vec (* jdx meta-len))) (offset (aref meta-vec (+ 1 (* jdx meta-len))))) - (when offset + (when (and anchor offset) (let ((col (save-excursion (goto-char anchor) (+ offset (current-column))))) diff --git a/lisp/wdired.el b/lisp/wdired.el index 771458508e6..5572dcb32f3 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -455,6 +455,7 @@ non-nil means return old filename." (setq major-mode 'dired-mode) (setq mode-name "Dired") (dired-advertise) + (dired-hide-details-update-invisibility-spec) (remove-hook 'kill-buffer-hook #'wdired-check-kill-buffer t) (remove-hook 'before-change-functions #'wdired--before-change-fn t) (remove-hook 'after-change-functions #'wdired--restore-properties t) diff --git a/src/macros.c b/src/macros.c index 0db0af89a71..d1541d2817f 100644 --- a/src/macros.c +++ b/src/macros.c @@ -128,9 +128,9 @@ end_kbd_macro (void) update_mode_lines = 20; kset_last_kbd_macro (current_kboard, - make_event_array ((current_kboard->kbd_macro_end - - current_kboard->kbd_macro_buffer), - current_kboard->kbd_macro_buffer)); + Fvector ((current_kboard->kbd_macro_end + - current_kboard->kbd_macro_buffer), + current_kboard->kbd_macro_buffer)); } DEFUN ("end-kbd-macro", Fend_kbd_macro, Send_kbd_macro, 0, 2, "p", diff --git a/src/xfaces.c b/src/xfaces.c index 4207b73ee25..953e5be3781 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -4223,7 +4223,9 @@ Default face attributes override any local face attributes. */) if (EQ (face, Qdefault)) { struct face_cache *c = FRAME_FACE_CACHE (f); - struct face *newface, *oldface = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID); + struct face *newface; + struct face *oldface = + c ? FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID) : NULL; Lisp_Object attrs[LFACE_VECTOR_SIZE]; /* This can be NULL (e.g., in batch mode). */ diff --git a/test/lisp/kmacro-tests.el b/test/lisp/kmacro-tests.el index 551fd8b60fc..a325220e8d9 100644 --- a/test/lisp/kmacro-tests.el +++ b/test/lisp/kmacro-tests.el @@ -614,6 +614,20 @@ This is a regression test for: Bug#3412, Bug#11817." (kmacro-tests-should-insert "bb" (kmacro-tests-simulate-command '(kmacro-tests-symbol-for-test)))) +;; Bug#61700 inserting named macro when the definition contains things +;; that `key-parse' thinks are named keys +(kmacro-tests-deftest kmacro-tests-name-last-macro-key-parse-syntax () + "Name last macro can rebind a symbol it binds." + ;; Make sure our symbol is unbound. + (when (fboundp 'kmacro-tests-symbol-for-test) + (fmakunbound 'kmacro-tests-symbol-for-test)) + (setplist 'kmacro-tests-symbol-for-test nil) + (kmacro-tests-define-macro " hello ") + (kmacro-name-last-macro 'kmacro-tests-symbol-for-test) + ;; Now run the function bound to the symbol. + (kmacro-tests-should-insert " hello " + (kmacro-tests-simulate-command '(kmacro-tests-symbol-for-test)))) + (kmacro-tests-deftest kmacro-tests-store-in-register () "Macro can be stored in and retrieved from a register." (use-local-map kmacro-tests-keymap) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 97fada91fa2..f19847b0103 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -4557,8 +4557,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." ;; Complete host name. (unless (or (tramp-string-empty-or-nil-p method) (string-empty-p tramp-method-regexp) - (tramp-string-empty-or-nil-p host) - (tramp--test-gvfs-p method)) + (tramp-string-empty-or-nil-p host)) (should (member (concat @@ -4640,171 +4639,181 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." ;; and Bug#60505. (ert-deftest tramp-test26-interactive-file-name-completion () "Check interactive completion with different `completion-styles'." - (tramp-cleanup-connection tramp-test-vec nil 'keep-password) - ;; Method, user and host name in completion mode. This kind of ;; completion does not work on MS Windows. - (unless (memq system-type '(cygwin windows-nt)) - (let ((method (file-remote-p ert-remote-temporary-file-directory 'method)) - (user (file-remote-p ert-remote-temporary-file-directory 'user)) - (host (file-remote-p ert-remote-temporary-file-directory 'host)) - (hop (file-remote-p ert-remote-temporary-file-directory 'hop)) - (orig-syntax tramp-syntax) - (non-essential t) - (inhibit-message t)) - (when (and (stringp host) (string-match tramp-host-with-port-regexp host)) - (setq host (match-string 1 host))) + (skip-unless (not (memq system-type '(cygwin windows-nt)))) + (tramp-cleanup-connection tramp-test-vec nil 'keep-password) - ;; (trace-function #'tramp-completion-file-name-handler) - ;; (trace-function #'completion-file-name-table) - (unwind-protect - (dolist (syntax (if (tramp--test-expensive-test-p) - (tramp-syntax-values) `(,orig-syntax))) - (tramp-change-syntax syntax) - ;; This has cleaned up all connection data, which are used - ;; for completion. We must refill the cache. - (tramp-set-connection-property tramp-test-vec "property" nil) + (let ((method (file-remote-p ert-remote-temporary-file-directory 'method)) + (user (file-remote-p ert-remote-temporary-file-directory 'user)) + (host (file-remote-p ert-remote-temporary-file-directory 'host)) + (hop (file-remote-p ert-remote-temporary-file-directory 'hop)) + (orig-syntax tramp-syntax) + (non-essential t) + (inhibit-message t)) + (when (and (stringp host) (string-match tramp-host-with-port-regexp host)) + (setq host (match-string 1 host))) - (dolist - (style - (if (tramp--test-expensive-test-p) - ;; It doesn't work for `initials' and `shorthand' - ;; completion styles. Should it? - '(emacs21 emacs22 basic partial-completion substring flex) - '(basic))) + ;; (trace-function #'tramp-completion-file-name-handler) + ;; (trace-function #'completion-file-name-table) + (unwind-protect + (dolist (syntax (if (tramp--test-expensive-test-p) + (tramp-syntax-values) `(,orig-syntax))) + (tramp-change-syntax syntax) + ;; This has cleaned up all connection data, which are used + ;; for completion. We must refill the cache. + (tramp-set-connection-property tramp-test-vec "property" nil) - (when (assoc style completion-styles-alist) - (let (;; Force the real minibuffer in batch mode. - (executing-kbd-macro noninteractive) - (completion-styles `(,style)) - (completions-format 'one-column) - completion-category-defaults - completion-category-overrides - ;; This is needed for the `simplified' syntax, - (tramp-default-method method) - (method-string - (unless (string-empty-p tramp-method-regexp) - (concat method tramp-postfix-method-format))) - ;; This is needed for the IPv6 host name syntax. - (ipv6-prefix - (and (string-match-p tramp-ipv6-regexp host) - tramp-prefix-ipv6-format)) - (ipv6-postfix - (and (string-match-p tramp-ipv6-regexp host) - tramp-postfix-ipv6-format)) - ;; The hop string fits only the initial syntax. - (hop (and (eq tramp-syntax orig-syntax) hop)) - test result completions) + (dolist + (style + (if (tramp--test-expensive-test-p) + ;; It doesn't work for `initials' and `shorthand' + ;; completion styles. Should it? + '(emacs21 emacs22 basic partial-completion substring flex) + '(basic))) - (dolist - (test-and-result - ;; These are triples (TEST-STRING RESULT-CHECK - ;; COMPLETION-CHECK). - (append - ;; Complete method name. - (unless (string-empty-p tramp-method-regexp) - `((,(concat - tramp-prefix-format hop - (substring-no-properties - method 0 (min 2 (length method)))) - ,(concat tramp-prefix-format method-string) - ,method-string))) - ;; Complete user name. - (unless (tramp-string-empty-or-nil-p user) - `((,(concat - tramp-prefix-format hop method-string - (substring-no-properties - user 0 (min 2 (length user)))) - ,(concat - tramp-prefix-format method-string - user tramp-postfix-user-format) - ,(concat - user tramp-postfix-user-format)))) - ;; Complete host name. - (unless (tramp-string-empty-or-nil-p host) - `((,(concat - tramp-prefix-format hop method-string - ipv6-prefix - (substring-no-properties - host 0 (min 2 (length host)))) - ,(concat - tramp-prefix-format method-string - ipv6-prefix host - ipv6-postfix tramp-postfix-host-format) - ,(concat - ipv6-prefix host - ipv6-postfix tramp-postfix-host-format)))) - ;; Complete user and host name. - (unless (or (tramp-string-empty-or-nil-p user) - (tramp-string-empty-or-nil-p host)) - `((,(concat - tramp-prefix-format hop method-string - user tramp-postfix-user-format - ipv6-prefix - (substring-no-properties - host 0 (min 2 (length host)))) - ,(concat - tramp-prefix-format method-string - user tramp-postfix-user-format - ipv6-prefix host - ipv6-postfix tramp-postfix-host-format) - ,(concat - ipv6-prefix host - ipv6-postfix tramp-postfix-host-format)))))) + (when (assoc style completion-styles-alist) + (let* (;; Force the real minibuffer in batch mode. + (executing-kbd-macro noninteractive) + (completion-styles `(,style)) + completion-category-defaults + completion-category-overrides + ;; This is needed for the `simplified' syntax, + (tramp-default-method method) + (method-string + (unless (string-empty-p tramp-method-regexp) + (concat method tramp-postfix-method-format))) + (user-string + (unless (tramp-string-empty-or-nil-p user) + (concat user tramp-postfix-user-format))) + ;; This is needed for the IPv6 host name syntax. + (ipv6-prefix + (and (string-match-p tramp-ipv6-regexp host) + tramp-prefix-ipv6-format)) + (ipv6-postfix + (and (string-match-p tramp-ipv6-regexp host) + tramp-postfix-ipv6-format)) + (host-string + (unless (tramp-string-empty-or-nil-p host) + (concat + ipv6-prefix host + ipv6-postfix tramp-postfix-host-format))) + ;; The hop string fits only the initial syntax. + (hop (and (eq tramp-syntax orig-syntax) hop)) + test result completions) - (ignore-errors (kill-buffer "*Completions*")) - ;; (and (bufferp trace-buffer) (kill-buffer trace-buffer)) - (discard-input) - (setq test (car test-and-result) - unread-command-events - (mapcar #'identity (concat test "\t\t\n")) - completions nil - result (read-file-name "Prompt: ")) + (dolist + (test-and-result + ;; These are triples of strings (TEST-STRING + ;; RESULT-CHECK COMPLETION-CHECK). RESULT-CHECK + ;; could be not unique, in this case it is a list + ;; (RESULT1 RESULT2 ...). + (append + ;; Complete method name. + (unless (string-empty-p tramp-method-regexp) + `((,(concat + tramp-prefix-format hop + (substring-no-properties + method 0 (min 2 (length method)))) + ,(concat tramp-prefix-format method-string) + ,method-string))) + ;; Complete user name. + (unless (tramp-string-empty-or-nil-p user) + `((,(concat + tramp-prefix-format hop method-string + (substring-no-properties + user 0 (min 2 (length user)))) + ,(concat + tramp-prefix-format method-string user-string) + ,user-string))) + ;; Complete host name. + (unless (tramp-string-empty-or-nil-p host) + `((,(concat + tramp-prefix-format hop method-string + ipv6-prefix + (substring-no-properties + host 0 (min 2 (length host)))) + (,(concat + tramp-prefix-format method-string host-string) + ,(concat + tramp-prefix-format method-string + user-string host-string)) + ,host-string))) + ;; Complete user and host name. + (unless (or (tramp-string-empty-or-nil-p user) + (tramp-string-empty-or-nil-p host)) + `((,(concat + tramp-prefix-format hop method-string user-string + ipv6-prefix + (substring-no-properties + host 0 (min 2 (length host)))) + ,(concat + tramp-prefix-format method-string + user-string host-string) + ,host-string))))) - (if (or (not (get-buffer "*Completions*")) - (string-match-p - (if (string-empty-p tramp-method-regexp) - (rx (| (regexp tramp-postfix-user-regexp) - (regexp tramp-postfix-host-regexp)) - eos) - (rx (| (regexp tramp-postfix-method-regexp) - (regexp tramp-postfix-user-regexp) - (regexp tramp-postfix-host-regexp)) - eos)) - result)) - (progn - ;; (tramp--test-message - ;; "syntax: %s style: %s test: %s result: %s" - ;; syntax style test result) - (should (string-prefix-p (cadr test-and-result) result))) + (ignore-errors (kill-buffer "*Completions*")) + ;; (and (bufferp trace-buffer) (kill-buffer trace-buffer)) + (discard-input) + (setq test (car test-and-result) + unread-command-events + (mapcar #'identity (concat test "\t\t\n")) + completions nil + result (read-file-name "Prompt: ")) - (with-current-buffer "*Completions*" - ;; We must remove leading `default-directory'. - (goto-char (point-min)) - (let ((inhibit-read-only t)) - (while (re-search-forward "//" nil 'noerror) - (delete-region (line-beginning-position) (point)))) - (goto-char (point-min)) - (re-search-forward - (rx bol (0+ nonl) - (any "Pp") "ossible completions" - (0+ nonl) eol)) - (forward-line 1) - (setq completions - (split-string - (buffer-substring-no-properties (point) (point-max)) - (rx (any "\r\n")) 'omit))) + (if (or (not (get-buffer "*Completions*")) + (string-match-p + (if (string-empty-p tramp-method-regexp) + (rx + (| (regexp tramp-postfix-user-regexp) + (regexp tramp-postfix-host-regexp)) + eos) + (rx + (| (regexp tramp-postfix-method-regexp) + (regexp tramp-postfix-user-regexp) + (regexp tramp-postfix-host-regexp)) + eos)) + result)) + (progn + ;; (tramp--test-message + ;; "syntax: %s style: %s test: %s result: %s" + ;; syntax style test result) + (if (stringp (cadr test-and-result)) + (should + (string-prefix-p (cadr test-and-result) result)) + (should + (let (res) + (dolist (elem (cadr test-and-result) res) + (setq + res (or res (string-prefix-p elem result)))))))) - ;; (tramp--test-message - ;; "syntax: %s style: %s test: %s result: %s completions: %S" - ;; syntax style test result completions) - (should (member (caddr test-and-result) completions)))))))) + (with-current-buffer "*Completions*" + ;; We must remove leading `default-directory'. + (goto-char (point-min)) + (let ((inhibit-read-only t)) + (while (re-search-forward "//" nil 'noerror) + (delete-region (line-beginning-position) (point)))) + (goto-char (point-min)) + (re-search-forward + (rx bol (0+ nonl) + (any "Pp") "ossible completions" + (0+ nonl) eol)) + (forward-line 1) + (setq completions + (split-string + (buffer-substring-no-properties (point) (point-max)) + (rx (any "\r\n\t ")) 'omit))) - ;; Cleanup. - ;; (tramp--test-message "%s" (tramp-get-buffer-string trace-buffer)) - ;; (untrace-function #'tramp-completion-file-name-handler) - ;; (untrace-function #'completion-file-name-table) - (tramp-change-syntax orig-syntax))))) + ;; (tramp--test-message + ;; "syntax: %s style: %s test: %s result: %s completions: %S" + ;; syntax style test result completions) + (should (member (caddr test-and-result) completions)))))))) + + ;; Cleanup. + ;; (tramp--test-message "%s" (tramp-get-buffer-string trace-buffer)) + ;; (untrace-function #'tramp-completion-file-name-handler) + ;; (untrace-function #'completion-file-name-table) + (tramp-change-syntax orig-syntax)))) (ert-deftest tramp-test27-load () "Check `load'." @@ -5097,18 +5106,16 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (sit-for 0.1 'nodisp)) (process-send-string proc "foo\r\n") (process-send-eof proc) - ;; Read output. - (with-timeout (10 (tramp--test-timeout-handler)) - (while (< (- (point-max) (point-min)) - (length "66\n6F\n6F\n0D\n0A\n")) - (while (accept-process-output proc 0 nil t)))) - (should - (string-match-p - ;; On macOS, there is always newline conversion. - ;; "telnet" converts \r to if `crlf' - ;; flag is FALSE. See telnet(1) man page. - (rx "66\n" "6F\n" "6F\n" (| "0D\n" "0A\n") (? "00\n") "0A\n") - (buffer-string)))) + ;; Read output. On macOS, there is always newline + ;; conversion. "telnet" converts \r to if + ;; `crlf' flag is FALSE. See telnet(1) man page. + (let ((expected + (rx "66\n" "6F\n" "6F\n" + (| "0D\n" "0A\n") (? "00\n") "0A\n"))) + (with-timeout (10 (tramp--test-timeout-handler)) + (while (not (string-match-p expected (buffer-string))) + (while (accept-process-output proc 0 nil t)))) + (should (string-match-p expected (buffer-string))))) ;; Cleanup. (ignore-errors (delete-process proc))))) @@ -5388,18 +5395,16 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (sit-for 0.1 'nodisp)) (process-send-string proc "foo\r\n") (process-send-eof proc) - ;; Read output. - (with-timeout (10 (tramp--test-timeout-handler)) - (while (< (- (point-max) (point-min)) - (length "66\n6F\n6F\n0D\n0A\n")) - (while (accept-process-output proc 0 nil t)))) - (should - (string-match-p - ;; On macOS, there is always newline conversion. - ;; "telnet" converts \r to if `crlf' - ;; flag is FALSE. See telnet(1) man page. - (rx "66\n" "6F\n" "6F\n" (| "0D\n" "0A\n") (? "00\n") "0A\n") - (buffer-string)))) + ;; Read output. On macOS, there is always newline + ;; conversion. "telnet" converts \r to if + ;; `crlf' flag is FALSE. See telnet(1) man page. + (let ((expected + (rx "66\n" "6F\n" "6F\n" + (| "0D\n" "0A\n") (? "00\n") "0A\n"))) + (with-timeout (10 (tramp--test-timeout-handler)) + (while (not (string-match-p expected (buffer-string))) + (while (accept-process-output proc 0 nil t)))) + (should (string-match-p expected (buffer-string))))) ;; Cleanup. (ignore-errors (delete-process proc))))))))) diff --git a/test/lisp/progmodes/c-ts-mode-resources/indent-preproc.erts b/test/lisp/progmodes/c-ts-mode-resources/indent-preproc.erts index 5a4996f642e..57610b5483e 100644 --- a/test/lisp/progmodes/c-ts-mode-resources/indent-preproc.erts +++ b/test/lisp/progmodes/c-ts-mode-resources/indent-preproc.erts @@ -1,6 +1,7 @@ Code: (lambda () (c-ts-mode) + (setq-local indent-tabs-mode nil) (newline) (indent-for-tab-command)) diff --git a/test/lisp/wdired-tests.el b/test/lisp/wdired-tests.el index 74c2449076f..897c6cd69a8 100644 --- a/test/lisp/wdired-tests.el +++ b/test/lisp/wdired-tests.el @@ -189,5 +189,28 @@ wdired-get-filename before and after editing." (wdired-finish-edit)) (if buf (kill-buffer buf))))))) +(ert-deftest wdired-test-bug61510 () + "Test visibility of symlink target on leaving wdired-mode. +When dired-hide-details-mode is enabled and +dired-hide-details-hide-symlink-targets is non-nil (the default), +the link target becomes invisible. When wdired-mode is enabled +the target becomes visible, but on returning to dired-mode, it +should be invisible again." + (ert-with-temp-directory test-dir + (let ((buf (find-file-noselect test-dir)) + ;; Default value is t, but set it anyway, to be sure. + (dired-hide-details-hide-symlink-targets t)) + (unwind-protect + (with-current-buffer buf + (make-symbolic-link "bar" "foo") + (dired-hide-details-mode) + (should (memq 'dired-hide-details-link buffer-invisibility-spec)) + (dired-toggle-read-only) + (should-not (memq 'dired-hide-details-link + buffer-invisibility-spec)) + (wdired-finish-edit) + (should (memq 'dired-hide-details-link buffer-invisibility-spec))) + (if buf (kill-buffer buf)))))) + (provide 'wdired-tests) ;;; wdired-tests.el ends here