@@ -47,14 +47,8 @@ mode.")
4747 (add-to-list 'project-switch-commands '(project-switch-to-buffer " Switch buffer" ))
4848 (add-to-list 'project-switch-commands '(project-save-some-buffers " Save" ) t ))
4949
50- ; ; (use-package ibuffer-vc
51- ; ; ;; :disabled true
52- ; ; :ensure t
53- ; ; :after ibuffer
54- ; ; :hook (ibuffer-mode . ibuffer-vc-set-filter-groups-by-vc-root))
55-
5650(use-feature ibuffer
57- :bind ((" C-x C-b " . my/ibuffer-project))
51+ :bind ((" C-x B " . my/ibuffer-project))
5852 :config
5953 ; ; Don't show filter groups if there are no buffers in that group
6054 (setq ibuffer-show-empty-filter-groups nil )
@@ -69,69 +63,81 @@ mode.")
6963 (mode 16 16 :left :elide )
7064 " "
7165 filename-and-process)))
72- ; ; (setq ibuffer-saved-filter-groups
73- ; ; (quote (("default"
74- ; ; ("dired" (mode . dired-mode))
75- ; ; ("org " (name . "^.*org$"))
76- ; ; ("web" (or (mode . web-mode) (mode . js2-mode)) )
77- ; ; ("shell" (or (mode . eshell-mode) (mode . shell-mode )))
78- ; ; ("mu4e " (name . "\*mu4e\* "))
79- ; ; ("coding " (or
80- ; ; (mode . python -mode)
81- ; ; (mode . clojure-mode )
82- ; ; (name . "^ \\ *scratch-clj \\ *$")))
83- ; ; ("emacs" (or
84- ; ; (name . "^ \\ *scratch \\ *$" )
85- ; ; (name . "^\\ *Messages \\ *$")))
86- ; ; ))))
66+ (setq ibuffer-saved-filter-groups
67+ (quote ((" default"
68+ (" dired" (mode . dired-mode))
69+ ( " emacs " (or
70+ (name . " ^ \\ *scratch \\ *$ " )
71+ (name . " ^ \\ *Messages \\ *$ " )))
72+ ( " org " (name . " ^.*org$ " ))
73+ ( " web " (or (mode . web-mode) (mode . js2-mode)))
74+ ( " shell " ( or (mode . eshell-mode) (mode . shell -mode)) )
75+ ( " mu4e " (name . " \* mu4e \* " ) )
76+ ( " coding " ( or
77+ (mode . python-mode)
78+ (mode . clojure-mode )
79+ (name . " ^\\ *scratch-clj \\ *$" )))
80+ ))))
8781
8882 (defun my/ibuffer-project ()
89- " Open ibuffer filtered to the current project using `ibuffer-project' ."
83+ " Open ibuffer; name the buffer after the current project if any ."
9084 (interactive )
91- (let ((name (format " *Projet: %s * " (or (project-root (project-current )) " Unknown" ))))
85+ (let* ((proj (project-current ))
86+ (root (when proj (project-root proj)))
87+ (name (format " *Projet: %s * " (if root (abbreviate-file-name root) " Unknown" ))))
9288 (ibuffer nil name)))
9389 (defun my/ibuffer-for-current-project ()
94- " Open `ibuffer` showing only buffers in the current project.
95- If not in a project, fallback to regular `ibuffer`."
90+ " Open ibuffer showing only buffers in the current project; fallback to all."
9691 (interactive )
97- (let ((proj (project-current ) ))
98- ( if proj
99- ( let (( root (project-root proj)))
100- (ibuffer nil (format " *Projet: %s * " (abbreviate-file-name root))
101- `((filename . , root) )))
102- (message " Not in a project. Showing all buffers." )
92+ (let* ((proj (project-current ))
93+ (root ( when proj (project-root proj))))
94+ ( if root
95+ (ibuffer nil (format " *Projet: %s * " (abbreviate-file-name root))
96+ `((filename . , root )))
97+ (message " Pas dans un projet. Affichage de tous les buffers." )
10398 (call-interactively #'ibuffer ))))
104- ; ; (setq ibuffer-default-sorting-mode 'recency)
105- ; ; (add-hook 'ibuffer-mode-hook
106- ; ; (lambda ()
107- ; ; (ibuffer-auto-mode 1)
108- ; ; (ibuffer-switch-to-saved-filter-groups "default")))
10999 )
110100
111- ; ; (use-package ibuffer-project
112- ; ; :ensure t
113- ; ; :after (ibuffer project)
114- ; ; :hook ((ibuffer ibuffer-mode) . my/ibuffer-project-generate-filter-groups)
115- ; ; :config
116- ; ; (setq ibuffer-project-use-cache t)
117- ; ; (setq ibuffer-project-root-functions
118- ; ; `(((lambda (dir)
119- ; ; (let ((proj (with-current-buffer (or (get-file-buffer dir) (current-buffer))
120- ; ; (project-current nil dir))))
121- ; ; (when proj
122- ; ; (expand-file-name (project-root proj)))))
123- ; ; . "Project")))
124- ; ; (defun my/ibuffer-project-generate-filter-groups ()
125- ; ; (setq ibuffer-filter-groups
126- ; ; (ibuffer-project-generate-filter-groups))))
127-
128101(use-package ibuffer-project
129- :ensure t
102+ :disabled true
103+ ; ; Load only if present as a built-in (Emacs 29+) or installed package.
104+ :if (locate-library " ibuffer-project" )
105+ :ensure nil ; ; use built-in
130106 :after (ibuffer project)
131- :hook (ibuffer . ibuffer-project-hook )
107+ :hook (ibuffer . my/ ibuffer-project-group )
132108 :config
133- (setq ibuffer-project-use-cache t ))
109+ (setq ibuffer-project-use-cache t )
110+ (defun my/ibuffer-project-group ()
111+ " Group ibuffer by project, whether using built-in or MELPA API."
112+ (let ((group-fn (cond
113+ ((fboundp 'ibuffer-project-set-filter-groups )
114+ #'ibuffer-project-set-filter-groups ) ; Emacs 29+
115+ ((fboundp 'ibuffer-project-generate-filter-groups )
116+ (lambda ()
117+ (setq ibuffer-filter-groups
118+ (ibuffer-project-generate-filter-groups))))
119+ (t nil ))))
120+ (when group-fn
121+ (funcall group-fn)
122+ ; ; pick a stable default; change to 'recency if you like
123+ (unless (eq ibuffer-sorting-mode 'recency )
124+ (ibuffer-do-sort-by-recency ))))))
134125
126+ (use-package ibuffer-vc
127+ ; ; :disabled true
128+ :if (locate-library " ibuffer-vc" )
129+ :ensure t
130+ :after ibuffer
131+ :hook (ibuffer-mode . ibuffer-vc-set-filter-groups-by-vc-root)
132+ :config
133+ ; ; Add a VC status column (provided by ibuffer-vc)
134+ (with-eval-after-load 'ibuffer
135+ (add-to-list 'ibuffer-formats
136+ '(mark modified read-only " "
137+ (name 18 18 :left :elide ) " "
138+ (vc-status 12 12 :left ) " " ; ; ← from ibuffer-vc
139+ (mode 16 16 :left :elide ) " "
140+ filename-and-process))))
135141
136142; ;;; `diff-mode'
137143(use-package diff-mode
0 commit comments