Scrolling long wrapped lines in Vim - vim

Problem: When writing prose scrolling works in unexpected way when using j to scroll down. As I scroll between two long paragraphs (wrapped lines in vim) of text using j, when reaching the next long paragraph (line) the text "jumps" from the bottom of the screen to the top, aligning the first word of the paragraph (line) with the top of the screen (see screenshots bellow).
Affected: Folks who love Vim and want to use it to write prose.
Expected: I would like the paragraph (line) to jump to the middle of the screen OR to continue scrolling with the cursor at the bottom. The jump is too jarring otherwise--I am losing context. Two questions: 1) Is it possible to change the default behavior in .vimrc? 2) If not, how feasible would it be to write a plug-in altering the behavior?
Related Resources:
http://vim.1045645.n5.nabble.com/Long-lines-and-scrolling-td1183898.html
http://vim.wikia.com/wiki/Move_through_wrapped_lines
http://vim.1045645.n5.nabble.com/Scrolling-Long-Lines-Revisited-Again-td5031203.html
For example: here I am scrolling down some dummy text: .
After jj the next paragraph has moved up to the top of the screen:
My .vimrc is here. Prose mode is:
command! Prose setlocal linebreak nolist wrap wrapmargin=0
nnoremap k gk
nnoremap j gj

It will help to brief yourself on VIM's motion commands { and } are good ones with literary text. However in the case you describe these are not paragraphs they are lines. VIM manages them as lines. As such you had to go so far as to remap j and k which is the reverse of usual. My suggestion is to break the lines into paragraphs by way of textwidth.
Finally VIM has screen commands to manipulate the viewable area. Since VIM is attempting to show you as much context as possible (in your case a extremely long line) it takes up the whole screen and you see the "jump" To reverse this use the zz (AKA z<Enter>) command to move the screen viewable area to match the cursor in the center. The others are zt to place the viewable area to the top and zb to place the viable area to the bottom.
Hope these suggestions help and happy VIMing.

As mentioned by #denten they are not paragraphs they are long lines.
When you navigate using j or k; you are moving vertically through the same column. But with your mapping (j to gj and k to gk) you are moving vertically as visually wrapped by the editor.
I suggest to remove that mapping and use gj & gk manually as required.
Additionally if scrolling is your requirement, consider mapping PageUp & PageDown with the following:
" Slow PageUp/PageDown
nnoremap <silent> <PageUp> <c-y>
nnoremap <silent> <PageDown> <c-e>
Or if the idea of using PageUp or PageDown feel awkward, feel free to go with the actual keys to scroll: Control and y for up; and Control and e for down.

Vim is essentially a line-based editor. You're using :set wrap to display the entirety of long lines. Still, Vim still tries to keep the beginning of the current long line visible (for features like :set number), which showing as much of the entire line. With excessively long lines (that take up most of the windows, as in your screenshots), that results in the current line scrolling to the top of the window. I'm afraid there's nothing to prevent that. You can only workaround, either by increasing the size of the Vim window, or by editing with hard line breaks in the text.

Unfortunately this is one of Vim's problems. The command gq exists which can help you to format the text based on the text width you've set, which can save some time. se formatoptions+=a is helpful, as it will reformat the text as you edit it, so you don't have to keep hitting gq. The problem is, of course, now you have to define your paragraphs by blank lines, and it's not a very well rounded solution if you needed to scroll by screen lines for some other reason (such as a very long json object on one line, or log files or whatever).
Briefly looking at it, when using the gnu GUI version of emacs, it seems I can actually scroll with the mouse wheel by screen lines. This is unlike MacVim. So it looks like emacs at least has some kind of support for it. If you're writing prose, you may be able to get by just with the EVIL mode plugin for emacs, which is not complete but is a pretty sophisticated version of vim inside emacs. In general, emacs is a little more pliable for people who really like to tinker and touch every part of the system to do new things, so someone has probably written some good prose modes for it. Obviously it doesn't let you leverage your existing vimscripts, though.
From following your links, it looks like this scroll by screen lines issue has been on Bram's radar for 20 years. My guess is there's something tricky about implementing it in the existing system. It's too bad, because not only do people often get confused by what is wanted when someone asks this question, but there are plenty of simple reasons you would want it, too. It comes up rarely in code, and constantly in every other type of document.

Related

Vim: Only scroll the current line

