How to set initial caps in VIM? - vim

In VIM, it's really easy to change a word of text to use uppercase or lowercase:
# in visual mode
# change word to uppercase
gUw
# change word to lowercase
guw
Is there a simple way to modify the word to use initial caps?

Assuming cursor is at the beginning of the word, use
gUl
(if the word was all-lowercase) or
gUllgue
to explicitly make the first letter capital and other lower case.
It's the same that you used, only instead of w (word motion) you use l (one symbol motion).
If the cursor is somewhere in the middle of the word, prepend b (go to the beginning of the word) to the commands above.
You can map some key to do this if you use it often.

I'd suggest moving to the beginning of the word with whatever motion command(s) you want, then pressing ~. This behavior is affected by the tildeop option, see :help ~ and :help tildeop for more info.

Depending on what your use-case is, any of the following may work.
Use ~ to toggle the case of the letter under your cursor.
Use :s/\<\(\w\)\(\w*\)\>/\u\1\L\2/ to search for a word, upper-case the first letter, and lower-case the rest.
guiwgUl to lower-case the word your cursor is on and then upper-case the first letter.

If you're on the word:
bgUl
If you're at the beginning of the word:
gUl
Unpacking that: b goes back one word (or to the beginning of the word you're on), gU upcases over movement, l moves right one character (which will be the first letter in the word).

Side note:
I have a plugin (well, it's not its main purpose though) that is able to convert names between camel case, underscore separated words, etc. Move the cursor on an identifier, and type :NameConvert lower_camel_case for instance (the command supports completion (<tab>, <c-d>) to display all the possible naming schemes)
To install it, you'll need lh-dev, and lh-vim-lib.

There is a function toupper which you can use to make conversion. Even in substitution you can use that. Like find all sentence beginnings, and convert the first character to upper case, as explained here: search and replace

Related

Select first char up to first non camelCase or non upper case char or up to first snake case _ in vim

I used this map:
map ,w v/\([^ a-z0-9]\|[^ A-Z0-9]\)*<cr>h
the idea is to select
in the words
mysuperTest
MYSUPER_TEST
mysuper_test
to always select the part that says mysuper
but it doesnt work, not sure why
I would use something like the below:
nnoremap ,w v/\C\%#.\([a-z]\+\<bar>[A-Z]\+\)\zs<cr>h
One point to notice is that in a mapping you need to use <bar> (or escape | with an extra backslash) since otherwise | is recognized as a command separator (see :help map-bar.)
Another one to notice is that you want the match to start at the first character outside the word (so you'll land at the end of the word with the h). The visual selection will expand to the start of the match in a search. I suggest using \zs to set the start of the match explicitly (see :help /\zs.)
Finally, beware of 'ignorecase' or 'smartcase' settings. Use \C to explicitly request a case-sensitive match (see :help /\C.)
I also like the idea of using a stronger anchor for the start of the match, so I'm using \%# to match the current cursor position (see :help /\%#), so you're always sure to match the current word only and not end up wandering through the buffer.
Putting it all together:
\C Case-sensitive search
\%# From cursor position
. Skip first character
\( Either one of:
[a-z]\+ One or more lowercase letters
\| (\<bar>) Or:
[A-Z]\+ One or more uppercase letters
\) End group
\zs Set match position here
I'm skipping the first character under the cursor, since in a CamelCase word, the first character won't match capitalization of the remainder of the word.
I kept your original idea of finding the first character after the word then using h to go back one to the left. But that might be a problem if, for example, the word is at the end of the line.
You can actually match the last character of the word instead with something like [a-z]\+\zs[a-z], which will set the start of the match on the last lowercase character. You can do this for both sides of the group (you can have more than one \zs in your pattern, last wins.) If you structure your match that way, you won't need the final h to go back.
I didn't handle numbers, I'll leave those as an exercise to the reader.
Finally, consider there are quite a few corner cases that can make such a mapping quite tricky to get right. Rather than coming up with your own, why not look at plug-ins which add support for handling CamelCase words that have been battle-tested and will cover use cases a lot more advanced than the simple expression you're using here?
There's the excellent vim-scripts/camelcasemotion by Ingo Karkat which sets up a ,w mapping to move to the start of the next CamelCase word, but also i,w to select the current one. You can use powerful combinations such as v3i,w to visually select the current and next two CamelCase words.
You might also check Tim Pope's tpope/vim-abolish which, among other features, defines a set of cr mappings to do coercion from camelCase to MixedCase, snake_case, UPPER_CASE, etc. (Not directly about selecting them, but still related and you might find it useful.)

How to replace characters until matching character sequence?

I know that in command mode, ct{char} removes all text from current cursor position till next matching {char}, which can then be replaced by continuing to type.
For example, suppose the text is:
abcdefgh
and cursor is on b, then typing ctg will remove bcdef, which can be replaced by continuing to type.
But this works only for a single matching character. Is it possible to do this by matching a character sequence, for example, using gh instead of g, in above example?
Note: I know that the s/// could be used, but this is a little faster, and more convenient.
Yes. Use the search command:
c/gh
The search is a motion for the previous command. So it will delete characters until if finds a gh string.

vim: replace all characters up to a given token

Using vim I would like to replace all characters up to a certain one with another character, say a blank space - without affecting the layout/number of characters in the line. Here's an example:
Before:
real(kind=R12), intent(out) :: my_var
After replacing , intent(out) with blanks (i.e. starting from ,, and going up to )):
real(kind=R12) :: my_var
I know about r to replace one character, and about nr to replace n characters, but I would like to know whether I can accomplish my task without first having to count the characters I want to replace.
Thanks a lot for your replies!
Visual mode is probably the shortest way here:
vt:r
v enter visual mode
t: select till :
r (note space after r) replace selected region with spaces.
In command mode type 'df?' to delete up to that (?) character. Then 'i' to go back to insert.
For example if the following sentence is in your view:
The wizard quickly jinxed the gnomes before they vaporized.
and you enter dfs
You will be left with:
before they vaporized.
I know about r to replace one character
Did you know that R will keep you in that replace mode? So you could hit R and then hold Space until you've replaced everything you want.
However, I'd still go with Thor's answer. Visual mode allows you to use the efficient text navigation methods in vim without having to count out characters.
But if you disagree, there's always EasyMotion.
You can use regular expression here (use (.*?) to reference all values up to a token).
For instance:
The regex: (.*?)foo will get rid of everything up to foo.

How to change letters in a word from upper case to lower case or the other way around (swap case)?

Instead of deleting the word and retyping all the letters once again in the opposite case, I'd like to find some smart way in Vim to solve the problem.
It's
g~iw
with the cursor on the word.
Key:
g flag (I couldn't find a good reference for this...)
~ toggle case; alternatively use U for to-upper or u for to-lower
iw selects the Inner Word, i.e. the word that the cursor is on; ip selects the Inner Paragraph
See Michael Jakl's Vim Introduction and Tutorial - concise and has some nice graphical explanations.
g~ followed by a "motion" will flip the case of the letters.
gU will upper-case them
gu will lower case them
So
g~w will flip the case of the letters to the end of the current word.
guG will lower case the letters to the end of the file
gU$ will upper case the letters to the end of the current line.
you can do this in normal mode: vEU (having the cursor at the beginning of the word or pressing b to move it there)
v - go to visual
E - go to end of the word
U - make the visual selection uppercase
Instead of the U you can do u for lowercase or ~ for case flip.
~ (tilde) key. Should change the case of whatever is under the cursor. Works in normal and visual mode.
You can select the word with visual mode (viw) and press ~, it switches case for all letters in the word.
I would liek to emphasize that, in order to achiving switch the upper/lower case of a word, it depends on what is the exact position of the cursor.
if the cursor is now at the first character of the word, you can use g~w:
g stands for you want to do some operation in some scope(while the w definese the exact scope;
~ means you want to switch the upper&lower case(you can substitue ~ with U/u, which means you want to switch the word into upper case/lower case);
w means you want to do the case switch from the cursor to the end of the word;
if the cursor is now in the middle of the word, not the very beginning of it, you can use g~iw:
iw means you want to do the case swith for the word in which the corsor is now located.
Shift + F3 flips the word(s) between all uppercase, just the first letter and all lowercase. Has changed my life

Vim copy and paste

My previous question seems to be a bit ambiguous, I will rephrase it:
I have a file like this:
copythis abc
replacethis1 xyz
qwerty replacethis2
hasfshd replacethis3 fslfs
And so on...
NOTE: replacethis1, replacethis2, replacethis3, ... could be any words
How do I replace "replacethis1","replacethis2","replacethis3",.. word by "copythis" word by using minimum vim commands.
One way I can do is by these steps:
delete "replacethis1","replacethis2","replacethis3",.. by using 'dw'
copy "copythis" using 'yw'
move cursor to where "replacethis1" was and do 'p'; move cursor to where "replacethis2" was and do 'p' and so on...
Is there a better way to do this in VIM (using less number of vim commands)?
Since you changed your question, I'd do it this way:
Move to the first "replacethis1" and type cw (change word), then type "copythis" manually.
Move to the next "replacethis", hit . (repeat last operation)
Move to the next "replacethis", hit .,
and so on, and so on.
If "copythis" is a small word, I think this is the best solution.
The digit needs to be included, and there could be more than one instance per line:
:%s/replacethis\d/copythis/g
Given that "replacethis[1-3]" can be arbitrary unrelated words, the quickest/simplest way to do this globally would be:
:%s/replacethis1\|replacethis2\|replacethis3/copythis/g
(Note that you need to use \| to get the pipes to function as "or". Otherwise, vim will look for the literal | character.)
I've been struggling with this for a long time too, I think I just worked out the cleanest way:
Use whichever command is cleanest to put copythis into register r:
/copythis
"rye
Then go to the replacement and replace it with the contents of r:
/replacethis
cw<CTRL-R>r<ESC>
Then you can just n.n.n.n.n.n.n. for the rest of them, or if they're wildly different just go to the beginning of each and hit .
The key is replacing and pasting in one step so you can use . later.
:%s/copythis/replacethis/g
To replace all occurrences of copythis with replacethis. Or you can specify a range of line numbers like:
:8,10 s/copythis/replacethis/g
Note, the /g on the end will tell it to replace all occurrences. If you leave that off it will just do the first one.
create this mapping:
:map z cwcopythis^[
( ^[ is the escape character, you can type it in vim using Ctrl+V Ctrl+[ )
go to each word you want to replace and press z
if u need to do essentially the same action multiple times - swap 1st word of one line with second word of the next line, I say you could record a macro and call it whenever you need to
Have you tried string replacement?
%s/replacethis/copythis
A host of other parameters are possible to fine-tune the replacement. Dive into the Vim help for more details. Some more examples here.
You can remap e.g. the m key in normal mode to delete the word under the cursor and paste the buffer: :nnoremap m "_diwP.
Then you can just copy the desired word, move the cursor anywhere onto the to-be-replaced word and type m.
EDIT: Mapping to m is a bad idea since it is used to mark locations. But you can use e.g. ; anyway.

Resources