What is the definition of a non-blank character in Vim? - vim

Launch vim.
In the empty buffer, insert two lines where the first line consists of 3 spaces and the second line consists of hello world.
Here is an example file where the spaces are represented with dots.
...
hello world
Now press gg. The cursor moves to the third space of the first line.
Quoting :help gg:
<C-Home> or *gg* *<C-Home>*
gg Goto line [count], default first line, on the first
non-blank character |linewise|. If 'startofline' not
set, keep the same column.
The documentation says that the cursor should move to the first non-blank character of the first line. I have two questions.
Does :help document the definition of a non-blank character? If so, could you please point me to it?
Is the behaviour that we observe in the experiment mentioned above consistent with the documentation provided in :help gg?

I don't think there is a general definition of non-blank in the vim docs, but I also do not believe this is a "side effect" of gg.
Note that gg is consistent here with ^:
^ To the first non-blank character of the line.
|exclusive| motion.
and [:blank:] of vim's pattern matching behavior (:h blank) defines blank characters as space and tab:
*[:blank:]* [:blank:] space and tab characters
As far as whether or not this is consistent with gg, consider what it says it will do as two steps instead of one:
Go to the first line (default since no count was specified) -- it does this.
Go to the first non-blank character of said line.
Probably the easiest way to implement 2 as an algorithm is to position the cursor after all the blank characters at the beginning of the line. In your case, they are all blank characters (and it cannot move to the next line), so the cursor is positioned at the end of the line (after all the blank characters).

Related

delete first 2 white spaces from start of line in gvim

