Subject: Re: bug#18716: Patch for this bug

From: Reuben Thomas <[email-masked]>
Date: Mon, 28 Nov 2016 21:32:03 +0000

On 26 November 2016 at 18:29, Ken Brown <[email-masked]> wrote:

> On 11/26/2016 12:54 PM, Reuben Thomas wrote:
>
>> Sounds like a good compromise.  I agree about the default, except that
>>> it should default to case-insensitive matches on case-insensitive
>>> filesystems (Windows etc.)
>>>
>> I have now implemented this (apologies for the delay). I attach revised
>> patches.
>>
>
> As of commit 2809012 we have a new primitive,
> file-name-case-insensitive-p, that can be used to determine whether or not
> a filesystem is case insensitive.  This is better than relying on system
> type.  For example, on both Cygwin and macOS, it's possible that some
> filesystems are case-insensitive and others aren't.

​Thanks for the heads up, that's great news! It bothered me that there was
no easy way to do this previously.

​I updated my patch so that dired-omit-case-fold is now a three-valued
variable which defaults to 'filesystem, and a helper function that checks
(filename-case-sensitive-p dired-directory) when this value is used.

I've added info and NEWS documentation for dired-omit-case-fold.

-- 
http://rrt.sc3d.org
From 792edb24a8d7b617fcc8fbfa62f350fd01552d93 Mon Sep 17 00:00:00 2001
From: Reuben Thomas <[email-masked]>
Date: Tue, 8 Nov 2016 17:42:24 +0000
Subject: [PATCH 2/4] Allow files to be matched case-sensitively in dired-x

