what's the difference between command cw and ciw in Vim? - vim

Here's a link I find in stackoverflow about this question.
but I still cannot understand without a specific example about what's the difference between "change inner word" and "change word".
I test these two commands in my vim and finally find no differences ,Please give me an example to help me understand, thank you!

Here is an example:
foo bar baz
^
Typing cw and ciw will give the same result in this case (with the cursor positioned on the 'b' of 'bar').
Consider this:
foo bar baz
^
cw will yield
foo b baz
^
where ciw will yield
foo baz
^
so it changes the whole word, regardless of the cursor position. Very useful, i love this command.
Very useful is also the caw (or the aw) command:
foo bar baz
^
-> caw
foo baz
^
aw also contains the space. Try these commands with the v (visual) command, to see what they all do. Also, read motion.txt, part 6.

Above answers addressed HOW they behave different, i would like to share some idea on WHY they behave different.
First, in vim's world, w and iw have different semantics and can both be seen as target(see below):
w in cw refers to a Motion Object
while iw in ciw refers to a TextObject
Secondly, in Vim editing, Operator (c/change in your case, and y/yank, d/delete, =/indenting, >/shifting etc) and Target (w and iw in your case) helps you achieve what you want to do with less keystrokes compared to using visual selection + operator.
TextObject defines target range (start and end position).
Motion is essentially used to move cursor, so it only define final-target-position (destination to move).
Some good materials to read:
:h motion.txt part 4, 5
AdvancedTopicTutorial from atom-vim-mode-plus

someword
^ (cursor)
cw
some_
^ (cursor)
Changes from cursor to end of word. Leaves the start of the word.
Compared to
someword
^ (cursor)
ciw
_
^ (cursor)
Changes the entire word from start to end.

Mind you, cw has a bit 'unstandard' behavior by default in that it is behaves exactly like ce: It only works up until the end of the current word (like e, ce, de, ye) instead of including the whitespace up before the beginning of the next word (like w, dw, yw).
Therefore I recommend adding these mappings to your vimrc:
" Have `cw` adhere to its actual movement `w`, instead of duplicating `ce`.
nnoremap cw dwi
nnoremap cW dWi
and getting used to usually using ce. Typing ce is actually more efficient and less awkward than cw if you form the habit of pressing the e with your ring finger instead of middle finger when it comes right after c.
If you prefer to leave cw with its default assignment duplicating ce, then you can access its 'proper' functionality with an additional keystroke: dwi (or vwc).
(Mind you, I find dwi even more efficient to type than cw because of the positions of the keys, in spite of the additional key.)
Explanation of the second mapping: W (Shift+w) works on what vim calls "WORDS", which counts every non-blank character, e.g. punctuation, as part of a WORD; while w works on "words", which only consist of uninterrupted sequences of letters, digits and underscores (by default).

Related

Move cursor to end of line in vim (to delete last word)

