From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.bugs Subject: bug#41691: [PATCH] Add bookmark-jump-other-tab Date: Fri, 05 Jun 2020 02:34:23 +0300 Organization: LINKOV.NET Message-ID: <87y2p2gzvs.fsf@mail.linkov.net> References: <20200603163925.11161-1-pirata@gmail.com> <87bllzvjov.fsf@mail.linkov.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="24112"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (x86_64-pc-linux-gnu) Cc: Javier Olaechea , 41691@debbugs.gnu.org To: Glenn Morris Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Fri Jun 05 01:48:17 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jgzar-0006E3-2Z for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 05 Jun 2020 01:48:17 +0200 Original-Received: from localhost ([::1]:53892 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jgzap-0000q0-Jf for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 04 Jun 2020 19:48:15 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:49382) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jgzac-0000pQ-5E for bug-gnu-emacs@gnu.org; Thu, 04 Jun 2020 19:48:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:36303) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jgzab-0007LJ-OS for bug-gnu-emacs@gnu.org; Thu, 04 Jun 2020 19:48:01 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1jgzab-0006bA-MY for bug-gnu-emacs@gnu.org; Thu, 04 Jun 2020 19:48:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Juri Linkov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 04 Jun 2020 23:48:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 41691 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 41691-submit@debbugs.gnu.org id=B41691.159131443125306 (code B ref 41691); Thu, 04 Jun 2020 23:48:01 +0000 Original-Received: (at 41691) by debbugs.gnu.org; 4 Jun 2020 23:47:11 +0000 Original-Received: from localhost ([127.0.0.1]:47849 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jgzZm-0006a5-Qm for submit@debbugs.gnu.org; Thu, 04 Jun 2020 19:47:11 -0400 Original-Received: from relay9-d.mail.gandi.net ([217.70.183.199]:41001) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jgzZl-0006Zq-Cs for 41691@debbugs.gnu.org; Thu, 04 Jun 2020 19:47:10 -0400 X-Originating-IP: 91.129.108.6 Original-Received: from mail.gandi.net (m91-129-108-6.cust.tele2.ee [91.129.108.6]) (Authenticated sender: juri@linkov.net) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id D92E2FF805; Thu, 4 Jun 2020 23:47:01 +0000 (UTC) In-Reply-To: <87bllzvjov.fsf@mail.linkov.net> (Juri Linkov's message of "Thu, 04 Jun 2020 02:00:32 +0300") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:181530 Archived-At: --=-=-= Content-Type: text/plain >> 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: --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=other-tab-prefix.patch 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) (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) + + +(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))) + ;; 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) --=-=-=--