mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-09 15:50:21 +00:00
Merge from origin/emacs-28
c163fd9260
(origin/emacs-28) Minor fixes for recent changes in ELisp ...fefada4816
Fix example in calc manuale74e17c1f0
Rewrites of Elisp manual including tab-bar and tab-line ch...3b138917b7
; * INSTALL: Fix typo.ce71446585
* lisp/tab-bar.el: Improve docstrings (bug#51247)ace4ce16a3
* lisp/tab-bar.el (tab-bar-mouse-move-tab): Don't drag tab...04716ca48f
Add tab-bar-drag-maybe for indication of tab dragging (bug...81e3697600
* lisp/tab-bar.el: Add a new tab on [mouse-1] instead of [...a191d3c725
Add new and fix existing docstrings in tab-bar.el and tab-...77dbaedadc
Add tab bar support to the nextstep port7b6fb486c2
Fix potential buffer overflow (bug#50767)ed9f5546aa
Improve doc strings in tab-line.el686a03ee22
More documentation fixes in tab-bar.el35920791df
Improve doc strings of tab-bar commands2d15db6e89
Fix a semantic test on some macOS machinesac6ac76e3a
Update to Org 9.5-57-g9bc3a2
This commit is contained in:
commit
7d12c06725
2
INSTALL
2
INSTALL
@ -220,7 +220,7 @@ GNU/Linux distribution that you use, and the options that you want to
|
||||
configure Emacs with. On Debian-based systems, you can install all the
|
||||
packages needed to build the installed version of Emacs with a command
|
||||
like 'apt-get build-dep emacs' (on older systems, replace 'emacs' with
|
||||
eg 'emacs25'). On Red Hat-based systems, the corresponding command is
|
||||
e.g. 'emacs25'). On Red Hat-based systems, the corresponding command is
|
||||
'dnf builddep emacs' (on older systems, use 'yum-builddep' instead).
|
||||
|
||||
On FreeBSD, the command is 'pkg install -y `pkg rquery %dn emacs-devel`'.
|
||||
|
@ -89,11 +89,12 @@ in which most editing takes place. Most of the primitives for
|
||||
examining or changing text operate implicitly on the current buffer
|
||||
(@pxref{Text}).
|
||||
|
||||
Normally, the buffer displayed in the selected window is the current
|
||||
buffer, but this is not always so: a Lisp program can temporarily
|
||||
designate any buffer as current in order to operate on its contents,
|
||||
without changing what is displayed on the screen. The most basic
|
||||
function for designating a current buffer is @code{set-buffer}.
|
||||
Normally, the buffer displayed in the selected window
|
||||
(@pxref{Selecting Windows}) is the current buffer, but this is not
|
||||
always so: a Lisp program can temporarily designate any buffer as
|
||||
current in order to operate on its contents, without changing what is
|
||||
displayed on the screen. The most basic function for designating a
|
||||
current buffer is @code{set-buffer}.
|
||||
|
||||
@defun current-buffer
|
||||
This function returns the current buffer.
|
||||
@ -118,12 +119,12 @@ on it.
|
||||
|
||||
When an editing command returns to the editor command loop, Emacs
|
||||
automatically calls @code{set-buffer} on the buffer shown in the
|
||||
selected window. This is to prevent confusion: it ensures that the
|
||||
buffer that the cursor is in, when Emacs reads a command, is the
|
||||
buffer to which that command applies (@pxref{Command Loop}). Thus,
|
||||
you should not use @code{set-buffer} to switch visibly to a different
|
||||
buffer; for that, use the functions described in @ref{Switching
|
||||
Buffers}.
|
||||
selected window (@pxref{Selecting Windows}). This is to prevent
|
||||
confusion: it ensures that the buffer that the cursor is in, when Emacs
|
||||
reads a command, is the buffer to which that command applies
|
||||
(@pxref{Command Loop}). Thus, you should not use @code{set-buffer} to
|
||||
switch visibly to a different buffer; for that, use the functions
|
||||
described in @ref{Switching Buffers}.
|
||||
|
||||
When writing a Lisp function, do @emph{not} rely on this behavior of
|
||||
the command loop to restore the current buffer after an operation.
|
||||
@ -912,16 +913,17 @@ History}) provided it is shown in that window.
|
||||
|
||||
If @var{buffer-or-name} is @code{nil} or omitted, this means to bury the
|
||||
current buffer. In addition, if the current buffer is displayed in the
|
||||
selected window, this makes sure that the window is either deleted or
|
||||
another buffer is shown in it. More precisely, if the selected window
|
||||
is dedicated (@pxref{Dedicated Windows}) and there are other windows on
|
||||
its frame, the window is deleted. If it is the only window on its frame
|
||||
and that frame is not the only frame on its terminal, the frame is
|
||||
dismissed by calling the function specified by
|
||||
@code{frame-auto-hide-function} (@pxref{Quitting Windows}). Otherwise,
|
||||
it calls @code{switch-to-prev-buffer} (@pxref{Window History}) to show
|
||||
another buffer in that window. If @var{buffer-or-name} is displayed in
|
||||
some other window, it remains displayed there.
|
||||
selected window (@pxref{Selecting Windows}), this makes sure that the
|
||||
window is either deleted or another buffer is shown in it. More
|
||||
precisely, if the selected window is dedicated (@pxref{Dedicated
|
||||
Windows}) and there are other windows on its frame, the window is
|
||||
deleted. If it is the only window on its frame and that frame is not
|
||||
the only frame on its terminal, the frame is dismissed by calling the
|
||||
function specified by @code{frame-auto-hide-function} (@pxref{Quitting
|
||||
Windows}). Otherwise, it calls @code{switch-to-prev-buffer}
|
||||
(@pxref{Window History}) to show another buffer in that window. If
|
||||
@var{buffer-or-name} is displayed in some other window, it remains
|
||||
displayed there.
|
||||
|
||||
To replace a buffer in all the windows that display it, use
|
||||
@code{replace-buffer-in-windows}, @xref{Buffers and Windows}.
|
||||
|
@ -1048,6 +1048,7 @@ Windows
|
||||
|
||||
* Basic Windows:: Basic information on using windows.
|
||||
* Windows and Frames:: Relating windows to the frame they appear on.
|
||||
* Selecting Windows:: The selected window is the one that you edit in.
|
||||
* Window Sizes:: Accessing a window's size.
|
||||
* Resizing Windows:: Changing the sizes of windows.
|
||||
* Preserving Window Sizes:: Preserving the size of windows.
|
||||
@ -1055,7 +1056,6 @@ Windows
|
||||
* Deleting Windows:: Deleting a window gives its space to other windows.
|
||||
* Recombining Windows:: Preserving the frame layout when splitting and
|
||||
deleting windows.
|
||||
* Selecting Windows:: The selected window is the one that you edit in.
|
||||
* Cyclic Window Ordering:: Moving around the existing windows.
|
||||
* Buffers and Windows:: Each window displays the contents of a buffer.
|
||||
* Switching Buffers:: Higher-level functions for switching to a buffer.
|
||||
|
@ -151,7 +151,7 @@ the window (a.k.a.@: the @dfn{dominating} monitor).
|
||||
|
||||
This function itself does not make the new frame the selected frame.
|
||||
@xref{Input Focus}. The previously selected frame remains selected.
|
||||
On graphical terminals, however, the windowing system may select the
|
||||
On graphical terminals, however, the window system may select the
|
||||
new frame for its own reasons.
|
||||
@end deffn
|
||||
|
||||
@ -494,7 +494,8 @@ a graphical terminal:
|
||||
| | |_____________ Title Bar ______________| |
|
||||
| | (1)_____________ Menu Bar ______________| | ^
|
||||
| | (2)_____________ Tool Bar ______________| | ^
|
||||
| | (3) _________ Internal Border ________ | | ^
|
||||
| | (3)_____________ Tab Bar _______________| | ^
|
||||
| | | _________ Internal Border ________ | | ^
|
||||
| | | | ^ | | | |
|
||||
| | | | | | | | |
|
||||
Outer | | | Inner | | | Native
|
||||
@ -640,6 +641,15 @@ GTK+, on the other hand, never wraps the tool bar but may
|
||||
automatically increase the outer width of a frame in order to
|
||||
accommodate an overlong tool bar.
|
||||
|
||||
@item Tab Bar
|
||||
@cindex internal tab bar
|
||||
The tab bar (@pxref{Tab Bars,,,emacs, The GNU Emacs Manual}) is always
|
||||
drawn by Emacs itself. The tab bar appears above the tool bar in
|
||||
Emacs built with an internal tool bar, and below the tool bar in
|
||||
builds with an external tool bar.
|
||||
Display of the tab bar can be suppressed by setting the
|
||||
@code{tab-bar-lines} parameter (@pxref{Layout Parameters}) to zero.
|
||||
|
||||
@item Native Frame
|
||||
@cindex native frame
|
||||
@cindex native edges
|
||||
@ -740,8 +750,8 @@ the internal border, one vertical scroll bar, and one left and one right
|
||||
fringe if they are specified for this frame, see @ref{Layout
|
||||
Parameters}. Its height can be obtained by removing from that of the
|
||||
native height the widths of the internal border and the heights of the
|
||||
frame's internal menu and tool bars and one horizontal scroll bar if
|
||||
specified for this frame.
|
||||
frame's internal menu and tool bars, the tab bar and one horizontal
|
||||
scroll bar if specified for this frame.
|
||||
@end table
|
||||
|
||||
@cindex absolute position
|
||||
@ -1875,6 +1885,13 @@ 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 tab-bar-lines@r{, a frame parameter}
|
||||
@item tab-bar-lines
|
||||
The number of lines to use for the tab bar (@pxref{Tab Bars,,,emacs, The
|
||||
GNU Emacs Manual}). The default is one if Tab Bar mode is enabled and
|
||||
zero otherwise. This value may change whenever the tab bar wraps
|
||||
(@pxref{Frame Layout}).
|
||||
|
||||
@vindex line-spacing@r{, a frame parameter}
|
||||
@item line-spacing
|
||||
Additional space to leave below each text line, in pixels (a positive
|
||||
@ -2758,7 +2775,8 @@ Terminals}.
|
||||
@cindex selected frame
|
||||
|
||||
At any time, one frame in Emacs is the @dfn{selected frame}. The
|
||||
selected window always resides on the selected frame.
|
||||
selected window (@pxref{Selecting Windows}) always resides on the
|
||||
selected frame.
|
||||
|
||||
When Emacs displays its frames on several terminals (@pxref{Multiple
|
||||
Terminals}), each terminal has its own selected frame. But only one
|
||||
@ -2992,12 +3010,11 @@ Auto-selection}).
|
||||
|
||||
Note that this option does not distinguish ``sloppy'' focus (where the
|
||||
frame that previously had focus retains focus as long as the mouse
|
||||
pointer does not move into another window manager window) from
|
||||
``strict'' focus (where a frame immediately loses focus when it's left
|
||||
by the mouse pointer). Neither does it recognize whether your window
|
||||
manager supports delayed focusing or auto-raising where you can
|
||||
explicitly specify the time until a new frame gets focus or is
|
||||
auto-raised.
|
||||
pointer does not move into another window-system window) from ``strict''
|
||||
focus (where a frame immediately loses focus when it's left by the mouse
|
||||
pointer). Neither does it recognize whether your window manager
|
||||
supports delayed focusing or auto-raising where you can explicitly
|
||||
specify the time until a new frame gets focus or is auto-raised.
|
||||
|
||||
You can supply a ``focus follows mouse'' policy for individual Emacs
|
||||
windows by customizing the variable @code{mouse-autoselect-window}
|
||||
|
@ -1625,19 +1625,18 @@ markers.
|
||||
@node Window Type
|
||||
@subsection Window Type
|
||||
|
||||
A @dfn{window} describes the portion of the terminal screen that Emacs
|
||||
uses to display a buffer. Every window has one associated buffer, whose
|
||||
contents appear in the window. By contrast, a given buffer may appear
|
||||
in one window, no window, or several windows.
|
||||
A @dfn{window} describes the portion of the screen that Emacs uses to
|
||||
display buffers. Every live window (@pxref{Basic Windows}) has one
|
||||
associated buffer, whose contents appear in that window. By contrast, a
|
||||
given buffer may appear in one window, no window, or several windows.
|
||||
Windows are grouped on the screen into frames; each window belongs to
|
||||
one and only one frame. @xref{Frame Type}.
|
||||
|
||||
Though many windows may exist simultaneously, at any time one window
|
||||
is designated the @dfn{selected window}. This is the window where the
|
||||
cursor is (usually) displayed when Emacs is ready for a command. The
|
||||
selected window usually displays the current buffer (@pxref{Current
|
||||
Buffer}), but this is not necessarily the case.
|
||||
|
||||
Windows are grouped on the screen into frames; each window belongs to
|
||||
one and only one frame. @xref{Frame Type}.
|
||||
is designated the @dfn{selected window} (@pxref{Selecting Windows}).
|
||||
This is the window where the cursor is (usually) displayed when Emacs is
|
||||
ready for a command. The selected window usually displays the current
|
||||
buffer (@pxref{Current Buffer}), but this is not necessarily the case.
|
||||
|
||||
Windows have no read syntax. They print in hash notation, giving the
|
||||
window number and the name of the buffer being displayed. The window
|
||||
|
@ -179,6 +179,8 @@ copyleft
|
||||
counterintuitive
|
||||
cr
|
||||
creatable
|
||||
customization
|
||||
customizations
|
||||
customize
|
||||
deactivate
|
||||
deactivated
|
||||
@ -243,6 +245,8 @@ fmakunbound
|
||||
fo
|
||||
fol
|
||||
following'
|
||||
fontification
|
||||
fontified
|
||||
fooba
|
||||
foobaz
|
||||
foox
|
||||
@ -257,6 +261,7 @@ garbles
|
||||
gc
|
||||
getenv
|
||||
gid
|
||||
glyphs
|
||||
gp
|
||||
grep
|
||||
gtr
|
||||
@ -270,6 +275,8 @@ hostname
|
||||
hpux
|
||||
hscroll
|
||||
ick
|
||||
iconified
|
||||
iconify
|
||||
id
|
||||
idiom
|
||||
ii
|
||||
@ -314,6 +321,7 @@ mathsurround
|
||||
memq
|
||||
mh
|
||||
mini
|
||||
minibuf
|
||||
minibuffer's
|
||||
minibuffers
|
||||
misalignment
|
||||
@ -387,6 +395,7 @@ passwd
|
||||
ped
|
||||
perverse
|
||||
pid
|
||||
pixelwise
|
||||
plist
|
||||
pointer'
|
||||
pointm
|
||||
@ -417,6 +426,10 @@ reader'
|
||||
rebind
|
||||
rec
|
||||
rechecking
|
||||
redisplay
|
||||
redisplayed
|
||||
redisplaying
|
||||
redisplays
|
||||
redo
|
||||
redrawing
|
||||
redraws
|
||||
@ -430,6 +443,7 @@ reinitialize
|
||||
reinitialized
|
||||
reinstall
|
||||
reinstalled
|
||||
resizable
|
||||
resize
|
||||
resized
|
||||
resizes
|
||||
@ -486,6 +500,8 @@ terpri
|
||||
text'
|
||||
tildes
|
||||
time's
|
||||
tooltip
|
||||
tooltips
|
||||
towards
|
||||
transportable
|
||||
txt
|
||||
@ -494,6 +510,7 @@ unbind
|
||||
unbinding
|
||||
unbinds
|
||||
unclutters
|
||||
uncustomized
|
||||
undefine
|
||||
undefines
|
||||
underfull
|
||||
@ -520,6 +537,7 @@ vconcat
|
||||
vectorp
|
||||
vn
|
||||
voidness
|
||||
whitespace
|
||||
window'
|
||||
windowing
|
||||
windowp
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2865,7 +2865,7 @@ that always equals one. Let's try to verify this identity.
|
||||
@smallexample
|
||||
@group
|
||||
2: -64 2: -64 2: -64 2: 9.7192e54 2: 9.7192e54
|
||||
1: -64 1: -3.1175e27 1: 9.7192e54 1: -64 1: 9.7192e54
|
||||
1: -64 1: 3.1175e27 1: 9.7192e54 1: -64 1: 9.7192e54
|
||||
. . . . .
|
||||
|
||||
64 n @key{RET} @key{RET} H C 2 ^ @key{TAB} H S 2 ^
|
||||
|
@ -98,6 +98,15 @@ latest stable version of Org should be compatible with Emacs 28.x,
|
||||
|
||||
See [[https://orgmode.org/worg/org-maintenance.html#emacs-compatibility][this note on Worg]] and [[git::519947e508e081e71bf67db99e27b1c171ba4dfe][this commit]].
|
||||
|
||||
*** The keybinding for ~org-table-blank-field~ has been removed
|
||||
|
||||
If you prefer to keep the keybinding, you can add it back to
|
||||
~org-mode-map~ like so:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(define-key org-mode-map (kbd "C-c SPC") #'org-table-blank-field)
|
||||
#+end_src
|
||||
|
||||
** New features
|
||||
|
||||
*** New citation engine
|
||||
|
@ -69,7 +69,6 @@
|
||||
(require 'bibtex)
|
||||
(require 'json)
|
||||
(require 'oc)
|
||||
(require 'org)
|
||||
(require 'seq)
|
||||
|
||||
(declare-function org-open-at-point "org" (&optional arg))
|
||||
|
@ -213,8 +213,8 @@ PROPS is the local properties of the bibliography, as a property list."
|
||||
|
||||
(defun org-cite-biblatex-export-citation (citation style _ info)
|
||||
"Export CITATION object.
|
||||
STYLE is the citation style, as a string or nil. INFO is the export state, as
|
||||
a property list."
|
||||
STYLE is the citation style, as a pair of either strings or nil.
|
||||
INFO is the export state, as a property list."
|
||||
(apply
|
||||
#'org-cite-biblatex--command citation info
|
||||
(pcase style
|
||||
|
@ -248,11 +248,11 @@ If nil then the Chicago author-date style is used as a fallback.")
|
||||
("paras." . "paragraph")
|
||||
("¶" . "paragraph")
|
||||
("¶¶" . "paragraph")
|
||||
("§" . "paragraph")
|
||||
("§§" . "paragraph")
|
||||
("part" . "part")
|
||||
("pt." . "part")
|
||||
("pts." . "part")
|
||||
("§" . "section")
|
||||
("§§" . "section")
|
||||
("section" . "section")
|
||||
("sec." . "section")
|
||||
("secs." . "section")
|
||||
@ -270,11 +270,12 @@ If nil then the Chicago author-date style is used as a fallback.")
|
||||
(defconst org-cite-csl--label-regexp
|
||||
;; Prior to Emacs-27.1 argument of `regexp' form must be a string literal.
|
||||
;; It is the reason why `rx' is avoided here.
|
||||
(rx-to-string `(seq word-start
|
||||
(regexp ,(regexp-opt (mapcar #'car org-cite-csl--label-alist) t))
|
||||
(0+ digit)
|
||||
(or word-start line-end (any ?\s ?\t)))
|
||||
t)
|
||||
(rx-to-string
|
||||
`(seq (or line-start space)
|
||||
(regexp ,(regexp-opt (mapcar #'car org-cite-csl--label-alist) t))
|
||||
(0+ digit)
|
||||
(or word-end line-end space " "))
|
||||
t)
|
||||
"Regexp matching a label in a citation reference suffix.
|
||||
Label is in match group 1.")
|
||||
|
||||
@ -371,7 +372,7 @@ or raise an error if the variable is unset."
|
||||
((and (guard org-cite-csl-styles-dir) file)
|
||||
(expand-file-name file org-cite-csl-styles-dir))
|
||||
(other
|
||||
(user-error "Cannot handle relative style file name" other))))
|
||||
(user-error "Cannot handle relative style file name: %S" other))))
|
||||
|
||||
(defun org-cite-csl--locale-getter ()
|
||||
"Return a locale getter.
|
||||
@ -425,7 +426,9 @@ The result is a association list. Keys are: `id', `prefix',`suffix',
|
||||
((re-search-forward org-cite-csl--label-regexp nil t)
|
||||
(setq location-start (match-beginning 0))
|
||||
(setq label (cdr (assoc (match-string 1) org-cite-csl--label-alist)))
|
||||
(setq locator-start (match-end 1)))
|
||||
(goto-char (match-end 1))
|
||||
(skip-chars-forward "[:space:] ")
|
||||
(setq locator-start (point)))
|
||||
((re-search-forward (rx digit) nil t)
|
||||
(setq location-start (match-beginning 0))
|
||||
(setq label "page")
|
||||
|
@ -789,6 +789,20 @@ Citations are ordered by appearance in the document, when following footnotes.
|
||||
INFO is the export communication channel, as a property list."
|
||||
(or (plist-get info :citations)
|
||||
(letrec ((cites nil)
|
||||
(tree (plist-get info :parse-tree))
|
||||
(find-definition
|
||||
;; Find definition for standard reference LABEL. At
|
||||
;; this point, it is impossible to rely on
|
||||
;; `org-export-get-footnote-definition' because the
|
||||
;; function caches results that could contain
|
||||
;; un-processed citation objects. So we use
|
||||
;; a simplified version of the function above.
|
||||
(lambda (label)
|
||||
(org-element-map tree 'footnote-definition
|
||||
(lambda (d)
|
||||
(and (equal label (org-element-property :label d))
|
||||
(or (org-element-contents d) "")))
|
||||
info t)))
|
||||
(search-cites
|
||||
(lambda (data)
|
||||
(org-element-map data '(citation footnote-reference)
|
||||
@ -798,22 +812,13 @@ INFO is the export communication channel, as a property list."
|
||||
;; Do not force entering inline definitions, since
|
||||
;; `org-element-map' is going to enter it anyway.
|
||||
((guard (eq 'inline (org-element-property :type datum))))
|
||||
;; Find definition for current standard
|
||||
;; footnote reference. Unlike to
|
||||
;; `org-export-get-footnote-definition', do
|
||||
;; not cache results as they would contain
|
||||
;; un-processed citation objects.
|
||||
;; Walk footnote definition.
|
||||
(_
|
||||
(let ((label (org-element-property :label datum)))
|
||||
(funcall
|
||||
search-cites
|
||||
(org-element-map data 'footnote-definition
|
||||
(lambda (d)
|
||||
(and
|
||||
(equal label (org-element-property :label d))
|
||||
(or (org-element-contents d) "")))))))))
|
||||
(funcall search-cites
|
||||
(funcall find-definition label))))))
|
||||
info nil 'footnote-definition t))))
|
||||
(funcall search-cites (plist-get info :parse-tree))
|
||||
(funcall search-cites tree)
|
||||
(let ((result (nreverse cites)))
|
||||
(plist-put info :citations result)
|
||||
result))))
|
||||
@ -1593,8 +1598,9 @@ The generated function inserts or edit a citation at point. More specifically,
|
||||
(concat "/" style)
|
||||
""))
|
||||
"")
|
||||
(mapconcat (lambda (k) (concat "@" k)) keys ";"))))))))
|
||||
(mapconcat (lambda (k) (concat "@" k)) keys "; "))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-cite-insert (arg)
|
||||
"Insert a citation at point.
|
||||
Insertion is done according to the processor set in `org-cite-insert-processor'.
|
||||
@ -1603,7 +1609,7 @@ ARG is the prefix argument received when calling interactively the function."
|
||||
(let ((name org-cite-insert-processor))
|
||||
(cond
|
||||
((null name)
|
||||
(user-error "No processor set to follow citations"))
|
||||
(user-error "No processor set to insert citations"))
|
||||
((not (org-cite--get-processor name))
|
||||
(user-error "Unknown processor %S" name))
|
||||
((not (org-cite-processor-has-capability-p name 'insert))
|
||||
|
@ -11,7 +11,7 @@ Inserted by installing Org mode or when a release is made."
|
||||
(defun org-git-version ()
|
||||
"The Git version of Org mode.
|
||||
Inserted by installing Org or when a release is made."
|
||||
(let ((org-git-version "release_9.5-46-gb71474"))
|
||||
(let ((org-git-version "release_9.5-57-g9bc3a2"))
|
||||
org-git-version))
|
||||
|
||||
(provide 'org-version)
|
||||
|
@ -95,6 +95,7 @@
|
||||
(require 'org-keys)
|
||||
(require 'ol)
|
||||
(require 'oc)
|
||||
(require 'oc-basic)
|
||||
(require 'org-table)
|
||||
|
||||
;; `org-outline-regexp' ought to be a defconst but is let-bound in
|
||||
|
245
lisp/tab-bar.el
245
lisp/tab-bar.el
@ -227,6 +227,10 @@ a list of frames to update."
|
||||
;;; Key bindings
|
||||
|
||||
(defun tab-bar--key-to-number (key)
|
||||
"Return the tab number represented by KEY.
|
||||
If KEY is a symbol 'tab-N', where N is a tab number, the value is N.
|
||||
If KEY is \\='current-tab, the value is nil.
|
||||
For any other value of KEY, the value is t."
|
||||
(cond
|
||||
((null key) t)
|
||||
((eq key 'current-tab) nil)
|
||||
@ -235,7 +239,16 @@ a list of frames to update."
|
||||
(string-to-number (string-replace "tab-" "" key-name)))))
|
||||
(t t)))
|
||||
|
||||
(defvar tab-bar-drag-maybe)
|
||||
|
||||
(defun tab-bar--event-to-item (posn)
|
||||
"This function extracts extra info from the mouse event at position POSN.
|
||||
It returns a list of the form (KEY KEY-BINDING CLOSE-P), where:
|
||||
KEY is a symbol representing a tab, such as \\='tab-1 or \\='current-tab;
|
||||
KEY-BINDING is the binding of KEY;
|
||||
CLOSE-P is non-nil if the mouse event was a click on the close button \"x\",
|
||||
nil otherwise."
|
||||
(setq tab-bar-drag-maybe nil)
|
||||
(if (posn-window posn)
|
||||
(let ((caption (car (posn-string posn))))
|
||||
(when caption
|
||||
@ -259,31 +272,40 @@ a list of frames to update."
|
||||
(setq column (+ column (length (nth 1 binding))))))
|
||||
keymap))))))
|
||||
|
||||
(defun tab-bar-mouse-select-tab (event)
|
||||
(defun tab-bar-mouse-down-1 (event)
|
||||
"Select the tab at mouse click, or add a new tab on the tab bar.
|
||||
Whether this command adds a new tab or selects an existing tab
|
||||
depends on whether the click is on the \"+\" button or on an
|
||||
existing tab."
|
||||
(interactive "e")
|
||||
(let* ((item (tab-bar--event-to-item (event-start event)))
|
||||
(tab-number (tab-bar--key-to-number (nth 0 item))))
|
||||
;; Don't close the tab when clicked on the close button.
|
||||
;; Let `tab-bar-mouse-close-tab-from-button' do this.
|
||||
(unless (nth 2 item)
|
||||
(setq tab-bar-drag-maybe t)
|
||||
;; Don't close the tab when clicked on the close button. Also
|
||||
;; don't add new tab on down-mouse. Let `tab-bar-mouse-1' do this.
|
||||
(unless (or (eq (car item) 'add-tab) (nth 2 item))
|
||||
(if (functionp (nth 1 item))
|
||||
(call-interactively (nth 1 item))
|
||||
(unless (eq tab-number t)
|
||||
(tab-bar-select-tab tab-number))))))
|
||||
|
||||
(defun tab-bar-mouse-close-tab-from-button (event)
|
||||
"Close the tab only when clicked on the close button."
|
||||
(defun tab-bar-mouse-1 (event)
|
||||
"Close the tab whose \"x\" close button you click.
|
||||
See also `tab-bar-mouse-close-tab', which closes the tab
|
||||
regardless of where you click on it. Also add a new tab."
|
||||
(interactive "e")
|
||||
(let* ((item (tab-bar--event-to-item (event-start event)))
|
||||
(tab-number (tab-bar--key-to-number (nth 0 item))))
|
||||
(when (nth 2 item)
|
||||
(unless (eq tab-number t)
|
||||
(tab-bar-close-tab tab-number)))))
|
||||
(cond
|
||||
((and (eq (car item) 'add-tab) (functionp (nth 1 item)))
|
||||
(call-interactively (nth 1 item)))
|
||||
((and (nth 2 item) (not (eq tab-number t)))
|
||||
(tab-bar-close-tab tab-number)))))
|
||||
|
||||
(defun tab-bar-mouse-close-tab (event)
|
||||
"Close the tab when clicked anywhere on the tab.
|
||||
This is in contrast with `tab-bar-mouse-close-tab-from-button'
|
||||
that closes only when clicked on the close button."
|
||||
"Close the tab you click on.
|
||||
This is in contrast with `tab-bar-mouse-1' that closes a tab
|
||||
only when you click on its \"x\" close button."
|
||||
(interactive "e")
|
||||
(let* ((item (tab-bar--event-to-item (event-start event)))
|
||||
(tab-number (tab-bar--key-to-number (nth 0 item))))
|
||||
@ -291,6 +313,7 @@ that closes only when clicked on the close button."
|
||||
(tab-bar-close-tab tab-number))))
|
||||
|
||||
(defun tab-bar-mouse-context-menu (event)
|
||||
"Pop up the context menu for the tab on which you click."
|
||||
(interactive "e")
|
||||
(let* ((item (tab-bar--event-to-item (event-start event)))
|
||||
(tab-number (tab-bar--key-to-number (nth 0 item)))
|
||||
@ -330,23 +353,28 @@ that closes only when clicked on the close button."
|
||||
(popup-menu menu event)))
|
||||
|
||||
(defun tab-bar-mouse-move-tab (event)
|
||||
"Move a tab to a different position on the tab bar.
|
||||
This command should be bound to a drag event. It moves the tab
|
||||
at the mouse-down event to the position at mouse-up event."
|
||||
(interactive "e")
|
||||
(setq tab-bar-drag-maybe nil)
|
||||
(let ((from (tab-bar--key-to-number
|
||||
(nth 0 (tab-bar--event-to-item
|
||||
(event-start event)))))
|
||||
(to (tab-bar--key-to-number
|
||||
(nth 0 (tab-bar--event-to-item
|
||||
(event-end event))))))
|
||||
(unless (or (eq from t) (eq to t))
|
||||
(tab-bar-move-tab-to to from))))
|
||||
(unless (or (eq from to) (eq from t) (eq to t))
|
||||
(tab-bar-move-tab-to
|
||||
(if (null to) (1+ (tab-bar--current-tab-index)) to) from))))
|
||||
|
||||
(defvar tab-bar-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [down-mouse-1] 'tab-bar-mouse-select-tab)
|
||||
(define-key map [down-mouse-1] 'tab-bar-mouse-down-1)
|
||||
(define-key map [drag-mouse-1] 'tab-bar-mouse-move-tab)
|
||||
(define-key map [mouse-1] 'tab-bar-mouse-close-tab-from-button)
|
||||
(define-key map [mouse-1] 'tab-bar-mouse-1)
|
||||
(define-key map [down-mouse-2] 'tab-bar-mouse-close-tab)
|
||||
(define-key map [mouse-2] 'ignore)
|
||||
(define-key map [mouse-2] 'ignore)
|
||||
(define-key map [down-mouse-3] 'tab-bar-mouse-context-menu)
|
||||
|
||||
(define-key map [mouse-4] 'tab-previous)
|
||||
@ -677,11 +705,14 @@ the formatted tab name to display in the tab bar."
|
||||
"Template for displaying tab bar items.
|
||||
Every item in the list is a function that returns
|
||||
a string, or a list of menu-item elements, or nil.
|
||||
When you add more items `tab-bar-format-align-right' and
|
||||
`tab-bar-format-global' to the end, then after enabling
|
||||
`display-time-mode' (or any other mode that uses `global-mode-string')
|
||||
it will display time aligned to the right on the tab bar instead of
|
||||
the mode line. Replacing `tab-bar-format-tabs' with
|
||||
Adding a function to the list causes the tab bar to show
|
||||
that string, or display a menu with those menu items when
|
||||
you click on the tab bar.
|
||||
If the list ends with `tab-bar-format-align-right' and
|
||||
`tab-bar-format-global', then after enabling `display-time-mode'
|
||||
(or any other mode that uses `global-mode-string'),
|
||||
it will display time aligned to the right on the tab bar instead
|
||||
of the mode line. Replacing `tab-bar-format-tabs' with
|
||||
`tab-bar-format-tabs-groups' will group tabs on the tab bar."
|
||||
:type 'hook
|
||||
:options '(tab-bar-format-menu-global
|
||||
@ -700,7 +731,7 @@ the mode line. Replacing `tab-bar-format-tabs' with
|
||||
:version "28.1")
|
||||
|
||||
(defun tab-bar-format-menu-global ()
|
||||
"Show global menu on clicking the Menu button."
|
||||
"Produce the Menu button for the tab bar that shows a global menu."
|
||||
`((add-tab menu-item (propertize "Menu" 'face 'tab-bar-tab-inactive)
|
||||
(lambda (event) (interactive "e")
|
||||
(let ((menu (make-sparse-keymap
|
||||
@ -717,7 +748,8 @@ the mode line. Replacing `tab-bar-format-tabs' with
|
||||
:help "Global Menu")))
|
||||
|
||||
(defun tab-bar-format-history ()
|
||||
"Show back and forward buttons when `tab-bar-history-mode' is enabled.
|
||||
"Produce back and forward buttons for the tab bar.
|
||||
These buttons will be shown when `tab-bar-history-mode' is enabled.
|
||||
You can hide these buttons by customizing `tab-bar-format' and removing
|
||||
`tab-bar-format-history' from it."
|
||||
(when tab-bar-history-mode
|
||||
@ -731,7 +763,7 @@ You can hide these buttons by customizing `tab-bar-format' and removing
|
||||
:help "Click to go forward in tab history"))))
|
||||
|
||||
(defun tab-bar--format-tab (tab i)
|
||||
"Format TAB using its index I and return the result as a string."
|
||||
"Format TAB using its index I and return the result as a keymap."
|
||||
(append
|
||||
`((,(intern (format "sep-%i" i)) menu-item ,(tab-bar-separator) ignore))
|
||||
(cond
|
||||
@ -753,7 +785,7 @@ You can hide these buttons by customizing `tab-bar-format' and removing
|
||||
,(alist-get 'close-binding tab))))))
|
||||
|
||||
(defun tab-bar-format-tabs ()
|
||||
"Show all tabs."
|
||||
"Produce all the tabs for the tab bar."
|
||||
(let ((i 0))
|
||||
(mapcan
|
||||
(lambda (tab)
|
||||
@ -807,6 +839,9 @@ Function gets one argument: a tab."
|
||||
(tab-bar-tab-face-default tab)))
|
||||
|
||||
(defun tab-bar--format-tab-group (tab i &optional current-p)
|
||||
"Format TAB as a tab that represents a group of tabs.
|
||||
The argument I is the tab index, and CURRENT-P is non-nil
|
||||
when the tab is current. Return the result as a keymap."
|
||||
(append
|
||||
`((,(intern (format "sep-%i" i)) menu-item ,(tab-bar-separator) ignore))
|
||||
`((,(intern (format "group-%i" i))
|
||||
@ -824,7 +859,7 @@ Function gets one argument: a tab."
|
||||
:help "Click to visit group"))))
|
||||
|
||||
(defun tab-bar-format-tabs-groups ()
|
||||
"Show tabs with their groups."
|
||||
"Produce tabs for the tab bar grouped according to their groups."
|
||||
(let* ((tabs (funcall tab-bar-tabs-function))
|
||||
(current-group (funcall tab-bar-tab-group-function
|
||||
(tab-bar--current-tab-find tabs)))
|
||||
@ -868,7 +903,7 @@ Function gets one argument: a tab."
|
||||
`((align-right menu-item ,str ignore))))
|
||||
|
||||
(defun tab-bar-format-global ()
|
||||
"Format `global-mode-string' to display it in the tab bar.
|
||||
"Produce display of `global-mode-string' in the tab bar.
|
||||
When `tab-bar-format-global' is added to `tab-bar-format'
|
||||
(possibly appended after `tab-bar-format-align-right'),
|
||||
then modes that display information on the mode line
|
||||
@ -917,6 +952,7 @@ on the tab bar instead."
|
||||
(push '(tabs . frameset-filter-tabs) frameset-filter-alist)
|
||||
|
||||
(defun tab-bar--tab (&optional frame)
|
||||
"Make a new tab data structure that can be added to tabs on the FRAME."
|
||||
(let* ((tab (tab-bar--current-tab-find nil frame))
|
||||
(tab-explicit-name (alist-get 'explicit-name tab))
|
||||
(tab-group (alist-get 'group tab))
|
||||
@ -951,12 +987,15 @@ on the tab bar instead."
|
||||
(cdr tab)))))
|
||||
|
||||
(defun tab-bar--current-tab (&optional tab frame)
|
||||
"Make the current tab data structure from TAB on FRAME."
|
||||
(tab-bar--current-tab-make (or tab (tab-bar--current-tab-find nil frame))))
|
||||
|
||||
(defun tab-bar--current-tab-make (&optional tab)
|
||||
;; `tab' here is an argument meaning "use tab as template". This is
|
||||
;; necessary when switching tabs, otherwise the destination tab
|
||||
;; inherits the current tab's `explicit-name' parameter.
|
||||
"Make the current tab data structure from TAB.
|
||||
TAB here is an argument meaning \"use tab as template\",
|
||||
i.e. the tab is created using data from TAB. This is
|
||||
necessary when switching tabs, otherwise the destination tab
|
||||
inherits the current tab's `explicit-name' parameter."
|
||||
(let* ((tab-explicit-name (alist-get 'explicit-name tab))
|
||||
(tab-group (if tab
|
||||
(alist-get 'group tab)
|
||||
@ -979,27 +1018,33 @@ on the tab bar instead."
|
||||
(cdr tab)))))
|
||||
|
||||
(defun tab-bar--current-tab-find (&optional tabs frame)
|
||||
;; Find the current tab as a pointer to its data structure.
|
||||
(assq 'current-tab (or tabs (funcall tab-bar-tabs-function frame))))
|
||||
|
||||
(defun tab-bar--current-tab-index (&optional tabs frame)
|
||||
;; Return the index of the current tab.
|
||||
(seq-position (or tabs (funcall tab-bar-tabs-function frame))
|
||||
'current-tab (lambda (a b) (eq (car a) b))))
|
||||
|
||||
(defun tab-bar--tab-index (tab &optional tabs frame)
|
||||
;; Return the index of TAB.
|
||||
(seq-position (or tabs (funcall tab-bar-tabs-function frame))
|
||||
tab #'eq))
|
||||
|
||||
(defun tab-bar--tab-index-by-name (name &optional tabs frame)
|
||||
;; Return the index of TAB by the its NAME.
|
||||
(seq-position (or tabs (funcall tab-bar-tabs-function frame))
|
||||
name (lambda (a b) (equal (alist-get 'name a) b))))
|
||||
|
||||
(defun tab-bar--tab-index-recent (nth &optional tabs frame)
|
||||
;; Return the index of NTH recent tab.
|
||||
(let* ((tabs (or tabs (funcall tab-bar-tabs-function frame)))
|
||||
(sorted-tabs (tab-bar--tabs-recent tabs frame))
|
||||
(tab (nth (1- nth) sorted-tabs)))
|
||||
(tab-bar--tab-index tab tabs)))
|
||||
|
||||
(defun tab-bar--tabs-recent (&optional tabs frame)
|
||||
;; Return the list of tabs sorted by recency.
|
||||
(let* ((tabs (or tabs (funcall tab-bar-tabs-function frame))))
|
||||
(seq-sort-by (lambda (tab) (alist-get 'time tab)) #'>
|
||||
(seq-remove (lambda (tab)
|
||||
@ -1089,7 +1134,8 @@ the tab bar."
|
||||
(force-mode-line-update))))
|
||||
|
||||
(defun tab-bar-switch-to-next-tab (&optional arg)
|
||||
"Switch to ARGth next tab."
|
||||
"Switch to ARGth next tab.
|
||||
Interactively, ARG is the prefix numeric argument and defaults to 1."
|
||||
(interactive "p")
|
||||
(unless (integerp arg)
|
||||
(setq arg 1))
|
||||
@ -1099,20 +1145,24 @@ the tab bar."
|
||||
(tab-bar-select-tab (1+ to-index))))
|
||||
|
||||
(defun tab-bar-switch-to-prev-tab (&optional arg)
|
||||
"Switch to ARGth previous tab."
|
||||
"Switch to ARGth previous tab.
|
||||
Interactively, ARG is the prefix numeric argument and defaults to 1."
|
||||
(interactive "p")
|
||||
(unless (integerp arg)
|
||||
(setq arg 1))
|
||||
(tab-bar-switch-to-next-tab (- arg)))
|
||||
|
||||
(defun tab-bar-switch-to-last-tab (&optional arg)
|
||||
"Switch to the last tab or ARGth tab from the end of the tab bar."
|
||||
"Switch to the last tab or ARGth tab from the end of the tab bar.
|
||||
Interactively, ARG is the prefix numeric argument; it defaults to 1,
|
||||
which means the last tab on the tab bar."
|
||||
(interactive "p")
|
||||
(tab-bar-select-tab (- (length (funcall tab-bar-tabs-function))
|
||||
(1- (or arg 1)))))
|
||||
|
||||
(defun tab-bar-switch-to-recent-tab (&optional arg)
|
||||
"Switch to ARGth most recently visited tab."
|
||||
"Switch to ARGth most recently visited tab.
|
||||
Interactively, ARG is the prefix numeric argument and defaults to 1."
|
||||
(interactive "p")
|
||||
(unless (integerp arg)
|
||||
(setq arg 1))
|
||||
@ -1160,8 +1210,9 @@ where argument addressing is relative."
|
||||
|
||||
(defun tab-bar-move-tab (&optional arg)
|
||||
"Move the current tab ARG positions to the right.
|
||||
If a negative ARG, move the current tab ARG positions to the left.
|
||||
Argument addressing is relative in contrast to `tab-bar-move-tab-to'
|
||||
Interactively, ARG is the prefix numeric argument and defaults to 1.
|
||||
If ARG is negative, move the current tab ARG positions to the left.
|
||||
Argument addressing is relative in contrast to `tab-bar-move-tab-to',
|
||||
where argument addressing is absolute."
|
||||
(interactive "p")
|
||||
(let* ((tabs (funcall tab-bar-tabs-function))
|
||||
@ -1171,6 +1222,7 @@ where argument addressing is absolute."
|
||||
|
||||
(defun tab-bar-move-tab-backward (&optional arg)
|
||||
"Move the current tab ARG positions to the left.
|
||||
Interactively, ARG is the prefix numeric argument and defaults to 1.
|
||||
Like `tab-bar-move-tab', but moves in the opposite direction."
|
||||
(interactive "p")
|
||||
(tab-bar-move-tab (- (or arg 1))))
|
||||
@ -1181,7 +1233,8 @@ FROM-NUMBER defaults to the current tab number.
|
||||
FROM-NUMBER and TO-NUMBER count from 1.
|
||||
FROM-FRAME specifies the source frame and defaults to the selected frame.
|
||||
TO-FRAME specifies the target frame and defaults the next frame.
|
||||
Interactively, ARG selects the ARGth different frame to move to."
|
||||
Interactively, ARG selects the ARGth next frame on the same terminal,
|
||||
to which to move the tab; ARG defaults to 1."
|
||||
(interactive "P")
|
||||
(unless from-frame
|
||||
(setq from-frame (selected-frame)))
|
||||
@ -1209,7 +1262,7 @@ Interactively, ARG selects the ARGth different frame to move to."
|
||||
|
||||
(defun tab-bar-detach-tab (&optional from-number)
|
||||
"Move tab number FROM-NUMBER to a new frame.
|
||||
Interactively or without argument, move the current tab."
|
||||
FROM-NUMBER defaults to the current tab (which happens interactively)."
|
||||
(interactive (list (1+ (tab-bar--current-tab-index))))
|
||||
(let* ((tabs (funcall tab-bar-tabs-function))
|
||||
(tab-index (1- (or from-number (1+ (tab-bar--current-tab-index tabs)))))
|
||||
@ -1223,7 +1276,10 @@ Interactively or without argument, move the current tab."
|
||||
(tab-bar-close-tab))))
|
||||
|
||||
(defun tab-bar-move-window-to-tab ()
|
||||
"Detach the selected window to a new tab."
|
||||
"Move the selected window to a new tab.
|
||||
This command removes the selected window from the configuration stored
|
||||
on the current tab, and makes a new tab with that window in its
|
||||
configuration."
|
||||
(interactive)
|
||||
(let ((tab-bar-new-tab-choice 'window))
|
||||
(tab-bar-new-tab))
|
||||
@ -1233,17 +1289,17 @@ Interactively or without argument, move the current tab."
|
||||
|
||||
|
||||
(defcustom tab-bar-new-tab-to 'right
|
||||
"Defines where to create a new tab.
|
||||
"Where to create a new tab.
|
||||
If `leftmost', create as the first tab.
|
||||
If `left', create to the left from the current tab.
|
||||
If `right', create to the right from the current tab.
|
||||
If `left', create to the left of the current tab.
|
||||
If `right', create to the right of the current tab.
|
||||
If `rightmost', create as the last tab.
|
||||
If the value is a function, it should return a number as a position
|
||||
on the tab bar specifying where to insert a new tab."
|
||||
:type '(choice (const :tag "First tab" leftmost)
|
||||
(const :tag "To the left" left)
|
||||
(const :tag "To the right" right)
|
||||
(const :tag "Last tab" rightmost)
|
||||
on the tab bar specifying where to add a new tab."
|
||||
:type '(choice (const :tag "Add as First" leftmost)
|
||||
(const :tag "Add to Left" left)
|
||||
(const :tag "Add to Right" right)
|
||||
(const :tag "Add as Last" rightmost)
|
||||
(function :tag "Function"))
|
||||
:group 'tab-bar
|
||||
:version "27.1")
|
||||
@ -1262,7 +1318,7 @@ TAB-NUMBER counts from 1. If no TAB-NUMBER is specified, then add
|
||||
a new tab at the position specified by `tab-bar-new-tab-to'.
|
||||
Negative TAB-NUMBER counts tabs from the end of the tab bar,
|
||||
and -1 means the new tab will become the last one.
|
||||
Argument addressing is absolute in contrast to `tab-bar-new-tab'
|
||||
Argument addressing is absolute in contrast to `tab-bar-new-tab',
|
||||
where argument addressing is relative.
|
||||
After the tab is created, the hooks in
|
||||
`tab-bar-tab-post-open-functions' are run."
|
||||
@ -1335,7 +1391,7 @@ If a negative ARG, create a new tab ARG positions to the left.
|
||||
If ARG is zero, create a new tab in place of the current tab.
|
||||
If no ARG is specified, then add a new tab at the position
|
||||
specified by `tab-bar-new-tab-to'.
|
||||
Argument addressing is relative in contrast to `tab-bar-new-tab-to'
|
||||
Argument addressing is relative in contrast to `tab-bar-new-tab-to',
|
||||
where argument addressing is absolute.
|
||||
If FROM-NUMBER is a tab number, a new tab is created from that tab."
|
||||
(interactive "P")
|
||||
@ -1362,7 +1418,7 @@ ARG and FROM-NUMBER have the same meaning as in `tab-bar-new-tab'."
|
||||
"A list of closed tabs to be able to undo their closing.")
|
||||
|
||||
(defcustom tab-bar-close-tab-select 'recent
|
||||
"Defines what tab to select after closing the specified tab.
|
||||
"Which tab to make current after closing the specified tab.
|
||||
If `left', select the adjacent left tab.
|
||||
If `right', select the adjacent right tab.
|
||||
If `recent', select the most recently visited tab."
|
||||
@ -1373,7 +1429,7 @@ If `recent', select the most recently visited tab."
|
||||
:version "27.1")
|
||||
|
||||
(defcustom tab-bar-close-last-tab-choice nil
|
||||
"Defines what to do when the last tab is closed.
|
||||
"What to do when the last tab is closed.
|
||||
If nil, do nothing and show a message, like closing the last window or frame.
|
||||
If `delete-frame', delete the containing frame, as a web browser would do.
|
||||
If `tab-bar-mode-disable', disable `tab-bar-mode' so that tabs no longer show
|
||||
@ -1398,9 +1454,8 @@ function returns a non-nil value, the tab will not be closed."
|
||||
|
||||
(defcustom tab-bar-tab-pre-close-functions nil
|
||||
"List of functions to call before closing a tab.
|
||||
The tab to be closed and a boolean indicating whether or not it
|
||||
is the only tab in the frame are supplied as arguments,
|
||||
respectively."
|
||||
Each function is called with two arguments: the tab to be closed
|
||||
and a boolean indicating whether or not it is the only tab on its frame."
|
||||
:type '(repeat function)
|
||||
:group 'tab-bar
|
||||
:version "27.1")
|
||||
@ -1409,6 +1464,7 @@ respectively."
|
||||
"Close the tab specified by its absolute position TAB-NUMBER.
|
||||
If no TAB-NUMBER is specified, then close the current tab and switch
|
||||
to the tab specified by `tab-bar-close-tab-select'.
|
||||
Interactively, TAB-NUMBER is the prefix numeric argument, and defaults to 1.
|
||||
TAB-NUMBER counts from 1.
|
||||
Optional TO-NUMBER could be specified to override the value of
|
||||
`tab-bar-close-tab-select' programmatically with a position
|
||||
@ -1482,7 +1538,8 @@ for the last tab on a frame is determined by
|
||||
(message "Deleted tab and switched to %s" tab-bar-close-tab-select))))))
|
||||
|
||||
(defun tab-bar-close-tab-by-name (name)
|
||||
"Close the tab by NAME."
|
||||
"Close the tab given its NAME.
|
||||
Interactively, prompt for NAME."
|
||||
(interactive
|
||||
(list (completing-read "Close tab by name: "
|
||||
(mapcar (lambda (tab)
|
||||
@ -1491,8 +1548,9 @@ for the last tab on a frame is determined by
|
||||
(tab-bar-close-tab (1+ (tab-bar--tab-index-by-name name))))
|
||||
|
||||
(defun tab-bar-close-other-tabs (&optional tab-number)
|
||||
"Close all tabs on the selected frame, except TAB-NUMBER.
|
||||
TAB-NUMBER counts from 1 and defaults to the current tab."
|
||||
"Close all tabs on the selected frame, except the tab TAB-NUMBER.
|
||||
TAB-NUMBER counts from 1 and defaults to the current tab (which
|
||||
happens interactively)."
|
||||
(interactive)
|
||||
(let* ((tabs (funcall tab-bar-tabs-function))
|
||||
(current-index (tab-bar--current-tab-index tabs))
|
||||
@ -1558,9 +1616,12 @@ TAB-NUMBER counts from 1 and defaults to the current tab."
|
||||
|
||||
|
||||
(defun tab-bar-rename-tab (name &optional tab-number)
|
||||
"Rename the tab specified by its absolute position TAB-NUMBER.
|
||||
"Give the tab specified by its absolute position TAB-NUMBER a new NAME.
|
||||
If no TAB-NUMBER is specified, then rename the current tab.
|
||||
Interactively, TAB-NUMBER is the prefix numeric argument, and defaults
|
||||
to the current tab.
|
||||
TAB-NUMBER counts from 1.
|
||||
Interactively, prompt for the new NAME.
|
||||
If NAME is the empty string, then use the automatic name
|
||||
function `tab-bar-tab-name-function'."
|
||||
(interactive
|
||||
@ -1588,7 +1649,8 @@ function `tab-bar-tab-name-function'."
|
||||
(message "Renamed tab to '%s'" tab-new-name))))
|
||||
|
||||
(defun tab-bar-rename-tab-by-name (tab-name new-name)
|
||||
"Rename the tab named TAB-NAME.
|
||||
"Rename the tab named TAB-NAME to NEW-NAME.
|
||||
Interactively, prompt for TAB-NAME and NEW-NAME.
|
||||
If NEW-NAME is the empty string, then use the automatic name
|
||||
function `tab-bar-tab-name-function'."
|
||||
(interactive
|
||||
@ -1605,7 +1667,7 @@ function `tab-bar-tab-name-function'."
|
||||
;;; Tab groups
|
||||
|
||||
(defun tab-bar-move-tab-to-group (&optional tab)
|
||||
"Relocate TAB (or the current tab) closer to its group."
|
||||
"Relocate TAB (by default, the current tab) closer to its group."
|
||||
(interactive)
|
||||
(let* ((tabs (funcall tab-bar-tabs-function))
|
||||
(tab (or tab (tab-bar--current-tab-find tabs)))
|
||||
@ -1643,6 +1705,8 @@ The current tab is supplied as an argument."
|
||||
(defun tab-bar-change-tab-group (group-name &optional tab-number)
|
||||
"Add the tab specified by its absolute position TAB-NUMBER to GROUP-NAME.
|
||||
If no TAB-NUMBER is specified, then set the GROUP-NAME for the current tab.
|
||||
Interactively, TAB-NUMBER is the prefix numeric argument, and the command
|
||||
prompts for GROUP-NAME.
|
||||
TAB-NUMBER counts from 1.
|
||||
If GROUP-NAME is the empty string, then remove the tab from any group.
|
||||
While using this command, you might also want to replace
|
||||
@ -1680,7 +1744,8 @@ While using this command, you might also want to replace
|
||||
(message "Set tab group to '%s'" group-new-name))))
|
||||
|
||||
(defun tab-bar-close-group-tabs (group-name)
|
||||
"Close all tabs that belong to GROUP-NAME on the selected frame."
|
||||
"Close all tabs that belong to GROUP-NAME on the selected frame.
|
||||
Interactively, prompt for GROUP-NAME."
|
||||
(interactive
|
||||
(let ((group-name (funcall tab-bar-tab-group-function
|
||||
(tab-bar--current-tab-find))))
|
||||
@ -1727,7 +1792,7 @@ While using this command, you might also want to replace
|
||||
|
||||
(defun tab-bar--history-pre-change ()
|
||||
(setq tab-bar-history-old-minibuffer-depth (minibuffer-depth))
|
||||
;; Store wc before possibly entering the minibuffer
|
||||
;; Store window-configuration before possibly entering the minibuffer.
|
||||
(when (zerop tab-bar-history-old-minibuffer-depth)
|
||||
(setq tab-bar-history-old
|
||||
`((wc . ,(current-window-configuration))
|
||||
@ -1736,7 +1801,8 @@ While using this command, you might also want to replace
|
||||
(defun tab-bar--history-change ()
|
||||
(when (and (not tab-bar-history-omit)
|
||||
tab-bar-history-old
|
||||
;; Store wc before possibly entering the minibuffer
|
||||
;; Store window-configuration before possibly entering
|
||||
;; the minibuffer.
|
||||
(zerop tab-bar-history-old-minibuffer-depth))
|
||||
(puthash (selected-frame)
|
||||
(seq-take (cons tab-bar-history-old
|
||||
@ -1928,12 +1994,16 @@ Letters do not insert themselves; instead, they are commands.
|
||||
nil))))
|
||||
|
||||
(defun tab-switcher-next-line (&optional arg)
|
||||
"Move to ARGth next line in the list of tabs.
|
||||
Interactively, ARG is the prefix numeric argument and defaults to 1."
|
||||
(interactive "p")
|
||||
(forward-line arg)
|
||||
(beginning-of-line)
|
||||
(move-to-column tab-switcher-column))
|
||||
|
||||
(defun tab-switcher-prev-line (&optional arg)
|
||||
"Move to ARGth previous line in the list of tabs.
|
||||
Interactively, ARG is the prefix numeric argument and defaults to 1."
|
||||
(interactive "p")
|
||||
(forward-line (- arg))
|
||||
(beginning-of-line)
|
||||
@ -1941,7 +2011,7 @@ Letters do not insert themselves; instead, they are commands.
|
||||
|
||||
(defun tab-switcher-unmark (&optional backup)
|
||||
"Cancel requested operations on window configuration on this line and move down.
|
||||
Optional prefix arg means move up."
|
||||
With prefix arg, move up instead."
|
||||
(interactive "P")
|
||||
(beginning-of-line)
|
||||
(move-to-column tab-switcher-column)
|
||||
@ -1961,7 +2031,7 @@ Optional prefix arg means move up."
|
||||
|
||||
(defun tab-switcher-delete (&optional arg)
|
||||
"Mark window configuration on this line to be deleted by \\<tab-switcher-mode-map>\\[tab-switcher-execute] command.
|
||||
Prefix arg is how many window configurations to delete.
|
||||
Prefix arg says how many window configurations to delete.
|
||||
Negative arg means delete backwards."
|
||||
(interactive "p")
|
||||
(let ((buffer-read-only nil))
|
||||
@ -1986,7 +2056,7 @@ Then move up one line. Prefix arg means move that many lines."
|
||||
(tab-switcher-delete (- (or arg 1))))
|
||||
|
||||
(defun tab-switcher-delete-from-list (tab)
|
||||
"Delete the window configuration from both lists."
|
||||
"Delete the window configuration from the list of tabs."
|
||||
(push `((frame . ,(selected-frame))
|
||||
(index . ,(tab-bar--tab-index tab))
|
||||
(tab . ,tab))
|
||||
@ -2014,8 +2084,8 @@ Then move up one line. Prefix arg means move that many lines."
|
||||
|
||||
(defun tab-switcher-select ()
|
||||
"Select this line's window configuration.
|
||||
This command deletes and replaces all the previously existing windows
|
||||
in the selected frame."
|
||||
This command replaces all the existing windows in the selected frame
|
||||
with those specified by the selected window configuration."
|
||||
(interactive)
|
||||
(let* ((to-tab (tab-switcher-current-tab t)))
|
||||
(kill-buffer (current-buffer))
|
||||
@ -2041,8 +2111,8 @@ in the selected frame."
|
||||
(t (list (selected-frame)))))
|
||||
|
||||
(defun tab-bar-get-buffer-tab (buffer-or-name &optional all-frames ignore-current-tab)
|
||||
"Return a tab owning a window whose buffer is BUFFER-OR-NAME.
|
||||
BUFFER-OR-NAME may be a buffer or a buffer name and defaults to
|
||||
"Return the tab that owns the window whose buffer is BUFFER-OR-NAME.
|
||||
BUFFER-OR-NAME may be a buffer or a buffer name, and defaults to
|
||||
the current buffer.
|
||||
|
||||
The optional argument ALL-FRAMES specifies the frames to consider:
|
||||
@ -2090,7 +2160,7 @@ Otherwise, prefer buffers of the current tab."
|
||||
(tab-bar--reusable-frames all-frames)))))
|
||||
|
||||
(defun display-buffer-in-tab (buffer alist)
|
||||
"Display BUFFER in a tab.
|
||||
"Display BUFFER in a tab using display actions in ALIST.
|
||||
ALIST is an association list of action symbols and values. See
|
||||
Info node `(elisp) Buffer Display Action Alists' for details of
|
||||
such alists.
|
||||
@ -2098,8 +2168,8 @@ such alists.
|
||||
If ALIST contains a `tab-name' entry, it creates a new tab with that name and
|
||||
displays BUFFER in a new tab. If a tab with this name already exists, it
|
||||
switches to that tab before displaying BUFFER. The `tab-name' entry can be
|
||||
a function, then it is called with two arguments: BUFFER and ALIST, and
|
||||
should return the tab name. When a `tab-name' entry is omitted, create
|
||||
a function, in which case it is called with two arguments: BUFFER and ALIST,
|
||||
and should return the tab name. When a `tab-name' entry is omitted, create
|
||||
a new tab without an explicit name.
|
||||
|
||||
The ALIST entry `tab-group' (string or function) defines the tab group.
|
||||
@ -2149,7 +2219,7 @@ indirectly called by the latter."
|
||||
(display-buffer-in-new-tab buffer alist))))))
|
||||
|
||||
(defun display-buffer-in-new-tab (buffer alist)
|
||||
"Display BUFFER in a new tab.
|
||||
"Display BUFFER in a new tab using display actions in ALIST.
|
||||
ALIST is an association list of action symbols and values. See
|
||||
Info node `(elisp) Buffer Display Action Alists' for details of
|
||||
such alists.
|
||||
@ -2159,9 +2229,9 @@ without checking if a suitable tab already exists.
|
||||
|
||||
If ALIST contains a `tab-name' entry, it creates a new tab with that name
|
||||
and displays BUFFER in a new tab. The `tab-name' entry can be a function,
|
||||
then it is called with two arguments: BUFFER and ALIST, and should return
|
||||
the tab name. When a `tab-name' entry is omitted, create a new tab without
|
||||
an explicit name.
|
||||
in which case it is called with two arguments: BUFFER and ALIST, and should
|
||||
return the tab name. When a `tab-name' entry is omitted, create a new tab
|
||||
without an explicit name.
|
||||
|
||||
The ALIST entry `tab-group' (string or function) defines the tab group.
|
||||
|
||||
@ -2183,19 +2253,23 @@ indirectly called by the latter."
|
||||
(tab-bar-change-tab-group tab-group)))
|
||||
(window--display-buffer buffer (selected-window) 'tab alist)))
|
||||
|
||||
(defun switch-to-buffer-other-tab (buffer-or-name &optional norecord)
|
||||
(defun switch-to-buffer-other-tab (buffer-or-name &optional _norecord)
|
||||
"Switch to buffer BUFFER-OR-NAME in another tab.
|
||||
Like \\[switch-to-buffer-other-frame] (which see), but creates a new tab."
|
||||
Like \\[switch-to-buffer-other-frame] (which see), but creates a new tab.
|
||||
Interactively, prompt for the buffer to switch to."
|
||||
(declare (advertised-calling-convention (buffer-or-name) "28.1"))
|
||||
(interactive
|
||||
(list (read-buffer-to-switch "Switch to buffer in other tab: ")))
|
||||
(display-buffer (window-normalize-buffer-to-switch-to buffer-or-name)
|
||||
'((display-buffer-in-tab)
|
||||
(inhibit-same-window . nil))
|
||||
norecord))
|
||||
(inhibit-same-window . nil))))
|
||||
|
||||
(defun find-file-other-tab (filename &optional wildcards)
|
||||
"Edit file FILENAME, in another tab.
|
||||
Like \\[find-file-other-frame] (which see), but creates a new tab."
|
||||
Like \\[find-file-other-frame] (which see), but creates a new tab.
|
||||
Interactively, prompt for FILENAME.
|
||||
If WILDCARDS is non-nil, FILENAME can include widcards, and all matching
|
||||
files will be visited."
|
||||
(interactive
|
||||
(find-file-read-args "Find file in other tab: "
|
||||
(confirm-nonexistent-file-or-buffer)))
|
||||
@ -2212,7 +2286,10 @@ Like \\[find-file-other-frame] (which see), but creates a new tab."
|
||||
"Edit file FILENAME, in another tab, but don't allow changes.
|
||||
Like \\[find-file-other-frame] (which see), but creates a new tab.
|
||||
Like \\[find-file-other-tab], but marks buffer as read-only.
|
||||
Use \\[read-only-mode] to permit editing."
|
||||
Use \\[read-only-mode] to permit editing.
|
||||
Interactively, prompt for FILENAME.
|
||||
If WILDCARDS is non-nil, FILENAME can include widcards, and all matching
|
||||
files will be visited."
|
||||
(interactive
|
||||
(find-file-read-args "Find file read-only in other tab: "
|
||||
(confirm-nonexistent-file-or-buffer)))
|
||||
|
@ -262,13 +262,14 @@ If nil, don't show it at all."
|
||||
|
||||
(defcustom tab-line-tab-name-function #'tab-line-tab-name-buffer
|
||||
"Function to get a tab name.
|
||||
Function gets two arguments: tab to get name for and a list of tabs
|
||||
to display. By default, use function `tab-line-tab-name'."
|
||||
The function is called with one or two arguments: the buffer or
|
||||
another object whose tab's name is requested, and, optionally,
|
||||
the list of all tabs."
|
||||
:type '(choice (const :tag "Buffer name"
|
||||
tab-line-tab-name-buffer)
|
||||
(const :tag "Truncated buffer name"
|
||||
tab-line-tab-name-truncated-buffer)
|
||||
(function :tag "Function"))
|
||||
(function :tag "Function"))
|
||||
:initialize 'custom-initialize-default
|
||||
:set (lambda (sym val)
|
||||
(set-default sym val)
|
||||
@ -294,9 +295,9 @@ to `tab-line-tab-name-truncated-buffer'."
|
||||
(defvar tab-line-tab-name-ellipsis t)
|
||||
|
||||
(defun tab-line-tab-name-truncated-buffer (buffer &optional _buffers)
|
||||
"Generate tab name from BUFFER.
|
||||
"Generate tab name from BUFFER, truncating it as needed.
|
||||
Truncate it to the length specified by `tab-line-tab-name-truncated-max'.
|
||||
Append ellipsis `tab-line-tab-name-ellipsis' in this case."
|
||||
If truncated, append ellipsis per `tab-line-tab-name-ellipsis'."
|
||||
(let ((tab-name (buffer-name buffer)))
|
||||
(if (< (length tab-name) tab-line-tab-name-truncated-max)
|
||||
tab-name
|
||||
@ -343,7 +344,7 @@ Used only for `tab-line-tabs-mode-buffers' and `tab-line-tabs-buffer-groups'.")
|
||||
(buffer-list)))))
|
||||
|
||||
(defun tab-line-tabs-mode-buffers ()
|
||||
"Return a list of buffers with the same major mode with current buffer."
|
||||
"Return a list of buffers with the same major mode as the current buffer."
|
||||
(let ((mode major-mode))
|
||||
(seq-sort-by #'buffer-name #'string<
|
||||
(seq-filter (lambda (b) (with-current-buffer b
|
||||
@ -351,12 +352,12 @@ Used only for `tab-line-tabs-mode-buffers' and `tab-line-tabs-buffer-groups'.")
|
||||
(funcall tab-line-tabs-buffer-list-function)))))
|
||||
|
||||
(defvar tab-line-tabs-buffer-group-function nil
|
||||
"Function to put a buffer to the group.
|
||||
Takes a buffer as arg and should return a group name as string.
|
||||
When the return value is nil, filter out the buffer.")
|
||||
"Function to add a buffer to the appropriate group of tabs.
|
||||
Takes a buffer as arg and should return a group name as a string.
|
||||
If the return value is nil, the buffer should be filtered out.")
|
||||
|
||||
(defvar tab-line-tabs-buffer-group-sort-function nil
|
||||
"Function to sort buffers in group.")
|
||||
"Function to sort buffers in a group.")
|
||||
|
||||
(defvar tab-line-tabs-buffer-groups-sort-function #'string<
|
||||
"Function to sort group names.")
|
||||
@ -364,7 +365,9 @@ When the return value is nil, filter out the buffer.")
|
||||
(defvar tab-line-tabs-buffer-groups mouse-buffer-menu-mode-groups
|
||||
"How to group various major modes together in the tab line.
|
||||
Each element has the form (REGEXP . GROUPNAME).
|
||||
If the major mode's name string matches REGEXP, use GROUPNAME instead.")
|
||||
If the major mode's name matches REGEXP, it belongs to GROUPNAME.
|
||||
The default is for each major mode to have a separate group
|
||||
named the same as the mode.")
|
||||
|
||||
(defun tab-line-tabs-buffer-group-name (&optional buffer)
|
||||
(if (functionp tab-line-tabs-buffer-group-function)
|
||||
@ -460,8 +463,11 @@ variable `tab-line-tabs-function'."
|
||||
|
||||
(defcustom tab-line-tab-name-format-function #'tab-line-tab-name-format-default
|
||||
"Function to format a tab name.
|
||||
Function gets two arguments: the tab and a list of all tabs, and
|
||||
should return the formatted tab name to display in the tab line."
|
||||
The function will be called two arguments: the tab whose name to format,
|
||||
and the list of all the tabs; it should return the formatted tab name
|
||||
to display in the tab line.
|
||||
The first argument could also be a different object, for example the buffer
|
||||
which the tab will represent."
|
||||
:type 'function
|
||||
:initialize 'custom-initialize-default
|
||||
:set (lambda (sym val)
|
||||
@ -471,6 +477,7 @@ should return the formatted tab name to display in the tab line."
|
||||
:version "28.1")
|
||||
|
||||
(defun tab-line-tab-name-format-default (tab tabs)
|
||||
"Default function to use as `tab-line-tab-name-format-function', which see."
|
||||
(let* ((buffer-p (bufferp tab))
|
||||
(selected-p (if buffer-p
|
||||
(eq tab (window-buffer))
|
||||
@ -503,7 +510,8 @@ should return the formatted tab name to display in the tab line."
|
||||
mouse-face tab-line-highlight))))
|
||||
|
||||
(defun tab-line-format-template (tabs)
|
||||
"Template for displaying tab line for selected window."
|
||||
"Template of the format for displaying tab line for selected window.
|
||||
This is used by `tab-line-format'."
|
||||
(let* ((separator (or tab-line-separator (if window-system " " "|")))
|
||||
(hscroll (window-parameter nil 'tab-line-hscroll))
|
||||
(strings
|
||||
@ -535,7 +543,8 @@ should return the formatted tab name to display in the tab line."
|
||||
|
||||
(defun tab-line-tab-face-inactive-alternating (tab tabs face _buffer-p selected-p)
|
||||
"Return FACE for TAB in TABS with alternation.
|
||||
When TAB is an inactive buffer and is even-numbered, make FACE
|
||||
SELECTED-P nil means TAB is not the selected tab.
|
||||
When TAB is not selected and is even-numbered, make FACE
|
||||
inherit from `tab-line-tab-inactive-alternate'. For use in
|
||||
`tab-line-tab-face-functions'."
|
||||
(when (and (not selected-p) (cl-evenp (cl-position tab tabs)))
|
||||
@ -543,8 +552,8 @@ inherit from `tab-line-tab-inactive-alternate'. For use in
|
||||
face)
|
||||
|
||||
(defun tab-line-tab-face-special (tab _tabs face buffer-p _selected-p)
|
||||
"Return FACE for TAB according to whether it's special.
|
||||
When TAB is a non-file-backed buffer, make FACE inherit from
|
||||
"Return FACE for TAB according to whether its buffer is special.
|
||||
When TAB is a non-file-visiting buffer, make FACE inherit from
|
||||
`tab-line-tab-special'. For use in
|
||||
`tab-line-tab-face-functions'."
|
||||
(when (and buffer-p (not (buffer-file-name tab)))
|
||||
@ -552,7 +561,7 @@ When TAB is a non-file-backed buffer, make FACE inherit from
|
||||
face)
|
||||
|
||||
(defun tab-line-tab-face-modified (tab _tabs face buffer-p _selected-p)
|
||||
"Return FACE for TAB according to whether it's modified.
|
||||
"Return FACE for TAB according to whether its buffer is modified.
|
||||
When TAB is a modified, file-backed buffer, make FACE inherit
|
||||
from `tab-line-tab-modified'. For use in
|
||||
`tab-line-tab-face-functions'."
|
||||
@ -570,7 +579,7 @@ For use in `tab-line-tab-face-functions'."
|
||||
(defvar tab-line-auto-hscroll)
|
||||
|
||||
(defun tab-line-format ()
|
||||
"Template for displaying tab line for selected window."
|
||||
"Format for displaying the tab line of the selected window."
|
||||
(let* ((tabs (funcall tab-line-tabs-function))
|
||||
(cache-key (list tabs
|
||||
;; handle buffer renames
|
||||
@ -598,7 +607,7 @@ For use in `tab-line-tab-face-functions'."
|
||||
|
||||
(defcustom tab-line-auto-hscroll t
|
||||
"Allow or disallow automatic horizontal scrolling of the tab line.
|
||||
Non-nil means the tab line are automatically scrolled horizontally to make
|
||||
Non-nil means the tab lines are automatically scrolled horizontally to make
|
||||
the selected tab visible."
|
||||
:type 'boolean
|
||||
:group 'tab-line
|
||||
@ -694,12 +703,16 @@ the selected tab visible."
|
||||
(force-mode-line-update t))))
|
||||
|
||||
(defun tab-line-hscroll-right (&optional arg event)
|
||||
"Scroll the tab line ARG positions to the right.
|
||||
Interactively, ARG is the prefix numeric argument and defaults to 1."
|
||||
(interactive (list current-prefix-arg last-nonmenu-event))
|
||||
(let ((window (and (listp event) (posn-window (event-start event)))))
|
||||
(tab-line-hscroll arg window)
|
||||
(force-mode-line-update window)))
|
||||
|
||||
(defun tab-line-hscroll-left (&optional arg event)
|
||||
"Scroll the tab line ARG positions to the left.
|
||||
Interactively, ARG is the prefix numeric argument and defaults to 1."
|
||||
(interactive (list current-prefix-arg last-nonmenu-event))
|
||||
(let ((window (and (listp event) (posn-window (event-start event)))))
|
||||
(tab-line-hscroll (- (or arg 1)) window)
|
||||
@ -707,10 +720,10 @@ the selected tab visible."
|
||||
|
||||
|
||||
(defun tab-line-new-tab (&optional event)
|
||||
"Add a new tab to the tab line.
|
||||
Usually is invoked by clicking on the plus-shaped button.
|
||||
But any switching to other buffer also adds a new tab
|
||||
corresponding to the switched buffer."
|
||||
"Add a new tab to the selected-window's tab line.
|
||||
This command is usually invoked by clicking on the plus-shaped button
|
||||
on the tab line. Switching to another buffer also adds a new tab
|
||||
corresponding to the new buffer shown in the window."
|
||||
(interactive (list last-nonmenu-event))
|
||||
(if (functionp tab-line-new-tab-choice)
|
||||
(funcall tab-line-new-tab-choice)
|
||||
@ -723,9 +736,9 @@ corresponding to the switched buffer."
|
||||
(tmm-prompt (mouse-buffer-menu-keymap))))))
|
||||
|
||||
(defun tab-line-select-tab (&optional event)
|
||||
"Switch to the selected tab.
|
||||
"Switch to the buffer specified by the tab on which you click.
|
||||
This command maintains the original order of prev/next buffers.
|
||||
So for example, switching to a previous tab is equivalent to
|
||||
So, for example, switching to a previous tab is equivalent to
|
||||
using the `previous-buffer' command."
|
||||
(interactive "e")
|
||||
(let* ((posnp (event-start event))
|
||||
@ -771,7 +784,7 @@ when `tab-line-tabs-function' is `tab-line-tabs-window-buffers'."
|
||||
:version "28.1")
|
||||
|
||||
(defun tab-line-switch-to-prev-tab (&optional event)
|
||||
"Switch to the previous tab.
|
||||
"Switch to the previous tab's buffer.
|
||||
Its effect is the same as using the `previous-buffer' command
|
||||
(\\[previous-buffer])."
|
||||
(interactive (list last-nonmenu-event))
|
||||
@ -795,7 +808,7 @@ Its effect is the same as using the `previous-buffer' command
|
||||
(switch-to-buffer buffer)))))))
|
||||
|
||||
(defun tab-line-switch-to-next-tab (&optional event)
|
||||
"Switch to the next tab.
|
||||
"Switch to the next tab's buffer.
|
||||
Its effect is the same as using the `next-buffer' command
|
||||
(\\[next-buffer])."
|
||||
(interactive (list last-nonmenu-event))
|
||||
@ -820,9 +833,9 @@ Its effect is the same as using the `next-buffer' command
|
||||
|
||||
|
||||
(defcustom tab-line-close-tab-function 'bury-buffer
|
||||
"Defines what to do on closing the tab.
|
||||
"What to do upon closing a tab on the tab line.
|
||||
If `bury-buffer', put the tab's buffer at the end of the list of all
|
||||
buffers that effectively hides the buffer's tab from the tab line.
|
||||
buffers, which effectively hides the buffer's tab from the tab line.
|
||||
If `kill-buffer', kills the tab's buffer.
|
||||
When a function, it is called with the tab as its argument.
|
||||
This option is useful when `tab-line-tabs-function' has the value
|
||||
@ -835,9 +848,9 @@ This option is useful when `tab-line-tabs-function' has the value
|
||||
|
||||
(defun tab-line-close-tab (&optional event)
|
||||
"Close the selected tab.
|
||||
Usually is invoked by clicking on the close button on the right side
|
||||
of the tab. This command buries the buffer, so it goes out of sight
|
||||
from the tab line."
|
||||
This command is usually invoked by clicking on the close button on the
|
||||
right side of the tab. This command buries the buffer, so it goes out of
|
||||
sight of the tab line."
|
||||
(interactive (list last-nonmenu-event))
|
||||
(let* ((posnp (and (listp event) (event-start event)))
|
||||
(window (and posnp (posn-window posnp)))
|
||||
@ -860,7 +873,7 @@ from the tab line."
|
||||
(force-mode-line-update))))
|
||||
|
||||
(defun tab-line-tab-context-menu (&optional event)
|
||||
"Pop up context menu for the tab."
|
||||
"Pop up the context menu for a tab-line tab."
|
||||
(interactive "e")
|
||||
(let ((menu (make-sparse-keymap (propertize "Context Menu" 'hide t))))
|
||||
(define-key-after menu [close]
|
||||
@ -868,7 +881,7 @@ from the tab line."
|
||||
(popup-menu menu event)))
|
||||
|
||||
(defun tab-line-context-menu (&optional event)
|
||||
"Pop up context menu for the tab line."
|
||||
"Pop up the context menu for the tab line."
|
||||
(interactive "e")
|
||||
(let ((menu (make-sparse-keymap (propertize "Context Menu" 'hide t))))
|
||||
(define-key-after menu [close]
|
||||
@ -878,13 +891,15 @@ from the tab line."
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode tab-line-mode
|
||||
"Toggle display of window tab line in the buffer."
|
||||
"Toggle display of tab line in the windows displaying the current buffer."
|
||||
:lighter nil
|
||||
(setq tab-line-format (when tab-line-mode '(:eval (tab-line-format)))))
|
||||
|
||||
(defcustom tab-line-exclude-modes
|
||||
'(completion-list-mode)
|
||||
"List of major modes in which the tab line is not enabled."
|
||||
"List of major modes for which the tab-line display is not enabled.
|
||||
Buffers under any of these major modes will not show the tab line in
|
||||
their windows, even if `global-tab-line-mode' is enabled."
|
||||
:type '(repeat symbol)
|
||||
:group 'tab-line
|
||||
:version "27.1")
|
||||
@ -893,7 +908,12 @@ from the tab line."
|
||||
(defvar-local tab-line-exclude nil)
|
||||
|
||||
(defun tab-line-mode--turn-on ()
|
||||
"Turn on `tab-line-mode'."
|
||||
"Turn on `tab-line-mode' in all pertinent buffers.
|
||||
Temporary buffers, buffers whose names begin with a space, buffers
|
||||
under major modes that are either mentioned in `tab-line-exclude-mode'
|
||||
or have a non-nil `tab-line-exclude' property on their symbol,
|
||||
and buffers that have a non-nil buffer-local value
|
||||
of `tab-line-exclude', are exempt from `tab-line-mode'."
|
||||
(unless (or (minibufferp)
|
||||
(string-match-p "\\` " (buffer-name))
|
||||
(memq major-mode tab-line-exclude-modes)
|
||||
|
23
src/image.c
23
src/image.c
@ -9995,10 +9995,16 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
|
||||
if (!STRINGP (lcss))
|
||||
{
|
||||
/* Generate the CSS for the SVG image. */
|
||||
const char *css_spec = "svg{font-family:\"%s\";font-size:%4dpx}";
|
||||
int css_len = strlen (css_spec) + strlen (img->face_font_family);
|
||||
/* FIXME: The below calculations leave enough space for a font
|
||||
size up to 9999, if it overflows we just throw an error but
|
||||
should probably increase the buffer size. */
|
||||
const char *css_spec = "svg{font-family:\"%s\";font-size:%dpx}";
|
||||
int css_len = strlen (css_spec) + strlen (img->face_font_family) + 1;
|
||||
css = xmalloc (css_len);
|
||||
snprintf (css, css_len, css_spec, img->face_font_family, img->face_font_size);
|
||||
if (css_len <= snprintf (css, css_len, css_spec,
|
||||
img->face_font_family, img->face_font_size))
|
||||
goto rsvg_error;
|
||||
|
||||
rsvg_handle_set_stylesheet (rsvg_handle, (guint8 *)css, strlen (css), NULL);
|
||||
}
|
||||
else
|
||||
@ -10156,12 +10162,11 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
|
||||
|
||||
wrapped_contents = xmalloc (buffer_size);
|
||||
|
||||
if (!wrapped_contents
|
||||
|| buffer_size <= snprintf (wrapped_contents, buffer_size, wrapper,
|
||||
foreground & 0xFFFFFF, width, height,
|
||||
viewbox_width, viewbox_height,
|
||||
background & 0xFFFFFF,
|
||||
SSDATA (encoded_contents)))
|
||||
if (buffer_size <= snprintf (wrapped_contents, buffer_size, wrapper,
|
||||
foreground & 0xFFFFFF, width, height,
|
||||
viewbox_width, viewbox_height,
|
||||
background & 0xFFFFFF,
|
||||
SSDATA (encoded_contents)))
|
||||
goto rsvg_error;
|
||||
|
||||
wrapped_size = strlen (wrapped_contents);
|
||||
|
63
src/nsfns.m
63
src/nsfns.m
@ -609,13 +609,72 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ns_change_tab_bar_height (struct frame *f, int height)
|
||||
{
|
||||
int unit = FRAME_LINE_HEIGHT (f);
|
||||
int old_height = FRAME_TAB_BAR_HEIGHT (f);
|
||||
int lines = (height + unit - 1) / unit;
|
||||
Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
|
||||
|
||||
/* Make sure we redisplay all windows in this frame. */
|
||||
fset_redisplay (f);
|
||||
|
||||
/* Recalculate tab bar and frame text sizes. */
|
||||
FRAME_TAB_BAR_HEIGHT (f) = height;
|
||||
FRAME_TAB_BAR_LINES (f) = lines;
|
||||
store_frame_param (f, Qtab_bar_lines, make_fixnum (lines));
|
||||
|
||||
if (FRAME_NS_WINDOW (f) && FRAME_TAB_BAR_HEIGHT (f) == 0)
|
||||
{
|
||||
clear_frame (f);
|
||||
clear_current_matrices (f);
|
||||
}
|
||||
|
||||
if ((height < old_height) && WINDOWP (f->tab_bar_window))
|
||||
clear_glyph_matrix (XWINDOW (f->tab_bar_window)->current_matrix);
|
||||
|
||||
if (!f->tab_bar_resized)
|
||||
{
|
||||
/* As long as tab_bar_resized is false, effectively try to change
|
||||
F's native height. */
|
||||
if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
|
||||
adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
|
||||
1, false, Qtab_bar_lines);
|
||||
else
|
||||
adjust_frame_size (f, -1, -1, 4, false, Qtab_bar_lines);
|
||||
|
||||
f->tab_bar_resized = f->tab_bar_redisplayed;
|
||||
}
|
||||
else
|
||||
/* Any other change may leave the native size of F alone. */
|
||||
adjust_frame_size (f, -1, -1, 3, false, Qtab_bar_lines);
|
||||
|
||||
/* adjust_frame_size might not have done anything, garbage frame
|
||||
here. */
|
||||
adjust_frame_glyphs (f);
|
||||
SET_FRAME_GARBAGED (f);
|
||||
}
|
||||
|
||||
/* tabbar support */
|
||||
static void
|
||||
ns_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
|
||||
{
|
||||
/* Currently unimplemented. */
|
||||
NSTRACE ("ns_set_tab_bar_lines");
|
||||
int olines = FRAME_TAB_BAR_LINES (f);
|
||||
int nlines;
|
||||
|
||||
/* Treat tab bars like menu bars. */
|
||||
if (FRAME_MINIBUF_ONLY_P (f))
|
||||
return;
|
||||
|
||||
/* Use VALUE only if an int >= 0. */
|
||||
if (RANGED_FIXNUMP (0, value, INT_MAX))
|
||||
nlines = XFIXNAT (value);
|
||||
else
|
||||
nlines = 0;
|
||||
|
||||
if (nlines != olines && (olines == 0 || nlines == 0))
|
||||
ns_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1136,6 +1136,7 @@ extern void ns_implicitly_set_name (struct frame *f, Lisp_Object arg,
|
||||
Lisp_Object oldval);
|
||||
extern void ns_set_scroll_bar_default_width (struct frame *f);
|
||||
extern void ns_set_scroll_bar_default_height (struct frame *f);
|
||||
extern void ns_change_tab_bar_height (struct frame *f, int height);
|
||||
extern const char *ns_get_string_resource (void *_rdb,
|
||||
const char *name,
|
||||
const char *class);
|
||||
|
42
src/nsterm.m
42
src/nsterm.m
@ -2721,11 +2721,10 @@ Hide the window (X11 semantics)
|
||||
|
||||
if (FRAME_LIVE_P (f) && FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
|
||||
{
|
||||
int border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
|
||||
NSView *view = FRAME_NS_VIEW (f);
|
||||
NSRect edge_rect, frame_rect = [view bounds];
|
||||
NSRectEdge edge[] = {NSMinXEdge, NSMinYEdge, NSMaxXEdge, NSMaxYEdge};
|
||||
|
||||
int border = FRAME_INTERNAL_BORDER_WIDTH (f);
|
||||
int width = FRAME_PIXEL_WIDTH (f);
|
||||
int height = FRAME_PIXEL_HEIGHT (f);
|
||||
int margin = FRAME_TOP_MARGIN_HEIGHT (f);
|
||||
int face_id =
|
||||
(FRAME_PARENT_FRAME (f)
|
||||
? (!NILP (Vface_remapping_alist)
|
||||
@ -2747,12 +2746,12 @@ Hide the window (X11 semantics)
|
||||
|
||||
ns_focus (f, NULL, 1);
|
||||
[ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set];
|
||||
for (int i = 0; i < 4 ; i++)
|
||||
{
|
||||
NSDivideRect (frame_rect, &edge_rect, &frame_rect, border_width, edge[i]);
|
||||
|
||||
NSRectFill (edge_rect);
|
||||
}
|
||||
NSRectFill (NSMakeRect (0, margin, width, border));
|
||||
NSRectFill (NSMakeRect (0, 0, border, height));
|
||||
NSRectFill (NSMakeRect (0, margin, width, border));
|
||||
NSRectFill (NSMakeRect (width - border, 0, border, height));
|
||||
NSRectFill (NSMakeRect (0, height - border, width, border));
|
||||
ns_unfocus (f);
|
||||
}
|
||||
}
|
||||
@ -5066,6 +5065,7 @@ static Lisp_Object ns_new_font (struct frame *f, Lisp_Object font_object,
|
||||
terminal->free_pixmap = ns_free_pixmap;
|
||||
terminal->delete_frame_hook = ns_destroy_window;
|
||||
terminal->delete_terminal_hook = ns_delete_terminal;
|
||||
terminal->change_tab_bar_height_hook = ns_change_tab_bar_height;
|
||||
/* Other hooks are NULL by default. */
|
||||
|
||||
return terminal;
|
||||
@ -6675,7 +6675,27 @@ - (void)mouseDown: (NSEvent *)theEvent
|
||||
}
|
||||
else
|
||||
{
|
||||
emacs_event->kind = MOUSE_CLICK_EVENT;
|
||||
Lisp_Object tab_bar_arg = Qnil;
|
||||
bool tab_bar_p = false;
|
||||
|
||||
if (WINDOWP (emacsframe->tab_bar_window)
|
||||
&& WINDOW_TOTAL_LINES (XWINDOW (emacsframe->tab_bar_window)))
|
||||
{
|
||||
Lisp_Object window;
|
||||
int x = lrint (p.x);
|
||||
int y = lrint (p.y);
|
||||
|
||||
window = window_from_coordinates (emacsframe, x, y, 0, true, true);
|
||||
tab_bar_p = EQ (window, emacsframe->tab_bar_window);
|
||||
|
||||
if (tab_bar_p)
|
||||
tab_bar_arg = handle_tab_bar_click (emacsframe, x, y, EV_UDMODIFIERS (theEvent) & down_modifier,
|
||||
EV_MODIFIERS (theEvent) | EV_UDMODIFIERS (theEvent));
|
||||
}
|
||||
|
||||
if (!(tab_bar_p && NILP (tab_bar_arg)))
|
||||
emacs_event->kind = MOUSE_CLICK_EVENT;
|
||||
emacs_event->arg = tab_bar_arg;
|
||||
emacs_event->code = EV_BUTTON (theEvent);
|
||||
emacs_event->modifiers = EV_MODIFIERS (theEvent)
|
||||
| EV_UDMODIFIERS (theEvent);
|
||||
|
25
src/window.c
25
src/window.c
@ -765,6 +765,19 @@ selected one. */)
|
||||
{
|
||||
return make_fixnum (decode_live_window (window)->use_time);
|
||||
}
|
||||
|
||||
DEFUN ("window-bump-use-time", Fwindow_bump_use_time,
|
||||
Swindow_bump_use_time, 0, 1, 0,
|
||||
doc: /* Mark WINDOW as having been most recently used.
|
||||
WINDOW must be a live window and defaults to the selected one. */)
|
||||
(Lisp_Object window)
|
||||
{
|
||||
struct window *w = decode_live_window (window);
|
||||
|
||||
w->use_time = ++window_select_count;
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
DEFUN ("window-pixel-width", Fwindow_pixel_width, Swindow_pixel_width, 0, 1, 0,
|
||||
doc: /* Return the width of window WINDOW in pixels.
|
||||
@ -8122,18 +8135,6 @@ and scrolling positions. */)
|
||||
return Qt;
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
DEFUN ("window-bump-use-time", Fwindow_bump_use_time,
|
||||
Swindow_bump_use_time, 1, 1, 0,
|
||||
doc: /* Mark WINDOW as having been recently used. */)
|
||||
(Lisp_Object window)
|
||||
{
|
||||
struct window *w = decode_valid_window (window);
|
||||
|
||||
w->use_time = ++window_select_count;
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void init_window_once_for_pdumper (void);
|
||||
|
12
src/xdisp.c
12
src/xdisp.c
@ -33780,7 +33780,13 @@ note_mouse_highlight (struct frame *f, int x, int y)
|
||||
if (EQ (window, f->tab_bar_window))
|
||||
{
|
||||
note_tab_bar_highlight (f, x, y);
|
||||
return;
|
||||
if (tab_bar_drag_maybe)
|
||||
{
|
||||
cursor = FRAME_OUTPUT_DATA (f)->hand_cursor;
|
||||
goto set_cursor;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -35910,6 +35916,10 @@ When nil, mouse-movement events will not be generated as long as the
|
||||
mouse stays within the extent of a single glyph (except for images). */);
|
||||
mouse_fine_grained_tracking = false;
|
||||
|
||||
DEFVAR_BOOL ("tab-bar-drag-maybe", tab_bar_drag_maybe,
|
||||
doc: /* Non-nil when maybe dragging tab bar item. */);
|
||||
tab_bar_drag_maybe = false;
|
||||
|
||||
DEFVAR_BOOL ("redisplay-skip-initial-frame", redisplay_skip_initial_frame,
|
||||
doc: /* Non-nil to skip redisplay in initial frame.
|
||||
The initial frame is not displayed anywhere, so skipping it is
|
||||
|
@ -124,6 +124,11 @@ gcc version 2.95.2 19991024 (release)"
|
||||
"Test the output parser against the machine currently running Emacs."
|
||||
(skip-unless (executable-find "gcc"))
|
||||
(let ((semantic-gcc-test-strings (list (semantic-gcc-query "gcc" "-v"))))
|
||||
(semantic-gcc-test-output-parser)))
|
||||
;; Some macOS machines run llvm when you type gcc. (!)
|
||||
;; We can't even check if it's a symlink; it's a binary placed in
|
||||
;; "/usr/bin/gcc". So check the output and just skip this test if
|
||||
;; it says "Apple LLVM".
|
||||
(unless (string-match "Apple LLVM" (car semantic-gcc-test-strings))
|
||||
(semantic-gcc-test-output-parser))))
|
||||
|
||||
;;; gcc-tests.el ends here
|
||||
|
Loading…
Reference in New Issue
Block a user