I would like vim to scroll horizontally like nano does, by scrolling only the current line, not the whole screen.
I tried playing with nowrap and scrolloff settings, without success.
Here are some screenshots (with the cursor at the end of a long line) to explain myself.
Nano:
Vim (wrap):
Vim (nowrap):
Thanks!
No, Vim cannot do this, and I think it would be hard to implement this in a way that isn't inconsistent or confusing to the user. There would need to be an indicator (like with side scrolling) that only the current line is scrolled. Also in Vim, there are several commands (like j / k and i_CTRL-Y / i_CTRL-E) that refer to the same column in above / below lines. A partially scrolled view state would make it difficult to use those.
That said, you can sort-of achieve this with a hack: The foldtext of folded lines does not scroll horizontally. So if you fold each individual line (other than the current one) via a custom 'foldexpr', set the fold text to be the line's text, and automatically close all surrounding folds, you'll get this. However, as you'll lose syntax highlighting and "normal" folding, this is more for demonstration than an actual solution.

Highlight the line number in the middle of screen in Vim?

As it is very convenient to scroll half screen up and down(by using ctrl-d), but it is a little hard to estimate which line will disappear after scroll. It will be great if the middle line number can be highlighted, then I can use it as a marker for half screen scrolling.
These are standard VI commands in Command Mode. You may find them helpful:
z<Enter> - Put current line on top of your window
z. - Put current line in the middle of your window
z- - Put current line on the bottom of your window
See :help z for more information in VIM. There's a lot of stuff on cursor movements there.
That's not possible in Vim, and implementations of highlights while scrolling are notoriously difficult to implement well (leading to the introduction of the built-in 'cursorline' option to address the top use case).
I frankly don't see the need for that highlight, and I think that once you've learned all the various ways of moving (including commands like zt / zz, <C-Y> / <C-E> (which are great for repositioning when you're off a single / few lines only), and plain j / k with the 'relativenumber' option), this becomes a non-issue.

Vim, Long Lines and Scrolling

I use Vim to edit English text files with >10.000 words and long paragraphs. The files are formatted as plain text and each paragraph is a long line. I use the wrap option, and I bind j and k to gj and gk respectively so I can move by display lines.
If my cursor is on the top of the screen (but not the beginning of the document) and I move the cursor up (using gk), the screen scrolls up to display the whole long line (a 300-word paragraph). The problem is that because of the length of the line this makes the screen scroll by half of the screen. This is disorienting because I don't know beforehand how much the screen will move. Scrolling with ^Y has the same problem.
Is there a way to make Vim scroll by just one display line when using gk and its ilk? This is more natural for editing non-source-code and the default behavior in most text editors as well as in word processors, but not in Vim. I think this would mean that Vim would have to stop insisting on showing the entire line I'm editing.
I have personally fixed this problem by switching to hard wrapped prose documents. I don't believe there is any other solution. Here's one of the articles that first exposed me to the idea: http://alols.github.io/2012/11/07/writing-prose-with-vim/
I must confess that, in the beginning, the idea to convert all my documents to this old-fashioned way of writing text files looked annoying as hell to me, and it'll probably do to you too. But I soon realized by trying other modern editors that none of them was as powerful and stable as Vim. All it took me before this felt completely natural was some formatoptions tuning. In my case, this works best:
setlocal formatoptions=wat
Also, here's one handy function I discovered to go back to soft wrap at anytime which you might find useful: Unwrap text in vim
I suggest you define a macro to scroll your page. If you have a screen height of 50, you could go with something like:
map zp 48gj

Vim: transitioning from mouse to movement

I use MacVim (and gvim) a lot. I'm familiar with and use a lot of the basic movement commands (b, w, $, 0, G). However, for a lot of things—such as selecting particular lines on the screen or jumping to a particular column in a different line—I use the mouse (sometimes in concert with my left hand on the keyboard). It also helps that my mouse has a scroll wheel and buttons for changing tabs.
I also need to admit... I use the arrow keys on my keyboard rather than hjkl.
I think that my speed (and posture at the computer) will be improved by not having to escape from insert mode, and from keeping both hands on the main part of the keyboard.
What convinced you to abandon the mouse? What are the most helpful shortcuts for moving quickly between lines and columns, scrolling, etc.?
This question is inspired by this recent post
I think that my speed (and posture at
the computer) will be improved by not
having to escape from insert mode
No, you must escape from insert mode right after you typed what you want. It quickly becomes a reflex, so you don't really lose time (I sometimes even press escape after completing a web form...). Normal mode isn't just for moving around, it's used to perform most operations (save from typing): for instance deleting or moving sections of text. You also benefit from entering insert mode with the appropriate key: o to start a line, S to replace a line (while keeping indentation), A to move to the end of the line, c+motion to replace a few words or until a given character... All of these save keystrokes.
The mouse seems fast, but in reality it isn't precise, so you lose time (in addition to the constant back and forth with the keyboard). ViM has a long list of moving commands (see :help usr_03) which, when mastered, are faster than the mouse in most situations.
Use search the most you can (/, ?, *, #, f, t...). I personally use Ctrl+(d,u,f,b) a lot. Also, Ctrl+(o, i) and `` are really useful to go back where you were before a search or something else.
h, j, k, l are there to place your right hand near to useful commands (i, u, o...): I always have my fingers on them. The arrows force you to move your hand a lot.
Try to look at a few commands in :help, then use them a lot, and you'll get habits about what you should use to move according to the situation. Nobody uses ViM the same way.
The more I used the keyboard movement in vim, the less I wanted to use the mouse. It doesn't help that extended periods of time where I'm constantly moving from keyboard to mouse can take a toll on my wrist.
If you want to force doing things the vim way, unplug your mouse for a while! The more you use the keyboard, the more you will love it. This worked for me.
For moving between lines, I usually just use jk but I often skip to lines using :line_num. Getting to a specific column in a line, I typically use wbe^0$ and put modifiers in front of w, b, or e if I'm skipping through several words. And there is also the shifted versions, WBE which also come in handy often.
I have to admit that I often use the arrow keys for specific movement in vim.
I rarely use hjkl. However, I find that most of my navigation is done with other commands such as w (skip a word forward), b (skip a word backwards). Combine this with modifiers such as 3w (3 words forward). : skip to a specific line.
I've never really had to abandon the mouse since I never really started with it. All I can say is that attempting to use editors without all the keyboard shortcuts that vim has can feel quite painful.
I'd run vimtutor from the command line (Terminal.app in OS X). It runs vim with a tutorial document. That document was what really made me realize the power of some of the commands. You'll pick up some that are most useful to you and gain more over time. Eventually you'll find yourself using the mouse less and less.
One command that will really improve your movement speeds is f. f plus a character will jump to the first occurrence of that character on the current line. Pressing ; will jump to the next occurrence. Of course this can be used in combination with other commands. So, for example, removing all characters up to and including the first closing parenthesis is achieved by pressing d+f+).
You can seriously revolve your life around jk in hjkl.
nnoremap <c-k> ddkP "move current line up one
nnoremap <c-j> ddp "move current line down one
vnoremap <c-j> dp'[V'] "move visual block down one
vnoremap <c-k> dkP'[V'] "move visual block up one
"These may be a bit more esoteric to me"
inoremap jj <esc>o "Insert mode can move to next line (works mid line)
inoremap kk <esc>O "Insert mode new line on previous line
also for the desktop gui (ion3 and gnome)
winj - next window
wink - prev window
(This beats alttab if your editing in vim all day)
also read :he motion.txt in its entirety using j and k to scroll up and down as you do.
I learned vi so for me the mouse has never been something to use with a text editor.
I don't use hjkl except when the machine/network/keyboard/whatever-in-between is not comfortably configured.
Use the mouse where it makes sense. It often does (copy/paste to and from other gui applications).
To answer your question, though: Once you start using vim as a tool for transforming text bits with macros, the movements will all start to fall into place ;)
I think you're wondering if there's a quick way to move around while in insert mode (without using the mouse or arrow keys) but unfortunately there isn't; you have to escape out of insert mode. However I know that jumping all the way to your Esc key can be really annoying, which is why I've gotten into the habit of escaping with Ctrl+c, it's much faster.
I almost never use hjkl because it's too tedious. I usually try to jump right to where I want to go. There's a great cheat sheet out there (a Dvorak version is a available also (although it's in PDF)) that you can stare at and imagine the possibilities.
Mostly I use f, F, t, and T, and sometimes they're enhanced by typing a number up front like d2t) will delete up to the second close paren. Sometimes I use search. A lot of the time I use w, W, b, B, e, and E. They're all fantastic.
When I see vim users arrowing all over the place in visual mode just to delete text it makes me shudder, because there are so much easier ways (and hjkl only make you move your arm less, they don't change the number of button presses).
Something I did that I don't know if it's common or not is remapped my arrow keys to be <Esc><Up> and so on. For whatever reason I started out always arrowing around and assuming I'd be back in normal mode, so I just made it do that...
The biggest bummer about Vim is that now when I edit anything anywhere else I hit escape all of the time and type :w after every change...

Is there a way to emulate ReSharper's "extend selection" feature in Vim?

ReSharper has a nice feature called "extend selection": by pressing CTRL+W (I think this is the default) repeatedly, you select more and more from your current caret location. First it's a word, then more and more words, a line, inner then outer block of lines (for example an if-block), then a function, etc...
Basically, by pressing the key combination repeatedly, you can end up selecting the entire file. I'm sure at least some of you will be familiar with it.
I have just started learning all the intricacies of vim and I don't have enough experience to see how something like this could be implemented in Vim (although I assume it's possible). So my question is meant for Vim gurus out there: can this be done and how?
Update: a bit of a background story. I've been talking to my ex-boss about all the benefits of Vim, and he thinks it's all great. His only question/problem was: does it have "extend selection"? My question so far has been no. So, if someone knows the answer, I'll finally win a discussion :P (and maybe create a new Vim convert:-))
I had a quick go at this problem. It doesn't work as is. Feel Free to make edits and post on the vim wiki or as a plugin if you get it refined.
chances are you'd want to make a g:resharp_list for each language (eg. one for paranthesised languages, etc.)
All that is needed is a marker for the original cursor position :he markers and a timeout autocommand that resets the index.
"resharp emulator
"TODO this needs a marker
"also c-w is bad mapping as it has a lag with all the other-
"window mappings
"
let g:resharp_index = 0
let g:resharp_select = ['iw', 'is', 'ip', 'ggVG']
func! ResharpSelect()
if g:resharp_index >= len (g:resharp_select)
let g:resharp_index = 0
endif
exe "norm \<esc>v" . g:resharp_select[g:resharp_index]
let g:resharp_index = g:resharp_index + 1
endfun
nnoremap <c-w> :call ResharpSelect()<cr>
vnoremap <c-w> :call ResharpSelect()<cr>
"Something to reset on timeout. TODO this doesn't work
au CursorHold :let g:resharp_index = 0<cr>
The answer is yes. Once in Visual mode you can use all the regular navigation methods as well as some extra ones.
Some of my favourites? First hit v while in normal mode to get to visual mode then hit:
iw - to select the inner word. Great for selecting a word while excluding surrounding braces or quotes
w - hit multiple times to keep selecting each subsequent word.
b - select wordwise backwords
^ - select all from current position to beginning of text on line
$ - select all from current position to end of line
I'm sure others here could add to this list as well. Oh and don't forget Visual Block mode C-v try it out in vim with the above commands it works in two dimensions :-)
If you're talking about Vim (and you should be :-), you can start marking text with the v command, then you have all the standard cursor movement commands (and, as you know, there are a lot of them) which will extend the selection, as well as moving the cursor.
Then you just do whatever you want with the selected text.
See here for the gory details.
One would need to write a function that would save the current selection, then try increasingly wide selections, until the new selection exceeds the saved one or selects all text. Some possible selections are:
viW - select word
vis - select sentence
vip - select paragraph
viB - select text within the innermost brackets
v2iB - select text within the next most innermost brackets
ggVG - select all text
I think Jeremy Wall's heading in the right direction. And to get a little further in that direction, you might look at the "surround.vim" script from Tim Pope. A good description is available on github. Or, if you'd rather, get it from vim.org. It'll probably help you do some of the things you'd like to do, though it doesn't seem to have a feature for say, simply selecting within a tag. Let me know if I'm wrong.
Ultimately, what you'd really like is a hierarchy of enclosing text-objects. You should read up on text-objects if you haven't. A nice overview is here. Note that you can grab multiple objects in one go using counts, or do this iteratively (try vawasap}}} from normal mode).
You can also get scripts which define other text-objects, like this one that uses indentation to define a text-object. It'll work for many languages if you're formatting according to common standards, and guaranteed for python.
One annoyance is that the cursor ends up at the end of the visual block, so, for example, you can't easily select everything between some ()'s, then get the function name that precedes them...
...BUT, I just found in this post that you can change this behavior with o. Cool!
I suspect you'll find yourself more efficient being able to skip over intermediate selections in the long run.
Anyway, I'll be curious to see if anyone else comes up with a more general solution as well!
In Rider [on a Mac with VS Mac bindings with IdeaVim], I bind:
Ctrl+= to Extend Selection
Ctrl+- to Shrink Selection
Doesn't clash with any other bindings of consequence and doesn't require a v for mode switching, and easier than Cmd+Option+-> and Cmd+Option+<-
Putting it here as I always hit this question with any Rider Vim selection searches. If I get enough harassment, I'll create a self-answered "How to use Extend Selection with Rider Vim mode".

Resources