This post is the seventh part of the series Dired as Default File Manager

Wdired is a special mode that allows you to perform file operations by editing the Dired buffer directly (the “W” in “Wdired” stands for “writable”.). Imagine that you want to rename multiple files, you will have to call the rename command several times. Wdired help you to transform the current dired buffer to an editable one, then you can change multiple file names and apply the changes. To activate it, simply run the command dired-toggle-read-only (bound to C-x C-q by default). When you finish, just call wdired-finish-edit (C-c C-c) to commit the changes or wdired-abort-changes (C-c C-k) to cancel.

This is much faster comparing to the other GUI file managers. However, it's still not very convenience since you still have to mark the text that you want to change. Also, in normal file manager, when you rename one file, it will auto select the file name exclude the extension for you to edit. This can be achieved easily using a little emacs lisp.

  (defun my-mark-file-name-for-rename ()
    "Mark file name on current line except its extension"
    (interactive)

    ;; get the file file name first
    ;; full-name: full file name
    ;; extension: extension of the file
    ;; base-name: file name without extension
    (let ((full-name (file-name-nondirectory (dired-get-filename)))
          extension base-name)

      ;; check if it's a dir or a file
      ;; TODO not use if, use switch case check for symlink
      (if (file-directory-p full-name)
          (progn
            ;; if file name is directory, mark file name should mark the whole
            ;; file name
            (call-interactively 'end-of-line) ;move the end of line
            (backward-char (length full-name)) ;back to the beginning
            (set-mark (point))
            (forward-char (length full-name)))
        (progn
          ;; if current file is a file, mark file name mark only the base name,
          ;; exclude the extension
          (setq extension (file-name-extension full-name))
          (setq base-name (file-name-sans-extension full-name))
          (call-interactively 'end-of-line)
          (backward-char (length full-name))
          (set-mark (point))
          (forward-char (length base-name))))))

  (defun my-mark-file-name-forward ()
    "Mark file name on the next line"
    (interactive)
    (deactivate-mark)
    (next-line)
    (my-mark-file-name-for-rename))

  (defun my-mark-file-name-backward ()
    "Mark file name on the next line"
    (interactive)
    (deactivate-mark)
    (previous-line)
    (my-mark-file-name-for-rename))

Here I defined some functions for fast file name marking. The first one marks the file name on current line. The next one moves the point to next line and marks the file name while the last function does the opposite. Next, you need to bind key for those functions, for example

(eval-after-load 'wdired
  (define-key wdired-mode-map (kbd "TAB") 'my-mark-file-name-forward)
  (define-key wdired-mode-map (kbd "S-<tab>") 'my-mark-file-name-backward)
  (define-key wdired-mode-map (kbd "s-a") 'my-mark-file-name-for-rename))

Usuage: when entering wdired mode, pressing TAB will mark the next file for renaming, type a new name and continue pressing TAB to move to next file. The file name is automatically selected for you to replace. Shift-tab will do the opposite while s-a mark the current file. After the mark is activate, if you want to mark all file name (include the extension), just press C-e (move-end-of-line). See the video below for demonstration

Previous part: Dired as Default File Manager - Dired Async
Next part: Dired as Default file manager - Color and Preview