How to prevent Vim scrolling when splitting a window? - vim

I want to stop Vim from scrolling (if that's the right word) when I split a window horizontally.
Let's say I edit a 10 line file in Vim. I have a single window onto the buffer and the window is 40 lines high. There's more than enough room for two windows, one on top of the other, with both showing the whole buffer. And let's say scrolloff is set to 4.
When I split the window horizontally, the original window is scrolled so that exactly scrolloff lines are shown between the top of the window and the line the cursor is on -- if there were more than scrolloff lines between the top of the window and the cursor line -- even though there is no need to scroll.
Put another way, if the cursor is on line 1, 2, 3, 4 or 5 when I split the window, the original window doesn't "move" (good). But if the cursor is on line 6, the window scrolls so that line 2 becomes the top-most visible line...ensuring scrolloff lines (4) are visible above the cursor line (annoying). Similarly if the cursor is on line 7 when I split the window, the original window scrolls to that line 3 becomes the top-most visible line. And so on.
Is there a way to configure Vim never to scroll the original window when I split it horizontally?
I imagine it's possible to map <C-W>s to a function which does what I want, but I'd prefer to solve this by configuration if possible.

I've found a solution, borrowing the answer from here.
In my .vimrc I have:
nnoremap <C-W>s Hmx`` \|:split<CR>`xzt``
And now when I split the window horizontally with <C-W>s, the original window doesn't scroll at all.

As an alternative to Andy Stewart's solution here's what I use in my .vimrc:
(3) (5)
++ +--+
|| | |
nnoremap _ Hmx``<C-w>szz<C-w><C-p>`x``<C-w><C-p>
| || | | | | |
+-+-++----+ +--------+ +--------+
(1) (2) (4) (6)
(1) Go top left save mark it to x and go back to where you were.
(2) Create a new split. Cursor will move to this new split window.
(3) Use zz to center the cursorline.
(4) Go back to the window you have created the split.
(5) Go back to x mark and then go back to where you were (to simulate step (1))
(6) Go back to the split you created.
One addition I made is to add zz onto the newly opened split to make the cursor on the new window easier to catch. My brain can automatically focus onto the center row of the new split.

A recently available option is the stable-windows plugin. I've tried it and it's working well.

Related

Vim to always only jump one row at a time [duplicate]

I can get the bottom of the window to display partial lines by setting display=lastline
Is there a similar option that would allow partial lines to be displayed at the top of a window?
Without this functionality, my vim still scrolls (down) by more than 1 screen line when the topmost file line being displayed is wrapped into multiple screen lines.
For example, in the following scenario, when I press C-E, my vim will scroll down by 3 screen lines. Is there a way to make it scroll by only 1 screen line such that only the first two words in line 1 are hidden, but the following 3 words are still displayed? This will be very useful for editing long paragraphs of text.
Note: I'm referring to the scrolling of the entire screen, not the movement of cursor.
------------------
1 abcdefg abcefg
abcasdfsa sdfsf
sdfc
2 adfadf
3 adfadf
4 adfadf
------------------
I don't think it is possible to do exactly what you want.
Here's the description I get when I type :help CTRL-E
CTRL-E
CTRL-E Scroll windows [count] lines downwards in the buffer.
Mnemonic: Extra lines.
Note that while it says it is scrolling the window, it also mentions that it is scrolling lines in the buffer. You really are scrolling only one (wrapped) line at a time.
I don't think there's another way around this.
I can get the bottom of the window to display partial lines by setting display=lastline
I think display=lastline is a false solution - you still scroll the same amount, you just have more visible.
The real way to solve this is to disable wrapping:
:set nowrap
Edit
Some related threads that show that a "scrolling via screen lines" feature is under consideration, but will take a while to be implemented:
http://vim.1045645.n5.nabble.com/Feature-request-Display-partial-paragraph-at-the-top-of-the-window-td1166809.html (4 years ago)
http://vim.1045645.n5.nabble.com/Scrolling-screen-lines-I-knew-it-s-impossible-td3358342.html (the beginning of this year. Same dev mentioned wanting to implement it: "Ben Schmidt")
For anyone reading this thread:
This thread on the Vi stackexchange offers a slightly hacky (but useable) solution to visual scrolling across wrapped lines.
Now there's a built-in option for this:
'smoothscroll' 'sms' boolean (default off)
local to window
Scrolling works with screen lines. When 'wrap' is set and the first
line in the window wraps part of it may not be visible, as if it is
above the window. "<<<" is displayed at the start of the first line,
highlighted with hl-NonText.
NOTE: only partly implemented, currently works with CTRL-E, CTRL-Y
and scrolling with the mouse.

Vim Relative Numbering Reset on Scroll

When I scroll down a page the relative numbering is no longer based upon the cursor position.
Instead the line position relative to the top of the screen is displayed.
Sometimes I would like to delete or yank 200 lines and I dont want to have to do the subtraction and addition to figure out how many lines down my text is.
How can I show relative line numbers to the cursor even when scrolling?
I think what you want is, you scroll with mouse, and expect that vim keeps the cursor in original place. E.g. your cursor is at line 5, and you scroll down 5000 lines, you expect your cursor is still at line 5. That is, the cursor is out of the window.
AFAIK, the cursor won't go out of the window. That means, if you keep scrolling down, and the cursor line will be the top line of your current window. and the rnu are gonna re-calculated by the cursor line.
May be you could just explain what do you want to do. the cases in your question could be done by 200dd or 200Y but I guess it is not as simple as that.
You may want to find out the ending line by reading/scanning your text lines, and pick the line number (rnu), and do a xxxdd if this was the case. Here you should use normal line number. e.g. your cursor was at line 5, and you scroll down a lot, find the line you want to delete till from line 5. you could do :5,.d vim will delete from line 5 to your current line.
Or you can do 5, 23452d if you find out the lines between 5 and 23452 need to be removed.
If you can search your ending line by /pattern search, vim can do :.,/foo/d this will delete from current line till the next line, which matches foo.
You can still press V enter line-wise visual mode, and moving down by vim-motions. when it reaches the point you want to remove/yand press Y or d
You can take a look this Question/answer:
VIM to delete a range of lines into a register
At the end, I suggest you not using mouse in vim.
This is probably because the cursor moves down a page when you scroll down a page. In vim, the cursor is always on the screen. If you're scrolling down with, say, the mouse wheel, the cursor will just get "stuck" on the top line (modulo scrolloff) and stay there as you continue to scroll down.
Perhaps use ShiftV to start a line-based visual selection before scrolling, then use d or y on the selection?
I can confirm that the desired feature is available in Visual Studio Code (VSC) with the Vim extension installed. This is because VSC does not function like Vim by default and holds the cursor in place like other text editors do. This feature not only makes VSC bearable but proves more useful than vanilla Vim when coding large blocks of code also.
Additionally, VSC also allows for easy and language agnostic comment/uncomment toggling with <Ctrl> + / which is also very useful when used together with the above feature.

Is possible to change the positions of the tabs in vim?

I was wondering if is there any way to change the place of the tabs. Anyone can help me about this? I would like to have vim as my favourite ide..:)
Check out help :tabm[ove]. Essentially you could do:
:tabm +N to move current tab N places to the right. Or :tabm -N to move N places left.
Vim is not an IDE, it's an editor. You won't turn it into an IDE, no matter how hard you try.
Anyway, read :h tabmove:
:tabmove 0
moves the current tab to the first position
:tabmove 2
moves the current tab to after the 2 tab
:tabmove
moves the current tab to the last position
What do you exactly mean by "place of the tabs"? The other answers have already shown how to move individual tab pages around.
If you're inquiring about where Vim places the tab labels, that cannot be changed; they will always be between the GUI menu and the windows. In GVIM, you can only "downgrade" the tab appearance from graphical to textual via
:set guioptions-=e
When using the tabline (with guioptions-=e), you can drag and drop tabs with your mouse.
There is a patch pending (but not applied yet as of Vim 7.4.1054) to expand this to the GUI tabs as well:
https://groups.google.com/forum/#!msg/vim_dev/LnZVZYls1yk/fj_Gz0vhnrsJ
Split Manipulation
Ctrl+W, R (Swap top/bottom or left/right split)
Ctrl+W, T (Break out current window into a new tabview)
Ctrl+W, o (Close every window in the current tabview but the current one)

