"book" split for vim?

118 views
Skip to first unread message

Nelson Castillo

unread,
Dec 22, 2008, 12:55:03 AM12/22/08
to vim...@googlegroups.com
Hello.

Is there a way to do a vertical split where you can read something
like you read a book?

Let's say you cannot edit in the right window but that it shows what
comes after the left window.

It would be useful for reading source code in wide-screen monitors.

Regards.

Tony Mechelynck

unread,
Dec 22, 2008, 1:22:36 AM12/22/08
to vim...@googlegroups.com

Try ":vsplit" followed by adjusting the views (e.g. PgDn in one of the
windows), and then ":setlocal scrollbind" in both windows. Then both
windows will scroll together; if they come out of sync, adjust them (in
gvim) by means of the non-current window's scrollbar.

Best regards,
Tony.
--
Join in the new game that's sweeping the country. It's called
"Bureaucracy". Everybody stands in a circle. The first person to do
anything loses.

Tom Link

unread,
Dec 22, 2008, 4:14:03 AM12/22/08
to vim_use
> Try ":vsplit" followed by adjusting the views (e.g. PgDn in one of the
> windows), and then ":setlocal scrollbind" in both windows.

I tried to wrap this up in a function. Unfortunately it doesn't seem
to work properly. The windows always get out of sync:

function! reader#Reader()
let top = line('w$') + 1

wincmd v
exec 'norm! '. top .'ztM'
setlocal scrollbind

wincmd p
setlocal scrollbind
endf

Do you have an idea how to make this work?

Regards,
Thomas.

fritzophrenic

unread,
Dec 22, 2008, 10:33:41 AM12/22/08
to vim_use


On Dec 22, 3:14 am, Tom Link <micat...@gmail.com> wrote:
>
> I tried to wrap this up in a function. Unfortunately it doesn't seem
> to work properly. The windows always get out of sync:
>
> function! reader#Reader()
>     let top = line('w$') + 1
>
>     wincmd v
>     exec 'norm! '. top .'ztM'
>     setlocal scrollbind
>
>     wincmd p
>     setlocal scrollbind
> endf
>
> Do you have an idea how to make this work?
>

That looks like a pretty neat function! When do the Windows get out of
sync? It *looks* like it should work.

Do you have "scrolloff" set to anything? To make it work in general,
you'll need to clear this option at the beginning of your function and
(probably) restore it later.

Tom Link

unread,
Dec 22, 2008, 11:55:00 AM12/22/08
to vim_use
> Do you have "scrolloff" set to anything? To make it work in general,
> you'll need to clear this option at the beginning of your function and
> (probably) restore it later.

No, scrolloff is 0. The strange thing is that it works when I enter
the lines manually on the command line. When I call it as a function
the other window is out of sync after pressing pagedown + pageup. I
suspect that for whatever reason scrollbind doesn't properly set the
other window's offset when running the code as a function. Maybe zt
should be replaced with something else in the context of a script.

BTW the function currently assumes 'splitright'.

Nelson Castillo

unread,
Feb 20, 2009, 12:06:52 AM2/20/09
to vim...@googlegroups.com

Thanks a lot for your answer. I am really sorry for replying this late
because you tried to help me promptly.

I tried this and I got exactly the same thing in both windows after
:setlocal scrollbind, which is what is supposed to happen anyway.

Anyway, I think I can do with vsplit...

What I really wanted to have was the illusion that I had a big
vertical monitor and not a wide screen when scrolling windows.

Thus if each number form the following list were pages say in a C program:

1
2
3
4
4
5
6

I really wish I could get this in my wide-screen monitor:

23

And if I scrolled a little (in only one of the windows) I could eventually get

34 or 56

I don't know if this is possible. It would really be useful for
today's laptop with wide-screens when programming.

Thanks again.

Tom Link

unread,
Feb 20, 2009, 1:05:58 AM2/20/09
to vim_use
> I tried this and I got exactly the same thing in both windows after
> :setlocal scrollbind, which is what is supposed to happen anyway.

