Subject: Re: bug#41250: 28.0.50; Dired displays unconditionally ls-switches on modeline

From: Arthur Miller <[email-masked]>
Date: Mon, 18 May 2020 17:08:40 +0200

Stefan Kangas <[email-masked]> writes:

> Arthur Miller <[email-masked]> writes:
>
>> Another question: can I assume, at this time of civilisation
>> development, that everybody has GNU ls, since binutils, or coreutils, or
>> what is the name, is probably default on most *nix distros, as well as
>> on msys2 which is needed to build on Windows. No idea how Mac people are
>> doing in that regard though?
>
> MacOS has BSD userland, as does *BSD.
>
> You can install it and use GNU coreutils optionally, but I would expect
> only a minority of users to do that.
>
> Best regards,
> Stefan Kangas
Alright, thanks. I can then either opt for status quo, as it is now
(just date and name) or add extra sort options and bool flag in
defcustom for users to enable if they now they have gnu ls. I could also
add utility funciton to print version of ls in say message buffer.

Anyway I have red the manual about propertize and seen some examples in
code that Eli pointed me to, online aw well, and as I understand this
feature (help-echo) is fairly trivial and easy to use. I like it, it
seems really usefull. However, for some reason modeline ignores my
propertized string :-).

Below is another sketch for this. Instead of displaying actual switches,
I display string "by user". I tested with elipsis at the end, "by
user...", but I don't think it lookes so nice on modeline. The strategy
is to show the tooltip with switches when user hoovers with pointer over
the modeline (I completely missed that feature of Emacs since I use
mouse and modeline so little :-)).

Attached is a patch with this sketch, the only problem seems that I
missundestand something, seems modeline does not display the tooltip.

I am sorry for me being such noob, I will look around more, but if
somebody can point out the misstake it will be helpful.

--- dired.el	2020-05-14 03:06:34.046112281 +0200
+++ lisp/dired.el	2020-05-18 13:37:21.934674831 +0200
@@ -223,6 +223,14 @@
 (define-obsolete-variable-alias 'dired-free-space-args
   'directory-free-space-args "27.1")
 
+(defcustom dired-sort-mode-line-info t
+  "Run when dired is displaying it's info on modeline. Default hook is
+dired-set-sort-mode-line, which displays sorting order used in current
+  dired buffer. Every hook in the list should return a string that
+  will be appended to dired info already shown on modeline."
+  :group 'dired
+  :type 'boolean)
+
 ;;; Hook variables
 
 (defcustom dired-load-hook nil
@@ -4114,24 +4122,43 @@
   "Non-nil means the Dired sort command is disabled.
 The idea is to set this buffer-locally in special Dired buffers.")
 
-(defun dired-sort-set-mode-line ()
-  ;; Set mode line display according to dired-actual-switches.
-  ;; Mode line display of "by name" or "by date" guarantees the user a
-  ;; match with the corresponding regexps.  Non-matching switches are
-  ;; shown literally.
+(defun dired-set-mode-line ()
+  ;; Flush dired info to mode-line (eval all dired-mode-line-hook)
+  ;; If dired-mode-line-hook is nil, it means user has manually
+  ;; disabled displaying of Dired info on mode-line, so let's respect
+  ;; the user decision.
   (when (eq major-mode 'dired-mode)
-    (setq mode-name
-	  (let (case-fold-search)
-	    (cond ((string-match-p
-		    dired-sort-by-name-regexp dired-actual-switches)
-		   "Dired by name")
-		  ((string-match-p
-		    dired-sort-by-date-regexp dired-actual-switches)
-		   "Dired by date")
-		  (t
-		   (concat "Dired " dired-actual-switches)))))
+    (if dired-sort-mode-line-info
+        (setq mode-name
+              (concat
+               mode-name
+               (propertize
+                (dired-sort-set-mode-line)
+                'help-echo dired-actual-switches)))
+      (setq mode-name "Dired")) ;; reset name if dired-mode-line-hook is nil
     (force-mode-line-update)))
 
+(defun dired-sort-set-mode-line ()
+  "Set mode line display according to dired-actual-switches.
+  Mode line display of \"by name\" or \"by date\" guarantees the user a
+  match with the corresponding regexps.  Non-matching switches are
+  shown as \"by user\". has not disabled displaying them by
+  customizing dired-display-listing-switches variable."
+  (when (eq major-mode 'dired-mode)
+    (let* ((mode-line-info)
+           (case-fold-search))
+      (cond ((string-match-p
+	      dired-sort-by-name-regexp dired-actual-switches)
+             (setq mode-line-info " by name"))
+
+            ((string-match-p
+	      dired-sort-by-date-regexp dired-actual-switches)
+             (setq mode-line-info " by date"))
+
+            (t
+             (setq mode-line-info " by user")))
+      mode-line-info)))
+
 (define-obsolete-function-alias 'dired-sort-set-modeline
   #'dired-sort-set-mode-line "24.3")
 
@@ -4174,7 +4201,7 @@
                                         dired-actual-switches)
                         "t"
                       " -t")))))
-  (dired-sort-set-mode-line)
+  (dired-set-mode-line)
   (revert-buffer))
 
 ;; Some user code loads dired especially for this.
@@ -4197,7 +4224,7 @@
 With optional second arg NO-REVERT, don't refresh the listing afterwards."
   (dired-sort-R-check switches)
   (setq dired-actual-switches switches)
-  (dired-sort-set-mode-line)
+  (dired-set-mode-line)
   (or no-revert (revert-buffer)))
 
 (defvar-local dired-subdir-alist-pre-R nil