diff options
author | Vincent Ambo <mail@tazj.in> | 2023-08-23T20·03+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2023-08-23T20·22+0000 |
commit | df4a09864af58468c5f54aa19cd90b27910910ce (patch) | |
tree | 146615299a644b55d99dc0a901e70111dd6bfa9f /users | |
parent | 561a9fa45b4fe35809b0bec17147e17c027092ac (diff) |
feat(tazjin/emacs): implement reliably-switch-buffer r/6520
Adds a completing-read function (defaulting to ivy for me, but it doesn't matter) that offers a reliable alternative to standard buffer-switching implementations. In particular, this implementation retains a mapping of buffer names to their buffer *objects*, so that the correct buffer is selected even if some renaming took place during the selection. I tried to account for a bunch of the common behaviours I could think of: * invisible buffers are ... invisible * entering a buffer name manually creates that buffer, if there is no match * ... unless that buffer is an invisible buffer, in which case it is selected and switched to * the first element is always `(other-buffer (current-buffer))`, because of the ordering of #'buffer-list Yet, the entire code of my implementation is less than the *setup* code of ivy-switch-buffers, so it's possible I missed something. Well, I'll find out ... Change-Id: I08be0da0863d06c9a930e5efaf916719655db90e Reviewed-on: https://cl.tvl.fyi/c/depot/+/9147 Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
Diffstat (limited to 'users')
-rw-r--r-- | users/tazjin/emacs/config/bindings.el | 3 | ||||
-rw-r--r-- | users/tazjin/emacs/config/functions.el | 19 |
2 files changed, 22 insertions, 0 deletions
diff --git a/users/tazjin/emacs/config/bindings.el b/users/tazjin/emacs/config/bindings.el index 85643657010b..fc33cd1840cf 100644 --- a/users/tazjin/emacs/config/bindings.el +++ b/users/tazjin/emacs/config/bindings.el @@ -1,3 +1,6 @@ +;; Switch buffers reliably in the face of spurious renames. +(global-set-key (kbd "C-x b") #'reliably-switch-buffer) + ;; Font size (define-key global-map (kbd "C-=") 'increase-default-text-scale) ;; '=' because there lies '+' (define-key global-map (kbd "C--") 'decrease-default-text-scale) diff --git a/users/tazjin/emacs/config/functions.el b/users/tazjin/emacs/config/functions.el index 835b4e44d518..4ac4580176ae 100644 --- a/users/tazjin/emacs/config/functions.el +++ b/users/tazjin/emacs/config/functions.el @@ -371,4 +371,23 @@ by looking for a `Cargo.toml' file." (error "Not a .nix/.exp file!"))))) (find-file other))) +(defun reliably-switch-buffer () + "Reliably and interactively switch buffers, without ending up in a +situation where the buffer was renamed during selection and an +empty new buffer is created. + +This is done by, in contrast to functions like +`ivy-switch-buffer', retaining a list of the buffer objects and +their associated names." + + (interactive) + (let* ((buffers (seq-map (lambda (b) (cons (buffer-name b) b)) + (seq-filter (lambda (b) (not (string-prefix-p " " (buffer-name b)))) + (buffer-list)))) + (name (completing-read "Switch to buffer: " (seq-map #'car buffers))) + (selected (or (cdr (assoc name buffers)) + ;; Allow users to manually select invisible buffers ... + (get-buffer name)))) + (switch-to-buffer (or selected name) nil 't))) + (provide 'functions) |