[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: *shell*: annoying behavior with long output
From: |
Michael Slass |
Subject: |
Re: *shell*: annoying behavior with long output |
Date: |
Mon, 17 May 2004 23:35:12 GMT |
User-agent: |
Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 |
bill <please_post@nomail.com> writes:
>I'm a big fan of the Emacs shell, but one thing that really annoys
>me is its behavior when a lot of output is sent to stdout. The
>cursor ends up at the very bottom of the output, even though,
>invariably I'm more interested in looking at the top first and then
>work my way down, which means that I end up having to search
>backwards for the shell prompt to see the beginning of the output.
>
>I have not found a satisfactory solution to this. When I'm not in
>the Emacs shell, the solution is simple: I pipe the output through
>/usr/bin/less. But the Emacs shell can't handle less too well.
>
>Another thing I've tried is to set the mark before executing a
>command, and then C-x C-x after executing it. The problem with
>this is that the top of the output gets placed in the middle of
>the screen, so I have to do C-u 0 C-l to see the top screenful of
>output. Besides, this works only when I know ahead of time that
>the output will be long.
>
>Is there a way to tell the Emacs shell to keep the cursor at the
>top of the output in such a way that the top screenful of output
>is what is visible of the *shell* buffer immediately after executing
>a command?
>
>Thanks!
>
> -bill
You'd think that frobbing this variable would do it:
,----
| comint-scroll-to-bottom-on-output's value is nil
|
| Documentation:
| *Controls whether interpreter output causes window to scroll.
| If nil, then do not scroll. If t or `all', scroll all windows showing buffer.
| If `this', scroll only the selected window.
| If `others', scroll only those that are not the selected window.
|
| The default is nil.
|
| See variable `comint-scroll-show-maximum-output' and function
| `comint-postoutput-scroll-to-bottom'. This variable is buffer-local.
|
| You can customize this variable.
|
| Defined in `comint'.
`----
But I can't get any effects by changing it at all.
So, I hacked this together, which will return you to your starting
point if a prompt shows up in the shell N lines after your last
prompt, where N is your screen height. I tried the more elegant
solution of using around-advice, and a (let ...) form to set the value
of my-comint-process-start-point:
,----
| (defadvice comint-send-input (around my-comint-send-input)
| "go to beginning after comint-send-input"
| (let ((my-comint-process-start-point (point)))
| ad-do-it))
`----
but the filter function was always seeing
my-comint-process-start-point as undefined, so I've gone with the
uglier (because more global) setq.
Criticisms from gurus welcomed as always.
(defadvice comint-send-input (before my-comint-send-input)
"Set starting point variable for use in `my-comint-return-to-start-maybe'"
(setq my-comint-process-start-point (point)))
(ad-activate 'comint-send-input)
(defun my-comint-return-to-start-maybe (output)
"Return to start of shell-output if it has scrolled off-screen.
Depends on advising `comint-send-input' to set the value of
`my-comint-process-start-point' before running.
This can be done with this advice form:
\(defadvice comint-send-input (before my-comint-send-input)
\"go to beginning after comint\"
(setq my-comint-process-start-point (point)))
"
(if (and (bound-and-true-p my-comint-process-start-point)
(string-match comint-prompt-regexp output)
(> (count-screen-lines my-comint-process-start-point (point))
(cdr (assoc 'height (frame-parameters)))))
(goto-char (1+ my-comint-process-start-point))))
--
Mike Slass