Comment puis-je exécuter un processus asynchrone en arrière-plan sans faire apparaître de tampon?

23

J'ai défini certaines fonctions pour exécuter un processus d'arrière-plan asynchrone à l'aide async-shell-commandde mon .emacs, mais chaque fois que j'exécute les commandes, une nouvelle fenêtre (pas un cadre) est créée et le tampon du processus y est affiché. Comment pourrais-je exécuter la commande sans le tampon "pop up"?

rlazo
la source

Réponses:

21

Vous pouvez démarrer des processus en arrière-plan avec start-process, qui ne devraient pas faire apparaître de tampon:

(start-process "process-name" "buffer-name" "program")

Les noms de processus sont modifiés pour éviter la duplication si nécessaire, alors ne vous inquiétez pas. Donnez-lui simplement un nom utile pour le débogage à l'avenir!

Si vous donnez un "buffer-name", un tampon sera créé mais ne s'affichera pas immédiatement. Cela peut être pratique pour gérer les processus et regarder les résultats. Si vous ne voulez pas du tout créer de tampon, passez nilcomme nom de tampon:

(start-process "process-name" nil "program")
Tikhon Jelvis
la source
Est-il possible d'utiliser start-processpour une commande sudo? J'ai essayé envelopper mon appel à start-processen , (let ((default-directory "/sudo::")) ... )mais cela n'a pas fonctionné pour moi.
sid-kap
@ sid-kap: Je ne sais pas. Vous devriez probablement poser cela comme une question autonome.
Tikhon Jelvis
1
"program"dans ce cas, ce n'est que le nom du programme (par exemple nautilus, caja, firefox) et "arg1 arg2 ..."doit être dans le quatrième argument positionnel de start-process. J'ai compris cela en lisant la documentation :)
biocyberman
8

Comme Tikhon l'a mentionné, (start-process)c'est la voie à suivre. Dans le cas où vous ne souhaitez pas créer de tampon mais souhaitez tout de même réagir à l'état du processus d'arrière-plan, vous pouvez également l'utiliser (set-process-sentinel). Voici un exemple modifié que je prends de mon projectorpackage:

(set-process-sentinel (start-process "process-name" nil "command") #'output-message-sentinel)

(defun output-message-sentinel (process msg)
  (when (memq (process-status process) '(exit signal))
    (message (concat (process-name process) " - " msg))))

De la description de la fonction Emacs:

(set-process-sentinel PROCESS SENTINEL)

Give PROCESS the sentinel SENTINEL; nil for default.
The sentinel is called as a function when the process changes state.
It gets two arguments: the process, and a string describing the change.

Les pages de manuel GNU sur les processus sont assez bonnes pour plus d'informations.

waymondo
la source
Pourriez-vous décrire ce que set-process-sentinelfait un peu plus précisément? J'ai l'idée générale d'avoir une fonction qui gère le processus, mais je ne comprends pas tous les détails. Merci!
Tikhon Jelvis
Si vous le faites M-x describe-functionet entrez, set-process-sentinelvous obtiendrez la réponse courte de la documentation Emacs: (set-process-sentinel PROCESS SENTINEL) Donnez à PROCESS la sentinelle SENTINEL; nul par défaut. La sentinelle est appelée en fonction lorsque le processus change d'état. Il obtient deux arguments: le processus et une chaîne décrivant le changement.
waymondo
1
Les pages de manuel de GNU Emacs sur les sentinelles et les processus sont en fait assez bonnes pour des informations plus détaillées.
waymondo
Cool. Peut-être pourriez-vous modifier les liens dans votre réponse? Je suppose que l'on pourrait aussi en savoir plus en utilisant simplement C-h f...
Tikhon Jelvis
2

Il n'est pas nécessaire de modifier la façon dont vous exécutez une commande asynchrone. Emacs a une capacité générique pour vous permettre de contrôler où ou si un tampon apparaîtra, en modifiant une seule structure de données, le display-buffer-alist.

Dans la solution ci-dessous, vous pouvez voir que la fonction d'action display-buffer-no-window(c.-à-d. Pas de fenêtre contextuelle) est définie pour être associée à tout tampon dont le nom commence *Asynchronous Shell Command*(emacs ajoute un suffixe incrémentiel lorsqu'il est demandé d'en créer plusieurs).

Pour voir la liste des autres options d'affichage disponibles, saisissez C-h f display-bufferet recherchez la liste des "fonctions d'action".

;; Buffers that I don't want popping up by default
(add-to-list 'display-buffer-alist
  '("\\*Async Shell Command\\*.*" display-buffer-no-window))
user1404316
la source