From: Juri Linkov <juri@linkov.net>
To: Glenn Morris <rgm@gnu.org>
Cc: Javier Olaechea <pirata@gmail.com>, 41691@debbugs.gnu.org
Subject: bug#41691: [PATCH] Add bookmark-jump-other-tab
Date: Fri, 05 Jun 2020 02:34:23 +0300 [thread overview]
Message-ID: <87y2p2gzvs.fsf@mail.linkov.net> (raw)
In-Reply-To: <87bllzvjov.fsf@mail.linkov.net> (Juri Linkov's message of "Thu, 04 Jun 2020 02:00:32 +0300")
[-- Attachment #1: Type: text/plain, Size: 1037 bytes --]
>> Personally I hope that every "-other-window" command doesn't get an
>> "-other-tab" counterpart (to go along with "-other-frame"), but rather
>> that a single systematic method is developed, like the elpa.gnu.org
>> package other-frame-window. Ref eg
>>
>> https://lists.gnu.org/r/emacs-devel/2019-10/msg00261.html
>>
>> (AFAICS nothing has been implemented)
>
> Actually, this is already implemented, but without an obvious keybinding.
> This small patch binds a general command to 'C-x t t' (or maybe a better
> key would be 'C-x t w').
>
> Then after typing 'C-x t t' as a prefix key sequence,
> the next command will display its buffer in a new tab:
>
> @@ -1585,6 +1585,7 @@ tab-prefix-map
> (define-key tab-prefix-map "b" 'switch-to-buffer-other-tab)
> (define-key tab-prefix-map "f" 'find-file-other-tab)
> (define-key tab-prefix-map "\C-f" 'find-file-other-tab)
> +(define-key tab-prefix-map "t" 'windmove-display-new-tab)
I see that using windmove-display-new-tab in tab-bar.el is inappropriate,
so here is refactoring:
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: other-tab-prefix.patch --]
[-- Type: text/x-diff, Size: 8667 bytes --]
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index 76e7f8c33a..dd9d520ed9 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -1575,6 +1575,21 @@ find-file-other-tab
value)
(switch-to-buffer-other-tab value))))
+(defun other-tab-prefix ()
+ "Display the next buffer in a new tab.
+The next buffer is the buffer displayed by the next command invoked
+immediately after this command (ignoring reading from the minibuffer).
+Creates a new tab before displaying the buffer.
+When `switch-to-buffer-obey-display-actions' is non-nil,
+`switch-to-buffer' commands are also supported."
+ (interactive)
+ (display-buffer-override-next-command
+ (lambda (buffer alist)
+ (cons (let ((tab-bar-new-tab-choice t))
+ (tab-bar-new-tab)
+ (selected-window))
+ 'tab))))
+
(define-key tab-prefix-map "2" 'tab-new)
(define-key tab-prefix-map "1" 'tab-close-other)
(define-key tab-prefix-map "0" 'tab-close)
@@ -1585,6 +1600,7 @@ tab-prefix-map
(define-key tab-prefix-map "b" 'switch-to-buffer-other-tab)
(define-key tab-prefix-map "f" 'find-file-other-tab)
(define-key tab-prefix-map "\C-f" 'find-file-other-tab)
+(define-key tab-prefix-map "t" 'other-tab-prefix)
\f
(provide 'tab-bar)
diff --git a/lisp/window.el b/lisp/window.el
index d658cb81f6..3f851c86f4 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -10069,6 +10069,46 @@ window--adjust-process-windows
(set-process-window-size process (cdr size) (car size))))))))))
(add-hook 'window-configuration-change-hook 'window--adjust-process-windows)
+
+\f
+(defun display-buffer-override-next-command (action-function &optional exit-function)
+ "Override `display-buffer-overriding-action' for the next command.
+`action-function' is called to prepare the window where the buffer should
+be displayed. This function takes two arguments `buffer' and `alist', and
+should return a cons with the displayed window and type. See argument
+meaning in `window--display-buffer'. `exit-function' is called after the
+buffer is displayed in the window. The function takes one argument `window'."
+ (let* ((new-window)
+ (minibuffer-depth (minibuffer-depth))
+ (action (lambda (buffer alist)
+ (unless (> (minibuffer-depth) minibuffer-depth)
+ (let* ((ret (funcall action-function buffer alist))
+ (window (car ret))
+ (type (cdr ret)))
+ (setq new-window (window--display-buffer buffer window
+ type alist))))))
+ (command this-command)
+ (clearfun (make-symbol "clear-display-buffer-overriding-action"))
+ (exitfun
+ (lambda ()
+ (setq display-buffer-overriding-action
+ (delq action display-buffer-overriding-action))
+ (when (functionp exit-function)
+ (funcall exit-function new-window))
+ (remove-hook 'post-command-hook clearfun))))
+ (fset clearfun
+ (lambda ()
+ (unless (or
+ ;; Remove the hook immediately
+ ;; after exiting the minibuffer.
+ (> (minibuffer-depth) minibuffer-depth)
+ ;; But don't remove immediately after
+ ;; adding the hook by the same command below.
+ (eq this-command command))
+ (funcall exitfun))))
+ (add-hook 'post-command-hook clearfun)
+ (push action display-buffer-overriding-action)))
+
\f
;; Some of these are in tutorial--default-keys, so update that if you
;; change these.
diff --git a/lisp/windmove.el b/lisp/windmove.el
index f96383197b..38e3fee83a 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -462,59 +462,38 @@ windmove-display-in-direction
When `switch-to-buffer-obey-display-actions' is non-nil,
`switch-to-buffer' commands are also supported."
(let* ((no-select (xor (consp arg) windmove-display-no-select))
- (old-window (or (minibuffer-selected-window) (selected-window)))
- (new-window)
- (minibuffer-depth (minibuffer-depth))
- (action (lambda (buffer alist)
- (unless (> (minibuffer-depth) minibuffer-depth)
- (let* ((type 'reuse)
- (window (cond
- ((eq dir 'new-tab)
- (let ((tab-bar-new-tab-choice t))
- (tab-bar-new-tab))
- (setq type 'tab)
- (selected-window))
- ((eq dir 'new-frame)
- (let* ((params (cdr (assq 'pop-up-frame-parameters alist)))
- (pop-up-frame-alist (append params pop-up-frame-alist))
- (frame (make-frame-on-current-monitor
- pop-up-frame-alist)))
- (unless (cdr (assq 'inhibit-switch-frame alist))
- (window--maybe-raise-frame frame))
- (setq type 'frame)
- (frame-selected-window frame)))
- ((eq dir 'same-window)
- (selected-window))
- (t (window-in-direction
- dir nil nil
- (and arg (prefix-numeric-value arg))
- windmove-wrap-around)))))
- (unless window
- (setq window (split-window nil nil dir) type 'window))
- (setq new-window (window--display-buffer buffer window
- type alist))))))
- (command this-command)
- (clearfun (make-symbol "clear-display-buffer-overriding-action"))
- (exitfun
- (lambda ()
- (setq display-buffer-overriding-action
- (delq action display-buffer-overriding-action))
- (when (window-live-p (if no-select old-window new-window))
- (select-window (if no-select old-window new-window)))
- (remove-hook 'post-command-hook clearfun))))
- (fset clearfun
- (lambda ()
- (unless (or
- ;; Remove the hook immediately
- ;; after exiting the minibuffer.
- (> (minibuffer-depth) minibuffer-depth)
- ;; But don't remove immediately after
- ;; adding the hook by the same command below.
- (eq this-command command))
- (funcall exitfun))))
- (add-hook 'post-command-hook clearfun)
- (push action display-buffer-overriding-action)
- (message "[display-%s]" dir)))
+ (old-window (or (minibuffer-selected-window) (selected-window))))
+ (display-buffer-override-next-command
+ (lambda (buffer alist)
+ (let* ((type 'reuse)
+ (window (cond
+ ((eq dir 'new-tab)
+ (let ((tab-bar-new-tab-choice t))
+ (tab-bar-new-tab))
+ (setq type 'tab)
+ (selected-window))
+ ((eq dir 'new-frame)
+ (let* ((params (cdr (assq 'pop-up-frame-parameters alist)))
+ (pop-up-frame-alist (append params pop-up-frame-alist))
+ (frame (make-frame-on-current-monitor
+ pop-up-frame-alist)))
+ (unless (cdr (assq 'inhibit-switch-frame alist))
+ (window--maybe-raise-frame frame))
+ (setq type 'frame)
+ (frame-selected-window frame)))
+ ((eq dir 'same-window)
+ (selected-window))
+ (t (window-in-direction
+ dir nil nil
+ (and arg (prefix-numeric-value arg))
+ windmove-wrap-around)))))
+ (unless window
+ (setq window (split-window nil nil dir) type 'window))
+ (cons window type)))
+ (lambda (new-window)
+ (when (window-live-p (if no-select old-window new-window))
+ (select-window (if no-select old-window new-window))))))
+ (message "[display-%s]" dir))
;;;###autoload
(defun windmove-display-left (&optional arg)
next prev parent reply other threads:[~2020-06-04 23:34 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-03 16:39 bug#41691: [PATCH] Add bookmark-jump-other-tab Javier Olaechea
2020-06-03 17:16 ` Glenn Morris
2020-06-03 23:00 ` Juri Linkov
2020-06-04 23:34 ` Juri Linkov [this message]
2020-06-06 23:42 ` Juri Linkov
2020-06-07 1:40 ` Javier Olaechea
2020-06-10 21:50 ` Juri Linkov
2020-06-21 23:18 ` Juri Linkov
2020-06-22 15:06 ` Eli Zaretskii
2020-06-28 22:00 ` Juri Linkov
2020-06-29 14:35 ` Eli Zaretskii
2020-06-29 22:52 ` Juri Linkov
2020-06-30 21:30 ` Juri Linkov
2020-07-01 14:34 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87y2p2gzvs.fsf@mail.linkov.net \
--to=juri@linkov.net \
--cc=41691@debbugs.gnu.org \
--cc=pirata@gmail.com \
--cc=rgm@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).