TransWikia.com

Switch from Dired to Wdired rename file and directory errors when using "-F" or "--classify" ls switch regex help

Emacs Asked by J Spen on September 2, 2021

If you set -F or --classify in the dired-actual-switches then it places a / at the end of directory names and * at the end of executables. When you finish renaming the files, these characters are taken literally so every directory it will try to move it inside of itself if it was renamed.

Of note, I have recently switched to emacs 27 head, so I can’t remember if this happened in Emacs 26.1 or not when switching.

I tried to use this hacky solution to remove --classify from dired-actual-switches but it doesn’t seem to work. Is there a better to do this? Maybe wrapping an advice around wdired instead of using the hooks might be better but not sure how to do that.

(defvar-local jj/dired-classify-enabled nil)

(add-hook 'wdired-mode-hook
      (lambda ()
        (if (string-match "--classify " dired-actual-switches)
        (setq jj/dired-classify-enabled t))
        (setq dired-actual-switches
          (if (string-match "--classify " dired-actual-switches)
              (replace-match "" t t dired-actual-switches)))))

(add-hook 'dired-mode-hook
      (lambda ()
        (cond ((eq jj/dired-classify-enabled t)
           (setq jj/dired-classify-enabled nil)
           (setq dired-actual-switches
             (if (string-match "-a " dired-actual-switches)
                 (replace-match "-a --classify" t t dired-actual-switches)))))))

Edit: I noticed the above works to remove the --classify when entering wdired-mode but I have to call revert-buffer to get it to update properly. I tried putting revert-buffer in the wdired-mode-hook but then I got errors.

Edit2:I’ve figured out how to do this with defadvice. I’d greatly appreciate someones help with using emacs regex functions and syntax. If someone can modify my answer below for a version using regex instead of just removing --classify and readding it that would be great and I will accept your answer.

Edit2: Root on my mac seems to not recognize --classify but only -F, so if using root for dired best to change the script to use -F instead of --classify. This could be due to an old version of gnutils ls on the system that is possibly fixed in newer versions.

One Answer

Here is my solution that works for my setup but won't work universally. Need to change this to using regex and removing any -F or --classify switches. Then, saving the current state of the switches to set back to when wdired changes back to dired. If anyone has any ideas how to implement this using regex in emacs, would be greatly appreciated. I don't know emacs regex string functions or syntax well.

(defun jj/dired-sort-toggle-reverse-switch ()
  "Toggle ls -r switch and update buffer.
Does not affect other sort switches."
  (interactive)
  (let (case-fold-search)
    (setq dired-actual-switches
      (if (string-match "-r " dired-actual-switches)
          (replace-match "" t t dired-actual-switches)
        (concat "-r " dired-actual-switches)))
    (dired-sort-set-mode-line)
    (revert-buffer)))

(defun jj/dired-sort-remove-classify-switch ()
  "Remove --classify switch.
TODO: Change to using regex to remove any -F or --classify switches."
  (interactive)
  (let (case-fold-search)
    (setq dired-actual-switches
      (if (string-match "--classify " dired-actual-switches)
          (replace-match "" t t dired-actual-switches)
        (concat dired-actual-switches)))
    ;; Don't need as doesn't change the mode-line currently
    ;; (dired-sort-set-mode-line)
    (revert-buffer)))

(defun jj/dired-sort-add-classify-switch ()
  "Add --classify switch after -a.
TODO: change to using regex"
  (interactive)
  (let (case-fold-search)
    (cond ((string-match "--classify " dired-actual-switches))
      (t
       (setq dired-actual-switches
         (if (string-match "-a " dired-actual-switches)
             (replace-match "-a --classify " t t dired-actual-switches)
           (concat dired-actual-switches)))
       ))
    (revert-buffer)))

;; Possibly use this to solve the above problem
(defvar-local jj/wdired-classify-enabled nil)
(defun jj/wdired-before-start-advice ()
  "Execute when switching from `dired' to `wdired'."
  ;; TODO: Change to save current dired-switches if the add and remove functions use regex
  (setq jj/wdired-classify-enabled
    (if (string-match "--classify " dired-actual-switches)
        t nil))
  (when (string-match "--classify " dired-actual-switches)
    (jj/dired-sort-remove-classify-switch)))
(defun jj/wdired-after-finish-advice ()
  "Execute when switching from `wdired' to `dired'"
  (when (eq jj/wdired-classify-enabled t)
    ;; can save the current switches in defvar-local and set here instead
    (jj/dired-sort-add-classify-switch)
    (setq jj/wdired-classify-enabled nil)))
(advice-add 'wdired-change-to-wdired-mode :before #'jj/wdired-before-start-advice)
(advice-add 'wdired-change-to-dired-mode :after #'jj/wdired-after-finish-advice)

Answered by J Spen on September 2, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP