#org-mode #emacs #doom #claude #ai

Tabs in emacs doom with centaur and vertical mode

Moving files around of the screen with emacs and vertical sidebar


Introduction

preview

Time ago i was moved right into vertical mode with browsers, i think its a productive tool that i did notice at the beggining, but i continuesly for debug and create code i ended like 30/50 tabs open for some reason, so i close all of them right after is not showing in the main screen, don't scroll on top of the browsers to do it. well then the solution appears: vertical mode tabs.

Develop

i was started with chromium based browsers and take chrome as default, another features looks good on firefox, safari, brave. then notice as something happens on emacs doom, it was by accident and see a post on reedit, related to sidebar tabs on emacs, that blow completely my mind so, ive decided to build my own, and why not do it with AI small piece of code, generation on a language which is elisp, also i read implementation to be able to describe and guide on complete tool criteria. ive configured on tree files configuraion of doom emacs, that will depends on your path

doom.d/init.el # configuration on support: tabs package

Added following code snippets that met some of criteria described.

  • `SPC t S` <- Capital `S`
(after! centaur-tabs
  (centaur-tabs-mode t)
  (setq centaur-tabs-buffer-groups-function
        #'centaur-tabs-projectile-buffer-groups)

  ;; ── Hide the top tab bar ────────────────────────────────
  (centaur-tabs-mode -1)

  ;; ── Sidebar keymap defined once, outside refresh ────────
  (defvar my/tab-sidebar-map (make-sparse-keymap))
  (evil-define-key 'normal my/tab-sidebar-map (kbd "q")
    (lambda ()
      (interactive)
      (let ((win (get-buffer-window "*Tab Sidebar*")))
        (when win (delete-window win)))))

  (defun my/centaur-tabs-sidebar-refresh (&optional source-buf)
    "Build *Tab Sidebar* showing ALL centaur-tabs groups and their buffers."
    (let* ((sidebar-buf  (get-buffer-create "*Tab Sidebar*"))
           (current-buf  (or source-buf (window-buffer (selected-window))))
           (all-buffers  (centaur-tabs-buffer-list))
           (groups       (make-hash-table :test 'equal)))

      (dolist (buf all-buffers)
        (with-current-buffer buf
          (let ((group (car (funcall centaur-tabs-buffer-groups-function))))
            (puthash group
                     (append (gethash group groups) (list buf))
                     groups))))

      (with-current-buffer sidebar-buf
        (let ((inhibit-read-only t))
          (erase-buffer)
          (if (hash-table-empty-p groups)
              (insert (propertize "  No tabs found.\n"
                                  'face '(:foreground "#5b6268")))
            (maphash
             (lambda (group-name buffers)
               (insert (propertize (format " ⬡ %s\n" group-name)
                                   'face '(:foreground "#c678dd"
                                           :weight bold)))
               (dolist (buf buffers)
                 (let* ((name     (buffer-name buf))
                        (active   (eq buf current-buf))
                        (modified (and (buffer-file-name buf)
                                       (buffer-modified-p buf)))
                        (start    (point)))
                   (insert (if active
                               (propertize (format "  ▶ %s%s\n" name
                                                   (if modified " ●" ""))
                                           'face '(:foreground "#51afef"
                                                   :weight bold))
                             (propertize (format "    %s%s\n" name
                                                 (if modified " ●" ""))
                                         'face '(:foreground "#bbc2cf"))))
                   (make-text-button start (1- (point))
                                     'action `(lambda (_)
                                                (let ((target-win
                                                       (cl-find-if
                                                        (lambda (w)
                                                          (and (not (equal w (get-buffer-window "*Tab Sidebar*")))
                                                               (not (window-parameter w 'window-side))))
                                                        (window-list))))
                                                  (when target-win
                                                    (select-window target-win))
                                                  (switch-to-buffer ,buf)
                                                  (let ((sidebar-win (get-buffer-window "*Tab Sidebar*")))
                                                    (when sidebar-win
                                                      (delete-window sidebar-win)))))
                                     'follow-link t)))
               (insert (propertize "  ─────────────────\n"
                                   'face '(:foreground "#3d4451"))))
             groups))

          (insert (propertize "\n  [q] close sidebar\n"
                              'face '(:foreground "#5b6268" :slant italic)))
          (setq buffer-read-only t))

        ;; ── Apply the pre-defined keymap ────────────────────
        (use-local-map my/tab-sidebar-map))
      sidebar-buf))

  (defun my/toggle-centaur-tabs-sidebar ()
    (interactive)
    (let ((win (get-buffer-window "*Tab Sidebar*")))
      (if win
          (delete-window win)
        (let* ((src         (current-buffer))
               (buf         (my/centaur-tabs-sidebar-refresh src))
               (sidebar-win (display-buffer-in-side-window
                             buf
                             '((side         . left)
                               (slot         . 0)
                               (window-width . 30)
                               (window-parameters
                                . ((no-delete-other-windows . t)
                                   (no-other-window         . t)))))))
          (when sidebar-win
            (select-window sidebar-win))))))

  (add-hook 'buffer-list-update-hook
            (lambda ()
              (when (get-buffer-window "*Tab Sidebar*")
                (let ((real-buf (window-buffer (selected-window))))
                  (unless (string= (buffer-name real-buf) "*Tab Sidebar*")
                    (my/centaur-tabs-sidebar-refresh real-buf))))))

  (map! :leader :desc "Toggle tab sidebar" "t S" #'my/toggle-centaur-tabs-sidebar))

Functionality on emacs tabs vertical mode

with `SPC t S` it open vertical mode tabs

  • grouped by project open
  • show all buffers opened and searcheable with `evil-mode`
  • possibility to close with `q`

Conclusion

Generate this help me to navigate throght the code of multiple projects and use either format to different languages edits. maybe ill taking a look better for tag in emacs to reference files in org mode. a fun tool that im using

Links

https://github.com/ema2159/centaur-tabs https://github.com/doomemacs/doomemacs https://www.reddit.com/r/emacs/comments/1sy8yon/sidetabs_using_side_windows/