Aktives M-! in M- & (a'ka emacs entspricht Ctrl-Z)

14

Von Zeit zu Zeit stelle ich fest, M-! some_commanddass der Befehl länger ausgeführt wird als erwartet und meine Emacs für lange Sekunden eingefroren sind. Also glasiere ich meinen gefrorenen Emac und trete mich dafür, dass ich ihn nicht benutzt habe M-& some_commandund verspreche mir, ihn das M-&nächste Mal zu benutzen . Aber es M-!ist seit Jahrzehnten in meinem Muskelgedächtnis… Und natürlich gibt es Ctrl-G, aber es gibt Fälle, in denen ein Abbruch des Befehls und ein erneutes Ausführen nicht vorzuziehen sind (möglicherweise kann es etw zerbrechen, möglicherweise wäre es kostspielig, es erneut auszuführen…).

Ein ähnlicher Fehler in der Shell-Konsole ist trivial zu korrigieren Ctrl-Z, bgund der Job wird im Hintergrund ausgeführt.

Gibt es einen ähnlichen Trick in Emacs - eine Möglichkeit, den aktuell ausgeführten Vordergrundbefehl (synchron) in einen Hintergrundbefehl (asynchron) umzuwandeln?

Hinweis: Für den Fall, dass es standardmäßig nicht möglich ist M-! , bin ich offen für Vorschläge, wie Sie M-!sich an etwas anderes binden können (was ohne diesen Trick funktionell äquivalent wäre).

Mekk
quelle
2
Es könnte Sie interessieren, dass das Hinzufügen von &an das Ende eines regular shell-command( M-!) asynchron macht. Natürlich müssen Sie dies tun, bevor Sie einen Befehl ausführen, aber Sie können zumindest die gleiche Tastenkombination verwenden.
Kindermädchen
4
Man konnte immer nur neu zuordnen M-!zu async-shell-command. :-) Das Einzige, was Sie verlieren, ist die Ausgabe im Echo-Bereich, wenn es kurz genug ist.
Glucas
1
@ Kindermädchen, in der Tat, das ist alles async-shell-command. Es fügt &am Ende der COMMANDZeichenfolge ein hinzu und wird ausgeführt shell-command.
Matthew Piziak

Antworten:

2

Gibt es einen ähnlichen Trick in Emacs - eine Möglichkeit, den aktuell ausgeführten Vordergrundbefehl (synchron) in einen Hintergrundbefehl (asynchron) umzuwandeln?

Ich vermute, dass es keinen solchen Trick gibt. Das Problem ist, dass der synchrone Shell-Befehl (der wirklich ist call-process-region) die Ereignisschleife von emacs blockiert. Die einzige Möglichkeit, dies zu unterbrechen, besteht darin, den Prozess mit einem USR1- oder USR2-Signal abzubrechen oder zu beenden C-g. (Es kann andere Wege geben, aber das ist was ich tue).

Dies bedeutet, dass Sie nichts tun können, da Sie den Trick nicht aufrufen können, da Emacs keine Eingaben verarbeitet, während die Ereignisschleife blockiert ist.


Eine Sache, die Sie tun können , ist einfach die Schlüssel zu tauschen:

(global-set-key (kbd "M-!") #'async-shell-command)
(global-set-key (kbd "M-&") #'shell-command)
PythonNut
quelle
Rebinding M-! async-shell-command macht teilweise Sinn, aber: (1) Ich bin mir nicht sicher, ob M-1 M-! Verhalten (Befehlsausgabe in Puffer) - einfache, schnelle Fälle funktionieren, aber was ist, wenn der Befehl langsamer ist und ich etw eingebe? (2) in vielen Fällen , die ich wie das Einfrieren bis Befehl beendet Verhalten , wie es gibt klare Zielanzeige (einige Befehle haben keine Ausgabe ...), deshalb explizit Tastendruck „gestellt Hintergrund“ schöner wäre (3) Asynchron - Blätter jene Async Puffer aufweisen müssen , geerntet werden
Mekk
Ich überlege, ob ein Wrapper um einen Async-Shell-Befehl geschrieben werden könnte (eine Funktion, die einen Async-Shell-Befehl erzeugt, dann auf dessen Beendigung wartet, auf Strg-G reagiert, indem sie den Befehl abbricht, und auf einen anderen Tastendruck, indem sie ihn verlässt Es läuft, wartet aber nicht mehr und erntet den Async- Puffer, wenn die Ausgabe leer oder kurz ist. Ich bin mir nicht sicher, wie ich diesen wartenden Teil machen soll ...
Mekk