Cómo hacer que un comando de shell sea totalmente silencioso (evitando que divida una ventana o abra un nuevo marco / ventana, etc.)

8

¿Es posible ejecutar un comando de shell en silencio (en segundo plano)? Cuando uso async-shell-command, emacs divide las ventanas. Me gustaría que un comando de shell específico esté totalmente en segundo plano (sin ningún efecto visual).

Como ejemplo explícito, tengo el siguiente código (tomado de https://emacs.stackexchange.com/a/7932 ). Abre la versión pdf del archivo tex en el que estoy trabajando. Al ejecutarlo, divide la ventana, me gustaría evitar este comportamiento en esta situación particular.

 (defun my-view-pdf ()
  (interactive)
  (async-shell-command
    (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf")))
Nombre
fuente
3
No se trata de la pregunta abstracta, sino del caso de uso específico: ¿Está utilizando AUCTeX? ¿Alguna razón en particular que no estés usando TeX-view( C-c C-v)?
Dan
@ Dan, el problema es que cuando no hago C-c C-vnada sucede. No entiendo por qué. Si conoce una personalización simple en lo .emacsque hace que C-c C-vfuncione, me encantaría usarla. Mi sistema operativo es Windows y mi visor de pdf se encuentra en C:\Program Files\SumatraPDF\sumatrapdf.exe. En ese enlace, la lista legal ha proporcionado un enlace completo. Solo estoy interesado en hacer que TeX-viewer funcione.
Nombre
No en Windows, así que no puedo decir por qué estás teniendo problemas. Podrías intentar trabajar con TeX-view-program-list.
Dan
Esta pregunta tiene muy buenas respuestas, así que odiaré que esto se cierre. Pero este es un duplicado de esta pregunta: emacs.stackexchange.com/q/5553/115
Kaushal Modi

Respuestas:

8

save-window-excursiones una macro para ejecutar un fragmento de código sin alterar la configuración de la ventana. Algo como esto debería funcionar:

 (defun my-view-pdf ()
  (interactive)
  (save-window-excursion
   (async-shell-command
     (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf"))))
legoscia
fuente
Bonita macro, confirmo que su solución funciona.
Nombre
2
@legoscia que estaba buscando save-window-excursion, que es casi idéntico a su implementación.
bmag
@bmag Estoy interesado en saber sobre la diferencia entre save-window-excursiony save-window-configuration. Parece que ambos trabajan en esta situación.
Nombre
1
@Nombre No hay diferencia, excepto que save-window-excursionutiliza algunas prácticas recomendadas macro para evitar introducir variables en el entorno del cuerpo. Además, save-window-excursionestá integrado en Emacs. Estaba buscando esa macro, pero no la encontré, así que escribí mi propia versión. Afortunadamente, bmag sabía el verdadero.
legoscia
8

Si solo desea generar un proceso en segundo plano, no necesita todas las campanas y silbatos que proporcionan las funciones de comando de shell.

En cambio, puede usar la función call-process. Por ejemplo:

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

Concretamente, esto significa que puede implementar su comando como:

(defun my-view-pdf ()
    (interactive)
    (call-process "SumatraPDF" nil 0 nil
                  (concat (file-name-base (buffer-file-name)) ".pdf")))
Lindydancer
fuente
Traté de aplicar su sugerencia para mi ejemplo 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") ). Aparece el error `Argumento de tipo incorrecto: stringp, comint-output-filter`. No estoy seguro de si la sintaxis que utilicé es correcta.
Nombre
Deberías dejarlo async-shell-commandtodo junto. Debería ser algo así (defun my-pdf-viewer () (interactive) (call-process "SumatraPDF" nil 0 nil (concat (file-name-base (buffer-file-name)) ".pdf")).
Lindydancer
1
Gracias, su solución funciona perfectamente, sólo había una llave que falta, por lo que el código correcto debe ser: (defun my-view-pdf () (interactive) (call-process "SumatraPDF" nil 0 nil (concat (file-name-base (buffer-file-name)) ".pdf"))) .
Nombre
@ Nombre, gracias, he actualizado la respuesta para incluir la función concreta.
Lindydancer
7

Úselo display-buffer-alistcon el display-buffer-no-windowsi está en Emacs 24.4 o posterior.

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

Alternativamente, use grillete :

(setq shackle-rules '(("*Async Shell Command*" :ignore t)))
wasamasa
fuente
Usando (setq display-buffer-alist '(("\`\\*Async Shell Command\\*\\'" display-buffer-no-window)))me sale el error apply: Wrong type argument: sequencep, display-buffer-no-window.
Nombre
Ah, claro, display-buffer-no-windowse introdujo en Emacs 24.4, por lo que no funcionará. Mi paquete, por otro lado, debería funcionar en 24.3.
wasamasa
El backporting display-buffer-no-windowes una tercera opción, simplemente inserte (defun display-buffer-no-window (_buffer alist) (when (cdr (assq 'allow-no-window alist)) 'fail))en su configuración de Emacs.
wasamasa
Traté de aplicar tu último comentario juntando las cosas (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")))) . Pero después de ejecutar my-view-pdf, emacs divide la ventana y *Async Shell Command*se muestra.
Nombre
Confirmo que su solución funciona perfectamente para la versión 24.4 o posterior.
Nombre