commit dd2caf1a7634ea6fd8aebbdc45ea4caf22d786cd (HEAD, refs/remotes/origin/master) Author: F. Jason Park Date: Sun Jan 14 13:02:27 2024 -0800 Redo doc strings for ERC's entry point commands * lisp/erc/erc.el: Bump Compat version in Package-Requires header to 29.1.4.4. (erc-select-read-args): Revise doc string, and update name of internal `--interactive-env--' entry-point parameter. (erc, erc-tls): Don't use `&interactive-env' as a variable name, in case it confuses persons or programs. Overhaul doc string in response to user complaints. For `erc' specifically, include literal `:keyword' symbols to help non-Emacs users understand the required syntax, which isn't obvious without an example, like `erc-tls' has, and with only "&key" and upcased metasynctatic variables to go by. (erc--current-buffer-joined-p): Remove assertion. * test/lisp/erc/erc-scenarios-keep-place-indicator.el (erc-scenarios-keep-place-indicator--follow): Try waiting for intermittently failing condition. * test/lisp/erc/erc-tests.el (erc-select-read-args): Update name of internal keyword variable. diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 6332a8f6763..767a693a52e 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -13,7 +13,7 @@ ;; Michael Olson (mwolson@gnu.org) ;; Kelvin White (kwhite@gnu.org) ;; Version: 5.6-git -;; Package-Requires: ((emacs "27.1") (compat "29.1.4.3")) +;; Package-Requires: ((emacs "27.1") (compat "29.1.4.4")) ;; Keywords: IRC, chat, client, Internet ;; URL: https://www.gnu.org/software/emacs/erc.html @@ -2637,8 +2637,11 @@ typically the same as that reported by `erc-current-nick'." ;;;###autoload (defun erc-select-read-args () - "Prompt the user for values of nick, server, port, and password. -With prefix arg, also prompt for user and full name." + "Prompt for connection parameters and return them in a plist. +By default, collect `:server', `:port', `:nickname', and +`:password'. With a non-nil prefix argument, also prompt for +`:user' and `:full-name'. Also return various environmental +properties needed by entry-point commands, like `erc-tls'." (let* ((input (let ((d (erc-compute-server))) (if erc--prompt-for-server-function (funcall erc--prompt-for-server-function) @@ -2692,7 +2695,7 @@ With prefix arg, also prompt for user and full name." (setq passwd nil)) `( :server ,server :port ,port :nick ,nick ,@(and user `(:user ,user)) ,@(and passwd `(:password ,passwd)) ,@(and full `(:full-name ,full)) - ,@(and env `(&interactive-env ,env))))) + ,@(and env `(--interactive-env-- ,env))))) (defmacro erc--with-entrypoint-environment (env &rest body) "Run BODY with bindings from ENV alist." @@ -2721,30 +2724,40 @@ With prefix arg, also prompt for user and full name." (full-name (erc-compute-full-name)) id ;; Used by interactive form - ((&interactive-env --interactive-env--))) - "ERC is a powerful, modular, and extensible IRC client. -This function is the main entry point for ERC. - -It allows selecting connection parameters, and then starts ERC. - -Non-interactively, it takes the keyword arguments - (server (erc-compute-server)) - (port (erc-compute-port)) - (nick (erc-compute-nick)) - (user (erc-compute-user)) - password - (full-name (erc-compute-full-name)) - id - -That is, if called with + ((--interactive-env-- --interactive-env--))) + "Connect to an Internet Relay Chat SERVER on a non-TLS PORT. +Use NICK and USER, when non-nil, to inform the IRC commands of +the same name, possibly factoring in a non-nil FULL-NAME as well. +When PASSWORD is non-nil, also send an opening server password +via the \"PASS\" command. Interactively, prompt for SERVER, +PORT, NICK, and PASSWORD, along with USER and FULL-NAME when +given a prefix argument. Non-interactively, expect the rarely +needed ID parameter, when non-nil, to be a symbol or a string for +naming the server buffer and identifying the connection +unequivocally. (See Info node `(erc) Connecting' for details +about all mentioned parameters.) + +Together with `erc-tls', this command serves as the main entry +point for ERC, the powerful, modular, and extensible IRC client. +Non-interactively, both commands accept the following keyword +arguments, with their defaults supplied by the indicated +\"compute\" functions: + + :server `erc-compute-server' + :port `erc-compute-port' + :nick `erc-compute-nick' + :user `erc-compute-user' + :password N/A + :full-name `erc-compute-full-name' + :id' N/A + +For example, when called in the following manner (erc :server \"irc.libera.chat\" :full-name \"J. Random Hacker\") -then the server and full-name will be set to those values, -whereas `erc-compute-port' and `erc-compute-nick' will be invoked -for the values of the other parameters. - -See `erc-tls' for the meaning of ID. +ERC assigns SERVER and FULL-NAME the associated keyword values +and defers to `erc-compute-port', `erc-compute-user', and +`erc-compute-nick' for those respective parameters. \(fn &key SERVER PORT NICK USER PASSWORD FULL-NAME ID)" (interactive (let ((erc--display-context `((erc-interactive-display . erc) @@ -2770,51 +2783,26 @@ See `erc-tls' for the meaning of ID. client-certificate id ;; Used by interactive form - ((&interactive-env --interactive-env--))) - "ERC is a powerful, modular, and extensible IRC client. -This function is the main entry point for ERC over TLS. - -It allows selecting connection parameters, and then starts ERC -over TLS. - -Non-interactively, it takes the keyword arguments - (server (erc-compute-server)) - (port (erc-compute-port)) - (nick (erc-compute-nick)) - (user (erc-compute-user)) - password - (full-name (erc-compute-full-name)) - client-certificate - id - -That is, if called with - - (erc-tls :server \"irc.libera.chat\" :full-name \"J. Random Hacker\") - -then the server and full-name will be set to those values, -whereas `erc-compute-port' and `erc-compute-nick' will be invoked -for the values of their respective parameters. - -CLIENT-CERTIFICATE, if non-nil, should either be a list where the -first element is the certificate key file name, and the second -element is the certificate file name itself, or t, which means -that `auth-source' will be queried for the key and the -certificate. Authenticating using a TLS client certificate is -also referred to as \"CertFP\" (Certificate Fingerprint) -authentication by various IRC networks. - -Example usage: + ((--interactive-env-- --interactive-env--))) + "Connect to an IRC server over a TLS-encrypted connection. +Interactively, prompt for SERVER, PORT, NICK, and PASSWORD, along +with USER and FULL-NAME when given a prefix argument. +Non-interactively, also accept a CLIENT-CERTIFICATE, which should +be a list containing the file name of the certificate's key +followed by that of the certificate itself. Alternatively, +accept a value of t instead of a list, to tell ERC to query +`auth-source' for the certificate's details. + +Example client certificate (CertFP) usage: (erc-tls :server \"irc.libera.chat\" :port 6697 :client-certificate \\='(\"/home/bandali/my-cert.key\" \"/home/bandali/my-cert.crt\")) -When present, ID should be a symbol or a string to use for naming -the server buffer and identifying the connection unequivocally. -See Info node `(erc) Network Identifier' for details. Like -CLIENT-CERTIFICATE, this parameter cannot be specified -interactively. +See the alternative entry-point command `erc' as well as Info +node `(erc) Connecting' for a fuller description of the various +parameters, like ID. \(fn &key SERVER PORT NICK USER PASSWORD FULL-NAME CLIENT-CERTIFICATE ID)" (interactive @@ -8055,7 +8043,6 @@ See also `erc-downcase'." (defun erc--current-buffer-joined-p () "Return non-nil if the current buffer is a channel and is joined." - (cl-assert erc--target) (and (erc--target-channel-p erc--target) (erc--target-channel-joined-p erc--target) t)) diff --git a/test/lisp/erc/erc-scenarios-keep-place-indicator.el b/test/lisp/erc/erc-scenarios-keep-place-indicator.el index b8ff59f4e02..572045cf0bc 100644 --- a/test/lisp/erc/erc-scenarios-keep-place-indicator.el +++ b/test/lisp/erc/erc-scenarios-keep-place-indicator.el @@ -85,8 +85,8 @@ (goto-char (window-point)) (should (looking-back (rx " tester, welcome!"))) (should (= (pos-bol) (window-start))) - (should (= (overlay-start erc--keep-place-indicator-overlay) - (pos-bol)))) + (erc-d-t-wait-for 20 + (= (overlay-start erc--keep-place-indicator-overlay) (pos-bol)))) ;; Lower window is still centered at start. (other-window 1) (switch-to-buffer "#chan") diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index e3e20b7ba8f..49c72836a22 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -2707,7 +2707,7 @@ (list :server "irc.libera.chat" :port 6697 :nick (user-login-name) - '&interactive-env + '--interactive-env-- '((erc-server-connect-function . erc-open-tls-stream) (erc-join-buffer . window)))))) @@ -2717,7 +2717,7 @@ (list :server "irc.gnu.org" :port 6697 :nick (user-login-name) - '&interactive-env + '--interactive-env-- '((erc-server-connect-function . erc-open-tls-stream) (erc-join-buffer . window)))))) @@ -2728,7 +2728,7 @@ (list :server "irc.gnu.org" :port 6697 :nick (user-login-name) - '&interactive-env + '--interactive-env-- '((erc-server-connect-function . erc-open-tls-stream) (erc--display-context commit 13c7933a9d4b26e74e7f5e19d70bb89003239c34 Author: F. Jason Park Date: Mon Jan 15 05:53:24 2024 -0800 Add test for erc-extract-command-from-line * lisp/erc/erc.el (erc-extract-command-from-line): Redo doc string. * test/lisp/erc/erc-tests.el (erc--parse-isupport-value): Add case for commonly seen escaped character ?=. (erc-extract-command-from-line): New test. ; * test/lisp/erc/resources/erc-d/resources/basic.eld: Update. ; Don't send unnegotiated multi-prefixed userhost names. ; * test/lisp/erc/resources/erc-d/resources/dynamic-barnet.eld: Update. ; * test/lisp/erc/resources/erc-d/resources/dynamic-foonet.eld: Update. ; * test/lisp/erc/resources/erc-d/resources/dynamic.eld: Update. ; * test/lisp/erc/resources/erc-d/resources/eof.eld: Update. ; * test/lisp/erc/resources/erc-d/resources/fuzzy.eld: Update. ; * test/lisp/erc/resources/erc-d/resources/incremental.eld: Update. ; * test/lisp/erc/resources/erc-d/resources/linger.eld: Update. ; * test/lisp/erc/resources/erc-d/resources/no-block.eld: Update. ; * test/lisp/erc/resources/erc-d/resources/no-match.eld: Update. ; * test/lisp/erc/resources/erc-d/resources/unexpected.eld: Update. diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 478683a77f5..6332a8f6763 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -7973,9 +7973,18 @@ as outgoing chat messages and echoed slash commands." (when (fboundp cmd) cmd))) (defun erc-extract-command-from-line (line) - "Extract command and args from the input LINE. -If no command was given, return nil. If command matches, return a -list of the form: (command args) where both elements are strings." + "Extract a \"slash command\" and its args from a prompt-input LINE. +If LINE doesn't start with a slash command, return nil. If it +does, meaning the pattern `erc-command-regexp' matches, return a +list of the form (COMMAND ARGS), where COMMAND is either a symbol +for a known handler function or `erc-cmd-default' if unknown. +When COMMAND has the symbol property `do-not-parse-args', return +a string in place of ARGS: that is, either LINE itself, when LINE +consists of only whitespace, or LINE stripped of any trailing +whitespace, including a final newline. When COMMAND lacks the +symbol property `do-not-parse-args', return a possibly empty list +of non-whitespace tokens. Do not perform any shell-style parsing +of quoted or escaped substrings." (when (string-match erc-command-regexp line) (let* ((cmd (erc-command-symbol (match-string 1 line))) ;; note: return is nil, we apply this simply for side effects diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index b3912cab33d..e3e20b7ba8f 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -969,6 +969,7 @@ (should (equal (erc--parse-isupport-value "\\x20\\x20\\x20") '(" "))) (should (equal (erc--parse-isupport-value "\\x5Co/") '("\\o/"))) (should (equal (erc--parse-isupport-value "\\x7F,\\x19") '("\\x7F" "\\x19"))) + (should (equal (erc--parse-isupport-value "a\\x3Db") '("a=b"))) (should (equal (erc--parse-isupport-value "a\\x2Cb,c") '("a,b" "c")))) (ert-deftest erc--get-isupport-entry () @@ -1663,6 +1664,53 @@ (should-not (erc--check-prompt-input-for-excess-lines "" '("a" "b"))))) (should-not erc-ask-about-multiline-input))) +(ert-deftest erc-extract-command-from-line () + ;; FIXME when next modifying `erc-command-regexp's default value, + ;; move the single quote in the first group's character alternative + ;; to the front, i.e., [A-Za-z'] -> ['A-Za-z], so we can assert + ;; equivalence with this more readable `rx' form. + (rx bol + "/" + (group (+ (in "'A-Za-z"))) + (group (| (: (+ (syntax whitespace)) (* nonl)) + (* (syntax whitespace)))) + eol) + (erc-mode) ; for `erc-mode-syntax-table' + + ;; Non-command. + (should-not (erc-extract-command-from-line "FAKE\n")) + ;; Unknown command. + (should (equal (erc-extract-command-from-line "/FAKE\n") + '(erc-cmd-default "/FAKE\n"))) + + (ert-info ("With `do-not-parse-args'") + (should (equal (erc-extract-command-from-line "/MSG\n") + '(erc-cmd-MSG "\n"))) + (should (equal (erc-extract-command-from-line "/MSG \n") + '(erc-cmd-MSG " \n"))) + (should (equal (erc-extract-command-from-line "/MSG \n\n") + '(erc-cmd-MSG " \n\n"))) + (should (equal (erc-extract-command-from-line "/MSG foo\n") + '(erc-cmd-MSG " foo"))) + (should (equal (erc-extract-command-from-line "/MSG foo\n\n") + '(erc-cmd-MSG " foo"))) + (should (equal (erc-extract-command-from-line "/MSG foo\n \n") + '(erc-cmd-MSG " foo"))) + (should (equal (erc-extract-command-from-line "/MSG foo\n") + '(erc-cmd-MSG " foo")))) + + (ert-info ("Without `do-not-parse-args'") + (should (equal (erc-extract-command-from-line "/HELP\n") + '(erc-cmd-HELP nil))) + (should (equal (erc-extract-command-from-line "/HELP \n") + '(erc-cmd-HELP nil))) + (should (equal (erc-extract-command-from-line "/HELP foo\n") + '(erc-cmd-HELP ("foo")))) + (should (equal (erc-extract-command-from-line "/HELP foo\n") + '(erc-cmd-HELP ("foo")))) + (should (equal (erc-extract-command-from-line "/HELP foo bar\n") + '(erc-cmd-HELP ("foo" "bar")))))) + ;; The point of this test is to ensure output is handled identically ;; regardless of whether a command handler is summoned. diff --git a/test/lisp/erc/resources/erc-d/resources/basic.eld b/test/lisp/erc/resources/erc-d/resources/basic.eld index a020eec3fff..80e46d9a279 100644 --- a/test/lisp/erc/resources/erc-d/resources/basic.eld +++ b/test/lisp/erc/resources/erc-d/resources/basic.eld @@ -8,8 +8,7 @@ (0 ":irc.example.org 002 tester :Your host is irc.example.org") (0 ":irc.example.org 003 tester :This server was created just now") (0 ":irc.example.org 004 tester irc.example.org BERios CEIRabehiklmnoqstv Iabehkloqv") - (0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+" - " :are supported by this server") + (0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+ :are supported by this server") (0 ":irc.example.org 251 tester :There are 3 users and 0 invisible on 1 server(s)") ;; Just to mix thing's up (force handler to schedule timer) (0.1 ":irc.example.org 252 tester 0 :IRC Operators online") @@ -24,7 +23,7 @@ (0 ":irc.example.org 221 tester +Zi") (0 ":irc.example.org 306 tester :You have been marked as being away") (0 ":tester!~tester@localhost JOIN #chan") - (0 ":irc.example.org 353 alice = #chan :+alice!~alice@example.com @%+bob!~bob@example.org") + (0 ":irc.example.org 353 alice = #chan :+alice @bob") (0 ":irc.example.org 366 alice #chan :End of NAMES list")) ;; Some comment (to prevent regression) diff --git a/test/lisp/erc/resources/erc-d/resources/dynamic-barnet.eld b/test/lisp/erc/resources/erc-d/resources/dynamic-barnet.eld index e8feb2e6fd8..47be0722115 100644 --- a/test/lisp/erc/resources/erc-d/resources/dynamic-barnet.eld +++ b/test/lisp/erc/resources/erc-d/resources/dynamic-barnet.eld @@ -22,7 +22,7 @@ (0. ":irc.barnet.org 221 tester +Zi") (0. ":irc.barnet.org 306 tester :You have been marked as being away") (0 ":tester!~u@awyxgybtkx7uq.irc JOIN #chan") - (0 ":irc.barnet.org 353 joe = #chan :+joe!~joe@example.com @%+mike!~mike@example.org") + (0 ":irc.barnet.org 353 joe = #chan :+joe @mike") (0 ":irc.barnet.org 366 joe #chan :End of NAMES list")) ((mode 3 "MODE #chan") diff --git a/test/lisp/erc/resources/erc-d/resources/dynamic-foonet.eld b/test/lisp/erc/resources/erc-d/resources/dynamic-foonet.eld index 2db750e49da..5d5f8ed18a8 100644 --- a/test/lisp/erc/resources/erc-d/resources/dynamic-foonet.eld +++ b/test/lisp/erc/resources/erc-d/resources/dynamic-foonet.eld @@ -21,7 +21,7 @@ (0. ":irc.foonet.org 221 tester +Zi") (0. ":irc.foonet.org 306 tester :You have been marked as being away") (0 ":tester!~u@awyxgybtkx7uq.irc JOIN #chan") - (0 ":irc.foonet.org 353 alice = #chan :+alice!~alice@example.com @%+bob!~bob@example.org") + (0 ":irc.foonet.org 353 alice = #chan :+alice @bob") (0 ":irc.foonet.org 366 alice #chan :End of NAMES list")) ((mode 3 "MODE #chan") diff --git a/test/lisp/erc/resources/erc-d/resources/dynamic.eld b/test/lisp/erc/resources/erc-d/resources/dynamic.eld index 459b6e52bfe..64d8c091ad7 100644 --- a/test/lisp/erc/resources/erc-d/resources/dynamic.eld +++ b/test/lisp/erc/resources/erc-d/resources/dynamic.eld @@ -7,8 +7,7 @@ (0.0 ":" dom " 002 " nick " :Your host is " dom) (0.0 ":" dom " 003 " nick " :This server was created just now") (0.0 ":" dom " 004 " nick " " dom " BERios CEIRabehiklmnoqstv Iabehkloqv") - (0.0 ":" dom " 005 " nick " MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+" - " :are supported by this server") + (0.0 ":" dom " 005 " nick " MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+ :are supported by this server") (0.0 ":" dom " 251 " nick " :There are 3 users and 0 invisible on 1 server(s)") (0.0 ":" dom " 252 " nick " 0 :IRC Operators online") (0.0 ":" dom " 253 " nick " 0 :unregistered connections") @@ -23,7 +22,7 @@ (0.0 ":" dom " 306 " nick " :You have been marked as being away") (0.0 ":" nick "!~" nick "@localhost JOIN #chan") - (0.0 ":" dom " 353 alice = #chan :+alice!~alice@example.com @%+bob!~bob@example.org") + (0.0 ":" dom " 353 alice = #chan :+alice @bob") (0.0 ":" dom " 366 alice #chan :End of NAMES list")) ((mode 2.2 "MODE #chan") diff --git a/test/lisp/erc/resources/erc-d/resources/eof.eld b/test/lisp/erc/resources/erc-d/resources/eof.eld index 5da84b2e74f..db39b3d4af1 100644 --- a/test/lisp/erc/resources/erc-d/resources/eof.eld +++ b/test/lisp/erc/resources/erc-d/resources/eof.eld @@ -8,8 +8,7 @@ (0 ":irc.example.org 002 tester :Your host is irc.example.org") (0 ":irc.example.org 003 tester :This server was created just now") (0 ":irc.example.org 004 tester irc.example.org BERios CEIRabehiklmnoqstv Iabehkloqv") - (0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+" - " :are supported by this server") + (0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+ :are supported by this server") (0 ":irc.example.org 251 tester :There are 3 users and 0 invisible on 1 server(s)") ;; Just to mix thing's up (force handler to schedule timer) (0.1 ":irc.example.org 252 tester 0 :IRC Operators online") @@ -24,7 +23,7 @@ (0 ":irc.example.org 221 tester +Zi") (0 ":irc.example.org 306 tester :You have been marked as being away") (0 ":tester!~tester@localhost JOIN #chan") - (0 ":irc.example.org 353 alice = #chan :+alice!~alice@example.com @%+bob!~bob@example.org") + (0 ":irc.example.org 353 alice = #chan :+alice @bob") (0 ":irc.example.org 366 alice #chan :End of NAMES list")) ((mode-chan 1.2 "MODE #chan") diff --git a/test/lisp/erc/resources/erc-d/resources/fuzzy.eld b/test/lisp/erc/resources/erc-d/resources/fuzzy.eld index 0504b6a6682..cf64004da0d 100644 --- a/test/lisp/erc/resources/erc-d/resources/fuzzy.eld +++ b/test/lisp/erc/resources/erc-d/resources/fuzzy.eld @@ -23,12 +23,12 @@ ((~join-foo 3.2 "JOIN #foo") (0 "@time=" now " :tester!~tester@localhost JOIN #foo") - (0 "@time=" now " :irc.example.org 353 alice = #foo :+alice!~alice@example.com @%+bob!~bob@example.org") + (0 "@time=" now " :irc.example.org 353 alice = #foo :+alice @bob") (0 "@time=" now " :irc.example.org 366 alice #foo :End of NAMES list")) ((~join-bar 1.2 "JOIN #bar") (0 "@time=" now " :tester!~tester@localhost JOIN #bar") - (0 "@time=" now " :irc.example.org 353 alice = #bar :+alice!~alice@example.com @%+bob!~bob@example.org") + (0 "@time=" now " :irc.example.org 353 alice = #bar :+alice @bob") (0 "@time=" now " :irc.example.org 366 alice #bar :End of NAMES list")) ((~mode-foo 3.2 "MODE #foo") diff --git a/test/lisp/erc/resources/erc-d/resources/incremental.eld b/test/lisp/erc/resources/erc-d/resources/incremental.eld index a1b48495ec3..7d192a53066 100644 --- a/test/lisp/erc/resources/erc-d/resources/incremental.eld +++ b/test/lisp/erc/resources/erc-d/resources/incremental.eld @@ -7,8 +7,7 @@ (0.0 ":irc.foo.net 002 tester :Your host is irc.foo.net") (0.0 ":irc.foo.net 003 tester :This server was created just now") (0.0 ":irc.foo.net 004 tester irc.foo.net BERios CEIRabehiklmnoqstv Iabehkloqv") - (0.0 ":irc.foo.net 005 tester MODES NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+" - " :are supported by this server") + (0.0 ":irc.foo.net 005 tester MODES NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ :are supported by this server") (0.0 ":irc.foo.net 251 tester :There are 3 users and 0 invisible on 1 server(s)") (0.0 ":irc.foo.net 252 tester 0 :IRC Operators online") (0.0 ":irc.foo.net 253 tester 0 :unregistered connections") @@ -24,7 +23,7 @@ ((join 3 "JOIN #foo") (0 ":tester!~tester@localhost JOIN #foo") - (0 ":irc.foo.net 353 alice = #foo :+alice!~alice@example.com @%+bob!~bob@example.org") + (0 ":irc.foo.net 353 alice = #foo :+alice @bob") (0 ":irc.foo.net 366 alice #foo :End of NAMES list")) ((mode 3 "MODE #foo") diff --git a/test/lisp/erc/resources/erc-d/resources/linger.eld b/test/lisp/erc/resources/erc-d/resources/linger.eld index e456370a800..d68da730581 100644 --- a/test/lisp/erc/resources/erc-d/resources/linger.eld +++ b/test/lisp/erc/resources/erc-d/resources/linger.eld @@ -8,8 +8,7 @@ (0 ":irc.example.org 002 tester :Your host is irc.example.org") (0 ":irc.example.org 003 tester :This server was created just now") (0 ":irc.example.org 004 tester irc.example.org BERios CEIRabehiklmnoqstv Iabehkloqv") - (0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+" - " :are supported by this server") + (0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+ :are supported by this server") (0 ":irc.example.org 251 tester :There are 3 users and 0 invisible on 1 server(s)") ;; Just to mix thing's up (force handler to schedule timer) (0.1 ":irc.example.org 252 tester 0 :IRC Operators online") @@ -24,7 +23,7 @@ (0 ":irc.example.org 221 tester +Zi") (0 ":irc.example.org 306 tester :You have been marked as being away") (0 ":tester!~tester@localhost JOIN #chan") - (0 ":irc.example.org 353 alice = #chan :+alice!~alice@example.com @%+bob!~bob@example.org") + (0 ":irc.example.org 353 alice = #chan :+alice @bob") (0 ":irc.example.org 366 alice #chan :End of NAMES list")) ((mode-chan 2 "MODE #chan") diff --git a/test/lisp/erc/resources/erc-d/resources/no-block.eld b/test/lisp/erc/resources/erc-d/resources/no-block.eld index 2811923d8ac..af2f4a83ff6 100644 --- a/test/lisp/erc/resources/erc-d/resources/no-block.eld +++ b/test/lisp/erc/resources/erc-d/resources/no-block.eld @@ -7,8 +7,7 @@ (0.0 ":irc.org 002 tester :Your host is irc.org") (0.0 ":irc.org 003 tester :This server was created just now") (0.0 ":irc.org 004 tester irc.org BERios CEIRabehiklmnoqstv Iabehkloqv") - (0.0 ":irc.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+" - " :are supported by this server") + (0.0 ":irc.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+ :are supported by this server") (0.0 ":irc.org 251 tester :There are 3 users and 0 invisible on 1 server(s)") (0.0 ":irc.org 252 tester 0 :IRC Operators online") (0.0 ":irc.org 253 tester 0 :unregistered connections") @@ -24,13 +23,13 @@ ((join-foo 1.2 "JOIN #foo") (0 ":tester!~tester@localhost JOIN #foo") - (0 ":irc.example.org 353 alice = #foo :+alice!~alice@example.com @%+bob!~bob@example.org") + (0 ":irc.example.org 353 alice = #foo :+alice @bob") (0 ":irc.example.org 366 alice #foo :End of NAMES list")) ;; This would time out if the mode-foo's outgoing blocked (remove minus signs to see) ((~join-bar 1.5 "JOIN #bar") (0 ":tester!~tester@localhost JOIN #bar") - (0 ":irc.example.org 353 alice = #bar :+alice!~alice@example.com @%+bob!~bob@example.org") + (0 ":irc.example.org 353 alice = #bar :+alice @bob") (0 ":irc.example.org 366 alice #bar :End of NAMES list")) ((mode-foo 1.2 "MODE #foo") diff --git a/test/lisp/erc/resources/erc-d/resources/no-match.eld b/test/lisp/erc/resources/erc-d/resources/no-match.eld index d147be1e084..d12854de551 100644 --- a/test/lisp/erc/resources/erc-d/resources/no-match.eld +++ b/test/lisp/erc/resources/erc-d/resources/no-match.eld @@ -8,8 +8,7 @@ (0 ":irc.example.org 002 tester :Your host is irc.example.org") (0 ":irc.example.org 003 tester :This server was created just now") (0 ":irc.example.org 004 tester irc.example.org BERios CEIRabehiklmnoqstv Iabehkloqv") - (0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+" - " :are supported by this server") + (0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+ :are supported by this server") (0 ":irc.example.org 251 tester :There are 3 users and 0 invisible on 1 server(s)") (0 ":irc.example.org 252 tester 0 :IRC Operators online") (0 ":irc.example.org 253 tester 0 :unregistered connections") @@ -25,7 +24,7 @@ ((join 1.2 "JOIN #chan") (0 ":tester!~tester@localhost JOIN #chan") - (0 ":irc.example.org 353 alice = #chan :+alice!~alice@example.com @%+bob!~bob@example.org") + (0 ":irc.example.org 353 alice = #chan :+alice @bob") (0 ":irc.example.org 366 alice #chan :End of NAMES list")) ((mode-chan 0.2 "MODE #chan") diff --git a/test/lisp/erc/resources/erc-d/resources/unexpected.eld b/test/lisp/erc/resources/erc-d/resources/unexpected.eld index ac0a8fecfa6..c03b1dbcfdb 100644 --- a/test/lisp/erc/resources/erc-d/resources/unexpected.eld +++ b/test/lisp/erc/resources/erc-d/resources/unexpected.eld @@ -7,8 +7,7 @@ (0.0 ":irc.example.org 002 tester :Your host is irc.example.org") (0.0 ":irc.example.org 003 tester :This server was created just now") (0.0 ":irc.example.org 004 tester irc.example.org BERios CEIRabehiklmnoqstv Iabehkloqv") - (0.0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+" - " :are supported by this server") + (0.0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+ :are supported by this server") (0.0 ":irc.example.org 251 tester :There are 3 users and 0 invisible on 1 server(s)") (0.0 ":irc.example.org 252 tester 0 :IRC Operators online") (0.0 ":irc.example.org 253 tester 0 :unregistered connections") @@ -23,6 +22,6 @@ (0.0 ":irc.example.org 306 tester :You have been marked as being away") (0.0 ":tester!~tester@localhost JOIN #chan") - (0.0 ":irc.example.org 353 alice = #chan :+alice!~alice@example.com @%+bob!~bob@example.org") + (0.0 ":irc.example.org 353 alice = #chan :+alice @bob") (0.0 ":irc.example.org 366 alice #chan :End of NAMES list") (0.1 ":bob!~bob@example.org PRIVMSG #chan :hey")) commit 81a2212bd52f68045b47d8be9345736655de6607 Author: Stefan Monnier Date: Thu Jan 18 18:28:54 2024 -0500 * lisp/international/quail.el (quail-input-method): Fix bug#68338 diff --git a/lisp/international/quail.el b/lisp/international/quail.el index 56f049aedf5..48d2ccb8828 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el @@ -1324,9 +1324,11 @@ If STR has `advice' text property, append the following special event: ;; binding in `universal-argument-map' just return ;; (list KEY), otherwise act as if there was no ;; overriding map. - (or (not (eq (cadr overriding-terminal-local-map) - universal-argument-map)) - (lookup-key overriding-terminal-local-map (vector key)))) + ;; We used to do that only for `universal-argument-map', + ;; but according to bug#68338 this should also apply to + ;; other transient maps. Let's hope it's OK to apply it + ;; to all `overriding-terminal-local-map's. + (lookup-key overriding-terminal-local-map (vector key))) overriding-local-map) (list key) (quail-setup-overlays (quail-conversion-keymap)) commit a33f3947ea1ba429570e2ecb4c3167341dcae1a2 Author: Stefan Monnier Date: Thu Jan 18 14:05:16 2024 -0500 * lisp/progmodes/elisp-mode.el (elisp-completion-at-point): Fix bug#68514 Redo the commit 0db2126d7176 to try and avoid selecting more than a mere symbol. diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 00910fb67c7..da0cb96e1cf 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -657,12 +657,13 @@ functions are annotated with \"\" via the (save-excursion (backward-sexp 1) (skip-chars-forward "`',‘#") - (point)) + (min (point) pos)) (scan-error pos))) (end - (unless (or (eq beg (point-max)) - (member (char-syntax (char-after beg)) - '(?\" ?\())) + (cond + ((and (< beg (point-max)) + (memq (char-syntax (char-after beg)) + '(?w ?\\ ?_))) (condition-case nil (save-excursion (goto-char beg) @@ -670,7 +671,11 @@ functions are annotated with \"\" via the (skip-chars-backward "'’") (when (>= (point) pos) (point))) - (scan-error pos)))) + (scan-error pos))) + ((or (>= beg (point-max)) + (memq (char-syntax (char-after beg)) + '(?\) ?\s))) + beg))) ;; t if in function position. (funpos (eq (char-before beg) ?\()) (quoted (elisp--form-quoted-p beg)) commit b07a86abb6d5bb3d5cd178bb77592ad7208882f5 Author: Stefan Monnier Date: Thu Jan 18 14:00:15 2024 -0500 * test/lisp/emacs-lisp/comp-cstr-tests.el: Use macros in a simpler way (comp-cstr-test-ts): Move out of `cl-eval-when`. (comp-cstr-typespec-test): Delete. (comp-cstr-synthesize-tests): Make it take the tests as an argument. (comp-cstr-typespec-tests-alist): Delete var, pass its value to the macro instead. diff --git a/test/lisp/emacs-lisp/comp-cstr-tests.el b/test/lisp/emacs-lisp/comp-cstr-tests.el index fb1770f1f4a..edc70b12d4b 100644 --- a/test/lisp/emacs-lisp/comp-cstr-tests.el +++ b/test/lisp/emacs-lisp/comp-cstr-tests.el @@ -29,218 +29,212 @@ (require 'cl-lib) (require 'comp-cstr) -(cl-eval-when (compile eval load) - - (defun comp-cstr-test-ts (type-spec) - "Create a constraint from TYPE-SPEC and convert it back to type specifier." - (let ((comp-ctxt (make-comp-cstr-ctxt))) - (comp-cstr-to-type-spec (comp-type-spec-to-cstr type-spec)))) - - (defun comp-cstr-typespec-test (number type-spec expected-type-spec) - `(ert-deftest ,(intern (concat "comp-cstr-test-" (int-to-string number))) () - (should (equal (comp-cstr-test-ts ',type-spec) - ',expected-type-spec)))) - - (defconst comp-cstr-typespec-tests-alist - '(;; 1 - (symbol . symbol) - ;; 2 - ((or string array) . array) - ;; 3 - ((or symbol number) . (or number symbol)) - ;; 4 - ((or cons atom) . t) ;; SBCL return T - ;; 5 - ((or integer number) . number) - ;; 6 - ((or (or integer symbol) number) . (or number symbol)) - ;; 7 - ((or (or integer symbol) (or number list)) . (or list number symbol)) - ;; 8 - ((or (or integer number) nil) . number) - ;; 9 - ((member foo) . (member foo)) - ;; 10 - ((member foo bar) . (member bar foo)) - ;; 11 - ((or (member foo) (member bar)) . (member bar foo)) - ;; 12 - ((or (member foo) symbol) . symbol) ;; SBCL return (OR SYMBOL (MEMBER FOO)) - ;; 13 - ((or (member foo) number) . (or (member foo) number)) - ;; 14 - ((or (integer 1 3) number) . number) - ;; 15 - (integer . integer) - ;; 16 - ((integer 1 2) . (integer 1 2)) - ;; 17 - ((or (integer -1 0) (integer 3 4)) . (or (integer -1 0) (integer 3 4))) - ;; 18 - ((or (integer -1 2) (integer 3 4)) . (integer -1 4)) - ;; 19 - ((or (integer -1 3) (integer 3 4)) . (integer -1 4)) - ;; 20 - ((or (integer -1 4) (integer 3 4)) . (integer -1 4)) - ;; 21 - ((or (integer -1 5) (integer 3 4)) . (integer -1 5)) - ;; 22 - ((or (integer -1 *) (integer 3 4)) . (integer -1 *)) - ;; 23 - ((or (integer -1 2) (integer * 4)) . (integer * 4)) - ;; 24 - ((and string array) . string) - ;; 25 - ((and cons atom) . nil) - ;; 26 - ((and (member foo) (member foo bar baz)) . (member foo)) - ;; 27 - ((and (member foo) (member bar)) . nil) - ;; 28 - ((and (member foo) symbol) . (member foo)) - ;; 29 - ((and (member foo) string) . nil) - ;; 30 - ((and (member foo) (integer 1 2)) . nil) - ;; 31 - ((and (member 1 2) (member 3 2)) . (integer 2 2)) - ;; 32 - ((and number (integer 1 2)) . (integer 1 2)) - ;; 33 - ((and integer (integer 1 2)) . (integer 1 2)) - ;; 34 - ((and (integer -1 0) (integer 3 5)) . nil) - ;; 35 - ((and (integer -1 2) (integer 3 5)) . nil) - ;; 36 - ((and (integer -1 3) (integer 3 5)) . (integer 3 3)) - ;; 37 - ((and (integer -1 4) (integer 3 5)) . (integer 3 4)) - ;; 38 - ((and (integer -1 5) nil) . nil) - ;; 39 - ((not symbol) . (not symbol)) - ;; 40 - ((or (member foo) (not (member foo bar))) . (not (member bar))) - ;; 41 - ((or (member foo bar) (not (member foo))) . t) - ;; 42 - ((or symbol (not sequence)) . (not sequence)) - ;; 43 - ((or symbol (not symbol)) . t) - ;; 44 - ((or symbol (not sequence)) . (not sequence)) - ;; 45 Conservative. - ((or vector (not sequence)) . t) - ;; 46 - ((or (integer 1 10) (not (integer * 5))) . (not (integer * 0))) - ;; 47 - ((or symbol (integer 1 10) (not (integer * 5))) . (not (integer * 0))) - ;; 48 - ((or (not symbol) (integer 1 10) (not (integer * 5))) . (not (or symbol (integer * 0)))) - ;; 49 - ((or symbol (not (member foo))) . (not (member foo))) - ;; 50 - ((or (not symbol) (not (member foo))) . (not symbol)) - ;; 51 Conservative. - ((or (not (member foo)) string) . (not (member foo))) - ;; 52 Conservative. - ((or (member foo) (not string)) . (not string)) - ;; 53 - ((or (not (integer 1 2)) integer) . t) - ;; 54 - ((or (not (integer 1 2)) (not integer)) . (not integer)) - ;; 55 - ((or (integer 1 2) (not integer)) . (not (or (integer * 0) (integer 3 *)))) - ;; 56 - ((or number (not (integer 1 2))) . t) - ;; 57 - ((or atom (not (integer 1 2))) . t) - ;; 58 - ((or atom (not (member foo))) . t) - ;; 59 - ((and symbol (not cons)) . symbol) - ;; 60 - ((and symbol (not symbol)) . nil) - ;; 61 - ((and atom (not symbol)) . atom) - ;; 62 - ((and atom (not string)) . (or array sequence atom)) - ;; 63 Conservative - ((and symbol (not (member foo))) . symbol) - ;; 64 Conservative - ((and symbol (not (member 3))) . symbol) - ;; 65 - ((and (not (member foo)) (integer 1 10)) . (integer 1 10)) - ;; 66 - ((and (member foo) (not (integer 1 10))) . (member foo)) - ;; 67 - ((and t (not (member foo))) . (not (member foo))) - ;; 68 - ((and integer (not (integer 3 4))) . (or (integer * 2) (integer 5 *))) - ;; 69 - ((and (integer 0 20) (not (integer 5 10))) . (or (integer 0 4) (integer 11 20))) - ;; 70 - ((and (not (member a)) (not (member b))) . (not (member a b))) - ;; 71 - ((and (not boolean) (not (member b))) . (not (or (member b) boolean))) - ;; 72 - ((and t (integer 1 1)) . (integer 1 1)) - ;; 73 - ((not (integer -1 5)) . (not (integer -1 5))) - ;; 74 - ((and boolean (or number marker)) . nil) - ;; 75 - ((and atom (or number marker)) . number-or-marker) - ;; 76 - ((and symbol (or number marker)) . nil) - ;; 77 - ((and (or symbol string) (or number marker)) . nil) - ;; 78 - ((and t t) . t) - ;; 79 - ((and (or marker number) (integer 0 0)) . (integer 0 0)) - ;; 80 - ((and t (not t)) . nil) - ;; 81 - ((or (integer 1 1) (not (integer 1 1))) . t) - ;; 82 - ((not t) . nil) - ;; 83 - ((not nil) . t) - ;; 84 - ((or (not string) t) . t) - ;; 85 - ((or (not vector) sequence) . sequence) - ;; 86 - ((or (not symbol) null) . t) - ;; 87 - ((and (or null integer) (not (or null integer))) . nil) - ;; 88 - ((and (or (member a b c)) (not (or (member a b)))) . (member c)) - ;; 89 - ((or cons symbol) . (or list symbol)) ;; FIXME: Why `list'? - ;; 90 - ((or string char-table bool-vector vector) . array) - ;; 91 - ((or string char-table bool-vector vector number) . (or array number)) - ;; 92 - ((or string char-table bool-vector vector cons symbol number) . - (or number sequence symbol)) - ;; 93? - ;; FIXME: I get `cons' rather than `list'? - ;;((or null cons) . list) - ) - "Alist type specifier -> expected type specifier.")) - -(defmacro comp-cstr-synthesize-tests () - "Generate all tests from `comp-cstr-typespec-tests-alist'." +(defun comp-cstr-test-ts (type-spec) + "Create a constraint from TYPE-SPEC and convert it back to type specifier." + (let ((comp-ctxt (make-comp-cstr-ctxt))) + (comp-cstr-to-type-spec (comp-type-spec-to-cstr type-spec)))) + +(defmacro comp-cstr-synthesize-tests (typespec-tests-alist) + "Generate all tests from TYPESPEC-TESTS-ALIST. +The arg is an alist of: type specifier -> expected type specifier." `(progn ,@(cl-loop for i from 1 - for (ts . exp-ts) in comp-cstr-typespec-tests-alist - append (list (comp-cstr-typespec-test i ts exp-ts))))) - -(comp-cstr-synthesize-tests) + for (type-spec . expected-type-spec) in typespec-tests-alist + collect + `(ert-deftest ,(intern (format "comp-cstr-test-%d" i)) () + (should (equal (comp-cstr-test-ts ',type-spec) + ',expected-type-spec)))))) + +(comp-cstr-synthesize-tests + (;; 1 + (symbol . symbol) + ;; 2 + ((or string array) . array) + ;; 3 + ((or symbol number) . (or number symbol)) + ;; 4 + ((or cons atom) . t) ;; Like SBCL + ;; 5 + ((or integer number) . number) + ;; 6 + ((or (or integer symbol) number) . (or number symbol)) + ;; 7 + ((or (or integer symbol) (or number list)) . (or list number symbol)) + ;; 8 + ((or (or integer number) nil) . number) + ;; 9 + ((member foo) . (member foo)) + ;; 10 + ((member foo bar) . (member bar foo)) + ;; 11 + ((or (member foo) (member bar)) . (member bar foo)) + ;; 12 + ((or (member foo) symbol) . symbol) ;; SBCL return (OR SYMBOL (MEMBER FOO)) + ;; 13 + ((or (member foo) number) . (or (member foo) number)) + ;; 14 + ((or (integer 1 3) number) . number) + ;; 15 + (integer . integer) + ;; 16 + ((integer 1 2) . (integer 1 2)) + ;; 17 + ((or (integer -1 0) (integer 3 4)) . (or (integer -1 0) (integer 3 4))) + ;; 18 + ((or (integer -1 2) (integer 3 4)) . (integer -1 4)) + ;; 19 + ((or (integer -1 3) (integer 3 4)) . (integer -1 4)) + ;; 20 + ((or (integer -1 4) (integer 3 4)) . (integer -1 4)) + ;; 21 + ((or (integer -1 5) (integer 3 4)) . (integer -1 5)) + ;; 22 + ((or (integer -1 *) (integer 3 4)) . (integer -1 *)) + ;; 23 + ((or (integer -1 2) (integer * 4)) . (integer * 4)) + ;; 24 + ((and string array) . string) + ;; 25 + ((and cons atom) . nil) + ;; 26 + ((and (member foo) (member foo bar baz)) . (member foo)) + ;; 27 + ((and (member foo) (member bar)) . nil) + ;; 28 + ((and (member foo) symbol) . (member foo)) + ;; 29 + ((and (member foo) string) . nil) + ;; 30 + ((and (member foo) (integer 1 2)) . nil) + ;; 31 + ((and (member 1 2) (member 3 2)) . (integer 2 2)) + ;; 32 + ((and number (integer 1 2)) . (integer 1 2)) + ;; 33 + ((and integer (integer 1 2)) . (integer 1 2)) + ;; 34 + ((and (integer -1 0) (integer 3 5)) . nil) + ;; 35 + ((and (integer -1 2) (integer 3 5)) . nil) + ;; 36 + ((and (integer -1 3) (integer 3 5)) . (integer 3 3)) + ;; 37 + ((and (integer -1 4) (integer 3 5)) . (integer 3 4)) + ;; 38 + ((and (integer -1 5) nil) . nil) + ;; 39 + ((not symbol) . (not symbol)) + ;; 40 + ((or (member foo) (not (member foo bar))) . (not (member bar))) + ;; 41 + ((or (member foo bar) (not (member foo))) . t) + ;; 42 + ((or symbol (not sequence)) . (not sequence)) + ;; 43 + ((or symbol (not symbol)) . t) + ;; 44 + ((or symbol (not sequence)) . (not sequence)) + ;; 45 Conservative. + ((or vector (not sequence)) . t) + ;; 46 + ((or (integer 1 10) (not (integer * 5))) . (not (integer * 0))) + ;; 47 + ((or symbol (integer 1 10) (not (integer * 5))) . (not (integer * 0))) + ;; 48 + ((or (not symbol) (integer 1 10) (not (integer * 5))) . (not (or symbol (integer * 0)))) + ;; 49 + ((or symbol (not (member foo))) . (not (member foo))) + ;; 50 + ((or (not symbol) (not (member foo))) . (not symbol)) + ;; 51 Conservative. + ((or (not (member foo)) string) . (not (member foo))) + ;; 52 Conservative. + ((or (member foo) (not string)) . (not string)) + ;; 53 + ((or (not (integer 1 2)) integer) . t) + ;; 54 + ((or (not (integer 1 2)) (not integer)) . (not integer)) + ;; 55 + ((or (integer 1 2) (not integer)) . (not (or (integer * 0) (integer 3 *)))) + ;; 56 + ((or number (not (integer 1 2))) . t) + ;; 57 + ((or atom (not (integer 1 2))) . t) + ;; 58 + ((or atom (not (member foo))) . t) + ;; 59 + ((and symbol (not cons)) . symbol) + ;; 60 + ((and symbol (not symbol)) . nil) + ;; 61 + ((and atom (not symbol)) . atom) + ;; 62 + ((and atom (not string)) . (or array sequence atom)) + ;; 63 Conservative + ((and symbol (not (member foo))) . symbol) + ;; 64 Conservative + ((and symbol (not (member 3))) . symbol) + ;; 65 + ((and (not (member foo)) (integer 1 10)) . (integer 1 10)) + ;; 66 + ((and (member foo) (not (integer 1 10))) . (member foo)) + ;; 67 + ((and t (not (member foo))) . (not (member foo))) + ;; 68 + ((and integer (not (integer 3 4))) . (or (integer * 2) (integer 5 *))) + ;; 69 + ((and (integer 0 20) (not (integer 5 10))) . (or (integer 0 4) (integer 11 20))) + ;; 70 + ((and (not (member a)) (not (member b))) . (not (member a b))) + ;; 71 + ((and (not boolean) (not (member b))) . (not (or (member b) boolean))) + ;; 72 + ((and t (integer 1 1)) . (integer 1 1)) + ;; 73 + ((not (integer -1 5)) . (not (integer -1 5))) + ;; 74 + ((and boolean (or number marker)) . nil) + ;; 75 + ((and atom (or number marker)) . number-or-marker) + ;; 76 + ((and symbol (or number marker)) . nil) + ;; 77 + ((and (or symbol string) (or number marker)) . nil) + ;; 78 + ((and t t) . t) + ;; 79 + ((and (or marker number) (integer 0 0)) . (integer 0 0)) + ;; 80 + ((and t (not t)) . nil) + ;; 81 + ((or (integer 1 1) (not (integer 1 1))) . t) + ;; 82 + ((not t) . nil) + ;; 83 + ((not nil) . t) + ;; 84 + ((or (not string) t) . t) + ;; 85 + ((or (not vector) sequence) . sequence) + ;; 86 + ((or (not symbol) null) . t) + ;; 87 + ((and (or null integer) (not (or null integer))) . nil) + ;; 88 + ((and (or (member a b c)) (not (or (member a b)))) . (member c)) + ;; 89 + ((or cons symbol) . (or list symbol)) ;; FIXME: Why `list'? + ;; 90 + ((or string char-table bool-vector vector) . array) + ;; 91 + ((or string char-table bool-vector vector number) . (or array number)) + ;; 92 + ((or string char-table bool-vector vector cons symbol number) . + (or number sequence symbol)) + ;; 93? + ;; FIXME: I get `cons' rather than `list'? + ;;((or null cons) . list) + )) ;;; comp-cstr-tests.el ends here commit e7a6ce847fd06c4f132bbac2f2fdc8474753ad3c Author: Mattias Engdegård Date: Thu Jan 18 18:48:12 2024 +0100 Don't use Qunbound as hash table key when printing (bug#68244) This flaw could cause an assertion failure. * src/print.c (PRINT_CIRCLE_CANDIDATE_P): Don't consider Qunbound a print-circle candidate; it should never be seen by Lisp anyway. diff --git a/src/print.c b/src/print.c index 0899dcdeb03..61999c096aa 100644 --- a/src/print.c +++ b/src/print.c @@ -1311,7 +1311,8 @@ print (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) || RECORDP (obj))) \ || (! NILP (Vprint_gensym) \ && SYMBOLP (obj) \ - && !SYMBOL_INTERNED_P (obj))) + && !SYMBOL_INTERNED_P (obj) \ + && !hash_unused_entry_key_p (obj))) /* The print preprocess stack, used to traverse data structures. */ commit ef01250ef9c22aa1ac2ecff3136aabf79b2a677b Author: Mattias Engdegård Date: Thu Jan 18 18:45:16 2024 +0100 Only use a hash index size of 1 for tables with size 0 (bug#68244) This invariant was intended but insufficiently enforced which could lead to an assertion failure. * src/fns.c (hash_index_size): Assume size>0, and return a value >1. (make_hash_table): Only use hash_index_size for size>0. diff --git a/src/fns.c b/src/fns.c index 5bedf49ef36..15bbd270311 100644 --- a/src/fns.c +++ b/src/fns.c @@ -4525,9 +4525,14 @@ hash_index_size (ptrdiff_t size) ptrdiff_t upper_bound = min (MOST_POSITIVE_FIXNUM, min (TYPE_MAXIMUM (hash_idx_t), PTRDIFF_MAX / sizeof (ptrdiff_t))); - ptrdiff_t index_size = size + (size >> 2); /* 1.25x larger */ + /* Single-element index vectors are used iff size=0. */ + eassert (size > 0); + ptrdiff_t lower_bound = 2; + ptrdiff_t index_size = size + max (size >> 2, 1); /* 1.25x larger */ if (index_size < upper_bound) - index_size = next_almost_prime (index_size); + index_size = (index_size < lower_bound + ? lower_bound + : next_almost_prime (index_size)); if (index_size > upper_bound) error ("Hash table too large"); return index_size; @@ -4565,15 +4570,13 @@ make_hash_table (const struct hash_table_test *test, EMACS_INT size, h->weakness = weak; h->count = 0; h->table_size = size; - int index_size = hash_index_size (size); - h->index_size = index_size; if (size == 0) { h->key_and_value = NULL; h->hash = NULL; h->next = NULL; - eassert (index_size == 1); + h->index_size = 1; h->index = (hash_idx_t *)empty_hash_index_vector; h->next_free = -1; } @@ -4591,6 +4594,8 @@ make_hash_table (const struct hash_table_test *test, EMACS_INT size, h->next[i] = i + 1; h->next[size - 1] = -1; + int index_size = hash_index_size (size); + h->index_size = index_size; h->index = hash_table_alloc_bytes (index_size * sizeof *h->index); for (ptrdiff_t i = 0; i < index_size; i++) h->index[i] = -1; commit 2c887f497c723c2397888e2f406faa4de3a8208a Author: Eric Abrahamsen Date: Thu Jan 18 07:24:39 2024 -0800 Avoid font-lock reset in `gnus-message-citation-mode' * lisp/gnus/gnus-cite.el (gnus-message-citation-mode): Use `font-lock-add-keywords' and `font-lock-remove-keywords' instead of modifying font-lock defaults. Make no font-lock changes until `font-lock-mode' is active. Thanks to Morgan Willcock diff --git a/lisp/gnus/gnus-cite.el b/lisp/gnus/gnus-cite.el index 04abdfc0d1b..3fde9baa0fe 100644 --- a/lisp/gnus/gnus-cite.el +++ b/lisp/gnus/gnus-cite.el @@ -1122,31 +1122,17 @@ Returns nil if there is no such line before LIMIT, t otherwise." When enabled, it automatically turns on `font-lock-mode'." :lighter "" (when (derived-mode-p 'message-mode) - ;; FIXME: Use font-lock-add-keywords! - (let ((defaults (car font-lock-defaults)) - default) ;; keywords - (while defaults - (setq default (if (consp defaults) - (pop defaults) - (prog1 - defaults - (setq defaults nil)))) - (if gnus-message-citation-mode - ;; `gnus-message-citation-keywords' should be the last - ;; elements of the keywords because the others are unlikely - ;; to have the OVERRIDE flags -- XEmacs applies a keyword - ;; having no OVERRIDE flag to matched text even if it has - ;; already other faces, while Emacs doesn't. - (set (make-local-variable default) - (append (default-value default) - gnus-message-citation-keywords)) - (kill-local-variable default)))) - ;; Force `font-lock-set-defaults' to update `font-lock-keywords'. - (setq font-lock-set-defaults nil) - (font-lock-set-defaults) - (if font-lock-mode - (font-lock-flush) - (gnus-message-citation-mode (font-lock-mode 1))))) + (if (not font-lock-mode) + (gnus-message-citation-mode (font-lock-mode 1)) + (if gnus-message-citation-mode + ;; `gnus-message-citation-keywords' should be the last + ;; elements of the keywords because the others are unlikely + ;; to have the OVERRIDE flags -- XEmacs applies a keyword + ;; having no OVERRIDE flag to matched text even if it has + ;; already other faces, while Emacs doesn't. + (font-lock-add-keywords nil gnus-message-citation-keywords t) + (font-lock-remove-keywords nil gnus-message-citation-keywords)) + (font-lock-flush)))) (defun turn-on-gnus-message-citation-mode () "Turn on `gnus-message-citation-mode'."