0

I'm using Emacs 24.2 with a line-wrapping activated.

When I read log files of various simulations which contain messages like: "Error: ...some message...", I perform an incremental search: C-s error RET, C-s, C-s...

I find it very annoying that the highlighted result of the search (the word Error) is displayed at the bottom of the screen, and all the additional wrapped lines can't be seen:

enter image description here

I'd like to add modifications which ensure that the whole line of text will be displayed in the buffer, like this:

enter image description here

I found this question concerning re-centering of the search results. It seems that I could use the same defadvice statements for the search functions, but rather than re-centering the line I need just scroll the screen down by the number of wrapped parts.

How to do this?

Community
  • 1
  • 1
Vasiliy
  • 16,221
  • 11
  • 71
  • 127

3 Answers3

1

You can use the solution on the question you reference, but changing recenter-top-bottom by this highly untested function:

(defun scroll-if-truncated()
  (scroll-up
   (/ (- (save-excursion
           (end-of-line) (point))
         (save-excursion
           (beginning-of-line) (point)))
      (window-body-width))))
juanleon
  • 9,220
  • 30
  • 41
0

After playing a bit with the code according to @juanleon's advice, I ended up with this:

;; Execute after each update in isearch-mode
(setq isearch-update-post-hook 'show-whole-line)


(defun show-whole-line ()
  "Scroll such that the whole line (which contains the point) will be visible."

  ;; If it is the top part which is truncated
  (if (not (pos-visible-in-window-p (line-beginning-position)))
      (let
      ((amount 
        ;; the required number of lines to scroll
        (ceiling (/
              (- (window-start) 
             (line-beginning-position))
              (float (window-body-width))))))
    ;; don't scroll at all if the search result will be scrolled out
    (if (< amount (/ 
               (- (window-end)
              (point) )
               (float (window-body-width))))
        (scroll-down amount)))

    ;; Else
    (if (not (pos-visible-in-window-p (line-end-position)))
    (let
        ((amount 
          (min 
           ;; the required number of lines to scroll
           (ceiling (/ 
             (- 
              (line-end-position) 
              (window-end (selected-window) t)) 
             (float (window-body-width))) )
           ;; however not to scroll out the first line
           (/ (- (line-beginning-position) (window-start)) (window-body-width)))))
      (scroll-up amount)))))

Few explanations:

  • Setting defadvice for isearch-forward is not enough - this function is not called again when you add chars to the search string. After a quick review of isearch.el.gz package I decided to advice to isearch-update function. This also eliminates the need of adding a separate advice for isearch-repeat-forward and etc. Later I noticed that there is a predefined hook in isearch-update, therefore no need for defadvice here.
  • show-whole-line function checks whether the beginning of the current line is visible. If not, it scrolls-down to show the beginning of the line, unless this scrolling will result in hiding the search match itself.
  • If the beginning of the line is visible, show-whole-line checks whether the end of the line is also visible. If not, it scrolls-up to show the end of the line, unless this scrolling will result in hiding the beginning of the line. I prefer to be able to see the beginning of the line.

This function and a hook work pretty well, but there is one annoying thing about it: the function is called when you initially press C-s (before you typed in any search string). This means that if the point is at a line which has its beginning or end out of the window, a simple invocation of C-s will result in scrolling in some manner.

While not critical at all, I'll be glad to hear suggestions how to remove the above side effect.

Vasiliy
  • 16,221
  • 11
  • 71
  • 127
0

You should be able to get the behavior you want using variables scroll-conservatively and scroll-margin, in particular the latter.

Drew
  • 29,895
  • 7
  • 74
  • 104