Skip to content

Switching tabs via frog menu

Colin McLear edited this page Oct 27, 2022 · 1 revision

Courtesy of EFLS (see issue #19). Use frog-menu, which pops up a posframe and uses avy keys to select a candidate. More on frog-menu here: https://elpa.gnu.org/packages/frog-menu.html

In short: the code below allows to (1) pop-up a list of tabs in a posframe, and (2) switch to a tab by typing a single key (based on the first letter of the key). It takes inspiration from https://github.com/waymondo/frog-jump-buffer.

(require 'frog-menu)

(defun efls/frog-tab ()
  "Pick a tab to switch to via `frog-menu'."
  (interactive)
  (let* ((frog-menu-avy-padding t)
         (frog-menu-min-col-padding 1)
         (frog-menu-display-option-alist
          '((avy-posframe . posframe-poshandler-frame-center)
            (avy-side-window display-buffer-in-side-window (side . bottom))))
         (prompt "Switch tab")
         (tabs (mapcar (lambda (tab) (alist-get 'name tab))
                       (tab-bar-tabs)))
         (frog-menu-avy-keys (efls/frog-tabs-generate-keys tabs))
         (actions '(("C-l" "List tabs"
                      (call-interactively tabspaces-switch-or-create-workspace))))
         (res (frog-menu-read prompt tabs actions)))
    (if (stringp res)
        (progn (message res)
               (tabspaces-switch-or-create-workspace res))
      (apply res))))

Generating the keys for switching perspectives is done via a separate function.

(defun efls/frog-tabs-generate-keys (tabs)
  "Generate keys for TABS (a list of tab names).
Returns a list of first chars from each tab. If two chars are
identical, make second capitalized. If more chars than two are
identical, then... nothing else."
  (let ((new-chars))
    (dolist (char (-map (lambda (s) (string (string-to-char s)))
                        tabs))
      (if (member char new-chars)
          (setq new-chars (append new-chars (list (capitalize char))))
        (setq new-chars (append new-chars (list char)))))
    (-map 'string-to-char new-chars)))

It works as follows:

  • Create a list of tab names.
  • Construct a list of strings with first character of each tab name.
  • Make a new list where each repetition of a char is capitalized.
  • Turn that list of strings into a list of characters.

There are potential issues:

  • when more than two tab names start with the same character
  • when a tab name starts with something other than an alphabetic character
Clone this wiki locally