1

Sometimes when in e.g. a Python or SQL buffer I accidentally evaluate something that outputs e.g. multiple megabytes of text into the buffer.

>>> zps = _read_zipfile_container(br.response().read(), br.geturl())
>>> len(zps)
1
>>> zps[0]  # oops
\xfc\xc0H\x19#\x15\x8a\xb4XN\xb5\x9b\xd2\xfeT\x9a\xbeL\xe7a\x90l\xb3Y\xfbL
\xf2Pq\x84\x941R\xa1H\xdb\x82\xe5T\x15\xb7]\xcd\xddk\xd2\xd9\x19$;\tHcW\x8
4\x83\xc1d\x06S\x10\xcc\xb60\xd9T\x89m=\xba\'\x1ay\x0b\x83d\x0bR\xfae\xd1F
H\x19#x15\x8a\xb4-XNUq\xdb]\xdeF\xdf\xde\xc2 \x99\x85A\x1a\x9b!\x1c\x9b!\x

... all one line, but rendered increasingly slowly to many 
                            tens of thousands of continuation lines ... 

At the moment I can either kill the process, or else wait for it to all render to the buffer and then delete it manually (might take a half hour, particularly when the output string has no linebreaks). I usually have to choose the latter option to avoid losing work in progress. Is there any way to discard the text without losing the buffer?

1

For large output, the process filter function (comint-output-filter in this case) is called many times. So the simple solution is to replace the process filter function as below.

If you print a large object, then please call my-ignore-output in the process buffer. It replaces the process filter by my-ignore-output--filter-func. The process filter prints a number in the echo area. It indicates how many times the filter function (my-ignore-output--filter-func) is called.

If the number stops increasing, then please call my-ignore-output-cleanup. It restores the original filter function and deletes the previous output.

If you use the following code, I recommend byte-compiling the code for performance. I tested this in the inferior python buffer but not in SQL buffer.

(require 'cl-lib)
(require 'comint)

(defvar my-ignore-output--counter nil)
(defvar my-ignore-ouptut--original-filter nil)
(defvar my-ignore-output--last-input-end nil)

(defun my-ignore-output--filter-func (_proc _output)
  (cl-incf my-ignore-output--counter)
  (let ((message-log-max nil))
    (message "%d" my-ignore-output--counter)))

(defun my-ignore-output ()
  (interactive)
  (let ((proc (get-buffer-process (current-buffer))))
    (unless (equal (process-filter proc) #'my-ignore-output--filter-func)
      (setq my-ignore-ouptut--original-filter (process-filter proc)
            my-ignore-output--counter 0
            my-ignore-output--last-input-end (marker-position comint-last-input-end))
      (set-process-filter proc #'my-ignore-output--filter-func))))

(defun my-ignore-output-cleanup ()
  (interactive)
  (let ((proc (get-buffer-process (current-buffer)))
        (inhibit-read-only t))
    (delete-region my-ignore-output--last-input-end
                   (marker-position (process-mark proc)))
    (set-process-filter proc my-ignore-ouptut--original-filter)
    ;; Print the prompt
    (comint-simple-send proc "\n")))
  • This looks really cool, gonna put it through it's paces in the wild before accepting the answer! – EoghanM Apr 3 '16 at 21:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.