Comment rendre une commande shell totalement silencieuse (l'empêcher de diviser la fenêtre ou d'ouvrir un nouveau cadre / fenêtre, etc.)

8

Est-il possible d'exécuter une commande shell en silence (en arrière-plan)? Lorsque j'utilise async-shell-command, emacs divise les fenêtres. J'aimerais qu'une commande shell spécifique soit totalement en arrière-plan (sans aucun effet visuel).

À titre d'exemple explicite, j'ai le code suivant (emprunté à https://emacs.stackexchange.com/a/7932 ). Il ouvre la version pdf du fichier tex sur lequel je travaille. Lors de son exécution, il divise la fenêtre, je voudrais l'empêcher de ce comportement dans cette situation particulière.

 (defun my-view-pdf ()
  (interactive)
  (async-shell-command
    (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf")))
Nom
la source
3
Pas sur la question abstraite, mais sur le cas d'utilisation spécifique: utilisez-vous AUCTeX? Une raison particulière que vous n'utilisez pas TeX-view( C-c C-v)?
Dan
@Dan le problème est que lorsque je ne fais C-c C-vrien, il ne se passe rien. Je ne comprends pas pourquoi. Si vous connaissez une personnalisation simple dans le .emacsqui fait C-c C-vfonctionner, je serais heureux de l'utiliser. Mon système d'exploitation est Windows et ma visionneuse PDF se trouve à C:\Program Files\SumatraPDF\sumatrapdf.exe. Dans ce lien, lawlist a fourni un lien complet. Je ne souhaite que faire fonctionner TeX-viewer.
Nom
Pas sur Windows, donc je ne peux pas dire pourquoi vous rencontrez des problèmes. Vous pourriez essayer de travailler avec TeX-view-program-list.
Dan
Cette question a de très bonnes réponses, donc je détesterai que cela soit clos. Mais ceci est un double de cette question: emacs.stackexchange.com/q/5553/115
Kaushal Modi

Réponses:

8

save-window-excursionest une macro pour exécuter un morceau de code sans modifier la configuration de la fenêtre. Quelque chose comme ça devrait fonctionner:

 (defun my-view-pdf ()
  (interactive)
  (save-window-excursion
   (async-shell-command
     (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf"))))
legoscia
la source
Belle macro, je confirme que votre solution fonctionne.
Nom du
2
@legoscia que vous cherchiez save-window-excursion, ce qui est presque identique à votre implémentation.
bmag
@bmag Je souhaite connaître la différence entre save-window-excursionet save-window-configuration. Il semble que les deux fonctionnent dans cette situation.
Nom
1
@Name Aucune différence, sauf qu'il save-window-excursionutilise certaines meilleures pratiques de macro pour éviter d'introduire des variables dans l'environnement du corps. Il save-window-excursionest également intégré à Emacs. Je cherchais cette macro, mais je ne l'ai pas trouvée, j'ai donc écrit ma propre version. Heureusement, bmag connaissait le vrai.
legoscia
8

Si vous souhaitez simplement lancer un processus en arrière-plan, vous n'avez pas besoin de toutes les cloches que les fonctions de commande de shell fournissent.

Au lieu de cela, vous pouvez utiliser la fonction call-process. Par exemple:

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

Concrètement, cela signifie que vous pouvez implémenter votre commande comme:

(defun my-view-pdf ()
    (interactive)
    (call-process "SumatraPDF" nil 0 nil
                  (concat (file-name-base (buffer-file-name)) ".pdf")))
Lindydancer
la source
J'ai essayé d'appliquer votre suggestion pour mon exemple spécifique (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") ). J'obtiens l'erreur `Mauvais argument de type: stringp, comint-output-filter`. Je ne sais pas si la syntaxe que j'ai utilisée est correcte.
Nom
Vous devez laisser tomber async-shell-commandtous ensemble. Cela devrait ressembler à quelque chose (defun my-pdf-viewer () (interactive) (call-process "SumatraPDF" nil 0 nil (concat (file-name-base (buffer-file-name)) ".pdf")).
Lindydancer
1
Merci, votre solution fonctionne parfaitement, il n'y avait qu'une accolade manquante, devrait donc être le bon code: (defun my-view-pdf () (interactive) (call-process "SumatraPDF" nil 0 nil (concat (file-name-base (buffer-file-name)) ".pdf"))) .
Nom du
@Name, merci, j'ai mis à jour la réponse pour inclure la fonction concrète.
Lindydancer
7

À utiliser display-buffer-alistavec display-buffer-no-windowsi vous utilisez Emacs 24.4 ou une version ultérieure.

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

Vous pouvez également utiliser une manille :

(setq shackle-rules '(("*Async Shell Command*" :ignore t)))
wasamasa
la source
J'obtiens (setq display-buffer-alist '(("\`\\*Async Shell Command\\*\\'" display-buffer-no-window)))l'erreur apply: Wrong type argument: sequencep, display-buffer-no-window.
Nom du
Oh display-buffer-no-windowoui , a été introduit dans Emacs 24.4, donc cela ne fonctionnera pas. Mon paquet devrait par contre fonctionner sur 24.3.
wasamasa
Le rétroportage display-buffer-no-windowest une troisième option, il suffit de l'insérer (defun display-buffer-no-window (_buffer alist) (when (cdr (assq 'allow-no-window alist)) 'fail))dans votre configuration Emacs.
wasamasa
J'ai essayé d'appliquer votre dernier commentaire en rassemblant les choses (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")))) . Mais après l'exécution my-view-pdf, emacs divise la fenêtre et *Async Shell Command*s'affiche.
Nom du
Je confirme que votre solution fonctionne parfaitement pour la version 24.4 ou ultérieure.
Nom