EasyMotion get text in commandline - vim

I would like to add an EasyMotion mapping, such that * maps to <CR> if there is already one character, but * is itself when zero. For example, something like this:
EMCommandLineNoreMap * <CR> <-- if one character entered
EMCommandLineNoreMap * * <-- if zero characters entered
I know I can use an <expr> for this, but I'm not sure how to check to see the output of the current command, for example:
I'm hoping to be able to do something like this, but not sure how/if it's possible:
EMCommandLineNoreMap <expr> * (egetcmdline() != '') ? '<CR>' : '*'
How could that be done?

Related

What do all the markings in vim `:imap` outputs mean?

e.g. if I type :im it outputs a long list of messages of the insert mode mappings.
i <Plug>(fzf-maps-i) * <C-O>:call fzf#vim#maps('i', 0)<CR>
The i is for insert mode.
:help <Plug> says that you use it for "internal mappings which is not to be matched with any key sequence". What is this good for? If you manage to press an unpressable key combination it will open the :Maps terminal buffer? Aside from this specific situation, why would you want to bind an unpressable binding?
Next, we have the *. What does it refer to? :helpgrep star or :helpgrep * fail me.
Next we have this line:
i <Plug>(fzf-complete-file-ag) * fzf#vim#complete#path('ag -l -g ""')
Why does the first line above use * and then still use <C-O>:call ... <CR> while this one just mentions the function name?
<Plug> [...] What is this good for? If you manage to press an unpressable key combination it will open the :Maps terminal buffer?
It is an unpressable key combination. It doesn't mean it cannot be generated. If you look at the docs of fzf.vim, you will see an example of a related mapping that user can insert into their .vimrc:
nmap <leader><tab> <plug>(fzf-maps-n)
If the user then presses LeaderTab, it will generate <plug>(fzf-maps-n). This mapping is not noremap, so it will trigger the map <plug>(fzf-maps-n) mapping defined by the plugin. This way the plugin exposes a mappable key sequence, but without any side-effects for the users where they might accidentally trigger it; though they can still map to it if they wish to.
Next, we have the *
:help map-listing will tell you * means it is not remappable (i.e. created by inoremap instead of imap).
Why does the first line above use * and then still use <C-O>:call ... <CR> while this one just mentions the function name?
It is not visible from the listing, but the command that created it was:
inoremap <expr> <plug>(fzf-complete-file-ag) fzf#vim#complete#path('ag -l -g ""')
Note the <expr> modifier. :help :map-<expr>

In vim remapping, how do I "capture" and reuse "any" character?

In my .vimrc, I have the following which, in insert mode, nicely adds a semi-colon to the end of the line and returns the cursor to its original spot:
inoremap <leader><leader>; <C-o>mp<C-o>A;<C-o>`p
How can I do the same but for ANY/ALL characters? For example, something like this pseudocode:
inoremap <leader><leader><any> <C-o>mp<C-o>A<any><C-o>`p
Or using regex, something like this pseudocode...
inoremap <leader><leader>(\w) <C-o>mp<C-o>A$1<C-o>`p
Is it even possible to capture and reuse like that?
I think this does what you want:
inoremap <expr> <leader><leader> "<C-o>mp<C-o>A" . (nr2char(getchar())) . "<C-o>`p"
To break it down, there is a command for inoremap called <expr>. This command changes inoremap to look like this: inoremap <expr> {keys} {function} When you press the keys defined in the {keys} section, it will call a function in the {function} section and insert the return value of that function. Anything in quotes in the {function} section will be inserted. So, here is the breakdown of the function section:
"<C-o>mp<C-o>A" . (nr2char(getchar())) . "<C-o>`p"
^ | ^
|-------------------|-----------------|
These just do |
what the original |
mapping does |
This just gets a single character
from the user and concatenates it to your
original mapping, in place of the ';'
Read these for more information on these topics:
:help :map-<expr>
:help getchar()
:help nr2char()
Note: getchar doesn't actually take from the mapping itself, it just prompts the user for a character, then inserts it.

In vimscript using current word as parameter in if statement

I would like to do something like this
if exists(expand('<cword>'))
inoremap ( (<esc>g_i)<left>
else
inoremap ( ()<left>
endif
The logic behind this is that if there is something under my curser, surround that with the parenthesis, otherwise just create a closed parenthesis.
The if does not currently recognize the element under the cursor.
Is there a solution?
To have a mapping react to the current conditions when it is invoked, you cannot redefine the mapping itself. Instead you have to make the right-hand side of the mapping react to the conditions. This is done easiest with a :help :map-expr, like this:
:inoremap <expr> ( (empty(expand('<cword>')) ? '()<Left>' : '(<Esc>g_i)<Left>')
Note that I just translated your example, I didn't check that it makes sense or works as expected.

How to remap number keys and number key special characters in VIM

I am trying to remap the * operator in VIM. I have tried nnoremap <*> and nnoremap <S-8> to no avail. I haven't been able to find any instructions on how to properly do this. How can I remap my *, or any number keys/number key special characters?
Since many of you will no doubt wonder why anyone would want to do this, it's so I can make my * operator behave like normal, except not advance automatically to the next occurrence of the word under cursor (see under section Highlight Matches Without Moving).
EDIT:
The complete command I'm working with is this:
nnoremap <*> :let #/='\<<C-R>=expand("<cword>")<CR>\>'<CR>:set hls<CR>
Where * remaps the functionality of * or <shift + 8>
Getting rid of the < and > works for me.
nnoremap * :let #/='\<<C-R>=expand("<cword>")<CR>\>'<CR>:set hls<CR>
Try nnoremap <F7> <*>. It will remap the * with F7

Automatically insert a matching brace in Vim

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

Resources