You can set the position of the synchronized windows by moving the
scrollbar with the mouse -- as pointed out by others.

I personally wish there were a way to do this from vimscript though. I
would like to use such a split view for reading plain-text ebooks.

John Beckett

unread,
Feb 20, 2009, 2:10:15 AM2/20/09
to vim...@googlegroups.com
On the Vim Tips wiki, a new contributor called Nsg
has created a tip on this:
http://vim.wikia.com/wiki/View_text_file_in_two_columns

I'd really like someone to look at the tip and report:
1. Is it the same as was posted here?
2. Does it work?
3. Is it worth keeping on the wiki?

John

Tom Link

unread,
Feb 20, 2009, 3:49:35 AM2/20/09
to vim_use
>  2. Does it work?

Not the way it is posted. With minor modifications it works to some
degree:

set noscrollbind
botright vert split
normal Ljzt
set scrollbind
wincmd p
set scrollbind

But this doesn't work (for me) when being executed from a function or
if you source those lines from a file. So you'd have to enter the
commands on the command line which isn't really practical. I also
noticed minor "line shifts" so 2<pagedown> doesn't always get you to
the next book page -- but maybe there is an option I forgot/don't know
about controlling the behaviour of pagedown.

I'd say, a good start but it doesn't really work yet.

Tony Mechelynck

unread,
Feb 20, 2009, 5:08:36 AM2/20/09
to vim...@googlegroups.com

":set [no]scrollbind" should be ":setlocal" -- you don't want new [No
Name] buffers to open in 'scrollbind' mode (to be scrolled "together"
after you fill them with more than one screen of data).


Best regards,
Tony.
--
So when I saw the post to comp.editors, I rushed over to the FTP site to
grab it. So I yank apart the tarball, light x candles, where x= the
vim version multiplied by the md5sum of the source divided by the MAC of
my NIC (8A3FA78155A8A1D346C3C4A), put on black robes, dim the lights,
wave a dead chicken over the hard drive, and summon the power of GNU GCC
with the magic words "make config ; make!".
[Jason Spence, compiling Vim 5.0]

Tom Link

unread,
Feb 20, 2009, 5:49:34 AM2/20/09
to vim_use
> ":set [no]scrollbind" should be ":setlocal"

Hm, ok.

David Liang wrote it works if you use a keymap. After checking his
macro, I currently use the following keymap, which seems to work:

noremap <silent> ZC :bo vs<cr>Ljzt:setl scb<cr><c-w>p:setl scb<cr>

David also makes sure that scrolloff is set to 0 when splitting the
window which is necessary for L to move the cursor to the last line.

David Liang

unread,
Feb 20, 2009, 5:51:05 AM2/20/09
to vim_use
I had this same problem a couple days ago and like Tom, I tried a
functional approach at first, but the windows would somehow get de-
synced. I ended up writing a macro to do it--see the wiki page for
details. It uses @z and marks a and z, which I have set aside as temps
by convention.

Tony Mechelynck

unread,
Feb 20, 2009, 6:13:12 AM2/20/09
to vim...@googlegroups.com

By "keymap" you mean a mapping, don't you? The term "keymap" has a
technical meaning in Vim, as a script containing the ":loadkeymap"
command followed (in a specific format) by several (often many)
language-mappings. See the scripts in $VIMRUNTIME/keymap/ for examples.
These scripts are activated by setting the 'keymap' option (again,
preferably by a ":setlocal" command).

The mapping you show (and where I know my mailer probably misquoted the
spaces next to <> signs) includes two instances of the ":setl[ocal]"
command, none of the ":set" command. I won't criticize its contents
(favourably or unfavourably), I'm leaving that to better specialists of
Vim's scrolling commands.


Best regards,
Tony.
--
God made machine language; all the rest is the work of man.

ssiz...@gmail.com

