Включение М-! в M- & (a'ka emacs, эквивалентный bash Ctrl-Z)

14

Время от времени я M-! some_commandпросто обнаруживаю, что команда выполняется дольше, чем я ожидал, и сохраняет мои emacs замороженными на долгие секунды. Поэтому я смотрю на свои замороженные emacs и бью себя за то, что я не использую, M-& some_commandи обещаю использовать в M-&следующий раз. Но M-!в моей мышечной памяти на протяжении десятилетий ... И, конечно, есть Ctrl-G, но есть случаи, когда нарушение команды и повторный запуск не являются предпочтительными (может быть, это может нарушить, может быть, может потребоваться повторный запуск ...).

Подобная ошибка в оболочке konsole тривиальна для исправления Ctrl-Z, bgи задание выполняется в фоновом режиме.

Существует ли в emacs похожая хитрость - способ превратить текущую запущенную команду переднего плана (синхронную) в фоновую (асинхронную)?

Примечание: в случае, если это невозможно по умолчанию M-! , я открыт для предложений о том, как сделать привязку M-!к чему-то другому (что было бы функционально эквивалентным, кроме этого трюка).

Мекк
источник
2
Возможно, вам будет интересно узнать, что простое добавление &в конец функции normal shell-command( M-!) сделает его асинхронным. Конечно, вы должны сделать это перед выполнением команды, но по крайней мере вы можете использовать ту же привязку клавиш.
няня
4
Вы всегда можете просто переназначить M-!к async-shell-command. :-) Похоже, единственное, что вы теряете, это получение результата в эхо-области, когда он достаточно короткий.
glucas
1
@nanny, на самом деле, это все, что async-shell-commandделает. Он добавляет &в конец COMMANDстроки и выполняет shell-command.
Мэтью Пизиак

Ответы:

2

Существует ли в emacs похожая хитрость - способ превратить текущую запущенную команду переднего плана (синхронную) в фоновую (асинхронную)?

Я подозреваю, что такой уловки не существует. Проблема в том, что синхронная команда оболочки (которая действительно call-process-region) блокирует цикл событий emacs. Единственный способ прекратить это - остановить процесс с помощью сигнала USR1 или USR2 или сделать C-g. (Могут быть и другие способы, но я так и делаю).

Это означает, что вы ничего не можете сделать, потому что у вас нет способа вызвать трюк, так как Emacs не обрабатывает ввод, пока цикл событий остановлен.


Одна вещь, которую вы можете сделать, это просто поменять местами ключи:

(global-set-key (kbd "M-!") #'async-shell-command)
(global-set-key (kbd "M-&") #'shell-command)
PythonNut
источник
Переплет М-! к async-shell-command имеет частичный смысл, но: (1) я не уверен насчет M-1 M-! поведение (вывод команды в буфер) - работают простые быстрые случаи, но что, если команда медленнее и я набираю sth? (2) во многих случаях мне нравится замораживание до тех пор, пока команда не завершит поведение, поскольку она дает четкую индикацию завершения (некоторые команды не имеют вывода…), поэтому явное нажатие клавиши «положить в фон» было бы лучше (3) async оставляет эти асинхронные буферы, которые должны быть пожиненным
Мекк
Я думаю, можно ли написать какую-нибудь оболочку вокруг async-shell-command (функция, которая будет вызывать async-shell-command, затем ждать ее завершения, реагировать на Ctrl-G, отменив команду, и на какое-то другое нажатие клавиши, оставив он работает, но больше не ждет, и пожнет асинхронный буфер, если выходной сигнал пустой или короткий). Я не уверен, как сделать эту часть ожидания ...
Мекк