Emacs - कुछ मिनीबफ़र संदेशों को अक्षम करें


20

Emacs में, कुछ मामले हैं जहाँ मैं संदेश को मिनीबफ़र में प्रदर्शित होने से रोकना चाहूंगा, मुख्य रूप से "शुरुआत / बफर के अंत" और "पाठ केवल-पढ़ने के लिए" से संबंधित है।

क्या कोई तरीका है जिससे मैं इन संदेशों को मिनीबार में प्रदर्शित होने से रोक सकूं?

इसके अलावा, क्या कुछ महत्वपूर्ण कारण हैं जो मैं इन्हें अक्षम नहीं करना चाहता? अंकित मूल्य पर, मैं आसानी से मॉडल पर पंक्ति संख्या और बफर लेखन स्थिति को आसानी से देख सकता हूं।


2
कोई कारण नहीं है कि आपको उन संदेशों की आवश्यकता होगी, नहीं। उन संदेशों के मौजूद होने का कारण यह है कि यह सुनिश्चित करने के लिए कि प्रत्येक आदेश का कुछ दृश्य प्रभाव है: जब कमांड के अपेक्षित दृश्यमान प्रभाव का प्रदर्शन नहीं किया जा सकता है, तो हम इसके बजाय एक संदेश का उत्सर्जन करते हैं, इसलिए आप बता सकते हैं कि कमांड वास्तव में चलाया गया था।
स्टीफन

जवाबों:


21

Emacs 25 में, आप inhibit-messageगैर-शून्य मान से बाइंड करके मिनीबफ़र संदेशों को दबा सकते हैं :

(let ((inhibit-message t))
  (message "Listen to me, you!"))

क्या यह सी से बुलाए गए आदिम पर भी काम करता है?
एरोन मिलर

1
यह चाहिए, जैसा कि C फ़ंक्शन message1कॉल करता है message3, जो इस चर का सम्मान करता है।
जैक्सन

कष्टप्रद mu4e "मेल को पुनः प्राप्त करना ..." संदेश के लिए उपयोगी है: (let ((inhibit-message t)) (message make-progress-reporter))
manandearth

1
यह मेरे लिए 26.1 Emacs पर काम नहीं करता है, अजीब तरह से पर्याप्त है। कोई विचार क्यों?
क्रिश्चियन हडॉन

1
@ChristianHudon मैंने अभी Emacs 26.1 में परीक्षण किया है और बिना init फ़ाइल के मास्टर है, और यह मेरे लिए दोनों जगहों पर काम करता है। ध्यान दें कि messageसंदेश स्ट्रिंग लौटाता है, इसलिए हो सकता है कि आप कोड का मूल्यांकन करते समय लौटे स्ट्रिंग को देख रहे हों। यदि आप इस कोड को कीबाइंडिंग में निकालते हैं, तो कोई संदेश नहीं छपेगा ( संदेश बफर के अलावा)।
जैक्सन

9

आप कर सकते हैं एक तरह से लिस्प कोड से यह करते हैं। क्यों "की तरह"? क्योंकि मेसेज एक प्रिमिटिव है, जो C लिस्ट में है, लिस्प फंक्शन के बजाय, और, Emacs लिस्प रेफरेंस मैनुअल के अनुसार , C कोड से प्रिमिटिव्स को कॉल करना सलाह को नजरअंदाज करता है।