I usually type the command db to remove one word backwards in Vim. Doing this at the end of a line without whitespace leaves the last character of the word since the cursor starts removing from the second last character.
I can press b followed by de instead, but I find this confusing sometimes when doing it many times in a row, leading to unneccesary mistakes. I was hoping there was a way to go to the end of the line and remove the last word backwards.
Is there a way to do this?
You should train yourself to stop using db and learn to love text objects instead. This problem happens even if you're not at the end of a line.
foo bar baz
^
and then db will give
foo r bax
^
Instead of using db or de or even dw, train yourself to use diw and daw. This might take some getting used to, but down the road it will become natural and be way more convenient to use. And once the text objects become natural to you, you can then start using other commands ('c' or 'y', etc.) or even other text objects. (I can't even count how many times I've used dap or ci()
For a short explanation of what these do, think of diw as (d)elete (i)nside this (w)ord and daw as (d)elete (a)round this (w)ord or (d)elete (a) (w)ord. For a more concrete example:
foo bar baz
^
typing diw gives
foo bar
^
(note the leading space)
But
foo bar baz
^
typing daw gives
foo bar
^
And as long as your cursor is over the same word, these will still do the same thing. So if we moved the cursor back to the 'a' or the 'b', you'll get the exact same results. This blog goes into more depth on text objects.
You can either:
use a mapping like this:
:nnoremap <silent> db :exe 'norm!' (col('.')==col('$')-1 ? 'daw' : 'db')<cr>
alternatively, you can do :set ve=onemore which allows you to go one
char past the end of line, then once your cursor is past the end (see command g$), simply use db.
EDIT (explanations)
:exe executes the string formed by its arguments as a command.
So if the cursor is at the end of line (col('.')==col('$')-1),
it will execute:
:norm! daw
otherwise it will execute:
:norm! db
:norm lets you run normal commands in the command line. For example if you're already in
normal mode, typing :norm db + return will do the same as just typing db.
It's useful inside commands. The ! prevents mappings to be used in the :norm commands.
See :h :norm.
<silent> makes a mapping silent: without it you would see
:exe 'norm!' (col('.')==col('$')-1 ? 'daw' : 'db') in the bottom of the
screen.
See :h <silent>.
<cr> is the key code for the return key. You can put this kind of codes inside mappings.
In this case, <cr> will validate the command just entered in the mapping.
See :h keycodes for details.
What about
$diw
$ - takes you to last character of the line
d - as you know is for delete
i - implies from inside. Read more on other powerful text objects :help text-objects
w - word
If you are not habituated using text-objects, start using. You will love it

c, i and s commands combined in VIM

I've been using VIM for a while and it surprises me each time. Under "Building Sentences" section in this tutorial, I saw the combination of commands cis and yip. I have used Vim quite a while and I am familiar with most commands in Normal Mode. I also know combining the commands in a meaningful way to produce combined actions.
However, the examples I showed above (cis and yip) totally broke my understanding of VIM command system in normal mode. "c" stands for change, "i" stands for insert and "s" stands for substitute but combined action is different than I would expect. I also went through VIM help files but never saw an example illustrating given usage.
Could someone clarify what's going on ?
cis
In vim help it is described as follows
:help c
"Delete {motion} text [into register x] and start insert …"
The next part of the command cis refer to the "motion" part. These commands are for text object selection. An explanation on the different types of text object selections can you get here:
:help text-objects
e.g. for
is – "inner sentence", select [count] sentences …
Analog to the explanation above its the same with yip
:help y
"Yank {motion} text [into register x] … "
And the text selection part yip
ip – "inner paragraph", select [count] paragraphs (see paragraph) …
In this case i does not stand for Insert and s not for substitute.
cis = change inner sentence.
This is completly logic once you understand the basic principle. Each command is like a sentence, it needs an Verb(Action) and an Noun(Object) and there are modifiers.
So the first button is your action C (Change). Now the following keystrokes will not be actions, until the c action ended (Until an Object is provided, or an invalid sequence is inserted). I (inner) is a modifier here and S the Object (Sentence).
I find this especially usefull for Changing words. if you only press cw on a word, you have to have the cursor on the beginning of the word.
With ciw you can change the whole word regardless of the cursor position (Note if you have / or some other seperators in the word, you maybe need ciW)
same letter can have different meanings. E.g. (/{ move to sentences/paragraph back, but ci( or ci{ means change in (...)/{...}.
Same as your s case, s in normal mode alone, does delete & start insert, however in cis, das means sentence.
p case: in normal mode alone, means paste, however in cip, yap ... means paragraph.
:h text-objects
will show you the concept of text-objects. It is a must skill for vim user. ;-)

vim: command like f{char} but for series of chars instead of single char

In vim I can navigate to char in current line using f{char} -- To [count]'th occurrence of {char} to the right. The cursor is placed on {char} (inclusive).
Lets look on next line:
from fmodule import futility
-- there are three words starting from f letter and assume that I want to jump to futils. To do it (with cursor at the beginning of line) I will execute 2ff, but instead I would really like to do something like f{fut} (providing first chars of word not single one).
What are the ways to accomplish this task?
You can use the / search as a motion, also in visual mode and in combination with a command like d. You need to conclude the search with <Enter>, as usual. In contrast to f, this will also find matches in following lines. Some consider this a feature (and change f accordingly via plugins), others don't like this. If you're in the latter camp, the following mapping will restrict the pattern to the current line automatically:
noremap <expr> <Leader>/ '/\%' . line('.') . 'l'
You might also want to define <Leader>? for the opposite direction.

How to move through words in camel-cased identifiers in Vim?

How to move the cursor before or after the first uppercase letter of a word in Vim?
My motivation is removing or selecting the first word of a camel-case identifier in code. For example, if the cursor is on the m character in the word camelCase, I can use the FcdtC sequence of Normal-mode commands to delete the camel prefix.
Is there a general way to jump to the next occurrence of an uppercase letter in an identifier?
In situations where approaches using only built-in Vim instruments are
preferred, the following search commands can be used.
For jumping to the next uppercase character:
/\u
For moving the cursor one character to the right of the next uppercase
character:
/\u/s+
or
/\u\zs
If one expects to use a movement like that often, one can always
define a key mapping for it as a shorthand, e.g.:
:nnoremap <leader>u /\u/s+<cr>
I don't think there is anything built-in.
As #ib. indicates, you can use a regular expression motion, but it’s not particularly easy to type. However, there is camelcasemotion plugin that adds the necessary motions, for this, as well as underscore seperated identifiers.
Updated Answer (using #ib.'s contribution)
"select from first char up to First uppercase letter ( after first char )
map ,b bv/[A-Z]<cr>h
Original Answer
Regarding jumping before and after the first uppercase letter—
You can map it if you want to.
"Before next uppercase letter
map ,A /[A-Z]<cr>l
"After next uppercase letter
map ,B /[A-Z]<cr>h
:D. Hope this helps. I'm reading your second question now.
Ok, read it. Now you can do this
bv,A
:D
I think I thought maybe "the vim way" to do it :
Vim allow us to define our own operator !
" movement mapping {
" Delete yank or change until next UpperCase
" o waits for you to enter a movement command : http://learnvimscriptthehardway.stevelosh.com/chapters/15.html
" M is for Maj (as in french)
" :<c-u>execute -> special way to run multiple normal commande in a map : learnvimscriptthehardway.stevelosh.com/chapters/16.html
onoremap M :<c-u>execute "normal! /[A-Z]\r:nohlsearch\r"<cr>
That way giving
DailyAverage.new(FooBarBaz)
If my cursor is on a (from DailyMesure) and I press dM It delete to A and give
Average.new(FooBarBaz)
It works with all command waiting for a movement (c y ........)
This snippet need to be improved because of bad highlight.

Preferred way to move around in vim (normal mode)

I haven't seen this asked on stackoverflow, and this is my biggest pain point in vim:
How do you all navigate within a file? I found myself using the hjkl too much, or too repetitively, and I want to get better at this. This is frustrating when you're on a large monitor.
I installed EasyMotion - and so far it's been good for me - I just want to know if there's something better...
Thanks!
I like the cheatsheet of Ted Naleid. It's like a reticle so you can easily find the horizontal and vertical movements. Put it on a wall next to your monitor and you will soon pick up new movements on the fly.
The movements that I liked recently are:
() and {} which let you hop function wise in source code
/ and ? + n/N just search, you normally know where you want to go
fx and tx - to jump to or before the next character x
of course you can do a 2fx to jump to the second occurrence of x, like you can do with all movements
% to move between starting and ending parenthesis
I use b and w to move left and right respectively on a single line. For up and down, I use Ctrl+u and Ctrl+d respectively. IMO Ctrl+u and Ctrl+d are better than Ctrl+b and Ctrl+f because they scroll half window at a time so that you don't loose context.
I haven't really used any plugin for moving around in vim so far.
Forgot to mention two other important keystrokes, $ and ^ to move to end of line and start of line respectively.
Several move commands:
b B e E f F ge gE gj gk go G h H j k l L M n N t T w W { } / ? ^ $ # * ` ' | %
Learn them, plus all commands starting with [ like [{ which is very useful when editing C-style code…
See :help index.txt for reference.
Mostly I use the following (in order of frequency):
'R go to marked position (the ` is too off the baseline keyboard to use much)
/search|?search forward|backward search
n|N next|previous in search
H|L|M top|bottom|middle of display
G go to end of file
1G go to line 1
{ go backward a 'paragraph' (often a code block)
} go forward one 'paragraph'
Most all of these can be augmented with a count before the command.
It depends on how you want to move around, but generally,
A puts you in insert mode at the end of a line
I at the beginning
o inserts a line below
O above
and more powerfully, searching with /<thing you want to jump to> is very handy. In a c file where the functions are formatted
int
funcname()
/^funcname will jump you to the start of the function. There's a bunch more, but this shold be a good start for someone new to vim.
Simple documentation:
http://vim.wikia.com/wiki/Moving_around
Regular movement:
hjkl/arrow keys/page up/page down
% will switch between open/ending braces
gg/G move to top/bottom
Folding:
For collapsing large blocks of code, you can use folding.
http://vimdoc.sourceforge.net/htmldoc/fold.html
Search:
To jump to something in particular type /searchstring (use with set inc for jumping to matches while typing)
* to search forward for the same word the cursor is on
# same but search backward
You can also use marks.
http://vim.wikia.com/wiki/Using_marks
I also use ctags and jumping to find stuff across multiple files.
http://vimdoc.sourceforge.net/htmldoc/tagsrch.html
I've never needed anything else.
I don't really see much to add in terms of general enlightenment but I use (ranked by how often I use them):
w and b
to move by one word to the right and to the left.
/ and ?
to search for a word or pattern to the bottom or to the top.
G and gg
to jump to the bottom and the top of the buffer.
<C-f> and <C-b>
to jump to the next and previous screen.
* and #
to jump to next and previous occurence of the word under the cursor.
f and F
to jump before a character to the right or to the left.
t and T
to jump on a character to the right or to the left.
Ho! and
$ and ^
a lot, too, to jump to the end and the beginning of a line.
Read http://www.viemu.com/a-why-vi-vim.html and run vimtutor, also :help motion.txt will be usefull. I recommend also staying in normal mode all the time - as described in article above. Generally, learning vim is learning piano - you have to practice much.

Resources