Vim: word vs WORD - vim

I'm learning Vim and can't wrap my head around the difference between word and WORD.
I got the following from the Vim manual.
A word consists of a sequence of letters, digits and underscores, or a
sequence of other non-blank characters, separated with white space
(spaces, tabs, ). This can be changed with the 'iskeyword'
option. An empty line is also considered to be a word.
A WORD consists of a sequence of non-blank characters, separated with
white space. An empty line is also considered to be a WORD.
I feel word and WORD are just the same thing. They are both a sequence of non-blank chars separated with white spaces. An empty line can be considered as both word and WORD.
Question:
What's the difference between them?
And why/when would someone use WORD over word?
I've already done Google and SO search, but their search-engine interpret WORD as just word so it's like I'm searching for Vim word vs word and of course won't find anything useful.

A WORD is always delimited by whitespace.
A word is delimited by non-keyword characters, which are configurable. Whitespace characters aren't keywords, and usually other characters (like ()[],-) aren't, neither. Therefore, a word usually is smaller than a WORD; the word-navigation is more fine-grained.
Example
This "stuff" is not-so difficult!
wwww wwwww ww www ww wwwwwwwww " (key)words, delimiters are non-keywords: "-! and whitespace
WWWW WWWWWWW WW WWWWWW WWWWWWWWWW " WORDS, delimiters are whitespace only

To supplement the previous answers... I visualise it like this; WORD is bigger than word, it encompasses more...

If I do viw ("select inner word") while my cursor is on app in the following line, it selects app:
app/views/layouts/admin.blade.php
If I do viW (WORD) while my cursor is at the same place, it selects the whole sequence of characters. A WORD includes characters that words, which are like English words, do not, such as asterisks, slashes, parentheses, brackets, etc.

According to Vim documentation ( :h 03.1 )
A word ends at a non-word character, such as a ".", "-" or ")".
A WORD ends strictly with a white-space. This may not be a word in normal sense, hence the uppercase.
eg.
ge b w e
<- <- ---> --->
This is-a line, with special/separated/words (and some more). ~
<----- <----- --------------------> ----->
gE B W E
If your cursor is at m (of more above)
a word would mean 'more' (i.e delimited by ')' non-word character)
whereas a WORD would mean 'more).' (i.e. delimited by white-space only)
similarly, If your cursor is at p (of special)
a word would mean 'special'
whereas a WORD would mean 'special/separated/words'

That's a grammar problem while understanding the definition of "word".
I get stuck at first in Chinese version of this definition (could be miss-translation).
The definition is definitely correct, but it should be read like that:
A word consists of:
[(a sequence of letters,digits and underscores),
or (a sequence of other non-blank characters)],
separated with white space (spaces, tabs, <EOL>).
Whitespace characters were only needed when delimiting two same types of 'word'
More examples in brackets as follow:
(example^&$%^Example) three "word" :(example), (^&$%^) and (Example)
(^&^&^^ &&^&^) two "word" : (^&^&^^) and (&&^&^)
(we're in stackoverflow) five "word" :(we), ('), (re), (in) and (stackoverflow)

Another way to say it. If ur coding, and want to move thru the line stopping at delimiters and things line that "() . [] , :" use w.
if you want to bypass those and just jump to words lets say like a novel or short story has, use W.
For coding the small w is probably the one used most often. Depends where you are in the code.

Related

Is there a succinct way to delete to the end of the word or the next punctuation mark in Vim?