इसलिए, वास्तव में आप जो कार्यक्षमता चाहते हैं, उसे लागू करने का एक उचित काम करने के लिए, आपको लिस्प फ़ंक्शन के रूप में मेसेज आदिम को फिर से परिभाषित करना होगा; एक बार जब आप ऐसा कर लेते हैं, तो आप इसे कोड के साथ सलाह दे सकते हैं जो स्ट्रिंग को प्राप्त करता है MESSAGE, मिनीबफ़र को गूँजता है, इसकी तुलना उन संदेशों की सूची से करता है जिन्हें आप देखना नहीं चाहते हैं, और फिर कॉल करें या निर्भरता के अनुसार कॉल न करें परिणाम पर। सिद्धांत रूप में, यह उदाहरण के लिए पूरा किया जा सकता है (defvar *message-prim* (symbol-function 'message)), और फिर (defun message (format &rest args) ... (funcall *message-prim* format args))- लेकिन प्रतीक ने एक आदिम तर्क दिया है जो वास्तव में कॉल करने योग्य नहीं है, इसलिए FUNCALL एक वीओआईडी-फंक्शन स्थिति का संकेत देता है।

हालाँकि, अगर वह काम करता है, तब भी यह वास्तव में चाल नहीं चलेगा, क्योंकि एक आदिम को पुनर्परिभाषित करना केवल इस बात की गारंटी देता है कि फ़ंक्शन को लिस्प कोड से कॉल करने पर पुनर्परिभाषित का उपयोग किया जाएगा; सी कोड में कॉल अभी भी आदिम परिभाषा का उपयोग कर सकते हैं । (सी कोड के लिए Emacs लिस्प में कॉल करना संभव है, और ऐसे मामलों में पुनर्वितरण दिखाई देगा; यह निश्चित रूप से, सी कोड के लिए सी कोड को कॉल करना संभव है, और ऐसे मामलों में मूल परिभाषा दिखाई देगी।)

मैं अस्पष्ट रूप से C कोड को पैच करने पर विचार कर रहा हूं और उचित संदेश दमन कार्यक्षमता प्रदान करने के लिए Emacs को फिर से जमा कर रहा हूं; मुझे वास्तव में उस कार्यक्षमता की आवश्यकता नहीं है, लेकिन यह एक दिलचस्प अभ्यास साबित हो सकता है, खासकर जब से मैं सी हैकर नहीं हूं। इस बीच, मैं यहाँ कुछ मार पड़ी है, जब एक फ़ाइल में गिरा दिया, अपनी एक init फ़ाइलों में शामिल है, और अपने स्वाद के लिए अनुकूलित, लिस्प कोड से होने वाले संदेशों को दबा देगा जो वास्तव में दमन के लिए आपके द्वारा सूचीबद्ध तार से मेल खाते हैं। जब तक दमन सक्षम होता है, तब तक ये संदेश मिनीबफ़र में दिखाई नहीं देंगे; आपके पास विकल्प है कि उन्हें *Messages*बफर से भी दबाएं।

;; message-suppression.el
;; a quick hack by Aaron (me@aaron-miller.me), 2013-11-12
;; half a solution for http://superuser.com/questions/669701/emacs-disable-some-minibuffer-messages
;; NB this does nothing until you 
;; M-x customize-group RET message-suppression RET
;; and adjust to taste

(defgroup message-suppression nil
  "Customization options for selective message suppression."
  :prefix "message-suppression")

(defcustom message-suppression-enabled nil
  "Whether or not to suppress messages listed in
`message-suppress-these'."
  :group 'message-suppression
  :tag "Suppress some messages?"
  :type '(choice (const :tag "No" nil)
                 (const :tag "Yes" t)))

(defcustom message-suppression-to-messages-buffer t
  "Whether or not to insert messages suppressed from the
minibuffer into the *Messages* buffer."
  :group 'message-suppression
  :tag "Insert suppressed messages into *Messages* buffer?"
  :type '(choice (const :tag "No" nil)
                 (const :tag "Yes" t)))

(defcustom message-suppression-these nil
  "A list of messages which the `message-except-these' advice
should suppress from being echoed in the minibuffer. Messages
are matched by `member', i.e., only exact strings match.

NB! Per the Emacs manual, calls from C code to primitives (such
as `message') ignore advice entirely, which means some messages
cannot be suppressed by this mechanism. ('Advising
Functions' in the Emacs Lisp Reference Manual, q.v.)"
  :group 'message-suppression
  :tag "Messages to suppress"
  :type '(repeat (string))
  :link '(info-link "(elisp)Advising Functions"))

(defadvice message (around message-suppress-advice)
  "Suppress messages listed in `message-suppress-these' from being
  echoed in the minibuffer."
  (let ((message-string nil)
        (current-buffer nil))
    (if (and message-suppression-enabled
             (length (ad-get-args 0))
             (stringp (car (ad-get-args 0)))
             ;; message-string doesn't get set until here because `format'
             ;; will complain if its first argument isn't a string
             (setq message-string (apply 'format (ad-get-args 0)))
             (member message-string
                     message-suppression-these))
        ;; we won't call `message', but we might echo to *Messages*
        (and message-suppression-to-messages-buffer
             (progn
               (setq current-buffer (current-buffer))
               (switch-to-buffer (get-buffer-create "*Messages*"))
               (goto-char (point-max))
               (insert (make-string 1 10))
               (insert message-string)
               (switch-to-buffer current-buffer)))
      ad-do-it)))

(ad-activate 'message)

मैंने इसे उन संदेशों के साथ काम करने के लिए परीक्षण किया है, जो वास्तव में लिस्प कोड से उत्पन्न होते हैं, उदाहरण के लिए "आप एक फ़ंक्शन निर्दिष्ट नहीं करते" शिकायत DESCRIBE-FUNCTION द्वारा गूँजती है जब आप इसे एक खाली स्ट्रिंग तर्क देते हैं। दुर्भाग्य से, आप जिन संदेशों को दबाने की इच्छा रखते हैं, जैसे "बफर की शुरुआत", "बफर का अंत", और "टेक्स्ट रीड-ओनली", सी कोड से उत्पन्न होने के लिए सभी प्रकट होते हैं, जिसका अर्थ है कि आप सक्षम नहीं होंगे इस विधि से उन्हें दबाएं।

अगर मैं कभी भी स्रोत पैच के आसपास पहुँचता हूँ, तो यह (शायद) Emacs 24.3 के विरुद्ध होगा, और मैं इस उत्तर को जानकारी के साथ अपडेट करूँगा कि इसका उपयोग कैसे किया जाए।


8

Emacs 25 में और शायद कुछ पहले के संस्करणों में, ऐसा करने का सबसे साफ तरीका इस प्रकार है:

पहले परिभाषित करें:

(defun suppress-messages (old-fun &rest args)
  (cl-flet ((silence (&rest args1) (ignore)))
    (advice-add 'message :around #'silence)
    (unwind-protect
         (apply old-fun args)
      (advice-remove 'message #'silence))))

फिर यदि आप अपने द्वारा उत्पादित सभी संदेशों को दबाना चाहते some-functionहैं:

(advice-add 'some-function :around #'suppress-messages)

उदाहरण के लिए, मैं संदेश "Ispell प्रक्रिया मारा" समारोह द्वारा उत्पादित को दबाने ispell-kill-ispell(में ispell.el.gzलेखन से):

(advice-add 'ispell-kill-ispell :around #'suppress-messages)

यदि आपको कभी संदेशों को फिर से सक्षम करना है तो चलाएं:

(advice-remove 'some-function #'suppress-messages)

ध्यान देने योग्य कुछ बातें:

1) द्वारा उत्पादित सभी संदेशों some-functionको दबा दिया जाएगा क्योंकि किसी भी लिस्प द्वारा उत्पादित सभी संदेश फ़ंक्शन कॉल करेंगे।

2) C कोड द्वारा निर्मित संदेश सुपरिचित नहीं होंगे, लेकिन यह शायद सभी के लिए सबसे अच्छा है।

3) आपको यह सुनिश्चित करने की आवश्यकता है कि -*- lexical-binding: t -*-आपकी .elफ़ाइल की पहली पंक्ति में निहित है ।

लेकिन आपको कैसे पता चलता है कि किस फंक्शन को कहा जाता है message ? आप किसी और के सुझाव के अनुसार कोड के माध्यम से पकड़ सकते हैं, लेकिन Emacs को आपके लिए काम करने देना आसान है।

यदि आप परिभाषित करते हैं:

(defun who-called-me? (old-fun format &rest args)
  (let ((trace nil) (n 1) (frame nil))
      (while (setf frame (backtrace-frame n))
        (setf n     (1+ n) 
              trace (cons (cadr frame) trace)) )
      (apply old-fun (concat "<<%S>>\n" format) (cons trace args))))

और फिर करें:

(advice-add 'message :around #'who-called-me?)

आपको संदेश में जोड़ा गया एक बैकट्रेस मिलेगा। इससे आप आसानी से देख सकते हैं कि संदेश कहां उत्पन्न हुआ था।

आप इसके साथ उल्टा कर सकते हैं:

(advice-remove 'message #'who-called-me?)

एक वैकल्पिक तरीका यह होगा messageकि आप संदेश को प्रिंट करना चाहते हैं या नहीं, यह देखने के लिए फ़ंक्शन और परीक्षण की सलाह दें । यह सरल है यदि प्रश्न में संदेश एक निश्चित स्ट्रिंग है। उदाहरण के लिए "इसपेल प्रक्रिया को मार दिया गया" को दबाने के लिए आप इसे परिभाषित कर सकते हैं:

(defun suppress-ispell-message (old-fun format &rest args)
  (if (string= format "Ispell process killed")
         (ignore)
    (apply old-fun format args)))

और फिर करें:

(advice-add 'message :around #'suppress-ispell-message)

यदि संदेश कुछ भी जटिल है, तो यह दृष्टिकोण जल्द ही बहुत गड़बड़ हो जाता है।


3

आप स्पष्ट रूप से कुछ संदेशों को चुनिंदा रूप से बाधित करने का तरीका पूछ रहे हैं । इसका उत्तर यह है कि आपको उस कोड को फिर से परिभाषित करने या सलाह देने की आवश्यकता होगी जो उन विशेष संदेशों को जारी करता है।

सभी संदेशों को रोकने के लिए, उदाहरण के लिए, कुछ कोड की अवधि के लिए, आप स्थानीय रूप से (फ़ंक्शन) फ़ंक्शन का उपयोग fletया cl-fletफिर से परिभाषित करने के लिए कर सकते हैं । या में इस्तेमाल तकनीक का उपयोग बचाने की मूल परिभाषा: , करने के लिए , फिर इसे वापस मूल डीईएफ़ करने के लिए (हालांकि यह उपयोग करने के लिए बेहतर है , तो आप ऐसा कर)।messageignoreedt-electric-helpifymessagefsetignorefsetunwind-protect


क्षमा करें, लेकिन क्या आप मेरी मदद कर पाएंगे कि मैं इन त्रुटि संदेशों की खोज कैसे कर सकता हूं? इस बिंदु पर, यह लगभग महसूस करता है कि संदेशों को निष्क्रिय करने से अधिक परेशानी यह है कि उन्हें रखने से है।
बिटफ्लिप्स

1
"इन त्रुटि संदेशों" की खोज करने के लिए, उपयोग करें grepया ADired में। Emacs Lisp स्रोत फ़ाइलों में त्रुटि संदेश पाठ के लिए खोजें (और संभवतः Emacs C फ़ाइलों में भी, यदि आपके पास उपलब्ध है)। HTH।
आकर्षित किया

2

यह "बफर की शुरुआत" और "बफर के अंत" को दबाने के लिए काम करता है और इसके लिए emacs 25 की आवश्यकता नहीं होती है।

; Suppress "Beginning of buffer" and "End of buffer" messages
(defadvice previous-line (around silencer activate)
  (condition-case nil
    ad-do-it
    ((beginning-of-buffer))))

(defadvice next-line (around silencer activate)
  (condition-case nil
    ad-do-it
    ((end-of-buffer))))

Https://lists.gnu.org/archive/html/help-gnu-emacs/2015-12/msg00189.html से प्रेरित होकर अधिक अनुकूलता के लिए "अवहेलना" का उपयोग करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.