W Emacsie jest kilka przypadków, w których chciałbym zapobiec pojawianiu się wiadomości w minibuforze, głównie dotyczących „Początku / końca bufora” i „Tekst jest tylko do odczytu”.
Czy jest jakiś sposób, aby zapobiec pojawianiu się tych wiadomości w minibuforze?
Czy jest jakiś ważny powód, dla którego mógłbym nie chcieć ich wyłączać? Na wartość nominalną mogę równie łatwo spojrzeć na numer wiersza i status zapisu buforu na modeline.
Odpowiedzi:
W Emacsie 25 możesz ukryć komunikaty minibufora, wiążąc się
inhibit-message
z wartością inną niż zero:źródło
message1
wywołuje funkcja Cmessage3
, szanować tę zmienną.(let ((inhibit-message t)) (message make-progress-reporter))
message
zwraca ciąg komunikatu, więc być może widzisz zwrócony ciąg podczas oceny kodu. Jeśli ewaluujesz ten kod w skrócie klawiszowym, żadna wiadomość nie zostanie wydrukowana (z wyjątkiem bufora Wiadomości ).Można rodzaj zrobić to z kodu Lisp. Dlaczego „w pewnym sensie”? Ponieważ MESSAGE jest prymitywem zdefiniowanym w C, zamiast funkcji Lisp, i zgodnie z podręcznikiem Emacsa Lispa , wywołania prymitywów z kodu C ignorują porady.
Dlatego, aby naprawdę dobrze wykonać pożądaną funkcjonalność, musisz ponownie zdefiniować prymityw MESSAGE jako funkcję Lisp; kiedy już to zrobisz, możesz doradzić kodem, który otrzymuje ciąg MESSAGE, który echo przekazuje do minibufora, porównuje go z listą wiadomości, których nie chcesz widzieć, a następnie wywołuje lub nie wywołuje MESSAGE w zależności na wynik. Teoretycznie można to osiągnąć np.
(defvar *message-prim* (symbol-function 'message))
, A następnie(defun message (format &rest args) ... (funcall *message-prim* format args))
- ale funkcja SYMBOL podana w pierwotnym argumencie zwraca coś, co w rzeczywistości nie jest możliwe do wywołania, więc FUNCALL sygnalizuje warunek VOID-FUNCTION.Jednak nawet gdyby to zadziałało, nadal nie dałoby rady, ponieważ ponowne zdefiniowanie prymitywu gwarantuje tylko, że redefinicja zostanie użyta, gdy funkcja zostanie wywołana z kodu Lisp; wywołania w kodzie C mogą nadal używać pierwotnej definicji . (Kod C może wywoływać Emacs Lisp, a takie przypadki zobaczą redefinicję; możliwe jest również, że kod C wywoła kod C, a takie przypadki zobaczą oryginalną definicję.)
Zastanawiam się nad łataniem kodu C i ponownej kompilacji Emacsa, aby zapewnić odpowiednią funkcję tłumienia wiadomości; Tak naprawdę nie potrzebuję tej funkcjonalności, ale może okazać się ciekawym ćwiczeniem, zwłaszcza że nie jestem hakerem C. W międzyczasie przygotowałem coś, co po upuszczeniu do pliku, dołączonego do jednego z twoich plików init i dostosowanego do twojego gustu, ukryje wiadomości pochodzące z kodu Lisp, które dokładnie pasują do napisów, które chcesz pominąć. Dopóki włączone jest tłumienie, komunikaty te nigdy nie pojawią się w minibuforze; masz opcję, czy je również
*Messages*
usunąć z bufora.Przetestowałem to do pracy z komunikatami, które faktycznie są generowane z kodu Lisp, np. Skarga „Nie określiłeś funkcji” powtórzona przez DESCRIBE-FUNCTION, gdy podajesz pusty argument ciągu. Niestety wiadomości, które chcesz ukryć, takie jak „Początek bufora”, „Koniec bufora” i „Tekst jest tylko do odczytu”, wydają się pochodzić z kodu C, co oznacza, że nie będziesz w stanie tłumić je tą metodą.
Jeśli kiedykolwiek przejdę do łatki źródłowej, będzie (prawdopodobnie) przeciwko Emacsowi 24.3 i zaktualizuję tę odpowiedź o informacje o tym, jak z niej korzystać.
źródło
W Emacsie 25 i prawdopodobnie we wcześniejszych wersjach najczystszy sposób to zrobić:
Najpierw zdefiniuj:
Następnie, jeśli chcesz ukryć wszystkie produkowane przez
some-function
ciebie wiadomości :Na przykład pomijam komunikat „Proces Ispell zabity” wywołany przez funkcję
ispell-kill-ispell
(inispell.el.gz
), pisząc:Jeśli kiedykolwiek będziesz musiał ponownie włączyć wiadomości, uruchom:
Kilka rzeczy do zapamiętania:
1) Wszystkie komunikaty generowane przez
some-function
będą pomijane, podobnie jak wszystkie komunikaty generowane przez dowolną funkcję lisp wywoływaną przez funkcję.2) Wiadomości generowane przez kod C nie będą tłumione, ale to chyba wszystko, co najlepsze.
3) Musisz upewnić się, że
-*- lexical-binding: t -*-
znajduje się w pierwszym wierszu.el
pliku.Ale jak dowiedzieć się, która funkcja jest wywoływana
message
? Możesz przeglądać kod, jak sugerował ktoś inny, ale łatwiej jest pozwolić Emacsowi wykonać pracę za Ciebie.Jeśli zdefiniujesz:
a następnie wykonaj:
otrzymasz wiadomość wsteczną dodaną do wiadomości. Dzięki temu możesz łatwo zobaczyć, gdzie wiadomość została wygenerowana.
Możesz to odwrócić za pomocą:
Alternatywnym podejściem byłoby doradzenie
message
funkcji i przetestowanie, czy chcesz wydrukować wiadomość, czy nie. Jest to proste, jeśli wiadomość jest stałym ciągiem. Np. Aby ukryć „proces Ispell zabity”, możesz zdefiniować:a następnie wykonaj:
Takie podejście wkrótce staje się bardzo nieuporządkowane, jeśli wiadomość jest czymś skomplikowanym.
źródło
Najwyraźniej pytasz o sposób selektywnego blokowania niektórych wiadomości. Odpowiedzią na to jest to, że musiałbyś przedefiniować lub doradzić kodowi, który emituje te konkretne komunikaty.
Aby zapobiec wszystkim wiadomościom, na przykład na czas trwania jakiegoś kodu, możesz użyć
flet
lubcl-flet
ponownie zdefiniować funkcjęmessage
lokalnie na (funkcja)ignore
. Lub użyj techniki użytej wedt-electric-helpify
: zapisz oryginalną definicjęmessage
,fset
abyignore
, ponowniefset
ją do pierwotnego def (lepiej,unwind-protect
jeśli to zrobisz).źródło
grep
lubA
w Dired. Wyszukaj tekst komunikatu o błędzie w plikach źródłowych Emacs Lisp (i ewentualnie także w plikach Emacs C, jeśli są dostępne). HTH.Działa to w celu pomijania „Początku bufora” i „Koniec bufora” i nie wymaga emacsa 25.
Zainspirowany https://lists.gnu.org/archive/html/help-gnu-emacs/2015-12/msg00189.html, ale używa „defadvice” dla większej kompatybilności.
źródło