Come rendere totalmente silenzioso un comando di shell (impedendogli di dividere la finestra o di aprire un nuovo frame / finestra ecc.)


8

È possibile eseguire un comando shell silenziosamente (in background)? Quando uso async-shell-command, emacs divide le finestre. Vorrei che un comando shell specifico fosse totalmente in background (senza alcun effetto visivo).

Come esempio esplicito, ho il seguente codice (preso in prestito da https://emacs.stackexchange.com/a/7932 ). Apre la versione pdf del file tex su cui sto lavorando. Durante l'esecuzione, divide la finestra, vorrei impedirlo da questo comportamento in questa situazione particolare.

 (defun my-view-pdf ()
  (interactive)
  (async-shell-command
    (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf")))

3
Non sulla domanda astratta, ma sul caso d'uso specifico: stai usando AUCTeX? Qualche motivo particolare che non stai utilizzando TeX-view( C-c C-v)?
Dan

@Il problema è che quando non faccio C-c C-vnulla succede. Non capisco perché. Se conosci una semplice personalizzazione nella .emacsquale rende le C-c C-vopere, sarei felice di usarlo. Il mio sistema operativo è Windows e il mio visualizzatore di pdf si trova in C:\Program Files\SumatraPDF\sumatrapdf.exe. In quel link la lista della legge ha fornito un link completo. Sono interessato solo a far funzionare TeX-viewer.
Nome

Non su Windows, quindi non posso dire perché stai riscontrando problemi. Potresti provare a lavorare con TeX-view-program-list.
Dan

Questa domanda ha risposte molto buone, quindi odio che questa venga chiusa. Ma questo è un duplicato di questa domanda: emacs.stackexchange.com/q/5553/115
Kaushal Modi,

Risposte:


8

save-window-excursionè una macro per eseguire un pezzo di codice senza alterare la configurazione della finestra. Qualcosa del genere dovrebbe funzionare:

 (defun my-view-pdf ()
  (interactive)
  (save-window-excursion
   (async-shell-command
     (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf"))))

Bella macro, confermo che la tua soluzione funziona.
Nome

2
@legoscia che stavi cercando save-window-excursion, il che è quasi identico alla tua implementazione.
bmag

@bmag Sono interessato a conoscere la differenza tra save-window-excursione save-window-configuration. Sembra che entrambi funzionino in questa situazione.
Nome

1
@Nome Nessuna differenza, tranne per il fatto che save-window-excursionutilizza alcune best practice per macro per evitare di introdurre variabili nell'ambiente del corpo. Inoltre, save-window-excursionè integrato in Emacs. Stavo cercando quella macro, ma non l'ho trovata, quindi ho scritto la mia versione. Fortunatamente Bmag conosceva quello vero.
Legoscia,

8

Se desideri semplicemente generare un processo in background, non hai bisogno di tutte le campane e fischi che le funzioni di comando della shell forniscono.

Invece, puoi usare la funzione call-process. Per esempio:

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

Concretamente, questo significa che puoi implementare il tuo comando come:

(defun my-view-pdf ()
    (interactive)
    (call-process "SumatraPDF" nil 0 nil
                  (concat (file-name-base (buffer-file-name)) ".pdf")))

Ho provato ad applicare il tuo suggerimento per il mio esempio specifico, (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") )ricevo l'errore "Argomento di tipo errato: stringp, comint-output-filter`. Non sono sicuro che la sintassi che ho usato sia corretta.
Nome

Dovresti lasciarli async-shell-commandtutti insieme. Dovrebbe essere qualcosa del genere (defun my-pdf-viewer () (interactive) (call-process "SumatraPDF" nil 0 nil (concat (file-name-base (buffer-file-name)) ".pdf")).
Lindydancer,

1
Grazie a voi, la vostra soluzione funziona perfettamente, c'era solo una doppietta mancante, in modo che il codice corretto dovrebbe essere: (defun my-view-pdf () (interactive) (call-process "SumatraPDF" nil 0 nil (concat (file-name-base (buffer-file-name)) ".pdf"))) .
Nome

@Nome, grazie, ho aggiornato la risposta per includere la funzione concreta.
Lindydancer,

7

Usa display-buffer-alistcon il display-buffer-no-windowse sei su Emacs 24.4 o successivo.

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

In alternativa, utilizzare grillo :

(setq shackle-rules '(("*Async Shell Command*" :ignore t)))

Usando (setq display-buffer-alist '(("\`\\*Async Shell Command\\*\\'" display-buffer-no-window)))ottengo l'errore apply: Wrong type argument: sequencep, display-buffer-no-window.
Nome

Oh giusto, è display-buffer-no-windowstato introdotto in Emacs 24.4, quindi non funzionerà. Il mio pacchetto invece dovrebbe funzionare il 24.3.
wasamasa,

Il backporting display-buffer-no-windowè una terza opzione, basta inserirla (defun display-buffer-no-window (_buffer alist) (when (cdr (assq 'allow-no-window alist)) 'fail))nella configurazione di Emacs.
wasamasa,

Ho provato ad applicare il tuo ultimo commento mettendo insieme le cose (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")))) . Ma dopo l'esecuzione my-view-pdf, emacs divide la finestra e *Async Shell Command*viene mostrato.
Nome

Confermo che la tua soluzione funziona perfettamente per la versione 24.4 o successive.
Nome
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.