Ibuffer: 'w' and 'B' default to buffer at current line

See discussion in:
https://lists.gnu.org/archive/html/emacs-devel/2016-09/msg00384.html
* lisp/ibuffer.el (ibuffer--near-buffers): New defun;
return buffers near current line.
* lisp/ibuf-ext.el (ibuffer-copy-buffername-as-kill): Use it.
Add argument ARG; if a non-zero integer, return next ARG buffers.
Otherwise return the marked buffers.
If there are not marked buffers, return buffer at current line
without prompting the user.
Use ibuffer-get-marked-buffers instead of ibuffer-map-marked-lines.
Append to kill ring when last command was a kill-region.
(ibuffer-copy-filename-as-kill): Idem.
Simplify the code.
Use ibuffer-buffer-file-name instead of buffer-file-name to
include buffers in Dired mode.
This commit is contained in:
Tino Calancha 2016-10-03 21:16:00 +09:00
parent 3b6eb9489d
commit a7e9d1cce3
2 changed files with 52 additions and 46 deletions

View file

@ -1420,7 +1420,7 @@ This requires the external program \"diff\" to be in your `exec-path'."
;;;###autoload
(defun ibuffer-copy-filename-as-kill (&optional arg)
"Copy filenames of marked buffers into the kill ring.
"Copy filenames of marked (or next ARG) buffers into the kill ring.
The names are separated by a space.
If a buffer has no filename, it is ignored.
@ -1431,55 +1431,51 @@ With \\[universal-argument], use the filename of each marked file relative
to `ibuffer-default-directory' if non-nil, otherwise `default-directory'.
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 ((result "")
(type (cond ((or (null arg) (zerop arg))
'full)
((= arg 4)
'relative)
(t
'name))))
(ibuffer-map-marked-lines
#'(lambda (buf _mark)
(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))))
(interactive "P")
(let* ((buffers (cond ((and (integerp arg) (not (zerop arg)))
(ibuffer--near-buffers arg))
(t
(or (ibuffer-get-marked-buffers)
(list (ibuffer-current-buffer))))))
(file-names
(mapcar
(lambda (buf)
(let ((name (with-current-buffer buf
(ibuffer-buffer-file-name))))
(if (null name)
""
(cond ((and (integerp arg) (zerop arg)) name)
((consp arg)
(file-relative-name
name (or ibuffer-default-directory
default-directory)))
(t (file-name-nondirectory name))))))
buffers))
(string
(mapconcat 'identity (delete "" file-names) " ")))
(unless (string= string "")
(if (eq last-command 'kill-region)
(kill-append string nil)
(kill-new string))
(message "%s" string))))
;;;###autoload
(defun ibuffer-copy-buffername-as-kill ()
"Copy buffer names of marked buffers into the kill ring.
(defun ibuffer-copy-buffername-as-kill (&optional arg)
"Copy buffer names of marked (or next ARG) buffers into the kill ring.
The names are separated by a space.
You can then feed the file name(s) to other commands with \\[yank]."
(interactive)
(if (zerop (ibuffer-count-marked-lines))
(message "No buffers marked; use 'm' to mark a buffer")
(let ((res ""))
(ibuffer-map-marked-lines
#'(lambda (buf _mark)
(setq res (concat res (buffer-name buf) " "))))
(when (not (zerop (length res)))
(setq res (substring res 0 -1)))
(kill-new res)
(message res))))
(interactive "P")
(let* ((buffers (cond ((and (integerp arg) (not (zerop arg)))
(ibuffer--near-buffers arg))
(t
(or (ibuffer-get-marked-buffers)
(list (ibuffer-current-buffer))))))
(string (mapconcat #'buffer-name buffers " ")))
(unless (string= string "")
(if (eq last-command 'kill-region)
(kill-append string nil)
(kill-new string))
(message "%s" string))))
(defun ibuffer-mark-on-buffer (func &optional ibuffer-mark-on-buffer-mark group)
(let ((count

View file

@ -2022,6 +2022,16 @@ the buffer object itself and the current mark symbol."
(ibuffer-forward-line 0)
(ibuffer-forward-line (1- target-line-offset))))))
;; Return buffers around current line.
(defun ibuffer--near-buffers (n)
(delq nil
(mapcar
(lambda (x)
(car (get-text-property
(line-beginning-position (if (natnump n) x (- (1- x))))
'ibuffer-properties)))
(number-sequence 1 (abs n)))))
(defun ibuffer-get-marked-buffers ()
"Return a list of buffer objects currently marked."
(delq nil