Merge from origin/emacs-27
45a64c97c7
(origin/emacs-27) Clarify semantics of trace-function CONT...821760fdc4
Don't let a code literal get modified in mml parsing (Bug#...74a92be16d
* lisp/simple.el (kill-ring-save): Doc fix. (Bug#40797)3d0e859692
Minor doc clarification regarding fringe bitmaps4d86c7f822
Fix documentation of fringe bitmapsa76af88dd8
Tweak mutability doc a bit moref7e488d206
Calc: fix autoload errors (bug#40800)369761b36d
; * src/xdisp.c: Improve the introductory commentary.a92ca1f177
Improve indexing of ELisp manual5a25d17760
* lisp/image-mode.el (image-transform-resize): Remove FIXM...37ebec3a95
Improve the default value of 'doc-view-ghostscript-program'.ba6104d1e8
Change doc-view-mode-map prefix key 's' to 'c'.400ff5cd19
Improve wording about constantsd2836fe71b
Improve the default value of 'doc-view-ghostscript-program'.fc55f65305
Minor improvements in documentation of the last changea64da75961
Add image-auto-resize defcustoms to image-mode.el692ad40539
Improve the documentation of tab-bar and tab-line # Conflicts: # etc/NEWS
This commit is contained in:
commit
519567878f
22 changed files with 440 additions and 209 deletions
|
@ -735,6 +735,7 @@ in a way that does not interact well with @code{highlight}.
|
|||
@cindex @code{tab-line} face
|
||||
Similar to @code{mode-line} for a window's tab line, which appears
|
||||
at the top of a window with tabs representing window buffers.
|
||||
@xref{Tab Line}.
|
||||
@item vertical-border
|
||||
@cindex @code{vertical-border} face
|
||||
This face is used for the vertical divider between windows on text
|
||||
|
|
|
@ -517,6 +517,7 @@ Multiple Windows
|
|||
* Displaying Buffers:: How Emacs picks a window for displaying a buffer.
|
||||
* Temporary Displays:: Displaying non-editable buffers.
|
||||
* Window Convenience:: Convenience functions for window handling.
|
||||
* Tab Line:: Window tab line.
|
||||
|
||||
Displaying a Buffer in a Window
|
||||
|
||||
|
|
|
@ -2113,8 +2113,6 @@ point. Partial Completion mode offers other features extending
|
|||
|
||||
@findex image-mode
|
||||
@findex image-toggle-display
|
||||
@findex image-next-file
|
||||
@findex image-previous-file
|
||||
@cindex images, viewing
|
||||
Visiting image files automatically selects Image mode. In this
|
||||
major mode, you can type @kbd{C-c C-c} (@code{image-toggle-display})
|
||||
|
@ -2122,12 +2120,34 @@ to toggle between displaying the file as an image in the Emacs buffer,
|
|||
and displaying its underlying text (or raw byte) representation.
|
||||
Additionally you can type @kbd{C-c C-x} (@code{image-toggle-hex-display})
|
||||
to toggle between displaying the file as an image in the Emacs buffer,
|
||||
and displaying it in hex representation.
|
||||
Displaying the file as an image works only if Emacs is compiled with
|
||||
support for displaying such images. If the displayed image is wider
|
||||
or taller than the frame, the usual point motion keys (@kbd{C-f},
|
||||
@kbd{C-p}, and so forth) cause different parts of the image to be
|
||||
displayed. You can press @kbd{n} (@code{image-next-file}) and @kbd{p}
|
||||
and displaying it in hex representation. Displaying the file as an
|
||||
image works only if Emacs is compiled with support for displaying
|
||||
such images.
|
||||
|
||||
@vindex image-auto-resize
|
||||
@vindex image-auto-resize-on-window-resize
|
||||
If the displayed image is wider or taller than the window in which it
|
||||
is displayed, the usual point motion keys (@kbd{C-f}, @kbd{C-p}, and
|
||||
so forth) cause different parts of the image to be displayed.
|
||||
However, by default images are resized automatically to fit the
|
||||
window, so this is only necessary if you customize the default
|
||||
behavior by using the options @code{image-auto-resize} and
|
||||
@code{image-auto-resize-on-window-resize}.
|
||||
|
||||
@findex image-transform-fit-both
|
||||
@findex image-transform-set-scale
|
||||
@findex image-transform-reset
|
||||
To resize the image manually you can use the command
|
||||
@code{image-transform-fit-both} bound to @kbd{s b}
|
||||
that fits the image to both the window height and width.
|
||||
To scale the image specifying a scale factor, use the command
|
||||
@code{image-transform-set-scale} bound to @kbd{s s}.
|
||||
To reset all transformations to the initial state, use
|
||||
@code{image-transform-reset} bound to @kbd{s 0}.
|
||||
|
||||
@findex image-next-file
|
||||
@findex image-previous-file
|
||||
You can press @kbd{n} (@code{image-next-file}) and @kbd{p}
|
||||
(@code{image-previous-file}) to visit the next image file and the
|
||||
previous image file in the same directory, respectively.
|
||||
|
||||
|
@ -2195,7 +2215,6 @@ can be used to transform the image in question to @acronym{PNG} before
|
|||
displaying. GraphicsMagick, ImageMagick and @command{ffmpeg} are
|
||||
currently supported for image conversions.
|
||||
|
||||
|
||||
@findex thumbs-mode
|
||||
@cindex mode, Thumbs
|
||||
The Image-Dired package can also be used to view images as
|
||||
|
|
|
@ -1262,6 +1262,12 @@ sessions (@pxref{Saving Emacs Sessions}), the tabs from the Tab Bar are
|
|||
recorded in the desktop file, together with their associated window
|
||||
configurations, and will be available after restoring the session.
|
||||
|
||||
Note that the Tab Bar is different from the Tab Line (@pxref{Tab Line}).
|
||||
Whereas tabs on the Tab Line at the top of each window are used to
|
||||
switch between buffers, tabs on the Tab Bar at the top of each frame
|
||||
are used to switch between window configurations containing several
|
||||
windows.
|
||||
|
||||
@findex tab-bar-mode
|
||||
To toggle the use of tab bars, type @kbd{M-x tab-bar-mode}. This
|
||||
command applies to all frames, including frames yet to be created. To
|
||||
|
@ -1275,9 +1281,11 @@ is turned on automatically. If the value is @code{t}, then
|
|||
tabs. The value @code{1} hides the tab bar when it has only one tab,
|
||||
and shows it again when more tabs are created. The value @code{nil}
|
||||
always keeps the tab bar hidden; in this case it's still possible to
|
||||
use persistent named window configurations without using the tab bar
|
||||
by typing the related commands: @kbd{M-x tab-new}, @kbd{M-x tab-next},
|
||||
@kbd{M-x tab-close}, @kbd{M-x tab-switcher}, etc.
|
||||
switch between named window configurations without the tab bar by
|
||||
using @kbd{M-x tab-next}, @kbd{M-x tab-switcher}, and other commands
|
||||
that provide completion on tab names. Also it's possible to create
|
||||
and close tabs without the tab bar by using commands @kbd{M-x
|
||||
tab-new}, @kbd{M-x tab-close}, etc.
|
||||
|
||||
@kindex C-x t
|
||||
The prefix key @kbd{C-x t} is analogous to @kbd{C-x 5}.
|
||||
|
@ -1286,7 +1294,8 @@ Whereas each @kbd{C-x 5} command pops up a buffer in a different frame
|
|||
tab with a different window configuration in the selected frame.
|
||||
|
||||
The various @kbd{C-x t} commands differ in how they find or create the
|
||||
buffer to select:
|
||||
buffer to select. The following commands can be used to select a buffer
|
||||
in a new tab:
|
||||
|
||||
@table @kbd
|
||||
@item C-x t 2
|
||||
|
@ -1295,19 +1304,18 @@ buffer to select:
|
|||
Add a new tab (@code{tab-new}). You can control the choice of the
|
||||
buffer displayed in a new tab by customizing the variable
|
||||
@code{tab-bar-new-tab-choice}.
|
||||
|
||||
@item C-x t b @var{bufname} @key{RET}
|
||||
Select buffer @var{bufname} in another tab. This runs
|
||||
@code{switch-to-buffer-other-tab}.
|
||||
|
||||
@item C-x t f @var{filename} @key{RET}
|
||||
Visit file @var{filename} and select its buffer in another tab. This
|
||||
runs @code{find-file-other-tab}. @xref{Visiting}.
|
||||
|
||||
@item C-x t d @var{directory} @key{RET}
|
||||
Select a Dired buffer for directory @var{directory} in another tab.
|
||||
This runs @code{dired-other-tab}. @xref{Dired}.
|
||||
@item C-x t r @var{tabname} @key{RET}
|
||||
Renames the current tab to @var{tabname}. You can control the
|
||||
programmatic name given to a tab by default by customizing the
|
||||
variable @code{tab-bar-tab-name-function}.
|
||||
@end table
|
||||
|
||||
@vindex tab-bar-new-tab-choice
|
||||
|
@ -1316,7 +1324,7 @@ current before calling the command that adds a new tab.
|
|||
To start a new tab with other buffers, customize the variable
|
||||
@code{tab-bar-new-tab-choice}.
|
||||
|
||||
The following commands are used to delete and operate on tabs:
|
||||
The following commands can be used to delete tabs:
|
||||
|
||||
@table @kbd
|
||||
@item C-x t 0
|
||||
|
@ -1325,19 +1333,45 @@ To start a new tab with other buffers, customize the variable
|
|||
Close the selected tab (@code{tab-close}). It has no effect if there
|
||||
is only one tab.
|
||||
|
||||
@item C-x t o
|
||||
@kindex C-x t o
|
||||
@kindex C-TAB
|
||||
@findex tab-next
|
||||
Switch to another tab. If you repeat this command, it cycles through
|
||||
all the tabs on the selected frame. With a positive numeric argument
|
||||
N, it switches to the next Nth tab; with a negative argument −N, it
|
||||
switches back to the previous Nth tab.
|
||||
|
||||
@item C-x t 1
|
||||
@kindex C-x t 1
|
||||
@findex tab-close-other
|
||||
Close all tabs on the selected frame, except the selected one.
|
||||
@end table
|
||||
|
||||
The following commands can be used to switch between tabs:
|
||||
|
||||
@table @kbd
|
||||
@item C-x t o
|
||||
@itemx C-@key{TAB}
|
||||
@kindex C-x t o
|
||||
@kindex C-TAB
|
||||
@findex tab-next
|
||||
Switch to the next tab. If you repeat this command, it cycles through
|
||||
all the tabs on the selected frame. With a positive numeric argument
|
||||
N, it switches to the next Nth tab; with a negative argument −N, it
|
||||
switches back to the previous Nth tab.
|
||||
|
||||
@item S-C-@key{TAB}
|
||||
@kindex S-C-TAB
|
||||
@findex tab-previous
|
||||
Switch to the previous tab. With a positive numeric argument N, it
|
||||
switches to the previous Nth tab; with a negative argument −N, it
|
||||
switches back to the next Nth tab.
|
||||
@end table
|
||||
|
||||
The following commands can be used to operate on tabs:
|
||||
|
||||
@table @kbd
|
||||
@item C-x t r @var{tabname} @key{RET}
|
||||
Rename the current tab to @var{tabname}. You can control the
|
||||
programmatic name given to a tab by default by customizing the
|
||||
variable @code{tab-bar-tab-name-function}.
|
||||
|
||||
@item C-x t m
|
||||
Move the current tab N positions to the right with a positive numeric
|
||||
argument N. With a negative argument −N, it moves the current tab
|
||||
N positions to the left.
|
||||
@end table
|
||||
|
||||
@node Dialog Boxes
|
||||
|
|
|
@ -1367,7 +1367,7 @@ configurations. @xref{Tab Bars}.
|
|||
|
||||
@item Tab Line
|
||||
The tab line is a line of tabs at the top of an Emacs window.
|
||||
Clicking on one of these tabs switches window buffers.
|
||||
Clicking on one of these tabs switches window buffers. @xref{Tab Line}.
|
||||
|
||||
@anchor{Glossary---Tags Table}
|
||||
@item Tags Table
|
||||
|
|
|
@ -617,12 +617,12 @@ of pages to display. A slice is a rectangle within the page area;
|
|||
once you specify a slice in DocView, it applies to whichever page you
|
||||
look at.
|
||||
|
||||
To specify the slice numerically, type @kbd{s s}
|
||||
To specify the slice numerically, type @kbd{c s}
|
||||
(@code{doc-view-set-slice}); then enter the top left pixel position
|
||||
and the slice's width and height.
|
||||
@c ??? how does this work?
|
||||
|
||||
A more convenient graphical way to specify the slice is with @kbd{s
|
||||
A more convenient graphical way to specify the slice is with @kbd{c
|
||||
m} (@code{doc-view-set-slice-using-mouse}), where you use the mouse to
|
||||
select the slice. Simply press and hold the left mouse button at the
|
||||
upper-left corner of the region you want to have in the slice, then
|
||||
|
@ -631,10 +631,10 @@ button.
|
|||
|
||||
The most convenient way is to set the optimal slice by using
|
||||
BoundingBox information automatically determined from the document by
|
||||
typing @kbd{s b} (@code{doc-view-set-slice-from-bounding-box}).
|
||||
typing @kbd{c b} (@code{doc-view-set-slice-from-bounding-box}).
|
||||
|
||||
@findex doc-view-reset-slice
|
||||
To cancel the selected slice, type @kbd{s r}
|
||||
To cancel the selected slice, type @kbd{c r}
|
||||
(@code{doc-view-reset-slice}). Then DocView shows the entire page
|
||||
including its entire margins.
|
||||
|
||||
|
@ -791,7 +791,7 @@ the same number of columns as provided by the shell.
|
|||
@vindex shell-command-prompt-show-cwd
|
||||
To make the above commands show the current directory in their
|
||||
prompts, customize the variable @code{shell-command-prompt-show-cwd}
|
||||
to a non-nil value.
|
||||
to a non-@code{nil} value.
|
||||
|
||||
@kindex M-|
|
||||
@findex shell-command-on-region
|
||||
|
|
|
@ -299,7 +299,7 @@ Bars}.
|
|||
Tab Bar mode gives each frame a tab bar. @xref{Tab Bars}.
|
||||
|
||||
@item
|
||||
Tab Line mode gives each window a tab line.
|
||||
Tab Line mode gives each window a tab line. @xref{Tab Line}.
|
||||
|
||||
@item
|
||||
Transient Mark mode highlights the region, and makes many Emacs
|
||||
|
|
|
@ -21,6 +21,7 @@ one frame.
|
|||
* Change Window:: Deleting windows and changing their sizes.
|
||||
* Displaying Buffers:: How Emacs picks a window for displaying a buffer.
|
||||
* Window Convenience:: Convenience functions for window handling.
|
||||
* Tab Line:: Window tab line.
|
||||
@end menu
|
||||
|
||||
@node Basic Window
|
||||
|
@ -542,16 +543,6 @@ Reference Manual}), and cannot exceed the size of the containing frame.
|
|||
@node Window Convenience
|
||||
@section Convenience Features for Window Handling
|
||||
|
||||
@findex global-tab-line-mode
|
||||
@cindex tab line
|
||||
The command @code{global-tab-line-mode} toggles the display of a
|
||||
@dfn{tab line} on the top screen line of each window. The tab line
|
||||
shows special buttons (``tabs'') for each buffer that was displayed in
|
||||
a window, and allows switching to any of these buffers by clicking the
|
||||
corresponding button. You can add a tab by clicking on the @kbd{+}
|
||||
icon and delete a tab by clicking on the @kbd{x} icon of a tab. The
|
||||
mouse wheel on the tab line scrolls the tabs horizontally.
|
||||
|
||||
@findex winner-mode
|
||||
@vindex winner-dont-bind-my-keys
|
||||
@vindex winner-ring-size
|
||||
|
@ -616,3 +607,29 @@ shown in different windows. @xref{Comparing Files}.
|
|||
Scroll All mode (@kbd{M-x scroll-all-mode}) is a global minor mode
|
||||
that causes scrolling commands and point motion commands to apply to
|
||||
every single window.
|
||||
|
||||
|
||||
@node Tab Line
|
||||
@section Window Tab Line
|
||||
|
||||
@findex global-tab-line-mode
|
||||
@cindex tab line
|
||||
The command @code{global-tab-line-mode} toggles the display of
|
||||
a @dfn{tab line} on the top screen line of each window. The Tab Line
|
||||
shows special buttons (``tabs'') for each buffer that was displayed in
|
||||
a window, and allows switching to any of these buffers by clicking the
|
||||
corresponding button. Clicking on the @kbd{+} icon adds a new buffer
|
||||
to the window-local tab line of buffers, and clicking on the @kbd{x}
|
||||
icon of a tab deletes it. The mouse wheel on the tab line scrolls
|
||||
the tabs horizontally.
|
||||
|
||||
Selecting the previous window-local tab is the same as typing @kbd{C-x
|
||||
@key{LEFT}} (@code{previous-buffer}), selecting the next tab is the
|
||||
same as @kbd{C-x @key{RIGHT}} (@code{next-buffer}). Both commands
|
||||
support a numeric prefix argument as a repeat count.
|
||||
|
||||
Note that the Tab Line is different from the Tab Bar (@pxref{Tab Bars}).
|
||||
Whereas tabs on the Tab Bar at the top of each frame are used to
|
||||
switch between window configurations containing several windows,
|
||||
tabs on the Tab Line at the top of each window are used to switch
|
||||
between buffers.
|
||||
|
|
|
@ -4155,8 +4155,8 @@ topmost and bottommost buffer text line; and @code{top-bottom}
|
|||
indicates where there is just one line of text in the buffer.
|
||||
|
||||
@item @code{empty-line}
|
||||
Used to indicate empty lines when @code{indicate-empty-lines} is
|
||||
non-@code{nil}.
|
||||
Used to indicate empty lines after the buffer end when
|
||||
@code{indicate-empty-lines} is non-@code{nil}.
|
||||
|
||||
@item @code{overlay-arrow}
|
||||
Used for overlay arrows (@pxref{Overlay Arrow}).
|
||||
|
@ -4298,6 +4298,7 @@ The former is used by overlay arrows. The latter is unused.
|
|||
@itemx @code{bottom-left-angle}, @code{bottom-right-angle}
|
||||
@itemx @code{top-left-angle}, @code{top-right-angle}
|
||||
@itemx @code{left-bracket}, @code{right-bracket}
|
||||
@itemx @code{empty-line}
|
||||
Used to indicate buffer boundaries.
|
||||
|
||||
@item @code{filled-rectangle}, @code{hollow-rectangle}
|
||||
|
@ -4305,7 +4306,7 @@ Used to indicate buffer boundaries.
|
|||
@itemx @code{vertical-bar}, @code{horizontal-bar}
|
||||
Used for different types of fringe cursors.
|
||||
|
||||
@item @code{empty-line}, @code{exclamation-mark}, @code{question-mark}
|
||||
@item @code{exclamation-mark}, @code{question-mark}
|
||||
Not used by core Emacs features.
|
||||
@end table
|
||||
|
||||
|
@ -4338,7 +4339,8 @@ The argument @var{bits} specifies the image to use. It should be
|
|||
either a string or a vector of integers, where each element (an
|
||||
integer) corresponds to one row of the bitmap. Each bit of an integer
|
||||
corresponds to one pixel of the bitmap, where the low bit corresponds
|
||||
to the rightmost pixel of the bitmap.
|
||||
to the rightmost pixel of the bitmap. (Note that this order of bits
|
||||
is opposite of the order in XBM images; @pxref{XBM Images}.)
|
||||
|
||||
The height is normally the length of @var{bits}. However, you
|
||||
can specify a different height with non-@code{nil} @var{height}. The width
|
||||
|
|
|
@ -606,6 +606,12 @@ Here are some examples of expressions that use @code{quote}:
|
|||
@end group
|
||||
@end example
|
||||
|
||||
Although the expressions @code{(list '+ 1 2)} and @code{'(+ 1 2)}
|
||||
both yield lists equal to @code{(+ 1 2)}, the former yields a
|
||||
freshly-minted mutable list whereas the latter yields a constant list
|
||||
built from conses that may be shared with other constants.
|
||||
@xref{Constants and Mutability}.
|
||||
|
||||
Other quoting constructs include @code{function} (@pxref{Anonymous
|
||||
Functions}), which causes an anonymous lambda expression written in Lisp
|
||||
to be compiled, and @samp{`} (@pxref{Backquote}), which is used to quote
|
||||
|
|
|
@ -1625,10 +1625,9 @@ keys may not be symbols:
|
|||
'(("simple leaves" . oak)
|
||||
("compound leaves" . horsechestnut)))
|
||||
|
||||
;; @r{The @code{copy-sequence} means the keys are not @code{eq}.}
|
||||
(assq (copy-sequence "simple leaves") leaves)
|
||||
@result{} nil
|
||||
(assoc (copy-sequence "simple leaves") leaves)
|
||||
(assq "simple leaves" leaves)
|
||||
@result{} @r{Unspecified; might be @code{nil} or non-@code{nil}.}
|
||||
(assoc "simple leaves" leaves)
|
||||
@result{} ("simple leaves" . oak)
|
||||
@end smallexample
|
||||
@end defun
|
||||
|
|
|
@ -46,7 +46,7 @@ you store in it, type and all. (Actually, a small number of Emacs
|
|||
Lisp variables can only take on values of a certain type.
|
||||
@xref{Variables with Restricted Values}.)
|
||||
|
||||
Some Lisp objects are @dfn{constant}: their values never change.
|
||||
Some Lisp objects are @dfn{constant}: their values should never change.
|
||||
Others are @dfn{mutable}: their values can be changed via destructive
|
||||
operations that involve side effects.
|
||||
|
||||
|
@ -2388,22 +2388,28 @@ that for two strings to be equal, they have the same text properties.
|
|||
@cindex constants
|
||||
@cindex mutable objects
|
||||
|
||||
Some Lisp objects are constant: their values never change.
|
||||
Some Lisp objects are constant: their values should never change
|
||||
during a single execution of Emacs running well-behaved Lisp code.
|
||||
For example, you can create a new integer by calculating one, but you
|
||||
cannot modify the value of an existing integer.
|
||||
|
||||
Other Lisp objects are mutable: their values can be changed
|
||||
Other Lisp objects are mutable: it is safe to change their values
|
||||
via destructive operations involving side effects. For example, an
|
||||
existing marker can be changed by moving the marker to point to
|
||||
somewhere else.
|
||||
|
||||
Although numbers are always constants and markers are always
|
||||
Although all numbers are constants and all markers are
|
||||
mutable, some types contain both constant and mutable members. These
|
||||
types include conses, vectors, strings, and symbols. For example, the string
|
||||
literal @code{"aaa"} yields a constant string, whereas the function
|
||||
call @code{(make-string 3 ?a)} yields a mutable string that can be
|
||||
changed via later calls to @code{aset}.
|
||||
|
||||
A mutable object can become constant if it is part of an expression
|
||||
that is evaluated, because a program should not modify an object
|
||||
that is being evaluated. The reverse does not occur: constant objects
|
||||
should stay constant.
|
||||
|
||||
Trying to modify a constant variable signals an error
|
||||
(@pxref{Constant Variables}).
|
||||
A program should not attempt to modify other types of constants because the
|
||||
|
@ -2411,9 +2417,10 @@ resulting behavior is undefined: the Lisp interpreter might or might
|
|||
not detect the error, and if it does not detect the error the
|
||||
interpreter can behave unpredictably thereafter. Another way to put
|
||||
this is that although mutable objects are safe to change and constant
|
||||
symbols reliably reject attempts to change them, other constants are
|
||||
not safely mutable: if you try to change one your program might
|
||||
behave as you expect but it might crash or worse. This problem occurs
|
||||
variables reliably prevent attempts to change them, other constants
|
||||
are not safely mutable: if a misbehaving program tries to change such a
|
||||
constant then the constant's value might actually change, or the
|
||||
program might crash or worse. This problem occurs
|
||||
with types that have both constant and mutable members, and that have
|
||||
mutators like @code{setcar} and @code{aset} that are valid on mutable
|
||||
objects but hazardous on constants.
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
@cindex tips for writing Lisp
|
||||
@cindex standards of coding style
|
||||
@cindex coding standards
|
||||
@cindex best practices
|
||||
|
||||
This chapter describes no additional features of Emacs Lisp. Instead
|
||||
it gives advice on making effective use of the features described in the
|
||||
|
|
64
etc/NEWS.27
64
etc/NEWS.27
|
@ -866,6 +866,11 @@ its functions.
|
|||
*** A new user option 'doc-view-pdftotext-program-args' has been added
|
||||
to allow controlling how the conversion to text is done.
|
||||
|
||||
+++
|
||||
*** The prefix key 's' was changed to 'c' for slicing commands
|
||||
to avoid conflicts with image-mode key 's'. The new key 'c' still
|
||||
has good mnemonics of "cut", "clip", "crop".
|
||||
|
||||
** Ido
|
||||
|
||||
---
|
||||
|
@ -2720,8 +2725,8 @@ left to higher-level functions.
|
|||
+++
|
||||
*** Tab Bar mode
|
||||
The new command 'tab-bar-mode' enables the tab bar at the top of each
|
||||
frame, where you can use tabs to switch between named persistent
|
||||
window configurations.
|
||||
frame (including TTY frames), where you can use tabs to switch between
|
||||
named persistent window configurations.
|
||||
|
||||
The 'C-x t' sequence is the new prefix key for tab-related commands:
|
||||
'C-x t 2' creates a new tab; 'C-x t 0' deletes the current tab;
|
||||
|
@ -2738,6 +2743,11 @@ when its value is "on", "yes" or "1".
|
|||
|
||||
The user option 'tab-bar-position' specifies where to show the tab bar.
|
||||
|
||||
Tab-related commands can be used even without the tab bar when
|
||||
'tab-bar-mode' is disabled by a nil value of the user option
|
||||
'tab-bar-show'. Without the tab bar you can switch between tabs
|
||||
using completion on tab names, or using 'tab-switcher'.
|
||||
|
||||
Read the new Info node "(emacs) Tab Bars" for full description
|
||||
of all related features.
|
||||
|
||||
|
@ -2752,6 +2762,9 @@ a repeat count. Clicking on the plus icon adds a new buffer to the
|
|||
window-local tab line of buffers. Using the mouse wheel on the tab
|
||||
line scrolls tabs.
|
||||
|
||||
Read the new Info node "(emacs) Tab Line" for full description
|
||||
of all related features.
|
||||
|
||||
+++
|
||||
** fileloop.el lets one setup multifile operations like search&replace.
|
||||
|
||||
|
@ -3515,9 +3528,32 @@ functions.
|
|||
*** 'image-mode' now uses this library to automatically rotate images
|
||||
according to the orientation in the Exif data, if any.
|
||||
|
||||
+++
|
||||
*** The command 'image-rotate' now accepts a prefix argument.
|
||||
With a prefix argument, 'image-rotate' now rotates the image at point
|
||||
90 degrees counter-clockwise, instead of the default clockwise.
|
||||
|
||||
+++
|
||||
*** In 'image-mode' the image is resized automatically to fit in window.
|
||||
The image will resize upon first display and whenever the window's
|
||||
dimensions change.
|
||||
By default, the image will resize upon first display and whenever the
|
||||
window's dimensions change. Two user options 'image-auto-resize' and
|
||||
'image-auto-resize-on-window-resize' control the resizing behavior
|
||||
(including the possibility to disable auto-resizing). A new key
|
||||
prefix 's' contains the commands that can be used to fit the image to
|
||||
the window manually.
|
||||
|
||||
---
|
||||
*** Some 'image-mode' variables are now buffer-local.
|
||||
The image parameters 'image-transform-rotation',
|
||||
'image-transform-scale' and 'image-transform-resize' are now declared
|
||||
buffer-local, so each buffer could have its own values for these
|
||||
parameters.
|
||||
|
||||
+++
|
||||
*** Three new 'image-mode' commands have been added: 'm', which marks
|
||||
the file in the dired buffer(s) for the directory the file is in; 'u',
|
||||
which unmarks the file; and 'w', which pushes the current buffer's file
|
||||
name to the kill ring.
|
||||
|
||||
---
|
||||
*** New library image-converter.
|
||||
|
@ -3538,26 +3574,6 @@ These now default to using 'image-mode'.
|
|||
some years back. It now respects 'imagemagick-types-inhibit' as a way
|
||||
to disable that.
|
||||
|
||||
---
|
||||
*** Some 'image-mode' variables are now buffer-local.
|
||||
The image parameters 'image-transform-rotation',
|
||||
'image-transform-scale' and 'image-transform-resize' are now declared
|
||||
buffer-local, so each buffer could have its own values for these
|
||||
parameters.
|
||||
|
||||
+++
|
||||
*** Three new 'image-mode' commands have been added: 'm', which marks
|
||||
the file in the dired buffer(s) for the directory the file is in; 'u',
|
||||
which unmarks the file; and 'w', which pushes the current buffer's file
|
||||
name to the kill ring.
|
||||
|
||||
+++
|
||||
*** The command 'image-rotate' now accepts a prefix argument.
|
||||
With a prefix argument, 'image-rotate' now rotates the image at point
|
||||
90 degrees counter-clockwise, instead of the default clockwise.
|
||||
|
||||
*** 'image-mode' has a new key prefix 's' for transformation commands.
|
||||
|
||||
** Modules
|
||||
|
||||
---
|
||||
|
|
|
@ -674,7 +674,6 @@
|
|||
(define-key calc-mode-map "Z/" 'calc-kbd-break)
|
||||
(define-key calc-mode-map "Z`" 'calc-kbd-push)
|
||||
(define-key calc-mode-map "Z'" 'calc-kbd-pop)
|
||||
(define-key calc-mode-map "Z=" 'calc-kbd-report)
|
||||
(define-key calc-mode-map "Z#" 'calc-kbd-query)
|
||||
|
||||
(calc-init-prefixes)
|
||||
|
@ -845,8 +844,8 @@ math-bernoulli-number math-gammap1-raw)
|
|||
("calc-incom" calc-digit-dots)
|
||||
|
||||
("calc-keypd" calc-do-keypad
|
||||
calc-keypad-x-left-click calc-keypad-x-middle-click
|
||||
calc-keypad-x-right-click)
|
||||
calc-keypad-left-click calc-keypad-middle-click
|
||||
calc-keypad-right-click)
|
||||
|
||||
("calc-lang" calc-set-language
|
||||
math-read-big-balance math-read-big-rec)
|
||||
|
@ -1003,7 +1002,7 @@ calc-find-root calc-poly-interp)
|
|||
calc-floor calc-idiv calc-increment calc-mant-part calc-max calc-min
|
||||
calc-round calc-scale-float calc-sign calc-trunc calc-xpon-part)
|
||||
|
||||
("calc-bin" calc-and calc-binary-radix calc-clip calc-twos-complement-mode
|
||||
("calc-bin" calc-and calc-binary-radix calc-clip
|
||||
calc-decimal-radix calc-diff calc-hex-radix calc-leading-zeros
|
||||
calc-lshift-arith calc-lshift-binary calc-not calc-octal-radix calc-or calc-radix
|
||||
calc-rotate-binary calc-rshift-arith calc-rshift-binary calc-word-size
|
||||
|
@ -1116,7 +1115,7 @@ calc-equal-to calc-get-user-defn calc-greater-equal calc-greater-than
|
|||
calc-in-set calc-kbd-break calc-kbd-else calc-kbd-else-if
|
||||
calc-kbd-end-for calc-kbd-end-if calc-kbd-end-loop calc-kbd-end-repeat
|
||||
calc-kbd-for calc-kbd-if calc-kbd-loop calc-kbd-pop calc-kbd-push
|
||||
calc-kbd-query calc-kbd-repeat calc-kbd-report calc-less-equal
|
||||
calc-kbd-query calc-kbd-repeat calc-less-equal
|
||||
calc-less-than calc-logical-and calc-logical-if calc-logical-not
|
||||
calc-logical-or calc-not-equal-to calc-pass-errors calc-remove-equal
|
||||
calc-timing calc-user-define calc-user-define-composition
|
||||
|
|
|
@ -1452,11 +1452,6 @@ Redefine the corresponding command."
|
|||
(error "%s" "Unbalanced Z' in keyboard macro")))
|
||||
|
||||
|
||||
;; (defun calc-kbd-report (msg)
|
||||
;; (interactive "sMessage: ")
|
||||
;; (calc-wrapper
|
||||
;; (math-working msg (calc-top-n 1))))
|
||||
|
||||
(defun calc-kbd-query ()
|
||||
(interactive)
|
||||
(let ((defining-kbd-macro nil)
|
||||
|
|
|
@ -59,16 +59,16 @@
|
|||
;; will be remembered and applied to all pages of the current
|
||||
;; document. This enables you to cut away the margins of a document
|
||||
;; to save some space. To select a slice you can use
|
||||
;; `doc-view-set-slice' (bound to `s s') which will query you for the
|
||||
;; `doc-view-set-slice' (bound to `c s') which will query you for the
|
||||
;; coordinates of the slice's top-left corner and its width and
|
||||
;; height. A much more convenient way to do the same is offered by
|
||||
;; the command `doc-view-set-slice-using-mouse' (bound to `s m').
|
||||
;; the command `doc-view-set-slice-using-mouse' (bound to `c m').
|
||||
;; After invocation you only have to press mouse-1 at the top-left
|
||||
;; corner and drag it to the bottom-right corner of the desired slice.
|
||||
;; Even more accurate and convenient is to use
|
||||
;; `doc-view-set-slice-from-bounding-box' (bound to `s b') which uses
|
||||
;; `doc-view-set-slice-from-bounding-box' (bound to `c b') which uses
|
||||
;; the BoundingBox information of the current page to set an optimal
|
||||
;; slice. To reset the slice use `doc-view-reset-slice' (bound to `s
|
||||
;; slice. To reset the slice use `doc-view-reset-slice' (bound to `c
|
||||
;; r').
|
||||
;;
|
||||
;; You can also search within the document. The command `doc-view-search'
|
||||
|
@ -155,9 +155,19 @@
|
|||
(defcustom doc-view-ghostscript-program
|
||||
(cond
|
||||
((memq system-type '(windows-nt ms-dos))
|
||||
"gswin32c")
|
||||
(t
|
||||
"gs"))
|
||||
(cond
|
||||
;; Windows Ghostscript
|
||||
((executable-find "gswin64c") "gswin64c")
|
||||
((executable-find "gswin32c") "gswin32c")
|
||||
;; The GS wrapper coming with TeX Live
|
||||
((executable-find "rungs") "rungs")
|
||||
;; The MikTeX builtin GS Check if mgs is functional for external
|
||||
;; non-MikTeX apps. Was available under:
|
||||
;; http://blog.miktex.org/post/2005/04/07/Starting-mgsexe-at-the-DOS-Prompt.aspx
|
||||
((and (executable-find "mgs")
|
||||
(= 0 (shell-command "mgs -q -dNODISPLAY -c quit")))
|
||||
"mgs")))
|
||||
(t "gs"))
|
||||
"Program to convert PS and PDF files to PNG."
|
||||
:type 'file
|
||||
:version "27.1")
|
||||
|
@ -421,10 +431,10 @@ Typically \"page-%s.png\".")
|
|||
;; Killing the buffer (and the process)
|
||||
(define-key map (kbd "K") 'doc-view-kill-proc)
|
||||
;; Slicing the image
|
||||
(define-key map (kbd "s s") 'doc-view-set-slice)
|
||||
(define-key map (kbd "s m") 'doc-view-set-slice-using-mouse)
|
||||
(define-key map (kbd "s b") 'doc-view-set-slice-from-bounding-box)
|
||||
(define-key map (kbd "s r") 'doc-view-reset-slice)
|
||||
(define-key map (kbd "c s") 'doc-view-set-slice)
|
||||
(define-key map (kbd "c m") 'doc-view-set-slice-using-mouse)
|
||||
(define-key map (kbd "c b") 'doc-view-set-slice-from-bounding-box)
|
||||
(define-key map (kbd "c r") 'doc-view-reset-slice)
|
||||
;; Searching
|
||||
(define-key map (kbd "C-s") 'doc-view-search)
|
||||
(define-key map (kbd "<find>") 'doc-view-search)
|
||||
|
|
|
@ -292,7 +292,9 @@ If `current-prefix-arg' is non-nil, also read a buffer and a \"context\"
|
|||
(defun trace-function-foreground (function &optional buffer context)
|
||||
"Trace calls to function FUNCTION.
|
||||
With a prefix argument, also prompt for the trace buffer (default
|
||||
`trace-buffer'), and a Lisp expression CONTEXT.
|
||||
`trace-buffer'), and a Lisp expression CONTEXT. When called from
|
||||
Lisp, CONTEXT should be a function of no arguments which returns
|
||||
a value to insert into BUFFER during the trace.
|
||||
|
||||
Tracing a function causes every call to that function to insert
|
||||
into BUFFER Lisp-style trace messages that display the function's
|
||||
|
|
|
@ -281,7 +281,7 @@ part. This is for the internal use, you should never modify the value.")
|
|||
(setq tag (mml-read-tag)
|
||||
no-markup-p nil
|
||||
warn nil)
|
||||
(setq tag (list 'part '(type . "text/plain"))
|
||||
(setq tag (list 'part (cons 'type "text/plain"))
|
||||
no-markup-p t
|
||||
warn t))
|
||||
(setq raw (cdr (assq 'raw tag))
|
||||
|
|
|
@ -53,11 +53,37 @@ See `image-mode-winprops'.")
|
|||
"Special hook run when image data is requested in a new window.
|
||||
It is called with one argument, the initial WINPROPS.")
|
||||
|
||||
;; FIXME this doesn't seem mature yet. Document in manual when it is.
|
||||
(defcustom image-auto-resize t
|
||||
"Non-nil to resize the image upon first display.
|
||||
Its value should be one of the following:
|
||||
- nil, meaning no resizing.
|
||||
- t, meaning to fit the image to the window height and width.
|
||||
- `fit-height', meaning to fit the image to the window height.
|
||||
- `fit-width', meaning to fit the image to the window width.
|
||||
- A number, which is a scale factor (the default size is 1)."
|
||||
:type '(choice (const :tag "No resizing" nil)
|
||||
(other :tag "Fit height and width" t)
|
||||
(const :tag "Fit height" fit-height)
|
||||
(const :tag "Fit width" fit-width)
|
||||
(number :tag "Scale factor" 1))
|
||||
:version "27.1"
|
||||
:group 'image)
|
||||
|
||||
(defcustom image-auto-resize-on-window-resize 1
|
||||
"Non-nil to resize the image whenever the window's dimensions change.
|
||||
This will always keep the image fit to the window.
|
||||
When non-nil, the value should be a number of seconds to wait before
|
||||
resizing according to the value specified in `image-auto-resize'."
|
||||
:type '(choice (const :tag "No auto-resize on window size change" nil)
|
||||
(integer :tag "Wait for number of seconds before resize" 1))
|
||||
:version "27.1"
|
||||
:group 'image)
|
||||
|
||||
(defvar-local image-transform-resize nil
|
||||
"The image resize operation.
|
||||
Its value should be one of the following:
|
||||
- nil, meaning no resizing.
|
||||
- t, meaning to fit the image to the window height and width.
|
||||
- `fit-height', meaning to fit the image to the window height.
|
||||
- `fit-width', meaning to fit the image to the window width.
|
||||
- A number, which is a scale factor (the default size is 1).")
|
||||
|
@ -427,9 +453,10 @@ call."
|
|||
(define-key map "sf" 'image-mode-fit-frame)
|
||||
(define-key map "sh" 'image-transform-fit-to-height)
|
||||
(define-key map "sw" 'image-transform-fit-to-width)
|
||||
(define-key map "sb" 'image-transform-fit-both)
|
||||
(define-key map "ss" 'image-transform-set-scale)
|
||||
(define-key map "sr" 'image-transform-set-rotation)
|
||||
(define-key map "s0" 'image-transform-reset)
|
||||
(define-key map "ss" 'image-transform-set-scale)
|
||||
|
||||
;; Multi-frame keys
|
||||
(define-key map (kbd "RET") 'image-toggle-animation)
|
||||
|
@ -482,6 +509,10 @@ call."
|
|||
:help "Resize image to match the window height"]
|
||||
["Fit to Window Width" image-transform-fit-to-width
|
||||
:help "Resize image to match the window width"]
|
||||
["Fit to Window Height and Width" image-transform-fit-both
|
||||
:help "Resize image to match the window height and width"]
|
||||
["Set Scale..." image-transform-set-scale
|
||||
:help "Resize image by specified scale factor"]
|
||||
["Rotate Image..." image-transform-set-rotation
|
||||
:help "Rotate the image"]
|
||||
["Reset Transformations" image-transform-reset
|
||||
|
@ -569,6 +600,7 @@ Key bindings:
|
|||
|
||||
(major-mode-suspend)
|
||||
(setq major-mode 'image-mode)
|
||||
(setq image-transform-resize image-auto-resize)
|
||||
|
||||
(if (not (image-get-display-property))
|
||||
(progn
|
||||
|
@ -611,7 +643,8 @@ Key bindings:
|
|||
|
||||
(add-hook 'change-major-mode-hook #'image-toggle-display-text nil t)
|
||||
(add-hook 'after-revert-hook #'image-after-revert-hook nil t)
|
||||
(add-hook 'window-state-change-functions #'image--window-state-change nil t)
|
||||
(when image-auto-resize-on-window-resize
|
||||
(add-hook 'window-state-change-functions #'image--window-state-change nil t))
|
||||
|
||||
(run-mode-hooks 'image-mode-hook)
|
||||
(let ((image (image-get-display-property))
|
||||
|
@ -768,7 +801,7 @@ was inserted."
|
|||
filename))
|
||||
;; If we have a `fit-width' or a `fit-height', don't limit
|
||||
;; the size of the image to the window size.
|
||||
(edges (and (null image-transform-resize)
|
||||
(edges (and (eq image-transform-resize t)
|
||||
(window-inside-pixel-edges (get-buffer-window))))
|
||||
(type (if (image--imagemagick-wanted-p filename)
|
||||
'imagemagick
|
||||
|
@ -878,7 +911,9 @@ Otherwise, display the image by calling `image-mode'."
|
|||
;; image resizing happens later during redisplay. So if those
|
||||
;; consecutive calls happen without any redisplay between them,
|
||||
;; the costly operation of image resizing should happen only once.
|
||||
(run-with-idle-timer 1 nil #'image-fit-to-window window))
|
||||
(when (numberp image-auto-resize-on-window-resize)
|
||||
(run-with-idle-timer image-auto-resize-on-window-resize nil
|
||||
#'image-fit-to-window window)))
|
||||
|
||||
(defun image-fit-to-window (window)
|
||||
"Adjust size of image to display it exactly in WINDOW boundaries."
|
||||
|
@ -1282,7 +1317,7 @@ These properties are determined by the Image mode variables
|
|||
`image-transform-resize' and `image-transform-rotation'. The
|
||||
return value is suitable for appending to an image spec."
|
||||
(setq image-transform-scale 1.0)
|
||||
(when (or image-transform-resize
|
||||
(when (or (not (memq image-transform-resize '(nil t)))
|
||||
(/= image-transform-rotation 0.0))
|
||||
;; Note: `image-size' looks up and thus caches the untransformed
|
||||
;; image. There's no easy way to prevent that.
|
||||
|
@ -1328,6 +1363,12 @@ return value is suitable for appending to an image spec."
|
|||
(setq image-transform-resize 'fit-width)
|
||||
(image-toggle-display-image))
|
||||
|
||||
(defun image-transform-fit-both ()
|
||||
"Fit the current image both to the height and width of the current window."
|
||||
(interactive)
|
||||
(setq image-transform-resize t)
|
||||
(image-toggle-display-image))
|
||||
|
||||
(defun image-transform-set-rotation (rotation)
|
||||
"Prompt for an angle ROTATION, and rotate the image by that amount.
|
||||
ROTATION should be in degrees."
|
||||
|
@ -1338,7 +1379,7 @@ ROTATION should be in degrees."
|
|||
(defun image-transform-reset ()
|
||||
"Display the current image with the default size and rotation."
|
||||
(interactive)
|
||||
(setq image-transform-resize nil
|
||||
(setq image-transform-resize image-auto-resize
|
||||
image-transform-rotation 0.0
|
||||
image-transform-scale 1)
|
||||
(image-toggle-display-image))
|
||||
|
|
|
@ -4846,7 +4846,7 @@ In Transient Mark mode, deactivate the mark.
|
|||
If `interprogram-cut-function' is non-nil, also save the text for a window
|
||||
system cut and paste.
|
||||
|
||||
If you want to append the killed line to the last killed text,
|
||||
If you want to append the killed region to the last killed text,
|
||||
use \\[append-next-kill] before \\[kill-ring-save].
|
||||
|
||||
The copied text is filtered by `filter-buffer-substring' before it is
|
||||
|
|
271
src/xdisp.c
271
src/xdisp.c
|
@ -30,8 +30,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
Updating the display is triggered by the Lisp interpreter when it
|
||||
decides it's time to do it. This is done either automatically for
|
||||
you as part of the interpreter's command loop or as the result of
|
||||
calling Lisp functions like `sit-for'. The C function `redisplay'
|
||||
in xdisp.c is the only entry into the inner redisplay code.
|
||||
calling Lisp functions like `sit-for'. The C function
|
||||
`redisplay_internal' in xdisp.c is the only entry into the inner
|
||||
redisplay code.
|
||||
|
||||
The following diagram shows how redisplay code is invoked. As you
|
||||
can see, Lisp calls redisplay and vice versa.
|
||||
|
@ -89,7 +90,15 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
second glyph matrix is constructed, the so called `desired glyph
|
||||
matrix' or short `desired matrix'. Current and desired matrix are
|
||||
then compared to find a cheap way to update the display, e.g. by
|
||||
reusing part of the display by scrolling lines.
|
||||
reusing part of the display by scrolling lines. The actual update
|
||||
of the display of each window by comparing the desired and the
|
||||
current matrix is done by `update_window', which calls functions
|
||||
which draw to the glass (those functions are specific to the type
|
||||
of the window's frame: X, w32, NS, etc.).
|
||||
|
||||
Once the display of a window on the glass has been updated, its
|
||||
desired matrix is used to update the corresponding rows of the
|
||||
current matrix, and then the desired matrix is discarded.
|
||||
|
||||
You will find a lot of redisplay optimizations when you start
|
||||
looking at the innards of redisplay. The overall goal of all these
|
||||
|
@ -119,13 +128,13 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
||||
. try_window
|
||||
|
||||
This function performs the full redisplay of a single window
|
||||
assuming that its fonts were not changed and that the cursor
|
||||
will not end up in the scroll margins. (Loading fonts requires
|
||||
re-adjustment of dimensions of glyph matrices, which makes this
|
||||
method impossible to use.)
|
||||
This function performs the full, unoptimized, redisplay of a
|
||||
single window assuming that its fonts were not changed and that
|
||||
the cursor will not end up in the scroll margins. (Loading
|
||||
fonts requires re-adjustment of dimensions of glyph matrices,
|
||||
which makes this method impossible to use.)
|
||||
|
||||
These optimizations are tried in sequence (some can be skipped if
|
||||
The optimizations are tried in sequence (some can be skipped if
|
||||
it is known that they are not applicable). If none of the
|
||||
optimizations were successful, redisplay calls redisplay_windows,
|
||||
which performs a full redisplay of all windows.
|
||||
|
@ -145,38 +154,62 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
||||
Desired matrices.
|
||||
|
||||
Desired matrices are always built per Emacs window. The function
|
||||
`display_line' is the central function to look at if you are
|
||||
interested. It constructs one row in a desired matrix given an
|
||||
Desired matrices are always built per Emacs window. It is
|
||||
important to know that a desired matrix is in general "sparse": it
|
||||
only has some of the glyph rows "enabled". This is because
|
||||
redisplay tries to optimize its work, and thus only generates
|
||||
glyphs for rows that need to be updated on the screen. Rows that
|
||||
don't need to be updated are left "disabled", and their contents
|
||||
should be ignored.
|
||||
|
||||
The function `display_line' is the central function to look at if
|
||||
you are interested in how the rows of the desired matrix are
|
||||
produced. It constructs one row in a desired matrix given an
|
||||
iterator structure containing both a buffer position and a
|
||||
description of the environment in which the text is to be
|
||||
displayed. But this is too early, read on.
|
||||
|
||||
Glyph rows.
|
||||
|
||||
A glyph row is an array of `struct glyph', where each glyph element
|
||||
describes a "display element" to be shown on the screen. More
|
||||
accurately, a glyph row can have up to 3 different arrays of
|
||||
glyphs: one each for every display margins, and one for the "text
|
||||
area", where buffer text is displayed. The text-area glyph array
|
||||
is always present, whereas the arrays for the marginal areas are
|
||||
present (non-empty) only if the corresponding display margin is
|
||||
shown in the window. If the glyph array for a marginal area is not
|
||||
present its beginning and end coincide, i.e. such arrays are
|
||||
actually empty (they contain no glyphs). Frame glyph matrics, used
|
||||
on text-mode terminals (see below) never have marginal areas, they
|
||||
treat the entire frame-wide row of glyphs as a single large "text
|
||||
area".
|
||||
|
||||
Iteration over buffer and strings.
|
||||
|
||||
Characters and pixmaps displayed for a range of buffer text depend
|
||||
on various settings of buffers and windows, on overlays and text
|
||||
properties, on display tables, on selective display. The good news
|
||||
is that all this hairy stuff is hidden behind a small set of
|
||||
interface functions taking an iterator structure (struct it)
|
||||
interface functions taking an iterator structure (`struct it')
|
||||
argument.
|
||||
|
||||
Iteration over things to be displayed is then simple. It is
|
||||
started by initializing an iterator with a call to init_iterator,
|
||||
started by initializing an iterator with a call to `init_iterator',
|
||||
passing it the buffer position where to start iteration. For
|
||||
iteration over strings, pass -1 as the position to init_iterator,
|
||||
and call reseat_to_string when the string is ready, to initialize
|
||||
iteration over strings, pass -1 as the position to `init_iterator',
|
||||
and call `reseat_to_string' when the string is ready, to initialize
|
||||
the iterator for that string. Thereafter, calls to
|
||||
get_next_display_element fill the iterator structure with relevant
|
||||
information about the next thing to display. Calls to
|
||||
set_iterator_to_next move the iterator to the next thing.
|
||||
`get_next_display_element' fill the iterator structure with
|
||||
relevant information about the next thing to display. Calls to
|
||||
`set_iterator_to_next' move the iterator to the next thing.
|
||||
|
||||
Besides this, an iterator also contains information about the
|
||||
display environment in which glyphs for display elements are to be
|
||||
produced. It has fields for the width and height of the display,
|
||||
the information whether long lines are truncated or continued, a
|
||||
current X and Y position, and lots of other stuff you can better
|
||||
see in dispextern.h.
|
||||
current X and Y position, the face currently in effect, and lots of
|
||||
other stuff you can better see in dispextern.h.
|
||||
|
||||
The "stop position".
|
||||
|
||||
|
@ -184,57 +217,62 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
infrequently. These include the face of the characters, whether
|
||||
text is invisible, the object (buffer or display or overlay string)
|
||||
being iterated, character composition info, etc. For any given
|
||||
buffer or string position, the sources of information that
|
||||
affects the display can be determined by calling the appropriate
|
||||
primitives, such as Fnext_single_property_change, but both these
|
||||
buffer or string position, the sources of information that affects
|
||||
the display can be determined by calling the appropriate
|
||||
primitives, such as `Fnext_single_property_change', but both these
|
||||
calls and the processing of their return values is relatively
|
||||
expensive. To optimize redisplay, the display engine checks these
|
||||
sources of display information only when needed. To that end, it
|
||||
always maintains the position of the next place where it must stop
|
||||
and re-examine all those potential sources. This is called "stop
|
||||
position" and is stored in the stop_charpos field of the iterator.
|
||||
The stop position is updated by compute_stop_pos, which is called
|
||||
whenever the iteration reaches the current stop position and
|
||||
processes it. Processing a stop position is done by handle_stop,
|
||||
which invokes a series of handlers, one each for every potential
|
||||
source of display-related information; see the it_props array for
|
||||
those handlers. For example, one handler is handle_face_prop,
|
||||
which detects changes in face properties, and supplies the face ID
|
||||
that the iterator will use for all the glyphs it generates up to
|
||||
the next stop position; this face ID is the result of realizing the
|
||||
face specified by the relevant text properties at this position.
|
||||
Each handler called by handle_stop processes the sources of display
|
||||
sources of display information only when needed, not for every
|
||||
character. To that end, it always maintains the position of the
|
||||
next place where it must stop and re-examine all those potential
|
||||
sources. This is called "the stop position" and is stored in the
|
||||
`stop_charpos' field of the iterator. The stop position is updated
|
||||
by `compute_stop_pos', which is called whenever the iteration
|
||||
reaches the current stop position and processes it. Processing a
|
||||
stop position is done by `handle_stop', which invokes a series of
|
||||
handlers, one each for every potential source of display-related
|
||||
information; see the `it_props' array for those handlers. For
|
||||
example, one handler is `handle_face_prop', which detects changes
|
||||
in face properties, and supplies the face ID that the iterator will
|
||||
use for all the glyphs it generates up to the next stop position;
|
||||
this face ID is the result of "realizing" the face specified by the
|
||||
relevant text properties at this position (see xfaces.c). Each
|
||||
handler called by `handle_stop' processes the sources of display
|
||||
information for which it is "responsible", and returns a value
|
||||
which tells handle_stop what to do next.
|
||||
which tells `handle_stop' what to do next.
|
||||
|
||||
Once handle_stop returns, the information it stores in the iterator
|
||||
fields will not be refreshed until the iteration reaches the next
|
||||
stop position, which is computed by compute_stop_pos called at the
|
||||
end of handle_stop. compute_stop_pos examines the buffer's or
|
||||
string's interval tree to determine where the text properties
|
||||
change, finds the next position where overlays and character
|
||||
composition can change, and stores in stop_charpos the closest
|
||||
position where any of these factors should be reconsidered.
|
||||
Once `handle_stop' returns, the information it stores in the
|
||||
iterator fields will not be refreshed until the iteration reaches
|
||||
the next stop position, which is computed by `compute_stop_pos'
|
||||
called at the end of `handle_stop'. `compute_stop_pos' examines
|
||||
the buffer's or string's interval tree to determine where the text
|
||||
properties change, finds the next position where overlays and
|
||||
character composition can change, and stores in `stop_charpos' the
|
||||
closest position where any of these factors should be reconsidered.
|
||||
|
||||
Handling of the stop position is done as part of the code in
|
||||
`get_next_display_element'.
|
||||
|
||||
Producing glyphs.
|
||||
|
||||
Glyphs in a desired matrix are normally constructed in a loop
|
||||
calling get_next_display_element and then PRODUCE_GLYPHS. The call
|
||||
to PRODUCE_GLYPHS will fill the iterator structure with pixel
|
||||
information about the element being displayed and at the same time
|
||||
produce glyphs for it. If the display element fits on the line
|
||||
being displayed, set_iterator_to_next is called next, otherwise the
|
||||
glyphs produced are discarded. The function display_line is the
|
||||
workhorse of filling glyph rows in the desired matrix with glyphs.
|
||||
In addition to producing glyphs, it also handles line truncation
|
||||
and continuation, word wrap, and cursor positioning (for the
|
||||
latter, see also set_cursor_from_row).
|
||||
calling `get_next_display_element' and then `PRODUCE_GLYPHS'. The
|
||||
call to `PRODUCE_GLYPHS' will fill the iterator structure with
|
||||
pixel information about the element being displayed and at the same
|
||||
time will produce glyphs for it. If the display element fits on
|
||||
the line being displayed, `set_iterator_to_next' is called next,
|
||||
otherwise the glyphs produced are discarded, and `display_line'
|
||||
marks this glyph row as a "continued line". The function
|
||||
`display_line' is the workhorse of filling glyph rows in the
|
||||
desired matrix with glyphs. In addition to producing glyphs, it
|
||||
also handles line truncation and continuation, word wrap, and
|
||||
cursor positioning (for the latter, see `set_cursor_from_row').
|
||||
|
||||
Frame matrices.
|
||||
|
||||
That just couldn't be all, could it? What about terminal types not
|
||||
supporting operations on sub-windows of the screen (a.k.a. "TTY" or
|
||||
"text-mode terminal")? To update the display on such a terminal,
|
||||
"text-mode terminals")? To update the display on such a terminal,
|
||||
window-based glyph matrices are not well suited. To be able to
|
||||
reuse part of the display (scrolling lines up and down), we must
|
||||
instead have a view of the whole screen. This is what `frame
|
||||
|
@ -252,19 +290,62 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
using the frame matrices, which allows frame-global optimization of
|
||||
what is actually written to the glass.
|
||||
|
||||
To be honest, there is a little bit more done, but not much more.
|
||||
If you plan to extend that code, take a look at dispnew.c. The
|
||||
function build_frame_matrix is a good starting point.
|
||||
Frame matrices don't have marginal areas, only a text area. That
|
||||
is, the entire row of glyphs that spans the width of a text-mode
|
||||
frame is treated as a single large "text area" for the purposes of
|
||||
manipulating and updating a frame glyph matrix.
|
||||
|
||||
To be honest, there is a little bit more done for frame matrices,
|
||||
but not much more. If you plan to extend that code, take a look at
|
||||
dispnew.c. The function build_frame_matrix is a good starting
|
||||
point.
|
||||
|
||||
Simulating display.
|
||||
|
||||
Some of Emacs commands and functions need to take display layout
|
||||
into consideration. For example, C-n moves to the next screen
|
||||
line, but to implement that, Emacs needs to find the buffer
|
||||
position which is directly below the cursor position on display.
|
||||
This is not trivial when buffer display includes variable-size
|
||||
elements such as different fonts, tall images, etc.
|
||||
|
||||
To solve this problem, the display engine implements several
|
||||
functions that can move through buffer text in the same manner as
|
||||
`display_line' and `display_string' do, but without producing any
|
||||
glyphs for the glyph matrices. The workhorse of this is
|
||||
`move_it_in_display_line_to'. Its code and logic are very similar
|
||||
to `display_line', but it differs in two important aspects: it
|
||||
doesn't produce glyphs for any glyph matrix, and it returns a
|
||||
status telling the caller how it ended the iteration: whether it
|
||||
reached the required position, hit the end of line, arrived at the
|
||||
window edge without exhausting the buffer's line, etc. Since the
|
||||
glyphs are not produced, the layout information available to the
|
||||
callers of this function is what is recorded in `struct it' by the
|
||||
iteration process.
|
||||
|
||||
Several higher-level functions call `move_it_in_display_line_to' to
|
||||
perform more complex tasks: `move_it_by_lines' can move N lines up
|
||||
or down from a given buffer position and `move_it_to' can move to a
|
||||
given buffer position or to a given X or Y pixel coordinate.
|
||||
|
||||
These functions are called by the display engine itself as well,
|
||||
when it needs to make layout decisions before producing the glyphs.
|
||||
For example, one of the first things to decide when redisplaying a
|
||||
window is where to put the `window-start' position; if the window
|
||||
is to be recentered (the default), Emacs makes that decision by
|
||||
starting from the position of point, then moving up the number of
|
||||
lines corresponding to half the window height using
|
||||
`move_it_by_lines'.
|
||||
|
||||
Bidirectional display.
|
||||
|
||||
Bidirectional display adds quite some hair to this already complex
|
||||
design. The good news are that a large portion of that hairy stuff
|
||||
is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
|
||||
reordering engine which is called by set_iterator_to_next and
|
||||
reordering engine which is called by `set_iterator_to_next' and
|
||||
returns the next character to display in the visual order. See
|
||||
commentary on bidi.c for more details. As far as redisplay is
|
||||
concerned, the effect of calling bidi_move_to_visually_next, the
|
||||
concerned, the effect of calling `bidi_move_to_visually_next', the
|
||||
main interface of the reordering engine, is that the iterator gets
|
||||
magically placed on the buffer or string position that is to be
|
||||
displayed next in the visual order. In other words, a linear
|
||||
|
@ -279,27 +360,27 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
monotonously changing with vertical positions. Also, accounting
|
||||
for face changes, overlays, etc. becomes more complex because
|
||||
non-linear iteration could potentially skip many positions with
|
||||
changes, and then cross them again on the way back (see
|
||||
handle_stop_backwards)...
|
||||
such changes, and then cross them again on the way back (see
|
||||
`handle_stop_backwards')...
|
||||
|
||||
One other prominent effect of bidirectional display is that some
|
||||
paragraphs of text need to be displayed starting at the right
|
||||
margin of the window---the so-called right-to-left, or R2L
|
||||
paragraphs. R2L paragraphs are displayed with R2L glyph rows,
|
||||
which have their reversed_p flag set. The bidi reordering engine
|
||||
which have their `reversed_p' flag set. The bidi reordering engine
|
||||
produces characters in such rows starting from the character which
|
||||
should be the rightmost on display. PRODUCE_GLYPHS then reverses
|
||||
the order, when it fills up the glyph row whose reversed_p flag is
|
||||
set, by prepending each new glyph to what is already there, instead
|
||||
of appending it. When the glyph row is complete, the function
|
||||
extend_face_to_end_of_line fills the empty space to the left of the
|
||||
leftmost character with special glyphs, which will display as,
|
||||
well, empty. On text terminals, these special glyphs are simply
|
||||
blank characters. On graphics terminals, there's a single stretch
|
||||
glyph of a suitably computed width. Both the blanks and the
|
||||
stretch glyph are given the face of the background of the line.
|
||||
This way, the terminal-specific back-end can still draw the glyphs
|
||||
left to right, even for R2L lines.
|
||||
should be the rightmost on display. `PRODUCE_GLYPHS' then reverses
|
||||
the order, when it fills up the glyph row whose `reversed_p' flag
|
||||
is set, by prepending each new glyph to what is already there,
|
||||
instead of appending it. When the glyph row is complete, the
|
||||
function `extend_face_to_end_of_line' fills the empty space to the
|
||||
left of the leftmost character with special glyphs, which will
|
||||
display as, well, empty. On text terminals, these special glyphs
|
||||
are simply blank characters. On graphics terminals, there's a
|
||||
single stretch glyph of a suitably computed width. Both the blanks
|
||||
and the stretch glyph are given the face of the background of the
|
||||
line. This way, the terminal-specific back-end can still draw the
|
||||
glyphs left to right, even for R2L lines.
|
||||
|
||||
Bidirectional display and character compositions.
|
||||
|
||||
|
@ -310,23 +391,23 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
||||
Emacs display supports this by providing "character compositions",
|
||||
most of which is implemented in composite.c. During the buffer
|
||||
scan that delivers characters to PRODUCE_GLYPHS, if the next
|
||||
scan that delivers characters to `PRODUCE_GLYPHS', if the next
|
||||
character to be delivered is a composed character, the iteration
|
||||
calls composition_reseat_it and next_element_from_composition. If
|
||||
they succeed to compose the character with one or more of the
|
||||
calls `composition_reseat_it' and `next_element_from_composition'.
|
||||
If they succeed to compose the character with one or more of the
|
||||
following characters, the whole sequence of characters that were
|
||||
composed is recorded in the `struct composition_it' object that is
|
||||
part of the buffer iterator. The composed sequence could produce
|
||||
one or more font glyphs (called "grapheme clusters") on the screen.
|
||||
Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
|
||||
in the direction corresponding to the current bidi scan direction
|
||||
(recorded in the scan_dir member of the `struct bidi_it' object
|
||||
that is part of the iterator). In particular, if the bidi iterator
|
||||
currently scans the buffer backwards, the grapheme clusters are
|
||||
delivered back to front. This reorders the grapheme clusters as
|
||||
appropriate for the current bidi context. Note that this means
|
||||
that the grapheme clusters are always stored in the LGSTRING object
|
||||
(see composite.c) in the logical order.
|
||||
Each of these grapheme clusters is then delivered to
|
||||
`PRODUCE_GLYPHS' in the direction corresponding to the current bidi
|
||||
scan direction (recorded in the `scan_dir' member of the `struct
|
||||
bidi_it' object that is part of the iterator). In particular, if
|
||||
the bidi iterator currently scans the buffer backwards, the
|
||||
grapheme clusters are delivered back to front. This reorders the
|
||||
grapheme clusters as appropriate for the current bidi context.
|
||||
Note that this means that the grapheme clusters are always stored
|
||||
in the `LGSTRING' object (see composite.c) in the logical order.
|
||||
|
||||
Moving an iterator in bidirectional text
|
||||
without producing glyphs.
|
||||
|
@ -337,18 +418,18 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
As far as the iterator is concerned, the geometry of such rows is
|
||||
still left to right, i.e. the iterator "thinks" the first character
|
||||
is at the leftmost pixel position. The iterator does not know that
|
||||
PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
|
||||
delivers. This is important when functions from the move_it_*
|
||||
`PRODUCE_GLYPHS' reverses the order of the glyphs that the iterator
|
||||
delivers. This is important when functions from the `move_it_*'
|
||||
family are used to get to certain screen position or to match
|
||||
screen coordinates with buffer coordinates: these functions use the
|
||||
iterator geometry, which is left to right even in R2L paragraphs.
|
||||
This works well with most callers of move_it_*, because they need
|
||||
This works well with most callers of `move_it_*', because they need
|
||||
to get to a specific column, and columns are still numbered in the
|
||||
reading order, i.e. the rightmost character in a R2L paragraph is
|
||||
still column zero. But some callers do not get well with this; a
|
||||
notable example is mouse clicks that need to find the character
|
||||
that corresponds to certain pixel coordinates. See
|
||||
buffer_posn_from_coords in dispnew.c for how this is handled. */
|
||||
`buffer_posn_from_coords' in dispnew.c for how this is handled. */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
|
|
Loading…
Add table
Reference in a new issue