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.
Related
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.
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.
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
I recently saw some VIM configuration where search matches would scroll to N lines past the match, so that there would be N lines below the search match instead of it being on the last line (to give context). I cannot find the page where this was mentioned, and apparently I do not know the right keywords to google for!
What is this feature called, and how could I have used the VIM manual to find it assuming that I don't know what it is called?
Thanks.
As far as I tell this can't be set just for search, but is a setting that will be used in all situations.
You are looking for scrolloff: Minimal number of screen lines to keep above and below the cursor. This will make some context visible around where you are working. sidescrolloff does the same thing but horizontally.
This is what I have in my .vimrc:
" When the page starts to scroll, keep the cursor 8 lines from the top and 8
" lines from the bottom and 15 lines on the left
set scrolloff=8
set sidescrolloff=15
set sidescroll=1
Is it possible to not display a ~ for blank lines in Vim?
This confuses Mac Vim's scrollbar, and I quite don't like these tildes.
:hi NonText guifg=bg
That command should set the color of non text characters to be the same as the background color.
Vim 8.x:
You can now change the color just for the end of the buffer ~:
highlight EndOfBuffer ctermfg=black ctermbg=black
See changelog for Vim 8.x.
As jamessan said, you can’t disable them. The scrolling behavior isn’t specific to MacVim, either — it works the same way in the terminal and in gvim:
Instead of seeing this as a problem, what you should do is learn to see this as part of Vim’s flexibility. For example, you can use the zt command to scroll the current line to the top of the screen, regardless of where in the file it is. This can make it easier to write macros that do some work and then scroll back to where you were. The commands <C-E> and <C-Y> are made simpler because of this, as is the 'scrolloffset' option.
If you must, retrain your brain to think of Vim’s scrollbar as mapping to which line is on top, instead of which screenful is visible.
For NeoVim, you can set the fillchars value for eob to a space character and that will effectively hide it. (This might not work for plain Vim).
In Lua (Nvim 0.5+):
vim.wo.fillchars='eob: '
In VimScript:
set fillchars=eob:\
Note: Calling the above will override your fillchars value for other items as well (if set), so use this as a reference to set multiple values together:
set fillchars=eob:\ ,fold:\ ,vert:\│
Or use set fillchars+=... to append it your existing values.
You can't disable them, but you can change your colorscheme such that the NonText highlight group is colored the same as the Normal highlight group. However, this affects more than just the end of document tildes.
I doubt that it's actually "confusing" MacVim's scrollbar and if it is, then that's a bug in the patching that MacVim does.
The tilde ~ characters are meant to remind the user that those lines are not part of buffer content.
The above highlight trick will hide the ~ character, but it is still there. For some terminals, this may not even work. If you happen to be a Neovim user, you can use fillchars option to change the end of buffer symbol like this:
set fillchars=fold:\ ,vert:\│,eob:\ ,msgsep:‾
This will use space instead of ~ for end of buffer, effectively hiding the annoying ~.
You may also be interested in discussions here.