Function: define-ibuffer-op

define-ibuffer-op is an autoloaded macro defined in ibuf-macs.el.gz.

Signature

(define-ibuffer-op OP ARGS DOCUMENTATION (&key INTERACTIVE MARK MODIFIER-P DANGEROUS OPSTRING ACTIVE-OPSTRING BEFORE AFTER COMPLEX) &rest BODY)

Documentation

Generate a function which operates on a buffer.

OP becomes the name of the function; if it doesn't begin with ibuffer-do-, then that is prepended to it. When an operation is performed, this function will be called once for each marked buffer, with that buffer current.

ARGS becomes the formal parameters of the function. DOCUMENTATION becomes the docstring of the function. INTERACTIVE becomes the interactive specification of the function. MARK describes which type of mark (:deletion, or nil) this operation uses. :deletion means the function operates on buffers marked for deletion, otherwise it acts on normally marked buffers. MODIFIER-P describes how the function modifies buffers. This is used to set the modification flag of the Ibuffer buffer itself. Valid values are:
 nil - the function never modifiers buffers
 t - the function it always modifies buffers
 :maybe - attempt to discover this information by comparing the
  buffer's modification flag.
DANGEROUS is a boolean which should be set if the user should be prompted before performing this operation. OPSTRING is a string which will be displayed to the user after the operation is complete, in the form:
 "Operation complete; OPSTRING x buffers"
ACTIVE-OPSTRING is a string which will be displayed to the user in a confirmation message, in the form:
 "Really ACTIVE-OPSTRING x buffers?"
BEFORE is a form to evaluate before start the operation. AFTER is a form to evaluate once the operation is complete. COMPLEX means this function is special; if COMPLEX is nil BODY evaluates once for each marked buffer, MBUF, with MBUF current and saving the point. If COMPLEX is non-nil, BODY evaluates without requiring MBUF current. BODY define the operation; they are forms to evaluate per each marked buffer. BODY is evaluated with buf bound to the buffer object.

Source Code

;; Defined in /usr/src/emacs/lisp/ibuf-macs.el.gz
;;;###autoload
(cl-defmacro define-ibuffer-op (op args
				 documentation
				 (&key
				  interactive
				  mark
				  modifier-p
				  dangerous
				  (opstring "operated on")
				  (active-opstring "Operate on")
                                  before
                                  after
				  complex)
				 &rest body)
  "Generate a function which operates on a buffer.
OP becomes the name of the function; if it doesn't begin with
`ibuffer-do-', then that is prepended to it.
When an operation is performed, this function will be called once for
each marked buffer, with that buffer current.

ARGS becomes the formal parameters of the function.
DOCUMENTATION becomes the docstring of the function.
INTERACTIVE becomes the interactive specification of the function.
MARK describes which type of mark (:deletion, or nil) this operation
uses.  :deletion means the function operates on buffers marked for
deletion, otherwise it acts on normally marked buffers.
MODIFIER-P describes how the function modifies buffers.  This is used
to set the modification flag of the Ibuffer buffer itself.  Valid
values are:
 nil - the function never modifiers buffers
 t - the function it always modifies buffers
 :maybe - attempt to discover this information by comparing the
  buffer's modification flag.
DANGEROUS is a boolean which should be set if the user should be
prompted before performing this operation.
OPSTRING is a string which will be displayed to the user after the
operation is complete, in the form:
 \"Operation complete; OPSTRING x buffers\"
ACTIVE-OPSTRING is a string which will be displayed to the user in a
confirmation message, in the form:
 \"Really ACTIVE-OPSTRING x buffers?\"
BEFORE is a form to evaluate before start the operation.
AFTER is a form to evaluate once the operation is complete.
COMPLEX means this function is special; if COMPLEX is nil BODY
evaluates once for each marked buffer, MBUF, with MBUF current
and saving the point.  If COMPLEX is non-nil, BODY evaluates
without requiring MBUF current.
BODY define the operation; they are forms to evaluate per each
marked buffer.  BODY is evaluated with `buf' bound to the
buffer object.

\(fn OP ARGS DOCUMENTATION (&key INTERACTIVE MARK MODIFIER-P DANGEROUS OPSTRING ACTIVE-OPSTRING BEFORE AFTER COMPLEX) &rest BODY)"
  (declare (indent 2) (doc-string 3))
  `(progn
     (defun ,(intern (concat (if (string-match "^ibuffer-do" (symbol-name op))
				 "" "ibuffer-do-")
                             (symbol-name op)))
       ,args
       ,(if (stringp documentation)
	    documentation
	  (format "%s marked buffers." active-opstring))
       ,(if (not (null interactive))
	    `(interactive ,interactive)
	  '(interactive))
       (cl-assert (derived-mode-p 'ibuffer-mode))
       (setq ibuffer-did-modification nil)
       (let ((marked-names  (,(pcase mark
				(:deletion
				 'ibuffer-deletion-marked-buffer-names)
				(_
				 'ibuffer-marked-buffer-names)))))
	 (when (null marked-names)
	   (setq marked-names (list (buffer-name (ibuffer-current-buffer))))
	   (ibuffer-set-mark ,(pcase mark
				(:deletion
				 'ibuffer-deletion-char)
				(_
				 'ibuffer-marked-char))))
	 ,(let* ((finish (append
			  '(progn)
			  (if (eq modifier-p t)
			      '((setq ibuffer-did-modification t))
			    ())
                          (and after `(,after)) ; post-operation form.
			  `((ibuffer-redisplay t)
			    (message ,(concat "Operation finished; " opstring " %s buffers") count))))
		 (inner-body (if complex
				 `(progn ,@body)
			       `(progn
				  (with-current-buffer buf
				    (save-excursion
				      ,@body))
				  t)))
		 (body `(let ((_ ,before) ; pre-operation form.
                               (count
			       (,(pcase mark
				   (:deletion
				    'ibuffer-map-deletion-lines)
				   (_
				    'ibuffer-map-marked-lines))
                                (lambda (buf mark)
                                  ;; Silence warning for code that doesn't
                                  ;; use `mark'.
                                  (ignore mark)
                                  ,(if (eq modifier-p :maybe)
                                       `(let ((ibuffer-tmp-previous-buffer-modification
                                               (buffer-modified-p buf)))
                                          (prog1 ,inner-body
                                            (when (not (eq ibuffer-tmp-previous-buffer-modification
                                                           (buffer-modified-p buf)))
                                              (setq ibuffer-did-modification t))))
                                     inner-body)))))
			  ,finish)))
	    (if dangerous
		`(when (ibuffer-confirm-operation-on ,active-opstring marked-names)
		   ,body)
	      body))))
     :autoload-end))