From: Vitalie Spinu <spinuvit@gmail.com>
To: Michael Mauger <mmaug@yahoo.com>
Cc: Emacs Devel <emacs-devel@gnu.org>
Subject: Re: Deffering redisplay in COMINT
Date: Tue, 25 Dec 2012 12:09:30 +0100 [thread overview]
Message-ID: <87obhi1j85.fsf@gmail.com> (raw)
In-Reply-To: <1354842513.76326.YahooMailNeo@web160901.mail.bf1.yahoo.com> (Michael Mauger's message of "Thu, 6 Dec 2012 17:08:33 -0800 (PST)")
>> Michael Mauger <mmaug@yahoo.com>
>> on Thu, 6 Dec 2012 17:08:33 -0800 (PST) wrote:
> I don't believe this is possible, but I figured I'd run it past the brain trust....
> In sql-interactive-mode, a derivative of comint, I will submit a SELECT
> statement that returns many very long rows (2000+ characters per line). The
> redisplay fireworks that follow are impressive but slow. As text streams to
> the buffer with `auto-hscroll-mode' enabled the screen flashes as it redraws the
> buffer with more lines of data and scrolled horizontally in different places
> until all the data stream is complete.
> I have figured out how to turn off horizontal scrolling with a
> comint-preoutput-filter-function' and a `pre-command-hook' for the duration of
> SQL command so the redisplay is limited to a slow march straight down the page
> without the intervening horizontal scrolling but the column number in the mode
> line going crazy. I've also discovered that if I switch to another buffer so
> that the SQL buffer is not displayed and then switch back, the SQL buffer is
> populated very quickly. (That is, Emacs can fetch the results quickly, it just
> can't redraw it quickly a couple of hundred times)
> So what I'm asking: Is there a way (say by setting `inhibit-redisplay' to t) for
> the duration of the comint command and then restoring redisplay when I am at the
> prompt at the end. The trick that I use for `auto-hscroll-mode' won't work
> because I don't find out about the completion until the user causes an event. I
> understand also that I don't want to universally block redisplay in case I
> switch to another buffer while the comint command is running and I want to
> interact with another buffer (i.e., I want to inhibit redisplay in that buffer
> only--buffer-local inhibit-redisplay). Looking at comint.el and based on my
> understanding of how processes are handled, I don't believe that it is easy to
> do because I don't know when the output is complete. (I've noticed in my
> disable auto-hscroll-mode code that the comint-preoutput-filter-function will
> get called a couple of hundred times with chunks of the output. I'm probably
> getting a redisplay after
> each chunk.)
> My only thought is that I could route the output to a temp buffer until I see
> the prompt at the end of a chunk
To the best of my knowledge this is the only way out. But it is not bad
at all. You have to replace comint-output-filter with your own filter
that does that. The filter is triggered each time emacs receives output
from the sub-process (roughly 500 chars last time I counted). It's
pretty trivial to wait for a prompt at the end of output chunk, and you
will be surprised how reliable this procedure actually is.
This is how we do it in ESS:
(defun ess-wait-for-process (proc &optional sec-prompt wait force-redisplay)
"Wait for 'busy property of the process to become nil.
If SEC-PROMPT is non-nil return if secondary prompt is detected
regardless of whether primary prompt was detected or not. If
WAIT is non-nil wait for WAIT seconds for process output before
the prompt check, default 0.001s. When FORCE-REDISPLAY is non-nil
force redisplay. You better use WAIT >= 0.1 if you need
FORCE-REDISPLAY to avoid excesive redisplay."
(unless (eq (process-status proc) 'run)
(ess-error "ESS process has died unexpectedly."))
(setq wait (or wait 0.001)) ;;xemacs is stuck if it's 0 here
(save-excursion
(while (or (accept-process-output proc wait)
(if (and sec-prompt (process-get proc 'sec-prompt))
nil
(if force-redisplay (redisplay 'force))
(process-get proc 'busy))))))
The 'busy is set in the process filter by searching for prompt anchored
at the end of output chunk.
HTH,
Vitalie
next prev parent reply other threads:[~2012-12-25 11:09 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-07 1:08 Deffering redisplay in COMINT Michael Mauger
2012-12-25 11:09 ` Vitalie Spinu [this message]
2013-01-06 8:09 ` Michael Mauger
2013-01-08 18:19 ` Stefan Monnier
2013-01-11 14:40 ` Michael Mauger
2013-01-11 15:55 ` Stefan Monnier
2013-01-13 8:14 ` Michael Mauger
2013-01-13 16:46 ` Eli Zaretskii
2013-01-16 14:39 ` Stefan Monnier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87obhi1j85.fsf@gmail.com \
--to=spinuvit@gmail.com \
--cc=emacs-devel@gnu.org \
--cc=mmaug@yahoo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).