bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: shell-command-on-region fooled by long lines


From: Kevin Rodgers
Subject: Re: shell-command-on-region fooled by long lines
Date: Wed, 01 Feb 2006 10:07:13 -0700
User-agent: Mozilla Thunderbird 0.9 (X11/20041105)

Dan Jacobson wrote:
> shell-command-on-region on this:
>   perl -le 'for(1..6){print $_ x 111}'
> mistakenly thinks it is showing all the output in the minibuffer, so
> it doesn't create new a new buffer for the output, when in fact it
> gets fooled by the wrapped lines. Adjust the 6 and 111 for your screen
> if you don't see the effect. I was using Emacs.geometry: 81x35+-6+.
> emacs-version"21.4.1"

shell-command always captures the command's output in the *Shell Command
Output* buffer.  Whether the output is displayed in the echo area or in
a pop-up buffer is determined by the resize-mini-windows and
max-mini-window-height variables.  You are right, though, that the
length of the output lines is not considered, only the number of output
lines.

Here's an experimental version of display-message-or-buffer that counts
display lines by comparing each line length to the frame width.  It
tries to do so efficiently for both empty messages and large messages,
like the original:

(defun display-message-or-buffer (message
                                  &optional buffer-name not-this-window frame)
"Display MESSAGE in the echo area if possible, otherwise in a pop-up buffer.
MESSAGE may be either a string or a buffer.

A buffer is displayed using `display-buffer' if MESSAGE is too long for
the maximum height of the echo area, as defined by `max-mini-window-height'
if `resize-mini-windows' is non-nil.

Returns either the string shown in the echo area, or when a pop-up
buffer is used, the window used to display it.

If MESSAGE is a string, then the optional argument BUFFER-NAME is the
name of the buffer used to display it in the case where a pop-up buffer
is used, defaulting to `*Message*'.  In the case where MESSAGE is a
string and it is displayed in the echo area, it is not specified whether
the contents are inserted into the buffer anyway.

Optional arguments NOT-THIS-WINDOW and FRAME are as for `display-buffer',
and only used if a buffer is displayed."
  (cond ((and (stringp message)
              (not (string-match "\n" message))
              (<= (length message) (frame-width)))
         ;; Trivial case where we can use the echo area
         (message "%s" message))
        ((and (stringp message)
              (= (string-match "\n" message) (1- (length message)))
              (<= (1- (length message)) (frame-width)))
         ;; Trivial case where we can just remove single trailing newline
         (message "%s" (substring message 0 (1- (length message)))))
        (t
         ;; General case
         (with-current-buffer
             (if (bufferp message)
                 message
               (get-buffer-create (or buffer-name "*Message*")))
           (unless (bufferp message)
             (erase-buffer)
             (insert message))
           (let* ((max-height (if resize-mini-windows
                                  (cond ((floatp max-mini-window-height)
                                         (* (frame-height)
                                            max-mini-window-height))
                                        ((integerp max-mini-window-height)
                                         max-mini-window-height)
                                        (t 1))
                                1))
                  (line 1)              ; buffer position
                  (height 1))
             (unless (= (buffer-size) 0)
               (unless (> max-height (frame-height))
                 (save-excursion
                   (goto-char (point-min))
                   (while (and (<= height max-height)
                               (re-search-forward "\n" nil t))
                     (unless (eobp)
                       (setq height (1+ height)))
                     (when (> (- (point) line 1) (frame-width))
                       (setq height (1+ height)))
                     (setq line (point)))
                   (when (> (- (point) line) (frame-width))
                     (setq height (1+ height)))))
               (if (> height max-height)
                   (progn               ; buffer
                     (goto-char (point-min))
(display-buffer (current-buffer) not-this-window frame))
                 (progn                 ; echo area
                   (goto-char (point-max))
                   (when (bolp)
                     (backward-char 1))
                   (message "%s" (buffer-substring (point-min)
                                                   (point)))))))))))

--
Kevin Rodgers





reply via email to

[Prev in Thread] Current Thread [Next in Thread]