In Vim, I regularly use dw to delete from the cursor to the end of the word and daw to delete an entire word.
Now that I'm editing SQL all the time, I'd love to be able do something similar for all the table and field names, which use underscores as delimiters.
Is there a succinct hotkey in Vim to delete from the cursor to the end of the word, or to the next punctuation mark? I don't want to have to spend the mental energy to decide "is the end I'm trying to delete up to an underscore, or is it the line end? Or is it a period between the table and field names?"
I'm sure I could do something like df(_|>), but if I'm typing that many characters, I might as well just hit the delete key 8 times.
If another way to rephrase the question is "how do I make vim consider _ to be a word delimiter so that I can use dw and other word-related commands with it?", then you can use
:set iskeyword-=_
Vim will then consider _ to be a word separator, allowing you to use dw to delete the text before the underline.
Some other options are mentioned in the answers in this post: Customising word separators in vi
use dw to delete from the cursor to the end of the word
The actual meaning of dw is "delete from the cursor to the next word". It certainly can "delete from the cursor to the end of the word", but only in some cases. de, which actually means "delete from the cursor to the end of the word" seems more appropriate.
Now, Vim has the notion of :help word:
A word consists of a sequence of letters, digits and underscores, or a
sequence of other non-blank characters, separated with white space (spaces,
tabs, <EOL>).
and :help WORD:
A WORD consists of a sequence of non-blank characters, separated with white
space.
For example, in the sample below:
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
all these would be considered as "words", covered by lowercase word motions:
fmt
.
Println
("
hello
world
")
while these would be "WORDS", covered by uppercase word motions:
fmt.Println("hello
world")
And then there is the way w and W handle leading/trailing whitespace to take into account.
See :help word-motions.
I don't want to have to spend the mental energy to decide "is the end I'm trying to delete up to an underscore, or is it the line end? Or is it a period between the table and field names?"
All that to say that Vim can't be expected to read your mind with regard to what you exactly want to delete. Instead, it comes with mildly opinionated defaults and :help 'iskeyword', that you can adjust as you wish.
You are the only one who can decipher the riddle above so yes, you have to spend that mental energy.
Alternatively, you could provide precise and exhaustive requirements so we can help you figure out a way out of this.

Replace a word (or many words) with spaces of same length?

In a general sense, my question is how do I do something like "dw" or "dd", but instead of deleting characters, I want to over-write with spaces?
E.g. lets say I have text:
first second third
if the cursor is on the "s" in second, I can hit "dw" to get:
first third
but what if I want:
first third
Is there a simple way to do that? An ideal solution would be to use the "d" style syntax (e.g. dw, daw, d$, etc.) but with whitespace replacement instead of deletion.
From the start of the word,
Ctrl-v to enter visual block mode,
e to move to the end of the word (highlighting the word in the process),
r[SPACE] to replace the highlighted characters with spaces.
Because of their very nature (the next character must be consumed), r and R can't work like operators. If you want to replace a motion, visually select it first, and then do r<Space> or r_ or whatever.
In this very specific case:
ver<Space>
or:
viwr<Space>
NOTE: I used ve and viw because the semantics of w are inconsistent so I prefer to avoid it when possible.

Vim yank path under the cursor

What's the most efficient way to yank a path that's under a cursor? So if a line has the following contents:
/some/file /some/other/file /last/file
... and the cursor is over other, I would like to yank /some/other/file. Normally, if it were a word yiw would work, but since that path contains quotes, yiw would only yank other rather than the entire /some/other/file.
Is there a way to efficiently yank the entire filename?
A word consists of a sequence of letters, digits and underscores, or a
sequence of other non-blank characters, separated with white space (spaces,
tabs, ). This can be changed with the 'iskeyword' option. An empty line
is also considered to be a word.
A WORD consists of a sequence of non-blank characters, separated with white
space. An empty line is also considered to be a WORD.
yiW - just need to capitalize the W
While I would use yiW as in dave's answer, ByE (go to beginning of WORD, yank to end of WORD) is another possibility.
Byt<space>:
B to go to the start of the file location,
yt<space> to yank up to the next line space.

Vim - Insert something between every letter

In vim I have a line of text like this:
abcdef
Now I want to add an underscore or something else between every letter, so this would be the result:
a_b_c_d_e_f
The only way I know of doing this wold be to record a macro like this:
qqa_<esc>lq4#q
Is there a better, easier way to do this?
:%s/\(\p\)\p\#=/\1_/g
The : starts a command.
The % searches the whole document.
The \(\p\) will match and capture a printable symbol. You could replace \p with \w if you only wanted to match characters, for example.
The \p\#= does a lookahead check to make sure that the matched (first) \p is followed by another \p. This second one, i.e., \p\#= does not form part of the match. This is important.
In the replacement part, \1 fills in the matched (first) \p value, and the _ is a literal.
The last flag, g is the standard do them all flag.
If you want to add _ only between letters you can do it like this:
:%s/\a\zs\ze\a/_/g
Replace \a with some other pattern if you want more than ASCII letters.
To understand how this is supposed to work: :help \a, :help \zs, :help \ze.
Here's a quick and a little more interactive way of doing this, all in normal mode.
With the cursor at the beginning of the line, press:
i_<Esc>x to insert and delete the separator character. (We do this for the side effect.)
gp to put the separator back.
., hold it down until the job is done.
Unfortunately we can't use a count with . here, because it would just paste the separator 'count' times on the spot.
Use positive lookahead and substitute:
:%s/\(.\(.\)\#=\)/\1_/g
This will match any character followed by any character except line break.
:%s/../&:/g
This will add ":" after every two characters, for the whole line.
The first two periods signify the number of characters to be skipped.
The "&" (from what I gathered) is interpreted by vim to identify what character is going to be added.
Simply indicate that character right after "&"
"/g" makes the change globally.
I haven't figured out how to exclude the end of the line though, with the result being that the characters inserted get tagged onto the end...so that something like:
"c400ad4db63b"
Becomes "c4:00:ad:4d:b6:3b:"

In Vim, I'd like to go back a word. The opposite of `w`

When you're using vim, you can move forward word by word with w. How do I go backwards?
Use b to go back a word.
You may also want to check out W and B to advance/go back a WORD (which
consists of a sequence of non-blank characters separated with white space, according to :h WORD).
It helps for me to think of it as:
b to go to beginning of current or previous word
w to go the beginning of next word
e to go to the end of current or next word
ge to go the end of the previous word
Try :h word-motions for more details and how to combine them with operations.
use "b" to move back - just tested in vi - works fine.
Alternatively, if you use w, b, W, and B to navigate lines by hopping over words, consider the following alternatives which can be faster if used correctly.
f<char> # jump to next occurrence of <char> to right (inclusive)
or
F<char> # jump back to next occurrence of <char> to left (inclusive)
If your words are separated by spaces
If your words are separated by <space> you can hop over words by spaces:
f<space>;;;; where ; repeats the previous command, so you hop forward by spaces
F<space>;; to hop backwards by space
If your words are separated by punctuation and not spaces
just replace <char> with punctuation, for example .
The punctuation method is not efficient for scrolling through, but if you know where you want to jump, it can usually get there in a jump or two.

Resources