How and when would the ":ab" mapping be triggered? - vim

The ab family of command (iab and cab) could be a huge time saver. However, it is yet unclear when will it be triggered. For example, with the following settings in _vimrc:
iab sj <c-r>=strftime("20%y-%m-%d %H:%M:%S")<cr>
cab cab drop C:\users\llinfeng\dropbox
For c and i being "mode-indicator", a complete time-tag will be inserted while in Insert mode if one presses <space> (or <ESC>, <C-[>) right after typing sj. For the second mapping, the full directory will be inserted in Command-line mode if one hits \ (or <space>) right after typing drop.
So, it seems that, for iab, the following characters will trigger the expansion of an abbreviation defined through iab-mapping:
<space>
<esc> (or escape in general)
Ideally, one may guess the <tab> key shall also trigger such expansion. However, for my case (set expandtab tabstop=4 shiftwidth=4, i.e. one "tab" key == 4 spaces"), no expansion would have been triggered.
Then, for cab, the following may work to trigger the expansion:
\
<space>
??
What is confusing to me is that: what is the thing "laying at the core" that triggers the expansion of an abbreviation defined through ab-mapping? And, does there exist a complete list of keys that could trigger such expansion, for both Insert mode and Command-line mode?
Thank you!
All the best,
-Linfeng

It's all exhaustively documented in the vimdocs:
http://vimdoc.sourceforge.net/htmldoc/map.html#abbreviations
Specifically:
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.
But it goes on a good few paragraphs detailing precisely what conditions trigger different types of abbreviations. Specifically watch out for the difference between
full-id (foo, g3, -1)
end-id (#i, ..f, $/7)
non-id (def#, 4/7$)
abbreviations

Related

Doing an insert remapping for commenter

I am trying to do a remapping when I'm in insert mode to insert a comment but am having a tough time figuring out what all the keys map to. What I am trying to do is:
:inoremap leadercspace ==> escleadercspacei
Basically, if I'm in insert mode I want to get out of insert mode to insert the comment (leader+c+space) and then go back into insert mode.
What would the correct :inoremap mapping for this be? What I have right now is:
:inoremap <leader>c<space> <Esc><Leader>c<space>i
But this doesn't seem to work (at least the latter half of it -- it does seem to be executing the mapping command). Note: the plugin I'm trying to remap is:
https://github.com/preservim/nerdcommenter
[count]<leader>c<space> |NERDCommenterToggle|
Toggles the comment state of the selected line(s). If the topmost selected line is commented, all selected lines are uncommented and vice versa.
From vim doc (:help nore):
Disallow mapping of {rhs}, to avoid nested and recursive mappings
In other words, the nore part forbids mapping to be applied to the rhs (right hand side).
So in your case, the <Esc><Leader>c<space>i doesn't trigger the VimCommenter mapping for that reason.
To allow recursion, you can take off the nore:
:imap <leader>c<space> <Esc><Leader>c<space>i
My recommendation is that, instead of creating an insert-mode mapping for this purpose, just use the native Ctrl+O mapping to run a single Normal mode command from Insert mode.
Assuming your leader key is set to the default \, you can use:
Ctrl+O, \, c, Space
You'll be left in Insert mode at the end of this sequence.
The advantages of this approach over an insert mode mapping are:
You don't need any extra configuration, since Ctrl+O is a native Vim command.
This works for any Normal mode command, so you don't need to add extra mappings for other commands you might want to be able to access from Insert mode.
Adding a multi-character mapping in Insert mode starting with <Leader> means Vim will always pause and hold if you insert the leader character. In this case, it will also pause when you insert <Leader> and c. I find that avoiding this kind of mappings of otherwise printable characters is usually best.

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>.

Vim "trigger abbreviation" command i_CTRL-] sometimes inserts literal <C-]>

In insert mode, the command CTRL-] expands an abbreviation without entering a space. So if you set :abbrev foo bar, typing foo<C-]> will change foo to bar.
But what happens if you type bar<C-]> when you have not set any abbreviations for bar?
In one version of vim (7.3.754), the CTRL-] is ignored. In other versions that I have access to (7.3.0 and 7.2.411), a literal character ^] is inserted, so you get bar^].
Is this a bug that was fixed? Or is the different treatment because of different compiling options? And is there a way to avoid inserting extraneous ^]s when I must work in these older vims?
As discussed in the comments, the behavior changed in 7.3.489, which fixed a related bug that prevented <C-]> from expanding an abbreviation if the <C-]> was inserted via a mapping.
Funny enough, the reason I came across this was because I was defining a mapping
inoremap <CR> <C-]><CR><C-U>g
The last three characters simply create a new undo point after each <CR> pressed in insert mode. Under normal circumstances, pressing enter will also expand an abbreviation if applicable, but not if <CR> has been remapped. The <C-]> was to forcibly expand abbreviations. It turns out this is the exact mapping that led Yichao Zhou to write the above bugfix.
It isn't a perfect workaround, but by using if has("patch489") when defining the map, you can at least degrade gracefully to older versions of vim. Pressing enter will not expand abbreviations, but at least it won't insert <C-]>.

Clear all currently defined vim macros

I have a vim macro that I keep mistyping, usually when I'm trying to save something so I do it quickly and I can't work out what keys I pressed. It is annoying as it pastes some irrelevant bash code into my file so I have to undo the erroneous pasting which also undos the last thing I typed that I do want.
I was looking for a way to either list the currently defined macros (so I can redefine the offending one), or a way to clear out them completely. I only use macros in the very short term so I don't mind losing them all.
Cheers
Macros
What is mostly called a macro in vim is initiated with # and a letter. It executes the contents of a register with the said letter as its name.
List the register contents
:reg
You can clear the register a with
:let #a = ''
Sometimes mappings or abbreviations are confused for macros, therefore here is some information about them.
List mappings
all mappings
:map
all mappings that start with \
:map \
normal mode
:nmap
insert mode
:imap
visual mode
:vmap
command mode
:cmap
List abbreviations
all abbreviations
:abbr
all abbreviations starting with email
:abbr email
insert mode
:iabbr
command mode
:cabbr
You can use :verbose before the previous commands to get more info about where the mapping/abbreviation was last set, as in :verbose nmap. These commands also show all the mappings that have been set by plugins and other configuration files.
Removing a mapping/abbreviation
(only a couple of modes listed here, you should be able to remove one just for a certain mode just like with the listing commands above.)
insert mode, remove a mapping that is defined as \:
:iunmap \\
normal mode:
:nunmap \\
remove an abbreviation defined as email:
:unabbr email
insert mode:
:iunabbr email
Clear mappings/abbreviations
I wouldn't recommend clearing all mappings/abbreviations since you would lose everything your plugins have mapped/abbreviated. However, you can clear mappings by putting the letter c after the above listing command, as in :imapc to clear insert mode mappings. Abbreviations can be cleared with :abclear, or just for insert mode :iabclear and just for command mode :cabclear.
To clear a single macro - record over it - with nothing.
For your situation in normal mode you'd just type "qwq".
q to begin to record a macro
w to set the buffer space to w
q again to save the (now empty) macro
Verify with :reg[ister] w
This is only slightly quicker than :let #w = '' but for myself is easier to remember.

Resources