[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 1a86b5d 05/15: Merge from origin/emacs-25
From: |
Paul Eggert |
Subject: |
[Emacs-diffs] master 1a86b5d 05/15: Merge from origin/emacs-25 |
Date: |
Fri, 5 Aug 2016 21:15:39 +0000 (UTC) |
branch: master
commit 1a86b5d6074d26d1a3a978cb52b2147b6f359694
Merge: c5823cd d4c6774
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>
Merge from origin/emacs-25
d4c6774 Fix missing point information in undo
3a9d629 Avoid crashes when buffer modification hooks clobber match data
178b2f5 Note combine-and-quote-strings doesn't shell quote
dec7567 Explain when package-initialize isn't called
113d1e2 Fix escaping in sh-indent-after-continuation docstr
80e2044 ; * etc/NEWS: Improve previous change.
5bb9e6c ; * etc/NEWS: Document how to avoid horizontal scroll bars.
38f4b8e Clarify the documentation of back-references in replacements
---
doc/emacs/search.texi | 12 +++++-----
doc/lispref/os.texi | 10 +++++---
doc/lispref/processes.texi | 5 ++++
etc/NEWS | 9 +++++++
lisp/progmodes/sh-script.el | 12 +++++-----
lisp/replace.el | 17 +++++++------
lisp/subr.el | 5 +++-
src/search.c | 13 ++++++++++
src/undo.c | 56 +++++++++++++++++++++++--------------------
test/lisp/simple-tests.el | 19 ++++++++++++++-
10 files changed, 108 insertions(+), 50 deletions(-)
diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index d841934..b41214d 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -1356,12 +1356,12 @@ Replace every match for @var{regexp} with
@var{newstring}.
it can refer to all or part of what is matched by the @var{regexp}.
@samp{\&} in @var{newstring} stands for the entire match being
replaced. @address@hidden in @var{newstring}, where @var{d} is a
-digit, stands for whatever matched the @var{d}th parenthesized
-grouping in @var{regexp}. (This is called a ``back reference''.)
address@hidden refers to the count of replacements already made in this
-command, as a decimal number. In the first replacement, @samp{\#}
-stands for @samp{0}; in the second, for @samp{1}; and so on. For
-example,
+digit starting from 1, stands for whatever matched the @var{d}th
+parenthesized grouping in @var{regexp}. (This is called a ``back
+reference''.) @samp{\#} refers to the count of replacements already
+made in this command, as a decimal number. In the first replacement,
address@hidden stands for @samp{0}; in the second, for @samp{1}; and so on.
+For example,
@example
M-x replace-regexp @key{RET} c[ad]+r @key{RET} \&-safe @key{RET}
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index 38dde26..08c69d3 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -155,9 +155,13 @@ It loads your abbrevs from the file specified by
option @samp{--batch} was specified.
@item
-If @code{package-enable-at-startup} is address@hidden, it calls the
-function @code{package-initialize} to activate any optional Emacs Lisp
-package that has been installed. @xref{Packaging Basics}.
+It calls the function @code{package-initialize} to activate any
+optional Emacs Lisp package that has been installed. @xref{Packaging
+Basics}. However, Emacs doesn't initialize packages when
address@hidden is @code{nil} or when it's started
+with one of the options @samp{-q}, @samp{-Q}, or @samp{--batch}. To
+initialize packages in the latter case, @code{package-initialize}
+should be called explicitly (e.g., via the @samp{--funcall} option).
@vindex after-init-time
@item
diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi
index f859b3a..cd12012 100644
--- a/doc/lispref/processes.texi
+++ b/doc/lispref/processes.texi
@@ -215,6 +215,11 @@ converting user input in the minibuffer, a Lisp string,
into a list of
string arguments to be passed to @code{call-process} or
@code{start-process}, or for converting such lists of arguments into
a single Lisp string to be presented in the minibuffer or echo area.
+Note that if a shell is involved (e.g., if using
address@hidden), arguments should still be
+protected by @code{shell-quote-argument};
address@hidden is @emph{not} intended to protect
+special characters from shell evaluation.
@defun split-string-and-unquote string &optional separators
This function splits @var{string} into substrings at matches for the
diff --git a/etc/NEWS b/etc/NEWS
index f845c1d..c9b33c8 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2452,6 +2452,15 @@ scroll bars on the selected frame.
'scroll-bar-height' to set horizontal scroll bars and their height
for individual frames and in 'default-frame-alist'.
+***** The 'horizontal-scroll-bars' parameter was already present and non-nil
+by default in Emacs 24 and before (although it didn't have any
+effect). This could cause a problem if you share your desktop files
+with older versions of Emacs: saving desktop in Emacs before v25.1,
+then restoring it in v25.1 would turn on horizontal scroll bars in all
+buffers. To resolve this issue, put this in your ~/.emacs init file:
+
+ (modify-all-frames-parameters '((horizontal-scroll-bars . nil)))
+
**** New functions 'frame-scroll-bar-height' and
'window-scroll-bar-height' return the height of horizontal scroll
bars on a specific frame or window.
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index 10e56d0..39e9707 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -2003,16 +2003,16 @@ Does not preserve point."
Continued lines can either be indented as \"one long wrapped line\" without
paying attention to the actual syntactic structure, as in:
- for f \
- in a; do \
- toto; \
+ for f \\
+ in a; do \\
+ toto; \\
done
or as lines that just don't have implicit semi-colons between them, as in:
- for f \
- in a; do \
- toto; \
+ for f \\
+ in a; do \\
+ toto; \\
done
With `always' you get the former behavior whereas with nil you get the latter.
diff --git a/lisp/replace.el b/lisp/replace.el
index 9e2d521..e6124f4 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -391,9 +391,10 @@ replace backward.
Fourth and fifth arg START and END specify the region to operate on.
-In TO-STRING, `\\&' stands for whatever matched the whole of REGEXP,
-and `\\=\\N' (where N is a digit) stands for
-whatever what matched the Nth `\\(...\\)' in REGEXP.
+In TO-STRING, `\\&' or `\\0' stands for whatever matched the whole of
+REGEXP, and `\\=\\N' (where N is a digit) stands for whatever matched
+the Nth `\\(...\\)' (1-based) in REGEXP. The `\\(...\\)' groups are
+counted from 1.
`\\?' lets you edit the replacement text in the minibuffer
at the given position for each replacement.
@@ -451,7 +452,9 @@ If the result of TO-EXPR is not a string, it is converted
to one using
For convenience, when entering TO-EXPR interactively, you can use `\\&' or
`\\0' to stand for whatever matched the whole of REGEXP, and `\\N' (where
-N is a digit) to stand for whatever matched the Nth `\\(...\\)' in REGEXP.
+N is a digit) to stand for whatever matched the Nth `\\(...\\)' (1-based)
+in REGEXP.
+
Use `\\#&' or `\\#N' if you want a number instead of a string.
In interactive use, `\\#' in itself stands for `replace-count'.
@@ -635,9 +638,9 @@ replace backward.
Fourth and fifth arg START and END specify the region to operate on.
-In TO-STRING, `\\&' stands for whatever matched the whole of REGEXP,
-and `\\=\\N' (where N is a digit) stands for
-whatever what matched the Nth `\\(...\\)' in REGEXP.
+In TO-STRING, `\\&' or `\\0' stands for whatever matched the whole of
+REGEXP, and `\\=\\N' (where N is a digit) stands for
+whatever matched the Nth `\\(...\\)' (1-based) in REGEXP.
`\\?' lets you edit the replacement text in the minibuffer
at the given position for each replacement.
diff --git a/lisp/subr.el b/lisp/subr.el
index aa9b751..8ab1178 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -3740,7 +3740,10 @@ Modifies the match data; use `save-match-data' if
necessary."
"Concatenate the STRINGS, adding the SEPARATOR (default \" \").
This tries to quote the strings to avoid ambiguity such that
(split-string-and-unquote (combine-and-quote-strings strs)) == strs
-Only some SEPARATORs will work properly."
+Only some SEPARATORs will work properly.
+
+Note that this is not intended to protect STRINGS from
+interpretation by shells, use `shell-quote-argument' for that."
(let* ((sep (or separator " "))
(re (concat "[\\\"]" "\\|" (regexp-quote sep))))
(mapconcat
diff --git a/src/search.c b/src/search.c
index 7f2b4f9..7c4a024 100644
--- a/src/search.c
+++ b/src/search.c
@@ -2677,6 +2677,14 @@ since only regular expressions have distinguished
subexpressions. */)
xfree (substed);
}
+ /* The functions below modify the buffer, so they could trigger
+ various modification hooks (see signal_before_change and
+ signal_after_change), which might clobber the match data we need
+ to adjust after the replacement. If that happens, we error out. */
+ ptrdiff_t sub_start = search_regs.start[sub];
+ ptrdiff_t sub_end = search_regs.end[sub];
+ unsigned num_regs = search_regs.num_regs;
+
/* Replace the old text with the new in the cleanest possible way. */
replace_range (search_regs.start[sub], search_regs.end[sub],
newtext, 1, 0, 1);
@@ -2690,6 +2698,11 @@ since only regular expressions have distinguished
subexpressions. */)
Fupcase_initials_region (make_number (search_regs.start[sub]),
make_number (newpoint));
+ if (search_regs.start[sub] != sub_start
+ || search_regs.end[sub] != sub_end
+ || search_regs.num_regs != num_regs)
+ error ("Match data clobbered by buffer modification hooks");
+
/* Adjust search data for this change. */
{
ptrdiff_t oldend = search_regs.end[sub];
diff --git a/src/undo.c b/src/undo.c
index be5b270..ed69a62 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -31,25 +31,21 @@ along with GNU Emacs. If not, see
<http://www.gnu.org/licenses/>. */
an undo-boundary. */
static Lisp_Object pending_boundary;
-/* Record point as it was at beginning of this command (if necessary)
- and prepare the undo info for recording a change.
- Prepare the undo info for recording a change. */
+/* Prepare the undo info for recording a change. */
static void
prepare_record (void)
{
/* Allocate a cons cell to be the undo boundary after this command. */
if (NILP (pending_boundary))
pending_boundary = Fcons (Qnil, Qnil);
-
- if (MODIFF <= SAVE_MODIFF)
- record_first_change ();
}
-/* Record point as it was at beginning of this command.
- PT is the position of point that will naturally occur as a result of the
- undo record that will be added just after this command terminates. */
+/* Record point, if necessary, as it was at beginning of this command.
+ BEG is the position of point that will naturally occur as a result
+ of the undo record that will be added just after this command
+ terminates. */
static void
-record_point (ptrdiff_t pt)
+record_point (ptrdiff_t beg)
{
/* Don't record position of pt when undo_inhibit_record_point holds. */
if (undo_inhibit_record_point)
@@ -57,16 +53,28 @@ record_point (ptrdiff_t pt)
bool at_boundary;
+ /* Check whether we are at a boundary now, in case we record the
+ first change. FIXME: This check is currently dependent on being
+ called before record_first_change, but could be made not to by
+ ignoring timestamp undo entries */
at_boundary = ! CONSP (BVAR (current_buffer, undo_list))
|| NILP (XCAR (BVAR (current_buffer, undo_list)));
- prepare_record ();
+ /* If this is the first change since save, then record this.*/
+ if (MODIFF <= SAVE_MODIFF)
+ record_first_change ();
- /* If we are just after an undo boundary, and
- point wasn't at start of deleted range, record where it was. */
- if (at_boundary)
+ /* We may need to record point if we are immediately after a
+ boundary, so that this will be restored correctly after undo. We
+ do not need to do this if point is at the start of a change
+ region since it will be restored there anyway, and we must not do
+ this if the buffer has changed since the last command, since the
+ value of point that we have will be for that buffer, not this.*/
+ if (at_boundary
+ && point_before_last_command_or_undo != beg
+ && buffer_before_last_command_or_undo == current_buffer )
bset_undo_list (current_buffer,
- Fcons (make_number (pt),
+ Fcons (make_number (point_before_last_command_or_undo),
BVAR (current_buffer, undo_list)));
}
@@ -85,6 +93,8 @@ record_insert (ptrdiff_t beg, ptrdiff_t length)
prepare_record ();
+ record_point (beg);
+
/* If this is following another insertion and consecutive with it
in the buffer, combine the two. */
if (CONSP (BVAR (current_buffer, undo_list)))
@@ -120,9 +130,7 @@ record_marker_adjustments (ptrdiff_t from, ptrdiff_t to)
register struct Lisp_Marker *m;
register ptrdiff_t charpos, adjustment;
- /* Allocate a cons cell to be the undo boundary after this command. */
- if (NILP (pending_boundary))
- pending_boundary = Fcons (Qnil, Qnil);
+ prepare_record();
for (m = BUF_MARKERS (current_buffer); m; m = m->next)
{
@@ -163,19 +171,17 @@ record_delete (ptrdiff_t beg, Lisp_Object string, bool
record_markers)
if (EQ (BVAR (current_buffer, undo_list), Qt))
return;
- if (point_before_last_command_or_undo != beg
- && buffer_before_last_command_or_undo == current_buffer)
- record_point (point_before_last_command_or_undo);
+ prepare_record ();
+
+ record_point (beg);
if (PT == beg + SCHARS (string))
{
XSETINT (sbeg, -beg);
- prepare_record ();
}
else
{
XSETFASTINT (sbeg, beg);
- prepare_record ();
}
/* primitive-undo assumes marker adjustments are recorded
@@ -234,9 +240,7 @@ record_property_change (ptrdiff_t beg, ptrdiff_t length,
if (EQ (BVAR (buf, undo_list), Qt))
return;
- /* Allocate a cons cell to be the undo boundary after this command. */
- if (NILP (pending_boundary))
- pending_boundary = Fcons (Qnil, Qnil);
+ prepare_record();
if (MODIFF <= SAVE_MODIFF)
record_first_change ();
diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el
index 97b6c49..d022240 100644
--- a/test/lisp/simple-tests.el
+++ b/test/lisp/simple-tests.el
@@ -325,6 +325,7 @@
(undo-test-point-after-forward-kill))))
(defmacro simple-test-undo-with-switched-buffer (buffer &rest body)
+ (declare (indent 1) (debug t))
(let ((before-buffer (make-symbol "before-buffer")))
`(let ((,before-buffer (current-buffer)))
(unwind-protect
@@ -354,8 +355,24 @@ C-/ ;; undo
(point-min)
(point-max))))))
+(ert-deftest missing-record-point-in-undo ()
+ "Check point is being restored correctly.
-
+See Bug#21722."
+ (should
+ (= 5
+ (with-temp-buffer
+ (generate-new-buffer " *temp*")
+ (emacs-lisp-mode)
+ (setq buffer-undo-list nil)
+ (insert "(progn (end-of-line) (insert \"hello\"))")
+ (beginning-of-line)
+ (forward-char 4)
+ (undo-boundary)
+ (eval-defun nil)
+ (undo-boundary)
+ (undo)
+ (point)))))
(provide 'simple-test)
;;; simple-test.el ends here
- [Emacs-diffs] master c5823cd 04/15: ; Merge from origin/emacs-25, (continued)
- [Emacs-diffs] master c5823cd 04/15: ; Merge from origin/emacs-25, Paul Eggert, 2016/08/05
- [Emacs-diffs] master 95c6606 08/15: ; Merge from origin/emacs-25, Paul Eggert, 2016/08/05
- [Emacs-diffs] master fe32258 14/15: ; Merge from origin/emacs-25, Paul Eggert, 2016/08/05
- [Emacs-diffs] master f902a6b 12/15: ; Merge from origin/emacs-25, Paul Eggert, 2016/08/05
- [Emacs-diffs] master 80fcf41 03/15: Merge from origin/emacs-25, Paul Eggert, 2016/08/05
- [Emacs-diffs] master 20e1d54 06/15: ; Merge from origin/emacs-25, Paul Eggert, 2016/08/05
- [Emacs-diffs] master b76885f 01/15: Merge from origin/emacs-25, Paul Eggert, 2016/08/05
- [Emacs-diffs] master 8c818d8 10/15: ; Merge from origin/emacs-25, Paul Eggert, 2016/08/05
- [Emacs-diffs] master a855bf4 11/15: Merge from origin/emacs-25, Paul Eggert, 2016/08/05
- [Emacs-diffs] master 3498a1a 07/15: Merge from origin/emacs-25, Paul Eggert, 2016/08/05
- [Emacs-diffs] master 1a86b5d 05/15: Merge from origin/emacs-25,
Paul Eggert <=
- [Emacs-diffs] master 6b780a2 09/15: Merge from origin/emacs-25, Paul Eggert, 2016/08/05
- [Emacs-diffs] master c1b5000 15/15: Merge from origin/emacs-25, Paul Eggert, 2016/08/05
- [Emacs-diffs] master 0274862 13/15: Merge from origin/emacs-25, Paul Eggert, 2016/08/05