В Emacs есть некоторые случаи, когда я хотел бы запретить появление сообщений в минибуфере, в основном относящихся к «Beginning / End of buffer» и «Text только для чтения».
Можно ли как-то предотвратить появление этих сообщений в минибуфере?
Кроме того, есть ли какая-то существенная причина, по которой я не хочу отключать их? По номинальной стоимости я так же легко могу посмотреть на номер строки и состояние записи в буфер на моделине.
Ответы:
В Emacs 25 вы можете подавить сообщения минибуфера, связавшись
inhibit-message
с ненулевым значением:источник
message1
вызывает функция Cmessage3
, уважать эту переменную.(let ((inhibit-message t)) (message make-progress-reporter))
message
возвращается строка сообщения, поэтому, возможно, вы видите возвращенную строку при оценке кода. Если вы введете этот код в связке ключей, сообщение не будет напечатано (кроме как в буфере сообщений ).Вы можете рода это сделать из кода Lisp. Почему "вроде"? Поскольку MESSAGE является примитивом, определенным в C, вместо функции Lisp, и, согласно справочному руководству по Emacs Lisp , вызовы примитивов из кода C игнорируют рекомендации.
Следовательно, для того, чтобы по-настоящему правильно реализовать желаемую функциональность, вам нужно переопределить примитив MESSAGE как функцию Lisp; как только вы это сделаете, вы можете сообщить ему код, который получает строку, которую MESSAGE отобразит в минибуфере, сравнивает ее со списком сообщений, которые вы не хотите видеть, а затем вызывает или не вызывает MESSAGE в зависимости от на результат. Теоретически, это может быть выполнено, например
(defvar *message-prim* (symbol-function 'message))
, и затем(defun message (format &rest args) ... (funcall *message-prim* format args))
- но SYMBOL-FUNCTION с заданным примитивным аргументом возвращает то, что на самом деле не вызывается, поэтому FUNCALL сигнализирует об условии VOID-FUNCTION.Однако, даже если бы это сработало, это все равно не сработало бы, потому что переопределение примитива только гарантирует, что переопределение будет использовано при вызове функции из кода на Лиспе; вызовы в C-коде могут все еще использовать определение примитива . (Код на C может вызываться в Emacs Lisp, и в таких случаях будет переопределение; конечно, для кода C также возможно вызывать код на C, и такие случаи увидят исходное определение.)
Я смутно размышляю над исправлением кода C и перекомпиляцией Emacs для обеспечения надлежащей функциональности подавления сообщений; Мне действительно не нужна эта функциональность, но это может оказаться интересным упражнением, тем более что я не хакер Си. В то же время, вот что я написал, что, будучи помещенным в файл, включенный в один из ваших файлов инициализации и настроенный по вашему вкусу, будет подавлять сообщения, исходящие из кода Lisp, которые точно соответствуют строкам, которые вы перечислили для подавления. Пока подавление включено, эти сообщения никогда не будут появляться в минибуфере; у вас есть выбор, подавлять ли их из
*Messages*
буфера.Я проверил это, чтобы работать с сообщениями, которые фактически генерируются из кода на Лиспе, например, жалоба «Вы не указали функцию», повторяемая DESCRIBE-FUNCTION, когда вы даете ему пустой строковый аргумент. К сожалению, сообщения, о которых вы упомянули, что хотите подавить, такие как «Начало буфера», «Конец буфера» и «Текст только для чтения», выглядят как все происходящие из кода C, что означает, что вы не сможете подавить их этим методом.
Если я когда-нибудь доберусь до исходного патча, он будет (вероятно) против Emacs 24.3 , и я обновлю этот ответ информацией о том, как его использовать.
источник
В Emacs 25 и, возможно, в некоторых более ранних версиях, самый чистый способ сделать это так:
Сначала определите:
Затем, если вы хотите подавить все сообщения, созданные
some-function
вами:Например, я подавляю сообщение «процесс Ispell убит», созданный функцией
ispell-kill-ispell
(inispell.el.gz
), записав:Если вам когда-нибудь понадобится снова включить сообщения, запустите:
Несколько вещей на заметку:
1) Все сообщения, генерируемые программой,
some-function
будут подавлены, как и все сообщения, генерируемые любой функцией lisp, вызываемой функцией.2) Сообщения, создаваемые кодом C, не будут подавлены, но это, вероятно, все к лучшему.
3) Вы должны убедиться, что
-*- lexical-binding: t -*-
содержится в первой строке вашего.el
файла.Но как вы узнаете, какая функция вызывается
message
? Вы могли бы просмотреть код, как предлагал кто-то другой, но проще позволить Emacs сделать всю работу за вас.Если вы определите:
а затем сделать:
Вы получите добавленный к сообщению след. Отсюда вы можете легко увидеть, где было сгенерировано сообщение.
Вы можете изменить это с помощью:
Альтернативным подходом было бы рекомендовать
message
функцию и проверить, хотите ли вы напечатать сообщение или нет. Это просто, если рассматриваемое сообщение является фиксированной строкой. Например, чтобы подавить "процесс Ispell убит", вы можете определить:а затем сделать:
Этот подход скоро становится очень грязным, если сообщение является чем-то сложным.
источник
Вы, очевидно, просите способ избирательного запрета определенных сообщений. Ответ заключается в том, что вам нужно будет переопределить или сообщить код, который выдает эти конкретные сообщения.
Чтобы запретить все сообщения, например, для продолжительности какого-либо кода, вы можете использовать
flet
илиcl-flet
переопределить функциюmessage
локально для (функция)ignore
. Или используйте технику, используемую вedt-electric-helpify
: сохранить оригинальное определениеmessage
,fset
чтобыignore
,fset
вернуться к исходному определению (хотя лучше использовать,unwind-protect
если вы это сделаете).источник
grep
илиA
в Dired. Найдите текст сообщения об ошибке в исходных файлах Emacs Lisp (и, возможно, также в файлах Emacs C, если они у вас есть). НТН.Это работает для подавления «Начало буфера» и «Конец буфера» и не требует emacs 25.
Вдохновлен https://lists.gnu.org/archive/html/help-gnu-emacs/2015-12/msg00189.html, но использует «defadvice» для большей совместимости.
источник