diff options
| author | Juanma Barranquero | 2014-03-26 16:57:13 +0100 |
|---|---|---|
| committer | Juanma Barranquero | 2014-03-26 16:57:13 +0100 |
| commit | 16adf2e6eb1ddf0b32ebea2d5ce8fa1e4c226614 (patch) | |
| tree | 29b782fd6e7c44a834dd09442a551520e30bcbd6 | |
| parent | 5af73b0fe8975eeb47fb270819b4143c18d71caa (diff) | |
| parent | 196716cf35f81bea108c3b75362e92c86ed1c016 (diff) | |
| download | emacs-16adf2e6eb1ddf0b32ebea2d5ce8fa1e4c226614.tar.gz emacs-16adf2e6eb1ddf0b32ebea2d5ce8fa1e4c226614.zip | |
Merge from emacs-24; up to 2014-03-23T23:14:52Z!yamaoka@jpl.org
| -rw-r--r-- | ChangeLog | 6 | ||||
| -rw-r--r-- | doc/lispref/ChangeLog | 13 | ||||
| -rw-r--r-- | doc/lispref/files.texi | 54 | ||||
| -rw-r--r-- | doc/lispref/markers.texi | 10 | ||||
| -rw-r--r-- | doc/lispref/text.texi | 9 | ||||
| -rw-r--r-- | doc/misc/ChangeLog | 8 | ||||
| -rw-r--r-- | doc/misc/texinfo.tex | 28 | ||||
| -rw-r--r-- | doc/misc/tramp.texi | 21 | ||||
| -rw-r--r-- | lib/strftime.c | 48 | ||||
| -rw-r--r-- | lisp/ChangeLog | 77 | ||||
| -rw-r--r-- | lisp/align.el | 2 | ||||
| -rw-r--r-- | lisp/emacs-lisp/package.el | 74 | ||||
| -rw-r--r-- | lisp/frame.el | 2 | ||||
| -rw-r--r-- | lisp/frameset.el | 6 | ||||
| -rw-r--r-- | lisp/net/tramp-sh.el | 114 | ||||
| -rw-r--r-- | lisp/net/tramp.el | 82 | ||||
| -rw-r--r-- | lisp/progmodes/ruby-mode.el | 6 | ||||
| -rw-r--r-- | lisp/simple.el | 91 | ||||
| -rw-r--r-- | lisp/url/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/url/url-handlers.el | 12 | ||||
| -rw-r--r-- | src/ChangeLog | 58 | ||||
| -rw-r--r-- | src/buffer.c | 49 | ||||
| -rw-r--r-- | src/editfns.c | 15 | ||||
| -rw-r--r-- | src/fileio.c | 3 | ||||
| -rw-r--r-- | src/insdel.c | 45 | ||||
| -rw-r--r-- | src/lisp.h | 3 | ||||
| -rw-r--r-- | src/undo.c | 112 | ||||
| -rw-r--r-- | src/w32term.c | 35 | ||||
| -rw-r--r-- | src/xdisp.c | 46 | ||||
| -rw-r--r-- | test/ChangeLog | 8 | ||||
| -rw-r--r-- | test/automated/undo-tests.el | 98 |
31 files changed, 787 insertions, 353 deletions
| @@ -1,3 +1,9 @@ | |||
| 1 | 2014-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 | |||
| 1 | 2014-03-26 Glenn Morris <rgm@gnu.org> | 7 | 2014-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 @@ | |||
| 1 | 2014-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 | |||
| 6 | 2014-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 | |||
| 1 | 2014-03-26 Glenn Morris <rgm@gnu.org> | 14 | 2014-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 |
| 952 | If the file @var{filename} is a symbolic link, the | 952 | If 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 |
| 954 | as a string. (Determining the file name that the link points to from | 954 | as a string. (The link target string is not necessarily the full |
| 955 | the target is nontrivial.) First, this function recursively follows | 955 | absolute file name of the target; determining the full file name that |
| 956 | symbolic links at all levels of parent directories. | 956 | the link points to is nontrivial, see below.) If the leading |
| 957 | 957 | directories of @var{filename} include symbolic links, this function | |
| 958 | If the file @var{filename} is not a symbolic link (or there is no such file), | 958 | recursively follows them. |
| 959 | |||
| 960 | If 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 | ||
| 963 | Here 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 | |||
| 984 | Note that in the third example, the function returned @file{sym-link}, | ||
| 985 | but did not proceed to resolve it, although that file is itself a | ||
| 986 | symbolic link. This is what we meant by ``non-recursive'' above---the | ||
| 987 | process of following the symbolic links does not recurse if the link | ||
| 988 | target is itself a link. | ||
| 989 | |||
| 990 | The string that this function returns is what is recorded in the | ||
| 991 | symbolic link; it may or may not include any leading directories. | ||
| 992 | This function does @emph{not} expand the link target to produce a | ||
| 993 | fully-qualified file name, and in particular does not use the leading | ||
| 994 | directories, if any, of the @var{filename} argument if the link target | ||
| 995 | is 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 | ||
| 1005 | Here, although @file{/foo/bar/baz} was given as a fully-qualified file | ||
| 1006 | name, the result is not, and in fact does not have any leading | ||
| 1007 | directories at all. And since @file{some-file} might itself be a | ||
| 1008 | symbolic link, you cannot simply prepend leading directories to it, | ||
| 1009 | nor even naively use @code{expand-file-name} (@pxref{File Name | ||
| 1010 | Expansion}) to produce its absolute file name. | ||
| 1011 | |||
| 1012 | For this reason, this function is seldom useful if you need to | ||
| 1013 | determine more than just the fact that a file is or isn't a symbolic | ||
| 1014 | link. 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 | ||
| 981 | The next two functions recursively follow symbolic links at | 1019 | The 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 |
| 347 | marker. When you do this, be sure you know how the marker is used | 347 | marker. When you do this, be sure you know whether the marker is used |
| 348 | outside of your program. For example, moving a marker to an unrelated | 348 | outside of your program, and, if so, what effects will result from |
| 349 | new position can cause undo to later adjust the marker incorrectly. | 349 | moving it---otherwise, confusing things may happen in other parts of |
| 350 | Often when you wish to relocate a marker to an unrelated position, it | 350 | Emacs. |
| 351 | is preferable to make a new marker and set the prior one to point | ||
| 352 | nowhere. | ||
| 353 | 351 | ||
| 354 | @defun set-marker marker position &optional buffer | 352 | @defun set-marker marker position &optional buffer |
| 355 | This function moves @var{marker} to @var{position} | 353 | This 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. | |||
| 1270 | The deleted text itself is the string @var{text}. The place to | 1270 | The deleted text itself is the string @var{text}. The place to |
| 1271 | reinsert it is @code{(abs @var{position})}. If @var{position} is | 1271 | reinsert it is @code{(abs @var{position})}. If @var{position} is |
| 1272 | positive, point was at the beginning of the deleted text, otherwise it | 1272 | positive, point was at the beginning of the deleted text, otherwise it |
| 1273 | was at the end. | 1273 | was at the end. Zero or more (@var{marker} . @var{adjustment}) |
| 1274 | elements follow immediately after this element. | ||
| 1274 | 1275 | ||
| 1275 | @item (t . @var{time-flag}) | 1276 | @item (t . @var{time-flag}) |
| 1276 | This kind of element indicates that an unmodified buffer became | 1277 | This 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}) |
| 1297 | This kind of element records the fact that the marker @var{marker} was | 1298 | This kind of element records the fact that the marker @var{marker} was |
| 1298 | relocated due to deletion of surrounding text, and that it moved | 1299 | relocated 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. | 1301 | consistent with the (@var{text} . @var{position}) element preceding it |
| 1302 | in 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}) |
| 1303 | This is an extensible undo item, which is undone by calling | 1306 | This 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 @@ | |||
| 1 | 2014-03-26 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | * texinfo.tex: Update from gnulib. | ||
| 4 | |||
| 5 | 2014-03-26 Michael Albinus <michael.albinus@gmx.de> | ||
| 6 | |||
| 7 | * tramp.texi (Frequently Asked Questions): Add fish shell settings. | ||
| 8 | |||
| 1 | 2014-03-23 Katsumi Yamaoka <yamaoka@jpl.org> | 9 | 2014-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 | |||
| 3053 | If it fails, or the cursor is not moved at the end of the buffer, your | 3053 | If it fails, or the cursor is not moved at the end of the buffer, your |
| 3054 | prompt is not recognized correctly. | 3054 | prompt is not recognized correctly. |
| 3055 | 3055 | ||
| 3056 | A special problem is the zsh, which uses left-hand side and right-hand | 3056 | A special problem is the zsh shell, which uses left-hand side and |
| 3057 | side prompts in parallel. Therefore, it is necessary to disable the | 3057 | right-hand side prompts in parallel. Therefore, it is necessary to |
| 3058 | zsh line editor on the remote host. You shall add to @file{~/.zshrc} | 3058 | disable the zsh line editor on the remote host. You shall add to |
| 3059 | the 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 | ||
| 3065 | Similar fancy prompt settings are known from the fish shell. Here you | ||
| 3066 | must add in @file{~/.config/fish/config.fish}: | ||
| 3067 | |||
| 3068 | @example | ||
| 3069 | function fish_prompt | ||
| 3070 | if test $TERM = "dumb" | ||
| 3071 | echo "\$ " | ||
| 3072 | else | ||
| 3073 | @dots{} | ||
| 3074 | end | ||
| 3075 | end | ||
| 3076 | @end example | ||
| 3077 | |||
| 3065 | Furthermore it has been reported, that @value{tramp} (like sshfs, | 3078 | Furthermore it has been reported, that @value{tramp} (like sshfs, |
| 3066 | incidentally) doesn't work with WinSSHD due to strange prompt settings. | 3079 | incidentally) 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 @@ | |||
| 1 | 2014-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 | |||
| 12 | 2014-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 | |||
| 24 | 2014-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 | |||
| 36 | 2014-03-26 Nicolas Richard <theonewiththeevillook@yahoo.fr> | ||
| 37 | |||
| 38 | * align.el (align-region): Do not fail when end-mark is nil (bug#17088). | ||
| 39 | |||
| 40 | 2014-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 | |||
| 48 | 2014-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 | |||
| 53 | 2014-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 | |||
| 61 | 2014-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 | |||
| 66 | 2014-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 | |||
| 1 | 2014-03-26 Reto Zimmermann <reto@gnu.org> | 76 | 2014-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 | ||
| 1250 | 2013-10-02 Michael Albinus <michael.albinus@gmx.de> | 1325 | 2014-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, | |||
| 770 | and evaluates BODY while that buffer is current. This work | 766 | and evaluates BODY while that buffer is current. This work |
| 771 | buffer is killed afterwards. Return the last value in BODY." | 767 | buffer 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. | ||
| 794 | Parse the HTTP response and throw if an error occurred. | ||
| 795 | The url package seems to require extra processing for this. | ||
| 796 | This should be called in a `save-excursion', in the download buffer. | ||
| 797 | It 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 | |||
| 2117 | shown." | 2086 | shown." |
| 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." | |||
| 940 | Setting position and size parameters as soon as possible helps reducing | 940 | Setting position and size parameters as soon as possible helps reducing |
| 941 | flickering; other parameters, like `minibuffer' and `border-width', can | 941 | flickering; other parameters, like `minibuffer' and `border-width', can |
| 942 | not be changed once the frame has been created. Internal use only." | 942 | not 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. |
| 4680 | Sends `echo $?' along with the COMMAND for checking the exit status. If | 4693 | Sends `echo $?' along with the COMMAND for checking the exit status. |
| 4681 | COMMAND is nil, just sends `echo $?'. Returns the exit status found. | 4694 | If COMMAND is nil, just sends `echo $?'. Returns `t' if the exit |
| 4695 | status is 0, and `nil' otherwise. | ||
| 4682 | 4696 | ||
| 4683 | If the optional argument SUBSHELL is non-nil, the command is | 4697 | If the optional argument SUBSHELL is non-nil, the command is |
| 4684 | executed in a subshell, ie surrounded by parentheses. If | 4698 | executed 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). |
| 1047 | This can be overwritten for different connection types in `tramp-methods'." | 1047 | This can be overwritten for different connection types in `tramp-methods'. |
| 1048 | |||
| 1049 | The 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. |
| 2342 | The elements come from `buffer-undo-list', but we keep only | 2358 | The 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, | |||
| 2345 | we stop and ignore all further elements." | 2361 | we 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. |
| 2414 | If it crosses the edge, we return nil." | 2444 | If it crosses the edge, we return nil. |
| 2445 | |||
| 2446 | Generally this function is not useful for determining | ||
| 2447 | whether (MARKER . ADJUSTMENT) undo elements are in the region, | ||
| 2448 | because markers can be arbitrarily relocated. Instead, pass the | ||
| 2449 | marker 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 @@ | |||
| 1 | 2014-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 | |||
| 1 | 2014-02-05 Glenn Morris <rgm@gnu.org> | 6 | 2014-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 @@ | |||
| 1 | 2014-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 | |||
| 10 | 2014-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 | |||
| 38 | 2014-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 | |||
| 43 | 2014-03-26 Glenn Morris <rgm@gnu.org> | ||
| 44 | |||
| 45 | * fileio.c (Ffile_symlink_p): Doc fix. (Bug#17073) | ||
| 46 | |||
| 47 | 2014-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 | |||
| 53 | 2014-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 | |||
| 1 | 2014-03-26 Juanma Barranquero <lekktu@gmail.com> | 59 | 2014-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 | ||
| 3147 | static int | 3148 | static 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, | |||
| 2682 | The value is the link target, as a string. | 2682 | The value is the link target, as a string. |
| 2683 | Otherwise it returns nil. | 2683 | Otherwise it returns nil. |
| 2684 | 2684 | ||
| 2685 | This function returns t when given the name of a symlink that | 2685 | This function does not check whether the link target exists. */) |
| 2686 | points 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 | |||
| 214 | adjust_markers_for_delete (ptrdiff_t from, ptrdiff_t from_byte, | 214 | adjust_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); | |||
| 4199 | extern Lisp_Object Qapply; | 4199 | extern Lisp_Object Qapply; |
| 4200 | extern Lisp_Object Qinhibit_read_only; | 4200 | extern Lisp_Object Qinhibit_read_only; |
| 4201 | extern void truncate_undo_list (struct buffer *); | 4201 | extern void truncate_undo_list (struct buffer *); |
| 4202 | extern void record_marker_adjustment (Lisp_Object, ptrdiff_t); | ||
| 4203 | extern void record_insert (ptrdiff_t, ptrdiff_t); | 4202 | extern void record_insert (ptrdiff_t, ptrdiff_t); |
| 4204 | extern void record_delete (ptrdiff_t, Lisp_Object); | 4203 | extern void record_delete (ptrdiff_t, Lisp_Object, bool); |
| 4205 | extern void record_first_change (void); | 4204 | extern void record_first_change (void); |
| 4206 | extern void record_change (ptrdiff_t, ptrdiff_t); | 4205 | extern void record_change (ptrdiff_t, ptrdiff_t); |
| 4207 | extern void record_property_change (ptrdiff_t, ptrdiff_t, | 4206 | extern 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 | |||
| 137 | static void | ||
| 138 | record_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 | ||
| 153 | void | 184 | void |
| 154 | record_delete (ptrdiff_t beg, Lisp_Object string) | 185 | record_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 | |||
| 182 | void | ||
| 183 | record_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) | |||
| 206 | void | 218 | void |
| 207 | record_change (ptrdiff_t beg, ptrdiff_t length) | 219 | record_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 @@ | |||
| 1 | 2014-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 | |||
| 1 | 2014-03-23 Dmitry Gutov <dgutov@yandex.ru> | 9 | 2014-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. | ||
| 313 | Demonstrates 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 | ||
| 331 | obstruct undo in region from finding the correct change group. | ||
| 332 | Demonstrates 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") |