commit 85108d541217f0333860c4f86c3b16b4349f85a4 (HEAD, refs/remotes/origin/master) Merge: 4f31ad6be56 f221105723d Author: Stefan Kangas Date: Sun Dec 11 06:30:22 2022 +0100 Merge from origin/emacs-29 f221105723d ; * doc/misc/use-package.texi: Prepare for GNU ELPA. commit f221105723dc8d3ee9f3c8d1c2717058afbc6666 (refs/remotes/origin/emacs-29) Author: Stefan Kangas Date: Sun Dec 11 01:43:25 2022 +0100 ; * doc/misc/use-package.texi: Prepare for GNU ELPA. diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 6447f96c63f..0aa8975f30a 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -1,15 +1,17 @@ \input texinfo @c -*- texinfo -*- @c %**start of header -@setfilename ../../use-package.info +@setfilename ../../info/use-package.info @settitle use-package User Manual +@set USEP_VER 2.4.5 +@set USEP_DIST as distributed with Emacs @value{EMACSVER} @include docstyle.texi @syncodeindex vr cp @syncodeindex fn cp +@include emacsver.texi @c %**end of header @copying -This manual is for use-package, a configuration macro for simplifying -your init file. +This manual is for use-package @value{USEP_VER} @value{USEP_DIST}. Copyright @copyright{} 2022 Free Software Foundation, Inc. @@ -34,7 +36,7 @@ @finalout @titlepage @title use-package User Manual -@subtitle for version 2.4.5 +@subtitle for version USEP_VER @author John Wiegley & Stefan Kangas @page @vskip 0pt plus 1filll commit 4f31ad6be5656113a3406c73a36e44af8baefc65 Author: Stefan Kangas Date: Sun Dec 11 03:09:18 2022 +0100 ; Auto-commit of loaddefs files. diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 1c049107f00..31db9289aa8 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -1943,6 +1943,85 @@ "bibtex" (fn)" t) (register-definition-prefixes "bibtex-style" '("bibtex-style-")) + +;;; Generated autoloads from use-package/bind-key.el + +(push (purecopy '(bind-key 2 4 1)) package--builtin-versions) +(autoload 'bind-key "bind-key" "\ +Bind KEY-NAME to COMMAND in KEYMAP (`global-map' if not passed). + +KEY-NAME may be a vector, in which case it is passed straight to +`define-key'. Or it may be a string to be interpreted as +spelled-out keystrokes, e.g., \"C-c C-z\". See the documentation +of `edmacro-mode' for details. + +COMMAND must be an interactive function or lambda form. + +KEYMAP, if present, should be a keymap variable or symbol. +For example: + + (bind-key \"M-h\" #\\='some-interactive-function my-mode-map) + + (bind-key \"M-h\" #\\='some-interactive-function \\='my-mode-map) + +If PREDICATE is non-nil, it is a form evaluated to determine when +a key should be bound. It must return non-nil in such cases. +Emacs can evaluate this form at any time that it does redisplay +or operates on menu data structures, so you should write it so it +can safely be called at any time. + +(fn KEY-NAME COMMAND &optional KEYMAP PREDICATE)" nil t) +(autoload 'unbind-key "bind-key" "\ +Unbind the given KEY-NAME, within the KEYMAP (if specified). +See `bind-key' for more details. + +(fn KEY-NAME &optional KEYMAP)" nil t) +(autoload 'bind-key* "bind-key" "\ +Similar to `bind-key', but overrides any mode-specific bindings. + +(fn KEY-NAME COMMAND &optional PREDICATE)" nil t) +(autoload 'bind-keys "bind-key" "\ +Bind multiple keys at once. + +Accepts keyword arguments: +:map MAP - a keymap into which the keybindings should be + added +:prefix KEY - prefix key for these bindings +:prefix-map MAP - name of the prefix map that should be created + for these bindings +:prefix-docstring STR - docstring for the prefix-map variable +:menu-name NAME - optional menu string for prefix map +:repeat-docstring STR - docstring for the repeat-map variable +:repeat-map MAP - name of the repeat map that should be created + for these bindings. If specified, the + `repeat-map' property of each command bound + (within the scope of the `:repeat-map' keyword) + is set to this map. +:exit BINDINGS - Within the scope of `:repeat-map' will bind the + key in the repeat map, but will not set the + `repeat-map' property of the bound command. +:continue BINDINGS - Within the scope of `:repeat-map' forces the + same behavior as if no special keyword had + been used (that is, the command is bound, and + it's `repeat-map' property set) +:filter FORM - optional form to determine when bindings apply + +The rest of the arguments are conses of keybinding string and a +function symbol (unquoted). + +(fn &rest ARGS)" nil t) +(autoload 'bind-keys* "bind-key" "\ +Bind multiple keys at once, in `override-global-map'. +Accepts the same keyword arguments as `bind-keys' (which see). + +This binds keys in such a way that bindings are not overridden by +other modes. See `override-global-mode'. + +(fn &rest ARGS)" nil t) +(autoload 'describe-personal-keybindings "bind-key" "\ +Display all the personal keybindings defined by `bind-key'." t) +(register-definition-prefixes "bind-key" '("bind-key" "override-global-m" "personal-keybindings")) + ;;; Generated autoloads from emacs-lisp/bindat.el @@ -2841,9 +2920,11 @@ "semantic/bovine/c" ;;; Generated autoloads from progmodes/c-ts-mode.el -(autoload 'c-ts-mode--base-mode "c-ts-mode" "\ +(autoload 'c-ts-base-mode "c-ts-mode" "\ Major mode for editing C, powered by tree-sitter. +\\{c-ts-mode-map} + (fn)" t) (autoload 'c-ts-mode "c-ts-mode" "\ Major mode for editing C, powered by tree-sitter. @@ -2853,7 +2934,7 @@ "semantic/bovine/c" Major mode for editing C++, powered by tree-sitter. (fn)" t) -(register-definition-prefixes "c-ts-mode" '("c-ts-")) +(register-definition-prefixes "c-ts-mode" '("c-ts-mode-")) ;;; Generated autoloads from calendar/cal-bahai.el @@ -7896,6 +7977,16 @@ "semantic/doc" (fn BMK)") (register-definition-prefixes "doc-view" '("doc-view-")) + +;;; Generated autoloads from progmodes/dockerfile-ts-mode.el + +(add-to-list 'auto-mode-alist '("\\(?:Dockerfile\\(?:\\..*\\)?\\|\\.[Dd]ockerfile\\)$" . dockerfile-ts-mode)) +(autoload 'dockerfile-ts-mode "dockerfile-ts-mode" "\ +Major mode for editing Dockerfiles, powered by tree-sitter. + +(fn)" t) +(register-definition-prefixes "dockerfile-ts-mode" '("dockerfile-ts-mode--")) + ;;; Generated autoloads from play/doctor.el @@ -11276,6 +11367,12 @@ "expand" (register-definition-prefixes "srecode/expandproto" '("srecode-")) + +;;; Generated autoloads from external-completion.el + +(push (purecopy '(external-completion 0 1)) package--builtin-versions) +(register-definition-prefixes "external-completion" '("external-completion-")) + ;;; Generated autoloads from cedet/srecode/extract.el @@ -23377,11 +23474,11 @@ package-vc-selected-packages (autoload 'package-vc-checkout "package-vc" "\ Clone the sources for PKG-DESC into DIRECTORY and visit that directory. Unlike `package-vc-install', this does not yet set up the package -for use with Emacs; use `package-vc-link-directory' for setting -the package up after this function finishes. -Optional argument REV means to clone a specific version of the -package; it defaults to the last version available from the -package's repository. If REV has the special value +for use with Emacs; use `package-vc-install-from-checkout' for +setting the package up after this function finishes. Optional +argument REV means to clone a specific version of the package; it +defaults to the last version available from the package's +repository. If REV has the special value `:last-release' (interactively, the prefix argument), that stands for the last released version of the package. @@ -24970,7 +25067,7 @@ "ede/proj-shared" ;;; Generated autoloads from progmodes/project.el -(push (purecopy '(project 0 8 3)) package--builtin-versions) +(push (purecopy '(project 0 9 2)) package--builtin-versions) (autoload 'project-current "project" "\ Return the project instance in DIRECTORY, defaulting to `default-directory'. @@ -24982,8 +25079,8 @@ "ede/proj-shared" The \"transient\" project instance is a special kind of value which denotes a project rooted in that directory and includes all -the files under the directory except for those that should be -ignored (per `project-ignores'). +the files under the directory except for those that match entries +in `vc-directory-exclusion-list' or `grep-find-ignored-files'. See the doc string of `project-find-functions' for the general form of the project instance object. @@ -28116,29 +28213,17 @@ server-mode If emacsclient was started with a list of filenames to edit, then only these files will be asked to be saved. +When running Emacs as a daemon and with +`server-stop-automatically' (which see) set to `kill-terminal' or +`delete-frame', this function may call `save-buffers-kill-emacs' +if there are no other active clients. + (fn ARG)") (autoload 'server-stop-automatically "server" "\ -Automatically stop server as specified by ARG. +Automatically stop the Emacs server as specified by VALUE. +This sets the variable `server-stop-automatically' (which see). -If ARG is the symbol `empty', stop the server when it has no -remaining clients, no remaining unsaved file-visiting buffers, -and no running processes with a `query-on-exit' flag. - -If ARG is the symbol `delete-frame', ask the user when the last -frame is deleted whether each unsaved file-visiting buffer must -be saved and each running process with a `query-on-exit' flag -can be stopped, and if so, stop the server itself. - -If ARG is the symbol `kill-terminal', ask the user when the -terminal is killed with \\[save-buffers-kill-terminal] whether each unsaved file-visiting -buffer must be saved and each running process with a `query-on-exit' -flag can be stopped, and if so, stop the server itself. - -Any other value of ARG will cause this function to signal an error. - -This function is meant to be called from the user init file. - -(fn ARG)") +(fn VALUE)") (register-definition-prefixes "server" '("server-")) @@ -32875,10 +32960,18 @@ "type-break" ;;; Generated autoloads from progmodes/typescript-ts-mode.el (add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-ts-mode)) -(add-to-list 'auto-mode-alist '("\\.tsx\\'" . typescript-ts-mode)) +(add-to-list 'auto-mode-alist '("\\.tsx\\'" . tsx-ts-mode)) +(autoload 'typescript-ts-base-mode "typescript-ts-mode" "\ +Major mode for editing TypeScript. + +(fn)" t) (autoload 'typescript-ts-mode "typescript-ts-mode" "\ Major mode for editing TypeScript. +(fn)" t) +(autoload 'tsx-ts-mode "typescript-ts-mode" "\ +Major mode for editing TypeScript. + (fn)" t) (register-definition-prefixes "typescript-ts-mode" '("typescript-ts-mode-")) @@ -33605,6 +33698,195 @@ "url-util" (register-definition-prefixes "url-vars" '("url-")) + +;;; Generated autoloads from use-package/use-package.el + +(push (purecopy '(use-package 2 4 4)) package--builtin-versions) + + +;;; Generated autoloads from use-package/use-package-bind-key.el + +(autoload 'use-package-autoload-keymap "use-package-bind-key" "\ +Load PACKAGE and bind key sequence invoking this function to KEYMAP-SYMBOL. +Then simulate pressing the same key sequence a again, so that the +next key pressed is routed to the newly loaded keymap. + +This function supports use-package's :bind-keymap keyword. It +works by binding the given key sequence to an invocation of this +function for a particular keymap. The keymap is expected to be +defined by the package. In this way, loading the package is +deferred until the prefix key sequence is pressed. + +(fn KEYMAP-SYMBOL PACKAGE OVERRIDE)") +(autoload 'use-package-normalize-binder "use-package-bind-key" "\ + + +(fn NAME KEYWORD ARGS)") +(defalias 'use-package-normalize/:bind 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) +(defalias 'use-package-autoloads/:bind 'use-package-autoloads-mode) +(defalias 'use-package-autoloads/:bind* 'use-package-autoloads-mode) +(autoload 'use-package-handler/:bind "use-package-bind-key" "\ + + +(fn NAME KEYWORD ARGS REST STATE &optional BIND-MACRO)") +(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) +(autoload 'use-package-handler/:bind-keymap "use-package-bind-key" "\ + + +(fn NAME KEYWORD ARGS REST STATE &optional OVERRIDE)") +(autoload 'use-package-handler/:bind-keymap* "use-package-bind-key" "\ + + +(fn NAME KEYWORD ARG REST STATE)") +(register-definition-prefixes "use-package-bind-key" '("use-package-handler/:bind*")) + + +;;; Generated autoloads from use-package/use-package-core.el + +(autoload 'use-package "use-package-core" "\ +Declare an Emacs package by specifying a group of configuration options. + +For the full documentation, see Info node `(use-package) top'. +Usage: + + (use-package package-name + [:keyword [option]]...) + +:init Code to run before PACKAGE-NAME has been loaded. +:config Code to run after PACKAGE-NAME has been loaded. Note that + if loading is deferred for any reason, this code does not + execute until the lazy load has occurred. +:preface Code to be run before everything except `:disabled'; this + can be used to define functions for use in `:if', or that + should be seen by the byte-compiler. + +:mode Form to be added to `auto-mode-alist'. +:magic Form to be added to `magic-mode-alist'. +:magic-fallback Form to be added to `magic-fallback-mode-alist'. +:interpreter Form to be added to `interpreter-mode-alist'. + +:commands Define autoloads for commands that will be defined by the + package. This is useful if the package is being lazily + loaded, and you wish to conditionally call functions in your + `:init' block that are defined in the package. +:autoload Similar to :commands, but it for no-interactive one. +:hook Specify hook(s) to attach this package to. + +:bind Bind keys, and define autoloads for the bound commands. +:bind* Bind keys, and define autoloads for the bound commands, + *overriding all minor mode bindings*. +:bind-keymap Bind a key prefix to an auto-loaded keymap defined in the + package. This is like `:bind', but for keymaps. +:bind-keymap* Like `:bind-keymap', but overrides all minor mode bindings + +:defer Defer loading of a package -- this is implied when using + `:commands', `:bind', `:bind*', `:mode', `:magic', `:hook', + `:magic-fallback', or `:interpreter'. This can be an integer, + to force loading after N seconds of idle time, if the package + has not already been loaded. +:demand Prevent the automatic deferred loading introduced by constructs + such as `:bind' (see `:defer' for the complete list). + +:after Delay the effect of the use-package declaration + until after the named libraries have loaded. + Before they have been loaded, no other keyword + has any effect at all, and once they have been + loaded it is as if `:after' was not specified. + +:if EXPR Initialize and load only if EXPR evaluates to a non-nil value. +:disabled The package is ignored completely if this keyword is present. +:defines Declare certain variables to silence the byte-compiler. +:functions Declare certain functions to silence the byte-compiler. +:load-path Add to the `load-path' before attempting to load the package. +:diminish Support for diminish.el (if installed). +:delight Support for delight.el (if installed). +:custom Call `Custom-set' or `set-default' with each variable + definition without modifying the Emacs `custom-file'. + (compare with `custom-set-variables'). +:custom-face Call `custom-set-faces' with each face definition. +:ensure Loads the package using package.el if necessary. +:pin Pin the package to an archive. + +(fn NAME &rest ARGS)" nil t) +(function-put 'use-package 'lisp-indent-function 'defun) +(register-definition-prefixes "use-package-core" '("use-package-")) + + +;;; Generated autoloads from use-package/use-package-delight.el + +(autoload 'use-package-normalize/:delight "use-package-delight" "\ +Normalize arguments to delight. + +(fn NAME KEYWORD ARGS)") +(autoload 'use-package-handler/:delight "use-package-delight" "\ + + +(fn NAME KEYWORD ARGS REST STATE)") +(register-definition-prefixes "use-package-delight" '("use-package-normalize-delight")) + + +;;; Generated autoloads from use-package/use-package-diminish.el + +(autoload 'use-package-normalize/:diminish "use-package-diminish" "\ + + +(fn NAME KEYWORD ARGS)") +(autoload 'use-package-handler/:diminish "use-package-diminish" "\ + + +(fn NAME KEYWORD ARG REST STATE)") +(register-definition-prefixes "use-package-diminish" '("use-package-normalize-diminish")) + + +;;; Generated autoloads from use-package/use-package-ensure.el + +(autoload 'use-package-normalize/:ensure "use-package-ensure" "\ + + +(fn NAME KEYWORD ARGS)") +(autoload 'use-package-handler/:ensure "use-package-ensure" "\ + + +(fn NAME KEYWORD ENSURE REST STATE)") +(register-definition-prefixes "use-package-ensure" '("use-package-")) + + +;;; Generated autoloads from use-package/use-package-ensure-system-package.el + +(push (purecopy '(use-package-ensure-system-package 0 2)) package--builtin-versions) +(autoload 'use-package-normalize/:ensure-system-package "use-package-ensure-system-package" "\ +Turn ARGS into a list of conses of the form (PACKAGE-NAME . INSTALL-COMMAND). + +(fn NAME-SYMBOL KEYWORD ARGS)") +(autoload 'use-package-handler/:ensure-system-package "use-package-ensure-system-package" "\ +Execute the handler for `:ensure-system-package' keyword in `use-package'. + +(fn NAME KEYWORD ARG REST STATE)") +(register-definition-prefixes "use-package-ensure-system-package" '("use-package-ensure-system-package-")) + + +;;; Generated autoloads from use-package/use-package-jump.el + +(autoload 'use-package-jump-to-package-form "use-package-jump" "\ +Attempt to find and jump to the `use-package' form that loaded PACKAGE. +This will only find the form if that form actually required +PACKAGE. If PACKAGE was previously required then this function +will jump to the file that originally required PACKAGE instead. + +(fn PACKAGE)" t) +(register-definition-prefixes "use-package-jump" '("use-package-find-require")) + + +;;; Generated autoloads from use-package/use-package-lint.el + +(autoload 'use-package-lint "use-package-lint" "\ +Check for errors in `use-package' declarations. +For example, if the module's `:if' condition is met, but even +with the specified `:load-path' the module cannot be found." t) +(register-definition-prefixes "use-package-lint" '("use-package-lint-declaration")) + ;;; Generated autoloads from userlock.el commit 1af0c21eb0cc787e202703cb83e43b0b09058625 Merge: 66fdd45bdd8 80122cde3db Author: Stefan Kangas Date: Sun Dec 11 02:58:00 2022 +0100 Merge from origin/emacs-29 80122cde3db ; Unbreak bootstrap # Conflicts: # lisp/ldefs-boot.el commit 80122cde3dbcd191b4b82e463fb26777b355a4b3 Author: Stefan Kangas Date: Sun Dec 11 02:32:21 2022 +0100 ; Unbreak bootstrap * lisp/progmodes/dockerfile-ts-mode.el (auto-mode-alist): Wrap autoloaded definition using the rx macro in eval-and-compile. diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 5765d2d4feb..fb89baf0949 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -7980,7 +7980,7 @@ "doc-view" ;;; Generated autoloads from progmodes/dockerfile-ts-mode.el -(add-to-list 'auto-mode-alist `(,(rx (| (: "Dockerfile" (32 "." (* nonl))) (: "." (any "dD") "ockerfile")) eol) . dockerfile-ts-mode)) +(add-to-list 'auto-mode-alist '("\\(?:Dockerfile\\(?:\\..*\\)?\\|\\.[Dd]ockerfile\\)$" . dockerfile-ts-mode)) (autoload 'dockerfile-ts-mode "dockerfile-ts-mode" "\ Major mode for editing Dockerfiles, powered by tree-sitter. diff --git a/lisp/progmodes/dockerfile-ts-mode.el b/lisp/progmodes/dockerfile-ts-mode.el index e08387ad969..1ece3dd59bf 100644 --- a/lisp/progmodes/dockerfile-ts-mode.el +++ b/lisp/progmodes/dockerfile-ts-mode.el @@ -131,10 +131,8 @@ dockerfile-ts-mode--imenu-1 ;;;###autoload (add-to-list 'auto-mode-alist - `(,(rx (| - (: "Dockerfile" (? "." (* nonl))) - (: "." (any "dD") "ockerfile")) - eol) + ;; NOTE: We can't use `rx' here, as it breaks bootstrap. + '("\\(?:Dockerfile\\(?:\\..*\\)?\\|\\.[Dd]ockerfile\\)$" . dockerfile-ts-mode)) ;;;###autoload commit 66fdd45bdd8e427178c589990c7c23ee295f14e9 Merge: 6048503c526 05ece1eb8b7 Author: Po Lu Date: Sun Dec 11 09:34:03 2022 +0800 Merge from origin/emacs-29 05ece1eb8b7 Improve last change to xfaces.c commit 6048503c52607a1df026a742d03934799e7ead05 Merge: 5737c2a3af7 7013b0179cb Author: Po Lu Date: Sun Dec 11 09:34:03 2022 +0800 ; Merge from origin/emacs-29 The following commit was skipped: 7013b0179cb ; Auto-commit of loaddefs files. commit 5737c2a3af70bc8d653abdb22922c4dc2a49e878 Merge: 52de8885048 79659416f95 Author: Po Lu Date: Sun Dec 11 09:34:03 2022 +0800 Merge from origin/emacs-29 79659416f95 ; * admin/git-bisect-start: Fix commit hash a9037aa8e81 ; Fix use-package-ensure-system-package macOS footnote 7d787564c08 Actually improve detection of long lines 118465f6fed ; Improve checkdoc.el commentary section 30e3cb21351 Unset the weight/slant/width in the spec when realizing a... 01154166057 Update to Org 9.6-31-g954a95 26a8644a587 ; tabulated-list.el: Remove duplicate obsolete declaration 29b9aeae32a ; * doc/misc/use-package.texi: Fix misplaced @end group. 3c5a41b2008 ; * doc/lispref/keymaps.texi (Searching Keymaps): Fix a t... 1753da24cd4 Fix infloop in 'shell-resync-dirs' with tcsh 2f1269c3331 ; Fix some minor issues in use-package.texi commit 52de8885048daf444bdbdb34c4b3d0318dc6a76c Merge: 6d6ca47aba7 1b7ece20956 Author: Po Lu Date: Sun Dec 11 09:34:03 2022 +0800 ; Merge from origin/emacs-29 The following commit was skipped: 1b7ece20956 ; Fix a failure when running server-tests via the command... commit 6d6ca47aba7b72d2a770d7ed01c849d3cc729e21 Merge: e0856443291 44c5f361497 Author: Po Lu Date: Sun Dec 11 09:34:03 2022 +0800 Merge from origin/emacs-29 44c5f361497 ; Fix two byte-compiler warnings a8ee046fb50 Ensure 'package-vc--version' always returns a version 022ab1061b2 Ensure 'package-vc--main-file' always returns an existing... 357fe91996b Check if package already exists before installing from ch... 5e8bc79f6b2 ; Fix reference in docstring to 'package-vc-install-from-... af88b00b19c Refresh the package quickstart file in package-vc 5a092c8e461 ; * admin/notes/tree-sitter/starter-guide (Indent): Minor... ebef8905b0d Make indirect buffers use tree-sitter parsers of their ba... 8f53fa10d94 Fontify "this" as a keyword in c++-ts-mode (bug#59924) 8de8f1dc051 Add class_body indentation for typescript (bug#59680) 839341d7370 Make more granular defun-type-regexp (bug#59873) 8f49137c9bf Add dockerfile-ts-mode (Bug#59894) 1014bcc8e32 Fix fontification of method-invocations in js-ts-mode (bu... 7141920c6af Fix escape-sequence feature in typescript-ts-mode (bug#59... 4df35e3491c Improve fontification in csharp-ts-mode (bug#59909) 33a8415eb7e Use 'project--value-in-dir' for 'project-vc-include-untra... 594267395d5 Update Turkish Hello 940d9070e97 Support newer glib versions (Bug#59061) 0bd26abf7fb ; * doc/misc/use-package.texi: Fix @file. bcf235acd58 Merge branch 'emacs-29' of git.savannah.gnu.org:/srv/git/... 2ea7a357fd1 ; * doc/misc/use-package.texi: Fix @acronym. d268ab1c5d7 Bring back the project--value-in-dir logic commit e08564432918aa87b49da58ac90bb43718424364 Merge: 13310643cd6 fa36b5ddf58 Author: Po Lu Date: Sun Dec 11 09:34:03 2022 +0800 ; Merge from origin/emacs-29 The following commits were skipped: fa36b5ddf58 Backport: Enable native speed 2 EMBA build and tests and ... 6a9e38f22c6 * test/infra/test-jobs.yml: Regenerate for the new use-pa... commit 13310643cd642bb1403bb2f8a5c27d1929725897 Merge: 0878279809c 5fbd12ff494 Author: Po Lu Date: Sun Dec 11 09:34:02 2022 +0800 Merge from origin/emacs-29 5fbd12ff494 Adapt manual names in emacs-news-mode b36bc692671 ; * etc/NEWS: Fix typos. f626b9f3856 ; * doc/misc/use-package.texi: Fix indexing. 56a6712bd6f ; * lisp/erc/erc.el (erc-default-target): Fix comment. dcf69a1da4a Respect some spaces in auth-source-pass--match-regexp acd462b0306 ; Improve the use-package manual 801c1c22de8 ; Prefer HTTPS to HTTP in some URLs 74a009dd96a Eglot: Handle LSP progress with Emacs progress reporters ... 0cfeb1c2bc9 Eglot: cleanup whitespace and indentation 465a9e78b96 Better test-custom-opts diagnostics bdbb7099784 ; Fix groff warnings in man pages d3d9676bf88 New script admin/check-man-pages c2aea9d1323 ; Mention flush-lines in kill-matching-lines docstring f5c3585e4dd ; Fix typos 58a483960dd ; Improve use-package-autoload-keymap docstring # Conflicts: # etc/NEWS commit 05ece1eb8b7ce28d366d02df89449d453be8d37e Author: Po Lu Date: Sun Dec 11 09:32:20 2022 +0800 Improve last change to xfaces.c * src/xfaces.c (font_unset_attribute): New function. (realize_gui_face): Improve commentary and use list instead of bitmask. (syms_of_xfaces): Get rid of bitmask. Replace it by a list, there is no reason any user should have to think about bitmasks in Emacs lisp. diff --git a/src/xfaces.c b/src/xfaces.c index 643f4365896..88d3a79f8c0 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -6014,6 +6014,23 @@ realize_non_ascii_face (struct frame *f, Lisp_Object font_object, } #endif /* HAVE_WINDOW_SYSTEM */ +/* Remove the attribute at INDEX from the font object if SYMBOL + appears in `font-fallback-ignored-attributes'. */ + +static void +font_unset_attribute (Lisp_Object font_object, enum font_property_index index, + Lisp_Object symbol) +{ + Lisp_Object tail; + + tail = Vfont_fallback_ignored_attributes; + + FOR_EACH_TAIL_SAFE (tail) + { + if (EQ (XCAR (tail), symbol)) + ASET (font_object, index, Qnil); + } +} /* Realize the fully-specified face with attributes ATTRS in face cache CACHE for ASCII characters. Do it for GUI frame CACHE->f. @@ -6029,7 +6046,7 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] #ifdef HAVE_WINDOW_SYSTEM struct face *default_face; struct frame *f; - Lisp_Object stipple, underline, overline, strike_through, box; + Lisp_Object stipple, underline, overline, strike_through, box, spec; eassert (FRAME_WINDOW_P (cache->f)); @@ -6072,39 +6089,34 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] } if (! FONT_OBJECT_P (attrs[LFACE_FONT_INDEX])) { - Lisp_Object spec = copy_font_spec (attrs[LFACE_FONT_INDEX]); -#define MAYBE_UNSET_ATTRIBUTE(ATTR) \ - if (realize_gui_face_ignored_spec_attributes \ - & (1 << FONT_##ATTR##_INDEX)) \ - ASET (spec, FONT_##ATTR##_INDEX, Qnil); - /* The default value of - realize_gui_face_ignored_spec_attributes unsets the - weight, slant and width in spec. The best possible - values for these attributes is determined in - font_find_for_lface, called by font_load_for_lface, when - the candidate list returned by font_list_entities is - sorted by font_select_entity (which calls - font_sort_entities, which calls font_score). If these - attributes are not unset here, the candidate font list - returned by font_list_entities only contains fonts that - are exact matches for these weight, slant and width - attributes, which leads to suboptimal or wrong font - choices. See bug#59347. */ - MAYBE_UNSET_ATTRIBUTE (WEIGHT); - MAYBE_UNSET_ATTRIBUTE (SLANT); - MAYBE_UNSET_ATTRIBUTE (WIDTH); + spec = copy_font_spec (attrs[LFACE_FONT_INDEX]); + + /* Unset several values in SPEC, usually the width, slant, + and weight. The best possible values for these + attributes is determined in font_find_for_lface, called + by font_load_for_lface, when the candidate list returned + by font_list_entities is sorted by font_select_entity + (which calls font_sort_entities, which calls font_score). + If these attributes are not unset here, the candidate + font list returned by font_list_entities only contains + fonts that are exact matches for these weight, slant and + width attributes, which leads to suboptimal or wrong font + choices. (bug#5934) */ + font_unset_attribute (spec, FONT_WEIGHT_INDEX, QCwidth); + font_unset_attribute (spec, FONT_SLANT_INDEX, QCslant); + font_unset_attribute (spec, FONT_WIDTH_INDEX, QCwidth); /* Also allow unsetting other attributes for debugging - purposes. */ - MAYBE_UNSET_ATTRIBUTE (FAMILY); - MAYBE_UNSET_ATTRIBUTE (FOUNDRY); - MAYBE_UNSET_ATTRIBUTE (REGISTRY); - MAYBE_UNSET_ATTRIBUTE (ADSTYLE); - MAYBE_UNSET_ATTRIBUTE (SIZE); - MAYBE_UNSET_ATTRIBUTE (DPI); - MAYBE_UNSET_ATTRIBUTE (SPACING); - MAYBE_UNSET_ATTRIBUTE (AVGWIDTH); - MAYBE_UNSET_ATTRIBUTE (EXTRA); -#undef MAYBE_UNSET_ATTRIBUTE + purposes. But not FONT_EXTRA_INDEX; that is not safe to + touch in the Haiku font backend. */ + font_unset_attribute (spec, FONT_FAMILY_INDEX, QCfamily); + font_unset_attribute (spec, FONT_FOUNDRY_INDEX, QCfoundry); + font_unset_attribute (spec, FONT_REGISTRY_INDEX, QCregistry); + font_unset_attribute (spec, FONT_ADSTYLE_INDEX, QCadstyle); + font_unset_attribute (spec, FONT_SIZE_INDEX, QCsize); + font_unset_attribute (spec, FONT_DPI_INDEX, QCdpi); + font_unset_attribute (spec, FONT_SPACING_INDEX, QCspacing); + font_unset_attribute (spec, FONT_AVGWIDTH_INDEX, QCavgwidth); + attrs[LFACE_FONT_INDEX] = font_load_for_lface (f, attrs, spec); } if (FONT_OBJECT_P (attrs[LFACE_FONT_INDEX])) @@ -7394,27 +7406,22 @@ syms_of_xfaces (void) clear the face cache, see `clear-face-cache'. */); face_near_same_color_threshold = 30000; - DEFVAR_INT ("realize-gui-face-ignored-spec-attributes", - realize_gui_face_ignored_spec_attributes, - doc: /* Ignored font-spec attributes in realize_gui_face. - -The value is an integer number and represents a bit mask. -The attribute corresponding to each bit that is set is cleared in -realize_gui_face. The bits are: 1 = :foundry, 2 = :family, -3 = :adstyle, 4 = :registry, 5 = :weight, 6 = :slant, 7 = :width, -8 = :size, 9 = :dpi, 10 = :spacing, 11 = :avgwidth, 12 = extra -attributes (:name, :script, :lang and :otf). - -Bits 5 to 7 are set in the default value. When these bits are not -set, and when the font chosen for the default face has a weight, slant -or width that is not supported by other available fonts on the system, -such as 'medium', Emacs may select suboptimal fonts for other faces. - -There is no reason to change that value except for debugging purposes. */); - realize_gui_face_ignored_spec_attributes = - (1 << FONT_WEIGHT_INDEX) | - (1 << FONT_SLANT_INDEX) | - (1 << FONT_WIDTH_INDEX); + DEFVAR_LISP ("font-fallback-ignored-attributes", + Vfont_fallback_ignored_attributes, + doc: /* A list of face attributes to ignore. + +List of font-related face attributes to ignore when realizing a face. +This is a list of symbols representing face attributes that will be +ignored by Emacs when realizing a face, and an exact match couldn't be +found for its preferred font. For example: + + (:weight :slant :width) + +tells Emacs to ignore the `:weight', `:slant' and `:width' face +attributes when searching for a font and an exact match could not be +found for the font attributes specified in the face being realized. */); + Vfont_fallback_ignored_attributes + = list3 (QCwidth, QCslant, QCwidth); #ifdef HAVE_WINDOW_SYSTEM defsubr (&Sbitmap_spec_p); commit 7013b0179cbe5cce19e114d7673770d1425d3005 Author: Stefan Kangas Date: Sun Dec 11 02:15:56 2022 +0100 ; Auto-commit of loaddefs files. diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 938859c6916..5765d2d4feb 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -1943,6 +1943,85 @@ "bibtex" (fn)" t) (register-definition-prefixes "bibtex-style" '("bibtex-style-")) + +;;; Generated autoloads from use-package/bind-key.el + +(push (purecopy '(bind-key 2 4 1)) package--builtin-versions) +(autoload 'bind-key "bind-key" "\ +Bind KEY-NAME to COMMAND in KEYMAP (`global-map' if not passed). + +KEY-NAME may be a vector, in which case it is passed straight to +`define-key'. Or it may be a string to be interpreted as +spelled-out keystrokes, e.g., \"C-c C-z\". See the documentation +of `edmacro-mode' for details. + +COMMAND must be an interactive function or lambda form. + +KEYMAP, if present, should be a keymap variable or symbol. +For example: + + (bind-key \"M-h\" #\\='some-interactive-function my-mode-map) + + (bind-key \"M-h\" #\\='some-interactive-function \\='my-mode-map) + +If PREDICATE is non-nil, it is a form evaluated to determine when +a key should be bound. It must return non-nil in such cases. +Emacs can evaluate this form at any time that it does redisplay +or operates on menu data structures, so you should write it so it +can safely be called at any time. + +(fn KEY-NAME COMMAND &optional KEYMAP PREDICATE)" nil t) +(autoload 'unbind-key "bind-key" "\ +Unbind the given KEY-NAME, within the KEYMAP (if specified). +See `bind-key' for more details. + +(fn KEY-NAME &optional KEYMAP)" nil t) +(autoload 'bind-key* "bind-key" "\ +Similar to `bind-key', but overrides any mode-specific bindings. + +(fn KEY-NAME COMMAND &optional PREDICATE)" nil t) +(autoload 'bind-keys "bind-key" "\ +Bind multiple keys at once. + +Accepts keyword arguments: +:map MAP - a keymap into which the keybindings should be + added +:prefix KEY - prefix key for these bindings +:prefix-map MAP - name of the prefix map that should be created + for these bindings +:prefix-docstring STR - docstring for the prefix-map variable +:menu-name NAME - optional menu string for prefix map +:repeat-docstring STR - docstring for the repeat-map variable +:repeat-map MAP - name of the repeat map that should be created + for these bindings. If specified, the + `repeat-map' property of each command bound + (within the scope of the `:repeat-map' keyword) + is set to this map. +:exit BINDINGS - Within the scope of `:repeat-map' will bind the + key in the repeat map, but will not set the + `repeat-map' property of the bound command. +:continue BINDINGS - Within the scope of `:repeat-map' forces the + same behavior as if no special keyword had + been used (that is, the command is bound, and + it's `repeat-map' property set) +:filter FORM - optional form to determine when bindings apply + +The rest of the arguments are conses of keybinding string and a +function symbol (unquoted). + +(fn &rest ARGS)" nil t) +(autoload 'bind-keys* "bind-key" "\ +Bind multiple keys at once, in `override-global-map'. +Accepts the same keyword arguments as `bind-keys' (which see). + +This binds keys in such a way that bindings are not overridden by +other modes. See `override-global-mode'. + +(fn &rest ARGS)" nil t) +(autoload 'describe-personal-keybindings "bind-key" "\ +Display all the personal keybindings defined by `bind-key'." t) +(register-definition-prefixes "bind-key" '("bind-key" "compare-keybindings" "get-binding-description" "override-global-m" "personal-keybindings")) + ;;; Generated autoloads from emacs-lisp/bindat.el @@ -2841,9 +2920,11 @@ "semantic/bovine/c" ;;; Generated autoloads from progmodes/c-ts-mode.el -(autoload 'c-ts-mode--base-mode "c-ts-mode" "\ +(autoload 'c-ts-base-mode "c-ts-mode" "\ Major mode for editing C, powered by tree-sitter. +\\{c-ts-mode-map} + (fn)" t) (autoload 'c-ts-mode "c-ts-mode" "\ Major mode for editing C, powered by tree-sitter. @@ -2853,7 +2934,7 @@ "semantic/bovine/c" Major mode for editing C++, powered by tree-sitter. (fn)" t) -(register-definition-prefixes "c-ts-mode" '("c-ts-")) +(register-definition-prefixes "c-ts-mode" '("c-ts-mode-")) ;;; Generated autoloads from calendar/cal-bahai.el @@ -7896,6 +7977,16 @@ "semantic/doc" (fn BMK)") (register-definition-prefixes "doc-view" '("doc-view-")) + +;;; Generated autoloads from progmodes/dockerfile-ts-mode.el + +(add-to-list 'auto-mode-alist `(,(rx (| (: "Dockerfile" (32 "." (* nonl))) (: "." (any "dD") "ockerfile")) eol) . dockerfile-ts-mode)) +(autoload 'dockerfile-ts-mode "dockerfile-ts-mode" "\ +Major mode for editing Dockerfiles, powered by tree-sitter. + +(fn)" t) +(register-definition-prefixes "dockerfile-ts-mode" '("dockerfile-ts-mode--")) + ;;; Generated autoloads from play/doctor.el @@ -8096,7 +8187,6 @@ 'define-global-minor-mode `nodigits' to suppress digits as prefix arguments. (fn BS &optional NAME M ARGS)") -(make-obsolete 'easy-mmode-define-keymap 'define-keymap "29.1") (autoload 'easy-mmode-defmap "easy-mmode" "\ Define a constant M whose value is the result of `easy-mmode-define-keymap'. The M, BS, and ARGS arguments are as per that function. DOC is @@ -8107,7 +8197,6 @@ 'define-global-minor-mode (fn M BS DOC &rest ARGS)" nil t) (function-put 'easy-mmode-defmap 'doc-string-elt 3) (function-put 'easy-mmode-defmap 'lisp-indent-function 1) -(make-obsolete 'easy-mmode-defmap 'defvar-keymap "29.1") (autoload 'easy-mmode-defsyntax "easy-mmode" "\ Define variable ST as a syntax-table. CSS contains a list of syntax specifications of the form (CHAR . SYNTAX). @@ -11276,6 +11365,12 @@ "expand" (register-definition-prefixes "srecode/expandproto" '("srecode-")) + +;;; Generated autoloads from external-completion.el + +(push (purecopy '(external-completion 0 1)) package--builtin-versions) +(register-definition-prefixes "external-completion" '("external-completion-")) + ;;; Generated autoloads from cedet/srecode/extract.el @@ -23377,11 +23472,11 @@ package-vc-selected-packages (autoload 'package-vc-checkout "package-vc" "\ Clone the sources for PKG-DESC into DIRECTORY and visit that directory. Unlike `package-vc-install', this does not yet set up the package -for use with Emacs; use `package-vc-link-directory' for setting -the package up after this function finishes. -Optional argument REV means to clone a specific version of the -package; it defaults to the last version available from the -package's repository. If REV has the special value +for use with Emacs; use `package-vc-install-from-checkout' for +setting the package up after this function finishes. Optional +argument REV means to clone a specific version of the package; it +defaults to the last version available from the package's +repository. If REV has the special value `:last-release' (interactively, the prefix argument), that stands for the last released version of the package. @@ -24970,7 +25065,7 @@ "ede/proj-shared" ;;; Generated autoloads from progmodes/project.el -(push (purecopy '(project 0 9 0)) package--builtin-versions) +(push (purecopy '(project 0 9 2)) package--builtin-versions) (autoload 'project-current "project" "\ Return the project instance in DIRECTORY, defaulting to `default-directory'. @@ -32875,10 +32970,18 @@ "type-break" ;;; Generated autoloads from progmodes/typescript-ts-mode.el (add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-ts-mode)) -(add-to-list 'auto-mode-alist '("\\.tsx\\'" . typescript-ts-mode)) +(add-to-list 'auto-mode-alist '("\\.tsx\\'" . tsx-ts-mode)) +(autoload 'typescript-ts-base-mode "typescript-ts-mode" "\ +Major mode for editing TypeScript. + +(fn)" t) (autoload 'typescript-ts-mode "typescript-ts-mode" "\ Major mode for editing TypeScript. +(fn)" t) +(autoload 'tsx-ts-mode "typescript-ts-mode" "\ +Major mode for editing TypeScript. + (fn)" t) (register-definition-prefixes "typescript-ts-mode" '("typescript-ts-mode-")) @@ -33605,6 +33708,195 @@ "url-util" (register-definition-prefixes "url-vars" '("url-")) + +;;; Generated autoloads from use-package/use-package.el + +(push (purecopy '(use-package 2 4 4)) package--builtin-versions) + + +;;; Generated autoloads from use-package/use-package-bind-key.el + +(autoload 'use-package-autoload-keymap "use-package-bind-key" "\ +Load PACKAGE and bind key sequence invoking this function to KEYMAP-SYMBOL. +Then simulate pressing the same key sequence a again, so that the +next key pressed is routed to the newly loaded keymap. + +This function supports use-package's :bind-keymap keyword. It +works by binding the given key sequence to an invocation of this +function for a particular keymap. The keymap is expected to be +defined by the package. In this way, loading the package is +deferred until the prefix key sequence is pressed. + +(fn KEYMAP-SYMBOL PACKAGE OVERRIDE)") +(autoload 'use-package-normalize-binder "use-package-bind-key" "\ + + +(fn NAME KEYWORD ARGS)") +(defalias 'use-package-normalize/:bind 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) +(defalias 'use-package-autoloads/:bind 'use-package-autoloads-mode) +(defalias 'use-package-autoloads/:bind* 'use-package-autoloads-mode) +(autoload 'use-package-handler/:bind "use-package-bind-key" "\ + + +(fn NAME KEYWORD ARGS REST STATE &optional BIND-MACRO)") +(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) +(autoload 'use-package-handler/:bind-keymap "use-package-bind-key" "\ + + +(fn NAME KEYWORD ARGS REST STATE &optional OVERRIDE)") +(autoload 'use-package-handler/:bind-keymap* "use-package-bind-key" "\ + + +(fn NAME KEYWORD ARG REST STATE)") +(register-definition-prefixes "use-package-bind-key" '("use-package-handler/:bind*")) + + +;;; Generated autoloads from use-package/use-package-core.el + +(autoload 'use-package "use-package-core" "\ +Declare an Emacs package by specifying a group of configuration options. + +For the full documentation, see Info node `(use-package) top'. +Usage: + + (use-package package-name + [:keyword [option]]...) + +:init Code to run before PACKAGE-NAME has been loaded. +:config Code to run after PACKAGE-NAME has been loaded. Note that + if loading is deferred for any reason, this code does not + execute until the lazy load has occurred. +:preface Code to be run before everything except `:disabled'; this + can be used to define functions for use in `:if', or that + should be seen by the byte-compiler. + +:mode Form to be added to `auto-mode-alist'. +:magic Form to be added to `magic-mode-alist'. +:magic-fallback Form to be added to `magic-fallback-mode-alist'. +:interpreter Form to be added to `interpreter-mode-alist'. + +:commands Define autoloads for commands that will be defined by the + package. This is useful if the package is being lazily + loaded, and you wish to conditionally call functions in your + `:init' block that are defined in the package. +:autoload Similar to :commands, but it for no-interactive one. +:hook Specify hook(s) to attach this package to. + +:bind Bind keys, and define autoloads for the bound commands. +:bind* Bind keys, and define autoloads for the bound commands, + *overriding all minor mode bindings*. +:bind-keymap Bind a key prefix to an auto-loaded keymap defined in the + package. This is like `:bind', but for keymaps. +:bind-keymap* Like `:bind-keymap', but overrides all minor mode bindings + +:defer Defer loading of a package -- this is implied when using + `:commands', `:bind', `:bind*', `:mode', `:magic', `:hook', + `:magic-fallback', or `:interpreter'. This can be an integer, + to force loading after N seconds of idle time, if the package + has not already been loaded. +:demand Prevent the automatic deferred loading introduced by constructs + such as `:bind' (see `:defer' for the complete list). + +:after Delay the effect of the use-package declaration + until after the named libraries have loaded. + Before they have been loaded, no other keyword + has any effect at all, and once they have been + loaded it is as if `:after' was not specified. + +:if EXPR Initialize and load only if EXPR evaluates to a non-nil value. +:disabled The package is ignored completely if this keyword is present. +:defines Declare certain variables to silence the byte-compiler. +:functions Declare certain functions to silence the byte-compiler. +:load-path Add to the `load-path' before attempting to load the package. +:diminish Support for diminish.el (if installed). +:delight Support for delight.el (if installed). +:custom Call `Custom-set' or `set-default' with each variable + definition without modifying the Emacs `custom-file'. + (compare with `custom-set-variables'). +:custom-face Call `custom-set-faces' with each face definition. +:ensure Loads the package using package.el if necessary. +:pin Pin the package to an archive. + +(fn NAME &rest ARGS)" nil t) +(function-put 'use-package 'lisp-indent-function 'defun) +(register-definition-prefixes "use-package-core" '("use-package-")) + + +;;; Generated autoloads from use-package/use-package-delight.el + +(autoload 'use-package-normalize/:delight "use-package-delight" "\ +Normalize arguments to delight. + +(fn NAME KEYWORD ARGS)") +(autoload 'use-package-handler/:delight "use-package-delight" "\ + + +(fn NAME KEYWORD ARGS REST STATE)") +(register-definition-prefixes "use-package-delight" '("use-package-normalize-delight")) + + +;;; Generated autoloads from use-package/use-package-diminish.el + +(autoload 'use-package-normalize/:diminish "use-package-diminish" "\ + + +(fn NAME KEYWORD ARGS)") +(autoload 'use-package-handler/:diminish "use-package-diminish" "\ + + +(fn NAME KEYWORD ARG REST STATE)") +(register-definition-prefixes "use-package-diminish" '("use-package-normalize-diminish")) + + +;;; Generated autoloads from use-package/use-package-ensure.el + +(autoload 'use-package-normalize/:ensure "use-package-ensure" "\ + + +(fn NAME KEYWORD ARGS)") +(autoload 'use-package-handler/:ensure "use-package-ensure" "\ + + +(fn NAME KEYWORD ENSURE REST STATE)") +(register-definition-prefixes "use-package-ensure" '("use-package-")) + + +;;; Generated autoloads from use-package/use-package-ensure-system-package.el + +(push (purecopy '(use-package-ensure-system-package 0 2)) package--builtin-versions) +(autoload 'use-package-normalize/:ensure-system-package "use-package-ensure-system-package" "\ +Turn ARGS into a list of conses of the form (PACKAGE-NAME . INSTALL-COMMAND). + +(fn NAME-SYMBOL KEYWORD ARGS)") +(autoload 'use-package-handler/:ensure-system-package "use-package-ensure-system-package" "\ +Execute the handler for `:ensure-system-package' keyword in `use-package'. + +(fn NAME KEYWORD ARG REST STATE)") +(register-definition-prefixes "use-package-ensure-system-package" '("use-package-ensure-system-package-")) + + +;;; Generated autoloads from use-package/use-package-jump.el + +(autoload 'use-package-jump-to-package-form "use-package-jump" "\ +Attempt to find and jump to the `use-package' form that loaded PACKAGE. +This will only find the form if that form actually required +PACKAGE. If PACKAGE was previously required then this function +will jump to the file that originally required PACKAGE instead. + +(fn PACKAGE)" t) +(register-definition-prefixes "use-package-jump" '("use-package-find-require")) + + +;;; Generated autoloads from use-package/use-package-lint.el + +(autoload 'use-package-lint "use-package-lint" "\ +Check for errors in `use-package' declarations. +For example, if the module's `:if' condition is met, but even +with the specified `:load-path' the module cannot be found." t) +(register-definition-prefixes "use-package-lint" '("use-package-lint-declaration")) + ;;; Generated autoloads from userlock.el commit 79659416f95ac986812a8b40c1260907b95aaa0b Author: Gregory Heytings Date: Sat Dec 10 23:31:30 2022 +0000 ; * admin/git-bisect-start: Fix commit hash diff --git a/admin/git-bisect-start b/admin/git-bisect-start index 7a715b4261d..dcb291a3ace 100755 --- a/admin/git-bisect-start +++ b/admin/git-bisect-start @@ -41,4 +41,4 @@ git bisect good 806734c1b1f433de43d59d9a5e3a1e89d64315f6 # Prune commits 31ea42e15e..a6cbfdd8f1 introduced by 4a1e9d61b5 # (use-package merge on Nov 30 2022) -git bisect good 4a1e9d61b57c36255752437a2668e037e79fe870 +git bisect good 58cc931e92ece70c3e64131ee12a799d65409100 commit a9037aa8e81952f30b0a6ad92eefead0c4d231c4 Author: Stefan Kangas Date: Sun Dec 11 00:30:28 2022 +0100 ; Fix use-package-ensure-system-package macOS footnote * doc/misc/use-package.texi (use-package-ensure-system-package): Fix macOS footnote. diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 4fd2882e109..6447f96c63f 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -1918,11 +1918,12 @@ use-package-ensure-system-package @findex :ensure-system-package The @code{:ensure-system-package} keyword allows you to ensure certain executables are available on your system alongside your package -declarations.@footnote{On macOS, you will want to make sure -@code{exec-path} is cognisant of all binary package names that you -would like to ensure are installed. The +declarations.@footnote{On macOS, your @code{exec-path} might be +different if you are starting Emacs as a GUI app instead of from a +shell. If you find that Emacs on macOS cannot find some executables +that you know are already installed, you could try the @uref{https://github.com/purcell/exec-path-from-shell,@samp{exec-path-from-shell}} -package is often a good way to do this.} +package.} To use this extension, add this immediately after loading @code{use-package}: commit 7d787564c08351b275e8f729e8e9f1ec2ae8fe04 Author: Gregory Heytings Date: Sat Dec 10 23:04:10 2022 +0000 Actually improve detection of long lines * src/xdisp.c (redisplay_window): Update condition. * src/xdisp.c (mark_window_display_accurate_1): * src/pdumper.c (dump_buffer): * src/buffer.h (BUF_CHARS_UNCHANGED_MODIFIED): (struct buffer_text): * src/buffer.c (Fget_buffer_create): Revert 1c837c42c2, which was misguided. diff --git a/src/buffer.c b/src/buffer.c index 71be7ed9e13..69f27c9f476 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -604,7 +604,6 @@ DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 2, 0, set_buffer_intervals (b, NULL); BUF_UNCHANGED_MODIFIED (b) = 1; BUF_OVERLAY_UNCHANGED_MODIFIED (b) = 1; - BUF_CHARS_UNCHANGED_MODIFIED (b) = 1; BUF_END_UNCHANGED (b) = 0; BUF_BEG_UNCHANGED (b) = 0; *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */ diff --git a/src/buffer.h b/src/buffer.h index dded0cd98c1..80b3fd81e09 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -149,18 +149,12 @@ #define BUF_OVERLAY_UNCHANGED_MODIFIED(buf) \ #define BUF_BEG_UNCHANGED(buf) ((buf)->text->beg_unchanged) #define BUF_END_UNCHANGED(buf) ((buf)->text->end_unchanged) -#define BUF_CHARS_UNCHANGED_MODIFIED(buf) \ - ((buf)->text->chars_unchanged_modified) - #define UNCHANGED_MODIFIED \ BUF_UNCHANGED_MODIFIED (current_buffer) #define OVERLAY_UNCHANGED_MODIFIED \ BUF_OVERLAY_UNCHANGED_MODIFIED (current_buffer) #define BEG_UNCHANGED BUF_BEG_UNCHANGED (current_buffer) #define END_UNCHANGED BUF_END_UNCHANGED (current_buffer) - -#define CHARS_UNCHANGED_MODIFIED \ - BUF_CHARS_UNCHANGED_MODIFIED (current_buffer) /* Functions to set PT in the current buffer, or another buffer. */ @@ -274,11 +268,6 @@ #define FETCH_BYTE(n) *(BYTE_POS_ADDR ((n))) end_unchanged contain no useful information. */ modiff_count overlay_unchanged_modified; - /* CHARS_MODIFF as of last redisplay that finished. It's used - when we only care about changes in actual buffer text, not in - any other kind of changes, like properties etc. */ - modiff_count chars_unchanged_modified; - /* Properties of this buffer's text. */ INTERVAL intervals; diff --git a/src/pdumper.c b/src/pdumper.c index fedcd3e4044..263343f60be 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2811,7 +2811,6 @@ dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer) DUMP_FIELD_COPY (out, buffer, own_text.end_unchanged); DUMP_FIELD_COPY (out, buffer, own_text.unchanged_modified); DUMP_FIELD_COPY (out, buffer, own_text.overlay_unchanged_modified); - DUMP_FIELD_COPY (out, buffer, own_text.chars_unchanged_modified); if (buffer->own_text.intervals) dump_field_fixup_later (ctx, out, buffer, &buffer->own_text.intervals); dump_field_lv_rawptr (ctx, out, buffer, &buffer->own_text.markers, diff --git a/src/xdisp.c b/src/xdisp.c index 255851b9213..d14cd468191 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -17264,7 +17264,6 @@ mark_window_display_accurate_1 (struct window *w, bool accurate_p) BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b); BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b); - BUF_CHARS_UNCHANGED_MODIFIED (b) = BUF_CHARS_MODIFF (b); BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b); BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b); @@ -19535,7 +19534,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) /* Check whether the buffer to be displayed contains long lines. */ if (!NILP (Vlong_line_threshold) && !current_buffer->long_line_optimizations_p - && (CHARS_MODIFF - CHARS_UNCHANGED_MODIFIED > 8 + && (CHARS_MODIFF - UNCHANGED_MODIFIED > 8 || current_buffer->clip_changed)) { ptrdiff_t cur, next, found, max = 0, threshold; commit 118465f6fed8bf490cc69634b96d1ffa721abb7b Author: Stefan Kangas Date: Sat Dec 10 23:45:25 2022 +0100 ; Improve checkdoc.el commentary section * lisp/emacs-lisp/checkdoc.el: Improve wording of Commentary. (checkdoc): Link commentary from defgroup. diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index 3bddb93b64a..26d87a3622d 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -22,28 +22,35 @@ ;; along with GNU Emacs. If not, see . ;;; Commentary: -;; + ;; The Emacs Lisp manual has a nice chapter on how to write ;; documentation strings. Many stylistic suggestions are fairly ;; deterministic and easy to check for syntactically, but also easy ;; to forget. The main checkdoc engine will perform the stylistic ;; checks needed to make sure these styles are remembered. ;; -;; There are three ways to use checkdoc: -;; 1) Use `flymake-mode'. +;; There are four ways to use checkdoc: +;; +;; 1) Use `flymake-mode'. Type `M-x flymake-mode' in any Emacs Lisp +;; buffer; the checkdoc back-end is enabled by default. +;; ;; 2) Periodically use `checkdoc' or `checkdoc-current-buffer'. -;; `checkdoc' is a more interactive version of -;; `checkdoc-current-buffer' +;; The `checkdoc' command is a more interactive version of +;; `checkdoc-current-buffer'. +;; ;; 3) Use `checkdoc-minor-mode' to automatically check your ;; documentation whenever you evaluate Lisp code with C-M-x ;; or [menu-bar emacs-lisp eval-buffer]. Additional key-bindings ;; are also provided under C-c ? KEY ;; (add-hook 'emacs-lisp-mode-hook 'checkdoc-minor-mode) ;; +;; 4) Use `checkdoc-ispell' to spellcheck docstrings interactively. +;; ;; Using `checkdoc': ;; -;; The commands `checkdoc' and `checkdoc-ispell' are the top-level -;; entry points to all of the different checks that are available. It +;; Most users will probably use checkdoc through `flymake'. The +;; commands `checkdoc' and `checkdoc-ispell' are the top-level entry +;; points to all of the different checks that are available. It ;; breaks examination of your Lisp file into four sections (comments, ;; documentation, messages, and spacing) and indicates its current ;; state in a status buffer. @@ -66,7 +73,7 @@ ;; interface offers several options, including the ability to skip to ;; the next error, or back up to previous errors. Auto-fixing is ;; turned off at this stage, but you can use the `f' or `F' key to fix -;; a given error (if the fix is available.) +;; a given error (if the fix is available). ;; ;; Auto-fixing: ;; @@ -99,6 +106,7 @@ ;; install into Ispell on the fly, but only if Ispell is not already ;; running. Use `ispell-kill-ispell' to make checkdoc restart it with ;; these words enabled. +;; See also the `flyspell-prog-mode' minor mode. ;; ;; Checking parameters: ;; @@ -176,6 +184,7 @@ checkdoc "Support for doc string checking in Emacs Lisp." :prefix "checkdoc" :group 'lisp + :link '(emacs-commentary-link "checkdoc.el") :version "20.3") (defcustom checkdoc-minor-mode-string " CDoc" commit 30e3cb213517461c7dbfe7b4875c92b2606fa2d5 Author: Gregory Heytings Date: Sat Dec 10 22:13:58 2022 +0000 Unset the weight/slant/width in the spec when realizing a font Between commits bf0d3f76dc (2014) and 6b1ed2f2c9 (2022), realize_gui_face called font_load_for_lface with an empty or partly emptied font spec, i.e. it ignored a part of its attrs argument. The rationale given in bug#17973, which led to bf0d3f76dc, is not clear. However, 6b1ed2f2c9, which passes the full font spec to font_load_for_lface and font_find_for_lface, leads to suboptimal font choices, for example when the font chosen for the default face has a weight, slant or width that is not supported by other available fonts on the system, such as 'medium' or 'heavy'. If these attributes are not unset here, the call to font_list_entities in font_find_for_lface arbitrarily limits the candidate font list to those that are perfect matches for these attributes, which means that the scoring mechanism is bypassed. Note that the size attribute in spec is also unset, in font_find_for_lface. Also allow unsetting the other attributes, for debugging purposes. * src/xfaces.c (realize_gui_face): Unset the weight, slant and width of the font spec. Fixes bug#57555 and bug#59347. (syms_of_xfaces): New variable 'realize-gui-face-ignored-spec-attributes'. diff --git a/src/xfaces.c b/src/xfaces.c index df078227c8a..643f4365896 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -6071,8 +6071,42 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] emacs_abort (); } if (! FONT_OBJECT_P (attrs[LFACE_FONT_INDEX])) - attrs[LFACE_FONT_INDEX] - = font_load_for_lface (f, attrs, attrs[LFACE_FONT_INDEX]); + { + Lisp_Object spec = copy_font_spec (attrs[LFACE_FONT_INDEX]); +#define MAYBE_UNSET_ATTRIBUTE(ATTR) \ + if (realize_gui_face_ignored_spec_attributes \ + & (1 << FONT_##ATTR##_INDEX)) \ + ASET (spec, FONT_##ATTR##_INDEX, Qnil); + /* The default value of + realize_gui_face_ignored_spec_attributes unsets the + weight, slant and width in spec. The best possible + values for these attributes is determined in + font_find_for_lface, called by font_load_for_lface, when + the candidate list returned by font_list_entities is + sorted by font_select_entity (which calls + font_sort_entities, which calls font_score). If these + attributes are not unset here, the candidate font list + returned by font_list_entities only contains fonts that + are exact matches for these weight, slant and width + attributes, which leads to suboptimal or wrong font + choices. See bug#59347. */ + MAYBE_UNSET_ATTRIBUTE (WEIGHT); + MAYBE_UNSET_ATTRIBUTE (SLANT); + MAYBE_UNSET_ATTRIBUTE (WIDTH); + /* Also allow unsetting other attributes for debugging + purposes. */ + MAYBE_UNSET_ATTRIBUTE (FAMILY); + MAYBE_UNSET_ATTRIBUTE (FOUNDRY); + MAYBE_UNSET_ATTRIBUTE (REGISTRY); + MAYBE_UNSET_ATTRIBUTE (ADSTYLE); + MAYBE_UNSET_ATTRIBUTE (SIZE); + MAYBE_UNSET_ATTRIBUTE (DPI); + MAYBE_UNSET_ATTRIBUTE (SPACING); + MAYBE_UNSET_ATTRIBUTE (AVGWIDTH); + MAYBE_UNSET_ATTRIBUTE (EXTRA); +#undef MAYBE_UNSET_ATTRIBUTE + attrs[LFACE_FONT_INDEX] = font_load_for_lface (f, attrs, spec); + } if (FONT_OBJECT_P (attrs[LFACE_FONT_INDEX])) { face->font = XFONT_OBJECT (attrs[LFACE_FONT_INDEX]); @@ -7360,6 +7394,28 @@ syms_of_xfaces (void) clear the face cache, see `clear-face-cache'. */); face_near_same_color_threshold = 30000; + DEFVAR_INT ("realize-gui-face-ignored-spec-attributes", + realize_gui_face_ignored_spec_attributes, + doc: /* Ignored font-spec attributes in realize_gui_face. + +The value is an integer number and represents a bit mask. +The attribute corresponding to each bit that is set is cleared in +realize_gui_face. The bits are: 1 = :foundry, 2 = :family, +3 = :adstyle, 4 = :registry, 5 = :weight, 6 = :slant, 7 = :width, +8 = :size, 9 = :dpi, 10 = :spacing, 11 = :avgwidth, 12 = extra +attributes (:name, :script, :lang and :otf). + +Bits 5 to 7 are set in the default value. When these bits are not +set, and when the font chosen for the default face has a weight, slant +or width that is not supported by other available fonts on the system, +such as 'medium', Emacs may select suboptimal fonts for other faces. + +There is no reason to change that value except for debugging purposes. */); + realize_gui_face_ignored_spec_attributes = + (1 << FONT_WEIGHT_INDEX) | + (1 << FONT_SLANT_INDEX) | + (1 << FONT_WIDTH_INDEX); + #ifdef HAVE_WINDOW_SYSTEM defsubr (&Sbitmap_spec_p); defsubr (&Sx_list_fonts); commit 01154166057e7cf289318a8cfa4d43716f26ca20 Author: Kyle Meyer Date: Sat Dec 10 16:59:46 2022 -0500 Update to Org 9.6-31-g954a95 diff --git a/doc/misc/org.org b/doc/misc/org.org index 43d85099cff..0b926e3ceed 100644 --- a/doc/misc/org.org +++ b/doc/misc/org.org @@ -1401,7 +1401,7 @@ you, configure the option ~org-table-auto-blank-field~. - {{{kbd(M-x org-table-blank-field)}}} :: #+findex: org-table-blank-field - Blank the field at point. + Blank the current table field or active region. - {{{kbd(S-TAB)}}} (~org-table-previous-field~) :: diff --git a/lisp/org/ob-comint.el b/lisp/org/ob-comint.el index e8d83670767..064ba94464f 100644 --- a/lisp/org/ob-comint.el +++ b/lisp/org/ob-comint.el @@ -117,6 +117,14 @@ org-babel-comint-with-output (goto-char (process-mark (get-buffer-process (current-buffer)))) (insert dangling-text) + ;; Replace partially supplied input lines. + ;; This is needed when output filter spits partial lines that + ;; do not include a full prompt at a time. + (setq string-buffer + (replace-regexp-in-string + comint-prompt-regexp + ,org-babel-comint-prompt-separator + string-buffer)) ;; remove echo'd FULL-BODY from input (when (and ,remove-echo ,full-body (string-match diff --git a/lisp/org/ob-core.el b/lisp/org/ob-core.el index 5b78ee946ff..f69538f78c9 100644 --- a/lisp/org/ob-core.el +++ b/lisp/org/ob-core.el @@ -2709,7 +2709,9 @@ org-babel-result-to-file ((and 'attachment (guard in-attach-dir)) "attachment") (_ "file")) (if (and request-attachment in-attach-dir) - (file-relative-name result-file-name) + (file-relative-name + result-file-name + (file-name-as-directory attach-dir)) (if (and default-directory base-file-name same-directory?) (if (eq org-link-file-path-type 'adaptive) diff --git a/lisp/org/ol.el b/lisp/org/ol.el index cd52e9cf4df..3ae8f887554 100644 --- a/lisp/org/ol.el +++ b/lisp/org/ol.el @@ -1488,9 +1488,9 @@ org-previous-link (defun org-link-descriptive-ensure () "Toggle the literal or descriptive display of links in current buffer if needed." - (if org-link-descriptive - (org-fold-core-set-folding-spec-property (car org-link--link-folding-spec) :visible nil) - (org-fold-core-set-folding-spec-property (car org-link--link-folding-spec) :visible t))) + (org-fold-core-set-folding-spec-property + (car org-link--link-folding-spec) + :visible (not org-link-descriptive))) ;;;###autoload (defun org-toggle-link-display () diff --git a/lisp/org/org-clock.el b/lisp/org/org-clock.el index f28805d5e6b..02cddddb304 100644 --- a/lisp/org/org-clock.el +++ b/lisp/org/org-clock.el @@ -3049,53 +3049,58 @@ org-clock-update-time-maybe "If this is a CLOCK line, update it and return t. Otherwise, return nil." (interactive) - (save-excursion - (beginning-of-line 1) - (skip-chars-forward " \t") - (when (looking-at org-clock-string) - (let ((re (concat "[ \t]*" org-clock-string - " *[[<]\\([^]>]+\\)[]>]\\(-+[[<]\\([^]>]+\\)[]>]" - "\\([ \t]*=>.*\\)?\\)?")) - ts te h m s neg) - (cond - ((not (looking-at re)) - nil) - ((not (match-end 2)) - (when (and (equal (marker-buffer org-clock-marker) (current-buffer)) - (> org-clock-marker (point)) - (<= org-clock-marker (line-end-position))) - ;; The clock is running here - (setq org-clock-start-time - (org-time-string-to-time (match-string 1))) - (org-clock-update-mode-line))) - (t - ;; Prevent recursive call from `org-timestamp-change'. - (cl-letf (((symbol-function 'org-clock-update-time-maybe) #'ignore)) - ;; Update timestamps. - (save-excursion - (goto-char (match-beginning 1)) ; opening timestamp - (save-match-data (org-timestamp-change 0 'day))) + (let ((origin (point))) ;; `save-excursion' may not work when deleting. + (save-excursion + (beginning-of-line 1) + (skip-chars-forward " \t") + (when (looking-at org-clock-string) + (let ((re (concat "[ \t]*" org-clock-string + " *[[<]\\([^]>]+\\)[]>]\\(-+[[<]\\([^]>]+\\)[]>]" + "\\([ \t]*=>.*\\)?\\)?")) + ts te h m s neg) + (cond + ((not (looking-at re)) + nil) + ((not (match-end 2)) + (when (and (equal (marker-buffer org-clock-marker) (current-buffer)) + (> org-clock-marker (point)) + (<= org-clock-marker (line-end-position))) + ;; The clock is running here + (setq org-clock-start-time + (org-time-string-to-time (match-string 1))) + (org-clock-update-mode-line))) + (t + ;; Prevent recursive call from `org-timestamp-change'. + (cl-letf (((symbol-function 'org-clock-update-time-maybe) #'ignore)) + ;; Update timestamps. + (save-excursion + (goto-char (match-beginning 1)) ; opening timestamp + (save-match-data (org-timestamp-change 0 'day))) + ;; Refresh match data. + (looking-at re) + (save-excursion + (goto-char (match-beginning 3)) ; closing timestamp + (save-match-data (org-timestamp-change 0 'day)))) ;; Refresh match data. (looking-at re) - (save-excursion - (goto-char (match-beginning 3)) ; closing timestamp - (save-match-data (org-timestamp-change 0 'day)))) - ;; Refresh match data. - (looking-at re) - (and (match-end 4) (delete-region (match-beginning 4) (match-end 4))) - (end-of-line 1) - (setq ts (match-string 1) - te (match-string 3)) - (setq s (- (org-time-string-to-seconds te) - (org-time-string-to-seconds ts)) - neg (< s 0) - s (abs s) - h (floor (/ s 3600)) - s (- s (* 3600 h)) - m (floor (/ s 60)) - s (- s (* 60 s))) - (insert " => " (format (if neg "-%d:%02d" "%2d:%02d") h m)) - t)))))) + (and (match-end 4) (delete-region (match-beginning 4) (match-end 4))) + (end-of-line 1) + (setq ts (match-string 1) + te (match-string 3)) + (setq s (- (org-time-string-to-seconds te) + (org-time-string-to-seconds ts)) + neg (< s 0) + s (abs s) + h (floor (/ s 3600)) + s (- s (* 3600 h)) + m (floor (/ s 60)) + s (- s (* 60 s))) + (insert " => " (format (if neg "-%d:%02d" "%2d:%02d") h m)) + t))))) + ;; Move back to initial position, but never beyond updated + ;; clock. + (unless (< (point) origin) + (goto-char origin)))) (defun org-clock-save () "Persist various clock-related data to disk. diff --git a/lisp/org/org-element.el b/lisp/org/org-element.el index 48ede9c5289..1f36775a7b5 100644 --- a/lisp/org/org-element.el +++ b/lisp/org/org-element.el @@ -5717,7 +5717,11 @@ org-element--cache-active-p ;; `combine-change-calls' because the buffer is potentially ;; changed without notice (the change will be registered ;; after exiting the `combine-change-calls' body though). - (memq #'org-element--cache-after-change after-change-functions)))))) + (catch :inhibited + (org-fold-core-cycle-over-indirect-buffers + (unless (memq #'org-element--cache-after-change after-change-functions) + (throw :inhibited nil))) + t)))))) ;; FIXME: Remove after we establish that hashing is effective. (defun org-element-cache-hash-show-statistics () diff --git a/lisp/org/org-fold-core.el b/lisp/org/org-fold-core.el index be600f8a0cc..ffa689d4fa1 100644 --- a/lisp/org/org-fold-core.el +++ b/lisp/org/org-fold-core.el @@ -497,7 +497,7 @@ org-fold-core-cycle-over-indirect-buffers (declare (debug (form body)) (indent 0)) `(let (buffers dead-properties) (if (and (not (buffer-base-buffer)) - (not (eq (current-buffer) (car org-fold-core--indirect-buffers)))) + (not (memq (current-buffer) org-fold-core--indirect-buffers))) ;; We are in base buffer with `org-fold-core--indirect-buffers' value from ;; different buffer. This can happen, for example, when ;; org-capture copies local variables into *Capture* buffer. @@ -930,6 +930,8 @@ org-fold-core-get-regions If FROM is non-nil and TO is nil, search the folded regions at FROM. +When both FROM and TO are nil, search folded regions in the whole buffer. + When SPECS is non-nil it should be a list of folding specs or a symbol. Only return the matching fold types. @@ -946,6 +948,9 @@ org-fold-core-get-regions (unless (listp specs) (setq specs (list specs))) (let (regions region mk-region) (org-with-wide-buffer + (when (and (not from) (not to)) + (setq from (point-min) + to (point-max))) (when (and from (not to)) (setq to (point-max))) (when (and from (< from (point-min))) (setq from (point-min))) (when (and to (> to (point-max))) (setq to (point-max))) @@ -1058,7 +1063,7 @@ org-fold-core-save-visibility because otherwise all these markers will point to nowhere." (declare (debug (form body)) (indent 1)) (org-with-gensyms (regions) - `(let* ((,regions ,(org-fold-core-get-regions :with-markers use-markers))) + `(let* ((,regions (org-fold-core-get-regions :with-markers ,use-markers))) (unwind-protect (progn ,@body) (org-fold-core-regions ,regions :override t :clean-markers t))))) diff --git a/lisp/org/org-footnote.el b/lisp/org/org-footnote.el index aedd413351c..ac78360aeff 100644 --- a/lisp/org/org-footnote.el +++ b/lisp/org/org-footnote.el @@ -851,9 +851,12 @@ org-footnote-sort (format "[fn:%s] DEFINITION NOT FOUND." label)) "\n")))) ;; Insert un-referenced footnote definitions at the end. - (pcase-dolist (`(,label . ,definition) definitions) - (unless (member label inserted) - (insert "\n" definition "\n"))))))))) + ;; Combine all insertions into one to create a single cache + ;; update call. + (combine-change-calls (point) (point) + (pcase-dolist (`(,label . ,definition) definitions) + (unless (member label inserted) + (insert "\n" definition "\n")))))))))) (defun org-footnote-normalize () "Turn every footnote in buffer into a numbered one." diff --git a/lisp/org/org-persist.el b/lisp/org/org-persist.el index 108292f1e92..1a32ed01020 100644 --- a/lisp/org/org-persist.el +++ b/lisp/org/org-persist.el @@ -161,7 +161,7 @@ (declare-function org-at-heading-p "org" (&optional invisible-not-ok)) -(defconst org-persist--storage-version "2.5" +(defconst org-persist--storage-version "2.7" "Persistent storage layout version.") (defgroup org-persist nil @@ -856,9 +856,16 @@ org-persist-write (setq associated (org-persist--normalize-associated (get-file-buffer (plist-get associated :file))))) (let ((collection (org-persist--get-collection container associated))) (setf collection (plist-put collection :associated associated)) - (unless (seq-find (lambda (v) - (run-hook-with-args-until-success 'org-persist-before-write-hook v associated)) - (plist-get collection :container)) + (unless (or + ;; Prevent data leakage from encrypted files. + ;; We do it in somewhat paranoid manner and do not + ;; allow anything related to encrypted files to be + ;; written. + (and (plist-get associated :file) + (string-match-p epa-file-name-regexp (plist-get associated :file))) + (seq-find (lambda (v) + (run-hook-with-args-until-success 'org-persist-before-write-hook v associated)) + (plist-get collection :container))) (when (or (file-exists-p org-persist-directory) (org-persist--save-index)) (let ((file (org-file-name-concat org-persist-directory (plist-get collection :persist-file))) (data (mapcar (lambda (c) (cons c (org-persist-write:generic c collection))) diff --git a/lisp/org/org-table.el b/lisp/org/org-table.el index 8e0e8e6cf86..fa9a0319be2 100644 --- a/lisp/org/org-table.el +++ b/lisp/org/org-table.el @@ -41,6 +41,7 @@ (require 'org-macs) (require 'org-compat) (require 'org-keys) +(require 'org-fold-core) (declare-function calc-eval "calc" (str &optional separator &rest args)) (declare-function face-remap-remove-relative "face-remap" (cookie)) @@ -4448,6 +4449,13 @@ org-table-align (defun org-table-justify-field-maybe (&optional new) "Justify the current field, text to left, number to right. Optional argument NEW may specify text to replace the current field content." + ;; FIXME: Prevent newlines inside field. They are currently not + ;; supported. + (when (and (stringp new) (string-match-p "\n" new)) + (message "Removing newlines from formula result: %S" new) + (setq new (replace-regexp-in-string + "\n" " " + (replace-regexp-in-string "\\(^\n+\\)\\|\\(\n+$\\)" "" new)))) (cond ((and (not new) org-table-may-need-update)) ; Realignment will happen anyway ((org-at-table-hline-p)) @@ -5721,31 +5729,32 @@ orgtbl-to-generic ;; Initialize communication channel in INFO. (with-temp-buffer (let ((org-inhibit-startup t)) (org-mode)) - (let ((standard-output (current-buffer)) - (org-element-use-cache nil)) - (dolist (e table) - (cond ((eq e 'hline) (princ "|--\n")) - ((consp e) - (princ "| ") (dolist (c e) (princ c) (princ " |")) - (princ "\n"))))) - (org-element-cache-reset) - ;; Add back-end specific filters, but not user-defined ones. In - ;; particular, make sure to call parse-tree filters on the - ;; table. - (setq info - (let ((org-export-filters-alist nil)) - (org-export-install-filters - (org-combine-plists - (org-export-get-environment backend nil params) - `(:back-end ,(org-export-get-backend backend)))))) - (setq data - (org-export-filter-apply-functions - (plist-get info :filter-parse-tree) - (org-element-map (org-element-parse-buffer) 'table - #'identity nil t) - info))) - (when (and backend (symbolp backend) (not (org-export-get-backend backend))) - (user-error "Unknown :backend value")) + (org-fold-core-ignore-modifications + (let ((standard-output (current-buffer)) + (org-element-use-cache nil)) + (dolist (e table) + (cond ((eq e 'hline) (princ "|--\n")) + ((consp e) + (princ "| ") (dolist (c e) (princ c) (princ " |")) + (princ "\n"))))) + (org-element-cache-reset) + ;; Add back-end specific filters, but not user-defined ones. In + ;; particular, make sure to call parse-tree filters on the + ;; table. + (setq info + (let ((org-export-filters-alist nil)) + (org-export-install-filters + (org-combine-plists + (org-export-get-environment backend nil params) + `(:back-end ,(org-export-get-backend backend)))))) + (setq data + (org-export-filter-apply-functions + (plist-get info :filter-parse-tree) + (org-element-map (org-element-parse-buffer) 'table + #'identity nil t) + info)) + (when (and backend (symbolp backend) (not (org-export-get-backend backend))) + (user-error "Unknown :backend value")))) (when (or (not backend) (plist-get info :raw)) (require 'ox-org)) ;; Handle :skip parameter. (let ((skip (plist-get info :skip))) diff --git a/lisp/org/org-version.el b/lisp/org/org-version.el index e9339690409..b9f8d5d66e7 100644 --- a/lisp/org/org-version.el +++ b/lisp/org/org-version.el @@ -11,7 +11,7 @@ org-release (defun org-git-version () "The Git version of Org mode. Inserted by installing Org or when a release is made." - (let ((org-git-version "release_9.6-3-ga4d38e")) + (let ((org-git-version "release_9.6-31-g954a95")) org-git-version)) (provide 'org-version) diff --git a/lisp/org/org.el b/lisp/org/org.el index ab6212daccd..19f94c5e232 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -11380,7 +11380,7 @@ org-make-tags-matcher (pv (match-string 7 term)) (regexp (eq (string-to-char pv) ?{)) (strp (eq (string-to-char pv) ?\")) - (timep (string-match-p "^\"[[<][0-9]+.*[]>]\"$" pv)) + (timep (string-match-p "^\"[[<]\\(?:[0-9]+\\|now\\|today\\|tomorrow\\|[+-][0-9]+[dmwy]\\).*[]>]\"$" pv)) (po (org-op-to-function (match-string 6 term) (if timep 'time strp)))) (setq pv (if (or regexp strp) (substring pv 1 -1) pv)) @@ -16322,6 +16322,10 @@ org-display-inline-images (org-element-property :end link)) (skip-chars-backward " \t") (point))))) + ;; FIXME: See bug#59902. We cannot rely + ;; on Emacs to update image if the file + ;; has changed. + (image-flush image) (overlay-put ov 'display image) (overlay-put ov 'face 'default) (overlay-put ov 'org-image-overlay t) diff --git a/lisp/org/ox-md.el b/lisp/org/ox-md.el index 01e0aa0491b..dcd95e98711 100644 --- a/lisp/org/ox-md.el +++ b/lisp/org/ox-md.el @@ -87,7 +87,8 @@ org-md-toplevel-hlevel headings for its own use." :group 'org-export-md :package-version '(Org . "9.6") - :type 'natnum) + ;; Avoid `natnum' because that's not available until Emacs 28.1. + :type 'integer) diff --git a/lisp/org/ox.el b/lisp/org/ox.el index f6629cde4dc..aed669ee87d 100644 --- a/lisp/org/ox.el +++ b/lisp/org/ox.el @@ -3036,6 +3036,11 @@ org-export-as (org-narrow-to-subtree) (goto-char (point-min)) (org-end-of-meta-data) + ;; Make the region include top heading in the subtree. + ;; This way, we will be able to retrieve its export + ;; options when calling + ;; `org-export--get-subtree-options'. + (backward-char) (narrow-to-region (point) (point-max)))) ;; Initialize communication channel with original buffer ;; attributes, unavailable in its copy. commit 26a8644a58768281bae249121f4f18d7b0661c44 Author: Juanma Barranquero Date: Sat Dec 10 21:31:59 2022 +0100 ; tabulated-list.el: Remove duplicate obsolete declaration * lisp/emacs-lisp/tabulated-list.el (tabulated-list-line-number-width): Remove second `define-obsolete-function-alias' for the same function. diff --git a/lisp/emacs-lisp/tabulated-list.el b/lisp/emacs-lisp/tabulated-list.el index 206c10a7734..595dc9b29db 100644 --- a/lisp/emacs-lisp/tabulated-list.el +++ b/lisp/emacs-lisp/tabulated-list.el @@ -263,8 +263,6 @@ 'tabulated-list-line-number-width 'header-line-indent--line-number-width "29.1") (define-obsolete-function-alias 'tabulated-list-watch-line-number-width 'header-line-indent--watch-line-number-width "29.1") -(define-obsolete-function-alias 'tabulated-list-watch-line-number-width - 'header-line-indent--watch-line-number-width "29.1") (define-obsolete-function-alias 'tabulated-list-window-scroll-function 'header-line-indent--window-scroll-function "29.1") commit 29b9aeae32acd951aeeed8001bf349800d4e5db4 Author: Stefan Kangas Date: Sat Dec 10 21:25:04 2022 +0100 ; * doc/misc/use-package.texi: Fix misplaced @end group. diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 7975138bd6f..4fd2882e109 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -1720,9 +1720,8 @@ Byte-compiling (defun my-ruby-mode-hook () (require 'inf-ruby) (inf-ruby-keys)) -@end group - (add-hook 'ruby-mode-hook 'my-ruby-mode-hook)) +@end group @end lisp @findex :no-require commit 0878279809c8acc8de703ae9774e89695b4ffc37 Author: Manuel Giraud Date: Mon Dec 5 17:48:15 2022 +0100 Fix GDB save history (bug#59838) * lisp/progmodes/gdb-mi.el (gdb-reset): Save GDB comint history. (gdb-delchar-or-quit): Remove useless progn and add comment. diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 9cbee50ce31..eb0e5b0481c 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -1113,13 +1113,13 @@ gdb-delchar-or-quit (process-live-p proc) (not gud-running) (= (point) (marker-position (process-mark proc)))) - ;; Sending an EOF does not work with GDB-MI; submit an - ;; explicit quit command. - (progn - (if (> gdb-control-level 0) - (process-send-eof proc) - (insert "quit") - (comint-send-input t t))) + ;; Exit a recursive reading loop or quit. + (if (> gdb-control-level 0) + (process-send-eof proc) + ;; Sending an EOF does not work with GDB-MI; submit an + ;; explicit quit command. + (insert "quit") + (comint-send-input t t)) (delete-char arg)))) (defvar gdb-define-alist nil "Alist of #define directives for GUD tooltips.") @@ -5157,6 +5157,8 @@ gdb-restore-windows (defun gdb-reset () "Exit a debugging session cleanly. Kills the gdb buffers, and resets variables and the source buffers." + ;; Save GDB history + (comint-write-input-ring) ;; The gdb-inferior buffer has a pty hooked up to the main gdb ;; process. This pty must be deleted explicitly. (let ((pty (get-process "gdb-inferior"))) commit 9c670695b91deb3424a74cd2b0f6a37356a4efcc Author: Eli Zaretskii Date: Sat Dec 10 15:32:41 2022 +0200 ; * etc/NEWS: Fix last change. diff --git a/etc/NEWS b/etc/NEWS index e92e3b84682..0c1fdfc454b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -42,18 +42,19 @@ connection. * Changes in Specialized Modes and Packages in Emacs 30.1 --- ** Variable order and truncation can now be configured in gdb-many-window mode. -The new variable `gdb-locals-table-row-config' allows users to +The new variable 'gdb-locals-table-row-config' allows users to configure the order and max length of various properties in the local -variables buffer when using `gdb-many-windows'. +variables buffer when using 'gdb-many-windows'. By default, this variable is set to write the properties in the order: -name, type and value. Where the name and type are truncated to 20 -characters, and the value is truncated to the value of -`gdb-locals-value-limit'. +name, type and value, where the name and type are truncated to 20 +characters, and the value is truncated according to the value of +'gdb-locals-value-limit'. -In order to restore the old display behavior, set -`gdb-locals-table-row-config' to `((type . 0)(name . 0)(value -. ,gdb-locals-value-limit)). +If you want to get back the old behavior, set +'gdb-locals-table-row-config' to the value + + ((type . 0)(name . 0)(value . ,gdb-locals-value-limit)). ** VC commit 5d506a7eab693bbd3ef4c9a6f2ff6e61ee5b84b7 Author: Gustaf Waldemarson Date: Tue Nov 29 23:40:23 2022 +0100 gdb-mi.el: Configure variable order and length in local-vars window This changes allows users to configure the order of various properties as well as truncating their length. The full description of each property is available as a help-text (tooltip). * lisp/progmodes/gdb-mi.el (gdb-locals-table-row-config): New user option. (gdb-locals-value-filter): Don't limit the values here. (gdb-locals-table-columns-list): New function. (gdb-locals-handler-custom): Call it. (Bug#59730) * etc/NEWS: Announce the change. diff --git a/etc/NEWS b/etc/NEWS index 61f813568f0..e92e3b84682 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -40,6 +40,20 @@ connection. * Changes in Specialized Modes and Packages in Emacs 30.1 +--- +** Variable order and truncation can now be configured in gdb-many-window mode. +The new variable `gdb-locals-table-row-config' allows users to +configure the order and max length of various properties in the local +variables buffer when using `gdb-many-windows'. + +By default, this variable is set to write the properties in the order: +name, type and value. Where the name and type are truncated to 20 +characters, and the value is truncated to the value of +`gdb-locals-value-limit'. + +In order to restore the old display behavior, set +`gdb-locals-table-row-config' to `((type . 0)(name . 0)(value +. ,gdb-locals-value-limit)). ** VC diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index e8d8f9104e4..9cbee50ce31 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -4355,6 +4355,24 @@ gdb-locals-value-limit :group 'gud :version "29.1") +(defcustom gdb-locals-table-row-config `((name . 20) + (type . 20) + (value . ,gdb-locals-value-limit)) + "Configuration for table rows in the local variable display. + +An alist that controls the display of the name, type and value of +local variables inside the currently active stack-frame. The key +controls which column to change whereas the value determines the +maximum number of characters to display in each column. A value +of 0 means there is no limit. + +Additionally, the order the element in the alist determines the +left-to-right display order of the properties." + :type '(alist :key-type 'symbol :value-type 'integer) + :group 'gud + :version "30.1") + + (defvar gdb-locals-values-table (make-hash-table :test #'equal) "Mapping of local variable names to a string with their value.") @@ -4384,12 +4402,9 @@ gdb-edit-locals-map-1 (defun gdb-locals-value-filter (value) "Filter function for the local variable VALUE." - (let* ((no-nl (replace-regexp-in-string "\n" " " value)) - (str (replace-regexp-in-string "[[:space:]]+" " " no-nl)) - (limit gdb-locals-value-limit)) - (if (>= (length str) limit) - (concat (substring str 0 limit) "...") - str))) + (let* ((no-nl (replace-regexp-in-string "\n" " " (or value ""))) + (str (replace-regexp-in-string "[[:space:]]+" " " no-nl))) + str)) (defun gdb-edit-locals-value (&optional event) "Assign a value to a variable displayed in the locals buffer." @@ -4403,6 +4418,22 @@ gdb-edit-locals-value (gud-basic-call (concat "-gdb-set variable " var " = " value))))) + +(defun gdb-locals-table-columns-list (alist) + "Format and arrange the columns in locals display based on ALIST." + (let (columns) + (dolist (config gdb-locals-table-row-config columns) + (let* ((key (car config)) + (max (cdr config)) + (prop (alist-get key alist))) + (when prop + (if (and (> max 0) (length> prop max)) + (push (propertize (string-truncate-left prop max) 'help-echo prop) + columns) + (push prop columns))))) + (nreverse columns))) + + ;; Complex data types are looked up in `gdb-locals-values-table'. (defun gdb-locals-handler-custom () "Handler to rebuild the local variables table buffer." @@ -4431,12 +4462,14 @@ gdb-locals-handler-custom help-echo "mouse-2: edit value" local-map ,gdb-edit-locals-map-1) value)) + (setf (gdb-table-right-align table) t) + (setq name (propertize name 'font-lock-face font-lock-variable-name-face)) + (setq type (propertize type 'font-lock-face font-lock-type-face)) (gdb-table-add-row table - (list - (propertize type 'font-lock-face font-lock-type-face) - (propertize name 'font-lock-face font-lock-variable-name-face) - value) + (gdb-locals-table-columns-list `((name . ,name) + (type . ,type) + (value . ,value))) `(gdb-local-variable ,local)))) (insert (gdb-table-string table " ")) (setq mode-name commit 3c5a41b20085e1a07a8dae6957929d2b2872e2d3 Author: Eli Zaretskii Date: Sat Dec 10 15:06:27 2022 +0200 ; * doc/lispref/keymaps.texi (Searching Keymaps): Fix a typo (bug#59886). diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index 1e4bf4eb861..5882f247948 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -841,7 +841,7 @@ Searching Keymaps (@var{find-in-any} emulation-mode-map-alists) (@var{find-in-any} minor-mode-overriding-map-alist) (@var{find-in-any} minor-mode-map-alist) - (if (get-text-property (point) 'local-map) + (if (get-char-property (point) 'local-map) (@var{find-in} (get-char-property (point) 'local-map)) (@var{find-in} (current-local-map))))) (@var{find-in} (current-global-map))) commit 1753da24cd44821bf39f03dc32476e320e732fca Author: Eli Zaretskii Date: Sat Dec 10 14:55:01 2022 +0200 Fix infloop in 'shell-resync-dirs' with tcsh * lisp/shell.el (shell-resync-dirs): Remove trailing slash from output of 'dirs', for csh/tcsh's sake. (Bug#59804) diff --git a/lisp/shell.el b/lisp/shell.el index b396bc2b180..dadbdcbc034 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -1162,6 +1162,7 @@ shell-resync-dirs (dlsl nil) (pos 0) (ds nil)) + (setq dls (string-trim-right dls "[ ]+")) ;; Split the dirlist into whitespace and non-whitespace chunks. ;; dlsl will be a reversed list of tokens. (while (string-match "\\(\\S-+\\|\\s-+\\)" dls pos) commit 2f1269c3331bfe2b570a9238ce52dafb14c3cf7b Author: Stefan Kangas Date: Sat Dec 10 12:59:30 2022 +0100 ; Fix some minor issues in use-package.texi * doc/misc/use-package.texi: Fix some minor issues. diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index d3b6ee99003..7975138bd6f 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -652,12 +652,11 @@ Load path whatever was determined during compilation, to avoid looking up the same information again on each startup. For example: -@c FIXME: the below should use shell-command-to-string, surely? @lisp @group (eval-and-compile (defun ess-site-load-path () - (shell-command "find ~ -path ess/lisp"))) + (shell-command-to-string "find ~ -path ess/lisp"))) @end group @group @@ -739,10 +738,8 @@ Preface keyword @enumerate @item -@c FIXME: ``within a guard block''? what's that?? Make the byte-compiler happy: it will not complain about functions -whose definitions are unknown because you have them within a guard -block. +whose definitions are unknown. @item Define functions and variables that will be used in an @code{:if} @@ -1684,9 +1681,9 @@ Byte-compiling Some users might want to byte-compile their init file to make Emacs startup faster. This is not recommended in most cases, as the -speed-up is often too small to be worth it, and can lead to confusion -if the byte-compiled files are out-of-date. If you still want to do -it, this chapter explains how to do that. +speed-up is usually too small to be worth it, and it can lead to +confusion if the byte-compiled files are out-of-date. If you still +want to do it, this chapter explains how to do that. @code{use-package} always loads every library that it can while a file is being byte-compiled. This helps silence spurious warnings about @@ -1962,7 +1959,7 @@ use-package-ensure-system-package @end group @end lisp -For example, on a @code{Debian GNU/Linux} system, this would call +For example, on a Debian GNU/Linux system, this would call @samp{apt-get install foo}. If the package is named differently than the binary, you can use a @@ -1976,11 +1973,10 @@ use-package-ensure-system-package @end group @end lisp -On a @code{Debian GNU/Linux} system, this would call @code{apt install -foo} if Emacs could not locate the executable -@code{foocmd}.@footnote{For manual testing, you could use the -@code{executable-find} function, which is what @samp{system-packages} -uses internally.} +On a Debian GNU/Linux system, this would call @code{apt install foo} +if Emacs could not locate the executable @code{foocmd}.@footnote{For +manual testing, you could use the @code{executable-find} function, +which is what @samp{system-packages} uses internally.} @code{:ensure-system-package} can also take a cons where the @code{cdr} is a string that will get called by commit cb202d30edbdaf710327f71feaa5985e35c75d86 Author: Po Lu Date: Sat Dec 10 19:29:02 2022 +0800 ; * src/xterm.c (x_connection_closed): Fix typo in change. diff --git a/src/xterm.c b/src/xterm.c index c6fa29943bf..38775c3f52e 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -26050,7 +26050,8 @@ x_connection_closed (Display *dpy, const char *error_message, bool ioerror) /* Dump the list of error handlers for debugging purposes if the list exists. */ - if (dpyinfo->failable_requests || x_error_message) + if ((dpyinfo->failable_requests + != dpyinfo->next_failable_request) || x_error_message) fprintf (stderr, "X error handlers currently installed:\n"); for (failable = dpyinfo->failable_requests; commit dc37090d6e26f561b8f89e7afe8e2c3fa3543608 Author: Po Lu Date: Sat Dec 10 19:26:54 2022 +0800 Improve X error messages * src/xterm.c (x_connection_closed): Don't print handler blurb if nothing is there to be printed. diff --git a/src/xterm.c b/src/xterm.c index 872326392a6..c6fa29943bf 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -26048,9 +26048,10 @@ x_connection_closed (Display *dpy, const char *error_message, bool ioerror) if (!ioerror && dpyinfo) { /* Dump the list of error handlers for debugging - purposes. */ + purposes if the list exists. */ - fprintf (stderr, "X error handlers currently installed:\n"); + if (dpyinfo->failable_requests || x_error_message) + fprintf (stderr, "X error handlers currently installed:\n"); for (failable = dpyinfo->failable_requests; failable < dpyinfo->next_failable_request; commit d3494f1bded55a3dce3dcaee1e10a76b7b8765f4 Author: Eli Zaretskii Date: Sat Dec 10 13:22:48 2022 +0200 Resurrect changes omitted by a recent merge from emacs-29 (bug#59921) This includes the changes for the following commits: 670daa8b b429e524 c83c95634e7 6479691cf07 b710ca62c00 d31a2539834 a669d5fae54 f7262b8f81e fef17557365 bf81df86e52 bfc00f1c120 d2411615e8b dcf69a1d diff --git a/lisp/auth-source-pass.el b/lisp/auth-source-pass.el index 74d38084480..fbb6944e26f 100644 --- a/lisp/auth-source-pass.el +++ b/lisp/auth-source-pass.el @@ -111,12 +111,12 @@ auth-source-pass--match-regexp (defun auth-source-pass--match-regexp (s) (rx-to-string ; autoloaded `(: (or bot "/") - (or (: (? (group-n 20 (+ (not (in ?\ ?/ ,s)))) "@") - (group-n 10 (+ (not (in ?\ ?/ ?@ ,s)))) - (? ,s (group-n 30 (+ (not (in ?\ ?/ ,s)))))) - (: (group-n 11 (+ (not (in ?\ ?/ ?@ ,s)))) - (? ,s (group-n 31 (+ (not (in ?\ ?/ ,s))))) - (? "/" (group-n 21 (+ (not (in ?\ ?/ ,s))))))) + (or (: (? (group-n 20 (+ (not (in ?/ ,s)))) "@") ; user prefix + (group-n 10 (+ (not (in ?/ ?@ ,s)))) ; host + (? ,s (group-n 30 (+ (not (in ?\s ?/ ,s)))))) ; port + (: (group-n 11 (+ (not (in ?/ ?@ ,s)))) ; host + (? ,s (group-n 31 (+ (not (in ?\s ?/ ,s))))) ; port + (? "/" (group-n 21 (+ (not (in ?/ ,s))))))) ; user suffix eot) 'no-group)) diff --git a/lisp/erc/erc-compat.el b/lisp/erc/erc-compat.el index abbaafcd936..bd932547586 100644 --- a/lisp/erc/erc-compat.el +++ b/lisp/erc/erc-compat.el @@ -176,12 +176,12 @@ auth-source-backend-parser-functions ;; This hard codes `auth-source-pass-port-separator' to ":" (defun erc-compat--29-auth-source-pass--retrieve-parsed (seen e port-number-p) (when (string-match (rx (or bot "/") - (or (: (? (group-n 20 (+ (not (in " /:")))) "@") - (group-n 10 (+ (not (in " /:@")))) + (or (: (? (group-n 20 (+ (not (in "/:")))) "@") + (group-n 10 (+ (not (in "/:@")))) (? ":" (group-n 30 (+ (not (in " /:")))))) - (: (group-n 11 (+ (not (in " /:@")))) + (: (group-n 11 (+ (not (in "/:@")))) (? ":" (group-n 31 (+ (not (in " /:"))))) - (? "/" (group-n 21 (+ (not (in " /:"))))))) + (? "/" (group-n 21 (+ (not (in "/:"))))))) eot) e) (puthash e `( :host ,(or (match-string 10 e) (match-string 11 e)) diff --git a/lisp/icomplete.el b/lisp/icomplete.el index ef710d582d3..983931c20ca 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -416,7 +416,6 @@ icomplete--fido-mode-setup icomplete-scroll (not (null icomplete-vertical-mode)) completion-styles '(flex) completion-flex-nospace nil - completion-category-defaults nil completion-ignore-case t read-buffer-completion-ignore-case t read-file-name-completion-ignore-case t))) diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 08b03d5666a..7b41718a745 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -78,6 +78,8 @@ c-ts-mode--syntax-table (modify-syntax-entry ?\240 "." table) (modify-syntax-entry ?/ ". 124b" table) (modify-syntax-entry ?* ". 23" table) + (modify-syntax-entry ?\n "> b" table) + (modify-syntax-entry ?\^m "> b" table) table) "Syntax table for `c-ts-mode'.") @@ -232,7 +234,8 @@ c-ts-mode--font-lock-settings (false) @font-lock-constant-face (null) @font-lock-constant-face ,@(when (eq mode 'cpp) - '((this) @font-lock-constant-face))) + '((this) @font-lock-constant-face + (nullptr) @font-lock-constant-face))) :language mode :feature 'keyword @@ -516,9 +519,30 @@ c-ts-mode--end-of-defun (if (looking-at "\\s<\\|\n") (forward-line 1))))) +(defun c-ts-mode-indent-defun () + "Indent the current top-level declaration syntactically. + +`treesit-defun-type-regexp' defines what constructs to indent." + (interactive "*") + (let ((orig-point (point-marker))) + ;; If `treesit-beginning-of-defun' returns nil, we are not in a + ;; defun, so don't indent anything. + (when (treesit-beginning-of-defun) + (let ((start (point))) + (treesit-end-of-defun) + (indent-region start (point)))) + (goto-char orig-point))) + +(defvar-keymap c-ts-mode-map + :doc "Keymap for the C language with tree-sitter" + :parent prog-mode-map + "C-c C-q" #'c-ts-mode-indent-defun) + ;;;###autoload (define-derived-mode c-ts-base-mode prog-mode "C" - "Major mode for editing C, powered by tree-sitter." + "Major mode for editing C, powered by tree-sitter. + +\\{c-ts-mode-map}" :syntax-table c-ts-mode--syntax-table ;; Navigation. diff --git a/lisp/progmodes/csharp-mode.el b/lisp/progmodes/csharp-mode.el index 8ab5fbc91df..f08e8d6506e 100644 --- a/lisp/progmodes/csharp-mode.el +++ b/lisp/progmodes/csharp-mode.el @@ -893,6 +893,7 @@ csharp-mode ;;;###autoload (define-derived-mode csharp-ts-mode prog-mode "C#" "Major mode for editing C# code." + :syntax-table (csharp--make-mode-syntax-table) (unless (treesit-ready-p 'c-sharp) (error "Tree-sitter for C# isn't available")) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index c266f6e18a3..cafb99c6d80 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -7,7 +7,7 @@ ;; Maintainer: João Távora ;; URL: https://github.com/joaotavora/eglot ;; Keywords: convenience, languages -;; Package-Requires: ((emacs "26.3") (jsonrpc "1.0.14") (flymake "1.2.1") (project "0.3.0") (xref "1.0.1") (eldoc "1.11.0") (seq "2.23")) +;; Package-Requires: ((emacs "26.3") (jsonrpc "1.0.14") (flymake "1.2.1") (project "0.3.0") (xref "1.0.1") (eldoc "1.11.0") (seq "2.23") (external-completion "0.1")) ;; This is a GNU ELPA :core package. Avoid adding functionality ;; that is not available in the version of Emacs recorded above or any @@ -110,6 +110,7 @@ (require 'filenotify) (require 'ert) (require 'array) +(require 'external-completion) ;; ElDoc is preloaded in Emacs, so `require'-ing won't guarantee we are ;; using the latest version from GNU Elpa when we load eglot.el. Use an @@ -2060,9 +2061,11 @@ eglot-handle-notification (t 'eglot-note))) (mess (source code message) (concat source (and code (format " [%s]" code)) ": " message))) - (if-let ((buffer (find-buffer-visiting (eglot--uri-to-path uri)))) + (if-let* ((path (expand-file-name (eglot--uri-to-path uri))) + (buffer (find-buffer-visiting path))) (with-current-buffer buffer (cl-loop + initially (assoc-delete-all path flymake-list-only-diagnostics #'string=) for diag-spec across diagnostics collect (eglot--dbind ((Diagnostic) range code message severity source tags) diag-spec @@ -2105,7 +2108,6 @@ eglot-handle-notification (t (setq eglot--diagnostics diags))))) (cl-loop - with path = (expand-file-name (eglot--uri-to-path uri)) for diag-spec across diagnostics collect (eglot--dbind ((Diagnostic) code range message severity source) diag-spec (setq message (mess source code message)) @@ -2571,7 +2573,7 @@ xref-backend-identifier-completion-table (let ((probe (gethash pat cache :missing))) (if (eq probe :missing) (puthash pat (refresh pat) cache) probe))) - (lookup (pat) + (lookup (pat _point) (let ((res (lookup-1 pat)) (def (and (string= pat "") (gethash :default cache)))) (append def res nil))) @@ -2579,16 +2581,12 @@ xref-backend-identifier-completion-table (cl-getf (get-text-property 0 'eglot--lsp-workspaceSymbol c) :score 0))) - (lambda (string _pred action) - (pcase action - (`metadata `(metadata - (cycle-sort-function - . ,(lambda (completions) - (cl-sort completions #'> :key #'score))) - (category . eglot-indirection-joy))) - (`(eglot--lsp-tryc . ,point) `(eglot--lsp-tryc . (,string . ,point))) - (`(eglot--lsp-allc . ,_point) `(eglot--lsp-allc . ,(lookup string))) - (_ nil)))))) + (external-completion-table + 'eglot-indirection-joy + #'lookup + `((cycle-sort-function + . ,(lambda (completions) + (cl-sort completions #'> :key #'score)))))))) (defun eglot--recover-workspace-symbol-meta (string) "Search `eglot--workspace-symbols-cache' for rich entry of STRING." @@ -2600,9 +2598,6 @@ eglot--recover-workspace-symbol-meta (setq v (cdr v)))) eglot--workspace-symbols-cache))) -(add-to-list 'completion-category-overrides - '(eglot-indirection-joy (styles . (eglot--lsp-backend-style)))) - (cl-defmethod xref-backend-identifier-at-point ((_backend (eql eglot))) (let ((attempt (and (xref--prompt-p this-command) @@ -3437,42 +3432,6 @@ eglot-list-connections 'eglot-managed-mode-hook "1.6") (provide 'eglot) - -;;; Backend completion - -;; Written by Stefan Monnier circa 2016. Something to move to -;; minibuffer.el "ASAP" (with all the `eglot--lsp-' replaced by -;; something else. The very same code already in SLY and stable for a -;; long time. - -;; This "completion style" delegates all the work to the "programmable -;; completion" table which is then free to implement its own -;; completion style. Typically this is used to take advantage of some -;; external tool which already has its own completion system and -;; doesn't give you efficient access to the prefix completion needed -;; by other completion styles. The table should recognize the symbols -;; 'eglot--lsp-tryc and 'eglot--lsp-allc as ACTION, reply with -;; (eglot--lsp-tryc COMP...) or (eglot--lsp-allc . (STRING . POINT)), -;; accordingly. tryc/allc names made akward/recognizable on purpose. - -(add-to-list 'completion-styles-alist - '(eglot--lsp-backend-style - eglot--lsp-backend-style-try-completion - eglot--lsp-backend-style-all-completions - "Ad-hoc completion style provided by the completion table.")) - -(defun eglot--lsp-backend-style-call (op string table pred point) - (when (functionp table) - (let ((res (funcall table string pred (cons op point)))) - (when (eq op (car-safe res)) - (cdr res))))) - -(defun eglot--lsp-backend-style-try-completion (string table pred point) - (eglot--lsp-backend-style-call 'eglot--lsp-tryc string table pred point)) - -(defun eglot--lsp-backend-style-all-completions (string table pred point) - (eglot--lsp-backend-style-call 'eglot--lsp-allc string table pred point)) - ;; Local Variables: ;; bug-reference-bug-regexp: "\\(github#\\([0-9]+\\)\\)" diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el index 96e0d5244c7..23e166ee4c3 100644 --- a/lisp/progmodes/java-ts-mode.el +++ b/lisp/progmodes/java-ts-mode.el @@ -57,6 +57,11 @@ java-ts-mode--syntax-table (modify-syntax-entry ?| "." table) (modify-syntax-entry ?\' "\"" table) (modify-syntax-entry ?\240 "." table) + (modify-syntax-entry ?/ ". 124b" table) + (modify-syntax-entry ?* ". 23" table) + (modify-syntax-entry ?\n "> b" table) + (modify-syntax-entry ?\^m "> b" table) + (modify-syntax-entry ?@ "'" table) table) "Syntax table for `java-ts-mode'.") diff --git a/lisp/progmodes/json-ts-mode.el b/lisp/progmodes/json-ts-mode.el index 0a0113d1d88..a118908a00c 100644 --- a/lisp/progmodes/json-ts-mode.el +++ b/lisp/progmodes/json-ts-mode.el @@ -45,9 +45,7 @@ json-ts-mode-indent-offset (defvar json-ts-mode--syntax-table (let ((table (make-syntax-table))) - ;; Taken from the cc-langs version (modify-syntax-entry ?_ "_" table) - (modify-syntax-entry ?$ "_" table) (modify-syntax-entry ?\\ "\\" table) (modify-syntax-entry ?+ "." table) (modify-syntax-entry ?- "." table) @@ -57,8 +55,12 @@ json-ts-mode--syntax-table (modify-syntax-entry ?> "." table) (modify-syntax-entry ?& "." table) (modify-syntax-entry ?| "." table) - (modify-syntax-entry ?` "\"" table) + (modify-syntax-entry ?\' "\"" table) (modify-syntax-entry ?\240 "." table) + (modify-syntax-entry ?/ ". 124b" table) + (modify-syntax-entry ?* ". 23" table) + (modify-syntax-entry ?\n "> b" table) + (modify-syntax-entry ?\^m "> b" table) table) "Syntax table for `json-ts-mode'.") diff --git a/lisp/progmodes/typescript-ts-mode.el b/lisp/progmodes/typescript-ts-mode.el index 20916eaf373..243f6146ae7 100644 --- a/lisp/progmodes/typescript-ts-mode.el +++ b/lisp/progmodes/typescript-ts-mode.el @@ -44,7 +44,6 @@ typescript-ts-mode--syntax-table (let ((table (make-syntax-table))) ;; Taken from the cc-langs version (modify-syntax-entry ?_ "_" table) - (modify-syntax-entry ?$ "_" table) (modify-syntax-entry ?\\ "\\" table) (modify-syntax-entry ?+ "." table) (modify-syntax-entry ?- "." table) @@ -54,8 +53,14 @@ typescript-ts-mode--syntax-table (modify-syntax-entry ?> "." table) (modify-syntax-entry ?& "." table) (modify-syntax-entry ?| "." table) - (modify-syntax-entry ?` "\"" table) + (modify-syntax-entry ?\' "\"" table) (modify-syntax-entry ?\240 "." table) + (modify-syntax-entry ?/ ". 124b" table) + (modify-syntax-entry ?* ". 23" table) + (modify-syntax-entry ?\n "> b" table) + (modify-syntax-entry ?\^m "> b" table) + (modify-syntax-entry ?$ "_" table) + (modify-syntax-entry ?` "\"" table) table) "Syntax table for `typescript-ts-mode'.") diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 8a66986dc6f..822097a86d8 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -1822,6 +1822,7 @@ css-ts-mode can also be used to fill comments. \\{css-mode-map}" + :syntax-table css-mode-syntax-table (when (treesit-ready-p 'css) ;; Borrowed from `css-mode'. (add-hook 'completion-at-point-functions diff --git a/lisp/treesit.el b/lisp/treesit.el index dbbf7ec18c3..85154d0d1c7 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -833,21 +833,28 @@ treesit--children-covering-range (nreverse result)) (list node))) -(defun treesit--children-covering-range-recurse (node start end threshold) +(defun treesit--children-covering-range-recurse + (node start end threshold &optional limit) "Return a list of children of NODE covering a range. + Recursively go down the parse tree and collect children, until all nodes in the returned list are smaller than THRESHOLD. The -range is between START and END." +range is between START and END. + +LIMIT is the recursion limit, which defaults to 100." (let* ((child (treesit-node-first-child-for-pos node start)) + (limit (or limit 100)) result) - (while (and child (<= (treesit-node-start child) end)) + ;; If LIMIT is exceeded, we are probably seeing the erroneously + ;; tall tree, in that case, just give up. + (while (and (> limit 0) child (<= (treesit-node-start child) end)) ;; If child still too large, recurse down. Otherwise collect ;; child. (if (> (- (treesit-node-end child) (treesit-node-start child)) threshold) (dolist (r (treesit--children-covering-range-recurse - child start end threshold)) + child start end threshold (1- limit))) (push r result)) (push child result)) (setq child (treesit-node-next-sibling child))) @@ -888,6 +895,12 @@ treesit--font-lock-fast-mode ;; top-level nodes and query them. This ensures that querying is fast ;; everywhere else, except for the problematic region. ;; +;; Some other time the source file has a top-level node that contains +;; a huge number of children (say, 10k children), querying that node +;; is also very slow, so instead of getting the top-level node, we +;; recursively go down the tree to find nodes that cover the region +;; but are reasonably small. +;; ;; 3. It is possible to capture a node that's completely outside the ;; region between START and END: as long as the whole pattern ;; intersects the region, all the captured nodes in that pattern are @@ -917,8 +930,8 @@ treesit-font-lock-fontify-region ;; If we run into problematic files, use the "fast mode" to ;; try to recover. See comment #2 above for more explanation. (when treesit--font-lock-fast-mode - (setq nodes (treesit--children-covering-range - (car nodes) start end))) + (setq nodes (treesit--children-covering-range-recurse + (car nodes) start end (* 4 jit-lock-chunk-size)))) ;; Query each node. (dolist (sub-node nodes) diff --git a/src/treesit.c b/src/treesit.c index 9926806612a..8b485ca4ece 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -1642,6 +1642,17 @@ treesit_check_node (Lisp_Object obj) xsignal1 (Qtreesit_node_outdated, obj); } +/* Checks that OBJ is a positive integer and it is within the visible + portion of BUF. */ +static void +treesit_check_position (Lisp_Object obj, struct buffer *buf) +{ + treesit_check_positive_integer (obj); + ptrdiff_t pos = XFIXNUM (obj); + if (pos < BUF_BEGV (buf) || pos > BUF_ZV (buf)) + xsignal1 (Qargs_out_of_range, obj); +} + bool treesit_node_uptodate_p (Lisp_Object obj) { @@ -1990,14 +2001,12 @@ DEFUN ("treesit-node-first-child-for-pos", if (NILP (node)) return Qnil; treesit_check_node (node); - treesit_check_positive_integer (pos); struct buffer *buf = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg; ptrdiff_t byte_pos = buf_charpos_to_bytepos (buf, XFIXNUM (pos)); - if (byte_pos < BUF_BEGV_BYTE (buf) || byte_pos > BUF_ZV_BYTE (buf)) - xsignal1 (Qargs_out_of_range, pos); + treesit_check_position (pos, buf); treesit_initialize (); @@ -2028,19 +2037,14 @@ DEFUN ("treesit-node-descendant-for-range", { if (NILP (node)) return Qnil; treesit_check_node (node); - CHECK_INTEGER (beg); - CHECK_INTEGER (end); struct buffer *buf = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg; ptrdiff_t byte_beg = buf_charpos_to_bytepos (buf, XFIXNUM (beg)); ptrdiff_t byte_end = buf_charpos_to_bytepos (buf, XFIXNUM (end)); - /* Checks for BUFFER_BEG <= BEG <= END <= BUFFER_END. */ - if (!(BUF_BEGV_BYTE (buf) <= byte_beg - && byte_beg <= byte_end - && byte_end <= BUF_ZV_BYTE (buf))) - xsignal2 (Qargs_out_of_range, beg, end); + treesit_check_position (beg, buf); + treesit_check_position (end, buf); treesit_initialize (); @@ -2426,21 +2430,24 @@ DEFUN ("treesit-query-capture", (Lisp_Object node, Lisp_Object query, Lisp_Object beg, Lisp_Object end, Lisp_Object node_only) { - if (!NILP (beg)) - CHECK_INTEGER (beg); - if (!NILP (end)) - CHECK_INTEGER (end); - if (!(TS_COMPILED_QUERY_P (query) || CONSP (query) || STRINGP (query))) wrong_type_argument (Qtreesit_query_p, query); + treesit_initialize (); + /* Resolve NODE into an actual node. */ Lisp_Object lisp_node; if (TS_NODEP (node)) - lisp_node = node; + { + treesit_check_node (node); /* Check if up-to-date. */ + lisp_node = node; + } else if (TS_PARSERP (node)) - lisp_node = Ftreesit_parser_root_node (node); + { + treesit_check_parser (node); /* Check if deleted. */ + lisp_node = Ftreesit_parser_root_node (node); + } else if (SYMBOLP (node)) { Lisp_Object parser @@ -2452,8 +2459,6 @@ DEFUN ("treesit-query-capture", list4 (Qor, Qtreesit_node_p, Qtreesit_parser_p, Qsymbolp), node); - treesit_initialize (); - /* Extract C values from Lisp objects. */ TSNode treesit_node = XTS_NODE (lisp_node)->node; @@ -2464,6 +2469,13 @@ DEFUN ("treesit-query-capture", const TSLanguage *lang = ts_parser_language (XTS_PARSER (lisp_parser)->parser); + /* Check BEG and END. */ + struct buffer *buf = XBUFFER (XTS_PARSER (lisp_parser)->buffer); + if (!NILP (beg)) + treesit_check_position (beg, buf); + if (!NILP (end)) + treesit_check_position (end, buf); + /* Initialize query objects. At the end of this block, we should have a working TSQuery and a TSQueryCursor. */ TSQuery *treesit_query; diff --git a/test/lisp/auth-source-pass-tests.el b/test/lisp/auth-source-pass-tests.el index 1107e09b51b..d6d42ce942e 100644 --- a/test/lisp/auth-source-pass-tests.el +++ b/test/lisp/auth-source-pass-tests.el @@ -175,7 +175,8 @@ auth-source-pass-match-any-entry-p (ert-deftest auth-source-pass-any-host () (auth-source-pass--with-store '(("foo" ("port" . "foo-port") ("host" . "foo-user")) ("bar")) - (should-not (auth-source-pass-search :host t)))) + (let ((inhibit-message t)) ; silence "... does not handle host wildcards." + (should-not (auth-source-pass-search :host t))))) (ert-deftest auth-source-pass-undefined-host () (auth-source-pass--with-store '(("foo" ("port" . "foo-port") ("host" . "foo-user")) @@ -697,29 +698,29 @@ auth-source-pass-extra-query-keywords--ambiguous-user-host ;; with slightly more realistic and less legible values. (ert-deftest auth-source-pass-extra-query-keywords--suffixed-user () - (let ((store (sort (copy-sequence '(("x.com:42/b@r" (secret . "a")) - ("b@r@x.com" (secret . "b")) + (let ((store (sort (copy-sequence '(("x.com:42/s p@m" (secret . "a")) + ("s p@m@x.com" (secret . "b")) ("x.com" (secret . "?")) - ("b@r@y.org" (secret . "c")) - ("fake.com" (secret . "?")) - ("fake.com/b@r" (secret . "d")) - ("y.org/b@r" (secret . "?")) - ("b@r@fake.com" (secret . "e")))) + ("s p@m@y.org" (secret . "c")) + ("fa ke" (secret . "?")) + ("fa ke/s p@m" (secret . "d")) + ("y.org/s p@m" (secret . "?")) + ("s p@m@fa ke" (secret . "e")))) (lambda (&rest _) (zerop (random 2)))))) (auth-source-pass--with-store store (auth-source-pass-enable) (let* ((auth-source-pass-extra-query-keywords t) - (results (auth-source-search :host '("x.com" "fake.com" "y.org") - :user "b@r" + (results (auth-source-search :host '("x.com" "fa ke" "y.org") + :user "s p@m" :require '(:user) :max 5))) (dolist (result results) (setf (plist-get result :secret) (auth-info-password result))) (should (equal results - '((:host "x.com" :user "b@r" :secret "b") - (:host "x.com" :user "b@r" :port "42" :secret "a") - (:host "fake.com" :user "b@r" :secret "e") - (:host "fake.com" :user "b@r" :secret "d") - (:host "y.org" :user "b@r" :secret "c")))))))) + '((:host "x.com" :user "s p@m" :secret "b") + (:host "x.com" :user "s p@m" :port "42" :secret "a") + (:host "fa ke" :user "s p@m" :secret "e") + (:host "fa ke" :user "s p@m" :secret "d") + (:host "y.org" :user "s p@m" :secret "c")))))))) ;; This is a more distilled version of `suffixed-user', above. It ;; better illustrates that search order takes precedence over "/user" diff --git a/test/lisp/comint-tests.el b/test/lisp/comint-tests.el index 8402c13daf3..ce1a6865b65 100644 --- a/test/lisp/comint-tests.el +++ b/test/lisp/comint-tests.el @@ -59,9 +59,23 @@ comint-test-password-regexp (dolist (str comint-testsuite-password-strings) (should (string-match comint-password-prompt-regexp str)))) +(declare-function w32-application-type "w32proc.c") +(defun w32-native-executable-p (fname) + "Predicate to test program FNAME for being a native Windows application." + (and (memq (w32-application-type fname) '(w32-native dos)) + (file-executable-p fname))) + +(defun w32-native-executable-find (name) + "Find a native MS-Windows application named NAME. +This is needed to avoid invoking MSYS or Cygwin executables that +happen to lurk on PATH when running the test suite." + (locate-file name exec-path exec-suffixes 'w32-native-executable-p)) + (defun comint-tests/test-password-function (password-function) "PASSWORD-FUNCTION can return nil or a string." - (when-let ((cat (executable-find "cat"))) + (when-let ((cat (if (eq system-type 'windows-nt) + (w32-native-executable-find "cat") + (executable-find "cat")))) (let ((comint-password-function password-function)) (cl-letf (((symbol-function 'read-passwd) (lambda (&rest _args) "non-nil"))) diff --git a/test/src/sqlite-tests.el b/test/src/sqlite-tests.el index e9ddf9c0bef..a2472c43dad 100644 --- a/test/src/sqlite-tests.el +++ b/test/src/sqlite-tests.el @@ -36,6 +36,7 @@ (declare-function sqlite-select "sqlite.c") (declare-function sqlite-open "sqlite.c") (declare-function sqlite-load-extension "sqlite.c") +(declare-function sqlite-version "sqlite.c") (ert-deftest sqlite-select () (skip-unless (sqlite-available-p)) diff --git a/test/src/treesit-tests.el b/test/src/treesit-tests.el index 80fde408cd3..aba12759c34 100644 --- a/test/src/treesit-tests.el +++ b/test/src/treesit-tests.el @@ -143,6 +143,8 @@ treesit-node-api (treesit-node-string (treesit-node-first-child-for-pos doc-node 3)))) + (should-error (treesit-node-first-child-for-pos doc-node 100) + :type 'args-out-of-range) ;; `treesit-node-descendant-for-range'. (should (equal "(\"{\")" (treesit-node-string @@ -152,6 +154,9 @@ treesit-node-api (treesit-node-string (treesit-node-descendant-for-range root-node 6 7 t)))) + (should-error (treesit-node-descendant-for-range + root-node 100 101) + :type 'args-out-of-range) ;; `treesit-node-eq'. (should (treesit-node-eq root-node root-node)) (should (not (treesit-node-eq root-node doc-node)))))) @@ -167,6 +172,9 @@ treesit-query-api (setq root-node (treesit-parser-root-node parser))) + (should-error (treesit-query-capture root-node "" 100 101) + :type 'args-out-of-range) + ;; Test `treesit-query-capture' on string, sexp and compiled ;; queries. (dolist (query1 commit 1b7ece2095614fc5ff08cfc03641720ba1143100 Author: Jim Porter Date: Fri Dec 9 22:56:24 2022 -0800 ; Fix a failure when running server-tests via the command line * test/lisp/server-tests.el (server-tests/server-force-stop/keeps-frames): Delete every new frame created during the test. On some systems, 'delete-terminal' will delete the frames for us, so this ensures that if there are no new frames, nothing happens. (cherry picked from commit 3785fe52e4692ffef14c0a1e50361c22d66fabe8) diff --git a/test/lisp/server-tests.el b/test/lisp/server-tests.el index ebf84481c61..5ef66052c80 100644 --- a/test/lisp/server-tests.el +++ b/test/lisp/server-tests.el @@ -218,8 +218,8 @@ server-tests/server-force-stop/keeps-frames (eq (terminal-live-p terminal) t) (not (eq system-type 'windows-nt))) (delete-terminal terminal))) - ;; Delete the created frame. - (delete-frame (car (cl-set-difference (frame-list) starting-frames)) - t))) + ;; If there are any new frames remaining, delete them. + (mapc (lambda (frame) (delete-frame frame t)) + (cl-set-difference (frame-list) starting-frames)))) ;;; server-tests.el ends here commit 44c5f3614973d8dc389ddcdc1b3f8ab1c809194d Author: Stefan Kangas Date: Sat Dec 10 10:48:28 2022 +0100 ; Fix two byte-compiler warnings * lisp/gnus/gnus-icalendar.el (gnus-icalendar--show-org-event): * test/lisp/progmodes/project-tests.el (project/quoted-directory): Fix warnings. diff --git a/lisp/gnus/gnus-icalendar.el b/lisp/gnus/gnus-icalendar.el index 1bffdf3513a..f3665c3f1a4 100644 --- a/lisp/gnus/gnus-icalendar.el +++ b/lisp/gnus/gnus-icalendar.el @@ -603,7 +603,7 @@ gnus-icalendar--show-org-event (when file (switch-to-buffer (find-file file)) (goto-char (org-find-entry-with-id (gnus-icalendar-event:uid event))) - (org-show-entry)))) + (org-fold-show-entry)))) (defun gnus-icalendar--update-org-event (event reply-status &optional org-file) diff --git a/test/lisp/progmodes/project-tests.el b/test/lisp/progmodes/project-tests.el index e666e3a6fab..8814f30b047 100644 --- a/test/lisp/progmodes/project-tests.el +++ b/test/lisp/progmodes/project-tests.el @@ -41,7 +41,7 @@ project/quoted-directory (skip-unless (executable-find "grep")) (ert-with-temp-directory directory (let ((default-directory directory) - (project-current-inhibit-prompt t) + (project-current-directory-override t) (project-find-functions nil) (project-list-file (expand-file-name "projects" directory)) commit a8ee046fb500a527d3fa44e69a4bc178d0ae8406 Author: Philip Kaludercic Date: Sat Dec 10 09:47:42 2022 +0100 Ensure 'package-vc--version' always returns a version * lisp/emacs-lisp/package-vc.el (package-vc--version): Return "0" even if the main file exists, but lacks version headers. diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el index b514afe288e..db54e0e130e 100644 --- a/lisp/emacs-lisp/package-vc.el +++ b/lisp/emacs-lisp/package-vc.el @@ -294,7 +294,8 @@ package-vc--version (insert-file-contents main-file) (package-strip-rcs-id (or (lm-header "package-version") - (lm-header "version")))) + (lm-header "version") + "0"))) "0")) (defun package-vc--main-file (pkg-desc) commit 022ab1061b2a5ffebcc1a000386c1a568ac06e2f Author: Philip Kaludercic Date: Sat Dec 10 09:43:22 2022 +0100 Ensure 'package-vc--main-file' always returns an existing file * lisp/emacs-lisp/package-vc.el (require): Explicitly require cl-lib. (package-vc--main-file): If the expected file name is missing, try and find the closest match. diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el index cf9b98308f1..b514afe288e 100644 --- a/lisp/emacs-lisp/package-vc.el +++ b/lisp/emacs-lisp/package-vc.el @@ -50,6 +50,7 @@ (eval-when-compile (require 'rx)) (eval-when-compile (require 'inline)) (eval-when-compile (require 'map)) +(eval-when-compile (require 'cl-lib)) (require 'package) (require 'lisp-mnt) (require 'vc) @@ -299,15 +300,34 @@ package-vc--version (defun package-vc--main-file (pkg-desc) "Return the name of the main file for PKG-DESC." (cl-assert (package-vc-p pkg-desc)) - (let ((pkg-spec (package-vc--desc->spec pkg-desc)) - (name (symbol-name (package-desc-name pkg-desc)))) - (or (plist-get pkg-spec :main-file) - (expand-file-name - (concat name ".el") - (file-name-concat - (or (package-desc-dir pkg-desc) - (expand-file-name name package-user-dir)) - (plist-get pkg-spec :lisp-dir)))))) + (let* ((pkg-spec (package-vc--desc->spec pkg-desc)) + (name (symbol-name (package-desc-name pkg-desc))) + (directory (file-name-concat + (or (package-desc-dir pkg-desc) + (expand-file-name name package-user-dir)) + (plist-get pkg-spec :lisp-dir))) + (file (or (plist-get pkg-spec :main-file) + (expand-file-name + (concat name ".el") + directory)))) + (if (file-exists-p file) file + ;; The following heuristic is only necessary when fetching a + ;; repository with URL that would break the above assumptions. + ;; Concrete example: https://github.com/sachac/waveform-el does + ;; not have a file waveform-el.el, but a file waveform.el, so we + ;; try and find the closest match. + (let ((distance most-positive-fixnum) (best nil)) + (dolist (alt (directory-files directory t "\\.el\\'" t)) + (let ((sd (string-distance file alt))) + (when (and (not (string-match-p (rx (or (: "-autoloads.el") + (: "-pkg.el")) + eos) + alt)) + (< sd distance)) + (when (< sd distance) + (setq distance (string-distance file alt) + best alt))))) + best)))) (defun package-vc--generate-description-file (pkg-desc pkg-file) "Generate a package description file for PKG-DESC and write it to PKG-FILE." commit 357fe91996bc6015af002fe4259a3a61a5f32dbb Author: Philip Kaludercic Date: Fri Dec 9 19:54:25 2022 +0100 Check if package already exists before installing from checkout * lisp/emacs-lisp/package-vc.el (package-vc-install-from-checkout): Copy check from 'package-vc--unpack'. diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el index 80d268c2958..cf9b98308f1 100644 --- a/lisp/emacs-lisp/package-vc.el +++ b/lisp/emacs-lisp/package-vc.el @@ -754,6 +754,10 @@ package-vc-install-from-checkout (package-vc--archives-initialize) (let* ((name (or name (file-name-base (directory-file-name dir)))) (pkg-dir (expand-file-name name package-user-dir))) + (when (file-exists-p pkg-dir) + (if (yes-or-no-p (format "Overwrite previous checkout for package `%s'?" name)) + (package--delete-directory pkg-dir) + (error "There already exists a checkout for %s" name))) (make-symbolic-link (expand-file-name dir) pkg-dir) (package-vc--unpack-1 (package-desc-create commit 5e8bc79f6b22cda99b522dbbdaa116ea62feb48e Author: Philip Kaludercic Date: Fri Dec 9 19:49:44 2022 +0100 ; Fix reference in docstring to 'package-vc-install-from-checkout' * lisp/emacs-lisp/package-vc.el (package-vc-checkout): Fix reference. diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el index 193d7c5b567..80d268c2958 100644 --- a/lisp/emacs-lisp/package-vc.el +++ b/lisp/emacs-lisp/package-vc.el @@ -711,11 +711,11 @@ package-vc-install (defun package-vc-checkout (pkg-desc directory &optional rev) "Clone the sources for PKG-DESC into DIRECTORY and visit that directory. Unlike `package-vc-install', this does not yet set up the package -for use with Emacs; use `package-vc-link-directory' for setting -the package up after this function finishes. -Optional argument REV means to clone a specific version of the -package; it defaults to the last version available from the -package's repository. If REV has the special value +for use with Emacs; use `package-vc-install-from-checkout' for +setting the package up after this function finishes. Optional +argument REV means to clone a specific version of the package; it +defaults to the last version available from the package's +repository. If REV has the special value `:last-release' (interactively, the prefix argument), that stands for the last released version of the package." (interactive commit af88b00b19c155ce566757ccfa9ee2dbe03a705f Author: Matt Armstrong Date: Wed Nov 30 15:58:07 2022 -0800 Refresh the package quickstart file in package-vc * lisp/emacs-lisp/package-vc.el (package-vc--unpack-1): Call `package--quickstart-maybe-refresh', just as `package-install-from-buffer' does. (bug#59728) diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el index 299964c6924..193d7c5b567 100644 --- a/lisp/emacs-lisp/package-vc.el +++ b/lisp/emacs-lisp/package-vc.el @@ -466,6 +466,7 @@ package-vc--unpack-1 (package--save-selected-packages (cons (package-desc-name pkg-desc) package-selected-packages)) + (package--quickstart-maybe-refresh) ;; Confirm that the installation was successful (let ((main-file (package-vc--main-file pkg-desc))) commit 5a092c8e461c4e72aee16bd2884feb824de3bf3a Author: Yuan Fu Date: Fri Dec 9 20:55:43 2022 -0800 ; * admin/notes/tree-sitter/starter-guide (Indent): Minor fix. diff --git a/admin/notes/tree-sitter/starter-guide b/admin/notes/tree-sitter/starter-guide index 123dabd9f29..a6a4c647f23 100644 --- a/admin/notes/tree-sitter/starter-guide +++ b/admin/notes/tree-sitter/starter-guide @@ -282,7 +282,7 @@ For MATHCER we have NODE-INDEX-MIN NODE-INDEX-MAX) => checks everything. If an argument is nil, don’t match that. Eg, - (match nil nil TYPE) is the same as (parent-is TYPE) + (match nil TYPE) is the same as (parent-is TYPE) For ANCHOR we have commit ebef8905b0df9572e80e20fdc8da7829b9270e3f Author: Yuan Fu Date: Wed Dec 7 14:50:16 2022 -0800 Make indirect buffers use tree-sitter parsers of their base buffer Fix the problem described in bug#59693. * src/treesit.c (treesit_record_change): Always use the base buffer. (Ftreesit_parser_create): Always use the base buffer. Also change the for loop into FOR_EACH_TAIL (stylistic change). (Ftreesit_parser_list): Always use the base buffer. * doc/lispref/parsing.texi (Using Parser): Update manual. * test/src/treesit-tests.el (treesit-indirect-buffer): New test. diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi index 3223875320a..af7be2ebf36 100644 --- a/doc/lispref/parsing.texi +++ b/doc/lispref/parsing.texi @@ -409,6 +409,13 @@ Using Parser By default, this function reuses a parser if one already exists for @var{language} in @var{buffer}, but if @var{no-reuse} is non-@code{nil}, this function always creates a new parser. + +If that buffer is an indirect buffer, its base buffer is used instead. +That is, indirect buffers use their base buffer's parsers. If the +base buffer is narrowed, an indirect buffer might not be able to +retrieve information of the portion of the buffer text that are +invisible in the base buffer. Lisp programs should widen as necessary +should they want to use a parser in an indirect buffer. @end defun Given a parser, we can query information about it. @@ -447,7 +454,8 @@ Using Parser @defun treesit-parser-list &optional buffer This function returns the parser list of @var{buffer}. If @var{buffer} is @code{nil} or omitted, it defaults to the current -buffer. +buffer. If that buffer is an indirect buffer, its base buffer is used +instead. That is, indirect buffers use their base buffer's parsers. @end defun @defun treesit-parser-delete parser diff --git a/src/treesit.c b/src/treesit.c index 8b485ca4ece..d361a3da932 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -384,7 +384,18 @@ #define ts_tree_root_node fn_ts_tree_root_node mysteriously drops. 3) what if a user uses so many stuff that the default cache size (20) is not enough and we end up thrashing? These are all imaginary scenarios but they are not impossible - :-) */ + :-) + + Parsers in indirect buffers: We make indirect buffers to share the + parser of its base buffer. Indirect buffers and their base buffer + share the same buffer content but not other buffer attributes. If + they have separate parser lists, changes made in an indirect buffer + will only update parsers of that indirect buffer, and not parsers + in the base buffer or other indirect buffers, and vice versa. We + could keep track of all the base and indirect buffers, and update + all of their parsers, but ultimately decide to take a simpler + approach, which is to make indirect buffers share their base + buffer's parser list. The discussion can be found in bug#59693. */ /*** Initialization */ @@ -697,9 +708,10 @@ treesit_tree_edit_1 (TSTree *tree, ptrdiff_t start_byte, treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, ptrdiff_t new_end_byte) { - Lisp_Object parser_list; - - parser_list = BVAR (current_buffer, ts_parser_list); + struct buffer *base_buffer = current_buffer; + if (current_buffer->base_buffer) + base_buffer = current_buffer->base_buffer; + Lisp_Object parser_list = BVAR (base_buffer, ts_parser_list); FOR_EACH_TAIL_SAFE (parser_list) { @@ -1252,12 +1264,16 @@ DEFUN ("treesit-parser-create", 1, 3, 0, doc: /* Create and return a parser in BUFFER for LANGUAGE. -The parser is automatically added to BUFFER's parser list, as -returned by `treesit-parser-list'. -LANGUAGE is a language symbol. If BUFFER is nil or omitted, it -defaults to the current buffer. If BUFFER already has a parser for -LANGUAGE, return that parser, but if NO-REUSE is non-nil, always -create a new parser. */) +The parser is automatically added to BUFFER's parser list, as returned +by `treesit-parser-list'. LANGUAGE is a language symbol. If BUFFER +is nil or omitted, it defaults to the current buffer. If BUFFER +already has a parser for LANGUAGE, return that parser, but if NO-REUSE +is non-nil, always create a new parser. + +If that buffer is an indirect buffer, its base buffer is used instead. +That is, indirect buffers use their base buffer's parsers. Lisp +programs should widen as necessary should they want to use a parser in +an indirect buffer. */) (Lisp_Object language, Lisp_Object buffer, Lisp_Object no_reuse) { treesit_initialize (); @@ -1271,16 +1287,21 @@ DEFUN ("treesit-parser-create", CHECK_BUFFER (buffer); buf = XBUFFER (buffer); } + if (buf->base_buffer) + buf = buf->base_buffer; + treesit_check_buffer_size (buf); /* See if we can reuse a parser. */ - for (Lisp_Object tail = BVAR (buf, ts_parser_list); - NILP (no_reuse) && !NILP (tail); - tail = XCDR (tail)) + if (NILP (no_reuse)) { - struct Lisp_TS_Parser *parser = XTS_PARSER (XCAR (tail)); - if (EQ (parser->language_symbol, language)) - return XCAR (tail); + Lisp_Object tail = BVAR (buf, ts_parser_list); + FOR_EACH_TAIL (tail) + { + struct Lisp_TS_Parser *parser = XTS_PARSER (XCAR (tail)); + if (EQ (parser->language_symbol, language)) + return XCAR (tail); + } } /* Load language. */ @@ -1329,7 +1350,10 @@ DEFUN ("treesit-parser-list", Ftreesit_parser_list, Streesit_parser_list, 0, 1, 0, doc: /* Return BUFFER's parser list. -BUFFER defaults to the current buffer. */) + +BUFFER defaults to the current buffer. If that buffer is an indirect +buffer, its base buffer is used instead. That is, indirect buffers +use their base buffer's parsers. */) (Lisp_Object buffer) { struct buffer *buf; @@ -1340,6 +1364,9 @@ DEFUN ("treesit-parser-list", CHECK_BUFFER (buffer); buf = XBUFFER (buffer); } + if (buf->base_buffer) + buf = buf->base_buffer; + /* Return a fresh list so messing with that list doesn't affect our internal data. */ Lisp_Object return_list = Qnil; diff --git a/test/src/treesit-tests.el b/test/src/treesit-tests.el index aba12759c34..1cc2217bd3b 100644 --- a/test/src/treesit-tests.el +++ b/test/src/treesit-tests.el @@ -161,6 +161,40 @@ treesit-node-api (should (treesit-node-eq root-node root-node)) (should (not (treesit-node-eq root-node doc-node)))))) +(ert-deftest treesit-indirect-buffer () + "Tests for indirect buffers." + (skip-unless (treesit-language-available-p 'json)) + (let ((base (get-buffer-create "*treesit test*")) + parser indirect) + (unwind-protect + (progn + (with-current-buffer base + (setq indirect (clone-indirect-buffer "*treesit test 1*" nil))) + (with-current-buffer indirect + (setq parser (treesit-parser-create 'json))) + ;; 1. Parser created in the indirect buffer should be + ;; actually be created in the base buffer. + (with-current-buffer base + (should (equal (list parser) + (treesit-parser-list))) + (insert "[1,2,3]")) + ;; Change in the base buffer should be reflected in the + ;; indirect buffer. + (with-current-buffer indirect + (should (eq (treesit-node-end + (treesit-buffer-root-node)) + 8)) + (erase-buffer)) + ;; Change in the indirect buffer should be reflected in the + ;; base buffer. + (with-current-buffer base + (should (eq (treesit-node-end + (treesit-buffer-root-node)) + 1)) + (erase-buffer))) + (kill-buffer base) + (kill-buffer indirect)))) + (ert-deftest treesit-query-api () "Tests for query API." (skip-unless (treesit-language-available-p 'json)) commit 8f53fa10d9453f36aa601e5943cb903adeacc7fe Author: Brian Leung Date: Fri Dec 9 03:09:31 2022 -0800 Fontify "this" as a keyword in c++-ts-mode (bug#59924) * lisp/progmodes/c-ts-mode.el (c-ts-mode--font-lock-settings): Following c++-mode, fontify as a keyword instead of a constant. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 7b41718a745..824325d83e0 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -234,14 +234,14 @@ c-ts-mode--font-lock-settings (false) @font-lock-constant-face (null) @font-lock-constant-face ,@(when (eq mode 'cpp) - '((this) @font-lock-constant-face - (nullptr) @font-lock-constant-face))) + '((nullptr) @font-lock-constant-face))) :language mode :feature 'keyword `([,@(c-ts-mode--keywords mode)] @font-lock-keyword-face ,@(when (eq mode 'cpp) - '((auto) @font-lock-keyword-face))) + '((auto) @font-lock-keyword-face + (this) @font-lock-keyword-face))) :language mode :feature 'operator commit 8de8f1dc05198ea9a1106ac2282acc9c93ee1ebd Author: Theodor Thornhill Date: Tue Nov 29 16:12:18 2022 +0100 Add class_body indentation for typescript (bug#59680) * lisp/progmodes/typescript-ts-mode.el (typescript-ts-mode--indent-rules): New indent rule. diff --git a/lisp/progmodes/typescript-ts-mode.el b/lisp/progmodes/typescript-ts-mode.el index c4a5bd37e05..8c4364ecc5b 100644 --- a/lisp/progmodes/typescript-ts-mode.el +++ b/lisp/progmodes/typescript-ts-mode.el @@ -89,6 +89,7 @@ typescript-ts-mode--indent-rules ((parent-is "object") parent-bol typescript-ts-mode-indent-offset) ((parent-is "object_type") parent-bol typescript-ts-mode-indent-offset) ((parent-is "enum_body") parent-bol typescript-ts-mode-indent-offset) + ((parent-is "class_body") parent-bol typescript-ts-mode-indent-offset) ((parent-is "arrow_function") parent-bol typescript-ts-mode-indent-offset) ((parent-is "parenthesized_expression") parent-bol typescript-ts-mode-indent-offset) commit 839341d73707be2082abbd8834ba46292e59aeb7 Author: Theodor Thornhill Date: Wed Dec 7 10:07:37 2022 +0100 Make more granular defun-type-regexp (bug#59873) We don't want to match local_variable_declaration and others to hit on beginning-of-defun. The fix is just to make the regexp a bit more granular. * lisp/progmodes/java-ts-mode.el (java-ts-mode): Use regexp-opt to distinguish more granularly. diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el index 23e166ee4c3..9155a7fff25 100644 --- a/lisp/progmodes/java-ts-mode.el +++ b/lisp/progmodes/java-ts-mode.el @@ -321,7 +321,15 @@ java-ts-mode (append "{}():;," electric-indent-chars)) ;; Navigation. - (setq-local treesit-defun-type-regexp "declaration") + (setq-local treesit-defun-type-regexp + (regexp-opt '("method_declaration" + "class_declaration" + "record_declaration" + "interface_declaration" + "enum_declaration" + "import_declaration" + "package_declaration" + "module_declaration"))) ;; Font-lock. (setq-local treesit-font-lock-settings java-ts-mode--font-lock-settings) commit 8f49137c9bf614b285c19a3a845c7606fcba23a4 Author: Randy Taylor Date: Wed Dec 7 20:53:35 2022 -0500 Add dockerfile-ts-mode (Bug#59894) * admin/notes/tree-sitter/build-module/batch.sh: Add dockerfile support. * admin/notes/tree-sitter/build-module/build.sh: Support different namespaces and add dockerfile support. * etc/NEWS: Mention it. * lisp/progmodes/dockerfile-ts-mode.el: New major mode with tree-sitter support. * lisp/progmodes/eglot.el (eglot-server-programs): Add it. diff --git a/admin/notes/tree-sitter/build-module/batch.sh b/admin/notes/tree-sitter/build-module/batch.sh index d45f37f4b64..6dce000caa6 100755 --- a/admin/notes/tree-sitter/build-module/batch.sh +++ b/admin/notes/tree-sitter/build-module/batch.sh @@ -5,6 +5,7 @@ languages= 'cpp' 'css' 'c-sharp' + 'dockerfile' 'go' 'html' 'javascript' diff --git a/admin/notes/tree-sitter/build-module/build.sh b/admin/notes/tree-sitter/build-module/build.sh index d562f1a7846..cc31e3f6f02 100755 --- a/admin/notes/tree-sitter/build-module/build.sh +++ b/admin/notes/tree-sitter/build-module/build.sh @@ -14,11 +14,15 @@ topdir= ### Retrieve sources +namespace="tree-sitter" repo="tree-sitter-${lang}" sourcedir="tree-sitter-${lang}/src" grammardir="tree-sitter-${lang}" case "${lang}" in + "dockerfile") + namespace="camdencheek" + ;; "typescript") sourcedir="tree-sitter-typescript/typescript/src" grammardir="tree-sitter-typescript/typescript" @@ -30,7 +34,7 @@ grammardir= ;; esac -git clone "https://github.com/tree-sitter/${repo}.git" \ +git clone "https://github.com/${namespace}/${repo}.git" \ --depth 1 --quiet cp "${grammardir}"/grammar.js "${sourcedir}" # We have to go into the source directory to compile, because some diff --git a/etc/NEWS b/etc/NEWS index e4a19e29869..233ef3f5729 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3068,6 +3068,11 @@ A major mode based on the tree-sitter library for editing Bash shell scripts. It includes support for font-locking, indentation, Imenu, which-func, and navigation. +** New major mode 'dockerfile-ts-mode'. +A major mode based on the tree-sitter library for editing +Dockerfiles. It includes support for font-locking, indentation, Imenu, +and which-func. + * Incompatible Lisp Changes in Emacs 29.1 diff --git a/lisp/progmodes/dockerfile-ts-mode.el b/lisp/progmodes/dockerfile-ts-mode.el new file mode 100644 index 00000000000..e08387ad969 --- /dev/null +++ b/lisp/progmodes/dockerfile-ts-mode.el @@ -0,0 +1,176 @@ +;;; dockerfile-ts-mode.el --- tree-sitter support for Dockerfiles -*- lexical-binding: t; -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; Author : Randy Taylor +;; Maintainer : Randy Taylor +;; Created : December 2022 +;; Keywords : dockerfile languages tree-sitter + +;; 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: +;; + +;;; Code: + +(require 'treesit) +(eval-when-compile (require 'rx)) + +(declare-function treesit-parser-create "treesit.c") +(declare-function treesit-induce-sparse-tree "treesit.c") +(declare-function treesit-node-child "treesit.c") +(declare-function treesit-node-start "treesit.c") +(declare-function treesit-node-type "treesit.c") + +(defvar dockerfile-ts-mode--syntax-table + (let ((table (make-syntax-table))) + (modify-syntax-entry ?# "<" table) + (modify-syntax-entry ?\n ">" table) + table) + "Syntax table for `dockerfile-ts-mode'.") + +(defvar dockerfile-ts-mode--indent-rules + `((dockerfile + ((parent-is "copy_instruction") (nth-sibling 1) 0) + ((parent-is "env_instruction") (nth-sibling 1) 0) + ((parent-is "expose_instruction") (nth-sibling 1) 0) + ((parent-is "label_instruction") (nth-sibling 1) 0) + ((parent-is "shell_command") first-sibling 0) + ((parent-is "string_array") first-sibling 1))) + "Tree-sitter indent rules.") + +(defvar dockerfile-ts-mode--keywords + '("ADD" "ARG" "AS" "CMD" "COPY" "CROSS_BUILD" "ENTRYPOINT" "ENV" + "EXPOSE" "FROM" "HEALTHCHECK" "LABEL" "MAINTAINER" "ONBUILD" "RUN" + "SHELL" "STOPSIGNAL" "USER" "VOLUME" "WORKDIR") + "Dockerfile keywords for tree-sitter font-locking.") + +(defvar dockerfile-ts-mode--font-lock-settings + (treesit-font-lock-rules + :language 'dockerfile + :feature 'bracket + '((["[" "]"]) @font-lock-bracket-face) + + :language 'dockerfile + :feature 'comment + '((comment) @font-lock-comment-face) + + :language 'dockerfile + :feature 'delimiter + '(([","]) @font-lock-delimiter-face) + + :language 'dockerfile + :feature 'image-spec + '((image_spec) @font-lock-constant-face) + + :language 'dockerfile + :feature 'keyword + `([,@dockerfile-ts-mode--keywords] @font-lock-keyword-face) + + :language 'dockerfile + :feature 'number + '((expose_port) @font-lock-number-face) + + :language 'dockerfile + :feature 'operator + '((["="]) @font-lock-operator-face) + + :language 'dockerfile + :feature 'string + '((double_quoted_string) @font-lock-string-face) + + :language 'dockerfile + :feature 'error + :override t + '((ERROR) @font-lock-warning-face)) + "Tree-sitter font-lock settings.") + +(defun dockerfile-ts-mode--imenu () + "Return Imenu alist for the current buffer." + (let* ((node (treesit-buffer-root-node)) + (stage-tree (treesit-induce-sparse-tree + node "from_instruction" + nil 1000))) + `(("Stage" . ,(dockerfile-ts-mode--imenu-1 stage-tree))))) + +(defun dockerfile-ts-mode--imenu-1 (node) + "Helper for `dockerfile-ts-mode--imenu'. +Find string representation for NODE and set marker, then recurse +the subtrees." + (let* ((ts-node (car node)) + (children (cdr node)) + (subtrees (mapcan #'dockerfile-ts-mode--imenu-1 + children)) + (name (when ts-node + (pcase (treesit-node-type ts-node) + ("from_instruction" (treesit-node-text + (treesit-node-child ts-node 1) t))))) + (marker (when ts-node + (set-marker (make-marker) + (treesit-node-start ts-node))))) + (cond + ((or (null ts-node) (null name)) subtrees) + (subtrees + `((,name ,(cons name marker) ,@subtrees))) + (t + `((,name . ,marker)))))) + +;;;###autoload +(add-to-list 'auto-mode-alist + `(,(rx (| + (: "Dockerfile" (? "." (* nonl))) + (: "." (any "dD") "ockerfile")) + eol) + . dockerfile-ts-mode)) + +;;;###autoload +(define-derived-mode dockerfile-ts-mode prog-mode "Dockerfile" + "Major mode for editing Dockerfiles, powered by tree-sitter." + :group 'dockerfile + :syntax-table dockerfile-ts-mode--syntax-table + + (when (treesit-ready-p 'dockerfile) + (treesit-parser-create 'dockerfile) + + ;; Comments. + (setq-local comment-start "# ") + (setq-local comment-end "") + (setq-local comment-start-skip (rx "#" (* (syntax whitespace)))) + + ;; Imenu. + (setq-local imenu-create-index-function + #'dockerfile-ts-mode--imenu) + (setq-local which-func-functions nil) + + ;; Indent. + (setq-local treesit-simple-indent-rules + dockerfile-ts-mode--indent-rules) + + ;; Font-lock. + (setq-local treesit-font-lock-settings + dockerfile-ts-mode--font-lock-settings) + (setq-local treesit-font-lock-feature-list + '((comment) + (keyword string) + (image-spec number) + (bracket delimiter error operator))) + + (treesit-major-mode-setup))) + +(provide 'dockerfile-ts-mode) + +;;; dockerfile-ts-mode.el ends here diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index a53f62fc565..2ef022992e7 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -236,7 +236,7 @@ eglot-server-programs . ,(eglot-alternatives '(("vscode-css-language-server" "--stdio") ("css-languageserver" "--stdio")))) (html-mode . ,(eglot-alternatives '(("vscode-html-language-server" "--stdio") ("html-languageserver" "--stdio")))) - (dockerfile-mode . ("docker-langserver" "--stdio")) + ((dockerfile-mode dockerfile-ts-mode) . ("docker-langserver" "--stdio")) ((clojure-mode clojurescript-mode clojurec-mode) . ("clojure-lsp")) ((csharp-mode csharp-ts-mode) commit 1014bcc8e32c8ab7b25e148d13e7e3a82f9635b9 Author: Jostein Kjønigsen Date: Thu Dec 8 15:45:00 2022 +0100 Fix fontification of method-invocations in js-ts-mode (bug#59904) * lisp/progmodes/js.el (js--treesit-font-lock-settings): Move rules for property in front of function names, so function names override property. diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 45dfef372cd..f7318c481a2 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -3543,6 +3543,20 @@ js--treesit-font-lock-settings (arrow_function parameter: (identifier) @font-lock-variable-name-face)) + :language 'javascript + :override t + :feature 'property + ;; This needs to be before function-name feature, because methods + ;; can be both property and function-name, and we want them in + ;; function-name face. + `((property_identifier) @font-lock-property-face + + (pair value: (identifier) @font-lock-variable-name-face) + + ((shorthand_property_identifier) @font-lock-property-face) + + ((shorthand_property_identifier_pattern) @font-lock-property-face)) + :language 'javascript :override t :feature 'expression @@ -3611,18 +3625,7 @@ js--treesit-font-lock-settings :language 'javascript :feature 'escape-sequence :override t - '((escape_sequence) @font-lock-escape-face) - - :language 'javascript - :override t - :feature 'property - `((property_identifier) @font-lock-property-face - - (pair value: (identifier) @font-lock-variable-name-face) - - ((shorthand_property_identifier) @font-lock-property-face) - - ((shorthand_property_identifier_pattern) @font-lock-property-face))) + '((escape_sequence) @font-lock-escape-face)) "Tree-sitter font-lock settings.") (defun js--fontify-template-string (node override start end &rest _) commit 7141920c6afdd9ead4a94f2a3314a8c1097d1b6b Author: Theodor Thornhill Date: Thu Dec 8 16:17:49 2022 +0100 Fix escape-sequence feature in typescript-ts-mode (bug#59906) * lisp/progmodes/typescript-ts-mode.el: (typescript-ts-mode, tsx-ts-mode): Use escape-sequence feature. diff --git a/lisp/progmodes/typescript-ts-mode.el b/lisp/progmodes/typescript-ts-mode.el index 243f6146ae7..c4a5bd37e05 100644 --- a/lisp/progmodes/typescript-ts-mode.el +++ b/lisp/progmodes/typescript-ts-mode.el @@ -361,8 +361,7 @@ typescript-ts-mode (setq-local treesit-font-lock-settings (typescript-ts-mode--font-lock-settings 'typescript)) (setq-local treesit-font-lock-feature-list - '((comment declaration) - (keyword string) + '((comment declaration keyword string escape-sequence) (constant expression identifier number pattern property) (bracket delimiter))) @@ -396,8 +395,7 @@ tsx-ts-mode (setq-local treesit-font-lock-settings (typescript-ts-mode--font-lock-settings 'tsx)) (setq-local treesit-font-lock-feature-list - '((comment declaration) - (keyword string) + '((comment declaration keyword string escape-sequence) (constant expression identifier jsx number pattern property) (bracket delimiter))) commit 4df35e3491cd82ff3ea08f05ded23cb89abadece Author: Jostein Kjønigsen Date: Thu Dec 8 20:36:49 2022 +0100 Improve fontification in csharp-ts-mode (bug#59909) - Fontity escape sequences. - Highlight syntax errors. * lisp/progmodes/csharp-mode.el (csharp-ts-mode--font-lock-settings) (csharp-ts-mode): Add new features diff --git a/lisp/progmodes/csharp-mode.el b/lisp/progmodes/csharp-mode.el index d0465b26f05..8a7313b1ce8 100644 --- a/lisp/progmodes/csharp-mode.el +++ b/lisp/progmodes/csharp-mode.el @@ -818,7 +818,13 @@ csharp-ts-mode--font-lock-settings :language 'c-sharp :feature 'delimiter - '((["," ":" ";"]) @font-lock-delimiter-face))) + '((["," ":" ";"]) @font-lock-delimiter-face) + + :language 'c-sharp + :feature 'escape-sequence + :override t + '((escape_sequence) @font-lock-escape-face + (ERROR) @font-lock-warning-face))) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-mode)) @@ -926,7 +932,7 @@ csharp-ts-mode (setq-local treesit-font-lock-settings csharp-ts-mode--font-lock-settings) (setq-local treesit-font-lock-feature-list '(( comment definition) - ( keyword string type) + ( keyword string escape-sequence type) ( attribute constant expression literal) ( bracket delimiter))) commit 33a8415eb7e2f5baebffc529a422fb17dc3fd09e Author: Dmitry Gutov Date: Fri Dec 9 23:21:10 2022 +0200 Use 'project--value-in-dir' for 'project-vc-include-untracked' too * lisp/progmodes/project.el (project--vc-list-files): Use 'project--value-in-dir' for 'project-vc-include-untracked' too. So that is can be reliably set through dir-locals. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 342ee239c7e..016dfdd5b4d 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -609,13 +609,16 @@ project--vc-list-files (defvar vc-git-use-literal-pathspecs) (pcase backend (`Git - (let ((default-directory (expand-file-name (file-name-as-directory dir))) - (args '("-z")) - (vc-git-use-literal-pathspecs nil) - files) + (let* ((default-directory (expand-file-name (file-name-as-directory dir))) + (args '("-z")) + (vc-git-use-literal-pathspecs nil) + (include-untracked (project--value-in-dir + 'project-vc-include-untracked + dir)) + files) (setq args (append args '("-c" "--exclude-standard") - (and project-vc-include-untracked '("-o")))) + (and include-untracked '("-o")))) (when extra-ignores (setq args (append args (cons "--" @@ -666,10 +669,13 @@ project--vc-list-files ;; XXX: Better solutions welcome, but this seems cheap enough. (delete-consecutive-dups files))) (`Hg - (let ((default-directory (expand-file-name (file-name-as-directory dir))) - (args (list (concat "-mcard" (and project-vc-include-untracked "u")) - "--no-status" - "-0"))) + (let* ((default-directory (expand-file-name (file-name-as-directory dir))) + (include-untracked (project--value-in-dir + 'project-vc-include-untracked + dir)) + (args (list (concat "-mcard" (and include-untracked "u")) + "--no-status" + "-0"))) (when extra-ignores (setq args (nconc args (mapcan commit 594267395d5b082d14d3009278213f1dbe91cd46 Author: Eli Zaretskii Date: Fri Dec 9 22:02:03 2022 +0200 Update Turkish Hello * etc/HELLO (Turkish): * lisp/language/european.el ("Turkish"): Add a Turkish Hello. Suggested by YUSUF ALPER ÇIKIŞIR . diff --git a/etc/HELLO b/etc/HELLO index 7bc12063f8e..fbe65a451e1 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -114,7 +114,7 @@ Thai (ภาษาไทย) สวัสดีครับ / สวัสดี Tibetan (བོད་སྐད་) བཀྲ་ཤིས་བདེ་ལེགས༎ Tigrigna (ትግርኛ) ሰላማት Tirhuta (𑒞𑒱𑒩𑒯𑒳𑒞𑒰) 𑒣𑓂𑒩𑒢𑒰𑒧 / 𑒮𑒲𑒞𑒰𑒩𑒰𑒧 -Turkish (Türkçe) Merhaba +Turkish (Türkçe) Esenlikler / Merhaba Ukrainian (українська) Вітаю / Добрий день! / Привіт Vietnamese (tiếng Việt) Chào bạn Wancho (𞋒𞋀𞋉𞋃𞋕) 𞋂𞋈𞋛 diff --git a/lisp/language/european.el b/lisp/language/european.el index 937215074bc..18b72bd3b2b 100644 --- a/lisp/language/european.el +++ b/lisp/language/european.el @@ -585,7 +585,7 @@ 'ibm437 (nonascii-translation . iso-8859-9) (unibyte-display . iso-latin-5) (input-method . "turkish-postfix") - (sample-text . "Turkish (Türkçe) Merhaba") + (sample-text . "Turkish (Türkçe) Esenlikler / Merhaba") (setup-function . turkish-case-conversion-enable) (exit-function . turkish-case-conversion-disable) (documentation . "Support for Turkish. commit 940d9070e97858fdb6c0d84fc5617b8c10dab0ba Author: Philipp Stephani Date: Fri Dec 9 19:32:14 2022 +0100 Support newer glib versions (Bug#59061) * lib-src/seccomp-filter.c (main): Allow pidfd_open system call diff --git a/lib-src/seccomp-filter.c b/lib-src/seccomp-filter.c index 7e54b878a22..69b56aed5c5 100644 --- a/lib-src/seccomp-filter.c +++ b/lib-src/seccomp-filter.c @@ -342,6 +342,8 @@ main (int argc, char **argv) RULE (SCMP_ACT_ALLOW, SCMP_SYS (eventfd2)); RULE (SCMP_ACT_ALLOW, SCMP_SYS (wait4)); RULE (SCMP_ACT_ALLOW, SCMP_SYS (poll)); + RULE (SCMP_ACT_ALLOW, SCMP_SYS (pidfd_open), + SCMP_A1_32 (SCMP_CMP_EQ, 0)); /* Don't allow creating sockets (network access would be extremely dangerous), but also don't crash. */ commit 0bd26abf7fbcfdc6068cdbd9da278cf0bd97eacc Author: Eli Zaretskii Date: Fri Dec 9 18:21:38 2022 +0200 ; * doc/misc/use-package.texi: Fix @file. diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 3dabea4eea1..d3b6ee99003 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -1273,7 +1273,7 @@ Modes and interpreters The following example reproduces the default @code{ruby-mode} configuration, exactly as it is in Emacs out-of-the-box. That mode is enabled automatically when a file whose name matches the regexp -@code{"\\.rb\\'"} (a file with the @samp{.rb} extension), or when the +@code{"\\.rb\\'"} (a file with the @file{.rb} extension), or when the first line of the file (known as the ``shebang'') matches the string @code{"ruby"}: commit bcf235acd58dfc0d335114c18bcf9299f5155d36 Merge: 2ea7a357fd1 d268ab1c5d7 Author: Eli Zaretskii Date: Fri Dec 9 18:21:31 2022 +0200 Merge branch 'emacs-29' of git.savannah.gnu.org:/srv/git/emacs into emacs-29 commit 2ea7a357fd1ed9de89ee506a3810e644a2d847fd Author: Eli Zaretskii Date: Fri Dec 9 18:20:04 2022 +0200 ; * doc/misc/use-package.texi: Fix @acronym. diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index daf27ec5bbc..3dabea4eea1 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -190,7 +190,7 @@ Getting Started that will slow down Emacs startup. Instead, you should try to set things up so that packages are only loaded when they are actually needed (a.k.a. ``autoloading''). If you have installed a package from -@acronym{GNU ELPA} that provides it's own autoloads, it is often +@acronym{GNU} @acronym{ELPA} that provides it's own autoloads, it is often enough to say: @lisp commit d268ab1c5d749d0f15474f9d200bc0356ad85765 Author: Dmitry Gutov Date: Fri Dec 9 18:15:49 2022 +0200 Bring back the project--value-in-dir logic Essentialy revert commit 2389158a31b4a12, restoring the changes and fixing the conflicts. Motivated by the problem brought up in bug#59722 (behavior of project-find-files/regexp when switching projects). We should find other ways to improve performance. * lisp/progmodes/project.el (project--value-in-dir, project--vc-merge-submodules-p): Restore. (project-try-vc, project-files, project--vc-list-files) (project-ignores, project-buffers): Use. * test/lisp/progmodes/project-tests.el (project-vc-supports-project-in-different-dir): New test. * test/lisp/progmodes/project-resources/.dir-locals.el: * test/lisp/progmodes/project-resources/foo: * test/lisp/progmodes/project-resources/etc: New files. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 38d4fdad5fc..342ee239c7e 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -515,7 +515,8 @@ project-try-vc (marker-re (mapconcat (lambda (m) (format "\\(%s\\)" (wildcard-to-regexp m))) - (append backend-markers project-vc-extra-root-markers) + (append backend-markers + (project--value-in-dir 'project-vc-extra-root-markers dir)) "\\|")) (locate-dominating-stop-dir-regexp (or vc-ignore-dir-regexp locate-dominating-stop-dir-regexp)) @@ -535,7 +536,7 @@ project-try-vc project) (when (and (eq backend 'Git) - project-vc-merge-submodules + (project--vc-merge-submodules-p root) (project--submodule-p root)) (let* ((parent (file-name-directory (directory-file-name root)))) (setq root (vc-call-backend 'Git 'root parent)))) @@ -582,7 +583,7 @@ project-external-roots (cl-defmethod project-files ((project (head vc)) &optional dirs) (mapcan (lambda (dir) - (let ((ignores project-vc-ignores) + (let ((ignores (project--value-in-dir 'project-vc-ignores (nth 2 project))) (backend (cadr project))) (when backend (require (intern (concat "vc-" (downcase (symbol-name backend)))))) @@ -647,7 +648,7 @@ project--vc-list-files (split-string (apply #'vc-git--run-command-string nil "ls-files" args) "\0" t))) - (when project-vc-merge-submodules + (when (project--vc-merge-submodules-p default-directory) ;; Unfortunately, 'ls-files --recurse-submodules' conflicts with '-o'. (let* ((submodules (project--git-submodules)) (sub-files @@ -681,6 +682,11 @@ project--vc-list-files (lambda (s) (concat default-directory s)) (split-string (buffer-string) "\0" t))))))) +(defun project--vc-merge-submodules-p (dir) + (project--value-in-dir + 'project-vc-merge-submodules + dir)) + (defun project--git-submodules () ;; 'git submodule foreach' is much slower. (condition-case nil @@ -722,7 +728,7 @@ project-ignores (condition-case nil (vc-call-backend backend 'ignore-completion-table root) (vc-not-supported () nil))))) - project-vc-ignores + (project--value-in-dir 'project-vc-ignores root) (mapcar (lambda (dir) (concat dir "/")) @@ -753,9 +759,16 @@ project-subtract-directories ;; Sidestep the issue of expanded/abbreviated file names here. (cl-set-difference files dirs :test #'file-in-directory-p)) +(defun project--value-in-dir (var dir) + (with-temp-buffer + (setq default-directory dir) + (let ((enable-local-variables :all)) + (hack-dir-local-variables-non-file-buffer)) + (symbol-value var))) + (cl-defmethod project-buffers ((project (head vc))) (let* ((root (expand-file-name (file-name-as-directory (project-root project)))) - (modules (unless (or project-vc-merge-submodules + (modules (unless (or (project--vc-merge-submodules-p root) (project--submodule-p root)) (mapcar (lambda (m) (format "%s%s/" root m)) diff --git a/test/lisp/progmodes/project-resources/.dir-locals.el b/test/lisp/progmodes/project-resources/.dir-locals.el new file mode 100644 index 00000000000..a311b7efa9a --- /dev/null +++ b/test/lisp/progmodes/project-resources/.dir-locals.el @@ -0,0 +1 @@ +((nil . ((project-vc-ignores . ("etc"))))) diff --git a/test/lisp/progmodes/project-resources/etc b/test/lisp/progmodes/project-resources/etc new file mode 100644 index 00000000000..dd7999bd3dd --- /dev/null +++ b/test/lisp/progmodes/project-resources/etc @@ -0,0 +1 @@ +etc \ No newline at end of file diff --git a/test/lisp/progmodes/project-resources/foo b/test/lisp/progmodes/project-resources/foo new file mode 100644 index 00000000000..19102815663 --- /dev/null +++ b/test/lisp/progmodes/project-resources/foo @@ -0,0 +1 @@ +foo \ No newline at end of file diff --git a/test/lisp/progmodes/project-tests.el b/test/lisp/progmodes/project-tests.el index c3b886873d3..e666e3a6fab 100644 --- a/test/lisp/progmodes/project-tests.el +++ b/test/lisp/progmodes/project-tests.el @@ -139,4 +139,17 @@ project-vc-extra-root-markers-supports-wildcards (should-not (null project)) (should (string-match-p "/test/lisp/\\'" (project-root project))))) +(ert-deftest project-vc-supports-project-in-different-dir () + "Check that it picks up dir-locals settings from somewhere else." + (skip-unless (eq (vc-responsible-backend default-directory) 'Git)) + (let* ((dir (ert-resource-directory)) + (_ (vc-file-clearprops dir)) + (project-vc-extra-root-markers '(".dir-locals.el")) + (project (project-current nil dir))) + (should-not (null project)) + (should (string-match-p "/test/lisp/progmodes/project-resources/\\'" (project-root project))) + (should (member "etc" (project-ignores project dir))) + (should (equal '(".dir-locals.el" "foo") + (mapcar #'file-name-nondirectory (project-files project)))))) + ;;; project-tests.el ends here commit fa36b5ddf58d7b0ef47bd908eb49b3ac8964311d Author: Andrea Corallo Date: Thu Dec 8 16:40:54 2022 +0100 Backport: Enable native speed 2 EMBA build and tests and disable speed 0 * test/infra/gitlab-ci.yml (build-native-comp-speed2): Uncomment. (build-native-comp-speed0): Comment. (test-native-comp-speed0): Remove. (test-native-comp-speed2): Add. (cherry picked from commit 06bf218f69a62d5d5c8d3b3767d7db8d9fb4bb9f) diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml index 64b47eb7e47..96fe9e3a1c3 100644 --- a/test/infra/gitlab-ci.yml +++ b/test/infra/gitlab-ci.yml @@ -246,32 +246,32 @@ test-gnustep: target: emacs-gnustep make_params: install -build-native-comp-speed0: - stage: native-comp-images - extends: [.job-template, .build-template, .native-comp-template] - variables: - target: emacs-native-comp-speed0 - -# build-native-comp-speed1: +# build-native-comp-speed0: # stage: native-comp-images # extends: [.job-template, .build-template, .native-comp-template] # variables: -# target: emacs-native-comp-speed1 +# target: emacs-native-comp-speed0 -# build-native-comp-speed2: +# build-native-comp-speed1: # stage: native-comp-images # extends: [.job-template, .build-template, .native-comp-template] # variables: -# target: emacs-native-comp-speed2 +# target: emacs-native-comp-speed1 + +build-native-comp-speed2: + stage: native-comp-images + extends: [.job-template, .build-template, .native-comp-template] + variables: + target: emacs-native-comp-speed2 -test-native-comp-speed0: +test-native-comp-speed2: stage: native-comp extends: [.job-template, .test-template, .native-comp-template] needs: - - job: build-native-comp-speed0 + - job: build-native-comp-speed2 optional: true variables: - target: emacs-native-comp-speed0 + target: emacs-native-comp-speed2 make_params: "-k -C test check SELECTOR='(not (tag :unstable))'" # Local Variables: commit 6a9e38f22c6dc4ad0c4800338e072f88c00956ec Author: Michael Albinus Date: Fri Dec 9 15:53:49 2022 +0100 * test/infra/test-jobs.yml: Regenerate for the new use-package subdirectory. diff --git a/test/infra/test-jobs.yml b/test/infra/test-jobs.yml index 51707c181b1..55ce590af89 100644 --- a/test/infra/test-jobs.yml +++ b/test/infra/test-jobs.yml @@ -493,6 +493,23 @@ test-lisp-url-inotify: target: emacs-inotify make_params: "-k -C test check-lisp-url" +test-lisp-use-package-inotify: + stage: normal + extends: [.job-template, .test-template] + needs: + - job: build-image-inotify + optional: true + rules: + - if: '$CI_PIPELINE_SOURCE == "schedule"' + when: never + - changes: + - lisp/use-package/*.el + - test/lisp/use-package/*.el + - test/lisp/use-package/*resources/** + variables: + target: emacs-inotify + make_params: "-k -C test check-lisp-use-package" + test-lisp-vc-inotify: stage: normal extends: [.job-template, .test-template] commit 5fbd12ff49410bbc150e677b527ca4939ffcaf5f Author: Michael Albinus Date: Fri Dec 9 15:53:00 2022 +0100 Adapt manual names in emacs-news-mode * lisp/textmodes/emacs-news-mode.el (emacs-news--buttonize): Allow hyphen in manual names. diff --git a/lisp/textmodes/emacs-news-mode.el b/lisp/textmodes/emacs-news-mode.el index ebb31da9cf4..26f8f610eff 100644 --- a/lisp/textmodes/emacs-news-mode.el +++ b/lisp/textmodes/emacs-news-mode.el @@ -226,7 +226,7 @@ emacs-news--buttonize ;; Do manual references. (goto-char (point-min)) (search-forward "\f" nil t) - (while (re-search-forward "\"\\(([a-z0-9]+)[ \n][^\"]\\{1,80\\}\\)\"" + (while (re-search-forward "\"\\(([a-z0-9-]+)[ \n][^\"]\\{1,80\\}\\)\"" nil t) (buttonize-region (match-beginning 1) (match-end 1) (lambda (node) (info node)) commit b36bc6926715de72bc84303c95772c06c29b33db Author: Michael Albinus Date: Fri Dec 9 15:51:48 2022 +0100 ; * etc/NEWS: Fix typos. diff --git a/etc/NEWS b/etc/NEWS index 67711fd7666..e4a19e29869 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2002,14 +2002,14 @@ After Emacs 29.1, some aspects of EUDC will be deprecated. The goal of these deprecations is to simplify EUDC server configuration by making 'eudc-server-hotlist' the only place to add servers. There will not be a need to set the server using the 'eudc-set-server' -function. Instead, the 'eudc-server-hotlist' variable should be +command. Instead, the 'eudc-server-hotlist' user option should be customized to have an entry for the server. The plan is to obsolete -the 'eudc-hotlist' editor since Customize is sufficient for changing -'eudc-server-hotlist'. How the 'eudc-server' variable works in this +the 'eudc-hotlist' package since Customize is sufficient for changing +'eudc-server-hotlist'. How the 'eudc-server' user option works in this context is to-be-determined; it can't be removed, because that would break compatibility, but it may become synchronized with -'eudc-server-hotlist' so that 'eudc-server' is always equal to (first -eudc-server-hotlist). The first entry in 'eudc-server-hotlist' is the +'eudc-server-hotlist' so that 'eudc-server' is always equal to '(car +eudc-server-hotlist)'. The first entry in 'eudc-server-hotlist' is the first server tried by 'eudc-expand-try-all'. The hotlist simplification will allow 'eudc-query-form' to show a drop down of possible servers, instead of requiring a call to 'eudc-set-server' @@ -2967,7 +2967,7 @@ Protocol (LSP). use-package is shipped with Emacs. It provides the 'use-package' macro, which allows you to isolate package configuration in your init file in a way that is declarative, tidy, and performance-oriented. -See the new Info manual 'use-package' for more. +See the new Info manual "(use-package) Top" for more. +++ ** New commands 'image-crop' and 'image-cut'. @@ -3017,13 +3017,13 @@ when visiting JSON files. A major mode based on the tree-sitter library for editing programs in the TypeScript language. It includes support for font-locking, indentation, and navigation. This mode will be auto-enabled for -files with the '.ts' extension. +files with the ".ts" extension. ** New major mode 'tsx-ts-mode'. A major mode based on the tree-sitter library for editing programs in the TypeScript language, with support for TSX. It includes support for font-locking, indentation, and navigation. This mode -will be auto-enabled for files with the '.tsx' extension. +will be auto-enabled for files with the ".tsx" extension. ** New major mode 'c-ts-mode'. A major mode based on the tree-sitter library for editing programs @@ -4418,7 +4418,7 @@ variable for compatibility but its limiting powers have been taken away. This function returns a completion table designed to ease communication between Emacs's completion facilities and external tools offering completion services, particularly tools whose full working -set is too big to transfer to Emacs's every time a completion is +set is too big to transfer to Emacs every time a completion is needed. The table uses new 'external' completion style exclusively and cannot work with regular styles such as 'basic' or 'flex'. commit f626b9f385686affd174f267713b9dfafdea9e08 Author: Eli Zaretskii Date: Fri Dec 9 16:50:13 2022 +0200 ; * doc/misc/use-package.texi: Fix indexing. diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 53abd4519d3..daf27ec5bbc 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -838,7 +838,6 @@ Best practices @node Key bindings @section Key bindings -@cindex :bind @cindex binding keys for package commands @cindex key bindings for package commands One common thing to do when loading a package is to bind keys to @@ -1661,7 +1660,7 @@ Other package managers @section Non-standard package managers @cindex non-standard package managers @cindex package managers, other than @file{package.el} -@cindex installing packages using non-standard package managers +@cindex installing using non-standard package managers By default, use-package assumes that you are using the Emacs built-in @file{package.el} package manager. We expect that most users will commit 56a6712bd6f6ea63095f9abe2777070cd569f941 Author: F. Jason Park Date: Fri Dec 9 06:26:13 2022 -0800 ; * lisp/erc/erc.el (erc-default-target): Fix comment. diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 268d83dc449..6bb2e013c3b 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -5994,18 +5994,17 @@ erc--current-buffer-joined-p (and (erc--target-channel-p erc--target) (erc-get-channel-user (erc-current-nick)) t)) -;; This function happens to return nil in channel buffers previously -;; parted or those from which a user had been kicked. While this -;; "works" for detecting whether a channel is currently subscribed to, -;; new code should consider using +;; While `erc-default-target' happens to return nil in channel buffers +;; you've parted or from which you've been kicked, using it to detect +;; whether a channel is currently joined may become unreliable in the +;; future. For now, new code should consider using ;; ;; (erc-get-channel-user (erc-current-nick)) ;; -;; instead. For retrieving a target regardless of subscription or -;; connection status, use replacements based on `erc--target'. -;; (Coming soon.) -;; -;; TODO deprecate this +;; and expect a nicer option eventually. For retrieving a target +;; regardless of subscription or connection status, use replacements +;; based on `erc--target' instead. See also `erc--default-target'. + (defun erc-default-target () "Return the current default target (as a character string) or nil if none." (let ((tgt (car erc-default-recipients))) commit dcf69a1da4a41c27cc3c8782c40df24678847f3e Author: F. Jason Park Date: Thu Nov 24 21:03:03 2022 -0800 Respect some spaces in auth-source-pass--match-regexp * lisp/auth-source-pass.el (auth-source-pass--match-regexp): Allow an entry's host and user fields to contain spaces, just like other backends do. * lisp/erc/erc-compat.el (erc-compat--29-auth-source-pass--retrieve-parsed): Change regexp to allow spaces in host and user components of file names. * test/lisp/auth-source-pass-tests.el (auth-source-pass-any-host): Silence warning message re wildcards emitted by `auth-source-pass-search'. (auth-source-pass-extra-query-keywords--suffixed-user): Add spaces to users and hosts of some example entries. (Bug#58985.) diff --git a/lisp/auth-source-pass.el b/lisp/auth-source-pass.el index 74d38084480..fbb6944e26f 100644 --- a/lisp/auth-source-pass.el +++ b/lisp/auth-source-pass.el @@ -111,12 +111,12 @@ auth-source-pass--match-regexp (defun auth-source-pass--match-regexp (s) (rx-to-string ; autoloaded `(: (or bot "/") - (or (: (? (group-n 20 (+ (not (in ?\ ?/ ,s)))) "@") - (group-n 10 (+ (not (in ?\ ?/ ?@ ,s)))) - (? ,s (group-n 30 (+ (not (in ?\ ?/ ,s)))))) - (: (group-n 11 (+ (not (in ?\ ?/ ?@ ,s)))) - (? ,s (group-n 31 (+ (not (in ?\ ?/ ,s))))) - (? "/" (group-n 21 (+ (not (in ?\ ?/ ,s))))))) + (or (: (? (group-n 20 (+ (not (in ?/ ,s)))) "@") ; user prefix + (group-n 10 (+ (not (in ?/ ?@ ,s)))) ; host + (? ,s (group-n 30 (+ (not (in ?\s ?/ ,s)))))) ; port + (: (group-n 11 (+ (not (in ?/ ?@ ,s)))) ; host + (? ,s (group-n 31 (+ (not (in ?\s ?/ ,s))))) ; port + (? "/" (group-n 21 (+ (not (in ?/ ,s))))))) ; user suffix eot) 'no-group)) diff --git a/lisp/erc/erc-compat.el b/lisp/erc/erc-compat.el index abbaafcd936..bd932547586 100644 --- a/lisp/erc/erc-compat.el +++ b/lisp/erc/erc-compat.el @@ -176,12 +176,12 @@ auth-source-backend-parser-functions ;; This hard codes `auth-source-pass-port-separator' to ":" (defun erc-compat--29-auth-source-pass--retrieve-parsed (seen e port-number-p) (when (string-match (rx (or bot "/") - (or (: (? (group-n 20 (+ (not (in " /:")))) "@") - (group-n 10 (+ (not (in " /:@")))) + (or (: (? (group-n 20 (+ (not (in "/:")))) "@") + (group-n 10 (+ (not (in "/:@")))) (? ":" (group-n 30 (+ (not (in " /:")))))) - (: (group-n 11 (+ (not (in " /:@")))) + (: (group-n 11 (+ (not (in "/:@")))) (? ":" (group-n 31 (+ (not (in " /:"))))) - (? "/" (group-n 21 (+ (not (in " /:"))))))) + (? "/" (group-n 21 (+ (not (in "/:"))))))) eot) e) (puthash e `( :host ,(or (match-string 10 e) (match-string 11 e)) diff --git a/test/lisp/auth-source-pass-tests.el b/test/lisp/auth-source-pass-tests.el index 1107e09b51b..d6d42ce942e 100644 --- a/test/lisp/auth-source-pass-tests.el +++ b/test/lisp/auth-source-pass-tests.el @@ -175,7 +175,8 @@ auth-source-pass-match-any-entry-p (ert-deftest auth-source-pass-any-host () (auth-source-pass--with-store '(("foo" ("port" . "foo-port") ("host" . "foo-user")) ("bar")) - (should-not (auth-source-pass-search :host t)))) + (let ((inhibit-message t)) ; silence "... does not handle host wildcards." + (should-not (auth-source-pass-search :host t))))) (ert-deftest auth-source-pass-undefined-host () (auth-source-pass--with-store '(("foo" ("port" . "foo-port") ("host" . "foo-user")) @@ -697,29 +698,29 @@ auth-source-pass-extra-query-keywords--ambiguous-user-host ;; with slightly more realistic and less legible values. (ert-deftest auth-source-pass-extra-query-keywords--suffixed-user () - (let ((store (sort (copy-sequence '(("x.com:42/b@r" (secret . "a")) - ("b@r@x.com" (secret . "b")) + (let ((store (sort (copy-sequence '(("x.com:42/s p@m" (secret . "a")) + ("s p@m@x.com" (secret . "b")) ("x.com" (secret . "?")) - ("b@r@y.org" (secret . "c")) - ("fake.com" (secret . "?")) - ("fake.com/b@r" (secret . "d")) - ("y.org/b@r" (secret . "?")) - ("b@r@fake.com" (secret . "e")))) + ("s p@m@y.org" (secret . "c")) + ("fa ke" (secret . "?")) + ("fa ke/s p@m" (secret . "d")) + ("y.org/s p@m" (secret . "?")) + ("s p@m@fa ke" (secret . "e")))) (lambda (&rest _) (zerop (random 2)))))) (auth-source-pass--with-store store (auth-source-pass-enable) (let* ((auth-source-pass-extra-query-keywords t) - (results (auth-source-search :host '("x.com" "fake.com" "y.org") - :user "b@r" + (results (auth-source-search :host '("x.com" "fa ke" "y.org") + :user "s p@m" :require '(:user) :max 5))) (dolist (result results) (setf (plist-get result :secret) (auth-info-password result))) (should (equal results - '((:host "x.com" :user "b@r" :secret "b") - (:host "x.com" :user "b@r" :port "42" :secret "a") - (:host "fake.com" :user "b@r" :secret "e") - (:host "fake.com" :user "b@r" :secret "d") - (:host "y.org" :user "b@r" :secret "c")))))))) + '((:host "x.com" :user "s p@m" :secret "b") + (:host "x.com" :user "s p@m" :port "42" :secret "a") + (:host "fa ke" :user "s p@m" :secret "e") + (:host "fa ke" :user "s p@m" :secret "d") + (:host "y.org" :user "s p@m" :secret "c")))))))) ;; This is a more distilled version of `suffixed-user', above. It ;; better illustrates that search order takes precedence over "/user" commit acd462b0306ead1b47278e810e11a3d66e4dd2cc Author: Eli Zaretskii Date: Fri Dec 9 16:32:59 2022 +0200 ; Improve the use-package manual * doc/misc/use-package.texi (Top, Basic Concepts) (Getting Started, Loading Packages, Loading basics) (Deferring loading, Forcing loading, Conditional loading) (Loading sequentially, Load dependencies, Load path) (Manual autoloads, Configuring Packages, Lisp Configuration) (Preface keyword, Init keyword, Best practices, Key bindings) (Global keybindings, Binding in keymaps, Binding to a keymap) (Binding to repeat-maps, Displaying keybindings) (Modes and interpreters, Magic handlers, User options, Faces) (Delight, Diminish, Install package, Pinning packages) (Other package managers, Byte-compiling, Troubleshooting) (Troubleshooting Options, Gathering Statistics) (Disabling a package, Keyword extensions) (use-package-ensure-system-package, Creating an extension): Fix wording, punctuation, typos, and markup; add indexing. Add @group..@end group in code examples. diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 4f0f8a26773..53abd4519d3 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -47,9 +47,9 @@ @node Top @top use-package User Manual -The @code{use-package} macro allows you to isolate package +The @code{use-package} macro allows you to set up package customization in your init file in a declarative way. It takes care -of a lot of things for you that would otherwise require a lot of +of many things for you that would otherwise require a lot of repetitive boilerplate code. It can help with common customization, such as binding keys, setting up hooks, customizing user options and faces, autoloading, and more. It also helps you keep Emacs startup @@ -57,8 +57,9 @@ Top Note that use-package is not a package manager. Although use-package does have the useful capability to interface with the Emacs package -manager, its primary purpose is for the configuration and loading of -packages. +manager, its primary purpose is help with the configuration and +loading of packages, not with managing their download, upgrades, and +installation. @insertcopying @@ -75,6 +76,8 @@ Top * Keyword extensions:: Adding new use-package keywords. * History:: History and acknowledgments. * GNU Free Documentation License:: The license for this manual. + +Index * Index:: @end menu @end ifnottex @@ -88,52 +91,58 @@ Basic Concepts basic reasons, each of which drove the design. Understanding these reasons may help make some of those decisions clearer: +@cindex reasons for developing use-package @enumerate @item -To gather all configuration details of a package into one place, -making it easier to copy, disable, or move it elsewhere in the init -file. +Allow gathering all the configuration details of a package into one +place, making it easier to copy, disable, or move it elsewhere in the +init file. @item -To reduce duplication and boilerplate, capturing several common -practices as mere keywords both easy and intuitive to use. +Reduce duplication and repetitive boilerplate, capturing several +common practices as mere keywords both easy and intuitive to use. @item -To make startup time of Emacs as quick as possible, without -sacrificing the quantity of add-on packages used. +Make startup time of Emacs as short as possible, without sacrificing +the quantity of add-on packages used. @item -To make it so errors encountered during startup disable only the -package raising the error, and as little else as possible, leaving as -close to a functional Emacs as possible. +Ensure that errors encountered during startup disable only the +package(s) raising the error(s), and as little else as possible, +leaving Emacs as close to fully functional as possible. @item -To allow byte-compilation of one's init file so that any warnings or -errors seen are meaningful. In this way, even if byte-compilation is -not used for speed (reason 3), it can still be used as a sanity check. +Allow byte-compiling your init file, so that any warnings or errors +you see at startup are meaningful. In this way, even if +byte-compilation is not used for speed (see item 3 above), it can +still be used as a sanity check. @end enumerate It is worth noting that use-package is not intended to replace the -standard @w{@code{M-x customize}}. On the contrary, it is designed to -work together with it, for things that customize cannot do. +standard customization command @w{@kbd{M-x customize}} (@pxref{Easy +Customization,,, emacs, GNU Emacs Manual}). On the contrary, it is +designed to work together with it, for things that Customize cannot +do. @c ---------------------------------------------------------------------------- @node Getting Started @chapter Getting Started +@cindex quick-start instructions This chapter provides instructions and examples for quickly getting started with use-package. The first thing you need to do is make sure -that @samp{use-package} itself is loaded. To do that, put this at the +that @file{use-package} itself is loaded. To do that, put this at the top of your init file: @lisp (require 'use-package) @end lisp -The above makes the @code{use-macro} for in the rest of your init -file. In this manual, we call each call to @code{use-macro} a -@dfn{declaration}, to highlight the declarative nature of its -semantic. +@cindex declaration +The above makes the @code{use-macro} available for us in the rest of +your init file. In this manual, we say that each call to +@code{use-macro} is a @dfn{declaration}, to highlight the declarative +nature of its syntax. To unconditionally load a package named @samp{foo}, add the following declaration to your init file: @@ -143,62 +152,70 @@ Getting Started @end lisp @noindent -This declaration is equivalent to using @code{require}, with some -use-package specific error handling added in. Just like require, it -needs the package @samp{foo} to be installed and available in your -@code{load-path} (@pxref{Installing packages}). +This declaration is equivalent to using @code{require} (@pxref{Named +Features,,, elisp, GNU Emacs Lisp Reference Manual}), with some +use-package specific error handling added in. Just like +@code{require}, it needs the package @samp{foo} to be installed and +available via your @code{load-path} (@pxref{Installing packages}). -To evaluate Lisp code @emph{before} the @samp{foo} package is loaded, +To evaluate some Lisp @emph{before} the @samp{foo} package is loaded, use the @code{:init} keyword: @lisp +@group (use-package foo :init (setq foo-variable t)) +@end group @end lisp Similarly, @code{:config} can be used to execute code @emph{after} a package is loaded. In cases where loading is done lazily (@pxref{Loading Packages}), this execution is deferred until after the -autoload occurs. As you might expect, you can use @code{:init} and -@code{:config} together: +loading actually occurs. As you might expect, you can use +@code{:init} and @code{:config} together: @lisp +@group (use-package foo :init (setq foo-variable t) :config (foo-mode 1)) +@end group @end lisp -The above declarations will all load the @samp{foo} package +The above declarations will load the @samp{foo} package immediately. In most cases, this is not necessary or desirable, as that will slow down Emacs startup. Instead, you should try to set things up so that packages are only loaded when they are actually -needed (autoloading). If you have installed a package from +needed (a.k.a. ``autoloading''). If you have installed a package from @acronym{GNU ELPA} that provides it's own autoloads, it is often enough to say: @lisp +@group (use-package foo :defer t) +@end group @end lisp @noindent This will avoid loading the package. Now, when you run any autoloaded -command, the package @samp{foo} is loaded automatically. Package -authors will make their own decisions about which commands are marked -to autoload by default. +command, the package @samp{foo} is loaded automatically. (Which +commands from a package are marked to auto-load by default is the +decision of the package authors.) In some cases, you might need or want to provide your own autoloads. -The below more complex example autoloads the commands -@code{isearch-moccur} and @code{isearch-all} from +The more complex example below autoloads the commands +@code{isearch-moccur} and @code{isearch-all} from the package @file{color-moccur.el}, and binds keys both globally and in -@code{isearch-mode-map}. When one of these commands are used, the -package is loaded. At that point, @code{moccur-edit} is also loaded, +@code{isearch-mode-map}. When one of these two commands are used, the +package will be loaded. At that point, @code{moccur-edit} is also loaded, to allow editing of the @code{moccur} buffer. @lisp +@group (use-package color-moccur :commands (isearch-moccur isearch-all) :bind (("M-s O" . moccur) @@ -209,6 +226,7 @@ Getting Started (setq isearch-lazy-highlight t) :config (use-package moccur-edit)) +@end group @end lisp Some packages will suggest ready-made @code{use-package} declarations @@ -220,8 +238,8 @@ Getting Started @c ---------------------------------------------------------------------------- @node Loading Packages @chapter Loading Packages +@cindex loading packages with use-package -@cindex loading packages Before use-package can load an Emacs Lisp package, it must be available in a directory on your @code{load-path}. When you install packages using the built-in @code{install-package} command, it will do @@ -230,15 +248,15 @@ Loading Packages If you install packages manually, you must make sure they are available on your @code{load-path}. @xref{Lisp Libraries,,, emacs, -GNU Emacs Manual} for details. +GNU Emacs Manual}, for details. Some packages have more than one library. In those cases, you might -need more than one @code{use-package} declaration to make sure it is -properly loaded. For complex configurations, you might also need more -than one declaration for a package with the same name. +need more than one @code{use-package} declaration to make sure the +package is properly loaded. For complex configurations, you might +also need more than one declaration for a package with the same name. use-package can interface with @samp{package.el} to install packages -on Emacs start. @xref{Installing packages} for details. +on Emacs start. @xref{Installing packages}, for details. @menu * Loading basics:: How and when packages are loaded. @@ -254,32 +272,38 @@ Loading Packages @node Loading basics @section How and when use-package loads packages -The @code{use-package} macro either will either load a package -immediately, or when they are first used (autoloading). In the +The call to the @code{use-package} macro will load a package either +immediately, or when the package is first used (via autoloading). In the simplest case, a @code{use-package} declaration loads a package when it is evaluated.@footnote{This happens both at run-time and at compile-time. @xref{Byte-compiling}.} If the declaration is in your init file, this happens automatically each time Emacs is started. -For example, the below declaration immediately loads the library -@code{foo}, just like @code{require} would. If the library @samp{foo} -is not available in your @code{load-path}, it logs a warning to the -@samp{*Messages*} buffer: +For example, the declaration below immediately loads the library +@code{foo}, just like @code{require} would: @lisp (use-package foo) @end lisp +@noindent +If the library @samp{foo} is not available in your @code{load-path}, +the declaration logs a warning to the @samp{*Messages*} buffer. + +@cindex package vs library +@c So, confusingly, (use-package foo) actually means to use the +@c _library_ foo.el, not all of the _package_ foo's libraries? +@c Should this be explicitly explained here? Note that a ``package'' is different from an Emacs Lisp ``library''. The above declaration tells use-package to load the @emph{library} -@file{foo.el}, which the overwhelming majority of cases also resides -in a @emph{package} named @code{foo}. But the @code{foo} package -might also contain a library named @file{foo-extra.el}. If that -library is not loaded automatically, you will need a separate -@code{use-package} declaration to make sure that it is. This manual -will often use these terms interchangeably, as this distinction does -not usually matter, but you should keep it in mind for the cases when -it does. +@file{foo.el}, which in the overwhelming majority of cases also +resides in a @emph{package} named @code{foo}. But the package +@code{foo} might also contain a library named @file{foo-extra.el}. If +that library is not loaded automatically, you will need a separate +@code{use-package} declaration to make sure that it is loaded when +needed. This manual will often use the terms ``package'' and +``library'' interchangeably, as this distinction does not usually +matter, but you should keep it in mind for the cases when it does. The details of how and when you should load a package might differ from one package to another. When in doubt, refer to the package @@ -287,17 +311,19 @@ Loading basics @node Deferring loading @section Deferring package loading +@cindex deferring loading of package @cindex autoloading packages @cindex loading lazily +@cindex lazy loading of packages In the examples we have seen so far, use-package loads packages every time you start Emacs, even if that package is never used. That will -make starting Emacs slower. use-package therefore tries to set things -up in such a way that it only loads packages when a command is first -used (either with @kbd{M-x} or some key binding). This is based on -autoloading, a full description of which is outside the scope of this -manual. @xref{Autoload,,, elisp, GNU Emacs Lisp Reference Manual} for -the full story. +make starting Emacs slower. use-package therefore allows setting +things up in such a way that packages are only loaded when some of the +package's commands is first used (either with @kbd{M-x} or via some key +binding). This is based on autoloading, a full description of which +is outside the scope of this manual. @xref{Autoload,,, elisp, GNU +Emacs Lisp Reference Manual}, for the full story. @cindex triggers, for loading packages Some @code{use-package} keywords provide autoload @dfn{triggers} that @@ -320,8 +346,10 @@ Deferring loading using @code{:defer} to postpone loading the package @samp{foo}: @lisp +@group (use-package foo :defer t) +@end group @end lisp Using @code{:defer t} by itself like this is rarely useful. @@ -331,21 +359,25 @@ Deferring loading @subheading Defer loading until idle for N seconds -You can also give a numeric argument @var{N} to @w{@code{:defer}} to +@findex :defer@r{, with a numeric argument} +You can also give a numeric argument @var{n} to @w{@code{:defer}} to specify that a package should be loaded (if it hasn't already) after -Emacs has been idle for @var{N} seconds. For example, use this to -make use-package load @samp{foo} after 30 seconds of idle time: +Emacs has been idle for @var{n} seconds. For example, use the +following to make use-package load @samp{foo} after 30 seconds of idle +time: @lisp +@group (use-package foo :defer 30) +@end group @end lisp @subheading When to use @code{:defer} When using autoloading keywords, there is no need to also use -@code{:defer}. It doesn't hurt anything to add it in this case, -perhaps for extra clarity, but it is redundant. +@code{:defer}. It doesn't hurt to add it in this case, perhaps for +extra clarity, but it is redundant. You should use @code{:defer} to force deferred loading, in cases when use-package isn't creating any autoloads for you. For example, you @@ -357,6 +389,8 @@ Deferring loading @subheading Making @w{@code{:defer t}} the default +@cindex defer loading by default +@cindex lazy loading by default @vindex use-package-always-defer If you customize the user option @code{use-package-always-defer} to non-@code{nil}, the @code{use-package} macro will behave as if @@ -366,6 +400,7 @@ Deferring loading @node Forcing loading @section Forcing package to load immediately +@cindex forcing immediate loading @findex :demand The presence of autoloading trigger keywords can be overridden using @@ -380,6 +415,8 @@ Forcing loading @node Conditional loading @section Loading packages conditionally +@cindex conditional loading +@cindex loading conditions @findex :if @findex :when @@ -398,8 +435,10 @@ Conditional loading sessions, you could use the following: @lisp +@group (use-package foo :if (display-graphic-p)) +@end group @end lisp @subheading Some common use cases @@ -407,39 +446,46 @@ Conditional loading Here are some common cases for conditional loading, and how to achieve them. +@c FIXME: Too many redundant examples? E.g., why do we need both an +@c example for system-type and window-system? or both of the last 2 +@c examples? @itemize -@item Operating system +@item +Operating system -This example loads a package only on GNU/Linux. See the -@code{system-type} docstring for other valid values. +The following example loads a package only on GNU/Linux. See the +docstring of @code{system-type} for other valid values. @lisp :if (eq system-type 'gnu/linux) @end lisp -@item Window system +@item +Window system -This example loads a package only on macOS and X. See the -@code{window-system} docstring for valid values. +The example below loads a package only on macOS and X. See the +docstring of @code{window-system} for valid values. @lisp :if (memq window-system '(ns x)) @end lisp -@item Installed package +@item +Installed package -This example loads a package only when the @samp{foo} package is -installed. +The following example loads a package only when the @samp{foo} package +is installed. @lisp :if (package-installed-p 'foo) @end lisp -@item Libraries in @code{load-path} +@item +Libraries in @code{load-path} -This example loads a package only when @file{foo.el} is available in -your @code{load-path} (for example, if you installed that file +The example below loads a package only when @file{foo.el} is available +in your @code{load-path} (for example, if you installed that file manually): @lisp @@ -450,38 +496,45 @@ Conditional loading @subheading Making conditional loading affect @code{:preface} and @code{:ensure} @cindex conditional loading before @code{:preface} or @code{:ensure} -If you need to conditionalize a use-package form so that the condition -occurs before even @code{:ensure} or @code{:preface}, use @code{when} -around the use-package form itself. For example: +If you need to make a use-package form conditional so that the condition +occurs before even @code{:ensure} (@pxref{Install package}) or +@code{:preface} (@pxref{Preface keyword}), use @code{when} +around the @code{use-package} form itself. For example: @lisp +@group (when (memq window-system '(mac ns)) (use-package foo :ensure t)) +@end group @end lisp @node Loading sequentially @section Loading packages in sequence +@cindex loading a package after other packages @findex :after Sometimes it only makes sense to configure a package after another one has been loaded, because certain variables or functions are not in -scope until that time. This can achieved with the @code{:after} +scope until that time. This can be achieved with the @code{:after} keyword, which allows a fairly rich description of the exact -conditions when loading should occur. It takes either a symbol -indicating the package name, a list of such symbols, or a list of -selectors (see below). +conditions when loading should occur. The @code{:after} keyword takes +as argument either a symbol indicating the package name, a list of +such symbols, or a list of selectors (see below). -Here is an example of using the @acronym{GNU ELPA} packages hydra, -ivy, and ivy-hydra. Note that ivy-hydra will always be loaded last: +Here is an example of using the @acronym{GNU} @acronym{ELPA} packages +@file{hydra}, @file{ivy}, and @file{ivy-hydra}. Note that +@file{ivy-hydra} will always be loaded last: @lisp (use-package hydra) (use-package ivy) +@group (use-package ivy-hydra :after (ivy hydra)) +@end group @end lisp In this case, because the declarations are evaluated in the order they @@ -494,11 +547,12 @@ Loading sequentially @subheading Using @code{:after} selectors -@findex :all (with :after) -@findex :any (with :after) +@findex :all@r{, (with @code{:after})} +@findex :any@r{, (with @code{:after})} +@cindex list of selectors, for @code{:after} The @code{:after} keyword also accepts a list of selectors. By -default, @code{:after (foo bar)} is the same as @w{@code{:after (:all -foo bar)}}, meaning that loading of the given package will not happen +default, @w{@code{:after (foo bar)}} is the same as @w{@code{:after +(:all foo bar)}}, meaning that loading of the given package will not happen until both @code{foo} and @code{bar} have been loaded. Here are some of the other possibilities: @@ -510,22 +564,25 @@ Loading sequentially :after (:any (:all foo bar) (:all baz quux)) @end verbatim -When you nest selectors, such as @code{(:any (:all foo bar) (:all baz -quux))}, it means that the package will be loaded when either both -@code{foo} and @code{bar} have been loaded, or when both @code{baz} -and @code{quux} have been loaded. +When you nest selectors, such as in @w{@code{(:any (:all foo bar) +(:all baz quux))}}, it means that the package will be loaded when +either both @code{foo} and @code{bar} have been loaded, or when both +@code{baz} and @code{quux} have been loaded. +@cindex @code{use-package-always-defer}, with @code{:after} Pay attention when setting @code{use-package-always-defer} to a non-@code{nil} value, and also using the @code{:after} keyword. In -this case, you will need to specify how the declared package is to be -loaded: for example, by some @code{:bind}. If you are not using one -of the keywords that registers autoloads, such as @code{:bind} or -@code{:hook}, and your package manager does not provide autoloads, it -is possible that your package will never be loaded if you do not add -@code{:demand t} to those declarations. +that case, you will need to specify how the declared package is to be +loaded: for example, by some @code{:bind} (@pxref{Global +keybindings}). If you are not using one of the keywords that +registers autoloads, such as @code{:bind} or @code{:hook} +(@pxref{Hooks}), and your package manager does not provide autoloads, +it is possible that your package will never be loaded if you do not +add @code{:demand t} to those declarations. @node Load dependencies @section Prevent loading if dependencies are missing +@cindex prevent loading package if dependencies are missing @findex :requires While the @code{:after} keyword delays loading until the dependencies @@ -536,22 +593,29 @@ Load dependencies 'foo)}} evaluates to a non-@code{nil} value. For example: @lisp +@group (use-package abbrev :requires foo) +@end group @end lisp +@noindent This is the same as: @lisp +@group (use-package abbrev :if (featurep 'foo)) +@end group @end lisp As a convenience, a list of such packages may be specified: @lisp +@group (use-package abbrev :requires (foo bar baz)) +@end group @end lisp For more complex logic, such as that supported by @code{:after}, @@ -559,64 +623,81 @@ Load dependencies @node Load path @section Setting a custom @code{load-path} +@cindex custom @code{load-path} for loading a package +@cindex @code{load-path}, add directories for loading a package @findex :load-path If a package resides in some directory that is not in your @code{load-path}, use the @code{:load-path} keyword to add it. It -takes a symbol, a function, a string or a list of strings. If the -path is relative, it is expanded within @code{user-emacs-directory}. +takes as argument a symbol, a function, a string or a list of strings. +If a directory is specified as a relative file name, it is expanded +relative to @code{user-emacs-directory}. For example: @lisp +@group (use-package ess-site :load-path "site-lisp/ess/lisp/" :commands R) +@end group @end lisp Note that when using a symbol or a function to provide a dynamically -generated list of paths, you must inform the byte-compiler of this +generated list of directories, you must inform the byte-compiler of this definition so that the value is available at byte-compilation time. This is done by using the special form @code{eval-and-compile} (as -opposed to @code{eval-when-compile}). Further, this value is fixed at +opposed to @code{eval-when-compile}, @pxref{Eval During Compile,,, +elisp, GNU Emacs Lisp Reference Manual}). Further, this value is fixed at whatever was determined during compilation, to avoid looking up the same information again on each startup. For example: +@c FIXME: the below should use shell-command-to-string, surely? @lisp +@group (eval-and-compile (defun ess-site-load-path () (shell-command "find ~ -path ess/lisp"))) +@end group +@group (use-package ess-site :load-path (lambda () (list (ess-site-load-path))) :commands R) +@end group @end lisp @node Manual autoloads @section Setting up autoloads manually +@cindex autoloads for packages, setting up manually +@cindex package autoloads, setting up manually @findex :commands @findex :autoload To autoload an interactive command, use the @code{:commands} keyword. When you use the @code{:commands} keyword, it creates autoloads for -those commands (which defers loading of the module until they are +those commands (which defers loading of the module until those commands are used). The @code{:commands} keyword takes either a symbol or a list -of symbols. +of symbols as its argument. The @code{:autoload} keyword works like @code{:commands}, but is used to autoload non-interactive functions. Here is an example: @lisp +@group (use-package org-crypt :autoload org-crypt-use-before-save-magic) +@end group @end lisp @c ---------------------------------------------------------------------------- @node Configuring Packages @chapter Configuring Packages +@cindex configure packages using @code{use-package} +@cindex customize package configuration This chapter describes the various keywords provided by -@code{use-package} that helps you configure packages. +@code{use-package} that help you configure packages. @menu * Lisp Configuration:: Using Lisp to configure packages. @@ -631,6 +712,7 @@ Configuring Packages @node Lisp Configuration @section Using Lisp code for configuring packages +@cindex configure package using Lisp forms The most general way to add customizations are the @code{:preface}, @code{:init}, and @code{:config} keywords. They all accept one or @@ -657,19 +739,22 @@ Preface keyword @enumerate @item -Make the byte-compiler happy. It will not complain about functions +@c FIXME: ``within a guard block''? what's that?? +Make the byte-compiler happy: it will not complain about functions whose definitions are unknown because you have them within a guard block. @item -Define code that can be used in an @code{:if} test. +Define functions and variables that will be used in an @code{:if} +test. @end enumerate Note that whatever is specified within @code{:preface} is evaluated both at load time and at byte-compilation time, in order to ensure that definitions are seen by both the Lisp evaluator and the byte-compiler. Therefore, you should avoid having any side-effects in -your preface, and restrict it to symbol declarations and definitions. +your @code{:preface} forms, and restrict them to symbol declarations +and definitions. @node Init keyword @subsection @code{:init} is evaluated before loading package @@ -677,10 +762,11 @@ Init keyword @findex :init The @code{:init} section is evaluated just before the package is loaded. Note that the @code{:init} form is run unconditionally -- -even if the @code{foo} package happens to not exist on your system. -You must therefore remember to restrict @code{:init} code to only what -would succeed either way. @code{:init} also always happens before -package load, whether @code{:config} has been deferred or not. +even if the package happens to not exist on your system. You must +therefore remember to restrict @code{:init} code to what would succeed +either way; put the rest in the @code{:config} section. @code{:init} +also always happens before package load, whether @code{:config} has +been deferred or not. @node Config keyword @subsection @code{:config} is evaluated after loading package @@ -698,58 +784,69 @@ Config keyword @node Best practices @subheading When to use @code{:preface}, @code{:config} and @code{:init}? +@cindex tips for using @code{:preface}, @code{:config}, @code{:init} Where possible, it is better to avoid @code{:preface}, @code{:config} and @code{:init}. Instead, prefer autoloading keywords such as -@code{:bind}, @code{:hook}, and @code{:mode}, as they will take care +@code{:bind} (@pxref{Key bindings}), @code{:hook} (@pxref{Hooks}), and +@code{:mode} (@pxref{Modes and interpreters}), as they will take care of setting up autoloads for you without any need for boilerplate code. For example, consider the following declaration: @lisp +@group (use-package foo :init (add-hook 'some-hook 'foo-mode)) +@end group @end lisp +@noindent This has two problems. First, it will unconditionally load the package @samp{foo} on startup, which will make things slower. You can -fix this by adding @code{:defer t}: +fix this by adding @w{@code{:defer t}}: @lisp +@group (use-package foo :defer t :init (add-hook 'some-hook 'foo-mode)) +@end group @end lisp +@noindent This is better, as @samp{foo} is now only loaded when it is actually needed (that is, when the hook @samp{some-hook} is run). The second problem is that there is a lot of boilerplate that you have to write. In this case, it might not be so bad, but avoiding that was -what use-package was made to avoid. The better option in this case is -therefore to use @code{:hook} (@xref{Hooks}), which also implies +what use-package was made to allow. The better option in this case is +therefore to use @code{:hook} (@pxref{Hooks}), which also implies @w{@code{:defer t}}. The above is thereby reduced down to: @lisp +@group (use-package foo :hook some-hook) +@end group @end lisp -use-package will set up autoloading for you, and your Emacs startup -time will not suffer one bit. +Now use-package will set up autoloading for you, and your Emacs +startup time will not suffer one bit. @node Key bindings @section Key bindings @cindex :bind -@cindex binding keys -@cindex key bindings -One common thing to do when loading a package is to bind a key to +@cindex binding keys for package commands +@cindex key bindings for package commands +One common thing to do when loading a package is to bind keys to commands within that module. Without use-package, this would be done using a combination of @code{keymap-local-set}, @code{keymap-global-set} and various autoloads. With use-package, you -can simplify this using the @code{:bind} keyword. +can simplify this using the @code{:bind} keyword, as described in this +section. @menu * Global keybindings:: Bindings you can use anywhere. @@ -761,25 +858,29 @@ Key bindings @node Global keybindings @subsection Global keybindings +@cindex global keybindings @findex :bind -To bind keys globally, the @code{:bind} keyword takes either a single -cons or a list of conses. Every cons has the form @code{(@var{key} -. @var{command}}, where @var{key} is a string indicating the key to -bind, and @var{command} is the name of a command (a symbol). The -syntax for the keys is similar to the syntax used by the @code{kbd} -function (@pxref{Init Rebinding,,, emacs, GNU Emacs Manual} for more -information). +To bind keys globally, the @code{:bind} keyword takes as its argument +either a single cons or a list of conses. Each cons has the form +@w{@code{(@var{key} . @var{command})}}, where @var{key} is a string +indicating the key to bind, and @var{command} is the name of a command +(a symbol). The syntax for the keys is similar to the syntax used by +the @code{kbd} function (see @ref{Init Rebinding,,, emacs, GNU Emacs +Manual}, for more information). @subheading Using @code{:bind} with a single cons Here is an example of using a single cons: @lisp +@group (use-package ace-jump-mode :bind ("C-." . ace-jump-mode)) +@end group @end lisp +@noindent This does two things: first, it creates an autoload for the @code{ace-jump-mode} command and defers loading of the @code{ace-jump-mode} package until you actually use it. Second, it @@ -790,73 +891,100 @@ Global keybindings Here is an example of using @code{:bind} with a list of conses: @lisp +@group (use-package hi-lock :bind (("M-o l" . highlight-lines-matching-regexp) ("M-o r" . highlight-regexp) ("M-o w" . highlight-phrase))) +@end group @end lisp +@noindent +This binds the three key sequences to the corresponding commands. + @subheading Using special keys +@cindex binding function keys with @code{:bind} +@cindex @code{:bind}, and function keys +@c FIXME: TAB vs [tab] -- is letter-case important? In general, these +@c are two different keys: one is an ASCII character, the other a +@c function key on GUI frames. Inside key strings, special keys like @kbd{TAB} or @kbd{F1}--@kbd{F12} -have to be written inside angle brackets, e.g. @code{"C-"}. +have to be written inside angle brackets, e.g., @code{"C-"}. +@c FIXME: ``Some combinations''? which ones? Standalone special keys (and some combinations) can be written in square brackets, e.g.@ @code{[tab]} instead of @code{""}. Examples: @lisp +@group (use-package helm :bind (("M-x" . helm-M-x) ("M-" . helm-find-files) ([f10] . helm-buffers-list) ([S-f10] . helm-recentf))) +@end group @end lisp @subheading Remapping commands +@cindex remapping commands with @code{:bind} +@cindex @code{:bind}, and remapping of commands -Remapping commands with @code{:bind} and @code{bind-key} works as +Remapping of commands with @code{:bind} and @code{bind-key} works as expected, because when the binding is a vector, it is passed straight to @code{define-key}. @xref{Remapping Commands,,, elisp, GNU Emacs -Lisp Reference Manual}) for more information about command remapping. +Lisp Reference Manual}), for more information about command remapping. For example, the following declaration will rebind @code{fill-paragraph} (bound to @kbd{M-q} by default) to @code{unfill-toggle}: @lisp +@group (use-package unfill :bind ([remap fill-paragraph] . unfill-toggle)) +@end group @end lisp +@c FIXME: Should the below be an Appendix? @subheading What @code{:bind} does behind the scenes +@cindex @code{:bind}, internals To understand what @code{:bind} does behind the scenes, it might be useful to consider an example: @lisp +@group (use-package ace-jump-mode :bind ("C-." . ace-jump-mode)) +@end group @end lisp +@noindent This could be expressed in a much more verbose way with the -@code{:commands} and @code{:init} keywords. +@code{:commands} and @code{:init} keywords: @lisp +@group (use-package ace-jump-mode :commands ace-jump-mode :init (bind-key "C-." 'ace-jump-mode)) +@end group @end lisp +@noindent Without using even the @code{:commands} keyword, we could also write the above like so: @lisp +@group (use-package ace-jump-mode :defer t :init (autoload 'ace-jump-mode "ace-jump-mode" nil t) (bind-key "C-." 'ace-jump-mode)) +@end group @end lisp Although these three forms are all equivalent, the first form is @@ -864,28 +992,33 @@ Global keybindings @node Binding in keymaps @subsection Key bindings in local keymaps +@cindex local keybindings -@findex :map, inside :bind +@findex :map@r{, inside} :bind Slightly different from binding a key to a keymap, is binding a key @emph{within} a local keymap that only exists after the package is loaded. @code{use-package} supports this with a @code{:map} modifier, taking the local keymap to bind to: @lisp +@group (use-package helm :bind (:map helm-command-map ("C-c h" . helm-execute-persistent-action))) +@end group @end lisp -The effect of this statement is to wait until @code{helm} has loaded, -and then to bind the key @code{C-c h} to +@noindent +The effect of this is to wait until @code{helm} has loaded, and then +to bind the key sequence @kbd{C-c h} to @code{helm-execute-persistent-action} within Helm's local keymap, @code{helm-command-map}. -Multiple uses of @code{:map} may be specified. Any binding occurring +Multiple uses of @code{:map} may be specified. Any binding occurring before the first use of @code{:map} are applied to the global keymap: @lisp +@group (use-package term :bind (("C-c t" . term) :map term-mode-map @@ -895,21 +1028,23 @@ Binding in keymaps ("M-o" . other-window) ("M-p" . term-send-up) ("M-n" . term-send-down))) +@end group @end lisp @node Binding to a keymap @subsection Binding to keymaps +@cindex binding keys to keymaps -@findex :bind-keymap, inside :bind +@findex :bind-keymap Normally @code{:bind} expects that commands are functions that will be -autoloaded from the given package. However, this does not work if one of +autoloaded from the given package. However, this does not work if one of those commands is actually a keymap, since keymaps are not functions, and cannot be autoloaded using the built-in @code{autoload} function. To handle this case, @code{use-package} offers a special, limited -variant of @code{:bind} called @code{:bind-keymap}. The only difference +variant of @code{:bind} called @code{:bind-keymap}. The only difference is that the ``commands'' bound to by @code{:bind-keymap} must be keymaps -defined in the package, rather than command functions. This is handled +defined in the package, rather than interactive functions. This is handled behind the scenes by generating custom code that loads the package containing the keymap, and then re-executes your keypress after the first load, to reinterpret that keypress as a prefix key. @@ -917,31 +1052,35 @@ Binding to a keymap For example: @lisp +@group (use-package foo :bind-keymap ("C-c p" . foo-command-map)) +@end group @end lisp @node Binding to repeat-maps @subsection Binding to repeat-maps +@cindex keybinding for @code{repeat-mode} keymaps -@findex :repeat-map, inside :bind -@cindex repeat-mode and use-package, using +@findex :repeat-map@r{, inside} :bind +@cindex @code{repeat-mode} and use-package, using A special case of binding within a local keymap is when that keymap is -used by @code{repeat-mode} @pxref{Repeating,,, emacs, GNU Emacs -Manual}. These keymaps are usually defined specifically for +used by @code{repeat-mode} (@pxref{Repeating,,, emacs, GNU Emacs +Manual}). These keymaps are usually defined specifically for this. Using the @code{:repeat-map} keyword, and passing it a name for -the map it defines, will bind all following keys inside that map, and +the map it defines, will bind all the following keys inside that map, and (by default) set the @code{repeat-map} property of each bound command to that map. The following example creates a keymap called -@code{git-gutter+-repeat-map}, makes four bindings in it as above, -then sets the @code{repeat-map} property of each bound command -(@code{git-gutter+-next-hunk} @code{git-gutter+-previous-hunk}, -@code{git-gutter+-stage-hunks} and @code{git-gutter+-revert-hunk}) to +@code{git-gutter+-repeat-map}, makes four bindings in it, then sets +the @code{repeat-map} property of each bound command +(@code{git-gutter+-next-hunk}, @code{git-gutter+-previous-hunk}, +@code{git-gutter+-stage-hunks}, and @code{git-gutter+-revert-hunk}) to that keymap. @lisp +@group (use-package git-gutter+ :bind (:repeat-map git-gutter+-repeat-map @@ -949,16 +1088,19 @@ Binding to repeat-maps ("p" . git-gutter+-previous-hunk) ("s" . git-gutter+-stage-hunks) ("r" . git-gutter+-revert-hunk))) +@end group @end lisp -@findex :exit, inside :repeat-map and :bind +@findex :exit@r{, inside} :repeat-map@r{ and} :bind +@cindex binding commands used at end of repeat series Specifying @code{:exit} inside the scope of @code{:repeat-map} will -prevent the @code{repeat-map} property being set, so that the command -can be used from within the repeat map, but after it using it the repeat +prevent the @code{repeat-map} property from being set, so that the command +can be used from within the repeat map, but after using it the repeat map will no longer be available. This is useful for commands often used -at the end of a series of repeated commands: +at the end of a series of repeated commands. Example: @lisp +@group (use-package git-gutter+ :bind (:repeat-map my/git-gutter+-repeat-map @@ -970,14 +1112,16 @@ Binding to repeat-maps ("c" . magit-commit-create) ("C" . magit-commit) ("b" . magit-blame))) +@end group @end lisp -@findex :continue, inside :repeat-map and :bind +@findex :continue@r{, inside} :repeat-map@r{ and} :bind Specifying @code{:continue} @emph{forces} setting the @code{repeat-map} property (just like @emph{not} specifying @code{:exit}), so the above snippet is equivalent to: @lisp +@group (use-package git-gutter+ :bind (:repeat-map my/git-gutter+-repeat-map @@ -990,10 +1134,12 @@ Binding to repeat-maps ("p" . git-gutter+-previous-hunk) ("s" . git-gutter+-stage-hunks) ("r" . git-gutter+-revert-hunk))) +@end group @end lisp @node Displaying keybindings -@subsection Displaying personal keybinding +@subsection Displaying personal keybindings +@cindex display your keybindings @findex describe-personal-keybindings The @code{:bind} keyword uses the @code{bind-keys} macro from the @@ -1001,7 +1147,7 @@ Displaying keybindings all keybindings you make, so that you can display them separately from the default keybindings. -Use @w{@code{M-x describe-personal-keybindings}} to see all +Use @w{@kbd{M-x describe-personal-keybindings}} to see all keybindings you've set using either the @code{:bind} keyword or the @code{bind-keys} macro. @@ -1010,7 +1156,8 @@ Hooks @cindex hooks @findex :hook -The @code{:hook} keyword allows adding functions onto hooks. It takes +The @code{:hook} keyword allows adding functions to hooks. It takes +@c FIXME: The actual forms accepted by :hook are different, see below! one argument of the form @var{hooks}, specifying one or more functions to add to one or more hooks. For the purposes of @code{:hook}, the name of hook variables should always exclude the @samp{-hook} suffix. @@ -1021,17 +1168,21 @@ Hooks package, and adds @samp{company-mode} to @code{prog-mode-hook}: @lisp +@group (use-package company :commands company-mode :init (add-hook 'prog-mode-hook #'company-mode)) +@end group @end lisp Using @code{:hook}, this can be simplified to: @lisp +@group (use-package company :hook (prog-mode . company-mode)) +@end group @end lisp Here, @code{:hook} will automatically set up autoloads for the @@ -1044,8 +1195,10 @@ Hooks simplify the above to the equivalent: @lisp +@group (use-package company :hook prog-mode) +@end group @end lisp @cindex multiple hooks @@ -1053,21 +1206,29 @@ Hooks applied, the following examples are all equivalent: @lisp +@group (use-package company :hook (prog-mode text-mode)) +@end group +@group (use-package company :hook ((prog-mode text-mode) . company-mode)) +@end group +@group (use-package company :hook ((prog-mode . company-mode) (text-mode . company-mode))) +@end group +@group (use-package company :commands company-mode :init (add-hook 'prog-mode-hook #'company-mode) (add-hook 'text-mode-hook #'company-mode)) +@end group @end lisp One common mistake when using @code{:hook} is to forget to omit the @@ -1076,9 +1237,11 @@ Hooks to add a function to non-existent @code{prog-mode-hook-hook}: @lisp +@group ;; DOES NOT WORK (use-package ace-jump-mode :hook (prog-mode-hook . ace-jump-mode)) +@end group @end lisp @vindex use-package-hook-name-suffix @@ -1095,12 +1258,16 @@ Hooks @node Modes and interpreters @section Modes and interpreters +@cindex @code{auto-mode-alist} customization +@cindex @code{interpreter-mode-alist} customization +@cindex setting up major modes @findex :mode @findex :interpreter Similar to @code{:bind}, you can use @code{:mode} and @code{:interpreter} to establish a deferred binding within the -@code{auto-mode-alist} and @code{interpreter-mode-alist} variables. +@code{auto-mode-alist} and @code{interpreter-mode-alist} variables +(@pxref{Auto Major Mode,,, elisp, GNU Emacs Lisp Reference Manual}). The specifier to either keyword can be a cons cell, a list of cons cells, or a string or regexp. @@ -1112,51 +1279,63 @@ Modes and interpreters @code{"ruby"}: @lisp +@group (use-package ruby-mode :mode "\\.rb\\'" :interpreter "ruby") +@end group @end lisp The default @code{python-mode} configuration can be reproduced using -the below declaration. Note that the package that should be loaded +the declaration below. Note that the package that should be loaded differs from the mode name in this case, so we must use a cons: @lisp +@group ;; The package is "python" but the mode is "python-mode": (use-package python :mode ("\\.py\\'" . python-mode) :interpreter ("python" . python-mode)) +@end group @end lisp Both the @code{:mode} and @code{:interpreter} keywords also accept a list of regexps: @lisp +@group (use-package foo ;; Equivalent to "\\(ba[rz]\\)\\'": :mode ("\\.bar\\'" "\\.baz\\'") ;; Equivalent to "\\(foo[ab]\\)": :interpreter ("fooa" "foob")) +@end group @end lisp @node Magic handlers @section Magic handlers +@cindex @code{magic-mode-alist} customization @findex :magic @findex :magic-fallback Similar to @code{:mode} and @code{:interpreter}, you can also use @code{:magic} and @code{:magic-fallback} to cause certain function to -be run if the beginning of a file matches a given regular expression. -The difference between @code{:magic} and @code{:magic-fallback}, is -that the latter has a lower priority than @code{:mode}. +be run if the beginning of a file matches a given regular expression, +as if these regular expressions were added to @code{magic-mode-alist} +and @code{magic-fallback-mode-alist} (@pxref{Auto Major Mode,,, elisp, +GNU Emacs Lisp Reference Manual}). The difference between +@code{:magic} and @code{:magic-fallback}, is that the latter has a +lower priority than @code{:mode}. Here is an example: @lisp +@group (use-package pdf-tools :magic ("%PDF" . pdf-view-mode) :config (pdf-tools-install :no-query)) +@end group @end lisp This registers an autoloaded command for @code{pdf-view-mode}, defers @@ -1165,53 +1344,67 @@ Magic handlers @node User options @section User options +@cindex customization of variables +@cindex variable customizations +@cindex user options, setting @findex :custom In Emacs, you normally set customizable variables (user options) using the @code{M-x customize} interface (@pxref{Easy Customization,,, -emacs, GNU Emacs Manual}). We recommended this method for most users. +emacs, GNU Emacs Manual}). We recommend this method for most users. However, it is also possible to set them in your @code{use-package} declarations by using the @code{:custom} keyword. @lisp +@group (use-package comint :defer t :custom (comint-buffer-maximum-size 20000 "Increase comint buffer size.") (comint-prompt-read-only t "Make the prompt read only.")) +@end group @end lisp This is better than using @code{setq} in a @code{:config} block, as customizable variables might have some code associated with it that -Emacs will execute when you assign values to them. In Emacs 29, there -is also the new @code{setopt} macro that does this for you. - -Note that the values customized using this keyword are @emph{not} -saved in the standard Emacs @code{custom-file}. You should therefore -set each user option using either the @code{:custom} keyword @emph{or} -@w{@code{M-x customize-option}}, which will save customized values in -the Emacs @code{custom-file}. Do not use both for the same variable, -as this risk having conflicting values in your use-package declaration -and your @code{custom-file}. This can lead to problems that are both -tricky and tedious to debug. +Emacs will execute when you assign values to them. (In Emacs 29 and +later, there is also the new @code{setopt} macro that does this for +you.) + +Note that the values customized using @code{:custom} are @emph{not} +saved in the standard Emacs @code{custom-file} (@pxref{Saving +Customizations,,, emacs, GNU Emacs Manual}). You should therefore set +each user option using either the @code{:custom} keyword @emph{or} +@w{@kbd{M-x customize-option}} command; the latter will save +customized values in the Emacs @code{custom-file}. Do not use both +for the same variable, as this risks having conflicting values in your +use-package declaration and your @code{custom-file}, which can lead to +problems that are both tricky and tedious to debug. @node Faces @section Faces +@cindex faces, setting +@cindex customization of faces @findex :custom-face -The @code{:custom-face} keyword allows customization of package custom -faces. +The @code{:custom-face} keyword allows customization of package's +faces. Example: @lisp +@group (use-package eruby-mode :custom-face (eruby-standard-face ((t (:slant italic))))) +@end group +@group (use-package example :custom-face (example-1-face ((t (:foreground "LightPink")))) (example-2-face ((t (:foreground "LightGreen"))) face-defspec-spec)) +@end group +@group (use-package zenburn-theme :preface (setq my/zenburn-colors-alist @@ -1220,17 +1413,19 @@ Faces (region ((t (:background ,(alist-get my/zenburn-colors-alist 'cyan))))) :config (load-theme 'zenburn t)) +@end group @end lisp @node Hiding minor modes @section Hiding minor modes with diminish and delight +@cindex hiding minor modes -@code{use-package} supports the diminish and delight packages, both of -which make it possible remove or change minor mode strings in your -mode-line. Which one to use is up to you, but you should normally -only use one or the other -- never both.@footnote{When in doubt, you -might as well use diminish.} To use either of them, you must first -install the corresponding package from @acronym{GNU ELPA}. +@code{use-package} supports the @file{diminish} and @file{delight} +packages, both of which make it possible to remove or change minor mode +strings in your mode-line. Which one to use is up to you, but you +should normally only use one or the other -- never both.@footnote{When +in doubt, you might as well use @file{diminish}.} To use either of them, you +must first install the corresponding package from @acronym{GNU} @acronym{ELPA}. @menu * Diminish:: Hiding minor modes with Diminish. @@ -1241,61 +1436,72 @@ Diminish @subsection Diminish @findex :diminish -When diminish@footnote{The diminish package is installable from -@acronym{GNU ELPA}.} is installed, you can use the @code{:diminish} -keyword. If diminish is not installed, the @code{:diminish} keyword +When diminish@footnote{The @file{diminish} package is installable from +@acronym{GNU} @acronym{ELPA}.} is installed, you can use the @code{:diminish} +keyword. If @file{diminish} is not installed, the @code{:diminish} keyword does nothing. First, add the following declaration to the beginning of your init -file. The optional @w{@code{:ensure t}} makes sure the package is -installed if it isn't already (@pxref{Installing packages}). +file. @lisp (use-package diminish :ensure t) @end lisp -The @code{:diminish} keyword takes either a minor mode symbol, a cons -of the symbol and its replacement string, or just a replacement -string, in which case the minor mode symbol is guessed to be the -package name with @samp{-mode} appended at the end: +@noindent +The optional @w{@code{:ensure t}} makes sure the package is installed +if it isn't already (@pxref{Installing packages}). + +The @code{:diminish} keyword takes as its argument either a minor mode +symbol, a cons of the symbol and its replacement string, or just a +replacement string, in which case the minor mode symbol is guessed to +be the package name with @samp{-mode} appended at the end: @lisp +@group (use-package abbrev :diminish abbrev-mode :config (if (file-exists-p abbrev-file-name) (quietly-read-abbrev-file))) +@end group @end lisp @node Delight @subsection Delight @findex :delight -When delight@footnote{The @samp{delight} package is installable from -GNU ELPA.} is installed, you can use the @code{:delight} keyword. If -delight is not installed, the @code{:delight} keyword does nothing. +When @file{delight}@footnote{The @file{delight} package is installable from +@acronym{GNU} @acronym{ELPA}.} is installed, you can use the +@code{:delight} keyword. If @file{delight} is not installed, the +@code{:delight} keyword does nothing. First, add the following declaration to the beginning of your init -file. The optional @w{@code{:ensure t}} makes sure the package is -installed if it isn't already (@pxref{Installing packages}). +file. @lisp (use-package delight :ensure t) @end lisp -The @code{:delight} keyword takes a minor mode symbol, a replacement -string, or quoted mode line data (in which case the minor mode symbol -is assumed to be the package name with @samp{-mode} appended at the -end), both of these, or several lists of both. @xref{Mode Line -Data,,, elisp, GNU Emacs Lisp Reference Manual}. If no arguments are -provided, the default mode name is hidden completely. +@noindent +The optional @w{@code{:ensure t}} makes sure the package is installed +if it isn't already (@pxref{Installing packages}). + +The @code{:delight} keyword takes as its argument a minor mode symbol, +a replacement string, or quoted mode line data (in which case the +minor mode symbol is assumed to be the package name with @samp{-mode} +appended at the end), both of these, or several lists of both. +@xref{Mode Line Data,,, elisp, GNU Emacs Lisp Reference Manual}. If +no arguments are provided, the default mode name is hidden completely. For example, the following hides everything for the @samp{foo-mode} minor mode in the @samp{foo} package: @lisp +@group (use-package foo :delight) +@end group @end lisp If the mode name doesn't match the package name with @samp{-mode} @@ -1303,28 +1509,35 @@ Delight @code{auto-revert-mode} from the mode line: @lisp +@group ;; Don't show anything for auto-revert-mode, which doesn't match ;; its package name. (use-package autorevert :delight auto-revert-mode) +@end group @end lisp -You can also run arbitrary Lisp code. For example, to replace -@samp{foo-mode} with the value of the current buffer: +You can also use arbitrary Lisp code as argument of @code{:delight}. +For example, to replace @samp{foo-mode} with the value of the current +buffer: @lisp +@group (use-package foo :delight '(:eval buffer-file-name)) +@end group @end lisp Here is an example of hiding several built-in minor modes: @lisp +@group ;; Completely hide visual-line-mode and change auto-fill-mode to " AF". (use-package emacs :delight (auto-fill-function " AF") (visual-line-mode)) +@end group @end lisp @c ---------------------------------------------------------------------------- @@ -1334,7 +1547,7 @@ Installing packages The standard Emacs package manager is documented in the Emacs manual (@pxref{Package Installation,,, emacs, GNU Emacs Manual}). The @code{use-package} macro provides the @code{:ensure} and @code{:pin} -keywords, that interface with that package manager to automatically +keywords that interface with that package manager to automatically install packages. This is particularly useful if you use your init file on more than one system. @@ -1346,6 +1559,7 @@ Installing packages @node Install package @section Installing package +@cindex installing packages from archives @findex :ensure The @code{:ensure} keyword makes use-package ask the Emacs package @@ -1355,25 +1569,32 @@ Install package For example: @lisp +@group (use-package magit :ensure t) +@end group @end lisp If you need to install a different package from the one named by @code{use-package}, you can use a symbol: @lisp +@group (use-package tex :ensure auctex) +@end group @end lisp +@vindex use-package-always-ensure You can customize the user option @code{use-package-always-ensure} to -non-@code{nil} if you want this behavior to be global for all -packages. +a non-@code{nil} value if you want this behavior to be global for all +packages: @lisp +@group (require 'use-package-ensure) (setq use-package-always-ensure t) +@end group @end lisp @noindent @@ -1382,23 +1603,27 @@ Install package @node Pinning packages @section Pinning packages using @code{:pin} +@cindex installing package from specific archive +@cindex pinning a package to archive @findex :pin -use-package can pin a package to a specific archive using the +use-package can @dfn{pin} a package to a specific archive using the @code{:pin} keyword.@footnote{The @code{:pin} keyword has no effect on Emacs versions older than 24.4.} This allows you to mix and match packages from different archives. The primary use-case for this is -preferring to install packages from @acronym{GNU ELPA} or -@acronym{NonGNU ELPA} (indicated by @code{gnu} and @code{nongnu}, +preferring to install packages from @acronym{GNU} @acronym{ELPA} or +@acronym{NonGNU} @acronym{ELPA} (indicated by @code{gnu} and @code{nongnu}, respectively), while installing specific packages from third-party archives. For example: @lisp +@group (use-package company :ensure t :pin gnu) ; GNU ELPA +@end group @end lisp @vindex use-package-always-pin @@ -1410,6 +1635,7 @@ Pinning packages package that has been specifically marked for release by its developer, and not a development snapshot. +@cindex manual update of packages @c FIXME: This needs clarifying. AFAIK, :ensure does not update packages. If you want to manually keep a package updated and ignore upstream updates, you can pin it to @samp{manual}. This will work as long as @@ -1419,10 +1645,12 @@ Pinning packages Example: @lisp +@group (use-package org :ensure t ;; ignore org-mode from upstream and use a manually installed version :pin manual) +@end group @end lisp @code{use-package} signals an error if you try to pin a package to an @@ -1431,10 +1659,13 @@ Pinning packages @node Other package managers @section Non-standard package managers +@cindex non-standard package managers +@cindex package managers, other than @file{package.el} +@cindex installing packages using non-standard package managers -By default, use-package assumes that you are using the built-in -@code{package.el} package manager. We expect that most users will -find that it is more than capable enough, even for advanced use cases. +By default, use-package assumes that you are using the Emacs built-in +@file{package.el} package manager. We expect that most users will +find that it is capable enough, even for advanced use cases. @vindex use-package-ensure-function However, some users might prefer to use a third-party package manager @@ -1450,12 +1681,13 @@ Other package managers @c ---------------------------------------------------------------------------- @node Byte-compiling @chapter Byte-compiling your init file +@cindex byte-compiling your init file Some users might want to byte-compile their init file to make Emacs -startup even faster. This is not recommended in most cases, as the +startup faster. This is not recommended in most cases, as the speed-up is often too small to be worth it, and can lead to confusion if the byte-compiled files are out-of-date. If you still want to do -it, read on. +it, this chapter explains how to do that. @code{use-package} always loads every library that it can while a file is being byte-compiled. This helps silence spurious warnings about @@ -1463,23 +1695,27 @@ Byte-compiling @findex :defines @findex :functions +@cindex silence byte-compilation warnings However, there are times when this is just not enough. For those times, use the @code{:defines} and @code{:functions} keywords to introduce dummy variable and function declarations solely for the sake of silencing byte-compiler warnings. For example: @lisp +@group (use-package texinfo :defines texinfo-section-list :commands texinfo-mode :init (add-to-list 'auto-mode-alist '("\\.texi$" . texinfo-mode))) +@end group @end lisp If you need to silence a missing function warning, you can use @code{:functions}: @lisp +@group (use-package ruby-mode :mode "\\.rb\\'" :interpreter "ruby" @@ -1488,12 +1724,14 @@ Byte-compiling (defun my-ruby-mode-hook () (require 'inf-ruby) (inf-ruby-keys)) +@end group (add-hook 'ruby-mode-hook 'my-ruby-mode-hook)) @end lisp @findex :no-require @cindex prevent a package from loading at compile-time +@cindex package loading at byte-compilation time, prevent Normally, @code{use-package} will load each package at compile time before compiling the configuration, to ensure that any necessary symbols are in scope to satisfy the byte-compiler. At times this can @@ -1503,21 +1741,23 @@ Byte-compiling the @code{:no-require} keyword: @lisp +@group (use-package foo :no-require t :config (message "Evaluate this immediately after loading `foo'")) +@end group @end lisp @c ---------------------------------------------------------------------------- @node Troubleshooting @chapter Troubleshooting -@cindex troubleshooting -@cindex debugging +@cindex troubleshooting use-package +@cindex debugging use-package If an error occurs while initializing or configuring a package, this will not stop your Emacs from loading. Instead, @code{use-package} -captures the error and reports it in a special @code{*Warnings*} popup +captures the error and reports it in a special @file{*Warnings*} popup buffer, so that you can debug the situation in an otherwise functional Emacs. @@ -1528,11 +1768,13 @@ Troubleshooting documented below): @lisp +@group (when init-file-debug (setq use-package-verbose t use-package-expand-minimally nil use-package-compute-statistics t debug-on-error t)) +@end group @end lisp @cindex reporting bugs @@ -1552,6 +1794,8 @@ Troubleshooting @node Troubleshooting Options @section Options that help when troubleshooting +@cindex options for troubleshooting +@cindex troubleshooting, options that help @vindex use-package-expand-minimally By default, use-package will attempts to catch and report errors that @@ -1568,9 +1812,10 @@ Troubleshooting Options example: @lisp +@group (use-package example - ;; Note that errors are never trapped in the preface, since doing so would - ;; hide definitions from the byte-compiler. + ;; Note that errors are never trapped in the preface, since + ;; doing so would hide definitions from the byte-compiler. :preface (message "I'm here at byte-compile and load time") :init (message "I'm always here at startup") :config @@ -1580,20 +1825,23 @@ Troubleshooting Options :no-require t :catch (lambda (keyword err) (message (error-message-string err)))) +@end group @end lisp Evaluating the above form will print these messages: @verbatim -I’m here at byte-compile and load time -I’m always here at startup +I'm here at byte-compile and load time +I'm always here at startup Configuring package example... -I’m always here after the package is loaded +I'm always here after the package is loaded oops @end verbatim @node Gathering Statistics @section Gathering Statistics +@cindex gathering use-package statistics +@cindex usage statistics for use-package @vindex use-package-verbose When a package is loaded, and if you have @code{use-package-verbose} @@ -1616,21 +1864,21 @@ Gathering Statistics particular column, move point to it and type @kbd{S}, or click the column name at the top of the buffer on graphical displays. -@cindex use-package-reset-statistics +@findex use-package-reset-statistics To reset all statistics that use-package has gathered for the current Emacs invocation, run the command @kbd{M-x use-package-reset-statistics}. -Note that, if you are setting @code{use-package-compute-statistics} +Note that if you are setting @code{use-package-compute-statistics} directly in your init file, and not with @code{customize}, you must do this after loading @code{use-package}, but before any @code{use-package} forms. @node Disabling a package @section Disabling a package - @cindex disable package + @findex :disabled -The @code{:disabled} keyword inhibits loading a package, and all it's +The @code{:disabled} keyword inhibits loading a package, and all its customizations. It is equivalent to commenting out or deleting the definition. @@ -1641,8 +1889,10 @@ Disabling a package This example disables the @samp{foo} package: @lisp +@group (use-package foo :disabled) +@end group @end lisp When byte-compiling your init file, use-package omits disabled @@ -1652,6 +1902,8 @@ Disabling a package @c ---------------------------------------------------------------------------- @node Keyword extensions @appendix Keyword extensions +@cindex keyword extension +@cindex extending use-package keywords use-package is based on an extensible framework that makes it easy for package authors to add new keywords, or modify the behavior of @@ -1666,7 +1918,7 @@ Keyword extensions @end menu @node use-package-ensure-system-package -@section :use-package-ensure-system-package +@appendixsec :use-package-ensure-system-package @findex :ensure-system-package The @code{:ensure-system-package} keyword allows you to ensure certain @@ -1688,14 +1940,16 @@ use-package-ensure-system-package Here's an example usage: @lisp +@group (use-package foo :ensure-system-package foo) +@end group @end lisp This will expect a global binary package to exist called @code{foo}. If it does not, it will use your system package manager to attempt an install of a binary by the same name asynchronously. This requires -the GNU ELPA package +the @acronym{GNU} @acronym{ELPA} package @uref{https://gitlab.com/jabranham/system-packages,@samp{system-packages}}, so for this to work you must install that first. @@ -1703,8 +1957,10 @@ use-package-ensure-system-package together with @code{:ensure}. @lisp +@group (use-package system-packages :ensure t) +@end group @end lisp For example, on a @code{Debian GNU/Linux} system, this would call @@ -1714,9 +1970,11 @@ use-package-ensure-system-package cons in the form of @code{(binary . package-name)}. For example: @lisp +@group (use-package foo :ensure-system-package (foocmd . foo)) +@end group @end lisp On a @code{Debian GNU/Linux} system, this would call @code{apt install @@ -1725,36 +1983,42 @@ use-package-ensure-system-package @code{executable-find} function, which is what @samp{system-packages} uses internally.} -@code{:ensure-system-package} can also take a cons where its +@code{:ensure-system-package} can also take a cons where the @code{cdr} is a string that will get called by @code{(async-shell-command)} to install if it isn't found. This does -not depend upon any external package. +not depend on any external package. @lisp +@group (use-package tern :ensure-system-package (tern . "npm i -g tern")) +@end group @end lisp To install several packages, you can pass in a list of conses: @lisp +@group (use-package ruby-mode :ensure-system-package ((rubocop . "gem install rubocop") (ruby-lint . "gem install ruby-lint") (ripper-tags . "gem install ripper-tags") (pry . "gem install pry"))) +@end group @end lisp Finally, in case the package dependency does not provide a global -executable, you can ensure packages exist by checking the presence of a -file path by providing a string like so: +executable, you can ensure that packages exist by checking the +presence of a file by providing a string like so: @lisp +@group (use-package dash-at-point :if (eq system-type 'darwin) :ensure-system-package ("/Applications/Dash.app" . "brew cask install dash")) +@end group @end lisp @code{:ensure-system-package} will use @code{system-packages-install} @@ -1768,7 +2032,8 @@ use-package-ensure-system-package command if needed. @node Creating an extension -@section How to create an extension keyword +@appendixsec How to create an extension keyword +@cindex extension keywords This section describes how to create a new keyword. @@ -1794,6 +2059,7 @@ Creating an extension after the keyword, for example: @lisp +@group (defun use-package-normalize/:pin (name-symbol keyword args) (use-package-only-one (symbol-name keyword) args (lambda (label arg) @@ -1803,6 +2069,7 @@ Creating an extension (t (use-package-error ":pin wants an archive name (a string)")))))) +@end group @end lisp @item @@ -1810,13 +2077,13 @@ Creating an extension Once you have a normalizer, you must create a handler for the keyword. -Handlers can affect the handling of keywords in two ways. First, it +Handlers can affect the handling of keywords in two ways. First, they can modify the @code{state} plist before recursively processing the remaining keywords, to influence keywords that pay attention to the state (one example is the state keyword @code{:deferred}, not to be confused with the @code{use-package} keyword @code{:defer}). Then, once the remaining keywords have been handled and their resulting -forms returned, the handler may manipulate, extend, or just ignore +forms returned, the handlers may manipulate, extend, or just ignore those forms. The task of each handler is to return a @emph{list of forms} @@ -1830,6 +2097,7 @@ Creating an extension This is an example handler: @lisp +@group (defun use-package-handler/:pin (name-symbol keyword archive-name rest state) (let ((body (use-package-process-keywords name-symbol rest state))) ;; This happens at macro expansion time, not when the expanded code is @@ -1841,16 +2109,17 @@ Creating an extension body `((push '(,name-symbol . ,archive-name) package-pinned-packages)))))) +@end group @end lisp @item Test it. After the keyword has been inserted into @code{use-package-keywords}, -and a normalizer and a handler defined, you can now test it by seeing -how usages of the keyword will expand. For this, use @code{M-x -pp-macroexpand-last-sexp} with the cursor set immediately after the -@code{(use-package ...)} expression. +and a normalizer and a handler has been defined, you can now test the +keyword by seeing how usages of the keyword will expand. For this, +use @w{@kbd{M-x pp-macroexpand-last-sexp}} with the cursor set +immediately after the @code{(use-package @dots{})} expression. @end enumerate @c ---------------------------------------------------------------------------- commit 801c1c22de85a5212fbb8ca5eb5bb28cd9669497 Author: Stefan Kangas Date: Fri Dec 9 15:31:41 2022 +0100 ; Prefer HTTPS to HTTP in some URLs diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index 73f773e8f4d..da7641774fb 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -690,7 +690,7 @@ tramp-gvfs-gio-mapping ("gvfs-set-attribute" . "set")) "List of cons cells, mapping \"gvfs-\" to \"gio \".") -;; +;; (eval-and-compile (defconst tramp-gvfs-file-attributes '("name" diff --git a/lisp/progmodes/csharp-mode.el b/lisp/progmodes/csharp-mode.el index f08e8d6506e..d0465b26f05 100644 --- a/lisp/progmodes/csharp-mode.el +++ b/lisp/progmodes/csharp-mode.el @@ -505,7 +505,7 @@ csharp-guess-basic-syntax (defun csharp--compilation-error-file-resolve () "Resolve an msbuild error to a (filename . dirname) cons cell." - ;; http://stackoverflow.com/a/18049590/429091 + ;; https://stackoverflow.com/a/18049590/429091 (cons (match-string 1) (file-name-directory (match-string 4)))) (defconst csharp-compilation-re-msbuild-error diff --git a/src/itree.c b/src/itree.c index 04fa9e827a2..975f3a8e4fb 100644 --- a/src/itree.c +++ b/src/itree.c @@ -15,7 +15,7 @@ Copyright (C) 2017-2022 Free Software Foundation, Inc. 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 . */ +along with GNU Emacs. If not, see . */ #include #include diff --git a/src/itree.h b/src/itree.h index 291fa53fd30..c0c7060ac71 100644 --- a/src/itree.h +++ b/src/itree.h @@ -15,7 +15,7 @@ Copyright (C) 2017-2022 Free Software Foundation, Inc. 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 . */ +along with GNU Emacs. If not, see . */ #ifndef ITREE_H #define ITREE_H commit 74a009dd96a643b12a63a29fba3d40a74e7d82a2 Author: dannyfreeman Date: Fri Dec 9 12:49:26 2022 +0000 Eglot: Handle LSP progress with Emacs progress reporters (bug#59149) Co-authored-by: João Távora * lisp/progmodes/eglot.el (eglot-report-progress): New custom variable. (eglot-lsp-server): New slot for tracking active progress reporters. (eglot-handle-notification (eql $/progress)): New method. The LSP spec describes methods for reporting progress on long running jobs to the client: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#progress https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workDoneProgress This change reports those notifications in the minibuffer as they come in. It shows a percent indicator (if the server provides theme), or a spinner. This change could open the door for writing a "cancel long running request" command, which are identified by these progress notifications. See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#window_workDoneProgress_cancel * doc/misc/eglot.texi (Customizing Eglot): Describe new variable. diff --git a/doc/misc/eglot.texi b/doc/misc/eglot.texi index b76f8bdfd71..2aff038b9ab 100644 --- a/doc/misc/eglot.texi +++ b/doc/misc/eglot.texi @@ -955,6 +955,13 @@ Customizing Eglot to use Eglot in your @code{eglot-managed-mode-hook} or via some other mechanism. +@vindex eglot-report-progress +@cindex progress +@item eglot-report-progress +Set this variable to true if you'd like progress notifications coming +from the LSP server to be handled as Emacs's progress reporting +facilities. + @vindex eglot-workspace-configuration @cindex server workspace configuration @item eglot-workspace-configuration diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 06541d47d82..a53f62fc565 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -387,6 +387,11 @@ eglot-menu-string "String displayed in mode line when Eglot is active." :type 'string) +(defcustom eglot-report-progress t + "If non-nil, show progress of long running LSP server work" + :type 'boolean + :version "29.1") + (defvar eglot-withhold-process-id nil "If non-nil, Eglot will not send the Emacs process id to the language server. This can be useful when using docker to run a language server.") @@ -471,6 +476,7 @@ eglot--executable-find (TextDocumentEdit (:textDocument :edits) ()) (TextEdit (:range :newText)) (VersionedTextDocumentIdentifier (:uri :version) ()) + (WorkDoneProgress (:kind) (:title :message :percentage :cancellable)) (WorkspaceEdit () (:changes :documentChanges)) (WorkspaceSymbol (:name :kind) (:containerName :location :data))) "Alist (INTERFACE-NAME . INTERFACE) of known external LSP interfaces. @@ -832,6 +838,9 @@ eglot-lsp-server (project :documentation "Project associated with server." :accessor eglot--project) + (progress-reporters + :initform (make-hash-table :test #'equal) :accessor eglot--progress-reporters + :documentation "Maps LSP progress tokens to progress reporters.") (inhibit-autoreconnect :initform t :documentation "Generalized boolean inhibiting auto-reconnection if true." @@ -2050,6 +2059,27 @@ eglot-handle-notification (_server (_method (eql telemetry/event)) &rest _any) "Handle notification telemetry/event.") ;; noop, use events buffer +(cl-defmethod eglot-handle-notification + (server (_method (eql $/progress)) &key token value) + "Handle $/progress notification identified by TOKEN from SERVER." + (when eglot-report-progress + (cl-flet ((fmt (&rest args) (mapconcat #'identity args " "))) + (eglot--dbind ((WorkDoneProgress) kind title percentage message) value + (pcase kind + ("begin" + (let* ((prefix (format (concat "[eglot] %s %s:" (when percentage " ")) + (eglot-project-nickname server) token)) + (pr (puthash token + (if percentage + (make-progress-reporter prefix 0 100 percentage 1 0) + (make-progress-reporter prefix nil nil nil 1 0)) + (eglot--progress-reporters server)))) + (progress-reporter-update pr percentage (fmt title message)))) + ("report" + (when-let ((pr (gethash token (eglot--progress-reporters server)))) + (progress-reporter-update pr percentage (fmt title message)))) + ("end" (remhash token (eglot--progress-reporters server)))))))) + (cl-defmethod eglot-handle-notification (_server (_method (eql textDocument/publishDiagnostics)) &key uri diagnostics &allow-other-keys) ; FIXME: doesn't respect `eglot-strict-mode' commit 0cfeb1c2bc98b3b4c9ea8c28d176ac65b9211f7f Author: dannyfreeman Date: Fri Dec 9 11:40:53 2022 +0000 Eglot: cleanup whitespace and indentation Co-authored-by: João Távora * lisp/progmodes/eglot: Misc whitespace fixes. diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index cafb99c6d80..06541d47d82 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -541,7 +541,7 @@ eglot--check-object for type = (or (cdr (assoc k types)) t) ;; FIXME: enforce nil type? unless (cl-typep v type) do (eglot--error "A `%s' must have a %s as %s, but has %s" - interface-name ))) + interface-name))) t)) (eval-and-compile @@ -1126,11 +1126,11 @@ eglot-ensure (let ((buffer (current-buffer))) (cl-labels ((maybe-connect - () - (remove-hook 'post-command-hook #'maybe-connect nil) - (eglot--when-live-buffer buffer - (unless eglot--managed-mode - (apply #'eglot--connect (eglot--guess-contact)))))) + () + (remove-hook 'post-command-hook #'maybe-connect nil) + (eglot--when-live-buffer buffer + (unless eglot--managed-mode + (apply #'eglot--connect (eglot--guess-contact)))))) (when buffer-file-name (add-hook 'post-command-hook #'maybe-connect 'append nil))))) @@ -1182,7 +1182,7 @@ eglot--cmd (list "sh" "-c" (string-join (cons "stty raw > /dev/null;" (mapcar #'shell-quote-argument contact)) - " ")) + " ")) contact)) (defvar-local eglot--cached-server nil @@ -1236,7 +1236,7 @@ eglot--connect ,@more-initargs))))) (spread (lambda (fn) (lambda (server method params) (let ((eglot--cached-server server)) - (apply fn server method (append params nil)))))) + (apply fn server method (append params nil)))))) (server (apply #'make-instance class @@ -1570,7 +1570,7 @@ eglot--format-markup (setq-local markdown-fontify-code-blocks-natively t) (insert string) (let ((inhibit-message t) - (message-log-max nil)) + (message-log-max nil)) (ignore-errors (delay-mode-hooks (funcall mode)))) (font-lock-ensure) (string-trim (buffer-string))))) @@ -1855,8 +1855,8 @@ eglot--mouse-call (force-mode-line-update t)))))) (defun eglot-manual () "Open documentation." - (declare (obsolete info "29.1")) - (interactive) (info "(eglot)")) + (declare (obsolete info "29.1")) + (interactive) (info "(eglot)")) (easy-menu-define eglot-menu nil "Eglot" `("Eglot" @@ -1960,17 +1960,17 @@ eglot--mode-line-format 'keymap (let ((map (make-sparse-keymap))) (define-key map [mode-line down-mouse-1] eglot-server-menu) map)) - ,@(when last-error + ,@(when last-error `("/" ,(eglot--mode-line-props "error" 'compilation-mode-line-fail '((mouse-3 eglot-clear-status "Clear this status")) (format "An error occurred: %s\n" (plist-get last-error - :message))))) - ,@(when (cl-plusp pending) - `("/" ,(eglot--mode-line-props - (format "%d" pending) 'warning - '((mouse-3 eglot-forget-pending-continuations - "Forget pending continuations")) + :message))))) + ,@(when (cl-plusp pending) + `("/" ,(eglot--mode-line-props + (format "%d" pending) 'warning + '((mouse-3 eglot-forget-pending-continuations + "Forget pending continuations")) "Number of outgoing, \ still unanswered LSP requests to the server\n")))))))) @@ -1988,13 +1988,13 @@ 'eglot--make-diag (defalias 'eglot--diag-data 'flymake-diagnostic-data) (cl-loop for i from 1 - for type in '(eglot-note eglot-warning eglot-error ) + for type in '(eglot-note eglot-warning eglot-error) do (put type 'flymake-overlay-control `((mouse-face . highlight) (priority . ,(+ 50 i)) (keymap . ,(let ((map (make-sparse-keymap))) (define-key map [mouse-1] - (eglot--mouse-call 'eglot-code-actions)) + (eglot--mouse-call 'eglot-code-actions)) map))))) @@ -2174,7 +2174,7 @@ eglot--TextDocumentItem (append (eglot--VersionedTextDocumentIdentifier) (list :languageId - (eglot--language-id (eglot--current-server-or-lose)) + (eglot--language-id (eglot--current-server-or-lose)) :text (eglot--widening (buffer-substring-no-properties (point-min) (point-max)))))) @@ -2636,7 +2636,7 @@ eglot--lsp-xrefs-for-method uri range)))))) (if (vectorp response) response (and response (list response))))))) -(cl-defun eglot--lsp-xref-helper (method &key extra-params capability ) +(cl-defun eglot--lsp-xref-helper (method &key extra-params capability) "Helper for `eglot-find-declaration' & friends." (let ((eglot--lsp-xref-refs (eglot--lsp-xrefs-for-method method @@ -2668,7 +2668,7 @@ xref-backend-definitions (get-text-property 0 'eglot--lsp-workspaceSymbol probe) (eglot--dbind ((Location) uri range) location (list (eglot--xref-make-match name uri range)))) - (eglot--lsp-xrefs-for-method :textDocument/definition)))) + (eglot--lsp-xrefs-for-method :textDocument/definition)))) (cl-defmethod xref-backend-references ((_backend (eql eglot)) _identifier) (or @@ -2707,7 +2707,7 @@ eglot-format `(:textDocument/onTypeFormatting :documentOnTypeFormattingProvider ,`(:position ,(eglot--pos-to-lsp-position beg) - :ch ,(string on-type-format)))) + :ch ,(string on-type-format)))) ((and beg end) `(:textDocument/rangeFormatting :documentRangeFormattingProvider @@ -3280,24 +3280,24 @@ eglot-register-capability (eglot--project server)))))) (cl-labels ((handle-event - (event) - (pcase-let* ((`(,desc ,action ,file ,file1) event) - (action-type (cl-case action - (created 1) (changed 2) (deleted 3))) - (action-bit (when action-type - (ash 1 (1- action-type))))) - (cond - ((and (memq action '(created changed deleted)) - (cl-loop for (glob . kind-bitmask) in globs - thereis (and (> (logand kind-bitmask action-bit) 0) - (funcall glob file)))) - (jsonrpc-notify - server :workspace/didChangeWatchedFiles - `(:changes ,(vector `(:uri ,(eglot--path-to-uri file) - :type ,action-type))))) - ((eq action 'renamed) - (handle-event `(,desc 'deleted ,file)) - (handle-event `(,desc 'created ,file1))))))) + (event) + (pcase-let* ((`(,desc ,action ,file ,file1) event) + (action-type (cl-case action + (created 1) (changed 2) (deleted 3))) + (action-bit (when action-type + (ash 1 (1- action-type))))) + (cond + ((and (memq action '(created changed deleted)) + (cl-loop for (glob . kind-bitmask) in globs + thereis (and (> (logand kind-bitmask action-bit) 0) + (funcall glob file)))) + (jsonrpc-notify + server :workspace/didChangeWatchedFiles + `(:changes ,(vector `(:uri ,(eglot--path-to-uri file) + :type ,action-type))))) + ((eq action 'renamed) + (handle-event `(,desc 'deleted ,file)) + (handle-event `(,desc 'created ,file1))))))) (unwind-protect (progn (dolist (dir dirs-to-watch) commit 465a9e78b9661edd1b77a8c1d8e262913724ab71 Author: Mattias Engdegård Date: Fri Dec 9 12:04:01 2022 +0100 Better test-custom-opts diagnostics Make it easier to understand errors from the test-custom-opts test by reporting variable values and types that didn't match. * admin/cus-test.el (cus-test-errors): Richer contents. (cus-test--format-error): New. (cus-test-apropos, cus-test-errors-display, cus-test-opts): Use new format. diff --git a/admin/cus-test.el b/admin/cus-test.el index 7e73f2e44aa..44897cd1060 100644 --- a/admin/cus-test.el +++ b/admin/cus-test.el @@ -145,7 +145,8 @@ viper-mode (require 'cus-load) (defvar cus-test-errors nil - "List of problematic variables found by `cus-test-apropos'.") + "List of problematic variables found by `cus-test-apropos'. +Each element is (VARIABLE . PROBLEM); see `cus-test--format-problem'.") (defvar cus-test-tested-variables nil "List of options tested by last call of `cus-test-apropos'.") @@ -181,6 +182,15 @@ cus-test-vars-not-cus-loaded ;; (defvar cus-test-vars-cus-loaded nil ;; "A list of options loaded by `custom-load-symbol'.") +(defun cus-test--format-error (err) + "Format an element of `cus-test-errors'." + (pcase err + (`(,var :type-error ,value ,type) + (format "variable: %s\n value: %S\n type: %S" var value type)) + (`(,var :other-error ,e) + (format "variable: %s\n error: %S" var e)) + (_ (format "%S" err)))) + (defun cus-test-apropos (regexp) "Check the options matching REGEXP. The detected problematic options are stored in `cus-test-errors'." @@ -200,8 +210,7 @@ cus-test-apropos (let* ((type (custom-variable-type symbol)) (conv (widget-convert type)) (get (or (get symbol 'custom-get) 'default-value)) - values - mismatch) + values) (when (default-boundp symbol) (push (funcall get symbol) values) (push (eval (car (get symbol 'standard-value)) t) values)) @@ -215,7 +224,9 @@ cus-test-apropos ;; TODO for booleans, check for values that can be ;; evaluated and are not t or nil. Usually a bug. (unless (widget-apply conv :match value) - (setq mismatch 'mismatch))) + (let ((err (list symbol :type-error value type))) + (unless (member err cus-test-errors) + (push err cus-test-errors))))) values) ;; Store symbols with a custom-get property. @@ -231,13 +242,12 @@ cus-test-apropos (and (consp c-value) (boundp symbol) (not (equal (eval (car c-value) t) (symbol-value symbol))) - (add-to-list 'cus-test-vars-with-changed-state symbol))) - - (if mismatch - (push symbol cus-test-errors))) + (add-to-list 'cus-test-vars-with-changed-state symbol)))) (error - (push symbol cus-test-errors) + (let ((err (list symbol :other-error alpha))) + (unless (member err cus-test-errors) + (push err cus-test-errors))) (message "Error for %s: %s" symbol alpha)))) (cus-test-get-options regexp)) (message "%s options tested" @@ -292,7 +302,7 @@ cus-test-errors-display (insert "No errors found by cus-test.") (insert "The following variables seem to have problems:\n\n") (dolist (e cus-test-errors) - (insert (symbol-name e) "\n"))))) + (insert (cus-test--format-error e) "\n"))))) (defun cus-test-load-custom-loads () "Call `custom-load-symbol' on all atoms." @@ -399,7 +409,7 @@ cus-test-opts (message "No problems found") nil) (message "The following options might have problems:") - (cus-test-message cus-test-errors) + (cus-test-message (mapcar #'cus-test--format-error cus-test-errors)) cus-test-errors)) (defun cus-test-deps () commit bdbb7099784eb79ef9b94bb85f0c3dc9dae82d6c Author: Stefan Kangas Date: Mon Nov 28 00:00:11 2022 +0100 ; Fix groff warnings in man pages This fixes check-man-pages warnings such as: troff: doc/man/etags.1:203: warning: escape character ignored before '=' * doc/man/etags.1: Fix groff warnings. diff --git a/doc/man/etags.1 b/doc/man/etags.1 index 8dbea25c4cf..d3d58b82123 100644 --- a/doc/man/etags.1 +++ b/doc/man/etags.1 @@ -209,7 +209,7 @@ otherwise. This is particularly useful when storing many predefined regexps in a file. .br In its second form, \fIregexfile\fP is the name of a file that contains -a number of arguments to the \fI\-\-regex\=\fP option, +a number of arguments to the \fI\-\-regex=\fP option, one per line. Lines beginning with a space or tab are assumed to be comments, and ignored. @@ -220,22 +220,22 @@ from shell interpretation. Tag the DEFVAR macros in the emacs source files: .br -\fI\-\-regex\='/[ \\t]*DEFVAR_[A-Z_ \\t(]+"\\([^"]+\\)"/'\fP +\fI\-\-regex='/[ \\t]*DEFVAR_[A-Z_ \\t(]+"\\([^"]+\\)"/'\fP .\"" This comment is to avoid confusion to Emacs syntax highlighting .br Tag VHDL files (this example is a single long line, broken here for formatting reasons): .br -\fI\-\-language\=none\ \-\-regex='/[\ \\t]*\\(ARCHITECTURE\\|\\ -CONFIGURATION\\)\ +[^\ ]*\ +OF/'\ \-\-regex\='/[\ \\t]*\\ +\fI\-\-language=none\ \-\-regex='/[\ \\t]*\\(ARCHITECTURE\\|\\ +CONFIGURATION\\)\ +[^\ ]*\ +OF/'\ \-\-regex='/[\ \\t]*\\ \\(ATTRIBUTE\\|ENTITY\\|FUNCTION\\|PACKAGE\\(\ BODY\\)?\\ \\|PROCEDURE\\|PROCESS\\|TYPE\\)[\ \\t]+\\([^\ \\t(]+\\)/\\3/'\fP .br Tag Tcl files (this last example shows the usage of a \fItagregexp\fP): .br -\fI\-\-lang\=none \-\-regex\='/proc[\ \\t]+\\([^\ \\t]+\\)/\\1/'\fP +\fI\-\-lang=none \-\-regex='/proc[\ \\t]+\\([^\ \\t]+\\)/\\1/'\fP .br A regexp can be preceded by {\fIlang\fP}, thus restricting it to match commit d3d9676bf88cc14391ad17326d70ec21c3f4f867 Author: Stefan Kangas Date: Sun Nov 27 18:37:37 2022 +0100 New script admin/check-man-pages * admin/check-man-pages: New file with script used to check man pages for errors. (Bug#59631) * admin/make-tarball.txt: Document when to use the above script. diff --git a/admin/check-man-pages b/admin/check-man-pages new file mode 100755 index 00000000000..c7d781ba3d2 --- /dev/null +++ b/admin/check-man-pages @@ -0,0 +1,56 @@ +#!/bin/bash +### check-man-pages - check man pages for errors + +## Copyright (C) 2022 Free Software Foundation, Inc. + +## Author: Stefan Kangas + +## 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: + +## Check Emacs man pages for errors using `man'. + +### Code: + +source "${0%/*}/emacs-shell-lib" + +exit_status=0 + +cd "$PD"/../doc/man +for page in *.1; do + # ctags.1 just includes the man page etags.1, which AFAICT will + # default to the one installed on the system (!), instead of the + # one in the repository. So checking it is pointless, and we will + # in any case already check etags.1 separately. + if [ "$page" == "ctags.1" ]; then + continue + fi + log=$(emacs_mktemp) + LC_ALL=C.UTF-8 MANROFFSEQ='' MANWIDTH=80 \ + man --warnings=all,mac -E UTF-8 -l -Tutf8 -Z "$page" >/dev/null 2> "$log" + log_size=$(stat --format=%s "$log") + if [ "$log_size" -ne 0 ]; then + echo "doc/man/$page:" + # Point to the correct file for *compilation* buffers. + cat "$log" \ + | sed 's/troff: man1\/\([^ ]\+\)\.1/troff: doc\/man\/\1.1/' \ + | sed "s//doc\/man\/$page/" + exit_status=1 + fi +done + +exit $exit_status diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt index d881b816125..45da3ed6be5 100644 --- a/admin/make-tarball.txt +++ b/admin/make-tarball.txt @@ -150,6 +150,12 @@ General steps (for each step, check for possible errors): 4. autoreconf -i -I m4 --force make bootstrap + ./admin/check-man-pages + + The above script checks for any mistakes in the source text of + manual pages. Fix any errors and re-run the script to verify. + Then do this: + make -C etc/refcards make -C etc/refcards clean commit c2aea9d13232c39178351a12c1c33987f263c280 Author: Stefan Kangas Date: Fri Dec 9 11:05:34 2022 +0100 ; Mention flush-lines in kill-matching-lines docstring * lisp/replace.el (kill-matching-lines): Add cross-reference to flush-lines. diff --git a/lisp/replace.el b/lisp/replace.el index c7ae77d128b..6f59166e352 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -1101,7 +1101,10 @@ kill-matching-lines ended is ignored. Return the number of killed matching lines. When called -interactively, also print the number." +interactively, also print the number. + +If you merely want to delete the lines, without adding them to +the kill ring, the \\[flush-lines] command is faster." (interactive (progn (barf-if-buffer-read-only) commit f5c3585e4ddb71c78309f06e844a6c2dd31f3a5f Author: Stefan Kangas Date: Fri Dec 9 10:18:00 2022 +0100 ; Fix typos diff --git a/doc/misc/flymake.texi b/doc/misc/flymake.texi index 4561b760c04..80e1bceb8ec 100644 --- a/doc/misc/flymake.texi +++ b/doc/misc/flymake.texi @@ -847,7 +847,7 @@ The legacy Proc backend @findex flymake-proc-legacy-flymake The backend @code{flymake-proc-legacy-flymake} was originally designed to be extended for supporting new syntax check tools and error message -patterns. It is also controlled by its own set of customization variables +patterns. It is also controlled by its own set of customization variables. @node Proc customization variables @section Customization variables for the Proc backend diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index adb984c3e59..a4a8cd84050 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -54,9 +54,8 @@ ;; (question mark) if no backends were even configured. ;; ;; For programmers interested in writing a new Flymake backend, the -;; docstring of `flymake-diagnostic-functions', the Flymake manual, -;; and the code of existing backends are probably a good starting -;; point. +;; docstring of `flymake-diagnostic-functions', the Flymake manual, and the +;; code of existing backends are probably good starting points. ;; ;; The user wishing to customize the appearance of error types should ;; set properties on the symbols associated with each diagnostic type. diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 9a1d65ba5ef..a5d6a5f45bb 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -282,7 +282,7 @@ bind-keys-form key in the repeat map, but will not set the `repeat-map' property of the bound command. :continue BINDINGS - Within the scope of `:repeat-map' forces the - same behaviour as if no special keyword had + same behavior as if no special keyword had been used (that is, the command is bound, and it's `repeat-map' property set) :filter FORM - optional form to determine when bindings apply @@ -429,7 +429,7 @@ bind-keys key in the repeat map, but will not set the `repeat-map' property of the bound command. :continue BINDINGS - Within the scope of `:repeat-map' forces the - same behaviour as if no special keyword had + same behavior as if no special keyword had been used (that is, the command is bound, and it's `repeat-map' property set) :filter FORM - optional form to determine when bindings apply commit 58a483960dd3e8807cf0df2a865f8b4cda22f784 Author: Stefan Kangas Date: Fri Dec 9 06:55:48 2022 +0100 ; Improve use-package-autoload-keymap docstring * lisp/use-package/use-package-bind-key.el (use-package-autoload-keymap): Improve docstring. diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 44242c9e01d..4ebf54825c6 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -38,15 +38,14 @@ ;;;###autoload (defun use-package-autoload-keymap (keymap-symbol package override) - "Loads PACKAGE and then binds the key sequence used to invoke -this function to KEYMAP-SYMBOL. It then simulates pressing the -same key sequence a again, so that the next key pressed is routed -to the newly loaded keymap. + "Load PACKAGE and bind key sequence invoking this function to KEYMAP-SYMBOL. +Then simulate pressing the same key sequence a again, so that the +next key pressed is routed to the newly loaded keymap. -This function supports use-package's :bind-keymap keyword. It +This function supports use-package's :bind-keymap keyword. It works by binding the given key sequence to an invocation of this -function for a particular keymap. The keymap is expected to be -defined by the package. In this way, loading the package is +function for a particular keymap. The keymap is expected to be +defined by the package. In this way, loading the package is deferred until the prefix key sequence is pressed." (if (not (require package nil t)) (use-package-error (format "Cannot load package.el: %s" package))