commit 033f2cc6140d03e78403f37689b9f54b64bded01 (HEAD, refs/remotes/origin/master) Merge: 60240f54e5f 1cbc22b9c7f Author: Stefan Kangas Date: Wed Jan 11 06:30:12 2023 +0100 Merge from origin/emacs-29 1cbc22b9c7f CC Mode: partially revert commit from 2022-10-04 136c0272215 Fix reftex-citation docstring (bug#60710) 64fe6bdb618 Improve 'describe-char-fold-equivalences' docstring fda1ad4a9ec Remove obsolete server buffers on MOTD in erc-track bb98666d03f ; Fix wrong type in erc-ignore hide-list options c267cd01517 ; Kill some stray buffers left behind by ERC tests f31e65694ca Fix completion-auto-help docstring (bug#60709) commit 1cbc22b9c7f836f5b3311213dca8afa853513442 (refs/remotes/origin/emacs-29) Author: Alan Mackenzie Date: Tue Jan 10 20:29:37 2023 +0000 CC Mode: partially revert commit from 2022-10-04 This reversion is of an ill-advised optimization, which resulted in non-type identifiers getting fontified as types. * lisp/progmodes/cc-fonts.el (c-fontify-new-found-type): Rather than writing the expected face directly to the text, instead remove the `fontified' property. This allows the full font-lock mechanism to fontify the buffer correctly. diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index d84c4f8ad8a..4dcc3e0ade9 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el @@ -2530,8 +2530,8 @@ c-fontify-new-found-type (get-text-property (match-beginning 0) 'fontified) (not (memq (c-get-char-property (match-beginning 0) 'face) c-literal-faces))) - (c-put-font-lock-face (match-beginning 0) (match-end 0) - font-lock-type-face)) + (put-text-property (match-beginning 0) (match-end 0) + 'fontified nil)) (dolist (win-boundary window-boundaries) (when (and (< (match-beginning 0) (cdr win-boundary)) (> (match-end 0) (car win-boundary)) commit 136c0272215e167fe1cc4fc713c814c6c6cd8d7d Author: Manuel Uberti Date: Tue Jan 10 15:51:46 2023 +0100 Fix reftex-citation docstring (bug#60710) * lisp/textmodes/reftex-cite.el (reftex-citation): Fix spelling. diff --git a/lisp/textmodes/reftex-cite.el b/lisp/textmodes/reftex-cite.el index 77373707d65..6beae816257 100644 --- a/lisp/textmodes/reftex-cite.el +++ b/lisp/textmodes/reftex-cite.el @@ -636,7 +636,7 @@ reftex-citation The regular expression uses an expanded syntax: && is interpreted as `and'. Thus, `aaaa&&bbb' matches entries which contain both `aaaa' and `bbb'. -While entering the regexp, completion on knows citation keys is possible. +While entering the regexp, completion on known citation keys is possible. `=' is a good regular expression to match all entries in all files." (interactive) commit 64fe6bdb618ff37336b3a8c635f23fc807785ef2 Author: Robert Pluim Date: Tue Jan 10 15:22:34 2023 +0100 Improve 'describe-char-fold-equivalences' docstring * lisp/char-fold.el (describe-char-fold-equivalences): Explain what the output looks like. diff --git a/lisp/char-fold.el b/lisp/char-fold.el index eff2f5558b3..6da2dae8471 100644 --- a/lisp/char-fold.el +++ b/lisp/char-fold.el @@ -436,7 +436,23 @@ describe-char-fold-equivalences describe all available character equivalences of `char-fold-to-regexp'. Optional argument LAX (interactively, the prefix argument), if non-nil, means also include partially matching ligatures and -non-canonical equivalences." +non-canonical equivalences. + +Each line of the display shows the equivalences in two different +ways separated by a colon: + + - as the literal character or sequence + - using an ASCII-only escape syntax + +For example, for the letter \\='r\\=', the first line is + + r: ?\\N{LATIN SMALL LETTER R} + +which is for the requested character itself, and a later line has + + ṟ: ?\\N{LATIN SMALL LETTER R}?\\N{COMBINING MACRON BELOW} + +which clearly shows what the constituent characters are." (interactive (list (ignore-errors (read-char-by-name (format-prompt "Unicode name, single char, or hex" commit fda1ad4a9ec030d013fc16c92d8494bc755b3763 Author: F. Jason Park Date: Tue Jan 3 23:10:53 2023 -0800 Remove obsolete server buffers on MOTD in erc-track * lisp/erc/erc-networks.el (erc-networks--copy-server-buffer-functions): New internal hook through which modules can perform housekeeping when server buffers belonging to the same network context are merged. (erc-networks--copy-over-server-buffer-contents): Run new internal hook `erc-networks--copy-server-buffer-functions'. * lisp/erc/erc-track.el (erc-track-enable, erc-track-disable): Manage membership in `erc-networks--copy-server-buffer-functions' hook. (erc-track--replace-killed-buffer): New function to replace server buffer being killed in `erc-modified-channels-alist'. * test/lisp/erc/erc-scenarios-base-association.el (erc-scenarios-networks-merge-server-track): New test. * test/lisp/erc/resources/networks/merge-server/track.eld: New test data. (Bug#60560.) diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el index 4044be08f92..95fd8990c99 100644 --- a/lisp/erc/erc-networks.el +++ b/lisp/erc/erc-networks.el @@ -1366,6 +1366,11 @@ erc-networks--reclaim-orphaned-target-buffers erc-server-connected t erc-networks--id nid)))))) +(defvar erc-networks--copy-server-buffer-functions nil + "Abnormal hook run in new server buffers when deduping. +Passed the existing buffer to be killed, whose contents have +already been copied over to the current, replacement buffer.") + (defun erc-networks--copy-over-server-buffer-contents (existing name) "Kill off existing server buffer after copying its contents. Must be called from the replacement buffer." @@ -1386,6 +1391,7 @@ erc-networks--copy-over-server-buffer-contents erc-kill-server-hook erc-kill-buffer-hook) (erc-networks--insert-transplanted-content text) + (run-hook-with-args 'erc-networks--copy-server-buffer-functions existing) (kill-buffer name))) ;; This stands alone for testing purposes diff --git a/lisp/erc/erc-track.el b/lisp/erc/erc-track.el index 61c0c66abfb..7fd7b53602e 100644 --- a/lisp/erc/erc-track.el +++ b/lisp/erc/erc-track.el @@ -521,7 +521,9 @@ track (add-hook 'erc-disconnected-hook #'erc-modified-channels-update)) ;; enable the tracking keybindings (add-hook 'erc-connect-pre-hook #'erc-track-minor-mode-maybe) - (erc-track-minor-mode-maybe))) + (erc-track-minor-mode-maybe)) + (add-hook 'erc-networks--copy-server-buffer-functions + #'erc-track--replace-killed-buffer)) ;; Disable: ((when (boundp 'erc-track-when-inactive) (erc-track-remove-from-mode-line) @@ -539,7 +541,9 @@ track ;; disable the tracking keybindings (remove-hook 'erc-connect-pre-hook #'erc-track-minor-mode-maybe) (when erc-track-minor-mode - (erc-track-minor-mode -1))))) + (erc-track-minor-mode -1))) + (remove-hook 'erc-networks--copy-server-buffer-functions + #'erc-track--replace-killed-buffer))) (defcustom erc-track-when-inactive nil "Enable channel tracking even for visible buffers, if you are inactive." @@ -942,6 +946,10 @@ erc-track-switch-buffer-other-window (interactive "p") (erc-track--switch-buffer 'switch-to-buffer-other-window arg)) +(defun erc-track--replace-killed-buffer (existing) + (when-let ((found (assq existing erc-modified-channels-alist))) + (setcar found (current-buffer)))) + (provide 'erc-track) ;;; erc-track.el ends here diff --git a/test/lisp/erc/erc-scenarios-base-association.el b/test/lisp/erc/erc-scenarios-base-association.el index 1e280d0fdd7..a40a4cb7550 100644 --- a/test/lisp/erc/erc-scenarios-base-association.el +++ b/test/lisp/erc/erc-scenarios-base-association.el @@ -26,7 +26,9 @@ (declare-function erc-network-name "erc-networks") (declare-function erc-network "erc-networks") +(declare-function erc-track-get-active-buffer "erc-track" (arg)) (defvar erc-autojoin-channels-alist) +(defvar erc-track-mode) (defvar erc-network) ;; Two networks, same channel name, no confusion (no bouncer). Some @@ -190,4 +192,51 @@ erc-scenarios-base-association-bouncer-history (with-current-buffer "#chan@barnet" (erc-d-t-search-for 10 "I'll bid adieu"))))) +;; Some modules may need to perform housekeeping when a newly +;; connected server buffer is deemed a duplicate after its persistent +;; network context is discovered on MOTD end. One such module is +;; `track', which needs to rid its list of modified channels of the +;; buffer being killed. Without this, a user may encounter an +;; "Attempt to display deleted buffer" error when they try switching +;; to it. + +(ert-deftest erc-scenarios-networks-merge-server-track () + :tags '(:expensive-test) + (erc-scenarios-common-with-cleanup + ((erc-scenarios-common-dialog "networks/merge-server") + (dumb-server (erc-d-run "localhost" t 'track 'track)) + (port (process-contact dumb-server :service)) + (erc-server-flood-penalty 0.1) + (expect (erc-d-t-make-expecter))) + + (ert-info ("Connect") + (with-current-buffer (erc :server "127.0.0.1" + :port port + :nick "tester") + (should (string= (buffer-name) (format "127.0.0.1:%d" port))) + (should erc-track-mode) + (funcall expect 5 "changed mode for tester") + (erc-cmd-JOIN "#chan"))) + + (ert-info ("Join channel and quit") + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan")) + (funcall expect 5 "The hour that fools should ask") + (erc-cmd-QUIT "")) + (with-current-buffer "FooNet" + (funcall expect 5 "finished"))) + + (ert-info ("Reconnect") + (with-current-buffer (erc :server "127.0.0.1" + :port port + :nick "tester") + (should (string= (buffer-name) (format "127.0.0.1:%d" port))) + (funcall expect 5 "changed mode for tester"))) + + (with-current-buffer "#chan" + (funcall expect 5 "The hour that fools should ask") + ;; Simulate the old `erc-track-switch-buffer' + (switch-to-buffer (erc-track-get-active-buffer 1)) + (erc-d-t-wait-for 10 (eq (get-buffer "FooNet") (current-buffer))) + (erc-cmd-QUIT "")))) + ;;; erc-scenarios-base-association.el ends here diff --git a/test/lisp/erc/resources/networks/merge-server/track.eld b/test/lisp/erc/resources/networks/merge-server/track.eld new file mode 100644 index 00000000000..4a97f92f722 --- /dev/null +++ b/test/lisp/erc/resources/networks/merge-server/track.eld @@ -0,0 +1,44 @@ +;; -*- mode: lisp-data; -*- +((nick 10 "NICK tester")) +((user 10 "USER user 0 * :unknown") + (0.00 ":irc.example.net NOTICE * :*** Looking up your hostname...") + (0.01 ":irc.example.net NOTICE tester :*** Could not resolve your hostname: Domain not found; using your IP address (10.0.2.100) instead.") + (0.10 ":irc.example.net 001 tester :Welcome to the FooNet IRC Network tester!user@10.0.2.100") + (0.02 ":irc.example.net 002 tester :Your host is irc.example.net, running version InspIRCd-3") + (0.02 ":irc.example.net 003 tester :This server was created 05:58:57 Jan 04 2023") + (0.01 ":irc.example.net 004 tester irc.example.net InspIRCd-3 BIRcgikorsw ACHIKMORTXabcefghijklmnopqrstvz :HIXabefghjkloqv") + (0.00 ":irc.example.net 005 tester ACCEPT=30 AWAYLEN=200 BOT=B CALLERID=g CASEMAPPING=ascii CHANLIMIT=#:20 CHANMODES=IXbeg,k,Hfjl,ACKMORTcimnprstz CHANNELLEN=64 CHANTYPES=# ELIST=CMNTU ESILENCE=CcdiNnPpTtx EXCEPTS=e :are supported by this server") + (0.02 ":irc.example.net 005 tester EXTBAN=,ACORTUacjrwz HOSTLEN=64 INVEX=I KEYLEN=32 KICKLEN=255 LINELEN=512 MAXLIST=I:100,X:100,b:100,e:100,g:100 MAXTARGETS=20 MODES=20 MONITOR=30 NAMELEN=128 NAMESX NETWORK=FooNet :are supported by this server") + (0.01 ":irc.example.net 005 tester NICKLEN=30 PREFIX=(qaohv)~&@%+ SAFELIST SILENCE=32 STATUSMSG=~&@%+ TOPICLEN=307 UHNAMES USERIP USERLEN=10 USERMODES=,,s,BIRcgikorw WHOX :are supported by this server") + (0.01 ":irc.example.net 251 tester :There are 2 users and 0 invisible on 2 servers") + (0.01 ":irc.example.net 253 tester 1 :unknown connections") + (0.01 ":irc.example.net 254 tester 1 :channels formed") + (0.00 ":irc.example.net 255 tester :I have 2 clients and 1 servers") + (0.00 ":irc.example.net 265 tester :Current local users: 2 Max: 3") + (0.00 ":irc.example.net 266 tester :Current global users: 2 Max: 3") + (0.00 ":irc.example.net 375 tester :irc.example.net message of the day") + (0.00 ":irc.example.net 372 tester : Have fun with the image!") + (0.00 ":irc.example.net 376 tester :End of message of the day.")) + +((mode 10 "MODE tester +i") + (0.00 ":irc.example.net 501 tester x :is not a recognised user mode.") + (0.00 ":NickServ!NickServ@services.int NOTICE tester :Welcome to FooNet, tester! Here on FooNet, we provide services to enable the registration of nicknames and channels! For details, type \2/msg NickServ help\2 and \2/msg ChanServ help\2.") + (0.02 ":tester!user@10.0.2.100 MODE tester :+i")) + +((join 10 "JOIN #chan") + (0.01 ":tester!user@10.0.2.100 JOIN :#chan")) + +((mode 10 "MODE #chan") + (0.01 ":irc.example.net 353 tester = #chan :@alice bob tester") + (0.01 ":irc.example.net 366 tester #chan :End of /NAMES list.") + (0.00 ":alice!alice@0::1 PRIVMSG #chan :tester, welcome!") + (0.02 ":bob!bob@0::1 PRIVMSG #chan :tester, welcome!") + (0.02 ":irc.example.net 324 tester #chan :+nt") + (0.01 ":irc.example.net 329 tester #chan :1672811954") + (0.07 ":alice!alice@0::1 PRIVMSG #chan :bob: This afternoon, sir ? well, she shall be there.") + (0.05 ":bob!bob@0::1 PRIVMSG #chan :alice: The hour that fools should ask.")) + +((quit 10 "QUIT :\2ERC\2") + (0.04 "ERROR :Closing link: (user@10.0.2.100) [Quit: \2ERC\2]")) + +((drop 1 DROP)) commit bb98666d03f2898f52f8b03f6056f8f8c9368131 Author: F. Jason Park Date: Mon Jan 2 18:13:08 2023 -0800 ; Fix wrong type in erc-ignore hide-list options * lisp/erc/erc.el (erc-network-hide-list, erc-channel-hide-list): Fix type in custom definition. diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 6315d5aa482..ba7db15cf8c 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -323,7 +323,8 @@ erc-network-hide-list \(\"OFTC\" \"JOIN\" \"QUIT\"))." :version "25.1" :group 'erc-ignore - :type 'erc-message-type) + :type '(alist :key-type string :value-type erc-message-type + :options ("Libera.Chat"))) (defcustom erc-channel-hide-list nil "A list of IRC channels to hide message types from. @@ -331,7 +332,8 @@ erc-channel-hide-list \(\"#erc\" \"NICK\")." :version "25.1" :group 'erc-ignore - :type 'erc-message-type) + :type '(alist :key-type string :value-type erc-message-type + :options ("#emacs"))) (defcustom erc-disconnected-hook nil "Run this hook with arguments (NICK IP REASON) when disconnected. commit c267cd01517bca9570faf13c4454793e7fb0c97b Author: F. Jason Park Date: Tue Jan 3 23:10:53 2023 -0800 ; Kill some stray buffers left behind by ERC tests * test/lisp/erc/erc-services-tests.el (erc--auth-source-search--plstore-standard, erc--auth-source-search--plstore-announced, erc--auth-source-search--plstore-overrides): Kill buffer renamed by plstore. In the future, try using the `:buffer' keyword introduced in Emacs 29. * test/lisp/erc/resources/erc-d/erc-d-t.el (erc-d-t-kill-related-buffers): Don't forget about `erc-dcc-chat-mode' buffers. diff --git a/test/lisp/erc/erc-services-tests.el b/test/lisp/erc/erc-services-tests.el index b1d36d868eb..9181a47ee3b 100644 --- a/test/lisp/erc/erc-services-tests.el +++ b/test/lisp/erc/erc-services-tests.el @@ -248,7 +248,8 @@ erc--auth-source-search--plstore-standard (let ((auth-sources (list plstore-file)) (auth-source-do-cache nil)) (erc-services-tests--auth-source-standard - #'erc-services-test--call-with-plstore)))) + #'erc-services-test--call-with-plstore)) + (kill-buffer (get-file-buffer plstore-file)))) (ert-deftest erc--auth-source-search--plstore-announced () (ert-with-temp-file plstore-file @@ -264,7 +265,8 @@ erc--auth-source-search--plstore-announced (let ((auth-sources (list plstore-file)) (auth-source-do-cache nil)) (erc-services-tests--auth-source-announced - #'erc-services-test--call-with-plstore)))) + #'erc-services-test--call-with-plstore)) + (kill-buffer (get-file-buffer plstore-file)))) (ert-deftest erc--auth-source-search--plstore-overrides () (ert-with-temp-file plstore-file @@ -296,7 +298,8 @@ erc--auth-source-search--plstore-overrides (let ((auth-sources (list plstore-file)) (auth-source-do-cache nil)) (erc-services-tests--auth-source-overrides - #'erc-services-test--call-with-plstore)))) + #'erc-services-test--call-with-plstore)) + (kill-buffer (get-file-buffer plstore-file)))) ;; auth-source JSON backend diff --git a/test/lisp/erc/resources/erc-d/erc-d-t.el b/test/lisp/erc/resources/erc-d/erc-d-t.el index 282c193b707..7b2adf4f07b 100644 --- a/test/lisp/erc/resources/erc-d/erc-d-t.el +++ b/test/lisp/erc/resources/erc-d/erc-d-t.el @@ -32,7 +32,7 @@ erc-d-t-kill-related-buffers (dolist (buf (buffer-list)) (with-current-buffer buf (when (or erc-d-u--process-buffer - (derived-mode-p 'erc-mode)) + (derived-mode-p 'erc-mode 'erc-dcc-chat-mode)) (push buf buflist)))) (dolist (buf buflist) (when (and (boundp 'erc-server-flood-timer) commit f31e65694caf7bd7aa981e13969e2c86fde59a13 Author: Manuel Uberti Date: Tue Jan 10 14:24:04 2023 +0100 Fix completion-auto-help docstring (bug#60709) * lisp/minibuffer.el (completion-auto-help): Remove extra period. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index f47299bd0da..21d4607e7cf 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -986,7 +986,7 @@ completion-auto-help If the value is `visible', the *Completions* buffer is displayed whenever completion is requested but cannot be done for the first time, but remains visible thereafter, and the list of completions in it is -updated for subsequent attempts to complete.." +updated for subsequent attempts to complete." :type '(choice (const :tag "Don't show" nil) (const :tag "Show only when cannot complete" t) (const :tag "Show after second failed completion attempt" lazy) commit 60240f54e5fed16a0522fb766ffef073db596f1f Merge: 4d1d43e41fa 55aabfea4ac Author: Stefan Kangas Date: Tue Jan 10 09:51:57 2023 +0100 Merge from origin/emacs-29 55aabfea4ac Fix c-ts-mode comment indent 8377ed5298f Highlight identifier in import statements in js-ts-mode aa9df1260c3 Don't print named tree-sitter nodes with parenthesizes (b... e385c099b8c Improve fontification for import-statements in typescript... 28dd6021384 Fix c-ts-mode indentation for 2nd line in block comment (... 8a36a0f44aa ; xref.el: Bump version f16cc7c49c7 ; project.el: Bump version ebc5263667b ; * src/callint.c (Finteractive): Doc string clarification. c1401d1c6c8 * lisp/vc/diff-mode.el (diff-font-lock-keywords): Check f... 1f8ad353d9f Minor improvement for tree-sitter explorer ef87c755660 Make sure NODE is not the root node in tree-sitter indent... 1238fa8e49b Fix label indent of GNU and Linux style in c-ts-mode (bug... dc911e4ba5c Improve go-ts-mode Imenu, navigation and electric pair (b... 20f36c8f6f9 ; ruby.rb: Fix pattern matching syntax and extend the exa... d46f7f4edcc Revert "Add c-or-c++-ts-mode (bug#59613)" 1469aac20d8 ; * src/pgtkfns.c (parse_resource_key): Use recursive sch... da96a1fd741 Add back renamed function 'font-lock-fontify-syntacticall... b1aa720671e ; * lisp/progmodes/ruby-ts-mode.el: Fix compilation warni... 5cb01ac5d78 ; * src/callint.c (Finteractive): Fix the doc string (bug... 53e64cfb852 Improve options and docs of M-x command completion fef4f18cc33 ; Fix NEWS e04b3d41bb4 Update to Org 9.6-90-ga6523f e3d806b4172 Fix string fontification on python-ts-mode (bug#60599) 800e15e3be0 Fix string-interpolation feature of python-ts-mode (bug#6... 38b63f4c3ce Add indentation rule for concatenated_string (bug#60572) 2cdd75a18ff Fix highlighting of variable-declarations in typescript-t... 73168793c01 Fix label indentation for Linux style in c-ts-mode (bug#6... 8575043f56b Remove duplicate entries in c-ts-mode's Imenu ef7f3c6388b Fix use of treesit-ready-p in c/c++-ts-mode cc1de953d4f ; * lisp/progmodes/gud.el (gud-tooltip-modes): Add ts- mo... 16f1e47ca8b ; * lisp/align.el (align-c++-modes): Add c/c++-ts-mode. 508389ad2bb Add documentation for c/c++-ts-mode (bug#60443) ee3e8d3f927 (ruby-ts--font-lock-settings): Improve highlighting in pa... 614f8c431d3 Optionally include the namespace in c-ts-mode--declarator... 7c356934fbb Support namespaces in c++-ts-mode (bug#60397) 757c2c25922 Fix c-ts-mode--looking-at-star 1df2826639c Add c-or-c++-ts-mode (bug#59613) 0cb686ffb6b Document the 'definition-name' property. 7f855b5297b ; Fix description of etc/DOC e9341119fe4 ; Fix documentation of etc/DOC 86a3462e3d2 (treesit-simple-indent-presets): Do that for 'or' as well. e0fef510b00 ; Minor rewording of tree-sitter terminology f58452e3ae7 Fix 'python-shell-buffer-substring' when START is in midd... 7f9588685a0 ; Fix last change e8b85f225d9 Rearrange the "Saving Emacs Sessions" section of the user... # Conflicts: # etc/NEWS # lisp/progmodes/c-ts-mode.el commit 55aabfea4accd04aed9424b5cdbe304d12be6224 Author: Yuan Fu Date: Mon Jan 9 21:46:07 2023 -0800 Fix c-ts-mode comment indent * lisp/progmodes/c-ts-mode.el: (c-ts-mode--comment-2nd-line-matcher): Also make sure PARENT is a comment node. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 898b89b9fce..5c7df4b2141 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -246,10 +246,11 @@ c-ts-mode--comment-start-after-first-star (defun c-ts-mode--comment-2nd-line-matcher (_n parent &rest _) "Matches if point is at the second line of a block comment. PARENT should be a comment node." - (save-excursion - (forward-line -1) - (back-to-indentation) - (eq (point) (treesit-node-start parent)))) + (and (equal (treesit-node-type parent) "comment") + (save-excursion + (forward-line -1) + (back-to-indentation) + (eq (point) (treesit-node-start parent))))) (defun c-ts-mode--comment-2nd-line-anchor (&rest _) "Return appropriate anchor for the second line of a comment. commit 8377ed5298f0529512294956269dcd06a8e6ed18 Author: Yuan Fu Date: Mon Jan 9 21:31:38 2023 -0800 Highlight identifier in import statements in js-ts-mode Follow-up on bug#60689. This commit just copied the change in e385c099b8c to js-ts-mode. * lisp/progmodes/js.el: (js--treesit-font-lock-settings): Add import query. diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index fe483f220da..058c8907bb5 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -3542,7 +3542,10 @@ js--treesit-font-lock-settings (identifier) (identifier) @font-lock-function-name-face) - value: (array (number) (function)))) + value: (array (number) (function))) + (import_clause (identifier) @font-lock-variable-name-face) + (import_clause (named_imports (import_specifier (identifier)) + @font-lock-variable-name-face))) :language 'javascript :feature 'property commit aa9df1260c3fe5e872bef926288ce345bedbe1bb Author: Yuan Fu Date: Mon Jan 9 20:15:12 2023 -0800 Don't print named tree-sitter nodes with parenthesizes (bug#60696) * src/print.c (print_vectorlike): Use empty string as delimiters if the node is named. diff --git a/src/print.c b/src/print.c index d4a9ff89246..e65b4c40b0e 100644 --- a/src/print.c +++ b/src/print.c @@ -2034,8 +2034,13 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag, /* Now the node must be up-to-date, and calling functions like Ftreesit_node_start will not signal. */ bool named = treesit_named_node_p (XTS_NODE (obj)->node); - const char *delim1 = named ? "(" : "\""; - const char *delim2 = named ? ")" : "\""; + /* We used to use () as delimiters for named nodes, but that + confuses pretty-printing a tad bit. There might be more + little breakages here and there if we print parenthesizes + inside an object, so I guess better not do it. + (bug#60696) */ + const char *delim1 = named ? "" : "\""; + const char *delim2 = named ? "" : "\""; print_c_string (delim1, printcharfun); print_string (Ftreesit_node_type (obj), printcharfun); print_c_string (delim2, printcharfun); commit e385c099b8c3eda3c7e3ad397c1b4a8ff2be4010 Author: Jostein Kjønigsen Date: Mon Jan 9 11:17:53 2023 +0100 Improve fontification for import-statements in typescript-ts-mode (bug#60689) * lisp/progmodes/typescript-ts-mode.el: (typescript-ts-mode--font-lock-settings): Add rules to highlight the actual imports in import-statements. diff --git a/lisp/progmodes/typescript-ts-mode.el b/lisp/progmodes/typescript-ts-mode.el index b26dca101db..037d5c8e87e 100644 --- a/lisp/progmodes/typescript-ts-mode.el +++ b/lisp/progmodes/typescript-ts-mode.el @@ -197,7 +197,10 @@ typescript-ts-mode--font-lock-settings value: (array (number) (function))) (catch_clause - parameter: (identifier) @font-lock-variable-name-face)) + parameter: (identifier) @font-lock-variable-name-face) + + (import_clause (identifier) @font-lock-variable-name-face) + (import_clause (named_imports (import_specifier (identifier)) @font-lock-variable-name-face))) :language language :override t commit 28dd60213846a04d3f8c4006bd4ec252bd883ed0 Author: Yuan Fu Date: Mon Jan 9 01:44:44 2023 -0800 Fix c-ts-mode indentation for 2nd line in block comment (bug#60270) If the first line is "/*" or "/* ", indent like this: /* aaa If the first line is "/* some text", indent like this: /* some text aaa * lisp/progmodes/c-ts-mode.el (c-ts-mode--indent-styles): (c-ts-mode--looking-at-star): Minor refactor. (c-ts-mode--comment-2nd-line-matcher) (c-ts-mode--comment-2nd-line-anchor): New functions. * lisp/treesit.el (treesit-simple-indent-presets): prev-adaptive-prefix doesn't handle the comment-start-skip case (i.e, 2nd line) anymore. (Handled by the new matcher.) diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 772b259d59e..898b89b9fce 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -122,6 +122,9 @@ c-ts-mode--indent-styles ((node-is "else") parent-bol 0) ((node-is "case") parent-bol 0) ((node-is "preproc_arg") no-indent) + (c-ts-mode--comment-2nd-line-matcher + c-ts-mode--comment-2nd-line-anchor + 1) ((and (parent-is "comment") c-ts-mode--looking-at-star) c-ts-mode--comment-start-after-first-star -1) ((parent-is "comment") prev-adaptive-prefix 0) @@ -227,11 +230,8 @@ c-ts-mode--bracket-children-anchor (defun c-ts-mode--looking-at-star (_n _p bol &rest _) "A tree-sitter simple indent matcher. -Matches if there is a \"*\" after point (ignoring whitespace in -between)." - (save-excursion - (goto-char bol) - (looking-at (rx (* (syntax whitespace)) "*")))) +Matches if there is a \"*\" after BOL." + (eq (char-after bol) ?*)) (defun c-ts-mode--comment-start-after-first-star (_n parent &rest _) "A tree-sitter simple indent anchor. @@ -243,6 +243,34 @@ c-ts-mode--comment-start-after-first-star (match-end 0) (point)))) +(defun c-ts-mode--comment-2nd-line-matcher (_n parent &rest _) + "Matches if point is at the second line of a block comment. +PARENT should be a comment node." + (save-excursion + (forward-line -1) + (back-to-indentation) + (eq (point) (treesit-node-start parent)))) + +(defun c-ts-mode--comment-2nd-line-anchor (&rest _) + "Return appropriate anchor for the second line of a comment. + +If the first line is /* alone, return the position right after +the star; if the first line is /* followed by some text, return +the position right before the text minus 1. + +Use an offset of 1 with this anchor." + (save-excursion + (forward-line -1) + (back-to-indentation) + (when (looking-at comment-start-skip) + (goto-char (match-end 0)) + (if (looking-at (rx (* (or " " "\t")) eol)) + ;; Only /* at the first line. + (progn (skip-chars-backward " \t") + (point)) + ;; There is something after /* at the first line. + (1- (point)))))) + ;;; Font-lock (defvar c-ts-mode--preproc-keywords diff --git a/lisp/treesit.el b/lisp/treesit.el index 7a604121c4e..5b306354465 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -1143,20 +1143,17 @@ treesit-simple-indent-presets (point)))) (cons 'prev-adaptive-prefix (lambda (_n parent &rest _) - (save-excursion - (re-search-backward - (rx (not (or " " "\t" "\n"))) nil t) - (beginning-of-line) - (and (>= (point) (treesit-node-start parent)) - ;; `adaptive-fill-regexp' will not match "/*", - ;; so we need to also try `comment-start-skip'. - (or (and adaptive-fill-regexp - (looking-at adaptive-fill-regexp) - (> (- (match-end 0) (match-beginning 0)) 0) - (match-end 0)) - (and comment-start-skip - (looking-at comment-start-skip) - (match-end 0))))))) + (let ((comment-start-bol + (save-excursion + (goto-char (treesit-node-start parent)) + (line-beginning-position)))) + (save-excursion + (forward-line -1) + (and (>= (point) comment-start-bol) + adaptive-fill-regexp + (looking-at adaptive-fill-regexp) + (> (match-end 0) (match-beginning 0)) + (match-end 0)))))) ;; TODO: Document. (cons 'grand-parent (lambda (_n parent &rest _) commit 8a36a0f44aafc10f1d10e23d5371bf19ee344b41 Author: Dmitry Gutov Date: Tue Jan 10 02:02:09 2023 +0200 ; xref.el: Bump version diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index d5cee9fa84f..916d83d407b 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -1,7 +1,7 @@ ;;; xref.el --- Cross-referencing commands -*-lexical-binding:t-*- ;; Copyright (C) 2014-2023 Free Software Foundation, Inc. -;; Version: 1.6.0 +;; Version: 1.6.1 ;; Package-Requires: ((emacs "26.1")) ;; This is a GNU ELPA :core package. Avoid functionality that is not commit f16cc7c49c7f341558fda08bd14e2c1b7e80baf5 Author: Dmitry Gutov Date: Tue Jan 10 02:00:29 2023 +0200 ; project.el: Bump version diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 730998727ce..dc87cb8e15d 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1,7 +1,7 @@ ;;; project.el --- Operations on the current project -*- lexical-binding: t; -*- ;; Copyright (C) 2015-2023 Free Software Foundation, Inc. -;; Version: 0.9.3 +;; Version: 0.9.4 ;; Package-Requires: ((emacs "26.1") (xref "1.4.0")) ;; This is a GNU ELPA :core package. Avoid using functionality that commit ebc5263667b17af30d8e91b47aba0cdd67a389d4 Author: Eli Zaretskii Date: Mon Jan 9 14:03:04 2023 +0200 ; * src/callint.c (Finteractive): Doc string clarification. diff --git a/src/callint.c b/src/callint.c index 04bd64535c9..d8d2b278458 100644 --- a/src/callint.c +++ b/src/callint.c @@ -105,13 +105,12 @@ DEFUN ("interactive", Finteractive, Sinteractive, 0, UNEVALLED, 0, You may use `@', `*', and `^' together. They are processed in the order that they appear, before reading any arguments. -If MODES is present, it should be a list of mode names (symbols) that -this command is applicable for. The main effect of this is that -`M-x TAB' will be able to exclude this command from the list of -completion candidates if the current buffer's mode doesn't match the list. -That is, if either the major mode isn't derived from them, or (when it's -a minor mode) the mode isn't in effect. Which commands are excluded -from the list of completion candidates is controlled by the value +If MODES is present, it should be one or more mode names (symbols) +for which this command is applicable. This is so that `M-x TAB' +will be able to exclude this command from the list of completion +candidates if the current buffer's mode doesn't match the list. +Which commands are excluded from the list of completion +candidates based on this information is controlled by the value of `read-extended-command-predicate', which see. usage: (interactive &optional ARG-DESCRIPTOR &rest MODES) */ commit c1401d1c6c834c4b264cc2435f562b28bc9c83a8 Author: Juri Linkov Date: Mon Jan 9 09:54:19 2023 +0200 * lisp/vc/diff-mode.el (diff-font-lock-keywords): Check for limit. This check is necessary since 'diff-beginning-of-hunk' can move not only backwards, but also forwards (bug#60660). diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index acfd2c30f0c..eb01dede56e 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -485,17 +485,19 @@ diff-font-lock-keywords ;; if below, use `diff-added'. (save-match-data (let ((limit (save-excursion (diff-beginning-of-hunk)))) - (if (save-excursion (re-search-backward diff-context-mid-hunk-header-re limit t)) - diff-indicator-added-face - diff-indicator-removed-face))))) + (when (< limit (point)) + (if (save-excursion (re-search-backward diff-context-mid-hunk-header-re limit t)) + diff-indicator-added-face + diff-indicator-removed-face)))))) (2 (if diff-use-changed-face 'diff-changed-unspecified ;; Otherwise, use the same method as above. (save-match-data (let ((limit (save-excursion (diff-beginning-of-hunk)))) - (if (save-excursion (re-search-backward diff-context-mid-hunk-header-re limit t)) - 'diff-added - 'diff-removed)))))) + (when (< limit (point)) + (if (save-excursion (re-search-backward diff-context-mid-hunk-header-re limit t)) + 'diff-added + 'diff-removed))))))) ("^\\(?:Index\\|revno\\): \\(.+\\).*\n" (0 'diff-header) (1 'diff-index prepend)) ("^\\(?:index .*\\.\\.\\|diff \\).*\n" . 'diff-header) commit 1f8ad353d9fbf8fb7706e91dda336dfd650b57cc Author: Yuan Fu Date: Sun Jan 8 20:30:07 2023 -0800 Minor improvement for tree-sitter explorer If you open an empty python buffer and type 1 + 2 a b Currently the explorer only displays the top-level node at point, ie, only 1 + 2, only a, or only b. That's kind of awkward, so if the buffer is small, show the entire parse tree. * lisp/treesit.el (treesit--explorer-refresh): See above. diff --git a/lisp/treesit.el b/lisp/treesit.el index e53d5d53bd0..7a604121c4e 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -2415,11 +2415,15 @@ treesit--explorer-refresh (window-start) (window-end) treesit--explorer-language)) ;; Only highlight the current top-level construct. ;; Highlighting the whole buffer is slow and unnecessary. - (top-level (treesit-node-first-child-for-pos - root (if (eolp) - (max (point-min) (1- (point))) - (point)) - t)) + ;; But if the buffer is small (ie, used in playground + ;; style), just highlight the whole buffer. + (top-level (if (< (buffer-size) 4000) + root + (treesit-node-first-child-for-pos + root (if (eolp) + (max (point-min) (1- (point))) + (point)) + t))) ;; Only highlight node when region is active, if we ;; highlight node at point the syntax tree is too jumpy. (nodes-hl commit ef87c75566018b546e56f64f66f665ebfd8da305 Author: Yuan Fu Date: Sun Jan 8 19:05:19 2023 -0800 Make sure NODE is not the root node in tree-sitter indent (bug#60602) There are two possible ways to solve the problem raised in the bug report: either make sure NODE is never the root (so that parent is never nil), or allow parent to be nil. If we go with the latter, a lot of matcher and anchor functions need change (they need to guard against a null parent). I tried it, and needing to check for null parent is pretty annoying. In comparison, if NODE is never the root, it is very convenient for the user, and it doesn't complicate the rule that much (and it's rather intuitive, people usually don't think of the case where NODE is the root node). So that's what I choose. * doc/lispref/modes.texi (Parser-based Indentation): Update manual. * lisp/treesit.el (treesit-indent-function): Update docstring. (treesit--indent-1): Make sure NODE is not the root. diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index b2dd294ea28..ff372edb3ff 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -4936,10 +4936,10 @@ Parser-based Indentation arguments: @var{node}, @var{parent}, and @var{bol}. The argument @var{bol} is the buffer position whose indentation is required: the position of the first non-whitespace character after the beginning of -the line. The argument @var{node} is the largest (highest-in-tree) -node that starts at that position; and @var{parent} is the parent of -@var{node}. However, when that position is in a whitespace or inside -a multi-line string, no node can start at that position, so +the line. The argument @var{node} is the largest node that starts at +that position (and is not a root node); and @var{parent} is the parent +of @var{node}. However, when that position is in a whitespace or +inside a multi-line string, no node can start at that position, so @var{node} is @code{nil}. In that case, @var{parent} would be the smallest node that spans that position. diff --git a/lisp/treesit.el b/lisp/treesit.el index 7205e43916d..e53d5d53bd0 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -1341,10 +1341,10 @@ treesit-indent-function (ANCHOR . OFFSET). BOL is the position of the beginning of the line; NODE is the -\"largest\" node that starts at BOL; PARENT is its parent; ANCHOR -is a point (not a node), and OFFSET is a number. Emacs finds the -column of ANCHOR and adds OFFSET to it as the final indentation -of the current line.") +\"largest\" node that starts at BOL (and isn't a root node); +PARENT is its parent; ANCHOR is a point (not a node), and OFFSET +is a number. Emacs finds the column of ANCHOR and adds OFFSET to +it as the final indentation of the current line.") (defun treesit--indent-1 () "Indent the current line. @@ -1362,10 +1362,13 @@ treesit--indent-1 ((treesit-language-at (point)) (treesit-node-at bol (treesit-language-at (point)))) (t (treesit-node-at bol)))) + (root (treesit-parser-root-node + (treesit-node-parser smallest-node))) (node (treesit-parent-while smallest-node (lambda (node) - (eq bol (treesit-node-start node)))))) + (and (eq bol (treesit-node-start node)) + (not (treesit-node-eq node root))))))) (let* ((parser (if smallest-node (treesit-node-parser smallest-node) commit 1238fa8e49bdb12db66d856dcb4b192db5d026ff Author: Yuan Fu Date: Sun Jan 8 16:57:29 2023 -0800 Fix label indent of GNU and Linux style in c-ts-mode (bug#60543) The previous fix isn't correct. * lisp/progmodes/c-ts-mode.el: (c-ts-mode--indent-styles): New indent rule. Fix the rule for Linux style. (c-ts-mode--top-level-label-matcher): New function. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index e1b45b06e1a..772b259d59e 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -125,6 +125,7 @@ c-ts-mode--indent-styles ((and (parent-is "comment") c-ts-mode--looking-at-star) c-ts-mode--comment-start-after-first-star -1) ((parent-is "comment") prev-adaptive-prefix 0) + (c-ts-mode--top-level-label-matcher point-min 1) ((node-is "labeled_statement") parent-bol 0) ((parent-is "labeled_statement") parent-bol c-ts-mode-indent-offset) ((match "preproc_ifdef" "compound_statement") point-min 0) @@ -171,7 +172,10 @@ c-ts-mode--indent-styles ,@common) (k&r ,@common) (linux - ((node-is "labeled_statement") point-min 1) + ;; Reference: + ;; https://www.kernel.org/doc/html/latest/process/coding-style.html, + ;; and script/Lindent in Linux kernel repository. + ((node-is "labeled_statement") point-min 0) ,@common) (bsd ((parent-is "if_statement") parent-bol 0) @@ -195,6 +199,17 @@ c-ts-mode--set-indent-style ('linux (alist-get 'linux (c-ts-mode--indent-styles mode))))))) `((,mode ,@style)))) +(defun c-ts-mode--top-level-label-matcher (node &rest _) + "A matcher that matches a top-level label. +NODE should be a labeled_statement." + (let ((func (treesit-parent-until + node (lambda (n) + (equal (treesit-node-type n) + "function_definition"))))) + (and (equal (treesit-node-type node) + "labeled_statement") + (not (treesit-node-top-level func "function_definition"))))) + (defun c-ts-mode--bracket-children-anchor (_n parent &rest _) "This anchor is used for children of a compound_statement. So anything inside a {} block. PARENT should be the commit dc911e4ba5ccfc99d66504b6e99c9abcf3e617f3 Author: Evgeni Kolev Date: Thu Dec 29 17:49:40 2022 +0200 Improve go-ts-mode Imenu, navigation and electric pair (bug#60407) The Imenu items are extended to support "Method", "Struct", "Interface", "Alias" and "Type". go-ts-mode is updated to use the Imenu facility added in commit b39dc7ab27a696a8607ab859aeff3c71509231f5. Variable electric-indent-chars is set in order to improve integration with Electric Pair mode. * lisp/progmodes/go-ts-mode.el (go-ts-mode--imenu-1) (go-ts-mode--imenu): Remove functions. (go-ts-mode--defun-name, go-ts-mode--interface-node-p) (go-ts-mode--struct-node-p, go-ts-mode--other-type-node-p) (go-ts-mode--alias-node-p): New functions. (go-ts-mode): Improve Imenu settings, navigation, add Electric Pair mode settings. diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el index 1d6a8a30db5..64e761d2f72 100644 --- a/lisp/progmodes/go-ts-mode.el +++ b/lisp/progmodes/go-ts-mode.el @@ -36,6 +36,7 @@ (declare-function treesit-node-child-by-field-name "treesit.c") (declare-function treesit-node-start "treesit.c") (declare-function treesit-node-type "treesit.c") +(declare-function treesit-search-subtree "treesit.c") (defcustom go-ts-mode-indent-offset 4 "Number of spaces for each indentation step in `go-ts-mode'." @@ -173,44 +174,6 @@ go-ts-mode--font-lock-settings '((ERROR) @font-lock-warning-face)) "Tree-sitter font-lock settings for `go-ts-mode'.") -(defun go-ts-mode--imenu () - "Return Imenu alist for the current buffer." - (let* ((node (treesit-buffer-root-node)) - (func-tree (treesit-induce-sparse-tree - node "function_declaration" nil 1000)) - (type-tree (treesit-induce-sparse-tree - node "type_spec" nil 1000)) - (func-index (go-ts-mode--imenu-1 func-tree)) - (type-index (go-ts-mode--imenu-1 type-tree))) - (append - (when func-index `(("Function" . ,func-index))) - (when type-index `(("Type" . ,type-index)))))) - -(defun go-ts-mode--imenu-1 (node) - "Helper for `go-ts-mode--imenu'. -Find string representation for NODE and set marker, then recurse -the subtrees." - (let* ((ts-node (car node)) - (children (cdr node)) - (subtrees (mapcan #'go-ts-mode--imenu-1 - children)) - (name (when ts-node - (treesit-node-text - (pcase (treesit-node-type ts-node) - ("function_declaration" - (treesit-node-child-by-field-name ts-node "name")) - ("type_spec" - (treesit-node-child-by-field-name ts-node "name")))))) - (marker (when ts-node - (set-marker (make-marker) - (treesit-node-start ts-node))))) - (cond - ((or (null ts-node) (null name)) subtrees) - (subtrees - `((,name ,(cons name marker) ,@subtrees))) - (t - `((,name . ,marker)))))) - ;;;###autoload (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode)) @@ -228,14 +191,30 @@ go-ts-mode (setq-local comment-end "") (setq-local comment-start-skip (rx "//" (* (syntax whitespace)))) + ;; Navigation. + (setq-local treesit-defun-type-regexp + (regexp-opt '("method_declaration" + "function_declaration" + "type_declaration"))) + (setq-local treesit-defun-name-function #'go-ts-mode--defun-name) + ;; Imenu. - (setq-local imenu-create-index-function #'go-ts-mode--imenu) - (setq-local which-func-functions nil) + (setq-local treesit-simple-imenu-settings + `(("Function" "\\`function_declaration\\'" nil nil) + ("Method" "\\`method_declaration\\'" nil nil) + ("Struct" "\\`type_declaration\\'" go-ts-mode--struct-node-p nil) + ("Interface" "\\`type_declaration\\'" go-ts-mode--interface-node-p nil) + ("Type" "\\`type_declaration\\'" go-ts-mode--other-type-node-p nil) + ("Alias" "\\`type_declaration\\'" go-ts-mode--alias-node-p nil))) ;; Indent. (setq-local indent-tabs-mode t treesit-simple-indent-rules go-ts-mode--indent-rules) + ;; Electric + (setq-local electric-indent-chars + (append "{}()" electric-indent-chars)) + ;; Font-lock. (setq-local treesit-font-lock-settings go-ts-mode--font-lock-settings) (setq-local treesit-font-lock-feature-list @@ -247,6 +226,54 @@ go-ts-mode (treesit-major-mode-setup))) +(defun go-ts-mode--defun-name (node) + "Return the defun name of NODE. +Return nil if there is no name or if NODE is not a defun node." + (pcase (treesit-node-type node) + ("function_declaration" + (treesit-node-text + (treesit-node-child-by-field-name + node "name") + t)) + ("method_declaration" + (let* ((receiver-node (treesit-node-child-by-field-name node "receiver")) + (type-node (treesit-search-subtree receiver-node "type_identifier")) + (name-node (treesit-node-child-by-field-name node "name"))) + (concat + "(" (treesit-node-text type-node) ")." + (treesit-node-text name-node)))) + ("type_declaration" + (treesit-node-text + (treesit-node-child-by-field-name + (treesit-node-child node 0 t) "name") + t)))) + +(defun go-ts-mode--interface-node-p (node) + "Return t if NODE is an interface." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (treesit-search-subtree node "interface_type" nil nil 2))) + +(defun go-ts-mode--struct-node-p (node) + "Return t if NODE is a struct." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (treesit-search-subtree node "struct_type" nil nil 2))) + +(defun go-ts-mode--alias-node-p (node) + "Return t if NODE is a type alias." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (treesit-search-subtree node "type_alias" nil nil 1))) + +(defun go-ts-mode--other-type-node-p (node) + "Return t if NODE is a type, other than interface, struct or alias." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (not (go-ts-mode--interface-node-p node)) + (not (go-ts-mode--struct-node-p node)) + (not (go-ts-mode--alias-node-p node)))) + ;; go.mod support. (defvar go-mod-ts-mode--syntax-table commit 20f36c8f6f98478dd86ddfe93da2803de2518ea2 Author: Dmitry Gutov Date: Mon Jan 9 00:57:36 2023 +0200 ; ruby.rb: Fix pattern matching syntax and extend the example diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby.rb b/test/lisp/progmodes/ruby-mode-resources/ruby.rb index bfae948b259..3f0dfdf68ba 100644 --- a/test/lisp/progmodes/ruby-mode-resources/ruby.rb +++ b/test/lisp/progmodes/ruby-mode-resources/ruby.rb @@ -513,7 +513,7 @@ def qux case translation in ['th', orig_text, 'en', trans_text] puts "English translation: #{orig_text} => #{trans_text}" -in {'th' => orig_text, 'ja' => trans_text} +in {th: orig_text, ja: trans_text} => whole puts "Japanese translation: #{orig_text} => #{trans_text}" end commit d46f7f4edcce14e6cbd8e2d7091dbabbe08defc1 Author: Yuan Fu Date: Sun Jan 8 09:40:49 2023 -0800 Revert "Add c-or-c++-ts-mode (bug#59613)" This reverts commit 1df2826639c912396fac0af108301533dac71406. I forgot about the feature freeze, sorry :-) diff --git a/etc/NEWS b/etc/NEWS index e9366fe8dd4..a28f5c9a65a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3210,11 +3210,6 @@ programs in the C language. An optional major mode based on the tree-sitter library for editing programs in the C++ language. -+++ -*** New command 'c-or-c++-ts-mode'. -A command that automatically guesses the language of a header file, -and enables either 'c-ts-mode' or 'c++-ts-mode' accordingly. - +++ *** New major mode 'java-ts-mode'. An optional major mode based on the tree-sitter library for editing diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 66f179f2f7f..e1b45b06e1a 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -858,50 +858,6 @@ c++-ts-mode (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'cpp)) (treesit-major-mode-setup))) -;; We could alternatively use parsers, but if this works well, I don't -;; see the need to change. This is copied verbatim from cc-guess.el. -(defconst c-ts-mode--c-or-c++-regexp - (eval-when-compile - (let ((id "[a-zA-Z_][a-zA-Z0-9_]*") (ws "[ \t]+") (ws-maybe "[ \t]*") - (headers '("string" "string_view" "iostream" "map" "unordered_map" - "set" "unordered_set" "vector" "tuple"))) - (concat "^" ws-maybe "\\(?:" - "using" ws "\\(?:namespace" ws - "\\|" id "::" - "\\|" id ws-maybe "=\\)" - "\\|" "\\(?:inline" ws "\\)?namespace" - "\\(:?" ws "\\(?:" id "::\\)*" id "\\)?" ws-maybe "{" - "\\|" "class" ws id - "\\(?:" ws "final" "\\)?" ws-maybe "[:{;\n]" - "\\|" "struct" ws id "\\(?:" ws "final" ws-maybe "[:{\n]" - "\\|" ws-maybe ":\\)" - "\\|" "template" ws-maybe "<.*?>" - "\\|" "#include" ws-maybe "<" (regexp-opt headers) ">" - "\\)"))) - "A regexp applied to C header files to check if they are really C++.") - -;;;###autoload -(defun c-or-c++-ts-mode () - "Analyze buffer and enable either C or C++ mode. - -Some people and projects use .h extension for C++ header files -which is also the one used for C header files. This makes -matching on file name insufficient for detecting major mode that -should be used. - -This function attempts to use file contents to determine whether -the code is C or C++ and based on that chooses whether to enable -`c-ts-mode' or `c++-ts-mode'." - (interactive) - (if (save-excursion - (save-restriction - (save-match-data ; Why `save-match-data'? - (widen) - (goto-char (point-min)) - (re-search-forward c-ts-mode--c-or-c++-regexp nil t)))) - (c++-ts-mode) - (c-ts-mode))) - (provide 'c-ts-mode) ;;; c-ts-mode.el ends here commit 1469aac20d8ebcd3c5cca898b814c305278d4c27 Author: Tad Fisher Date: Wed Jan 4 13:40:17 2023 -0800 ; * src/pgtkfns.c (parse_resource_key): Use recursive schema lookup XDG_DATA_DIRS may consist of multiple directories, and g_settings_schema_source_get_default composes these into a recursive schema source. One must pass TRUE to g_settings_schema_source_lookup, otherwise only the first directory in XDG_DATA_DIRS is searched. It follows that in the case that the directory containing the compiled GSettings schema for Emacs is not the first in XDG_DATA_DIRS, parse_resource_key will not accept any resource key, which causes pgtk_get_defaults_value and pgtk_set_defaults_value to fail. This impacts systems that compose multiple GSettings schema sources via XDG_DATA_DIRS, such Flatpak and NixOS. Supporting GIO documentation for g_settings_schema_source_get_default: > The returned source may actually consist of multiple schema sources > from different directories, depending on which directories were given > in `XDG_DATA_DIRS` and `GSETTINGS_SCHEMA_DIR`. For this reason, all > lookups performed against the default source should probably be done > recursively. Bug#60565 Copyright-paperwork-exempt: yes diff --git a/src/pgtkfns.c b/src/pgtkfns.c index 6b3a0459d36..6e5bb22375a 100644 --- a/src/pgtkfns.c +++ b/src/pgtkfns.c @@ -1902,7 +1902,7 @@ parse_resource_key (const char *res_key, char *setting_key) /* check existence of setting_key */ GSettingsSchemaSource *ssrc = g_settings_schema_source_get_default (); - GSettingsSchema *scm = g_settings_schema_source_lookup (ssrc, SCHEMA_ID, FALSE); + GSettingsSchema *scm = g_settings_schema_source_lookup (ssrc, SCHEMA_ID, TRUE); if (!scm) return NULL; /* *.schema.xml is not installed. */ if (!g_settings_schema_has_key (scm, setting_key)) commit da96a1fd74189106c065e65002c7a4ac416fb5bb Author: Benson Chu Date: Sat Dec 31 19:45:43 2022 -0600 Add back renamed function 'font-lock-fontify-syntactically-region' A more accurate replacement for font-lock-fontify-syntactically-region would be a function that funcalls the font-lock-fontify-syntactically-function variable. That way, callers of the function can inherit new behavior, if the value of that variable changes. * lisp/font-lock.el (font-lock-fontify-syntactically-region): Add function back, remove its obsolete alias. Copyright-paperwork-exempt: yes diff --git a/lisp/font-lock.el b/lisp/font-lock.el index 99df8fb9e06..1fa45379b9f 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -1183,7 +1183,7 @@ font-lock-default-fontify-region (setq font-lock-syntactically-fontified end)) (font-lock-fontify-syntactic-keywords-region start end))) (unless font-lock-keywords-only - (funcall font-lock-fontify-syntactically-function beg end loudly)) + (font-lock-fontify-syntactically-region beg end loudly)) (font-lock-fontify-keywords-region beg end loudly) `(jit-lock-bounds ,beg . ,end)))) @@ -1531,6 +1531,12 @@ font-lock-comment-start-skip (defvar font-lock-comment-end-skip nil "If non-nil, Font Lock mode uses this instead of `comment-end-skip'.") +(defun font-lock-fontify-syntactically-region (beg end &optional loudly) + "Syntactically fontify the text between BEG and END. +If LOUDLY is non-nil, print status messages while fontifying. +This works by calling `font-lock-fontify-syntactically-function'." + (funcall font-lock-fontify-syntactically-function beg end loudly)) + (defun font-lock-default-fontify-syntactically (start end &optional loudly) "Put proper face on each string and comment between START and END. START should be at the beginning of a line." @@ -2369,7 +2375,6 @@ cpp-font-lock-keywords (define-obsolete-function-alias 'font-lock-after-fontify-buffer #'ignore "29.1") (define-obsolete-function-alias 'font-lock-after-unfontify-buffer #'ignore "29.1") -(define-obsolete-function-alias 'font-lock-fontify-syntactically-region #'font-lock-default-fontify-syntactically "29.1") (provide 'font-lock) commit b1aa720671efc37b85f222179d8ebc97d6d9baad Author: Eli Zaretskii Date: Sun Jan 8 12:56:13 2023 +0200 ; * lisp/progmodes/ruby-ts-mode.el: Fix compilation warnings (bug#60647). diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el index 9ec771e2fff..d68b57966ba 100644 --- a/lisp/progmodes/ruby-ts-mode.el +++ b/lisp/progmodes/ruby-ts-mode.el @@ -82,6 +82,16 @@ (require 'ruby-mode) (declare-function treesit-parser-create "treesit.c") +(declare-function treesit-induce-sparse-tree "treesit.c") +(declare-function treesit-node-child-by-field-name "treesit.c") +(declare-function treesit-search-subtree "treesit.c") +(declare-function treesit-node-parent "treesit.c") +(declare-function treesit-node-next-sibling "treesit.c") +(declare-function treesit-node-type "treesit.c") +(declare-function treesit-node-child "treesit.c") +(declare-function treesit-node-end "treesit.c") +(declare-function treesit-node-start "treesit.c") +(declare-function treesit-node-string "treesit.c") (defgroup ruby-ts nil "Major mode for editing Ruby code." commit 5cb01ac5d78e52d276857b45cd1f17e5d53b7899 Author: Eli Zaretskii Date: Sun Jan 8 12:43:56 2023 +0200 ; * src/callint.c (Finteractive): Fix the doc string (bug#60645). diff --git a/src/callint.c b/src/callint.c index c60a376b958..04bd64535c9 100644 --- a/src/callint.c +++ b/src/callint.c @@ -107,9 +107,12 @@ DEFUN ("interactive", Finteractive, Sinteractive, 0, UNEVALLED, 0, If MODES is present, it should be a list of mode names (symbols) that this command is applicable for. The main effect of this is that -`M-x TAB' (by default) won't list this command if the current buffer's -mode doesn't match the list. That is, if either the major mode isn't -derived from them, or (when it's a minor mode) the mode isn't in effect. +`M-x TAB' will be able to exclude this command from the list of +completion candidates if the current buffer's mode doesn't match the list. +That is, if either the major mode isn't derived from them, or (when it's +a minor mode) the mode isn't in effect. Which commands are excluded +from the list of completion candidates is controlled by the value +of `read-extended-command-predicate', which see. usage: (interactive &optional ARG-DESCRIPTOR &rest MODES) */ attributes: const) commit 53e64cfb852e8c953e90448970f7d48b3872bc1e Author: Eli Zaretskii Date: Sun Jan 8 12:23:26 2023 +0200 Improve options and docs of M-x command completion * lisp/simple.el (read-extended-command-predicate): Expand the doc string. Add 2 more selectable values. (command-completion-using-modes-and-keymaps-p): New function. (execute-extended-command): Mention 'read-extended-command-predicate' in the doc string. (Bug#60645) diff --git a/lisp/simple.el b/lisp/simple.el index 63479e9ce0a..24df86c80c2 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -2207,15 +2207,39 @@ read-extended-command-predicate "Predicate to use to determine which commands to include when completing. If it's nil, include all the commands. If it's a function, it will be called with two parameters: the -symbol of the command and a buffer. The predicate should return -non-nil if the command should be present when doing \\`M-x TAB' -in that buffer." +symbol of the command and the current buffer. The predicate should +return non-nil if the command should be considered as a completion +candidate for \\`M-x' in that buffer. + +Several predicate functions suitable for various optional behaviors +are available: + + `command-completion-default-include-p' + This excludes from completion candidates those commands + which have been marked specific to modes other than the + current buffer's mode. Commands that are not specific + to any mode are included. + + `command-completion-using-modes-p' + This includes in completion candidates only commands + marked as specific to the current buffer's mode. + + `command-completion-using-modes-and-keymaps-p' + This includes commands marked as specific to the current + buffer's modes and commands that have keybindings in the + current buffer's active local keymaps. It also includes + several commands, like Cuztomize commands, which should + always be avaliable." :version "28.1" :group 'completion :type '(choice (const :tag "Don't exclude any commands" nil) (const :tag "Exclude commands irrelevant to current buffer's mode" command-completion-default-include-p) - (function :tag "Other function"))) + (const :tag "Include only commands relevant to current buffer's mode" + command-completion-using-modes-p) + (const :tag "Commands relevant to current buffer's mode or bound in its keymaps" + command-completion-using-modes-and-keymaps-p) + (function :tag "Other predicate function"))) (defun execute-extended-command-cycle () "Choose the next version of the extended command predicates. @@ -2401,6 +2425,35 @@ command-completion-with-modes-p #'eq) (seq-intersection modes global-minor-modes #'eq))) +(defun command-completion-using-modes-and-keymaps-p (symbol buffer) + "Return non-nil if SYMBOL is marked for BUFFER's mode or bound in its keymaps." + (with-current-buffer buffer + (let ((keymaps + ;; The major mode's keymap and any active minor modes. + (nconc + (and (current-local-map) (list (current-local-map))) + (mapcar + #'cdr + (seq-filter + (lambda (elem) + (symbol-value (car elem))) + minor-mode-map-alist))))) + (or (command-completion-using-modes-p symbol buffer) + ;; Include commands that are bound in a keymap in the + ;; current buffer. + (and (where-is-internal symbol keymaps) + ;; But not if they have a command predicate that + ;; says that they shouldn't. (This is the case + ;; for `ignore' and `undefined' and similar + ;; commands commonly found in keymaps.) + (or (null (get symbol 'completion-predicate)) + (funcall (get symbol 'completion-predicate) + symbol buffer))) + ;; Include customize-* commands (do we need a list of such + ;; "always available" commands? customizable?) + (string-match-p "customize-" (symbol-name symbol)))))) + + (defun command-completion-button-p (category buffer) "Return non-nil if there's a button of CATEGORY at point in BUFFER." (with-current-buffer buffer @@ -2502,7 +2555,11 @@ execute-extended-command--describe-binding-msg (defun execute-extended-command (prefixarg &optional command-name typed) "Read a command name, then read the arguments and call the command. To pass a prefix argument to the command you are -invoking, give a prefix argument to `execute-extended-command'." +invoking, give a prefix argument to `execute-extended-command'. + +This command provides completion when reading the command name. +Which completion candidates are shown can be controlled by +customizing `read-extended-command-predicate'." (declare (interactive-only command-execute)) ;; FIXME: Remember the actual text typed by the user before completion, ;; so that we don't later on suggest the same shortening. commit fef4f18cc33754c1c06be3100563e2b0b690c067 Author: Michael Albinus Date: Sun Jan 8 10:56:06 2023 +0100 ; Fix NEWS diff --git a/etc/NEWS b/etc/NEWS index c7cfead5fd0..e9366fe8dd4 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -797,10 +797,10 @@ 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-bracket-face', 'font-lock-delimiter-face', -'font-lock-escape-face', 'font-lock-number-face', -'font-lock-regexp-face', -'font-lock-misc-punctuation-face', 'font-lock-operator-face', -'font-lock-property-face', and 'font-lock-punctuation-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'. +++ ** New face 'variable-pitch-text'. @@ -3211,8 +3211,8 @@ An optional major mode based on the tree-sitter library for editing programs in the C++ language. +++ -*** New major mode 'c-or-c++-ts-mode'. -A function that automatically guesses the language of a header file, +*** New command 'c-or-c++-ts-mode'. +A command that automatically guesses the language of a header file, and enables either 'c-ts-mode' or 'c++-ts-mode' accordingly. +++ commit e04b3d41bb41ccca3d403345b12b9a614213d488 Author: Kyle Meyer Date: Sat Jan 7 23:50:54 2023 -0500 Update to Org 9.6-90-ga6523f diff --git a/doc/misc/org.org b/doc/misc/org.org index ed3eb0626f2..7ca2cce9e7f 100644 --- a/doc/misc/org.org +++ b/doc/misc/org.org @@ -1249,11 +1249,12 @@ After the drawer. #+findex: org-insert-drawer You can interactively insert a drawer at point by calling ~org-insert-drawer~, which is bound to {{{kbd(C-c C-x d)}}}. With an -active region, this command puts the region inside the drawer. With -a prefix argument, this command calls ~org-insert-property-drawer~, -which creates a =PROPERTIES= drawer right below the current headline. -Org mode uses this special drawer for storing properties (see -[[*Properties and Columns]]). You cannot use it for anything else. +active region, this command puts the region inside the drawer. With a +prefix argument, this command calls non-interactive function +~org-insert-property-drawer~, which creates a =PROPERTIES= drawer +right below the current headline. Org mode uses this special drawer +for storing properties (see [[*Properties and Columns]]). You cannot use +it for anything else. Completion over drawer keywords is also possible using {{{kbd(M-TAB)}}}[fn:6]. diff --git a/lisp/org/ob-core.el b/lisp/org/ob-core.el index 9bb77f7920b..93cdf6ae868 100644 --- a/lisp/org/ob-core.el +++ b/lisp/org/ob-core.el @@ -1690,6 +1690,7 @@ org-babel-process-params (append (split-string (if (stringp raw-result) raw-result + ;; FIXME: Arbitrary code evaluation. (eval raw-result t))) (cdr (assq :result-params params)))))) (append @@ -2860,6 +2861,7 @@ org-babel-merge-params (split-string (cond ((stringp value) value) ((functionp value) (funcall value)) + ;; FIXME: Arbitrary code evaluation. (t (eval value t))))))) (`(:exports . ,value) (setq exports (funcall merge @@ -3188,16 +3190,8 @@ org-babel-read ((and (not inhibit-lisp-eval) (or (memq (string-to-char cell) '(?\( ?' ?` ?\[)) (string= cell "*this*"))) - ;; Prevent arbitrary function calls. - (if (and (memq (string-to-char cell) '(?\( ?`)) - (not (org-babel-confirm-evaluate - ;; See `org-babel-get-src-block-info'. - (list "emacs-lisp" cell - '((:eval . yes)) nil (format "%s" cell) - nil nil)))) - ;; Not allowed. - (user-error "Evaluation of elisp code %S aborted." cell) - (eval (read cell) t))) + ;; FIXME: Arbitrary code evaluation. + (eval (read cell) t)) ((save-match-data (and (string-match "^[[:space:]]*\"\\(.*\\)\"[[:space:]]*$" cell) (not (string-match "[^\\]\"" (match-string 1 cell))))) diff --git a/lisp/org/ob-shell.el b/lisp/org/ob-shell.el index 4a60186cd5d..2c30a26056b 100644 --- a/lisp/org/ob-shell.el +++ b/lisp/org/ob-shell.el @@ -79,7 +79,7 @@ org-babel-shell-initialize ,(format "Execute a block of %s commands with Babel." name) (let ((shell-file-name ,name) (org-babel-prompt-command - (or (alist-get ,name org-babel-shell-set-prompt-commands) + (or (cdr (assoc ,name org-babel-shell-set-prompt-commands)) (alist-get t org-babel-shell-set-prompt-commands)))) (org-babel-execute:shell body params)))) (eval `(defalias ',(intern (concat "org-babel-variable-assignments:" name)) diff --git a/lisp/org/org-macs.el b/lisp/org/org-macs.el index 72929cdd26c..07c668a807d 100644 --- a/lisp/org/org-macs.el +++ b/lisp/org/org-macs.el @@ -372,18 +372,23 @@ org-compile-file it for output." (let* ((base-name (file-name-base source)) (full-name (file-truename source)) - (out-dir (or (file-name-directory source) "./")) + (relative-name (file-relative-name source)) + (out-dir (if (file-name-directory source) + ;; Expand "~". Shell expansion will be disabled + ;; in the shell command call. + (file-name-directory full-name) + "./")) (output (expand-file-name (concat base-name "." ext) out-dir)) (time (file-attribute-modification-time (file-attributes output))) (err-msg (if (stringp err-msg) (concat ". " err-msg) ""))) (save-window-excursion (pcase process - ((pred functionp) (funcall process (shell-quote-argument source))) + ((pred functionp) (funcall process (shell-quote-argument relative-name))) ((pred consp) (let ((log-buf (and log-buf (get-buffer-create log-buf))) (spec (append spec `((?b . ,(shell-quote-argument base-name)) - (?f . ,(shell-quote-argument source)) + (?f . ,(shell-quote-argument relative-name)) (?F . ,(shell-quote-argument full-name)) (?o . ,(shell-quote-argument out-dir)) (?O . ,(shell-quote-argument output)))))) diff --git a/lisp/org/org-persist.el b/lisp/org/org-persist.el index c3650c167e2..336496efbfb 100644 --- a/lisp/org/org-persist.el +++ b/lisp/org/org-persist.el @@ -753,12 +753,12 @@ org-persist-unregister When ASSOCIATED is `all', unregister CONTAINER everywhere." (unless org-persist--index (org-persist--load-index)) (setq container (org-persist--normalize-container container)) - (setq associated (org-persist--normalize-associated associated)) (if (eq associated 'all) (mapc (lambda (collection) (when (member container (plist-get collection :container)) (org-persist-unregister container (plist-get collection :associated)))) org-persist--index) + (setq associated (org-persist--normalize-associated associated)) (let ((collection (org-persist--find-index `(:container ,container :associated ,associated)))) (when collection (if (= (length (plist-get collection :container)) 1) diff --git a/lisp/org/org-table.el b/lisp/org/org-table.el index 06cf919db76..fac9e68c124 100644 --- a/lisp/org/org-table.el +++ b/lisp/org/org-table.el @@ -2614,6 +2614,7 @@ org-table-eval-formula (if lispp (setq ev (condition-case nil + ;; FIXME: Arbitrary code evaluation. (eval (eval (read form))) (error "#ERROR")) ev (if (numberp ev) (number-to-string ev) ev) diff --git a/lisp/org/org-version.el b/lisp/org/org-version.el index dd6d92d8e58..942cc4eae8b 100644 --- a/lisp/org/org-version.el +++ b/lisp/org/org-version.el @@ -11,7 +11,7 @@ org-release (defun org-git-version () "The Git version of Org mode. Inserted by installing Org or when a release is made." - (let ((org-git-version "release_9.6-81-g563a43")) + (let ((org-git-version "release_9.6-90-ga6523f")) org-git-version)) (provide 'org-version) diff --git a/lisp/org/org.el b/lisp/org/org.el index 21764f3d434..8d226c2c5ab 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -4898,16 +4898,20 @@ org-mode (= (point-min) (point-max))) (insert "# -*- mode: org -*-\n\n")) (unless org-inhibit-startup + (when (or org-startup-align-all-tables org-startup-shrink-all-tables) + (org-table-map-tables + (cond ((and org-startup-align-all-tables + org-startup-shrink-all-tables) + (lambda () (org-table-align) (org-table-shrink))) + (org-startup-align-all-tables #'org-table-align) + (t #'org-table-shrink)) + t)) + ;; Suppress modification hooks to speed up the startup. + ;; However, do it only when text properties/overlays, but not + ;; buffer text are actually modified. We still need to track text + ;; modifications to make cache updates work reliably. (org-unmodified (when org-startup-with-beamer-mode (org-beamer-mode)) - (when (or org-startup-align-all-tables org-startup-shrink-all-tables) - (org-table-map-tables - (cond ((and org-startup-align-all-tables - org-startup-shrink-all-tables) - (lambda () (org-table-align) (org-table-shrink))) - (org-startup-align-all-tables #'org-table-align) - (t #'org-table-shrink)) - t)) (when org-startup-with-inline-images (org-display-inline-images)) (when org-startup-with-latex-preview (org-latex-preview '(16))) (unless org-inhibit-startup-visibility-stuff (org-cycle-set-startup-visibility)) @@ -8855,7 +8859,7 @@ org-options-keywords "EXCLUDE_TAGS:" "FILETAGS:" "INCLUDE:" "INDEX:" "KEYWORDS:" "LANGUAGE:" "MACRO:" "OPTIONS:" "PROPERTY:" "PRINT_BIBLIOGRAPHY" "PRIORITIES:" "SELECT_TAGS:" "SEQ_TODO:" "SETUPFILE:" "STARTUP:" "TAGS:" "TITLE:" "TODO:" - "TYP_TODO:" "SELECT_TAGS:" "EXCLUDE_TAGS:")) + "TYP_TODO:" "SELECT_TAGS:" "EXCLUDE_TAGS:" "EXPORT_FILE_NAME:")) (defcustom org-structure-template-alist '(("a" . "export ascii") diff --git a/lisp/org/ox.el b/lisp/org/ox.el index 62fc8d583e4..12767267a71 100644 --- a/lisp/org/ox.el +++ b/lisp/org/ox.el @@ -6757,7 +6757,6 @@ org-export-output-file-name (cond (pub-dir (concat (file-name-as-directory pub-dir) (file-name-nondirectory base-name))) - ((file-name-absolute-p base-name) base-name) (t base-name)))) ;; If writing to OUTPUT-FILE would overwrite original file, append ;; EXTENSION another time to final name. commit e3d806b4172f16c446bb3c5b31a160ed24fa5244 Author: Yuan Fu Date: Sat Jan 7 18:41:28 2023 -0800 Fix string fontification on python-ts-mode (bug#60599) * lisp/progmodes/python.el: (python--treesit-fontify-string): Generalize and skip anything before the first quote character. diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index e6ded7a0646..21d16db287c 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1067,8 +1067,11 @@ python--treesit-fontify-string "expression_statement")) 'font-lock-doc-face 'font-lock-string-face))) - (when (eq (char-after string-beg) ?f) - (cl-incf string-beg)) + ;; Don't highlight string prefixes like f/r/b. + (save-excursion + (goto-char string-beg) + (when (search-forward "\"" string-end t) + (setq string-beg (match-beginning 0)))) (treesit-fontify-with-override string-beg string-end face override start end))) commit 800e15e3be0569efdaa5e42c82937b1c87b7ec58 Author: Yuan Fu Date: Sat Jan 7 18:38:24 2023 -0800 Fix string-interpolation feature of python-ts-mode (bug#60599) * lisp/progmodes/python.el: (python--treesit-fontify-string-interpolation): New function. (python--treesit-settings): Use the new function for string-interpolation. diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index c399bbc64f8..e6ded7a0646 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1072,6 +1072,20 @@ python--treesit-fontify-string (treesit-fontify-with-override string-beg string-end face override start end))) +(defun python--treesit-fontify-string-interpolation + (node _ start end &rest _) + "Fontify string interpolation. +NODE is the string node. Do not fontify the initial f for +f-strings. START and END mark the region to be +fontified." + ;; This is kind of a hack, it basically removes the face applied by + ;; the string feature, so that following features can apply their + ;; face. + (let ((n-start (treesit-node-start node)) + (n-end (treesit-node-end node))) + (remove-text-properties + (max start n-start) (min end n-end) '(face)))) + (defvar python--treesit-settings (treesit-font-lock-rules :feature 'comment @@ -1082,10 +1096,12 @@ python--treesit-settings :language 'python '((string) @python--treesit-fontify-string) + ;; HACK: This feature must come after the string feature and before + ;; other features. Maybe we should make string-interpolation an + ;; option rather than a feature. :feature 'string-interpolation :language 'python - :override t - '((interpolation (identifier) @font-lock-variable-name-face)) + '((interpolation) @python--treesit-fontify-string-interpolation) :feature 'definition :language 'python commit 38b63f4c3ce55f998f00ba9a9a48d6f1b4533f7d Author: Theodor Thornhill Date: Sat Jan 7 13:04:07 2023 +0100 Add indentation rule for concatenated_string (bug#60572) * lisp/progmodes/c-ts-mode.el (c-ts-mode--indent-styles): Indent to parent-bol. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index f58fac40ce2..66f179f2f7f 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -138,6 +138,7 @@ c-ts-mode--indent-styles ((parent-is "function_definition") parent-bol 0) ((parent-is "conditional_expression") first-sibling 0) ((parent-is "assignment_expression") parent-bol c-ts-mode-indent-offset) + ((parent-is "concatenated_string") parent-bol c-ts-mode-indent-offset) ((parent-is "comma_expression") first-sibling 0) ((parent-is "init_declarator") parent-bol c-ts-mode-indent-offset) ((parent-is "parenthesized_expression") first-sibling 1) commit 2cdd75a18ff8815ca22a04228e3282e54097e242 Author: Jostein Kjønigsen Date: Wed Jan 4 09:13:23 2023 +0100 Fix highlighting of variable-declarations in typescript-ts-mode (bug#60546) - Highlight variable declarations in catch-clauses. - Remove highlighting of variables where not declarations (improve consistency with other *-ts-modes). * lisp/progmodes/typescript-ts-mode.el: (typescript-ts-mode--font-lock-settings): See above. diff --git a/lisp/progmodes/typescript-ts-mode.el b/lisp/progmodes/typescript-ts-mode.el index 5a9a7eea959..b26dca101db 100644 --- a/lisp/progmodes/typescript-ts-mode.el +++ b/lisp/progmodes/typescript-ts-mode.el @@ -194,7 +194,10 @@ typescript-ts-mode--font-lock-settings name: (array_pattern (identifier) (identifier) @font-lock-function-name-face) - value: (array (number) (function)))) + value: (array (number) (function))) + + (catch_clause + parameter: (identifier) @font-lock-variable-name-face)) :language language :override t @@ -223,17 +226,7 @@ typescript-ts-mode--font-lock-settings parameters: [(_ (identifier) @font-lock-variable-name-face) (_ (_ (identifier) @font-lock-variable-name-face)) - (_ (_ (_ (identifier) @font-lock-variable-name-face)))]) - - (return_statement (identifier) @font-lock-variable-name-face) - - (binary_expression left: (identifier) @font-lock-variable-name-face) - (binary_expression right: (identifier) @font-lock-variable-name-face) - - (arguments (identifier) @font-lock-variable-name-face) - - (parenthesized_expression (identifier) @font-lock-variable-name-face) - (parenthesized_expression (_ (identifier) @font-lock-variable-name-face))) + (_ (_ (_ (identifier) @font-lock-variable-name-face)))])) :language language :override t @@ -245,8 +238,6 @@ typescript-ts-mode--font-lock-settings (pair key: (property_identifier) @font-lock-variable-name-face) - (pair value: (identifier) @font-lock-variable-name-face) - ((shorthand_property_identifier) @font-lock-property-face) ((shorthand_property_identifier_pattern) commit 73168793c015d3da6b21bc96db784f9ef9225cbb Author: Yuan Fu Date: Sat Jan 7 18:11:03 2023 -0800 Fix label indentation for Linux style in c-ts-mode (bug#60543) Reference: 1. https://www.gnu.org/software/indent/manual/indent/Common-styles.html 2. https://www.gnu.org/software/indent/manual/indent/Option-Summary.html The GNU indent manual says Linux style should use -il1 flag, which means "indent labels to column 1". * lisp/progmodes/c-ts-mode.el (c-ts-mode--indent-styles): Indent label to column 1 in Linux style. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 3463600bda2..f58fac40ce2 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -169,7 +169,9 @@ c-ts-mode--indent-styles ((match "while" "do_statement") parent 0) ,@common) (k&r ,@common) - (linux ,@common) + (linux + ((node-is "labeled_statement") point-min 1) + ,@common) (bsd ((parent-is "if_statement") parent-bol 0) ((parent-is "for_statement") parent-bol 0) commit 8575043f56b6b09001d53657f91eb2bb706e802a Author: Yuan Fu Date: Sat Jan 7 17:46:27 2023 -0800 Remove duplicate entries in c-ts-mode's Imenu Right now the Class subindex includes top-level functions, which is wrong. This change ensures the Class subindex only contain classes and functions nested in those classes. * lisp/progmodes/c-ts-mode.el: (c-ts-mode--defun-for-class-in-imenu-p): New function. * lisp/progmodes/c-ts-mode.el (c-ts-base-mode): Use the new function. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index d2280f1d382..3463600bda2 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -583,6 +583,23 @@ c-ts-mode--defun-valid-p node "declarator")) "function_declarator"))))) +(defun c-ts-mode--defun-for-class-in-imenu-p (node) + "Check if NODE is a valid entry for the Class subindex. + +Basically, if NODE is a class, return non-nil; if NODE is a +function but is under a class, return non-nil; if NODE is a +top-level function, return nil. + +This is for the Class subindex in +`treesit-simple-imenu-settings'." + (pcase (treesit-node-type node) + ;; The Class subindex only has class_specifier and + ;; function_definition. + ("class_specifier" t) + ("function_definition" + ;; Return t if this function is nested in a class. + (treesit-node-top-level node "class_specifier")))) + (defun c-ts-mode--defun-skipper () "Custom defun skipper for `c-ts-mode' and friends. Structs in C ends with a semicolon, but the semicolon is not @@ -788,7 +805,7 @@ c-ts-base-mode ("Class" ,(rx bos (or "class_specifier" "function_definition") eos) - ,pred nil)))) + c-ts-mode--defun-for-class-in-imenu-p nil)))) (setq-local treesit-font-lock-feature-list '(( comment definition) commit ef7f3c6388be1299e3834f7c96889f0e17745c24 Author: Yuan Fu Date: Sat Jan 7 17:26:26 2023 -0800 Fix use of treesit-ready-p in c/c++-ts-mode * lisp/progmodes/c-ts-mode.el: (c-ts-mode) (c++-ts-mode): Put setup code in a when form. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index ae50c0ef991..d2280f1d382 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -805,22 +805,17 @@ c-ts-mode `c-basic-offset', don't affect this mode." :group 'c - (unless (treesit-ready-p 'c) - (error "Tree-sitter for C isn't available")) - - (treesit-parser-create 'c) - - ;; Comments. - (setq-local comment-start "/* ") - (setq-local comment-end " */") - - (setq-local treesit-simple-indent-rules - (c-ts-mode--set-indent-style 'c)) - - ;; Font-lock. - (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'c)) - - (treesit-major-mode-setup)) + (when (treesit-ready-p 'c) + (treesit-parser-create 'c) + ;; Comments. + (setq-local comment-start "/* ") + (setq-local comment-end " */") + ;; Indent. + (setq-local treesit-simple-indent-rules + (c-ts-mode--set-indent-style 'c)) + ;; Font-lock. + (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'c)) + (treesit-major-mode-setup))) ;;;###autoload (define-derived-mode c++-ts-mode c-ts-base-mode "C++" @@ -831,20 +826,17 @@ c++-ts-mode `c-basic-offset', don't affect this mode." :group 'c++ - (unless (treesit-ready-p 'cpp) - (error "Tree-sitter for C++ isn't available")) - - (treesit-parser-create 'cpp) - (setq-local syntax-propertize-function - #'c-ts-mode--syntax-propertize) - - (setq-local treesit-simple-indent-rules - (c-ts-mode--set-indent-style 'cpp)) - - ;; Font-lock. - (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'cpp)) - - (treesit-major-mode-setup)) + (when (treesit-ready-p 'cpp) + (treesit-parser-create 'cpp) + ;; Syntax. + (setq-local syntax-propertize-function + #'c-ts-mode--syntax-propertize) + ;; Indent. + (setq-local treesit-simple-indent-rules + (c-ts-mode--set-indent-style 'cpp)) + ;; Font-lock. + (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'cpp)) + (treesit-major-mode-setup))) ;; We could alternatively use parsers, but if this works well, I don't ;; see the need to change. This is copied verbatim from cc-guess.el. commit cc1de953d4fa203b3a0c58a63e0251b515be991d Author: Yuan Fu Date: Sat Jan 7 16:54:43 2023 -0800 ; * lisp/progmodes/gud.el (gud-tooltip-modes): Add ts- modes. Prompted by bug#60463. diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el index cb766c68411..3b792354cbc 100644 --- a/lisp/progmodes/gud.el +++ b/lisp/progmodes/gud.el @@ -3608,8 +3608,9 @@ gud-tooltip-mode (kill-local-variable 'gdb-define-alist) (remove-hook 'after-save-hook #'gdb-create-define-alist t)))) -(defcustom gud-tooltip-modes '(gud-mode c-mode c++-mode fortran-mode - python-mode) +(defcustom gud-tooltip-modes '( gud-mode c-mode c++-mode fortran-mode + python-mode c-ts-mode c++-ts-mode + python-ts-mode) "List of modes for which to enable GUD tooltips." :type '(repeat (symbol :tag "Major mode")) :group 'tooltip) commit 16f1e47ca8b2e0948691d63e8a0cbf30c5685301 Author: Yuan Fu Date: Sat Jan 7 16:52:17 2023 -0800 ; * lisp/align.el (align-c++-modes): Add c/c++-ts-mode. This fixes bug#60463. diff --git a/lisp/align.el b/lisp/align.el index 569186d241d..79a75dcec79 100644 --- a/lisp/align.el +++ b/lisp/align.el @@ -179,7 +179,8 @@ align-large-region :type '(choice (const :tag "Align a large region silently" nil) integer) :group 'align) -(defcustom align-c++-modes '(c++-mode c-mode java-mode) +(defcustom align-c++-modes '( c++-mode c-mode java-mode + c-ts-mode c++-ts-mode) "A list of modes whose syntax resembles C/C++." :type '(repeat symbol) :group 'align) commit 508389ad2bb3e33269a66f2fcb020839b5a9a132 Author: Yuan Fu Date: Sat Jan 7 16:32:46 2023 -0800 Add documentation for c/c++-ts-mode (bug#60443) Explain that tree-sitter c modes and cc-mode c modes don't share config variables. * lisp/progmodes/c-ts-mode.el (c-ts-mode) (c++-ts-mode): Update docstring. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index a35a0f12f51..ae50c0ef991 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -798,7 +798,11 @@ c-ts-base-mode ;;;###autoload (define-derived-mode c-ts-mode c-ts-base-mode "C" - "Major mode for editing C, powered by tree-sitter." + "Major mode for editing C, powered by tree-sitter. + +This mode is independent from the classic cc-mode.el based +`c-mode', so configuration variables of that mode, like +`c-basic-offset', don't affect this mode." :group 'c (unless (treesit-ready-p 'c) @@ -820,7 +824,11 @@ c-ts-mode ;;;###autoload (define-derived-mode c++-ts-mode c-ts-base-mode "C++" - "Major mode for editing C++, powered by tree-sitter." + "Major mode for editing C++, powered by tree-sitter. + +This mode is independent from the classic cc-mode.el based +`c++-mode', so configuration variables of that mode, like +`c-basic-offset', don't affect this mode." :group 'c++ (unless (treesit-ready-p 'cpp) commit ee3e8d3f927eba45b6863d4b2448376aacb02501 Author: Dmitry Gutov Date: Sun Jan 8 03:56:32 2023 +0200 (ruby-ts--font-lock-settings): Improve highlighting in patterns * lisp/progmodes/ruby-ts-mode.el (ruby-ts--font-lock-settings): Improve highlighting in patterns: highlight values not keys as variable in the usual case; highlight keys when no value; highlight the "as pattern" variable. diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el index 5f5de500435..9ec771e2fff 100644 --- a/lisp/progmodes/ruby-ts-mode.el +++ b/lisp/progmodes/ruby-ts-mode.el @@ -304,7 +304,12 @@ ruby-ts--font-lock-settings (array_pattern (identifier) @font-lock-variable-name-face) (keyword_pattern - key: (hash_key_symbol) @font-lock-variable-name-face) + value: (identifier) @font-lock-variable-name-face) + (keyword_pattern + key: (hash_key_symbol) @font-lock-variable-name-face + !value) + (as_pattern + name: (identifier) @font-lock-variable-name-face) (in_clause pattern: (identifier) @font-lock-variable-name-face)) commit 614f8c431d3e47d0e930207809454efc7118850d Author: Yuan Fu Date: Sat Jan 7 16:03:37 2023 -0800 Optionally include the namespace in c-ts-mode--declarator-identifier This is an additional fix for bug#60397. * lisp/progmodes/c-ts-mode.el: (c-ts-mode--declarator-identifier): New parameter QUALIFIED. (c-ts-mode--defun-name): Use qualified identifier. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 43d714dbb20..a35a0f12f51 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -423,20 +423,29 @@ c-ts-mode--font-lock-settings ;;; Font-lock helpers -(defun c-ts-mode--declarator-identifier (node) - "Return the identifier of the declarator node NODE." +(defun c-ts-mode--declarator-identifier (node &optional qualified) + "Return the identifier of the declarator node NODE. + +If QUALIFIED is non-nil, include the names space part of the +identifier and return a qualified_identifier." (pcase (treesit-node-type node) ;; Recurse. ((or "attributed_declarator" "parenthesized_declarator") - (c-ts-mode--declarator-identifier (treesit-node-child node 0 t))) + (c-ts-mode--declarator-identifier (treesit-node-child node 0 t) + qualified)) ((or "pointer_declarator" "reference_declarator") - (c-ts-mode--declarator-identifier (treesit-node-child node -1))) + (c-ts-mode--declarator-identifier (treesit-node-child node -1) + qualified)) ((or "function_declarator" "array_declarator" "init_declarator") (c-ts-mode--declarator-identifier - (treesit-node-child-by-field-name node "declarator"))) + (treesit-node-child-by-field-name node "declarator") + qualified)) ("qualified_identifier" - (c-ts-mode--declarator-identifier - (treesit-node-child-by-field-name node "name"))) + (if qualified + node + (c-ts-mode--declarator-identifier + (treesit-node-child-by-field-name node "name") + qualified))) ;; Terminal case. ((or "identifier" "field_identifier") node))) @@ -538,7 +547,8 @@ c-ts-mode--defun-name (pcase (treesit-node-type node) ((or "function_definition" "declaration") (c-ts-mode--declarator-identifier - (treesit-node-child-by-field-name node "declarator"))) + (treesit-node-child-by-field-name node "declarator") + t)) ((or "struct_specifier" "enum_specifier" "union_specifier" "class_specifier" "namespace_definition") commit 7c356934fbb07d6b0f267f8d21ffc9b3f7d9d1c3 Author: Yuan Fu Date: Sat Jan 7 15:45:05 2023 -0800 Support namespaces in c++-ts-mode (bug#60397) Not a complete fix. See the next commit. * lisp/progmodes/c-ts-mode.el (c-ts-mode--indent-styles): Add rules. (c-ts-mode--defun-name): Add namespace_definition. (c-ts-base-mode): Add namespace_definition to treesit-defun-type-regexp. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index a6ab454012d..43d714dbb20 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -151,7 +151,9 @@ c-ts-mode--indent-styles ((parent-is "call_expression") parent 0) ((parent-is "enumerator_list") parent-bol c-ts-mode-indent-offset) ,@(when (eq mode 'cpp) - '(((node-is "access_specifier") parent-bol 0))) + '(((node-is "access_specifier") parent-bol 0) + ;; Indent the body of namespace definitions. + ((parent-is "declaration_list") parent-bol c-ts-mode-indent-offset))) ((parent-is "field_declaration_list") parent-bol c-ts-mode-indent-offset) ((parent-is "initializer_list") parent-bol c-ts-mode-indent-offset) ((parent-is "if_statement") parent-bol c-ts-mode-indent-offset) @@ -538,7 +540,8 @@ c-ts-mode--defun-name (c-ts-mode--declarator-identifier (treesit-node-child-by-field-name node "declarator"))) ((or "struct_specifier" "enum_specifier" - "union_specifier" "class_specifier") + "union_specifier" "class_specifier" + "namespace_definition") (treesit-node-child-by-field-name node "name"))) t)) @@ -743,7 +746,8 @@ c-ts-base-mode "struct_specifier" "enum_specifier" "union_specifier" - "class_specifier")) + "class_specifier" + "namespace_definition")) #'c-ts-mode--defun-valid-p)) (setq-local treesit-defun-skipper #'c-ts-mode--defun-skipper) (setq-local treesit-defun-name-function #'c-ts-mode--defun-name) commit 757c2c25922e9c9dea33dd34f0112b631ea5c208 Author: Yuan Fu Date: Sat Jan 7 15:26:56 2023 -0800 Fix c-ts-mode--looking-at-star Not the topic of bug#60270 but reported in one of the replies. * lisp/progmodes/c-ts-mode.el (c-ts-mode--looking-at-star): Check not the character after point but character after BOL. Otherwise indentation is wrong when point is not at BOL. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index b8c4313c0f9..a6ab454012d 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -205,11 +205,13 @@ c-ts-mode--bracket-children-anchor (treesit-node-parent parent) parent))))) -(defun c-ts-mode--looking-at-star (&rest _) +(defun c-ts-mode--looking-at-star (_n _p bol &rest _) "A tree-sitter simple indent matcher. Matches if there is a \"*\" after point (ignoring whitespace in between)." - (looking-at (rx (* (syntax whitespace)) "*"))) + (save-excursion + (goto-char bol) + (looking-at (rx (* (syntax whitespace)) "*")))) (defun c-ts-mode--comment-start-after-first-star (_n parent &rest _) "A tree-sitter simple indent anchor. commit 1df2826639c912396fac0af108301533dac71406 Author: Yuan Fu Date: Sat Jan 7 14:58:37 2023 -0800 Add c-or-c++-ts-mode (bug#59613) * lisp/progmodes/c-ts-mode.el (c-ts-mode--c-or-c++-regexp): New variable. (c-or-c++-ts-mode): New mode. * etc/NEWS: Mention c-or-c++-ts-mode. diff --git a/etc/NEWS b/etc/NEWS index 5901b2718e9..c7cfead5fd0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3210,6 +3210,11 @@ programs in the C language. An optional major mode based on the tree-sitter library for editing programs in the C++ language. ++++ +*** New major mode 'c-or-c++-ts-mode'. +A function that automatically guesses the language of a header file, +and enables either 'c-ts-mode' or 'c++-ts-mode' accordingly. + +++ *** New major mode 'java-ts-mode'. An optional major mode based on the tree-sitter library for editing diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 30a14ecdfae..b8c4313c0f9 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -822,6 +822,50 @@ c++-ts-mode (treesit-major-mode-setup)) +;; We could alternatively use parsers, but if this works well, I don't +;; see the need to change. This is copied verbatim from cc-guess.el. +(defconst c-ts-mode--c-or-c++-regexp + (eval-when-compile + (let ((id "[a-zA-Z_][a-zA-Z0-9_]*") (ws "[ \t]+") (ws-maybe "[ \t]*") + (headers '("string" "string_view" "iostream" "map" "unordered_map" + "set" "unordered_set" "vector" "tuple"))) + (concat "^" ws-maybe "\\(?:" + "using" ws "\\(?:namespace" ws + "\\|" id "::" + "\\|" id ws-maybe "=\\)" + "\\|" "\\(?:inline" ws "\\)?namespace" + "\\(:?" ws "\\(?:" id "::\\)*" id "\\)?" ws-maybe "{" + "\\|" "class" ws id + "\\(?:" ws "final" "\\)?" ws-maybe "[:{;\n]" + "\\|" "struct" ws id "\\(?:" ws "final" ws-maybe "[:{\n]" + "\\|" ws-maybe ":\\)" + "\\|" "template" ws-maybe "<.*?>" + "\\|" "#include" ws-maybe "<" (regexp-opt headers) ">" + "\\)"))) + "A regexp applied to C header files to check if they are really C++.") + +;;;###autoload +(defun c-or-c++-ts-mode () + "Analyze buffer and enable either C or C++ mode. + +Some people and projects use .h extension for C++ header files +which is also the one used for C header files. This makes +matching on file name insufficient for detecting major mode that +should be used. + +This function attempts to use file contents to determine whether +the code is C or C++ and based on that chooses whether to enable +`c-ts-mode' or `c++-ts-mode'." + (interactive) + (if (save-excursion + (save-restriction + (save-match-data ; Why `save-match-data'? + (widen) + (goto-char (point-min)) + (re-search-forward c-ts-mode--c-or-c++-regexp nil t)))) + (c++-ts-mode) + (c-ts-mode))) + (provide 'c-ts-mode) ;;; c-ts-mode.el ends here commit 0cb686ffb6bbc017d3b71acbf40ed3e5c1a32863 Author: Eli Zaretskii Date: Sat Jan 7 19:57:30 2023 +0200 Document the 'definition-name' property. * doc/lispref/symbols.texi (Standard Properties): Document 'definition-name'. * doc/lispref/functions.texi (Defining Functions): Describe how to use 'definition-name' when generating function definitions at run time. (Bug#60568) diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index 3a8eddb93ea..f5572e447d3 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi @@ -685,6 +685,20 @@ Defining Functions @end group @end example +@cindex defining functions dynamically +Most Emacs functions are part of the source code of Lisp programs, and +are defined when the Emacs Lisp reader reads the program source before +executing it. However, you can also define functions dynamically at +run time, e.g., by generating @code{defun} calls when your program's +code is executed. If you do this, be aware that Emacs's Help +commands, such as @kbd{C-h f}, which present in the @file{*Help*} +buffer a button to jump to the function's definition, might be unable +to find the source code because generating a function dynamically +usually looks very different from the usual static calls to +@code{defun}. You can make the job of finding the code which +generates such functions easier by using the @code{definition-name} +property, @pxref{Standard Properties}. + @cindex override existing functions @cindex redefine existing functions Be careful not to redefine existing functions unintentionally. diff --git a/doc/lispref/symbols.texi b/doc/lispref/symbols.texi index 183367c0cda..5b53cbe310a 100644 --- a/doc/lispref/symbols.texi +++ b/doc/lispref/symbols.texi @@ -555,6 +555,23 @@ Standard Properties Do not set them directly; they are managed by @code{defcustom} and related functions. @xref{Variable Definitions}. +@item definition-name +This property is used to find the definition of a symbol in the source +code, when it might be hard to find the definition by textual search +of the source file. For example, a @code{define-derived-mode} +(@pxref{Derived Modes}) might define a mode-specific function or a +variable implicitly; or your Lisp program might generate a run-time +call to @code{defun} to define a function (@pxref{Defining +Functions}). In these and similar cases, the @code{definition-name} +property of the symbol should be another symbol whose definition can +be found by textual search and whose code defines the original symbol. +In the example with @code{define-derived-mode}, the value of this +property of the functions and variables it defines should be the mode +symbol. The Emacs Help commands such as @kbd{C-h f} (@pxref{Help,,, +emacs, The GNU Emacs Manual}) use this property to show the definition +of a symbol via a button in the @file{*Help*} buffer where the +symbol's documentation is shown. + @item disabled If the value is non-@code{nil}, the named function is disabled as a command. @xref{Disabling Commands}. commit 7f855b5297b2806fa508e73de98cb8cecc6e7d8d Author: Eli Zaretskii Date: Sat Jan 7 19:16:47 2023 +0200 ; Fix description of etc/DOC * doc/lispref/help.texi (Accessing Documentation): Doc strings of preloaded symbols are no longer in etc/DOC. diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index d902113122f..59b6b6dab1d 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi @@ -303,7 +303,7 @@ Accessing Documentation @defvar doc-directory This variable holds the name of the directory which should contain the file @code{"DOC"} that contains documentation strings for -built-in and preloaded functions and variables. +built-in functions and variables. In most cases, this is the same as @code{data-directory}. They may be different when you run Emacs from the directory where you built it, commit e9341119fe462c53b1f8d6650a3b6729a0728a0a Author: Eli Zaretskii Date: Sat Jan 7 15:25:11 2023 +0200 ; Fix documentation of etc/DOC * doc/lispref/help.texi (Documentation Basics): Doc strings of preloaded symbols are no longer in etc/DOC. diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index de5ed76c7f7..d902113122f 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi @@ -69,14 +69,14 @@ Documentation Basics @cindex @file{DOC} (documentation) file Sometimes, Emacs does not keep documentation strings in memory. There are two such circumstances. Firstly, to save memory, the -documentation for preloaded functions and variables (including -primitives) is kept in a file named @file{DOC}, in the directory -specified by @code{doc-directory} (@pxref{Accessing Documentation}). -Secondly, when a function or variable is loaded from a byte-compiled -file, Emacs avoids loading its documentation string (@pxref{Docs and -Compilation}). In both cases, Emacs looks up the documentation string -from the file only when needed, such as when the user calls @kbd{C-h -f} (@code{describe-function}) for a function. +documentation for primitive functions (@pxref{What Is a Function}) and +built-in variables is kept in a file named @file{DOC}, in the +directory specified by @code{doc-directory} (@pxref{Accessing +Documentation}). Secondly, when a function or variable is loaded from +a byte-compiled file, Emacs avoids loading its documentation string +(@pxref{Docs and Compilation}). In both cases, Emacs looks up the +documentation string from the file only when needed, such as when the +user calls @kbd{C-h f} (@code{describe-function}) for a function. Documentation strings can contain special @dfn{key substitution sequences}, referring to key bindings which are looked up only when commit 86a3462e3d286d4d39337ad450987bbba9415f16 Author: Dmitry Gutov Date: Sat Jan 7 13:16:56 2023 +0200 (treesit-simple-indent-presets): Do that for 'or' as well. * lisp/treesit.el (treesit-simple-indent-presets): Do that for 'or' as well. diff --git a/lisp/treesit.el b/lisp/treesit.el index 11a78bddcd8..7205e43916d 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -1187,9 +1187,12 @@ treesit-simple-indent-presets res)))) (cons 'or (lambda (&rest fns) (lambda (node parent bol &rest _) - (seq-find - (lambda (fn) (funcall fn node parent bol)) - fns)))) + (let (res) + (catch 'break + (dolist (fn fns) + (setq res (funcall fn node parent bol)) + (and res (throw 'break t)))) + res)))) (cons 'not (lambda (fn) (lambda (node parent bol &rest _) (not (funcall fn node parent bol))))) commit e0fef510b00d00b4a2e89b310e7ac3b64ab3455b Author: Eli Zaretskii Date: Sat Jan 7 11:25:52 2023 +0200 ; Minor rewording of tree-sitter terminology * doc/lispref/parsing.texi (Retrieving Nodes): Minor rewording. (Bug#60555) diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi index 9635427f940..b55af912f9b 100644 --- a/doc/lispref/parsing.texi +++ b/doc/lispref/parsing.texi @@ -540,11 +540,15 @@ Retrieving Nodes Here's some terminology and conventions we use when documenting tree-sitter functions. -We talk about a node being ``smaller'' or ``larger'', and ``lower'' or -``higher''. A smaller and lower node is lower in the syntax tree and -therefore spans a smaller portion of buffer text; a larger and higher -node is higher up in the syntax tree, it contains many smaller nodes -as its children, and therefore spans a larger portion of text. +A node in a syntax tree spans some portion of the program text in the +buffer. We say that a node is ``smaller'' or ``larger'' than another +if it spans, respectively, a smaller or larger portion of buffer text +than the other node. Since nodes that are deeper (``lower'') in the +tree are children of the nodes that are ``higher'' in the tree, it +follows that a lower node will always be smaller than a node that is +higher in the node hierarchy. A node that is higher up in the syntax +tree contains one or more smaller nodes as its children, and therefore +spans a larger portion of buffer text. When a function cannot find a node, it returns @code{nil}. For convenience, all functions that take a node as argument and return commit f58452e3ae7ed595566028010128c99e3afb572b Author: kobarity Date: Sun Jan 1 21:09:10 2023 +0900 Fix 'python-shell-buffer-substring' when START is in middle of 1st line * lisp/progmodes/python.el (python-shell-buffer-substring): Instead of checking whether START is point-min, check whether START is in the first line. (Bug#60466) * test/lisp/progmodes/python-tests.el (python-shell-buffer-substring-18): New test. diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 59164d7d50c..c399bbc64f8 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -3766,15 +3766,16 @@ python-shell-buffer-substring (line-beginning-position) start)))) (substring (buffer-substring-no-properties start end)) - (starts-at-point-min-p (save-restriction - (widen) - (= (point-min) start))) + (starts-at-first-line-p (save-restriction + (widen) + (goto-char start) + (= (line-number-at-pos) 1))) (encoding (python-info-encoding)) (toplevel-p (zerop (save-excursion (goto-char start) (python-util-forward-comment 1) (current-indentation)))) - (fillstr (cond (starts-at-point-min-p + (fillstr (cond (starts-at-first-line-p nil) ((not no-cookie) (concat diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el index eac558db10f..df71990278e 100644 --- a/test/lisp/progmodes/python-tests.el +++ b/test/lisp/progmodes/python-tests.el @@ -4520,6 +4520,16 @@ python-shell-buffer-substring-17 (python-tests-look-at "\"\"\"")) "# -*- coding: utf-8 -*-\n\nif True:\n a = 1\n b = 2\n\n")))) +(ert-deftest python-shell-buffer-substring-18 () + "Check substring from the part of the first line." + (python-tests-with-temp-buffer + "s = 'test' +" + (should (string= (python-shell-buffer-substring + (python-tests-look-at "'test'") + (pos-eol)) + "'test'")))) + ;;; Shell completion commit 7f9588685a0e1fe2dd0fcc5c3204426ac81cc6ac Author: Eli Zaretskii Date: Sat Jan 7 10:47:44 2023 +0200 ; Fix last change * doc/emacs/misc.texi (Saving Emacs Sessions): Minor rewording and rearrangements. (Bug#60600) diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index b707a7faa7c..e2764c34482 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -2705,15 +2705,16 @@ Saving Emacs Sessions @cindex restore session @cindex remember editing session @cindex reload files -@cindex desktop - Use the desktop library to save the state of Emacs from one session -to another. The Emacs @dfn{desktop} consists of the buffers, their -file names, major modes, buffer positions, and so on. +@cindex desktop configuration + You can use the desktop library to save the state of Emacs from one +session to another. The saved Emacs @dfn{desktop configuration} +includes the buffers, their file names, major modes, buffer positions, +window and frame configuration, and some important global variables. @vindex desktop-save-mode @findex desktop-save-mode -To enable this feature, use the Customization buffer (@pxref{Easy + To enable this feature, use the Customization buffer (@pxref{Easy Customization}) to set @code{desktop-save-mode} to @code{t} for future sessions, or add this line in your init file (@pxref{Init File}): @@ -2728,17 +2729,27 @@ Saving Emacs Sessions (which defaults to @code{user-emacs-directory} and then your home directory) and uses the first desktop it finds. While Emacs runs with @code{desktop-save-mode} turned on, it by default auto-saves the -desktop whenever any of it changes. The variable -@code{desktop-auto-save-timeout} determines how frequently Emacs -checks for modifications to your desktop. The desktop is also saved -when you exit Emacs. +desktop whenever any of the desktop configuration changes. The +variable @code{desktop-auto-save-timeout} determines how frequently +Emacs checks for modifications to your desktop. The desktop is also +saved when you exit Emacs. + +@cindex disable restoring of desktop configuration + Specify the option @samp{--no-desktop} on the Emacs command line +when you don't want it to reload any saved desktop configurations. +This turns off @code{desktop-save-mode} for the current session. +Starting Emacs with the @samp{--no-init-file} option also disables +desktop reloading, since it bypasses the init file, where +@code{desktop-save-mode} is usually turned on. @findex desktop-change-dir @findex desktop-revert - You can have separate saved desktops in different directories. You -can save the current desktop and reload one saved in another directory -by typing @kbd{M-x desktop-change-dir}. Typing @kbd{M-x -desktop-revert} reverts to the desktop previously reloaded. + You can have separate saved desktop configurations in different +directories; starting Emacs from a directory where you have a saved +desktop configuration will restore that configuration. You can save +the current desktop and reload the one saved in another directory by +typing @kbd{M-x desktop-change-dir}. Typing @kbd{M-x desktop-revert} +reverts to the previously reloaded desktop. @vindex desktop-load-locked-desktop The file in which Emacs saves the desktop is locked while the @@ -2749,33 +2760,46 @@ Saving Emacs Sessions can avoid the question by customizing the variable @code{desktop-load-locked-desktop} to either @code{nil}, which means never load the desktop in this case, or @code{t}, which means load the -desktop without asking. Finally, the @code{check-pid} value means to -load the file if the Emacs process that has locked the desktop is not -running on the local machine. This should not be used in -circumstances where the locking Emacs might still be running on -another machine. This could be the case in multi-user environments -where your home directory is mounted remotely using NFS or similar. +desktop without asking. You can also customize the variable to the +special value @code{check-pid}, which means to load the file if the +Emacs process that has locked the desktop is not running on the local +machine. This should not be used in circumstances where the locking +Emacs might still be running on another machine, which could be the +case in multi-user environments where your home directory is mounted +remotely using NFS or similar. + +@cindex desktop restore in daemon mode + When Emacs starts in daemon mode, it cannot ask you any questions, +so if it finds the desktop file locked, it will not load it, unless +@code{desktop-load-locked-desktop} is @code{t}. Note that restoring +the desktop in daemon mode is somewhat problematic for other reasons: +e.g., the daemon cannot use GUI features, so parameters such as frame +position, size, and decorations cannot be restored. For that reason, +you may wish to delay restoring the desktop in daemon mode until the +first client connects, by calling @code{desktop-read} (see below) in a +hook function that you add to @code{server-after-make-frame-hook} +(@pxref{Creating Frames,,, elisp, The Emacs Lisp Reference Manual}). @findex desktop-save @findex desktop-read Whenever you want, you can use the command @kbd{M-x desktop-save} to -force saving the current desktop. If you do not want to use the -automatic @code{desktop-save-mode}, you can use @kbd{M-x desktop-save} -and then @kbd{M-x desktop-read} to restore a previous desktop. +force immediate saving of the current desktop. This is useful either +if you do not want to use the automatic desktop restoration, and thus +don't turn on @code{desktop-save-mode}, or when you have made +significant changes to the desktop, and want to make sure the +configuration doesn't get lost if Emacs or your system crashes. You +can use @kbd{M-x desktop-read} to restore a previously-saved desktop +if the current Emacs session didn't load any desktop yet. @vindex desktop-restore-frames - By default, the desktop also tries to save the frame and window -configuration. To disable this, set @code{desktop-restore-frames} to -@code{nil}. (See that variable's documentation for some related -options that you can customize to fine-tune this behavior.) - -@vindex desktop-files-not-to-save - Information about buffers visiting remote files is not saved by -default. Customize the variable @code{desktop-files-not-to-save} to -change this. + By default, the desktop tries to save and restore the frame and +window configuration. To disable this, set +@code{desktop-restore-frames} to @code{nil}. (See that variable's +documentation for some related options that you can customize to +fine-tune this behavior.) @vindex frameset-filter-alist - When the desktop restores the frame and window configuration, it + When the desktop restores the frame and window configuration, it uses the recorded values of frame parameters, disregarding any settings for those parameters you have in your init file (@pxref{Init File}). This means that frame parameters such as fonts and faces for @@ -2783,7 +2807,13 @@ Saving Emacs Sessions saved when you exited your previous Emacs session; any settings for those parameters in your init file will be ignored. To disable this, customize the value of @code{frameset-filter-alist} to filter out the -frame parameters you don't want to be restored. +frame parameters you don't want to be restored; they will then be set +according to your customizations in the init file. + +@vindex desktop-files-not-to-save + Information about buffers visiting remote files is not saved by +default. Customize the variable @code{desktop-files-not-to-save} to +change this. @vindex desktop-restore-eager By default, all the buffers in the desktop are restored in one go. @@ -2795,32 +2825,15 @@ Saving Emacs Sessions @findex desktop-clear @vindex desktop-globals-to-clear @vindex desktop-clear-preserve-buffers-regexp - Type @kbd{M-x desktop-clear} to empty the Emacs desktop. This kills -all buffers except for internal ones, and clears the global variables -listed in @code{desktop-globals-to-clear}. If you want this to -preserve certain buffers, customize the variable + Type @kbd{M-x desktop-clear} to empty the Emacs desktop; this can be +useful, for example, if you want to switch to another desktop by +invoking @kbd{M-x desktop-read} next. The @code{desktop-clear} +command kills all buffers except for internal ones, and clears the +global variables listed in @code{desktop-globals-to-clear}. If you +want it to preserve certain buffers, customize the variable @code{desktop-clear-preserve-buffers-regexp}, whose value is a regular expression matching the names of buffers not to kill. - Specify the option @samp{--no-desktop} on the command line when you -don't want it to reload any saved desktop. This turns off -@code{desktop-save-mode} for the current session. Starting Emacs with -the @samp{--no-init-file} option also disables desktop reloading, -since it bypasses the init file, where @code{desktop-save-mode} is -usually turned on. - -@cindex desktop restore in daemon mode - When Emacs starts in daemon mode, it cannot ask you any questions, -so if it finds the desktop file locked, it will not load it, unless -@code{desktop-load-locked-desktop} is @code{t}. Note that restoring -the desktop in daemon mode is somewhat problematic for other reasons: -e.g., the daemon cannot use GUI features, so parameters such as frame -position, size, and decorations cannot be restored. For that reason, -you may wish to delay restoring the desktop in daemon mode until the -first client connects, by calling @code{desktop-read} in a hook -function that you add to @code{server-after-make-frame-hook} -(@pxref{Creating Frames,,, elisp, The Emacs Lisp Reference Manual}). - If you want to save minibuffer history from one session to another, use the @code{savehist} library. commit e8b85f225d9094aa05a6be1739245e816f0101a6 Author: Manuel Giraud Date: Fri Jan 6 11:29:20 2023 +0100 Rearrange the "Saving Emacs Sessions" section of the user manual * doc/emacs/misc.texi (Saving Emacs Sessions): Organize this node more logically with main behavior and important features near the top. (Bug#60600) diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 5b60e93bb3d..b707a7faa7c 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -2707,38 +2707,13 @@ Saving Emacs Sessions @cindex reload files @cindex desktop -@vindex desktop-restore-frames Use the desktop library to save the state of Emacs from one session -to another. Once you save the Emacs @dfn{desktop}---the buffers, -their file names, major modes, buffer positions, and so on---then -subsequent Emacs sessions reload the saved desktop. By default, -the desktop also tries to save the frame and window configuration. -To disable this, set @code{desktop-restore-frames} to @code{nil}. -(See that variable's documentation for some related options -that you can customize to fine-tune this behavior.) - -@vindex desktop-files-not-to-save -Information about buffers visiting remote files is not saved by -default. Customize the variable @code{desktop-files-not-to-save} to -change this. +to another. The Emacs @dfn{desktop} consists of the buffers, their +file names, major modes, buffer positions, and so on. -@vindex frameset-filter-alist - When the desktop restores the frame and window configuration, it -uses the recorded values of frame parameters, disregarding any -settings for those parameters you have in your init file (@pxref{Init -File}). This means that frame parameters such as fonts and faces for -the restored frames will come from the desktop file, where they were -saved when you exited your previous Emacs session; any settings for -those parameters in your init file will be ignored. To disable this, -customize the value of @code{frameset-filter-alist} to filter out the -frame parameters you don't want to be restored. - -@findex desktop-save @vindex desktop-save-mode - You can save the desktop manually with the command @kbd{M-x -desktop-save}. You can also enable automatic saving of the desktop -when you exit Emacs, and automatic restoration of the last saved -desktop when Emacs starts: use the Customization buffer (@pxref{Easy +@findex desktop-save-mode +To enable this feature, use the Customization buffer (@pxref{Easy Customization}) to set @code{desktop-save-mode} to @code{t} for future sessions, or add this line in your init file (@pxref{Init File}): @@ -2746,25 +2721,69 @@ Saving Emacs Sessions (desktop-save-mode 1) @end example -@findex desktop-change-dir -@findex desktop-revert @vindex desktop-path +@vindex desktop-auto-save-timeout If you turn on @code{desktop-save-mode} in your init file, then when -Emacs starts, it looks for a saved desktop in the current directory. -(More precisely, it looks in the directories specified by -@code{desktop-path}, and uses the first desktop it finds.) -Thus, you can have separate saved desktops in different directories, -and the starting directory determines which one Emacs reloads. You +Emacs starts, it looks for a saved desktop in @code{desktop-path} +(which defaults to @code{user-emacs-directory} and then your home +directory) and uses the first desktop it finds. While Emacs runs with +@code{desktop-save-mode} turned on, it by default auto-saves the +desktop whenever any of it changes. The variable +@code{desktop-auto-save-timeout} determines how frequently Emacs +checks for modifications to your desktop. The desktop is also saved +when you exit Emacs. + +@findex desktop-change-dir +@findex desktop-revert + You can have separate saved desktops in different directories. You can save the current desktop and reload one saved in another directory by typing @kbd{M-x desktop-change-dir}. Typing @kbd{M-x desktop-revert} reverts to the desktop previously reloaded. - Specify the option @samp{--no-desktop} on the command line when you -don't want it to reload any saved desktop. This turns off -@code{desktop-save-mode} for the current session. Starting Emacs with -the @samp{--no-init-file} option also disables desktop reloading, -since it bypasses the init file, where @code{desktop-save-mode} is -usually turned on. +@vindex desktop-load-locked-desktop + The file in which Emacs saves the desktop is locked while the +session runs, to avoid inadvertently overwriting it from another Emacs +session. That lock is normally removed when Emacs exits, but if Emacs +or your system crashes, the lock stays, and when you restart Emacs, it +will by default ask you whether to use the locked desktop file. You +can avoid the question by customizing the variable +@code{desktop-load-locked-desktop} to either @code{nil}, which means +never load the desktop in this case, or @code{t}, which means load the +desktop without asking. Finally, the @code{check-pid} value means to +load the file if the Emacs process that has locked the desktop is not +running on the local machine. This should not be used in +circumstances where the locking Emacs might still be running on +another machine. This could be the case in multi-user environments +where your home directory is mounted remotely using NFS or similar. + +@findex desktop-save +@findex desktop-read + Whenever you want, you can use the command @kbd{M-x desktop-save} to +force saving the current desktop. If you do not want to use the +automatic @code{desktop-save-mode}, you can use @kbd{M-x desktop-save} +and then @kbd{M-x desktop-read} to restore a previous desktop. + +@vindex desktop-restore-frames + By default, the desktop also tries to save the frame and window +configuration. To disable this, set @code{desktop-restore-frames} to +@code{nil}. (See that variable's documentation for some related +options that you can customize to fine-tune this behavior.) + +@vindex desktop-files-not-to-save + Information about buffers visiting remote files is not saved by +default. Customize the variable @code{desktop-files-not-to-save} to +change this. + +@vindex frameset-filter-alist + When the desktop restores the frame and window configuration, it +uses the recorded values of frame parameters, disregarding any +settings for those parameters you have in your init file (@pxref{Init +File}). This means that frame parameters such as fonts and faces for +the restored frames will come from the desktop file, where they were +saved when you exited your previous Emacs session; any settings for +those parameters in your init file will be ignored. To disable this, +customize the value of @code{frameset-filter-alist} to filter out the +frame parameters you don't want to be restored. @vindex desktop-restore-eager By default, all the buffers in the desktop are restored in one go. @@ -2783,30 +2802,12 @@ Saving Emacs Sessions @code{desktop-clear-preserve-buffers-regexp}, whose value is a regular expression matching the names of buffers not to kill. - If you want to save minibuffer history from one session to -another, use the @code{savehist} library. - -@vindex desktop-auto-save-timeout - While Emacs runs with @code{desktop-save-mode} turned on, it by -default auto-saves the desktop whenever any of it changes. The -variable @code{desktop-auto-save-timeout} determines how frequently -Emacs checks for modifications to your desktop. - -@vindex desktop-load-locked-desktop - The file in which Emacs saves the desktop is locked while the -session runs, to avoid inadvertently overwriting it from another Emacs -session. That lock is normally removed when Emacs exits, but if Emacs -or your system crashes, the lock stays, and when you restart Emacs, it -will by default ask you whether to use the locked desktop file. You -can avoid the question by customizing the variable -@code{desktop-load-locked-desktop} to either @code{nil}, which means -never load the desktop in this case, or @code{t}, which means load the -desktop without asking. Finally, the @code{check-pid} value means to -load the file if the Emacs process that has locked the desktop is not -running on the local machine. This should not be used in -circumstances where the locking Emacs might still be running on -another machine. This could be the case in multi-user environments -where your home directory is mounted remotely using NFS or similar. + Specify the option @samp{--no-desktop} on the command line when you +don't want it to reload any saved desktop. This turns off +@code{desktop-save-mode} for the current session. Starting Emacs with +the @samp{--no-init-file} option also disables desktop reloading, +since it bypasses the init file, where @code{desktop-save-mode} is +usually turned on. @cindex desktop restore in daemon mode When Emacs starts in daemon mode, it cannot ask you any questions, @@ -2820,6 +2821,9 @@ Saving Emacs Sessions function that you add to @code{server-after-make-frame-hook} (@pxref{Creating Frames,,, elisp, The Emacs Lisp Reference Manual}). + If you want to save minibuffer history from one session to +another, use the @code{savehist} library. + @node Recursive Edit @section Recursive Editing Levels @cindex recursive editing level