Subject: Re: bug#34621: [PATCH] Fix rgrep in dired taking default search file pattern from directory name (e.g. *.11 for django-1.11)

From: Juri Linkov <[email-masked]>
Date: Tue, 09 Apr 2019 23:32:01 +0300

> However, it doesn't cover the case where emacs is in a dired buffer called
> django-1.11 with nothing at point. In this case, *.11 will be suggested
> because buffer-name is used. I'm not sure how to fix this in grep.el
> without an "if is dired" check.

When I tried the change that I suggested to use, I forgot that I have
this customization:

  (add-hook 'dired-after-readin-hook
            (lambda ()
              ;; Set name of dired buffers to absolute directory names.
              (when (stringp dired-directory)
                (rename-buffer (generate-new-buffer-name dired-directory)))))

that renames dired buffers to e.g. "django-1.11/", and due to the
trailing slash, grep-read-files doesn't use it's buffer name.
But since by default there is no trailing slash in dired buffer names,
this is unsuitable.  So I agree with your approach to allow modes
to override using buffer names as candidates.

> diff --git a/lisp/dired.el b/lisp/dired.el
> index fc0b71238b..33abca550a 100644
> --- a/lisp/dired.el
> +++ b/lisp/dired.el
> @@ -4162,6 +4162,17 @@ dired-restore-desktop-buffer
>  (add-to-list 'desktop-buffer-mode-handlers
>  	     '(dired-mode . dired-restore-desktop-buffer))
>  
> +(defun dired-grep-file-name-for-default-pattern ()
> +  "Use file at point as the file for grep's default file-name pattern suggestion.
> +If a directory or nothing is found at point, return nil."
> +  (let ((dired-file-name
> +	  (run-hook-with-args-until-success 'file-name-at-point-functions)))
> +    (if (and dired-file-name
> +	     (not (file-directory-p dired-file-name)))
> +	dired-file-name)))
> +(put 'dired-mode 'grep-file-name-for-default-pattern-function 'dired-grep-file-name-for-default-pattern)

This is an overwhelmingly long name, please use the same name as
the function that uses this feature, i.e. just 'grep-read-files'.
Then when someone reading dired.el will find a line

  (put 'dired-mode 'grep-read-files 'dired-grep-read-files)

it will be clear for them the purpose of this feature.

Please place this change in dired.el after the definition of
'dired-file-name-at-point' that you can use in your dired function
instead of (run-hook-with-args-until-success 'file-name-at-point-functions)

> diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el
> index c0f47159c9..b0bb8e6924 100644
> --- a/lisp/progmodes/grep.el
> +++ b/lisp/progmodes/grep.el
> @@ -959,8 +959,12 @@ grep-read-files
>  The pattern can include shell wildcards.  As whitespace triggers
>  completion when entering a pattern, including it requires
>  quoting, e.g. `\\[quoted-insert]<space>'."
> -  (let* ((bn (or (buffer-file-name)
> -		 (replace-regexp-in-string "<[0-9]+>\\'" "" (buffer-name))))
> +  (let* ((file-name-for-default-pattern-function
> +	   (get major-mode 'grep-file-name-for-default-pattern-function))
> +	 (bn (if file-name-for-default-pattern-function
> +		 (funcall file-name-for-default-pattern-function)
> +	       (or (buffer-file-name)
> +		 (replace-regexp-in-string "<[0-9]+>\\'" "" (buffer-name)))))

If you want you could also add as a 4th option additionally
(run-hook-with-args-until-success 'file-name-at-point-functions)
to automatically support modes other than dired, i.e. other modes
that set file-name-at-point-functions.