Vim Tips Wiki
No edit summary
(Change <tt> to <code>, perhaps also minor tweak.)
 
(14 intermediate revisions by 3 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.
 
 
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.
 
 
This can be accomplished by issuing the following commands:
 
   
  +
==Mapping==
  +
Enter the following command (or put in your [[vimrc]]):
 
<pre>
 
<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>
" view file in 2 columns
 
set noscrollbind
 
set nowrap
 
normal mb50%zz
 
vert split
 
exe "normal Lma\<c-w>l'azt"
 
set scrollbind
 
exe "normal \<c-w>h"
 
set scrollbind
 
 
</pre>
 
</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>.
Here is a macro you can map to:
 
   
  +
The mapping performs these operations:
 
<pre>
 
<pre>
  +
:<C-u> " clear command line (if in visual mode)
" display current file in two columns
 
 
let @z=&so " save scrolloff in register z
noremap<silent> ZC :<C-U>let @z=&so<CR>:set so=0<CR>maHmz:set noscb<CR>
 
  +
:set so=0 noscb " set scrolloff to 0 and clear scrollbind
\:vs<CR><C-W>wLzt:set scb<CR><C-W>p:set scb<CR>
 
\`zzt`a:let &so=@z<CR>
+
: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
 
</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>).
Replace ZC with your mapping of choice. This will:
 
   
  +
;Problems
<pre>
 
  +
*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).
:<C-U>let @z=&so " enter the command line, clear it, and save the current
 
  +
*Register z is changed.
'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'
 
 
</pre>
 
 
Yet another keymap to solve this problem (other than the solution above this one doesn't set scrolloff though, so you might want to set that as in the aforementioned keymap):
 
 
<pre>
 
noremap <silent> ZC :bo vs<cr>Ljzt:setl scb<cr><c-w>p:setl scb<cr>
 
</pre>
 
   
  +
==See also==
This will:
 
  +
*[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>
:bo vs<cr> " Split the window vertically, make sure the new window is on the right
 
  +
function! AddColumn()
Lj " Move the cursor to the first line on the next page (this requires scrolloff to be 0)
 
 
exe "norm \<C-u>"
zt " Scroll that line to the top
 
  +
let @z=&so
:setl scb<cr> " Set scrollbind
 
  +
set noscb so=0
<c-w>p " Return to the previous window
 
  +
bo vs
:setl scb<cr> " Set scrollbind
 
  +
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.
   
  +
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?