Vim Tips Wiki
No edit summary
(Change <tt> to <code>, perhaps also minor tweak.)
 
(18 intermediate revisions by 5 users not shown)
Line 1: Line 1:
  +
{{TipNew
==View text file in two columns==
 
  +
|id=1615
  +
|previous=1614
  +
|next=1616
  +
|created=2009
  +
|complexity=basic
  +
|author=Nsg
  +
|version=7.0
  +
|subpage=/200902
  +
|category1=
  +
|category2=
  +
}}
  +
When reading text, it can be useful to make a wide window, then split it vertically so two consecutive pages of text can be seen in the left and right windows.
   
  +
With a large monitor, you might enter <code>:set columns=160</code> to make the screen 160 columns wide. This tip can then be used to split the screen to show two windows, with the '<code>scrollbind</code>' option set so that scrolling one window also scrolls the other window.
Large wide monitors can be utilized better if text can be viewed in multiple columns.
 
   
  +
==Mapping==
The idea is to make wide widow (132, 160 or even more characters wide), then split it vertically, view 2 consequtive pages of the same text in left and right split widows and, finally, scrollbind them together to keep them synchronized.
 
  +
Enter the following command (or put in your [[vimrc]]):
  +
<pre>
 
:noremap <silent> <Leader>vs :<C-u>let @z=&so<CR>:set so=0 noscb<CR>:bo vs<CR>Ljzt:setl scb<CR><C-w>p:setl scb<CR>:let &so=@z<CR>
  +
</pre>
   
  +
With the default leader, you can now press <code>\vs</code> to vertically split the screen into two windows with '<code>scrollbind</code>' set. To display only a single window, press Ctrl-W then <code>o</code>.
This can be accomplished by issuing the following commands:
 
   
  +
The mapping performs these operations:
 
<pre>
 
<pre>
  +
:<C-u> " clear command line (if in visual mode)
" view file in 2 columns
 
 
let @z=&so " save scrolloff in register z
set noscrollbind
 
  +
:set so=0 noscb " set scrolloff to 0 and clear scrollbind
set nowrap
 
  +
:bo vs " split window vertically, new window on right
normal mb50%zz
 
  +
Ljzt " jump to bottom of window + 1, scroll to top
vert split
 
  +
:setl scb " setlocal scrollbind in right window
exe "normal Lma\<c-w>l'azt"
 
  +
<C-w>p " jump to previous window
set scrollbind
 
  +
:setl scb " setlocal scrollbind in left window
exe "normal \<c-w>h"
 
  +
:let &so=@z " restore scrolloff
set scrollbind
 
 
</pre>
 
</pre>
   
  +
The mapping clears '<code>scrollbind</code>' before manipulating the windows so that the position of the second window can be adjusted without scrolling the first window. Setting '<code>scrolloff</code>' to 0 allows the cursor to be positioned at the bottom of the screen (with command <code>L</code>).
Here is a macro you can map to:
 
   
  +
;Problems
  +
*If the cursor is in the last line when the mapping is executed, the mapping fails because <code>j</code> cannot move the cursor down (and the remaining commands are not executed).
  +
*Register z is changed.
  +
  +
==See also==
  +
