Vim normal! sending literal <Space> string instead of whitespace character - vim

I'm not sure what I'm doing wrong here.
:normal! I###<Space><Esc>
The end result I want when I execute this command over a word is this:
### word
But instead I get this:
###<Space>word

Vim's :normal is a nightmare with anything moderately complicated. I don't remember why, but this is the easiest way to get what you want. You need to escape the opening < in a string passed to execute.
execute "normal! I###\<Space>\<Esc>"
Edit: Vim doesn't really explain why, but :help normal
An alternative is to use |:execute|, which uses an
expression as argument. This allows the use of
printable characters to represent special characters.

Lets first explain the vim command:
:normal! run the rest of the commands as normal mode
I enter insert mode from the beginning of the line <shift> + i
###<Space><Esc> - type out the characters ###<Space><Esc> literally since we are in insert mode (notice that if you just enter insert mode, and type ###<space><esc>, you'll get just that literally.)
When this command finishes, you'll notice how it's still in normal mode. This means that your command can just omit the <space><esc> and enter the space literally:
:norm! I###
(There is an extra space after the last hash)

Related

Vim normal editing in Visual line not working as expected?

So this is the first time i am experimenting around visual line editing in vim. I have a couple of words as following
cat
dog
and i want to surround them with brackets (without using surround.vim) for learning. The commands that i use after visual selection is as follows
:'<,'>norm 0i(<esc>$a)
and also
:'<,'>norm 0i(<C-v><esc>$a)
The problem is that vim seems to print out as well and the output i get is
(<esc>$a)cat
(<esc>$a)dog
Any hint to where i might be going wrong will be greatly appreciated.
Also worth noting that i am running vim using vim -u NONE so vimrc file doesn't get loaded.
The :normal command does not parse special characters. As you may have guessed, <esc> is inserted literally as five different characters.
You will need to wrap it in :execute with an escape on those special characters:
:exe "'<,'>norm 0i(\<esc>$a)"
Alternative ways of doing this (using the full buffer range %):
:exe "%norm I(\eA)" - an alternative way of writing the esc character
:%norm I(^[A) - where ^[ is ctrl-v and then esc, to insert a literal esc character which doesn’t need to be parsed.
:%s/.*/(&)

extra space added when going into insert mode in an abbreviation

I'm trying to create an abbreviation which replace typed text by what I want but also move the cursor and enters insert mode.
the ab is as following:
:abbreviate MSG `MSG(("")); <Esc>F"i
everything works fine except when entering insert mode, I have to extra spaces before the cursor.
I've tried then to add <BS><BS> but it's leading to delete the first quote. Same thing if I'm putting only one <BS> (which is really strange, it seems the second <BS> has no effect at all...)
I guess I'm missing something but I can't figure out what...
Thanks for your help !
A citation from Vim help system (:help abbreviations):
An abbreviation is only recognized when you type a non-keyword
character. This can also be the <Esc> that ends insert mode or the
<CR> that ends a command. The non-keyword character which ends the
abbreviation is inserted after the expanded abbreviation. An
exception to this is the character <C-]>, which is used to expand an
abbreviation without inserting any extra characters.
Example:
:ab hh hello
"hh<Space>" is expanded to "hello<Space>"
"hh<C-]>" is expanded to "hello"
So if you press <Space> after entering MSG a space is inserted after expanding your abbreviation.
To avoid adding a needless space you can invoke the abbreviation with pressing <C-]> after entering MSG or you can try elaborate a mapping like this:
:inoremap MSG `MSG(("")); <C-O>F"
But IMHO such a mapping is very inconvenient.
Another option may be to use use one of the many abbreviation plugins like this (first shown by Google).

How can I use the commands defined in this vim tip?

I am looking for a way to use f followed by some character to jump to the next uppercase letter.
I ran across this question and want to use the accepted answer, since that did not appear to have any dependencies.
However, after I added the lines into my .vimrc, I cannot figure out how to actually jump to the next uppercase character.
I tried Ctrl-Right and Ctrl-o, and both orderings of them, but I could not jump to the next uppercase letter in the line. I also read the actual vim tip, but that also does not explain how to actually use the commands.
What is the correct sequence of commands, and in which mode, to actually jump to the next uppercase letter?
Does it have to be the find command? What about typing /[A-Z]? It'll find the next upper case character (even if it's on a different line), and it's fast to type. Pressing n will take you to the next one without retyping the command again.
What you found in the other answer was a macro command. VIM has a rich macro language that allows you to define functions. You can run a function by typing a colon and then its name.
Of course, typing :findNextCapitalCharacter is a bit long to type. You can use map to define a key macro that will basically type the letters for you to find the next command. I like prefixing my mapped macros with some character like %, so typing %c will find the next capital character.
Further Explanation
I'm currently just doing /\u, but I still want to know how to use the macro in that answer for my own learning. In the case of those macros, what is the actual means to invoke the macro command?
You're way ahead of me! I didn't know about \u being uppercase.
Looking at the answer, I see they're not defining a macro, but doing key mapping. Here's a quick intro:
In command mode (that's where you can't type in anything into your file, but where you can use commands), type in :map #$ iHello World and press return. Now, still in command mode, type #$. You'll see that VIM typed iHello World for you. The i put VIM into insert mode, so it could type in Hello World That's mapping!
In VIM, you have special map modes depending on the mode you're in. In the original VI, you had two modes: Command and Insert. In VIM, you have Command, Select, Visual, and Command-Pending modes. The different map command depend upon the mode. Type :help mapmode into VIM and press <RETURN> to see about the various map modes and their VIM commands. This will be VIM help manual sections 1.3 to 1.5. Read it thoroughly to understand what the different map command mean.
What the accepted answer is doing is entering the maps three different times, once for each mode. There are two different maps (one search to the previous and one search to the next), so six all together.
The accepted answer is mapping Cntrl-Left Arrow <C-left> and Cntrl-Right Arrow <C-Right> to each of these mappings. Much like I mapped #$ to Hello World.
Setting g:camelcase is setting a global variable called camelcase to a string. If the string is A-Z, it will be for just capital letters. If it's A-Z0-9, it's for capital letters and numbers. You should only define one instance of this variable.
I think you're problem is that you're typing in <C-Left> for the map. What you're suppose to type is ^V^-> where ^V is Ctrl-V and ^-> is Ctrl-Left Arrow. When you type that in, the map command will change those into <C-Left>.

How to escape in g command's norm mode of Vim

I want to add []( to the beginning of a line and ) to the end of a line that starts with http in Vim.
To do this I am using the following g command:
g/^htt/norm I[](
Now, I want to press Esc key now inside g and put A). How can I do that?
You can escape the Esc key by using ctrl+vfollowed by esc.
ctrl+v will insert the next non-digit literally.
Note: You may have to use ctrl+q depending on your system. (Nice mnemonic is quote)
See help for more information
:h c_Ctrl-V
To be able to use two :normal commands in sequence, you have to wrap them in :execute. When you use double quotes, you can then write the Escape as \<Esc>, like this:
:g/^htt/exe "norm I[](\<Esc>" | norm A)
Notes:
Unless you need mappings to apply, using :normal! (with the bang) is preferred, because it's more robust.
You could have also used :substitute here.
This is easier to do with :s:
:%s/^htt.*/[](&)/

