commit 9cbc0fd66a999f76c1897311d1b8369271549d21 (HEAD, refs/remotes/origin/master) Author: Juri Linkov Date: Wed Nov 9 09:45:17 2022 +0200 * lisp/tab-bar.el (tab-bar-get-buffer-tab): Add optional arg 'all-tabs'. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index cdea856ac2..84e1c432ff 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -2334,7 +2334,7 @@ with those specified by the selected window configuration." ((framep all-frames) (list all-frames)) (t (list (selected-frame))))) -(defun tab-bar-get-buffer-tab (buffer-or-name &optional all-frames ignore-current-tab) +(defun tab-bar-get-buffer-tab (buffer-or-name &optional all-frames ignore-current-tab all-tabs) "Return the tab that owns the window whose buffer is BUFFER-OR-NAME. BUFFER-OR-NAME may be a buffer or a buffer name, and defaults to the current buffer. @@ -2352,14 +2352,20 @@ selected frame and no others. When the optional argument IGNORE-CURRENT-TAB is non-nil, don't take into account the buffers in the currently selected tab. -Otherwise, prefer buffers of the current tab." +Otherwise, prefer buffers of the current tab. + +When the optional argument ALL-TABS is non-nil, return a list of all tabs +that contain the buffer BUFFER-OR-NAME." (let ((buffer (if buffer-or-name (get-buffer buffer-or-name) - (current-buffer)))) + (current-buffer))) + buffer-tabs) (when (bufferp buffer) - (seq-some + (funcall + (if all-tabs #'seq-each #'seq-some) (lambda (frame) - (seq-some + (funcall + (if all-tabs #'seq-each #'seq-some) (lambda (tab) (when (if (eq (car tab) 'current-tab) (get-buffer-window buffer frame) @@ -2371,8 +2377,9 @@ Otherwise, prefer buffers of the current tab." (memq buffer buffers) ;; writable window-state (member (buffer-name buffer) buffers)))) - (append tab `((index . ,(tab-bar--tab-index tab nil frame)) - (frame . ,frame))))) + (push (append tab `((index . ,(tab-bar--tab-index tab nil frame)) + (frame . ,frame))) + buffer-tabs))) (let* ((tabs (funcall tab-bar-tabs-function frame)) (current-tab (tab-bar--current-tab-find tabs))) (setq tabs (remq current-tab tabs)) @@ -2381,7 +2388,8 @@ Otherwise, prefer buffers of the current tab." tabs ;; Make sure current-tab is at the beginning of tabs. (cons current-tab tabs))))) - (tab-bar--reusable-frames all-frames))))) + (tab-bar--reusable-frames all-frames)) + (if all-tabs (nreverse buffer-tabs) (car (last buffer-tabs)))))) (defun display-buffer-in-tab (buffer alist) "Display BUFFER in a tab using display actions in ALIST. commit 0e25a39e69acca0324c326ea8e46b1725594bff5 Author: Alexander Adolf Date: Tue Nov 8 13:39:19 2022 -0500 EUDC: Add ecomplete and mailabbrev backends * doc/misc/eudc.texi (Overview): Add ecomplete and mailabbrev nodes. (ecomplete, mailabbrev): New nodes. (Installation): Add ecomplete and mailabbrev nodes. (LDAP Configuration): Use code formatting instead of quotes. (macOS Contacts Configuration): Likewise. (ecomplete Configuration): New node. (mailabbrev Configuration): Likewise. * etc/NEWS (EUDC): Mention ecomplete and mailabbrev backends, mention eudc-server-hotlist default change. * lisp/net/eudc-vars.el (eudc-known-protocols): Add ecomplete and mailabbrev. (eudc-server-hotlist): Add entries for ecomplete and mailabbrev. * lisp/net/eudcb-ecomplete.el: New EUDC backend file. * lisp/net/eudcb-mailabbrev.el: Likewise. * test/lisp/net/eudc-resources/ecompleterc, test/lisp/net/eudc-resources/mailrc: New eudc-tests resource files. * test/lisp/net/eudc-tests.el (eudc-test-rfc5322-quote-phrase) (eudc-test-make-address, eudcb-ecomplete, eudcb-mailabbrev): New test cases. diff --git a/doc/misc/eudc.texi b/doc/misc/eudc.texi index 50e483057d..7293f48f41 100644 --- a/doc/misc/eudc.texi +++ b/doc/misc/eudc.texi @@ -85,6 +85,10 @@ LDAP, Lightweight Directory Access Protocol BBDB, Big Brother's Insidious Database @item macOS Contacts +@item +@code{ecomplete}, Emacs's electrical completion +@item +@code{mailabbrev}, Emacs's abbrev-expansion of mail aliases @end itemize The main features of the EUDC interface are: @@ -110,6 +114,8 @@ Interface to BBDB to let you insert server records into your own BBDB database * LDAP:: What is LDAP ? * BBDB:: What is BBDB ? * macOS Contacts:: What is macOS Contacts ? +* ecomplete:: What is @code{ecomplete} ? +* mailabbrev:: What is @code{mailabbrev}? @end menu @@ -173,14 +179,73 @@ Address Book; the EUDC macOS Contacts back end also works on those older versions. +@node ecomplete +@section @code{ecomplete} + +@code{ecomplete} is Emacs's ``electric completion'', and it is part of +Emacs. It stores all information in an @file{ecompleterc} file, whose +location, and name can be configured via the variable +@code{ecomplete-database-file} (which see). The format of the file +is: + +@display +((TYPE_1 ITEM_1 ITEM_2 ...) + (TYPE_2 ITEM_N+1 ITEM_N+2 ...) + ...) +@end display + +That is, it is an alist map where the key is the type of match (so +that you can have one list of things for ``mail'', and one for, say, +``mastodon''). In each of these sections you then have a list where +each item is of the form: + +@display +(KEY TIMES-USED LAST-TIME-USED STRING) +@end display + +When performing a query, the result will be all items where the search +term matches all, or part of STRING. + +When EUDC performs queries with @code{ecomplete}, the name of each +attribute making up the query is used as the type in which the lookup +is performed. The mapping from EUDC attribute names to +@code{ecomplete} type names is performed according to the variable +@code{eudc-ecomplete-attributes-translation-alist} (which see). + + +@node mailabbrev +@section @code{mailabbrev} + +@code{mailabbrev} is Emacs's ``abbrev-expansion of mail aliases'', and +it is part of Emacs. It stores all information in a @file{mailrc} +file, whose location, and name can be configured via the variable +@code{mail-personal-alias-file} (which see). The @file{mailrc} file +has the same format as the @command{mail} and @command{mailx} commands +use for their startup configuration file. @code{mailabbrev} processes +@samp{alias}, and @samp{source} statements in the @file{mailrc} file. +@samp{alias} statements can define simple aliases and distribution +lists, and and can be nested in that the alias expansion can contain +references to other alias definitions. Forward references, that is +references to aliases before they are actually defined, are possible, +too. + +Originally, @code{mailabbrev} was designed to be used with +@code{abbrev-mode}. The @code{mailabbrev} EUDC backend does not use +@code{abbrev-mode}, but queries @code{mailabbrev} for alias entries +only, and returns these as EUDC results. All entries where the alias +name exactly equals either the @code{email}, @code{name}, or +@code{firstname} attribute value in the EUDC query, will be returned +as matches. When a @file{mailrc} alias defines a distribution list, +that is it expands to more than one email address, the EUDC result +will contain a single entry, which will contain an email attribute +only, whose value will be a comma-separated list of RFC 5322 formatted +recipient specifications. + + @node Installation @chapter Installation -Add the following to your @file{.emacs} init file: -@lisp -(require 'eudc) -@end lisp -This will install EUDC at startup. +EUDC is built-in to Emacs, and its main functions are autoloaded. After installing EUDC you will find (the next time you launch Emacs) a new @code{Directory Search} submenu in the @samp{Tools} menu that will @@ -200,6 +265,8 @@ email composition buffers (@pxref{Inline Query Expansion}) @menu * LDAP Configuration:: EUDC needs external support for LDAP * macOS Contacts Configuration:: Enable the macOS Contacts backend +* ecomplete Configuration:: Enable the ecomplete backend +* mailabbrev Configuration:: Enable the mailabbrev backend @end menu @node LDAP Configuration @@ -256,7 +323,7 @@ will return all LDAP entries with surnames that begin with @code{Smith}. In every LDAP query it makes, EUDC implicitly appends the wildcard character to the end of the last word, except if the word corresponds to an attribute which is a member of -`eudc-ldap-no-wildcard-attributes'. +@code{eudc-ldap-no-wildcard-attributes}. @menu * Emacs-only Configuration:: Configure with @file{.emacs} @@ -406,9 +473,9 @@ level to 5 by appending @code{-d 5} to the command line. macOS Contacts support is added by means of @file{eudcb-mab.el}, or @file{eudcb-macos-contacts.el} which are part of Emacs. -To enable a macOS Contacts backend, first `require' the respective -library to load it, and then set the `eudc-server' to localhost in -your init file: +To enable a macOS Contacts backend, first @code{require} the +respective library to load it, and then set the @code{eudc-server} to +localhost in your init file: @lisp (require 'eudcb-macos-contacts) (eudc-macos-contacts-set-server "localhost") @@ -433,6 +500,32 @@ command-line utility before upgrading to a new version of macOS. existing configurations, and may be removed in a future release. +@node ecomplete Configuration +@section @code{ecomplete} Configuration + +@code{ecomplete} is Emacs's ``electrical completion'', and is part of +Emacs. To use it, you will need to set up a database file +(@pxref{ecomplete}) first. + +It will be autoloaded on demand. + +You can also enable multi-server queries as described in +@pxref{Multi-server Queries}. + + +@node mailabbrev Configuration +@section @code{mailabbrev} Configuration + +@code{mailabbrev} is Emacs's ``abbrev-expansion of mail aliases'', and +it is part of Emacs. To use it, you will need to set up a database file +(@pxref{mailabbrev}) first. + +It will be autoloaded on demand. + +You can also enable multi-server queries as described in +@pxref{Multi-server Queries}. + + @node Usage @chapter Usage diff --git a/etc/NEWS b/etc/NEWS index 60b2caccc8..ab64eff74e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2017,6 +2017,25 @@ The EUDC back-end for the macOS Contacts app now provides a wider set of attributes to use for queries, and delivers more attributes in query results. ++++ +*** New back-end for ecomplete +A new back-end for ecomplete allows information from that database to +be queried by EUDC, too. The attributes present in the EUDC query are +used to select the entry type in the ecomplete database. + ++++ +*** New back-end for mailabbrev +A new back-end for mailabbrev allows information from that database to +be queried by EUDC, too. The attributes email, name, and firstname +are supported only. + ++++ +*** New default for 'eudc-server-hotlist' includes built-in backends +The 'eudc-server-hotlist' user option now defaults to including +entries for the new built-in ecomplete and mailabbrev EUDC backends. +As a result, 'C-u M-x eudc-expand-try-all' will query both of these +backends for email address completions, by default. + ** EWW/SHR +++ diff --git a/lisp/net/eudc-vars.el b/lisp/net/eudc-vars.el index 3ce363cf68..b44989d906 100644 --- a/lisp/net/eudc-vars.el +++ b/lisp/net/eudc-vars.el @@ -51,9 +51,10 @@ instead." ;; Known protocols (used in completion) ;; Not to be mistaken with `eudc-supported-protocols' -(defvar eudc-known-protocols '(bbdb ldap)) +(defvar eudc-known-protocols '(bbdb ldap ecomplete mailabbrev)) -(defcustom eudc-server-hotlist nil +(defcustom eudc-server-hotlist '(("localhost" . ecomplete) + ("localhost" . mailabbrev)) "Directory servers to query. This is an alist of the form (SERVER . PROTOCOL). SERVER is the host name or URI of the server, PROTOCOL is a symbol representing diff --git a/lisp/net/eudcb-ecomplete.el b/lisp/net/eudcb-ecomplete.el new file mode 100644 index 0000000000..55011d29f6 --- /dev/null +++ b/lisp/net/eudcb-ecomplete.el @@ -0,0 +1,108 @@ +;;; eudcb-ecomplete.el --- EUDC - ecomplete backend -*- lexical-binding: t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. +;; +;; Author: Alexander Adolf +;; +;; This file is part of GNU Emacs. +;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: +;; This library provides an interface to the ecomplete package as +;; an EUDC data source. + +;;; Usage: +;; No setup is required, since there is an entry for this backend +;; in `eudc-server-hotlist' by default. +;; +;; For example, if your `ecomplete-database-file' (typically +;; ~/.emacs.d/ecompleterc) contains: +;; +;; ((mail ("larsi@gnus.org" 38154 1516109510 "Lars "))) +;; +;; Then: +;; +;; C-x m lars C-u M-x eudc-expand-try-all RET +;; +;; should expand the email address into the To: field of the new +;; message. + +;;; Code: + +(require 'eudc) +(require 'ecomplete) +(require 'mail-parse) + +(defvar eudc-ecomplete-attributes-translation-alist + '((email . mail)) + "See `eudc-protocol-attributes-translation-alist'. +The back-end-specific attribute names are used as the \"type\" of +entry when searching, and they must hence match the types you use +in your ecompleterc database file.") + +;; hook ourselves into the EUDC framework +(eudc-protocol-set 'eudc-query-function + 'eudc-ecomplete-query-internal + 'ecomplete) +(eudc-protocol-set 'eudc-list-attributes-function + nil + 'ecomplete) +(eudc-protocol-set 'eudc-protocol-attributes-translation-alist + 'eudc-ecomplete-attributes-translation-alist + 'ecomplete) +(eudc-protocol-set 'eudc-protocol-has-default-query-attributes + nil + 'ecomplete) + +;;;###autoload +(defun eudc-ecomplete-query-internal (query &optional _return-attrs) + "Query `ecomplete' with QUERY. +QUERY is a list of cons cells (ATTR . VALUE). Since `ecomplete' +does not provide attributes in the usual sense, the +back-end-specific attribute names in +`eudc-ecomplete-attributes-translation-alist' are used as the +KEY (that is, the \"type\" of match) when looking for matches in +`ecomplete-database'. + +RETURN-ATTRS is ignored." ; FIXME: why is this being ignored? + (ecomplete-setup) + (let ((email-attr (car (eudc-translate-attribute-list '(email)))) + result) + (dolist (term query) + (let* ((attr (car term)) + (value (cdr term)) + (matches (ecomplete-get-matches attr value))) + (when matches + (dolist (match (split-string (string-trim (substring-no-properties + matches)) + "[\n\r]")) + ;; Try to decompose the email address. + (let* ((decoded (mail-header-parse-address match t)) + (name (cdr decoded)) + (email (car decoded))) + (if (and decoded (eq attr email-attr)) + ;; The email could be decomposed, push individual + ;; fields. + (push `((,attr . ,email) + ,@(when name (list (cons 'name name)))) + result) + ;; Otherwise just forward the value as-is. + (push (list (cons attr match)) result))))))) + result)) + +(eudc-register-protocol 'ecomplete) + +(provide 'eudcb-ecomplete) +;;; eudcb-ecomplete.el ends here diff --git a/lisp/net/eudcb-mailabbrev.el b/lisp/net/eudcb-mailabbrev.el new file mode 100644 index 0000000000..64b50af09b --- /dev/null +++ b/lisp/net/eudcb-mailabbrev.el @@ -0,0 +1,127 @@ +;;; eudcb-mailabbrev.el --- EUDC - mailabbrev backend -*- lexical-binding: t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. +;; +;; Author: Alexander Adolf +;; +;; This file is part of GNU Emacs. +;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: +;; This library provides an interface to the mailabbrev package as +;; an EUDC data source. + +;;; Usage: +;; No setup is required, since there is an entry for this backend +;; in `eudc-server-hotlist' by default. +;; +;; For example, if your `mail-personal-alias-file' (typically +;; ~/.mailrc) contains: +;; +;; alias lars "Lars " +;; +;; Then: +;; +;; C-x m lars C-u M-x eudc-expand-try-all RET +;; +;; will expand the correct email address into the To: field of the +;; new message. + +;;; Code: + +(require 'eudc) +(require 'mailabbrev) +(require 'mail-parse) + +;; hook ourselves into the EUDC framework +(eudc-protocol-set 'eudc-query-function + 'eudc-mailabbrev-query-internal + 'mailabbrev) +(eudc-protocol-set 'eudc-list-attributes-function + nil + 'mailabbrev) +(eudc-protocol-set 'eudc-protocol-attributes-translation-alist + nil + 'mailabbrev) +(eudc-protocol-set 'eudc-protocol-has-default-query-attributes + nil + 'mailabbrev) +;;;###autoload +(defun eudc-mailabbrev-query-internal (query &optional _return-attrs) + "Query `mailabbrev' with QUERY. +QUERY is a list of cons cells (ATTR . VALUE). Since `mailabbrev' +does not provide attributes in the usual sense, only the email, +name, and firstname attributes in the QUERY are considered, and +their values are matched against the alias names in the mailrc +file. When a mailrc alias is a distribution list, that is it +expands to more that one email address, the individual recipient +specifications are formatted using `eudc-rfc5322-make-address', +and returned as a comma-separated list in the email address +attribute. + +RETURN-ATTRS is a list of attributes to return, defaulting to +`eudc-default-return-attributes'." + (mail-abbrevs-setup) + (let (result) + (dolist (term query) + (let* ((attr (car term)) + (value (cdr term)) + (raw-matches (symbol-value (intern-soft value mail-abbrevs)))) + (when (and raw-matches + (memq attr '(email firstname name))) + (let* ((matches (split-string raw-matches ", ")) + (num-matches (length matches))) + (if (> num-matches 1) + ;; multiple matches: distribution list + (let ((distr-str (string))) + (dolist (recipient matches) + ;; try to decompose email construct + (let* ((decoded (mail-header-parse-address recipient t)) + (name (cdr decoded)) + (email (car decoded))) + (if decoded + ;; decoding worked, push rfc5322 rendered address + (setq distr-str + (copy-sequence + (concat distr-str ", " + (eudc-rfc5322-make-address email + nil + name)))) + ;; else, just forward the value as-is + (setq distr-str + (copy-sequence + (concat distr-str ", " recipient)))))) + ;; push result, removing the leading ", " + (push (list (cons 'email (substring distr-str 2 -1))) + result)) + ;; simple case: single match + (let* ((match (car matches)) + (decoded (mail-header-parse-address match t)) + (name (cdr decoded)) + (email (car decoded))) + (if decoded + ;; decoding worked, push individual fields + (push `((email . ,email) + ,@(when name (list (cons 'name name)))) + result) + ;; else, just forward the value as-is + (push (list (cons 'email match)) result)))))))) + result)) + +(eudc-register-protocol 'mailabbrev) + +(provide 'eudcb-mailabbrev) + +;;; eudcb-mailabbrev.el ends here diff --git a/test/lisp/net/eudc-resources/ecompleterc b/test/lisp/net/eudc-resources/ecompleterc new file mode 100644 index 0000000000..9019b26c9f --- /dev/null +++ b/test/lisp/net/eudc-resources/ecompleterc @@ -0,0 +1,7 @@ +((mail + ("larsi@gnus.org" 38154 1516109510 "Lars Ingebrigtsen ") + ("kfogel@red-bean.com" 10 1516065455 "Karl Fogel ") + ("behse@ecomplete.org" 10 1516065455 "behse@ecomplete.org")) + (phone + ("Lars Ingebrigtsen" 0 0 "+1 234 5678 9012") + ("Karl Fogel" 0 0 "+33 701 4567 8901"))) diff --git a/test/lisp/net/eudc-resources/mailrc b/test/lisp/net/eudc-resources/mailrc new file mode 100644 index 0000000000..c565f71837 --- /dev/null +++ b/test/lisp/net/eudc-resources/mailrc @@ -0,0 +1,3 @@ +alias lars "Lars Ingebrigtsen " +alias karl "Karl Fogel " +alias emacsheroes lars karl diff --git a/test/lisp/net/eudc-tests.el b/test/lisp/net/eudc-tests.el index 915006a97c..c326dcc793 100644 --- a/test/lisp/net/eudc-tests.el +++ b/test/lisp/net/eudc-tests.el @@ -152,4 +152,120 @@ (should (eq 'b (eudc-lax-plist-get '(nil a "a" a) 'a 'b))) (should (eq 'b (eudc-lax-plist-get '(a nil "nil" nil) nil 'b))))) +;; eudc-rfc5322-quote-phrase (string) +(ert-deftest eudc-test-rfc5322-quote-phrase () + "Tests for RFC5322 compliant phrase quoting." + ;; atext-token "[:alpha:][:digit:]!#$%&'*+/=?^_`{|}~-" + (should (equal (eudc-rfc5322-quote-phrase "Foo Bar !#$%&'*+/=?^_`{|}~-") + "Foo Bar !#$%&'*+/=?^_`{|}~-")) + (should (equal (eudc-rfc5322-quote-phrase "Foo, Bar !#$%&'*+/=?^_`{|}~-") + "\"Foo, Bar !#$%&'*+/=?^_`{|}~-\""))) + +;; eudc-rfc5322-valid-comment-p (string) +(ert-deftest eudc-test-rfc5322-valid-comment-p () + "Tests for RFC5322 compliant comments." + ;; cctext-token "\u005D-\u007E\u002A-\u005B\u0021-\u0027" + fwsp-token (TAB, LF, SPC) + ;; Printable US-ASCII characters not including "(", ")", or "\". + (let ((good-chars (append (number-sequence #x09 #x0a) + (number-sequence #x20 #x20) + (number-sequence #x21 #x27) + (number-sequence #x2a #x5b) + (number-sequence #x5d #x7e))) + (bad-chars (append (number-sequence #x00 #x08) + (number-sequence #x0b #x1f) + (number-sequence #x28 #x29) + (number-sequence #x5c #x5c) + (number-sequence #x7f #xff)))) + (dolist (gc good-chars) + (should (eq (eudc-rfc5322-valid-comment-p (format "%c" gc)) t))) + (dolist (bc bad-chars) + (should (eq (eudc-rfc5322-valid-comment-p (format "%c" bc)) nil))))) + +;; eudc-rfc5322-make-address (address &optional firstname name comment) +(ert-deftest eudc-test-make-address () + "Tests for RFC5322 compliant email address formatting." + (should (equal (eudc-rfc5322-make-address "") + nil)) + (should (equal (eudc-rfc5322-make-address nil) + nil)) + (should (equal (eudc-rfc5322-make-address "j.sixpack@example.org") + "j.sixpack@example.org")) + (should (equal (eudc-rfc5322-make-address "") + "")) + (should (equal (eudc-rfc5322-make-address "j.sixpack@example.org" + "Joey") + "Joey ")) + (should (equal (eudc-rfc5322-make-address "j.sixpack@example.org" + "Joey" + "Sixpack") + "Joey Sixpack ")) + (should (equal (eudc-rfc5322-make-address "j.sixpack@example.org" + "Joey" + "Sixpack" + "ten-packs are fine, too") + "Joey Sixpack \ +(ten-packs are fine, too)")) + (should (equal (eudc-rfc5322-make-address "j.sixpack@example.org" + "" + "Sixpack, Joey") + "\"Sixpack, Joey\" ")) + (should (equal (eudc-rfc5322-make-address "j.sixpack@example.org" + nil + "Sixpack, Joey") + "\"Sixpack, Joey\" ")) + (should (equal (eudc-rfc5322-make-address "j.sixpack@example.org" + nil + nil + "Duh!") + "j.sixpack@example.org (Duh!)")) + (should (equal (eudc-rfc5322-make-address "j.sixpack@example.org" + nil + nil + "Duh\\!") + "j.sixpack@example.org"))) + +(require 'ert-x) ; ert-with-temp-directory + +(defvar ecomplete-database-file (ert-resource-file "ecompleterc")) + +(ert-deftest eudcb-ecomplete () + "Test the ecomplete back-end." + (ert-with-temp-directory home + (with-environment-variables (("HOME" home)) + (let ((eudc-ignore-options-file t)) + (should (equal (eudc-ecomplete-query-internal '((mail . "brigts"))) + '(((mail . "Lars Ingebrigtsen "))))) + (should (equal (eudc-ecomplete-query-internal '((mail . "karl"))) + '(((mail . "Karl Fogel "))))) + (should (equal (eudc-ecomplete-query-internal '((mail . "behs"))) + '(((mail . "behse@ecomplete.org"))))) + (should (equal (eudc-ecomplete-query-internal '((mail . "louie"))) + nil)))))) + +(ert-with-temp-directory + home + (ert-deftest eudcb-mailabbrev () + "Test the mailabbrev back-end." + (with-environment-variables + (("HOME" home)) + (let ((mail-personal-alias-file (ert-resource-file "mailrc")) + (eudc-ignore-options-file t)) + (should (equal (eudc-mailabbrev-query-internal '((email . "lars"))) + '(((email . "larsi@mail-abbrev.com") + (name . "Lars Ingebrigtsen"))))) + (should (equal (eudc-mailabbrev-query-internal '((name . "lars"))) + '(((email . "larsi@mail-abbrev.com") + (name . "Lars Ingebrigtsen"))))) + (should (equal (eudc-mailabbrev-query-internal '((phone . "lars"))) + nil)) + (should (equal (eudc-mailabbrev-query-internal '((firstname . "karl"))) + '(((email . "kfogel@mail-abbrev.com") + (name . "Karl Fogel"))))) + (should (equal (eudc-mailabbrev-query-internal '((email . "louie"))) + nil)) + (should (equal (eudc-mailabbrev-query-internal '((name . "emacsheroes"))) + '(((email . "Lars Ingebrigtsen , \ +Karl Fogel Date: Tue Nov 8 13:30:17 2022 -0500 EUDC: Deprecate eudc-server variable * lisp/net/eudc-vars.el (eudc-server): Deprecate variable for Emacs 29.1. diff --git a/lisp/net/eudc-vars.el b/lisp/net/eudc-vars.el index bb1f9d9f0f..3ce363cf68 100644 --- a/lisp/net/eudc-vars.el +++ b/lisp/net/eudc-vars.el @@ -38,6 +38,9 @@ (defcustom eudc-server nil "The name or IP address of the directory server. +This variable is deprecated as of Emacs 29.1. Please add an +entry to `eudc-server-hotlist' instead of setting `eudc-server'. + A port number may be specified by appending a colon and a number to the name of the server. Use `localhost' if the directory server resides on your computer (BBDB backend). commit 5b9b393c614f18f7cc2260436fbf99ed2a6d05ed Author: Stephen Leake Date: Tue Nov 8 09:45:26 2022 -0800 * lisp/progmodes/eglot.el (eglot--pos-to-lsp-position): Improve comment diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 204121045a..ce989b5611 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -1426,7 +1426,8 @@ LBP defaults to `line-beginning-position'." (defun eglot--pos-to-lsp-position (&optional pos) "Convert point POS to LSP position." (eglot--widening - (list :line (1- (line-number-at-pos pos t)) ; F!@&#$CKING OFF-BY-ONE + ;; LSP line is zero-origin; emacs is one-origin. + (list :line (1- (line-number-at-pos pos t)) :character (progn (when pos (goto-char pos)) (funcall eglot-current-column-function))))) commit 5fa0fcf18bb23f3a6f028a1478644b7027b02d8c Author: Alan Mackenzie Date: Tue Nov 8 14:55:40 2022 +0000 CC Mode: Improve accuracy of recognition of bitfields * lisp/progmodes/cc-engine.el (c-forward-decl-or-cast-1): When we've got two identifiers followed by a colon, additionally check for a number (or identifier) followed by a semicolon or comma before concluding we have a bitfield. diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 145f0cacd1..a13a0c838a 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -10773,7 +10773,15 @@ This function might do hidden buffer changes." ((eq at-decl-or-cast t) (throw 'at-decl-or-cast t)) ((and c-has-bitfields - (eq at-decl-or-cast 'ids)) ; bitfield. + ;; Check for a bitfield. + (eq at-decl-or-cast 'ids) + (save-excursion + (forward-char) ; Over the : + (c-forward-syntactic-ws) + (and (looking-at "[[:alnum:]]") + (progn (c-forward-token-2) + (c-forward-syntactic-ws) + (memq (char-after) '(?\; ?,)))))) (setq backup-if-not-cast t) (throw 'at-decl-or-cast t))) commit 444e46fbee45f1b16db5759eed633a08c7b14fc7 Author: Robert Pluim Date: Tue Nov 8 10:40:43 2022 +0100 Don't use @w around @xref in ede.texi Texinfo 7 warns about this now. * doc/misc/ede.texi (ede-project-placeholder, ede-project, ede-cpp-root-project, ede-simple-project,ede-simple-base-project, ede-proj-project, project-am-makefile, ede-step-project, ede-target, ede-proj-target, ede-proj-target-makefile, semantic-ede-proj-target-grammar, ede-proj-target-makefile-objectcode, ede-proj-target-makefile-archive, ede-proj-target-makefile-program, ede-proj-target-makefile-shared-object, ede-proj-target-elisp, ede-proj-target-elisp-autoloads, ede-proj-target-makefile-miscelaneous, ede-proj-target-makefile-info, ede-proj-target-scheme, project-am-target, project-am-objectcode, project-am-program, project-am-header-noinst, project-am-header-inst, project-am-lisp, project-am-texinfo, project-am-man, ede-compilation-program, ede-compiler, ede-object-compiler, ede-linker): Remove @w around @xref. diff --git a/doc/misc/ede.texi b/doc/misc/ede.texi index c0c2ef93d9..7a26fe0e57 100644 --- a/doc/misc/ede.texi +++ b/doc/misc/ede.texi @@ -1432,7 +1432,7 @@ See @file{ede-proj-obj.el} for examples of the combination. @item ede-project-placeholder @table @asis @item Children: -@w{@xref{ede-project}.} +@xref{ede-project}. @end table @end table @end table @@ -1515,12 +1515,12 @@ Make sure placeholder @var{THIS} is replaced with the real thing, and pass throu @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-project-placeholder}.} +@item @xref{ede-project-placeholder}. @table @code @item ede-project @table @asis @item Children: -@w{@xref{ede-cpp-root-project},} @w{ede-emacs-project,} @w{ede-linux-project,} @w{ede-maven-project,} @w{@xref{ede-simple-project},} @w{@xref{ede-simple-base-project},} @w{@xref{ede-proj-project},} @w{@xref{project-am-makefile},} @w{@xref{ede-step-project}.} +@xref{ede-cpp-root-project}, @w{ede-emacs-project,} @w{ede-linux-project,} @w{ede-maven-project,} @xref{ede-simple-project}, @xref{ede-simple-base-project}, @xref{ede-proj-project}, @xref{project-am-makefile}, @xref{ede-step-project}. @end table @end table @end table @@ -1801,9 +1801,9 @@ Commit change to local variables in @var{PROJ}. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-project-placeholder}.} +@item @xref{ede-project-placeholder}. @table @code -@item @w{@xref{ede-project}.} +@item @xref{ede-project}. @table @code @item ede-cpp-root-project No children @@ -1923,9 +1923,9 @@ This knows details about or source tree. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-project-placeholder}.} +@item @xref{ede-project-placeholder}. @table @code -@item @w{@xref{ede-project}.} +@item @xref{ede-project}. @table @code @item ede-simple-project No children @@ -1953,9 +1953,9 @@ Commit any change to @var{PROJ} to its file. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-project-placeholder}.} +@item @xref{ede-project-placeholder}. @table @code -@item @w{@xref{ede-project}.} +@item @xref{ede-project}. @table @code @item ede-simple-base-project No children @@ -1983,9 +1983,9 @@ This one project could control a tree of subdirectories. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-project-placeholder}.} +@item @xref{ede-project-placeholder}. @table @code -@item @w{@xref{ede-project}.} +@item @xref{ede-project}. @table @code @item ede-proj-project No children @@ -2173,9 +2173,9 @@ Commit change to local variables in @var{PROJ}. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-project-placeholder}.} +@item @xref{ede-project-placeholder}. @table @code -@item @w{@xref{ede-project}.} +@item @xref{ede-project}. @table @code @item project-am-makefile No children @@ -2215,9 +2215,9 @@ buffer being in order to provide a smart default target type. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-project-placeholder}.} +@item @xref{ede-project-placeholder}. @table @code -@item @w{@xref{ede-project}.} +@item @xref{ede-project}. @table @code @item ede-step-project No children @@ -2371,7 +2371,7 @@ Commit change to local variables in @var{PROJ}. @item ede-target @table @asis @item Children: -@w{ede-cpp-root-target,} @w{ede-emacs-target-c,} @w{ede-emacs-target-el,} @w{ede-emacs-target-misc,} @w{ede-linux-target-c,} @w{ede-linux-target-misc,} @w{ede-maven-target-java,} @w{ede-maven-target-c,} @w{ede-maven-target-misc,} @w{ede-simple-target,} @w{@xref{ede-proj-target},} @w{@xref{project-am-target}.} +@w{ede-cpp-root-target,} @w{ede-emacs-target-c,} @w{ede-emacs-target-el,} @w{ede-emacs-target-misc,} @w{ede-linux-target-c,} @w{ede-linux-target-misc,} @w{ede-maven-target-java,} @w{ede-maven-target-c,} @w{ede-maven-target-misc,} @w{ede-simple-target,} @xref{ede-proj-target}, @xref{project-am-target}. @end table @end table @end table @@ -2577,12 +2577,12 @@ Retrieves the slot @code{menu} from an object of class @code{ede-target} @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code @item ede-proj-target @table @asis @item Children: -@w{@xref{ede-proj-target-makefile},} @w{ede-proj-target-aux,} @w{@xref{ede-proj-target-scheme}.} +@xref{ede-proj-target-makefile}, @w{ede-proj-target-aux,} @xref{ede-proj-target-scheme}. @end table @end table @end table @@ -2766,14 +2766,14 @@ sources variable. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{ede-proj-target}.} +@item @xref{ede-proj-target}. @table @code @item ede-proj-target-makefile @table @asis @item Children: -@w{@xref{semantic-ede-proj-target-grammar},} @w{@xref{ede-proj-target-makefile-objectcode},} @w{@xref{ede-proj-target-elisp},} @w{@xref{ede-proj-target-makefile-miscelaneous},} @w{@xref{ede-proj-target-makefile-info}.} +@xref{semantic-ede-proj-target-grammar}, @xref{ede-proj-target-makefile-objectcode}, @xref{ede-proj-target-elisp}, @xref{ede-proj-target-makefile-miscelaneous}, @xref{ede-proj-target-makefile-info}. @end table @end table @end table @@ -2864,11 +2864,11 @@ Use @var{CONFIGURATION} as the current configuration to query. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{ede-proj-target}.} +@item @xref{ede-proj-target}. @table @code -@item @w{@xref{ede-proj-target-makefile}.} +@item @xref{ede-proj-target-makefile}. @table @code @item semantic-ede-proj-target-grammar No children @@ -2918,16 +2918,16 @@ Argument @var{THIS} is the target that should insert stuff. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{ede-proj-target}.} +@item @xref{ede-proj-target}. @table @code -@item @w{@xref{ede-proj-target-makefile}.} +@item @xref{ede-proj-target-makefile}. @table @code @item ede-proj-target-makefile-objectcode @table @asis @item Children: -@w{@xref{ede-proj-target-makefile-archive},} @w{@xref{ede-proj-target-makefile-program}.} +@xref{ede-proj-target-makefile-archive}, @xref{ede-proj-target-makefile-program}. @end table @end table @end table @@ -2980,13 +2980,13 @@ Argument @var{THIS} is the target to get sources from. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{ede-proj-target}.} +@item @xref{ede-proj-target}. @table @code -@item @w{@xref{ede-proj-target-makefile}.} +@item @xref{ede-proj-target-makefile}. @table @code -@item @w{@xref{ede-proj-target-makefile-objectcode}.} +@item @xref{ede-proj-target-makefile-objectcode}. @table @code @item ede-proj-target-makefile-archive No children @@ -3023,18 +3023,18 @@ Makefile.am generator, so use it to add this important bin program. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{ede-proj-target}.} +@item @xref{ede-proj-target}. @table @code -@item @w{@xref{ede-proj-target-makefile}.} +@item @xref{ede-proj-target-makefile}. @table @code -@item @w{@xref{ede-proj-target-makefile-objectcode}.} +@item @xref{ede-proj-target-makefile-objectcode}. @table @code @item ede-proj-target-makefile-program @table @asis @item Children: -@w{@xref{ede-proj-target-makefile-shared-object}.} +@xref{ede-proj-target-makefile-shared-object}. @end table @end table @end table @@ -3102,15 +3102,15 @@ Insert bin_PROGRAMS variables needed by target @var{THIS}. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{ede-proj-target}.} +@item @xref{ede-proj-target}. @table @code -@item @w{@xref{ede-proj-target-makefile}.} +@item @xref{ede-proj-target-makefile}. @table @code -@item @w{@xref{ede-proj-target-makefile-objectcode}.} +@item @xref{ede-proj-target-makefile-objectcode}. @table @code -@item @w{@xref{ede-proj-target-makefile-program}.} +@item @xref{ede-proj-target-makefile-program}. @table @code @item ede-proj-target-makefile-shared-object No children @@ -3162,16 +3162,16 @@ Makefile.am generator, so use it to add this important bin program. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{ede-proj-target}.} +@item @xref{ede-proj-target}. @table @code -@item @w{@xref{ede-proj-target-makefile}.} +@item @xref{ede-proj-target-makefile}. @table @code @item ede-proj-target-elisp @table @asis @item Children: -@w{@xref{ede-proj-target-elisp-autoloads}.} +@xref{ede-proj-target-elisp-autoloads}. @end table @end table @end table @@ -3238,13 +3238,13 @@ is found, such as a @code{-version} variable, or the standard header. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{ede-proj-target}.} +@item @xref{ede-proj-target}. @table @code -@item @w{@xref{ede-proj-target-makefile}.} +@item @xref{ede-proj-target-makefile}. @table @code -@item @w{@xref{ede-proj-target-elisp}.} +@item @xref{ede-proj-target-elisp}. @table @code @item ede-proj-target-elisp-autoloads No children @@ -3353,11 +3353,11 @@ sources variable. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{ede-proj-target}.} +@item @xref{ede-proj-target}. @table @code -@item @w{@xref{ede-proj-target-makefile}.} +@item @xref{ede-proj-target-makefile}. @table @code @item ede-proj-target-makefile-miscelaneous No children @@ -3409,11 +3409,11 @@ Return a list of files which @var{THIS} target depends on. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{ede-proj-target}.} +@item @xref{ede-proj-target}. @table @code -@item @w{@xref{ede-proj-target-makefile}.} +@item @xref{ede-proj-target-makefile}. @table @code @item ede-proj-target-makefile-info No children @@ -3495,9 +3495,9 @@ when working in Automake mode. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{ede-proj-target}.} +@item @xref{ede-proj-target}. @table @code @item ede-proj-target-scheme No children @@ -3539,12 +3539,12 @@ Tweak the configure file (current buffer) to accommodate @var{THIS}. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code @item project-am-target @table @asis @item Children: -@w{@xref{project-am-objectcode},} @w{project-am-header,} @w{@xref{project-am-lisp},} @w{@xref{project-am-texinfo},} @w{@xref{project-am-man}.} +@xref{project-am-objectcode}, @w{project-am-header,} @xref{project-am-lisp}, @xref{project-am-texinfo}, @xref{project-am-man}. @end table @end table @end table @@ -3577,14 +3577,14 @@ Edit the target associated w/ this file. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{project-am-target}.} +@item @xref{project-am-target}. @table @code @item project-am-objectcode @table @asis @item Children: -@w{@xref{project-am-program},} @w{project-am-lib.} +@xref{project-am-program}, @w{project-am-lib.} @end table @end table @end table @@ -3622,11 +3622,11 @@ There are no default header files. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{project-am-target}.} +@item @xref{project-am-target}. @table @code -@item @w{@xref{project-am-objectcode}.} +@item @xref{project-am-objectcode}. @table @code @item project-am-program No children @@ -3660,9 +3660,9 @@ Additional LD args. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{project-am-target}.} +@item @xref{project-am-target}. @table @code @item @w{project-am-header.} @table @code @@ -3693,9 +3693,9 @@ Return the default macro to 'edit' for this object. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{project-am-target}.} +@item @xref{project-am-target}. @table @code @item @w{project-am-header.} @table @code @@ -3726,9 +3726,9 @@ Return the default macro to 'edit' for this object. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{project-am-target}.} +@item @xref{project-am-target}. @table @code @item project-am-lisp No children @@ -3756,9 +3756,9 @@ Return the default macro to 'edit' for this object. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{project-am-target}.} +@item @xref{project-am-target}. @table @code @item project-am-texinfo No children @@ -3808,9 +3808,9 @@ files in the project. @table @code @item eieio-speedbar-directory-button @table @code -@item @w{@xref{ede-target}.} +@item @xref{ede-target}. @table @code -@item @w{@xref{project-am-target}.} +@item @xref{project-am-target}. @table @code @item project-am-man No children @@ -3963,7 +3963,7 @@ compile commands. @item ede-compilation-program @table @asis @item Children: -@w{@xref{ede-compiler},} @w{@xref{ede-linker}.} +@xref{ede-compiler}, @xref{ede-linker}. @end table @end table @end table @@ -4071,12 +4071,12 @@ Tweak the configure file (current buffer) to accommodate @var{THIS}. @table @code @item eieio-instance-inheritor @table @code -@item @w{@xref{ede-compilation-program}.} +@item @xref{ede-compilation-program}. @table @code @item ede-compiler @table @asis @item Children: -@w{@xref{ede-object-compiler},} @w{semantic-ede-grammar-compiler-class.} +@xref{ede-object-compiler}, @w{semantic-ede-grammar-compiler-class.} @end table @end table @@ -4179,9 +4179,9 @@ Return a string based on @var{THIS} representing a make object variable. @table @code @item eieio-instance-inheritor @table @code -@item @w{@xref{ede-compilation-program}.} +@item @xref{ede-compilation-program}. @table @code -@item @w{@xref{ede-compiler}.} +@item @xref{ede-compiler}. @table @code @item ede-object-compiler No children @@ -4222,7 +4222,7 @@ Insert variables needed by the compiler @var{THIS}. @table @code @item eieio-instance-inheritor @table @code -@item @w{@xref{ede-compilation-program}.} +@item @xref{ede-compilation-program}. @table @code @item ede-linker No children commit 12e601f9811479d657f6abd8f63099dc73dda471 Author: Po Lu Date: Tue Nov 8 19:59:47 2022 +0800 Clean up some duplicate event group conversion code * src/xterm.c (xi_convert_event_keyboard_state): New function. Move keyboard event state over. (handle_one_xevent): Use it where necessary. diff --git a/src/xterm.c b/src/xterm.c index 84438e8590..861cf5da54 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -5245,7 +5245,9 @@ xi_convert_button_state (XIButtonState *in, unsigned int *out) } } -/* Return the modifier state in XEV as a standard X modifier mask. */ +/* Return the modifier state in XEV as a standard X modifier mask. + This should be used for non-keyboard events, where the group does + not matter. */ #ifdef USE_GTK static @@ -5263,6 +5265,17 @@ xi_convert_event_state (XIDeviceEvent *xev) return mods | buttons; } +/* Like the above. However, buttons are not converted, while the + group is. This should be used for key events being passed to the + likes of input methods and Xt. */ + +static unsigned int +xi_convert_event_keyboard_state (XIDeviceEvent *xev) +{ + return ((xev->mods.effective & ~(1 << 13 | 1 << 14)) + | (xev->group.effective << 13)); +} + /* Free all XI2 devices on DPYINFO. */ static void x_free_xi_devices (struct x_display_info *dpyinfo) @@ -23092,8 +23105,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, copy.xkey.root = xev->root; copy.xkey.subwindow = xev->child; copy.xkey.time = xev->time; - copy.xkey.state = ((xev->mods.effective & ~(1 << 13 | 1 << 14)) - | (xev->group.effective << 13)); + copy.xkey.state = xi_convert_event_keyboard_state (xev); xi_convert_button_state (&xev->buttons, ©.xkey.state); copy.xkey.x = lrint (xev->event_x); @@ -23149,8 +23161,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, xkey.root = xev->root; xkey.subwindow = xev->child; xkey.time = xev->time; - xkey.state = ((xev->mods.effective & ~(1 << 13 | 1 << 14)) - | (xev->group.effective << 13)); + xkey.state = xi_convert_event_keyboard_state (xev); xkey.x = lrint (xev->event_x); xkey.y = lrint (xev->event_y); @@ -23568,8 +23579,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, xkey.root = xev->root; xkey.subwindow = xev->child; xkey.time = xev->time; - xkey.state = ((xev->mods.effective & ~(1 << 13 | 1 << 14)) - | (xev->group.effective << 13)); + xkey.state = xi_convert_event_keyboard_state (xev); xkey.x = lrint (xev->event_x); xkey.y = lrint (xev->event_y); xkey.x_root = lrint (xev->root_x); commit b8134a7eba2e0334925e011e953044ea33408ec6 Author: Alan Mackenzie Date: Tue Nov 8 11:53:37 2022 +0000 CC Mode: Stabilize the fontification in the presence of "register" keywords This fixes bug #58883. * lisp/progmodes/cc-engine.el (c-forward-decl-or-cast-1): New variable unsafe-maybe. Set it in CASE 10 rather than setting c-record-type-identifiers to nil. Near the end of the function, when unsafe-maybe is set, bind c-promote-possible-types to 'just-one rather than t around the call to c-forward-type. diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 8cf882d569..145f0cacd1 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -10208,7 +10208,11 @@ This function might do hidden buffer changes." (save-rec-ref-ids c-record-ref-identifiers) ;; Set when we parse a declaration which might also be an expression, ;; such as "a *b". See CASE 16 and CASE 17. - maybe-expression) + maybe-expression + ;; Set for the type when `c-forward-type' returned `maybe', and we + ;; want to fontify it as a type, but aren't confident enough to enter + ;; it into `c-found-types'. + unsafe-maybe) (save-excursion (goto-char preceding-token-end) @@ -10904,7 +10908,7 @@ This function might do hidden buffer changes." ;; a statement beginning with an identifier. (when (and (eq at-type 'maybe) (not (eq context 'top))) - (setq c-record-type-identifiers nil)) + (setq unsafe-maybe t)) (throw 'at-decl-or-cast t)) ;; CASE 11 @@ -11207,7 +11211,8 @@ This function might do hidden buffer changes." ;; fontification just because it's "a known type that can't ;; be a name or other expression". 2013-09-18. ) - (let ((c-promote-possible-types t)) + (let ((c-promote-possible-types + (if unsafe-maybe 'just-one t))) (save-excursion (goto-char type-start) (c-forward-type))))