* lisp/dired-x.el (dired-mark-unmarked-files): Add an argument which
controls case folding for matching the regex (Bug#18716).
(dired-omit-case-fold): New variable.  Defaults to `t' on case-sensitive
systems, `nil' otherwise.
(dired-mark-omitted, dired-omit-expunge): Use dired-omit-case-fold.
* doc/misc/dired-x.texi, etc/NEWS: Document dired-omit-case-fold.
---
 doc/misc/dired-x.texi | 11 +++++++++++
 etc/NEWS              |  6 ++++++
 lisp/dired-x.el       | 37 ++++++++++++++++++++++++++++++++-----
 3 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/doc/misc/dired-x.texi b/doc/misc/dired-x.texi
index db01896..4b5ca6d 100644
--- a/doc/misc/dired-x.texi
+++ b/doc/misc/dired-x.texi
@@ -369,6 +369,17 @@ Omitting Variables
 If non-@code{nil}, a list of extensions (strings) to omit from Dired listings.
 Its format is the same as that of @code{completion-ignored-extensions}.
 
+@vindex dired-omit-case-fold
+@item dired-omit-case-fold
+
+Default:  @code{filesystem}
+
+By default, @code{dired-omit-mode} will match filenames and extensions
+case-sensitively on Dired buffers visiting case-sensitive filesystems,
+and case-insensitively on case-insensitive filesystems.  Set to
+@code{nil} to be always case-sensitive, and @code{t} to be always
+case-sensitive.
+
 @vindex dired-omit-localp
 @item dired-omit-localp
 
diff --git a/etc/NEWS b/etc/NEWS
index cbce027..33b8a42 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -83,6 +83,12 @@ of curved quotes for 'electric-quote-mode', allowing user to choose
 the types of quotes to be used.
 
 +++
+** The new user variable 'dired-omit-case-fold' allows the
+case-sensitivity of dired-omit-mode to be configured.  It defaults to
+the same sensitivity as that of the filesystem for the corresponding
+dired buffer.
+
++++
 ** Emacs now uses double buffering to reduce flicker when editing and
 resizing graphical Emacs frames on the X Window System.  This support
 requires the DOUBLE-BUFFER extension, which major X servers have
diff --git a/lisp/dired-x.el b/lisp/dired-x.el
index 8313905..8f20955 100644
--- a/lisp/dired-x.el
+++ b/lisp/dired-x.el
@@ -133,6 +133,26 @@ dired-omit-size-limit
   :type '(choice (const :tag "no maximum" nil) integer)
   :group 'dired-x)
 
+(defcustom dired-omit-case-fold 'filesystem
+  "Whether `dired-omit-mode' will use case-folding to match the
+regexp of files to omit.  When nil, always be case-sensitive; when
+t, always be case-insensitive; the default value, 'filesystem,
+causes case folding to be used on case-insensitive filesystems
+only."
+  :type '(choice (const :tag "Always case-sensitive" nil)
+		 (const :tag "Always case-insensitive" t)
+		 (const :tag "According to filesystem" filesystem))
+  :group 'dired-x
+  :version "26.1")
+
+(defun dired-omit-case-fold-p (dir)
+  "Return t if, according to `dired-omit-case-fold',
+  `dired-omit-mode' should use case folding to interpret its
+  regexp in directory DIR."
+  (if (eq dired-omit-case-fold 'filesystem)
+      (file-name-case-sensitive-p dir)
+    dired-omit-case-fold))
+
 ;; For backward compatibility
 (define-obsolete-variable-alias 'dired-omit-files-p 'dired-omit-mode "22.1")
 (define-minor-mode dired-omit-mode
@@ -507,7 +527,8 @@ dired-mark-omitted
   "Mark files matching `dired-omit-files' and `dired-omit-extensions'."
   (interactive)
   (let ((dired-omit-mode nil)) (revert-buffer)) ;; Show omitted files
-  (dired-mark-unmarked-files (dired-omit-regexp) nil nil dired-omit-localp))
+  (dired-mark-unmarked-files (dired-omit-regexp) nil nil dired-omit-localp
+                             (dired-omit-case-fold-p dired-directory)))
 
 (defcustom dired-omit-extensions
   (append completion-ignored-extensions
@@ -551,7 +572,8 @@ dired-omit-expunge
         (or (string= omit-re "")
             (let ((dired-marker-char dired-omit-marker-char))
               (when dired-omit-verbose (message "Omitting..."))
-              (if (dired-mark-unmarked-files omit-re nil nil dired-omit-localp)
+              (if (dired-mark-unmarked-files omit-re nil nil dired-omit-localp
+                                             (dired-omit-case-fold-p dired-directory))
                   (progn
                     (setq count (dired-do-kill-lines
 				 nil
@@ -577,12 +599,14 @@ dired-omit-regexp
             "")))
 
 ;; Returns t if any work was done, nil otherwise.
-(defun dired-mark-unmarked-files (regexp msg &optional unflag-p localp)
+(defun dired-mark-unmarked-files (regexp msg &optional unflag-p localp case-fold-p)
   "Mark unmarked files matching REGEXP, displaying MSG.
 REGEXP is matched against the entire file name.  When called
 interactively, prompt for REGEXP.
 With prefix argument, unflag all those files.
-Optional fourth argument LOCALP is as in `dired-get-filename'."
+Optional fourth argument LOCALP is as in `dired-get-filename'.
+Optional fifth argument CASE-FOLD-P specifies the value of
+`case-fold-search' used for matching REGEXP."
   (interactive
    (list (read-regexp
 	  "Mark unmarked files matching regexp (default all): "
@@ -594,7 +618,10 @@ dired-mark-unmarked-files
       ;; not already marked
       (looking-at-p " ")
       ;; uninteresting
-      (let ((fn (dired-get-filename localp t)))
+      (let ((fn (dired-get-filename localp t))
+            ;; Match patterns case-insensitively on case-insensitive
+            ;; systems
+            (case-fold-search case-fold-p))
         (and fn (string-match-p regexp fn))))
      msg)))
 
-- 
2.7.4

From 85ac884a98e0e1a25e1401e1baeeb992325cc634 Mon Sep 17 00:00:00 2001
From: Reuben Thomas <[email-masked]>
Date: Tue, 8 Nov 2016 22:01:59 +0000
Subject: [PATCH 3/4] Remove pre-customize dired-x.el documentation

* lisp/dired-x.el (Commentary): Remove USAGE section explaining how to
use dired-x from .emacs.  It is now fully customizable.
* lisp/dired-x.el (dired-guess-shell-alist-user): Remove explanation of
how to set this custom variable in .emacs.  It should be customized.
---
 lisp/dired-x.el | 26 +-------------------------
 1 file changed, 1 insertion(+), 25 deletions(-)

diff --git a/lisp/dired-x.el b/lisp/dired-x.el
index 8f20955..6a3143e 100644
--- a/lisp/dired-x.el
+++ b/lisp/dired-x.el
@@ -29,20 +29,6 @@
 ;; This is based on Sebastian Kremer's excellent dired-x.el (Dired Extra),
 ;; version 1.191, adapted for GNU Emacs.  See the `dired-x' info pages.
 
-;; USAGE: In your ~/.emacs,
-;;
-;; (add-hook 'dired-load-hook
-;;           (lambda ()
-;;                       (load "dired-x")
-;;                       ;; Set global variables here.  For example:
-;;                       ;; (setq dired-guess-shell-gnutar "gtar")
-;;                       ))
-;; (add-hook 'dired-mode-hook
-;;           (lambda ()
-;;                       ;; Set buffer-local variables here.  For example:
-;;                       ;; (dired-omit-mode 1)
-;;                       ))
-;;
 ;; At load time dired-x.el will install itself and bind some dired keys.
 ;; Some dired.el and dired-aux.el functions have extra features if
 ;; dired-x is loaded.
@@ -1106,17 +1092,7 @@ dired-guess-shell-alist-user
 with \\[previous-history-element] (M-p) .
 
 The variable `dired-guess-shell-case-fold-search' controls whether
-REGEXP is matched case-sensitively.
-
-You can set this variable in your ~/.emacs.  For example, to add rules for
-`.foo' and `.bar' files, write
-
- (setq dired-guess-shell-alist-user
-        '((\"\\\\.foo\\\\'\" \"FOO-COMMAND\")
-          (\"\\\\.bar\\\\'\"
-           (if condition
-              \"BAR-COMMAND-1\"
-            \"BAR-COMMAND-2\"))))"
+REGEXP is matched case-sensitively."
   :group 'dired-x
   :type '(alist :key-type regexp :value-type (repeat sexp)))
 
-- 
2.7.4

From 888b62451a3b9e9fe2d175be4d18b2dc30c59714 Mon Sep 17 00:00:00 2001
From: Reuben Thomas <[email-masked]>
Date: Tue, 8 Nov 2016 22:04:52 +0000
Subject: [PATCH 4/4] Remove obsolete comments and commented code from
 dired-x.el

* lisp/dired-x.el (dired-mark-sexp): Remove a query from 1993 and its
1997 answer about whether dired-mark-sexp is used.
* lisp/dired-x.el (dired-buffers-for-dir-exact): Remove this function
commented out since before dired-x.el was added to RCS in 1994.
---
 lisp/dired-x.el | 26 --------------------------
 1 file changed, 26 deletions(-)

diff --git a/lisp/dired-x.el b/lisp/dired-x.el
index 6a3143e..34a02ec 100644
--- a/lisp/dired-x.el
+++ b/lisp/dired-x.el
@@ -1400,29 +1400,6 @@ dired-buffer-more-recently-used-p
        (memq buffer1 (buffer-list))
        (not (memq buffer1 (memq buffer2 (buffer-list))))))
 
-;; Same thing as `dired-buffers-for-dir' of dired.el? - lrd 11/23/93
-;; (defun dired-buffers-for-dir-exact (dir)
-;; ;; Return a list of buffers that dired DIR (a directory or wildcard)
-;; ;; at top level, or as subdirectory.
-;; ;; Top level matches must match the wildcard part too, if any.
-;; ;; The list is in reverse order of buffer creation, most recent last.
-;; ;; As a side effect, killed dired buffers for DIR are removed from
-;; ;; dired-buffers.
-;;   (let ((alist dired-buffers) result elt)
-;;     (while alist
-;;       (setq elt (car alist)
-;;             alist (cdr alist))
-;;       (let ((buf (cdr elt)))
-;;         (if (buffer-name buf)
-;;             ;; Top level must match exactly against dired-directory in
-;;             ;; case one of them is a wildcard.
-;;             (if (or (equal dir (with-current-buffer buf dired-directory))
-;;                     (assoc dir (with-current-buffer buf dired-subdir-alist)))
-;;                 (setq result (cons buf result)))
-;;           ;; else buffer is killed - clean up:
-;;           (setq dired-buffers (delq elt dired-buffers)))))
-;;     result))
-
 
 ;; Needed if ls -lh is supported and also for GNU ls -ls.
 (defun dired-x--string-to-number (str)
@@ -1440,9 +1417,6 @@ dired-x--string-to-number
           (setq val (* 1024.0 val)))))
     val))
 
-;; Does anyone use this? - lrd 6/29/93.
-;; Apparently people do use it. - lrd 12/22/97.
-
 (defun dired-mark-sexp (predicate &optional unflag-p)
   "Mark files for which PREDICATE returns non-nil.
 With a prefix arg, unmark or unflag those files instead.
-- 
2.7.4