सभी खुले बफ़र्स वापस करें (और त्रुटियों को अनदेखा करें)


12

जब गिट के साथ संस्करण नियंत्रण में एक परियोजना पर काम कर रहा हूं, तो मैं अक्सर शेल में कुछ चीजें करना चाहता हूं जो मेरी कई खुली फाइलों को प्रभावित करते हैं, फिर हर बफर को वापस करते हैं जो मुझे यह सुनिश्चित करने के लिए खुला है कि मैं गलती से नया संस्करण नहीं खोल रहा हूं मेरे पास जो कुछ भी खुला था। मुझे पता है कि magitयहाँ उपयोगी हो सकता है, लेकिन मैं अपने वर्कफ़्लो का उपयोग शेल में कर रहा हूँ और मैं इसे अभी के लिए रखना चाहूँगा। इसलिए इसके बजाय, मैं सभी खुले बफ़र्स को वापस करना चाहूंगा, और शायद किसी भी बंद को बंद कर दूं (जैसे कि git checkoutएक शाखा के कारण जो अब उस फ़ाइल में नहीं है)।

मेरे पास निम्नलिखित ऐसपीट है जो मैंने Google खोज से लिए हैं:

(defun revert-all-buffers ()
  "Refreshes all open buffers from their respective files"
  (interactive)
  (let* ((list (buffer-list))
         (buffer (car list)))
    (while buffer
      (when (and (buffer-file-name buffer) 
                 (not (buffer-modified-p buffer)))
        (set-buffer buffer)
        (revert-buffer t t t))
      (setq list (cdr list))
      (setq buffer (car list))))
  (message "Refreshed open files"))

लेकिन इस टूट जाता है, तो यह मेरे खुली फ़ाइलों में से एक, यानी जब वापस लाने में में एक त्रुटि हिट B1, B2, B3, ..., Bnवापस लौटने की कोशिश करते समय त्रुटि B2रोकता है B3- Bnसे वापस लाया गया जा रहा है।

इस मामले में पॉप अप करने वाली किसी भी त्रुटि को अनदेखा करने के लिए मैं एमएसीएस को कैसे बता सकता हूं? मैं उपयोग नहीं करना चाहता global-auto-revert-modeक्योंकि प्रत्येक रिवर्ट कुछ भारी शुल्क सामान जैसे मेरे ऑटो-पूर्ण और सिंटैक्स चेकर फ़ाइल को फिर से पार्स करता है, एक या दूसरे के लिए emacs लटकाता है।


किस तरह की त्रुटि B2बफर को आपके उदाहरण में बदलने से रोकती है । मैं एक बहुत ही समान फ़ंक्शन (इस स्निपेट से प्राप्त होने की संभावना) का उपयोग करता हूं और इसने ठीक काम किया है।
कौशल मोदी

@ कौशल: ऐसा लगता है कि "फ़ाइल अब मौजूद नहीं है" एक करता है, और / या पैकेज द्वारा फेंकी गई त्रुटियां हैं जो मेरे पास फिर से चल रही हैं। अधिकतर मैंने देखा है कि इसे चलाने के बाद भी मुझे एक "फाइल बदल गई है जो पिछली बार देखी गई थी!" परC-x s
पैट्रिक कॉलिन्स

"file no longer exists".. अहा! मेरा संस्करण ठीक करता है कि :) जल्द ही इसे पोस्ट करूंगा।
कौशल मोदी

जवाबों:


12

मूल

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

यहां वह कोड दिया गया है जो मेरे लिए स्थिर है:

(defun modi/revert-all-file-buffers ()
  "Refresh all open buffers from their respective files."
  (interactive)
  (let* ((list (buffer-list))
         (buffer (car list)))
    (while buffer
      (let ((filename (buffer-file-name buffer)))
        ;; Revert only buffers containing files, which are not modified;
        ;; do not try to revert non-file buffers like *Messages*.
        (when (and filename
                   (not (buffer-modified-p buffer)))
          (if (file-exists-p filename)
              ;; If the file exists, revert the buffer.
              (with-current-buffer buffer
                (revert-buffer :ignore-auto :noconfirm :preserve-modes))
            ;; If the file doesn't exist, kill the buffer.
            (let (kill-buffer-query-functions) ; No query done when killing buffer
              (kill-buffer buffer)
              (message "Killed non-existing file buffer: %s" filename)))))
      (setq buffer (pop list)))
    (message "Finished reverting buffers containing unmodified files.")))