How does :normal! /something<cr> relate to incsearch and the / operator?

A few micro-questions regarding normal!, incsearch and the / operator (search). I'm not solving any particular problem here, just trying to understand the relations between the mentioned, so I can put up some sort of analogy in my head.
If I have, set incsearch on, while in normal mode upon pressing /something Vim will jump to the first instance of something even before/without me pressing enter.
Okey, so normal! /something should do the same thing. Why doesn't it?
Similarly, normal! doesn't recognize special characters. So if I have a text file with this text in it,
something<cr>
(that's not a special character in there, but literally typed in text)
`normal! /something<cr>`
should put me up to that text. Why doesn't it?
I like it, but sometimes Vim's inconsistencies are, to put it mildly, most interesting :)
In :help :normal the relevant text is:
{commands} should be a complete command. If
{commands} does not finish a command, the last one
will be aborted as if <Esc> or <C-C> was typed.
The command string you give to normal has to be a complete command, or it aborts. However, normal! /something isn't complete; if you were typing it, Vim would be waiting for you to finish. You could press Esc or Ctrl-C to abort. Or you could complete it by pressing Enter. So the command isn't complete and it aborts, instead of jumping. To get it to complete, give it the Enter it wants (at the command line):
:normal! /something^M
You can get the ^M by typing Ctrl-V and then Enter. (If on Windows and Ctrl-V pastes, use Ctrl-Q.) Then you'll need to press Enter again to finish the whole command. If you were using execute you could do it with:
:execute "normal! /something\<cr>"
Be sure to use double-quotes so the \<cr> will be interpreted correctly.
I believe your second question is the same thing. The literally typed <cr> doesn't affect this situation, you just need to provide the carriage return that will complete the search command, or normal aborts it.
Since you've tagged this question with vimscript, I'm guessing that at least part of your interest is in using this in a script. Getting the literal carriage return into a script and having it work right is kind of a pain. In those cases, I would use execute as shown above, so you can use the double-quote interpretted string method of getting the carriage return.
As for incsearch, it won't have an effect because you can't be partially searching with normal, as we've seen. You can only submit the entire search. It will, however, update the most-recent-search register "/, so highlighting will still update correctly.

Resources