Merge branch 'master' into scratch/org-mode-merge

This commit is contained in:
Bastien 2017-07-03 09:06:29 +02:00
commit 5ca1888fe6
113 changed files with 4936 additions and 2031 deletions

View file

@ -40,7 +40,7 @@ GNULIB_MODULES='
sig2str socklen stat-time std-gnu11 stdalign stddef stdio
stpcpy strftime strtoimax symlink sys_stat
sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub
update-copyright utimens
update-copyright unlocked-io utimens
vla warnings
'

View file

@ -1346,50 +1346,56 @@ Property value is a symbol `o' (Open), `c' (Close), or `n' (None)."
(generator (unidata-prop-generator proplist))
(default-value (unidata-prop-default proplist))
(val-list (unidata-prop-val-list proplist))
(table (progn
(message "Generating %S table..." prop)
(funcall generator prop index default-value val-list)))
(decoder (char-table-extra-slot table 1))
(alist (and (functionp index)
(funcall index)))
(check #x400))
(dolist (e unidata-list)
(let* ((char (car e))
(val1
(if alist (nth 1 (assoc char alist))
(nth index e)))
val2)
(if (and (stringp val1) (= (length val1) 0))
(setq val1 nil))
(unless (or (consp char)
(integerp decoder))
(setq val2
(cond ((functionp decoder)
(funcall decoder char (aref table char) table))
(t ; must be nil
(aref table char))))
(if val1
(cond ((eq generator 'unidata-gen-table-symbol)
(setq val1 (intern val1)))
((eq generator 'unidata-gen-table-integer)
(setq val1 (string-to-number val1)))
((eq generator 'unidata-gen-table-character)
(setq val1 (string-to-number val1 16)))
((eq generator 'unidata-gen-table-decomposition)
(setq val1 (unidata-split-decomposition val1))))
(cond ((eq prop 'decomposition)
(setq val1 (list char)))
((eq prop 'bracket-type)
(setq val1 'n))))
(when (>= char check)
(message "%S %04X" prop check)
(setq check (+ check #x400)))
(or (equal val1 val2)
;; <control> characters get a 'name' property of nil
(and (eq prop 'name) (string= val1 "<control>") (null val2))
(insert (format "> %04X %S\n< %04X %S\n"
char val1 char val2)))
(sit-for 0))))))))
(check #x400)
table decoder alist)
;; We compare values in unidata.txt with the ones returned by various
;; generator functions. However, SpecialCasing.txt is read directly by
;; unidata-gen-table-special-casing--do-load and there is no other file
;; to compare those values with. This is why were skipping the check
;; for special casing properties.
(unless (eq generator 'unidata-gen-table-special-casing)
(setq table (progn
(message "Generating %S table..." prop)
(funcall generator prop index default-value val-list))
decoder (char-table-extra-slot table 1))
(unless (integerp decoder)
(setq alist (and (functionp index) (funcall index)))
(dolist (e unidata-list)
(let ((char (car e)) val1 val2)
(unless (consp char)
(setq val1 (if alist
(nth 1 (assoc char alist))
(nth index e)))
(and (stringp val1)
(= (length val1) 0)
(setq val1 nil))
(if val1
(cond ((eq generator 'unidata-gen-table-symbol)
(setq val1 (intern val1)))
((eq generator 'unidata-gen-table-integer)
(setq val1 (string-to-number val1)))
((eq generator 'unidata-gen-table-character)
(setq val1 (string-to-number val1 16)))
((eq generator 'unidata-gen-table-decomposition)
(setq val1 (unidata-split-decomposition val1))))
(cond ((eq prop 'decomposition)
(setq val1 (list char)))
((eq prop 'bracket-type)
(setq val1 'n))))
(setq val2 (aref table char))
(when decoder
(setq val2 (funcall decoder char val2 table)))
(when (>= char check)
(message "%S %04X" prop check)
(setq check (+ check #x400)))
(or (equal val1 val2)
;; <control> characters get a 'name' property of nil
(and (eq prop 'name)
(string= val1 "<control>")
(null val2))
(insert (format "> %04X %S\n< %04X %S\n"
char val1 char val2)))
(sit-for 0))))))))))
;; The entry functions. They generate files described in the header
;; comment of this file.

View file

@ -4240,7 +4240,7 @@ AC_CHECK_HEADERS(valgrind/valgrind.h)
AC_CHECK_MEMBERS([struct unipair.unicode], [], [], [[#include <linux/kd.h>]])
AC_CHECK_FUNCS_ONCE([getc_unlocked sbrk])
AC_CHECK_FUNCS_ONCE([sbrk])
ok_so_far=yes
AC_CHECK_FUNC(socket, , ok_so_far=no)

View file

@ -875,25 +875,31 @@ treat it specially.
@item
Otherwise, if the command string contains @samp{?} surrounded by
whitespace, Emacs runs the shell command once @emph{for each file},
substituting the current file name for @samp{?} each time. You can
use @samp{?} more than once in the command; the same file name
replaces each occurrence.
whitespace or @samp{`?`}, Emacs runs the shell command once
@emph{for each file}, substituting the current file name for @samp{?}
and @samp{`?`} each time. You can use both @samp{?} or @samp{`?`} more
than once in the command; the same file name replaces each occurrence.
If you mix them with @samp{*} the command signals an error.
@item
If the command string contains neither @samp{*} nor @samp{?}, Emacs
runs the shell command once for each file, adding the file name at the
If the command string contains neither @samp{*} nor @samp{?} nor @samp{`?`},
Emacs runs the shell command once for each file, adding the file name at the
end. For example, @kbd{! uudecode @key{RET}} runs @code{uudecode} on
each file.
@end itemize
To iterate over the file names in a more complicated fashion, use an
explicit shell loop. For example, here is how to uuencode each file,
making the output file name by appending @samp{.uu} to the input file
name:
To iterate over the file names in a more complicated fashion, you might
prefer to use an explicit shell loop. For example, here is how to uuencode
each file, making the output file name by appending @samp{.uu} to the input
file name:
@example
for file in * ; do uuencode "$file" "$file" >"$file".uu; done
@end example
The same example with @samp{`?`} notation:
@example
uuencode ? ? > `?`.uu
@end example
The @kbd{!} and @kbd{&} commands do not attempt to update the Dired

View file

@ -203,9 +203,10 @@ string}, which describes exactly what the command does.
describes the command corresponding to @var{key}.
@kbd{C-h c}, @kbd{C-h k} and @kbd{C-h K} work for any sort of key
sequences, including function keys, menus, and mouse events. For
instance, after @kbd{C-h k} you can select a menu item from the menu
bar, to view the documentation string of the command it runs.
sequences, including function keys, menus, and mouse events (except
that @kbd{C-h c} ignores mouse movement events). For instance, after
@kbd{C-h k} you can select a menu item from the menu bar, to view the
documentation string of the command it runs.
@kindex C-h w
@findex where-is

View file

@ -519,6 +519,10 @@ when exiting Emacs; if you wish to prevent Emacs from transferring
data to the clipboard manager, change the variable
@code{x-select-enable-clipboard-manager} to @code{nil}.
Since strings containing NUL bytes are usually truncated when passed
through the clipboard, Emacs replaces such characters with ``\0''
before transfering them to the system's clipboard.
@vindex select-enable-primary
@findex clipboard-kill-region
@findex clipboard-kill-ring-save

View file

@ -1795,8 +1795,12 @@ of the first character you read precedes that of the next character.
Reordering of bidirectional text into the @dfn{visual} order happens
at display time. As result, character positions no longer increase
monotonically with their positions on display. Emacs implements the
Unicode Bidirectional Algorithm described in the Unicode Standard
Annex #9, for reordering of bidirectional text for display.
Unicode Bidirectional Algorithm (UBA) described in the Unicode
Standard Annex #9, for reordering of bidirectional text for display.
It deviates from the UBA only in how continuation lines are displayed
when text direction is opposite to the base paragraph direction,
e.g. when a long line of English text appears in a right-to-left
paragraph.
@vindex bidi-display-reordering
The buffer-local variable @code{bidi-display-reordering} controls

View file

@ -1974,6 +1974,71 @@ line, if present, in the return value. If it is @code{t}, include the
height of both, if present, in the return value.
@end defun
@code{window-text-pixel-size} treats the text displayed in a window as a
whole and does not care about the size of individual lines. The
following function does.
@defun window-lines-pixel-dimensions &optional window first last body inverse
This function calculates the pixel dimensions of each line displayed in
the specified @var{window}. It does so by walking @var{window}'s
current glyph matrix---a matrix storing the glyph (@pxref{Glyphs}) of
each buffer character currently displayed in @var{window}. If
successful, it returns a list of cons pairs representing the x- and
y-coordinates of the lower right corner of the last character of each
line. Coordinates are measured in pixels from an origin (0, 0) at the
top-left corner of @var{window}. @var{window} must be a live window and
defaults to the selected one.
If the optional argument @var{first} is an integer, it denotes the index
(starting with 0) of the first line of @var{window}'s glyph matrix to be
returned. Note that if @var{window} has a header line, the line with
index 0 is that header line. If @var{first} is nil, the first line to
be considered is determined by the value of the optional argument
@var{body}: If @var{body} is non-@code{nil}, this means to start with
the first line of @var{window}'s body, skipping any header line, if
present. Otherwise, this function will start with the first line of
@var{window}'s glyph matrix, possibly the header line.
If the optional argument @var{last} is an integer, it denotes the index
of the last line of @var{window}'s glyph matrix that shall be returned.
If @var{last} is nil, the last line to be considered is determined by
the value of @var{body}: If @var{body} is non-@code{nil}, this means to
use the last line of @var{window}'s body, omitting @var{window}'s mode
line, if present. Otherwise, this means to use the last line of
@var{window} which may be the mode line.
The optional argument @var{inverse}, if @code{nil}, means that the
y-pixel value returned for any line specifies the distance in pixels
from the left edge (body edge if @var{body} is non-@code{nil}) of
@var{window} to the right edge of the last glyph of that line.
@var{inverse} non-@code{nil} means that the y-pixel value returned for
any line specifies the distance in pixels from the right edge of the
last glyph of that line to the right edge (body edge if @var{body} is
non-@code{nil}) of @var{window}. This is useful for determining the
amount of slack space at the end of each line.
The optional argument @var{left}, if non-@code{nil} means to return the
x- and y-coordinates of the lower left corner of the leftmost character
on each line. This is the value that should be used for windows that
mostly display text from right to left.
If @var{left} is non-@code{nil} and @var{inverse} is @code{nil}, this
means that the y-pixel value returned for any line specifies the
distance in pixels from the left edge of the last (leftmost) glyph of
that line to the right edge (body edge if @var{body} is non-@code{nil})
of @var{window}. If @var{left} and @var{inverse} are both
non-@code{nil}, the y-pixel value returned for any line specifies the
distance in pixels from the left edge (body edge if @var{body} is
non-@code{nil}) of @var{window} to the left edge of the last (leftmost)
glyph of that line.
This function returns @code{nil} if the current glyph matrix of
@var{window} is not up-to-date which usually happens when Emacs is busy,
for example, when processing a command. The value should be retrievable
though when this function is run from an idle timer with a delay of zero
seconds.
@end defun
@defun line-pixel-height
This function returns the height in pixels of the line at point in the
selected window. The value includes the line spacing of the line
@ -7297,7 +7362,11 @@ follows the Unicode Bidirectional Algorithm (a.k.a.@: @acronym{UBA}),
which is described in Annex #9 of the Unicode standard
(@url{http://www.unicode.org/reports/tr9/}). Emacs provides a ``Full
Bidirectionality'' class implementation of the @acronym{UBA},
consistent with the requirements of the Unicode Standard v8.0.
consistent with the requirements of the Unicode Standard v9.0. Note,
however, that the way Emacs displays continuation lines when text
direction is opposite to the base paragraph direction deviates from
the UBA, which requires to perform line wrapping before reordering
text for display.
@defvar bidi-display-reordering
If the value of this buffer-local variable is non-@code{nil} (the

View file

@ -1130,6 +1130,8 @@ Window Frame Parameters
* Buffer Parameters:: Which buffers have been or should be shown.
* Frame Interaction Parameters:: Parameters for interacting with other
frames.
* Mouse Dragging Parameters:: Parameters for resizing and moving
frames with the mouse.
* Management Parameters:: Communicating with the window manager.
* Cursor Parameters:: Controlling the cursor appearance.
* Font and Color Parameters:: Fonts and colors for the frame text.

View file

@ -974,14 +974,7 @@ Parameters}). The text size of the initial frame can be also set with
the help of an X-style geometry specification. @xref{Emacs Invocation,,
Command Line Arguments for Emacs Invocation, emacs, The GNU Emacs
Manual}. Below we list some functions to access and set the size of an
existing, visible frame.
@defun frame-text-height &optional frame
@defunx frame-text-width &optional frame
These functions return the height and width of the text area of
@var{frame} (@pxref{Frame Layout}), measured in pixels. For a text
terminal, the results are in characters rather than pixels.
@end defun
existing, visible frame, by default the selected one.
@defun frame-height &optional frame
@defunx frame-width &optional frame
@ -997,11 +990,33 @@ rounded down to the number of characters of the default font that fully
fit into the text area.
@end defun
@defun frame-pixel-height &optional frame
@defunx frame-pixel-width &optional frame
These functions return the native width and height, see @ref{Frame
Layout}) of @var{frame} in pixels. For a text terminal, the results are
in characters rather than pixels.
The functions following next return the pixel widths and heights of the
native, outer and inner frame and the text area (@pxref{Frame Layout})
of a given frame. For a text terminal, the results are in characters
rather than pixels.
@defun frame-outer-width &optional frame
@defunx frame-outer-height &optional frame
These functions return the outer width and height of @var{frame} in
pixels.
@end defun
@defun frame-native-height &optional frame
@defunx frame-native-width &optional frame
These functions return the native width and height of @var{frame} in
pixels.
@end defun
@defun frame-inner-width &optional frame
@defunx frame-inner-height &optional frame
These functions return the inner width and height of @var{frame} in
pixels.
@end defun
@defun frame-text-width &optional frame
@defunx frame-text-height &optional frame
These functions return the width and height of the text area of
@var{frame} in pixels.
@end defun
On window systems that support it, Emacs tries by default to make the
@ -1345,6 +1360,8 @@ text terminals.
* Buffer Parameters:: Which buffers have been or should be shown.
* Frame Interaction Parameters:: Parameters for interacting with other
frames.
* Mouse Dragging Parameters:: Parameters for resizing and moving
frames with the mouse.
* Management Parameters:: Communicating with the window manager.
* Cursor Parameters:: Controlling the cursor appearance.
* Font and Color Parameters:: Fonts and colors for the frame text.
@ -1404,18 +1421,19 @@ named, this parameter will be @code{nil}.
@cindex frame position
Parameters describing the X- and Y-offsets of a frame are always
measured in pixels. For normal, non-child frames they specify the
frame's absolute outer position (@pxref{Frame Geometry}) with respect to
its display's origin. For a child frame (@pxref{Child Frames}) they
specify the frame's outer position relative to the native position of
the frame's parent frame. (Note that none of these parameters is
meaningful on TTY frames.)
measured in pixels. For a normal, non-child frame they specify the
frame's outer position (@pxref{Frame Geometry}) relative to its
display's origin. For a child frame (@pxref{Child Frames}) they specify
the frame's outer position relative to the native position of the
frame's parent frame. (Note that none of these parameters is meaningful
on TTY frames.)
@table @code
@vindex left, a frame parameter
@item left
The position, in pixels, of the left outer edge of the frame with
respect to the left edge of the frame's display or parent frame.
respect to the left edge of the frame's display or parent frame. It can
be specified in one of the following ways.
@table @asis
@item an integer
@ -1436,6 +1454,30 @@ right edge of the display or parent frame. The integer @var{pos} may be
positive or negative; a negative value specifies a position outside the
screen or parent frame or on a monitor other than the primary one (for
multi-monitor displays).
@cindex left position ratio
@cindex top position ratio
@item a floating-point value
A floating-point value in the range 0.0 to 1.0 specifies the left edge's
offset via the @dfn{left position ratio} of the frame---the ratio of the
left edge of its outer frame to the width of the frame's workarea
(@pxref{Multiple Terminals}) or its parent's native frame (@pxref{Child
Frames}) minus the width of the outer frame. Thus, a left position
ratio of 0.0 flushes a frame to the left, a ratio of 0.5 centers it and
a ratio of 1.0 flushes it to the right of its display or parent frame.
Similarly, the @dfn{top position ratio} of a frame is the ratio of the
frame's top position to the height of its workarea or parent frame minus
the height of the frame.
Emacs will try to keep the position ratios of a child frame unaltered if
that frame has a non-@code{nil} @code{keep-ratio} parameter
(@pxref{Frame Interaction Parameters}) and its parent frame is resized.
Since the outer size of a frame (@pxref{Frame Geometry}) is usually
unavailable before a frame has been made visible, it is generally not
advisable to use floating-point values when creating decorated frames.
Floating-point values are more suited for ensuring that an (undecorated)
child frame is positioned nicely within the area of its parent frame.
@end table
Some window managers ignore program-specified positions. If you want to
@ -1448,17 +1490,19 @@ following example:
nil '((user-position . t) (left . (+ -4))))
@end example
In general, it is not a good idea to specify negative offsets to
position a frame relative to the right or bottom edge of its display.
Positioning the initial or a new frame is either not accurate (because
the size of the outer frame is not yet fully known before the frame has
been made visible) or will cause additional flicker (if the frame is
repositioned after becoming visible).
In general, it is not a good idea to position a frame relative to the
right or bottom edge of its display. Positioning the initial or a new
frame is either not accurate (because the size of the outer frame is not
yet fully known before the frame has been made visible) or will cause
additional flicker (if the frame has to be repositioned after becoming
visible).
Note also, that negative offsets are not stored internally and are not
returned by the function @code{frame-parameters}. This means that the
desktop saving routines will restore the frame from the positive offsets
obtained by that function.
Note also, that positions specified relative to the right/bottom edge
of a display, workarea or parent frame as well as floating-point offsets
are stored internally as integer offsets relative to the left/top edge
of the display, workarea or parent frame edge. They are also returned
as such by functions like @code{frame-parameters} and restored as such
by the desktop saving routines.
@vindex top, a frame parameter
@item top
@ -1523,24 +1567,61 @@ function @code{frame-restack} (@pxref{Raising and Lowering}).
@subsubsection Size Parameters
@cindex window size on display
Frame parameters specify frame sizes in character units. On
graphical displays, the @code{default} face determines the actual
pixel sizes of these character units (@pxref{Face Attributes}).
Frame parameters usually specify frame sizes in character units. On
graphical displays, the @code{default} face determines the actual pixel
sizes of these character units (@pxref{Face Attributes}).
@table @code
@vindex width, a frame parameter
@item width
The width of the frame's text area (@pxref{Frame Geometry}), in
characters. The value can be also a cons cell of the symbol
@code{text-pixels} and an integer denoting the width of the text area in
pixels.
This parameter specifies the width of the frame. It can be specified as
in the following ways:
@table @asis
@item an integer
A positive integer specifies the width of the frame's text area
(@pxref{Frame Geometry}) in characters.
@item a cons cell
If this is a cons cell with the symbol @code{text-pixels} in its
@sc{car}, the @sc{cdr} of that cell specifies the width of the frame's
text area in pixels.
@cindex frame width ratio
@cindex frame height ratio
@item a floating-point value
A floating-point number between 0.0 and 1.0 can be used to specify the
width of a frame via its @dfn{width ratio}---the ratio of its outer
width (@pxref{Frame Geometry}) to the width of the frame's workarea
(@pxref{Multiple Terminals}) or its parent frame's (@pxref{Child
Frames}) native frame. Thus, a value of 0.5 makes the frame occupy half
of the width of its workarea or parent frame, a value of 1.0 the full
width. Similarly, the @dfn{height ratio} of a frame is the ratio of its
outer height to the height of its workarea or its parent's native frame.
Emacs will try to keep the width and height ratio of a child frame
unaltered if that frame has a non-@code{nil} @code{keep-ratio} parameter
(@pxref{Frame Interaction Parameters}) and its parent frame is resized.
Since the outer size of a frame is usually unavailable before a frame
has been made visible, it is generally not advisable to use
floating-point values when creating decorated frames. Floating-point
values are more suited to ensure that a child frame always fits within
the area of its parent frame as, for example, when customizing
@code{display-buffer-alist} (@pxref{Choosing Window}) via
@code{display-buffer-in-child-frame}.
@end table
Regardless of how this parameter was specified, functions reporting the
value of this parameter like @code{frame-parameters} always report the
width of the frame's text area in characters as an integer rounded, if
necessary, to a multiple of the frame's default character width. That
value is also used by the desktop saving routines.
@vindex height, a frame parameter
@item height
The height of the frame's text area (@pxref{Frame Geometry}), in
characters. The value can be also a cons cell of the symbol
@code{text-pixels} and an integer denoting the height of the text area
in pixels.
This parameter specifies the height of the frame. It works just like
@code{width}, except vertically instead of horizontally.
@vindex user-size, a frame parameter
@item user-size
@ -1551,25 +1632,25 @@ user-position}) does for the position parameters @code{top} and
@vindex min-width, a frame parameter
@item min-width
This parameter specifies the minimum native width of the frame
(@pxref{Frame Geometry}), in characters. Normally, the functions that
This parameter specifies the minimum native width (@pxref{Frame
Geometry}) of the frame, in characters. Normally, the functions that
establish a frame's initial width or resize a frame horizontally make
sure that all the frame's windows, vertical scroll bars, fringes,
margins and vertical dividers can be displayed. This parameter, if
non-@code{nil} allows to make a frame narrower than that with the
consequence that any components that do not fit on the frame will be
clipped by the window manager.
consequence that any components that do not fit will be clipped by the
window manager.
@vindex min-height, a frame parameter
@item min-height
This parameter specifies the minimum height of the native (@pxref{Frame
Geometry}), in characters. Normally, the functions that establish a
frame's initial size or resize a frame make sure that all the frame's
windows, horizontal scroll bars and dividers, mode and header lines, the
echo area and the internal menu and tool bar can be displayed. This
parameter, if non-@code{nil} allows to make a frame smaller than that
with the consequence that any components that do not fit on the frame
will be clipped by the window-system or window manager.
This parameter specifies the minimum native height (@pxref{Frame
Geometry}) of the frame, in characters. Normally, the functions that
establish a frame's initial size or resize a frame make sure that all
the frame's windows, horizontal scroll bars and dividers, mode and
header lines, the echo area and the internal menu and tool bar can be
displayed. This parameter, if non-@code{nil} allows to make a frame
smaller than that with the consequence that any components that do not
fit will be clipped by the window manager.
@cindex fullboth frames
@cindex fullheight frames
@ -1623,6 +1704,20 @@ file as, for example
This will give a new frame full height after typing in it @key{F11} for
the first time.
@vindex fit-frame-to-buffer-margins, a frame parameter
@item fit-frame-to-buffer-margins
This parameter allows to override the value of the option
@code{fit-frame-to-buffer-margins} when fitting this frame to the buffer
of its root window with @code{fit-frame-to-buffer} (@pxref{Resizing
Windows}).
@vindex fit-frame-to-buffer-sizes, a frame parameter
@item fit-frame-to-buffer-sizes
This parameter allows to override the value of the option
@code{fit-frame-to-buffer-sizes} when fitting this frame to the buffer
of its root window with @code{fit-frame-to-buffer} (@pxref{Resizing
Windows}).
@end table
@ -1646,9 +1741,9 @@ Geometry}).
@vindex vertical-scroll-bars, a frame parameter
@item vertical-scroll-bars
Whether the frame has scroll bars for vertical scrolling, and which side
of the frame they should be on. The possible values are @code{left},
@code{right}, and @code{nil} for no scroll bars.
Whether the frame has scroll bars (@pxref{Scroll Bars}) for vertical
scrolling, and which side of the frame they should be on. The possible
values are @code{left}, @code{right}, and @code{nil} for no scroll bars.
@vindex horizontal-scroll-bars, a frame parameter
@item horizontal-scroll-bars
@ -1692,30 +1787,40 @@ to not draw bottom dividers.
@vindex menu-bar-lines frame parameter
@item menu-bar-lines
The number of lines to allocate at the top of the frame for a menu bar.
The default is one if Menu Bar mode is enabled and zero otherwise.
@xref{Menu Bars,,,emacs, The GNU Emacs Manual}. For an external menu
bar, this value remains unchanged even when the menu bar wraps to two or
more lines. In that case, the @code{menu-bar-size} value returned by
@code{frame-geometry} (@pxref{Frame Geometry}) allows to derive whether
the menu bar actually occupies one or more lines.
The number of lines to allocate at the top of the frame for a menu bar
(@pxref{Menu Bar}). The default is one if Menu Bar mode is enabled and
zero otherwise. @xref{Menu Bars,,,emacs, The GNU Emacs Manual}. For an
external menu bar (@pxref{Frame Layout}), this value remains unchanged
even when the menu bar wraps to two or more lines. In that case, the
@code{menu-bar-size} value returned by @code{frame-geometry}
(@pxref{Frame Geometry}) allows to derive whether the menu bar actually
occupies one or more lines.
@vindex tool-bar-lines frame parameter
@item tool-bar-lines
The number of lines to use for the tool bar. The default is one if Tool
Bar mode is enabled and zero otherwise. @xref{Tool Bars,,,emacs, The
GNU Emacs Manual}. This value may change whenever the tool bar wraps.
The number of lines to use for the tool bar (@pxref{Tool Bar}). The
default is one if Tool Bar mode is enabled and zero otherwise.
@xref{Tool Bars,,,emacs, The GNU Emacs Manual}. This value may change
whenever the tool bar wraps (@pxref{Frame Layout}).
@vindex tool-bar-position frame parameter
@item tool-bar-position
The position of the tool bar. Currently only for the GTK tool bar.
Value can be one of @code{top}, @code{bottom} @code{left}, @code{right}.
The default is @code{top}.
The position of the tool bar when Emacs was built with GTK+. Its value
can be one of @code{top}, @code{bottom} @code{left}, @code{right}. The
default is @code{top}.
@vindex line-spacing, a frame parameter
@item line-spacing
Additional space to leave below each text line, in pixels (a positive
integer). @xref{Line Height}, for more information.
@vindex no-special-glyphs, a frame parameter
@item no-special-glyphs
If this is non-@code{nil}, it suppresses the display of any truncation
and continuation glyphs (@pxref{Truncation}) for all buffers displayed
by this frame. This is useful to eliminate such glyphs when fitting a
frame to its buffer via @code{fit-frame-to-buffer} (@pxref{Resizing
Windows}).
@end table
@ -1781,15 +1886,115 @@ Frames}.
@item mouse-wheel-frame
If non-@code{nil}, this parameter specifies the frame whose windows will
be scrolled whenever the mouse wheel is scrolled with the mouse pointer
hovering over this frame (@pxref{Mouse Commands,,, emacs, The GNU Emacs
Manual}).
hovering over this frame, see @ref{Mouse Commands,,, emacs, The GNU
Emacs Manual}.
@vindex no-other-frame, a frame parameter
@item no-other-frame
If this is non-@code{nil}, then this frame is not eligible as candidate
for the functions @code{next-frame}, @code{previous-frame}
(@pxref{Finding All Frames}) and @code{other-frame} (@pxref{Frame
Commands,,, emacs, The GNU Emacs Manual}).
(@pxref{Finding All Frames}) and @code{other-frame}, see @ref{Frame
Commands,,, emacs, The GNU Emacs Manual}.
@vindex auto-hide-function, a frame parameter
@item auto-hide-function
When this parameter specifies a function, that function will be called
instead of the function specified by the variable
@code{frame-auto-hide-function} when quitting the frame's only window
(@pxref{Quitting Windows}) and there are other frames left.
@vindex minibuffer-exit, a frame parameter
@item minibuffer-exit
When this parameter is non-@code{nil}, Emacs will by default make this
frame invisible whenever the minibuffer (@pxref{Minibuffers}) is exited.
Alternatively, it can specify the functions @code{iconify-frame} and
@code{delete-frame}. This parameter is useful to make a child frame
disappear automatically (similar to how Emacs deals with a window) when
exiting the minibuffer.
@vindex keep-ratio, a frame parameter
@item keep-ratio
This parameter is currently meaningful for child frames (@pxref{Child
Frames}) only. If it is non-@code{nil}, then Emacs will try to keep the
frame's size (width and height) ratios (@pxref{Size Parameters}) as well
as its left and right position ratios (@pxref{Position Parameters})
unaltered whenever its parent frame is resized.
If the value of this parameter is @code{nil}, the frame's position and
size remain unaltered when the parent frame is resized, so the position
and size ratios may change. If the value of this parameter is @code{t},
Emacs will try to preserve the frame's size and position ratios, hence
the frame's size and position relative to its parent frame may change.
More individual control is possible by using a cons cell: In that case
the frame's width ratio is preserved if the @sc{car} of the cell is
either @code{t} or @code{width-only}. The height ratio is preserved if
the @sc{car} of the cell is either @code{t} or @code{height-only}. The
left position ratio is preserved if the @sc{cdr} of the cell is either
@code{t} or @code{left-only}. The top position ratio is preserved if
the @sc{cdr} of the cell is either @code{t} or @code{top-only}.
@end table
@node Mouse Dragging Parameters
@subsubsection Mouse Dragging Parameters
@cindex mouse dragging parameters
@cindex parameters for resizing frames with the mouse
@cindex parameters for moving frames with the mouse
The parameters described below provide support for resizing a frame by
dragging its internal borders with the mouse. They also allow moving a
frame with the mouse by dragging the header line of its topmost or the
mode line of its bottommost window.
These parameters are mostly useful for child frames (@pxref{Child
Frames}) that come without window manager decorations. If necessary,
they can be used for undecorated top-level frames as well.
@table @code
@vindex drag-internal-border, a frame parameter
@item drag-internal-border
If non-@code{nil}, the frame can be resized by dragging its internal
borders, if present, with the mouse.
@vindex drag-with-header-line, a frame parameter
@item drag-with-header-line
If non-@code{nil}, the frame can be moved with the mouse by dragging the
header line of its topmost window.
@vindex drag-with-mode-line, a frame parameter
@item drag-with-mode-line
If non-@code{nil}, the frame can be moved with the mouse by dragging the
mode line of its bottommost window. Note that such a frame is not
allowed to have its own minibuffer window.
@vindex snap-width, a frame parameter
@item snap-width
A frame that is moved with the mouse will ``snap'' at the border(s) of
the display or its parent frame whenever it is dragged as near to such
an edge as the number of pixels specified by this parameter.
@vindex top-visible, a frame parameter
@item top-visible
If this parameter is a number, the top edge of the frame never appears
above the top edge of its display or parent frame. Moreover, as many
pixels of the frame as specified by that number will remain visible when
the frame is moved against any of the remaining edges of its display or
parent frame. Setting this parameter is useful to guard against
dragging a child frame with a non-@code{nil}
@code{drag-with-header-line} parameter completely out of the area
of its parent frame.
@vindex bottom-visible, a frame parameter
@item bottom-visible
If this parameter is a number, the bottom edge of the frame never
appears below the bottom edge of its display or parent frame. Moreover,
as many pixels of the frame as specified by that number will remain
visible when the frame is moved against any of the remaining edges of
its display or parent frame. Setting this parameter is useful to guard
against dragging a child frame with a non-@code{nil}
@code{drag-with-mode-line} parameter completely out of the area of
its parent frame.
@end table
@ -1797,9 +2002,9 @@ Commands,,, emacs, The GNU Emacs Manual}).
@subsubsection Window Management Parameters
@cindex window manager interaction, and frame parameters
The following frame parameters control various aspects of the
frame's interaction with the window manager. They have no effect on
text terminals.
The following frame parameters control various aspects of the frame's
interaction with the window manager or window system. They have no
effect on text terminals.
@table @code
@vindex visibility, a frame parameter
@ -1908,7 +2113,8 @@ If non-@code{nil}, this means that this is an @dfn{override redirect}
frame---a frame not handled by window managers under X. Override
redirect frames have no window manager decorations, can be positioned
and resized only via Emacs' positioning and resizing functions and are
usually drawn on top of all other frames.
usually drawn on top of all other frames. Setting this parameter has
no effect on MS-Windows.
@ignore
@vindex parent-id, a frame parameter
@ -2080,6 +2286,9 @@ The @code{alpha} frame parameter can also be a cons cell
@code{(@var{active} . @var{inactive})}, where @var{active} is the
opacity of the frame when it is selected, and @var{inactive} is the
opacity when it is not selected.
Some window systems do not support the @code{alpha} parameter for child
frames (@pxref{Child Frames}).
@end table
The following frame parameters are semi-obsolete in that they are
@ -2824,57 +3033,78 @@ unwanted frames are iconified instead.
@cindex child frames
@cindex parent frames
On some window-systems the @code{parent-frame} parameter (@pxref{Frame
Interaction Parameters}) can be used to make a frame a child of the
frame specified by that parameter. The frame specified by that
parameter will then be the frame's parent frame as long as the parameter
is not changed or reset. Technically, this makes the child frame's
window-system window a child window of the parent frame's window-system
window.
Child frames are objects halfway between windows (@pxref{Windows}) and
``normal'' frames. Like windows, they are attached to an owning frame.
Unlike windows, they may overlap each other---changing the size or
position of one child frame does not change the size or position of any
of its sibling child frames.
By design, operations to make or modify child frames are implemented
with the help of frame parameters (@pxref{Frame Parameters}) without any
specialized functions or customizable variables. Note that child frames
are meaningful on graphical terminals only.
To create a new child frame or to convert a normal frame into a child
frame, set that frame's @code{parent-frame} parameter (@pxref{Frame
Interaction Parameters}) to that of an already existing frame. The
frame specified by that parameter will then be the frame's parent frame
as long as the parameter is not changed or reset. Technically, this
makes the child frame's window-system window a child window of the
parent frame's window-system window.
@cindex top-level frame
@cindex reparent frame
@cindex nest frame
The @code{parent-frame} parameter can be changed at any time. Setting
it to another frame ``reparents'' the child frame. Setting it to
another child frame makes the frame a ``nested'' child frame. Setting
it to @code{nil} restores the frame's status as a top-level frame---one
whose window-system window is a child of its display's root window.
it to another frame @dfn{reparents} the child frame. Setting it to
another child frame makes the frame a @dfn{nested} child frame. Setting
it to @code{nil} restores the frame's status as a @dfn{top-level
frame}---a frame whose window-system window is a child of its display's
root window.
Since child frames can be arbitrarily nested, a frame can be both a
child and a parent frame. Also, the relative roles of child and parent
frame may be reversed at any time (though it's usually a good idea to
keep the size of child frames sufficiently smaller than that of their
keep the size of a child frame sufficiently smaller than that of its
parent). An error will be signaled for the attempt to make a frame an
ancestor of itself.
A child frame is clipped at the native edges (@pxref{Frame Geometry})
of its parent frame---everything outside these edges is invisible. Its
@code{left} and @code{top} parameters specify positions relative to the
top-left corner of its parent's native frame. When either of the frames
is resized, the relative position of the child frame remains unaltered.
Hence, resizing either of these frames can hide or reveal parts of the
child frame.
Most window-systems clip a child frame at the native edges
(@pxref{Frame Geometry}) of its parent frame---everything outside these
edges is usually invisible. A child frame's @code{left} and @code{top}
parameters specify a position relative to the top-left corner of its
parent's native frame. When the parent frame is resized, this position
remains conceptually unaltered.
NS builds do not clip child frames at the parent frame's edges,
allowing them to be positioned so they do not obscure the parent
frame while still being visible themselves.
allowing them to be positioned so they do not obscure the parent frame
while still being visible themselves.
Usually, moving a parent frame moves along all its child frames and
their descendants as well, keeping their relative positions unaltered.
The hook @code{move-frame-functions} (@pxref{Frame Position}) is run for
a child frame only when the position of the child frame relative to its
parent frame changes. When a parent frame is resized, the child frame
retains its position respective to the left and upper native edges of
its parent. In this case, the position respective to the lower or right
native edge of the parent frame is usually lost.
Note that the hook @code{move-frame-functions} (@pxref{Frame Position})
is run for a child frame only when the position of the child frame
relative to its parent frame changes. It is not run for a child frame
when the position of the parent frame changes.
When a parent frame is resized, its child frames conceptually retain
their previous sizes and their positions relative to the left upper
corner of the parent. This means that a child frame may become
(partially) invisible when its parent frame shrinks. The parameter
@code{keep-ratio} (@pxref{Frame Interaction Parameters}) can be used to
resize and reposition a child frame proportionally whenever its parent
frame is resized. This may avoid obscuring parts of a frame when its
parent frame is shrunk.
A visible child frame always appears on top of its parent frame thus
obscuring parts of it, except on NS builds where it may be positioned
beneath the parent. This is comparable to the window-system window of
a top-level frame which also always appears on top of its parent
window---the desktop's root window. When a parent frame is iconified
or made invisible (@pxref{Visibility of Frames}), its child frames are
made invisible. When a parent frame is deiconified or made visible,
its child frames are made visible. When a parent frame is about to be
deleted, (@pxref{Deleting Frames}) its child frames are recursively
beneath the parent. This is comparable to the window-system window of a
top-level frame which also always appears on top of its parent
window---the desktop's root window. When a parent frame is iconified or
made invisible (@pxref{Visibility of Frames}), its child frames are made
invisible. When a parent frame is deiconified or made visible, its
child frames are made visible. When a parent frame is about to be
deleted (@pxref{Deleting Frames}), its child frames are recursively
deleted before it.
Whether a child frame can have a menu or tool bar is window-system or
@ -2892,7 +3122,55 @@ outer border can be used. On MS-Windows, specifying a non-zero outer
border width will show a one-pixel wide external border. Under all
window-systems, the internal border can be used. In either case, it's
advisable to disable a child frame's window manager decorations with the
@code{undecorated} frame parameter @pxref{Management Parameters}).
@code{undecorated} frame parameter (@pxref{Management Parameters}).
To resize or move an undecorated child frame with the mouse, special
frame parameters (@pxref{Mouse Dragging Parameters}) have to be used.
The internal border of a child frame, if present, can be used to resize
the frame with the mouse, provided that frame has a non-@code{nil}
@code{drag-internal-border} parameter. If set, the @code{snap-width}
parameter indicates the number of pixels where the frame @dfn{snaps} at
the respective edge or corner of its parent frame.
There are two ways to drag an entire child frame with the mouse: The
@code{drag-with-mode-line} parameter, if non-@code{nil}, allows to drag
a frame without minibuffer window (@pxref{Minibuffer Windows}) via the
mode line area of its bottommost window. The
@code{drag-with-header-line} parameter, if non-@code{nil}, allows to
drag the frame via the header line area of its topmost window.
In order to give a child frame a draggable header or mode line, the
window parameters @code{mode-line-format} and @code{header-line-format}
are handy (@pxref{Window Parameters}). These allow to remove an
unwanted mode line (when @code{drag-with-header-line} is chosen) and to
remove mouse-sensitive areas which might interfere with frame dragging.
To avoid that dragging moves a frame completely out of its parent's
native frame, something which might happen when the mouse cursor
overshoots and makes the frame difficult to retrieve once the mouse
button has been released, it is advisable to set the frame's
@code{top-visible} or @code{bottom-visible} parameter correspondingly.
The @code{top-visible} parameter specifies the number of pixels at the
top of the frame that always remain visible within the parent's native
frame during dragging and should be set when specifying a non-@code{nil}
@code{drag-with-header-line} parameter. The @code{bottom-visible}
parameter specifies the number of pixels at the bottom of the frame that
always remain visible within the parent's native frame during dragging
and should be preferred when specifying a non-@code{nil}
@code{drag-with-mode-line} parameter.
When a child frame is used for displaying a buffer via
@code{display-buffer-in-child-frame} (@pxref{Display Action Functions}),
the frame's @code{auto-hide-function} parameter (@pxref{Frame
Interaction Parameters}) can be set to a function, in order to
appropriately deal with the frame when the window displaying the buffer
shall be quit.
When a child frame is used during minibuffer interaction, for example,
to display completions in a separate window, the @code{minibuffer-exit}
parameter (@pxref{Frame Interaction Parameters}) is useful in order to
deal with the frame when the minibuffer is exited.
The behavior of child frames deviates from that of top-level frames in
a number of other ways as well. Here we sketch a few of them:
@ -2930,7 +3208,7 @@ work on all window-systems. Some will drop the object on the parent
frame or on some ancestor instead.
@end itemize
The following two functions may be useful when working with child and
The following two functions can be useful when working with child and
parent frames:
@defun frame-parent &optional frame
@ -2951,6 +3229,12 @@ of @var{descendant}'s parent frame. Both, @var{ancestor} and
frame.
@end defun
Note also the function @code{window-largest-empty-rectangle}
(@pxref{Coordinates and Windows}) which can be used to inscribe a child
frame in the largest empty area of an existing window. This can be
useful to avoid that a child frame obscures any text shown in that
window.
@node Mouse Tracking
@section Mouse Tracking

View file

@ -1737,7 +1737,9 @@ holds a @dfn{mode line construct}: a template that controls what is
displayed on the buffer's mode line. The value of
@code{header-line-format} specifies the buffer's header line in the same
way. All windows for the same buffer use the same
@code{mode-line-format} and @code{header-line-format}.
@code{mode-line-format} and @code{header-line-format} unless a
@code{mode-line-format} or @code{header-line-format} parameter has been
specified for that window (@pxref{Window Parameters}).
For efficiency, Emacs does not continuously recompute each window's
mode line and header line. It does so when circumstances appear to call

View file

@ -283,11 +283,11 @@ character @kbd{a}.
?Q @result{} 81 ?q @result{} 113
@end example
You can use the same syntax for punctuation characters, but it is
often a good idea to add a @samp{\} so that the Emacs commands for
editing Lisp code don't get confused. For example, @samp{?\(} is the
way to write the open-paren character. If the character is @samp{\},
you @emph{must} use a second @samp{\} to quote it: @samp{?\\}.
You can use the same syntax for punctuation characters. However, if
the punctuation character has a special syntactic meaning in Lisp, you
must quote it with a @samp{\}. For example, @samp{?\(} is the way to
write the open-paren character. Likewise, if the character is
@samp{\}, you must use a second @samp{\} to quote it: @samp{?\\}.
@cindex whitespace
@cindex bell character
@ -336,18 +336,19 @@ escape character; this has nothing to do with the
character @key{ESC}. @samp{\s} is meant for use in character
constants; in string constants, just write the space.
A backslash is allowed, and harmless, preceding any character without
a special escape meaning; thus, @samp{?\+} is equivalent to @samp{?+}.
There is no reason to add a backslash before most characters. However,
you should add a backslash before any of the characters
@samp{()\|;'`"#.,} to avoid confusing the Emacs commands for editing
Lisp code. You can also add a backslash before whitespace characters such as
space, tab, newline and formfeed. However, it is cleaner to use one of
the easily readable escape sequences, such as @samp{\t} or @samp{\s},
instead of an actual whitespace character such as a tab or a space.
(If you do write backslash followed by a space, you should write
an extra space after the character constant to separate it from the
following text.)
A backslash is allowed, and harmless, preceding any character
without a special escape meaning; thus, @samp{?\+} is equivalent to
@samp{?+}. There is no reason to add a backslash before most
characters. However, you must add a backslash before any of the
characters @samp{()[]\;"}, and you should add a backslash before any
of the characters @samp{|'`#.,} to avoid confusing the Emacs commands
for editing Lisp code. You can also add a backslash before whitespace
characters such as space, tab, newline and formfeed. However, it is
cleaner to use one of the easily readable escape sequences, such as
@samp{\t} or @samp{\s}, instead of an actual whitespace character such
as a tab or a space. (If you do write backslash followed by a space,
you should write an extra space after the character constant to
separate it from the following text.)
@node General Escape Syntax
@subsubsection General Escape Syntax

View file

@ -752,6 +752,7 @@ The optional argument @var{pixelwise} non-@code{nil} means to return the
minimum size of @var{window} counted in pixels.
@end defun
@node Resizing Windows
@section Resizing Windows
@cindex window resizing
@ -943,7 +944,8 @@ help of the two options listed next.
@defopt fit-frame-to-buffer-margins
This option can be used to specify margins around frames to be fit by
@code{fit-frame-to-buffer}. Such margins can be useful to avoid, for
example, that such frames overlap the taskbar.
example, that the resized frame overlaps the taskbar or parts of its
parent frame.
It specifies the numbers of pixels to be left free on the left, above,
the right, and below a frame that shall be fit. The default specifies
@ -2484,6 +2486,25 @@ the function specified in @code{pop-up-frame-function}
is added to the newly created frame's parameters.
@end defun
@defun display-buffer-in-child-frame buffer alist
This function tries to display @var{buffer} in a child frame
(@pxref{Child Frames}) of the selected frame, either reusing an existing
child frame or by making a new one. If @var{alist} has a non-@code{nil}
@code{child-frame-parameters} entry, the corresponding value is an alist
of frame parameters to give the new frame. A @code{parent-frame}
parameter specifying the selected frame is provided by default. If the
child frame should be or become the child of another frame, a
corresponding entry must be added to @var{alist}.
The appearance of child frames is largely dependent on the parameters
provided via @var{alist}. It is advisable to use at least ratios to
specify the size (@pxref{Size Parameters}) and the position
(@pxref{Position Parameters}) of the child frame and to add the
@code{keep-ratio} in order to make sure that the child frame remains
visible. For other parameters that should be considered see @ref{Child
Frames}.
@end defun
@defun display-buffer-use-some-frame buffer alist
This function tries to display @var{buffer} by trying to find a
frame that meets a predicate (by default any frame other than the
@ -3124,12 +3145,17 @@ killed.
The default is to call @code{iconify-frame} (@pxref{Visibility of
Frames}). Alternatively, you may specify either @code{delete-frame}
(@pxref{Deleting Frames}) to remove the frame from its display,
@code{ignore} to leave the frame unchanged, or any other function that
can take a frame as its sole argument.
@code{make-frame-invisible} to make the frame invisible, @code{ignore}
to leave the frame unchanged, or any other function that can take a
frame as its sole argument.
Note that the function specified by this option is called only if the
specified frame contains just one live window and there is at least one
other frame on the same terminal.
For a particular frame, the value specified here may be overridden by
that frame's @code{auto-hide-function} frame parameter (@pxref{Frame
Interaction Parameters}).
@end defopt
@ -4364,13 +4390,12 @@ is off the screen due to horizontal scrolling:
@cindex coordinate, relative to frame
@cindex window position
This section describes functions that report the position of a window.
Most of these functions report positions relative to an origin at the
native position of the window's frame (@pxref{Frame Geometry}). Some
functions report positions relative to the origin of the display of the
window's frame. In any case, the origin has the coordinates (0, 0) and
X and Y coordinates increase rightward and downward
respectively.
This section describes functions that report positions of and within a
window. Most of these functions report positions relative to an origin
at the native position of the window's frame (@pxref{Frame Geometry}).
Some functions report positions relative to the origin of the display of
the window's frame. In any case, the origin has the coordinates (0, 0)
and X and Y coordinates increase rightward and downward respectively.
For the following functions, X and Y coordinates are reported in
integer character units, i.e., numbers of lines and columns
@ -4608,6 +4633,49 @@ point in the selected window, it's sufficient to write:
@end example
@end defun
The following function returns the largest rectangle that can be
inscribed in a window without covering text displayed in that window.
@defun window-largest-empty-rectangle &optional window count min-width min-height positions left
This function calculates the dimensions of the largest empty rectangle
that can be inscribed in the specified @var{window}'s text area.
@var{window} must be a live window and defaults to the selected one.
The return value is a triple of the width and the start and end
y-coordinates of the largest rectangle that can be inscribed into the
empty space (space not displaying any text) of the text area of
@var{window}. No x-coordinates are returned by this function---any such
rectangle is assumed to end at the right edge of @var{window}'s text
area. If no empty space can be found, the return value is @code{nil}.
The optional argument @var{count}, if non-@code{nil}, specifies a
maximum number of rectangles to return. This means that the return
value is a list of triples specifying rectangles with the largest
rectangle first. @var{count} can be also a cons cell whose car
specifies the number of rectangles to return and whose @sc{cdr}, if
non-@code{nil}, states that all rectangles returned must be disjoint.
The optional arguments @var{min-width} and @var{min-height}, if
non-@code{nil}, specify the minimum width and height of any rectangle
returned.
The optional argument @var{positions}, if non-@code{nil}, is a cons cell
whose @sc{car} specifies the uppermost and whose @sc{cdr} specifies the
lowermost pixel position that must be covered by any rectangle returned.
These positions measure from the start of the text area of @var{window}.
The optional argument @var{left}, if non-@code{nil}, means to return
values suitable for buffers displaying right to left text. In that
case, any rectangle returned is assumed to start at the left edge of
@var{window}'s text area.
Note that this function has to retrieve the dimensions of each line of
@var{window}'s glyph matrix via @code{window-lines-pixel-dimensions}
(@pxref{Size of Displayed Text}). Hence, this function may also return
@code{nil} when the current glyph matrix of @var{window} is not
up-to-date.
@end defun
@node Mouse Window Auto-selection
@section Mouse Window Auto-selection
@ -4911,37 +4979,45 @@ windows when exiting that function.
The following parameters are currently used by the window management
code:
@table @asis
@item @code{delete-window}
@table @code
@item delete-window
@vindex delete-window, a window parameter
This parameter affects the execution of @code{delete-window}
(@pxref{Deleting Windows}).
@item @code{delete-other-windows}
@item delete-other-windows
@vindex delete-other-windows, a window parameter
This parameter affects the execution of @code{delete-other-windows}
(@pxref{Deleting Windows}).
@item @code{no-delete-other-window}
@item no-delete-other-window
@vindex no-delete-other-window, a window parameter
This parameter marks the window as not deletable by
@code{delete-other-windows} (@pxref{Deleting Windows}).
@item @code{split-window}
@item split-window
@vindex split-window, a window parameter
This parameter affects the execution of @code{split-window}
(@pxref{Splitting Windows}).
@item @code{other-window}
@item other-window
@vindex other-window, a window parameter
This parameter affects the execution of @code{other-window}
(@pxref{Cyclic Window Ordering}).
@item @code{no-other-window}
@item no-other-window
@vindex no-other-window, a window parameter
This parameter marks the window as not selectable by @code{other-window}
(@pxref{Cyclic Window Ordering}).
@item @code{clone-of}
@item clone-of
@vindex clone-of, a window parameter
This parameter specifies the window that this one has been cloned
from. It is installed by @code{window-state-get} (@pxref{Window
Configurations}).
@item @code{preserved-size}
@item preserved-size
@vindex preserved-size, a window parameter
This parameter specifies a buffer, a direction where @code{nil} means
vertical and @code{t} horizontal, and a size in pixels. If this window
displays the specified buffer and its size in the indicated direction
@ -4950,7 +5026,8 @@ preserve the size of this window in the indicated direction. This
parameter is installed and updated by the function
@code{window-preserve-size} (@pxref{Preserving Window Sizes}).
@item @code{quit-restore}
@item quit-restore
@vindex quit-restore, a window parameter
This parameter is installed by the buffer display functions
(@pxref{Choosing Window}) and consulted by @code{quit-restore-window}
(@pxref{Quitting Windows}). It contains four elements:
@ -4981,15 +5058,37 @@ only if it still shows that buffer.
See the description of @code{quit-restore-window} in @ref{Quitting
Windows} for details.
@item @code{window-side} @code{window-slot}
@item window-side window-slot
@vindex window-side, a window parameter
@vindex window-slot, a window parameter
These parameters are used for implementing side windows (@pxref{Side
Windows}).
@item @code{window-atom}
@item window-atom
@vindex window-atom, a window parameter
This parameter is used for implementing atomic windows, see @ref{Atomic
Windows}.
@item @code{min-margins}
@item mode-line-format
@vindex mode-line-format, a window parameter
This parameter replaces the value of the buffer-local variable
@code{mode-line-format} (@pxref{Mode Line Basics}) of this window's
buffer whenever this window is displayed. The symbol @code{none} means
to suppress display of a mode line for this window. Display and
contents of the mode line on other windows showing this buffer are not
affected.
@item header-line-format
@vindex header-line-format, a window parameter
This parameter replaces the value of the buffer-local variable
@code{header-line-format} (@pxref{Mode Line Basics}) of this window's
buffer whenever this window is displayed. The symbol @code{none} means
to suppress display of a header line for this window. Display and
contents of the header line on other windows showing this buffer are not
affected.
@item min-margins
@vindex min-margins, a window parameter
The value of this parameter is a cons cell whose @sc{car} and @sc{cdr},
if non-@code{nil}, specify the minimum values (in columns) for the left
and right margin of this window. When present, Emacs will use these

View file

@ -405,7 +405,7 @@ variable will cause @samp{text/html} parts to be treated as attachments.
@item mm-text-html-renderer
@vindex mm-text-html-renderer
This selects the function used to render @acronym{HTML}. The predefined
renderers are selected by the symbols @code{gnus-article-html},
renderers are selected by the symbols @code{shr}, @code{gnus-w3m},
@code{w3m}@footnote{See @uref{http://emacs-w3m.namazu.org/} for more
information about emacs-w3m}, @code{links}, @code{lynx},
@code{w3m-standalone} or @code{html2text}. If @code{nil} use an

View file

@ -72,21 +72,21 @@ local and the remote host, whereas @value{tramp} uses a combination of
@command{ssh}/@command{scp}.
You can find the latest version of this document on the web at
@uref{http://www.gnu.org/software/tramp/}.
@uref{https://www.gnu.org/software/tramp/}.
@ifhtml
The latest release of @value{tramp} is available for
@uref{ftp://ftp.gnu.org/gnu/tramp/, download}, or you may see
@uref{https://ftp.gnu.org/gnu/tramp/, download}, or you may see
@ref{Obtaining Tramp} for more details, including the Git server
details.
@value{tramp} also has a @uref{http://savannah.gnu.org/projects/tramp/,
@value{tramp} also has a @uref{https://savannah.gnu.org/projects/tramp/,
Savannah Project Page}.
@end ifhtml
There is a mailing list for @value{tramp}, available at
@email{tramp-devel@@gnu.org}, and archived at
@uref{http://lists.gnu.org/archive/html/tramp-devel/, the
@uref{https://lists.gnu.org/archive/html/tramp-devel/, the
@value{tramp} Mail Archive}.
@page
@ -321,7 +321,7 @@ behind the scenes when you open a file with @value{tramp}.
@value{tramp} is included as part of Emacs (since Emacs version 22.1).
@value{tramp} is also freely packaged for download on the Internet at
@uref{ftp://ftp.gnu.org/gnu/tramp/}.
@uref{https://ftp.gnu.org/gnu/tramp/}.
@value{tramp} development versions are available on Git servers.
Development versions contain new and incomplete features.
@ -331,7 +331,7 @@ page at the following URL and then clicking on the Git link in the
navigation bar at the top.
@noindent
@uref{http://savannah.gnu.org/projects/tramp/}
@uref{https://savannah.gnu.org/projects/tramp/}
@noindent
Another way is to follow the terminal session below:
@ -349,7 +349,7 @@ From behind a firewall:
@example
@group
] @strong{git config --global http.proxy http://user:pwd@@proxy.server.com:8080}
] @strong{git clone http://git.savannah.gnu.org/r/tramp.git}
] @strong{git clone https://git.savannah.gnu.org/r/tramp.git}
@end group
@end example
@ -917,7 +917,7 @@ numbers are not applicable to Android devices connected through USB@.
@cindex dbus
GVFS is the virtual file system for the Gnome Desktop,
@uref{http://en.wikipedia.org/wiki/GVFS}. Remote files on GVFS are
@uref{https://en.wikipedia.org/wiki/GVFS}. Remote files on GVFS are
mounted locally through FUSE and @value{tramp} uses this locally
mounted directory internally.
@ -1896,12 +1896,16 @@ where @samp{192.168.0.1} is the remote host IP address
@value{tramp} uses the @option{adb} method to access Android devices.
Android devices provide a restricted shell access through an USB
connection. The local host must have the @command{adb} program
installed.
installed. Usually, it is sufficient to open the file
@file{@trampfn{adb,,/}}. Then you can navigate in the filesystem via
@code{dired}.
Applications such as @code{SSHDroid} that run @command{sshd} process
on the Android device can accept any @option{ssh}-based methods
provided these settings are adjusted:
Alternatively, applications such as @code{SSHDroid} that run
@command{sshd} process on the Android device can accept any
@option{ssh}-based methods provided these settings are adjusted:
@itemize
@item
@command{sh} must be specified for remote shell since Android devices
do not provide @command{/bin/sh}. @command{sh} will then invoke
whatever shell is installed on the device with this setting:
@ -1917,6 +1921,7 @@ whatever shell is installed on the device with this setting:
where @samp{192.168.0.26} is the Android device's IP address.
(@pxref{Predefined connection information}).
@item
@value{tramp} requires preserving @env{PATH} environment variable from
user settings. Android devices prefer @file{/system/xbin} path over
@file{/system/bin}. Both of these are set as follows:
@ -1928,7 +1933,7 @@ user settings. Android devices prefer @file{/system/xbin} path over
@end group
@end lisp
@noindent
@item
When the Android device is not @samp{rooted}, specify a writable
directory for temporary files:
@ -1936,7 +1941,7 @@ directory for temporary files:
(add-to-list 'tramp-remote-process-environment "TMPDIR=$HOME")
@end lisp
@noindent
@item
Open a remote connection with the command @kbd{C-x C-f
@trampfn{ssh,192.168.0.26#2222,}}, where @command{sshd} is listening
on port @samp{2222}.
@ -1967,6 +1972,7 @@ the previous example, fix the connection properties as follows:
@noindent
Open a remote connection with a more concise command @kbd{C-x C-f
@trampfn{ssh,android,}}.
@end itemize
@node Auto-save and Backup
@ -2083,7 +2089,7 @@ Pseudo-terminal will not be allocated because stdin is not a terminal.
Some older versions of Cygwin's @command{ssh} work with the
@option{sshx} access method. Consult Cygwin's FAQ at
@uref{http://cygwin.com/faq/} for details.
@uref{https://cygwin.com/faq/} for details.
@cindex Cygwin and fakecygpty
@cindex fakecygpty and Cygwin
@ -2797,7 +2803,7 @@ this address go to all the subscribers. This is @emph{not} the
address to send subscription requests to.
To subscribe to the mailing list, visit:
@uref{http://lists.gnu.org/mailman/listinfo/tramp-devel/, the
@uref{https://lists.gnu.org/mailman/listinfo/tramp-devel/, the
@value{tramp} Mail Subscription Page}.
@ifset installchapter
@ -2849,13 +2855,13 @@ Where is the latest @value{tramp}?
@value{tramp} is available at the GNU URL:
@noindent
@uref{ftp://ftp.gnu.org/gnu/tramp/}
@uref{https://ftp.gnu.org/gnu/tramp/}
@noindent
@value{tramp}'s GNU project page is located here:
@noindent
@uref{http://savannah.gnu.org/projects/tramp/}
@uref{https://savannah.gnu.org/projects/tramp/}
@item

View file

@ -8,7 +8,7 @@
@c In the Tramp GIT, the version number is auto-frobbed from
@c configure.ac, so you should edit that file and run
@c "autoconf && ./configure" to change the version number.
@set trampver 2.3.2-pre
@set trampver 2.3.2
@c Other flags from configuration
@set instprefix /usr/local

View file

@ -129,6 +129,22 @@ given file is on a case-insensitive filesystem.
of curved quotes for 'electric-quote-mode', allowing user to choose
the types of quotes to be used.
** The new user option 'electric-quote-context-sensitive' makes
'electric-quote-mode' context sensitive. If it is non-nil, you can
type an ASCII apostrophe to insert an opening or closing quote,
depending on context. Emacs will replace the apostrophe by an opening
quote character at the beginning of the buffer, the beginning of a
line, after a whitespace character, and after an opening parenthesis;
and it will replace the apostrophe by a closing quote character in all
other cases.
** The new variable 'electric-quote-code-faces' controls when to
disable electric quoting in text modes. Major modes can add faces to
this list; Emacs will temporarily disable 'electric-quote-mode'
whenever point is before a character having such a face. This is
intended for major modes that derive from 'text-mode' but allow inline
code segments, such as 'markdown-mode'.
+++
** The new user variable 'dired-omit-case-fold' allows the user to
customize the case-sensitivity of dired-omit-mode. It defaults to
@ -320,6 +336,15 @@ questions, with a handy way to display help texts.
all call stack frames in a Lisp backtrace buffer as lists. Both
debug.el and edebug.el have been updated to heed to this variable.
---
** Values in call stack frames are now displayed using 'cl-prin1'.
The old behaviour of using 'prin1' can be restored by customizing the
new option 'debugger-print-function'.
+++
** NUL bytes in strings copied to the system clipboard are now
replaced with "\0".
+++
** The new variable 'x-ctrl-keysym' has been added to the existing
roster of X keysyms. It can be used in combination with another
@ -363,6 +388,9 @@ environment variable on a remote machine to emacsclient, and
use the local Emacs to edit remote files via Tramp. See the node
"emacsclient Options" in the user manual for the details.
+++
** 'describe-key-briefly' now ignores mouse movement events.
+++
** The new variable 'eval-expression-print-maximum-character' prevents
large integers from being displayed as characters.
@ -471,6 +499,12 @@ properties as intact as possible.
* Changes in Specialized Modes and Packages in Emacs 26.1
** Dired
You can now use '`?`' in 'dired-do-shell-command'; as ' ? ', it gets replaced
by the current file name.
*** html2text is now marked obsolete.
*** smerge-refine-regions can refine regions in separate buffers
*** Info menu and index completion uses substring completion by default.
@ -642,6 +676,13 @@ replaced by the real images asynchronously, which will also now
respect width/height HTML specs (unless they specify widths/heights
bigger than the current window).
---
*** The 'w' command on links is now 'shr-maybe-probe-and-copy-url'.
'shr-copy-url' now only copies the url at point; users who wish to
avoid accidentally accessing remote links may rebind 'w' and 'u' in
'eww-link-keymap' to it.
** Ido
*** The commands 'find-alternate-file-other-window',
@ -1203,7 +1244,7 @@ run.
frame's outer border.
+++
*** New frame parameters
*** New frame parameters and changed semantics for older ones
+++
**** 'z-group' positions a frame above or below all others.
@ -1248,10 +1289,32 @@ focus via the mouse.
frame.
+++
*** The 'width' and 'height' frame parameters allow to specify pixel
values now.
**** 'width' and 'height' allow to specify pixel values and ratios now.
+++
**** 'left' and 'top' allow to specify ratios now.
+++
**** 'keep-ratio' preserves size and position of child frames when their
parent frame is resized.
+++
**** 'no-special-glyphs' suppresses display of truncation and
continuation glyphs in a frame.
+++
**** 'auto-hide-function' and 'minibuffer-exit' handle auto hiding of
frames and exiting from minibuffer individually.
+++
**** 'fit-frame-to-buffer-margins' and 'fit-frame-to-buffer-sizes'
handle fitting a frame to its buffer individually.
+++
**** 'drag-internal-border', 'drag-with-header-line',
'drag-with-mode-line', 'snap-width', 'top-visible' and 'bottom-visible'
allow to drag and resize frames with the mouse.
*** The new function 'frame-list-z-order' returns a list of all frames
in Z (stacking) order.
@ -1309,6 +1372,10 @@ a new window when opening man pages when there's already one, use
*** New window parameter 'no-delete-other-window' prevents that
its window gets deleted by 'delete-other-windows'.
+++
*** New window parameters 'mode-line-format' and 'header-line-format'
allow to override the buffer-local formats for this window.
+++
*** New command 'window-swap-states' swaps the states of two live
windows.
@ -1318,10 +1385,24 @@ windows.
'window-pixel-height-before-size-change' support detecting which
window changed size when 'window-size-change-functions' are run.
+++
*** The new function 'window-lines-pixel-dimensions' returns the pixel
dimensions of a window's text lines.
+++
*** The new function 'window-largest-empty-rectangle' returns the
dimensions of the largest rectangular area not occupying any text in a
window's body.
+++
*** The semantics of 'mouse-autoselect-window' has changed slightly.
For details see the section "Mouse Window Auto-selection" in the Elisp
manual.
---
** 'tcl-auto-fill-mode' is now declared obsolete. It's functionality
can be replicated simply by setting 'comment-auto-fill-only-comments'.
* Changes in Emacs 26.1 on Non-Free Operating Systems
@ -1364,7 +1445,7 @@ This is in contrast to the default action on POSIX Systems, where it
causes the receiving process to terminate with a core dump if no
debugger has been attached to it.
** `set-mouse-position' and `set-mouse-absolute-pixel-position' work
** 'set-mouse-position' and 'set-mouse-absolute-pixel-position' work
on macOS.

View file

@ -20,21 +20,21 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <getopt.h>
#include <flexmember.h>
#include <min-max.h>
#include <unlocked-io.h>
/* The SunOS compiler doesn't have SEEK_END. */
#ifndef SEEK_END
#define SEEK_END 2
#endif
#include <flexmember.h>
#include <min-max.h>
/* Files are read in chunks of this number of bytes. */
enum { READ_CHUNK_SIZE = 100 * 1024 };

View file

@ -73,7 +73,6 @@ char *w32_getenv (const char *);
#include <stdarg.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
@ -84,6 +83,8 @@ char *w32_getenv (const char *);
#include <signal.h>
#include <errno.h>
#include <unlocked-io.h>
#ifndef VERSION
#define VERSION "unspecified"
#endif

View file

@ -123,6 +123,7 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4";
#include <errno.h>
#include <fcntl.h>
#include <binary-io.h>
#include <unlocked-io.h>
#include <c-ctype.h>
#include <c-strcase.h>

View file

@ -22,11 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <binary-io.h>
#include <unlocked-io.h>
static char *progname;

View file

@ -39,10 +39,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <binary-io.h>
#include <intprops.h>
#include <min-max.h>
#include <unlocked-io.h>
#ifdef WINDOWSNT
/* Defined to be sys_fopen in ms-w32.h, but only #ifdef emacs, so this
is really just insurance. */
@ -50,10 +54,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <direct.h>
#endif /* WINDOWSNT */
#include <binary-io.h>
#include <intprops.h>
#include <min-max.h>
#ifdef DOS_NT
/* Defined to be sys_chdir in ms-w32.h, but only #ifdef emacs, so this
is really just insurance.

View file

@ -59,7 +59,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
@ -69,6 +68,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <unlocked-io.h>
#include "syswait.h"
#ifdef MAIL_USE_POP
#include "pop.h"

View file

@ -34,11 +34,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <intprops.h>
#include <systime.h>
#include <unlocked-io.h>
static struct timespec TV1;
static int watch_not_started = 1; /* flag */

View file

@ -39,7 +39,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <pwd.h>
#include <ctype.h>
@ -47,6 +46,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <sys/stat.h>
#include <getopt.h>
#include <unlocked-io.h>
#ifdef WINDOWSNT
#include "ntlib.h"
#endif

View file

@ -21,7 +21,7 @@
# the same distribution terms as the rest of that program.
#
# Generated by gnulib-tool.
# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stat --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=tzset --avoid=unsetenv --avoid=utime --avoid=utime-h --gnu-make --makefile-name=gnulib.mk.in --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-leading-zeros count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 diffseq dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode filevercmp flexmember fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog ignore-value intprops largefile lstat manywarnings memrchr minmax mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time std-gnu11 stdalign stddef stdio stpcpy strftime strtoimax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub update-copyright utimens vla warnings
# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stat --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=tzset --avoid=unsetenv --avoid=utime --avoid=utime-h --gnu-make --makefile-name=gnulib.mk.in --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-leading-zeros count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 diffseq dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode filevercmp flexmember fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog ignore-value intprops largefile lstat manywarnings memrchr minmax mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time std-gnu11 stdalign stddef stdio stpcpy strftime strtoimax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub unlocked-io update-copyright utimens vla warnings
MOSTLYCLEANFILES += core *.stackdump
@ -2996,6 +2996,15 @@ EXTRA_DIST += unistd.in.h
endif
## end gnulib module unistd
## begin gnulib module unlocked-io
ifeq (,$(OMIT_GNULIB_MODULE_unlocked-io))
EXTRA_DIST += unlocked-io.h
endif
## end gnulib module unlocked-io
## begin gnulib module update-copyright
ifeq (,$(OMIT_GNULIB_MODULE_update-copyright))

136
lib/unlocked-io.h Normal file
View file

@ -0,0 +1,136 @@
/* Prefer faster, non-thread-safe stdio functions if available.
Copyright (C) 2001-2004, 2009-2017 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by Jim Meyering. */
#ifndef UNLOCKED_IO_H
# define UNLOCKED_IO_H 1
/* These are wrappers for functions/macros from the GNU C library, and
from other C libraries supporting POSIX's optional thread-safe functions.
The standard I/O functions are thread-safe. These *_unlocked ones are
more efficient but not thread-safe. That they're not thread-safe is
fine since all of the applications in this package are single threaded.
Also, some code that is shared with the GNU C library may invoke
the *_unlocked functions directly. On hosts that lack those
functions, invoke the non-thread-safe versions instead. */
# include <stdio.h>
# if HAVE_DECL_CLEARERR_UNLOCKED
# undef clearerr
# define clearerr(x) clearerr_unlocked (x)
# else
# define clearerr_unlocked(x) clearerr (x)
# endif
# if HAVE_DECL_FEOF_UNLOCKED
# undef feof
# define feof(x) feof_unlocked (x)
# else
# define feof_unlocked(x) feof (x)
# endif
# if HAVE_DECL_FERROR_UNLOCKED
# undef ferror
# define ferror(x) ferror_unlocked (x)
# else
# define ferror_unlocked(x) ferror (x)
# endif
# if HAVE_DECL_FFLUSH_UNLOCKED
# undef fflush
# define fflush(x) fflush_unlocked (x)
# else
# define fflush_unlocked(x) fflush (x)
# endif
# if HAVE_DECL_FGETS_UNLOCKED
# undef fgets
# define fgets(x,y,z) fgets_unlocked (x,y,z)
# else
# define fgets_unlocked(x,y,z) fgets (x,y,z)
# endif
# if HAVE_DECL_FPUTC_UNLOCKED
# undef fputc
# define fputc(x,y) fputc_unlocked (x,y)
# else
# define fputc_unlocked(x,y) fputc (x,y)
# endif
# if HAVE_DECL_FPUTS_UNLOCKED
# undef fputs
# define fputs(x,y) fputs_unlocked (x,y)
# else
# define fputs_unlocked(x,y) fputs (x,y)
# endif
# if HAVE_DECL_FREAD_UNLOCKED
# undef fread
# define fread(w,x,y,z) fread_unlocked (w,x,y,z)
# else
# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
# endif
# if HAVE_DECL_FWRITE_UNLOCKED
# undef fwrite
# define fwrite(w,x,y,z) fwrite_unlocked (w,x,y,z)
# else
# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
# endif
# if HAVE_DECL_GETC_UNLOCKED
# undef getc
# define getc(x) getc_unlocked (x)
# else
# define getc_unlocked(x) getc (x)
# endif
# if HAVE_DECL_GETCHAR_UNLOCKED
# undef getchar
# define getchar() getchar_unlocked ()
# else
# define getchar_unlocked() getchar ()
# endif
# if HAVE_DECL_PUTC_UNLOCKED
# undef putc
# define putc(x,y) putc_unlocked (x,y)
# else
# define putc_unlocked(x,y) putc (x,y)
# endif
# if HAVE_DECL_PUTCHAR_UNLOCKED
# undef putchar
# define putchar(x) putchar_unlocked (x)
# else
# define putchar_unlocked(x) putchar (x)
# endif
# undef flockfile
# define flockfile(x) ((void) 0)
# undef ftrylockfile
# define ftrylockfile(x) 0
# undef funlockfile
# define funlockfile(x) ((void) 0)
#endif /* UNLOCKED_IO_H */

View file

@ -319,10 +319,12 @@ the list of old buffers.")
(defvar auto-revert-tail-pos 0
"Position of last known end of file.")
(defun auto-revert-find-file-function ()
(setq-local auto-revert-tail-pos
(nth 7 (file-attributes buffer-file-name))))
(add-hook 'find-file-hook
(lambda ()
(setq-local auto-revert-tail-pos
(nth 7 (file-attributes buffer-file-name)))))
#'auto-revert-find-file-function)
(defvar auto-revert-notify-watch-descriptor-hash-list
(make-hash-table :test 'equal)
@ -341,6 +343,11 @@ This has been reported by a file notification event.")
;; Functions:
(defun auto-revert-remove-current-buffer ()
"Remove dead buffer from `auto-revert-buffer-list'."
(setq auto-revert-buffer-list
(delq (current-buffer) auto-revert-buffer-list)))
;;;###autoload
(define-minor-mode auto-revert-mode
"Toggle reverting buffer when the file changes (Auto-Revert Mode).
@ -364,13 +371,10 @@ without being changed in the part that is already in the buffer."
(push (current-buffer) auto-revert-buffer-list)
(add-hook
'kill-buffer-hook
(lambda ()
(setq auto-revert-buffer-list
(delq (current-buffer) auto-revert-buffer-list)))
#'auto-revert-remove-current-buffer
nil t))
(when auto-revert-use-notify (auto-revert-notify-rm-watch))
(setq auto-revert-buffer-list
(delq (current-buffer) auto-revert-buffer-list)))
(auto-revert-remove-current-buffer))
(auto-revert-set-timer)
(when auto-revert-mode
(auto-revert-buffers)
@ -786,24 +790,24 @@ the timer when no buffers need to be checked."
(not (and auto-revert-stop-on-user-input
(input-pending-p))))
(let ((buf (car bufs)))
(if (buffer-live-p buf)
(with-current-buffer buf
;; Test if someone has turned off Auto-Revert Mode in a
;; non-standard way, for example by changing major mode.
(if (and (not auto-revert-mode)
(not auto-revert-tail-mode)
(memq buf auto-revert-buffer-list))
(setq auto-revert-buffer-list
(delq buf auto-revert-buffer-list)))
(when (auto-revert-active-p)
;; Enable file notification.
(when (and auto-revert-use-notify
(not auto-revert-notify-watch-descriptor))
(auto-revert-notify-add-watch))
(auto-revert-handler)))
;; Remove dead buffer from `auto-revert-buffer-list'.
(setq auto-revert-buffer-list
(delq buf auto-revert-buffer-list))))
(with-current-buffer buf
(if (buffer-live-p buf)
(progn
;; Test if someone has turned off Auto-Revert Mode
;; in a non-standard way, for example by changing
;; major mode.
(if (and (not auto-revert-mode)
(not auto-revert-tail-mode)
(memq buf auto-revert-buffer-list))
(auto-revert-remove-current-buffer))
(when (auto-revert-active-p)
;; Enable file notification.
(when (and auto-revert-use-notify
(not auto-revert-notify-watch-descriptor))
(auto-revert-notify-add-watch))
(auto-revert-handler)))
;; Remove dead buffer from `auto-revert-buffer-list'.
(auto-revert-remove-current-buffer))))
(setq bufs (cdr bufs)))
(setq auto-revert-remaining-buffers bufs)
;; Check if we should cancel the timer.

View file

@ -825,21 +825,18 @@ If COMP or STD is non-nil, put that in the units table instead."
(forward-char -1))
(insert ";;; Custom units stored by Calc on " (current-time-string) "\n")
(if math-additional-units
(progn
(let (expr)
(insert "(setq math-additional-units '(\n")
(let ((list math-additional-units))
(while list
(insert " (" (symbol-name (car (car list))) " "
(if (nth 1 (car list))
(if (stringp (nth 1 (car list)))
(prin1-to-string (nth 1 (car list)))
(prin1-to-string (math-format-flat-expr
(nth 1 (car list)) 0)))
"nil")
" "
(prin1-to-string (nth 2 (car list)))
")\n")
(setq list (cdr list))))
(dolist (u math-additional-units)
(insert " (" (symbol-name (car u)) " "
(if (setq expr (nth 1 u))
(if (stringp expr)
(prin1-to-string expr)
(prin1-to-string (math-format-flat-expr expr 0)))
"nil")
" "
(prin1-to-string (nth 2 u))
")\n"))
(insert "))\n"))
(insert ";;; (no custom units defined)\n"))
(insert ";;; End of custom units\n")
@ -916,15 +913,13 @@ If COMP or STD is non-nil, put that in the units table instead."
(defun math-find-base-units-rec (expr pow)
(let ((u (math-check-unit-name expr)))
(cond (u
(let ((ulist (math-find-base-units u)))
(while ulist
(let ((p (* (cdr (car ulist)) pow))
(old (assq (car (car ulist)) math-fbu-base)))
(if old
(setcdr old (+ (cdr old) p))
(setq math-fbu-base
(cons (cons (car (car ulist)) p) math-fbu-base))))
(setq ulist (cdr ulist)))))
(dolist (x (math-find-base-units u))
(let ((p (* (cdr x) pow))
(old (assq (car x) math-fbu-base)))
(if old
(setcdr old (+ (cdr old) p))
(setq math-fbu-base
(cons (cons (car x) p) math-fbu-base))))))
((math-scalarp expr))
((and (eq (car expr) '^)
(integerp (nth 2 expr)))
@ -1377,20 +1372,15 @@ If COMP or STD is non-nil, put that in the units table instead."
(if (eq pow1 1)
(math-to-standard-units (list '/ n d) nil)
(list '^ (math-to-standard-units (list '/ n d) nil) pow1))
(let (ud1)
(setq un (nth 4 un)
ud (nth 4 ud))
(while un
(setq ud1 ud)
(while ud1
(and (eq (car (car un)) (car (car ud1)))
(setq math-try-cancel-units
(+ math-try-cancel-units
(- (* (cdr (car un)) pow1)
(* (cdr (car ud)) pow2)))))
(setq ud1 (cdr ud1)))
(setq un (cdr un)))
nil))))))
(setq un (nth 4 un)
ud (nth 4 ud))
(dolist (x un)
(dolist (y ud)
(when (eq (car x) (car y))
(setq math-try-cancel-units
(+ math-try-cancel-units
(- (* (cdr x) pow1)
(* (cdr (car ud)) pow2))))))))))))
(math-defsimplify ^
(and math-simplifying-units
@ -1578,9 +1568,8 @@ If COMP or STD is non-nil, put that in the units table instead."
(insert "Calculator Units Table:\n\n")
(insert "(All definitions are exact unless marked with an asterisk (*).)\n\n")
(insert "Unit Type Definition Description\n\n")
(while uptr
(setq u (car uptr)
name (nth 2 u))
(dolist (u uptr)
(setq name (nth 2 u))
(when (eq (car u) 'm)
(setq std t))
(setq shadowed (and std (assq (car u) math-additional-units)))
@ -1618,8 +1607,7 @@ If COMP or STD is non-nil, put that in the units table instead."
(insert " (redefined above)")
(unless (nth 1 u)
(insert " (base unit)")))
(insert "\n")
(setq uptr (cdr uptr)))
(insert "\n"))
(insert "\n\nUnit Prefix Table:\n\n")
(setq uptr math-unit-prefixes)
(while uptr

View file

@ -413,12 +413,11 @@ relevant to POS."
(multibyte-p enable-multibyte-characters)
(overlays (mapcar (lambda (o) (overlay-properties o))
(overlays-at pos)))
(char-description (if (not multibyte-p)
(char-description (if (< char 128)
(single-key-description char)
(if (< char 128)
(single-key-description char)
(string-to-multibyte
(char-to-string char)))))
(string (if (not multibyte-p)
(decode-char 'eight-bit char)
char))))
(text-props-desc
(let ((tmp-buf (generate-new-buffer " *text-props*")))
(unwind-protect
@ -635,7 +634,9 @@ relevant to POS."
("buffer code"
,(if multibyte-p
(encoded-string-description
(string-as-unibyte (char-to-string char)) nil)
(encode-coding-string (char-to-string char)
'emacs-internal)
nil)
(format "#x%02X" char)))
("file code"
,@(if multibyte-p
@ -704,7 +705,6 @@ relevant to POS."
(called-interactively-p 'interactive))
(with-help-window (help-buffer)
(with-current-buffer standard-output
(set-buffer-multibyte multibyte-p)
(let ((formatter (format "%%%ds:" max-width)))
(dolist (elt item-list)
(when (cadr elt)

View file

@ -51,6 +51,33 @@ into this list; they also should call `dired-log' to log the errors.")
(defconst dired-star-subst-regexp "\\(^\\|[ \t]\\)\\*\\([ \t]\\|$\\)")
(defconst dired-quark-subst-regexp "\\(^\\|[ \t]\\)\\?\\([ \t]\\|$\\)")
(make-obsolete-variable 'dired-star-subst-regexp nil "26.1")
(make-obsolete-variable 'dired-quark-subst-regexp nil "26.1")
(defun dired-isolated-string-re (string)
"Return a regexp to match STRING isolated.
Isolated means that STRING is surrounded by spaces or at the beginning/end
of a string followed/prefixed with an space.
The regexp capture the preceding blank, STRING and the following blank as
the groups 1, 2 and 3 respectively."
(format "\\(\\`\\|[ \t]\\)\\(%s\\)\\([ \t]\\|\\'\\)" string))
(defun dired--star-or-qmark-p (string match &optional keep)
"Return non-nil if STRING contains isolated MATCH or `\\=`?\\=`'.
MATCH should be the strings \"?\", `\\=`?\\=`', \"*\" or nil. The latter
means STRING contains either \"?\" or `\\=`?\\=`' or \"*\".
If optional arg KEEP is non-nil, then preserve the match data. Otherwise,
this function changes it and saves MATCH as the second match group.
Isolated means that MATCH is surrounded by spaces or at the beginning/end
of STRING followed/prefixed with an space. A match to `\\=`?\\=`',
isolated or not, is also valid."
(let ((regexps (list (dired-isolated-string-re (if match (regexp-quote match) "[*?]")))))
(when (or (null match) (equal match "?"))
(setq regexps (append (list "\\(\\)\\(`\\?`\\)\\(\\)") regexps)))
(cl-some (lambda (x)
(funcall (if keep #'string-match-p #'string-match) x string))
regexps)))
;;;###autoload
(defun dired-diff (file &optional switches)
@ -308,7 +335,7 @@ List has a form of (file-name full-file-name (attribute-list))."
failures)
(setq failures
(dired-bunch-files 10000
(function dired-check-process)
#'dired-check-process
(append
(list operation program)
(unless (or (string-equal new-attribute "")
@ -512,7 +539,7 @@ with a prefix argument."
;; If the file has numeric backup versions,
;; put on dired-file-version-alist an element of the form
;; (FILENAME . VERSION-NUMBER-LIST)
(dired-map-dired-file-lines (function dired-collect-file-versions))
(dired-map-dired-file-lines #'dired-collect-file-versions)
;; Sort each VERSION-NUMBER-LIST,
;; and remove the versions not to be deleted.
(let ((fval dired-file-version-alist))
@ -528,7 +555,7 @@ with a prefix argument."
(setq fval (cdr fval))))
;; Look at each file. If it is a numeric backup file,
;; find it in a VERSION-NUMBER-LIST and maybe flag it for deletion.
(dired-map-dired-file-lines (function dired-trample-file-versions))
(dired-map-dired-file-lines #'dired-trample-file-versions)
(message "Cleaning numerical backups...done")))
;;; Subroutines of dired-clean-directory.
@ -658,13 +685,13 @@ If there is a `*' in COMMAND, surrounded by whitespace, this runs
COMMAND just once with the entire file list substituted there.
If there is no `*', but there is a `?' in COMMAND, surrounded by
whitespace, this runs COMMAND on each file individually with the
file name substituted for `?'.
whitespace, or a `\\=`?\\=`' this runs COMMAND on each file
individually with the file name substituted for `?' or `\\=`?\\=`'.
Otherwise, this runs COMMAND on each file individually with the
file name added at the end of COMMAND (separated by a space).
`*' and `?' when not surrounded by whitespace have no special
`*' and `?' when not surrounded by whitespace nor `\\=`' have no special
significance for `dired-do-shell-command', and are passed through
normally to the shell, but you must confirm first.
@ -704,32 +731,40 @@ can be produced by `dired-get-marked-files', for example."
(dired-read-shell-command "! on %s: " current-prefix-arg files)
current-prefix-arg
files)))
(let* ((on-each (not (string-match-p dired-star-subst-regexp command)))
(no-subst (not (string-match-p dired-quark-subst-regexp command)))
(star (string-match-p "\\*" command))
(qmark (string-match-p "\\?" command)))
;; Get confirmation for wildcards that may have been meant
;; to control substitution of a file name or the file name list.
(if (cond ((not (or on-each no-subst))
(error "You can not combine `*' and `?' substitution marks"))
((and star on-each)
(y-or-n-p (format-message
"Confirm--do you mean to use `*' as a wildcard? ")))
((and qmark no-subst)
(y-or-n-p (format-message
"Confirm--do you mean to use `?' as a wildcard? ")))
(t))
(if on-each
(dired-bunch-files
(- 10000 (length command))
(function (lambda (&rest files)
(dired-run-shell-command
(dired-shell-stuff-it command files t arg))))
nil
file-list)
;; execute the shell command
(dired-run-shell-command
(dired-shell-stuff-it command file-list nil arg))))))
(cl-flet ((need-confirm-p
(cmd str)
(let ((res cmd)
(regexp (regexp-quote str)))
;; Drop all ? and * surrounded by spaces and `?`.
(while (and (string-match regexp res)
(dired--star-or-qmark-p res str))
(setq res (replace-match "" t t res 0)))
(string-match regexp res))))
(let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep)))
(no-subst (not (dired--star-or-qmark-p command "?" 'keep)))
(star (string-match "\\*" command))
(qmark (string-match "\\?" command))
;; Get confirmation for wildcards that may have been meant
;; to control substitution of a file name or the file name list.
(ok (cond ((not (or on-each no-subst))
(error "You can not combine `*' and `?' substitution marks"))
((need-confirm-p command "*")
(y-or-n-p (format-message
"Confirm--do you mean to use `*' as a wildcard? ")))
((need-confirm-p command "?")
(y-or-n-p (format-message
"Confirm--do you mean to use `?' as a wildcard? ")))
(t))))
(when ok
(if on-each
(dired-bunch-files (- 10000 (length command))
(lambda (&rest files)
(dired-run-shell-command
(dired-shell-stuff-it command files t arg)))
nil file-list)
;; execute the shell command
(dired-run-shell-command
(dired-shell-stuff-it command file-list nil arg)))))))
;; Might use {,} for bash or csh:
(defvar dired-mark-prefix ""
@ -769,12 +804,10 @@ can be produced by `dired-get-marked-files', for example."
";"
"&"))
(stuff-it
(if (or (string-match-p dired-star-subst-regexp command)
(string-match-p dired-quark-subst-regexp command))
(if (dired--star-or-qmark-p command nil 'keep)
(lambda (x)
(let ((retval (concat cmd-prefix command)))
(while (string-match
"\\(^\\|[ \t]\\)\\([*?]\\)\\([ \t]\\|$\\)" retval)
(while (dired--star-or-qmark-p retval nil)
(setq retval (replace-match x t t retval 2)))
retval))
(lambda (x) (concat cmd-prefix command dired-mark-separator x)))))
@ -1122,7 +1155,7 @@ Return nil if no change in files."
(let ((files (dired-get-marked-files t arg nil t))
(string (if (eq op-symbol 'compress) "Compress or uncompress"
(capitalize (symbol-name op-symbol)))))
(dired-mark-pop-up nil op-symbol files (function y-or-n-p)
(dired-mark-pop-up nil op-symbol files #'y-or-n-p
(concat string " "
(dired-mark-prompt arg files) "? ")))))
@ -1190,7 +1223,7 @@ return t; if SYM is q or ESC, return nil."
(defun dired-do-compress (&optional arg)
"Compress or uncompress marked (or next ARG) files."
(interactive "P")
(dired-map-over-marks-check (function dired-compress) arg 'compress t))
(dired-map-over-marks-check #'dired-compress arg 'compress t))
;; Commands for Emacs Lisp files - load and byte compile
@ -1218,7 +1251,7 @@ return t; if SYM is q or ESC, return nil."
(defun dired-do-byte-compile (&optional arg)
"Byte compile marked (or next ARG) Emacs Lisp files."
(interactive "P")
(dired-map-over-marks-check (function dired-byte-compile) arg 'byte-compile t))
(dired-map-over-marks-check #'dired-byte-compile arg 'byte-compile t))
(defun dired-load ()
;; Return nil for success, offending file name else.
@ -1235,7 +1268,7 @@ return t; if SYM is q or ESC, return nil."
(defun dired-do-load (&optional arg)
"Load the marked (or next ARG) Emacs Lisp files."
(interactive "P")
(dired-map-over-marks-check (function dired-load) arg 'load t))
(dired-map-over-marks-check #'dired-load arg 'load t))
;;;###autoload
(defun dired-do-redisplay (&optional arg test-for-subdir)
@ -1308,7 +1341,7 @@ See Info node `(emacs)Subdir switches' for more details."
(defun dired-add-file (filename &optional marker-char)
(dired-fun-in-all-buffers
(file-name-directory filename) (file-name-nondirectory filename)
(function dired-add-entry) filename marker-char))
#'dired-add-entry filename marker-char))
(defvar dired-omit-mode)
(declare-function dired-omit-regexp "dired-x" ())
@ -1445,7 +1478,7 @@ files matching `dired-omit-regexp'."
(defun dired-remove-file (file)
(dired-fun-in-all-buffers
(file-name-directory file) (file-name-nondirectory file)
(function dired-remove-entry) file))
#'dired-remove-entry file))
(defun dired-remove-entry (file)
(save-excursion
@ -1459,7 +1492,7 @@ files matching `dired-omit-regexp'."
"Create or update the line for FILE in all Dired buffers it would belong in."
(dired-fun-in-all-buffers (file-name-directory file)
(file-name-nondirectory file)
(function dired-relist-entry) file))
#'dired-relist-entry file))
(defun dired-relist-entry (file)
;; Relist the line for FILE, or just add it if it did not exist.
@ -1553,7 +1586,7 @@ Special value `always' suppresses confirmation."
(setq from-dir (file-name-as-directory from-dir)
to-dir (file-name-as-directory to-dir))
(dired-fun-in-all-buffers from-dir nil
(function dired-rename-subdir-1) from-dir to-dir)
#'dired-rename-subdir-1 from-dir to-dir)
;; Update visited file name of all affected buffers
(let ((expanded-from-dir (expand-file-name from-dir))
(blist (buffer-list)))
@ -1788,7 +1821,7 @@ Optional arg HOW-TO determines how to treat the target.
For any other return value, TARGET is treated as a directory."
(or op1 (setq op1 operation))
(let* ((fn-list (dired-get-marked-files nil arg))
(rfn-list (mapcar (function dired-make-relative) fn-list))
(rfn-list (mapcar #'dired-make-relative fn-list))
(dired-one-file ; fluid variable inside dired-create-files
(and (consp fn-list) (null (cdr fn-list)) (car fn-list)))
(target-dir (dired-dwim-target-directory))
@ -1838,10 +1871,9 @@ Optional arg HOW-TO determines how to treat the target.
(if into-dir ; target is a directory
;; This function uses fluid variable target when called
;; inside dired-create-files:
(function
(lambda (from)
(expand-file-name (file-name-nondirectory from) target)))
(function (lambda (_from) target)))
(lambda (from)
(expand-file-name (file-name-nondirectory from) target))
(lambda (_from) target))
marker-char))))
;; Read arguments for a marked-files command that wants a file name,
@ -1857,7 +1889,7 @@ Optional arg HOW-TO determines how to treat the target.
&optional default)
(dired-mark-pop-up
nil op-symbol files
(function read-file-name)
#'read-file-name
(format prompt (dired-mark-prompt arg files)) dir default))
(defun dired-dwim-target-directory ()
@ -1985,7 +2017,7 @@ This command copies symbolic links by creating new ones, similar
to the \"-d\" option for the \"cp\" shell command."
(interactive "P")
(let ((dired-recursive-copies dired-recursive-copies))
(dired-do-create-files 'copy (function dired-copy-file)
(dired-do-create-files 'copy #'dired-copy-file
"Copy"
arg dired-keep-marker-copy
nil dired-copy-how-to-fn)))
@ -2002,7 +2034,7 @@ suggested for the target directory depends on the value of
For relative symlinks, use \\[dired-do-relsymlink]."
(interactive "P")
(dired-do-create-files 'symlink (function make-symbolic-link)
(dired-do-create-files 'symlink #'make-symbolic-link
"Symlink" arg dired-keep-marker-symlink))
;;;###autoload
@ -2015,7 +2047,7 @@ with the same names that the files currently have. The default
suggested for the target directory depends on the value of
`dired-dwim-target', which see."
(interactive "P")
(dired-do-create-files 'hardlink (function dired-hardlink)
(dired-do-create-files 'hardlink #'dired-hardlink
"Hardlink" arg dired-keep-marker-hardlink))
(defun dired-hardlink (file newname &optional ok-if-already-exists)
@ -2034,7 +2066,7 @@ This command also renames any buffers that are visiting the files.
The default suggested for the target directory depends on the value
of `dired-dwim-target', which see."
(interactive "P")
(dired-do-create-files 'move (function dired-rename-file)
(dired-do-create-files 'move #'dired-rename-file
"Move" arg dired-keep-marker-rename "Rename"))
;;;###end dired-cp.el
@ -2062,37 +2094,35 @@ Type SPC or `y' to %s one match, DEL or `n' to skip to next,
(regexp-name-constructor
;; Function to construct new filename using REGEXP and NEWNAME:
(if whole-name ; easy (but rare) case
(function
(lambda (from)
(let ((to (dired-string-replace-match regexp from newname))
;; must bind help-form directly around call to
;; dired-query
(help-form rename-regexp-help-form))
(if to
(and (dired-query 'rename-regexp-query
operation-prompt
from
to)
to)
(dired-log "%s: %s did not match regexp %s\n"
operation from regexp)))))
;; not whole-name, replace non-directory part only
(function
(lambda (from)
(let* ((new (dired-string-replace-match
regexp (file-name-nondirectory from) newname))
(to (and new ; nil means there was no match
(expand-file-name new
(file-name-directory from))))
(lambda (from)
(let ((to (dired-string-replace-match regexp from newname))
;; must bind help-form directly around call to
;; dired-query
(help-form rename-regexp-help-form))
(if to
(and (dired-query 'rename-regexp-query
operation-prompt
(dired-make-relative from)
(dired-make-relative to))
to)
(dired-log "%s: %s did not match regexp %s\n"
operation (file-name-nondirectory from) regexp)))))))
(if to
(and (dired-query 'rename-regexp-query
operation-prompt
from
to)
to)
(dired-log "%s: %s did not match regexp %s\n"
operation from regexp))))
;; not whole-name, replace non-directory part only
(lambda (from)
(let* ((new (dired-string-replace-match
regexp (file-name-nondirectory from) newname))
(to (and new ; nil means there was no match
(expand-file-name new
(file-name-directory from))))
(help-form rename-regexp-help-form))
(if to
(and (dired-query 'rename-regexp-query
operation-prompt
(dired-make-relative from)
(dired-make-relative to))
to)
(dired-log "%s: %s did not match regexp %s\n"
operation (file-name-nondirectory from) regexp))))))
rename-regexp-query)
(dired-create-files
file-creator operation fn-list regexp-name-constructor marker-char)))
@ -2130,7 +2160,7 @@ With a zero prefix arg, renaming by regexp affects the absolute file name.
Normally, only the non-directory part of the file name is used and changed."
(interactive (dired-mark-read-regexp "Rename"))
(dired-do-create-files-regexp
(function dired-rename-file)
#'dired-rename-file
"Rename" arg regexp newname whole-name dired-keep-marker-rename))
;;;###autoload
@ -2140,7 +2170,7 @@ See function `dired-do-rename-regexp' for more info."
(interactive (dired-mark-read-regexp "Copy"))
(let ((dired-recursive-copies nil)) ; No recursive copies.
(dired-do-create-files-regexp
(function dired-copy-file)
#'dired-copy-file
(if dired-copy-preserve-time "Copy [-p]" "Copy")
arg regexp newname whole-name dired-keep-marker-copy)))
@ -2150,7 +2180,7 @@ See function `dired-do-rename-regexp' for more info."
See function `dired-do-rename-regexp' for more info."
(interactive (dired-mark-read-regexp "HardLink"))
(dired-do-create-files-regexp
(function add-name-to-file)
#'add-name-to-file
"HardLink" arg regexp newname whole-name dired-keep-marker-hardlink))
;;;###autoload
@ -2159,7 +2189,7 @@ See function `dired-do-rename-regexp' for more info."
See function `dired-do-rename-regexp' for more info."
(interactive (dired-mark-read-regexp "SymLink"))
(dired-do-create-files-regexp
(function make-symbolic-link)
#'make-symbolic-link
"SymLink" arg regexp newname whole-name dired-keep-marker-symlink))
(defvar rename-non-directory-query)
@ -2174,39 +2204,38 @@ See function `dired-do-rename-regexp' for more info."
file-creator
operation
(dired-get-marked-files nil arg)
(function
(lambda (from)
(let ((to (concat (file-name-directory from)
(funcall basename-constructor
(file-name-nondirectory from)))))
(and (let ((help-form (format-message "\
(lambda (from)
(let ((to (concat (file-name-directory from)
(funcall basename-constructor
(file-name-nondirectory from)))))
(and (let ((help-form (format-message "\
Type SPC or `y' to %s one file, DEL or `n' to skip to next,
`!' to %s all remaining matches with no more questions."
(downcase operation)
(downcase operation))))
(dired-query 'rename-non-directory-query
(concat operation " `%s' to `%s'")
(dired-make-relative from)
(dired-make-relative to)))
to))))
(downcase operation)
(downcase operation))))
(dired-query 'rename-non-directory-query
(concat operation " `%s' to `%s'")
(dired-make-relative from)
(dired-make-relative to)))
to)))
dired-keep-marker-rename)))
(defun dired-rename-non-directory (basename-constructor operation arg)
(dired-create-files-non-directory
(function dired-rename-file)
#'dired-rename-file
basename-constructor operation arg))
;;;###autoload
(defun dired-upcase (&optional arg)
"Rename all marked (or next ARG) files to upper case."
(interactive "P")
(dired-rename-non-directory (function upcase) "Rename upcase" arg))
(dired-rename-non-directory #'upcase "Rename upcase" arg))
;;;###autoload
(defun dired-downcase (&optional arg)
"Rename all marked (or next ARG) files to lower case."
(interactive "P")
(dired-rename-non-directory (function downcase) "Rename downcase" arg))
(dired-rename-non-directory #'downcase "Rename downcase" arg))
;;;###end dired-re.el
@ -2316,12 +2345,11 @@ This function takes some pains to conform to `ls -lR' output."
(when real-switches
(let (case-fold-search)
(mapcar
(function
(lambda (x)
(or (eq (null (string-match-p x real-switches))
(null (string-match-p x dired-actual-switches)))
(error
"Can't have dirs with and without -%s switches together" x))))
(lambda (x)
(or (eq (null (string-match-p x real-switches))
(null (string-match-p x dired-actual-switches)))
(error
"Can't have dirs with and without -%s switches together" x)))
;; all switches that make a difference to dired-get-filename:
'("F" "b"))))))
@ -2334,9 +2362,9 @@ This function takes some pains to conform to `ls -lR' output."
;; Keep the alist sorted on buffer position.
(setq dired-subdir-alist
(sort dired-subdir-alist
(function (lambda (elt1 elt2)
(> (dired-get-subdir-min elt1)
(dired-get-subdir-min elt2)))))))
(lambda (elt1 elt2)
(> (dired-get-subdir-min elt1)
(dired-get-subdir-min elt2))))))
(defun dired-kill-tree (dirname &optional remember-marks kill-root)
"Kill all proper subdirs of DIRNAME, excluding DIRNAME itself.

View file

@ -335,9 +335,8 @@ The directory name must be absolute, but need not be fully expanded.")
(defvar dired-re-dir (concat dired-re-maybe-mark dired-re-inode-size "d[^:]"))
(defvar dired-re-sym (concat dired-re-maybe-mark dired-re-inode-size "l[^:]"))
(defvar dired-re-exe;; match ls permission string of an executable file
(mapconcat (function
(lambda (x)
(concat dired-re-maybe-mark dired-re-inode-size x)))
(mapconcat (lambda (x)
(concat dired-re-maybe-mark dired-re-inode-size x))
'("-[-r][-w][xs][-r][-w].[-r][-w]."
"-[-r][-w].[-r][-w][xs][-r][-w]."
"-[-r][-w].[-r][-w].[-r][-w][xst]")
@ -607,9 +606,9 @@ marked file, return (t FILENAME) instead of (FILENAME)."
(progn ;; no save-excursion, want to move point.
(dired-repeat-over-lines
,arg
(function (lambda ()
(if ,show-progress (sit-for 0))
(setq results (cons ,body results)))))
(lambda ()
(if ,show-progress (sit-for 0))
(setq results (cons ,body results))))
(if (< ,arg 0)
(nreverse results)
results))
@ -1995,8 +1994,8 @@ Keybindings:
;; Ignore dired-hide-details-* value of invisible text property by default.
(when (eq buffer-invisibility-spec t)
(setq buffer-invisibility-spec (list t)))
(setq-local revert-buffer-function (function dired-revert))
(setq-local buffer-stale-function (function dired-buffer-stale-p))
(setq-local revert-buffer-function #'dired-revert)
(setq-local buffer-stale-function #'dired-buffer-stale-p)
(setq-local page-delimiter "\n\n")
(setq-local dired-directory (or dirname default-directory))
;; list-buffers uses this to display the dir being edited in this buffer.
@ -2469,7 +2468,7 @@ You can then feed the file name(s) to other commands with \\[yank]."
(interactive "P")
(let ((string
(or (dired-get-subdir)
(mapconcat (function identity)
(mapconcat #'identity
(if arg
(cond ((zerop (prefix-numeric-value arg))
(dired-get-marked-files))
@ -2971,12 +2970,12 @@ non-empty directories is allowed."
;; lines still to be changed, so the (point) values in L stay valid.
;; Also, for subdirs in natural order, a subdir's files are deleted
;; before the subdir itself - the other way around would not work.
(let* ((files (mapcar (function car) l))
(let* ((files (mapcar #'car l))
(count (length l))
(succ 0)
(trashing (and trash delete-by-moving-to-trash)))
;; canonicalize file list for pop up
(setq files (nreverse (mapcar (function dired-make-relative) files)))
(setq files (nreverse (mapcar #'dired-make-relative files)))
(if (dired-mark-pop-up
" *Deletions*" 'delete files dired-deletion-confirmer
(format "%s %s "
@ -2999,7 +2998,7 @@ non-empty directories is allowed."
(progress-reporter-update progress-reporter succ)
(dired-fun-in-all-buffers
(file-name-directory fn) (file-name-nondirectory fn)
(function dired-delete-entry) fn))
#'dired-delete-entry fn))
(error ;; catch errors from failed deletions
(dired-log "%s\n" err)
(setq failures (cons (car (car l)) failures)))))
@ -3293,7 +3292,7 @@ this subdir."
(let ((inhibit-read-only t))
(dired-repeat-over-lines
(prefix-numeric-value arg)
(function (lambda () (delete-char 1) (insert dired-marker-char))))))))
(lambda () (delete-char 1) (insert dired-marker-char)))))))
(defun dired-unmark (arg &optional interactive)
"Unmark the file at point in the Dired buffer.
@ -3928,7 +3927,7 @@ Ask means pop up a menu for the user to select one of copy, move or link."
(cdr
(nreverse
(mapcar
(function (lambda (f) (desktop-file-name (car f) dirname)))
(lambda (f) (desktop-file-name (car f) dirname))
dired-subdir-alist)))))
(defun dired-restore-desktop-buffer (_file-name

View file

@ -443,11 +443,24 @@ quote, left double quote, and right double quote, respectively."
:version "25.1"
:type 'boolean :safe 'booleanp :group 'electricity)
(defcustom electric-quote-context-sensitive nil
"Non-nil means to replace \\=' with an electric quote depending on context.
If `electric-quote-context-sensitive' is non-nil, Emacs replaces
\\=' and \\='\\=' with an opening quote after a line break,
whitespace, opening parenthesis, or quote and leaves \\=` alone."
:version "26.1"
:type 'boolean :safe #'booleanp :group 'electricity)
(defvar electric-quote-code-faces ()
"List of faces to treat as inline code in `text-mode'.")
(defun electric-quote-post-self-insert-function ()
"Function that `electric-quote-mode' adds to `post-self-insert-hook'.
This requotes when a quoting key is typed."
(when (and electric-quote-mode
(memq last-command-event '(?\' ?\`)))
(or (eq last-command-event ?\')
(and (not electric-quote-context-sensitive)
(eq last-command-event ?\`))))
(let ((start
(if (and comment-start comment-use-syntax)
(when (or electric-quote-comment electric-quote-string)
@ -462,30 +475,45 @@ This requotes when a quoting key is typed."
(syntax-ppss (1- (point)))))))))
(and electric-quote-paragraph
(derived-mode-p 'text-mode)
;; FIXME: There should be a cl-disjoint function.
(null (cl-intersection (face-at-point nil 'multiple)
electric-quote-code-faces
:test #'eq))
;; FIXME: Why is the next form there? Its never
;; nil.
(or (eq last-command-event ?\`)
(save-excursion (backward-paragraph) (point)))))))
(pcase electric-quote-chars
(`(,q< ,q> ,q<< ,q>>)
(when start
(save-excursion
(if (eq last-command-event ?\`)
(cond ((search-backward (string q< ?`) (- (point) 2) t)
(replace-match (string q<<))
(when (and electric-pair-mode
(eq (cdr-safe
(assq q< electric-pair-text-pairs))
(char-after)))
(delete-char 1))
(setq last-command-event q<<))
((search-backward "`" (1- (point)) t)
(replace-match (string q<))
(setq last-command-event q<)))
(cond ((search-backward (string q> ?') (- (point) 2) t)
(replace-match (string q>>))
(setq last-command-event q>>))
((search-backward "'" (1- (point)) t)
(replace-match (string q>))
(setq last-command-event q>)))))))))))
(let ((backtick ?\`))
(if (or (eq last-command-event ?\`)
(and electric-quote-context-sensitive
(save-excursion
(backward-char)
(or (bobp) (bolp)
(memq (char-before) (list q< q<<))
(memq (char-syntax (char-before))
'(?\s ?\())))
(setq backtick ?\')))
(cond ((search-backward (string q< backtick) (- (point) 2) t)
(replace-match (string q<<))
(when (and electric-pair-mode
(eq (cdr-safe
(assq q< electric-pair-text-pairs))
(char-after)))
(delete-char 1))
(setq last-command-event q<<))
((search-backward (string backtick) (1- (point)) t)
(replace-match (string q<))
(setq last-command-event q<)))
(cond ((search-backward (string q> ?') (- (point) 2) t)
(replace-match (string q>>))
(setq last-command-event q>>))
((search-backward "'" (1- (point)) t)
(replace-match (string q>))
(setq last-command-event q>))))))))))))
(put 'electric-quote-post-self-insert-function 'priority 10)

View file

@ -437,22 +437,38 @@ as an integer unless JUNK-ALLOWED is non-nil."
;; Random numbers.
(defun cl--random-time ()
(let* ((time (copy-sequence (current-time-string))) (i (length time)) (v 0))
(while (>= (cl-decf i) 0) (setq v (+ (* v 3) (aref time i))))
v))
;;;###autoload (autoload 'cl-random-state-p "cl-extra")
(cl-defstruct (cl--random-state
(:copier nil)
(:predicate cl-random-state-p)
(:constructor nil)
(:constructor cl--make-random-state (vec)))
(i -1) (j 30) vec)
(defvar cl--random-state (cl--make-random-state (cl--random-time)))
;;;###autoload
(defun cl-random (lim &optional state)
"Return a random nonnegative number less than LIM, an integer or float.
Optional second arg STATE is a random-state object."
(or state (setq state cl--random-state))
;; Inspired by "ran3" from Numerical Recipes. Additive congruential method.
(let ((vec (aref state 3)))
(let ((vec (cl--random-state-vec state)))
(if (integerp vec)
(let ((i 0) (j (- 1357335 (abs (% vec 1357333)))) (k 1))
(aset state 3 (setq vec (make-vector 55 nil)))
(setf (cl--random-state-vec state)
(setq vec (make-vector 55 nil)))
(aset vec 0 j)
(while (> (setq i (% (+ i 21) 55)) 0)
(aset vec i (setq j (prog1 k (setq k (- j k))))))
(while (< (setq i (1+ i)) 200) (cl-random 2 state))))
(let* ((i (aset state 1 (% (1+ (aref state 1)) 55)))
(j (aset state 2 (% (1+ (aref state 2)) 55)))
(let* ((i (cl-callf (lambda (x) (% (1+ x) 55)) (cl--random-state-i state)))
(j (cl-callf (lambda (x) (% (1+ x) 55)) (cl--random-state-j state)))
(n (logand 8388607 (aset vec i (- (aref vec i) (aref vec j))))))
(if (integerp lim)
(if (<= lim 512) (% n lim)
@ -466,17 +482,10 @@ Optional second arg STATE is a random-state object."
(defun cl-make-random-state (&optional state)
"Return a copy of random-state STATE, or of the internal state if omitted.
If STATE is t, return a new state object seeded from the time of day."
(cond ((null state) (cl-make-random-state cl--random-state))
((vectorp state) (copy-tree state t))
((integerp state) (vector 'cl--random-state-tag -1 30 state))
(t (cl-make-random-state (cl--random-time)))))
;;;###autoload
(defun cl-random-state-p (object)
"Return t if OBJECT is a random-state object."
(and (vectorp object) (= (length object) 4)
(eq (aref object 0) 'cl--random-state-tag)))
(unless state (setq state cl--random-state))
(if (cl-random-state-p state)
(copy-tree state t)
(cl--make-random-state (if (integerp state) state (cl--random-time)))))
;; Implementation limits.

View file

@ -90,7 +90,7 @@ call other entry points instead, such as `cl-prin1'."
- `disassemble' to print the disassembly of the code.
- nil to skip printing any details about the code.")
(defvar cl-print-compiled-button nil
(defvar cl-print-compiled-button t
"Control how to print byte-compiled functions into buffers.
When the stream is a buffer, make the bytecode part of the output
into a button whose action shows the function's disassembly.")
@ -105,10 +105,11 @@ into a button whose action shows the function's disassembly.")
(if args
(prin1 args stream)
(princ "()" stream)))
(let ((doc (documentation object 'raw)))
(when doc
(princ " " stream)
(prin1 doc stream)))
(pcase (help-split-fundoc (documentation object 'raw) object)
;; Drop args which `help-function-arglist' already printed.
(`(,_usage . ,(and doc (guard (stringp doc))))
(princ " " stream)
(prin1 doc stream)))
(let ((inter (interactive-form object)))
(when inter
(princ " " stream)

View file

@ -49,6 +49,12 @@ the middle is discarded, and just the beginning and end are displayed."
:group 'debugger
:version "21.1")
(defcustom debugger-print-function #'cl-prin1
"Function used to print values in the debugger backtraces."
:type 'function
:options '(cl-prin1 prin1)
:version "26.1")
(defcustom debugger-bury-or-kill 'bury
"What to do with the debugger buffer when exiting `debug'.
The value affects the behavior of operations on any window
@ -264,6 +270,40 @@ first will be printed into the backtrace buffer."
(setq debug-on-next-call debugger-step-after-exit)
debugger-value)))
(defun debugger-insert-backtrace (frames do-xrefs)
"Format and insert the backtrace FRAMES at point.
Make functions into cross-reference buttons if DO-XREFS is non-nil."
(let ((standard-output (current-buffer))
(eval-buffers eval-buffer-list))
(require 'help-mode) ; Define `help-function-def' button type.
(pcase-dolist (`(,evald ,fun ,args ,flags) frames)
(insert (if (plist-get flags :debug-on-exit)
"* " " "))
(let ((fun-file (and do-xrefs (symbol-file fun 'defun)))
(fun-pt (point)))
(cond
((and evald (not debugger-stack-frame-as-list))
(funcall debugger-print-function fun)
(if args (funcall debugger-print-function args) (princ "()")))
(t
(funcall debugger-print-function (cons fun args))
(cl-incf fun-pt)))
(when fun-file
(make-text-button fun-pt (+ fun-pt (length (symbol-name fun)))
:type 'help-function-def
'help-args (list fun fun-file))))
;; After any frame that uses eval-buffer, insert a line that
;; states the buffer position it's reading at.
(when (and eval-buffers (memq fun '(eval-buffer eval-region)))
(insert (format " ; Reading at buffer position %d"
;; This will get the wrong result if there are
;; two nested eval-region calls for the same
;; buffer. That's not a very useful case.
(with-current-buffer (pop eval-buffers)
(point)))))
(insert "\n"))))
(defun debugger-setup-buffer (args)
"Initialize the `*Backtrace*' buffer for entry to the debugger.
That buffer should be current already."
@ -271,27 +311,20 @@ That buffer should be current already."
(erase-buffer)
(set-buffer-multibyte t) ;Why was it nil ? -stef
(setq buffer-undo-list t)
(let ((standard-output (current-buffer))
(print-escape-newlines t)
(print-level 8)
(print-length 50))
;; FIXME the debugger could pass a custom callback to mapbacktrace
;; instead of manipulating printed results.
(mapbacktrace #'backtrace--print-frame 'debug))
(goto-char (point-min))
(delete-region (point)
(progn
(forward-line (if (eq (car args) 'debug)
;; Remove debug--implement-debug-on-entry
;; and the advice's `apply' frame.
3
1))
(point)))
(insert "Debugger entered")
;; lambda is for debug-on-call when a function call is next.
;; debug is for debug-on-entry function called.
(let ((pos (point)))
(let ((frames (nthcdr
;; Remove debug--implement-debug-on-entry and the
;; advice's `apply' frame.
(if (eq (car args) 'debug) 3 1)
(backtrace-frames 'debug)))
(print-escape-newlines t)
(print-escape-control-characters t)
(print-level 8)
(print-length 50)
(pos (point)))
(pcase (car args)
;; lambda is for debug-on-call when a function call is next.
;; debug is for debug-on-entry function called.
((or `lambda `debug)
(insert "--entering a function:\n")
(setq pos (1- (point))))
@ -300,11 +333,9 @@ That buffer should be current already."
(insert "--returning value: ")
(setq pos (point))
(setq debugger-value (nth 1 args))
(prin1 debugger-value (current-buffer))
(insert ?\n)
(delete-char 1)
(insert ? )
(beginning-of-line))
(funcall debugger-print-function debugger-value (current-buffer))
(setf (cl-getf (nth 3 (car frames)) :debug-on-exit) nil)
(insert ?\n))
;; Watchpoint triggered.
((and `watchpoint (let `(,symbol ,newval . ,details) (cdr args)))
(insert
@ -327,7 +358,7 @@ That buffer should be current already."
(`error
(insert "--Lisp error: ")
(setq pos (point))
(prin1 (nth 1 args) (current-buffer))
(funcall debugger-print-function (nth 1 args) (current-buffer))
(insert ?\n))
;; debug-on-call, when the next thing is an eval.
(`t
@ -337,98 +368,15 @@ That buffer should be current already."
(_
(insert ": ")
(setq pos (point))
(prin1 (if (eq (car args) 'nil)
(cdr args) args)
(current-buffer))
(funcall debugger-print-function
(if (eq (car args) 'nil)
(cdr args) args)
(current-buffer))
(insert ?\n)))
(debugger-insert-backtrace frames t)
;; Place point on "stack frame 0" (bug#15101).
(goto-char pos))
;; After any frame that uses eval-buffer,
;; insert a line that states the buffer position it's reading at.
(save-excursion
(let ((tem eval-buffer-list))
(while (and tem
(re-search-forward "^ eval-\\(buffer\\|region\\)(" nil t))
(end-of-line)
(insert (format " ; Reading at buffer position %d"
;; This will get the wrong result
;; if there are two nested eval-region calls
;; for the same buffer. That's not a very useful case.
(with-current-buffer (car tem)
(point))))
(pop tem))))
(debugger-make-xrefs))
(goto-char pos)))
(defun debugger-make-xrefs (&optional buffer)
"Attach cross-references to function names in the `*Backtrace*' buffer."
(interactive "b")
(with-current-buffer (or buffer (current-buffer))
(save-excursion
(setq buffer (current-buffer))
(let ((inhibit-read-only t)
(old-end (point-min)) (new-end (point-min)))
;; If we saved an old backtrace, find the common part
;; between the new and the old.
;; Compare line by line, starting from the end,
;; because that's the part that is likely to be unchanged.
(if debugger-previous-backtrace
(let (old-start new-start (all-match t))
(goto-char (point-max))
(with-temp-buffer
(insert debugger-previous-backtrace)
(while (and all-match (not (bobp)))
(setq old-end (point))
(forward-line -1)
(setq old-start (point))
(with-current-buffer buffer
(setq new-end (point))
(forward-line -1)
(setq new-start (point)))
(if (not (zerop
(let ((case-fold-search nil))
(compare-buffer-substrings
(current-buffer) old-start old-end
buffer new-start new-end))))
(setq all-match nil))))
;; Now new-end is the position of the start of the
;; unchanged part in the current buffer, and old-end is
;; the position of that same text in the saved old
;; backtrace. But we must subtract (point-min) since strings are
;; indexed in origin 0.
;; Replace the unchanged part of the backtrace
;; with the text from debugger-previous-backtrace,
;; since that already has the proper xrefs.
;; With this optimization, we only need to scan
;; the changed part of the backtrace.
(delete-region new-end (point-max))
(goto-char (point-max))
(insert (substring debugger-previous-backtrace
(- old-end (point-min))))
;; Make the unchanged part of the backtrace inaccessible
;; so it won't be scanned.
(narrow-to-region (point-min) new-end)))
;; Scan the new part of the backtrace, inserting xrefs.
(goto-char (point-min))
(while (progn
(goto-char (+ (point) 2))
(skip-syntax-forward "^w_")
(not (eobp)))
(let* ((beg (point))
(end (progn (skip-syntax-forward "w_") (point)))
(sym (intern-soft (buffer-substring-no-properties
beg end)))
(file (and sym (symbol-file sym 'defun))))
(when file
(goto-char beg)
;; help-xref-button needs to operate on something matched
;; by a regexp, so set that up for it.
(re-search-forward "\\(\\sw\\|\\s_\\)+")
(help-xref-button 0 'help-function-def sym file)))
(forward-line 1))
(widen))
(setq debugger-previous-backtrace (buffer-string)))))
(defun debugger-step-through ()
"Proceed, stepping through subexpressions of this expression.
@ -866,9 +814,13 @@ To specify a nil argument interactively, exit with an empty minibuffer."
'type 'help-function
'help-args (list fun))
(terpri))
(terpri)
(princ "Note: if you have redefined a function, then it may no longer\n")
(princ "be set to debug on entry, even if it is in the list."))))))
;; Now that debug--function-list uses advice-member-p, its
;; output should be reliable (except for bugs and the exceptional
;; case where some other advice ends up overriding ours).
;;(terpri)
;;(princ "Note: if you have redefined a function, then it may no longer\n")
;;(princ "be set to debug on entry, even if it is in the list.")
)))))
(defun debug--implement-debug-watch (symbol newval op where)
"Conditionally call the debugger.

View file

@ -84,7 +84,7 @@ Currently under control of this var:
(progn
;; Arrange for field access not to bother checking if the access is indeed
;; made to an eieio--class object.
(cl-declaim (optimize (safety 0)))
(eval-when-compile (cl-declaim (optimize (safety 0))))
(cl-defstruct (eieio--class
(:constructor nil)
@ -103,8 +103,12 @@ Currently under control of this var:
options ;; storage location of tagged class option
; Stored outright without modifications or stripping
)
;; Set it back to the default value.
(cl-declaim (optimize (safety 1))))
;; Set it back to the default value. NOTE: Using the default
;; `safety' value does NOT give the default
;; `byte-compile-delete-errors' value. Therefore limit this (and
;; the above `cl-declaim') to compile time so that we don't affect
;; code which only loads this library.
(eval-when-compile (cl-declaim (optimize (safety 1)))))
(eval-and-compile

View file

@ -670,48 +670,12 @@ and is displayed in front of the value of MESSAGE-FORM."
(cl-defstruct (ert-test-aborted-with-non-local-exit
(:include ert-test-result)))
(defun ert--record-backtrace ()
"Record the current backtrace (as a list) and return it."
;; Since the backtrace is stored in the result object, result
;; objects must only be printed with appropriate limits
;; (`print-level' and `print-length') in place. For interactive
;; use, the cost of ensuring this possibly outweighs the advantage
;; of storing the backtrace for
;; `ert-results-pop-to-backtrace-for-test-at-point' given that we
;; already have `ert-results-rerun-test-debugging-errors-at-point'.
;; For batch use, however, printing the backtrace may be useful.
(cl-loop
;; 6 is the number of frames our own debugger adds (when
;; compiled; more when interpreted). FIXME: Need to describe a
;; procedure for determining this constant.
for i from 6
for frame = (backtrace-frame i)
while frame
collect frame))
(defun ert--print-backtrace (backtrace)
(defun ert--print-backtrace (backtrace do-xrefs)
"Format the backtrace BACKTRACE to the current buffer."
;; This is essentially a reimplementation of Fbacktrace
;; (src/eval.c), but for a saved backtrace, not the current one.
(let ((print-escape-newlines t)
(print-level 8)
(print-length 50))
(dolist (frame backtrace)
(pcase-exhaustive frame
(`(nil ,special-operator . ,arg-forms)
;; Special operator.
(insert
(format " %S\n" (cons special-operator arg-forms))))
(`(t ,fn . ,args)
;; Function call.
(insert (format " %S(" fn))
(cl-loop for firstp = t then nil
for arg in args do
(unless firstp
(insert " "))
(insert (format "%S" arg)))
(insert ")\n"))))))
(debugger-insert-backtrace backtrace do-xrefs)))
;; A container for the state of the execution of a single test and
;; environment data needed during its execution.
@ -750,7 +714,19 @@ run. ARGS are the arguments to `debugger'."
((quit) 'quit)
((ert-test-skipped) 'skipped)
(otherwise 'failed)))
(backtrace (ert--record-backtrace))
;; We store the backtrace in the result object for
;; `ert-results-pop-to-backtrace-for-test-at-point'.
;; This means we have to limit `print-level' and
;; `print-length' when printing result objects. That
;; might not be worth while when we can also use
;; `ert-results-rerun-test-debugging-errors-at-point',
;; (i.e., when running interactively) but having the
;; backtrace ready for printing is important for batch
;; use.
;;
;; Grab the frames starting from `signal', frames below
;; that are all from the debugger.
(backtrace (backtrace-frames 'signal))
(infos (reverse ert--infos)))
(setf (ert--test-execution-info-result info)
(cl-ecase type
@ -1409,8 +1385,9 @@ Returns the stats object."
(ert-test-result-with-condition
(message "Test %S backtrace:" (ert-test-name test))
(with-temp-buffer
(ert--print-backtrace (ert-test-result-with-condition-backtrace
result))
(ert--print-backtrace
(ert-test-result-with-condition-backtrace result)
nil)
(goto-char (point-min))
(while (not (eobp))
(let ((start (point))
@ -1491,7 +1468,7 @@ this exits Emacs, with status as per `ert-run-tests-batch-and-exit'."
(with-temp-buffer
(while (setq logfile (pop command-line-args-left))
(erase-buffer)
(insert-file-contents logfile)
(when (file-readable-p logfile) (insert-file-contents logfile))
(if (not (re-search-forward "^Running \\([0-9]+\\) tests" nil t))
(push logfile notests)
(setq ntests (+ ntests (string-to-number (match-string 1))))
@ -1828,12 +1805,23 @@ EWOC and STATS are arguments for `ert--results-update-stats-display'."
BEGIN and END specify a region in the current buffer."
(save-excursion
(save-restriction
(narrow-to-region begin end)
;; Inhibit optimization in `debugger-make-xrefs' that would
;; sometimes insert unrelated backtrace info into our buffer.
(let ((debugger-previous-backtrace nil))
(debugger-make-xrefs)))))
(goto-char begin)
(while (progn
(goto-char (+ (point) 2))
(skip-syntax-forward "^w_")
(< (point) end))
(let* ((beg (point))
(end (progn (skip-syntax-forward "w_") (point)))
(sym (intern-soft (buffer-substring-no-properties
beg end)))
(file (and sym (symbol-file sym 'defun))))
(when file
(goto-char beg)
;; help-xref-button needs to operate on something matched
;; by a regexp, so set that up for it.
(re-search-forward "\\(\\sw\\|\\s_\\)+")
(help-xref-button 0 'help-function-def sym file)))
(forward-line 1))))
(defun ert--string-first-line (s)
"Return the first line of S, or S if it contains no newlines.
@ -2420,8 +2408,7 @@ To be used in the ERT results buffer."
;; Use unibyte because `debugger-setup-buffer' also does so.
(set-buffer-multibyte nil)
(setq truncate-lines t)
(ert--print-backtrace backtrace)
(debugger-make-xrefs)
(ert--print-backtrace backtrace t)
(goto-char (point-min))
(insert (substitute-command-keys "Backtrace for test `"))
(ert-insert-test-name-button (ert-test-name test))

View file

@ -326,12 +326,13 @@ Return argument is of the form (\"HOLDER\" \"YEAR1\" ... \"YEARN\")"
(start (point))
(end (line-end-position)))
;; Cope with multi-line copyright `lines'. Assume the second
;; line is indented (with the same commenting style).
;; line is indented at least as much as the original, with the
;; same commenting style.
(save-excursion
(beginning-of-line 2)
(let ((str (concat (match-string-no-properties 1) "[ \t]+")))
(let ((str (match-string-no-properties 1)))
(beginning-of-line)
(while (looking-at str)
(while (and (looking-at str) (not (looking-at lm-copyright-prefix)))
(setq end (line-end-position))
(beginning-of-line 2))))
;; Make a single line and parse that.

View file

@ -1047,7 +1047,7 @@ callback data (if any)."
(defun epg--status-TRUST_MARGINAL (context _string)
(let ((signature (car (epg-context-result-for context 'verify))))
(if (and signature
(eq (epg-signature-status signature) 'marginal))
(eq (epg-signature-status signature) 'good))
(setf (epg-signature-validity signature) 'marginal))))
(defun epg--status-TRUST_FULLY (context _string)

View file

@ -1148,6 +1148,8 @@ be finished later after the completion of an asynchronous subprocess."
;; command invocation
(declare-function help-fns-function-description-header "help-fns")
(defun eshell/which (command &rest names)
"Identify the COMMAND, and where it is located."
(dolist (name (cons command names))
@ -1164,25 +1166,17 @@ be finished later after the completion of an asynchronous subprocess."
(concat name " is an alias, defined as \""
(cadr alias) "\"")))
(unless program
(setq program (eshell-search-path name))
(let* ((esym (eshell-find-alias-function name))
(sym (or esym (intern-soft name))))
(if (and (or esym (and sym (fboundp sym)))
(or eshell-prefer-lisp-functions (not direct)))
(let ((desc (let ((inhibit-redisplay t))
(save-window-excursion
(prog1
(describe-function sym)
(message nil))))))
(setq desc (if desc (substring desc 0
(1- (or (string-match "\n" desc)
(length desc))))
;; This should not happen.
(format "%s is defined, \
but no documentation was found" name)))
(if (buffer-live-p (get-buffer "*Help*"))
(kill-buffer "*Help*"))
(setq program (or desc name))))))
(setq program
(let* ((esym (eshell-find-alias-function name))
(sym (or esym (intern-soft name))))
(if (and (or esym (and sym (fboundp sym)))
(or eshell-prefer-lisp-functions (not direct)))
(or (with-output-to-string
(require 'help-fns)
(princ (format "%s is " sym))
(help-fns-function-description-header sym))
name)
(eshell-search-path name)))))
(if (not program)
(eshell-error (format "which: no %s in (%s)\n"
name (getenv "PATH")))

View file

@ -1110,6 +1110,38 @@ differing font heights."
If FRAME is omitted, describe the currently selected frame."
(cdr (assq 'width (frame-parameters frame))))
(defalias 'frame-border-width 'frame-internal-border-width)
(defalias 'frame-pixel-width 'frame-native-width)
(defalias 'frame-pixel-height 'frame-native-height)
(defun frame-inner-width (&optional frame)
"Return inner width of FRAME in pixels.
FRAME defaults to the selected frame."
(setq frame (window-normalize-frame frame))
(- (frame-native-width frame)
(* 2 (frame-internal-border-width frame))))
(defun frame-inner-height (&optional frame)
"Return inner height of FRAME in pixels.
FRAME defaults to the selected frame."
(setq frame (window-normalize-frame frame))
(- (frame-native-height frame)
(* 2 (frame-internal-border-width frame))))
(defun frame-outer-width (&optional frame)
"Return outer width of FRAME in pixels.
FRAME defaults to the selected frame."
(setq frame (window-normalize-frame frame))
(let ((edges (frame-edges frame 'outer-edges)))
(- (nth 2 edges) (nth 0 edges))))
(defun frame-outer-height (&optional frame)
"Return outer height of FRAME in pixels.
FRAME defaults to the selected frame."
(setq frame (window-normalize-frame frame))
(let ((edges (frame-edges frame 'outer-edges)))
(- (nth 3 edges) (nth 1 edges))))
(declare-function x-list-fonts "xfaces.c"
(pattern &optional face frame maximum width))

View file

@ -560,8 +560,9 @@ FILE is the file where FUNCTION was probably defined."
(setq short rel))))
short))
;;;###autoload
(defun describe-function-1 (function)
(defun help-fns--analyse-function (function)
"Return information about FUNCTION.
Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)."
(let* ((advised (and (symbolp function)
(featurep 'nadvice)
(advice--p (advice--symbol-function function))))
@ -594,22 +595,24 @@ FILE is the file where FUNCTION was probably defined."
(setq f (symbol-function f)))
f))
((subrp def) (intern (subr-name def)))
(t def)))
(sig-key (if (subrp def)
(indirect-function real-def)
real-def))
(file-name (find-lisp-object-file-name function (if aliased 'defun
def)))
(pt1 (with-current-buffer (help-buffer) (point)))
(beg (if (and (or (byte-code-function-p def)
(keymapp def)
(memq (car-safe def) '(macro lambda closure)))
(stringp file-name)
(help-fns--autoloaded-p function file-name))
(if (commandp def)
"an interactive autoloaded "
"an autoloaded ")
(if (commandp def) "an interactive " "a "))))
(t def))))
(list real-function def aliased real-def)))
(defun help-fns-function-description-header (function)
"Print a line describing FUNCTION to `standard-output'."
(pcase-let* ((`(,_real-function ,def ,aliased ,real-def)
(help-fns--analyse-function function))
(file-name (find-lisp-object-file-name function (if aliased 'defun
def)))
(beg (if (and (or (byte-code-function-p def)
(keymapp def)
(memq (car-safe def) '(macro lambda closure)))
(stringp file-name)
(help-fns--autoloaded-p function file-name))
(if (commandp def)
"an interactive autoloaded "
"an autoloaded ")
(if (commandp def) "an interactive " "a "))))
;; Print what kind of function-like object FUNCTION is.
(princ (cond ((or (stringp def) (vectorp def))
@ -676,34 +679,42 @@ FILE is the file where FUNCTION was probably defined."
(re-search-backward (substitute-command-keys "`\\([^`']+\\)'")
nil t)
(help-xref-button 1 'help-function-def function file-name))))
(princ ".")
(with-current-buffer (help-buffer)
(fill-region-as-paragraph (save-excursion (goto-char pt1) (forward-line 0) (point))
(point)))
(terpri)(terpri)
(princ "."))))
(let ((doc-raw (documentation function t))
(key-bindings-buffer (current-buffer)))
;;;###autoload
(defun describe-function-1 (function)
(let ((pt1 (with-current-buffer (help-buffer) (point))))
(help-fns-function-description-header function)
(with-current-buffer (help-buffer)
(fill-region-as-paragraph (save-excursion (goto-char pt1) (forward-line 0) (point))
(point))))
(terpri)(terpri)
;; If the function is autoloaded, and its docstring has
;; key substitution constructs, load the library.
(and (autoloadp real-def) doc-raw
help-enable-auto-load
(string-match "\\([^\\]=\\|[^=]\\|\\`\\)\\\\[[{<]" doc-raw)
(autoload-do-load real-def))
(pcase-let ((`(,real-function ,def ,_aliased ,real-def)
(help-fns--analyse-function function))
(doc-raw (documentation function t))
(key-bindings-buffer (current-buffer)))
(help-fns--key-bindings function)
(with-current-buffer standard-output
(let ((doc (help-fns--signature function doc-raw sig-key
real-function key-bindings-buffer)))
(run-hook-with-args 'help-fns-describe-function-functions function)
(insert "\n"
(or doc "Not documented."))
;; Avoid asking the user annoying questions if she decides
;; to save the help buffer, when her locale's codeset
;; isn't UTF-8.
(unless (memq text-quoting-style '(straight grave))
(set-buffer-file-coding-system 'utf-8))))))))
;; If the function is autoloaded, and its docstring has
;; key substitution constructs, load the library.
(and (autoloadp real-def) doc-raw
help-enable-auto-load
(string-match "\\([^\\]=\\|[^=]\\|\\`\\)\\\\[[{<]" doc-raw)
(autoload-do-load real-def))
(help-fns--key-bindings function)
(with-current-buffer standard-output
(let ((doc (help-fns--signature
function doc-raw
(if (subrp def) (indirect-function real-def) real-def)
real-function key-bindings-buffer)))
(run-hook-with-args 'help-fns-describe-function-functions function)
(insert "\n" (or doc "Not documented.")))
;; Avoid asking the user annoying questions if she decides
;; to save the help buffer, when her locale's codeset
;; isn't UTF-8.
(unless (memq text-quoting-style '(straight grave))
(set-buffer-file-coding-system 'utf-8)))))
;; Add defaults to `help-fns-describe-function-functions'.
(add-hook 'help-fns-describe-function-functions #'help-fns--obsolete)

View file

@ -593,6 +593,39 @@ If INSERT (the prefix arg) is non-nil, insert the message in the buffer."
string
(format "%s (translated from %s)" string otherstring))))))
(defun help--analyze-key (key untranslated)
"Get information about KEY its corresponding UNTRANSLATED events.
Returns a list of the form (BRIEF-DESC DEFN EVENT MOUSE-MSG)."
(if (numberp untranslated)
(setq untranslated (this-single-command-raw-keys)))
(let* ((event (aref key (if (and (symbolp (aref key 0))
(> (length key) 1)
(consp (aref key 1)))
1
0)))
(modifiers (event-modifiers event))
(mouse-msg (if (or (memq 'click modifiers) (memq 'down modifiers)
(memq 'drag modifiers)) " at that spot" ""))
(defn (key-binding key t)))
;; Handle the case where we faked an entry in "Select and Paste" menu.
(when (and (eq defn nil)
(stringp (aref key (1- (length key))))
(eq (key-binding (substring key 0 -1)) 'yank-menu))
(setq defn 'menu-bar-select-yank))
;; Don't bother user with strings from (e.g.) the select-paste menu.
(when (stringp (aref key (1- (length key))))
(aset key (1- (length key)) "(any string)"))
(when (and untranslated
(stringp (aref untranslated (1- (length untranslated)))))
(aset untranslated (1- (length untranslated)) "(any string)"))
(list
;; Now describe the key, perhaps as changed.
(let ((key-desc (help-key-description key untranslated)))
(if (or (null defn) (integerp defn) (equal defn 'undefined))
(format "%s%s is undefined" key-desc mouse-msg)
(format "%s%s runs the command %S" key-desc mouse-msg defn)))
defn event mouse-msg)))
(defun describe-key-briefly (&optional key insert untranslated)
"Print the name of the function KEY invokes. KEY is a string.
If INSERT (the prefix arg) is non-nil, insert the message in the buffer.
@ -603,73 +636,12 @@ the last key hit are used.
If KEY is a menu item or a tool-bar button that is disabled, this command
temporarily enables it to allow getting help on disabled items and buttons."
(interactive
(let ((enable-disabled-menus-and-buttons t)
(cursor-in-echo-area t)
saved-yank-menu)
(unwind-protect
(let (key)
;; If yank-menu is empty, populate it temporarily, so that
;; "Select and Paste" menu can generate a complete event.
(when (null (cdr yank-menu))
(setq saved-yank-menu (copy-sequence yank-menu))
(menu-bar-update-yank-menu "(any string)" nil))
(while
(progn
(setq key (read-key-sequence "Describe the following key, mouse click, or menu item: "))
(and (vectorp key)
(consp (aref key 0))
(symbolp (car (aref key 0)))
(string-match "\\(mouse\\|down\\|click\\|drag\\)"
(symbol-name (car (aref key 0))))
(not (sit-for (/ double-click-time 1000.0) t)))))
;; Clear the echo area message (Bug#7014).
(message nil)
;; If KEY is a down-event, read and discard the
;; corresponding up-event. Note that there are also
;; down-events on scroll bars and mode lines: the actual
;; event then is in the second element of the vector.
(and (vectorp key)
(let ((last-idx (1- (length key))))
(and (eventp (aref key last-idx))
(memq 'down (event-modifiers (aref key last-idx)))))
(read-event))
(list
key
(if current-prefix-arg (prefix-numeric-value current-prefix-arg))
1))
;; Put yank-menu back as it was, if we changed it.
(when saved-yank-menu
(setq yank-menu (copy-sequence saved-yank-menu))
(fset 'yank-menu (cons 'keymap yank-menu))))))
(if (numberp untranslated)
(setq untranslated (this-single-command-raw-keys)))
(let* ((event (if (and (symbolp (aref key 0))
(> (length key) 1)
(consp (aref key 1)))
(aref key 1)
(aref key 0)))
(modifiers (event-modifiers event))
(standard-output (if insert (current-buffer) standard-output))
(mouse-msg (if (or (memq 'click modifiers) (memq 'down modifiers)
(memq 'drag modifiers)) " at that spot" ""))
(defn (key-binding key t))
key-desc)
;; Handle the case where we faked an entry in "Select and Paste" menu.
(if (and (eq defn nil)
(stringp (aref key (1- (length key))))
(eq (key-binding (substring key 0 -1)) 'yank-menu))
(setq defn 'menu-bar-select-yank))
;; Don't bother user with strings from (e.g.) the select-paste menu.
(if (stringp (aref key (1- (length key))))
(aset key (1- (length key)) "(any string)"))
(if (and (> (length untranslated) 0)
(stringp (aref untranslated (1- (length untranslated)))))
(aset untranslated (1- (length untranslated)) "(any string)"))
;; Now describe the key, perhaps as changed.
(setq key-desc (help-key-description key untranslated))
(if (or (null defn) (integerp defn) (equal defn 'undefined))
(princ (format "%s%s is undefined" key-desc mouse-msg))
(princ (format "%s%s runs the command %S" key-desc mouse-msg defn)))))
;; Ignore mouse movement events because it's too easy to miss the
;; message while moving the mouse.
(pcase-let ((`(,key ,_up-event) (help-read-key-sequence 'no-mouse-movement)))
`(,key ,current-prefix-arg 1)))
(princ (car (help--analyze-key key untranslated))
(if insert (current-buffer) standard-output)))
(defun help--key-binding-keymap (key &optional accept-default no-remap position)
"Return a keymap holding a binding for KEY within current keymaps.
@ -734,6 +706,59 @@ function `key-binding'."
(throw 'found x))))
nil)))))
(defun help-read-key-sequence (&optional no-mouse-movement)
"Reads a key sequence from the user.
Returns a list of the form (KEY UP-EVENT), where KEY is the key
sequence, and UP-EVENT is the up-event that was discarded by
reading KEY, or nil.
If NO-MOUSE-MOVEMENT is non-nil, ignore key sequences starting
with `mouse-movement' events."
(let ((enable-disabled-menus-and-buttons t)
(cursor-in-echo-area t)
saved-yank-menu)
(unwind-protect
(let (key)
;; If yank-menu is empty, populate it temporarily, so that
;; "Select and Paste" menu can generate a complete event.
(when (null (cdr yank-menu))
(setq saved-yank-menu (copy-sequence yank-menu))
(menu-bar-update-yank-menu "(any string)" nil))
(while
(pcase (setq key (read-key-sequence "\
Describe the following key, mouse click, or menu item: "))
((and (pred vectorp) (let `(,key0 . ,_) (aref key 0))
(guard (symbolp key0)) (let keyname (symbol-name key0)))
(if no-mouse-movement
(string-match "mouse-movement" keyname)
(and (string-match "\\(mouse\\|down\\|click\\|drag\\)"
keyname)
(not (sit-for (/ double-click-time 1000.0) t)))))))
(list
key
;; If KEY is a down-event, read and include the
;; corresponding up-event. Note that there are also
;; down-events on scroll bars and mode lines: the actual
;; event then is in the second element of the vector.
(and (vectorp key)
(let ((last-idx (1- (length key))))
(and (eventp (aref key last-idx))
(memq 'down (event-modifiers (aref key last-idx)))))
(or (and (eventp (aref key 0))
(memq 'down (event-modifiers (aref key 0)))
;; However, for the C-down-mouse-2 popup
;; menu, there is no subsequent up-event. In
;; this case, the up-event is the next
;; element in the supplied vector.
(= (length key) 1))
(and (> (length key) 1)
(eventp (aref key 1))
(memq 'down (event-modifiers (aref key 1)))))
(read-event))))
;; Put yank-menu back as it was, if we changed it.
(when saved-yank-menu
(setq yank-menu (copy-sequence saved-yank-menu))
(fset 'yank-menu (cons 'keymap yank-menu))))))
(defun describe-key (&optional key untranslated up-event)
"Display documentation of the function invoked by KEY.
KEY can be any kind of a key sequence; it can include keyboard events,
@ -748,83 +773,20 @@ UP-EVENT is the up-event that was discarded by reading KEY, or nil.
If KEY is a menu item or a tool-bar button that is disabled, this command
temporarily enables it to allow getting help on disabled items and buttons."
(interactive
(let ((enable-disabled-menus-and-buttons t)
(cursor-in-echo-area t)
saved-yank-menu)
(unwind-protect
(let (key)
;; If yank-menu is empty, populate it temporarily, so that
;; "Select and Paste" menu can generate a complete event.
(when (null (cdr yank-menu))
(setq saved-yank-menu (copy-sequence yank-menu))
(menu-bar-update-yank-menu "(any string)" nil))
(while
(progn
(setq key (read-key-sequence "Describe the following key, mouse click, or menu item: "))
(and (vectorp key)
(consp (aref key 0))
(symbolp (car (aref key 0)))
(string-match "\\(mouse\\|down\\|click\\|drag\\)"
(symbol-name (car (aref key 0))))
(not (sit-for (/ double-click-time 1000.0) t)))))
(list
key
(prefix-numeric-value current-prefix-arg)
;; If KEY is a down-event, read and include the
;; corresponding up-event. Note that there are also
;; down-events on scroll bars and mode lines: the actual
;; event then is in the second element of the vector.
(and (vectorp key)
(let ((last-idx (1- (length key))))
(and (eventp (aref key last-idx))
(memq 'down (event-modifiers (aref key last-idx)))))
(or (and (eventp (aref key 0))
(memq 'down (event-modifiers (aref key 0)))
;; However, for the C-down-mouse-2 popup
;; menu, there is no subsequent up-event. In
;; this case, the up-event is the next
;; element in the supplied vector.
(= (length key) 1))
(and (> (length key) 1)
(eventp (aref key 1))
(memq 'down (event-modifiers (aref key 1)))))
(read-event))))
;; Put yank-menu back as it was, if we changed it.
(when saved-yank-menu
(setq yank-menu (copy-sequence saved-yank-menu))
(fset 'yank-menu (cons 'keymap yank-menu))))))
(if (numberp untranslated)
(setq untranslated (this-single-command-raw-keys)))
(let* ((event (aref key (if (and (symbolp (aref key 0))
(> (length key) 1)
(consp (aref key 1)))
1
0)))
(modifiers (event-modifiers event))
(mouse-msg (if (or (memq 'click modifiers) (memq 'down modifiers)
(memq 'drag modifiers)) " at that spot" ""))
(defn (key-binding key t))
key-locus key-locus-up key-locus-up-tricky
defn-up defn-up-tricky ev-type
mouse-1-remapped mouse-1-tricky)
;; Handle the case where we faked an entry in "Select and Paste" menu.
(when (and (eq defn nil)
(stringp (aref key (1- (length key))))
(eq (key-binding (substring key 0 -1)) 'yank-menu))
(setq defn 'menu-bar-select-yank))
(if (or (null defn) (integerp defn) (equal defn 'undefined))
(message "%s%s is undefined"
(help-key-description key untranslated) mouse-msg)
(pcase-let ((`(,key ,up-event) (help-read-key-sequence)))
`(,key ,(prefix-numeric-value current-prefix-arg) ,up-event)))
(pcase-let ((`(,brief-desc ,defn ,event ,mouse-msg)
(help--analyze-key key untranslated))
(defn-up nil) (defn-up-tricky nil)
(key-locus-up nil) (key-locus-up-tricky nil)
(mouse-1-remapped nil) (mouse-1-tricky nil)
(ev-type nil))
(if (or (null defn)
(integerp defn)
(equal defn 'undefined))
(message "%s" brief-desc)
(help-setup-xref (list #'describe-function defn)
(called-interactively-p 'interactive))
;; Don't bother user with strings from (e.g.) the select-paste menu.
(when (stringp (aref key (1- (length key))))
(aset key (1- (length key)) "(any string)"))
(when (and untranslated
(stringp (aref untranslated (1- (length untranslated)))))
(aset untranslated (1- (length untranslated))
"(any string)"))
;; Need to do this before erasing *Help* buffer in case event
;; is a mouse click in an existing *Help* buffer.
(when up-event
@ -849,13 +811,12 @@ temporarily enables it to allow getting help on disabled items and buttons."
(aset sequence 0 'mouse-1)
(setq defn-up-tricky (key-binding sequence nil nil (event-start up-event)))
(setq key-locus-up-tricky (help--binding-locus sequence (event-start up-event))))))
(setq key-locus (help--binding-locus key (event-start event)))
(with-help-window (help-buffer)
(princ (help-key-description key untranslated))
(princ (format "%s runs the command %S%s, which is "
mouse-msg defn (if key-locus
(format " (found in %s)" key-locus)
"")))
(princ brief-desc)
(let ((key-locus (help--binding-locus key (event-start event))))
(when key-locus
(princ (format " (found in %s)" key-locus))))
(princ ", which is ")
(describe-function-1 defn)
(when up-event
(unless (or (null defn-up)

View file

@ -4952,7 +4952,7 @@ call other entry points instead, such as `cl-prin1'.
\(fn OBJECT)" nil nil)
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "cl-print" '("cl-print-")))
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "cl-print" '("cl-print-" "help-byte-code")))
;;;***
@ -16542,18 +16542,6 @@ The optional LABEL is used to label the buffer created.
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "holidays" '("holiday-" "calendar-")))
;;;***
;;;### (autoloads nil "html2text" "net/html2text.el" (0 0 0 0))
;;; Generated autoloads from net/html2text.el
(autoload 'html2text "html2text" "\
Convert HTML to plain text in the current buffer.
\(fn)" t nil)
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "html2text" '("html2text-")))
;;;***
;;;### (autoloads nil "htmlfontify" "htmlfontify.el" (0 0 0 0))
@ -30399,7 +30387,7 @@ then `snmpv2-mode-hook'.
;;;### (autoloads nil "soap-client" "net/soap-client.el" (0 0 0 0))
;;; Generated autoloads from net/soap-client.el
(push (purecopy '(soap-client 3 1 2)) package--builtin-versions)
(push (purecopy '(soap-client 3 1 3)) package--builtin-versions)
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "soap-client" '("soap-")))
@ -34165,7 +34153,7 @@ Reenable Ange-FTP, when Tramp is unloaded.
;;;### (autoloads nil "trampver" "net/trampver.el" (0 0 0 0))
;;; Generated autoloads from net/trampver.el
(push (purecopy '(tramp 2 3 2 -1)) package--builtin-versions)
(push (purecopy '(tramp 2 3 2)) package--builtin-versions)
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "trampver" '("tramp-")))

View file

@ -746,7 +746,7 @@ If the current buffer is not a minibuffer, erase its entire contents."
(defcustom completion-auto-help t
"Non-nil means automatically provide help for invalid completion input.
If the value is t the *Completion* buffer is displayed whenever completion
If the value is t the *Completions* buffer is displayed whenever completion
is requested but cannot be done.
If the value is `lazy', the *Completions* buffer is only displayed after
the second failed attempt to complete."

View file

@ -380,7 +380,7 @@ This command must be bound to a mouse click."
(defun mouse-drag-line (start-event line)
"Drag a mode line, header line, or vertical line with the mouse.
START-EVENT is the starting mouse-event of the drag action. LINE
START-EVENT is the starting mouse event of the drag action. LINE
must be one of the symbols `header', `mode', or `vertical'."
;; Give temporary modes such as isearch a chance to turn off.
(run-hooks 'mouse-leave-buffer-hook)
@ -405,29 +405,15 @@ must be one of the symbols `header', `mode', or `vertical'."
;; window's edge we drag.
(cond
((eq line 'header)
(if (window-at-side-p window 'top)
;; We can't drag the header line of a topmost window.
(setq draggable nil)
;; Drag bottom edge of window above the header line.
(setq window (window-in-direction 'above window t))))
((eq line 'mode)
(if (and (window-at-side-p window 'bottom)
;; Allow resizing the minibuffer window if it's on the
;; same frame as and immediately below `window', and it's
;; either active or `resize-mini-windows' is nil.
(let ((minibuffer-window (minibuffer-window frame)))
(not (and (eq (window-frame minibuffer-window) frame)
(or (not resize-mini-windows)
(eq minibuffer-window
(active-minibuffer-window)))))))
(setq draggable nil)))
;; Drag bottom edge of window above the header line.
(setq window (window-in-direction 'above window t)))
((eq line 'mode))
((eq line 'vertical)
(let ((divider-width (frame-right-divider-width frame)))
(when (and (or (not (numberp divider-width))
(zerop divider-width))
(eq (frame-parameter frame 'vertical-scroll-bars) 'left))
(setq window (window-in-direction 'left window t))))))
(let* ((exitfun nil)
(move
(lambda (event) (interactive "e")
@ -530,20 +516,405 @@ must be one of the symbols `header', `mode', or `vertical'."
t (lambda () (setq track-mouse old-track-mouse)))))))
(defun mouse-drag-mode-line (start-event)
"Change the height of a window by dragging on the mode line."
"Change the height of a window by dragging on its mode line.
START-EVENT is the starting mouse event of the drag action.
If the drag happens in a mode line on the bottom of a frame and
that frame's `drag-with-mode-line' parameter is non-nil, drag the
frame instead."
(interactive "e")
(mouse-drag-line start-event 'mode))
(let* ((start (event-start start-event))
(window (posn-window start))
(frame (window-frame window)))
(cond
((not (window-live-p window)))
((or (not (window-at-side-p window 'bottom))
;; Allow resizing the minibuffer window if it's on the
;; same frame as and immediately below `window', and it's
;; either active or `resize-mini-windows' is nil.
(let ((minibuffer-window (minibuffer-window frame)))
(and (eq (window-frame minibuffer-window) frame)
(or (not resize-mini-windows)
(eq minibuffer-window
(active-minibuffer-window))))))
(mouse-drag-line start-event 'mode))
((and (frame-parameter frame 'drag-with-mode-line)
(window-at-side-p window 'bottom)
(let ((minibuffer-window (minibuffer-window frame)))
(not (eq (window-frame minibuffer-window) frame))))
;; Drag frame when the window is on the bottom of its frame and
;; there is no minibuffer window below.
(mouse-drag-frame start-event 'move)))))
(defun mouse-drag-header-line (start-event)
"Change the height of a window by dragging on the header line."
"Change the height of a window by dragging on its header line.
START-EVENT is the starting mouse event of the drag action.
If the drag happens in a header line on the top of a frame and
that frame's `drag-with-header-line' parameter is non-nil, drag
the frame instead."
(interactive "e")
(mouse-drag-line start-event 'header))
(let* ((start (event-start start-event))
(window (posn-window start)))
(if (and (window-live-p window)
(not (window-at-side-p window 'top)))
(mouse-drag-line start-event 'header)
(let ((frame (window-frame window)))
(when (frame-parameter frame 'drag-with-header-line)
(mouse-drag-frame start-event 'move))))))
(defun mouse-drag-vertical-line (start-event)
"Change the width of a window by dragging on the vertical line."
"Change the width of a window by dragging on a vertical line.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
(mouse-drag-line start-event 'vertical))
(defun mouse-resize-frame (frame x-diff y-diff &optional x-move y-move)
"Helper function for `mouse-drag-frame'."
(let* ((frame-x-y (frame-position frame))
(frame-x (car frame-x-y))
(frame-y (cdr frame-x-y))
alist)
(if (> x-diff 0)
(when x-move
(setq x-diff (min x-diff frame-x))
(setq x-move (- frame-x x-diff)))
(let* ((min-width (frame-windows-min-size frame t nil t))
(min-diff (max 0 (- (frame-inner-width frame) min-width))))
(setq x-diff (max x-diff (- min-diff)))
(when x-move
(setq x-move (+ frame-x (- x-diff))))))
(if (> y-diff 0)
(when y-move
(setq y-diff (min y-diff frame-y))
(setq y-move (- frame-y y-diff)))
(let* ((min-height (frame-windows-min-size frame nil nil t))
(min-diff (max 0 (- (frame-inner-height frame) min-height))))
(setq y-diff (max y-diff (- min-diff)))
(when y-move
(setq y-move (+ frame-y (- y-diff))))))
(unless (zerop x-diff)
(when x-move
(push `(left . ,x-move) alist))
(push `(width . (text-pixels . ,(+ (frame-text-width frame) x-diff)))
alist))
(unless (zerop y-diff)
(when y-move
(push `(top . ,y-move) alist))
(push `(height . (text-pixels . ,(+ (frame-text-height frame) y-diff)))
alist))
(when alist
(modify-frame-parameters frame alist))))
(defun mouse-drag-frame (start-event part)
"Drag a frame or one of its edges with the mouse.
START-EVENT is the starting mouse event of the drag action. Its
position window denotes the frame that will be dragged.
PART specifies the part that has been dragged and must be one of
the symbols 'left', 'top', 'right', 'bottom', 'top-left',
'top-right', 'bottom-left', 'bottom-right' to drag an internal
border or edge. If PART equals 'move', this means to move the
frame with the mouse."
;; Give temporary modes such as isearch a chance to turn off.
(run-hooks 'mouse-leave-buffer-hook)
(let* ((echo-keystrokes 0)
(start (event-start start-event))
(window (posn-window start))
;; FRAME is the frame to drag.
(frame (if (window-live-p window)
(window-frame window)
window))
(width (frame-native-width frame))
(height (frame-native-height frame))
;; PARENT is the parent frame of FRAME or, if FRAME is a
;; top-level frame, FRAME's workarea.
(parent (frame-parent frame))
(parent-edges
(if parent
`(0 0 ,(frame-native-width parent) ,(frame-native-height parent))
(let* ((attributes
(car (display-monitor-attributes-list)))
(workarea (assq 'workarea attributes)))
(and workarea
`(,(nth 1 workarea) ,(nth 2 workarea)
,(+ (nth 1 workarea) (nth 3 workarea))
,(+ (nth 2 workarea) (nth 4 workarea)))))))
(parent-left (and parent-edges (nth 0 parent-edges)))
(parent-top (and parent-edges (nth 1 parent-edges)))
(parent-right (and parent-edges (nth 2 parent-edges)))
(parent-bottom (and parent-edges (nth 3 parent-edges)))
;; `pos-x' and `pos-y' record the x- and y-coordinates of the
;; last sampled mouse position. Note that we sample absolute
;; mouse positions to avoid that moving the mouse from one
;; frame into another gets into our way. `last-x' and `last-y'
;; records the x- and y-coordinates of the previously sampled
;; position. The differences between `last-x' and `pos-x' as
;; well as `last-y' and `pos-y' determine the amount the mouse
;; has been dragged between the last two samples.
pos-x-y pos-x pos-y
(last-x-y (mouse-absolute-pixel-position))
(last-x (car last-x-y))
(last-y (cdr last-x-y))
;; `snap-x' and `snap-y' record the x- and y-coordinates of the
;; mouse position when FRAME snapped. As soon as the
;; difference between `pos-x' and `snap-x' (or `pos-y' and
;; `snap-y') exceeds the value of FRAME's `snap-width'
;; parameter, unsnap FRAME (at the respective side). `snap-x'
;; and `snap-y' nil mean FRAME is curerntly not snapped.
snap-x snap-y
(exitfun nil)
(move
(lambda (event)
(interactive "e")
(when (consp event)
(setq pos-x-y (mouse-absolute-pixel-position))
(setq pos-x (car pos-x-y))
(setq pos-y (cdr pos-x-y))
(cond
((eq part 'left)
(mouse-resize-frame frame (- last-x pos-x) 0 t))
((eq part 'top)
(mouse-resize-frame frame 0 (- last-y pos-y) nil t))
((eq part 'right)
(mouse-resize-frame frame (- pos-x last-x) 0))
((eq part 'bottom)
(mouse-resize-frame frame 0 (- pos-y last-y)))
((eq part 'top-left)
(mouse-resize-frame
frame (- last-x pos-x) (- last-y pos-y) t t))
((eq part 'top-right)
(mouse-resize-frame
frame (- pos-x last-x) (- last-y pos-y) nil t))
((eq part 'bottom-left)
(mouse-resize-frame
frame (- last-x pos-x) (- pos-y last-y) t))
((eq part 'bottom-right)
(mouse-resize-frame
frame (- pos-x last-x) (- pos-y last-y)))
((eq part 'move)
(let* ((old-position (frame-position frame))
(old-left (car old-position))
(old-top (cdr old-position))
(left (+ old-left (- pos-x last-x)))
(top (+ old-top (- pos-y last-y)))
right bottom
;; `snap-width' (maybe also a yet to be provided
;; `snap-height') could become floats to handle
;; proportionality wrt PARENT. We don't do any
;; checks on this parameter so far.
(snap-width (frame-parameter frame 'snap-width)))
;; Docking and constraining.
(when (and (numberp snap-width) parent-edges)
(cond
;; Docking at the left parent edge.
((< pos-x last-x)
(cond
((and (> left parent-left)
(<= (- left parent-left) snap-width))
;; Snap when the mouse moved leftward and
;; FRAME's left edge would end up within
;; `snap-width' pixels from PARENT's left edge.
(setq snap-x pos-x)
(setq left parent-left))
((and (<= left parent-left)
(<= (- parent-left left) snap-width)
snap-x (<= (- snap-x pos-x) snap-width))
;; Stay snapped when the mouse moved leftward
;; but not more than `snap-width' pixels from
;; the time FRAME snapped.
(setq left parent-left))
(t
;; Unsnap when the mouse moved more than
;; `snap-width' pixels leftward from the time
;; FRAME snapped.
(setq snap-x nil))))
((> pos-x last-x)
(setq right (+ left width))
(cond
((and (< right parent-right)
(<= (- parent-right right) snap-width))
;; Snap when the mouse moved rightward and
;; FRAME's right edge would end up within
;; `snap-width' pixels from PARENT's right edge.
(setq snap-x pos-x)
(setq left (- parent-right width)))
((and (>= right parent-right)
(<= (- right parent-right) snap-width)
snap-x (<= (- pos-x snap-x) snap-width))
;; Stay snapped when the mouse moved rightward
;; but not more more than `snap-width' pixels
;; from the time FRAME snapped.
(setq left (- parent-right width)))
(t
;; Unsnap when the mouse moved rightward more
;; than `snap-width' pixels from the time FRAME
;; snapped.
(setq snap-x nil)))))
(cond
((< pos-y last-y)
(cond
((and (> top parent-top)
(<= (- top parent-top) snap-width))
;; Snap when the mouse moved upward and FRAME's
;; top edge would end up within `snap-width'
;; pixels from PARENT's top edge.
(setq snap-y pos-y)
(setq top parent-top))
((and (<= top parent-top)
(<= (- parent-top top) snap-width)
snap-y (<= (- snap-y pos-y) snap-width))
;; Stay snapped when the mouse moved upward but
;; not more more than `snap-width' pixels from
;; the time FRAME snapped.
(setq top parent-top))
(t
;; Unsnap when the mouse moved upward more than
;; `snap-width' pixels from the time FRAME
;; snapped.
(setq snap-y nil))))
((> pos-y last-y)
(setq bottom (+ top height))
(cond
((and (< bottom parent-bottom)
(<= (- parent-bottom bottom) snap-width))
;; Snap when the mouse moved downward and
;; FRAME's bottom edge would end up within
;; `snap-width' pixels from PARENT's bottom
;; edge.
(setq snap-y pos-y)
(setq top (- parent-bottom height)))
((and (>= bottom parent-bottom)
(<= (- bottom parent-bottom) snap-width)
snap-y (<= (- pos-y snap-y) snap-width))
;; Stay snapped when the mouse moved downward
;; but not more more than `snap-width' pixels
;; from the time FRAME snapped.
(setq top (- parent-bottom height)))
(t
;; Unsnap when the mouse moved downward more
;; than `snap-width' pixels from the time FRAME
;; snapped.
(setq snap-y nil))))))
;; If requested, constrain FRAME's draggable areas to
;; PARENT's edges. The `top-visible' parameter should
;; be set when FRAME has a draggable header-line. If
;; set to a number, it ascertains that the top of
;; FRAME is always constrained to the top of PARENT
;; and that at least as many pixels of FRAME as
;; specified by that number are visible on each of the
;; three remaining sides of PARENT.
;;
;; The `bottom-visible' parameter should be set when
;; FRAME has a draggable mode-line. If set to a
;; number, it ascertains that the bottom of FRAME is
;; always constrained to the bottom of PARENT and that
;; at least as many pixels of FRAME as specified by
;; that number are visible on each of the three
;; remaining sides of PARENT.
(let ((par (frame-parameter frame 'top-visible))
bottom-visible)
(unless par
(setq par (frame-parameter frame 'bottom-visible))
(setq bottom-visible t))
(when (and (numberp par) parent-edges)
(setq left
(max (min (- parent-right par) left)
(+ (- parent-left width) par)))
(setq top
(if bottom-visible
(min (max top (- parent-top (- height par)))
(- parent-bottom height))
(min (max top parent-top)
(- parent-bottom par))))))
;; Use `modify-frame-parameters' since `left' and
;; `top' may want to move FRAME out of its PARENT.
(modify-frame-parameters
frame
`((left . (+ ,left)) (top . (+ ,top)))))))
(setq last-x pos-x)
(setq last-y pos-y))))
(old-track-mouse track-mouse))
;; Start tracking. The special value 'dragging' signals the
;; display engine to freeze the mouse pointer shape for as long
;; as we drag.
(setq track-mouse 'dragging)
;; Loop reading events and sampling the position of the mouse.
(setq exitfun
(set-transient-map
(let ((map (make-sparse-keymap)))
(define-key map [switch-frame] #'ignore)
(define-key map [select-window] #'ignore)
(define-key map [scroll-bar-movement] #'ignore)
(define-key map [mouse-movement] move)
;; Swallow drag-mouse-1 events to avoid selecting some other window.
(define-key map [drag-mouse-1]
(lambda () (interactive) (funcall exitfun)))
;; Some of the events will of course end up looked up
;; with a mode-line, header-line or vertical-line prefix ...
(define-key map [mode-line] map)
(define-key map [header-line] map)
(define-key map [vertical-line] map)
;; ... and some maybe even with a right- or bottom-divider
;; prefix.
(define-key map [right-divider] map)
(define-key map [bottom-divider] map)
map)
t (lambda () (setq track-mouse old-track-mouse))))))
(defun mouse-drag-left-edge (start-event)
"Drag left edge of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
(mouse-drag-frame start-event 'left))
(defun mouse-drag-top-left-corner (start-event)
"Drag top left corner of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
(mouse-drag-frame start-event 'top-left))
(defun mouse-drag-top-edge (start-event)
"Drag top edge of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
(mouse-drag-frame start-event 'top))
(defun mouse-drag-top-right-corner (start-event)
"Drag top right corner of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
(mouse-drag-frame start-event 'top-right))
(defun mouse-drag-right-edge (start-event)
"Drag right edge of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
(mouse-drag-frame start-event 'right))
(defun mouse-drag-bottom-right-corner (start-event)
"Drag bottom right corner of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
(mouse-drag-frame start-event 'bottom-right))
(defun mouse-drag-bottom-edge (start-event)
"Drag bottom edge of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
(mouse-drag-frame start-event 'bottom))
(defun mouse-drag-bottom-left-corner (start-event)
"Drag bottom left corner of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
(mouse-drag-frame start-event 'bottom-left))
(defcustom mouse-select-region-move-to-beginning nil
"Effect of selecting a region extending backward from double click.
Nil means keep point at the position clicked (region end);
@ -2078,6 +2449,22 @@ is copied instead of being cut."
(global-set-key [bottom-divider down-mouse-1] 'mouse-drag-mode-line)
(global-set-key [bottom-divider mouse-1] 'ignore)
(global-set-key [bottom-divider C-mouse-2] 'mouse-split-window-horizontally)
(global-set-key [left-edge down-mouse-1] 'mouse-drag-left-edge)
(global-set-key [left-edge mouse-1] 'ignore)
(global-set-key [top-left-corner down-mouse-1] 'mouse-drag-top-left-corner)
(global-set-key [top-left-corner mouse-1] 'ignore)
(global-set-key [top-edge down-mouse-1] 'mouse-drag-top-edge)
(global-set-key [top-edge mouse-1] 'ignore)
(global-set-key [top-right-corner down-mouse-1] 'mouse-drag-top-right-corner)
(global-set-key [top-right-corner mouse-1] 'ignore)
(global-set-key [right-edge down-mouse-1] 'mouse-drag-right-edge)
(global-set-key [right-edge mouse-1] 'ignore)
(global-set-key [bottom-right-corner down-mouse-1] 'mouse-drag-bottom-right-corner)
(global-set-key [bottom-right-corner mouse-1] 'ignore)
(global-set-key [bottom-edge down-mouse-1] 'mouse-drag-bottom-edge)
(global-set-key [bottom-edge mouse-1] 'ignore)
(global-set-key [bottom-left-corner down-mouse-1] 'mouse-drag-bottom-left-corner)
(global-set-key [bottom-left-corner mouse-1] 'ignore)
(provide 'mouse)

View file

@ -312,11 +312,19 @@ word(s) will be searched for via `eww-search-prefix'."
(expand-file-name file))))
;;;###autoload
(defun eww-search-words (&optional beg end)
(defun eww-search-words ()
"Search the web for the text between BEG and END.
See the `eww-search-prefix' variable for the search engine used."
(interactive "r")
(eww (buffer-substring beg end)))
If region is active (and not whitespace), search the web for
the text between BEG and END. Else, prompt the user for a search
string. See the `eww-search-prefix' variable for the search
engine used."
(interactive)
(if (use-region-p)
(let ((region-string (buffer-substring (region-beginning) (region-end))))
(if (not (string-match-p "\\`[ \n\t\r\v\f]*\\'" region-string))
(eww region-string)
(call-interactively 'eww)))
(call-interactively 'eww)))
(defun eww-open-in-new-buffer ()
"Fetch link at point in a new EWW buffer."

View file

@ -185,8 +185,8 @@ and other things:
(define-key map [follow-link] 'mouse-face)
(define-key map [mouse-2] 'shr-browse-url)
(define-key map "I" 'shr-insert-image)
(define-key map "w" 'shr-copy-url)
(define-key map "u" 'shr-copy-url)
(define-key map "w" 'shr-maybe-probe-and-copy-url)
(define-key map "u" 'shr-maybe-probe-and-copy-url)
(define-key map "v" 'shr-browse-url)
(define-key map "O" 'shr-save-contents)
(define-key map "\r" 'shr-browse-url)
@ -290,43 +290,59 @@ DOM should be a parse tree as generated by
(forward-line 1)
(delete-region (point) (point-max))))))
(defun shr-copy-url (&optional image-url)
(defun shr-url-at-point (image-url)
"Return the URL under point as a string.
If IMAGE-URL is non-nil, or there is no link under point, but
there is an image under point then copy the URL of the image
under point instead."
(if image-url
(get-text-property (point) 'image-url)
(or (get-text-property (point) 'shr-url)
(get-text-property (point) 'image-url))))
(defun shr-copy-url (url)
"Copy the URL under point to the kill ring.
If IMAGE-URL (the prefix) is non-nil, or there is no link under
point, but there is an image under point then copy the URL of the
image under point instead.
If called twice, then try to fetch the URL and see whether it
redirects somewhere else."
image under point instead."
(interactive (list (shr-url-at-point current-prefix-arg)))
(if (not url)
(message "No URL under point")
(setq url (url-encode-url url))
(kill-new url)
(message "Copied %s" url)))
(defun shr-probe-url (url cont)
"Pass URL's redirect destination to CONT, if it has one.
CONT should be a function of one argument, the redirect
destination URL. If URL is not redirected, then CONT is never
called."
(interactive "P")
(let ((url (if image-url
(get-text-property (point) 'image-url)
(or (get-text-property (point) 'shr-url)
(get-text-property (point) 'image-url)))))
(cond
((not url)
(message "No URL under point"))
;; Resolve redirected URLs.
((equal url (car kill-ring))
(url-retrieve
url
(lambda (a)
(when (and (consp a)
(eq (car a) :redirect))
(with-temp-buffer
(insert (cadr a))
(goto-char (point-min))
;; Remove common tracking junk from the URL.
(when (re-search-forward ".utm_.*" nil t)
(replace-match "" t t))
(message "Copied %s" (buffer-string))
(copy-region-as-kill (point-min) (point-max)))))
nil t))
;; Copy the URL to the kill ring.
(t
(with-temp-buffer
(insert (url-encode-url url))
(copy-region-as-kill (point-min) (point-max))
(message "Copied %s" (buffer-string)))))))
(url-retrieve
url (lambda (a)
(pcase a
(`(:redirect ,destination . ,_)
;; Remove common tracking junk from the URL.
(funcall cont (replace-regexp-in-string
".utm_.*" "" destination)))))
nil t))
(defun shr-probe-and-copy-url (url)
"Copy the URL under point to the kill ring.
Like `shr-copy-url', but additionally fetch URL and use its
redirection destination if it has one."
(interactive (list (shr-url-at-point current-prefix-arg)))
(if url (shr-probe-url url #'shr-copy-url)
(shr-copy-url url)))
(defun shr-maybe-probe-and-copy-url (url)
"Copy the URL under point to the kill ring.
If the URL is already at the front of the kill ring act like
`shr-probe-and-copy-url', otherwise like `shr-copy-url'."
(interactive (list (shr-url-at-point current-prefix-arg)))
(if (equal url (car kill-ring))
(shr-probe-and-copy-url url)
(shr-copy-url url)))
(defun shr-next-link ()
"Skip to the next link."
@ -512,6 +528,7 @@ size, and full-buffer size."
(* (frame-char-width) 2)
0))))
(shr-insert text)
(shr-fill-lines (point-min) (point-max))
(buffer-string)))))
(define-inline shr-char-breakable-p (char)

View file

@ -72,7 +72,7 @@ It is used for TCP/IP devices."
(defconst tramp-adb-ls-toolbox-regexp
(concat
"^[[:space:]]*\\([-[:alpha:]]+\\)" ; \1 permissions
"\\(?:[[:space:]][[:digit:]]+\\)?" ; links (Android 7/ToolBox)
"\\(?:[[:space:]]+[[:digit:]]+\\)?" ; links (Android 7/toybox)
"[[:space:]]*\\([^[:space:]]+\\)" ; \2 username
"[[:space:]]+\\([^[:space:]]+\\)" ; \3 group
"[[:space:]]+\\([[:digit:]]+\\)" ; \4 size
@ -411,15 +411,17 @@ pass to the OPERATION."
(tramp-adb-get-ls-command v)
(tramp-shell-quote-argument localname)))
;; We insert also filename/. and filename/.., because "ls" doesn't.
(narrow-to-region (point) (point))
(tramp-adb-send-command
v (format "%s -d -a -l %s %s"
(tramp-adb-get-ls-command v)
(tramp-shell-quote-argument
(concat (file-name-as-directory localname) "."))
(tramp-shell-quote-argument
(concat (file-name-as-directory localname) ".."))))
(widen))
;; Looks like it does include them in toybox, since Android 6.
(unless (re-search-backward "\\.$" nil t)
(narrow-to-region (point-max) (point-max))
(tramp-adb-send-command
v (format "%s -d -a -l %s %s"
(tramp-adb-get-ls-command v)
(tramp-shell-quote-argument
(concat (file-name-as-directory localname) "."))
(tramp-shell-quote-argument
(concat (file-name-as-directory localname) ".."))))
(widen)))
(tramp-adb-sh-fix-ls-output)
(let ((result (tramp-do-parse-file-attributes-with-ls
v (or id-format 'integer))))
@ -443,11 +445,12 @@ pass to the OPERATION."
(with-tramp-connection-property vec "ls"
(tramp-message vec 5 "Finding a suitable `ls' command")
(cond
;; Can't disable coloring explicitly for toybox ls command
((tramp-adb-send-command-and-check vec "toybox") "ls")
;; Can't disable coloring explicitly for toybox ls command. We
;; must force "ls" to print just one column.
((tramp-adb-send-command-and-check vec "toybox") "env COLUMNS=1 ls")
;; On CyanogenMod based system BusyBox is used and "ls" output
;; coloring is enabled by default. So we try to disable it
;; when possible.
;; coloring is enabled by default. So we try to disable it when
;; possible.
((tramp-adb-send-command-and-check vec "ls --color=never -al /dev/null")
"ls --color=never")
(t "ls"))))
@ -569,13 +572,17 @@ Emacs dired can't find files."
(file-name-as-directory f)
f))
(with-current-buffer (tramp-get-buffer v)
(append
'("." "..")
(delq
nil
(mapcar
(lambda (l) (and (not (string-match "^[[:space:]]*$" l)) l))
(split-string (buffer-string) "\n")))))))))))
(delete-dups
(append
;; In older Android versions, "." and ".." are not
;; included. In newer versions (toybox, since Android
;; 6) they are. We fix this by `delete-dups'.
'("." "..")
(delq
nil
(mapcar
(lambda (l) (and (not (string-match "^[[:space:]]*$" l)) l))
(split-string (buffer-string) "\n"))))))))))))
(defun tramp-adb-handle-file-local-copy (filename)
"Like `file-local-copy' for Tramp files."

View file

@ -252,7 +252,8 @@ If NAME is a remote file name, the local part of NAME is unquoted."
(eval-after-load 'tramp
'(unless
(memq tramp-syntax (tramp-compat-funcall (quote tramp-syntax-values)))
(tramp-change-syntax (tramp-compat-tramp-syntax))))
(tramp-compat-funcall
(quote tramp-change-syntax) (tramp-compat-tramp-syntax))))
(provide 'tramp-compat)

View file

@ -3500,21 +3500,10 @@ the result will be a local, non-Tramp, file name."
(defun tramp-sh-file-name-handler (operation &rest args)
"Invoke remote-shell Tramp file name handler.
Fall back to normal file name handler if no Tramp handler exists."
(when (and tramp-locked (not tramp-locker))
(setq tramp-locked nil)
(tramp-error
(car-safe tramp-current-connection) 'file-error
"Forbidden reentrant call of Tramp"))
(let ((tl tramp-locked))
(setq tramp-locked t)
(unwind-protect
(let ((tramp-locker t))
(save-match-data
(let ((fn (assoc operation tramp-sh-file-name-handler-alist)))
(if fn
(apply (cdr fn) args)
(tramp-run-real-handler operation args)))))
(setq tramp-locked tl))))
(let ((fn (assoc operation tramp-sh-file-name-handler-alist)))
(if fn
(save-match-data (apply (cdr fn) args))
(tramp-run-real-handler operation args))))
;; This must be the last entry, because `identity' always matches.
;;;###tramp-autoload

View file

@ -2053,6 +2053,33 @@ ARGS are the arguments OPERATION has been called with."
`(let ((debug-on-error tramp-debug-on-error))
(condition-case-unless-debug ,var ,bodyform ,@handlers)))
;; In Emacs, there is some concurrency due to timers. If a timer
;; interrupts Tramp and wishes to use the same connection buffer as
;; the "main" Emacs, then garbage might occur in the connection
;; buffer. Therefore, we need to make sure that a timer does not use
;; the same connection buffer as the "main" Emacs. We implement a
;; cheap global lock, instead of locking each connection buffer
;; separately. The global lock is based on two variables,
;; `tramp-locked' and `tramp-locker'. `tramp-locked' is set to true
;; (with setq) to indicate a lock. But Tramp also calls itself during
;; processing of a single file operation, so we need to allow
;; recursive calls. That's where the `tramp-locker' variable comes in
;; -- it is let-bound to t during the execution of the current
;; handler. So if `tramp-locked' is t and `tramp-locker' is also t,
;; then we should just proceed because we have been called
;; recursively. But if `tramp-locker' is nil, then we are a timer
;; interrupting the "main" Emacs, and then we signal an error.
(defvar tramp-locked nil
"If non-nil, then Tramp is currently busy.
Together with `tramp-locker', this implements a locking mechanism
preventing reentrant calls of Tramp.")
(defvar tramp-locker nil
"If non-nil, then a caller has locked Tramp.
Together with `tramp-locked', this implements a locking mechanism
preventing reentrant calls of Tramp.")
;; Main function.
(defun tramp-file-name-handler (operation &rest args)
"Invoke Tramp file name handler.
@ -2090,7 +2117,20 @@ Falls back to normal file name handler if no Tramp file name handler exists."
(setq result
(catch 'non-essential
(catch 'suppress
(apply foreign operation args))))
(when (and tramp-locked (not tramp-locker))
(setq tramp-locked nil)
(tramp-error
(car-safe tramp-current-connection)
'file-error
"Forbidden reentrant call of Tramp"))
(let ((tl tramp-locked))
(setq tramp-locked t)
(unwind-protect
(let ((tramp-locker t))
(apply foreign operation args))
;; Give timers a chance.
(unless (setq tramp-locked tl)
(sit-for 0.001 'nodisp)))))))
(cond
((eq result 'non-essential)
(tramp-message
@ -2145,33 +2185,6 @@ Falls back to normal file name handler if no Tramp file name handler exists."
;; we don't do anything.
(tramp-run-real-handler operation args))))
;; In Emacs, there is some concurrency due to timers. If a timer
;; interrupts Tramp and wishes to use the same connection buffer as
;; the "main" Emacs, then garbage might occur in the connection
;; buffer. Therefore, we need to make sure that a timer does not use
;; the same connection buffer as the "main" Emacs. We implement a
;; cheap global lock, instead of locking each connection buffer
;; separately. The global lock is based on two variables,
;; `tramp-locked' and `tramp-locker'. `tramp-locked' is set to true
;; (with setq) to indicate a lock. But Tramp also calls itself during
;; processing of a single file operation, so we need to allow
;; recursive calls. That's where the `tramp-locker' variable comes in
;; -- it is let-bound to t during the execution of the current
;; handler. So if `tramp-locked' is t and `tramp-locker' is also t,
;; then we should just proceed because we have been called
;; recursively. But if `tramp-locker' is nil, then we are a timer
;; interrupting the "main" Emacs, and then we signal an error.
(defvar tramp-locked nil
"If non-nil, then Tramp is currently busy.
Together with `tramp-locker', this implements a locking mechanism
preventing reentrant calls of Tramp.")
(defvar tramp-locker nil
"If non-nil, then a caller has locked Tramp.
Together with `tramp-locked', this implements a locking mechanism
preventing reentrant calls of Tramp.")
;;;###autoload
(defun tramp-completion-file-name-handler (operation &rest args)
"Invoke Tramp file name completion handler.
@ -3631,31 +3644,17 @@ connection buffer."
"Like `accept-process-output' for Tramp processes.
This is needed in order to hide `last-coding-system-used', which is set
for process communication also."
;; FIXME: There are problems, when an asynchronous process runs in
;; parallel, and also timers are active. See
;; <http://lists.gnu.org/archive/html/tramp-devel/2017-01/msg00010.html>.
(when (and timer-event-last
(string-prefix-p "*tramp/" (process-name proc))
(let (result)
(maphash
(lambda (key _value)
(and (processp key)
(not (string-prefix-p "*tramp/" (process-name key)))
(process-live-p key)
(setq result t)))
tramp-cache-data)
result))
(sit-for 0.01 'nodisp))
(with-current-buffer (process-buffer proc)
(let (buffer-read-only last-coding-system-used)
;; Under Windows XP, accept-process-output doesn't return
;; Under Windows XP, `accept-process-output' doesn't return
;; sometimes. So we add an additional timeout. JUST-THIS-ONE
;; is set due to Bug#12145.
;; is set due to Bug#12145. It is an integer, in order to avoid
;; running timers as well.
(tramp-message
proc 10 "%s %s %s\n%s"
proc (process-status proc)
(with-timeout (timeout)
(accept-process-output proc timeout nil t))
(accept-process-output proc timeout nil 0))
(buffer-string)))))
(defun tramp-check-for-regexp (proc regexp)

View file

@ -7,7 +7,7 @@
;; Maintainer: Michael Albinus <michael.albinus@gmx.de>
;; Keywords: comm, processes
;; Package: tramp
;; Version: 2.3.2-pre
;; Version: 2.3.2
;; This file is part of GNU Emacs.
@ -33,7 +33,7 @@
;; should be changed only there.
;;;###tramp-autoload
(defconst tramp-version "2.3.2-pre"
(defconst tramp-version "2.3.2"
"This version of Tramp.")
;;;###tramp-autoload
@ -55,7 +55,7 @@
;; Check for Emacs version.
(let ((x (if (>= emacs-major-version 24)
"ok"
(format "Tramp 2.3.2-pre is not fit for %s"
(format "Tramp 2.3.2 is not fit for %s"
(when (string-match "^.*$" (emacs-version))
(match-string 0 (emacs-version)))))))
(unless (string-match "\\`ok\\'" x) (error "%s" x)))

View file

@ -3,6 +3,7 @@
;; Copyright (C) 2002-2017 Free Software Foundation, Inc.
;; Author: Joakim Hove <hove@phys.ntnu.no>
;; Obsolete-since: 26.1
;; This file is part of GNU Emacs.
@ -29,6 +30,8 @@
;;
;; The main function is `html2text'.
;; This package was obsoleted by shr.el.
;;; Code:
;;

View file

@ -1915,7 +1915,7 @@ with a brace block."
(save-restriction
(let ((start (point))
(paren-state (c-parse-state))
lim pos end-pos encl-decl-block where)
lim pos end-pos where)
;; Narrow enclosing brace blocks out, as required by the values of
;; `c-defun-tactic', `near', and the position of point.
(when (eq c-defun-tactic 'go-outward)

View file

@ -44,19 +44,12 @@
(load "cc-bytecomp" nil t)))
(eval-and-compile
(defvar c--mapcan-status
(cond ((and (fboundp 'mapcan)
(subrp (symbol-function 'mapcan)))
;; XEmacs
'mapcan)
((locate-file "cl-lib.elc" load-path)
;; Emacs >= 24.3
'cl-mapcan)
(t
;; Emacs <= 24.2
nil))))
(defvar c--cl-library
(if (locate-library "cl-lib")
'cl-lib
'cl)))
(cc-external-require (if (eq c--mapcan-status 'cl-mapcan) 'cl-lib 'cl))
(cc-external-require c--cl-library)
; was (cc-external-require 'cl). ACM 2005/11/29.
; Changed from (eval-when-compile (require 'cl)) back to
; cc-external-require, 2015-08-12.
@ -182,9 +175,12 @@ This variant works around bugs in `eval-when-compile' in various
;; The motivation for this macro is to avoid the irritating message
;; "function `mapcan' from cl package called at runtime" produced by Emacs.
(cond
((eq c--mapcan-status 'mapcan)
((and (fboundp 'mapcan)
(subrp (symbol-function 'mapcan)))
;; XEmacs and Emacs >= 26.
`(mapcan ,fun ,liszt))
((eq c--mapcan-status 'cl-mapcan)
((eq c--cl-library 'cl-lib)
;; Emacs >= 24.3, < 26.
`(cl-mapcan ,fun ,liszt))
(t
;; Emacs <= 24.2. It would be nice to be able to distinguish between
@ -193,13 +189,13 @@ This variant works around bugs in `eval-when-compile' in various
(defmacro c--set-difference (liszt1 liszt2 &rest other-args)
;; Macro to smooth out the renaming of `set-difference' in Emacs 24.3.
(if (eq c--mapcan-status 'cl-mapcan)
(if (eq c--cl-library 'cl-lib)
`(cl-set-difference ,liszt1 ,liszt2 ,@other-args)
`(set-difference ,liszt1 ,liszt2 ,@other-args)))
(defmacro c--intersection (liszt1 liszt2 &rest other-args)
;; Macro to smooth out the renaming of `intersection' in Emacs 24.3.
(if (eq c--mapcan-status 'cl-mapcan)
(if (eq c--cl-library 'cl-lib)
`(cl-intersection ,liszt1 ,liszt2 ,@other-args)
`(intersection ,liszt1 ,liszt2 ,@other-args)))
@ -212,7 +208,7 @@ This variant works around bugs in `eval-when-compile' in various
(defmacro c--delete-duplicates (cl-seq &rest cl-keys)
;; Macro to smooth out the renaming of `delete-duplicates' in Emacs 24.3.
(if (eq c--mapcan-status 'cl-mapcan)
(if (eq c--cl-library 'cl-lib)
`(cl-delete-duplicates ,cl-seq ,@cl-keys)
`(delete-duplicates ,cl-seq ,@cl-keys))))
@ -1175,6 +1171,63 @@ been put there by c-put-char-property. POINT remains unchanged."
nil ,from ,to ,value nil -property-))
;; GNU Emacs
`(c-clear-char-property-with-value-function ,from ,to ,property ,value)))
(defun c-clear-char-property-with-value-on-char-function (from to property
value char)
"Remove all text-properties PROPERTY with value VALUE on
characters with value CHAR from the region [FROM, TO), as tested
by `equal'. These properties are assumed to be over individual
characters, having been put there by c-put-char-property. POINT
remains unchanged."
(let ((place from)
)
(while ; loop round occurrences of (PROPERTY VALUE)
(progn
(while ; loop round changes in PROPERTY till we find VALUE
(and
(< place to)
(not (equal (get-text-property place property) value)))
(setq place (c-next-single-property-change place property nil to)))
(< place to))
(if (eq (char-after place) char)
(remove-text-properties place (1+ place) (cons property nil)))
;; Do we have to do anything with stickiness here?
(setq place (1+ place)))))
(defmacro c-clear-char-property-with-value-on-char (from to property value char)
"Remove all text-properties PROPERTY with value VALUE on
characters with value CHAR from the region [FROM, TO), as tested
by `equal'. These properties are assumed to be over individual
characters, having been put there by c-put-char-property. POINT
remains unchanged."
(if c-use-extents
;; XEmacs
`(let ((-property- ,property)
(-char- ,char))
(map-extents (lambda (ext val)
(if (and (equal (extent-property ext -property-) val)
(eq (char-after
(extent-start-position ext))
-char-))
(delete-extent ext)))
nil ,from ,to ,value nil -property-))
;; Gnu Emacs
`(c-clear-char-property-with-value-on-char-function ,from ,to ,property
,value ,char)))
(defmacro c-put-char-properties-on-char (from to property value char)
;; This needs to be a macro because `property' passed to
;; `c-put-char-property' must be a constant.
"Put the text property PROPERTY with value VALUE on characters
with value CHAR in the region [FROM to)."
`(let ((skip-string (concat "^" (list ,char)))
(-to- ,to))
(save-excursion
(goto-char ,from)
(while (progn (skip-chars-forward skip-string -to-)
(< (point) -to-))
(c-put-char-property (point) ,property ,value)
(forward-char)))))
;; Macros to put overlays (Emacs) or extents (XEmacs) on buffer text.
;; For our purposes, these are characterized by being possible to
@ -1232,6 +1285,8 @@ been put there by c-put-char-property. POINT remains unchanged."
(def-edebug-spec c-put-char-property t)
(def-edebug-spec c-get-char-property t)
(def-edebug-spec c-clear-char-property t)
(def-edebug-spec c-clear-char-property-with-value-on-char t)
(def-edebug-spec c-put-char-properties-on-char t)
(def-edebug-spec c-clear-char-properties t)
(def-edebug-spec c-put-overlay t)
(def-edebug-spec c-delete-overlay t)

View file

@ -4809,7 +4809,6 @@ comment at the start of cc-engine.el for more info."
(c-self-bind-state-cache
(let ((start (point))
state-2
;; A list of syntactically relevant positions in descending
;; order. It's used to avoid scanning repeatedly over
;; potentially large regions with `parse-partial-sexp' to verify
@ -7809,8 +7808,7 @@ comment at the start of cc-engine.el for more info."
;; looking (in C++) like this "FQN::of::base::Class". Move to the start of
;; this construct and return t. If the parsing fails, return nil, leaving
;; point unchanged.
(let ((here (point))
end)
(let (end)
(if (not (c-on-identifier))
nil
(c-simple-skip-symbol-backward)

View file

@ -702,6 +702,36 @@ stuff. Used on level 1 and higher."
t)
(c-put-font-lock-face start (1+ start) 'font-lock-warning-face)))))
(defun c-font-lock-invalid-single-quotes (limit)
;; This function will be called from font-lock for a region bounded by POINT
;; and LIMIT, as though it were to identify a keyword for
;; font-lock-keyword-face. It always returns NIL to inhibit this and
;; prevent a repeat invocation. See elisp/lispref page "Search-based
;; Fontification".
;;
;; This function fontifies invalid single quotes with
;; `font-lock-warning-face'. These are the single quotes which
;; o - aren't inside a literal;
;; o - are marked with a syntax-table text property value '(1); and
;; o - are NOT marked with a non-null c-digit-separator property.
(let ((limits (c-literal-limits))
state beg end)
(if limits
(goto-char (cdr limits))) ; Even for being in a ' '
(while (< (point) limit)
(setq beg (point))
(setq state (parse-partial-sexp (point) limit nil nil nil 'syntax-table))
(setq end (point))
(goto-char beg)
(while (progn (skip-chars-forward "^'" end)
(< (point) end))
(if (and (equal (c-get-char-property (point) 'syntax-table) '(1))
(not (c-get-char-property (point) 'c-digit-separator)))
(c-put-font-lock-face (point) (1+ (point)) font-lock-warning-face))
(forward-char))
(parse-partial-sexp end limit nil nil state 'syntax-table)))
nil)
(c-lang-defconst c-basic-matchers-before
"Font lock matchers for basic keywords, labels, references and various
other easily recognizable things that should be fontified before generic
@ -723,6 +753,9 @@ casts and declarations are fontified. Used on level 2 and higher."
(concat ".\\(" c-string-limit-regexp "\\)")
'((c-font-lock-invalid-string)))
;; Invalid single quotes.
c-font-lock-invalid-single-quotes
;; Fontify C++ raw strings.
,@(when (c-major-mode-is 'c++-mode)
'(c-font-lock-raw-strings))
@ -777,7 +810,8 @@ casts and declarations are fontified. Used on level 2 and higher."
(c-backward-syntactic-ws)
(setq id-end (point))
(< (skip-chars-backward
,(c-lang-const c-symbol-chars)) 0))
,(c-lang-const c-symbol-chars))
0))
(not (get-text-property (point) 'face)))
(c-put-font-lock-face (point) id-end
c-reference-face-name)
@ -1013,13 +1047,11 @@ casts and declarations are fontified. Used on level 2 and higher."
;;(message "c-font-lock-declarators from %s to %s" (point) limit)
(c-fontify-types-and-refs
((pos (point)) next-pos id-start id-end
((pos (point)) next-pos id-start
decl-res
paren-depth
id-face got-type got-init
c-last-identifier-range
(separator-prop (if types 'c-decl-type-start 'c-decl-id-start))
brackets-after-id)
(separator-prop (if types 'c-decl-type-start 'c-decl-id-start)))
;; The following `while' fontifies a single declarator id each time round.
;; It loops only when LIST is non-nil.
@ -1036,7 +1068,7 @@ casts and declarations are fontified. Used on level 2 and higher."
(forward-char)
(c-forward-syntactic-ws)
(looking-at "[*&]")))
(not (car (cddr decl-res))) ; brackets-after-id
(not (car (cddr decl-res)))
(or (not (c-major-mode-is 'c++-mode))
(save-excursion
(let (c-last-identifier-range)
@ -1375,7 +1407,6 @@ casts and declarations are fontified. Used on level 2 and higher."
;; it finds any. That's necessary so that we later will
;; stop inside them to fontify types there.
(c-parse-and-markup-<>-arglists t)
lbrace ; position of some {.
;; The font-lock package in Emacs is known to clobber
;; `parse-sexp-lookup-properties' (when it exists).
(parse-sexp-lookup-properties
@ -2503,7 +2534,7 @@ need for `c++-font-lock-extra-types'.")
limit
"[-+]"
nil
(lambda (match-pos inside-macro &optional top-level)
(lambda (_match-pos _inside-macro &optional _top-level)
(forward-char)
(c-font-lock-objc-method))))
nil)

View file

@ -130,7 +130,7 @@
;; This file is not always loaded. See note above.
(cc-external-require (if (eq c--mapcan-status 'cl-mapcan) 'cl-lib 'cl))
(cc-external-require (if (eq c--cl-library 'cl-lib) 'cl-lib 'cl))
;;; Setup for the `c-lang-defvar' system.
@ -474,18 +474,19 @@ so that all identifiers are recognized as words.")
;; The value here may be a list of functions or a single function.
t nil
c++ '(c-extend-region-for-CPP
; c-before-after-change-extend-region-for-lambda-capture ; doesn't seem needed.
c-before-change-check-raw-strings
c-before-change-check-<>-operators
c-depropertize-CPP
c-before-after-change-digit-quote
c-invalidate-macro-cache
c-truncate-bs-cache)
c-truncate-bs-cache
c-parse-quotes-before-change)
(c objc) '(c-extend-region-for-CPP
c-depropertize-CPP
c-invalidate-macro-cache
c-truncate-bs-cache)
;; java 'c-before-change-check-<>-operators
c-truncate-bs-cache
c-parse-quotes-before-change)
java 'c-parse-quotes-before-change
;; 'c-before-change-check-<>-operators
awk 'c-awk-record-region-clear-NL)
(c-lang-defvar c-get-state-before-change-functions
(let ((fs (c-lang-const c-get-state-before-change-functions)))
@ -515,18 +516,19 @@ parameters \(point-min) and \(point-max).")
t '(c-depropertize-new-text
c-change-expand-fl-region)
(c objc) '(c-depropertize-new-text
c-parse-quotes-after-change
c-extend-font-lock-region-for-macros
c-neutralize-syntax-in-and-mark-CPP
c-change-expand-fl-region)
c++ '(c-depropertize-new-text
c-parse-quotes-after-change
c-extend-font-lock-region-for-macros
; c-before-after-change-extend-region-for-lambda-capture ; doesn't seem needed.
c-before-after-change-digit-quote
c-after-change-re-mark-raw-strings
c-neutralize-syntax-in-and-mark-CPP
c-restore-<>-properties
c-change-expand-fl-region)
java '(c-depropertize-new-text
c-parse-quotes-after-change
c-restore-<>-properties
c-change-expand-fl-region)
awk '(c-depropertize-new-text
@ -609,6 +611,12 @@ EOL terminated statements."
(c c++ objc) t)
(c-lang-defvar c-has-bitfields (c-lang-const c-has-bitfields))
(c-lang-defconst c-has-quoted-numbers
"Whether the language has numbers quoted like 4'294'967'295."
t nil
c++ t)
(c-lang-defvar c-has-quoted-numbers (c-lang-const c-has-quoted-numbers))
(c-lang-defconst c-modified-constant
"Regexp that matches a “modified” constant literal such as \"L\\='a\\='\",
a long character. In particular, this recognizes forms of constant

View file

@ -1083,101 +1083,219 @@ Note that the style variables are always made local to the buffer."
(forward-line)) ; no infinite loop with, e.g., "#//"
)))))
(defun c-before-after-change-digit-quote (beg end &optional old-len)
;; This function either removes or applies the punctuation value ('(1)) of
;; the `syntax-table' text property on single quote marks which are
;; separator characters in long integer literals, e.g. "4'294'967'295". It
;; applies to both decimal/octal and hex literals. (FIXME (2016-06-10): it
;; should also apply to binary literals.)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Parsing of quotes.
;;
;; Valid digit separators in numbers will get the syntax-table "punctuation"
;; property, '(1), and also the text property `c-digit-separator' value t.
;;
;; Invalid other quotes (i.e. those not validly bounding a single character,
;; or escaped character) will get the syntax-table "punctuation" property,
;; '(1), too.
;;
;; Note that, for convenience, these properties are applied even inside
;; comments and strings.
(defconst c-maybe-quoted-number-head
(concat
"\\(0\\("
"\\([Xx]\\([0-9a-fA-F]\\('[0-9a-fA-F]\\|[0-9a-fA-F]\\)*'?\\)?\\)"
"\\|"
"\\([Bb]\\([01]\\('[01]\\|[01]\\)*'?\\)?\\)"
"\\|"
"\\('[0-7]\\|[0-7]\\)*'?"
"\\)"
"\\|"
"[1-9]\\('[0-9]\\|[0-9]\\)*'?"
"\\)")
"Regexp matching the head of a numeric literal, including with digit separators.")
(defun c-quoted-number-head-before-point ()
;; Return non-nil when the head of a possibly quoted number is found
;; immediately before point. The value returned in this case is the buffer
;; position of the start of the head. That position is also in
;; (match-beginning 0).
(when c-has-quoted-numbers
(save-excursion
(let ((here (point))
found)
(skip-chars-backward "0-9a-fA-F'")
(if (and (memq (char-before) '(?x ?X))
(eq (char-before (1- (point))) ?0))
(backward-char 2))
(while
(and
(setq found
(search-forward-regexp c-maybe-quoted-number-head here t))
(< found here)))
(and (eq found here) (match-beginning 0))))))
(defconst c-maybe-quoted-number-tail
(concat
"\\("
"\\([xX']?[0-9a-fA-F]\\('[0-9a-fA-F]\\|[0-9a-fA-F]\\)*\\)"
"\\|"
"\\([bB']?[01]\\('[01]\\|[01]\\)*\\)"
"\\|"
"\\('?[0-9]\\('[0-9]\\|[0-9]\\)*\\)"
"\\)")
"Regexp matching the tail of a numeric literal, including with digit separators.
Note that this is a strict tail, so won't match, e.g. \"0x....\".")
(defun c-quoted-number-tail-after-point ()
;; Return non-nil when a proper tail of a possibly quoted number is found
;; immediately after point. The value returned in this case is the buffer
;; position of the end of the tail. That position is also in (match-end 0).
(when c-has-quoted-numbers
(and (looking-at c-maybe-quoted-number-tail)
(match-end 0))))
(defconst c-maybe-quoted-number
(concat
"\\(0\\("
"\\([Xx][0-9a-fA-F]\\('[0-9a-fA-F]\\|[0-9a-fA-F]\\)*\\)"
"\\|"
"\\([Bb][01]\\('[01]\\|[01]\\)*\\)"
"\\|"
"\\('[0-7]\\|[0-7]\\)*"
"\\)"
"\\|"
"[1-9]\\('[0-9]\\|[0-9]\\)*"
"\\)")
"Regexp matching a numeric literal, including with digit separators.")
(defun c-quoted-number-straddling-point ()
;; Return non-nil if a definitely quoted number starts before point and ends
;; after point. In this case the number is bounded by (match-beginning 0)
;; and (match-end 0).
(when c-has-quoted-numbers
(save-excursion
(let ((here (point))
(bound (progn (skip-chars-forward "0-9a-fA-F'") (point))))
(goto-char here)
(when (< (skip-chars-backward "0-9a-fA-F'") 0)
(if (and (memq (char-before) '(?x ?X))
(eq (char-before (1- (point))) ?0))
(backward-char 2))
(while (and (search-forward-regexp c-maybe-quoted-number bound t)
(<= (match-end 0) here)))
(and (< (match-beginning 0) here)
(> (match-end 0) here)
(save-match-data
(goto-char (match-beginning 0))
(save-excursion (search-forward "'" (match-end 0) t)))))))))
(defun c-parse-quotes-before-change (beg end)
;; This function analyzes 's near the region (c-new-BEG c-new-END), amending
;; those two variables as needed to include 's into that region when they
;; might be syntactically relevant to the change in progress.
;;
;; In both uses of the function, the `syntax-table' properties are
;; removed/applied only on quote marks which appear to be digit separators.
;; Having amended that region, the function removes pertinent text
;; properties (syntax-table properties with value '(1) and c-digit-separator
;; props with value t) from 's in it. This operation is performed even
;; within strings and comments.
;;
;; Point is undefined on both entry and exit to this function, and the
;; return value has no significance. The function is called solely as a
;; before-change function (see `c-get-state-before-change-functions') and as
;; an after change function (see `c-before-font-lock-functions', with the
;; parameters BEG, END, and (optionally) OLD-LEN being given the standard
;; values for before/after-change functions.
(c-save-buffer-state ((num-begin c-new-BEG) digit-re try-end)
(goto-char c-new-END)
(when (looking-at "\\(x\\)?[0-9a-fA-F']+")
(setq c-new-END (match-end 0)))
;; This function is called exclusively as a before-change function via the
;; variable `c-get-state-before-change-functions'.
(c-save-buffer-state (p-limit limits found)
;; Special consideraton for deleting \ from '\''.
(if (and (> end beg)
(eq (char-before end) ?\\)
(<= c-new-END end))
(setq c-new-END (min (1+ end) (point-max))))
;; Do we have a ' (or something like ',',',',',') within range of
;; c-new-BEG?
(goto-char c-new-BEG)
(when (looking-at "\\(x?\\)[0-9a-fA-F']")
(if (re-search-backward "\\(0x\\)?[0-9a-fA-F]*\\=" nil t)
(setq c-new-BEG (point))))
(setq p-limit (max (- (point) 2) (point-min)))
(while (and (skip-chars-backward "^\\\\'" p-limit)
(> (point) p-limit))
(when (eq (char-before) ?\\)
(setq p-limit (max (1- p-limit) (point-min))))
(backward-char)
(setq c-new-BEG (point)))
(beginning-of-line)
(while (and
(setq found (search-forward-regexp "\\('\\([^'\\]\\|\\\\.\\)\\)*'"
c-new-BEG 'limit))
(< (point) (1- c-new-BEG))))
(if found
(setq c-new-BEG
(if (and (eq (point) (1- c-new-BEG))
(eq (char-after) ?')) ; "''" before c-new-BEG.
(1- c-new-BEG)
(match-beginning 0))))
(while
(re-search-forward "[0-9a-fA-F]'[0-9a-fA-F]" c-new-END t)
(setq try-end (1- (point)))
(re-search-backward "[^0-9a-fA-F']" num-begin t)
(setq digit-re
(cond
((and (not (bobp)) (eq (char-before) ?0) (memq (char-after) '(?x ?X)))
"[0-9a-fA-F]")
((and (eq (char-after (1+ (point))) ?0)
(memq (char-after (+ 2 (point))) '(?b ?B)))
"[01]")
((memq (char-after (1+ (point))) '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9))
"[0-9]")
(t nil)))
(when digit-re
(cond ((eq (char-after) ?x) (forward-char))
((looking-at ".?0[Bb]") (goto-char (match-end 0)))
((looking-at digit-re))
(t (forward-char)))
(when (not (c-in-literal))
(let ((num-end ; End of valid sequence of digits/quotes.
(save-excursion
(re-search-forward
(concat "\\=\\(" digit-re "+'\\)*" digit-re "+") nil t)
(point))))
(setq try-end ; End of sequence of digits/quotes
;; Check for a number with quote separators straddling c-new-BEG
(when c-has-quoted-numbers
(goto-char c-new-BEG)
(when ;; (c-quoted-number-straddling-point)
(c-quoted-number-head-before-point)
(setq c-new-BEG (match-beginning 0))))
;; Do we have a ' (or something like ',',',',...,',') within range of
;; c-new-END?
(goto-char c-new-END)
(setq p-limit (min (+ (point) 2) (point-max)))
(while (and (skip-chars-forward "^\\\\'" p-limit)
(< (point) p-limit))
(when (eq (char-after) ?\\)
(setq p-limit (min (1+ p-limit) (point-max))))
(forward-char)
(setq c-new-END (point)))
(if (looking-at "[^']?\\('\\([^'\\]\\|\\\\.\\)\\)*'")
(setq c-new-END (match-end 0)))
;; Check for a number with quote separators straddling c-new-END.
(when c-has-quoted-numbers
(goto-char c-new-END)
(when ;; (c-quoted-number-straddling-point)
(c-quoted-number-tail-after-point)
(setq c-new-END (match-end 0))))
;; Remove the '(1) syntax-table property from all "'"s within (c-new-BEG
;; c-new-END).
(c-clear-char-property-with-value-on-char
c-new-BEG c-new-END
'syntax-table '(1)
?')
;; Remove the c-digit-separator text property from the same "'"s.
(when c-has-quoted-numbers
(c-clear-char-property-with-value-on-char
c-new-BEG c-new-END
'c-digit-separator t
?'))))
(defun c-parse-quotes-after-change (beg end old-len)
;; This function applies syntax-table properties (value '(1)) and
;; c-digit-separator properties as needed to 's within the range (c-new-BEG
;; c-new-END). This operation is performed even within strings and
;; comments.
;;
;; This function is called exclusively as an after-change function via the
;; variable `c-before-font-lock-functions'.
(c-save-buffer-state (p-limit limits num-beg num-end clear-from-BEG-to)
;; Apply the needed syntax-table and c-digit-separator text properties to
;; quotes.
(goto-char c-new-BEG)
(while (and (< (point) c-new-END)
(search-forward "'" c-new-END 'limit))
(cond ((and (eq (char-before (1- (point))) ?\\)
;; Check we've got an odd number of \s, here.
(save-excursion
(re-search-forward
(concat "\\=\\(" digit-re "\\|'\\)+") nil t)
(point)))
(while (re-search-forward
(concat digit-re "\\('\\)" digit-re) num-end t)
(if old-len ; i.e. are we in an after-change function?
(c-put-char-property (match-beginning 1) 'syntax-table '(1))
(c-clear-char-property (match-beginning 1) 'syntax-table))
(backward-char)))))
(goto-char try-end)
(setq num-begin (point)))))
;; The following doesn't seem needed at the moment (2016-08-15).
;; (defun c-before-after-change-extend-region-for-lambda-capture
;; (_beg _end &optional _old-len)
;; ;; In C++ Mode, extend the region (c-new-BEG c-new-END) to cover any lambda
;; ;; function capture lists we happen to be inside. This function is expected
;; ;; to be called both as a before-change and after change function.
;; ;;
;; ;; Note that these things _might_ be nested, with a capture list looking
;; ;; like:
;; ;;
;; ;; [ ...., &foo = [..](){...}(..), ... ]
;; ;;
;; ;; . What a wonderful language is C++. ;-)
;; (c-save-buffer-state (paren-state pos)
;; (goto-char c-new-BEG)
;; (setq paren-state (c-parse-state))
;; (while (setq pos (c-pull-open-brace paren-state))
;; (goto-char pos)
;; (when (c-looking-at-c++-lambda-capture-list)
;; (setq c-new-BEG (min c-new-BEG pos))
;; (if (c-go-list-forward)
;; (setq c-new-END (max c-new-END (point))))))
;; (goto-char c-new-END)
;; (setq paren-state (c-parse-state))
;; (while (setq pos (c-pull-open-brace paren-state))
;; (goto-char pos)
;; (when (c-looking-at-c++-lambda-capture-list)
;; (setq c-new-BEG (min c-new-BEG pos))
;; (if (c-go-list-forward)
;; (setq c-new-END (max c-new-END (point))))))))
(backward-char)
(eq (logand (skip-chars-backward "\\\\") 1) 1)))) ; not a real '.
((c-quoted-number-straddling-point)
(setq num-beg (match-beginning 0)
num-end (match-end 0))
(c-put-char-properties-on-char num-beg num-end
'syntax-table '(1) ?')
(c-put-char-properties-on-char num-beg num-end
'c-digit-separator t ?')
(goto-char num-end))
((looking-at "\\([^\\']\\|\\\\.\\)'") ; balanced quoted expression.
(goto-char (match-end 0)))
(t (c-put-char-property (1- (point)) 'syntax-table '(1)))))))
(defun c-before-change (beg end)
;; Function to be put on `before-change-functions'. Primarily, this calls

View file

@ -47,6 +47,7 @@
;; `c-add-style' often contains references to functions defined there.
;; Silence the compiler.
(cc-bytecomp-defun c-guess-basic-syntax)
(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs

View file

@ -353,8 +353,6 @@ information):
Quotes all \"#\" characters that don't correspond to actual
Tcl comments. (Useful when editing code not originally created
with this mode).
`tcl-auto-fill-mode'
Auto-filling of Tcl comments.
Add functions to the hook with `add-hook':
@ -1413,6 +1411,9 @@ Prefix argument means switch to the Tcl buffer afterwards."
(defun tcl-auto-fill-mode (&optional arg)
"Like `auto-fill-mode', but sets `comment-auto-fill-only-comments'."
(declare
(obsolete
"Use `auto-fill-mode' with `comment-auto-fill-only-comments'." "26.1"))
(interactive "P")
(auto-fill-mode arg)
(if auto-fill-function

View file

@ -475,6 +475,9 @@ two markers or an overlay. Otherwise, it is nil."
(t
(error "Unknown selection type: %S" type)))))
;; Most programs are unable to handle NUL bytes in strings.
(setq str (replace-regexp-in-string "\0" "\\0" str t t))
(setq next-selection-coding-system nil)
(cons type str))))

View file

@ -437,7 +437,7 @@ is nil if SYM is not a symbol that names a cell."
(declare (debug t))
`(let ((rc (and (symbolp ,sym) (get ,sym 'ses-cell))))
(if (eq rc :ses-named)
(gethash ,sym ses--named-cell-hashmap)
(and ses--named-cell-hashmap (gethash ,sym ses--named-cell-hashmap))
rc)))
(defun ses-cell-p (cell)
@ -868,27 +868,39 @@ means Emacs will crash if FORMULA contains a circular list."
(oldref (ses-formula-references old))
(newref (ses-formula-references formula))
(inhibit-quit t)
not-a-cell-ref-list
x xrow xcol)
(cl-pushnew sym ses--deferred-recalc)
;;Delete old references from this cell. Skip the ones that are also
;;in the new list.
(dolist (ref oldref)
(unless (memq ref newref)
(setq x (ses-sym-rowcol ref)
xrow (car x)
xcol (cdr x))
(ses-set-cell xrow xcol 'references
(delq sym (ses-cell-references xrow xcol)))))
;; because we do not cancel edit when the user provides a
;; false reference in it, then we need to check that ref
;; points to a cell that is within the spreadsheet.
(setq x (ses-sym-rowcol ref))
(and x
(< (setq xrow (car x)) ses--numrows)
(< (setq xcol (cdr x)) ses--numcols)
(ses-set-cell xrow xcol 'references
(delq sym (ses-cell-references xrow xcol))))))
;;Add new ones. Skip ones left over from old list
(dolist (ref newref)
(setq x (ses-sym-rowcol ref)
xrow (car x)
xcol (cdr x)
x (ses-cell-references xrow xcol))
(or (memq sym x)
(ses-set-cell xrow xcol 'references (cons sym x))))
(setq x (ses-sym-rowcol ref))
;;Do not trust the user, the reference may be outside the spreadsheet
(if (and
x
(< (setq xrow (car x)) ses--numrows)
(< (setq xcol (cdr x)) ses--numcols))
(progn
(setq x (ses-cell-references xrow xcol))
(or (memq sym x)
(ses-set-cell xrow xcol 'references (cons sym x))))
(cl-pushnew ref not-a-cell-ref-list)))
(ses-formula-record formula)
(ses-set-cell row col 'formula formula))))
(ses-set-cell row col 'formula formula)
(and not-a-cell-ref-list
(error "Found in formula cells not in spreadsheet: %S" not-a-cell-ref-list)))))
(defun ses-repair-cell-reference-all ()
@ -1529,7 +1541,13 @@ by (ROWINCR,COLINCR)."
;;Relocate this variable, unless it is a named cell
(if (eq (get sym 'ses-cell) :ses-named)
sym
(ses-create-cell-symbol row col))
;; otherwise, we create the relocated cell symbol because
;; ses-cell-symbol gives the old symbols, however since
;; renamed cell are not relocated we keep the relocated
;; cell old symbol in this case.
(if (eq (get (setq sym (ses-cell-symbol row col)) 'ses-cell) :ses-named)
sym
(ses-create-cell-symbol row col)))
;;Delete reference to a deleted cell
nil))))
@ -2337,7 +2355,8 @@ to are recalculated first."
"Recalculate and reprint all cells."
(interactive "*")
(let ((startcell (ses--cell-at-pos (point)))
(ses--curcell (cons 'A1 (ses-cell-symbol (1- ses--numrows)
(ses--curcell (cons (ses-cell-symbol 0 0)
(ses-cell-symbol (1- ses--numrows)
(1- ses--numcols)))))
(ses-recalculate-cell ses--curcell)
(ses-jump-safe startcell)))

View file

@ -121,6 +121,7 @@ BODY should be a list of Lisp expressions.
(defmacro setq-local (var val)
"Set variable VAR to value VAL in current buffer."
;; Can't use backquote here, it's too early in the bootstrap.
(declare (debug (symbolp form)))
(list 'set (list 'make-local-variable (list 'quote var)) val))
(defmacro defvar-local (var val &optional docstring)
@ -4513,7 +4514,8 @@ EVALD, FUNC, ARGS, FLAGS are as in `mapbacktrace'."
(defun backtrace ()
"Print a trace of Lisp function calls currently active.
Output stream used is value of `standard-output'."
(let ((print-level (or print-level 8)))
(let ((print-level (or print-level 8))
(print-escape-control-characters t))
(mapbacktrace #'backtrace--print-frame 'backtrace)))
(defun backtrace-frames (&optional base)

View file

@ -396,7 +396,7 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.")
;;; Fix interface to (X-specific) mouse.el
(defun w32--set-selection (type value)
(if (eq type 'CLIPBOARD)
(w32-set-clipboard-data value)
(w32-set-clipboard-data (replace-regexp-in-string "\0" "\\0" value t t))
(put 'x-selections (or type 'PRIMARY) value)))
(defun w32--get-selection (&optional type data-type)

View file

@ -119,7 +119,8 @@ the value of `tooltip-y-offset' is ignored."
(defcustom tooltip-frame-parameters
'((name . "tooltip")
(internal-border-width . 2)
(border-width . 1))
(border-width . 1)
(no-special-glyphs . t))
"Frame parameters used for tooltips.
If `left' or `top' parameters are included, they specify the absolute
@ -130,7 +131,8 @@ of the `tooltip' face are used instead."
:type '(repeat (cons :format "%v"
(symbol :tag "Parameter")
(sexp :tag "Value")))
:group 'tooltip)
:group 'tooltip
:version "26.1")
(defface tooltip
'((((class color))

View file

@ -1,4 +1,4 @@
;;; url-history.el --- Global history tracking for URL package
;;; url-history.el --- Global history tracking for URL package -*- lexical-binding:t -*-
;; Copyright (C) 1996-1999, 2004-2017 Free Software Foundation, Inc.
@ -106,7 +106,7 @@ to run the `url-history-setup-save-timer' function manually."
(defun url-history-update-url (url time)
(setq url-history-changed-since-last-save t)
(puthash (if (vectorp url) (url-recreate-url url) url) time
(puthash (if (url-p url) (url-recreate-url url) url) time
url-history-hash-table))
(autoload 'url-make-private-file "url-util")
@ -157,6 +157,7 @@ user for what type to save as."
(gethash url url-history-hash-table nil))
(defun url-completion-function (string predicate function)
(declare (obsolete url-history-hash-table "26.1"))
;; Completion function to complete urls from the history.
;; This is obsolete since we can now pass the hash-table directly as a
;; completion table.
@ -164,7 +165,7 @@ user for what type to save as."
(cond
((eq function nil)
(let ((list nil))
(maphash (lambda (key val) (push key list))
(maphash (lambda (key _) (push key list))
url-history-hash-table)
;; Not sure why we bother reversing the list. --Stef
(try-completion string (nreverse list) predicate)))
@ -172,7 +173,7 @@ user for what type to save as."
(let ((stub (concat "\\`" (regexp-quote string)))
(retval nil))
(maphash
(lambda (url time)
(lambda (url _)
(if (string-match stub url) (push url retval)))
url-history-hash-table)
retval))

View file

@ -3703,7 +3703,7 @@ are one more than the actual value of these edges. Note that if
ABSOLUTE is non-nil, PIXELWISE is implicitly non-nil too."
(let* ((window (window-normalize-window window body))
(frame (window-frame window))
(border-width (frame-border-width frame))
(border-width (frame-internal-border-width frame))
(char-width (frame-char-width frame))
(char-height (frame-char-height frame))
(left (if pixelwise
@ -4572,12 +4572,13 @@ The function is called with one argument - a frame.
Functions affected by this option are those that bury a buffer
shown in a separate frame like `quit-window' and `bury-buffer'."
:type '(choice (const :tag "Iconify" iconify-frame)
(const :tag "Make invisible" make-frame-invisible)
(const :tag "Delete" delete-frame)
(const :tag "Do nothing" ignore)
function)
:group 'windows
:group 'frames
:version "24.1")
:version "26.1")
(defun window--delete (&optional window dedicated-only kill)
"Delete WINDOW if possible.
@ -4595,7 +4596,9 @@ if WINDOW gets deleted or its frame is auto-hidden."
(cond
(kill
(delete-frame frame))
((functionp frame-auto-hide-function)
((functionp (frame-parameter frame 'auto-hide-function))
(funcall (frame-parameter frame 'auto-hide-function)))
((functionp frame-auto-hide-function)
(funcall frame-auto-hide-function frame))))
'frame)
(deletable
@ -6734,15 +6737,17 @@ live."
window))
(defun window--maybe-raise-frame (frame)
(let ((visible (frame-visible-p frame)))
(unless (or (not visible)
;; Assume the selected frame is already visible enough.
(eq frame (selected-frame))
;; Assume the frame from which we invoked the
;; minibuffer is visible.
(and (minibuffer-window-active-p (selected-window))
(eq frame (window-frame (minibuffer-selected-window)))))
(raise-frame frame))))
(make-frame-visible frame)
(unless (or (frame-parameter frame 'no-focus-on-map)
;; Don't raise frames that should not get focus.
(frame-parameter frame 'no-accept-focus)
;; Assume the selected frame is already visible enough.
(eq frame (selected-frame))
;; Assume the frame from which we invoked the
;; minibuffer is visible.
(and (minibuffer-window-active-p (selected-window))
(eq frame (window-frame (minibuffer-selected-window)))))
(raise-frame frame)))
;; FIXME: Not implemented.
;; FIXME: By the way, there could be more levels of dedication:
@ -6762,6 +6767,7 @@ The actual non-nil value of this variable will be copied to the
(const display-buffer-pop-up-window)
(const display-buffer-same-window)
(const display-buffer-pop-up-frame)
(const display-buffer-in-child-frame)
(const display-buffer-below-selected)
(const display-buffer-at-bottom)
(const display-buffer-in-previous-window)
@ -6908,6 +6914,7 @@ Available action functions include:
`display-buffer-same-window'
`display-buffer-reuse-window'
`display-buffer-pop-up-frame'
`display-buffer-in-child-frame'
`display-buffer-pop-up-window'
`display-buffer-in-previous-window'
`display-buffer-use-some-window'
@ -7239,6 +7246,7 @@ raising the frame."
(get-largest-window frame t) alist)
(window--try-to-split-window
(get-lru-window frame t) alist))))
(prog1 (window--display-buffer
buffer window 'window alist display-buffer-mark-dedicated)
(unless (cdr (assq 'inhibit-switch-frame alist))
@ -7258,6 +7266,47 @@ again with `display-buffer-pop-up-window'."
(and pop-up-windows
(display-buffer-pop-up-window buffer alist))))
(defun display-buffer-in-child-frame (buffer alist)
"Display BUFFER in a child frame.
By default, this either reuses a child frame of the selected
frame or makes a new child frame of the selected frame. If
successful, return the window used; otherwise return nil.
If ALIST has a non-nil 'child-frame-parameters' entry, the
corresponding value is an alist of frame parameters to give the
new frame. A 'parent-frame' parameter specifying the selected
frame is provided by default. If the child frame should be or
become the child of any other frame, a corresponding entry must
be added to ALIST."
(let* ((parameters
(append
(cdr (assq 'child-frame-parameters alist))
`((parent-frame . ,(selected-frame)))))
(parent (or (assq 'parent-frame parameters)
(selected-frame)))
(share (assq 'share-child-frame parameters))
share1 frame window)
(with-current-buffer buffer
(when (frame-live-p parent)
(catch 'frame
(dolist (frame1 (frame-list))
(when (eq (frame-parent frame1) parent)
(setq share1 (assq 'share-child-frame
(frame-parameters frame1)))
(when (eq share share1)
(setq frame frame1)
(throw 'frame t))))))
(if frame
(setq window (frame-selected-window frame))
(setq frame (make-frame parameters))
(setq window (frame-selected-window frame))))
(prog1 (window--display-buffer
buffer window 'frame alist display-buffer-mark-dedicated)
(unless (cdr (assq 'inhibit-switch-frame alist))
(window--maybe-raise-frame frame)))))
(defun display-buffer-below-selected (buffer alist)
"Try displaying BUFFER in a window below the selected window.
If there is a window below the selected one and that window
@ -7272,7 +7321,8 @@ below the selected one, use that window."
(and (not (frame-parameter nil 'unsplittable))
(let ((split-height-threshold 0)
split-width-threshold)
(setq window (window--try-to-split-window (selected-window) alist)))
(setq window (window--try-to-split-window
(selected-window) alist)))
(window--display-buffer
buffer window 'window alist display-buffer-mark-dedicated))
(and (setq window (window-in-direction 'below))
@ -7885,10 +7935,12 @@ See also `fit-frame-to-buffer-margins'."
(declare-function x-display-pixel-height "xfns.c" (&optional terminal))
(defun window--sanitize-margin (margin left right)
"Return MARGIN if it's a number between LEFT and RIGHT."
(when (and (numberp margin)
(<= left (- right margin)) (<= margin right))
margin))
"Return MARGIN if it's a number between LEFT and RIGHT.
Return 0 otherwise."
(if (and (numberp margin)
(<= left (- right margin)) (<= margin right))
margin
0))
(declare-function tool-bar-height "xdisp.c" (&optional frame pixelwise))
@ -7906,190 +7958,197 @@ horizontally only.
The new position and size of FRAME can be additionally determined
by customizing the options `fit-frame-to-buffer-sizes' and
`fit-frame-to-buffer-margins' or the corresponding parameters of
FRAME."
`fit-frame-to-buffer-margins' or setting the corresponding
parameters of FRAME."
(interactive)
(unless (and (fboundp 'x-display-pixel-height)
;; We need the respective sizes now.
(fboundp 'display-monitor-attributes-list))
(unless (fboundp 'display-monitor-attributes-list)
(user-error "Cannot resize frame in non-graphic Emacs"))
(setq frame (window-normalize-frame frame))
(when (window-live-p (frame-root-window frame))
(with-selected-window (frame-root-window frame)
(let* ((char-width (frame-char-width))
(char-height (frame-char-height))
(monitor-attributes (car (display-monitor-attributes-list
(frame-parameter frame 'display))))
(geometry (cdr (assq 'geometry monitor-attributes)))
(display-width (- (nth 2 geometry) (nth 0 geometry)))
(display-height (- (nth 3 geometry) (nth 1 geometry)))
(workarea (cdr (assq 'workarea monitor-attributes)))
;; Handle margins.
(margins (or (frame-parameter frame 'fit-frame-to-buffer-margins)
fit-frame-to-buffer-margins))
(left-margin (if (nth 0 margins)
(or (window--sanitize-margin
(nth 0 margins) 0 display-width)
0)
(nth 0 workarea)))
(top-margin (if (nth 1 margins)
(or (window--sanitize-margin
(nth 1 margins) 0 display-height)
0)
(nth 1 workarea)))
(workarea-width (nth 2 workarea))
(right-margin (if (nth 2 margins)
(- display-width
(or (window--sanitize-margin
(nth 2 margins) left-margin display-width)
0))
(nth 2 workarea)))
(workarea-height (nth 3 workarea))
(bottom-margin (if (nth 3 margins)
(- display-height
(or (window--sanitize-margin
(nth 3 margins) top-margin display-height)
0))
(nth 3 workarea)))
;; The pixel width of FRAME (which does not include the
;; window manager's decorations).
(frame-width (frame-pixel-width))
;; The pixel width of the body of FRAME's root window.
(window-body-width (window-body-width nil t))
;; The difference in pixels between total and body width of
;; FRAME's window.
(window-extra-width (- (window-pixel-width) window-body-width))
;; The difference in pixels between the frame's pixel width
;; and the window's body width. This is the space we can't
;; use for fitting.
(extra-width (- frame-width window-body-width))
;; The pixel position of FRAME's left border. We usually
;; try to leave this alone.
(left
(let ((left (frame-parameter nil 'left)))
(if (consp left)
(funcall (car left) (cadr left))
left)))
;; The pixel height of FRAME (which does not include title
;; line, decorations, and sometimes neither the menu nor
;; the toolbar).
(frame-height (frame-pixel-height))
;; The pixel height of FRAME's root window (we don't care
;; about the window's body height since the return value of
;; `window-text-pixel-size' includes header and mode line).
(window-height (window-pixel-height))
;; The difference in pixels between the frame's pixel
;; height and the window's height.
(extra-height (- frame-height window-height))
;; The pixel position of FRAME's top border.
(top
(let ((top (frame-parameter nil 'top)))
(if (consp top)
(funcall (car top) (cadr top))
top)))
;; Sanitize minimum and maximum sizes.
(sizes (or (frame-parameter frame 'fit-frame-to-buffer-sizes)
fit-frame-to-buffer-sizes))
(max-height
(cond
((numberp (nth 0 sizes)) (* (nth 0 sizes) char-height))
((numberp max-height) (* max-height char-height))
(t display-height)))
(min-height
(cond
((numberp (nth 1 sizes)) (* (nth 1 sizes) char-height))
((numberp min-height) (* min-height char-height))
(t (* window-min-height char-height))))
(max-width
(cond
((numberp (nth 2 sizes))
(- (* (nth 2 sizes) char-width) window-extra-width))
((numberp max-width)
(- (* max-width char-width) window-extra-width))
(t display-width)))
(min-width
(cond
((numberp (nth 3 sizes))
(- (* (nth 3 sizes) char-width) window-extra-width))
((numberp min-width)
(- (* min-width char-width) window-extra-width))
(t (* window-min-width char-width))))
;; Note: Currently, for a new frame the sizes of the header
;; and mode line may be estimated incorrectly
(value (window-text-pixel-size
nil t t workarea-width workarea-height t))
(width (+ (car value) (window-right-divider-width)))
(height
(+ (cdr value)
(window-bottom-divider-width)
(window-scroll-bar-height))))
;; Don't change height or width when the window's size is fixed
;; in either direction or ONLY forbids it.
(cond
((or (eq window-size-fixed 'width) (eq only 'vertically))
(setq width nil))
((or (eq window-size-fixed 'height) (eq only 'horizontally))
(setq height nil)))
;; Fit width to constraints.
(when width
(unless frame-resize-pixelwise
;; Round to character sizes.
(setq width (* (/ (+ width char-width -1) char-width)
char-width)))
;; Fit to maximum and minimum widths.
(setq width (max (min width max-width) min-width))
;; Add extra width.
(setq width (+ width extra-width))
;; Preserve margins.
(let ((right (+ left width)))
(cond
((> right right-margin)
;; Move frame to left (we don't know its real width).
(setq left (max left-margin (- left (- right right-margin)))))
((< left left-margin)
;; Move frame to right.
(setq left left-margin)))))
;; Fit height to constraints.
(when height
(unless frame-resize-pixelwise
(setq height (* (/ (+ height char-height -1) char-height)
char-height)))
;; Fit to maximum and minimum heights.
(setq height (max (min height max-height) min-height))
;; Add extra height.
(setq height (+ height extra-height))
;; Preserve margins.
(let ((bottom (+ top height)))
(cond
((> bottom bottom-margin)
;; Move frame up (we don't know its real height).
(setq top (max top-margin (- top (- bottom bottom-margin)))))
((< top top-margin)
;; Move frame down.
(setq top top-margin)))))
;; Apply changes.
(set-frame-position frame left top)
;; Clumsily try to translate our calculations to what
;; `set-frame-size' wants.
(when width
(setq width (- (+ (frame-text-width) width)
extra-width window-body-width)))
(when height
(setq height (- (+ (frame-text-height) height)
extra-height window-height)))
(set-frame-size
frame
(if width
(if frame-resize-pixelwise
width
(/ width char-width))
(frame-text-width))
(if height
(if frame-resize-pixelwise
height
(/ height char-height))
(frame-text-height))
frame-resize-pixelwise)))))
(let* ((char-width (frame-char-width frame))
(char-height (frame-char-height frame))
;; WINDOW is FRAME's root window.
(window (frame-root-window frame))
(parent (frame-parent frame))
(monitor-attributes
(unless parent
(car (display-monitor-attributes-list
(frame-parameter frame 'display)))))
;; FRAME'S parent or display sizes. Used in connection
;; with margins.
(geometry
(unless parent
(cdr (assq 'geometry monitor-attributes))))
(parent-or-display-width
(if parent
(frame-native-width parent)
(- (nth 2 geometry) (nth 0 geometry))))
(parent-or-display-height
(if parent
(frame-native-height parent)
(- (nth 3 geometry) (nth 1 geometry))))
;; FRAME'S parent or workarea sizes. Used when no margins
;; are specified.
(parent-or-workarea
(if parent
`(0 0 ,parent-or-display-width ,parent-or-display-height)
(cdr (assq 'workarea monitor-attributes))))
;; The outer size of FRAME. Needed to calculate the
;; margins around the root window's body that have to
;; remain untouched by fitting.
(outer-edges (frame-edges frame 'outer-edges))
(outer-width (if outer-edges
(- (nth 2 outer-edges) (nth 0 outer-edges))
;; A poor guess.
(frame-pixel-width frame)))
(outer-height (if outer-edges
(- (nth 3 outer-edges) (nth 1 outer-edges))
;; Another poor guess.
(frame-pixel-height frame)))
;; The text size of of FRAME. Needed to specify FRAME's
;; text size after the root window's body's new sizes have
;; been calculated.
(text-width (frame-text-width frame))
(text-height (frame-text-height frame))
;; WINDOW's body size.
(body-width (window-body-width window t))
(body-height (window-body-height window t))
;; The difference between FRAME's outer size and WINDOW's
;; body size.
(outer-minus-body-width (- outer-width body-width))
(outer-minus-body-height (- outer-height body-height))
;; The difference between FRAME's text size and WINDOW's
;; body size (these values "should" be positive).
(text-minus-body-width (- text-width body-width))
(text-minus-body-height (- text-height body-height))
;; The current position of FRAME.
(position (frame-position frame))
(left (car position))
(top (cdr position))
;; The margins specified for FRAME. These represent pixel
;; offsets from the left, top, right and bottom edge of the
;; display or FRAME's parent's native rectangle and have to
;; take care of the display's taskbar and other obstacles.
;; If they are unspecified, constrain the resulting frame
;; to its workarea or the parent frame's native rectangle.
(margins (or (frame-parameter frame 'fit-frame-to-buffer-margins)
fit-frame-to-buffer-margins))
;; Convert margins intto pixel offsets from the left-top
;; corner of FRAME's display or parent.
(left-margin (if (nth 0 margins)
(window--sanitize-margin
(nth 0 margins) 0 parent-or-display-width)
(nth 0 parent-or-workarea)))
(top-margin (if (nth 1 margins)
(window--sanitize-margin
(nth 1 margins) 0 parent-or-display-height)
(nth 1 parent-or-workarea)))
(right-margin (if (nth 2 margins)
(- parent-or-display-width
(window--sanitize-margin
(nth 2 margins) left-margin
parent-or-display-width))
(nth 2 parent-or-workarea)))
(bottom-margin (if (nth 3 margins)
(- parent-or-display-height
(window--sanitize-margin
(nth 3 margins) top-margin
parent-or-display-height))
(nth 3 parent-or-workarea)))
;; Minimum and maximum sizes specified for FRAME.
(sizes (or (frame-parameter frame 'fit-frame-to-buffer-sizes)
fit-frame-to-buffer-sizes))
;; Calculate the minimum and maximum pixel sizes of FRAME
;; from the values provided by the MAX-HEIGHT, MIN-HEIGHT,
;; MAX-WIDTH and MIN-WIDTH arguments or, if these are nil,
;; from those provided by `fit-frame-to-buffer-sizes'.
(max-height
(min
(cond
((numberp max-height) (* max-height char-height))
((numberp (nth 0 sizes)) (* (nth 0 sizes) char-height))
(t parent-or-display-height))
;; The following is the maximum height that fits into the
;; top and bottom margins.
(max (- bottom-margin top-margin outer-minus-body-height))))
(min-height
(cond
((numberp min-height) (* min-height char-height))
((numberp (nth 1 sizes)) (* (nth 1 sizes) char-height))
(t (window-min-size window nil nil t))))
(max-width
(min
(cond
((numberp max-width) (* max-width char-width))
((numberp (nth 2 sizes)) (* (nth 2 sizes) char-width))
(t parent-or-display-width))
;; The following is the maximum width that fits into the
;; left and right margins.
(max (- right-margin left-margin outer-minus-body-width))))
(min-width
(cond
((numberp min-width) (* min-width char-width))
((numberp (nth 3 sizes)) (nth 3 sizes))
(t (window-min-size window t nil t))))
;; Note: Currently, for a new frame the sizes of the header
;; and mode line may be estimated incorrectly
(size
(window-text-pixel-size window t t max-width max-height))
(width (max (car size) min-width))
(height (max (cdr size) min-height)))
;; Don't change height or width when the window's size is fixed
;; in either direction or ONLY forbids it.
(cond
((or (eq window-size-fixed 'width) (eq only 'vertically))
(setq width nil))
((or (eq window-size-fixed 'height) (eq only 'horizontally))
(setq height nil)))
;; Fit width to constraints.
(when width
(unless frame-resize-pixelwise
;; Round to character sizes.
(setq width (* (/ (+ width char-width -1) char-width)
char-width)))
;; The new outer width (in pixels).
(setq outer-width (+ width outer-minus-body-width))
;; Maybe move FRAME to preserve margins.
(let ((right (+ left outer-width)))
(cond
((> right right-margin)
;; Move frame to left.
(setq left (max left-margin (- left (- right right-margin)))))
((< left left-margin)
;; Move frame to right.
(setq left left-margin)))))
;; Fit height to constraints.
(when height
(unless frame-resize-pixelwise
(setq height (* (/ (+ height char-height -1) char-height)
char-height)))
;; The new outer height.
(setq outer-height (+ height outer-minus-body-height))
;; Preserve margins.
(let ((bottom (+ top outer-height)))
(cond
((> bottom bottom-margin)
;; Move frame up.
(setq top (max top-margin (- top (- bottom bottom-margin)))))
((< top top-margin)
;; Move frame down.
(setq top top-margin)))))
;; Apply our changes.
(setq text-width
(if width
(+ width text-minus-body-width)
(frame-text-width frame)))
(setq text-height
(if height
(+ height text-minus-body-height)
(frame-text-height frame)))
(modify-frame-parameters
frame `((left . ,left) (top . ,top)
(width . (text-pixels . ,text-width))
(height . (text-pixels . ,text-height)))))))
(defun fit-window-to-buffer (&optional window max-height min-height max-width min-width preserve-size)
"Adjust size of WINDOW to display its buffer's contents exactly.
@ -8286,6 +8345,168 @@ Return non-nil if the window was shrunk, nil otherwise."
(when (and (window-combined-p window)
(pos-visible-in-window-p (point-min) window))
(fit-window-to-buffer window (window-total-height window))))
(defun window-largest-empty-rectangle--maximums-1 (quad maximums)
"Support function for `window-largest-empty-rectangle'."
(cond
((null maximums)
(list quad))
((> (car quad) (caar maximums))
(cons quad maximums))
(t
(cons (car maximums)
(window-largest-empty-rectangle--maximums-1 quad (cdr maximums))))))
(defun window-largest-empty-rectangle--maximums (quad maximums count)
"Support function for `window-largest-empty-rectangle'."
(setq maximums (window-largest-empty-rectangle--maximums-1 quad maximums))
(if (> (length maximums) count)
(nbutlast maximums)
maximums))
(defun window-largest-empty-rectangle--disjoint-maximums (maximums count)
"Support function for `window-largest-empty-rectangle'."
(setq maximums (sort maximums (lambda (x y) (> (car x) (car y)))))
(let ((new-length 0)
new-maximums)
(while (and maximums (< new-length count))
(let* ((maximum (car maximums))
(at (nth 2 maximum))
(to (nth 3 maximum)))
(catch 'drop
(dolist (new-maximum new-maximums)
(let ((new-at (nth 2 new-maximum))
(new-to (nth 3 new-maximum)))
(when (if (< at new-at) (> to new-at) (< at new-to))
;; Intersection -> drop.
(throw 'drop nil))))
(setq new-maximums (cons maximum new-maximums))
(setq new-length (1+ new-length)))
(setq maximums (cdr maximums))))
(nreverse new-maximums)))
(defun window-largest-empty-rectangle (&optional window count min-width min-height positions left)
"Return dimensions of largest empty rectangle in WINDOW.
WINDOW must be a live window and defaults to the selected one.
The return value is a triple of the width and the start and end
Y-coordinates of the largest rectangle that can be inscribed into
the empty space (the space not displaying any text) of WINDOW's
text area. The return value is nil if the current glyph matrix
of WINDOW is not up-to-date.
Optional argument COUNT, if non-nil, specifies the maximum number
of rectangles to return. This means that the return value is a
list of triples specifying rectangles with the largest rectangle
first. COUNT can be also a cons cell whose car specifies the
number of rectangles to return and whose cdr, if non-nil, states
that all rectangles returned must be disjoint.
Note that the right edge of any rectangle returned by this
function is the right edge of WINDOW (the left edge if its buffer
displays RTL text).
Optional arguments MIN-WIDTH and MIN-HEIGHT, if non-nil, specify
the minimum width and height of any rectangle returned.
Optional argument POSITIONS, if non-nil, is a cons cell whose car
specifies the uppermost and whose cdr specifies the lowermost
pixel position that must be covered by any rectangle returned.
Note that positions are counted from the start of the text area
of WINDOW.
Optional argument LEFT, if non-nil, means to return values suitable for
buffers displaying right to left text."
;; Process lines as returned by window-lines-pixel-dimensions.
;; STACK is a stack that contains rows that have to be processed yet.
(let* ((window (window-normalize-window window t))
(disjoint (and (consp count) (cdr count)))
(count (or (and (numberp count) count)
(and (consp count) (numberp (car count)) (car count))))
(rows (window-lines-pixel-dimensions window nil nil t t left))
(rows-at 0)
(max-size 0)
row stack stack-at stack-to
top top-width top-at top-to top-size
max-width max-at max-to maximums)
;; ROWS-AT is the position where the first element of ROWS starts.
;; STACK-AT is the position where the first element of STACK starts.
(while rows
(setq row (car rows))
(if (or (not stack) (>= (car row) (caar stack)))
(progn
(unless stack
(setq stack-at rows-at))
(setq stack (cons row stack))
;; Set ROWS-AT to where the first element of ROWS ends
;; which, after popping ROW, makes it the start position of
;; the next ROW.
(setq rows-at (cdr row))
(setq rows (cdr rows)))
(setq top (car stack))
(setq stack (cdr stack))
(setq top-width (car top))
(setq top-at (if stack (cdar stack) stack-at))
(setq top-to (cdr top))
(setq top-size (* top-width (- top-to top-at)))
(unless (or (and min-width (< top-width min-width))
(and min-height (< (- top-to top-at) min-height))
(and positions
(or (> top-at (car positions))
(< top-to (cdr positions)))))
(if count
(if disjoint
(setq maximums (cons (list top-size top-width top-at top-to)
maximums))
(setq maximums (window-largest-empty-rectangle--maximums
(list top-size top-width top-at top-to)
maximums count)))
(when (> top-size max-size)
(setq max-size top-size)
(setq max-width top-width)
(setq max-at top-at)
(setq max-to top-to))))
(if (and stack (> (caar stack) (car row)))
;; Have new top element of stack include old top.
(setq stack (cons (cons (caar stack) (cdr top)) (cdr stack)))
;; Move rows-at backwards to top-at.
(setq rows-at top-at))))
(when stack
;; STACK-TO is the position where the stack ends.
(setq stack-to (cdar stack))
(while stack
(setq top (car stack))
(setq stack (cdr stack))
(setq top-width (car top))
(setq top-at (if stack (cdar stack) stack-at))
(setq top-size (* top-width (- stack-to top-at)))
(unless (or (and min-width (< top-width min-width))
(and min-height (< (- stack-to top-at) min-height))
(and positions
(or (> top-at (car positions))
(< stack-to (cdr positions)))))
(if count
(if disjoint
(setq maximums (cons (list top-size top-width top-at stack-to)
maximums))
(setq maximums (window-largest-empty-rectangle--maximums
(list top-size top-width top-at stack-to)
maximums count)))
(when (> top-size max-size)
(setq max-size top-size)
(setq max-width top-width)
(setq max-at top-at)
(setq max-to stack-to))))))
(cond
(maximums
(if disjoint
(window-largest-empty-rectangle--disjoint-maximums maximums count)
maximums))
((> max-size 0)
(list max-width max-at max-to)))))
(defun kill-buffer-and-window ()
"Kill the current buffer and delete the selected window."

View file

@ -158,6 +158,7 @@ AC_DEFUN([gl_EARLY],
# Code from module timespec-sub:
# Code from module u64:
# Code from module unistd:
# Code from module unlocked-io:
# Code from module update-copyright:
# Code from module utimens:
# Code from module vararrays:
@ -399,6 +400,7 @@ AC_DEFUN([gl_INIT],
gl_TIMER_TIME
gl_TIMESPEC
gl_UNISTD_H
gl_FUNC_GLIBC_UNLOCKED_IO
gl_UTIMENS
AC_C_VARARRAYS
gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=false
@ -940,6 +942,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/u64.h
lib/unistd.c
lib/unistd.in.h
lib/unlocked-io.h
lib/utimens.c
lib/utimens.h
lib/verify.h
@ -1044,6 +1047,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/timespec.m4
m4/tm_gmtoff.m4
m4/unistd_h.m4
m4/unlocked-io.m4
m4/utimens.m4
m4/utimes.m4
m4/vararrays.m4

41
m4/unlocked-io.m4 Normal file
View file

@ -0,0 +1,41 @@
# unlocked-io.m4 serial 15
# Copyright (C) 1998-2006, 2009-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
dnl From Jim Meyering.
dnl
dnl See if the glibc *_unlocked I/O macros or functions are available.
dnl Use only those *_unlocked macros or functions that are declared
dnl (because some of them were declared in Solaris 2.5.1 but were removed
dnl in Solaris 2.6, whereas we want binaries built on Solaris 2.5.1 to run
dnl on Solaris 2.6).
AC_DEFUN([gl_FUNC_GLIBC_UNLOCKED_IO],
[
AC_DEFINE([USE_UNLOCKED_IO], [1],
[Define to 1 if you want getc etc. to use unlocked I/O if available.
Unlocked I/O can improve performance in unithreaded apps,
but it is not safe for multithreaded apps.])
dnl Persuade glibc and Solaris <stdio.h> to declare
dnl fgets_unlocked(), fputs_unlocked() etc.
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
AC_CHECK_DECLS_ONCE([clearerr_unlocked])
AC_CHECK_DECLS_ONCE([feof_unlocked])
AC_CHECK_DECLS_ONCE([ferror_unlocked])
AC_CHECK_DECLS_ONCE([fflush_unlocked])
AC_CHECK_DECLS_ONCE([fgets_unlocked])
AC_CHECK_DECLS_ONCE([fputc_unlocked])
AC_CHECK_DECLS_ONCE([fputs_unlocked])
AC_CHECK_DECLS_ONCE([fread_unlocked])
AC_CHECK_DECLS_ONCE([fwrite_unlocked])
AC_CHECK_DECLS_ONCE([getc_unlocked])
AC_CHECK_DECLS_ONCE([getchar_unlocked])
AC_CHECK_DECLS_ONCE([putc_unlocked])
AC_CHECK_DECLS_ONCE([putchar_unlocked])
])

View file

@ -29,7 +29,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
@ -40,6 +39,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "charset.h"
#include "coding.h"
#include "buffer.h"
#include "sysstdio.h"
/*** GENERAL NOTES on CODED CHARACTER SETS (CHARSETS) ***
@ -198,10 +198,6 @@ static struct
#define GET_TEMP_CHARSET_WORK_DECODER(CODE) \
(temp_charset_work->table.decoder[(CODE)])
#ifndef HAVE_GETC_UNLOCKED
#define getc_unlocked getc
#endif
/* Set to 1 to warn that a charset map is loaded and thus a buffer

View file

@ -19,10 +19,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdio.h>
#include "lisp.h"
#include "cm.h"
#include "sysstdio.h"
#include "termchar.h"
#include "tparam.h"
@ -45,8 +45,8 @@ int
cmputc (int c)
{
if (current_tty->termscript)
putc (c & 0177, current_tty->termscript);
putc (c & 0177, current_tty->output);
putc_unlocked (c & 0177, current_tty->termscript);
putc_unlocked (c & 0177, current_tty->output);
return c;
}
@ -117,11 +117,11 @@ cmcheckmagic (struct tty_display_info *tty)
if (!MagicWrap (tty) || curY (tty) >= FrameRows (tty) - 1)
emacs_abort ();
if (tty->termscript)
putc ('\r', tty->termscript);
putc ('\r', tty->output);
putc_unlocked ('\r', tty->termscript);
putc_unlocked ('\r', tty->output);
if (tty->termscript)
putc ('\n', tty->termscript);
putc ('\n', tty->output);
putc_unlocked ('\n', tty->termscript);
putc_unlocked ('\n', tty->output);
curX (tty) = 0;
curY (tty)++;
}

View file

@ -1106,7 +1106,7 @@ struct glyph_row *matrix_row (struct glyph_matrix *, int);
#define MATRIX_BOTTOM_TEXT_ROW(MATRIX, W) \
((MATRIX)->rows \
+ (MATRIX)->nrows \
- (WINDOW_WANTS_MODELINE_P ((W)) ? 1 : 0))
- (window_wants_mode_line ((W)) ? 1 : 0))
/* Non-zero if the face of the last glyph in ROW's text area has
to be drawn to the end of the text area. */
@ -1469,40 +1469,6 @@ struct glyph_string
#define DESIRED_HEADER_LINE_HEIGHT(W) \
MATRIX_HEADER_LINE_HEIGHT ((W)->desired_matrix)
/* PXW: The height checks below serve to show at least one text line
instead of a mode- and/or header line when a window gets very small.
But (1) the check fails when the mode- or header-line is taller than
the associated frame's line height and (2) we don't care much about
text visibility anyway when shrinking a frame containing a toolbar.
So maybe these checks should be removed and any clipping left to the
window manager. */
/* Value is true if window W wants a mode line and is large enough
to accommodate it. */
#define WINDOW_WANTS_MODELINE_P(W) \
(BUFFERP ((W)->contents) \
? (!MINI_WINDOW_P (W) \
&& !(W)->pseudo_window_p \
&& FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (W))) \
&& !NILP (BVAR (XBUFFER ((W)->contents), mode_line_format)) \
&& WINDOW_PIXEL_HEIGHT (W) > WINDOW_FRAME_LINE_HEIGHT (W)) \
: false)
/* Value is true if window W wants a header line and is large enough
to accommodate it. */
#define WINDOW_WANTS_HEADER_LINE_P(W) \
(BUFFERP ((W)->contents) \
? (!MINI_WINDOW_P (W) \
&& !(W)->pseudo_window_p \
&& FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (W))) \
&& !NILP (BVAR (XBUFFER ((W)->contents), header_line_format)) \
&& (WINDOW_PIXEL_HEIGHT (W) \
> (WINDOW_WANTS_MODELINE_P (W) \
? (2 * WINDOW_FRAME_LINE_HEIGHT (W)) \
: WINDOW_FRAME_LINE_HEIGHT (W)))) \
: false)
/* Return proper value to be used as baseline offset of font that has
ASCENT and DESCENT to draw characters by the font at the vertical
center of the line of frame F.

View file

@ -377,7 +377,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
{
window_box (w, ANY_AREA, 0, 0, &window_width, &window_height);
header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
header_line_p = window_wants_header_line (w);
header_line_changed_p = header_line_p != matrix->header_line_p;
}
matrix->header_line_p = header_line_p;
@ -446,7 +446,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
if (w == NULL
|| (row == matrix->rows + dim.height - 1
&& WINDOW_WANTS_MODELINE_P (w))
&& window_wants_mode_line (w))
|| (row == matrix->rows && matrix->header_line_p))
{
row->glyphs[TEXT_AREA]
@ -491,7 +491,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
/* The mode line, if displayed, never has marginal areas. */
if ((row == matrix->rows + dim.height - 1
&& !(w && WINDOW_WANTS_MODELINE_P (w)))
&& !(w && window_wants_mode_line (w)))
|| (row == matrix->rows && matrix->header_line_p))
{
row->glyphs[TEXT_AREA]
@ -570,7 +570,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
the mode line, if any, since otherwise it will remain
disabled in the current matrix, and expose events won't
redraw it. */
if (WINDOW_WANTS_MODELINE_P (w))
if (window_wants_mode_line (w))
w->update_mode_line = 1;
}
else if (matrix == w->desired_matrix)
@ -3126,9 +3126,9 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
{
if (FRAME_TTY (f)->termscript)
fflush (FRAME_TTY (f)->termscript);
fflush_unlocked (FRAME_TTY (f)->termscript);
if (FRAME_TERMCAP_P (f))
fflush (FRAME_TTY (f)->output);
fflush_unlocked (FRAME_TTY (f)->output);
}
/* Check window matrices for lost pointers. */
@ -3181,8 +3181,8 @@ update_frame_with_menu (struct frame *f, int row, int col)
update_end (f);
if (FRAME_TTY (f)->termscript)
fflush (FRAME_TTY (f)->termscript);
fflush (FRAME_TTY (f)->output);
fflush_unlocked (FRAME_TTY (f)->termscript);
fflush_unlocked (FRAME_TTY (f)->output);
/* Check window matrices for lost pointers. */
#if GLYPH_DEBUG
#if 0
@ -4531,7 +4531,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
ptrdiff_t outq = __fpending (display_output);
if (outq > 900
|| (outq > 20 && ((i - 1) % preempt_count == 0)))
fflush (display_output);
fflush_unlocked (display_output);
}
}
@ -5188,7 +5188,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
start position, i.e. it excludes the header-line row, but
MATRIX_ROW includes the header-line row. Adjust for a possible
header-line row. */
it_vpos = it.vpos + WINDOW_WANTS_HEADER_LINE_P (w);
it_vpos = it.vpos + window_wants_header_line (w);
if (it_vpos < w->current_matrix->nrows
&& (row = MATRIX_ROW (w->current_matrix, it_vpos),
row->enabled_p))
@ -5615,13 +5615,13 @@ when TERMINAL is nil. */)
if (tty->termscript)
{
fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
fflush (tty->termscript);
fwrite_unlocked (SDATA (string), 1, SBYTES (string), tty->termscript);
fflush_unlocked (tty->termscript);
}
out = tty->output;
}
fwrite (SDATA (string), 1, SBYTES (string), out);
fflush (out);
fwrite_unlocked (SDATA (string), 1, SBYTES (string), out);
fflush_unlocked (out);
unblock_input ();
return Qnil;
}
@ -5636,7 +5636,7 @@ terminate any keyboard macro currently executing. */)
if (!NILP (arg))
{
if (noninteractive)
putchar (07);
putchar_unlocked (07);
else
ring_bell (XFRAME (selected_frame));
}
@ -5650,7 +5650,7 @@ void
bitch_at_user (void)
{
if (noninteractive)
putchar (07);
putchar_unlocked (07);
else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
{
const char *msg

View file

@ -575,6 +575,8 @@ module_make_string (emacs_env *env, const char *str, ptrdiff_t length)
MODULE_FUNCTION_BEGIN (module_nil);
if (! (0 <= length && length <= STRING_BYTES_BOUND))
xsignal0 (Qoverflow_error);
/* FIXME: AUTO_STRING_WITH_LEN requires STR to be null-terminated,
but we shouldnt require that. */
AUTO_STRING_WITH_LEN (lstr, str, length);
return lisp_to_value (env,
code_convert_string_norecord (lstr, Qutf_8, false));
@ -599,7 +601,6 @@ module_get_user_ptr (emacs_env *env, emacs_value uptr)
static void
module_set_user_ptr (emacs_env *env, emacs_value uptr, void *ptr)
{
/* FIXME: This function should return bool because it can fail. */
MODULE_FUNCTION_BEGIN ();
Lisp_Object lisp = value_to_lisp (uptr);
CHECK_USER_PTR (lisp);
@ -619,7 +620,6 @@ static void
module_set_user_finalizer (emacs_env *env, emacs_value uptr,
emacs_finalizer_function fin)
{
/* FIXME: This function should return bool because it can fail. */
MODULE_FUNCTION_BEGIN ();
Lisp_Object lisp = value_to_lisp (uptr);
CHECK_USER_PTR (lisp);
@ -638,7 +638,6 @@ check_vec_index (Lisp_Object lvec, ptrdiff_t i)
static void
module_vec_set (emacs_env *env, emacs_value vec, ptrdiff_t i, emacs_value val)
{
/* FIXME: This function should return bool because it can fail. */
MODULE_FUNCTION_BEGIN ();
Lisp_Object lvec = value_to_lisp (vec);
check_vec_index (lvec, i);
@ -657,7 +656,6 @@ module_vec_get (emacs_env *env, emacs_value vec, ptrdiff_t i)
static ptrdiff_t
module_vec_size (emacs_env *env, emacs_value vec)
{
/* FIXME: Return a sentinel value (e.g., -1) on error. */
MODULE_FUNCTION_BEGIN (0);
Lisp_Object lvec = value_to_lisp (vec);
CHECK_VECTOR (lvec);

View file

@ -80,7 +80,7 @@ enum emacs_funcall_exit
emacs_funcall_exit_signal = 1,
/* Function has exit using `throw'. */
emacs_funcall_exit_throw = 2,
emacs_funcall_exit_throw = 2
};
struct emacs_env_25
@ -97,6 +97,7 @@ struct emacs_env_26
/* Every module should define a function as follows. */
extern int emacs_module_init (struct emacs_runtime *ert)
EMACS_NOEXCEPT
EMACS_ATTRIBUTE_NONNULL(1);
#ifdef __cplusplus

View file

@ -23,7 +23,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
@ -33,6 +32,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define MAIN_PROGRAM
#include "lisp.h"
#include "sysstdio.h"
#ifdef WINDOWSNT
#include <fcntl.h>
@ -885,7 +885,7 @@ main (int argc, char **argv)
}
#endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */
clearerr (stdin);
clearerr_unlocked (stdin);
emacs_backtrace (-1);
@ -983,7 +983,7 @@ main (int argc, char **argv)
int i;
printf ("Usage: %s [OPTION-OR-FILENAME]...\n", argv[0]);
for (i = 0; i < ARRAYELTS (usage_message); i++)
fputs (usage_message[i], stdout);
fputs_unlocked (usage_message[i], stdout);
exit (0);
}
@ -2197,7 +2197,7 @@ You must run Emacs in batch mode in order to dump it. */)
}
#endif
fflush (stdout);
fflush_unlocked (stdout);
/* Tell malloc where start of impure now is. */
/* Also arrange for warnings when nearly out of space. */
#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC

View file

@ -5643,14 +5643,12 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
{
block_input ();
if (!NILP (BVAR (b, filename)))
{
fwrite (SDATA (BVAR (b, filename)), 1,
SBYTES (BVAR (b, filename)), stream);
}
putc ('\n', stream);
fwrite (SDATA (BVAR (b, auto_save_file_name)), 1,
SBYTES (BVAR (b, auto_save_file_name)), stream);
putc ('\n', stream);
fwrite_unlocked (SDATA (BVAR (b, filename)), 1,
SBYTES (BVAR (b, filename)), stream);
putc_unlocked ('\n', stream);
fwrite_unlocked (SDATA (BVAR (b, auto_save_file_name)), 1,
SBYTES (BVAR (b, auto_save_file_name)), stream);
putc_unlocked ('\n', stream);
unblock_input ();
}
@ -5841,7 +5839,7 @@ effect except for flushing STREAM's data. */)
binmode = NILP (mode) ? O_TEXT : O_BINARY;
if (fp != stdin)
fflush (fp);
fflush_unlocked (fp);
return (set_binary_mode (fileno (fp), binmode) == O_BINARY) ? Qt : Qnil;
}

View file

@ -328,8 +328,8 @@ DEFUN ("frame-windows-min-size", Fframe_windows_min_size,
* frame_windows_min_size:
*
* Return the minimum number of lines (columns if HORIZONTAL is non-nil)
* of FRAME. If PIXELWISE is non-nil, return the minimum height (width)
* in pixels.
* of FRAME. If PIXELWISE is non-nil, return the minimum inner height
* (width) of FRAME in pixels.
*
* This value is calculated by the function `frame-windows-min-size' in
* window.el unless the `min-height' (`min-width' if HORIZONTAL is
@ -341,7 +341,7 @@ DEFUN ("frame-windows-min-size", Fframe_windows_min_size,
* of `window-min-height' (`window-min-width' if HORIZONTAL is non-nil).
* With IGNORE non-nil the values of these variables are ignored.
*
* In either case never return a value less than 1.
* In either case, never return a value less than 1.
*/
static int
frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
@ -373,46 +373,173 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
}
/* Make sure windows sizes of frame F are OK. new_width and new_height
are in pixels. A value of -1 means no change is requested for that
size (but the frame may still have to be resized to accommodate
windows with their minimum sizes). This can either issue a request
to resize the frame externally (via x_set_window_size), to resize the
frame internally (via resize_frame_windows) or do nothing at all.
#ifdef HAVE_WINDOW_SYSTEM
/**
* keep_ratio:
*
* Preserve ratios of frame F which usually happens after its parent
* frame P got resized. OLD_WIDTH, OLD_HEIGHT specifies the old native
* size of F's parent, NEW_WIDTH and NEW_HEIGHT its new size.
*
* Adjust F's width if F's 'keep_ratio' parameter is non-nil and, if
* it is a cons, its car is not 'height-only'. Adjust F's height if F's
* 'keep_ratio' parameter is non-nil and, if it is a cons, its car
* is not 'width-only'.
*
* Adjust F's left position if F's 'keep_ratio' parameter is non-nil
* and, if its is a cons, its cdr is non-nil and not 'top-only'. Adjust
* F's top position if F's 'keep_ratio' parameter is non-nil and, if
* its is a cons, its cdr is non-nil and not 'left-only'.
*
* Note that when positional adjustment is requested but the size of F
* should remain unaltered in the corresponding direction, this routine
* tries to constrain F to its parent frame - something which usually
* happens when the parent frame shrinks. This means, however, that
* when the parent frame is re-enlarged later, the child's original
* position will not get restored to its pre-shrinking value.
*
* This routine is currently useful for child frames only. It might be
* eventually useful when moving non-child frames between monitors with
* different resolutions.
*/
static void
keep_ratio (struct frame *f, struct frame *p, int old_width, int old_height,
int new_width, int new_height)
{
Lisp_Object keep_ratio = get_frame_param (f, Qkeep_ratio);
The argument INHIBIT can assume the following values:
0 means to unconditionally call x_set_window_size even if sizes
apparently do not change. Fx_create_frame uses this to pass the
initial size to the window manager.
if (!NILP (keep_ratio))
{
double width_factor = (double)new_width / (double)old_width;
double height_factor = (double)new_height / (double)old_height;
int pixel_width, pixel_height, pos_x, pos_y;
1 means to call x_set_window_size if the outer frame size really
changes. Fset_frame_size, Fset_frame_height, ... use this.
if (!CONSP (keep_ratio) || !NILP (Fcdr (keep_ratio)))
{
if (CONSP (keep_ratio) && EQ (Fcdr (keep_ratio), Qtop_only))
pos_x = f->left_pos;
else
{
pos_x = (int)(f->left_pos * width_factor + 0.5);
2 means to call x_set_window_size provided frame_inhibit_resize
allows it. The menu and tool bar code use this ("3" won't work
here in general because menu and tool bar are often not counted in
the frame's text height).
if (CONSP (keep_ratio)
&& (NILP (Fcar (keep_ratio))
|| EQ (Fcar (keep_ratio), Qheight_only))
&& p->pixel_width - f->pixel_width < pos_x)
{
int p_f_width = p->pixel_width - f->pixel_width;
3 means call x_set_window_size if window minimum sizes must be
preserved or frame_inhibit_resize allows it. x_set_left_fringe,
x_set_scroll_bar_width, x_new_font ... use (or should use) this.
if (p_f_width <= 0)
pos_x = 0;
else
pos_x = (int)(p_f_width * width_factor * 0.5 + 0.5);
}
4 means call x_set_window_size only if window minimum sizes must be
preserved. x_set_right_divider_width, x_set_border_width and the
code responsible for wrapping the tool bar use this.
f->left_pos = pos_x;
}
5 means to never call x_set_window_size. change_frame_size uses
this.
if (CONSP (keep_ratio) && EQ (Fcdr (keep_ratio), Qleft_only))
pos_y = f->top_pos;
else
{
pos_y = (int)(f->top_pos * height_factor + 0.5);
Note that even when x_set_window_size is not called, individual
windows may have to be resized (via `window--sanitize-window-sizes')
in order to support minimum size constraints.
if (CONSP (keep_ratio)
&& (NILP (Fcar (keep_ratio))
|| EQ (Fcar (keep_ratio), Qwidth_only))
&& p->pixel_height - f->pixel_height < pos_y)
/* When positional adjustment was requested and the
width of F should remain unaltered, try to constrain
F to its parent. This means that when the parent
frame is enlarged later the child's original position
won't get restored. */
{
int p_f_height = p->pixel_height - f->pixel_height;
PRETEND is as for change_frame_size. PARAMETER, if non-nil, is the
symbol of the parameter changed (like `menu-bar-lines', `font', ...).
This is passed on to frame_inhibit_resize to let the latter decide on
a case-by-case basis whether the frame may be resized externally. */
if (p_f_height <= 0)
pos_y = 0;
else
pos_y = (int)(p_f_height * height_factor * 0.5 + 0.5);
}
f->top_pos = pos_y;
}
x_set_offset (f, pos_x, pos_y, -1);
}
if (!CONSP (keep_ratio) || !NILP (Fcar (keep_ratio)))
{
if (CONSP (keep_ratio) && EQ (Fcar (keep_ratio), Qheight_only))
pixel_width = -1;
else
{
pixel_width = (int)(f->pixel_width * width_factor + 0.5);
pixel_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, pixel_width);
}
if (CONSP (keep_ratio) && EQ (Fcar (keep_ratio), Qwidth_only))
pixel_height = -1;
else
{
pixel_height = (int)(f->pixel_height * height_factor + 0.5);
pixel_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixel_height);
}
adjust_frame_size (f, pixel_width, pixel_height, 1, 0,
Qkeep_ratio);
}
}
}
#endif
/**
* adjust_frame_size:
*
* Adjust size of frame F. NEW_WIDTH and NEW_HEIGHT specify the new
* text size of F in pixels. A value of -1 means no change is requested
* for that direction (but the frame may still have to be resized to
* accommodate windows with their minimum sizes). This can either issue
* a request to resize the frame externally (via x_set_window_size), to
* resize the frame internally (via resize_frame_windows) or do nothing
* at all.
*
* The argument INHIBIT can assume the following values:
*
* 0 means to unconditionally call x_set_window_size even if sizes
* apparently do not change. Fx_create_frame uses this to pass the
* initial size to the window manager.
*
* 1 means to call x_set_window_size if the native frame size really
* changes. Fset_frame_size, Fset_frame_height, ... use this.
*
* 2 means to call x_set_window_size provided frame_inhibit_resize
* allows it. The menu and tool bar code use this ("3" won't work
* here in general because menu and tool bar are often not counted in
* the frame's text height).
*
* 3 means call x_set_window_size if window minimum sizes must be
* preserved or frame_inhibit_resize allows it. x_set_left_fringe,
* x_set_scroll_bar_width, x_new_font ... use (or should use) this.
*
* 4 means call x_set_window_size only if window minimum sizes must be
* preserved. x_set_right_divider_width, x_set_border_width and the
* code responsible for wrapping the tool bar use this.
*
* 5 means to never call x_set_window_size. change_frame_size uses
* this.
*
* Note that even when x_set_window_size is not called, individual
* windows may have to be resized (via `window--sanitize-window-sizes')
* in order to support minimum size constraints.
*
* PRETEND is as for change_frame_size. PARAMETER, if non-nil, is the
* symbol of the parameter changed (like `menu-bar-lines', `font', ...).
* This is passed on to frame_inhibit_resize to let the latter decide on
* a case-by-case basis whether the frame may be resized externally.
*/
void
adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
bool pretend, Lisp_Object parameter)
@ -636,6 +763,18 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
|| new_pixel_height != old_pixel_height);
unblock_input ();
#ifdef HAVE_WINDOW_SYSTEM
{
/* Adjust size of F's child frames. */
Lisp_Object frames, frame1;
FOR_EACH_FRAME (frames, frame1)
if (FRAME_PARENT_FRAME (XFRAME (frame1)) == f)
keep_ratio (XFRAME (frame1), f, old_pixel_width, old_pixel_height,
new_pixel_width, new_pixel_height);
}
#endif
}
/* Allocate basically initialized frame. */
@ -684,6 +823,7 @@ make_frame (bool mini_p)
f->horizontal_scroll_bars = false;
f->want_fullscreen = FULLSCREEN_NONE;
f->undecorated = false;
f->no_special_glyphs = false;
#ifndef HAVE_NTGUI
f->override_redirect = false;
#endif
@ -2004,8 +2144,101 @@ The functions are run with one argument, the frame to be deleted. */)
{
return delete_frame (frame, !NILP (force) ? Qt : Qnil);
}
#ifdef HAVE_WINDOW_SYSTEM
/**
* frame_internal_border_part:
*
* Return part of internal border the coordinates X and Y relative to
* frame F are on. Return nil if the coordinates are not on the
* internal border of F.
*
* Return one of INTERNAL_BORDER_LEFT_EDGE, INTERNAL_BORDER_TOP_EDGE,
* INTERNAL_BORDER_RIGHT_EDGE or INTERNAL_BORDER_BOTTOM_EDGE when the
* mouse cursor is on the corresponding border with an offset of at
* least one canonical character height from that border's edges.
*
* If no border part could be found this way, return one of
* INTERNAL_BORDER_TOP_LEFT_CORNER, INTERNAL_BORDER_TOP_RIGHT_CORNER,
* INTERNAL_BORDER_BOTTOM_LEFT_CORNER or
* INTERNAL_BORDER_BOTTOM_RIGHT_CORNER to indicate that the mouse is in
* one of the corresponding corners. This means that for very small
* frames an `edge' return value is preferred.
*/
enum internal_border_part
frame_internal_border_part (struct frame *f, int x, int y)
{
int border = FRAME_INTERNAL_BORDER_WIDTH (f);
int offset = FRAME_LINE_HEIGHT (f);
int width = FRAME_PIXEL_WIDTH (f);
int height = FRAME_PIXEL_HEIGHT (f);
enum internal_border_part part = INTERNAL_BORDER_NONE;
if (offset < border)
/* For very wide borders make offset at least as large as
border. */
offset = border;
if (offset < x && x < width - offset)
/* Top or bottom border. */
{
if (0 <= y && y <= border)
part = INTERNAL_BORDER_TOP_EDGE;
else if (height - border <= y && y <= height)
part = INTERNAL_BORDER_BOTTOM_EDGE;
}
else if (offset < y && y < height - offset)
/* Left or right border. */
{
if (0 <= x && x <= border)
part = INTERNAL_BORDER_LEFT_EDGE;
else if (width - border <= x && x <= width)
part = INTERNAL_BORDER_RIGHT_EDGE;
}
else
{
/* An edge. */
int half_width = width / 2;
int half_height = height / 2;
if (0 <= x && x <= border)
{
/* A left edge. */
if (0 <= y && y <= half_height)
part = INTERNAL_BORDER_TOP_LEFT_CORNER;
else if (half_height < y && y <= height)
part = INTERNAL_BORDER_BOTTOM_LEFT_CORNER;
}
else if (width - border <= x && x <= width)
{
/* A right edge. */
if (0 <= y && y <= half_height)
part = INTERNAL_BORDER_TOP_RIGHT_CORNER;
else if (half_height < y && y <= height)
part = INTERNAL_BORDER_BOTTOM_RIGHT_CORNER;
}
else if (0 <= y && y <= border)
{
/* A top edge. */
if (0 <= x && x <= half_width)
part = INTERNAL_BORDER_TOP_LEFT_CORNER;
else if (half_width < x && x <= width)
part = INTERNAL_BORDER_TOP_RIGHT_CORNER;
}
else if (height - border <= y && y <= height)
{
/* A bottom edge. */
if (0 <= x && x <= half_width)
part = INTERNAL_BORDER_BOTTOM_LEFT_CORNER;
else if (half_width < x && x <= width)
part = INTERNAL_BORDER_BOTTOM_RIGHT_CORNER;
}
}
return part;
}
#endif
/* Return mouse position in character cell units. */
DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
@ -2962,18 +3195,33 @@ For a terminal screen, the value is always 1. */)
return make_number (1);
}
DEFUN ("frame-pixel-height", Fframe_pixel_height,
Sframe_pixel_height, 0, 1, 0,
doc: /* Return a FRAME's height in pixels.
DEFUN ("frame-native-width", Fframe_native_width,
Sframe_native_width, 0, 1, 0,
doc: /* Return FRAME's native width in pixels.
For a terminal frame, the result really gives the width in characters.
If FRAME is omitted or nil, the selected frame is used. */)
(Lisp_Object frame)
{
struct frame *f = decode_any_frame (frame);
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
return make_number (FRAME_PIXEL_WIDTH (f));
else
#endif
return make_number (FRAME_TOTAL_COLS (f));
}
DEFUN ("frame-native-height", Fframe_native_height,
Sframe_native_height, 0, 1, 0,
doc: /* Return FRAME's native height in pixels.
If FRAME is omitted or nil, the selected frame is used. The exact value
of the result depends on the window-system and toolkit in use:
In the Gtk+ version of Emacs, it includes only any window (including
the minibuffer or echo area), mode line, and header line. It does not
include the tool bar or menu bar.
With other graphical versions, it also includes the tool bar and the
menu bar.
In the Gtk+ and NS versions, it includes only any window (including the
minibuffer or echo area), mode line, and header line. It does not
include the tool bar or menu bar. With other graphical versions, it may
also include the tool bar and the menu bar.
For a text terminal, it includes the menu bar. In this case, the
result is really in characters rather than pixels (i.e., is identical
@ -2990,23 +3238,6 @@ to `frame-height'). */)
return make_number (FRAME_TOTAL_LINES (f));
}
DEFUN ("frame-pixel-width", Fframe_pixel_width,
Sframe_pixel_width, 0, 1, 0,
doc: /* Return FRAME's width in pixels.
For a terminal frame, the result really gives the width in characters.
If FRAME is omitted or nil, the selected frame is used. */)
(Lisp_Object frame)
{
struct frame *f = decode_any_frame (frame);
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
return make_number (FRAME_PIXEL_WIDTH (f));
else
#endif
return make_number (FRAME_TOTAL_COLS (f));
}
DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width,
Stool_bar_pixel_width, 0, 1, 0,
doc: /* Return width in pixels of FRAME's tool bar.
@ -3087,8 +3318,8 @@ DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0,
return make_number (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame)));
}
DEFUN ("frame-border-width", Fborder_width, Sborder_width, 0, 1, 0,
doc: /* Return border width of FRAME in pixels. */)
DEFUN ("frame-internal-border-width", Fframe_internal_border_width, Sframe_internal_border_width, 0, 1, 0,
doc: /* Return width of FRAME's internal border in pixels. */)
(Lisp_Object frame)
{
return make_number (FRAME_INTERNAL_BORDER_WIDTH (decode_any_frame (frame)));
@ -3224,7 +3455,6 @@ bottom edge of FRAME's display. */)
return Qt;
}
/***********************************************************************
Frame Parameters
@ -3289,10 +3519,193 @@ static const struct frame_parm_table frame_parms[] =
{"no-accept-focus", SYMBOL_INDEX (Qno_accept_focus)},
{"z-group", SYMBOL_INDEX (Qz_group)},
{"override-redirect", SYMBOL_INDEX (Qoverride_redirect)},
{"no-special-glyphs", SYMBOL_INDEX (Qno_special_glyphs)},
};
#ifdef HAVE_WINDOW_SYSTEM
/* Enumeration type for switch in frame_float. */
enum frame_float_type
{
FRAME_FLOAT_WIDTH,
FRAME_FLOAT_HEIGHT,
FRAME_FLOAT_LEFT,
FRAME_FLOAT_TOP
};
/**
* frame_float:
*
* Process the value VAL of the float type frame parameter 'width',
* 'height', 'left', or 'top' specified via a frame_float_type
* enumeration type WHAT for frame F. Such parameters relate the outer
* size or position of F to the size of the F's display or parent frame
* which have to be both available in some way.
*
* The return value is a size or position value in pixels. VAL must be
* in the range 0.0 to 1.0 where a width/height of 0.0 means to return 0
* and 1.0 means to return the full width/height of the display/parent.
* For positions, 0.0 means position in the left/top corner of the
* display/parent while 1.0 means to position at the right/bottom corner
* of the display/parent frame.
*
* Set PARENT_DONE and OUTER_DONE to avoid recalculation of the outer
* size or parent or display attributes when more float parameters are
* calculated in a row: -1 means not processed yet, 0 means processing
* failed, 1 means processing succeeded.
*
* Return DEFAULT_VALUE when processing fails for whatever reason with
* one exception: When calculating F's outer edges fails (probably
* because F has not been created yet) return the difference between F's
* native and text size.
*/
static int
frame_float (struct frame *f, Lisp_Object val, enum frame_float_type what,
int *parent_done, int *outer_done, int default_value)
{
double d_val = XFLOAT_DATA (val);
if (d_val < 0.0 || d_val > 1.0)
/* Invalid VAL. */
return default_value;
else
{
static unsigned parent_width, parent_height;
static int parent_left, parent_top;
static unsigned outer_minus_text_width, outer_minus_text_height;
struct frame *p = FRAME_PARENT_FRAME (f);
if (*parent_done == 1)
;
else if (p)
{
parent_width = FRAME_PIXEL_WIDTH (p);
parent_height = FRAME_PIXEL_HEIGHT (p);
*parent_done = 1;
}
else
{
if (*parent_done == 0)
/* No workarea available. */
return default_value;
else if (*parent_done == -1)
{
Lisp_Object monitor_attributes;
Lisp_Object workarea;
Lisp_Object frame;
XSETFRAME (frame, f);
monitor_attributes = Fcar (call1 (Qdisplay_monitor_attributes_list, frame));
if (NILP (monitor_attributes))
{
/* No monitor attributes available. */
*parent_done = 0;
return default_value;
}
workarea = Fcdr (Fassq (Qworkarea, monitor_attributes));
if (NILP (workarea))
{
/* No workarea available. */
*parent_done = 0;
return default_value;
}
/* Workarea available. */
parent_left = XINT (Fnth (make_number (0), workarea));
parent_top = XINT (Fnth (make_number (1), workarea));
parent_width = XINT (Fnth (make_number (2), workarea));
parent_height = XINT (Fnth (make_number (3), workarea));
*parent_done = 1;
}
}
if (*outer_done == 1)
;
else if (FRAME_UNDECORATED (f))
{
outer_minus_text_width
= FRAME_PIXEL_WIDTH (f) - FRAME_TEXT_WIDTH (f);
outer_minus_text_height
= FRAME_PIXEL_HEIGHT (f) - FRAME_TEXT_HEIGHT (f);
*outer_done = 1;
}
else if (*outer_done == 0)
/* No outer size available. */
return default_value;
else if (*outer_done == -1)
{
Lisp_Object frame, outer_edges;
XSETFRAME (frame, f);
outer_edges = call2 (Qframe_edges, frame, Qouter_edges);
if (!NILP (outer_edges))
{
outer_minus_text_width
= (XINT (Fnth (make_number (2), outer_edges))
- XINT (Fnth (make_number (0), outer_edges))
- FRAME_TEXT_WIDTH (f));
outer_minus_text_height
= (XINT (Fnth (make_number (3), outer_edges))
- XINT (Fnth (make_number (1), outer_edges))
- FRAME_TEXT_HEIGHT (f));
}
else
{
/* If we can't get any outer edges, proceed as if the frame
were undecorated. */
outer_minus_text_width
= FRAME_PIXEL_WIDTH (f) - FRAME_TEXT_WIDTH (f);
outer_minus_text_height
= FRAME_PIXEL_HEIGHT (f) - FRAME_TEXT_HEIGHT (f);
}
*outer_done = 1;
}
switch (what)
{
case FRAME_FLOAT_WIDTH:
return parent_width * d_val - outer_minus_text_width;
case FRAME_FLOAT_HEIGHT:
return parent_height * d_val - outer_minus_text_height;
case FRAME_FLOAT_LEFT:
{
int rest_width = (parent_width
- FRAME_TEXT_WIDTH (f)
- outer_minus_text_width);
if (p)
return (rest_width <= 0 ? 0 : d_val * rest_width);
else
return (rest_width <= 0
? parent_left
: parent_left + d_val * rest_width);
}
case FRAME_FLOAT_TOP:
{
int rest_height = (parent_height
- FRAME_TEXT_HEIGHT (f)
- outer_minus_text_height);
if (p)
return (rest_height <= 0 ? 0 : d_val * rest_height);
else
return (rest_height <= 0
? parent_top
: parent_top + d_val * rest_height);
}
default:
emacs_abort ();
}
}
}
/* Change the parameters of frame F as specified by ALIST.
If a parameter is not specially recognized, do nothing special;
otherwise call the `x_set_...' function for that parameter.
@ -3302,7 +3715,8 @@ static const struct frame_parm_table frame_parms[] =
void
x_set_frame_parameters (struct frame *f, Lisp_Object alist)
{
Lisp_Object tail;
Lisp_Object tail, frame;
/* If both of these parameters are present, it's more efficient to
set them both at once. So we wait until we've looked at the
@ -3327,7 +3741,9 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
#ifdef HAVE_X_WINDOWS
bool icon_left_no_change = 0, icon_top_no_change = 0;
#endif
int parent_done = -1, outer_done = -1;
XSETFRAME (frame, f);
for (size = 0, tail = alist; CONSP (tail); tail = XCDR (tail))
size++;
CHECK_LIST_END (tail, alist);
@ -3388,6 +3804,9 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels)
&& RANGED_INTEGERP (0, XCDR (val), INT_MAX))
width = XFASTINT (XCDR (val));
else if (FLOATP (val))
width = frame_float (f, val, FRAME_FLOAT_WIDTH, &parent_done,
&outer_done, -1);
}
else if (EQ (prop, Qheight))
{
@ -3396,6 +3815,9 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels)
&& RANGED_INTEGERP (0, XCDR (val), INT_MAX))
height = XFASTINT (XCDR (val));
else if (FLOATP (val))
height = frame_float (f, val, FRAME_FLOAT_HEIGHT, &parent_done,
&outer_done, -1);
}
else if (EQ (prop, Qtop))
top = val;
@ -3472,105 +3894,100 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
Don't set these parameters unless they actually differ from the
window's current parameters; the window may not actually exist
yet. */
{
Lisp_Object frame;
if ((width != -1 && width != FRAME_TEXT_WIDTH (f))
|| (height != -1 && height != FRAME_TEXT_HEIGHT (f)))
/* We could consider checking f->after_make_frame here, but I
don't have the faintest idea why the following is needed at
all. With the old setting it can get a Heisenbug when
EmacsFrameResize intermittently provokes a delayed
change_frame_size in the middle of adjust_frame_size. */
/** || (f->can_x_set_window_size && (f->new_height || f->new_width))) **/
adjust_frame_size (f, width, height, 1, 0, Qx_set_frame_parameters);
XSETFRAME (frame, f);
if ((!NILP (left) || !NILP (top))
&& ! (left_no_change && top_no_change)
&& ! (NUMBERP (left) && XINT (left) == f->left_pos
&& NUMBERP (top) && XINT (top) == f->top_pos))
{
int leftpos = 0;
int toppos = 0;
if ((width != -1 && width != FRAME_TEXT_WIDTH (f))
|| (height != -1 && height != FRAME_TEXT_HEIGHT (f)))
/* We could consider checking f->after_make_frame here, but I
don't have the faintest idea why the following is needed at
all. With the old setting it can get a Heisenbug when
EmacsFrameResize intermittently provokes a delayed
change_frame_size in the middle of adjust_frame_size. */
/** || (f->can_x_set_window_size && (f->new_height || f->new_width))) **/
adjust_frame_size (f, width, height, 1, 0, Qx_set_frame_parameters);
if ((!NILP (left) || !NILP (top))
&& ! (left_no_change && top_no_change)
&& ! (NUMBERP (left) && XINT (left) == f->left_pos
&& NUMBERP (top) && XINT (top) == f->top_pos))
{
int leftpos = 0;
int toppos = 0;
/* Record the signs. */
f->size_hint_flags &= ~ (XNegative | YNegative);
if (EQ (left, Qminus))
f->size_hint_flags |= XNegative;
else if (TYPE_RANGED_INTEGERP (int, left))
{
leftpos = XINT (left);
if (leftpos < 0)
f->size_hint_flags |= XNegative;
}
else if (CONSP (left) && EQ (XCAR (left), Qminus)
&& CONSP (XCDR (left))
&& RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX))
{
leftpos = - XINT (XCAR (XCDR (left)));
/* Record the signs. */
f->size_hint_flags &= ~ (XNegative | YNegative);
if (EQ (left, Qminus))
f->size_hint_flags |= XNegative;
else if (TYPE_RANGED_INTEGERP (int, left))
{
leftpos = XINT (left);
if (leftpos < 0)
f->size_hint_flags |= XNegative;
}
else if (CONSP (left) && EQ (XCAR (left), Qplus)
&& CONSP (XCDR (left))
&& TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left))))
{
leftpos = XINT (XCAR (XCDR (left)));
}
}
else if (CONSP (left) && EQ (XCAR (left), Qminus)
&& CONSP (XCDR (left))
&& RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX))
{
leftpos = - XINT (XCAR (XCDR (left)));
f->size_hint_flags |= XNegative;
}
else if (CONSP (left) && EQ (XCAR (left), Qplus)
&& CONSP (XCDR (left))
&& TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left))))
leftpos = XINT (XCAR (XCDR (left)));
else if (FLOATP (left))
leftpos = frame_float (f, left, FRAME_FLOAT_LEFT, &parent_done,
&outer_done, 0);
if (EQ (top, Qminus))
f->size_hint_flags |= YNegative;
else if (TYPE_RANGED_INTEGERP (int, top))
{
toppos = XINT (top);
if (toppos < 0)
f->size_hint_flags |= YNegative;
}
else if (CONSP (top) && EQ (XCAR (top), Qminus)
&& CONSP (XCDR (top))
&& RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX))
{
toppos = - XINT (XCAR (XCDR (top)));
if (EQ (top, Qminus))
f->size_hint_flags |= YNegative;
else if (TYPE_RANGED_INTEGERP (int, top))
{
toppos = XINT (top);
if (toppos < 0)
f->size_hint_flags |= YNegative;
}
else if (CONSP (top) && EQ (XCAR (top), Qplus)
&& CONSP (XCDR (top))
&& TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top))))
{
toppos = XINT (XCAR (XCDR (top)));
}
}
else if (CONSP (top) && EQ (XCAR (top), Qminus)
&& CONSP (XCDR (top))
&& RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX))
{
toppos = - XINT (XCAR (XCDR (top)));
f->size_hint_flags |= YNegative;
}
else if (CONSP (top) && EQ (XCAR (top), Qplus)
&& CONSP (XCDR (top))
&& TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top))))
toppos = XINT (XCAR (XCDR (top)));
else if (FLOATP (top))
toppos = frame_float (f, top, FRAME_FLOAT_TOP, &parent_done,
&outer_done, 0);
/* Store the numeric value of the position. */
f->top_pos = toppos;
f->left_pos = leftpos;
/* Store the numeric value of the position. */
f->top_pos = toppos;
f->left_pos = leftpos;
f->win_gravity = NorthWestGravity;
f->win_gravity = NorthWestGravity;
/* Actually set that position, and convert to absolute. */
x_set_offset (f, leftpos, toppos, -1);
}
/* Actually set that position, and convert to absolute. */
x_set_offset (f, leftpos, toppos, -1);
}
if (fullscreen_change)
{
Lisp_Object old_value = get_frame_param (f, Qfullscreen);
if (fullscreen_change)
{
Lisp_Object old_value = get_frame_param (f, Qfullscreen);
frame_size_history_add
(f, Qx_set_fullscreen, 0, 0, list2 (old_value, fullscreen));
frame_size_history_add
(f, Qx_set_fullscreen, 0, 0, list2 (old_value, fullscreen));
store_frame_param (f, Qfullscreen, fullscreen);
if (!EQ (fullscreen, old_value))
x_set_fullscreen (f, fullscreen, old_value);
}
store_frame_param (f, Qfullscreen, fullscreen);
if (!EQ (fullscreen, old_value))
x_set_fullscreen (f, fullscreen, old_value);
}
#ifdef HAVE_X_WINDOWS
if ((!NILP (icon_left) || !NILP (icon_top))
&& ! (icon_left_no_change && icon_top_no_change))
x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
if ((!NILP (icon_left) || !NILP (icon_top))
&& ! (icon_left_no_change && icon_top_no_change))
x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
#endif /* HAVE_X_WINDOWS */
}
SAFE_FREE ();
}
@ -3990,7 +4407,6 @@ x_set_right_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
adjust_frame_glyphs (f);
SET_FRAME_GARBAGED (f);
}
}
void
@ -4204,6 +4620,22 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
return;
}
/**
* x_set_no_special_glyphs:
*
* Set frame F's `no-special-glyphs' parameter which, if non-nil,
* suppresses the display of truncation and continuation glyphs
* outside fringes.
*/
void
x_set_no_special_glyphs (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
{
if (!EQ (new_value, old_value))
FRAME_NO_SPECIAL_GLYPHS (f) = !NILP (new_value);
}
#ifndef HAVE_NS
/* Non-zero if mouse is grabbed on DPYINFO
@ -4759,6 +5191,7 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x
Lisp_Object height, width, user_size, top, left, user_position;
long window_prompting = 0;
Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
int parent_done = -1, outer_done = -1;
/* Default values if we fall through.
Actually, if that happens we should get
@ -4823,6 +5256,21 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x
f->inhibit_horizontal_resize = true;
*x_width = XINT (XCDR (width));
}
else if (FLOATP (width))
{
double d_width = XFLOAT_DATA (width);
if (d_width < 0.0 || d_width > 1.0)
xsignal1 (Qargs_out_of_range, width);
else
{
int new_width = frame_float (f, width, FRAME_FLOAT_WIDTH,
&parent_done, &outer_done, -1);
if (new_width > -1)
SET_FRAME_WIDTH (f, new_width);
}
}
else
{
CHECK_NUMBER (width);
@ -4845,6 +5293,21 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x
f->inhibit_vertical_resize = true;
*x_height = XINT (XCDR (height));
}
else if (FLOATP (height))
{
double d_height = XFLOAT_DATA (height);
if (d_height < 0.0 || d_height > 1.0)
xsignal1 (Qargs_out_of_range, height);
else
{
int new_height = frame_float (f, height, FRAME_FLOAT_HEIGHT,
&parent_done, &outer_done, -1);
if (new_height > -1)
SET_FRAME_HEIGHT (f, new_height);
}
}
else
{
CHECK_NUMBER (height);
@ -4885,6 +5348,9 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x
{
f->top_pos = XINT (XCAR (XCDR (top)));
}
else if (FLOATP (top))
f->top_pos = frame_float (f, top, FRAME_FLOAT_TOP, &parent_done,
&outer_done, 0);
else if (EQ (top, Qunbound))
f->top_pos = 0;
else
@ -4913,6 +5379,9 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x
{
f->left_pos = XINT (XCAR (XCDR (left)));
}
else if (FLOATP (left))
f->left_pos = frame_float (f, left, FRAME_FLOAT_LEFT, &parent_done,
&outer_done, 0);
else if (EQ (left, Qunbound))
f->left_pos = 0;
else
@ -5071,12 +5540,14 @@ syms_of_frame (void)
DEFSYM (Qframep, "framep");
DEFSYM (Qframe_live_p, "frame-live-p");
DEFSYM (Qframe_windows_min_size, "frame-windows-min-size");
DEFSYM (Qdisplay_monitor_attributes_list, "display-monitor-attributes-list");
DEFSYM (Qwindow__pixel_to_total, "window--pixel-to-total");
DEFSYM (Qexplicit_name, "explicit-name");
DEFSYM (Qheight, "height");
DEFSYM (Qicon, "icon");
DEFSYM (Qminibuffer, "minibuffer");
DEFSYM (Qundecorated, "undecorated");
DEFSYM (Qno_special_glyphs, "no-special-glyphs");
DEFSYM (Qparent_frame, "parent-frame");
DEFSYM (Qskip_taskbar, "skip-taskbar");
DEFSYM (Qno_focus_on_map, "no-focus-on-map");
@ -5129,6 +5600,7 @@ syms_of_frame (void)
DEFSYM (Qframes, "frames");
DEFSYM (Qsource, "source");
DEFSYM (Qframe_edges, "frame-edges");
DEFSYM (Qouter_edges, "outer-edges");
DEFSYM (Qouter_position, "outer-position");
DEFSYM (Qouter_size, "outer-size");
@ -5220,6 +5692,11 @@ syms_of_frame (void)
DEFSYM (Qmin_width, "min-width");
DEFSYM (Qmin_height, "min-height");
DEFSYM (Qmouse_wheel_frame, "mouse-wheel-frame");
DEFSYM (Qkeep_ratio, "keep-ratio");
DEFSYM (Qwidth_only, "width-only");
DEFSYM (Qheight_only, "height-only");
DEFSYM (Qleft_only, "left-only");
DEFSYM (Qtop_only, "top-only");
{
int i;
@ -5564,8 +6041,8 @@ Gtk+ tooltips are not used) and on Windows. */);
defsubr (&Smodify_frame_parameters);
defsubr (&Sframe_char_height);
defsubr (&Sframe_char_width);
defsubr (&Sframe_pixel_height);
defsubr (&Sframe_pixel_width);
defsubr (&Sframe_native_height);
defsubr (&Sframe_native_width);
defsubr (&Sframe_text_cols);
defsubr (&Sframe_text_lines);
defsubr (&Sframe_total_cols);
@ -5575,7 +6052,7 @@ Gtk+ tooltips are not used) and on Windows. */);
defsubr (&Sscroll_bar_width);
defsubr (&Sscroll_bar_height);
defsubr (&Sfringe_width);
defsubr (&Sborder_width);
defsubr (&Sframe_internal_border_width);
defsubr (&Sright_divider_width);
defsubr (&Sbottom_divider_width);
defsubr (&Stool_bar_pixel_width);

View file

@ -52,6 +52,19 @@ enum z_group
z_group_below,
z_group_above_suspended,
};
enum internal_border_part
{
INTERNAL_BORDER_NONE,
INTERNAL_BORDER_LEFT_EDGE,
INTERNAL_BORDER_TOP_LEFT_CORNER,
INTERNAL_BORDER_TOP_EDGE,
INTERNAL_BORDER_TOP_RIGHT_CORNER,
INTERNAL_BORDER_RIGHT_EDGE,
INTERNAL_BORDER_BOTTOM_RIGHT_CORNER,
INTERNAL_BORDER_BOTTOM_EDGE,
INTERNAL_BORDER_BOTTOM_LEFT_CORNER,
};
#endif /* HAVE_WINDOW_SYSTEM */
/* The structure representing a frame. */
@ -354,7 +367,11 @@ struct frame
/* The z-group this frame's window belongs to. */
ENUM_BF (z_group) z_group : 2;
#endif /* HAVE_WINDOW_SYSTEM and not HAVE_NS */
/* Non-zero if display of truncation and continuation glyphs outside
the fringes is suppressed. */
bool_bf no_special_glyphs : 1;
#endif /* HAVE_WINDOW_SYSTEM */
/* Whether new_height and new_width shall be interpreted
in pixels. */
@ -824,7 +841,7 @@ default_pixels_per_inch_y (void)
#ifdef USE_GTK
#define FRAME_TOOL_BAR_POSITION(f) (f)->tool_bar_position
#else
#define FRAME_TOOL_BAR_POSITION(f) ((void) f, Qtop)
#define FRAME_TOOL_BAR_POSITION(f) ((void) (f), Qtop)
#endif
/* Number of lines of frame F used for the tool-bar. */
@ -908,16 +925,17 @@ default_pixels_per_inch_y (void)
((f)->vertical_scroll_bar_type == vertical_scroll_bar_right)
#else /* not HAVE_WINDOW_SYSTEM */
/* If there is no window system, there are no scroll bars. */
#define FRAME_VERTICAL_SCROLL_BAR_TYPE(f) ((void) f, vertical_scroll_bar_none)
#define FRAME_HAS_VERTICAL_SCROLL_BARS(f) ((void) f, 0)
#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT(f) ((void) f, 0)
#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) ((void) f, 0)
#define FRAME_VERTICAL_SCROLL_BAR_TYPE(f) \
((void) (f), vertical_scroll_bar_none)
#define FRAME_HAS_VERTICAL_SCROLL_BARS(f) ((void) (f), 0)
#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT(f) ((void) (f), 0)
#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) ((void) (f), 0)
#endif /* HAVE_WINDOW_SYSTEM */
#if defined (HAVE_WINDOW_SYSTEM)
#define FRAME_UNDECORATED(f) ((f)->undecorated)
#ifdef HAVE_NTGUI
#define FRAME_OVERRIDE_REDIRECT(f) ((void) f, 0)
#define FRAME_OVERRIDE_REDIRECT(f) ((void) (f), 0)
#else
#define FRAME_OVERRIDE_REDIRECT(f) ((f)->override_redirect)
#endif
@ -928,6 +946,7 @@ default_pixels_per_inch_y (void)
#define FRAME_SKIP_TASKBAR(f) ((f)->skip_taskbar)
#define FRAME_NO_FOCUS_ON_MAP(f) ((f)->no_focus_on_map)
#define FRAME_NO_ACCEPT_FOCUS(f) ((f)->no_accept_focus)
#define FRAME_NO_SPECIAL_GLYPHS(f) ((f)->no_special_glyphs)
#define FRAME_Z_GROUP(f) ((f)->z_group)
#define FRAME_Z_GROUP_NONE(f) ((f)->z_group == z_group_none)
#define FRAME_Z_GROUP_ABOVE(f) ((f)->z_group == z_group_above)
@ -935,16 +954,17 @@ default_pixels_per_inch_y (void)
((f)->z_group == z_group_above_suspended)
#define FRAME_Z_GROUP_BELOW(f) ((f)->z_group == z_group_below)
#else /* not HAVE_WINDOW_SYSTEM */
#define FRAME_UNDECORATED(f) ((void) f, 0)
#define FRAME_OVERRIDE_REDIRECT(f) ((void) f, 0)
#define FRAME_PARENT_FRAME(f) ((void) f, NULL)
#define FRAME_SKIP_TASKBAR(f) ((void) f, 0)
#define FRAME_NO_FOCUS_ON_MAP(f) ((void) f, 0)
#define FRAME_NO_ACCEPT_FOCUS(f) ((void) f, 0)
#define FRAME_Z_GROUP(f) ((void) f, z_group_none)
#define FRAME_Z_GROUP_NONE(f) ((void) f, true)
#define FRAME_Z_GROUP_ABOVE(f) ((void) f, false)
#define FRAME_Z_GROUP_BELOW(f) ((void) f, false)
#define FRAME_UNDECORATED(f) ((void) (f), 0)
#define FRAME_OVERRIDE_REDIRECT(f) ((void) (f), 0)
#define FRAME_PARENT_FRAME(f) ((void) (f), NULL)
#define FRAME_SKIP_TASKBAR(f) ((void) (f), 0)
#define FRAME_NO_FOCUS_ON_MAP(f) ((void) (f), 0)
#define FRAME_NO_ACCEPT_FOCUS(f) ((void) (f), 0)
#define FRAME_NO_SPECIAL_GLYPHS(f) ((void) (f), 0)
#define FRAME_Z_GROUP(f) ((void) (f), z_group_none)
#define FRAME_Z_GROUP_NONE(f) ((void) (f), true)
#define FRAME_Z_GROUP_ABOVE(f) ((void) (f), false)
#define FRAME_Z_GROUP_BELOW(f) ((void) (f), false)
#endif /* HAVE_WINDOW_SYSTEM */
/* Whether horizontal scroll bars are currently enabled for frame F. */
@ -952,7 +972,7 @@ default_pixels_per_inch_y (void)
#define FRAME_HAS_HORIZONTAL_SCROLL_BARS(f) \
((f)->horizontal_scroll_bars)
#else
#define FRAME_HAS_HORIZONTAL_SCROLL_BARS(f) ((void) f, 0)
#define FRAME_HAS_HORIZONTAL_SCROLL_BARS(f) ((void) (f), 0)
#endif
/* Width that a scroll bar in frame F should have, if there is one.
@ -1288,19 +1308,20 @@ FRAME_TOTAL_FRINGE_WIDTH (struct frame *f)
return FRAME_LEFT_FRINGE_WIDTH (f) + FRAME_RIGHT_FRINGE_WIDTH (f);
}
/* Pixel-width of internal border lines */
/* Pixel-width of internal border lines. */
INLINE int
FRAME_INTERNAL_BORDER_WIDTH (struct frame *f)
{
return frame_dimension (f->internal_border_width);
}
/* Pixel-size of window divider lines */
/* Pixel-size of window divider lines. */
INLINE int
FRAME_RIGHT_DIVIDER_WIDTH (struct frame *f)
{
return frame_dimension (f->right_divider_width);
}
INLINE int
FRAME_BOTTOM_DIVIDER_WIDTH (struct frame *f)
{
@ -1498,6 +1519,7 @@ extern void x_set_scroll_bar_height (struct frame *, Lisp_Object, Lisp_Object);
extern long x_figure_window_size (struct frame *, Lisp_Object, bool, int *, int *);
extern void x_set_alpha (struct frame *, Lisp_Object, Lisp_Object);
extern void x_set_no_special_glyphs (struct frame *, Lisp_Object, Lisp_Object);
extern void validate_x_resource_name (void);
@ -1521,6 +1543,7 @@ extern void x_real_positions (struct frame *, int *, int *);
extern void free_frame_menubar (struct frame *);
extern void x_free_frame_resources (struct frame *);
extern bool frame_ancestor_p (struct frame *af, struct frame *df);
extern enum internal_border_part frame_internal_border_part (struct frame *f, int x, int y);
#if defined HAVE_X_WINDOWS
extern void x_wm_set_icon_position (struct frame *, int, int);

View file

@ -1503,6 +1503,7 @@ xg_set_undecorated (struct frame *f, Lisp_Object undecorated)
void
xg_frame_restack (struct frame *f1, struct frame *f2, bool above_flag)
{
#if GTK_CHECK_VERSION (2, 18, 0)
block_input ();
if (FRAME_GTK_OUTER_WIDGET (f1) && FRAME_GTK_OUTER_WIDGET (f2))
{
@ -1517,6 +1518,7 @@ xg_frame_restack (struct frame *f1, struct frame *f2, bool above_flag)
x_sync (f1);
}
unblock_input ();
#endif
}

View file

@ -20,7 +20,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
/* Include this before including <setjmp.h> to work around bugs with
@ -41,6 +40,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "buffer.h"
#include "dispextern.h"
#include "blockinput.h"
#include "sysstdio.h"
#include "systime.h"
#include <epaths.h>
#include "coding.h"
@ -2361,7 +2361,7 @@ slurp_file (int fd, ptrdiff_t *size)
This can happen if the file grows as we read it. */
ptrdiff_t buflen = st.st_size;
buf = xmalloc (buflen + 1);
if (fread (buf, 1, buflen + 1, fp) == buflen)
if (fread_unlocked (buf, 1, buflen + 1, fp) == buflen)
*size = buflen;
else
{
@ -5890,7 +5890,7 @@ png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length)
{
FILE *fp = png_get_io_ptr (png_ptr);
if (fread (data, 1, length, fp) < length)
if (fread_unlocked (data, 1, length, fp) < length)
png_error (png_ptr, "Read error");
}
@ -5959,7 +5959,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
}
/* Check PNG signature. */
if (fread (sig, 1, sizeof sig, fp) != sizeof sig
if (fread_unlocked (sig, 1, sizeof sig, fp) != sizeof sig
|| png_sig_cmp (sig, 0, sizeof sig))
{
fclose (fp);
@ -6598,7 +6598,8 @@ our_stdio_fill_input_buffer (j_decompress_ptr cinfo)
{
ptrdiff_t bytes;
bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file);
bytes = fread_unlocked (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE,
src->file);
if (bytes > 0)
src->mgr.bytes_in_buffer = bytes;
else

View file

@ -85,10 +85,10 @@ struct interval
#define LEAF_INTERVAL_P(i) ((i)->left == NULL && (i)->right == NULL)
/* True if this interval has no parent and is therefore the root. */
#define ROOT_INTERVAL_P(i) (NULL_PARENT (i))
#define ROOT_INTERVAL_P(i) NULL_PARENT (i)
/* True if this interval is the only interval in the interval tree. */
#define ONLY_INTERVAL_P(i) (ROOT_INTERVAL_P ((i)) && LEAF_INTERVAL_P ((i)))
#define ONLY_INTERVAL_P(i) (ROOT_INTERVAL_P (i) && LEAF_INTERVAL_P (i))
/* True if this interval has both left and right children. */
#define BOTH_KIDS_P(i) ((i)->left != NULL && (i)->right != NULL)
@ -98,13 +98,13 @@ struct interval
#define TOTAL_LENGTH(i) ((i) == NULL ? 0 : (i)->total_length)
/* The size of text represented by this interval alone. */
#define LENGTH(i) ((i) == NULL ? 0 : (TOTAL_LENGTH ((i)) \
- TOTAL_LENGTH ((i)->right) \
- TOTAL_LENGTH ((i)->left)))
#define LENGTH(i) ((i)->total_length \
- TOTAL_LENGTH ((i)->right) \
- TOTAL_LENGTH ((i)->left))
/* The position of the character just past the end of I. Note that
the position cache i->position must be valid for this to work. */
#define INTERVAL_LAST_POS(i) ((i)->position + LENGTH ((i)))
#define INTERVAL_LAST_POS(i) ((i)->position + LENGTH (i))
/* The total size of the left subtree of this interval. */
#define LEFT_TOTAL_LENGTH(i) ((i)->left ? (i)->left->total_length : 0)

View file

@ -39,6 +39,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "intervals.h"
#include "keymap.h"
#include "blockinput.h"
#include "sysstdio.h"
#include "systime.h"
#include "atimer.h"
#include "process.h"
@ -3290,7 +3291,7 @@ record_char (Lisp_Object c)
if (INTEGERP (c))
{
if (XUINT (c) < 0x100)
putc (XUINT (c), dribble);
putc_unlocked (XUINT (c), dribble);
else
fprintf (dribble, " 0x%"pI"x", XUINT (c));
}
@ -3303,15 +3304,15 @@ record_char (Lisp_Object c)
if (SYMBOLP (dribblee))
{
putc ('<', dribble);
fwrite (SDATA (SYMBOL_NAME (dribblee)), sizeof (char),
SBYTES (SYMBOL_NAME (dribblee)),
dribble);
putc ('>', dribble);
putc_unlocked ('<', dribble);
fwrite_unlocked (SDATA (SYMBOL_NAME (dribblee)), sizeof (char),
SBYTES (SYMBOL_NAME (dribblee)),
dribble);
putc_unlocked ('>', dribble);
}
}
fflush (dribble);
fflush_unlocked (dribble);
unblock_input ();
}
}
@ -3769,7 +3770,7 @@ kbd_buffer_get_event (KBOARD **kbp,
detaching from the terminal. */
|| (IS_DAEMON && DAEMON_RUNNING))
{
int c = getchar ();
int c = getchar_unlocked ();
XSETINT (obj, c);
*kbp = current_kboard;
return obj;
@ -5126,6 +5127,17 @@ static short const scroll_bar_parts[] = {
SYMBOL_INDEX (Qrightmost), SYMBOL_INDEX (Qend_scroll), SYMBOL_INDEX (Qratio)
};
/* An array of symbol indexes of internal border parts, indexed by an enum
internal_border_part value. Note that Qnil corresponds to
internal_border_part_none and should not appear in Lisp events. */
static short const internal_border_parts[] = {
SYMBOL_INDEX (Qnil), SYMBOL_INDEX (Qleft_edge),
SYMBOL_INDEX (Qtop_left_corner), SYMBOL_INDEX (Qtop_edge),
SYMBOL_INDEX (Qtop_right_corner), SYMBOL_INDEX (Qright_edge),
SYMBOL_INDEX (Qbottom_right_corner), SYMBOL_INDEX (Qbottom_edge),
SYMBOL_INDEX (Qbottom_left_corner)
};
/* A vector, indexed by button number, giving the down-going location
of currently depressed buttons, both scroll bar and non-scroll bar.
@ -5163,15 +5175,15 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
Lisp_Object extra_info = Qnil;
/* Coordinate pixel positions to return. */
int xret = 0, yret = 0;
/* The window under frame pixel coordinates (x,y) */
Lisp_Object window = f
/* The window or frame under frame pixel coordinates (x,y) */
Lisp_Object window_or_frame = f
? window_from_coordinates (f, XINT (x), XINT (y), &part, 0)
: Qnil;
if (WINDOWP (window))
if (WINDOWP (window_or_frame))
{
/* It's a click in window WINDOW at frame coordinates (X,Y) */
struct window *w = XWINDOW (window);
struct window *w = XWINDOW (window_or_frame);
Lisp_Object string_info = Qnil;
ptrdiff_t textpos = 0;
int col = -1, row = -1;
@ -5360,17 +5372,31 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
make_number (row)),
extra_info)));
}
else if (f != 0)
#ifdef HAVE_WINDOW_SYSTEM
else if (f)
{
/* Return mouse pixel coordinates here. */
XSETFRAME (window, f);
XSETFRAME (window_or_frame, f);
xret = XINT (x);
yret = XINT (y);
}
else
window = Qnil;
return Fcons (window,
if (FRAME_LIVE_P (f)
&& FRAME_INTERNAL_BORDER_WIDTH (f) > 0
&& !NILP (get_frame_param (f, Qdrag_internal_border)))
{
enum internal_border_part part
= frame_internal_border_part (f, xret, yret);
posn = builtin_lisp_symbol (internal_border_parts[part]);
}
}
#endif
else
window_or_frame = Qnil;
return Fcons (window_or_frame,
Fcons (posn,
Fcons (Fcons (make_number (xret),
make_number (yret)),
@ -10377,7 +10403,7 @@ handle_interrupt (bool in_signal_handler)
sigemptyset (&blocked);
sigaddset (&blocked, SIGINT);
pthread_sigmask (SIG_BLOCK, &blocked, 0);
fflush (stdout);
fflush_unlocked (stdout);
}
reset_all_sys_modes ();
@ -11158,6 +11184,17 @@ syms_of_keyboard (void)
Fset (Qinput_method_exit_on_first_char, Qnil);
Fset (Qinput_method_use_echo_area, Qnil);
/* Symbols for dragging internal borders. */
DEFSYM (Qdrag_internal_border, "drag-internal-border");
DEFSYM (Qleft_edge, "left-edge");
DEFSYM (Qtop_left_corner, "top-left-corner");
DEFSYM (Qtop_edge, "top-edge");
DEFSYM (Qtop_right_corner, "top-right-corner");
DEFSYM (Qright_edge, "right-edge");
DEFSYM (Qbottom_right_corner, "bottom-right-corner");
DEFSYM (Qbottom_edge, "bottom-edge");
DEFSYM (Qbottom_left_corner, "bottom-left-corner");
/* Symbols to head events. */
DEFSYM (Qmouse_movement, "mouse-movement");
DEFSYM (Qscroll_bar_movement, "scroll-bar-movement");

View file

@ -72,10 +72,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define file_tell ftell
#endif
#ifndef HAVE_GETC_UNLOCKED
#define getc_unlocked getc
#endif
/* The objects or placeholders read with the #n=object form.
A hash table maps a number to either a placeholder (while the
@ -474,16 +470,15 @@ readbyte_from_file (int c, Lisp_Object readcharfun)
}
block_input ();
c = getc_unlocked (instream);
/* Interrupted reads have been observed while reading over the network. */
while (c == EOF && ferror (instream) && errno == EINTR)
while ((c = getc_unlocked (instream)) == EOF && errno == EINTR
&& ferror_unlocked (instream))
{
unblock_input ();
maybe_quit ();
block_input ();
clearerr (instream);
c = getc_unlocked (instream);
clearerr_unlocked (instream);
}
unblock_input ();

View file

@ -20,7 +20,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <errno.h>
#include <stdio.h>
#include <binary-io.h>
@ -31,6 +30,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "frame.h"
#include "window.h"
#include "keymap.h"
#include "sysstdio.h"
#include "systty.h"
/* List of buffers for use as minibuffers.
@ -209,15 +209,15 @@ read_minibuf_noninteractive (Lisp_Object map, Lisp_Object initial,
suppress_echo_on_tty (STDIN_FILENO);
}
fwrite (SDATA (prompt), 1, SBYTES (prompt), stdout);
fflush (stdout);
fwrite_unlocked (SDATA (prompt), 1, SBYTES (prompt), stdout);
fflush_unlocked (stdout);
val = Qnil;
size = 100;
len = 0;
line = xmalloc (size);
while ((c = getchar ()) != '\n' && c != '\r')
while ((c = getchar_unlocked ()) != '\n' && c != '\r')
{
if (c == EOF)
{
@ -874,6 +874,30 @@ read_minibuf_unwind (void)
if (minibuf_level == 0)
resize_mini_window (XWINDOW (window), 0);
/* Deal with frames that should be removed when exiting the
minibuffer. */
{
Lisp_Object frames, frame1, val;
struct frame *f1;
FOR_EACH_FRAME (frames, frame1)
{
f1 = XFRAME (frame1);
if ((FRAME_PARENT_FRAME (f1)
|| !NILP (get_frame_param (f1, Qdelete_before)))
&& !NILP (val = (get_frame_param (f1, Qminibuffer_exit))))
{
if (EQ (val, Qiconify_frame))
Ficonify_frame (frame1);
else if (EQ (val, Qdelete_frame))
Fdelete_frame (frame1, Qnil);
else
Fmake_frame_invisible (frame1, Qnil);
}
}
}
/* In case the previous minibuffer displayed in this miniwindow is
dead, we may keep displaying this buffer (tho it's inactive), so reset it,
to make sure we don't leave around bindings and stuff which only
@ -1930,6 +1954,8 @@ syms_of_minibuf (void)
DEFSYM (Qactivate_input_method, "activate-input-method");
DEFSYM (Qcase_fold_search, "case-fold-search");
DEFSYM (Qmetadata, "metadata");
/* A frame parameter. */
DEFSYM (Qminibuffer_exit, "minibuffer-exit");
DEFVAR_LISP ("read-expression-history", Vread_expression_history,
doc: /* A history list for arguments that are Lisp expressions to evaluate.

View file

@ -92,7 +92,7 @@
SIZE must point to the total size of the buffer. If BUFFER is
NULL or if SIZE is not big enough, write the required buffer size
to SIZE and return false.
to SIZE and return true.
Note that SIZE must include the last null byte (e.g. "abc" needs
a buffer of size 4).

View file

@ -984,6 +984,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
x_set_no_accept_focus,
x_set_z_group, /* x_set_z_group */
0, /* x_set_override_redirect */
x_set_no_special_glyphs,
};
@ -1256,6 +1257,8 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
"leftFringe", "LeftFringe", RES_TYPE_NUMBER);
x_default_parameter (f, parms, Qright_fringe, Qnil,
"rightFringe", "RightFringe", RES_TYPE_NUMBER);
x_default_parameter (f, parms, Qno_special_glyphs, Qnil,
NULL, NULL, RES_TYPE_BOOLEAN);
init_frame_faces (f);
@ -1325,6 +1328,15 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
f->output_data.ns->hourglass_cursor = [NSCursor disappearingItemCursor];
f->output_data.ns->horizontal_drag_cursor = [NSCursor resizeLeftRightCursor];
f->output_data.ns->vertical_drag_cursor = [NSCursor resizeUpDownCursor];
f->output_data.ns->left_edge_cursor = [NSCursor resizeLeftRightCursor];
f->output_data.ns->top_left_corner_cursor = [NSCursor arrowCursor];
f->output_data.ns->top_edge_cursor = [NSCursor resizeUpDownCursor];
f->output_data.ns->top_right_corner_cursor = [NSCursor arrowCursor];
f->output_data.ns->right_edge_cursor = [NSCursor resizeLeftRightCursor];
f->output_data.ns->bottom_right_corner_cursor = [NSCursor arrowCursor];
f->output_data.ns->bottom_edge_cursor = [NSCursor resizeUpDownCursor];
f->output_data.ns->bottom_left_corner_cursor = [NSCursor arrowCursor];
FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor
= [NSCursor arrowCursor];
FRAME_DISPLAY_INFO (f)->horizontal_scroll_bar_cursor

View file

@ -957,6 +957,14 @@ struct ns_output
Cursor hourglass_cursor;
Cursor horizontal_drag_cursor;
Cursor vertical_drag_cursor;
Cursor left_edge_cursor;
Cursor top_left_corner_cursor;
Cursor top_edge_cursor;
Cursor top_right_corner_cursor;
Cursor right_edge_cursor;
Cursor bottom_right_corner_cursor;
Cursor bottom_edge_cursor;
Cursor bottom_left_corner_cursor;
/* NS-specific */
Cursor current_pointer;
@ -1225,8 +1233,11 @@ extern void x_set_no_accept_focus (struct frame *f, Lisp_Object new_value,
extern void x_set_z_group (struct frame *f, Lisp_Object new_value,
Lisp_Object old_value);
extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timespec const *timeout,
sigset_t const *sigmask);
fd_set *exceptfds, struct timespec *timeout,
sigset_t *sigmask);
#ifdef HAVE_PTHREAD
extern void ns_run_loop_break (void);
#endif
extern unsigned long ns_get_rgb_color (struct frame *f,
float r, float g, float b, float a);

View file

@ -4068,7 +4068,7 @@ overwriting cursor (usually when cursor on a tab) */
app->nextappdefined = value;
[app performSelectorOnMainThread:@selector (sendFromMainThread:)
withObject:nil
waitUntilDone:YES];
waitUntilDone:NO];
return;
}
@ -4293,8 +4293,8 @@ in certain situations (rapid incoming events).
int
ns_select (int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timespec const *timeout,
sigset_t const *sigmask)
fd_set *exceptfds, struct timespec *timeout,
sigset_t *sigmask)
/* --------------------------------------------------------------------------
Replacement for select, checking for events
-------------------------------------------------------------------------- */
@ -4327,7 +4327,13 @@ in certain situations (rapid incoming events).
if (NSApp == nil
|| ![NSThread isMainThread]
|| (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0))
return pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask);
return thread_select(pselect, nfds, readfds, writefds,
exceptfds, timeout, sigmask);
else
{
struct timespec t = {0, 0};
thread_select(pselect, 0, NULL, NULL, NULL, &t, sigmask);
}
[outerpool release];
outerpool = [[NSAutoreleasePool alloc] init];
@ -4430,6 +4436,18 @@ in certain situations (rapid incoming events).
return result;
}
#ifdef HAVE_PTHREAD
void
ns_run_loop_break ()
/* Break out of the NS run loop in ns_select or ns_read_socket. */
{
NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_run_loop_break");
/* If we don't have a GUI, don't send the event. */
if (NSApp != NULL)
ns_send_appdefined(-1);
}
#endif
/* ==========================================================================

View file

@ -228,7 +228,7 @@ printchar_to_stream (unsigned int ch, FILE *stream)
{
if (ASCII_CHAR_P (ch))
{
putc (ch, stream);
putc_unlocked (ch, stream);
#ifdef WINDOWSNT
/* Send the output to a debugger (nothing happens if there
isn't one). */
@ -246,7 +246,7 @@ printchar_to_stream (unsigned int ch, FILE *stream)
if (encode_p)
encoded_ch = code_convert_string_norecord (encoded_ch,
coding_system, true);
fwrite (SSDATA (encoded_ch), 1, SBYTES (encoded_ch), stream);
fwrite_unlocked (SSDATA (encoded_ch), 1, SBYTES (encoded_ch), stream);
#ifdef WINDOWSNT
if (print_output_debug_flag && stream == stderr)
OutputDebugString (SSDATA (encoded_ch));
@ -298,7 +298,7 @@ printchar (unsigned int ch, Lisp_Object fun)
if (DISP_TABLE_P (Vstandard_display_table))
printchar_to_stream (ch, stdout);
else
fwrite (str, 1, len, stdout);
fwrite_unlocked (str, 1, len, stdout);
noninteractive_need_newline = 1;
}
else
@ -350,7 +350,7 @@ strout (const char *ptr, ptrdiff_t size, ptrdiff_t size_byte,
}
}
else
fwrite (ptr, 1, size_byte, stdout);
fwrite_unlocked (ptr, 1, size_byte, stdout);
noninteractive_need_newline = 1;
}
@ -801,7 +801,7 @@ append to existing target file. */)
report_file_error ("Cannot open debugging output stream", file);
}
fflush (stderr);
fflush_unlocked (stderr);
if (dup2 (fd, STDERR_FILENO) < 0)
report_file_error ("dup2", file);
if (fd != stderr_dup)
@ -1870,21 +1870,36 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
}
else
{
bool still_need_nonhex = false;
/* If we just had a hex escape, and this character
could be taken as part of it,
output `\ ' to prevent that. */
if (need_nonhex && c_isxdigit (c))
print_c_string ("\\ ", printcharfun);
if (c == '\n' && print_escape_newlines
? (c = 'n', true)
: c == '\f' && print_escape_newlines
? (c = 'f', true)
: c == '\"' || c == '\\')
printchar ('\\', printcharfun);
printchar (c, printcharfun);
need_nonhex = false;
if (c_isxdigit (c))
{
if (need_nonhex)
print_c_string ("\\ ", printcharfun);
printchar (c, printcharfun);
}
else if (c == '\n' && print_escape_newlines
? (c = 'n', true)
: c == '\f' && print_escape_newlines
? (c = 'f', true)
: c == '\0' && print_escape_control_characters
? (c = '0', still_need_nonhex = true)
: c == '\"' || c == '\\')
{
printchar ('\\', printcharfun);
printchar (c, printcharfun);
}
else if (print_escape_control_characters && c_iscntrl (c))
{
char outbuf[1 + 3 + 1];
int len = sprintf (outbuf, "\\%03o", c + 0u);
strout (outbuf, len, len, printcharfun);
}
else
printchar (c, printcharfun);
need_nonhex = still_need_nonhex;
}
}
printchar ('\"', printcharfun);
@ -2329,6 +2344,11 @@ A value of nil means no limit. See also `eval-expression-print-level'. */);
Also print formfeeds as `\\f'. */);
print_escape_newlines = 0;
DEFVAR_BOOL ("print-escape-control-characters", print_escape_control_characters,
doc: /* Non-nil means print control characters in strings as `\\OOO'.
\(OOO is the octal representation of the character code.)*/);
print_escape_control_characters = 0;
DEFVAR_BOOL ("print-escape-nonascii", print_escape_nonascii,
doc: /* Non-nil means print unibyte non-ASCII chars in strings as \\OOO.
\(OOO is the octal representation of the character code.)
@ -2418,6 +2438,7 @@ priorities. */);
DEFSYM (Qprint_escape_newlines, "print-escape-newlines");
DEFSYM (Qprint_escape_multibyte, "print-escape-multibyte");
DEFSYM (Qprint_escape_nonascii, "print-escape-nonascii");
DEFSYM (Qprint_escape_control_characters, "print-escape-control-characters");
print_prune_charset_plist = Qnil;
staticpro (&print_prune_charset_plist);

View file

@ -5371,14 +5371,13 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
nfds = xg_select (max_desc + 1,
&Available, (check_write ? &Writeok : 0),
NULL, &timeout, NULL);
#elif defined HAVE_NS
/* And NS builds call thread_select in ns_select. */
nfds = ns_select (max_desc + 1,
&Available, (check_write ? &Writeok : 0),
NULL, &timeout, NULL);
#else /* !HAVE_GLIB */
nfds = thread_select (
# ifdef HAVE_NS
ns_select
# else
pselect
# endif
, max_desc + 1,
nfds = thread_select (pselect, max_desc + 1,
&Available,
(check_write ? &Writeok : 0),
NULL, &timeout, NULL);

View file

@ -1408,7 +1408,7 @@ reset_sys_modes (struct tty_display_info *tty_out)
{
if (noninteractive)
{
fflush (stdout);
fflush_unlocked (stdout);
return;
}
if (!tty_out->term_initted)
@ -1428,17 +1428,14 @@ reset_sys_modes (struct tty_display_info *tty_out)
}
else
{ /* have to do it the hard way */
int i;
tty_turn_off_insert (tty_out);
for (i = cursorX (tty_out); i < FrameCols (tty_out) - 1; i++)
{
fputc (' ', tty_out->output);
}
for (int i = cursorX (tty_out); i < FrameCols (tty_out) - 1; i++)
fputc_unlocked (' ', tty_out->output);
}
cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
fflush (tty_out->output);
fflush_unlocked (tty_out->output);
if (tty_out->terminal->reset_terminal_modes_hook)
tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal);
@ -3079,7 +3076,7 @@ procfs_ttyname (int rdev)
char minor[25]; /* 2 32-bit numbers + dash */
char *endp;
for (; !feof (fdev) && !ferror (fdev); name[0] = 0)
for (; !feof_unlocked (fdev) && !ferror_unlocked (fdev); name[0] = 0)
{
if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3
&& major == MAJOR (rdev))
@ -3129,7 +3126,7 @@ procfs_get_total_memory (void)
break;
case 0:
while ((c = getc (fmem)) != EOF && c != '\n')
while ((c = getc_unlocked (fmem)) != EOF && c != '\n')
continue;
done = c == EOF;
break;

View file

@ -33,4 +33,45 @@ extern FILE *emacs_fopen (char const *, char const *);
# define FOPEN_TEXT ""
#endif
/* These are compatible with unlocked-io.h, if both files are included. */
#if !HAVE_DECL_CLEARERR_UNLOCKED
# define clearerr_unlocked(x) clearerr (x)
#endif
#if !HAVE_DECL_FEOF_UNLOCKED
# define feof_unlocked(x) feof (x)
#endif
#if !HAVE_DECL_FERROR_UNLOCKED
# define ferror_unlocked(x) ferror (x)
#endif
#if !HAVE_DECL_FFLUSH_UNLOCKED
# define fflush_unlocked(x) fflush (x)
#endif
#if !HAVE_DECL_FGETS_UNLOCKED
# define fgets_unlocked(x,y,z) fgets (x,y,z)
#endif
#if !HAVE_DECL_FPUTC_UNLOCKED
# define fputc_unlocked(x,y) fputc (x,y)
#endif
#if !HAVE_DECL_FPUTS_UNLOCKED
# define fputs_unlocked(x,y) fputs (x,y)
#endif
#if !HAVE_DECL_FREAD_UNLOCKED
# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
#endif
#if !HAVE_DECL_FWRITE_UNLOCKED
# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
#endif
#if !HAVE_DECL_GETC_UNLOCKED
# define getc_unlocked(x) getc (x)
#endif
#if !HAVE_DECL_GETCHAR_UNLOCKED
# define getchar_unlocked() getchar ()
#endif
#if !HAVE_DECL_PUTC_UNLOCKED
# define putc_unlocked(x,y) putc (x,y)
#endif
#if !HAVE_DECL_PUTCHAR_UNLOCKED
# define putchar_unlocked(x) putchar (x)
#endif
#endif /* EMACS_SYSSTDIO_H */

View file

@ -20,6 +20,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <setjmp.h>
#include "lisp.h"
#ifdef HAVE_NS
#include "nsterm.h"
#endif
#ifndef THREADS_ENABLED
void
@ -130,6 +134,13 @@ void
sys_cond_broadcast (sys_cond_t *cond)
{
pthread_cond_broadcast (cond);
#ifdef HAVE_NS
/* Send an app defined event to break out of the NS run loop.
It seems that if ns_select is running the NS run loop, this
broadcast has no effect until the loop is done, breaking a couple
of tests in thread-tests.el. */
ns_run_loop_break ();
#endif
}
void

View file

@ -22,7 +22,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
#include <sys/time.h>
@ -45,6 +44,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "keymap.h"
#include "blockinput.h"
#include "syssignal.h"
#include "sysstdio.h"
#ifdef MSDOS
#include "msdos.h"
static int been_here = -1;
@ -146,7 +146,7 @@ tty_ring_bell (struct frame *f)
OUTPUT (tty, (tty->TS_visible_bell && visible_bell
? tty->TS_visible_bell
: tty->TS_bell));
fflush (tty->output);
fflush_unlocked (tty->output);
}
}
@ -167,9 +167,10 @@ tty_send_additional_strings (struct terminal *terminal, Lisp_Object sym)
Lisp_Object string = XCAR (extra_codes);
if (STRINGP (string))
{
fwrite (SDATA (string), 1, SBYTES (string), tty->output);
fwrite_unlocked (SDATA (string), 1, SBYTES (string), tty->output);
if (tty->termscript)
fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
fwrite_unlocked (SDATA (string), 1, SBYTES (string),
tty->termscript);
}
}
}
@ -197,7 +198,7 @@ tty_set_terminal_modes (struct terminal *terminal)
OUTPUT_IF (tty, tty->TS_keypad_mode);
losecursor (tty);
tty_send_additional_strings (terminal, Qtty_mode_set_strings);
fflush (tty->output);
fflush_unlocked (tty->output);
}
}
@ -220,7 +221,7 @@ tty_reset_terminal_modes (struct terminal *terminal)
/* Output raw CR so kernel can track the cursor hpos. */
current_tty = tty;
cmputc ('\r');
fflush (tty->output);
fflush_unlocked (tty->output);
}
}
@ -235,7 +236,7 @@ tty_update_end (struct frame *f)
tty_show_cursor (tty);
tty_turn_off_insert (tty);
tty_background_highlight (tty);
fflush (tty->output);
fflush_unlocked (tty->output);
}
/* The implementation of set_terminal_window for termcap frames. */
@ -497,8 +498,8 @@ tty_clear_end_of_line (struct frame *f, int first_unused_hpos)
for (i = curX (tty); i < first_unused_hpos; i++)
{
if (tty->termscript)
fputc (' ', tty->termscript);
fputc (' ', tty->output);
fputc_unlocked (' ', tty->termscript);
fputc_unlocked (' ', tty->output);
}
cmplus (tty, first_unused_hpos - curX (tty));
}
@ -771,11 +772,11 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
if (coding->produced > 0)
{
block_input ();
fwrite (conversion_buffer, 1, coding->produced, tty->output);
if (ferror (tty->output))
clearerr (tty->output);
fwrite_unlocked (conversion_buffer, 1, coding->produced, tty->output);
clearerr_unlocked (tty->output);
if (tty->termscript)
fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
fwrite_unlocked (conversion_buffer, 1, coding->produced,
tty->termscript);
unblock_input ();
}
string += n;
@ -832,11 +833,11 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str
if (coding->produced > 0)
{
block_input ();
fwrite (conversion_buffer, 1, coding->produced, tty->output);
if (ferror (tty->output))
clearerr (tty->output);
fwrite_unlocked (conversion_buffer, 1, coding->produced, tty->output);
clearerr_unlocked (tty->output);
if (tty->termscript)
fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
fwrite_unlocked (conversion_buffer, 1, coding->produced,
tty->termscript);
unblock_input ();
}
@ -918,11 +919,11 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
if (coding->produced > 0)
{
block_input ();
fwrite (conversion_buffer, 1, coding->produced, tty->output);
if (ferror (tty->output))
clearerr (tty->output);
fwrite_unlocked (conversion_buffer, 1, coding->produced, tty->output);
clearerr_unlocked (tty->output);
if (tty->termscript)
fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
fwrite_unlocked (conversion_buffer, 1, coding->produced,
tty->termscript);
unblock_input ();
}
@ -3327,7 +3328,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
which calls tty_show_cursor. Re-hide it, so it doesn't show
through the menus. */
tty_hide_cursor (tty);
fflush (tty->output);
fflush_unlocked (tty->output);
}
sf->mouse_moved = 0;
@ -3335,7 +3336,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
while (statecount--)
free_saved_screen (state[statecount].screen_behind);
tty_show_cursor (tty); /* Turn cursor back on. */
fflush (tty->output);
fflush_unlocked (tty->output);
/* Clean up any mouse events that are waiting inside Emacs event queue.
These events are likely to be generated before the menu was even

View file

@ -5889,6 +5889,8 @@ This function is an internal primitive--use `make-frame' instead. */)
NULL, NULL, RES_TYPE_BOOLEAN);
x_default_parameter (f, parameters, Qno_accept_focus, Qnil,
NULL, NULL, RES_TYPE_BOOLEAN);
x_default_parameter (f, parameters, Qno_special_glyphs, Qnil,
NULL, NULL, RES_TYPE_BOOLEAN);
/* Process alpha here (Bug#16619). On XP this fails with child
frames. For `no-focus-on-map' frames delay processing of alpha
@ -5957,6 +5959,14 @@ This function is an internal primitive--use `make-frame' instead. */)
f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT);
f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE);
f->output_data.w32->vertical_drag_cursor = w32_load_cursor (IDC_SIZENS);
f->output_data.w32->left_edge_cursor = w32_load_cursor (IDC_SIZEWE);
f->output_data.w32->top_left_corner_cursor = w32_load_cursor (IDC_SIZENWSE);
f->output_data.w32->top_edge_cursor = w32_load_cursor (IDC_SIZENS);
f->output_data.w32->top_right_corner_cursor = w32_load_cursor (IDC_SIZENESW);
f->output_data.w32->right_edge_cursor = w32_load_cursor (IDC_SIZEWE);
f->output_data.w32->bottom_right_corner_cursor = w32_load_cursor (IDC_SIZENWSE);
f->output_data.w32->bottom_edge_cursor = w32_load_cursor (IDC_SIZENS);
f->output_data.w32->bottom_left_corner_cursor = w32_load_cursor (IDC_SIZENESW);
f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor;
@ -7049,6 +7059,8 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
"cursorColor", "Foreground", RES_TYPE_STRING);
x_default_parameter (f, parms, Qborder_color, build_string ("black"),
"borderColor", "BorderColor", RES_TYPE_STRING);
x_default_parameter (f, parms, Qno_special_glyphs, Qt,
NULL, NULL, RES_TYPE_BOOLEAN);
/* Init faces before x_default_parameter is called for the
scroll-bar-width parameter because otherwise we end up in
@ -8950,33 +8962,47 @@ menu bar or tool bar of FRAME. */)
if (EQ (type, Qouter_edges))
{
RECT rectangle;
BOOL success = false;
block_input ();
/* Outer frame rectangle, including outer borders and title bar. */
GetWindowRect (FRAME_W32_WINDOW (f), &rectangle);
success = GetWindowRect (FRAME_W32_WINDOW (f), &rectangle);
unblock_input ();
return list4 (make_number (rectangle.left),
make_number (rectangle.top),
make_number (rectangle.right),
make_number (rectangle.bottom));
if (success)
return list4 (make_number (rectangle.left),
make_number (rectangle.top),
make_number (rectangle.right),
make_number (rectangle.bottom));
else
return Qnil;
}
else
{
RECT rectangle;
POINT pt;
int left, top, right, bottom;
BOOL success;
block_input ();
/* Inner frame rectangle, excluding borders and title bar. */
GetClientRect (FRAME_W32_WINDOW (f), &rectangle);
success = GetClientRect (FRAME_W32_WINDOW (f), &rectangle);
/* Get top-left corner of native rectangle in screen
coordinates. */
if (!success)
{
unblock_input ();
return Qnil;
}
pt.x = 0;
pt.y = 0;
ClientToScreen (FRAME_W32_WINDOW (f), &pt);
success = ClientToScreen (FRAME_W32_WINDOW (f), &pt);
unblock_input ();
if (!success)
return Qnil;
left = pt.x;
top = pt.y;
right = left + rectangle.right;
@ -10330,6 +10356,7 @@ frame_parm_handler w32_frame_parm_handlers[] =
x_set_no_accept_focus,
x_set_z_group,
0, /* x_set_override_redirect */
x_set_no_special_glyphs,
};
void

View file

@ -5086,6 +5086,51 @@ w32_read_socket (struct terminal *terminal,
}
case WM_WINDOWPOSCHANGED:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
{
RECT rect;
int /* rows, columns, */ width, height, text_width, text_height;
if (GetClientRect (msg.msg.hwnd, &rect)
/* GetClientRect evidently returns (0, 0, 0, 0) if
called on a minimized frame. Such "dimensions"
aren't useful anyway. */
&& !(rect.bottom == 0
&& rect.top == 0
&& rect.left == 0
&& rect.right == 0))
{
height = rect.bottom - rect.top;
width = rect.right - rect.left;
text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, width);
text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, height);
/* rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height); */
/* columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width); */
/* TODO: Clip size to the screen dimensions. */
/* Even if the number of character rows and columns
has not changed, the font size may have changed,
so we need to check the pixel dimensions as well. */
if (width != FRAME_PIXEL_WIDTH (f)
|| height != FRAME_PIXEL_HEIGHT (f)
|| text_width != FRAME_TEXT_WIDTH (f)
|| text_height != FRAME_TEXT_HEIGHT (f))
{
change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
f->win_gravity = NorthWestGravity;
}
}
}
check_visibility = 1;
break;
case WM_ACTIVATE:
case WM_ACTIVATEAPP:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
@ -6052,7 +6097,7 @@ x_calc_absolute_position (struct frame *f)
int display_top = 0;
struct frame *p = FRAME_PARENT_FRAME (f);
if (flags & (XNegative | YNegative))
if (!p && flags & (XNegative | YNegative))
{
Lisp_Object list;
@ -6078,20 +6123,26 @@ x_calc_absolute_position (struct frame *f)
}
/* Treat negative positions as relative to the rightmost bottommost
position that fits on the screen. */
position that fits on the screen or parent frame.
I see no need for subtracting 1 from the border widths - is there
any on the remaining platforms? Here these subtractions did put
the last pixel line/column of a frame off-display when, for
example, a (set-frame-parameter nil 'left '(- 0)) specification was
used - martin 20017-05-05. */
if (flags & XNegative)
{
if (p)
f->left_pos = (FRAME_PIXEL_WIDTH (p)
- FRAME_PIXEL_WIDTH (f)
+ f->left_pos
- (left_right_borders_width - 1));
- left_right_borders_width);
else
f->left_pos = (x_display_pixel_width (FRAME_DISPLAY_INFO (f))
+ display_left
- FRAME_PIXEL_WIDTH (f)
+ f->left_pos
- (left_right_borders_width - 1));
- left_right_borders_width);
}
if (flags & YNegative)
@ -6100,13 +6151,13 @@ x_calc_absolute_position (struct frame *f)
f->top_pos = (FRAME_PIXEL_HEIGHT (p)
- FRAME_PIXEL_HEIGHT (f)
+ f->top_pos
- (top_bottom_borders_height - 1));
- top_bottom_borders_height);
else
f->top_pos = (x_display_pixel_height (FRAME_DISPLAY_INFO (f))
+ display_top
- FRAME_PIXEL_HEIGHT (f)
+ f->top_pos
- (top_bottom_borders_height - 1));
- top_bottom_borders_height);
}
/* The left_pos and top_pos are now relative to the top and left

Some files were not shown because too many files have changed in this diff Show more