अपडेट करें

यहाँ @ ड्रू के घोल को देखने के बाद ऊपर का एक बेहतर और बेहतर डॉक्यूमेंटेड संस्करण है ।

(defun modi/revert-all-file-buffers ()
  "Refresh all open file buffers without confirmation.
Buffers in modified (not yet saved) state in emacs will not be reverted. They
will be reverted though if they were modified outside emacs.
Buffers visiting files which do not exist any more or are no longer readable
will be killed."
  (interactive)
  (dolist (buf (buffer-list))
    (let ((filename (buffer-file-name buf)))
      ;; Revert only buffers containing files, which are not modified;
      ;; do not try to revert non-file buffers like *Messages*.
      (when (and filename
                 (not (buffer-modified-p buf)))
        (if (file-readable-p filename)
            ;; If the file exists and is readable, revert the buffer.
            (with-current-buffer buf
              (revert-buffer :ignore-auto :noconfirm :preserve-modes))
          ;; Otherwise, kill the buffer.
          (let (kill-buffer-query-functions) ; No query done when killing buffer
            (kill-buffer buf)
            (message "Killed non-existing/unreadable file buffer: %s" filename))))))
  (message "Finished reverting buffers containing unmodified files."))

संदर्भ


5

एक और:

(defun revert-all-no-confirm ()
  "Revert all file buffers, without confirmation.
Buffers visiting files that no longer exist are ignored.
Files that are not readable (including do not exist) are ignored.
Other errors while reverting a buffer are reported only as messages."
  (interactive)
  (let (file)
    (dolist (buf  (buffer-list))
      (setq file  (buffer-file-name buf))
      (when (and file  (file-readable-p file))
        (with-current-buffer buf
          (with-demoted-errors "Error: %S" (revert-buffer t t)))))))

धन्यवाद। मैं चोरी कर रहा हूँ dolistबदलने के लिए शैली carऔर pop। मज़ेदार है कि आप अपने विन्यास में सुधार कैसे कर सकते हैं क्योंकि आप अधिक कुशल सीखते हैं :)
कौशल मोदी

@ कौशलमोडी यही कारण है कि मैंने इसे पोस्ट किया है। ;-)
ड्रू

1

मैंने कौसल के उत्तर को स्वीकार कर लिया क्योंकि मैं जो चाहता था, उसके सबसे करीब था, लेकिन मैंने ड्रू के समाधान का हिस्सा भी हड़प लिया। मैं लिपटे revert-bufferमें with-demoted-errorsऔर गिरा :preserve-modesतो पैरामीटर है कि मेरे वाक्य रचना चेकर हैं मेरी खुली फ़ाइलों के सभी फिर से पार्स। मैंने इसे संशोधित फ़ाइलों के साथ-साथ अनमॉडिफाइड को भी मारने दिया, क्योंकि मैं एक संशोधित C-x sएंट्रेंस git checkoutओपन के साथ गलती से- बाद में मुसीबत में पड़ जाता हूं ।

अंतिम संस्करण है:

(defun revert-all-buffers ()
  "Refresh all open buffers from their respective files."
  (interactive)
  (let* ((list (buffer-list))
         (buffer (car list)))
    (while buffer
      (let ((filename (buffer-file-name buffer)))
        ;; Revert only buffers containing files, which are not modified;
        ;; do not try to revert non-file buffers like *Messages*.
        (when filename
          (if (file-exists-p filename)
              ;; If the file exists, revert the buffer.
              (with-demoted-errors "Error: %S"
                (with-current-buffer buffer
                  (revert-buffer :ignore-auto :noconfirm)))
            ;; If the file doesn't exist, kill the buffer.
            (let (kill-buffer-query-functions) ; No query done when killing buffer
              (kill-buffer buffer)
              (message "Killed non-existing file buffer: %s" buffer))))
        (setq buffer (pop list)))))
  (message "Finished reverting non-file buffers."))

