Unable to successfully use custom mapped vim commands from vimrc (mac) - vim

I am trying to add a command to my .vimrc and use it.
I have recorded a macro (in the register h) that prints the following (ending with a newline):
one
two
three
I can see this in the register h by typing :reg. It looks like:
"h ione^Mtwo^Mthree^M^[
I've pasted this as well as an alternate version in my .vimrc under test and test2 respectively:
map <Leader>test ione^Mtwo^Mthree^M^[
map <Leader>test2 ione<C-R>two<C-R>three<C-R><ESC>
My understanding is that test uses characters that can't be displayed such as ^M and ^[, so I've created test2 with what I've read is the .vimrc equivalent.
After restarting vim (which I assume means starting another vim session after this .vimrc has been written to), I test these out.
In normal mode (after hitting ESC multiple times), I try both of the following:
:test
:test2
In both cases, I'm given the error for each respectively:
E492: Not an editor command: test
E492: Not an editor command: test2
After no avail, I check to see if what I've mapped has been mapped.
In normal mode, I type :map and do indeed see what I've added, but they appear with a backslash:
\test2 ione<C-R>two<C-R>three<C-R><Esc>
\test ione^Mtwo^Mthree^M^[
Finally, in normal mode, I try again, this time with a backslash. I try both of the following:
:\test
:\test2
This time, I receive the following error for both commands:
E10: \ should be followed by /, ? or &
I am on a mac and have tried using both Terminal (which comes with OSX) as well as iTerm2.
Could someone please lend me some guidance?

your mappings are executed if you press your leader key followed by the keys test or test2. You did not create commands (:).
If you want them as command, then you don't need a mapping, but something along the lines of this in your .vimrc:
function! Test()
execute "normal ione"
execute "normal otwo"
execute "normal othree"
execute "normal o"
endfunc
command -nargs=0 Test call Test()
Which you can then use as :Test.
However, if you want to make a mapping and not a command, you might want:
a shorter mapping to type (this is very subjective),
to use nnoremap instead of map (To be usable in normal mode only, and to not recursively execute mappings),
your test2 is what you need (that I change here into <leader>t)
<C-R> is Control R, you want <CR> for the return key.
Here's an example:
nnoremap <Leader>t ione<CR>two<CR>three<CR><ESC>

Related

vim-go: Can't get autocompletion

I'm trying to use vim-go, but I can't get autocompletion to work.
My go environment works well, I succesfully ran :GoInstallBinaries, and I can use any :GoXXX command without errors. But I can't get autocompletion to work.
When I hit <Ctrl-o> after a dot, vim just switches in the status bar between -- INSERTION -- and -- (insertion) -- modes (what's the difference btw ?) and moves my cursor one character to the left.
When I hit <Ctrl-x>, It just shows -- mode ^X (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y) in the status bar.
Sometimes (rarely) after spamming <Ctrl-o> it shows the vim-go autocompletion tooltip ...
vim-go is the only plugin installed, using pathogen.
Omni completion (which the Go plugin offers) is triggered via <C-x><C-o>, that is Ctrl + X followed by Ctrl-O. The prompt (-- mode ^X (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)) you've described hints at that.
If that is too cumbersome for you, you can define an insert mode mapping to shorten that; here's a (global) example to be put into your ~/.vimrc:
:inoremap <C-b> <C-x><C-o>
If you use GVIM, you can also use the IDE-like <C-Space> instead of the example <C-g> trigger.

Vim: Issue normal-mode commands in user-defined command

I'm certain this will have been asked somewhere, but I can't for the life of me find it, and it's not in the Defining command-line commands section of the Vim documentation.
I want to create a user-defined command which will insert the word foo before the current word.
(Note: I want it to be a function because I don't trust myself to remember yet another shortcut key. I know how to do it with noremap...)
In my .vimrc I add:
command AddFoo bifoo<esc>w
But when I type :AddFoo I get Not an editor command: bifoow.
Is it possible to have a function which issues normal mode commands?
The :normal Ex command allows to issue arbitrary normal mode commands.
command AddFoo normal! bifoo<esc>w
If you want to interpolate expressions etc., you need to use :execute; I'll just show your example again with the use of :help key-notation:
command AddFoo execute "normal! bifoo\<esc>w"
The ! after :normal prevents the use of custom mappings, like :noremap (vs :map).
Please make sure you get the difference between a command and a function.
The right hand side of a command definition is supposed to be at least one Ex command like write or bnext:
command! Foo update | tabnext
You can call a function:
command! Bar call Bar()
or execute a normal mode macro:
command! Baz normal ciw"<C-r>""
See :help :normal.
Should be simple to get what you want, you just need to switch to normal mode to make your changes:
command AddFoo normal bifoo<esc>w

How can I map Ctrl + semicolon to add a semicolon to the end of the line?

I'm trying to map pressing [ctrl] + [semicolon] in insert mode to move to the end of the line and add a semicolon. It's something I find myself doing a lot after installing the surround plugin.
I tried running this command
inoremap <c-;> <esc>A;<esc>
but when I try it, it exits me out of insert mode, and goes into command mode. Trying with another modifier d yields the same result too.
Can semicolon not be mapped with a modifier?
What am I doing wrong?
I didn't read your question carefully, just saw your mapping took you out of the insert mode and the last <esc>... my fault.
You want to map ctrl+; vim cannot capture the keycode. there are some key combination cannot be mapped in vim. ; is one of them, another example like ctrl+=.
so you may want to choose another mapping.
btw, you can try in insert mode press ctrl-v then the keycombination to see if it could be used.
Depending on your terminal it is possible to set up mappings. For example if you use urxvt, in ~/.Xresources add:
URxvt.keysym.C-semicolon: \033[;
And in ~/.vimrc add:
map <Esc>[; <C-Semicolon>
map! <Esc>[; <C-Semicolon>
Then you should be able to map it like this (not tested):
inoremap <c-Semicolon> <Esc>A;<Esc>
I use this to map split window movement like this (this works for me):
noremap <C-Semicolon> <C-w>l

vim: execute the rest of the line after the cursor as a vim command

I sometimes find myself writing text where part of the file is generated by an external program. Consider for example a C source file containing
/*
* To regenerate the following data, place the cursor at the beginning
* of the next line after this comment, then run
* ma:r!find /foo -name '*.in' | xargs whatever | some complicated processing
* and merge the result with
* 'a!}sort -u
*/
some
generated
stuff
here
I end up using the mouse to select the first command (ma:...), paste & run it, wait for the command to finish, the select 'a!}sort -u and paste & run it. That's inelegant because it's only semiautomatic when I think it could be fully automatic. I read the vim online help for :execute and friends but it looks like that's not doing what I want. I'm thinking more along filling a vim register with the proper command(s), then execute the register contents. The online :help registers did not give a clue so far.
Ideally, the new comment would say something like
/*
* To regenerate the following data, place the cursor on the 'j' on the
* next line in this comment, then execute it with <SHORT-MAGIC-VIM-INCANTATION>
* jjma:r!find /foo -name '*.in' | xargs whatever | ...<CR>'a!}sort -u<CR>
*/
How can this be achieved?
I would make it handle Ex commands, not normal mode commands (like ma in your example); it is easy to execute the latter via :normal ma, but feeding Ex commands into normal mode has escaping problems (like, how do you encode the Enter that has to conclude the Ex command?)
Here's a custom command:
command! -bar -range ExecuteFromCursor execute 'normal! "zy$' | #z
And here's a mapping:
nnoremap <Leader>e "zy$:#z<CR>
Edit Ingo's method of executing the register is easier than mine (#" instead of <^R>").
The advantage with my approach would be that you have a chance to interactively edit the command line just like any other, before pressing Enter to execute.
I'd do
y$:<^R>"
y$ yank to end of line
: start command mode
C-r" insert yanked text
Press Enter, profit.
I used to have something similar mapped. But I got lazy and often just do Y and edit the command line. On windows, I find Shift-Insert on the vim command line a bit smoother, so I'd then use "+Y to copy to the windows clipboard. But I digress

my vim jump to next word is quite slow, what am I doing wrong?

In my .vimrc file, I have the following mappings:
nnoremap \ *
nnoremap \| #
for the jump-to-next-word and jump-to-last-word commands.
For some reason my jump-to-next-word command is slow, on the order of 1 second before it seems like the command is executed, while the jump-to-last-word shortcut is fine (no noticeable delay). I've tried mapping different keys to the command, and it is only in some cases that there is this delay.
Does anyone know the cause of this behavior?
Because vim is waiting for more key after you typing \
You can change the waiting time(default 1 second) by:
:set timeout timeoutlen=100 ttimeoutlen=100
(time out on mapping after 0.1 second, time out on key codes after 0.1 second).
I had a similar issue, but not related to the mapleader. It turned out that there were some other commands that used my "jump to next word" key as a prefix (in my case that was y). Here is what I did:
Issue :nmap command to pull the list of all the mappings.
Mark the ones that start with your "jump to next word" key. In my case these were yo and yO.
Unmap this commands in your .vimrc. In my case these were unmap yo and unmap yO.
Reload your .vimrc with :so $MYVIMRC for changes to take effect.
If you intended to map backslash with first command I would suggest to put something like
let mapleader='_'
let maplocalleader='_'
into your vimrc (replace underscore with any sequence of symbols you are comfortable with) because many plugins create mappings whose {lhs} starts with <Leader> and thus vim is awaiting for next key in order to determine whether it was some of the plugin mappings as #kev correctly pointed out. If you put the above lines into the vimrc those plugins that use *map <Leader>... will now create mappings that start with underscore instead of starting them with backslash. If this does not help, check out verbose map \ and read documentation of the plugins in order to determine whether there is an official way to make them generate mapping with another leader.

Resources