unread,
Feb 20, 2009, 6:38:32 AM2/20/09
to vim...@googlegroups.com
I really like this idea of splitting, and would like it to adjust to
my three-pane setup.
I don't understand everything that's going on here, my most basic
guess is that it needs another :vs. But modified how? All it gets me
is two windows looking the same and the third one acting as expected.


noremap<silent> ZC :<C-U>let @z=&so<CR>:set so=0<CR>maHmz:set noscb<CR>
\:vs<CR><C-W>wLzt:set scb<CR><C-W>p:set scb<CR>
\`zzt`a:let &so=@z<CR>
" \:vs<CR><C-W>wLzt:set scb<CR><C-W>p:set scb<CR>
" \`zzt`a:let &so=@z<CR>

Tom Link

unread,
Feb 20, 2009, 6:47:13 AM2/20/09
to vim_use
> By "keymap" you mean a mapping, don't you?

It's clear from the context this is no keymap in the vim sense of the
word. But you're right that I should care more about vim terminology.

> The mapping you show (and where I know my mailer probably misquoted the
> spaces next to <> signs) includes two instances of the ":setl[ocal]"
> command, none of the ":set" command.

Hm?

David Liang

unread,
Feb 20, 2009, 6:54:07 AM2/20/09
to vim_use
noremap<silent> ZC :<C-U>let @z=&so<CR>:set so=0<CR>maHmz:set
noscb<CR>
\:vs<CR>:vs<CR><C-W>wLzt<C-W>wLztLzt
\:set scb<CR><C-W>p:set scb<CR><C-W>h:set scb<CR>
\`zzt`a:let &so=@z<CR>


On Feb 20, 3:38 am, ssiza...@gmail.com wrote:

ssiz...@gmail.com

unread,
Feb 20, 2009, 7:00:26 AM2/20/09
to vim...@googlegroups.com
On Fri, Feb 20, 2009 at 12:54, David Liang <bmd...@gmail.com> wrote:
>
> noremap<silent> ZC :<C-U>let @z=&so<CR>:set so=0<CR>maHmz:set
> noscb<CR>
> \:vs<CR>:vs<CR><C-W>wLzt<C-W>wLztLzt
> \:set scb<CR><C-W>p:set scb<CR><C-W>h:set scb<CR>
> \`zzt`a:let &so=@z<CR>
>

Woah, thanks a lot! Works like a charm.

Tony Mechelynck

unread,
Feb 20, 2009, 7:28:59 AM2/20/09
to vim...@googlegroups.com
> \`zzt`a:let&so=@z<CR>

> " \:vs<CR><C-W>wLzt:set scb<CR><C-W>p:set scb<CR>
> " \`zzt`a:let&so=@z<CR>
>

Well, let's set out the workflow (from top to bottom, and looks best in
a fixed-width font):
|
+------<----+----->-----+
| |
| (split off)
| (window 2 )
| |
| +-------->--------+
| | |
| | (split off)
| | (window 3 )
| | |
(make sure window 1 ) (make sure window 2 ) (make sure window 3 )
(is scrolled the way) (is scrolled the way) (is scrolled the way)
( you want it ) ( you want it ) ( you want it )
| | |
(setlocal scb in) (setlocal scb in) (setlocal scb in)
( window 1 ) ( window 2 ) ( window 3 )
| | |
+------>----+-----<-----+--------<--------+
|