प्रगति संदेश जोड़े गए क्योंकि इससे कई फाइलें खुली दिखाई दे सकती हैं: emacs.stackexchange.com/a/50730/2418
ideasman42

1

मैं इसे ( condition-caseया ignore-errorsडॉक्स यहाँ ) के साथ ठीक कर दूँगा । मुझे नहीं पता कि तुम क्या करना चाहते हो ; यदि आप त्रुटियों के साथ कुछ करना चाहते हैं, यदि आप condition-caseपरिणाम को निर्दिष्ट करने के लिए उपयोग कर सकते हैं , या आप ignore-errorsबस जारी रखने के लिए उपयोग कर सकते हैं । कुछ इस तरह:

(defun revert-all-buffers ()
  "Refreshes all open buffers from their respective files"
  (interactive)
  (let* ((list (buffer-list))
         (buffer (car list)))
    (while buffer
      (when (and (buffer-file-name buffer) 
                 (not (buffer-modified-p buffer)))
        (set-buffer buffer)
        (ignore-errors (revert-buffer t t t)))
      (setq list (cdr list))
      (setq buffer (car list))))
  (message "Refreshed open files"))

0

@ ड्रू के उत्तर के आधार पर, परिवर्धन के साथ:

  • प्रगति रिपोर्टिंग (चूंकि यह कई फाइलों के साथ धीमी हो सकती है)
  • साफ पूर्ववत राज्य (संकुल है कि इतिहास पूर्ववत लोड जब बफर पुन: लोड के लिए समर्थन के साथ - पूर्ववत-फू-सत्र उदाहरण के लिए)
(defun revert-all-buffers ()
  "Refresh all open buffers from their respective files.

Buffers which no longer exist are closed.

This can be useful when updating or checking out branches outside of Emacs."
  (interactive)
  (let* ((filename-and-buffer-list ;; Pairs of '(filename . buf)'.
          (let ((temp-list nil))
            (dolist (buf (buffer-list))
              (let ((filename (buffer-file-name buf)))
                (when filename
                  (push (cons filename buf) temp-list))))
            temp-list))

         (count (length filename-and-buffer-list))
         (count-final 0)
         (count-close 0)
         (count-error 0)
         ;; Keep text at a fixed width when redrawing.
         (format-count
          (format "%%%dd" (length (number-to-string count))))
         (format-text
          (concat "Reverting [" format-count " of " format-count "] %3d%%: %s"))
         (index 1))

    (message "Begin reverting %d buffers..." count)
    (while filename-and-buffer-list
      (pcase-let ((`(,filename . ,buf) (pop filename-and-buffer-list)))
        ;; Revert only buffers containing files, which are not modified;
        ;; do not try to revert non-file buffers such as '*Messages*'.
        (message format-text
                 index count (round (* 100 (/ (float index) count))) filename)
        (if (file-exists-p filename)
            ;; If the file exists, revert the buffer.
            (if (with-demoted-errors "Error: %S"
                  (with-current-buffer buf
                    (let ((no-undo (eq buffer-undo-list t)))

                      ;; Disable during revert.
                      (unless no-undo
                        (setq buffer-undo-list t)
                        (setq pending-undo-list nil))

                      (unwind-protect
                          (revert-buffer :ignore-auto :noconfirm)

                        ;; Enable again (always run).
                        (unless no-undo
                          ;; It's possible a plugin loads undo data from disk,
                          ;; check if this is still unset.
                          (when (and (eq buffer-undo-list t)
                                     (null pending-undo-list))
                            (setq buffer-undo-list nil))))))
                  t)
                (setq count-final (1+ count-final))
              (setq count-error (1+ count-error)))

          ;; If the file doesn't exist, kill the buffer.
          (let (kill-buffer-query-functions) ;; No query done when killing buffer.
            (message "Closing non-existing file buffer: %s" buf)
            (kill-buffer buf)
            (setq count-close (1+ count-close))))
        (setq index (1+ index))))
    (message
     (concat
      "Finished Revert All: " (format "%d buffer(s)" count-final)
      (if (zerop count-close)
          ""
        (format ", %d closed" count-close))
      (if (zerop count-error)
          ""
        (format ", %d error (see message buffer)" count-error))))))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.