Vim Tips Wiki
(rewrite; discuss scrolloff; new script)
(Change <tt> to <code>, perhaps also minor tweak.)
Line 11: Line 11:
 
|category2=
 
|category2=
 
}}
 
}}
When searching in Vim, it can be useful to have the text scroll so that the line with the next search hit is in the middle of the screen. That's easy with the built in commands: type <tt>n</tt> to jump to the next search hit, then <tt>zz</tt> to vertically center the line. In addition, the <tt>'scrolloff'</tt> option can be used to automatically scroll text into view, so that search hits always have some "context" lines before and after.
+
When searching in Vim, it can be useful to have the text scroll so that the line with the next search hit is in the middle of the screen. That's easy with the built in commands: type <code>n</code> to jump to the next search hit, then <code>zz</code> to vertically center the line. In addition, the <code>'scrolloff'</code> option can be used to automatically scroll text into view, so that search hits always have some "context" lines before and after.
   
This tip describes <tt>'scrolloff'</tt>, and shows some mappings to vertically center search hits automatically. There is also a script with more features.
+
This tip describes <code>'scrolloff'</code>, and shows some mappings to vertically center search hits automatically. There is also a script with more features.
   
 
==Scrolloff option==
 
==Scrolloff option==
The <tt>'scrolloff'</tt> (scroll offset) option determines the minimum number of screen lines that you would like above and below the cursor. By default, <tt>'scrolloff'</tt> is <tt>0</tt> which means that you can move the cursor to any line in the window without causing scrolling.
+
The <code>'scrolloff'</code> (scroll offset) option determines the minimum number of screen lines that you would like above and below the cursor. By default, <code>'scrolloff'</code> is <code>0</code> which means that you can move the cursor to any line in the window without causing scrolling.
   
 
The following command scrolls the text so that (when possible) there are always at least five lines visible above the cursor, and five lines visible below the cursor:
 
The following command scrolls the text so that (when possible) there are always at least five lines visible above the cursor, and five lines visible below the cursor:
Line 23: Line 23:
 
</pre>
 
</pre>
   
This option applies to all commands, including searching. After entering the above command (which can be abbreviated as <tt>:set&nbsp;so=5</tt>), the next search hit will have at least five visible lines of text above and below (except when near the beginning or the end of the buffer).
+
This option applies to all commands, including searching. After entering the above command (which can be abbreviated as <code>:set so=5</code>), the next search hit will have at least five visible lines of text above and below (except when near the beginning or the end of the buffer).
   
Entering <tt>:set so=999</tt> will keep the [[VimTip182|cursor vertically centered]].
+
Entering <code>:set so=999</code> will keep the [[VimTip182|cursor vertically centered]].
   
 
==Simple mappings==
 
==Simple mappings==
Line 39: Line 39:
   
 
==Script==
 
==Script==
An alternative to the simple mappings is to use a script that can cycle between different states (only <tt>n</tt> and <tt>N</tt> are mapped):
+
An alternative to the simple mappings is to use a script that can cycle between different states (only <code>n</code> and <code>N</code> are mapped):
 
*''Normal'' – No mappings: search next and search previous work as normal (default).
 
*''Normal'' – No mappings: search next and search previous work as normal (default).
 
*''Scroll hit to middle if not on same page'' – No scrolling occurs if the next hit is after the first line and before the last line of the window; otherwise, the search hit is scrolled to the middle.
 
*''Scroll hit to middle if not on same page'' – No scrolling occurs if the next hit is after the first line and before the last line of the window; otherwise, the search hit is scrolled to the middle.
 
*''Scroll hit to middle'' – The search hit is always scrolled to the middle (when possible).
 
*''Scroll hit to middle'' – The search hit is always scrolled to the middle (when possible).
   
With the following script in your [[vimrc]], press F4 to cycle the behavior of <tt>n</tt> and <tt>N</tt>:
+
With the following script in your [[vimrc]], press F4 to cycle the behavior of <code>n</code> and <code>N</code>:
 
<pre>
 
<pre>
 
nnoremap <silent> <F4> :call <SID>SearchMode()<CR>
 
nnoremap <silent> <F4> :call <SID>SearchMode()<CR>

Revision as of 05:34, 13 July 2012

Tip 528 Printable Monobook Previous Next

created 2003 · complexity basic · version 6.0


When searching in Vim, it can be useful to have the text scroll so that the line with the next search hit is in the middle of the screen. That's easy with the built in commands: type n to jump to the next search hit, then zz to vertically center the line. In addition, the 'scrolloff' option can be used to automatically scroll text into view, so that search hits always have some "context" lines before and after.

This tip describes 'scrolloff', and shows some mappings to vertically center search hits automatically. There is also a script with more features.

Scrolloff option

The 'scrolloff' (scroll offset) option determines the minimum number of screen lines that you would like above and below the cursor. By default, 'scrolloff' is 0 which means that you can move the cursor to any line in the window without causing scrolling.

The following command scrolls the text so that (when possible) there are always at least five lines visible above the cursor, and five lines visible below the cursor:

:set scrolloff=5

This option applies to all commands, including searching. After entering the above command (which can be abbreviated as :set so=5), the next search hit will have at least five visible lines of text above and below (except when near the beginning or the end of the buffer).

Entering :set so=999 will keep the cursor vertically centered.

Simple mappings

Following are some useful mappings to make search results appear in the middle of the screen:

:nnoremap n nzz
:nnoremap N Nzz
:nnoremap * *zz
:nnoremap # #zz
:nnoremap g* g*zz
:nnoremap g# g#zz

Script

An alternative to the simple mappings is to use a script that can cycle between different states (only n and N are mapped):

  • Normal – No mappings: search next and search previous work as normal (default).
  • Scroll hit to middle if not on same page – No scrolling occurs if the next hit is after the first line and before the last line of the window; otherwise, the search hit is scrolled to the middle.
  • Scroll hit to middle – The search hit is always scrolled to the middle (when possible).

With the following script in your vimrc, press F4 to cycle the behavior of n and N:

nnoremap <silent> <F4> :call <SID>SearchMode()<CR>
function s:SearchMode()
  if !exists('s:searchmode') || s:searchmode == 0
    echo 'Search next: scroll hit to middle if not on same page'
    nnoremap <silent> n n:call <SID>MaybeMiddle()<CR>
    nnoremap <silent> N N:call <SID>MaybeMiddle()<CR>
    let s:searchmode = 1
  elseif s:searchmode == 1
    echo 'Search next: scroll hit to middle'
    nnoremap n nzz
    nnoremap N Nzz
    let s:searchmode = 2
  else
    echo 'Search next: normal'
    nunmap n
    nunmap N
    let s:searchmode = 0
  endif
endfunction

" If cursor is in first or last line of window, scroll to middle line.
function s:MaybeMiddle()
  if winline() == 1 || winline() == winheight(0)
    normal! zz
  endif
endfunction

See also

Comments