From 98bbded2b37b7608573b1a9c596f5c215257b7ad Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 1 Oct 2019 19:53:48 +0200 Subject: [PATCH] Add support for Dired file marking from image-mode * doc/emacs/files.texi (File Conveniences): Document them. * lisp/image-mode.el (image-mode--mark-file): New function. (image-mode-unmark-file, image-mode-mark-file) (image-mode-copy-file-name-as-kill): New commands and keystrokes. --- doc/emacs/files.texi | 14 +++++++++ etc/NEWS | 6 ++++ lisp/image-mode.el | 69 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index 0ff64d529c0..9fe1b564a82 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -2119,6 +2119,20 @@ displayed. You can press @kbd{n} (@code{image-next-file}) and @kbd{p} (@code{image-previous-file}) to visit the next image file and the previous image file in the same directory, respectively. +@findex image-mode-mark-file +@findex image-mode-unmark-file +@findex image-mode-copy-file-name-as-kill + When looking through images, it's sometimes convenient to be able to +mark the files for later processing (for instance, if you want to +select a group of images to copy somewhere else). The @kbd{m} +(@code{image-mode-mark-file}) command will mark the current file in +any Dired buffer(s) that display the current file's directory. If no +such buffer is open, the directory is opened in a new buffer. To +unmark files, use the @kbd{u} (@code{image-mode-mark-file}) command. +Finally, if you just want to copy the current buffers file name to the +kill ring, you can use the @kbd{w} +(@code{image-mode-copy-file-name-as-kill}) command. + @findex image-toggle-animation @findex image-next-frame @findex image-previous-frame diff --git a/etc/NEWS b/etc/NEWS index f0289eb958d..04e2657e7c6 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2725,6 +2725,12 @@ The image parameters 'image-transform-rotation', buffer-local, so each buffer could have its own values for these parameters. ++++ +*** Three new 'image-mode' commands have been added: 'm', which marks +the file in the dired buffer(s) for the directory the file is in; 'u', +which unmarks the file; and 'w', which pushes the current buffer's file +name to the kill ring. + +++ *** The command 'image-rotate' now accepts a prefix argument. With a prefix argument, 'image-rotate' now rotates the image at point diff --git a/lisp/image-mode.el b/lisp/image-mode.el index aaec9026e57..ed796565a38 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el @@ -430,7 +430,9 @@ call." (define-key map "a-" 'image-decrease-speed) (define-key map "a0" 'image-reset-speed) (define-key map "ar" 'image-reverse-speed) - (define-key map "k" 'image-kill-buffer) + (define-key map "w" 'image-mode-copy-file-name-as-kill) + (define-key map "m" 'image-mode-mark-file) + (define-key map "u" 'image-mode-unmark-file) (define-key map [remap forward-char] 'image-forward-hscroll) (define-key map [remap backward-char] 'image-backward-hscroll) (define-key map [remap right-char] 'image-forward-hscroll) @@ -477,6 +479,9 @@ call." :help "Move to next image in this directory"] ["Previous Image" image-previous-file :active buffer-file-name :help "Move to previous image in this directory"] + ["Copy File Name" image-mode-copy-file-name-as-kill + :active buffer-file-name + :help "Copy the current file name to the kill ring"] "--" ["Fit Frame to Image" image-mode-fit-frame :active t :help "Resize frame to match image"] @@ -986,6 +991,68 @@ replacing the current Image mode buffer." (interactive "p") (image-next-file (- n))) +(defun image-mode-copy-file-name-as-kill () + "Push the currently visited file name onto the kill ring." + (interactive) + (unless buffer-file-name + (error "The current buffer doesn't visit a file")) + (kill-new buffer-file-name) + (message "Copied %s" buffer-file-name)) + +(defun image-mode-mark-file () + "Mark the current file in the appropriate dired buffer(s). +Any dired buffer that's opened to the current file's directory +will have the line where the image appears (if any) marked. + +If no such buffer exists, it will be opened." + (interactive) + (unless buffer-file-name + (error "The current buffer doesn't visit a file.")) + (image-mode--mark-file buffer-file-name #'dired-mark "marked")) + +(defun image-mode-unmark-file () + "Unmark the current file in the appropriate dired buffer(s). +Any dired buffer that's opened to the current file's directory +will remove the mark from the line where the image appears (if +any). + +If no such buffer exists, it will be opened." + (interactive) + (unless buffer-file-name + (error "The current buffer doesn't visit a file.")) + (image-mode--mark-file buffer-file-name #'dired-unmark "unmarked")) + +(declare-function dired-mark "dired" (arg &optional interactive)) +(declare-function dired-unmark "dired" (arg &optional interactive)) +(declare-function dired-goto-file "dired" (file)) + +(defun image-mode--mark-file (file function message) + (require 'dired) + (let* ((dir (file-name-directory file)) + (buffers + (cl-loop for buffer in (buffer-list) + when (with-current-buffer buffer + (and (eq major-mode 'dired-mode) + (equal (file-truename dir) + (file-truename default-directory)))) + collect buffer)) + results) + (unless buffers + (save-excursion + (setq buffers (list (find-file-noselect dir))))) + (dolist (buffer buffers) + (with-current-buffer buffer + (if (not (dired-goto-file file)) + (push (format "couldn't find in %s" (directory-file-name dir)) + results) + (funcall function 1) + (push (format "%s in %s" message (directory-file-name dir)) + results)))) + ;; Capitalize first character. + (let ((string (mapconcat #'identity results "; "))) + (message "%s%s" (capitalize (substring string 0 1)) + (substring string 1))))) + (defun image-mode--images-in-directory (file) (let* ((dir (file-name-directory buffer-file-name)) (files (directory-files dir nil -- 2.39.5