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?

Drew
  • 75,699
  • 9
  • 109
  • 225
EoghanM
  • 205
  • 1
  • 4
  • It may help http://emacs.stackexchange.com/questions/5545/how-to-prevent-slow-down-when-an-inferior-processes-generates-long-lines – artscan Apr 01 '16 at 01:37

1 Answers1

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")))
sho
  • 146
  • 3
  • This looks really cool, gonna put it through it's paces in the wild before accepting the answer! – EoghanM Apr 03 '16 at 21:26