5

For easy horizontal scrolling in long lines, I use these mappings that work well for me:

map <m-[> 20zh
map <m-]> 20zl

Something that has always annoyed me is when the following use case happens (| is the current cursor position):

some |short line
some other line
some other line
some other line
some other line
some other line
some veeeeeeeeeeeeeeeeeeeeeeeeery looooooooooooooooooooooooong liiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiine

Sometimes I want to scroll horizontally and have a quick peek at the very long line just to see if there is anything interesting in there. In GUI text editors, I would just horizontally scroll with my mouse, and scroll back. In Vim, if I try to scroll with zl, here is what happens:

..me short line|
..me other line
..me other line
..me other line
..me other line
..me other line
..me veeeeeeeeeeeeeeeeeeeeeeeeery looooooooooooooooooooooooong liiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiine

I can slightly scroll for a bit (as visually demonstrated by the .. above), but then the cursor is blocked at the end of the short line. I have to explicitly position my cursor on the very long line to be able to scroll again, which is very annoying.

There is an interesting half-solution to my problem: :set virtualedit=all. It frees the cursor of any line-limit. Hitting zl a few times on the above example now works as I want (notice the "free" cursor below):

..ine          |
..ine
..ine
..ine
..ine
..ine
..ooooooooooooooong liiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiine

I only need virtualedit=all for this specific use case though. Otherwise I want the cursor to behave normally and restore the option to the default virtualedit=. And I do not want to do this manually, it should be automatic: when I start scrolling right, I want it on. When I scroll left, I still need it on except when the first characters of the lines in the file become visible again.

I am thinking about something along those lines:

map <m-[> :SOME_VOODOO_VIMSCRIPT_MAGIC<cr>20zh
map <m-]> :set virtualedit=all<cr>20zl
noremap ^ :set virtualedit=<cr>^
noremap $ :set virtualedit=<cr>$

Any idea about what to do for the SOME_VOODOO_VIMSCRIPT_MAGIC part? Getting the absolute column position for the first visible left character could help, although I do not know how to do this in Vimscript (col does not seem to do what I want). Alternate ways of solving my problems are welcome too (I just don't want any line-wrapping).

1

After a lot of spelunking in the VIM help section and newsgroup archives, I came up with this not-so-straightforward solution. It even works in split-windows!

map <silent> <m-[> 20zh:call SetVirtualEdit()<cr>
map <silent> <m-]> :set virtualedit=all<cr>20zl
noremap <silent> ^ :set virtualedit=<cr>^
noremap <silent> $ :set virtualedit=<cr>$

python import vim
function! SetVirtualEdit()
  let absolute_col = virtcol('.') + pyeval('vim.current.window.col')
  let absolute_col += &foldcolumn + (&number ? &numberwidth : 0)

  let is_on_leftmost_screen = screencol() == absolute_col

  if is_on_leftmost_screen
    set virtualedit=
  else
    set virtualedit=all
  endif
endfunction

Notes:

  • The <silent> mapping for <m-[> is important for screencol() to work well.
  • You need Vim compiled with python support

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.