From 2fbb408219a2f17928705be048510c630ef3175f Mon Sep 17 00:00:00 2001 From: Manuel Uberti Date: Wed, 23 Feb 2022 09:25:32 +0100 Subject: [PATCH] Add project-ignore-buffer-conditions * lisp/progmodes/project.el (project-ignore-buffer-conditions): New defcustom. (project-switch-to-buffer): Use it (bug#54100). --- lisp/progmodes/project.el | 52 ++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 880c5b5517..78ccedf9fa 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1112,7 +1112,7 @@ project-compile compilation-buffer-name-function))) (call-interactively #'compile))) -(defun project--read-project-buffer () +(defun project--read-project-buffer (&optional predicate) (let* ((pr (project-current t)) (current-buffer (current-buffer)) (other-buffer (other-buffer current-buffer)) @@ -1121,7 +1121,8 @@ project--read-project-buffer (predicate (lambda (buffer) ;; BUFFER is an entry (BUF-NAME . BUF-OBJ) of Vbuffer_alist. - (memq (cdr buffer) buffers)))) + (and (memq (cdr buffer) buffers) + (funcall predicate buffer))))) (read-buffer "Switch to buffer: " (when (funcall predicate (cons other-name other-buffer)) @@ -1129,6 +1130,27 @@ project--read-project-buffer nil predicate))) +(defcustom project-ignore-buffer-conditions nil + "List of conditions to filter the buffers to be switched to. +If any of these conditions are satisfied for a buffer in the +current project, `project-switch-to-buffer' ignores it. +See the doc string of `project-kill-buffer-conditions' for the +general form of conditions." + :type '(repeat (choice regexp function symbol + (cons :tag "Major mode" + (const major-mode) symbol) + (cons :tag "Derived mode" + (const derived-mode) symbol) + (cons :tag "Negation" + (const not) sexp) + (cons :tag "Conjunction" + (const and) sexp) + (cons :tag "Disjunction" + (const or) sexp))) + :version "29.1" + :group 'project + :package-version '(project . "0.8.2")) + ;;;###autoload (defun project-switch-to-buffer (buffer-or-name) "Display buffer BUFFER-OR-NAME in the selected window. @@ -1136,7 +1158,12 @@ project-switch-to-buffer current project. Two buffers belong to the same project if their project instances, as reported by `project-current' in each buffer, are identical." - (interactive (list (project--read-project-buffer))) + (interactive + (list (project--read-project-buffer + (lambda (buffer) + (not + (project--buffer-check + (cdr buffer) project-ignore-buffer-conditions)))))) (switch-to-buffer buffer-or-name)) ;;;###autoload @@ -1239,11 +1266,12 @@ project--buffer-list (push buf bufs))) (nreverse bufs))) -(defun project--kill-buffer-check (buf conditions) +(defun project--buffer-check (buf conditions) "Check if buffer BUF matches any element of the list CONDITIONS. -See `project-kill-buffer-conditions' for more details on the form -of CONDITIONS." - (catch 'kill +See `project-kill-buffer-conditions' or +`project-ignore-buffer-conditions' for more details on the +form of CONDITIONS." + (catch 'match (dolist (c conditions) (when (cond ((stringp c) @@ -1258,15 +1286,15 @@ project--kill-buffer-check (buffer-local-value 'major-mode buf) (cdr c))) ((eq (car-safe c) 'not) - (not (project--kill-buffer-check buf (cdr c)))) + (not (project--buffer-check buf (cdr c)))) ((eq (car-safe c) 'or) - (project--kill-buffer-check buf (cdr c))) + (project--buffer-check buf (cdr c))) ((eq (car-safe c) 'and) (seq-every-p - (apply-partially #'project--kill-buffer-check + (apply-partially #'project--buffer-check buf) (mapcar #'list (cdr c))))) - (throw 'kill t))))) + (throw 'match t))))) (defun project--buffers-to-kill (pr) "Return list of buffers in project PR to kill. @@ -1274,7 +1302,7 @@ project--buffers-to-kill in `project-kill-buffer-conditions'." (let (bufs) (dolist (buf (project-buffers pr)) - (when (project--kill-buffer-check buf project-kill-buffer-conditions) + (when (project--buffer-check buf project-kill-buffer-conditions) (push buf bufs))) bufs)) -- 2.25.1