Como tornar um comando shell totalmente silencioso (impedindo que ele divida a janela ou abra um novo quadro / janela etc)

8

É possível executar um comando shell silenciosamente (em segundo plano)? Quando eu uso async-shell-command, o emacs divide as janelas. Eu gostaria que um comando shell específico estivesse totalmente em segundo plano (sem nenhum efeito visual).

Como exemplo explícito, eu tenho o seguinte código (emprestado de https://emacs.stackexchange.com/a/7932 ). Abre a versão pdf do arquivo tex no qual estou trabalhando. Ao executá-lo, ele divide a janela. Gostaria de evitar esse comportamento nessa situação específica.

 (defun my-view-pdf ()
  (interactive)
  (async-shell-command
    (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf")))
Nome
fonte
3
Não sobre a questão abstrata, mas o caso de uso específico: você está usando o AUCTeX? Algum motivo específico para você não estar usando TeX-view( C-c C-v)?
Dan
@ Dan, o problema é que, quando não faço, C-c C-vnada acontece. Eu não entendo o porquê. Se você conhece uma personalização simples na .emacsqual C-c C-vfunciona, ficaria feliz em usá-la. Meu SO é Windows e meu visualizador de pdf está localizado em C:\Program Files\SumatraPDF\sumatrapdf.exe. Nesse link, a lista de leis forneceu um link abrangente. Estou interessado apenas em fazer o visualizador TeX funcionar.
Nome
Não no Windows, então não sei dizer por que você está tendo problemas. Você pode tentar trabalhar TeX-view-program-list.
Dan
Esta pergunta tem respostas muito boas, então odeio que isso seja encerrado. Mas esta é uma duplicata de esta pergunta: emacs.stackexchange.com/q/5553/115
Kaushal Modi

Respostas:

8

save-window-excursioné uma macro para executar um pedaço de código sem alterar a configuração da janela. Algo assim deve funcionar:

 (defun my-view-pdf ()
  (interactive)
  (save-window-excursion
   (async-shell-command
     (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf"))))
legoscia
fonte
Boa macro, confirmo que sua solução funciona.
Nome
2
@legoscia Você estava procurando save-window-excursion, quase idêntico à sua implementação.
BMAG
@mag Estou interessado em saber sobre a diferença entre save-window-excursione save-window-configuration. Parece que os dois trabalham nessa situação.
Name
1
@Name Não há diferença, exceto que save-window-excursionutiliza algumas práticas recomendadas de macro para evitar a introdução de variáveis ​​no ambiente do corpo. Além disso, save-window-excursioné incorporado ao Emacs. Eu estava procurando por essa macro, mas não a encontrei, então escrevi minha própria versão. Felizmente, o bmag conhecia o verdadeiro.
legoscia
8

Se você apenas deseja gerar um processo em segundo plano, não precisa de todos os sinos e apitos que as funções de comando do shell fornecem.

Em vez disso, você pode usar a função call-process. Por exemplo:

(call-process
 "a_command"
 nil
 0                                  ; <- Discard and don't wait
 nil
 "arg1"
 "arg2")

Concretamente, isso significa que você pode implementar seu comando como:

(defun my-view-pdf ()
    (interactive)
    (call-process "SumatraPDF" nil 0 nil
                  (concat (file-name-base (buffer-file-name)) ".pdf")))
Lindydancer
fonte
Eu tentei aplicar sua sugestão para o meu exemplo específico (defun my-pdf-viewer () (interactive) (call-process (async-shell-command (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf")) nil 0 ; <- Discard and don't wait nil "arg1" "arg2") ). Recebo o erro `Argumento de tipo errado: stringp, comint-output-filter`. Não tenho certeza se a sintaxe que usei está correta.
Nome
Você deve largar async-shell-commandtodos juntos. Deve ser algo parecido (defun my-pdf-viewer () (interactive) (call-process "SumatraPDF" nil 0 nil (concat (file-name-base (buffer-file-name)) ".pdf")).
Lindydancer
1
Obrigado, sua solução funciona perfeitamente, havia apenas uma cinta faltando, então o código correto deve ser: (defun my-view-pdf () (interactive) (call-process "SumatraPDF" nil 0 nil (concat (file-name-base (buffer-file-name)) ".pdf"))) .
Name
@Name, obrigado, atualizei a resposta para incluir a função concreta.
Lindydancer
7

Use display-buffer-alistcom o display-buffer-no-windowse você estiver no Emacs 24.4 ou posterior.

(setq display-buffer-alist '(("\\`\\*Async Shell Command\\*\\'" display-buffer-no-window)))

Como alternativa, use a manilha :

(setq shackle-rules '(("*Async Shell Command*" :ignore t)))
wasamasa
fonte
Usando (setq display-buffer-alist '(("\`\\*Async Shell Command\\*\\'" display-buffer-no-window)))eu recebo o erro apply: Wrong type argument: sequencep, display-buffer-no-window.
Nome
Ah, certo, display-buffer-no-windowfoi introduzido no Emacs 24.4, para que não funcione. Meu pacote, por outro lado, deve funcionar em 24.3.
wasamasa
Backporting display-buffer-no-windowé uma terceira opção, basta inserir (defun display-buffer-no-window (_buffer alist) (when (cdr (assq 'allow-no-window alist)) 'fail))na configuração do Emacs.
wasamasa
Tentei aplicar seu último comentário, juntando tudo (defun display-buffer-no-window (_buffer alist) (when (cdr (assq 'allow-no-window alist)) 'fail)) (setq display-buffer-alist '(("\`\\*Async Shell Command\\*\\'" display-buffer-no-window))) (defun my-view-pdf () (interactive) (progn (async-shell-command (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf")))) . Porém, após a execução my-view-pdf, o emacs divide a janela e *Async Shell Command*é mostrado.
Nome
Confirmo que sua solução funciona perfeitamente para a versão 24.4 ou posterior.
Nome