-
Notifications
You must be signed in to change notification settings - Fork 0
/
pel-ibuffer.el
105 lines (85 loc) · 3.67 KB
/
pel-ibuffer.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
;;; pel-ibuffer.el --- Ibuffer utilities. -*- lexical-binding: t; -*-
;; Created : Friday, November 24 2023.
;; Author : Pierre Rouleau <prouleau001@gmail.com>
;; Time-stamp: <2023-11-25 18:38:35 EST, updated by Pierre Rouleau>
;; This file is part of the PEL package.
;; This file is not part of GNU Emacs.
;; This file is heavily based on code posted by jpkotta, October 29, 2015 on:
;; https://emacs.stackexchange.com/questions/10621/how-to-get-ibuffer-to-use-directory-tree-as-filter-groups/17731#17731
;; I cleaned it up a little, ensured it byte compiles cleanly and built an
;; interface for PEL.
;;; --------------------------------------------------------------------------
;;; Commentary:
;;
;;
;;; --------------------------------------------------------------------------
;;; Dependencies:
;;
;;
(require 'ibuffer)
(require 'ibuf-ext) ; for: `ibuffer-filtering-alist'
(require 'cl-lib)
;;; --------------------------------------------------------------------------
;;; Code:
;;
;; Define `ibuffer-do-sort-by-pathname', a ibuffer sorter that sorts by
;; directory.
(define-ibuffer-sorter pathname
"Sort by pathname"
(:description "path")
(cl-flet ((get-pathname
(data)
(with-current-buffer (car data)
(or buffer-file-name
(if (eq major-mode 'dired-mode)
(expand-file-name dired-directory))
;; so that all non pathnames are at the end
""))))
(string< (get-pathname a) (get-pathname b))))
;; ---------------------------------------------------------------------------
;; Define a directory filter
(defun get-all-buffer-directories ()
"Return a list of all directories that have at least one
file being visited."
(interactive)
(let (lst)
(dolist (e (sort (mapcar 'file-name-directory
(cl-remove-if-not 'identity
(mapcar 'buffer-file-name
(buffer-list))))
'string<))
(unless (string= (car lst) e)
(setq lst (cons e lst))))
lst))
(define-ibuffer-filter dirname
"Toggle current view to buffers with in a directory DIRNAME."
(:description "directory name"
:reader
(intern
(completing-read "Filter by directory: "
(get-all-buffer-directories)
'identity
t nil nil nil nil)))
(string= qualifier
(and (buffer-file-name buf)
(file-name-directory (buffer-file-name buf)))))
;; ---------------------------------------------------------------------------
;; Define a filter that groups per directory
(defun ibuffer-set-filter-groups-by-directory ()
"Set the current filter groups to filter by directory."
(interactive)
(setq ibuffer-filter-groups
(mapcar (lambda (dir)
(cons (format "%s" dir) `((dirname . ,dir))))
(get-all-buffer-directories)))
(ibuffer-update nil t))
;; ---------------------------------------------------------------------------
(defun pel-map-ibuffer-mode-filters ()
"Map the keys of extra ibuffer filters."
(define-key ibuffer-mode-map (kbd "s p") 'ibuffer-do-sort-by-pathname)
(define-key ibuffer-mode-map (kbd "/ D") 'ibuffer-set-filter-groups-by-directory)
(define-key ibuffer-mode-map (kbd "/ d") 'ibuffer-filter-by-dirname)
(define-key ibuffer-mode-map (kbd "/ M-d") 'ibuffer-decompose-filter))
;;; --------------------------------------------------------------------------
(provide 'pel-ibuffer)
;;; pel-ibuffer.el ends here