*[http://groups.google.com/group/vim_use/browse_thread/thread/64c46a0f0c573003/942231124a5163f4 vim_use discussion]
  +
*[http://www.drchip.org/astronaut/vim/index.html#MPAGE MPage] plugin that supports multiple windows (two or more) with sequential text
  +
  +
==Comments==
  +
I put this into a function:
 
<pre>
 
<pre>
  +
noremap <silent> <Leader>ac :exe AddColumn()<CR>
" display current file in two columns
 
  +
function! AddColumn()
noremap<silent> ZC :<C-U>let @z=&so<CR>:set so=0<CR>maHmz:set noscb<CR>
 
 
exe "norm \<C-u>"
\:vs<CR><C-W>wLzt:set scb<CR><C-W>p:set scb<CR>
 
\`zzt`a:let &so=@z<CR>
+
let @z=&so
  +
set noscb so=0
  +
bo vs
  +
exe "norm \<PageDown>"
 
setl scrollbind
  +
wincmd p
 
setl scrollbind
  +
let &so=@z
  +
endfunction
 
</pre>
 
</pre>
   
  +
Except when I try to scroll one of the buffer windows by one line or more. In that case, the line-difference between each buffer is reduced to zero. Curiously, this works perfectly when done by hand in the command prompt.
Replace ZC with your mapping of choice. This will:
 
:<C-U>let @z=&so " enter the command line, clear it, and save the current 'scrolloff' in register z
 
:set so=0 " set scrolloff to 0 so the cursor can get to the edge of the page
 
maHmz " save cursor position using marks a and z so we can get back later
 
:set noscb " reset 'scrollbind' so we can scroll in the new window
 
:vs<CR><C-W>w " split a vertical window and switch to it
 
Lzt " move to the bottom and scroll it to the top
 
:set scb<CR><C-W>p:set scb<CR> " scrollbind both windows
 
`zzt`a:let &so=@z " restore cursor position and 'scrolloff'
 
 
   
  +
I have read that that line-difference is meant for 2 different files. However, we are using the same file, but in two different windows. Then, how do I keep that line difference valid between the windows on_scroll?
[[Category:Usage]]
 

Latest revision as of 06:39, 13 July 2012

Tip 1615 Printable Monobook Previous Next

created 2009 · complexity basic · author Nsg · version 7.0


When reading text, it can be useful to make a wide window, then split it vertically so two consecutive pages of text can be seen in the left and right windows.

With a large monitor, you might enter :set columns=160 to make the screen 160 columns wide. This tip can then be used to split the screen to show two windows, with the 'scrollbind' option set so that scrolling one window also scrolls the other window.

Mapping[]

Enter the following command (or put in your vimrc):

:noremap <silent> <Leader>vs :<C-u>let @z=&so<CR>:set so=0 noscb<CR>:bo vs<CR>Ljzt:setl scb<CR><C-w>p:setl scb<CR>:let &so=@z<CR>

With the default leader, you can now press \vs to vertically split the screen into two windows with 'scrollbind' set. To display only a single window, press Ctrl-W then o.

The mapping performs these operations:

:<C-u>              " clear command line (if in visual mode)
let @z=&so          " save scrolloff in register z
:set so=0 noscb     " set scrolloff to 0 and clear scrollbind
:bo vs              " split window vertically, new window on right
Ljzt                " jump to bottom of window + 1, scroll to top
:setl scb           " setlocal scrollbind in right window
<C-w>p              " jump to previous window
:setl scb           " setlocal scrollbind in left window
:let &so=@z         " restore scrolloff

The mapping clears 'scrollbind' before manipulating the windows so that the position of the second window can be adjusted without scrolling the first window. Setting 'scrolloff' to 0 allows the cursor to be positioned at the bottom of the screen (with command L).

Problems
  • If the cursor is in the last line when the mapping is executed, the mapping fails because j cannot move the cursor down (and the remaining commands are not executed).
  • Register z is changed.

See also[]

Comments[]

I put this into a function:

noremap <silent> <Leader>ac :exe AddColumn()<CR>
function! AddColumn()
  exe "norm \<C-u>"
  let @z=&so
  set noscb so=0
  bo vs
  exe "norm \<PageDown>"
  setl scrollbind
  wincmd p
  setl scrollbind
  let &so=@z
endfunction

Except when I try to scroll one of the buffer windows by one line or more. In that case, the line-difference between each buffer is reduced to zero. Curiously, this works perfectly when done by hand in the command prompt.

I have read that that line-difference is meant for 2 different files. However, we are using the same file, but in two different windows. Then, how do I keep that line difference valid between the windows on_scroll?