aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuanma Barranquero2014-03-26 16:57:13 +0100
committerJuanma Barranquero2014-03-26 16:57:13 +0100
commit16adf2e6eb1ddf0b32ebea2d5ce8fa1e4c226614 (patch)
tree29b782fd6e7c44a834dd09442a551520e30bcbd6
parent5af73b0fe8975eeb47fb270819b4143c18d71caa (diff)
parent196716cf35f81bea108c3b75362e92c86ed1c016 (diff)
downloademacs-16adf2e6eb1ddf0b32ebea2d5ce8fa1e4c226614.tar.gz
emacs-16adf2e6eb1ddf0b32ebea2d5ce8fa1e4c226614.zip
Merge from emacs-24; up to 2014-03-23T23:14:52Z!yamaoka@jpl.org
-rw-r--r--ChangeLog6
-rw-r--r--doc/lispref/ChangeLog13
-rw-r--r--doc/lispref/files.texi54
-rw-r--r--doc/lispref/markers.texi10
-rw-r--r--doc/lispref/text.texi9
-rw-r--r--doc/misc/ChangeLog8
-rw-r--r--doc/misc/texinfo.tex28
-rw-r--r--doc/misc/tramp.texi21
-rw-r--r--lib/strftime.c48
-rw-r--r--lisp/ChangeLog77
-rw-r--r--lisp/align.el2
-rw-r--r--lisp/emacs-lisp/package.el74
-rw-r--r--lisp/frame.el2
-rw-r--r--lisp/frameset.el6
-rw-r--r--lisp/net/tramp-sh.el114
-rw-r--r--lisp/net/tramp.el82
-rw-r--r--lisp/progmodes/ruby-mode.el6
-rw-r--r--lisp/simple.el91
-rw-r--r--lisp/url/ChangeLog5
-rw-r--r--lisp/url/url-handlers.el12
-rw-r--r--src/ChangeLog58
-rw-r--r--src/buffer.c49
-rw-r--r--src/editfns.c15
-rw-r--r--src/fileio.c3
-rw-r--r--src/insdel.c45
-rw-r--r--src/lisp.h3
-rw-r--r--src/undo.c112
-rw-r--r--src/w32term.c35
-rw-r--r--src/xdisp.c46
-rw-r--r--test/ChangeLog8
-rw-r--r--test/automated/undo-tests.el98
31 files changed, 787 insertions, 353 deletions
diff --git a/ChangeLog b/ChangeLog
index 14587cfd24e..d019c1e4893 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
12014-03-26 Paul Eggert <eggert@cs.ucla.edu>
2
3 Merge from gnulib, incorporating:
4 2014-03-26 strftime: wrap macros in "do {...} while(0)"
5 * lib/strftime.c: Update from gnulib.
6
12014-03-26 Glenn Morris <rgm@gnu.org> 72014-03-26 Glenn Morris <rgm@gnu.org>
2 8
3 * configure.ac (CLASH_DETECTION): Remove option. Every platform 9 * configure.ac (CLASH_DETECTION): Remove option. Every platform
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index 71af1bc66a0..fdc266472e0 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,3 +1,16 @@
12014-03-26 Eli Zaretskii <eliz@gnu.org>
2
3 * files.texi (Kinds of Files): Improve documentation of
4 file-symlink-p. (Bug#17073) Add cross-references.
5
62014-03-26 Barry O'Reilly <gundaetiapo@gmail.com>
7
8 * markers.texi (Moving Marker Positions): The 2014-03-02 doc
9 change mentioning undo's inability to handle relocated markers no
10 longer applies. See bug#16818.
11 * text.texi (Undo): Expand documentation of (TEXT . POS) and
12 (MARKER . ADJUSTMENT) undo elements.
13
12014-03-26 Glenn Morris <rgm@gnu.org> 142014-03-26 Glenn Morris <rgm@gnu.org>
2 15
3 * files.texi (File Locks): All systems support locking. 16 * files.texi (File Locks): All systems support locking.
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index a00fa5b4795..64ed3a05ee6 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -950,22 +950,26 @@ as directories, symbolic links, and ordinary files.
950@defun file-symlink-p filename 950@defun file-symlink-p filename
951@cindex file symbolic links 951@cindex file symbolic links
952If the file @var{filename} is a symbolic link, the 952If the file @var{filename} is a symbolic link, the
953@code{file-symlink-p} function returns the (non-recursive) link target 953@code{file-symlink-p} function returns its (non-recursive) link target
954as a string. (Determining the file name that the link points to from 954as a string. (The link target string is not necessarily the full
955the target is nontrivial.) First, this function recursively follows 955absolute file name of the target; determining the full file name that
956symbolic links at all levels of parent directories. 956the link points to is nontrivial, see below.) If the leading
957 957directories of @var{filename} include symbolic links, this function
958If the file @var{filename} is not a symbolic link (or there is no such file), 958recursively follows them.
959
960If the file @var{filename} is not a symbolic link, or does not exist,
959@code{file-symlink-p} returns @code{nil}. 961@code{file-symlink-p} returns @code{nil}.
960 962
963Here are a few examples of using this function:
964
961@example 965@example
962@group 966@group
963(file-symlink-p "foo") 967(file-symlink-p "not-a-symlink")
964 @result{} nil 968 @result{} nil
965@end group 969@end group
966@group 970@group
967(file-symlink-p "sym-link") 971(file-symlink-p "sym-link")
968 @result{} "foo" 972 @result{} "not-a-symlink"
969@end group 973@end group
970@group 974@group
971(file-symlink-p "sym-link2") 975(file-symlink-p "sym-link2")
@@ -976,6 +980,40 @@ If the file @var{filename} is not a symbolic link (or there is no such file),
976 @result{} "/pub/bin" 980 @result{} "/pub/bin"
977@end group 981@end group
978@end example 982@end example
983
984Note that in the third example, the function returned @file{sym-link},
985but did not proceed to resolve it, although that file is itself a
986symbolic link. This is what we meant by ``non-recursive'' above---the
987process of following the symbolic links does not recurse if the link
988target is itself a link.
989
990The string that this function returns is what is recorded in the
991symbolic link; it may or may not include any leading directories.
992This function does @emph{not} expand the link target to produce a
993fully-qualified file name, and in particular does not use the leading
994directories, if any, of the @var{filename} argument if the link target
995is not an absolute file name. Here's an example:
996
997@example
998@group
999(file-symlink-p "/foo/bar/baz")
1000 @result{} "some-file"
1001@end group
1002@end example
1003
1004@noindent
1005Here, although @file{/foo/bar/baz} was given as a fully-qualified file
1006name, the result is not, and in fact does not have any leading
1007directories at all. And since @file{some-file} might itself be a
1008symbolic link, you cannot simply prepend leading directories to it,
1009nor even naively use @code{expand-file-name} (@pxref{File Name
1010Expansion}) to produce its absolute file name.
1011
1012For this reason, this function is seldom useful if you need to
1013determine more than just the fact that a file is or isn't a symbolic
1014link. If you actually need the file name of the link target, use
1015@code{file-chase-links} or @code{file-truename}, described in
1016@ref{Truenames}.
979@end defun 1017@end defun
980 1018
981The next two functions recursively follow symbolic links at 1019The next two functions recursively follow symbolic links at
diff --git a/doc/lispref/markers.texi b/doc/lispref/markers.texi
index 19386d638fe..51b87ab1e5b 100644
--- a/doc/lispref/markers.texi
+++ b/doc/lispref/markers.texi
@@ -344,12 +344,10 @@ specify the insertion type, create them with insertion type
344@section Moving Marker Positions 344@section Moving Marker Positions
345 345
346 This section describes how to change the position of an existing 346 This section describes how to change the position of an existing
347marker. When you do this, be sure you know how the marker is used 347marker. When you do this, be sure you know whether the marker is used
348outside of your program. For example, moving a marker to an unrelated 348outside of your program, and, if so, what effects will result from
349new position can cause undo to later adjust the marker incorrectly. 349moving it---otherwise, confusing things may happen in other parts of
350Often when you wish to relocate a marker to an unrelated position, it 350Emacs.
351is preferable to make a new marker and set the prior one to point
352nowhere.
353 351
354@defun set-marker marker position &optional buffer 352@defun set-marker marker position &optional buffer
355This function moves @var{marker} to @var{position} 353This function moves @var{marker} to @var{position}
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index f8a3e873449..7c5603fd645 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -1270,7 +1270,8 @@ This kind of element indicates how to reinsert text that was deleted.
1270The deleted text itself is the string @var{text}. The place to 1270The deleted text itself is the string @var{text}. The place to
1271reinsert it is @code{(abs @var{position})}. If @var{position} is 1271reinsert it is @code{(abs @var{position})}. If @var{position} is
1272positive, point was at the beginning of the deleted text, otherwise it 1272positive, point was at the beginning of the deleted text, otherwise it
1273was at the end. 1273was at the end. Zero or more (@var{marker} . @var{adjustment})
1274elements follow immediately after this element.
1274 1275
1275@item (t . @var{time-flag}) 1276@item (t . @var{time-flag})
1276This kind of element indicates that an unmodified buffer became 1277This kind of element indicates that an unmodified buffer became
@@ -1296,8 +1297,10 @@ Here's how you might undo the change:
1296@item (@var{marker} . @var{adjustment}) 1297@item (@var{marker} . @var{adjustment})
1297This kind of element records the fact that the marker @var{marker} was 1298This kind of element records the fact that the marker @var{marker} was
1298relocated due to deletion of surrounding text, and that it moved 1299relocated due to deletion of surrounding text, and that it moved
1299@var{adjustment} character positions. Undoing this element moves 1300@var{adjustment} character positions. If the marker's location is
1300@var{marker} @minus{} @var{adjustment} characters. 1301consistent with the (@var{text} . @var{position}) element preceding it
1302in the undo list, then undoing this element moves @var{marker}
1303@minus{} @var{adjustment} characters.
1301 1304
1302@item (apply @var{funname} . @var{args}) 1305@item (apply @var{funname} . @var{args})
1303This is an extensible undo item, which is undone by calling 1306This is an extensible undo item, which is undone by calling
diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog
index e20fc9955e7..7c4a9551769 100644
--- a/doc/misc/ChangeLog
+++ b/doc/misc/ChangeLog
@@ -1,3 +1,11 @@
12014-03-26 Paul Eggert <eggert@cs.ucla.edu>
2
3 * texinfo.tex: Update from gnulib.
4
52014-03-26 Michael Albinus <michael.albinus@gmx.de>
6
7 * tramp.texi (Frequently Asked Questions): Add fish shell settings.
8
12014-03-23 Katsumi Yamaoka <yamaoka@jpl.org> 92014-03-23 Katsumi Yamaoka <yamaoka@jpl.org>
2 10
3 * gnus.texi (Ma Gnus): Mention header attachment buttons. 11 * gnus.texi (Ma Gnus): Mention header attachment buttons.
diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex
index 3e521840ca2..0f2673c849e 100644
--- a/doc/misc/texinfo.tex
+++ b/doc/misc/texinfo.tex
@@ -3,7 +3,7 @@
3% Load plain if necessary, i.e., if running under initex. 3% Load plain if necessary, i.e., if running under initex.
4\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi 4\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
5% 5%
6\def\texinfoversion{2014-02-16.16} 6\def\texinfoversion{2014-03-17.07}
7% 7%
8% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, 8% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
9% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 9% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
@@ -3935,19 +3935,23 @@ end
3935} 3935}
3936 3936
3937% multitable-only commands. 3937% multitable-only commands.
3938% 3938%
3939% @headitem starts a heading row, which we typeset in bold. 3939% @headitem starts a heading row, which we typeset in bold. Assignments
3940% Assignments have to be global since we are inside the implicit group 3940% have to be global since we are inside the implicit group of an
3941% of an alignment entry. \everycr resets \everytab so we don't have to 3941% alignment entry. \everycr below resets \everytab so we don't have to
3942% undo it ourselves. 3942% undo it ourselves.
3943\def\headitemfont{\b}% for people to use in the template row; not changeable 3943\def\headitemfont{\b}% for people to use in the template row; not changeable
3944\def\headitem{% 3944\def\headitem{%
3945 \checkenv\multitable 3945 \checkenv\multitable
3946 \crcr 3946 \crcr
3947 \gdef\headitemcrhook{\nobreak}% attempt to avoid page break after headings
3947 \global\everytab={\bf}% can't use \headitemfont since the parsing differs 3948 \global\everytab={\bf}% can't use \headitemfont since the parsing differs
3948 \the\everytab % for the first item 3949 \the\everytab % for the first item
3949}% 3950}%
3950% 3951%
3952% default for tables with no headings.
3953\let\headitemcrhook=\relax
3954%
3951% A \tab used to include \hskip1sp. But then the space in a template 3955% A \tab used to include \hskip1sp. But then the space in a template
3952% line is not enough. That is bad. So let's go back to just `&' until 3956% line is not enough. That is bad. So let's go back to just `&' until
3953% we again encounter the problem the 1sp was intended to solve. 3957% we again encounter the problem the 1sp was intended to solve.
@@ -3978,15 +3982,15 @@ end
3978 % 3982 %
3979 \everycr = {% 3983 \everycr = {%
3980 \noalign{% 3984 \noalign{%
3981 \global\everytab={}% 3985 \global\everytab={}% Reset from possible headitem.
3982 \global\colcount=0 % Reset the column counter. 3986 \global\colcount=0 % Reset the column counter.
3983 % Check for saved footnotes, etc. 3987 %
3988 % Check for saved footnotes, etc.:
3984 \checkinserts 3989 \checkinserts
3985 % Keeps underfull box messages off when table breaks over pages. 3990 %
3986 %\filbreak 3991 % Perhaps a \nobreak, then reset:
3987 % Maybe so, but it also creates really weird page breaks when the 3992 \headitemcrhook
3988 % table breaks over pages. Wouldn't \vfil be better? Wait until the 3993 \global\let\headitemcrhook=\relax
3989 % problem manifests itself, so it can be fixed for real --karl.
3990 }% 3994 }%
3991 }% 3995 }%
3992 % 3996 %
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index 6dd5d2a88d8..c0a6156a4cf 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -3053,15 +3053,28 @@ setting the cursor at the top of the buffer, and applying the expression
3053If it fails, or the cursor is not moved at the end of the buffer, your 3053If it fails, or the cursor is not moved at the end of the buffer, your
3054prompt is not recognized correctly. 3054prompt is not recognized correctly.
3055 3055
3056A special problem is the zsh, which uses left-hand side and right-hand 3056A special problem is the zsh shell, which uses left-hand side and
3057side prompts in parallel. Therefore, it is necessary to disable the 3057right-hand side prompts in parallel. Therefore, it is necessary to
3058zsh line editor on the remote host. You shall add to @file{~/.zshrc} 3058disable the zsh line editor on the remote host. You shall add to
3059the following command: 3059@file{~/.zshrc} the following command:
3060 3060
3061@example 3061@example
3062[ $TERM = "dumb" ] && unsetopt zle && PS1='$ ' 3062[ $TERM = "dumb" ] && unsetopt zle && PS1='$ '
3063@end example 3063@end example
3064 3064
3065Similar fancy prompt settings are known from the fish shell. Here you
3066must add in @file{~/.config/fish/config.fish}:
3067
3068@example
3069function fish_prompt
3070 if test $TERM = "dumb"
3071 echo "\$ "
3072 else
3073 @dots{}
3074 end
3075end
3076@end example
3077
3065Furthermore it has been reported, that @value{tramp} (like sshfs, 3078Furthermore it has been reported, that @value{tramp} (like sshfs,
3066incidentally) doesn't work with WinSSHD due to strange prompt settings. 3079incidentally) doesn't work with WinSSHD due to strange prompt settings.
3067 3080
diff --git a/lib/strftime.c b/lib/strftime.c
index c1ec41422bd..857cca568b8 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -681,24 +681,44 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
681 switch (format_char) 681 switch (format_char)
682 { 682 {
683#define DO_NUMBER(d, v) \ 683#define DO_NUMBER(d, v) \
684 digits = d; \ 684 do \
685 number_value = v; goto do_number 685 { \
686 digits = d; \
687 number_value = v; \
688 goto do_number; \
689 } \
690 while (0)
686#define DO_SIGNED_NUMBER(d, negative, v) \ 691#define DO_SIGNED_NUMBER(d, negative, v) \
687 digits = d; \ 692 do \
688 negative_number = negative; \ 693 { \
689 u_number_value = v; goto do_signed_number 694 digits = d; \
695 negative_number = negative; \
696 u_number_value = v; \
697 goto do_signed_number; \
698 } \
699 while (0)
690 700
691 /* The mask is not what you might think. 701 /* The mask is not what you might think.
692 When the ordinal i'th bit is set, insert a colon 702 When the ordinal i'th bit is set, insert a colon
693 before the i'th digit of the time zone representation. */ 703 before the i'th digit of the time zone representation. */
694#define DO_TZ_OFFSET(d, negative, mask, v) \ 704#define DO_TZ_OFFSET(d, negative, mask, v) \
695 digits = d; \ 705 do \
696 negative_number = negative; \ 706 { \
697 tz_colon_mask = mask; \ 707 digits = d; \
698 u_number_value = v; goto do_tz_offset 708 negative_number = negative; \
709 tz_colon_mask = mask; \
710 u_number_value = v; \
711 goto do_tz_offset; \
712 } \
713 while (0)
699#define DO_NUMBER_SPACEPAD(d, v) \ 714#define DO_NUMBER_SPACEPAD(d, v) \
700 digits = d; \ 715 do \
701 number_value = v; goto do_number_spacepad 716 { \
717 digits = d; \
718 number_value = v; \
719 goto do_number_spacepad; \
720 } \
721 while (0)
702 722
703 case L_('%'): 723 case L_('%'):
704 if (modifier != 0) 724 if (modifier != 0)
@@ -1265,9 +1285,9 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
1265 } 1285 }
1266 if (modifier == L_('O')) 1286 if (modifier == L_('O'))
1267 goto bad_format; 1287 goto bad_format;
1268 else 1288
1269 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE, 1289 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE,
1270 tp->tm_year + (unsigned int) TM_YEAR_BASE); 1290 tp->tm_year + (unsigned int) TM_YEAR_BASE);
1271 1291
1272 case L_('y'): 1292 case L_('y'):
1273 if (modifier == L_('E')) 1293 if (modifier == L_('E'))
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 995c4f3acc4..ecb2a8e33a0 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,78 @@
12014-03-26 Juanma Barranquero <lekktu@gmail.com>
2
3 * emacs-lisp/package.el: Fix bug#16733 (again).
4 (url-http-parse-response, url-http-end-of-headers, url-recreate-url)
5 (url-http-target-url): Remove unused declarations.
6 (package-handle-response): Remove.
7 (package--with-work-buffer): Use url-insert-file-contents and simplify.
8 (package--download-one-archive): Use current-buffer instead of
9 dynamic binding of `buffer'.
10 (describe-package-1): Do not decode readme-string.
11
122014-03-26 Michael Albinus <michael.albinus@gmx.de>
13
14 * net/tramp.el (tramp-methods, tramp-connection-timeout): Fix docstring.
15
16 * net/tramp-sh.el (tramp-sh-handle-vc-registered): Revert change
17 from 2014-03-07, it decreases performance unnecessarily. Let-bind
18 `remote-file-name-inhibit-cache' to nil in the second pass.
19 (tramp-find-executable): Do not call "which" on SunOS.
20 (tramp-send-command-and-check): Fix docstring.
21 (tramp-do-copy-or-rename-file-directly): In the `rename' case,
22 check whether source directory has set the sticky bit.
23
242014-03-26 Barry O'Reilly <gundaetiapo@gmail.com>
25
26 * simple.el (primitive-undo): Only process marker adjustments
27 validated against their corresponding (TEXT . POS). Issue warning
28 for lone marker adjustments in undo history. (Bug#16818)
29 (undo-make-selective-list): Add marker adjustments to selective
30 undo list based on whether their corresponding (TEXT . POS) is in
31 the region. Remove variable adjusted-markers, which was unused
32 and only non nil during undo-make-selective-list.
33 (undo-elt-in-region): Return nil when passed a marker adjustment
34 and explain in function doc.
35
362014-03-26 Nicolas Richard <theonewiththeevillook@yahoo.fr>
37
38 * align.el (align-region): Do not fail when end-mark is nil (bug#17088).
39
402014-03-26 Dmitry Gutov <dgutov@yandex.ru>
41
42 * progmodes/ruby-mode.el (ruby-expression-expansion-re):
43 Match special global variables without curlies, too.
44 (ruby-font-lock-keywords): Simplify the matcher for special global
45 variables. Don't require a non-word character after the variable.
46 (Bug#17057)
47
482014-03-26 Stefan Monnier <monnier@iro.umontreal.ca>
49
50 * simple.el (redisplay-highlight-region-function): Increase priority of
51 overlay to make sure boundaries are visible (bug#15899).
52
532014-03-26 Juanma Barranquero <lekktu@gmail.com>
54
55 * frameset.el (frameset--initial-params): Fix typo in parameter name.
56 (frameset-restore): Compare display strings with equal.
57
58 * frame.el (make-frame): Don't quote display name in error message,
59 it is already a string.
60
612014-03-26 Thierry Volpiatto <thierry.volpiatto@gmail.com>
62
63 * net/tramp.el (tramp-read-passwd): Suspend the timers while reading
64 the password.
65
662014-03-26 Dmitry Gutov <dgutov@yandex.ru>
67
68 * emacs-lisp/package.el (package--add-to-archive-contents):
69 Include already installed and built-in packages in
70 `package-archive-contents'.
71 (package-install): Don't include already installed packages in the
72 options during interactive invocation. (Bug#16762)
73 (package-show-package-list): If the buffer is already displayed in
74 another window, switch to that window.
75
12014-03-26 Reto Zimmermann <reto@gnu.org> 762014-03-26 Reto Zimmermann <reto@gnu.org>
2 77
3 Sync with upstream vhdl mode v3.35.1. 78 Sync with upstream vhdl mode v3.35.1.
@@ -1247,7 +1322,7 @@
1247 dbus-call-method check for completion using a busy-wait loop with 1322 dbus-call-method check for completion using a busy-wait loop with
1248 gradual backoff. 1323 gradual backoff.
1249 1324
12502013-10-02 Michael Albinus <michael.albinus@gmx.de> 13252014-02-16 Michael Albinus <michael.albinus@gmx.de>
1251 1326
1252 Sync with Tramp 2.2.9. 1327 Sync with Tramp 2.2.9.
1253 1328
diff --git a/lisp/align.el b/lisp/align.el
index 9038adf624c..3b54aba264f 100644
--- a/lisp/align.el
+++ b/lisp/align.el
@@ -1603,7 +1603,7 @@ aligner would have dealt with are."
1603 rule-index (1+ rule-index))) 1603 rule-index (1+ rule-index)))
1604 ;; This function can use a lot of temporary markers, so instead of 1604 ;; This function can use a lot of temporary markers, so instead of
1605 ;; waiting for the next GC we delete them immediately (Bug#10047). 1605 ;; waiting for the next GC we delete them immediately (Bug#10047).
1606 (set-marker end-mark nil) 1606 (when end-mark (set-marker end-mark nil))
1607 (dolist (m markers) 1607 (dolist (m markers)
1608 (set-marker m nil)) 1608 (set-marker m nil))
1609 1609
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 480fddbd320..17136437cf9 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -205,13 +205,9 @@ If VERSION is nil, the package is not loaded (it is \"disabled\")."
205 205
206(defvar Info-directory-list) 206(defvar Info-directory-list)
207(declare-function info-initialize "info" ()) 207(declare-function info-initialize "info" ())
208(declare-function url-http-parse-response "url-http" ())
209(declare-function url-http-file-exists-p "url-http" (url)) 208(declare-function url-http-file-exists-p "url-http" (url))
210(declare-function lm-header "lisp-mnt" (header)) 209(declare-function lm-header "lisp-mnt" (header))
211(declare-function lm-commentary "lisp-mnt" (&optional file)) 210(declare-function lm-commentary "lisp-mnt" (&optional file))
212(defvar url-http-end-of-headers)
213(declare-function url-recreate-url "url-parse" (urlobj))
214(defvar url-http-target-url)
215 211
216(defcustom package-archives '(("gnu" . "http://elpa.gnu.org/packages/")) 212(defcustom package-archives '(("gnu" . "http://elpa.gnu.org/packages/"))
217 "An alist of archives from which to fetch. 213 "An alist of archives from which to fetch.
@@ -770,38 +766,14 @@ This macro retrieves FILE from LOCATION into a temporary buffer,
770and evaluates BODY while that buffer is current. This work 766and evaluates BODY while that buffer is current. This work
771buffer is killed afterwards. Return the last value in BODY." 767buffer is killed afterwards. Return the last value in BODY."
772 (declare (indent 2) (debug t)) 768 (declare (indent 2) (debug t))
773 `(let* ((http (string-match "\\`https?:" ,location)) 769 `(with-temp-buffer
774 (buffer 770 (if (string-match-p "\\`https?:" ,location)
775 (if http 771 (url-insert-file-contents (concat ,location ,file))
776 (url-retrieve-synchronously (concat ,location ,file)) 772 (unless (file-name-absolute-p ,location)
777 (generate-new-buffer "*package work buffer*")))) 773 (error "Archive location %s is not an absolute file name"
778 (prog1 774 ,location))
779 (with-current-buffer buffer 775 (insert-file-contents (expand-file-name ,file ,location)))
780 (if http 776 ,@body))
781 (progn (package-handle-response)
782 (re-search-forward "^$" nil 'move)
783 (forward-char)
784 (delete-region (point-min) (point)))
785 (unless (file-name-absolute-p ,location)
786 (error "Archive location %s is not an absolute file name"
787 ,location))
788 (insert-file-contents (expand-file-name ,file ,location)))
789 ,@body)
790 (kill-buffer buffer))))
791
792(defun package-handle-response ()
793 "Handle the response from a `url-retrieve-synchronously' call.
794Parse the HTTP response and throw if an error occurred.
795The url package seems to require extra processing for this.
796This should be called in a `save-excursion', in the download buffer.
797It will move point to somewhere in the headers."
798 ;; We assume HTTP here.
799 (require 'url-http)
800 (let ((response (url-http-parse-response)))
801 (when (or (< response 200) (>= response 300))
802 (error "Error downloading %s:%s"
803 (url-recreate-url url-http-target-url)
804 (buffer-substring-no-properties (point) (line-end-position))))))
805 777
806(defun package--archive-file-exists-p (location file) 778(defun package--archive-file-exists-p (location file)
807 (let ((http (string-match "\\`https?:" location))) 779 (let ((http (string-match "\\`https?:" location)))
@@ -1047,14 +1019,9 @@ Also, add the originating archive to the `package-desc' structure."
1047 (existing-packages (assq name package-archive-contents)) 1019 (existing-packages (assq name package-archive-contents))
1048 (pinned-to-archive (assoc name package-pinned-packages))) 1020 (pinned-to-archive (assoc name package-pinned-packages)))
1049 (cond 1021 (cond
1050 ;; Skip entirely if pinned to another archive or already installed. 1022 ;; Skip entirely if pinned to another archive.
1051 ((or (and pinned-to-archive 1023 ((and pinned-to-archive
1052 (not (equal (cdr pinned-to-archive) archive))) 1024 (not (equal (cdr pinned-to-archive) archive)))
1053 (let ((bi (assq name package--builtin-versions)))
1054 (and bi (version-list-= version (cdr bi))))
1055 (let ((ins (cdr (assq name package-alist))))
1056 (and ins (version-list-= version
1057 (package-desc-version (car ins))))))
1058 nil) 1025 nil)
1059 ((not existing-packages) 1026 ((not existing-packages)
1060 (push (list name pkg-desc) package-archive-contents)) 1027 (push (list name pkg-desc) package-archive-contents))
@@ -1090,8 +1057,11 @@ in an archive in `package-archives'. Interactively, prompt for its name."
1090 (package-refresh-contents)) 1057 (package-refresh-contents))
1091 (list (intern (completing-read 1058 (list (intern (completing-read
1092 "Install package: " 1059 "Install package: "
1093 (mapcar (lambda (elt) (symbol-name (car elt))) 1060 (delq nil
1094 package-archive-contents) 1061 (mapcar (lambda (elt)
1062 (unless (package-installed-p (car elt))
1063 (symbol-name (car elt))))
1064 package-archive-contents))
1095 nil t))))) 1065 nil t)))))
1096 (package-download-transaction 1066 (package-download-transaction
1097 (if (package-desc-p pkg) 1067 (if (package-desc-p pkg)
@@ -1272,7 +1242,7 @@ similar to an entry in `package-alist'. Save the cached copy to
1272 (car archive))))) 1242 (car archive)))))
1273 ;; Read the retrieved buffer to make sure it is valid (e.g. it 1243 ;; Read the retrieved buffer to make sure it is valid (e.g. it
1274 ;; may fetch a URL redirect page). 1244 ;; may fetch a URL redirect page).
1275 (when (listp (read buffer)) 1245 (when (listp (read (current-buffer)))
1276 (make-directory dir t) 1246 (make-directory dir t)
1277 (setq buffer-file-name (expand-file-name file dir)) 1247 (setq buffer-file-name (expand-file-name file dir))
1278 (let ((version-control 'never) 1248 (let ((version-control 'never)
@@ -1531,8 +1501,7 @@ If optional arg NO-ACTIVATE is non-nil, don't activate packages."
1531 (setq readme-string (buffer-string)) 1501 (setq readme-string (buffer-string))
1532 t)) 1502 t))
1533 (error nil)) 1503 (error nil))
1534 (let ((coding (detect-coding-string readme-string t))) 1504 (insert readme-string))
1535 (insert (decode-coding-string readme-string coding t))))
1536 ((file-readable-p readme) 1505 ((file-readable-p readme)
1537 (insert-file-contents readme) 1506 (insert-file-contents readme)
1538 (goto-char (point-max)))))))) 1507 (goto-char (point-max))))))))
@@ -2117,11 +2086,14 @@ When KEYWORDS are given, only packages with those KEYWORDS are
2117shown." 2086shown."
2118 (interactive) 2087 (interactive)
2119 (require 'finder-inf nil t) 2088 (require 'finder-inf nil t)
2120 (let ((buf (get-buffer-create "*Packages*"))) 2089 (let* ((buf (get-buffer-create "*Packages*"))
2090 (win (get-buffer-window buf)))
2121 (with-current-buffer buf 2091 (with-current-buffer buf
2122 (package-menu-mode) 2092 (package-menu-mode)
2123 (package-menu--generate nil packages keywords)) 2093 (package-menu--generate nil packages keywords))
2124 (switch-to-buffer buf))) 2094 (if win
2095 (select-window win)
2096 (switch-to-buffer buf))))
2125 2097
2126;; package-menu--generate rebinds "q" on the fly, so we have to 2098;; package-menu--generate rebinds "q" on the fly, so we have to
2127;; hard-code the binding in the doc-string here. 2099;; hard-code the binding in the doc-string here.
diff --git a/lisp/frame.el b/lisp/frame.el
index b62c939d536..7b0a0a80082 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -668,7 +668,7 @@ the new frame according to its own rules."
668 (cdr (assq 'window-system parameters))) 668 (cdr (assq 'window-system parameters)))
669 (display 669 (display
670 (or (window-system-for-display display) 670 (or (window-system-for-display display)
671 (error "Don't know how to interpret display \"%S\"" 671 (error "Don't know how to interpret display %S"
672 display))) 672 display)))
673 (t window-system))) 673 (t window-system)))
674 (frame-creation-function (cdr (assq w frame-creation-function-alist))) 674 (frame-creation-function (cdr (assq w frame-creation-function-alist)))
diff --git a/lisp/frameset.el b/lisp/frameset.el
index 3a43f39600c..2f1453f2a19 100644
--- a/lisp/frameset.el
+++ b/lisp/frameset.el
@@ -940,7 +940,7 @@ is the parameter alist of the frame being restored. Internal use only."
940Setting position and size parameters as soon as possible helps reducing 940Setting position and size parameters as soon as possible helps reducing
941flickering; other parameters, like `minibuffer' and `border-width', can 941flickering; other parameters, like `minibuffer' and `border-width', can
942not be changed once the frame has been created. Internal use only." 942not be changed once the frame has been created. Internal use only."
943 (cl-loop for param in '(left top with height border-width minibuffer) 943 (cl-loop for param in '(left top width height border-width minibuffer)
944 when (assq param parameters) collect it)) 944 when (assq param parameters) collect it))
945 945
946(defun frameset--restore-frame (parameters window-state filters force-onscreen) 946(defun frameset--restore-frame (parameters window-state filters force-onscreen)
@@ -1146,8 +1146,8 @@ All keyword parameters default to nil."
1146 frame to-tty duplicate) 1146 frame to-tty duplicate)
1147 ;; Only set target if forcing displays and the target display is different. 1147 ;; Only set target if forcing displays and the target display is different.
1148 (unless (or (frameset-keep-original-display-p force-display) 1148 (unless (or (frameset-keep-original-display-p force-display)
1149 (eq (frame-parameter nil 'display) 1149 (equal (frame-parameter nil 'display)
1150 (cdr (assq 'display frame-cfg)))) 1150 (cdr (assq 'display frame-cfg))))
1151 (setq frameset--target-display (cons 'display 1151 (setq frameset--target-display (cons 'display
1152 (frame-parameter nil 'display)) 1152 (frame-parameter nil 'display))
1153 to-tty (null (cdr frameset--target-display)))) 1153 to-tty (null (cdr frameset--target-display))))
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 106c14805d5..22ea7714743 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -2110,6 +2110,12 @@ the uid and gid from FILENAME."
2110 ;; We can do it directly. 2110 ;; We can do it directly.
2111 ((let (file-name-handler-alist) 2111 ((let (file-name-handler-alist)
2112 (and (file-readable-p localname1) 2112 (and (file-readable-p localname1)
2113 ;; No sticky bit when renaming.
2114 (or (eq op 'copy)
2115 (zerop
2116 (logand
2117 (file-modes (file-name-directory localname1))
2118 (tramp-compat-octal-to-decimal "1000"))))
2113 (file-writable-p (file-name-directory localname2)) 2119 (file-writable-p (file-name-directory localname2))
2114 (or (file-directory-p localname2) 2120 (or (file-directory-p localname2)
2115 (file-writable-p localname2)))) 2121 (file-writable-p localname2))))
@@ -3311,55 +3317,57 @@ the result will be a local, non-Tramp, filename."
3311 (with-tramp-progress-reporter 3317 (with-tramp-progress-reporter
3312 v 3 (format "Checking `vc-registered' for %s" file) 3318 v 3 (format "Checking `vc-registered' for %s" file)
3313 3319
3314 (unless remote-file-name-inhibit-cache 3320 ;; There could be new files, created by the vc backend. We
3315 ;; There could be new files, created by the vc backend. We 3321 ;; cannot reuse the old cache entries, therefore. In
3316 ;; cannot reuse the old cache entries, therefore. 3322 ;; `tramp-get-file-property', `remote-file-name-inhibit-cache'
3317 (let (tramp-vc-registered-file-names 3323 ;; could also be a timestamp as `current-time' returns. This
3318 (remote-file-name-inhibit-cache (current-time)) 3324 ;; means invalidate all cache entries with an older timestamp.
3319 (file-name-handler-alist 3325 (let (tramp-vc-registered-file-names
3320 `((,tramp-file-name-regexp . tramp-vc-file-name-handler)))) 3326 (remote-file-name-inhibit-cache (current-time))
3321 3327 (file-name-handler-alist
3322 ;; Here we collect only file names, which need an operation. 3328 `((,tramp-file-name-regexp . tramp-vc-file-name-handler))))
3323 (ignore-errors (tramp-run-real-handler 'vc-registered (list file))) 3329
3324 (tramp-message v 10 "\n%s" tramp-vc-registered-file-names) 3330 ;; Here we collect only file names, which need an operation.
3325 3331 (ignore-errors (tramp-run-real-handler 'vc-registered (list file)))
3326 ;; Send just one command, in order to fill the cache. 3332 (tramp-message v 10 "\n%s" tramp-vc-registered-file-names)
3327 (when tramp-vc-registered-file-names 3333
3328 (tramp-maybe-send-script 3334 ;; Send just one command, in order to fill the cache.
3329 v 3335 (when tramp-vc-registered-file-names
3330 (format tramp-vc-registered-read-file-names 3336 (tramp-maybe-send-script
3331 (tramp-get-file-exists-command v) 3337 v
3332 (format "%s -r" (tramp-get-test-command v))) 3338 (format tramp-vc-registered-read-file-names
3333 "tramp_vc_registered_read_file_names") 3339 (tramp-get-file-exists-command v)
3334 3340 (format "%s -r" (tramp-get-test-command v)))
3335 (dolist 3341 "tramp_vc_registered_read_file_names")
3336 (elt 3342
3337 (ignore-errors 3343 (dolist
3338 ;; We cannot use `tramp-send-command-and-read', 3344 (elt
3339 ;; because this does not cooperate well with 3345 (ignore-errors
3340 ;; heredoc documents. 3346 ;; We cannot use `tramp-send-command-and-read',
3341 (tramp-send-command 3347 ;; because this does not cooperate well with
3342 v 3348 ;; heredoc documents.
3343 (format 3349 (tramp-send-command
3344 "tramp_vc_registered_read_file_names <<'%s'\n%s\n%s\n" 3350 v
3345 tramp-end-of-heredoc 3351 (format
3346 (mapconcat 'tramp-shell-quote-argument 3352 "tramp_vc_registered_read_file_names <<'%s'\n%s\n%s\n"
3347 tramp-vc-registered-file-names 3353 tramp-end-of-heredoc
3348 "\n") 3354 (mapconcat 'tramp-shell-quote-argument
3349 tramp-end-of-heredoc)) 3355 tramp-vc-registered-file-names
3350 (with-current-buffer (tramp-get-connection-buffer v) 3356 "\n")
3351 ;; Read the expression. 3357 tramp-end-of-heredoc))
3352 (goto-char (point-min)) 3358 (with-current-buffer (tramp-get-connection-buffer v)
3353 (read (current-buffer))))) 3359 ;; Read the expression.
3354 3360 (goto-char (point-min))
3355 (tramp-set-file-property 3361 (read (current-buffer)))))
3356 v (car elt) (cadr elt) (cadr (cdr elt))))))) 3362
3363 (tramp-set-file-property
3364 v (car elt) (cadr elt) (cadr (cdr elt))))))
3357 3365
3358 ;; Second run. Now all `file-exists-p' or `file-readable-p' 3366 ;; Second run. Now all `file-exists-p' or `file-readable-p'
3359 ;; calls shall be answered from the file cache. We unset 3367 ;; calls shall be answered from the file cache. We unset
3360 ;; `process-file-side-effects' in order to keep the cache when 3368 ;; `process-file-side-effects' and `remote-file-name-inhibit-cache'
3361 ;; `process-file' calls appear. 3369 ;; in order to keep the cache.
3362 (let (process-file-side-effects) 3370 (let (remote-file-name-inhibit-cache process-file-side-effects)
3363 (ignore-errors 3371 (ignore-errors
3364 (tramp-run-real-handler 'vc-registered (list file)))))))) 3372 (tramp-run-real-handler 'vc-registered (list file))))))))
3365 3373
@@ -3604,8 +3612,13 @@ This function expects to be in the right *tramp* buffer."
3604 (let (result) 3612 (let (result)
3605 ;; Check whether the executable is in $PATH. "which(1)" does not 3613 ;; Check whether the executable is in $PATH. "which(1)" does not
3606 ;; report always a correct error code; therefore we check the 3614 ;; report always a correct error code; therefore we check the
3607 ;; number of words it returns. 3615 ;; number of words it returns. "SunOS 5.10" (and maybe "SunOS
3608 (unless ignore-path 3616 ;; 5.11") have problems with this command, we disable the call
3617 ;; therefore.
3618 (unless (or ignore-path
3619 (string-match
3620 (regexp-opt '("SunOS 5.10" "SunOS 5.11"))
3621 (tramp-get-connection-property vec "uname" "")))
3609 (tramp-send-command vec (format "which \\%s | wc -w" progname)) 3622 (tramp-send-command vec (format "which \\%s | wc -w" progname))
3610 (goto-char (point-min)) 3623 (goto-char (point-min))
3611 (if (looking-at "^\\s-*1$") 3624 (if (looking-at "^\\s-*1$")
@@ -4677,8 +4690,9 @@ function waits for output unless NOOUTPUT is set."
4677(defun tramp-send-command-and-check 4690(defun tramp-send-command-and-check
4678 (vec command &optional subshell dont-suppress-err) 4691 (vec command &optional subshell dont-suppress-err)
4679 "Run COMMAND and check its exit status. 4692 "Run COMMAND and check its exit status.
4680Sends `echo $?' along with the COMMAND for checking the exit status. If 4693Sends `echo $?' along with the COMMAND for checking the exit status.
4681COMMAND is nil, just sends `echo $?'. Returns the exit status found. 4694If COMMAND is nil, just sends `echo $?'. Returns `t' if the exit
4695status is 0, and `nil' otherwise.
4682 4696
4683If the optional argument SUBSHELL is non-nil, the command is 4697If the optional argument SUBSHELL is non-nil, the command is
4684executed in a subshell, ie surrounded by parentheses. If 4698executed in a subshell, ie surrounded by parentheses. If
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index b9b64ed70f8..20948181414 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -241,7 +241,7 @@ pair of the form (KEY VALUE). The following KEYs are defined:
241 * `tramp-copy-program' 241 * `tramp-copy-program'
242 This specifies the name of the program to use for remotely copying 242 This specifies the name of the program to use for remotely copying
243 the file; this might be the absolute filename of rcp or the name of 243 the file; this might be the absolute filename of rcp or the name of
244 a workalike program. 244 a workalike program. It is always applied on the local host.
245 * `tramp-copy-args' 245 * `tramp-copy-args'
246 This specifies the list of parameters to pass to the above mentioned 246 This specifies the list of parameters to pass to the above mentioned
247 program, the hints for `tramp-login-args' also apply here. 247 program, the hints for `tramp-login-args' also apply here.
@@ -1044,7 +1044,9 @@ opening a connection to a remote host."
1044 1044
1045(defcustom tramp-connection-timeout 60 1045(defcustom tramp-connection-timeout 60
1046 "Defines the max time to wait for establishing a connection (in seconds). 1046 "Defines the max time to wait for establishing a connection (in seconds).
1047This can be overwritten for different connection types in `tramp-methods'." 1047This can be overwritten for different connection types in `tramp-methods'.
1048
1049The timeout does not include the time reading a password."
1048 :group 'tramp 1050 :group 'tramp
1049 :version "24.4" 1051 :version "24.4"
1050 :type 'integer) 1052 :type 'integer)
@@ -4119,40 +4121,48 @@ Invokes `password-read' if available, `read-passwd' else."
4119 (with-current-buffer (process-buffer proc) 4121 (with-current-buffer (process-buffer proc)
4120 (tramp-check-for-regexp proc tramp-password-prompt-regexp) 4122 (tramp-check-for-regexp proc tramp-password-prompt-regexp)
4121 (format "%s for %s " (capitalize (match-string 1)) key)))) 4123 (format "%s for %s " (capitalize (match-string 1)) key))))
4122 auth-info auth-passwd) 4124 ;; We suspend the timers while reading the password.
4123 (with-parsed-tramp-file-name key nil 4125 (stimers (with-timeout-suspend))
4124 (prog1 4126 auth-info auth-passwd)
4125 (or 4127
4126 ;; See if auth-sources contains something useful, if it's 4128 (unwind-protect
4127 ;; bound. `auth-source-user-or-password' is an obsoleted 4129 (with-parsed-tramp-file-name key nil
4128 ;; function, it has been replaced by `auth-source-search'. 4130 (prog1
4129 (and (boundp 'auth-sources) 4131 (or
4130 (tramp-get-connection-property v "first-password-request" nil) 4132 ;; See if auth-sources contains something useful, if
4131 ;; Try with Tramp's current method. 4133 ;; it's bound. `auth-source-user-or-password' is an
4132 (if (fboundp 'auth-source-search) 4134 ;; obsoleted function, it has been replaced by
4133 (setq auth-info 4135 ;; `auth-source-search'.
4134 (tramp-compat-funcall 4136 (and (boundp 'auth-sources)
4135 'auth-source-search 4137 (tramp-get-connection-property
4136 :max 1 4138 v "first-password-request" nil)
4137 :user (or tramp-current-user t) 4139 ;; Try with Tramp's current method.
4138 :host tramp-current-host 4140 (if (fboundp 'auth-source-search)
4139 :port tramp-current-method) 4141 (setq auth-info
4140 auth-passwd (plist-get (nth 0 auth-info) :secret) 4142 (tramp-compat-funcall
4141 auth-passwd (if (functionp auth-passwd) 4143 'auth-source-search
4142 (funcall auth-passwd) 4144 :max 1
4143 auth-passwd)) 4145 :user (or tramp-current-user t)
4144 (tramp-compat-funcall 4146 :host tramp-current-host
4145 'auth-source-user-or-password 4147 :port tramp-current-method)
4146 "password" tramp-current-host tramp-current-method))) 4148 auth-passwd (plist-get (nth 0 auth-info) :secret)
4147 ;; Try the password cache. 4149 auth-passwd (if (functionp auth-passwd)
4148 (when (functionp 'password-read) 4150 (funcall auth-passwd)
4149 (let ((password 4151 auth-passwd))
4150 (tramp-compat-funcall 'password-read pw-prompt key))) 4152 (tramp-compat-funcall
4151 (tramp-compat-funcall 'password-cache-add key password) 4153 'auth-source-user-or-password
4152 password)) 4154 "password" tramp-current-host tramp-current-method)))
4153 ;; Else, get the password interactively. 4155 ;; Try the password cache.
4154 (read-passwd pw-prompt)) 4156 (when (functionp 'password-read)
4155 (tramp-set-connection-property v "first-password-request" nil))))) 4157 (let ((password
4158 (tramp-compat-funcall 'password-read pw-prompt key)))
4159 (tramp-compat-funcall 'password-cache-add key password)
4160 password))
4161 ;; Else, get the password interactively.
4162 (read-passwd pw-prompt))
4163 (tramp-set-connection-property v "first-password-request" nil)))
4164 ;; Reenable the timers.
4165 (with-timeout-unsuspend stimers))))
4156 4166
4157;;;###tramp-autoload 4167;;;###tramp-autoload
4158(defun tramp-clear-passwd (vec) 4168(defun tramp-clear-passwd (vec)
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index e05aef80e86..2b8f2fa6868 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -106,7 +106,7 @@
106 "Regexp to match the beginning of a heredoc.") 106 "Regexp to match the beginning of a heredoc.")
107 107
108 (defconst ruby-expression-expansion-re 108 (defconst ruby-expression-expansion-re
109 "\\(?:[^\\]\\|\\=\\)\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)\\)")) 109 "\\(?:[^\\]\\|\\=\\)\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\|\\$[^a-zA-Z \n]\\)\\)"))
110 110
111(defun ruby-here-doc-end-match () 111(defun ruby-here-doc-end-match ()
112 "Return a regexp to find the end of a heredoc. 112 "Return a regexp to find the end of a heredoc.
@@ -2113,8 +2113,8 @@ See `font-lock-syntax-table'.")
2113 ("\\(^\\|[^:]\\)\\(:\\([-+~]@?\\|[/%&|^`]\\|\\*\\*?\\|<\\(<\\|=>?\\)?\\|>[>=]?\\|===?\\|=~\\|![~=]?\\|\\[\\]=?\\|@?\\(\\w\\|_\\)+\\([!?=]\\|\\b_*\\)\\|#{[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\)\\)" 2113 ("\\(^\\|[^:]\\)\\(:\\([-+~]@?\\|[/%&|^`]\\|\\*\\*?\\|<\\(<\\|=>?\\)?\\|>[>=]?\\|===?\\|=~\\|![~=]?\\|\\[\\]=?\\|@?\\(\\w\\|_\\)+\\([!?=]\\|\\b_*\\)\\|#{[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\)\\)"
2114 2 font-lock-constant-face) 2114 2 font-lock-constant-face)
2115 ;; Variables. 2115 ;; Variables.
2116 ("\\(\\$\\([^a-zA-Z0-9 \n]\\|[0-9]\\)\\)\\W" 2116 ("\\$[^a-zA-Z \n]"
2117 1 font-lock-variable-name-face) 2117 0 font-lock-variable-name-face)
2118 ("\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+" 2118 ("\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+"
2119 0 font-lock-variable-name-face) 2119 0 font-lock-variable-name-face)
2120 ;; Constants. 2120 ;; Constants.
diff --git a/lisp/simple.el b/lisp/simple.el
index 453259475f6..96ac5efd5cc 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2283,20 +2283,38 @@ Return what remains of the list."
2283 (when (let ((apos (abs pos))) 2283 (when (let ((apos (abs pos)))
2284 (or (< apos (point-min)) (> apos (point-max)))) 2284 (or (< apos (point-min)) (> apos (point-max))))
2285 (error "Changes to be undone are outside visible portion of buffer")) 2285 (error "Changes to be undone are outside visible portion of buffer"))
2286 (if (< pos 0) 2286 (let (valid-marker-adjustments)
2287 (progn 2287 ;; Check that marker adjustments which were recorded
2288 (goto-char (- pos)) 2288 ;; with the (STRING . POS) record are still valid, ie
2289 (insert string)) 2289 ;; the markers haven't moved. We check their validity
2290 (goto-char pos) 2290 ;; before reinserting the string so as we don't need to
2291 ;; Now that we record marker adjustments 2291 ;; mind marker insertion-type.
2292 ;; (caused by deletion) for undo, 2292 (while (and (markerp (car-safe (car list)))
2293 ;; we should always insert after markers, 2293 (integerp (cdr-safe (car list))))
2294 ;; so that undoing the marker adjustments 2294 (let* ((marker-adj (pop list))
2295 ;; put the markers back in the right place. 2295 (m (car marker-adj)))
2296 (insert string) 2296 (and (eq (marker-buffer m) (current-buffer))
2297 (goto-char pos))) 2297 (= pos m)
2298 (push marker-adj valid-marker-adjustments))))
2299 ;; Insert string and adjust point
2300 (if (< pos 0)
2301 (progn
2302 (goto-char (- pos))
2303 (insert string))
2304 (goto-char pos)
2305 (insert string)
2306 (goto-char pos))
2307 ;; Adjust the valid marker adjustments
2308 (dolist (adj valid-marker-adjustments)
2309 (set-marker (car adj)
2310 (- (car adj) (cdr adj))))))
2298 ;; (MARKER . OFFSET) means a marker MARKER was adjusted by OFFSET. 2311 ;; (MARKER . OFFSET) means a marker MARKER was adjusted by OFFSET.
2299 (`(,(and marker (pred markerp)) . ,(and offset (pred integerp))) 2312 (`(,(and marker (pred markerp)) . ,(and offset (pred integerp)))
2313 (warn "Encountered %S entry in undo list with no matching (TEXT . POS) entry"
2314 next)
2315 ;; Even though these elements are not expected in the undo
2316 ;; list, adjust them to be conservative for the 24.4
2317 ;; release. (Bug#16818)
2300 (when (marker-buffer marker) 2318 (when (marker-buffer marker)
2301 (set-marker marker 2319 (set-marker marker
2302 (- marker offset) 2320 (- marker offset)
@@ -2335,8 +2353,6 @@ are ignored. If BEG and END are nil, all undo elements are used."
2335 (undo-make-selective-list (min beg end) (max beg end)) 2353 (undo-make-selective-list (min beg end) (max beg end))
2336 buffer-undo-list))) 2354 buffer-undo-list)))
2337 2355
2338(defvar undo-adjusted-markers)
2339
2340(defun undo-make-selective-list (start end) 2356(defun undo-make-selective-list (start end)
2341 "Return a list of undo elements for the region START to END. 2357 "Return a list of undo elements for the region START to END.
2342The elements come from `buffer-undo-list', but we keep only 2358The elements come from `buffer-undo-list', but we keep only
@@ -2345,7 +2361,6 @@ If we find an element that crosses an edge of this region,
2345we stop and ignore all further elements." 2361we stop and ignore all further elements."
2346 (let ((undo-list-copy (undo-copy-list buffer-undo-list)) 2362 (let ((undo-list-copy (undo-copy-list buffer-undo-list))
2347 (undo-list (list nil)) 2363 (undo-list (list nil))
2348 undo-adjusted-markers
2349 some-rejected 2364 some-rejected
2350 undo-elt temp-undo-list delta) 2365 undo-elt temp-undo-list delta)
2351 (while undo-list-copy 2366 (while undo-list-copy
@@ -2355,15 +2370,30 @@ we stop and ignore all further elements."
2355 ;; This is a "was unmodified" element. 2370 ;; This is a "was unmodified" element.
2356 ;; Keep it if we have kept everything thus far. 2371 ;; Keep it if we have kept everything thus far.
2357 (not some-rejected)) 2372 (not some-rejected))
2373 ;; Skip over marker adjustments, instead relying on
2374 ;; finding them after (TEXT . POS) elements
2375 ((markerp (car-safe undo-elt))
2376 nil)
2358 (t 2377 (t
2359 (undo-elt-in-region undo-elt start end))))) 2378 (undo-elt-in-region undo-elt start end)))))
2360 (if keep-this 2379 (if keep-this
2361 (progn 2380 (progn
2362 (setq end (+ end (cdr (undo-delta undo-elt)))) 2381 (setq end (+ end (cdr (undo-delta undo-elt))))
2363 ;; Don't put two nils together in the list 2382 ;; Don't put two nils together in the list
2364 (if (not (and (eq (car undo-list) nil) 2383 (when (not (and (eq (car undo-list) nil)
2365 (eq undo-elt nil))) 2384 (eq undo-elt nil)))
2366 (setq undo-list (cons undo-elt undo-list)))) 2385 (setq undo-list (cons undo-elt undo-list))
2386 ;; If (TEXT . POS), "keep" its subsequent (MARKER
2387 ;; . ADJUSTMENT) whose markers haven't moved.
2388 (when (and (stringp (car-safe undo-elt))
2389 (integerp (cdr-safe undo-elt)))
2390 (let ((list-i (cdr undo-list-copy)))
2391 (while (markerp (car-safe (car list-i)))
2392 (let* ((adj-elt (pop list-i))
2393 (m (car adj-elt)))
2394 (and (eq (marker-buffer m) (current-buffer))
2395 (= (cdr undo-elt) m)
2396 (push adj-elt undo-list))))))))
2367 (if (undo-elt-crosses-region undo-elt start end) 2397 (if (undo-elt-crosses-region undo-elt start end)
2368 (setq undo-list-copy nil) 2398 (setq undo-list-copy nil)
2369 (setq some-rejected t) 2399 (setq some-rejected t)
@@ -2411,7 +2441,12 @@ we stop and ignore all further elements."
2411 2441
2412(defun undo-elt-in-region (undo-elt start end) 2442(defun undo-elt-in-region (undo-elt start end)
2413 "Determine whether UNDO-ELT falls inside the region START ... END. 2443 "Determine whether UNDO-ELT falls inside the region START ... END.
2414If it crosses the edge, we return nil." 2444If it crosses the edge, we return nil.
2445
2446Generally this function is not useful for determining
2447whether (MARKER . ADJUSTMENT) undo elements are in the region,
2448because markers can be arbitrarily relocated. Instead, pass the
2449marker adjustment's corresponding (TEXT . POS) element."
2415 (cond ((integerp undo-elt) 2450 (cond ((integerp undo-elt)
2416 (and (>= undo-elt start) 2451 (and (>= undo-elt start)
2417 (<= undo-elt end))) 2452 (<= undo-elt end)))
@@ -2424,17 +2459,8 @@ If it crosses the edge, we return nil."
2424 (and (>= (abs (cdr undo-elt)) start) 2459 (and (>= (abs (cdr undo-elt)) start)
2425 (<= (abs (cdr undo-elt)) end))) 2460 (<= (abs (cdr undo-elt)) end)))
2426 ((and (consp undo-elt) (markerp (car undo-elt))) 2461 ((and (consp undo-elt) (markerp (car undo-elt)))
2427 ;; This is a marker-adjustment element (MARKER . ADJUSTMENT). 2462 ;; (MARKER . ADJUSTMENT)
2428 ;; See if MARKER is inside the region. 2463 (<= start (car undo-elt) end))
2429 (let ((alist-elt (assq (car undo-elt) undo-adjusted-markers)))
2430 (unless alist-elt
2431 (setq alist-elt (cons (car undo-elt)
2432 (marker-position (car undo-elt))))
2433 (setq undo-adjusted-markers
2434 (cons alist-elt undo-adjusted-markers)))
2435 (and (cdr alist-elt)
2436 (>= (cdr alist-elt) start)
2437 (<= (cdr alist-elt) end))))
2438 ((null (car undo-elt)) 2464 ((null (car undo-elt))
2439 ;; (nil PROPERTY VALUE BEG . END) 2465 ;; (nil PROPERTY VALUE BEG . END)
2440 (let ((tail (nthcdr 3 undo-elt))) 2466 (let ((tail (nthcdr 3 undo-elt)))
@@ -4467,6 +4493,11 @@ also checks the value of `use-empty-active-region'."
4467 (funcall redisplay-unhighlight-region-function rol) 4493 (funcall redisplay-unhighlight-region-function rol)
4468 (overlay-put nrol 'window window) 4494 (overlay-put nrol 'window window)
4469 (overlay-put nrol 'face 'region) 4495 (overlay-put nrol 'face 'region)
4496 ;; Normal priority so that a large region doesn't hide all the
4497 ;; overlays within it, but high secondary priority so that if it
4498 ;; ends/starts in the middle of a small overlay, that small overlay
4499 ;; won't hide the region's boundaries.
4500 (overlay-put nrol 'priority '(nil . 100))
4470 nrol) 4501 nrol)
4471 (unless (and (eq (overlay-buffer rol) (current-buffer)) 4502 (unless (and (eq (overlay-buffer rol) (current-buffer))
4472 (eq (overlay-start rol) start) 4503 (eq (overlay-start rol) start)
diff --git a/lisp/url/ChangeLog b/lisp/url/ChangeLog
index 0cdcc139905..cb37b4511bd 100644
--- a/lisp/url/ChangeLog
+++ b/lisp/url/ChangeLog
@@ -1,3 +1,8 @@
12014-03-26 Juanma Barranquero <lekktu@gmail.com>
2
3 * url-handlers.el (url-http-parse-response): Add autoload.
4 (url-insert-file-contents): Signal file-error in case of HTTP error.
5
12014-02-05 Glenn Morris <rgm@gnu.org> 62014-02-05 Glenn Morris <rgm@gnu.org>
2 7
3 * url-cookie.el (url-cookie-list): Doc fix. 8 * url-cookie.el (url-cookie-list): Doc fix.
diff --git a/lisp/url/url-handlers.el b/lisp/url/url-handlers.el
index e52aad83e47..ecf56e786b5 100644
--- a/lisp/url/url-handlers.el
+++ b/lisp/url/url-handlers.el
@@ -33,6 +33,7 @@
33(autoload 'url-expand-file-name "url-expand" "Convert url to a fully specified url, and canonicalize it.") 33(autoload 'url-expand-file-name "url-expand" "Convert url to a fully specified url, and canonicalize it.")
34(autoload 'mm-dissect-buffer "mm-decode" "Dissect the current buffer and return a list of MIME handles.") 34(autoload 'mm-dissect-buffer "mm-decode" "Dissect the current buffer and return a list of MIME handles.")
35(autoload 'url-scheme-get-property "url-methods" "Get property of a URL SCHEME.") 35(autoload 'url-scheme-get-property "url-methods" "Get property of a URL SCHEME.")
36(autoload 'url-http-parse-response "url-http" "Parse just the response code.")
36 37
37;; Always used after mm-dissect-buffer and defined in the same file. 38;; Always used after mm-dissect-buffer and defined in the same file.
38(declare-function mm-save-part-to-file "mm-decode" (handle file)) 39(declare-function mm-save-part-to-file "mm-decode" (handle file))
@@ -293,8 +294,15 @@ They count bytes from the beginning of the body."
293;;;###autoload 294;;;###autoload
294(defun url-insert-file-contents (url &optional visit beg end replace) 295(defun url-insert-file-contents (url &optional visit beg end replace)
295 (let ((buffer (url-retrieve-synchronously url))) 296 (let ((buffer (url-retrieve-synchronously url)))
296 (if (not buffer) 297 (unless buffer (signal 'file-error (list url "No Data")))
297 (error "Opening input file: No such file or directory, %s" url)) 298 (with-current-buffer buffer
299 (let ((response (url-http-parse-response)))
300 (if (and (>= response 200) (< response 300))
301 (goto-char (point-min))
302 (let ((desc (buffer-substring-no-properties (1+ (point))
303 (line-end-position))))
304 (kill-buffer buffer)
305 (signal 'file-error (list url desc))))))
298 (if visit (setq buffer-file-name url)) 306 (if visit (setq buffer-file-name url))
299 (save-excursion 307 (save-excursion
300 (let* ((start (point)) 308 (let* ((start (point))
diff --git a/src/ChangeLog b/src/ChangeLog
index 84cd041c36c..996bbb78995 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,61 @@
12014-03-26 Paul Eggert <eggert@cs.ucla.edu>
2
3 Fix core dump in char-equal (Bug#17011).
4 * editfns.c (Fchar_equal): Do not use MAKE_CHAR_MULTIBYTE in
5 unibyte buffers, as we can't tell whether the characters are
6 actually unibyte.
7
8 * insdel.c (adjust_markers_for_delete): Remove unused local.
9
102014-03-26 Barry O'Reilly <gundaetiapo@gmail.com>
11
12 Have (MARKER . ADJUSTMENT) undo records always be immediately
13 after their corresponding (TEXT . POS) record in undo list.
14 (Bug#16818)
15 * lisp.h (record-delete): New arg record_markers.
16 (record_marker_adjustment): No longer needed outside undo.c.
17 * insdel.c (adjust_markers_for_delete): Move calculation of marker
18 adjustments to undo.c's record_marker_adjustments. Note that
19 fileio.c's decide_coding_unwind is another caller to
20 adjust_markers_for_delete. Because it has undo list bound to t,
21 it does not rely on adjust_markers_for_delete to record marker
22 adjustments.
23 (del_range_2): Swap call to record_delete and
24 adjust_markers_for_delete so as undo marker adjustments are
25 recorded before current deletion's adjustments, as before.
26 (adjust_after_replace):
27 (replace_range): Pass value for new record_markers arg to
28 delete_record.
29 * undo.c (record_marker_adjustment): Renamed to
30 record_marker_adjustments and made static.
31 (record_delete): Check record_markers arg and call
32 record_marker_adjustments.
33 (record_change): Pass value for new record_markers arg to
34 delete_record.
35 (record_point): at_boundary calculation no longer needs to account
36 for marker adjustments.
37
382014-03-26 Martin Rudalics <rudalics@gmx.at>
39
40 * w32term.c (x_set_window_size): Refine fix from 2014-03-14
41 (Bug#17077).
42
432014-03-26 Glenn Morris <rgm@gnu.org>
44
45 * fileio.c (Ffile_symlink_p): Doc fix. (Bug#17073)
46
472014-03-26 Stefan Monnier <monnier@iro.umontreal.ca>
48
49 * buffer.c (struct sortvec): Add field `spriority'.
50 (compare_overlays): Use it.
51 (sort_overlays): Set it.
52
532014-03-26 Eli Zaretskii <eliz@gnu.org>
54
55 * xdisp.c (redisplay_window): If all previous attempts to find the
56 cursor row failed, try a few alternatives before falling back to
57 the top-most row of the window. Use row_containing_pos. (Bug#17047)
58
12014-03-26 Juanma Barranquero <lekktu@gmail.com> 592014-03-26 Juanma Barranquero <lekktu@gmail.com>
2 60
3 * image.c (x_bitmap_height, x_bitmap_width) [HAVE_X_WINDOWS]: 61 * image.c (x_bitmap_height, x_bitmap_width) [HAVE_X_WINDOWS]:
diff --git a/src/buffer.c b/src/buffer.c
index 5e923d26f3f..a22c6d7dd54 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -3142,6 +3142,7 @@ struct sortvec
3142 Lisp_Object overlay; 3142 Lisp_Object overlay;
3143 ptrdiff_t beg, end; 3143 ptrdiff_t beg, end;
3144 EMACS_INT priority; 3144 EMACS_INT priority;
3145 EMACS_INT spriority; /* Secondary priority. */
3145}; 3146};
3146 3147
3147static int 3148static int
@@ -3149,19 +3150,28 @@ compare_overlays (const void *v1, const void *v2)
3149{ 3150{
3150 const struct sortvec *s1 = v1; 3151 const struct sortvec *s1 = v1;
3151 const struct sortvec *s2 = v2; 3152 const struct sortvec *s2 = v2;
3153 /* Return 1 if s1 should take precedence, -1 if v2 should take precedence,
3154 and 0 if they're equal. */
3152 if (s1->priority != s2->priority) 3155 if (s1->priority != s2->priority)
3153 return s1->priority < s2->priority ? -1 : 1; 3156 return s1->priority < s2->priority ? -1 : 1;
3154 if (s1->beg != s2->beg) 3157 /* If the priority is equal, give precedence to the one not covered by the
3155 return s1->beg < s2->beg ? -1 : 1; 3158 other. If neither covers the other, obey spriority. */
3156 if (s1->end != s2->end) 3159 else if (s1->beg < s2->beg)
3160 return (s1->end < s2->end && s1->spriority > s2->spriority ? 1 : -1);
3161 else if (s1->beg > s2->beg)
3162 return (s1->end > s2->end && s1->spriority < s2->spriority ? -1 : 1);
3163 else if (s1->end != s2->end)
3157 return s2->end < s1->end ? -1 : 1; 3164 return s2->end < s1->end ? -1 : 1;
3158 /* Avoid the non-determinism of qsort by choosing an arbitrary ordering 3165 else if (s1->spriority != s2->spriority)
3159 between "equal" overlays. The result can still change between 3166 return (s1->spriority < s2->spriority ? -1 : 1);
3160 invocations of Emacs, but it won't change in the middle of 3167 else if (EQ (s1->overlay, s2->overlay))
3161 `find_field' (bug#6830). */ 3168 return 0;
3162 if (!EQ (s1->overlay, s2->overlay)) 3169 else
3170 /* Avoid the non-determinism of qsort by choosing an arbitrary ordering
3171 between "equal" overlays. The result can still change between
3172 invocations of Emacs, but it won't change in the middle of
3173 `find_field' (bug#6830). */
3163 return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1; 3174 return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1;
3164 return 0;
3165} 3175}
3166 3176
3167/* Sort an array of overlays by priority. The array is modified in place. 3177/* Sort an array of overlays by priority. The array is modified in place.
@@ -3204,10 +3214,23 @@ sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w)
3204 sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay)); 3214 sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay));
3205 sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay)); 3215 sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay));
3206 tem = Foverlay_get (overlay, Qpriority); 3216 tem = Foverlay_get (overlay, Qpriority);
3207 if (INTEGERP (tem)) 3217 if (NILP (tem))
3208 sortvec[j].priority = XINT (tem); 3218 {
3209 else 3219 sortvec[j].priority = 0;
3210 sortvec[j].priority = 0; 3220 sortvec[j].spriority = 0;
3221 }
3222 else if (INTEGERP (tem))
3223 {
3224 sortvec[j].priority = XINT (tem);
3225 sortvec[j].spriority = 0;
3226 }
3227 else if (CONSP (tem))
3228 {
3229 Lisp_Object car = XCAR (tem);
3230 Lisp_Object cdr = XCDR (tem);
3231 sortvec[j].priority = INTEGERP (car) ? XINT (car) : 0;
3232 sortvec[j].spriority = INTEGERP (cdr) ? XINT (cdr) : 0;
3233 }
3211 j++; 3234 j++;
3212 } 3235 }
3213 } 3236 }
diff --git a/src/editfns.c b/src/editfns.c
index 5018020a11b..1986ee53d23 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -4377,18 +4377,13 @@ Case is ignored if `case-fold-search' is non-nil in the current buffer. */)
4377 if (NILP (BVAR (current_buffer, case_fold_search))) 4377 if (NILP (BVAR (current_buffer, case_fold_search)))
4378 return Qnil; 4378 return Qnil;
4379 4379
4380 /* FIXME: When enable-multibyte-characters is nil, it's still possible
4381 to manipulate multibyte chars, which means there is a bug for chars
4382 in the range 128-255 as we can't tell whether they are eight-bit
4383 bytes or Latin-1 chars. For now, assume the latter. See Bug#17011.
4384 Also see casefiddle.c's casify_object, which has a similar problem. */
4380 i1 = XFASTINT (c1); 4385 i1 = XFASTINT (c1);
4381 if (NILP (BVAR (current_buffer, enable_multibyte_characters))
4382 && ! ASCII_CHAR_P (i1))
4383 {
4384 MAKE_CHAR_MULTIBYTE (i1);
4385 }
4386 i2 = XFASTINT (c2); 4386 i2 = XFASTINT (c2);
4387 if (NILP (BVAR (current_buffer, enable_multibyte_characters))
4388 && ! ASCII_CHAR_P (i2))
4389 {
4390 MAKE_CHAR_MULTIBYTE (i2);
4391 }
4392 return (downcase (i1) == downcase (i2) ? Qt : Qnil); 4387 return (downcase (i1) == downcase (i2) ? Qt : Qnil);
4393} 4388}
4394 4389
diff --git a/src/fileio.c b/src/fileio.c
index 152b7a8a8ed..4d27b58d2b7 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2682,8 +2682,7 @@ DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0,
2682The value is the link target, as a string. 2682The value is the link target, as a string.
2683Otherwise it returns nil. 2683Otherwise it returns nil.
2684 2684
2685This function returns t when given the name of a symlink that 2685This function does not check whether the link target exists. */)
2686points to a nonexistent file. */)
2687 (Lisp_Object filename) 2686 (Lisp_Object filename)
2688{ 2687{
2689 Lisp_Object handler; 2688 Lisp_Object handler;
diff --git a/src/insdel.c b/src/insdel.c
index 5bd97f98613..9f9fcbd041f 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -214,9 +214,8 @@ void
214adjust_markers_for_delete (ptrdiff_t from, ptrdiff_t from_byte, 214adjust_markers_for_delete (ptrdiff_t from, ptrdiff_t from_byte,
215 ptrdiff_t to, ptrdiff_t to_byte) 215 ptrdiff_t to, ptrdiff_t to_byte)
216{ 216{
217 Lisp_Object marker; 217 struct Lisp_Marker *m;
218 register struct Lisp_Marker *m; 218 ptrdiff_t charpos;
219 register ptrdiff_t charpos;
220 219
221 for (m = BUF_MARKERS (current_buffer); m; m = m->next) 220 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
222 { 221 {
@@ -233,34 +232,9 @@ adjust_markers_for_delete (ptrdiff_t from, ptrdiff_t from_byte,
233 /* Here's the case where a marker is inside text being deleted. */ 232 /* Here's the case where a marker is inside text being deleted. */
234 else if (charpos > from) 233 else if (charpos > from)
235 { 234 {
236 if (! m->insertion_type)
237 { /* Normal markers will end up at the beginning of the
238 re-inserted text after undoing a deletion, and must be
239 adjusted to move them to the correct place. */
240 XSETMISC (marker, m);
241 record_marker_adjustment (marker, from - charpos);
242 }
243 else if (charpos < to)
244 { /* Before-insertion markers will automatically move forward
245 upon re-inserting the deleted text, so we have to arrange
246 for them to move backward to the correct position. */
247 XSETMISC (marker, m);
248 record_marker_adjustment (marker, to - charpos);
249 }
250 m->charpos = from; 235 m->charpos = from;
251 m->bytepos = from_byte; 236 m->bytepos = from_byte;
252 } 237 }
253 /* Here's the case where a before-insertion marker is immediately
254 before the deleted region. */
255 else if (charpos == from && m->insertion_type)
256 {
257 /* Undoing the change uses normal insertion, which will
258 incorrectly make MARKER move forward, so we arrange for it
259 to then move backward to the correct place at the beginning
260 of the deleted region. */
261 XSETMISC (marker, m);
262 record_marker_adjustment (marker, to - from);
263 }
264 } 238 }
265} 239}
266 240
@@ -1219,7 +1193,7 @@ adjust_after_replace (ptrdiff_t from, ptrdiff_t from_byte,
1219 from + len, from_byte + len_byte, 0); 1193 from + len, from_byte + len_byte, 0);
1220 1194
1221 if (nchars_del > 0) 1195 if (nchars_del > 0)
1222 record_delete (from, prev_text); 1196 record_delete (from, prev_text, false);
1223 record_insert (from, len); 1197 record_insert (from, len);
1224 1198
1225 if (len > nchars_del) 1199 if (len > nchars_del)
@@ -1384,7 +1358,7 @@ replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new,
1384 if (!NILP (deletion)) 1358 if (!NILP (deletion))
1385 { 1359 {
1386 record_insert (from + SCHARS (deletion), inschars); 1360 record_insert (from + SCHARS (deletion), inschars);
1387 record_delete (from, deletion); 1361 record_delete (from, deletion, false);
1388 } 1362 }
1389 1363
1390 GAP_SIZE -= outgoing_insbytes; 1364 GAP_SIZE -= outgoing_insbytes;
@@ -1716,13 +1690,14 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte,
1716 else 1690 else
1717 deletion = Qnil; 1691 deletion = Qnil;
1718 1692
1719 /* Relocate all markers pointing into the new, larger gap 1693 /* Record marker adjustments, and text deletion into undo
1720 to point at the end of the text before the gap. 1694 history. */
1721 Do this before recording the deletion, 1695 record_delete (from, deletion, true);
1722 so that undo handles this after reinserting the text. */ 1696
1697 /* Relocate all markers pointing into the new, larger gap to point
1698 at the end of the text before the gap. */
1723 adjust_markers_for_delete (from, from_byte, to, to_byte); 1699 adjust_markers_for_delete (from, from_byte, to, to_byte);
1724 1700
1725 record_delete (from, deletion);
1726 MODIFF++; 1701 MODIFF++;
1727 CHARS_MODIFF = MODIFF; 1702 CHARS_MODIFF = MODIFF;
1728 1703
diff --git a/src/lisp.h b/src/lisp.h
index 98f6c8b4d8d..07bf4646441 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4199,9 +4199,8 @@ extern void syms_of_macros (void);
4199extern Lisp_Object Qapply; 4199extern Lisp_Object Qapply;
4200extern Lisp_Object Qinhibit_read_only; 4200extern Lisp_Object Qinhibit_read_only;
4201extern void truncate_undo_list (struct buffer *); 4201extern void truncate_undo_list (struct buffer *);
4202extern void record_marker_adjustment (Lisp_Object, ptrdiff_t);
4203extern void record_insert (ptrdiff_t, ptrdiff_t); 4202extern void record_insert (ptrdiff_t, ptrdiff_t);
4204extern void record_delete (ptrdiff_t, Lisp_Object); 4203extern void record_delete (ptrdiff_t, Lisp_Object, bool);
4205extern void record_first_change (void); 4204extern void record_first_change (void);
4206extern void record_change (ptrdiff_t, ptrdiff_t); 4205extern void record_change (ptrdiff_t, ptrdiff_t);
4207extern void record_property_change (ptrdiff_t, ptrdiff_t, 4206extern void record_property_change (ptrdiff_t, ptrdiff_t,
diff --git a/src/undo.c b/src/undo.c
index 7286d40b2e5..2dde02b99a9 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -75,27 +75,8 @@ record_point (ptrdiff_t pt)
75 Fundo_boundary (); 75 Fundo_boundary ();
76 last_undo_buffer = current_buffer; 76 last_undo_buffer = current_buffer;
77 77
78 if (CONSP (BVAR (current_buffer, undo_list))) 78 at_boundary = ! CONSP (BVAR (current_buffer, undo_list))
79 { 79 || NILP (XCAR (BVAR (current_buffer, undo_list)));
80 /* Set AT_BOUNDARY only when we have nothing other than
81 marker adjustment before undo boundary. */
82
83 Lisp_Object tail = BVAR (current_buffer, undo_list), elt;
84
85 while (1)
86 {
87 if (NILP (tail))
88 elt = Qnil;
89 else
90 elt = XCAR (tail);
91 if (NILP (elt) || ! (CONSP (elt) && MARKERP (XCAR (elt))))
92 break;
93 tail = XCDR (tail);
94 }
95 at_boundary = NILP (elt);
96 }
97 else
98 at_boundary = 1;
99 80
100 if (MODIFF <= SAVE_MODIFF) 81 if (MODIFF <= SAVE_MODIFF)
101 record_first_change (); 82 record_first_change ();
@@ -147,11 +128,61 @@ record_insert (ptrdiff_t beg, ptrdiff_t length)
147 Fcons (Fcons (lbeg, lend), BVAR (current_buffer, undo_list))); 128 Fcons (Fcons (lbeg, lend), BVAR (current_buffer, undo_list)));
148} 129}
149 130
150/* Record that a deletion is about to take place, 131/* Record the fact that markers in the region of FROM, TO are about to
151 of the characters in STRING, at location BEG. */ 132 be adjusted. This is done only when a marker points within text
133 being deleted, because that's the only case where an automatic
134 marker adjustment won't be inverted automatically by undoing the
135 buffer modification. */
136
137static void
138record_marker_adjustments (ptrdiff_t from, ptrdiff_t to)
139{
140 Lisp_Object marker;
141 register struct Lisp_Marker *m;
142 register ptrdiff_t charpos, adjustment;
143
144 /* Allocate a cons cell to be the undo boundary after this command. */
145 if (NILP (pending_boundary))
146 pending_boundary = Fcons (Qnil, Qnil);
147
148 if (current_buffer != last_undo_buffer)
149 Fundo_boundary ();
150 last_undo_buffer = current_buffer;
151
152 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
153 {
154 charpos = m->charpos;
155 eassert (charpos <= Z);
156
157 if (from <= charpos && charpos <= to)
158 {
159 /* insertion_type nil markers will end up at the beginning of
160 the re-inserted text after undoing a deletion, and must be
161 adjusted to move them to the correct place.
162
163 insertion_type t markers will automatically move forward
164 upon re-inserting the deleted text, so we have to arrange
165 for them to move backward to the correct position. */
166 adjustment = (m->insertion_type ? to : from) - charpos;
167
168 if (adjustment)
169 {
170 XSETMISC (marker, m);
171 bset_undo_list
172 (current_buffer,
173 Fcons (Fcons (marker, make_number (adjustment)),
174 BVAR (current_buffer, undo_list)));
175 }
176 }
177 }
178}
179
180/* Record that a deletion is about to take place, of the characters in
181 STRING, at location BEG. Optionally record adjustments for markers
182 in the region STRING occupies in the current buffer. */
152 183
153void 184void
154record_delete (ptrdiff_t beg, Lisp_Object string) 185record_delete (ptrdiff_t beg, Lisp_Object string, bool record_markers)
155{ 186{
156 Lisp_Object sbeg; 187 Lisp_Object sbeg;
157 188
@@ -169,34 +200,15 @@ record_delete (ptrdiff_t beg, Lisp_Object string)
169 record_point (beg); 200 record_point (beg);
170 } 201 }
171 202
172 bset_undo_list 203 /* primitive-undo assumes marker adjustments are recorded
173 (current_buffer, 204 immediately before the deletion is recorded. See bug 16818
174 Fcons (Fcons (string, sbeg), BVAR (current_buffer, undo_list))); 205 discussion. */
175} 206 if (record_markers)
176 207 record_marker_adjustments (beg, beg + SCHARS (string));
177/* Record the fact that MARKER is about to be adjusted by ADJUSTMENT.
178 This is done only when a marker points within text being deleted,
179 because that's the only case where an automatic marker adjustment
180 won't be inverted automatically by undoing the buffer modification. */
181
182void
183record_marker_adjustment (Lisp_Object marker, ptrdiff_t adjustment)
184{
185 if (EQ (BVAR (current_buffer, undo_list), Qt))
186 return;
187
188 /* Allocate a cons cell to be the undo boundary after this command. */
189 if (NILP (pending_boundary))
190 pending_boundary = Fcons (Qnil, Qnil);
191
192 if (current_buffer != last_undo_buffer)
193 Fundo_boundary ();
194 last_undo_buffer = current_buffer;
195 208
196 bset_undo_list 209 bset_undo_list
197 (current_buffer, 210 (current_buffer,
198 Fcons (Fcons (marker, make_number (adjustment)), 211 Fcons (Fcons (string, sbeg), BVAR (current_buffer, undo_list)));
199 BVAR (current_buffer, undo_list)));
200} 212}
201 213
202/* Record that a replacement is about to take place, 214/* Record that a replacement is about to take place,
@@ -206,7 +218,7 @@ record_marker_adjustment (Lisp_Object marker, ptrdiff_t adjustment)
206void 218void
207record_change (ptrdiff_t beg, ptrdiff_t length) 219record_change (ptrdiff_t beg, ptrdiff_t length)
208{ 220{
209 record_delete (beg, make_buffer_string (beg, beg + length, 1)); 221 record_delete (beg, make_buffer_string (beg, beg + length, 1), false);
210 record_insert (beg, length); 222 record_insert (beg, length);
211} 223}
212 224
diff --git a/src/w32term.c b/src/w32term.c
index 52eccc27e81..e8ec99e762d 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5653,30 +5653,41 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b
5653 5653
5654 compute_fringe_widths (f, 0); 5654 compute_fringe_widths (f, 0);
5655 5655
5656 if (pixelwise) 5656 if (frame_resize_pixelwise)
5657 { 5657 {
5658 pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); 5658 if (pixelwise)
5659 pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); 5659 {
5660 pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
5661 pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
5662 }
5663 else
5664 {
5665 pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
5666 pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
5667 }
5660 } 5668 }
5661 else 5669 else
5662 { 5670 {
5663 pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
5664 pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
5665 }
5666
5667 if (!frame_resize_pixelwise)
5668 {
5669 /* If we don't resize frames pixelwise, round sizes to multiples 5671 /* If we don't resize frames pixelwise, round sizes to multiples
5670 of character sizes here. Otherwise, when enforcing size hints 5672 of character sizes here. Otherwise, when enforcing size hints
5671 while processing WM_WINDOWPOSCHANGING in w32_wnd_proc, we might 5673 while processing WM_WINDOWPOSCHANGING in w32_wnd_proc, we might
5672 clip our frame rectangle to a multiple of the frame's character 5674 clip our frame rectangle to a multiple of the frame's character
5673 size and subsequently lose our mode line or scroll bar. 5675 size and subsequently lose our mode line or scroll bar.
5674 Bug#16923 could be one possible consequence of this. */ 5676 Bug#16923 could be one possible consequence of this. Carefully
5677 reverse-engineer what WM_WINDOWPOSCHANGING does here since
5678 otherwise we might make our frame too small, see Bug#17077. */
5675 int unit_width = FRAME_COLUMN_WIDTH (f); 5679 int unit_width = FRAME_COLUMN_WIDTH (f);
5676 int unit_height = FRAME_LINE_HEIGHT (f); 5680 int unit_height = FRAME_LINE_HEIGHT (f);
5677 5681
5678 pixelwidth = (pixelwidth / unit_width) * unit_width; 5682 pixelwidth = (((((pixelwise ? width : (width * FRAME_COLUMN_WIDTH (f)))
5679 pixelheight = (pixelheight / unit_height) * unit_height; 5683 + FRAME_TOTAL_FRINGE_WIDTH (f))
5684 / unit_width) * unit_width)
5685 + FRAME_SCROLL_BAR_AREA_WIDTH (f)
5686 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
5687
5688 pixelheight = ((((pixelwise ? height : (height * FRAME_LINE_HEIGHT (f)))
5689 / unit_height) * unit_height)
5690 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
5680 } 5691 }
5681 5692
5682 f->win_gravity = NorthWestGravity; 5693 f->win_gravity = NorthWestGravity;
diff --git a/src/xdisp.c b/src/xdisp.c
index 6f39324d2f0..53bd46328f2 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -16400,12 +16400,50 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
16400 /* Consider the following case: Window starts at BEGV, there is 16400 /* Consider the following case: Window starts at BEGV, there is
16401 invisible, intangible text at BEGV, so that display starts at 16401 invisible, intangible text at BEGV, so that display starts at
16402 some point START > BEGV. It can happen that we are called with 16402 some point START > BEGV. It can happen that we are called with
16403 PT somewhere between BEGV and START. Try to handle that case. */ 16403 PT somewhere between BEGV and START. Try to handle that case,
16404 and similar ones. */
16404 if (w->cursor.vpos < 0) 16405 if (w->cursor.vpos < 0)
16405 { 16406 {
16406 struct glyph_row *row = w->current_matrix->rows; 16407 /* First, try locating the proper glyph row for PT. */
16407 if (row->mode_line_p) 16408 struct glyph_row *row =
16408 ++row; 16409 row_containing_pos (w, PT, w->current_matrix->rows, NULL, 0);
16410
16411 /* Sometimes point is at the beginning of invisible text that is
16412 before the 1st character displayed in the row. In that case,
16413 row_containing_pos fails to find the row, because no glyphs
16414 with appropriate buffer positions are present in the row.
16415 Therefore, we next try to find the row which shows the 1st
16416 position after the invisible text. */
16417 if (!row)
16418 {
16419 Lisp_Object val =
16420 get_char_property_and_overlay (make_number (PT), Qinvisible,
16421 Qnil, NULL);
16422
16423 if (TEXT_PROP_MEANS_INVISIBLE (val))
16424 {
16425 ptrdiff_t alt_pos;
16426 Lisp_Object invis_end =
16427 Fnext_single_char_property_change (make_number (PT), Qinvisible,
16428 Qnil, Qnil);
16429
16430 if (NATNUMP (invis_end))
16431 alt_pos = XFASTINT (invis_end);
16432 else
16433 alt_pos = ZV;
16434 row = row_containing_pos (w, alt_pos, w->current_matrix->rows,
16435 NULL, 0);
16436 }
16437 }
16438 /* Finally, fall back on the first row of the window after the
16439 header line (if any). This is slightly better than not
16440 displaying the cursor at all. */
16441 if (!row)
16442 {
16443 row = w->current_matrix->rows;
16444 if (row->mode_line_p)
16445 ++row;
16446 }
16409 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); 16447 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16410 } 16448 }
16411 16449
diff --git a/test/ChangeLog b/test/ChangeLog
index 392a996662a..75a3d0101c3 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,11 @@
12014-03-26 Barry O'Reilly <gundaetiapo@gmail.com>
2
3 * automated/undo-tests.el (undo-test-marker-adjustment-nominal):
4 (undo-test-region-t-marker): New tests of marker adjustments.
5 (undo-test-marker-adjustment-moved):
6 (undo-test-region-mark-adjustment): New tests to demonstrate
7 bug#16818, which fail without the fix.
8
12014-03-23 Dmitry Gutov <dgutov@yandex.ru> 92014-03-23 Dmitry Gutov <dgutov@yandex.ru>
2 10
3 * automated/package-test.el (package-test-describe-package): 11 * automated/package-test.el (package-test-describe-package):
diff --git a/test/automated/undo-tests.el b/test/automated/undo-tests.el
index 8a963f10028..6ecac36b6b3 100644
--- a/test/automated/undo-tests.el
+++ b/test/automated/undo-tests.el
@@ -268,6 +268,104 @@
268 (should (string= (buffer-string) 268 (should (string= (buffer-string)
269 "This sentence corrupted?aaa")))) 269 "This sentence corrupted?aaa"))))
270 270
271(ert-deftest undo-test-marker-adjustment-nominal ()
272 "Test nominal behavior of marker adjustments."
273 (with-temp-buffer
274 (buffer-enable-undo)
275 (insert "abcdefg")
276 (undo-boundary)
277 (let ((m (make-marker)))
278 (set-marker m 2 (current-buffer))
279 (goto-char (point-min))
280 (delete-forward-char 3)
281 (undo-boundary)
282 (should (= (point-min) (marker-position m)))
283 (undo)
284 (undo-boundary)
285 (should (= 2 (marker-position m))))))
286
287(ert-deftest undo-test-region-t-marker ()
288 "Test undo in region containing marker with t insertion-type."
289 (with-temp-buffer
290 (buffer-enable-undo)
291 (transient-mark-mode 1)
292 (insert "abcdefg")
293 (undo-boundary)
294 (let ((m (make-marker)))
295 (set-marker-insertion-type m t)
296 (set-marker m (point-min) (current-buffer)) ; m at a
297 (goto-char (+ 2 (point-min)))
298 (push-mark (point) t t)
299 (setq mark-active t)
300 (goto-char (point-min))
301 (delete-forward-char 1) ;; delete region covering "ab"
302 (undo-boundary)
303 (should (= (point-min) (marker-position m)))
304 ;; Resurrect "ab". m's insertion type means the reinsertion
305 ;; moves it forward 2, and then the marker adjustment returns it
306 ;; to its rightful place.
307 (undo)
308 (undo-boundary)
309 (should (= (point-min) (marker-position m))))))
310
311(ert-deftest undo-test-marker-adjustment-moved ()
312 "Test marker adjustment behavior when the marker moves.
313Demonstrates bug 16818."
314 (with-temp-buffer
315 (buffer-enable-undo)
316 (insert "abcdefghijk")
317 (undo-boundary)
318 (let ((m (make-marker)))
319 (set-marker m 2 (current-buffer)) ; m at b
320 (goto-char (point-min))
321 (delete-forward-char 3) ; m at d
322 (undo-boundary)
323 (set-marker m 4) ; m at g
324 (undo)
325 (undo-boundary)
326 ;; m still at g, but shifted 3 because deletion undone
327 (should (= 7 (marker-position m))))))
328
329(ert-deftest undo-test-region-mark-adjustment ()
330 "Test that the mark's marker adjustment in undo history doesn't
331obstruct undo in region from finding the correct change group.
332Demonstrates bug 16818."
333 (with-temp-buffer
334 (buffer-enable-undo)
335 (transient-mark-mode 1)
336 (insert "First line\n")
337 (insert "Second line\n")
338 (undo-boundary)
339
340 (goto-char (point-min))
341 (insert "aaa")
342 (undo-boundary)
343
344 (undo)
345 (undo-boundary)
346
347 (goto-char (point-max))
348 (insert "bbb")
349 (undo-boundary)
350
351 (push-mark (point) t t)
352 (setq mark-active t)
353 (goto-char (- (point) 3))
354 (delete-forward-char 1)
355 (undo-boundary)
356
357 (insert "bbb")
358 (undo-boundary)
359
360 (goto-char (point-min))
361 (push-mark (point) t t)
362 (setq mark-active t)
363 (goto-char (+ (point) 3))
364 (undo)
365 (undo-boundary)
366
367 (should (string= (buffer-string) "aaaFirst line\nSecond line\nbbb"))))
368
271(defun undo-test-all (&optional interactive) 369(defun undo-test-all (&optional interactive)
272 "Run all tests for \\[undo]." 370 "Run all tests for \\[undo]."
273 (interactive "p") 371 (interactive "p")