I want to map the <space> key to <leader> (which is currently the \ key here) in VIM 7.4.
I would also like to be able to use both the <space> and \ keys as leaders.
If possible, it would be great to see the / character appearing in the bottom right corner when I type it (instead of funky stuff like <20>), but I can live without it.
I've tried to
nmap <space> <bslash>
this works for simple <leader>keys commands, but <leader><leader>key commands (like the easymotion maps) don't work.
I also tried to
let mapleader = " "
nmap <bslash> <space>
but analogously to the problem above stated, the <bslash> key doesn't work anymore for <leader><leader>key commands.
I already tried a bunch of stuff in these related questions/wiki pages:
Can I use SPACE as mapleader in VIM?
http://vim.wikia.com/wiki/Mapping_keys_in_Vim_-Tutorial(Part_2)
:h mapleader
I can't see your .vimrc, so I can't guarantee this is the issue, but I would bet that the issue comes from using nnoremap. The following works for me:
let mapleader =" "
nmap <leader>i iHello World<esc>
nmap <bslash> <space>
I can use either <space>i or <bslash>i and both of them run the iHello World<esc> mapping. But this:
let mapleader =" "
nnoremap <leader>i iHello World<esc>
nnoremap <bslash> <space>
Does not work. <space>i runs the mapping, but <bslash>i does not, which is exactly what should be expected, since nnoremap is used to avoid nested/recursive mappings. So one possible solution would be to use nmap everywhere. I would definitely not recommend this, since you'll likely end up in a map loop. This solution should work better:
let mapleader =" "
nnoremap <leader>i iHello World<esc>
nmap <expr> <bslash> mapleader
Note that if you change the mapleader setting, this will break because, as :h mapleader says:
Note that the value of "mapleader" is used at the moment the mapping is
defined. Changing "mapleader" after that has no effect for already defined
mappings.
I have my .vimrc in a different path, that I source from my main ~/.vimrc (so I can share same settings across Windows, bash on Windows, etc).
I'm trying to write something in the .vimrc in question, that would make a hotkey for editing said .vimrc, without hard coding the path.
What I currently have is this:
let g:vimrc_path = expand('<sfile>')
:map <Leader>v exec(":e " + g:vimrc_path + "<CR>")
But this doesn't seem to do anything. I've verified that g:vimrc_path is the right value, and that the <Leader>v ends up being called by subbing in echo messages, but I'm not wrapping my head around why the variable I'm trying to define doesn't get expanded correctly.
String concatenation is done with ., not with +, which performs coercion into numbers and addition. But :execute takes multiple arguments (which it space-separates), so you don't actually need this here.
You should use :noremap; it makes the mapping immune to remapping and recursion.
Also, I doubt you need visual and operator-pending modes (:help map-modes), so define this just for normal mode.
:exec[ute is an Ex command, so for a normal-mode mapping, you need to first enter command-line mode. So :exec 'edit' instead of exec ':edit'.
Also, this is not a function (though Vim 8 now also has execute()), so the parentheses are superfluous.
The <silent> avoids the printing of the whole command (you'll notice the loading of the vimrc file, anyway); it's optional.
The fnameescape() ensures that pathological path names are also handled; probably not necessary here.
let g:vimrc_path = expand('<sfile>')
nnoremap <silent> <Leader>v :execute 'edit' fnameescape(g:vimrc_path)<CR>
Alternative
As the script path is static, you can move the variable interpolation from runtime (mapping execution) to mapping definition, and get rid of the variable:
execute 'nnoremap <Leader>v :edit' fnameescape(expand('<sfile>')) . '<CR>'
Strings in vimscript are concatenated with ., not with +. For example:
:echo "Hello"." world!"
will echo
Hello world!
If you were to type
:echo "Hello" + " world!"
vim would echo
0
This is because the + operator is only for numbers, so vim attempts to cast these strings to numbers. If you were to run
:echo "3" + "1"
vim would echo "4".
So basically, you just need to change
:map <Leader>v exec(":e " + g:vimrc_path + "<CR>")
to
:map <Leader>v exec(":e ".g:vimrc_path."<CR>")
Another problem you might have not seen is that "<CR>" evaluates to the literal text "<CR>", so it only messes up your function. If you want a literal carriage return, you would need a backslash. However, you definitely do not want to do this! Seriously, try it out and see.
You can see the issue. It looks for a file that has a literal carriage return at the end of the filename! There is a very simple fix though. Remove the "\<cr>" completely. Since :exec runs ex commands by default, the carriage return (and the colon too for that matter) are unnecessary.
Also, as a nitpick,
The parenthesis are not needed for the "exec" function, and
Use nnoremap instead to avoid recursive mappings.
Taking all of this into consideration, I would simplify it to
:nnoremap <Leader>v :exec "e ".g:vimrc_path<cr>
In my vimrc file I have the following entry to surround a word with '+':
:nnoremap <silent> q+ wbi+<ESC>ea+<Esc>
I would like to change this to surround a word with any other symbol, for example a quote, but I would not like to use another plugin or to insert one more map. I would like something like this in my vimrc:
:nnoremap <silent> qX wbiX<ESC>eaX<Esc>
where X would be the character to put around the word.
How can this be done in VIM?
Thanks
The general idea:
:nnoremap q :let c=nr2char(getchar())\|:exec "normal wbi".c."\eea".c."\e"<CR>
But I don't think that q is a good choice, especially for your example with quotes, because q starts the extremely handy recording feature from vim. The normal q command also does expect a second character (the recording target register) and it actually can be ". This will be quite confusing for you when you're on another computer or if someone else is using your vim. You should preprend a leader for q. With a leader:
:nnoremap <leader>q :let c=nr2char(getchar())\|:exec "normal wbi".c."\eea".c."\e"<CR>
The default leader value is \, but this can be changed. Note that it had to be changed before defining the mapping. You can see the currently configured leader with let mapleader (which prints an error message if there's no leader configured). With these statements,
:let mapleader=','
:nnoremap <leader>q :let c=nr2char(getchar())\|:exec "normal wbi".c."\eea".c."\e"<CR>
you can type ,q+ to surround your word with + and ,q" in order to surround your word with ".
By the way: Your mapping doesn't work if your cursor is on the last character on line. Change the mapping to:
:nnoremap <leader>q :let c=nr2char(getchar())\|:exec "normal viwo\ei".c."\eea".c."\e"<CR>
Use Tim Pope's surround.vim plugin!
To surround a word with + signs:
ysiw+
I tried to do this:
nnoremap B ^ " comments over here
nnoremap E $ " comments over here
This surprised me by not working; instead the behavior of B and E became super-wonky. Then I tried getting rid of the whitespaces after these commands:
nnoremap B ^" comments over here
nnoremap E $" comments over here
and that fixed it. What effect were the trailing whitespaces having on these commands?
From :help map-comments:
It is not possible to put a comment after these commands, because the '"'
character is considered to be part of the {lhs} or {rhs}.
So… neither
nnoremap B ^ " comments over here
nor
nnoremap B ^" comments over here
can work as expected: the first one is the equivalent of typing
^<space><space><space><space>"<space>comments<space>over<space>here
and the second one is the equivalent of typing
^"<space><space><space><space>comments<space>ove<space>here
As Roland Smith suggested, put your comment above your mapping. And avoid trailing whitespace.
The arguments to a remap command are;
an optional attribute (<buffer>, <silent>,
<expr>, <script>, <unique> or <special>)
the left hand side
the right hand side
Try invoking :map after defining your original mappings. You'll see that the spaces and comments become part of the mapping. This is probably not what you want.
Waht I would advise is to put the comment on the line before the mapping command;
" Format the current paragraph
nnoremap <leader>f gqap
" Toggle line numbering.
nnoremap <c-n> :set number! number?<cr>
I spend way too much time fumbling around because Vim doesn't handle closing braces like most IDEs do. Here's what I want to happen:
Type this:
if( whatever )
{ <CR>
and get this:
if( whatever )
{
|
}
where <CR> mean hit the ENTER key and | is the position of the cursor. This is what Eclipse does. It's what Visual Studio does. And it's what I want Vim to do.
I've seen a few plugins, tried a few, and none of them seem to give me this behavior. Surely I can't be the first programmer to want this.
In VimL, you can map the { to do exactly as you wish:
inoremap { {<CR>}<Esc>ko
depending on your autoindent setup, you may want to add a <BS> after <CR>.
For a more complete solution, I'd suggest you take a look at Luc Hermitte's vim plugins. They've never failed me so far.
No need for plugin. Much cleaner and flexible solution:
inoremap { {}<Esc>ha
inoremap ( ()<Esc>ha
inoremap [ []<Esc>ha
inoremap " ""<Esc>ha
inoremap ' ''<Esc>ha
inoremap ` ``<Esc>ha
Details about vim and above mapping.
Mapping:- a mapping is a way to define a shortcut for a sequence of keystrokes.
keystroke:- a keystroke refers to a single key press on the keyboard.
About above mappings.
The :inoremap command is used to create a mapping that works in insert mode. Whenever you type { in insert mode, it will be replaced with {}. The <Esc> is used to exit insert mode, and the ha moves the cursor back to the position after the opening curly brace. Like that these all mapping works.
Using AutoClose with the following works correctly.
inoremap {<CR> {<CR>}<C-o>O
This is true for my system at least (Unix terminal on Mac OS X).
A solution for braces, brackets and parenthesis with tab in between.
" Automatically closing braces
inoremap {<CR> {<CR>}<Esc>ko<tab>
inoremap [<CR> [<CR>]<Esc>ko<tab>
inoremap (<CR> (<CR>)<Esc>ko<tab>
Result:
function() {
|
}
Here is what I have in my vimrc:
let s:pairs={
\'<': '>',
\'{': '}',
\'[': ']',
\'(': ')',
\'«': '»',
\'„': '“',
\'“': '”',
\'‘': '’',
\}
call map(copy(s:pairs), 'extend(s:pairs, {v:val : v:key}, "keep")')
function! InsertPair(left, ...)
let rlist=reverse(map(split(a:left, '\zs'), 'get(s:pairs, v:val, v:val)'))
let opts=get(a:000, 0, {})
let start = get(opts, 'start', '')
let lmiddle = get(opts, 'lmiddle', '')
let rmiddle = get(opts, 'rmiddle', '')
let end = get(opts, 'end', '')
let prefix = get(opts, 'prefix', '')
let start.=prefix
let rmiddle.=prefix
let left=start.a:left.lmiddle
let right=rmiddle.join(rlist, '').end
let moves=repeat("\<Left>", len(split(right, '\zs')))
return left.right.moves
endfunction
noremap! <expr> ,f InsertPair('{')
noremap! <expr> ,h InsertPair('[')
noremap! <expr> ,s InsertPair('(')
noremap! <expr> ,u InsertPair('<')
And, for some filetypes:
inoremap {<CR> {<C-o>o}<C-o>O
// I know that InsertPair function is trivial, but it saves time because with it I can define both command and normal mode mappings with one command without having to write lots of <Left>s.
Put the following in your .vimrc file:
inoremap { {}<ESC>ha
Whenever you press { in insert mode, {} is generated and puts your cursor on the right brace, so that you can start typing between them straight away. By putting the curly braces in sequence rather than on different lines, you can put tabs in front of } manually. That way you never have the wrong amount of tabs in front of it.
Perhaps someone can figure out how to count the amount of tabs the cursor is on, and then generate an equal amount of tabs in front of the } on a new line.
inoremap ( ()<ESC>i
inoremap " ""<ESC>i
inoremap ' ''<ESC>i
inoremap { {<Cr>}<Esc>O
For anyone that runs across this like I did, and was looking for something more recently updated than AutoClose: delimitMate I have found to be, not only a preferable solution to AutoClose, behavior wise, but also in active development. According to vim.org, AutoClose has not been updated since 2009.
I have tried different plugins but I found most accurate and most easy to use auto-pairs. It is really intuitive and when you install it you get what you've expected out of the box.
I've always preferred something like what sublime text does where it appends the closing brace as the next character, so I added the following to my .vimrc:
inoremap ( ()<ESC>hli
which moves the cursor to between the two braces.
As you'll see in the wikia tip: there are many solutions to this recurrent question (I even have mine).
That is if you limit yourself to bracket pairs. Here you are in the context of a control statement. You're thus more likely to find snippet systems that will not expect you to type the ") {" when typing an "if" statement. Vim shortcut tend to be shorter from what I read in your question. Here again there are a lot of choices, you'll find most likely snipmate, and may be my C&C++ suite.
Insert this into your ~/.vimrc if you have auto-indent enabled:
inoremap {<CR> {<CR>}<Esc>ko
inoremap [<CR> [<CR>]<Esc>ko
inoremap (<CR> (<CR>)<Esc>ko
and if not
inoremap {<CR> {<CR>}<Esc>ko<tab>
inoremap [<CR> [<CR>]<Esc>ko<tab>
inoremap (<CR> (<CR>)<Esc>ko<tab>
Then you can map a key (in my case the key is ä, this can be replaced with anything you want)...
map ä A<space>{<CR>
...to automatically do all of this for you, if you are anywhere in the line on key press.
example ('|' symbolizes where your cursor is):
int main(int a|rgc)
When you press the key now (in my case ä in command mode), the result will be this:
int main(int argc) {
|
}
delimitMate has a setting for this.
Vim patch 7.4.849 added a binding to allow for cursor movements without restarting the undo sequence. Once updated to >= 7.4.849 then something like this works great.
inoremap ( ()<C-G>U<Left>
Note that I grabbed that straight from the documentation included in the patch. Best simple solution for this feature yet.
commit for patch 7.4.849:
https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
mailing list thread: http://vim.1045645.n5.nabble.com/Any-automatic-bracket-insertion-plugins-not-breaking-undo-td5723654.html
Install and use Vim script AutoClose as recommended in the article titled Automatically append closing characters.
Just a note to #Bob.
Karl Guertin's AutoClose has a function named ``double brace'', that is, you can type curly brace twice, as below.
int func_name(void) {{ ==> Type `{' twice here.
would result in:
int func_name(void) {
| ==> Cursor here.
}
Then, you can type a single Tab, to get indented according to your `shiftwidth' setting, then type.
If you type {} and hit alti you will be in between the braces in INSERT mode (at least in a terminal). Then you can hit ENTER followed by altshifto to insert the line break. You could also just do {<CR>} and altshifto.
This may not be fully automatic, but I consider it semi-auto. It removes the need for more plugins, and is useful info to know for other use cases. For example, I use altshifto all the time to insert blank lines without having to explicitly leave INSERT mode, and alti for getting inside () etc.
You do not need a special plugin to do this - but it is a two-step process.
First, add the following to your .vimrc to eat the triggering character:
" eat characters after abbreviation
function! Eatchar(pat)
let c = nr2char(getchar(0))
return (c =~ a:pat) ? '' : c
endfunction
and then add this abbreviation to your .vimrc:
inoreabbr <silent> { {
\<cr><space><space>
\<cr><esc>0i}<esc>k$i<c-r>=Eatchar('\m\s\<bar>\r')<cr>
The \ at the start of lines two and three is just a line continuation character. You could have done this all on one line, however and i added it so that i could spread the abbreviation out in a way that mirrors the output you're looking for -- just so things are a little more intuitive.
My solution:
inoremap <expr> <CR> InsertMapForEnter()
function! InsertMapForEnter()
if pumvisible()
return "\<C-y>"
elseif strcharpart(getline('.'),getpos('.')[2]-1,1) == '}'
return "\<CR>\<Esc>O"
elseif strcharpart(getline('.'),getpos('.')[2]-1,2) == '</'
return "\<CR>\<Esc>O"
else
return "\<CR>"
endif
endfunction
Explaination:
The code above first check if you are using Enter to do confirm a code completion, if not it will indent the {|} when you type Enter. Also, it provides html tags auto indent.
Examples:
if( whatever ){|}
press Enter and you will get
if( whatever )
{
|
}
This also works for html file. See the following example
<html>|<html>
press Enter and you will get
<html>
|
</html>
This works great!
Put this in your .vimrc.
inoremap { {^M}<C-o>dd<C-o>k<C-o>]p<C-o>O
This matches the indenting level to the indenting level of the first {.