;;; -*- lexical-binding: t; -*- (require 'ibuffer) (require 'ibuf-ext) (setq ibuffer-expert t) (setq ibuffer-display-summary nil) (setq ibuffer-show-empty-filter-groups nil) ;;; Bindings related to buffers ;;;; Quickly switch to the last buffer. ;;;###autoload (defun durand-switch-to-last-buffer (&optional arg) "Switch to the last buffer. The last buffer is given by `other-buffer'. If ARG is non-nil, then display the last buffer in a new window." (interactive "P") (cond (arg (switch-to-buffer-other-window nil)) ((switch-to-buffer nil)))) ;;;###autoload (defun durand-switch-to-last-buffer-other-window () "Switch to the last buffer in a new window." (interactive) (switch-to-buffer-other-window nil)) ;;;###autoload (defun switch-to-buffer-same-mode (&optional arg) "Switch to a buffer with the same major mode as the current buffer. If the optional ARG is non-nil, then produce an IBUFFER buffer listing all buffers of the same mode as the current buffer." (interactive "P") (cond ((null arg) (let* ((mode (buffer-local-value 'major-mode (current-buffer))) (def (buffer-name (car (delete nil (mapcar (lambda (buf) (and (provided-mode-derived-p (buffer-local-value 'major-mode buf) mode) (not (= (aref (buffer-name buf) 0) 32)) (not (eq buf (current-buffer))) buf)) (buffer-list))))))) (switch-to-buffer (read-buffer (format "Switch to buffer with major mode %S:" (buffer-local-value 'major-mode (current-buffer))) def t (lambda (name-or-cons) (provided-mode-derived-p (buffer-local-value 'major-mode (cond ((consp name-or-cons) (cdr name-or-cons)) ((get-buffer name-or-cons)))) mode)))))) ((ibuffer nil (format "*Buffers for %S*" (buffer-local-value 'major-mode (current-buffer))) (list (cons 'used-mode (buffer-local-value 'major-mode (current-buffer)))))))) ;;;###autoload (defvar durand-clear-passlist nil "The list of buffers that should not be deleted \ automatically.") ;; from dashboard.el (defvar dashboard-buffer-name) (cond ((null dashboard-buffer-name) (setq dashboard-buffer-name ""))) (setq durand-clear-passlist (list dashboard-buffer-name "*Group*" ".newsrc-dribble")) ;;;###autoload (defun durand-ibuffer-clear (&optional arg) "Kill every buffer except for those in `durand-clear-passlist'. If the optional ARG is non-nil, then kill every buffer except for those that are marked." (interactive "P") (cond ((derived-mode-p 'ibuffer-mode)) ((user-error "durand-ibuffer-clear should only be used in \ derived modes of `ibuffer-mode'."))) (cond ((null arg) (mapc (function (lambda (buffer) (cond ((durand-member (buffer-name buffer) durand-clear-passlist #'string=)) ((kill-buffer buffer))))) (cons (current-buffer) (mapcar #'car (ibuffer-current-state-list))))) (t (mapc (function (lambda (buffer-and-mark) (cond ((or (= (cdr buffer-and-mark) ibuffer-marked-char) (string= (buffer-name (car buffer-and-mark)) dashboard-buffer-name))) ((kill-buffer (car buffer-and-mark)))))) (cons (cons (current-buffer) 32) (ibuffer-current-state-list)))))) (define-key global-map (vector 24 2) #'ibuffer) (define-key global-map (vector ?\s-h) #'ibuffer) (define-key global-map (vector ?\M-\s-b) #'switch-to-buffer-same-mode) (define-key global-map (vector ?\s-b) #'switch-to-buffer) (define-key global-map (vector ?\s-B) #'switch-to-buffer-other-window) (define-key global-map (vector ?\s-n) #'durand-switch-to-last-buffer) (define-key global-map (vector ?\s-N) #'durand-switch-to-last-buffer-other-window) (define-key ibuffer-mode-map (vector ?d) #'ibuffer-do-delete) (define-key ibuffer-mode-map (vector ?D) #'ibuffer-mark-for-delete) (define-key ibuffer-mode-map (vector ?c) #'durand-ibuffer-clear) ;;; filter for bongo ;;;###autoload (define-ibuffer-filter durand-bongo "Group bongo buffers together." (:description "Bongo buffers together" :reader (read-string "no effect: ")) (cond ((not (boundp 'durand-bongo-music-dir)) (load-config "bongo.el"))) (with-current-buffer buf (cond ((derived-mode-p 'dired-mode) (let ((bongo-dirs durand-bongo-music-dir) found) (while (and (not found) (consp bongo-dirs)) (cond ((file-in-directory-p default-directory (car bongo-dirs)) (setq found t)) (t (setq bongo-dirs (cdr bongo-dirs))))) found)) ((derived-mode-p 'bongo-playlist-mode 'bongo-library-mode))))) ;;;###autoload (define-ibuffer-filter durand-directory "Limit current view to buffers with directory a subdirectory of \ QUALIFIER. For a buffer not associated with a file, this matches against the value of `default-directory' in that buffer." (:description "directory name" :reader (read-from-minibuffer "Filter by directory name (regex): ")) (ibuffer-aif (with-current-buffer buf (ibuffer-buffer-file-name)) (let ((dirname (expand-file-name (file-name-directory it)))) (when dirname (string-match-p (expand-file-name qualifier) dirname))) (when (with-current-buffer buf default-directory) (string-match-p (expand-file-name qualifier) (expand-file-name (with-current-buffer buf default-directory)))))) ;;;###autoload (defun durand-bongo-set-filter () "Set my custom filters." (interactive) (setq ibuffer-filter-groups (list (cons "Bongo" '((durand-bongo))) (cons "C" '((mode . c-mode))) (cons "ELisp" '((mode . emacs-lisp-mode))) (cons "EWW" '((mode . eww-mode))) (cons "Roman" '((mode . novel-read-mode))))) (let ((ibuf (get-buffer "*Ibuffer*"))) (when ibuf (with-current-buffer ibuf ;; (pop-to-buffer ibuf) (ibuffer-update nil t))))) (add-hook 'ibuffer-hook 'durand-bongo-set-filter 100)