[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
feature/native-comp 7a161dc 3/3: Merge remote-tracking branch 'savahnna/
From: |
Andrea Corallo |
Subject: |
feature/native-comp 7a161dc 3/3: Merge remote-tracking branch 'savahnna/master' into HEAD |
Date: |
Sun, 26 Jul 2020 04:06:46 -0400 (EDT) |
branch: feature/native-comp
commit 7a161dc688f0eeee64e307a55efbc7d11bab3627
Merge: 79ed903 9f01ce6
Author: Andrea Corallo <akrl@sdf.org>
Commit: Andrea Corallo <akrl@sdf.org>
Merge remote-tracking branch 'savahnna/master' into HEAD
---
CONTRIBUTE | 2 +-
doc/emacs/custom.texi | 35 +++++----
doc/emacs/display.texi | 4 +-
doc/emacs/emacs.texi | 6 ++
doc/emacs/maintaining.texi | 161 ++++++++++++++++++++++++++++----------
doc/lispref/os.texi | 4 +
doc/misc/epa.texi | 5 +-
doc/misc/flymake.texi | 2 +-
etc/NEWS | 20 +++--
etc/NEWS.27 | 2 +-
lisp/allout-widgets.el | 81 +++++++++++--------
lisp/bookmark.el | 3 +-
lisp/calc/calc.el | 2 +-
lisp/cus-edit.el | 7 +-
lisp/emacs-lisp/byte-opt.el | 10 +++
lisp/emacs-lisp/eldoc.el | 61 ++++++++++-----
lisp/epa-mail.el | 5 +-
lisp/gnus/gnus-start.el | 1 +
lisp/gnus/mm-decode.el | 10 ++-
lisp/ielm.el | 4 +-
lisp/man.el | 4 +-
lisp/net/gnutls.el | 5 +-
lisp/net/tramp.el | 8 +-
lisp/progmodes/bug-reference.el | 66 ++++++++++------
lisp/progmodes/project.el | 79 ++++++++++++++++---
lisp/shell.el | 7 +-
lisp/url/url.el | 19 ++++-
lisp/vc/vc-git.el | 2 +-
lisp/xwidget.el | 3 +
src/emacs-module.c | 108 ++++++++++++++++++-------
src/emacs.c | 2 +
src/w32proc.c | 10 +--
test/data/emacs-module/mod-test.c | 32 ++++++++
test/src/emacs-module-tests.el | 29 +++++++
34 files changed, 587 insertions(+), 212 deletions(-)
diff --git a/CONTRIBUTE b/CONTRIBUTE
index 26efbd7..4e42c7a 100644
--- a/CONTRIBUTE
+++ b/CONTRIBUTE
@@ -63,7 +63,7 @@ also possible to use a command like
However, we prefer the 'git format-patch' method with attachment, as
doing so delivers patches in the correct and easily-recognizable format
more reliably, and makes the job of applying the patches easier and less
-error-prone. It also allows to send patches whose author is someone
+error-prone. It also allows sending patches whose author is someone
other than the email sender.
Once the cumulative amount of your submissions exceeds about 15 lines
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index 719e09e..acd7fb1 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -1630,6 +1630,10 @@ characters are actually defined by this map.
@item
@vindex mode-specific-map
@code{mode-specific-map} is for characters that follow @kbd{C-c}.
+@item
+@vindex project-prefix-map
+@code{project-prefix-map} is for characters that follow @kbd{C-x p},
+used for project-related commands (@pxref{Projects}).
@end itemize
@node Local Keymaps
@@ -2252,10 +2256,13 @@ as a function from Lisp programs.
When Emacs is started, it normally tries to load a Lisp program from
an @dfn{initialization file}, or @dfn{init file} for short. This
file, if it exists, specifies how to initialize Emacs for you.
-If the file @file{~/.config/emacs/init.el} exists, it is used as the
-init file; otherwise Emacs may look at @file{~/.emacs.el},
-@file{~/.emacs}, @file{~/.emacs.d/init.el}, or other locations.
-@xref{Find Init}.
+Traditionally, file @file{~/.emacs} is used as the init file, although
+Emacs also looks at @file{~/.emacs.el}, @file{~/.emacs.d/init.el},
+@file{~/.config/emacs/init.el}, or other locations. @xref{Find Init}.
+
+You may find it convenient to have all your Emacs configuration in one
+directory, in which case you should use @file{~/.emacs.d/init.el} or
+the XDG-compatible @file{~/.config/emacs/init.el}.
You can use the command line switch @samp{-q} to prevent loading
your init file, and @samp{-u} (or @samp{--user}) to specify a
@@ -2661,23 +2668,21 @@ library. @xref{Hooks}.
@subsection How Emacs Finds Your Init File
Emacs normally finds your init file in a location under your home
-directory. @xref{Init File}. By default this location is
-@file{~/.emacs.d/init.el} where @file{~/} stands for your home directory.
-This default can be overridden as described below.
+directory. @xref{Init File}.
-Emacs looks for your init file
-using the filenames @file{~/.emacs.el}, @file{~/.emacs}, or
-@file{~/.emacs.d/init.el}; you can choose to use any one of these
-names. (Note that only the locations directly in your home directory
-have a leading dot in the location's basename.)
+ Emacs looks for your init file using the filenames @file{~/.emacs.el},
+@file{~/.emacs}, or @file{~/.emacs.d/init.el} in that order; you can
+choose to use any one of these names. (Note that only the locations
+directly in your home directory have a leading dot in the location's
+basename.)
Emacs can also look in an XDG-compatible location for @file{init.el},
the default is the directory @file{~/.config/emacs}. This can be
overriden by setting @env{XDG_CONFIG_HOME} in your environment, its
value replaces @file{~/.config} in the name of the default XDG init
-file. However @file{~/.emacs.d} and @file{~/.emacs} are always
-preferred if they exist, which means that you must delete or rename
-them in order to use the XDG location.
+file. However @file{~/.emacs.d}, @file{~/.emacs}, and
+@file{~/.emacs.el} are always preferred if they exist, which means
+that you must delete or rename them in order to use the XDG location.
Note also that if neither the XDG location nor @file{~/.emacs.d}
exist, then Emacs will create @file{~/.emacs.d} (and therefore use it
diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi
index a2ace00..e96e43b 100644
--- a/doc/emacs/display.texi
+++ b/doc/emacs/display.texi
@@ -1584,7 +1584,9 @@ sequences}, with the @code{escape-glyph} face. For
instance,
character code @code{U+0098} (octal 230) is displayed as @samp{\230}.
If you change the buffer-local variable @code{ctl-arrow} to
@code{nil}, the @acronym{ASCII} control characters are also displayed
-as octal escape sequences instead of caret escape sequences.
+as octal escape sequences instead of caret escape sequences. (You can
+also request that raw bytes be shown in hex, @pxref{Display Custom,
+display-raw-bytes-as-hex}.)
@vindex nobreak-char-display
@cindex non-breaking space
diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi
index 6b82aeb..5b6b7b7 100644
--- a/doc/emacs/emacs.texi
+++ b/doc/emacs/emacs.texi
@@ -857,6 +857,12 @@ Customizing VC
* CVS Options:: Options for CVS.
@end ifnottex
+Projects
+
+* Project File Commands:: Commands for handling project files.
+* Project Buffer Commands:: Commands for handling project buffers.
+* Switching Projects:: Switching between projects.
+
Change Logs
* Change Log Commands:: Commands for editing change log files.
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index cc7415e..43ec2d4 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -1657,12 +1657,43 @@ the project back-end. For example, the VC back-end
doesn't consider
``ignored'' files (@pxref{VC Ignore}) to be part of the project.
@menu
-* Project File Commands:: Commands for handling project files.
-* Switching Projects:: Switching between projects.
+* Project File Commands:: Commands for handling project files.
+* Project Buffer Commands:: Commands for handling project buffers.
+* Switching Projects:: Switching between projects.
@end menu
@node Project File Commands
-@subsection Project File Commands
+@subsection Project Commands That Operate on Files
+
+@table @kbd
+@item C-x p f
+Visit a file that belongs to the current project
+(@code{project-find-file}).
+@item C-x p g
+Find matches for a regexp in all files that belong to the current
+project (@code{project-find-regexp}).
+@item M-x project-search
+Interactively search for regexp matches in all files that belong to
+the current project.
+@item C-x p r
+Perform query-replace for a regexp in all files that belong to the
+current project (@code{project-query-replace-regexp}).
+@item C-x p d
+Run Dired in the current project's root directory
+(@code{project-dired}).
+@item C-x p v
+Run @code{vc-dir} in the current project's root directory
+(@code{project-vc-dir}).
+@item C-x p s
+Start an inferior shell in the current project's root directory
+(@code{project-shell}).
+@item C-x p e
+Start Eshell in the current project's root directory
+(@code{project-eshell}).
+@item C-x p c
+Run compilation in the current project's root directory
+(@code{project-compile}).
+@end table
Emacs provides commands for handling project files conveniently.
This subsection describes these commands.
@@ -1676,25 +1707,26 @@ doesn't seem to belong to a recognizable project, these
commands
prompt you for the project directory.
@findex project-find-file
- The command @code{project-find-file} is a convenient way of visiting
-files (@pxref{Visiting}) that belong to the current project. Unlike
-@kbd{C-x C-f}, this command doesn't require to type the full file name
-of the file to visit, you can type only the file's base name (i.e.,
-omit the leading directories). In addition, the completion candidates
-considered by the command include only the files belonging to the
-current project, and nothing else. If there's a file name at point,
-this command offers that file as the default to visit.
+ The command @kbd{C-x p f} (@code{project-find-file}) is a convenient
+way of visiting files (@pxref{Visiting}) that belong to the current
+project. Unlike @kbd{C-x C-f}, this command doesn't require to type
+the full file name of the file to visit, you can type only the file's
+base name (i.e., omit the leading directories). In addition, the
+completion candidates considered by the command include only the files
+belonging to the current project, and nothing else. If there's a file
+name at point, this command offers that file as the default to visit.
@findex project-find-regexp
- The command @code{project-find-regexp} is similar to @code{rgrep}
-(@pxref{Grep Searching}), but it searches only the files that belong
-to the current project. The command prompts for the regular
-expression to search, and pops up an Xref mode buffer with the search
-results, where you can select a match using the Xref mode commands
-(@pxref{Xref Commands}). When invoked with a prefix argument, this
-command additionally prompts for the base directory from which to
-start the search; this allows, for example, to limit the search only
-to project files under a certain subdirectory of the project root.
+ The command @kbd{C-x p g} (@code{project-find-regexp}) is similar to
+@code{rgrep} (@pxref{Grep Searching}), but it searches only the files
+that belong to the current project. The command prompts for the
+regular expression to search, and pops up an Xref mode buffer with the
+search results, where you can select a match using the Xref mode
+commands (@pxref{Xref Commands}). When invoked with a prefix
+argument, this command additionally prompts for the base directory
+from which to start the search; this allows, for example, to limit the
+search only to project files under a certain subdirectory of the
+project root.
@findex project-search
@kbd{M-x project-search} is an interactive variant of
@@ -1706,7 +1738,7 @@ matched file. To find the rest of the matches, type
@w{@kbd{M-x
fileloop-continue @key{RET}}}.
@findex project-query-replace-regexp
- @kbd{M-x project-query-replace-regexp} is similar to
+ @kbd{C-x p r} (@code{project-query-replace-regexp}) is similar to
@code{project-search}, but it prompts you for whether to replace each
match it finds, like @code{query-replace} does (@pxref{Query
Replace}), and continues to the next match after you respond. If your
@@ -1714,40 +1746,85 @@ response causes Emacs to exit the query-replace loop,
you can later
continue with @w{@kbd{M-x fileloop-continue @key{RET}}}.
@findex project-dired
- The command @code{project-dired} opens a Dired buffer
-(@pxref{Dired}) listing the files in the current project's root
+ The command @kbd{C-x p d} (@code{project-dired}) opens a Dired
+buffer (@pxref{Dired}) listing the files in the current project's root
directory.
@findex project-vc-dir
- The command @code{project-vc-dir} opens a VC Directory buffer
-(@pxref{VC Directory Mode}) listing the version control statuses of
-the files in a directory tree under the current project's
-root directory.
+ The command @kbd{C-x p v} (@code{project-vc-dir}) opens a VC
+Directory buffer (@pxref{VC Directory Mode}) listing the version
+control statuses of the files in a directory tree under the current
+project's root directory.
@findex project-shell
- The command @code{project-shell} starts a shell session
-(@pxref{Shell}) in a new buffer with the current project's root as the
-working directory.
+ The command @kbd{C-x p s} (@code{project-shell}) starts a shell
+session (@pxref{Shell}) in a new buffer with the current project's
+root as the working directory.
@findex project-eshell
- The command @code{project-eshell} starts an Eshell session in a new
-buffer with the current project's root as the working directory.
-@xref{Top,Eshell,Eshell, eshell, Eshell: The Emacs Shell}.
+ The command @kbd{C-x p e} (@code{project-eshell}) starts an Eshell
+session in a new buffer with the current project's root as the working
+directory. @xref{Top,Eshell,Eshell, eshell, Eshell: The Emacs Shell}.
+
+@findex project-compile
+ The command @kbd{C-x p c} (@code{project-compile}) runs compilation
+(@pxref{Compilation}) in the current project's root directory.
+
+@node Project Buffer Commands
+@subsection Project Commands That Operate on Buffers
+
+@table @kbd
+@item C-x p b
+Switch to another buffer belonging to the current project
+(@code{project-switch-to-buffer}).
+@item C-x p k
+Kill all live buffers that belong to the current project
+(@code{project-kill-buffers}).
+@end table
+
+@findex project-switch-to-buffer
+ Working on a project could potentially involve having many buffers
+visiting files that belong to the project, and also buffers that
+belong to the project, but don't visit any files (like the
+@file{*compilation*} buffer created by @code{project-compile}). The
+command @kbd{C-x p b} (@code{project-switch-to-buffer}) helps you
+switch between buffers that belong to the current project by prompting
+for a buffer to switch and considering only the current project's
+buffers as candidates for completion.
+
+@findex project-kill-buffers
+@vindex project-kill-buffers-ignores
+ When you finish working on the project, you may wish to kill all the
+buffers that belong to the project, to keep your Emacs session
+smaller. The command @kbd{C-x p k} (@code{project-kill-buffers})
+accomplishes that: it kills all the buffers that belong to the current
+project, except if @code{project-kill-buffers-ignores} tells
+otherwise.
@node Switching Projects
@subsection Switching Projects
+@table @kbd
+@item C-x p p
+Run an Emacs command for another project (@code{project-switch-project}).
+@end table
+
+@findex project-switch-project
+@vindex project-switch-commands
Commands that operate on project files (@pxref{Project File
Commands}) will conveniently prompt you for a project directory when
-no project is current. When you are inside a project but you want to
-operate on a different project, the command
-@code{project-switch-project} can be used.
-
- This command prompts you to choose a directory among known project
-roots, and then displays the menu of available commands to operate on
-the chosen project. The variable @code{project-switch-commands}
-controls which commands are available in the menu, and by which keys
-they are invoked.
+no project is current. When you are inside some project, but you want
+to operate on a different project, use the @kbd{C-x p p} command
+(@code{project-switch-project}). This command prompts you to choose a
+directory among known project roots, and then displays the menu of
+available commands to operate on the project you choose. The variable
+@code{project-switch-commands} controls which commands are available
+in the menu, and which key invokes each command.
+
+@vindex project-list-file
+ The variable @code{project-list-file} names the file in which Emacs
+records the list of known projects. It defaults to the file
+@file{projects} in @code{user-emacs-directory} (@pxref{Find Init}).
@node Change Log
@section Change Logs
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index 9189452..942bda1 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -707,6 +707,10 @@ the Emacs process. (This is useful primarily in batch
operation; see
If @var{exit-data} is a string, its contents are stuffed into the
terminal input buffer so that the shell (or whatever program next reads
input) can read them.
+
+If @var{exit-data} is neither an integer nor a string, or is omitted,
+that means to use the (system-specific) exit status which indicates
+successful program termination.
@end deffn
@cindex SIGTERM
diff --git a/doc/misc/epa.texi b/doc/misc/epa.texi
index 49b6b53..fa1833a 100644
--- a/doc/misc/epa.texi
+++ b/doc/misc/epa.texi
@@ -337,7 +337,8 @@ Verify OpenPGP cleartext signed messages in the current
buffer.
@kindex C-c C-e C-s
@kindex C-c C-e s
@findex epa-mail-sign
-Compose a signed message from the current buffer.
+Compose a signed message from the current buffer, using your default
+key. With a prefix argument, select the key to use interactively.
@item C-c C-e C-e and C-c C-e e
@kindex C-c C-e C-e
@@ -352,6 +353,8 @@ key in the recipient list, use @samp{encrypt-to} option in
addresses using the @code{epa-mail-aliases} list. You can also
use that option to ignore specific recipients for encryption purposes.
+With prefix argument, asks you to select the recipients interactively,
+whether to sign, and which key(s) to sign with.
@end table
@node Encrypting/decrypting gpg files, , Mail-mode integration, Commands
diff --git a/doc/misc/flymake.texi b/doc/misc/flymake.texi
index 89d2265..19dcb19 100644
--- a/doc/misc/flymake.texi
+++ b/doc/misc/flymake.texi
@@ -684,7 +684,7 @@ Binding,,, elisp, The Emacs Lisp Reference Manual}) to be
active.
msg)
into diags
finally (funcall report-fn diags)))
- (flymake-log :warning "Cancelling obsolete check %s"
+ (flymake-log :warning "Canceling obsolete check %s"
proc))
;; Cleanup the temporary buffer used to hold the
;; check's output.
diff --git a/etc/NEWS b/etc/NEWS
index 7c6c9fe..650b958 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -502,21 +502,31 @@ information, see the related entry about 'shr-browse-url'
above.
*** New user option 'project-vc-merge-submodules'.
-*** Previously used project directories are now suggested by
-all commands that prompt for a project directory.
+*** Project commands now have their own history.
+Previously used project directories are now suggested by all commands
+that prompt for a project directory.
+
++++
+*** New prefix keymap 'project-prefix-map'.
+Key sequences that invoke project-related commands start with the
+prefix 'C-x p'. Type "C-x p C-h" to show the full list.
+++
*** New commands 'project-dired', 'project-vc-dir', 'project-shell',
'project-eshell'. These commands run Dired/VC-Dir and Shell/Eshell in
a project's root directory, respectively.
-*** New command 'project-compile', which runs compilation.
++++
+*** New command 'project-compile'.
+This command runs compilation in the current project's root
+directory.
+++
*** New command 'project-switch-project'.
This command lets you "switch" to another project and run a project
command chosen from a dispatch menu.
++++
*** New user option 'project-list-file'.
** json.el
@@ -566,8 +576,8 @@ appropriate values for those two variables. There are
three guessing
mechanisms so far: based on version control information of the current
buffer's file, based on newsgroup/mail-folder name and several news
and mail message headers in Gnus buffers, and based on IRC channel and
-server in rcirc buffers. All mechanisms are extensible with custom
-rules, see the variables 'bug-reference-setup-from-vc-alist',
+network in rcirc and ERC buffers. All mechanisms are extensible with
+custom rules, see the variables 'bug-reference-setup-from-vc-alist',
'bug-reference-setup-from-mail-alist', and
'bug-reference-setup-from-irc-alist'.
diff --git a/etc/NEWS.27 b/etc/NEWS.27
index 10a6e39..2c8fa9d 100644
--- a/etc/NEWS.27
+++ b/etc/NEWS.27
@@ -270,7 +270,7 @@ doing before changing the value.
+++
** Native GnuTLS connections can now use client certificates.
Previously, this support was only available when using the external
-'gnutls-cli' command. Call 'open-network-stream' with
+'gnutls-cli' or 'starttls' command. Call 'open-network-stream' with
':client-certificate t' to trigger looking up of per-server
certificates via 'auth-source'.
diff --git a/lisp/allout-widgets.el b/lisp/allout-widgets.el
index fbdddca..2a8dced 100644
--- a/lisp/allout-widgets.el
+++ b/lisp/allout-widgets.el
@@ -415,15 +415,17 @@ not altered with an escape sequence.")
;;;_ , Widget element formatting
;;;_ = allout-item-icon-keymap
(defvar allout-item-icon-keymap
- (let ((km (make-sparse-keymap)))
+ (let ((km (make-sparse-keymap))
+ (as-parent (if (current-local-map)
+ (make-composed-keymap (current-local-map)
+ (current-global-map))
+ (current-global-map))))
+ ;; The keymap parent is reset on the each local var when mode starts.
+ (set-keymap-parent km as-parent)
(dolist (digit '("0" "1" "2" "3"
"4" "5" "6" "7" "8" "9"))
(define-key km digit 'digit-argument))
(define-key km "-" 'negative-argument)
-;; (define-key km [(return)] 'allout-tree-expand-command)
-;; (define-key km [(meta return)] 'allout-toggle-torso-command)
-;; (define-key km [(down-mouse-1)] 'allout-item-button-click)
-;; (define-key km [(down-mouse-2)] 'allout-toggle-torso-event-command)
;; Override underlying mouse-1 and mouse-2 bindings in icon territory:
(define-key km [(mouse-1)] (lambda () (interactive) nil))
(define-key km [(mouse-2)] (lambda () (interactive) nil))
@@ -433,17 +435,16 @@ not altered with an escape sequence.")
km)
"General tree-node key bindings.")
+(make-variable-buffer-local 'allout-item-icon-keymap)
;;;_ = allout-item-body-keymap
(defvar allout-item-body-keymap
(let ((km (make-sparse-keymap))
- (local-map (current-local-map)))
-;; (define-key km [(control return)] 'allout-tree-expand-command)
-;; (define-key km [(meta return)] 'allout-toggle-torso-command)
- ;; XXX We need to reset this per buffer's mode; we do so in
- ;; allout-widgets-mode.
- (if local-map
- (set-keymap-parent km local-map))
-
+ (as-parent (if (current-local-map)
+ (make-composed-keymap (current-local-map)
+ (current-global-map))
+ (current-global-map))))
+ ;; The keymap parent is reset on the each local var when mode starts.
+ (set-keymap-parent km as-parent)
km)
"General key bindings for the text content of outline items.")
(make-variable-buffer-local 'allout-item-body-keymap)
@@ -456,6 +457,7 @@ not altered with an escape sequence.")
(set-keymap-parent km allout-item-icon-keymap)
km)
"Keymap used in the item cue area - the space between the icon and
headline.")
+(make-variable-buffer-local 'allout-cue-span-keymap)
;;;_ = allout-escapes-category
(defvar allout-escapes-category nil
"Symbol for category of text property used to hide escapes of prefix-like
@@ -566,8 +568,13 @@ outline hot-spot navigation (see `allout-mode')."
(add-to-invisibility-spec '(allout-torso . t))
(add-to-invisibility-spec 'allout-escapes)
- (if (current-local-map)
- (set-keymap-parent allout-item-body-keymap (current-local-map)))
+ (let ((as-parent (if (current-local-map)
+ (make-composed-keymap (current-local-map)
+ (current-global-map))
+ (current-global-map))))
+ (set-keymap-parent allout-item-body-keymap as-parent)
+ ;; allout-cue-span-keymap uses allout-item-icon-keymap as parent.
+ (set-keymap-parent allout-item-icon-keymap as-parent))
(add-hook 'allout-exposure-change-functions
'allout-widgets-exposure-change-recorder nil 'local)
@@ -677,7 +684,7 @@ outline hot-spot navigation (see `allout-mode')."
(setplist 'allout-cue-span-category nil)
(put 'allout-cue-span-category 'evaporate t)
(put 'allout-cue-span-category
- 'modification-hooks '(allout-body-modification-handler))
+ 'modification-hooks '(allout-graphics-modification-handler))
(put 'allout-cue-span-category 'local-map allout-cue-span-keymap)
(put 'allout-cue-span-category 'mouse-face widget-button-face)
(put 'allout-cue-span-category 'pointer 'arrow)
@@ -988,6 +995,7 @@ Generally invoked via `allout-exposure-change-functions'."
;; have to distinguish between concealing and exposing so that, eg,
;; `allout-expose-topic's mix is handled properly.
handled-expose
+ handled-conceal
covered
deactivate-mark)
@@ -1594,7 +1602,10 @@ We return the item-widget corresponding to the item at
point."
(if is-container
(progn (widget-put item-widget :is-container t)
(setq reverse-siblings-chart (list 1)))
- (goto-char (widget-apply parent :actual-position :from))
+ (let ((parent-position (widget-apply parent
+ :actual-position :from)))
+ (when parent-position
+ (goto-char parent-position)))
(if (widget-get parent :is-container)
;; `allout-goto-prefix' will go to first non-container item:
(allout-goto-prefix)
@@ -1994,8 +2005,7 @@ reapplying this method will rectify the glyphs."
;; NOTE: most of the cue-area
(when (not (widget-get item-widget :is-container))
- (let* ((cue-start (or (widget-get item-widget :distinctive-end)
- (widget-get item-widget :icon-end)))
+ (let* ((cue-start (widget-get item-widget :icon-end))
(body-start (widget-get item-widget :body-start))
;(expanded (widget-get item-widget :expanded))
;(has-subitems (widget-get item-widget :has-subitems))
@@ -2050,19 +2060,22 @@ Optional FORCE means force reassignment of the region
property."
;;;_ > allout-widgets-undecorate-region (start end)
(defun allout-widgets-undecorate-region (start end)
"Eliminate widgets and decorations for all items in region from START to
END."
- (let ((next start)
- widget)
+ (let (done next widget
+ (end (or end (point-max))))
(save-excursion
(goto-char start)
- (while (< (setq next (next-single-char-property-change next
- 'display
- (current-buffer)
- end))
- end)
- (goto-char next)
- (when (setq widget (allout-get-item-widget))
- ;; if the next-property/overly progression got us to a widget:
- (allout-widgets-undecorate-item widget t))))))
+ (while (not done)
+ (when (and (allout-on-current-heading-p)
+ (setq widget (allout-get-item-widget)))
+ (if widget
+ (allout-widgets-undecorate-item widget t)))
+ (goto-char (setq next
+ (next-single-char-property-change (point)
+ 'display
+ (current-buffer)
+ end)))
+ (if (>= next end)
+ (setq done t))))))
;;;_ > allout-widgets-undecorate-text (text)
(defun allout-widgets-undecorate-text (text)
"Eliminate widgets and decorations for all items in TEXT."
@@ -2389,7 +2402,7 @@ The elements of LIST are not copied, just the list
structure itself."
;;;_ : provide
(provide 'allout-widgets)
-;;;_. Local emacs vars.
-;;;_ , Local variables:
-;;;_ , allout-layout: (-1 : 0)
-;;;_ , End:
+;;;_ . Local emacs vars.
+;;;_ , Local variables:
+;;;_ , allout-layout: (-1 : 0)
+;;;_ , End:
diff --git a/lisp/bookmark.el b/lisp/bookmark.el
index 5bb1698..de7d60f 100644
--- a/lisp/bookmark.el
+++ b/lisp/bookmark.el
@@ -1774,7 +1774,8 @@ Bookmark names preceded by a \"*\" have annotations.
\\[bookmark-bmenu-show-annotation] -- show the annotation, if it exists, for
the current bookmark
in another buffer.
\\[bookmark-bmenu-show-all-annotations] -- show the annotations of all
bookmarks in another buffer.
-\\[bookmark-bmenu-edit-annotation] -- edit the annotation for the current
bookmark."
+\\[bookmark-bmenu-edit-annotation] -- edit the annotation for the current
bookmark.
+\\[bookmark-bmenu-search] -- incrementally search for bookmarks."
(setq truncate-lines t)
(setq buffer-read-only t))
diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index 4e4fb67..09b4962 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -2429,7 +2429,7 @@ the United States."
(if (and (memq last-command-event '(?@ ?o ?h ?\' ?m))
(string-match " " calc-hms-format))
(insert " "))
- (if (and (eq this-command last-command)
+ (if (and (memq last-command '(calcDigit-start calcDigit-key))
(eq last-command-event ?.))
(progn
(require 'calc-ext)
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index 1ec2708..1942f25 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -2102,11 +2102,12 @@ and `face'."
(insert " "))
(widget-put widget :children children))))
-(defun custom-magic-reset (widget)
+(defun custom-magic-reset (widget &optional buffer)
"Redraw the :custom-magic property of WIDGET."
(let ((magic (widget-get widget :custom-magic)))
(when magic
- (widget-value-set magic (widget-value magic)))))
+ (with-current-buffer (or buffer (current-buffer))
+ (widget-value-set magic (widget-value magic))))))
;;; The `custom' Widget.
@@ -2217,7 +2218,7 @@ and `face'."
;; commands like `M-u' (that work on a region in the buffer)
;; will upcase the wrong part of the buffer, since more text has
;; been inserted before point.
- (run-with-idle-timer 0.0 nil #'custom-magic-reset widget)
+ (run-with-idle-timer 0.0 nil #'custom-magic-reset widget
(current-buffer))
(apply 'widget-default-notify widget args))))
(defun custom-redraw (widget)
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 194ceee..6f801be 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -709,6 +709,9 @@
(integer (if integer-is-first arg1 arg2))
(other (if integer-is-first arg2 arg1)))
(list (if (eq integer 1) '1+ '1-) other)))
+ ;; (+ x y z) -> (+ (+ x y) z)
+ ((= (length args) 3)
+ `(+ ,(byte-optimize-plus `(+ ,(car args) ,(cadr args))) ,@(cddr args)))
;; not further optimized
((equal args (cdr form)) form)
(t (cons '+ args)))))
@@ -737,6 +740,9 @@
((and (null (cdr args))
(numberp (car args)))
(- (car args)))
+ ;; (- x y z) -> (- (- x y) z)
+ ((= (length args) 3)
+ `(- ,(byte-optimize-minus `(- ,(car args) ,(cadr args))) ,@(cddr
args)))
;; not further optimized
((equal args (cdr form)) form)
(t (cons '- args))))))
@@ -764,6 +770,10 @@
((null args) 1)
;; (* n) -> n, where n is a number
((and (null (cdr args)) (numberp (car args))) (car args))
+ ;; (* x y z) -> (* (* x y) z)
+ ((= (length args) 3)
+ `(* ,(byte-optimize-multiply `(* ,(car args) ,(cadr args)))
+ ,@(cddr args)))
;; not further optimized
((equal args (cdr form)) form)
(t (cons '* args)))))
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index 6ed5bff..fcb104e 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -5,7 +5,7 @@
;; Author: Noah Friedman <friedman@splode.com>
;; Keywords: extensions
;; Created: 1995-10-06
-;; Version: 1.5.0
+;; Version: 1.6.0
;; Package-Requires: ((emacs "26.3"))
;; This is a GNU ELPA :core package. Avoid functionality that is not
@@ -340,16 +340,32 @@ Also store it in `eldoc-last-message' and return that
value."
;; for us, but do note that the last-message will be gone.
(setq eldoc-last-message nil))))
-;; Decide whether now is a good time to display a message.
-(defun eldoc-display-message-p ()
- "Return non-nil when it is appropriate to display an ElDoc message."
- (and (eldoc-display-message-no-interference-p)
- ;; If this-command is non-nil while running via an idle
- ;; timer, we're still in the middle of executing a command,
- ;; e.g. a query-replace where it would be annoying to
- ;; overwrite the echo area.
- (not this-command)
- (eldoc--message-command-p last-command)))
+(defvar-local eldoc--last-request-state nil
+ "Tuple containing information about last ElDoc request.")
+(defun eldoc--request-state ()
+ "Compute information to store in `eldoc--last-request-state'."
+ (list (current-buffer) (buffer-modified-tick) (point)))
+
+(defun eldoc--request-docs-p (request-state)
+ "Return non-nil when it is appropriate to request docs.
+REQUEST-STATE is a candidate for `eldoc--last-request-state'"
+ (and
+ ;; FIXME: The original idea behind this function is to protect the
+ ;; Echo area from ElDoc interference, but since that is only one of
+ ;; the possible outlets of ElDoc, this must soon be reworked.
+ (eldoc-display-message-no-interference-p)
+ (not (and eldoc--doc-buffer
+ (get-buffer-window eldoc--doc-buffer)
+ (equal request-state
+ (with-current-buffer
+ eldoc--doc-buffer
+ eldoc--last-request-state))))
+ ;; If this-command is non-nil while running via an idle
+ ;; timer, we're still in the middle of executing a command,
+ ;; e.g. a query-replace where it would be annoying to
+ ;; overwrite the echo area.
+ (not this-command)
+ (eldoc--message-command-p last-command)))
;; Check various conditions about the current environment that might make
@@ -400,7 +416,8 @@ so that the global value (i.e. the default value of the
hook) is
taken into account if the major mode specific function does not
return any documentation.")
-(defvar eldoc--doc-buffer nil "Buffer holding latest eldoc-produced docs.")
+(defvar eldoc--doc-buffer nil "Buffer displaying latest ElDoc-produced docs.")
+
(defun eldoc-doc-buffer (&optional interactive)
"Get latest *eldoc* help buffer. Interactively, display it."
(interactive (list t))
@@ -410,6 +427,7 @@ return any documentation.")
(setq eldoc--doc-buffer (get-buffer-create "*eldoc*")))
(when interactive (display-buffer eldoc--doc-buffer))))
+
(defun eldoc--handle-docs (docs)
"Display multiple DOCS in echo area.
DOCS is a list of (STRING PLIST...). It is already sorted.
@@ -429,9 +447,12 @@ Honor most of `eldoc-echo-area-use-multiline-p'."
(integer val)
(t 1)))
(things-reported-on)
+ (request eldoc--last-request-state)
single-doc single-doc-sym)
;; Then, compose the contents of the `*eldoc*' buffer.
(with-current-buffer (eldoc-doc-buffer)
+ ;; Set doc-buffer's `eldoc--last-request-state', too
+ (setq eldoc--last-request-state request)
(let ((inhibit-read-only t))
(erase-buffer) (setq buffer-read-only t)
(local-set-key "q" 'quit-window)
@@ -741,14 +762,16 @@ should endeavour to display the docstrings eventually
produced."
(defun eldoc-print-current-symbol-info (&optional interactive)
"Document thing at point."
(interactive '(t))
- (cond (interactive
- (eldoc--invoke-strategy))
- (t
- (if (not (eldoc-display-message-p))
- ;; Erase the last message if we won't display a new one.
- (when eldoc-last-message
- (eldoc--message nil))
+ (let ((token (eldoc--request-state)))
+ (cond (interactive
+ (eldoc--invoke-strategy))
+ ((not (eldoc--request-docs-p token))
+ ;; Erase the last message if we won't display a new one.
+ (when eldoc-last-message
+ (eldoc--message nil)))
+ (t
(let ((non-essential t))
+ (setq eldoc--last-request-state token)
;; Only keep looking for the info as long as the user hasn't
;; requested our attention. This also locally disables
;; inhibit-quit.
diff --git a/lisp/epa-mail.el b/lisp/epa-mail.el
index 00f560a..6347525 100644
--- a/lisp/epa-mail.el
+++ b/lisp/epa-mail.el
@@ -85,7 +85,10 @@ The buffer is expected to contain a mail message."
;;;###autoload
(defun epa-mail-sign (start end signers mode)
"Sign the current buffer.
-The buffer is expected to contain a mail message."
+The buffer is expected to contain a mail message, and signing is
+performed with your default key.
+With prefix argument, asks you to select interactively the key to
+use from your key ring."
(declare (interactive-only t))
(interactive
(save-excursion
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index 78e0749..ba8b91b 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -2111,6 +2111,7 @@ The info element is shared with the same element of
((string= gnus-ignored-newsgroups "")
(delete-matching-lines "^to\\."))
(t
+ ;; relint suppression: Duplicated alternative branch
(delete-matching-lines (concat "^to\\.\\|" gnus-ignored-newsgroups))))
(goto-char (point-min))
diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el
index 96695aa..587c4e0 100644
--- a/lisp/gnus/mm-decode.el
+++ b/lisp/gnus/mm-decode.el
@@ -1680,8 +1680,14 @@ If RECURSIVE, search recursively."
(t (y-or-n-p
(format "Decrypt (S/MIME) part? "))))
(mm-view-pkcs7 parts from))
- (goto-char (point-min))
- (insert "Content-type: text/plain\n\n")
+ ;; Normally there will be a Content-type header here, but
+ ;; some mailers don't add that to the encrypted part, which
+ ;; makes the subsequent re-dissection fail here.
+ (save-restriction
+ (mail-narrow-to-head)
+ (unless (mail-fetch-field "content-type")
+ (goto-char (point-max))
+ (insert "Content-type: text/plain\n\n")))
(setq parts (mm-dissect-buffer t)))))
((equal subtype "signed")
(unless (and (setq protocol
diff --git a/lisp/ielm.el b/lisp/ielm.el
index 47c5158..b3654b9 100644
--- a/lisp/ielm.el
+++ b/lisp/ielm.el
@@ -537,7 +537,9 @@ Customized bindings may be defined in `ielm-map', which
currently contains:
'(comint-replace-by-expanded-history
ielm-complete-filename elisp-completion-at-point))
(add-hook 'eldoc-documentation-functions
- #'elisp-eldoc-documentation-function nil t)
+ #'elisp-eldoc-var-docstring nil t)
+ (add-hook 'eldoc-documentation-functions
+ #'elisp-eldoc-funcall nil t)
(set (make-local-variable 'ielm-prompt-internal) ielm-prompt)
(set (make-local-variable 'comint-prompt-read-only) ielm-prompt-read-only)
(setq comint-get-old-input 'ielm-get-old-input)
diff --git a/lisp/man.el b/lisp/man.el
index 8a36f3a..3121334 100644
--- a/lisp/man.el
+++ b/lisp/man.el
@@ -1396,7 +1396,7 @@ synchronously, PROCESS is the name of the buffer where
the manpage
command is run. Second argument STRING is the entire string of output."
(save-excursion
(let ((Man-buffer (process-buffer process)))
- (if (null (buffer-name Man-buffer)) ;; deleted buffer
+ (if (not (buffer-live-p Man-buffer)) ;; deleted buffer
(set-process-buffer process nil)
(with-current-buffer Man-buffer
@@ -1430,7 +1430,7 @@ manpage command."
(delete-buff nil)
message)
- (if (null (buffer-name Man-buffer)) ;; deleted buffer
+ (if (not (buffer-live-p Man-buffer)) ;; deleted buffer
(or (stringp process)
(set-process-buffer process nil))
diff --git a/lisp/net/gnutls.el b/lisp/net/gnutls.el
index cd86b4d..e713c94 100644
--- a/lisp/net/gnutls.el
+++ b/lisp/net/gnutls.el
@@ -105,12 +105,13 @@ Security'."
(defcustom gnutls-trustfiles
'(
- "/etc/ssl/certs/ca-certificates.crt" ; Debian, Ubuntu, Gentoo and Arch
Linux
+ "/etc/ssl/certs/ca-certificates.crt" ; Debian, Ubuntu, Gentoo,
+ ; Arch, Guix, Parabola
"/etc/pki/tls/certs/ca-bundle.crt" ; Fedora and RHEL
"/etc/ssl/ca-bundle.pem" ; Suse
"/usr/ssl/certs/ca-bundle.crt" ; Cygwin
"/usr/local/share/certs/ca-root-nss.crt" ; FreeBSD
- "/etc/ssl/cert.pem" ; macOS
+ "/etc/ssl/cert.pem" ; macOS, Dragora, Parabola
"/etc/certs/ca-certificates.crt" ; OpenIndiana
)
"List of CA bundle location filenames or a function returning said list.
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index cd35e3f..19cf333 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -2012,9 +2012,11 @@ without a visible progress reporter."
(tramp-message ,vec ,level "%s..." ,message)
(let ((cookie "failed")
(tm
- ;; We start a pulsing progress reporter after 3
- ;; seconds. Display only when there is a minimum level.
- (when-let ((pr (and (<= ,level (min tramp-verbose 3))
+ ;; We start a pulsing progress reporter after 3 seconds.
+ ;; Start only when there is no other progress reporter
+ ;; running, and when there is a minimum level.
+ (when-let ((pr (and (null tramp-inhibit-progress-reporter)
+ (<= ,level (min tramp-verbose 3))
(make-progress-reporter ,message nil nil))))
(run-at-time 3 0.1 #'tramp-progress-reporter-update pr))))
(unwind-protect
diff --git a/lisp/progmodes/bug-reference.el b/lisp/progmodes/bug-reference.el
index b88ea0a..c52331f 100644
--- a/lisp/progmodes/bug-reference.el
+++ b/lisp/progmodes/bug-reference.el
@@ -353,38 +353,45 @@ and set it if applicable."
This takes action if `bug-reference-mode' is enabled in IRC
channels using one of Emacs' IRC clients (rcirc and ERC).
-Currently, only rcirc is supported.
+Currently, rcirc and ERC are supported.
Each element has the form
- (CHANNEL-REGEXP SERVER-REGEXP BUG-REGEXP URL-FORMAT)
+ (CHANNEL-REGEXP NETWORK-REGEXP BUG-REGEXP URL-FORMAT)
-CHANNEL-REGEXP is a regexp matched against the current mail IRC
-channel name. SERVER-REGEXP is matched against the IRC server
-name. If any of those matches, BUG-REGEXP is set as
+CHANNEL-REGEXP is a regexp matched against the current IRC
+channel name (e.g. #emacs). NETWORK-REGEXP is matched against
+the IRC network name (e.g. freenode). Both entries are optional.
+If all given entries match, BUG-REGEXP is set as
`bug-reference-bug-regexp' and URL-FORMAT is set as
`bug-reference-url-format'.")
-(defun bug-reference--maybe-setup-from-irc (channel server)
- "Set up according to IRC CHANNEL or SERVER.
-CHANNEL is an IRC channel name and SERVER is that channel's
-server name.
+(defun bug-reference--maybe-setup-from-irc (channel network)
+ "Set up according to IRC CHANNEL or NETWORK.
+CHANNEL is an IRC channel name (or generally a target, i.e., it
+could also be a user name) and NETWORK is that channel's network
+name.
-If any CHANNEL-REGEXP or SERVER-REGEXP of
-`bug-reference-setup-from-irc-alist' matches CHANNEL or SERVER,
-the corresponding BUG-REGEXP and URL-FORMAT are set."
+If any `bug-reference-setup-from-irc-alist' entry's
+CHANNEL-REGEXP and NETWORK-REGEXP match CHANNEL and NETWORK, the
+corresponding BUG-REGEXP and URL-FORMAT are set."
(catch 'setup-done
(dolist (config bug-reference-setup-from-irc-alist)
- (when (or
- (and channel
- (car config)
- (string-match-p (car config) channel))
- (and server
- (nth 1 config)
- (string-match-p (car config) server)))
- (setq-local bug-reference-bug-regexp (nth 2 config))
- (setq-local bug-reference-url-format (nth 3 config))
- (throw 'setup-done t)))))
+ (let ((channel-rx (car config))
+ (network-rx (nth 1 config)))
+ (when (and
+ ;; One of both has to be given.
+ (or channel-rx network-rx)
+ ;; The args have to be set.
+ channel network)
+ (when (and
+ (or (null channel-rx)
+ (string-match-p channel-rx channel))
+ (or (null network-rx)
+ (string-match-p network-rx network)))
+ (setq-local bug-reference-bug-regexp (nth 2 config))
+ (setq-local bug-reference-url-format (nth 3 config))
+ (throw 'setup-done t)))))))
(defvar rcirc-target)
(defvar rcirc-server-buffer)
@@ -402,6 +409,18 @@ and set it if applicable."
(with-current-buffer rcirc-server-buffer
rcirc-server)))))
+(declare-function erc-format-target "erc")
+(declare-function erc-network-name "erc-networks")
+
+(defun bug-reference-try-setup-from-erc ()
+ "Try setting up `bug-reference-mode' based on ERC channel and server.
+Test each configuration in `bug-reference-setup-from-irc-alist'
+and set it if applicable."
+ (when (derived-mode-p 'erc-mode)
+ (bug-reference--maybe-setup-from-irc
+ (erc-format-target)
+ (erc-network-name))))
+
(defun bug-reference--run-auto-setup ()
(when (or bug-reference-mode
bug-reference-prog-mode)
@@ -414,7 +433,8 @@ and set it if applicable."
(catch 'setup
(dolist (f (list #'bug-reference-try-setup-from-vc
#'bug-reference-try-setup-from-gnus
- #'bug-reference-try-setup-from-rcirc))
+ #'bug-reference-try-setup-from-rcirc
+ #'bug-reference-try-setup-from-erc))
(when (funcall f)
(throw 'setup t))))))))
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index db8e54b..5cfc6a2 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -37,11 +37,29 @@
;; current project, without having to know which package handles
;; detection of that project type, parsing its config files, etc.
;;
-;; Infrastructure:
+;; This file consists of following parts:
;;
-;; Function `project-current', to determine the current project
-;; instance, and 4 (at the moment) generic functions that act on it.
-;; This list is to be extended in future versions.
+;; Infrastructure (the public API):
+;;
+;; Function `project-current' that returns the current project
+;; instance based on the value of the hook `project-find-functions',
+;; and several generic functions that act on it.
+;;
+;; `project-root' must be defined for every project.
+;; `project-files' can be overridden for performance purposes.
+;; `project-ignores' and `project-external-roots' describe the project
+;; files and its relations to external directories. `project-files'
+;; should be consistent with `project-ignores'.
+;;
+;; This list can change in future versions.
+;;
+;; VC project:
+;;
+;; Originally conceived as an example implementation, now it's a
+;; relatively fast backend that delegates to 'git ls-files' or 'hg
+;; status' to list the project's files. It honors the VC ignore
+;; files, but supports additions to the list using the user option
+;; `project-vc-ignores' (usually through .dir-locals.el).
;;
;; Utils:
;;
@@ -50,9 +68,49 @@
;;
;; Commands:
;;
-;; `project-find-file', `project-find-regexp' and
-;; `project-or-external-find-regexp' use the current API, and thus
-;; will work in any project that has an adapter.
+;; `project-prefix-map' contains the full list of commands defined in
+;; this package. This map uses the prefix `C-x p' by default.
+;; Type `C-x p f' to find file in the current project.
+;; Type `C-x p C-h' to see all available commands and bindings.
+;;
+;; All commands defined in this package are implemented using the
+;; public API only. As a result, they will work with any project
+;; backend that follows the protocol.
+;;
+;; Any third-party code that wants to use this package should likewise
+;; target the public API. Use any of the built-in commands as the
+;; example.
+;;
+;; How to create a new backend:
+;;
+;; - Consider whether you really should, or whether there are other
+;; ways to reach your goals. If the backend's performance is
+;; significantly lower than that of the built-in one, and it's first
+;; in the list, it will affect all commands that use it. Unless you
+;; are going to be using it only yourself or in special circumstances,
+;; you will probably want it to be fast, and it's unlikely to be a
+;; trivial endeavor. `project-files' is the method to optimize (the
+;; default implementation gets slower the more files the directory
+;; has, and the longer the list of ignores is).
+;;
+;; - Choose the format of the value that represents a project for your
+;; backend (we call it project instance). Don't use any of the
+;; formats from other backends. The format can be arbitrary, as long
+;; as the datatype is something `cl-defmethod' can dispatch on. The
+;; value should be stable (when compared with `equal') across
+;; invocations, meaning calls to that function from buffers belonging
+;; to the same project should return equal values.
+;;
+;; - Write a new function that will determine the current project
+;; based on the directory and add it to `project-find-functions'
+;; (which see) using `add-hook'. It is a good idea to depend on the
+;; directory only, and not on the current major mode, for example.
+;; Because the usual expectation is that all files in the directory
+;; belong to the same project (even if some/most of them are ignored).
+;;
+;; - Define new methods for some or all generic functions for this
+;; backend using `cl-defmethod'. A `project-root' method is
+;; mandatory, `project-files' is recommended, the rest are optional.
;;; TODO:
@@ -139,7 +197,7 @@ of the project instance object."
pr (project--find-in-directory directory))))
(when maybe-prompt
(if pr
- (project--add-to-project-list-front pr)
+ (project-remember-project pr)
(project--remove-from-project-list directory)
(setq pr (cons 'transient directory))))
pr))
@@ -517,6 +575,7 @@ DIRS must contain directory names."
(defvar project-prefix-map
(let ((map (make-sparse-keymap)))
(define-key map "f" 'project-find-file)
+ (define-key map "F" 'project-or-external-find-file)
(define-key map "b" 'project-switch-to-buffer)
(define-key map "s" 'project-shell)
(define-key map "d" 'project-dired)
@@ -526,6 +585,7 @@ DIRS must contain directory names."
(define-key map "k" 'project-kill-buffers)
(define-key map "p" 'project-switch-project)
(define-key map "g" 'project-find-regexp)
+ (define-key map "G" 'project-or-external-find-regexp)
(define-key map "r" 'project-query-replace-regexp)
map)
"Keymap for project commands.")
@@ -927,7 +987,8 @@ With some possible metadata (to be decided).")
(pp project--list (current-buffer))
(write-region nil nil filename nil 'silent))))
-(defun project--add-to-project-list-front (pr)
+;;;###autoload
+(defun project-remember-project (pr)
"Add project PR to the front of the project list.
Save the result in `project-list-file' if the list of projects has changed."
(project--ensure-read-project-list)
diff --git a/lisp/shell.el b/lisp/shell.el
index 1e2679f..dc52841 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -184,16 +184,13 @@ shell buffer. The value may depend on the operating
system or shell."
shell-environment-variable-completion
shell-command-completion
shell-c-a-p-replace-by-expanded-directory
+ pcomplete-completions-at-point
shell-filename-completion
- comint-filename-completion
- ;; Put `pcomplete-completions-at-point' last so that other
- ;; functions can run before it does, see bug#34330.
- pcomplete-completions-at-point)
+ comint-filename-completion)
"List of functions called to perform completion.
This variable is used to initialize `comint-dynamic-complete-functions' in the
shell buffer."
:type '(repeat function)
- :version "27.1"
:group 'shell)
(defcustom shell-command-regexp "[^;&|\n]+"
diff --git a/lisp/url/url.el b/lisp/url/url.el
index 12a8a9c..321e79c 100644
--- a/lisp/url/url.el
+++ b/lisp/url/url.el
@@ -238,7 +238,8 @@ how long to wait for a response before giving up."
(let ((retrieval-done nil)
(start-time (current-time))
(url-asynchronous nil)
- (asynch-buffer nil))
+ (asynch-buffer nil)
+ (timed-out nil))
(setq asynch-buffer
(url-retrieve url (lambda (&rest ignored)
(url-debug 'retrieval "Synchronous fetching done
(%S)" (current-buffer))
@@ -261,7 +262,9 @@ how long to wait for a response before giving up."
;; process output.
(while (and (not retrieval-done)
(or (not timeout)
- (time-less-p (time-since start-time) timeout)))
+ (not (setq timed-out
+ (time-less-p timeout
+ (time-since start-time))))))
(url-debug 'retrieval
"Spinning in url-retrieve-synchronously: %S (%S)"
retrieval-done asynch-buffer)
@@ -300,8 +303,16 @@ how long to wait for a response before giving up."
(when quit-flag
(delete-process proc))
(setq proc (and (not quit-flag)
- (get-buffer-process asynch-buffer)))))))
- asynch-buffer)))
+ (get-buffer-process asynch-buffer))))))
+ ;; On timeouts, make sure we kill any pending processes.
+ ;; There may be more than one if we had a redirect.
+ (when timed-out
+ (when (process-live-p proc)
+ (delete-process proc))
+ (when-let ((aproc (get-buffer-process asynch-buffer)))
+ (when (process-live-p aproc)
+ (delete-process aproc))))))
+ asynch-buffer))
;; url-mm-callback called from url-mm, which requires mm-decode.
(declare-function mm-dissect-buffer "mm-decode"
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index b5cb842..7f6e1db 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -1237,7 +1237,7 @@ log entries."
(set (make-local-variable 'log-view-message-re)
(if (not (memq vc-log-view-type '(long log-search with-diff)))
(cadr vc-git-root-log-format)
- "^commit *\\([0-9a-z]+\\)"))
+ "^commit +\\([0-9a-z]+\\)"))
;; Allow expanding short log entries.
(when (memq vc-log-view-type '(short log-outgoing log-incoming mergebase))
(setq truncate-lines t)
diff --git a/lisp/xwidget.el b/lisp/xwidget.el
index 775dddf..aed6c09 100644
--- a/lisp/xwidget.el
+++ b/lisp/xwidget.el
@@ -92,6 +92,9 @@ Interactively, URL defaults to the string looking like a url
around point."
(or (featurep 'xwidget-internal)
(user-error "Your Emacs was not compiled with xwidgets support"))
(when (stringp url)
+ ;; If it's a "naked url", just try adding https: to it.
+ (unless (string-match "\\`[A-Za-z]+:" url)
+ (setq url (concat "https://"; url)))
(if new-session
(xwidget-webkit-new-session url)
(xwidget-webkit-goto-url url))))
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 3d1827c..e4e7da0 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -78,6 +78,7 @@ To add a new module function, proceed as follows:
#include "emacs-module.h"
#include <stdarg.h>
+#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
@@ -154,11 +155,11 @@ struct emacs_value_frame
/* A structure that holds an initial frame (so that the first local
values require no dynamic allocation) and keeps track of the
current frame. */
-static struct emacs_value_storage
+struct emacs_value_storage
{
struct emacs_value_frame initial;
struct emacs_value_frame *current;
-} global_storage;
+};
/* Private runtime and environment members. */
@@ -371,10 +372,57 @@ module_get_environment (struct emacs_runtime *runtime)
}
/* To make global refs (GC-protected global values) keep a hash that
- maps global Lisp objects to reference counts. */
+ maps global Lisp objects to 'struct module_global_reference'
+ objects. We store the 'emacs_value' in the hash table so that it
+ is automatically garbage-collected (Bug#42482). */
static Lisp_Object Vmodule_refs_hash;
+/* Pseudovector type for global references. The pseudovector tag is
+ PVEC_OTHER since these values are never printed and don't need to
+ be special-cased for garbage collection. */
+
+struct module_global_reference {
+ /* Pseudovector header, must come first. */
+ union vectorlike_header header;
+
+ /* Holds the emacs_value for the object. The Lisp_Object stored
+ therein must be the same as the hash key. */
+ struct emacs_value_tag value;
+
+ /* Reference count, always positive. */
+ ptrdiff_t refcount;
+};
+
+static struct module_global_reference *
+XMODULE_GLOBAL_REFERENCE (Lisp_Object o)
+{
+ eassert (PSEUDOVECTORP (o, PVEC_OTHER));
+ return XUNTAG (o, Lisp_Vectorlike, struct module_global_reference);
+}
+
+/* Returns whether V is a global reference. Only used to check module
+ assertions. If V is not a global reference, increment *N by the
+ number of global references (for debugging output). */
+
+static bool
+module_global_reference_p (emacs_value v, ptrdiff_t *n)
+{
+ struct Lisp_Hash_Table *h = XHASH_TABLE (Vmodule_refs_hash);
+ /* Note that we can't use `hash_lookup' because V might be a local
+ reference that's identical to some global reference. */
+ for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); ++i)
+ {
+ if (!EQ (HASH_KEY (h, i), Qunbound)
+ && &XMODULE_GLOBAL_REFERENCE (HASH_VALUE (h, i))->value == v)
+ return true;
+ }
+ /* Only used for debugging, so we don't care about overflow, just
+ make sure the operation is defined. */
+ INT_ADD_WRAPV (*n, h->count, n);
+ return false;
+}
+
static emacs_value
module_make_global_ref (emacs_env *env, emacs_value value)
{
@@ -383,21 +431,30 @@ module_make_global_ref (emacs_env *env, emacs_value value)
Lisp_Object new_obj = value_to_lisp (value), hashcode;
ptrdiff_t i = hash_lookup (h, new_obj, &hashcode);
+ /* Note: This approach requires the garbage collector to never move
+ objects. */
+
if (i >= 0)
{
Lisp_Object value = HASH_VALUE (h, i);
- EMACS_INT refcount = XFIXNAT (value) + 1;
- if (MOST_POSITIVE_FIXNUM < refcount)
+ struct module_global_reference *ref = XMODULE_GLOBAL_REFERENCE (value);
+ bool overflow = INT_ADD_WRAPV (ref->refcount, 1, &ref->refcount);
+ if (overflow)
overflow_error ();
- value = make_fixed_natnum (refcount);
- set_hash_value_slot (h, i, value);
+ return &ref->value;
}
else
{
- hash_put (h, new_obj, make_fixed_natnum (1), hashcode);
+ struct module_global_reference *ref
+ = ALLOCATE_PLAIN_PSEUDOVECTOR (struct module_global_reference,
+ PVEC_OTHER);
+ ref->value.v = new_obj;
+ ref->refcount = 1;
+ Lisp_Object value;
+ XSETPSEUDOVECTOR (value, ref, PVEC_OTHER);
+ hash_put (h, new_obj, value, hashcode);
+ return &ref->value;
}
-
- return allocate_emacs_value (env, &global_storage, new_obj);
}
static void
@@ -411,25 +468,21 @@ module_free_global_ref (emacs_env *env, emacs_value
global_value)
Lisp_Object obj = value_to_lisp (global_value);
ptrdiff_t i = hash_lookup (h, obj, NULL);
- if (i >= 0)
+ if (module_assertions)
{
- EMACS_INT refcount = XFIXNAT (HASH_VALUE (h, i)) - 1;
- if (refcount > 0)
- set_hash_value_slot (h, i, make_fixed_natnum (refcount));
- else
- {
- eassert (refcount == 0);
- hash_remove_from_table (h, obj);
- }
+ ptrdiff_t n = 0;
+ if (! module_global_reference_p (global_value, &n))
+ module_abort ("Global value was not found in list of %"pD"d globals",
+ n);
}
- if (module_assertions)
+ if (i >= 0)
{
- ptrdiff_t count = 0;
- if (value_storage_contains_p (&global_storage, global_value, &count))
- return;
- module_abort ("Global value was not found in list of %"pD"d globals",
- count);
+ Lisp_Object value = HASH_VALUE (h, i);
+ struct module_global_reference *ref = XMODULE_GLOBAL_REFERENCE (value);
+ eassert (0 < ref->refcount);
+ if (--ref->refcount == 0)
+ hash_remove_from_table (h, obj);
}
}
@@ -1250,7 +1303,7 @@ value_to_lisp (emacs_value v)
++num_environments;
}
/* Also check global values. */
- if (value_storage_contains_p (&global_storage, v, &num_values))
+ if (module_global_reference_p (v, &num_values))
goto ok;
module_abort (("Emacs value not found in %"pD"d values "
"of %"pD"d environments"),
@@ -1467,10 +1520,7 @@ module_handle_nonlocal_exit (emacs_env *env, enum
nonlocal_exit type,
void
init_module_assertions (bool enable)
{
- /* If enabling module assertions, use a hidden environment for
- storing the globals. This environment is never freed. */
module_assertions = enable;
- initialize_storage (&global_storage);
}
/* Return whether STORAGE contains VALUE. Used to check module
diff --git a/src/emacs.c b/src/emacs.c
index 228ac29..34717cd 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -2356,6 +2356,8 @@ DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
doc: /* Exit the Emacs job and kill it.
If ARG is an integer, return ARG as the exit program code.
If ARG is a string, stuff it as keyboard input.
+Any other value of ARG, or ARG omitted, means return an
+exit code that indicates successful program termination.
This function is called upon receipt of the signals SIGTERM
or SIGHUP, and upon SIGINT in batch mode.
diff --git a/src/w32proc.c b/src/w32proc.c
index 16e32e4..c50f246 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -2790,11 +2790,11 @@ sys_kill (pid_t pid, int sig)
/* Set the foreground window to the child. */
if (SetForegroundWindow (cp->hwnd))
{
- /* Record the state of the Ctrl key: the user could
- have it depressed while we are simulating Ctrl-C,
- in which case we will have to leave the state of
- Ctrl depressed when we are done. */
- short ctrl_state = GetKeyState (VK_CONTROL) & 0x8000;
+ /* Record the state of the left Ctrl key: the user
+ could have it depressed while we are simulating
+ Ctrl-C, in which case we will have to leave the
+ state of that Ctrl depressed when we are done. */
+ short ctrl_state = GetKeyState (VK_LCONTROL) & 0x8000;
/* Generate keystrokes as if user had typed Ctrl-Break or
Ctrl-C. */
diff --git a/test/data/emacs-module/mod-test.c
b/test/data/emacs-module/mod-test.c
index 1e64bcd..ed289d7 100644
--- a/test/data/emacs-module/mod-test.c
+++ b/test/data/emacs-module/mod-test.c
@@ -201,7 +201,19 @@ Fmod_test_globref_free (emacs_env *env, ptrdiff_t nargs,
emacs_value args[],
return env->intern (env, "ok");
}
+/* Treat a local reference as global and free it. Module assertions
+ should detect this case even if a global reference representing the
+ same object also exists. */
+static emacs_value
+Fmod_test_globref_invalid_free (emacs_env *env, ptrdiff_t nargs,
+ emacs_value *args, void *data)
+{
+ emacs_value local = env->make_integer (env, 9876);
+ env->make_global_ref (env, local);
+ env->free_global_ref (env, local); /* Not allowed. */
+ return env->intern (env, "nil");
+}
/* Return a copy of the argument string where every 'a' is replaced
with 'b'. */
@@ -306,6 +318,22 @@ Fmod_test_invalid_load (emacs_env *env, ptrdiff_t nargs,
emacs_value *args,
return invalid_stored_value;
}
+/* The next function works in conjunction with the two previous ones.
+ It stows away a copy of the object created by
+ `Fmod_test_invalid_store' in a global reference. Module assertions
+ should still detect the invalid load of the local reference. */
+
+static emacs_value global_copy_of_invalid_stored_value;
+
+static emacs_value
+Fmod_test_invalid_store_copy (emacs_env *env, ptrdiff_t nargs,
+ emacs_value *args, void *data)
+{
+ emacs_value local = Fmod_test_invalid_store (env, 0, NULL, NULL);
+ return global_copy_of_invalid_stored_value
+ = env->make_global_ref (env, local);
+}
+
/* An invalid finalizer: Finalizers are run during garbage collection,
where Lisp code can't be executed. -module-assertions tests for
this case. */
@@ -678,12 +706,16 @@ emacs_module_init (struct emacs_runtime *ert)
1, 1, NULL, NULL);
DEFUN ("mod-test-globref-make", Fmod_test_globref_make, 0, 0, NULL, NULL);
DEFUN ("mod-test-globref-free", Fmod_test_globref_free, 4, 4, NULL, NULL);
+ DEFUN ("mod-test-globref-invalid-free", Fmod_test_globref_invalid_free, 0, 0,
+ NULL, NULL);
DEFUN ("mod-test-string-a-to-b", Fmod_test_string_a_to_b, 1, 1, NULL, NULL);
DEFUN ("mod-test-userptr-make", Fmod_test_userptr_make, 1, 1, NULL, NULL);
DEFUN ("mod-test-userptr-get", Fmod_test_userptr_get, 1, 1, NULL, NULL);
DEFUN ("mod-test-vector-fill", Fmod_test_vector_fill, 2, 2, NULL, NULL);
DEFUN ("mod-test-vector-eq", Fmod_test_vector_eq, 2, 2, NULL, NULL);
DEFUN ("mod-test-invalid-store", Fmod_test_invalid_store, 0, 0, NULL, NULL);
+ DEFUN ("mod-test-invalid-store-copy", Fmod_test_invalid_store_copy, 0, 0,
+ NULL, NULL);
DEFUN ("mod-test-invalid-load", Fmod_test_invalid_load, 0, 0, NULL, NULL);
DEFUN ("mod-test-invalid-finalizer", Fmod_test_invalid_finalizer, 0, 0,
NULL, NULL);
diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el
index 411b450..8465fd0 100644
--- a/test/src/emacs-module-tests.el
+++ b/test/src/emacs-module-tests.el
@@ -272,6 +272,24 @@ must evaluate to a regular expression string."
(mod-test-invalid-store)
(mod-test-invalid-load)))
+(ert-deftest module--test-assertions--load-non-live-object-with-global-copy ()
+ "Check that -module-assertions verify that non-live objects aren't accessed.
+This differs from `module--test-assertions-load-non-live-object'
+in that it stows away a global reference. The module assertions
+should nevertheless detect the invalid load."
+ (skip-unless (or (file-executable-p mod-test-emacs)
+ (and (eq system-type 'windows-nt)
+ (file-executable-p (concat mod-test-emacs ".exe")))))
+ ;; This doesn't yet cause undefined behavior.
+ (should (eq (mod-test-invalid-store-copy) 123))
+ (module--test-assertion (rx "Emacs value not found in "
+ (+ digit) " values of "
+ (+ digit) " environments\n")
+ ;; Storing and reloading a local value causes undefined behavior,
+ ;; which should be detected by the module assertions.
+ (mod-test-invalid-store-copy)
+ (mod-test-invalid-load)))
+
(ert-deftest module--test-assertions--call-emacs-from-gc ()
"Check that -module-assertions prevents calling Emacs functions
during garbage collection."
@@ -283,6 +301,17 @@ during garbage collection."
(mod-test-invalid-finalizer)
(garbage-collect)))
+(ert-deftest module--test-assertions--globref-invalid-free ()
+ "Check that -module-assertions detects invalid freeing of a
+local reference."
+ (skip-unless (or (file-executable-p mod-test-emacs)
+ (and (eq system-type 'windows-nt)
+ (file-executable-p (concat mod-test-emacs ".exe")))))
+ (module--test-assertion
+ (rx "Global value was not found in list of " (+ digit) " globals")
+ (mod-test-globref-invalid-free)
+ (garbage-collect)))
+
(ert-deftest module/describe-function-1 ()
"Check that Bug#30163 is fixed."
(with-temp-buffer