Getting vim to show the lines relative to other screen in splitscreen? - vim

I am splitting one document vertically in vim using :vsp.
Each side displays the relativenumber relative to the last cursor position at that side.
I want to move a line from the left side to the right side using the relative number of lines.
Say: :m-33.
How could I get the relativenumber on the right side to count relative to the cursor position on the left side?
P.S.
(I'm using NeoVim)
I could not find any such option in the :help
Also, vim would need to know that both sides are the same file, so it is reasonable that it has no such feature.

Cursor position is local to the window so there is always only one current line, which means that there is no native way to do exactly what you want.
But nothing is stopping you from dropping a mark on the left side:
ma
then switching to the right side:
<C-w>w
then moving the current line to below that mark:
:m'a

Related

Is it possible to make vim marks remember the relative position of the line in the current window?

I'm using (a modified version) of the solution proposed in http://www.thegeekstuff.com/2008/12/vi-and-vim-autocommand-3-steps-to-add-custom-header-to-your-file/ to create and update headers for my source codes automatically.
As explained in the above-mentioned page, upon invoking a write command in vim, the following sequence of commands are executed:
A mark is set at the current position of the file.
The "Last Modified" filed is updated. This moves the cursor to the beginning of the file (where the search-and-replace takes places).
The cursor is returned to previously marked position.
This is fine, but there is a slightly annoying issue: Suppose we're editing a line close to the bottom of the window. If at that point we save the file, because of the cursor moves (for updating the header) the line we were editing jumps so that it is positioned in the middle of the window.
To my understanding 'a moves the cursor to the place marked by mark a and adjusts the window contents such that the current line appears in the middle of the window. I was wondering if there is a way to make "marks" remember also the exact relative position of the marked line in the window and maintain this position when jumping back to the mark?
It's in the docs: Restoring the cursor position.
:map <F2> msHmt…'tzt`s
(I skipped irrelevant parts with ellipsis).
ms store cursor position in the 's' mark
H go to the first line in the window
mt store this position in the 't' mark
Breaking up restoring the position:
't go to the line previously at the top of the window
zt scroll to move this line to the top of the window
`s jump to the original position of the cursor
The mark itself only stores the position itself; the view (what's shown in the current window) isn't part of that.
What you're looking for is the pair of winsaveview() and winrestview() functions. These store the cursor position (like marks, but without adapting automatically to changes in the buffer; something that you probably won't need for the updating of headers), and the details of what is currently shown in the window. Use of these is recommended over marks; in custom mappings or commands it also has the benefit of not clobbering a mark.
If you use :substitute to update the header, you also may change the current search pattern (unless using a :function), and the search history. Undoing all of that is hard; I know because I've written such a plugin (AutoAdapt plugin) myself. You may want to have a look at its implementation for further tips (or start using it altogether). (The plugin page also has links to various alternative plugins.)

Vim: Select all without scrolling away

is it possible in vim to select all lines in the current file, but leave the position where my cursor is unchanged?
Let's say I am currently at line 500 (of 3000) and want to quickly select everything (not yank), as my selection is simply set up to show whitespace characters. Can this be done without leaving my current line?
To achieve exactly what you like, you can press the following:
ggVG<Esc><Ctrl-O><Ctrl-O>
gg moves to the beginning of the file
V starts visual line mode
G moves to the and of the file (now you have selected the whole
file)
<Esc> leaves visual mode
<Ctrl-O> moves your cursor back to the prevois location (first to the beginning of the file, then the second time to your last position before pressing gg)
And if you like to select only the visible lines in you window (to not scroll away). You can use HVL instead of ggVG (H moves to the top of your window and L to the bottom).
You also could show whitespaces without using visual selection with something like this in your .vimrc:
set list listchars=tab:»·,trail:·,nbsp:·
This helps me to detect trailing whitespaces, and mixed (spaces/tabs) indentation.
usually pressing
ggVG
in normal mode will select all the lines, but it will leave your cursor at the last line of the file.
If you wants to highlights the whitespace characters then you can highlight this by using the below command in command mode (this white color chosen is for dark theme)
: hi ExtraWhitespace ctermbg=White guibg=White
Depending on what you are trying to achieve you can use something like :
%cmd
To apply the command to the whole file.
For example, %y will yank the whole file, %=will format the whole file, without moving your cursor. It does not really work if you do something like %d...
It is not a real selection though but rather a way to apply a command on the whole file.
To go further you can use something like
%norm Atest
To add 'test' at the end of each line. (Actually this is a bad example, because this command will move to the last line...)
It is not possible to have the cursor inside a visual selection. This caused by that, vim defines visual selection through two marks. As soon as you move the cursor one of the marks gets updated. Basically this means one of the marks is always lays where the cursor is(at least when using "v" to select). You cannot have the border in the middle of the region that the border defines :)

Restore cursor position after executing make

Assume the cursor is at horizontal position 42 of a line. Then you go into normal mode and execute the command
:mak
which will call make. After make is executed you return to normal mode but your cursor is positioned at horizontal position 0 (assuming that no whitespace is contained at the beginning of the line) of the same line.
Is it possible to tell vim that it should return to the same horizontal position of the same line as before executing make?
I played with settings like nostartofline without luck. Any suggestions?
This is because of the following behavior, documented under :help :make:
7. If [!] is not given the first error is jumped to.
If you have no errors, Vim still somehow "jumps" to the first non-blank character in the current line (which may be a bug or an inconsequential side effect of the implementation).
If you want to keep the current cursor position, just use :make!.

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.

VIM: Stay away from the edges on searches

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

Resources