Chamar com eficiência várias variantes do comando grep
O contexto
Eu normalmente executo as seguintes variantes do grepcomando
grep --color -RHIn ''(pesquise no diretório de trabalho atual)grep --color -RHIn --include='*.org' '' ~/repos/dotfiles/emacs(pesquise em todos os arquivos Org presentes em um diretório que contém configurações de outros usuários Emacs)grep --color -RHIn --include='init.el' ~/repos/dotfiles/emacs(pesquise em todos osinit.elarquivos localizados no diretório mencionado acima)grep --color -RHIn --include='*.org' --include='*.el' '' ~/repos/dotfiles/emacs(pesquise em todos os arquivos.ele.orgarquivos localizados no diretório mencionado acima)
Sempre que desejo usar uma dessas variantes, pressiono M-x grepe as digito manualmente.
Estou procurando maneiras que podem me ajudar a evitar digitar manualmente essas variantes sempre que quiser executar qualquer uma delas
Contexto adicional
Eu tentei o seguinte
(let ((grep-command "grep --color -RHIn ''")) (call-interactively grep))
(let ((grep-command "grep --color -RHIn --include='*.org' '' ~/repos/dotfiles/emacs")) (call-interactively grep))
...
O problema com isso é que call-interactivelyconsidera o valor global da variável, em grep-commandvez daquele fornecido por let. Se isso funcionasse, eu só precisaria fazer
; 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)
A questão
Você conhece uma maneira melhor de automatizar isso para que eu não precise digitar manualmente nenhuma das grepvariantes? Existe um pacote que exibiria algo como um menu que exibisse um item de menu com uma descrição para cada variante de forma que, quando um item for selecionado, grepseja executado com a variante correspondente do item selecionado?
Se você não tem nenhuma ideia, eu realmente apreciaria se você pudesse explicar como posso fazer um comando ( (call-interactively 'grep), neste cenário) para considerar o valor de uma variável fornecida por let.
Respostas
O OP pode estar interessado na hydrabiblioteca de Abo-Abo:
https://github.com/abo-abo/hydra
Aqui está um exemplo personalizado que não depende da hydraseleção de opções predefinidas. A letra cno início da interactivedeclaração é um código interativo:https://www.gnu.org/software/emacs/manual/html_node/elisp/Interactive-Codes.htmlPode haver uma maneira melhor para obter uma linha de comando padrão preferido como a primeira escolha no minibuffer que não envolve deixar de ligação grep-host-defaults-alistpara nil, mas isso parece funcionar:
;;; 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."))))
Como sugerido na resposta de @lawlist, você pode fazer isso com o pacote 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)))))
Basta pressionar C-. C-g {key}para escolher uma grepvariante.