]> code.delx.au - gnu-emacs/blobdiff - lisp/ibuf-ext.el
Ibuffer: Mark locked buffers
[gnu-emacs] / lisp / ibuf-ext.el
index 1d6182596ed4f0916e4e284ab45f4aae3223dc36..2444dac58058c9e6b15e455d9f86aa0e26aacd7f 100644 (file)
@@ -85,6 +85,32 @@ regardless of any active filters in this buffer."
   :type '(repeat (choice regexp function))
   :group 'ibuffer)
 
+(defcustom ibuffer-never-search-content-name
+  (let* ((names    '("Completions" "Help" "Messages" "Pp Eval Output"
+                     "CompileLog" "Info" "Buffer List" "Ibuffer" "Apropos"))
+         (partial  '("Customize Option: " "Async Shell Command\\*"
+                     "Shell Command Output\\*" "ediff "))
+         (beg      "\\`\\*")
+         (end      "\\*\\'")
+         (excluded (mapcar (lambda (x)
+                             (format "%s%s" beg x)) partial)))
+    (dolist (str names (nreverse excluded))
+      (push (format "%s%s%s" beg str end) excluded)))
+  "A list of regexps for buffers ignored by `ibuffer-mark-by-content-regexp'.
+Buffers whose name matches a regexp in this list, are not searched."
+  :version "25.2"
+  :type '(repeat regexp)
+  :require 'ibuf-ext
+  :group 'ibuffer)
+
+(defcustom ibuffer-never-search-content-mode '(dired-mode)
+  "A list of major modes ignored by `ibuffer-mark-by-content-regexp'.
+Buffers whose major mode is in this list, are not searched."
+  :version "25.2"
+  :type '(repeat regexp)
+  :require 'ibuf-ext
+  :group 'ibuffer)
+
 (defvar ibuffer-tmp-hide-regexps nil
   "A list of regexps which should match buffer names to not show.")
 
@@ -347,10 +373,14 @@ the mode if ARG is omitted or nil."
    :modifier-p nil)
   (shell-command (concat command " "
                         (shell-quote-argument
-                         (if buffer-file-name
-                             buffer-file-name
-                           (make-temp-file
-                            (substring (buffer-name) 0 (min 10 (length (buffer-name))))))))))
+                         (or buffer-file-name
+                             (let ((file
+                                    (make-temp-file
+                                     (substring
+                                      (buffer-name) 0
+                                      (min 10 (length (buffer-name)))))))
+                               (write-region nil nil file nil 0)
+                               file))))))
 
 ;;;###autoload (autoload 'ibuffer-do-eval "ibuf-ext")
 (define-ibuffer-op eval (form)
@@ -1402,8 +1432,8 @@ You can then feed the file name(s) to other commands with \\[yank]."
   (interactive "p")
   (if (zerop (ibuffer-count-marked-lines))
       (message "No buffers marked; use 'm' to mark a buffer")
-    (let ((ibuffer-copy-filename-as-kill-result "")
-         (type (cond ((zerop arg)
+    (let ((result "")
+         (type (cond ((or (null arg) (zerop arg))
                       'full)
                      ((= arg 4)
                       'relative)
@@ -1411,22 +1441,26 @@ You can then feed the file name(s) to other commands with \\[yank]."
                       'name))))
       (ibuffer-map-marked-lines
        #'(lambda (buf _mark)
-          (setq ibuffer-copy-filename-as-kill-result
-                (concat ibuffer-copy-filename-as-kill-result
-                        (let ((name (buffer-file-name buf)))
-                          (if name
-                              (pcase type
-                                (`full
-                                 name)
-                                (`relative
-                                 (file-relative-name
-                                  name (or ibuffer-default-directory
-                                           default-directory)))
-                                (_
-                                 (file-name-nondirectory name)))
-                            ""))
-                        " "))))
-      (kill-new ibuffer-copy-filename-as-kill-result))))
+          (setq result
+                 (concat result
+                         (let ((name (buffer-file-name buf)))
+                           (cond (name
+                                  (concat
+                                   (pcase type
+                                     (`full
+                                      name)
+                                     (`relative
+                                      (file-relative-name
+                                       name (or ibuffer-default-directory
+                                                default-directory)))
+                                     (_
+                                      (file-name-nondirectory name))) " "))
+                                 (t "")))))))
+      (when (not (zerop (length result)))
+        (setq result
+              (substring result 0 -1)))
+      (kill-new result)
+      (message "%s" result))))
 
 (defun ibuffer-mark-on-buffer (func &optional ibuffer-mark-on-buffer-mark group)
   (let ((count
@@ -1450,6 +1484,24 @@ You can then feed the file name(s) to other commands with \\[yank]."
    #'(lambda (buf)
        (string-match regexp (buffer-name buf)))))
 
+(defun ibuffer-locked-buffer-p (&optional buf)
+  "Return non-nil if BUF is locked.
+When BUF nil, default to the buffer at current line."
+  (let ((_buffer (or buf (ibuffer-current-buffer)))
+        char)
+    (when _buffer
+      (with-current-buffer _buffer
+        (and (boundp 'emacs-lock-mode) emacs-lock-mode)))))
+
+;;;###autoload
+(defun ibuffer-mark-by-locked ()
+  "Mark all locked buffers."
+  (interactive)
+  (when (featurep 'emacs-lock)
+    (ibuffer-mark-on-buffer
+     (lambda (buf)
+       (ibuffer-locked-buffer-p buf)))))
+
 ;;;###autoload
 (defun ibuffer-mark-by-mode-regexp (regexp)
   "Mark all buffers whose major mode matches REGEXP."
@@ -1474,6 +1526,31 @@ You can then feed the file name(s) to other commands with \\[yank]."
         (when name
           (string-match regexp name))))))
 
+;;;###autoload
+(defun ibuffer-mark-by-content-regexp (regexp &optional all-buffers)
+  "Mark all buffers whose content matches REGEXP.
+Optional arg ALL-BUFFERS, if non-nil, then search in all buffers.
+Otherwise buffers whose name matches an element of
+`ibuffer-never-search-content-name' or whose major mode is on
+`ibuffer-never-search-content-mode' are excluded."
+  (interactive (let ((reg (read-string "Mark by content (regexp): ")))
+                 (list reg current-prefix-arg)))
+  (ibuffer-mark-on-buffer
+   #'(lambda (buf)
+       (let ((mode (with-current-buffer buf major-mode))
+             res)
+         (cond ((and (not all-buffers)
+                     (or
+                      (memq mode ibuffer-never-search-content-mode)
+                      (cl-some (lambda (x) (string-match x (buffer-name buf)))
+                               ibuffer-never-search-content-name)))
+                (setq res nil))
+               (t
+                (with-current-buffer buf
+                  (save-mark-and-excursion
+                   (goto-char (point-min))
+                   (setq res (re-search-forward regexp nil t)))))) res))))
+
 ;;;###autoload
 (defun ibuffer-mark-by-mode (mode)
   "Mark all buffers whose major mode equals MODE."