I am reading a file which has 2 unwanted spaces in each line.
import uvm_pkg::*;
`include "uvm_pkg.svh"
And it continues till last line
How to delete first 2 white spaces in each line in gvim?
Enter :%s/^ //, which substituttes 2 leading whitespaces (^ ) with nothing (the nothing between the second and third /) on every line (%).
position cursor at line 1, column 1 (press gg0)
enter visual block mode (Ctrl+v)
select first two columns of all lines by moving the cursor to the bottom and one to the right (Gl)
delete selection (x)
:%s/^ //
substitutes the two first leading spaces on every line of the buffer with nothing, effectively deleting them.
Note that, in this case, you don't even need the replacement part because it is implied: :%s/^ .
See :help :s and :help :range for the %.

Move to first character in line above in vi

When using vi in normal mode I've noticed that the enter key will bring the cursor to the first character of the line directly below. This is a nice feature but I can't seem to find the key for doing the same thing upwards. Anyone know either of a key that does this or how to create my own?
- (minus) goes to the first non black character on a line going upwards.
One way to figure this out is by looking at the help for <CR> here you find
+ or *+*
CTRL-M or *CTRL-M* *<CR>*
<CR> [count] lines downward, on the first non-blank
character |linewise|.
Which tells you that +, <C-M> and <CR> are equivalent. If you look at the section about this you would see
*-*
- <minus> [count] lines upward, on the first non-blank
character |linewise|.
which is what you were looking for.

Which operator can be used to move cursor to the last non-blank character of the screen line in vim?

I know g$ can be used to move the cursor to the last character of the screen line, but which operator can be used to move the cursor to the last non-blank character of the screen line?
g_ (g followed by underscore) moves to the last non-blank character of the screen line text line. (As pointed out by han pingtian in the comments).
To move to the last non-blank character of the screen line, there's no single operator that I could find, but you could combine g$ with ge to achieve this result: use g$ to go to the last character (blank or non-blank) of the screen line, then if the cursor is on whitespace, use ge to move backwards to the last character of the previous word. (And of course, if the character under the cursor is non-blank, just omit the ge operator).
If you're trying to write a script, this won't be as helpful as a single dedicated operator, since it requires making a decision about the character under the cursor after the g$ has completed. But if you're just trying to go to the last non-blank character in visual mode or for interactive editing purposes, the g$ ge combination should suffice for what you need.
Also try substituting gE for ge, depending on whether you want to skip over punctuation or not. (See :help word-motions for the distinction between e and E: basically, E counts ALL non-whitespace characters as word characters, while e counts only letters, digits and underscores.)
Right of Screen
g$
Left of Screen
g0
Top of Screen
H (high)
Middle of Screen
M
Bottom of Screen
L (low)

question about text formatting in Vim

I'm using Vim to write text that isn't code, just free form writing. To do this I like to have formatoptions include the w flag and sometimes the a flag.
The w flag is supposed to make it so an end-of-paragraph occurs when a line ends in a non-blank character, rather than at first blank line (which is Vim default). Here is snippet from the help docs:
w Trailing white space indicates a paragraph continues in the next line.
A line that ends in a non-white character ends a paragraph.
The a flag makes reformatting automatic, as you type. For example, in document with text below and w and a flags the lines reformat as I type only up to the 'last line in paragraph' and not below.
This it the first line of the paragraph. <cr>
The text in it reformats properly as I type <cr>
up to the last line of the paragraph, which is <cr>
right after this line, that is, just below here: <cr>
This is the last line of paragraph.<cr>
This is the first line of second paragraph. <cr>
Even though there is no blank line between <cr>
it and first paragraph, any reformatting of <cr>
the first paragraph ends at the last line <cr>
of first paragraph.<cr>
<cr>
This the the first line after second paragraph<cr>
Now to my question:
With a and w flags the reformatting works properly as I type in the first paragraph, i.e, second paragraph remains untouched. But sometimes I want to select the current paragraph using vap. It seems to me that with the w flag set this should select only the first paragraph. But in fact issuing vap in first paragraph selects the second paragraph also, all the way down to the blank line with <cr>, seemingly ignoring the w formatoptions flag.
Is this expected behavior? Am I missing something? Why does vap not select only the paragraph I'm in, which ends at first line with no trailing whitespace?
If you read the help at :h paragraph this does not mention the 'fo' setting. So it
looks like the fo setting does not really change, what defines a paragraph. This might be a bug or unclear documentation, so you might want to discuss this on the vim-dev mailinglist.
From :help text-objects or :h paragraph you can see that a paragraph for vim begins after each empty line, and also at each of a set of paragraph macros, specified by the pairs of characters in the 'paragraphs' option. Blank lines containing only whitespace are also paragraph boundaries.
The w flag in formatoptions only makes a difference when autoformatting a paragraph as you type: it will split lines and leave whitespace at the end of lines which do not end a paragraph. I suppose the help text is a bit confusing.

Yank n lines upwards without moving

To yank 7 lines downward without moving the cursor, I can 7yy. Is it possible to do the same upwards, not using macros or remapping?
You can use the :yank command with a range to accomplish this effect.
:.-6,.yank
The range explanation:
. or the dot means current line
.-6 means current line minus 6
.-6,. is current line minus 6 to the current line
This can be abbreviated .-6 to just -6 giving us -6,.yank
the current line is also assumed in the end of the range so -6,yank
the yank command can be shortened to just :y giving us -6,y
Final command:
:-6,y
For more help:
:h :yank
:h [range]
You could simply yank to a motion and then return the cursor to the position using either '[ or '].
The yank for 6 lines up, plus the current gives 7 in total:
y6u
Then, use some lesser known marks:
'[ -> to the first character on the first line of
the previously yanked text (or changed)
`[ -> to the first character of the previously yanked text
'] -> to the first character on the last line of yanked text
`] -> to the last character of the preciously yanked text
So:
y6u']
y6u`]
Are two solutions you could use depending on what exactly you want. The former moves the cursor back to the first character on the line your cursor was, and the latter moves to the last character on that line.
But there is another mark that might be handy: '^. It means the last position the cursor was when leaving insert mode.
'^ -> moves to the beginning of the last line when leaving insert mode.
`^ -> moves to the exact position where insert mode was last left.
Then here are two other solutions:
y6u'^
y6u`^
That's not the end! If you pretend to continue inserting text, you can use the gi command. It moves you to the `^ mark and enter insert mode. Then we have a fifth solution:
y6ugi
I hope one of these meets your needs!
You could do the following:
6yk6j
This is will yank the 6 preceding lines and the current one) but the courser will move. 6j jumps back to the previous position.

Resources