mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-03 10:31:37 -08:00
Merge from emacs-24; up to 2014-03-23T23:14:52Z!yamaoka@jpl.org
This commit is contained in:
commit
16adf2e6eb
31 changed files with 782 additions and 348 deletions
|
|
@ -1,3 +1,9 @@
|
|||
2014-03-26 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Merge from gnulib, incorporating:
|
||||
2014-03-26 strftime: wrap macros in "do {...} while(0)"
|
||||
* lib/strftime.c: Update from gnulib.
|
||||
|
||||
2014-03-26 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* configure.ac (CLASH_DETECTION): Remove option. Every platform
|
||||
|
|
|
|||
|
|
@ -1,3 +1,16 @@
|
|||
2014-03-26 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* files.texi (Kinds of Files): Improve documentation of
|
||||
file-symlink-p. (Bug#17073) Add cross-references.
|
||||
|
||||
2014-03-26 Barry O'Reilly <gundaetiapo@gmail.com>
|
||||
|
||||
* markers.texi (Moving Marker Positions): The 2014-03-02 doc
|
||||
change mentioning undo's inability to handle relocated markers no
|
||||
longer applies. See bug#16818.
|
||||
* text.texi (Undo): Expand documentation of (TEXT . POS) and
|
||||
(MARKER . ADJUSTMENT) undo elements.
|
||||
|
||||
2014-03-26 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* files.texi (File Locks): All systems support locking.
|
||||
|
|
|
|||
|
|
@ -950,22 +950,26 @@ as directories, symbolic links, and ordinary files.
|
|||
@defun file-symlink-p filename
|
||||
@cindex file symbolic links
|
||||
If the file @var{filename} is a symbolic link, the
|
||||
@code{file-symlink-p} function returns the (non-recursive) link target
|
||||
as a string. (Determining the file name that the link points to from
|
||||
the target is nontrivial.) First, this function recursively follows
|
||||
symbolic links at all levels of parent directories.
|
||||
@code{file-symlink-p} function returns its (non-recursive) link target
|
||||
as a string. (The link target string is not necessarily the full
|
||||
absolute file name of the target; determining the full file name that
|
||||
the link points to is nontrivial, see below.) If the leading
|
||||
directories of @var{filename} include symbolic links, this function
|
||||
recursively follows them.
|
||||
|
||||
If the file @var{filename} is not a symbolic link (or there is no such file),
|
||||
If the file @var{filename} is not a symbolic link, or does not exist,
|
||||
@code{file-symlink-p} returns @code{nil}.
|
||||
|
||||
Here are a few examples of using this function:
|
||||
|
||||
@example
|
||||
@group
|
||||
(file-symlink-p "foo")
|
||||
(file-symlink-p "not-a-symlink")
|
||||
@result{} nil
|
||||
@end group
|
||||
@group
|
||||
(file-symlink-p "sym-link")
|
||||
@result{} "foo"
|
||||
@result{} "not-a-symlink"
|
||||
@end group
|
||||
@group
|
||||
(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),
|
|||
@result{} "/pub/bin"
|
||||
@end group
|
||||
@end example
|
||||
|
||||
Note that in the third example, the function returned @file{sym-link},
|
||||
but did not proceed to resolve it, although that file is itself a
|
||||
symbolic link. This is what we meant by ``non-recursive'' above---the
|
||||
process of following the symbolic links does not recurse if the link
|
||||
target is itself a link.
|
||||
|
||||
The string that this function returns is what is recorded in the
|
||||
symbolic link; it may or may not include any leading directories.
|
||||
This function does @emph{not} expand the link target to produce a
|
||||
fully-qualified file name, and in particular does not use the leading
|
||||
directories, if any, of the @var{filename} argument if the link target
|
||||
is not an absolute file name. Here's an example:
|
||||
|
||||
@example
|
||||
@group
|
||||
(file-symlink-p "/foo/bar/baz")
|
||||
@result{} "some-file"
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
Here, although @file{/foo/bar/baz} was given as a fully-qualified file
|
||||
name, the result is not, and in fact does not have any leading
|
||||
directories at all. And since @file{some-file} might itself be a
|
||||
symbolic link, you cannot simply prepend leading directories to it,
|
||||
nor even naively use @code{expand-file-name} (@pxref{File Name
|
||||
Expansion}) to produce its absolute file name.
|
||||
|
||||
For this reason, this function is seldom useful if you need to
|
||||
determine more than just the fact that a file is or isn't a symbolic
|
||||
link. If you actually need the file name of the link target, use
|
||||
@code{file-chase-links} or @code{file-truename}, described in
|
||||
@ref{Truenames}.
|
||||
@end defun
|
||||
|
||||
The next two functions recursively follow symbolic links at
|
||||
|
|
|
|||
|
|
@ -344,12 +344,10 @@ specify the insertion type, create them with insertion type
|
|||
@section Moving Marker Positions
|
||||
|
||||
This section describes how to change the position of an existing
|
||||
marker. When you do this, be sure you know how the marker is used
|
||||
outside of your program. For example, moving a marker to an unrelated
|
||||
new position can cause undo to later adjust the marker incorrectly.
|
||||
Often when you wish to relocate a marker to an unrelated position, it
|
||||
is preferable to make a new marker and set the prior one to point
|
||||
nowhere.
|
||||
marker. When you do this, be sure you know whether the marker is used
|
||||
outside of your program, and, if so, what effects will result from
|
||||
moving it---otherwise, confusing things may happen in other parts of
|
||||
Emacs.
|
||||
|
||||
@defun set-marker marker position &optional buffer
|
||||
This function moves @var{marker} to @var{position}
|
||||
|
|
|
|||
|
|
@ -1270,7 +1270,8 @@ This kind of element indicates how to reinsert text that was deleted.
|
|||
The deleted text itself is the string @var{text}. The place to
|
||||
reinsert it is @code{(abs @var{position})}. If @var{position} is
|
||||
positive, point was at the beginning of the deleted text, otherwise it
|
||||
was at the end.
|
||||
was at the end. Zero or more (@var{marker} . @var{adjustment})
|
||||
elements follow immediately after this element.
|
||||
|
||||
@item (t . @var{time-flag})
|
||||
This kind of element indicates that an unmodified buffer became
|
||||
|
|
@ -1296,8 +1297,10 @@ Here's how you might undo the change:
|
|||
@item (@var{marker} . @var{adjustment})
|
||||
This kind of element records the fact that the marker @var{marker} was
|
||||
relocated due to deletion of surrounding text, and that it moved
|
||||
@var{adjustment} character positions. Undoing this element moves
|
||||
@var{marker} @minus{} @var{adjustment} characters.
|
||||
@var{adjustment} character positions. If the marker's location is
|
||||
consistent with the (@var{text} . @var{position}) element preceding it
|
||||
in the undo list, then undoing this element moves @var{marker}
|
||||
@minus{} @var{adjustment} characters.
|
||||
|
||||
@item (apply @var{funname} . @var{args})
|
||||
This is an extensible undo item, which is undone by calling
|
||||
|
|
|
|||
|
|
@ -1,3 +1,11 @@
|
|||
2014-03-26 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* texinfo.tex: Update from gnulib.
|
||||
|
||||
2014-03-26 Michael Albinus <michael.albinus@gmx.de>
|
||||
|
||||
* tramp.texi (Frequently Asked Questions): Add fish shell settings.
|
||||
|
||||
2014-03-23 Katsumi Yamaoka <yamaoka@jpl.org>
|
||||
|
||||
* gnus.texi (Ma Gnus): Mention header attachment buttons.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
% Load plain if necessary, i.e., if running under initex.
|
||||
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
|
||||
%
|
||||
\def\texinfoversion{2014-02-16.16}
|
||||
\def\texinfoversion{2014-03-17.07}
|
||||
%
|
||||
% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
|
||||
% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
|
|
@ -3936,18 +3936,22 @@ end
|
|||
|
||||
% multitable-only commands.
|
||||
%
|
||||
% @headitem starts a heading row, which we typeset in bold.
|
||||
% Assignments have to be global since we are inside the implicit group
|
||||
% of an alignment entry. \everycr resets \everytab so we don't have to
|
||||
% @headitem starts a heading row, which we typeset in bold. Assignments
|
||||
% have to be global since we are inside the implicit group of an
|
||||
% alignment entry. \everycr below resets \everytab so we don't have to
|
||||
% undo it ourselves.
|
||||
\def\headitemfont{\b}% for people to use in the template row; not changeable
|
||||
\def\headitem{%
|
||||
\checkenv\multitable
|
||||
\crcr
|
||||
\gdef\headitemcrhook{\nobreak}% attempt to avoid page break after headings
|
||||
\global\everytab={\bf}% can't use \headitemfont since the parsing differs
|
||||
\the\everytab % for the first item
|
||||
}%
|
||||
%
|
||||
% default for tables with no headings.
|
||||
\let\headitemcrhook=\relax
|
||||
%
|
||||
% A \tab used to include \hskip1sp. But then the space in a template
|
||||
% line is not enough. That is bad. So let's go back to just `&' until
|
||||
% we again encounter the problem the 1sp was intended to solve.
|
||||
|
|
@ -3978,15 +3982,15 @@ end
|
|||
%
|
||||
\everycr = {%
|
||||
\noalign{%
|
||||
\global\everytab={}%
|
||||
\global\everytab={}% Reset from possible headitem.
|
||||
\global\colcount=0 % Reset the column counter.
|
||||
% Check for saved footnotes, etc.
|
||||
%
|
||||
% Check for saved footnotes, etc.:
|
||||
\checkinserts
|
||||
% Keeps underfull box messages off when table breaks over pages.
|
||||
%\filbreak
|
||||
% Maybe so, but it also creates really weird page breaks when the
|
||||
% table breaks over pages. Wouldn't \vfil be better? Wait until the
|
||||
% problem manifests itself, so it can be fixed for real --karl.
|
||||
%
|
||||
% Perhaps a \nobreak, then reset:
|
||||
\headitemcrhook
|
||||
\global\let\headitemcrhook=\relax
|
||||
}%
|
||||
}%
|
||||
%
|
||||
|
|
|
|||
|
|
@ -3053,15 +3053,28 @@ setting the cursor at the top of the buffer, and applying the expression
|
|||
If it fails, or the cursor is not moved at the end of the buffer, your
|
||||
prompt is not recognized correctly.
|
||||
|
||||
A special problem is the zsh, which uses left-hand side and right-hand
|
||||
side prompts in parallel. Therefore, it is necessary to disable the
|
||||
zsh line editor on the remote host. You shall add to @file{~/.zshrc}
|
||||
the following command:
|
||||
A special problem is the zsh shell, which uses left-hand side and
|
||||
right-hand side prompts in parallel. Therefore, it is necessary to
|
||||
disable the zsh line editor on the remote host. You shall add to
|
||||
@file{~/.zshrc} the following command:
|
||||
|
||||
@example
|
||||
[ $TERM = "dumb" ] && unsetopt zle && PS1='$ '
|
||||
@end example
|
||||
|
||||
Similar fancy prompt settings are known from the fish shell. Here you
|
||||
must add in @file{~/.config/fish/config.fish}:
|
||||
|
||||
@example
|
||||
function fish_prompt
|
||||
if test $TERM = "dumb"
|
||||
echo "\$ "
|
||||
else
|
||||
@dots{}
|
||||
end
|
||||
end
|
||||
@end example
|
||||
|
||||
Furthermore it has been reported, that @value{tramp} (like sshfs,
|
||||
incidentally) doesn't work with WinSSHD due to strange prompt settings.
|
||||
|
||||
|
|
|
|||
|
|
@ -681,24 +681,44 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
|
|||
switch (format_char)
|
||||
{
|
||||
#define DO_NUMBER(d, v) \
|
||||
do \
|
||||
{ \
|
||||
digits = d; \
|
||||
number_value = v; goto do_number
|
||||
number_value = v; \
|
||||
goto do_number; \
|
||||
} \
|
||||
while (0)
|
||||
#define DO_SIGNED_NUMBER(d, negative, v) \
|
||||
do \
|
||||
{ \
|
||||
digits = d; \
|
||||
negative_number = negative; \
|
||||
u_number_value = v; goto do_signed_number
|
||||
u_number_value = v; \
|
||||
goto do_signed_number; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* The mask is not what you might think.
|
||||
When the ordinal i'th bit is set, insert a colon
|
||||
before the i'th digit of the time zone representation. */
|
||||
#define DO_TZ_OFFSET(d, negative, mask, v) \
|
||||
do \
|
||||
{ \
|
||||
digits = d; \
|
||||
negative_number = negative; \
|
||||
tz_colon_mask = mask; \
|
||||
u_number_value = v; goto do_tz_offset
|
||||
u_number_value = v; \
|
||||
goto do_tz_offset; \
|
||||
} \
|
||||
while (0)
|
||||
#define DO_NUMBER_SPACEPAD(d, v) \
|
||||
do \
|
||||
{ \
|
||||
digits = d; \
|
||||
number_value = v; goto do_number_spacepad
|
||||
number_value = v; \
|
||||
goto do_number_spacepad; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
case L_('%'):
|
||||
if (modifier != 0)
|
||||
|
|
@ -1265,7 +1285,7 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
|
|||
}
|
||||
if (modifier == L_('O'))
|
||||
goto bad_format;
|
||||
else
|
||||
|
||||
DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE,
|
||||
tp->tm_year + (unsigned int) TM_YEAR_BASE);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,78 @@
|
|||
2014-03-26 Juanma Barranquero <lekktu@gmail.com>
|
||||
|
||||
* emacs-lisp/package.el: Fix bug#16733 (again).
|
||||
(url-http-parse-response, url-http-end-of-headers, url-recreate-url)
|
||||
(url-http-target-url): Remove unused declarations.
|
||||
(package-handle-response): Remove.
|
||||
(package--with-work-buffer): Use url-insert-file-contents and simplify.
|
||||
(package--download-one-archive): Use current-buffer instead of
|
||||
dynamic binding of `buffer'.
|
||||
(describe-package-1): Do not decode readme-string.
|
||||
|
||||
2014-03-26 Michael Albinus <michael.albinus@gmx.de>
|
||||
|
||||
* net/tramp.el (tramp-methods, tramp-connection-timeout): Fix docstring.
|
||||
|
||||
* net/tramp-sh.el (tramp-sh-handle-vc-registered): Revert change
|
||||
from 2014-03-07, it decreases performance unnecessarily. Let-bind
|
||||
`remote-file-name-inhibit-cache' to nil in the second pass.
|
||||
(tramp-find-executable): Do not call "which" on SunOS.
|
||||
(tramp-send-command-and-check): Fix docstring.
|
||||
(tramp-do-copy-or-rename-file-directly): In the `rename' case,
|
||||
check whether source directory has set the sticky bit.
|
||||
|
||||
2014-03-26 Barry O'Reilly <gundaetiapo@gmail.com>
|
||||
|
||||
* simple.el (primitive-undo): Only process marker adjustments
|
||||
validated against their corresponding (TEXT . POS). Issue warning
|
||||
for lone marker adjustments in undo history. (Bug#16818)
|
||||
(undo-make-selective-list): Add marker adjustments to selective
|
||||
undo list based on whether their corresponding (TEXT . POS) is in
|
||||
the region. Remove variable adjusted-markers, which was unused
|
||||
and only non nil during undo-make-selective-list.
|
||||
(undo-elt-in-region): Return nil when passed a marker adjustment
|
||||
and explain in function doc.
|
||||
|
||||
2014-03-26 Nicolas Richard <theonewiththeevillook@yahoo.fr>
|
||||
|
||||
* align.el (align-region): Do not fail when end-mark is nil (bug#17088).
|
||||
|
||||
2014-03-26 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
* progmodes/ruby-mode.el (ruby-expression-expansion-re):
|
||||
Match special global variables without curlies, too.
|
||||
(ruby-font-lock-keywords): Simplify the matcher for special global
|
||||
variables. Don't require a non-word character after the variable.
|
||||
(Bug#17057)
|
||||
|
||||
2014-03-26 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* simple.el (redisplay-highlight-region-function): Increase priority of
|
||||
overlay to make sure boundaries are visible (bug#15899).
|
||||
|
||||
2014-03-26 Juanma Barranquero <lekktu@gmail.com>
|
||||
|
||||
* frameset.el (frameset--initial-params): Fix typo in parameter name.
|
||||
(frameset-restore): Compare display strings with equal.
|
||||
|
||||
* frame.el (make-frame): Don't quote display name in error message,
|
||||
it is already a string.
|
||||
|
||||
2014-03-26 Thierry Volpiatto <thierry.volpiatto@gmail.com>
|
||||
|
||||
* net/tramp.el (tramp-read-passwd): Suspend the timers while reading
|
||||
the password.
|
||||
|
||||
2014-03-26 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
* emacs-lisp/package.el (package--add-to-archive-contents):
|
||||
Include already installed and built-in packages in
|
||||
`package-archive-contents'.
|
||||
(package-install): Don't include already installed packages in the
|
||||
options during interactive invocation. (Bug#16762)
|
||||
(package-show-package-list): If the buffer is already displayed in
|
||||
another window, switch to that window.
|
||||
|
||||
2014-03-26 Reto Zimmermann <reto@gnu.org>
|
||||
|
||||
Sync with upstream vhdl mode v3.35.1.
|
||||
|
|
@ -1247,7 +1322,7 @@
|
|||
dbus-call-method check for completion using a busy-wait loop with
|
||||
gradual backoff.
|
||||
|
||||
2013-10-02 Michael Albinus <michael.albinus@gmx.de>
|
||||
2014-02-16 Michael Albinus <michael.albinus@gmx.de>
|
||||
|
||||
Sync with Tramp 2.2.9.
|
||||
|
||||
|
|
|
|||
|
|
@ -1603,7 +1603,7 @@ aligner would have dealt with are."
|
|||
rule-index (1+ rule-index)))
|
||||
;; This function can use a lot of temporary markers, so instead of
|
||||
;; waiting for the next GC we delete them immediately (Bug#10047).
|
||||
(set-marker end-mark nil)
|
||||
(when end-mark (set-marker end-mark nil))
|
||||
(dolist (m markers)
|
||||
(set-marker m nil))
|
||||
|
||||
|
|
|
|||
|
|
@ -205,13 +205,9 @@ If VERSION is nil, the package is not loaded (it is \"disabled\")."
|
|||
|
||||
(defvar Info-directory-list)
|
||||
(declare-function info-initialize "info" ())
|
||||
(declare-function url-http-parse-response "url-http" ())
|
||||
(declare-function url-http-file-exists-p "url-http" (url))
|
||||
(declare-function lm-header "lisp-mnt" (header))
|
||||
(declare-function lm-commentary "lisp-mnt" (&optional file))
|
||||
(defvar url-http-end-of-headers)
|
||||
(declare-function url-recreate-url "url-parse" (urlobj))
|
||||
(defvar url-http-target-url)
|
||||
|
||||
(defcustom package-archives '(("gnu" . "http://elpa.gnu.org/packages/"))
|
||||
"An alist of archives from which to fetch.
|
||||
|
|
@ -770,38 +766,14 @@ This macro retrieves FILE from LOCATION into a temporary buffer,
|
|||
and evaluates BODY while that buffer is current. This work
|
||||
buffer is killed afterwards. Return the last value in BODY."
|
||||
(declare (indent 2) (debug t))
|
||||
`(let* ((http (string-match "\\`https?:" ,location))
|
||||
(buffer
|
||||
(if http
|
||||
(url-retrieve-synchronously (concat ,location ,file))
|
||||
(generate-new-buffer "*package work buffer*"))))
|
||||
(prog1
|
||||
(with-current-buffer buffer
|
||||
(if http
|
||||
(progn (package-handle-response)
|
||||
(re-search-forward "^$" nil 'move)
|
||||
(forward-char)
|
||||
(delete-region (point-min) (point)))
|
||||
`(with-temp-buffer
|
||||
(if (string-match-p "\\`https?:" ,location)
|
||||
(url-insert-file-contents (concat ,location ,file))
|
||||
(unless (file-name-absolute-p ,location)
|
||||
(error "Archive location %s is not an absolute file name"
|
||||
,location))
|
||||
(insert-file-contents (expand-file-name ,file ,location)))
|
||||
,@body)
|
||||
(kill-buffer buffer))))
|
||||
|
||||
(defun package-handle-response ()
|
||||
"Handle the response from a `url-retrieve-synchronously' call.
|
||||
Parse the HTTP response and throw if an error occurred.
|
||||
The url package seems to require extra processing for this.
|
||||
This should be called in a `save-excursion', in the download buffer.
|
||||
It will move point to somewhere in the headers."
|
||||
;; We assume HTTP here.
|
||||
(require 'url-http)
|
||||
(let ((response (url-http-parse-response)))
|
||||
(when (or (< response 200) (>= response 300))
|
||||
(error "Error downloading %s:%s"
|
||||
(url-recreate-url url-http-target-url)
|
||||
(buffer-substring-no-properties (point) (line-end-position))))))
|
||||
,@body))
|
||||
|
||||
(defun package--archive-file-exists-p (location file)
|
||||
(let ((http (string-match "\\`https?:" location)))
|
||||
|
|
@ -1047,14 +1019,9 @@ Also, add the originating archive to the `package-desc' structure."
|
|||
(existing-packages (assq name package-archive-contents))
|
||||
(pinned-to-archive (assoc name package-pinned-packages)))
|
||||
(cond
|
||||
;; Skip entirely if pinned to another archive or already installed.
|
||||
((or (and pinned-to-archive
|
||||
;; Skip entirely if pinned to another archive.
|
||||
((and pinned-to-archive
|
||||
(not (equal (cdr pinned-to-archive) archive)))
|
||||
(let ((bi (assq name package--builtin-versions)))
|
||||
(and bi (version-list-= version (cdr bi))))
|
||||
(let ((ins (cdr (assq name package-alist))))
|
||||
(and ins (version-list-= version
|
||||
(package-desc-version (car ins))))))
|
||||
nil)
|
||||
((not existing-packages)
|
||||
(push (list name pkg-desc) package-archive-contents))
|
||||
|
|
@ -1090,8 +1057,11 @@ in an archive in `package-archives'. Interactively, prompt for its name."
|
|||
(package-refresh-contents))
|
||||
(list (intern (completing-read
|
||||
"Install package: "
|
||||
(mapcar (lambda (elt) (symbol-name (car elt)))
|
||||
package-archive-contents)
|
||||
(delq nil
|
||||
(mapcar (lambda (elt)
|
||||
(unless (package-installed-p (car elt))
|
||||
(symbol-name (car elt))))
|
||||
package-archive-contents))
|
||||
nil t)))))
|
||||
(package-download-transaction
|
||||
(if (package-desc-p pkg)
|
||||
|
|
@ -1272,7 +1242,7 @@ similar to an entry in `package-alist'. Save the cached copy to
|
|||
(car archive)))))
|
||||
;; Read the retrieved buffer to make sure it is valid (e.g. it
|
||||
;; may fetch a URL redirect page).
|
||||
(when (listp (read buffer))
|
||||
(when (listp (read (current-buffer)))
|
||||
(make-directory dir t)
|
||||
(setq buffer-file-name (expand-file-name file dir))
|
||||
(let ((version-control 'never)
|
||||
|
|
@ -1531,8 +1501,7 @@ If optional arg NO-ACTIVATE is non-nil, don't activate packages."
|
|||
(setq readme-string (buffer-string))
|
||||
t))
|
||||
(error nil))
|
||||
(let ((coding (detect-coding-string readme-string t)))
|
||||
(insert (decode-coding-string readme-string coding t))))
|
||||
(insert readme-string))
|
||||
((file-readable-p readme)
|
||||
(insert-file-contents readme)
|
||||
(goto-char (point-max))))))))
|
||||
|
|
@ -2117,11 +2086,14 @@ When KEYWORDS are given, only packages with those KEYWORDS are
|
|||
shown."
|
||||
(interactive)
|
||||
(require 'finder-inf nil t)
|
||||
(let ((buf (get-buffer-create "*Packages*")))
|
||||
(let* ((buf (get-buffer-create "*Packages*"))
|
||||
(win (get-buffer-window buf)))
|
||||
(with-current-buffer buf
|
||||
(package-menu-mode)
|
||||
(package-menu--generate nil packages keywords))
|
||||
(switch-to-buffer buf)))
|
||||
(if win
|
||||
(select-window win)
|
||||
(switch-to-buffer buf))))
|
||||
|
||||
;; package-menu--generate rebinds "q" on the fly, so we have to
|
||||
;; hard-code the binding in the doc-string here.
|
||||
|
|
|
|||
|
|
@ -668,7 +668,7 @@ the new frame according to its own rules."
|
|||
(cdr (assq 'window-system parameters)))
|
||||
(display
|
||||
(or (window-system-for-display display)
|
||||
(error "Don't know how to interpret display \"%S\""
|
||||
(error "Don't know how to interpret display %S"
|
||||
display)))
|
||||
(t window-system)))
|
||||
(frame-creation-function (cdr (assq w frame-creation-function-alist)))
|
||||
|
|
|
|||
|
|
@ -940,7 +940,7 @@ is the parameter alist of the frame being restored. Internal use only."
|
|||
Setting position and size parameters as soon as possible helps reducing
|
||||
flickering; other parameters, like `minibuffer' and `border-width', can
|
||||
not be changed once the frame has been created. Internal use only."
|
||||
(cl-loop for param in '(left top with height border-width minibuffer)
|
||||
(cl-loop for param in '(left top width height border-width minibuffer)
|
||||
when (assq param parameters) collect it))
|
||||
|
||||
(defun frameset--restore-frame (parameters window-state filters force-onscreen)
|
||||
|
|
@ -1146,7 +1146,7 @@ All keyword parameters default to nil."
|
|||
frame to-tty duplicate)
|
||||
;; Only set target if forcing displays and the target display is different.
|
||||
(unless (or (frameset-keep-original-display-p force-display)
|
||||
(eq (frame-parameter nil 'display)
|
||||
(equal (frame-parameter nil 'display)
|
||||
(cdr (assq 'display frame-cfg))))
|
||||
(setq frameset--target-display (cons 'display
|
||||
(frame-parameter nil 'display))
|
||||
|
|
|
|||
|
|
@ -2110,6 +2110,12 @@ the uid and gid from FILENAME."
|
|||
;; We can do it directly.
|
||||
((let (file-name-handler-alist)
|
||||
(and (file-readable-p localname1)
|
||||
;; No sticky bit when renaming.
|
||||
(or (eq op 'copy)
|
||||
(zerop
|
||||
(logand
|
||||
(file-modes (file-name-directory localname1))
|
||||
(tramp-compat-octal-to-decimal "1000"))))
|
||||
(file-writable-p (file-name-directory localname2))
|
||||
(or (file-directory-p localname2)
|
||||
(file-writable-p localname2))))
|
||||
|
|
@ -3311,9 +3317,11 @@ the result will be a local, non-Tramp, filename."
|
|||
(with-tramp-progress-reporter
|
||||
v 3 (format "Checking `vc-registered' for %s" file)
|
||||
|
||||
(unless remote-file-name-inhibit-cache
|
||||
;; There could be new files, created by the vc backend. We
|
||||
;; cannot reuse the old cache entries, therefore.
|
||||
;; cannot reuse the old cache entries, therefore. In
|
||||
;; `tramp-get-file-property', `remote-file-name-inhibit-cache'
|
||||
;; could also be a timestamp as `current-time' returns. This
|
||||
;; means invalidate all cache entries with an older timestamp.
|
||||
(let (tramp-vc-registered-file-names
|
||||
(remote-file-name-inhibit-cache (current-time))
|
||||
(file-name-handler-alist
|
||||
|
|
@ -3353,13 +3361,13 @@ the result will be a local, non-Tramp, filename."
|
|||
(read (current-buffer)))))
|
||||
|
||||
(tramp-set-file-property
|
||||
v (car elt) (cadr elt) (cadr (cdr elt)))))))
|
||||
v (car elt) (cadr elt) (cadr (cdr elt))))))
|
||||
|
||||
;; Second run. Now all `file-exists-p' or `file-readable-p'
|
||||
;; calls shall be answered from the file cache. We unset
|
||||
;; `process-file-side-effects' in order to keep the cache when
|
||||
;; `process-file' calls appear.
|
||||
(let (process-file-side-effects)
|
||||
;; `process-file-side-effects' and `remote-file-name-inhibit-cache'
|
||||
;; in order to keep the cache.
|
||||
(let (remote-file-name-inhibit-cache process-file-side-effects)
|
||||
(ignore-errors
|
||||
(tramp-run-real-handler 'vc-registered (list file))))))))
|
||||
|
||||
|
|
@ -3604,8 +3612,13 @@ This function expects to be in the right *tramp* buffer."
|
|||
(let (result)
|
||||
;; Check whether the executable is in $PATH. "which(1)" does not
|
||||
;; report always a correct error code; therefore we check the
|
||||
;; number of words it returns.
|
||||
(unless ignore-path
|
||||
;; number of words it returns. "SunOS 5.10" (and maybe "SunOS
|
||||
;; 5.11") have problems with this command, we disable the call
|
||||
;; therefore.
|
||||
(unless (or ignore-path
|
||||
(string-match
|
||||
(regexp-opt '("SunOS 5.10" "SunOS 5.11"))
|
||||
(tramp-get-connection-property vec "uname" "")))
|
||||
(tramp-send-command vec (format "which \\%s | wc -w" progname))
|
||||
(goto-char (point-min))
|
||||
(if (looking-at "^\\s-*1$")
|
||||
|
|
@ -4677,8 +4690,9 @@ function waits for output unless NOOUTPUT is set."
|
|||
(defun tramp-send-command-and-check
|
||||
(vec command &optional subshell dont-suppress-err)
|
||||
"Run COMMAND and check its exit status.
|
||||
Sends `echo $?' along with the COMMAND for checking the exit status. If
|
||||
COMMAND is nil, just sends `echo $?'. Returns the exit status found.
|
||||
Sends `echo $?' along with the COMMAND for checking the exit status.
|
||||
If COMMAND is nil, just sends `echo $?'. Returns `t' if the exit
|
||||
status is 0, and `nil' otherwise.
|
||||
|
||||
If the optional argument SUBSHELL is non-nil, the command is
|
||||
executed in a subshell, ie surrounded by parentheses. If
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ pair of the form (KEY VALUE). The following KEYs are defined:
|
|||
* `tramp-copy-program'
|
||||
This specifies the name of the program to use for remotely copying
|
||||
the file; this might be the absolute filename of rcp or the name of
|
||||
a workalike program.
|
||||
a workalike program. It is always applied on the local host.
|
||||
* `tramp-copy-args'
|
||||
This specifies the list of parameters to pass to the above mentioned
|
||||
program, the hints for `tramp-login-args' also apply here.
|
||||
|
|
@ -1044,7 +1044,9 @@ opening a connection to a remote host."
|
|||
|
||||
(defcustom tramp-connection-timeout 60
|
||||
"Defines the max time to wait for establishing a connection (in seconds).
|
||||
This can be overwritten for different connection types in `tramp-methods'."
|
||||
This can be overwritten for different connection types in `tramp-methods'.
|
||||
|
||||
The timeout does not include the time reading a password."
|
||||
:group 'tramp
|
||||
:version "24.4"
|
||||
:type 'integer)
|
||||
|
|
@ -4119,15 +4121,21 @@ Invokes `password-read' if available, `read-passwd' else."
|
|||
(with-current-buffer (process-buffer proc)
|
||||
(tramp-check-for-regexp proc tramp-password-prompt-regexp)
|
||||
(format "%s for %s " (capitalize (match-string 1)) key))))
|
||||
;; We suspend the timers while reading the password.
|
||||
(stimers (with-timeout-suspend))
|
||||
auth-info auth-passwd)
|
||||
|
||||
(unwind-protect
|
||||
(with-parsed-tramp-file-name key nil
|
||||
(prog1
|
||||
(or
|
||||
;; See if auth-sources contains something useful, if it's
|
||||
;; bound. `auth-source-user-or-password' is an obsoleted
|
||||
;; function, it has been replaced by `auth-source-search'.
|
||||
;; See if auth-sources contains something useful, if
|
||||
;; it's bound. `auth-source-user-or-password' is an
|
||||
;; obsoleted function, it has been replaced by
|
||||
;; `auth-source-search'.
|
||||
(and (boundp 'auth-sources)
|
||||
(tramp-get-connection-property v "first-password-request" nil)
|
||||
(tramp-get-connection-property
|
||||
v "first-password-request" nil)
|
||||
;; Try with Tramp's current method.
|
||||
(if (fboundp 'auth-source-search)
|
||||
(setq auth-info
|
||||
|
|
@ -4152,7 +4160,9 @@ Invokes `password-read' if available, `read-passwd' else."
|
|||
password))
|
||||
;; Else, get the password interactively.
|
||||
(read-passwd pw-prompt))
|
||||
(tramp-set-connection-property v "first-password-request" nil)))))
|
||||
(tramp-set-connection-property v "first-password-request" nil)))
|
||||
;; Reenable the timers.
|
||||
(with-timeout-unsuspend stimers))))
|
||||
|
||||
;;;###tramp-autoload
|
||||
(defun tramp-clear-passwd (vec)
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@
|
|||
"Regexp to match the beginning of a heredoc.")
|
||||
|
||||
(defconst ruby-expression-expansion-re
|
||||
"\\(?:[^\\]\\|\\=\\)\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)\\)"))
|
||||
"\\(?:[^\\]\\|\\=\\)\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\|\\$[^a-zA-Z \n]\\)\\)"))
|
||||
|
||||
(defun ruby-here-doc-end-match ()
|
||||
"Return a regexp to find the end of a heredoc.
|
||||
|
|
@ -2113,8 +2113,8 @@ See `font-lock-syntax-table'.")
|
|||
("\\(^\\|[^:]\\)\\(:\\([-+~]@?\\|[/%&|^`]\\|\\*\\*?\\|<\\(<\\|=>?\\)?\\|>[>=]?\\|===?\\|=~\\|![~=]?\\|\\[\\]=?\\|@?\\(\\w\\|_\\)+\\([!?=]\\|\\b_*\\)\\|#{[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\)\\)"
|
||||
2 font-lock-constant-face)
|
||||
;; Variables.
|
||||
("\\(\\$\\([^a-zA-Z0-9 \n]\\|[0-9]\\)\\)\\W"
|
||||
1 font-lock-variable-name-face)
|
||||
("\\$[^a-zA-Z \n]"
|
||||
0 font-lock-variable-name-face)
|
||||
("\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+"
|
||||
0 font-lock-variable-name-face)
|
||||
;; Constants.
|
||||
|
|
|
|||
|
|
@ -2283,20 +2283,38 @@ Return what remains of the list."
|
|||
(when (let ((apos (abs pos)))
|
||||
(or (< apos (point-min)) (> apos (point-max))))
|
||||
(error "Changes to be undone are outside visible portion of buffer"))
|
||||
(let (valid-marker-adjustments)
|
||||
;; Check that marker adjustments which were recorded
|
||||
;; with the (STRING . POS) record are still valid, ie
|
||||
;; the markers haven't moved. We check their validity
|
||||
;; before reinserting the string so as we don't need to
|
||||
;; mind marker insertion-type.
|
||||
(while (and (markerp (car-safe (car list)))
|
||||
(integerp (cdr-safe (car list))))
|
||||
(let* ((marker-adj (pop list))
|
||||
(m (car marker-adj)))
|
||||
(and (eq (marker-buffer m) (current-buffer))
|
||||
(= pos m)
|
||||
(push marker-adj valid-marker-adjustments))))
|
||||
;; Insert string and adjust point
|
||||
(if (< pos 0)
|
||||
(progn
|
||||
(goto-char (- pos))
|
||||
(insert string))
|
||||
(goto-char pos)
|
||||
;; Now that we record marker adjustments
|
||||
;; (caused by deletion) for undo,
|
||||
;; we should always insert after markers,
|
||||
;; so that undoing the marker adjustments
|
||||
;; put the markers back in the right place.
|
||||
(insert string)
|
||||
(goto-char pos)))
|
||||
(goto-char pos))
|
||||
;; Adjust the valid marker adjustments
|
||||
(dolist (adj valid-marker-adjustments)
|
||||
(set-marker (car adj)
|
||||
(- (car adj) (cdr adj))))))
|
||||
;; (MARKER . OFFSET) means a marker MARKER was adjusted by OFFSET.
|
||||
(`(,(and marker (pred markerp)) . ,(and offset (pred integerp)))
|
||||
(warn "Encountered %S entry in undo list with no matching (TEXT . POS) entry"
|
||||
next)
|
||||
;; Even though these elements are not expected in the undo
|
||||
;; list, adjust them to be conservative for the 24.4
|
||||
;; release. (Bug#16818)
|
||||
(when (marker-buffer marker)
|
||||
(set-marker marker
|
||||
(- marker offset)
|
||||
|
|
@ -2335,8 +2353,6 @@ are ignored. If BEG and END are nil, all undo elements are used."
|
|||
(undo-make-selective-list (min beg end) (max beg end))
|
||||
buffer-undo-list)))
|
||||
|
||||
(defvar undo-adjusted-markers)
|
||||
|
||||
(defun undo-make-selective-list (start end)
|
||||
"Return a list of undo elements for the region START to END.
|
||||
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,
|
|||
we stop and ignore all further elements."
|
||||
(let ((undo-list-copy (undo-copy-list buffer-undo-list))
|
||||
(undo-list (list nil))
|
||||
undo-adjusted-markers
|
||||
some-rejected
|
||||
undo-elt temp-undo-list delta)
|
||||
(while undo-list-copy
|
||||
|
|
@ -2355,15 +2370,30 @@ we stop and ignore all further elements."
|
|||
;; This is a "was unmodified" element.
|
||||
;; Keep it if we have kept everything thus far.
|
||||
(not some-rejected))
|
||||
;; Skip over marker adjustments, instead relying on
|
||||
;; finding them after (TEXT . POS) elements
|
||||
((markerp (car-safe undo-elt))
|
||||
nil)
|
||||
(t
|
||||
(undo-elt-in-region undo-elt start end)))))
|
||||
(if keep-this
|
||||
(progn
|
||||
(setq end (+ end (cdr (undo-delta undo-elt))))
|
||||
;; Don't put two nils together in the list
|
||||
(if (not (and (eq (car undo-list) nil)
|
||||
(when (not (and (eq (car undo-list) nil)
|
||||
(eq undo-elt nil)))
|
||||
(setq undo-list (cons undo-elt undo-list))))
|
||||
(setq undo-list (cons undo-elt undo-list))
|
||||
;; If (TEXT . POS), "keep" its subsequent (MARKER
|
||||
;; . ADJUSTMENT) whose markers haven't moved.
|
||||
(when (and (stringp (car-safe undo-elt))
|
||||
(integerp (cdr-safe undo-elt)))
|
||||
(let ((list-i (cdr undo-list-copy)))
|
||||
(while (markerp (car-safe (car list-i)))
|
||||
(let* ((adj-elt (pop list-i))
|
||||
(m (car adj-elt)))
|
||||
(and (eq (marker-buffer m) (current-buffer))
|
||||
(= (cdr undo-elt) m)
|
||||
(push adj-elt undo-list))))))))
|
||||
(if (undo-elt-crosses-region undo-elt start end)
|
||||
(setq undo-list-copy nil)
|
||||
(setq some-rejected t)
|
||||
|
|
@ -2411,7 +2441,12 @@ we stop and ignore all further elements."
|
|||
|
||||
(defun undo-elt-in-region (undo-elt start end)
|
||||
"Determine whether UNDO-ELT falls inside the region START ... END.
|
||||
If it crosses the edge, we return nil."
|
||||
If it crosses the edge, we return nil.
|
||||
|
||||
Generally this function is not useful for determining
|
||||
whether (MARKER . ADJUSTMENT) undo elements are in the region,
|
||||
because markers can be arbitrarily relocated. Instead, pass the
|
||||
marker adjustment's corresponding (TEXT . POS) element."
|
||||
(cond ((integerp undo-elt)
|
||||
(and (>= undo-elt start)
|
||||
(<= undo-elt end)))
|
||||
|
|
@ -2424,17 +2459,8 @@ If it crosses the edge, we return nil."
|
|||
(and (>= (abs (cdr undo-elt)) start)
|
||||
(<= (abs (cdr undo-elt)) end)))
|
||||
((and (consp undo-elt) (markerp (car undo-elt)))
|
||||
;; This is a marker-adjustment element (MARKER . ADJUSTMENT).
|
||||
;; See if MARKER is inside the region.
|
||||
(let ((alist-elt (assq (car undo-elt) undo-adjusted-markers)))
|
||||
(unless alist-elt
|
||||
(setq alist-elt (cons (car undo-elt)
|
||||
(marker-position (car undo-elt))))
|
||||
(setq undo-adjusted-markers
|
||||
(cons alist-elt undo-adjusted-markers)))
|
||||
(and (cdr alist-elt)
|
||||
(>= (cdr alist-elt) start)
|
||||
(<= (cdr alist-elt) end))))
|
||||
;; (MARKER . ADJUSTMENT)
|
||||
(<= start (car undo-elt) end))
|
||||
((null (car undo-elt))
|
||||
;; (nil PROPERTY VALUE BEG . END)
|
||||
(let ((tail (nthcdr 3 undo-elt)))
|
||||
|
|
@ -4467,6 +4493,11 @@ also checks the value of `use-empty-active-region'."
|
|||
(funcall redisplay-unhighlight-region-function rol)
|
||||
(overlay-put nrol 'window window)
|
||||
(overlay-put nrol 'face 'region)
|
||||
;; Normal priority so that a large region doesn't hide all the
|
||||
;; overlays within it, but high secondary priority so that if it
|
||||
;; ends/starts in the middle of a small overlay, that small overlay
|
||||
;; won't hide the region's boundaries.
|
||||
(overlay-put nrol 'priority '(nil . 100))
|
||||
nrol)
|
||||
(unless (and (eq (overlay-buffer rol) (current-buffer))
|
||||
(eq (overlay-start rol) start)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
2014-03-26 Juanma Barranquero <lekktu@gmail.com>
|
||||
|
||||
* url-handlers.el (url-http-parse-response): Add autoload.
|
||||
(url-insert-file-contents): Signal file-error in case of HTTP error.
|
||||
|
||||
2014-02-05 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* url-cookie.el (url-cookie-list): Doc fix.
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
(autoload 'url-expand-file-name "url-expand" "Convert url to a fully specified url, and canonicalize it.")
|
||||
(autoload 'mm-dissect-buffer "mm-decode" "Dissect the current buffer and return a list of MIME handles.")
|
||||
(autoload 'url-scheme-get-property "url-methods" "Get property of a URL SCHEME.")
|
||||
(autoload 'url-http-parse-response "url-http" "Parse just the response code.")
|
||||
|
||||
;; Always used after mm-dissect-buffer and defined in the same file.
|
||||
(declare-function mm-save-part-to-file "mm-decode" (handle file))
|
||||
|
|
@ -293,8 +294,15 @@ They count bytes from the beginning of the body."
|
|||
;;;###autoload
|
||||
(defun url-insert-file-contents (url &optional visit beg end replace)
|
||||
(let ((buffer (url-retrieve-synchronously url)))
|
||||
(if (not buffer)
|
||||
(error "Opening input file: No such file or directory, %s" url))
|
||||
(unless buffer (signal 'file-error (list url "No Data")))
|
||||
(with-current-buffer buffer
|
||||
(let ((response (url-http-parse-response)))
|
||||
(if (and (>= response 200) (< response 300))
|
||||
(goto-char (point-min))
|
||||
(let ((desc (buffer-substring-no-properties (1+ (point))
|
||||
(line-end-position))))
|
||||
(kill-buffer buffer)
|
||||
(signal 'file-error (list url desc))))))
|
||||
(if visit (setq buffer-file-name url))
|
||||
(save-excursion
|
||||
(let* ((start (point))
|
||||
|
|
|
|||
|
|
@ -1,3 +1,61 @@
|
|||
2014-03-26 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Fix core dump in char-equal (Bug#17011).
|
||||
* editfns.c (Fchar_equal): Do not use MAKE_CHAR_MULTIBYTE in
|
||||
unibyte buffers, as we can't tell whether the characters are
|
||||
actually unibyte.
|
||||
|
||||
* insdel.c (adjust_markers_for_delete): Remove unused local.
|
||||
|
||||
2014-03-26 Barry O'Reilly <gundaetiapo@gmail.com>
|
||||
|
||||
Have (MARKER . ADJUSTMENT) undo records always be immediately
|
||||
after their corresponding (TEXT . POS) record in undo list.
|
||||
(Bug#16818)
|
||||
* lisp.h (record-delete): New arg record_markers.
|
||||
(record_marker_adjustment): No longer needed outside undo.c.
|
||||
* insdel.c (adjust_markers_for_delete): Move calculation of marker
|
||||
adjustments to undo.c's record_marker_adjustments. Note that
|
||||
fileio.c's decide_coding_unwind is another caller to
|
||||
adjust_markers_for_delete. Because it has undo list bound to t,
|
||||
it does not rely on adjust_markers_for_delete to record marker
|
||||
adjustments.
|
||||
(del_range_2): Swap call to record_delete and
|
||||
adjust_markers_for_delete so as undo marker adjustments are
|
||||
recorded before current deletion's adjustments, as before.
|
||||
(adjust_after_replace):
|
||||
(replace_range): Pass value for new record_markers arg to
|
||||
delete_record.
|
||||
* undo.c (record_marker_adjustment): Renamed to
|
||||
record_marker_adjustments and made static.
|
||||
(record_delete): Check record_markers arg and call
|
||||
record_marker_adjustments.
|
||||
(record_change): Pass value for new record_markers arg to
|
||||
delete_record.
|
||||
(record_point): at_boundary calculation no longer needs to account
|
||||
for marker adjustments.
|
||||
|
||||
2014-03-26 Martin Rudalics <rudalics@gmx.at>
|
||||
|
||||
* w32term.c (x_set_window_size): Refine fix from 2014-03-14
|
||||
(Bug#17077).
|
||||
|
||||
2014-03-26 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* fileio.c (Ffile_symlink_p): Doc fix. (Bug#17073)
|
||||
|
||||
2014-03-26 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* buffer.c (struct sortvec): Add field `spriority'.
|
||||
(compare_overlays): Use it.
|
||||
(sort_overlays): Set it.
|
||||
|
||||
2014-03-26 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* xdisp.c (redisplay_window): If all previous attempts to find the
|
||||
cursor row failed, try a few alternatives before falling back to
|
||||
the top-most row of the window. Use row_containing_pos. (Bug#17047)
|
||||
|
||||
2014-03-26 Juanma Barranquero <lekktu@gmail.com>
|
||||
|
||||
* image.c (x_bitmap_height, x_bitmap_width) [HAVE_X_WINDOWS]:
|
||||
|
|
|
|||
39
src/buffer.c
39
src/buffer.c
|
|
@ -3142,6 +3142,7 @@ struct sortvec
|
|||
Lisp_Object overlay;
|
||||
ptrdiff_t beg, end;
|
||||
EMACS_INT priority;
|
||||
EMACS_INT spriority; /* Secondary priority. */
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
@ -3149,19 +3150,28 @@ compare_overlays (const void *v1, const void *v2)
|
|||
{
|
||||
const struct sortvec *s1 = v1;
|
||||
const struct sortvec *s2 = v2;
|
||||
/* Return 1 if s1 should take precedence, -1 if v2 should take precedence,
|
||||
and 0 if they're equal. */
|
||||
if (s1->priority != s2->priority)
|
||||
return s1->priority < s2->priority ? -1 : 1;
|
||||
if (s1->beg != s2->beg)
|
||||
return s1->beg < s2->beg ? -1 : 1;
|
||||
if (s1->end != s2->end)
|
||||
/* If the priority is equal, give precedence to the one not covered by the
|
||||
other. If neither covers the other, obey spriority. */
|
||||
else if (s1->beg < s2->beg)
|
||||
return (s1->end < s2->end && s1->spriority > s2->spriority ? 1 : -1);
|
||||
else if (s1->beg > s2->beg)
|
||||
return (s1->end > s2->end && s1->spriority < s2->spriority ? -1 : 1);
|
||||
else if (s1->end != s2->end)
|
||||
return s2->end < s1->end ? -1 : 1;
|
||||
else if (s1->spriority != s2->spriority)
|
||||
return (s1->spriority < s2->spriority ? -1 : 1);
|
||||
else if (EQ (s1->overlay, s2->overlay))
|
||||
return 0;
|
||||
else
|
||||
/* Avoid the non-determinism of qsort by choosing an arbitrary ordering
|
||||
between "equal" overlays. The result can still change between
|
||||
invocations of Emacs, but it won't change in the middle of
|
||||
`find_field' (bug#6830). */
|
||||
if (!EQ (s1->overlay, s2->overlay))
|
||||
return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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)
|
|||
sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay));
|
||||
sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay));
|
||||
tem = Foverlay_get (overlay, Qpriority);
|
||||
if (INTEGERP (tem))
|
||||
sortvec[j].priority = XINT (tem);
|
||||
else
|
||||
if (NILP (tem))
|
||||
{
|
||||
sortvec[j].priority = 0;
|
||||
sortvec[j].spriority = 0;
|
||||
}
|
||||
else if (INTEGERP (tem))
|
||||
{
|
||||
sortvec[j].priority = XINT (tem);
|
||||
sortvec[j].spriority = 0;
|
||||
}
|
||||
else if (CONSP (tem))
|
||||
{
|
||||
Lisp_Object car = XCAR (tem);
|
||||
Lisp_Object cdr = XCDR (tem);
|
||||
sortvec[j].priority = INTEGERP (car) ? XINT (car) : 0;
|
||||
sortvec[j].spriority = INTEGERP (cdr) ? XINT (cdr) : 0;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4377,18 +4377,13 @@ Case is ignored if `case-fold-search' is non-nil in the current buffer. */)
|
|||
if (NILP (BVAR (current_buffer, case_fold_search)))
|
||||
return Qnil;
|
||||
|
||||
/* FIXME: When enable-multibyte-characters is nil, it's still possible
|
||||
to manipulate multibyte chars, which means there is a bug for chars
|
||||
in the range 128-255 as we can't tell whether they are eight-bit
|
||||
bytes or Latin-1 chars. For now, assume the latter. See Bug#17011.
|
||||
Also see casefiddle.c's casify_object, which has a similar problem. */
|
||||
i1 = XFASTINT (c1);
|
||||
if (NILP (BVAR (current_buffer, enable_multibyte_characters))
|
||||
&& ! ASCII_CHAR_P (i1))
|
||||
{
|
||||
MAKE_CHAR_MULTIBYTE (i1);
|
||||
}
|
||||
i2 = XFASTINT (c2);
|
||||
if (NILP (BVAR (current_buffer, enable_multibyte_characters))
|
||||
&& ! ASCII_CHAR_P (i2))
|
||||
{
|
||||
MAKE_CHAR_MULTIBYTE (i2);
|
||||
}
|
||||
return (downcase (i1) == downcase (i2) ? Qt : Qnil);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2682,8 +2682,7 @@ DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0,
|
|||
The value is the link target, as a string.
|
||||
Otherwise it returns nil.
|
||||
|
||||
This function returns t when given the name of a symlink that
|
||||
points to a nonexistent file. */)
|
||||
This function does not check whether the link target exists. */)
|
||||
(Lisp_Object filename)
|
||||
{
|
||||
Lisp_Object handler;
|
||||
|
|
|
|||
45
src/insdel.c
45
src/insdel.c
|
|
@ -214,9 +214,8 @@ void
|
|||
adjust_markers_for_delete (ptrdiff_t from, ptrdiff_t from_byte,
|
||||
ptrdiff_t to, ptrdiff_t to_byte)
|
||||
{
|
||||
Lisp_Object marker;
|
||||
register struct Lisp_Marker *m;
|
||||
register ptrdiff_t charpos;
|
||||
struct Lisp_Marker *m;
|
||||
ptrdiff_t charpos;
|
||||
|
||||
for (m = BUF_MARKERS (current_buffer); m; m = m->next)
|
||||
{
|
||||
|
|
@ -233,34 +232,9 @@ adjust_markers_for_delete (ptrdiff_t from, ptrdiff_t from_byte,
|
|||
/* Here's the case where a marker is inside text being deleted. */
|
||||
else if (charpos > from)
|
||||
{
|
||||
if (! m->insertion_type)
|
||||
{ /* Normal markers will end up at the beginning of the
|
||||
re-inserted text after undoing a deletion, and must be
|
||||
adjusted to move them to the correct place. */
|
||||
XSETMISC (marker, m);
|
||||
record_marker_adjustment (marker, from - charpos);
|
||||
}
|
||||
else if (charpos < to)
|
||||
{ /* Before-insertion markers will automatically move forward
|
||||
upon re-inserting the deleted text, so we have to arrange
|
||||
for them to move backward to the correct position. */
|
||||
XSETMISC (marker, m);
|
||||
record_marker_adjustment (marker, to - charpos);
|
||||
}
|
||||
m->charpos = from;
|
||||
m->bytepos = from_byte;
|
||||
}
|
||||
/* Here's the case where a before-insertion marker is immediately
|
||||
before the deleted region. */
|
||||
else if (charpos == from && m->insertion_type)
|
||||
{
|
||||
/* Undoing the change uses normal insertion, which will
|
||||
incorrectly make MARKER move forward, so we arrange for it
|
||||
to then move backward to the correct place at the beginning
|
||||
of the deleted region. */
|
||||
XSETMISC (marker, m);
|
||||
record_marker_adjustment (marker, to - from);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1219,7 +1193,7 @@ adjust_after_replace (ptrdiff_t from, ptrdiff_t from_byte,
|
|||
from + len, from_byte + len_byte, 0);
|
||||
|
||||
if (nchars_del > 0)
|
||||
record_delete (from, prev_text);
|
||||
record_delete (from, prev_text, false);
|
||||
record_insert (from, len);
|
||||
|
||||
if (len > nchars_del)
|
||||
|
|
@ -1384,7 +1358,7 @@ replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new,
|
|||
if (!NILP (deletion))
|
||||
{
|
||||
record_insert (from + SCHARS (deletion), inschars);
|
||||
record_delete (from, deletion);
|
||||
record_delete (from, deletion, false);
|
||||
}
|
||||
|
||||
GAP_SIZE -= outgoing_insbytes;
|
||||
|
|
@ -1716,13 +1690,14 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte,
|
|||
else
|
||||
deletion = Qnil;
|
||||
|
||||
/* Relocate all markers pointing into the new, larger gap
|
||||
to point at the end of the text before the gap.
|
||||
Do this before recording the deletion,
|
||||
so that undo handles this after reinserting the text. */
|
||||
/* Record marker adjustments, and text deletion into undo
|
||||
history. */
|
||||
record_delete (from, deletion, true);
|
||||
|
||||
/* Relocate all markers pointing into the new, larger gap to point
|
||||
at the end of the text before the gap. */
|
||||
adjust_markers_for_delete (from, from_byte, to, to_byte);
|
||||
|
||||
record_delete (from, deletion);
|
||||
MODIFF++;
|
||||
CHARS_MODIFF = MODIFF;
|
||||
|
||||
|
|
|
|||
|
|
@ -4199,9 +4199,8 @@ extern void syms_of_macros (void);
|
|||
extern Lisp_Object Qapply;
|
||||
extern Lisp_Object Qinhibit_read_only;
|
||||
extern void truncate_undo_list (struct buffer *);
|
||||
extern void record_marker_adjustment (Lisp_Object, ptrdiff_t);
|
||||
extern void record_insert (ptrdiff_t, ptrdiff_t);
|
||||
extern void record_delete (ptrdiff_t, Lisp_Object);
|
||||
extern void record_delete (ptrdiff_t, Lisp_Object, bool);
|
||||
extern void record_first_change (void);
|
||||
extern void record_change (ptrdiff_t, ptrdiff_t);
|
||||
extern void record_property_change (ptrdiff_t, ptrdiff_t,
|
||||
|
|
|
|||
112
src/undo.c
112
src/undo.c
|
|
@ -75,27 +75,8 @@ record_point (ptrdiff_t pt)
|
|||
Fundo_boundary ();
|
||||
last_undo_buffer = current_buffer;
|
||||
|
||||
if (CONSP (BVAR (current_buffer, undo_list)))
|
||||
{
|
||||
/* Set AT_BOUNDARY only when we have nothing other than
|
||||
marker adjustment before undo boundary. */
|
||||
|
||||
Lisp_Object tail = BVAR (current_buffer, undo_list), elt;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (NILP (tail))
|
||||
elt = Qnil;
|
||||
else
|
||||
elt = XCAR (tail);
|
||||
if (NILP (elt) || ! (CONSP (elt) && MARKERP (XCAR (elt))))
|
||||
break;
|
||||
tail = XCDR (tail);
|
||||
}
|
||||
at_boundary = NILP (elt);
|
||||
}
|
||||
else
|
||||
at_boundary = 1;
|
||||
at_boundary = ! CONSP (BVAR (current_buffer, undo_list))
|
||||
|| NILP (XCAR (BVAR (current_buffer, undo_list)));
|
||||
|
||||
if (MODIFF <= SAVE_MODIFF)
|
||||
record_first_change ();
|
||||
|
|
@ -147,11 +128,61 @@ record_insert (ptrdiff_t beg, ptrdiff_t length)
|
|||
Fcons (Fcons (lbeg, lend), BVAR (current_buffer, undo_list)));
|
||||
}
|
||||
|
||||
/* Record that a deletion is about to take place,
|
||||
of the characters in STRING, at location BEG. */
|
||||
/* Record the fact that markers in the region of FROM, TO are about to
|
||||
be adjusted. This is done only when a marker points within text
|
||||
being deleted, because that's the only case where an automatic
|
||||
marker adjustment won't be inverted automatically by undoing the
|
||||
buffer modification. */
|
||||
|
||||
static void
|
||||
record_marker_adjustments (ptrdiff_t from, ptrdiff_t to)
|
||||
{
|
||||
Lisp_Object marker;
|
||||
register struct Lisp_Marker *m;
|
||||
register ptrdiff_t charpos, adjustment;
|
||||
|
||||
/* Allocate a cons cell to be the undo boundary after this command. */
|
||||
if (NILP (pending_boundary))
|
||||
pending_boundary = Fcons (Qnil, Qnil);
|
||||
|
||||
if (current_buffer != last_undo_buffer)
|
||||
Fundo_boundary ();
|
||||
last_undo_buffer = current_buffer;
|
||||
|
||||
for (m = BUF_MARKERS (current_buffer); m; m = m->next)
|
||||
{
|
||||
charpos = m->charpos;
|
||||
eassert (charpos <= Z);
|
||||
|
||||
if (from <= charpos && charpos <= to)
|
||||
{
|
||||
/* insertion_type nil markers will end up at the beginning of
|
||||
the re-inserted text after undoing a deletion, and must be
|
||||
adjusted to move them to the correct place.
|
||||
|
||||
insertion_type t markers will automatically move forward
|
||||
upon re-inserting the deleted text, so we have to arrange
|
||||
for them to move backward to the correct position. */
|
||||
adjustment = (m->insertion_type ? to : from) - charpos;
|
||||
|
||||
if (adjustment)
|
||||
{
|
||||
XSETMISC (marker, m);
|
||||
bset_undo_list
|
||||
(current_buffer,
|
||||
Fcons (Fcons (marker, make_number (adjustment)),
|
||||
BVAR (current_buffer, undo_list)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Record that a deletion is about to take place, of the characters in
|
||||
STRING, at location BEG. Optionally record adjustments for markers
|
||||
in the region STRING occupies in the current buffer. */
|
||||
|
||||
void
|
||||
record_delete (ptrdiff_t beg, Lisp_Object string)
|
||||
record_delete (ptrdiff_t beg, Lisp_Object string, bool record_markers)
|
||||
{
|
||||
Lisp_Object sbeg;
|
||||
|
||||
|
|
@ -169,36 +200,17 @@ record_delete (ptrdiff_t beg, Lisp_Object string)
|
|||
record_point (beg);
|
||||
}
|
||||
|
||||
/* primitive-undo assumes marker adjustments are recorded
|
||||
immediately before the deletion is recorded. See bug 16818
|
||||
discussion. */
|
||||
if (record_markers)
|
||||
record_marker_adjustments (beg, beg + SCHARS (string));
|
||||
|
||||
bset_undo_list
|
||||
(current_buffer,
|
||||
Fcons (Fcons (string, sbeg), BVAR (current_buffer, undo_list)));
|
||||
}
|
||||
|
||||
/* Record the fact that MARKER is about to be adjusted by ADJUSTMENT.
|
||||
This is done only when a marker points within text being deleted,
|
||||
because that's the only case where an automatic marker adjustment
|
||||
won't be inverted automatically by undoing the buffer modification. */
|
||||
|
||||
void
|
||||
record_marker_adjustment (Lisp_Object marker, ptrdiff_t adjustment)
|
||||
{
|
||||
if (EQ (BVAR (current_buffer, undo_list), Qt))
|
||||
return;
|
||||
|
||||
/* Allocate a cons cell to be the undo boundary after this command. */
|
||||
if (NILP (pending_boundary))
|
||||
pending_boundary = Fcons (Qnil, Qnil);
|
||||
|
||||
if (current_buffer != last_undo_buffer)
|
||||
Fundo_boundary ();
|
||||
last_undo_buffer = current_buffer;
|
||||
|
||||
bset_undo_list
|
||||
(current_buffer,
|
||||
Fcons (Fcons (marker, make_number (adjustment)),
|
||||
BVAR (current_buffer, undo_list)));
|
||||
}
|
||||
|
||||
/* Record that a replacement is about to take place,
|
||||
for LENGTH characters at location BEG.
|
||||
The replacement must not change the number of characters. */
|
||||
|
|
@ -206,7 +218,7 @@ record_marker_adjustment (Lisp_Object marker, ptrdiff_t adjustment)
|
|||
void
|
||||
record_change (ptrdiff_t beg, ptrdiff_t length)
|
||||
{
|
||||
record_delete (beg, make_buffer_string (beg, beg + length, 1));
|
||||
record_delete (beg, make_buffer_string (beg, beg + length, 1), false);
|
||||
record_insert (beg, length);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5653,6 +5653,8 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b
|
|||
|
||||
compute_fringe_widths (f, 0);
|
||||
|
||||
if (frame_resize_pixelwise)
|
||||
{
|
||||
if (pixelwise)
|
||||
{
|
||||
pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
|
||||
|
|
@ -5663,20 +5665,29 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b
|
|||
pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
|
||||
pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
|
||||
}
|
||||
|
||||
if (!frame_resize_pixelwise)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we don't resize frames pixelwise, round sizes to multiples
|
||||
of character sizes here. Otherwise, when enforcing size hints
|
||||
while processing WM_WINDOWPOSCHANGING in w32_wnd_proc, we might
|
||||
clip our frame rectangle to a multiple of the frame's character
|
||||
size and subsequently lose our mode line or scroll bar.
|
||||
Bug#16923 could be one possible consequence of this. */
|
||||
Bug#16923 could be one possible consequence of this. Carefully
|
||||
reverse-engineer what WM_WINDOWPOSCHANGING does here since
|
||||
otherwise we might make our frame too small, see Bug#17077. */
|
||||
int unit_width = FRAME_COLUMN_WIDTH (f);
|
||||
int unit_height = FRAME_LINE_HEIGHT (f);
|
||||
|
||||
pixelwidth = (pixelwidth / unit_width) * unit_width;
|
||||
pixelheight = (pixelheight / unit_height) * unit_height;
|
||||
pixelwidth = (((((pixelwise ? width : (width * FRAME_COLUMN_WIDTH (f)))
|
||||
+ FRAME_TOTAL_FRINGE_WIDTH (f))
|
||||
/ unit_width) * unit_width)
|
||||
+ FRAME_SCROLL_BAR_AREA_WIDTH (f)
|
||||
+ 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
|
||||
|
||||
pixelheight = ((((pixelwise ? height : (height * FRAME_LINE_HEIGHT (f)))
|
||||
/ unit_height) * unit_height)
|
||||
+ 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
|
||||
}
|
||||
|
||||
f->win_gravity = NorthWestGravity;
|
||||
|
|
|
|||
42
src/xdisp.c
42
src/xdisp.c
|
|
@ -16400,12 +16400,50 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
|
|||
/* Consider the following case: Window starts at BEGV, there is
|
||||
invisible, intangible text at BEGV, so that display starts at
|
||||
some point START > BEGV. It can happen that we are called with
|
||||
PT somewhere between BEGV and START. Try to handle that case. */
|
||||
PT somewhere between BEGV and START. Try to handle that case,
|
||||
and similar ones. */
|
||||
if (w->cursor.vpos < 0)
|
||||
{
|
||||
struct glyph_row *row = w->current_matrix->rows;
|
||||
/* First, try locating the proper glyph row for PT. */
|
||||
struct glyph_row *row =
|
||||
row_containing_pos (w, PT, w->current_matrix->rows, NULL, 0);
|
||||
|
||||
/* Sometimes point is at the beginning of invisible text that is
|
||||
before the 1st character displayed in the row. In that case,
|
||||
row_containing_pos fails to find the row, because no glyphs
|
||||
with appropriate buffer positions are present in the row.
|
||||
Therefore, we next try to find the row which shows the 1st
|
||||
position after the invisible text. */
|
||||
if (!row)
|
||||
{
|
||||
Lisp_Object val =
|
||||
get_char_property_and_overlay (make_number (PT), Qinvisible,
|
||||
Qnil, NULL);
|
||||
|
||||
if (TEXT_PROP_MEANS_INVISIBLE (val))
|
||||
{
|
||||
ptrdiff_t alt_pos;
|
||||
Lisp_Object invis_end =
|
||||
Fnext_single_char_property_change (make_number (PT), Qinvisible,
|
||||
Qnil, Qnil);
|
||||
|
||||
if (NATNUMP (invis_end))
|
||||
alt_pos = XFASTINT (invis_end);
|
||||
else
|
||||
alt_pos = ZV;
|
||||
row = row_containing_pos (w, alt_pos, w->current_matrix->rows,
|
||||
NULL, 0);
|
||||
}
|
||||
}
|
||||
/* Finally, fall back on the first row of the window after the
|
||||
header line (if any). This is slightly better than not
|
||||
displaying the cursor at all. */
|
||||
if (!row)
|
||||
{
|
||||
row = w->current_matrix->rows;
|
||||
if (row->mode_line_p)
|
||||
++row;
|
||||
}
|
||||
set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,11 @@
|
|||
2014-03-26 Barry O'Reilly <gundaetiapo@gmail.com>
|
||||
|
||||
* automated/undo-tests.el (undo-test-marker-adjustment-nominal):
|
||||
(undo-test-region-t-marker): New tests of marker adjustments.
|
||||
(undo-test-marker-adjustment-moved):
|
||||
(undo-test-region-mark-adjustment): New tests to demonstrate
|
||||
bug#16818, which fail without the fix.
|
||||
|
||||
2014-03-23 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
* automated/package-test.el (package-test-describe-package):
|
||||
|
|
|
|||
|
|
@ -268,6 +268,104 @@
|
|||
(should (string= (buffer-string)
|
||||
"This sentence corrupted?aaa"))))
|
||||
|
||||
(ert-deftest undo-test-marker-adjustment-nominal ()
|
||||
"Test nominal behavior of marker adjustments."
|
||||
(with-temp-buffer
|
||||
(buffer-enable-undo)
|
||||
(insert "abcdefg")
|
||||
(undo-boundary)
|
||||
(let ((m (make-marker)))
|
||||
(set-marker m 2 (current-buffer))
|
||||
(goto-char (point-min))
|
||||
(delete-forward-char 3)
|
||||
(undo-boundary)
|
||||
(should (= (point-min) (marker-position m)))
|
||||
(undo)
|
||||
(undo-boundary)
|
||||
(should (= 2 (marker-position m))))))
|
||||
|
||||
(ert-deftest undo-test-region-t-marker ()
|
||||
"Test undo in region containing marker with t insertion-type."
|
||||
(with-temp-buffer
|
||||
(buffer-enable-undo)
|
||||
(transient-mark-mode 1)
|
||||
(insert "abcdefg")
|
||||
(undo-boundary)
|
||||
(let ((m (make-marker)))
|
||||
(set-marker-insertion-type m t)
|
||||
(set-marker m (point-min) (current-buffer)) ; m at a
|
||||
(goto-char (+ 2 (point-min)))
|
||||
(push-mark (point) t t)
|
||||
(setq mark-active t)
|
||||
(goto-char (point-min))
|
||||
(delete-forward-char 1) ;; delete region covering "ab"
|
||||
(undo-boundary)
|
||||
(should (= (point-min) (marker-position m)))
|
||||
;; Resurrect "ab". m's insertion type means the reinsertion
|
||||
;; moves it forward 2, and then the marker adjustment returns it
|
||||
;; to its rightful place.
|
||||
(undo)
|
||||
(undo-boundary)
|
||||
(should (= (point-min) (marker-position m))))))
|
||||
|
||||
(ert-deftest undo-test-marker-adjustment-moved ()
|
||||
"Test marker adjustment behavior when the marker moves.
|
||||
Demonstrates bug 16818."
|
||||
(with-temp-buffer
|
||||
(buffer-enable-undo)
|
||||
(insert "abcdefghijk")
|
||||
(undo-boundary)
|
||||
(let ((m (make-marker)))
|
||||
(set-marker m 2 (current-buffer)) ; m at b
|
||||
(goto-char (point-min))
|
||||
(delete-forward-char 3) ; m at d
|
||||
(undo-boundary)
|
||||
(set-marker m 4) ; m at g
|
||||
(undo)
|
||||
(undo-boundary)
|
||||
;; m still at g, but shifted 3 because deletion undone
|
||||
(should (= 7 (marker-position m))))))
|
||||
|
||||
(ert-deftest undo-test-region-mark-adjustment ()
|
||||
"Test that the mark's marker adjustment in undo history doesn't
|
||||
obstruct undo in region from finding the correct change group.
|
||||
Demonstrates bug 16818."
|
||||
(with-temp-buffer
|
||||
(buffer-enable-undo)
|
||||
(transient-mark-mode 1)
|
||||
(insert "First line\n")
|
||||
(insert "Second line\n")
|
||||
(undo-boundary)
|
||||
|
||||
(goto-char (point-min))
|
||||
(insert "aaa")
|
||||
(undo-boundary)
|
||||
|
||||
(undo)
|
||||
(undo-boundary)
|
||||
|
||||
(goto-char (point-max))
|
||||
(insert "bbb")
|
||||
(undo-boundary)
|
||||
|
||||
(push-mark (point) t t)
|
||||
(setq mark-active t)
|
||||
(goto-char (- (point) 3))
|
||||
(delete-forward-char 1)
|
||||
(undo-boundary)
|
||||
|
||||
(insert "bbb")
|
||||
(undo-boundary)
|
||||
|
||||
(goto-char (point-min))
|
||||
(push-mark (point) t t)
|
||||
(setq mark-active t)
|
||||
(goto-char (+ (point) 3))
|
||||
(undo)
|
||||
(undo-boundary)
|
||||
|
||||
(should (string= (buffer-string) "aaaFirst line\nSecond line\nbbb"))))
|
||||
|
||||
(defun undo-test-all (&optional interactive)
|
||||
"Run all tests for \\[undo]."
|
||||
(interactive "p")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue