Date Series Part 1 of Emacs for writers Tags emacs / org-mode

For a very long time I've had a major problem with tabbar and tabbar-ruler. Tabbar-ruler was very good... except it clobbered my Messages file so that if I wanted to see the word count of the document that I was then working on, there was every chance that I might miss it, and without a working Messages file I was stuffed!

But I found out that if I didn't use tabbar-ruler I could manage very easily, if not better, using just plain old tabbar. So this is how I've done it...

(require 'tabbar)
(tabbar-mode t)

(defun tabbar-buffer-groups-by-dir ()
        "Put all files in the same directory into the same tab bar"
        (with-current-buffer (current-buffer)
          (let ((dir (expand-file-name default-directory)))
            (cond ;; assign group name until one clause succeeds, so the order is important
             ((eq major-mode 'dired-mode)
              (list "Dired"))
             ((memq major-mode
                    '(help-mode apropos-mode Info-mode Man-mode))
              (list "Help"))
             ((string-match-p "\*.*\*" (buffer-name))
              (list "Misc"))
             (t (list dir))))))

(defun tabbar-switch-grouping-method (&optional arg)
  "Changes grouping method of tabbar to grouping by dir.
With a prefix arg, changes to grouping by major mode."
  (interactive "P")
  (ignore-errors
    (if arg
      (setq tabbar-buffer-groups-function 'tabbar-buffer-groups) ;; the default setting
        (setq tabbar-buffer-groups-function 'tabbar-buffer-groups-by-dir))))

This is the basic setup, just the bare bones to hang everything else on, and is taken from 1

(setq tabbar-cycle-scope (quote tabs))
(setq table-time-before-update 0.1)
(setq tabbar-use-images 0)

Again from the same source as 1

(setq tabbar-background-color "gray12") ;; the color of the tabbar background
(custom-set-faces
;; '(tabbar-default ((t (:inherit variable-pitch :background "#959A79" :foreground "black" :weight bold))))
 '(tabbar-default ((t (:inherit variable-pitch :background "gray12" :foreground "gainsboro"))))
 '(tabbar-button ((t (:inherit tabbar-default :foreground "dark red"))))
 '(tabbar-button-highlight ((t (:inherit tabbar-default))))
 '(tabbar-highlight ((t (:underline t))))
 '(tabbar-selected ((t (:inherit tabbar-default :background "gainsboro" :foreground "gray12"))))
 '(tabbar-separator ((t (:inherit tabbar-default :background "red"))))
 '(tabbar-unselected ((t (:inherit tabbar-default)))))

This sets the colour of the tabs, to blend in with my theme 2

(advice-add 'tabbar-buffer-tab-label :before-until
   (lambda (tab)
    (with-current-buffer (buffer-name (tabbar-tab-value tab))
    (when (equal major-mode 'org-agenda-mode)
           "Agenda"))))

 ;; Add a buffer modification state indicator in the tab label, and place a
    ;; space around the label to make it looks less crowd.
    (defadvice tabbar-buffer-tab-label (after fixup_tab_label_space_and_flag activate)
      (setq ad-return-value
            (if (and (buffer-modified-p (tabbar-tab-value tab))
                     (buffer-file-name (tabbar-tab-value tab)))
                (concat " + " (concat ad-return-value " "))
              (concat " " (concat ad-return-value " ")))))

    ;; Called each time the modification state of the buffer changed.
    (defun ztl-modification-state-change ()
      (tabbar-set-template tabbar-current-tabset nil)
      (tabbar-display-update))

    ;; First-change-hook is called BEFORE the change is made.
    (defun ztl-on-buffer-modification ()
      (set-buffer-modified-p t)
      (ztl-modification-state-change))
    (add-hook 'after-save-hook 'ztl-modification-state-change)

    ;; This doesn't work for revert, I don't know.
    ;;(add-hook 'after-revert-hook 'ztl-modification-state-change)
    (add-hook 'first-change-hook 'ztl-on-buffer-modification)

I'm not too sure what this does, but it works 3

(global-set-key (kbd "s-/") 'kill-this-buffer)

This one I've found is very useful and is used quite frequently.

(defun tabbar-move-current-tab-one-place-left ()
      "Move current tab one place left, unless it's already the leftmost."
      (interactive)
      (let* ((bufset (tabbar-current-tabset t))
             (old-bufs (tabbar-tabs bufset))
             (first-buf (car old-bufs))
             (new-bufs (list)))
        (if (string= (buffer-name) (format "%s" (car first-buf)))
            old-bufs ; the current tab is the leftmost
          (setq not-yet-this-buf first-buf)
          (setq old-bufs (cdr old-bufs))
          (while (and
                  old-bufs
                  (not (string= (buffer-name) (format "%s" (car (car old-bufs))))))
            (push not-yet-this-buf new-bufs)
            (setq not-yet-this-buf (car old-bufs))
            (setq old-bufs (cdr old-bufs)))
          (if old-bufs ; if this is false, then the current tab's buffer name is mysteriously missing
              (progn
                (push (car old-bufs) new-bufs) ; this is the tab that was to be moved
                (push not-yet-this-buf new-bufs)
                (setq new-bufs (reverse new-bufs))
                (setq new-bufs (append new-bufs (cdr old-bufs))))
            (error "Error: current buffer's name was not found in Tabbar's buffer list."))
          (set bufset new-bufs)
          (tabbar-set-template bufset nil)
          (tabbar-display-update))))

And this is used for moving the tab to the left, one tab at a time, and comes from here 4.

(defun tabbar-move-current-tab-one-place-right ()
      "Move current tab one place right, unless it's already the rightmost."
      (interactive)
      (let* ((bufset (tabbar-current-tabset t))
             (old-bufs (tabbar-tabs bufset))
             (first-buf (car old-bufs))
             (new-bufs (list)))
        (while (and
                old-bufs
                (not (string= (buffer-name) (format "%s" (car (car old-bufs))))))
          (push (car old-bufs) new-bufs)
          (setq old-bufs (cdr old-bufs)))
        (if old-bufs ; if this is false, then the current tab's buffer name is mysteriously missing
            (progn
              (setq the-buffer (car old-bufs))
              (setq old-bufs (cdr old-bufs))
              (if old-bufs ; if this is false, then the current tab is the rightmost
                  (push (car old-bufs) new-bufs))
              (push the-buffer new-bufs)) ; this is the tab that was to be moved
          (error "Error: current buffer's name was not found in Tabbar's buffer list."))
        (setq new-bufs (reverse new-bufs))
        (setq new-bufs (append new-bufs (cdr old-bufs)))
        (set bufset new-bufs)
        (tabbar-set-template bufset nil)
        (tabbar-display-update)))

<!-- https://www.emacswiki.org/emacs/TabBarMode -->

;; Key sequences "C-S-PgUp" and "C-S-PgDn" move the current tab to the left and to the right.
(global-set-key (kbd "s-[") 'tabbar-move-current-tab-one-place-left)
(global-set-key (kbd "s-]") 'tabbar-move-current-tab-one-place-right)

<!-- https://www.emacswiki.org/emacs/TabBarMode -->

(define-key global-map (kbd "<s-prior>") 'tabbar-backward)
(define-key global-map (kbd "<s-next>") 'tabbar-forward)

<!-- https://amitp.blogspot.com/2018/10/emacs-prettier-tabbar.html -->
<!-- http://ergoemacs.org/emacs/emacs_key_combo.html -->

Now that is a fairly heft chunk of code, so lets see if I can break it up and make it more readable?



Comments

comments powered by Disqus