In vim, how to scroll, continuously, by screen lines when wrapping is enabled?

I can get the bottom of the window to display partial lines by setting display=lastline
Is there a similar option that would allow partial lines to be displayed at the top of a window?
Without this functionality, my vim still scrolls (down) by more than 1 screen line when the topmost file line being displayed is wrapped into multiple screen lines.
For example, in the following scenario, when I press C-E, my vim will scroll down by 3 screen lines. Is there a way to make it scroll by only 1 screen line such that only the first two words in line 1 are hidden, but the following 3 words are still displayed? This will be very useful for editing long paragraphs of text.
Note: I'm referring to the scrolling of the entire screen, not the movement of cursor.
------------------
1 abcdefg abcefg
abcasdfsa sdfsf
sdfc
2 adfadf
3 adfadf
4 adfadf
------------------
I don't think it is possible to do exactly what you want.
Here's the description I get when I type :help CTRL-E
CTRL-E
CTRL-E Scroll windows [count] lines downwards in the buffer.
Mnemonic: Extra lines.
Note that while it says it is scrolling the window, it also mentions that it is scrolling lines in the buffer. You really are scrolling only one (wrapped) line at a time.
I don't think there's another way around this.
I can get the bottom of the window to display partial lines by setting display=lastline
I think display=lastline is a false solution - you still scroll the same amount, you just have more visible.
The real way to solve this is to disable wrapping:
:set nowrap
Edit
Some related threads that show that a "scrolling via screen lines" feature is under consideration, but will take a while to be implemented:
http://vim.1045645.n5.nabble.com/Feature-request-Display-partial-paragraph-at-the-top-of-the-window-td1166809.html (4 years ago)
http://vim.1045645.n5.nabble.com/Scrolling-screen-lines-I-knew-it-s-impossible-td3358342.html (the beginning of this year. Same dev mentioned wanting to implement it: "Ben Schmidt")
For anyone reading this thread:
This thread on the Vi stackexchange offers a slightly hacky (but useable) solution to visual scrolling across wrapped lines.
Now there's a built-in option for this:
'smoothscroll' 'sms' boolean (default off)
local to window
Scrolling works with screen lines. When 'wrap' is set and the first
line in the window wraps part of it may not be visible, as if it is
above the window. "<<<" is displayed at the start of the first line,
highlighted with hl-NonText.
NOTE: only partly implemented, currently works with CTRL-E, CTRL-Y
and scrolling with the mouse.

Vim: Lock top line of a window

Is it possible in Vim to lock the top line of a window so that the first line in buffer is always seen on top of the window?
I have a file, say, dump of a database table. On the first line there are names of columns, other lines contain data. I want to be able to scroll contents up and down, and always see column names.
N.B. Lines can be lengthy, so I use nowrap and want column names and contents to scroll right and left simultaneously. That's why :1split doesn't suit -- unless there's a way to scroll two windows at the same time.
Thanks.
Thanks guys! Let me summarize the actual commands that did the job for me:
:1spl # create an extra window with only 1 line
:set scrollbind # synchronize upper window
ctr+W , arrowDown # switch to other window
:set scrollbind # synchronize lower window
:set sbo=hor # synchronize horizontally
Split your window, decrease the top window height, set the top most line to be the first one and get back to the working window.
:split
:resize 1
gg
Ctrl-w w
You can scroll two windows at the same time, so I think you can do what you want by splitting your window, and locking the scrolling behaviour. See :scrollbind and this tip for more details. Note that you have to lock each window in order that they move in sync.

Resources