Álvaro Ramírez
Interactive ordering of dired items
Redditor sauntcartas offers a nice solution for getting Emacs dired filenames in an arbitrary order. I have to say, while relatively rare, this is something I need from time to time. You see, I like to apply batch file operations from the comfort of dired buffers (via dwim-shell-command).
Take, for example, M-x dwim-shell-commands-join-images-horizontally
. It does what it says on the tin. I can mark a handful of image files via dired
and easily join them into a single file. The problem is that the file listing isn't always in the desired order, so this is where custom ordering comes in handy.
I wanted an interactive way of reordering dired
items. While bouncing ideas with arthurno1, it led us to a drag-stuff experience, which I'm already a fan of. While drag-stuff
works in most editable buffers, it breaks on dired
. For now, I figured I could just write a couple of dired-specific interactive commands to provide a similar dragging experience, and so I did.
We can likely improve the commands a bit, but hey they do the job as is…
(defun ar/dired-drag-item-up () "Drag dired item down in buffer." (interactive) (unless (dired-get-filename nil t) (error "Not a dired draggable item")) (when (= (line-number-at-pos) 2) (error "Already at top")) (let* ((inhibit-read-only t) (col (current-column)) (item-start (line-beginning-position)) (item-end (1+ (line-end-position))) (item (buffer-substring item-start item-end))) (delete-region item-start item-end) (forward-line -1) (beginning-of-line) (insert item) (forward-line -1) (move-to-column col))) (defun ar/dired-drag-item-down () "Drag dired item down in buffer." (interactive) (unless (dired-get-filename nil t) (error "Not a dired draggable item")) (when (save-excursion (forward-line 1) (eobp)) (error "Already at bottom")) (let* ((inhibit-read-only t) (col (current-column)) (item-start (line-beginning-position)) (item-end (1+ (line-end-position))) (item (buffer-substring item-start item-end))) (delete-region item-start item-end) (forward-line 1) (beginning-of-line) (insert item) (forward-line -1) (move-to-column col)))
I gotta say, these dired
dragging commands work great with M-x dwim-shell-commands-join-images-horizontally
. I bind them to M-<up>
and M-<down>
same as drag-stuff
elsewhere (already in my config).
(use-package dired :bind (:map dired-mode-map ("M-<up>" . ar/dired-drag-item-up) ("M-<down>" . ar/dired-drag-item-down)))
You can see the new dired
commands in action.
Bonus
While bouncing ideas with arthurno1
, we also came up with another helper to create new dired
buffers populated from marked items, maybe needed for those times you want a more focused experience.
(defun ar/dired-from-marked-items () "Create a new dired buffer containing only the marked files. Also allow dragging items up and down via M-<up> and M-x<down>." (interactive) (let ((marked-files (dired-get-marked-files)) (buffer-name (generate-new-buffer-name (format "*%s (selection)*" (file-name-nondirectory (directory-file-name default-directory)))))) (unless marked-files (error "No dired marked files")) (dired (cons buffer-name (mapcar (lambda (path) (file-relative-name path default-directory)) marked-files)))))
Make it all sustainable
Learned something new? Enjoying this blog or my projects? Help make it sustainable by ✨sponsoring✨
Need a blog? I can help with that. Maybe buy my iOS apps too ;)