Llamar de manera eficiente a múltiples variantes del comando grep

Oct 01 2020

El contexto

Normalmente ejecuto las siguientes variantes del grepcomando

  • grep --color -RHIn '' (buscar en el directorio de trabajo actual)
  • grep --color -RHIn --include='*.org' '' ~/repos/dotfiles/emacs (busque en todos los archivos Org presentes en un directorio que contiene configuraciones de otros usuarios de Emacs)
  • grep --color -RHIn --include='init.el' ~/repos/dotfiles/emacs(busque en todos los init.elarchivos ubicados en el directorio mencionado anteriormente)
  • grep --color -RHIn --include='*.org' --include='*.el' '' ~/repos/dotfiles/emacs(busque en todos los archivos .ely .orgarchivos ubicados en el directorio mencionado anteriormente)

Siempre que quiero usar una de esas variantes, presiono y las escribo M-x grepmanualmente.

Estoy buscando formas que puedan ayudarme a evitar escribir manualmente esas variantes cada vez que quiero ejecutar cualquiera de esas

Contexto adicional

He intentado lo siguiente

(let ((grep-command "grep --color -RHIn ''")) (call-interactively grep))
(let ((grep-command "grep --color -RHIn --include='*.org' '' ~/repos/dotfiles/emacs")) (call-interactively grep))
...

El problema con esto es que call-interactivelyconsidera el valor global de la variable en grep-commandlugar del proporcionado por let. Si esto funcionó, solo necesitaría hacer

; Variant 1

(global-set-key (kbd "C-x g 1")
                (let ((grep-command "grep --color -RHIn ''")) (call-interactively grep)))

; Variant 2

(global-set-key (kbd "C-x g 2")
                (let ((grep-command "grep --color -RHIn --include='*.org' ''")) (call-interactively grep)))

(... more variants)

La pregunta

¿Conoce una mejor manera de automatizar esto para que no tenga que escribir manualmente ninguna de las grepvariantes? ¿Existe un paquete que mostraría algo así como un menú que mostraría un elemento de menú con una descripción para cada variante de tal manera que cuando se selecciona un elemento, grepse ejecuta con la variante correspondiente del elemento seleccionado?

Si no tiene idea, le agradecería mucho que me explicara cómo puedo hacer un comando ( (call-interactively 'grep)en este escenario) para considerar el valor de una variable proporcionada por let.

Respuestas

2 lawlist Oct 01 2020 at 08:51

El OP puede estar interesado en la hydrabiblioteca de Abo-Abo:

https://github.com/abo-abo/hydra

Aquí hay un ejemplo personalizado que no se basa en hydraseleccionar entre opciones predefinidas. La letra cal comienzo de la interactivedeclaración es un código interactivo:https://www.gnu.org/software/emacs/manual/html_node/elisp/Interactive-Codes.htmlPuede haber una mejor manera de obtener una línea de comando predeterminado preferido como la primera opción en el minibuffer que no implica dejar de unión grep-host-defaults-alista nil, pero esto parece que funciona:

;;; Needed so that `pick-a-grep' works correctly the first time it is tried;
;;; otherwise, the let-bound `grep-command' gets ignored the first time around.
(require 'grep)

(defun pick-a-grep (choice)
  "Choices for selecting from pre-defined `grep-command'."
  (interactive "c[3] is one too many. | [D]o you like eggs?")
  (cond
    ((eq choice ?3)
      (let ((grep-host-defaults-alist nil)
            (grep-command "grep --color -RHIn ''"))
        (call-interactively 'grep)))
    ((eq choice ?D)
      (let ((grep-host-defaults-alist nil)
            (grep-command "grep --color -RHIn --include='*.org' '' ~/repos/dotfiles/emacs"))
        (call-interactively 'grep)))
    (t
      (message "You did not select any of the expected choices."))))
doltes Oct 03 2020 at 08:28

Como se sugiere en la respuesta de @lawlist, puede lograr esto con el paquete hydra .

(require 'grep)

(global-set-key (kbd "C-. g")
                (defhydra hydra-grep-variants (:color blue)
"
_r_: Search recursively
_co_: Search configurations (*.org)
_ce_: Search configurations (*.el)
_cm_: Search configurations (*.org, *.el)
"
                   ("r" (let ((grep-host-defaults-alist nil)
                              (grep-command "grep --color -RHIn '' ."))
                          (call-interactively 'grep)))
                   ("co" (let ((grep-host-defaults-alist nil)
                               (grep-command "grep --color -RHIn --include='*.org' '' ~/SourceCode/dotfiles/emacs"))
                           (call-interactively 'grep)))
                   ("ce" (let ((grep-host-defaults-alist nil)
                               (grep-find-command (concat "find " path/configs " -type f -name '*.el' ! -path '*/elpa/*' -exec grep --color -HIn '' {} +")))
                           (call-interactively 'find-grep)))
                   ("cm" (let ((grep-host-defaults-alist nil)
                               (grep-find-command (concat "find " path/configs " -type f \\( -name '*.org' -o -name '*.el' \\) ! -path '*/elpa/*' -exec grep --color -HIn '' {} +")))
                           (call-interactively 'find-grep)))))

Simplemente presione C-. C-g {key}para elegir una grepvariante.