Some buffer and performance changes. Spiffed up ibuffer.

This commit is contained in:
Micheal Smith
2025-12-11 05:42:32 -06:00
parent 3720739ca2
commit 79e0e7e405
7 changed files with 294 additions and 210 deletions

View File

@@ -218,8 +218,9 @@ Magic Hack) to handle this. It seems to work pretty well.
#+begin_src emacs-lisp
;; Garbage collection
(use-package gcmh
:ensure t
:hook (after-init . gcmh-mode)
:demand t
:init
(gcmh-mode)
:custom
(gcmh-idle-delay 'auto)
(gcmh-auto-idle-delay-factor 10))
@@ -383,18 +384,25 @@ There are a lot of solutions for editing files, and projects remotely. At the m
#+begin_src emacs-lisp
(use-feature tramp
:config
(setq tramp-ssh-controlmaster-options
(concat
"-o ControlPath=/tmp/ssh-ControlPath-%%r@%%h:%%p "
"-o ControlMaster=auto -o ControlPersist=yes"))
;; Enable full-featured Dirvish over TRAMP on ssh connections
;; https://www.gnu.org/software/tramp/#Improving-performance-of-asynchronous-remote-processes
(connection-local-set-profile-variables
'remote-direct-async-process
'((tramp-direct-async-process . t)))
(connection-local-set-profiles
'(:application tramp :protocol "ssh")
'(:application tramp :protocol "rsync")
'remote-direct-async-process)
(setq magit-tramp-pipe-stty-settings 'pty)
(with-eval-after-load 'compile
(remove-hook 'compilation-mode-hook #'tramp-compile-disable-ssh-controlmaster-options))
;; Tips to speed up connections
(setq tramp-verbose 0)
(setq tramp-chunksize 2000)
(setq tramp-ssh-controlmaster-options nil))
(setq tramp-copy-size-limit nil))
#+end_src
* Blocks, Parentheses and Formatting Oh My!
@@ -803,213 +811,132 @@ _SPC_ cancel _o_nly this _d_elete
<<window-hydra>>)
#+end_src
* Buferlo
# #+INCLUDE: "config/bufferlo.org" :minlevel 1
* IBuffer
The package itself sums it up best.
Buffer management is a constant irritation with any editor. After
having a bit of a performance issue when using [[https://github.com/florommel/bufferlo][bufferlo]] I've decided
to try doing something with emacs's built in IBuffer.
#+begin_quote
Easy-to-use buffer management and workspace persistence tools for Emacs workflow management.
Headbutt your way to productivity and moove ahead with [[https://github.com/florommel/bufferlo][bufferlo]].
#+end_quote
This is *heavily* inspired, and mostly outright copied from this [[https://olddeuteronomy.github.io/post/emacs-ibuffer-config/][post]]
by [[https://olddeuteronomy.github.io][The Emacs Cat]].
This is great for keeping tabs seperate.
Icons can make identifying buffers easy at a glance so I think adding
them is pretty handy.
#+begin_src emacs-lisp
;; Bufferlo package configuration
(use-package bufferlo
(use-package all-the-icons-ibuffer
:ensure t
:demand t
:after (consult orderless)
:after (all-the-icons)
:hook
(ibuffer-mode . all-the-icons-ibuffer-mode))
#+end_src
Now for the main part of the configuration. This provides a nice
logical grouping for buffers. As I use this more I might change
the grouping to be a bit less file type oriented, and lean more
towards use case.
#+begin_src emacs-lisp
(use-package ibuffer :ensure nil
:bind
;; Main transient menu binding
(("C-x B" . bufferlo-transient)) ; Capital B to avoid conflict with switch-to-buffer
:init
;; These must be set before bufferlo is loaded
(setq bufferlo-menu-bar-show t)
(setq bufferlo-menu-bar-list-buffers 'ibuffer)
(setq bufferlo-prefer-local-buffers 'tabs)
(setq bufferlo-ibuffer-bind-local-buffer-filter t)
(setq bufferlo-ibuffer-bind-keys t)
(("C-x B" . ibuffer))
:config
;; Enable bufferlo mode
(bufferlo-mode 1)
;; Optional: Enable bufferlo-anywhere mode for local buffer lists everywhere
(bufferlo-anywhere-mode 1)
;; Mode-line configuration
(setq bufferlo-mode-line-prefix "🐃")
(setq bufferlo-mode-line-set-active-prefix "")
(setq bufferlo-mode-line-frame-prefix "")
(setq bufferlo-mode-line-tab-prefix "")
(setq bufferlo-mode-line-left-prefix nil)
(setq bufferlo-mode-line-right-suffix nil)
;; Buffer management policies
(setq bufferlo-kill-buffers-prompt t)
(setq bufferlo-kill-modified-buffers-policy 'retain-modified-kill-without-file-name)
(setq bufferlo-delete-frame-kill-buffers-prompt t)
(setq bufferlo-close-tab-kill-buffers-prompt t)
;; Bookmark configuration
(setq bufferlo-bookmark-frame-save-on-delete 'when-bookmarked)
(setq bufferlo-bookmark-tab-save-on-close 'when-bookmarked)
(setq bufferlo-bookmark-frame-load-make-frame 'restore-geometry)
(setq bufferlo-bookmark-frame-load-policy 'prompt)
(setq bufferlo-bookmark-frame-duplicate-policy 'prompt)
(setq bufferlo-bookmark-tab-replace-policy 'new)
(setq bufferlo-bookmark-tab-duplicate-policy 'prompt)
(setq bufferlo-bookmarks-save-duplicates-policy 'prompt)
;; Auto-save configuration (optional - adjust interval as needed)
(setopt bufferlo-bookmarks-auto-save-interval (* 60 5)) ; 5 minutes
(setq bufferlo-bookmarks-auto-save-messages 'saved)
;; Filter configuration for bookmark saving
(setq bufferlo-bookmark-buffers-exclude-filters
(list
(rx bos " " (1+ anything)) ; ignores "invisible" buffers
(rx bos "*" (1+ anything) "*"))) ; ignores "special" buffers
(setq bufferlo-bookmark-buffers-include-filters
(list
(rx bos "*shell*")
(rx bos "*" (1+ anything) "-shell*")
(rx bos "*eshell*")
(rx bos "*" (1+ anything) "-eshell*")))
;; New tabs start with scratch buffer
(setq tab-bar-new-tab-choice "*scratch*")
;; New frames start with scratch buffer
(add-hook 'after-make-frame-functions #'bufferlo-switch-to-scratch-buffer)
;; Consult integration
(defvar my:bufferlo-consult--source-local-buffers
(list :name "Bufferlo Local Buffers"
:narrow ?l
:category 'buffer
:face 'consult-buffer
:history 'buffer-name-history
:state #'consult--buffer-state
:default t
:items (lambda () (consult--buffer-query
:predicate #'bufferlo-local-buffer-p
:sort 'visibility
:as #'buffer-name)))
"Local Bufferlo buffer candidate source for `consult-buffer'.")
(defvar my:bufferlo-consult--source-other-buffers
(list :name "Bufferlo Other Buffers"
:narrow ?o
:category 'buffer
:face 'consult-buffer
:history 'buffer-name-history
:state #'consult--buffer-state
:items (lambda () (consult--buffer-query
:predicate #'bufferlo-non-local-buffer-p
:sort 'visibility
:as #'buffer-name)))
"Non-local Bufferlo buffer candidate source for `consult-buffer'.")
(defvar my:bufferlo-consult--source-all-buffers
(list :name "Bufferlo All Buffers"
:narrow ?a
:hidden t
:category 'buffer
:face 'consult-buffer
:history 'buffer-name-history
:state #'consult--buffer-state
:items (lambda () (consult--buffer-query
:sort 'visibility
:as #'buffer-name)))
"All Bufferlo buffer candidate source for `consult-buffer'.")
;; Add consult sources in reverse order of display preference
(add-to-list 'consult-buffer-sources 'my:bufferlo-consult--source-all-buffers)
(add-to-list 'consult-buffer-sources 'my:bufferlo-consult--source-other-buffers)
(add-to-list 'consult-buffer-sources 'my:bufferlo-consult--source-local-buffers))
;; Transient menu for bufferlo
(use-package transient
:ensure t
:after bufferlo
:config
(transient-define-prefix bufferlo-transient ()
"Bufferlo management menu."
["Buffer Management"
["Local Buffers"
("b" "Switch to buffer" bufferlo-switch-to-buffer)
("B" "List buffers" bufferlo-list-buffers)
("i" "Ibuffer (local)" bufferlo-ibuffer)]
["Buffer Operations"
("c" "Clear local list" bufferlo-clear)
("r" "Remove buffer" bufferlo-remove)
("k" "Kill local buffers" bufferlo-kill-buffers)
("K" "Kill orphan buffers" bufferlo-kill-orphan-buffers)]]
["Bookmarks"
["Frame Bookmarks"
("fs" "Save frame" bufferlo-bookmark-frame-save)
("fu" "Update frame" bufferlo-bookmark-frame-save-current)
("fl" "Load frame" bufferlo-bookmark-frame-load)
("fr" "Reload frame" bufferlo-bookmark-frame-load-current)
("fm" "Merge frame" bufferlo-bookmark-frame-load-merge)]
["Tab Bookmarks"
("ts" "Save tab" bufferlo-bookmark-tab-save)
("tu" "Update tab" bufferlo-bookmark-tab-save-current)
("tl" "Load tab" bufferlo-bookmark-tab-load)
("tr" "Reload tab" bufferlo-bookmark-tab-load-current)]]
["Bookmark Sets & Management"
["Sets"
("ss" "Save set" bufferlo-set-save-interactive)
("su" "Update set" bufferlo-set-save-current-interactive)
("sl" "Load set" bufferlo-set-load-interactive)
("sc" "Close set" bufferlo-set-close-interactive)
("sC" "Clear set" bufferlo-set-clear-interactive)
("sL" "List sets" bufferlo-set-list-interactive)]
["General"
("L" "Load bookmarks" bufferlo-bookmarks-load-interactive)
("S" "Save bookmarks" bufferlo-bookmarks-save-interactive)
("C" "Close bookmarks" bufferlo-bookmarks-close-interactive)
("R" "Raise bookmark" bufferlo-bookmark-raise)]]
["Navigation & Utilities"
["Navigation"
("/" "Find buffer" bufferlo-find-buffer)
("." "Find & switch" bufferlo-find-buffer-switch)
("o" "List orphans" bufferlo-list-orphan-buffers)
("O" "Ibuffer orphans" bufferlo-ibuffer-orphans)]
["Project"
("p" "Isolate project" bufferlo-isolate-project)]
["Frame/Tab Operations"
("d" "Delete frame & kill buffers" bufferlo-delete-frame-kill-buffers)
("x" "Close tab & kill buffers" bufferlo-tab-close-kill-buffers)]]
["Quick Actions"
("q" "Quit" transient-quit-one)
("<escape>" "Quit" transient-quit-one)]))
;; Optional: Additional helper functions for common workflows
(defun my/bufferlo-switch-project ()
"Switch to a project and isolate its buffers."
(interactive)
(call-interactively 'project-switch-project)
(bufferlo-isolate-project))
(defun my/bufferlo-new-workspace (name)
"Create a new tab with a specific bookmark name."
(interactive "sWorkspace name: ")
(tab-bar-new-tab)
(bufferlo-bookmark-tab-save name))
(defun my/bufferlo-switch-workspace ()
"Switch to a saved workspace (tab bookmark)."
(interactive)
(call-interactively 'bufferlo-bookmark-tab-load))
(setq ibuffer-expert t)
(setq ibuffer-display-summary nil)
(setq ibuffer-use-other-window nil)
(setq ibuffer-show-empty-filter-groups nil)
(setq ibuffer-default-sorting-mode 'filename/process)
(setq ibuffer-title-face 'font-lock-doc-face)
(setq ibuffer-use-header-line t)
(setq ibuffer-default-shrink-to-minimum-size nil)
(setq ibuffer-formats
'((mark modified read-only locked " "
(name 30 30 :left :elide)
" "
(size 9 -1 :right)
" "
(mode 16 16 :left :elide)
" " filename-and-process)
(mark " "
(name 16 -1)
" " filename)))
(setq ibuffer-saved-filter-groups
'(("Main"
("Directories" (mode . dired-mode))
("C++" (or
(mode . c++-mode)
(mode . c++-ts-mode)
(mode . c-mode)
(mode . c-ts-mode)
(mode . c-or-c++-ts-mode)))
("Python" (or
(mode . python-ts-mode)
(mode . c-mode)
(mode . python-mode)))
("Build" (or
(mode . make-mode)
(mode . makefile-gmake-mode)
(name . "^Makefile$")
(mode . change-log-mode)))
("Scripts" (or
(mode . shell-script-mode)
(mode . shell-mode)
(mode . sh-mode)
(mode . lua-mode)
(mode . bat-mode)))
("Config" (or
(mode . conf-mode)
(mode . conf-toml-mode)
(mode . toml-ts-mode)
(mode . conf-windows-mode)
(name . "^\\.clangd$")
(name . "^\\.gitignore$")
(name . "^Doxyfile$")
(name . "^config\\.toml$")
(mode . yaml-mode)))
("Web" (or
(mode . mhtml-mode)
(mode . html-mode)
(mode . web-mode)
(mode . nxml-mode)))
("CSS" (or
(mode . css-mode)
(mode . sass-mode)))
("JS" (or
(mode . js-mode)
(mode . rjsx-mode)))
("Markup" (or
(mode . markdown-mode)
(mode . adoc-mode)))
("Org" (mode . org-mode))
("LaTeX" (name . "\.tex$"))
("Magit" (or
(mode . magit-blame-mode)
(mode . magit-cherry-mode)
(mode . magit-diff-mode)
(mode . magit-log-mode)
(mode . magit-process-mode)
(mode . magit-status-mode)))
("Apps" (or
(mode . elfeed-search-mode)
(mode . elfeed-show-mode)))
("Fundamental" (or
(mode . fundamental-mode)
(mode . text-mode)))
("Emacs" (or
(mode . emacs-lisp-mode)
(name . "^\\*Help\\*$")
(name . "^\\*Custom.*")
(name . "^\\*Org Agenda\\*$")
(name . "^\\*info\\*$")
(name . "^\\*scratch\\*$")
(name . "^\\*Backtrace\\*$")
(name . "^\\*Messages\\*$"))))))
:hook
(ibuffer-mode . (lambda ()
(ibuffer-switch-to-saved-filter-groups "Main")))
)
#+end_src
* Error Checking
@@ -1296,7 +1223,7 @@ certain dependencies. It will function without them however.
("d" "~/Downloads/" "Downloads")
("s" "/ssh:192.168.88.1" "SSH server")))
:config
(dirvish-peek-mode) ; Preview files in minibuffer
;;(dirvish-peek-mode) ; Preview files in minibuffer
(dirvish-side-follow-mode) ; similar to `treemacs-follow-mode'
(setq dirvish-mode-line-format
'(:left (sort symlink) :right (omit yank index)))
@@ -1483,6 +1410,17 @@ I like using catppuccin from time to time as well.
(use-package catppuccin-theme :ensure t)
#+end_src
* Icons
Some Icons might spruce things up a bit. Might as well try to have
[[https://github.com/domtronn/all-the-icons.el][all the icons]]!
#+begin_src emacs-lisp
(use-package all-the-icons
:ensure t
:if (display-graphic-p))
#+end_src
** Modeline
Doom emacs has a great modeline in my opinion so I'm using theirs almost