So machen Sie einen Shell-Befehl völlig stumm (verhindern, dass er das Fenster teilt oder einen neuen Frame / ein neues Fenster öffnet usw.)

8

Ist es möglich, einen Shell-Befehl still (im Hintergrund) auszuführen? Wenn ich benutze async-shell-command, teilen Emacs die Fenster. Ich möchte, dass ein bestimmter Shell-Befehl vollständig im Hintergrund ist (ohne visuellen Effekt).

Als explizites Beispiel habe ich den folgenden Code (ausgeliehen von https://emacs.stackexchange.com/a/7932 ). Es öffnet die PDF-Version der Tex-Datei, an der ich arbeite. Wenn es ausgeführt wird, wird das Fenster geteilt. Ich möchte dieses Verhalten in dieser speziellen Situation verhindern.

 (defun my-view-pdf ()
  (interactive)
  (async-shell-command
    (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf")))
Name
quelle
3
Nicht über die abstrakte Frage, sondern über den spezifischen Anwendungsfall: Verwenden Sie AUCTeX? Gibt es einen bestimmten Grund, warum Sie TeX-view( C-c C-v) nicht verwenden ?
Dan
@ Dan das Problem ist, dass wenn ich C-c C-vnichts tue, nichts passiert. Ich verstehe nicht warum. Wenn Sie eine einfache Anpassung kennen .emacs, die C-c C-vfunktioniert, würde ich sie gerne verwenden. Mein Betriebssystem ist Windows und mein PDF-Viewer befindet sich unter C:\Program Files\SumatraPDF\sumatrapdf.exe. In diesem Link hat lawlist einen umfassenden Link bereitgestellt. Ich bin nur daran interessiert, dass TeX-Viewer funktioniert.
Name
Nicht unter Windows, kann also nicht sagen, warum Sie Probleme haben. Sie könnten versuchen, mit zu arbeiten TeX-view-program-list.
Dan
Diese Frage hat sehr gute Antworten, daher werde ich es hassen, wenn diese Frage geschlossen wird. Aber dies ist ein Duplikat dieser Frage: emacs.stackexchange.com/q/5553/115
Kaushal Modi

Antworten:

8

save-window-excursionist ein Makro zum Ausführen eines Codeteils, ohne die Fensterkonfiguration zu ändern. So etwas sollte funktionieren:

 (defun my-view-pdf ()
  (interactive)
  (save-window-excursion
   (async-shell-command
     (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf"))))
Legoscia
quelle
Nettes Makro, ich bestätige, dass Ihre Lösung funktioniert.
Name
2
@legoscia Sie haben gesucht save-window-excursion, was fast identisch mit Ihrer Implementierung ist.
bmag
@bmag Ich bin interessiert über den Unterschied zwischen save-window-excursionund zu wissen save-window-configuration. Es scheint, dass beide in dieser Situation funktionieren.
Name
1
@Name Kein Unterschied, außer dass save-window-excursioneinige Best Practices für Makros verwendet werden, um zu vermeiden, dass Variablen in die Umgebung des Körpers eingeführt werden. Auch save-window-excursionist in Emacs eingebaut. Ich habe nach diesem Makro gesucht, es aber nicht gefunden, also habe ich meine eigene Version geschrieben. Zum Glück kannte bmag den echten.
Legoscia
8

Wenn Sie nur einen Prozess im Hintergrund erzeugen möchten, benötigen Sie nicht alle Schnickschnack, die die Shell-Befehlsfunktionen bieten.

Stattdessen können Sie die Funktion verwenden call-process. Zum Beispiel:

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

Konkret bedeutet dies, dass Sie Ihren Befehl wie folgt implementieren können:

(defun my-view-pdf ()
    (interactive)
    (call-process "SumatraPDF" nil 0 nil
                  (concat (file-name-base (buffer-file-name)) ".pdf")))
Lindydancer
quelle
Ich habe versucht, Ihren Vorschlag für mein spezielles Beispiel anzuwenden. (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") )Ich erhalte die Fehlermeldung "Falsches Argument: stringp, comint-output-filter". Ich bin nicht sicher, ob die von mir verwendete Syntax korrekt ist.
Name
Sie sollten async-shell-commandalle zusammen fallen lassen. Es sollte so etwas wie sein (defun my-pdf-viewer () (interactive) (call-process "SumatraPDF" nil 0 nil (concat (file-name-base (buffer-file-name)) ".pdf")).
Lindydancer
1
Vielen Dank, Ihre Lösung funktioniert einwandfrei, es fehlte nur eine Klammer, daher sollte der richtige Code lauten : (defun my-view-pdf () (interactive) (call-process "SumatraPDF" nil 0 nil (concat (file-name-base (buffer-file-name)) ".pdf"))) .
Name
@Name, danke, ich habe die Antwort aktualisiert, um die konkrete Funktion aufzunehmen.
Lindydancer
7

Verwenden Sie display-buffer-alistmit dem , display-buffer-no-windowwenn Sie auf Emacs 24.4 oder höher sind.

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

Alternativ können Sie auch einen Schäkel verwenden :

(setq shackle-rules '(("*Async Shell Command*" :ignore t)))
Wasamasa
quelle
Mit (setq display-buffer-alist '(("\`\\*Async Shell Command\\*\\'" display-buffer-no-window)))bekomme ich den Fehler apply: Wrong type argument: sequencep, display-buffer-no-window.
Name
Oh, richtig, display-buffer-no-windowwurde in Emacs 24.4 eingeführt, damit das nicht funktioniert. Mein Paket sollte dagegen am 24.3 funktionieren.
Wasamasa
Backporting display-buffer-no-windowist eine dritte Option. Fügen Sie es einfach (defun display-buffer-no-window (_buffer alist) (when (cdr (assq 'allow-no-window alist)) 'fail))in Ihre Emacs-Konfiguration ein.
Wasamasa
Ich habe versucht, Ihren letzten Kommentar anzuwenden, indem ich alles zusammengestellt habe (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")))) . Nach der Ausführung my-view-pdfteilt emacs das Fenster und *Async Shell Command*wird angezeigt.
Name
Ich bestätige, dass Ihre Lösung für die Version 24.4 oder höher perfekt funktioniert.
Name