I would like to share a code snippet designed to simplify the task of opening Vertico/Consult/Embark or Ivy/Counsel candidates in a new Emacs tab.
The generic function that opens candidates in a new tab
This function below, tab-new-func-buffer-from-other-window
, is designed to open the buffer generated by a specified function (func) in the other window and subsequently create a new tab. It also ensures that the state of the original window and tab is preserved.
;; License: MIT
;; Author: James Cherti
;; Latest version: https://www.jamescherti.com/emacs-open-vertico-consult-ivy-counsel-candidate-new-tab/
(defun tab-new-func-buffer-from-other-window (func)
"Open the buffer created by the FUNC function in the other window in a new tab."
(let* ((original-tab-index (1+ (tab-bar--current-tab-index)))
(original-window (selected-window)))
;; Save the state of the other window
(other-window 1)
(let* ((other-window (selected-window))
(other-window-buf (current-buffer))
(other-window-point (point))
(other-window-view (window-start)))
;; Move back to the original window
(other-window -1)
;; Call the specified function (e.g., embark-dwim, ivy-call...)
(funcall func)
;; Switch back to the other window
(other-window 1)
(unless (eq (selected-window) original-window)
(let* ((preview-buf (current-buffer)))
;; Create a new tab and switch to the preview buffer
(tab-bar-new-tab)
(switch-to-buffer preview-buf)
;; Go back to the original tab
(tab-bar-select-tab original-tab-index)
;; Restore the state of the other window
(select-window other-window)
(switch-to-buffer other-window-buf)
(goto-char other-window-point)
(set-window-start nil other-window-view)
;; Switch to the original window
(select-window original-window))))))
Option 1: Open Vertico, Consult, and Embark candidate in a new tab (embark-dwim)
For users of Vertico/Consult/Embark, the following function utilizes the generic function tab-new-func-buffer-from-other-window
to open the default Embark action buffer in a new tab:
(defun tab-new-embark-dwim ()
"Open embark-dwim in a new tab."
(interactive)
(tab-new-func-buffer-from-other-window #'embark-dwim))
You can add the following key mapping to Vertico:
(keymap-set vertico-map "C-t" #'tab-new-embark-dwim)
For Emacs Evil users, you can also add the following mappings:
(evil-define-key '(insert normal) vertico-map (kbd "C-t") 'tab-new-embark-dwim)
Option 2: Open Ivy, Counsel candidates in a new tab (ivy-call)
For users of Counsel/Ivy, the following function utilizes the generic function tab-new-func-buffer-from-other-window
to open the buffer opened by ivy-call
in a new tab:
(defun tab-new-ivy-call ()
"Open ivy-call in a new tab."
(interactive)
(tab-new-func-buffer-from-other-window #'ivy-call))
You can add the following key mapping to ivy-minibuffer-map:
(keymap-set ivy-minibuffer-map "C-t" #'tab-new-ivy-call)
For Emacs Evil users, you can also add the following mappings:
(evil-define-key '(insert normal) ivy-minibuffer-map (kbd "C-t") 'tab-new-ivy-call)
Links