The vertical lines show the "leeway" in executing each task or set of
tasks. There may be additional constraints if you define "the way you
want it" by comparison with another window whose scroll position you
have to set first (if only by deciding that "that"'s your reference) --
and remember that you can never scroll higher than the top or lower than
the bottom.

You may want to do it first by hand, either writing down your keystrokes
or "recording" them in a register by means of the q Normal-mode command,
then putting that into the {rhs} of your mapping (by means of CTRL-R if
you used q).

See
:help q
:help i_CTRL-R
:help c_CTRL-R
in addition to the help for the commands you used.


Best regards,
Tony.
--
Statisticians do it with 95% confidence.

Tony Mechelynck

unread,
Feb 20, 2009, 7:46:20 AM2/20/09
to vim...@googlegroups.com

Local and global-local options can be set by means of three closely
related commands:

- ":setlocal" sets only the local value (for the current buffer or
window, depending on the option);
- ":setglobal" sets only the global default (which will usually be used
when creating a new buffer or window);
- ":set" sets both.

Modelines set only the local value (as with ":setlocal")

In the ":let" command before the = sign, &l:option, &g:option or &option
set the local value, the global value, or both (in an expression,
&option "reads" the local value).

For global settings, which have only one value, all three commands are
equivalent (and modelines set the global value in that case, but it is
"unusual in the extreme" to set a global setting with a modeline).


Best regards,
Tony.
--
Females are strictly forbidden to appear unshaven in public.
[real standing law in New Mexico, United States of America]

Christian Brabandt

unread,
Feb 20, 2009, 8:27:40 AM2/20/09
to vim...@googlegroups.com
Hi Tom!

On Fri, 20 Feb 2009, Tom Link wrote:

> But this doesn't work (for me) when being executed from a function
> or if you source those lines from a file. So you'd have to enter the
> commands on the command line which isn't really practical. I also
> noticed minor "line shifts" so 2<pagedown> doesn't always get you to
> the next book page -- but maybe there is an option I forgot/don't
> know about controlling the behaviour of pagedown.

How about this "hackish" solution

function! Reader(nr)
if a:nr==0
return ''
else
:ka
:1
setl noscrollbind scrolloff=0
let a=''
let i=a:nr
let a .= repeat(':bo vsp\<CR>', i)
let a .= repeat(':normal Ljzt\<CR>',i)
let a .= ':setl scb\<CR>'
while i>1
let a .= ':wincmd h\<CR>'
let a .= repeat(':normal Ljzt\<CR>',i-1)
let a .= ':setl scb\<CR>'
let i-=1
endwhile
let a .= ':wincmd h\<CR>'
let a .= ':setl scb\<CR>'
let a .= ':normal `a\<CR>'
return a
endif
endfu

and then call this function via
:exe ':call feedkeys("' . Read(2) . '","t")'

If you want to open 2 new scrollbinded windows. Adjust the number to
the number of windows you like to open.

Mit freundlichen Grüßen
Christian
--
Wer viel Freude hat, muß ein guter Mensch sein: aber vielleicht ist
er nicht der Klügste, obwohl er gerade das erreicht, was der Klügste
mit all seiner Klugheit erstrebt.
-- Friedrich Wilhelm Nietzsche

Christian Brabandt

unread,
Feb 20, 2009, 8:31:43 AM2/20/09
to vim...@googlegroups.com
Hi vim_use!

On Fri, 20 Feb 2009, Christian Brabandt wrote:

> :exe ':call feedkeys("' . Read(2) . '","t")'

execuse me, I meant:
:exe ':call feedkeys("' . Reader(2) . '","t")'

regards,
Christian
--
hundred-and-one symptoms of being an internet addict:
122. You ask if the Netaholics Anonymous t-shirt you ordered can be
sent to you via e-mail.

ssiz...@gmail.com

unread,
Feb 20, 2009, 11:43:51 AM2/20/09
to vim...@googlegroups.com

Thanks for explaining, I'll use that as a starting point for future
changes to the macro.

- melisizwe

Charles Campbell

unread,
Feb 20, 2009, 3:51:07 PM2/20/09
to vim...@googlegroups.com
I've had a plugin (mpage.vim) available at my website for a few months now:

http://mysite.verizon.net/astronaut/vim/index.html#MPAGE

that supports multiple windows with sequential text.

:MPage 3

will, for example, set up three windows with sequential text for the
current buffer. It works
with AsNeeded, too (so you don't have to have the plugin always loaded,
just loaded on demand).

Regards,
Chip Campbell

Reply all
Reply to author
Forward
0 new messages