Combine two vim commands into one - vim

I'm having trouble combining two vim commands, specifically <C-w>s and <leader>x into <leader>r (i.e. split window and open spec counterpart of current file). Any help?
Thanks!

It would help if you'd post what exactly you've tried that didn't work. Generally, doing what you describe should be simple. It should be enough to put this in your .vimrc file:
nmap <leader>r <c-w>s<leader>x
This maps <leader>r to expand to the key sequence <c-w>s<leader>x. Note that these are not "commands", as you call them in your question, they're "mappings". A "command" is something completely different in vim, you can read up on that with :help user-commands.
One thing to be careful of is using nmap instead of nnoremap. The command nmap maps the sequence on the left to the sequence on the right while re-using mappings that have already been defined. On the other hand, nnoremap creates a mapping with the original meanings of the keys, so in your case won't work (since <leader>x is defined by some plugin). This is one possible reason you may have failed while trying to do it, but I can't tell from your question.

Related

Vim simple mapping

I started using Vim recently, just installed NERDTree (a plugin to navigate files).
The command to access that plugin is :NERDTree so I though it's a good idea to start learning mappings by assigning one to that command.
So I added to my .vimrc file the following line: map :nt :NERDTree - but when I type :nt in a vim file (even after restarting) I receive the following error message: not an editor command: nt
I also tried to add the mapping directly while editing a file by typing :map :nt :NERDTree but it returned the same error when I tried to use the command.
I checked that answer:What is the difference between the remap, noremap, nnoremap and vnoremap mapping commands in vim?, so it seems to me that :map (opposed to noremap etc.) is the good command for that.
The plugin works fine when typing the original command.
What am I doing wrong? (sorry for the noob question)
:NERDTree is a command, not a mapping, so there's no reason for creating a recursive mapping, here.
:map is too overreaching. You should use :<mode>map (for recursive mappings) or :<mode>noremap (for nn-recursive mappings).
You are missing a <CR> at the end of your mapping to tell Vim to actually execute the :NERDTree command.
In this specific case, the right mapping would be:
nnoremap :tn :NERDTree<CR>
But mapping something to :<anything> is not a good idea because it will introduce a timeout whenever you try to execute an Ex command. This means that you need to find another combo. Why not <Space>n?
nnoremap <Space>n :NERDTree<CR>
With the mapping that you have, it will be require multiple keystroke. Will it be okay for you to use a single key like F2?
nnoremap <F2> :NERDTreeToggle<CR>
This will toggle open/close NERDTree upon pressing F2 and save you some key stroke.
Here
you can figure out, how vim's mapping work and look like ;). Don't forget to source your new .vimrc before using.

Highlighting arbitrary lines in VIM

During the implementation process of a program I generally insert many append code lines, mainly with print command, to help me understand and debug the implemented program. Unfortunately, it is common to me to forget which lines are from the code and with were appended and should be deleted some time after. This problem gets worst with large programs.
Well, I found this article that teaches how to keep one arbitrary user selected line highlighted (see section: Highlighting that stays after cursor moves). The solution given by the article is to include in .vimrc the following code:
:nnoremap <silent> <Leader>l ml:execute 'match Search /\%'.line('.').'l/'<CR>
So, every time when I press \l the current line is highlighted and kept so, and the previous highlighted line, if there are one, is unhighlighted.
This isn't the behavior that I would like. Instead, I would like to be able to highlight as many arbitrary lines as I want without unhighlighting the previous highlighted lines. And if it is possible, with a unique command like \l.
Someone knows a solution for this?
Thanks in advance.
EDITED:
The command proposed by yolenoyer solved the initial problem. But, now other problem raised. The following command:
:call clearmatches()
proposed to clean the highlighted lines cleans all lines and I would like to be able to clean specific highlighted lines, instead off all of them at once. Is it possible?
I program in C quite alot, and when debugging tend to pepper the code with debug prints.
I use the vim command
:syntax match Error /\<debug_printf\>/
to ensure the word 'debug_printf' is highlighted in the default 'Error' colors for the particular colorscheme.
This doesn't help you bookmarking a series of lines, but for that you should check out the 'bookmark' plugin which allows you to create and remove bookmarks throughout the file.
VIM Bookmarks Plugin
:match accepts only one match.
Use the matchadd({highlight-group}, {pattern}) function instead, for example:
nnoremap <silent> <leader>l :call matchadd('Search', '\%'.line('.').'l')<cr>
To clear the matches you added, run :call clearmatches().
I used the answers here to come up with this combo, which I think is nice:
" \l to highlight a line
nnoremap <silent> <leader>l :call matchadd('Search', '\%'.line('.').'l')<CR>
" \L to remove highlighted line
nnoremap <silent> <leader>L :
\for m in filter(getmatches(), { i, v -> has_key(l:v, 'pattern') && l:v.pattern is? '\%'.line('.').'l'} )
\<BAR> :call matchdelete(m.id)
\<BAR> :endfor<CR>
I think your first paragraph, which explains your problem, has nothing to do with vim, so maybe you don't need to use vim to solve your problem.
What about not debugging with regular print statements, but with a function that wraps print? That would be really easy to search for program wide and also file wide (just search with * or # for all occurrences of your debug printing function).

What does <unique> mean in vim?

In my previous question I tried to "rewrite" default mapping of Netrw's NetrwRefresh command. The default mapping was <c-l> and I wanted to free it for different purpose. Suggested solution was the following:
nmap <unique> <c-r> <Plug>NetrwRefresh
" from now on I can use <c-l> for whatever I want
Everything is fine, but when I try to change <c-r> to <leader>xx every time I get this error:
Whatever I place after <leader> the error always occur. I tried to remove <unique> and I get the result. So the question is: what the <unique> is intended for?
As always, Vim's :help command should point you in the right direction. From :help unique, is documented:
If the first argument to one of these commands is "" and it is used to define a new mapping or abbreviation, the command will fail if the mapping or abbreviation already exists
So Vim is telling you that a mapping already exists for <leader>xx and refuses to overwrite it. To determine what is already using <leader>xx in your setup, you may view all mappings:
:map
It seems unusual and somewhat unlikely that anything you try following <leader> is already in use, so examining the output from :map should reveal some available combinations.

How to debug vim mapping overlaps?

In general how to debug and solve key bindings overlapping?
I had this problem..
Recently I add vim-latex plugin to my vim dir.
After that I noticed that my ctrl-j bind is overlapped by vim-latex/plugin/imaps.vim and lost a lot of time until solved that.
By the way: there is a bug in imaps.vim i think, because there is written " map only if there is no mapping already" and my example shows opposite.
You can get fine-grained info from the :map command:
To show only mappings relevant to a particular key (in this case ctrl-J):
:map <c-j>
or, better, to show mappings for particular key as well as the script where the mapping was set:
:verbose map <c-j>
It is the addition to other people’s answers, not the answer itself.
By the way: there is a bug in imaps.vim i think, because there is written " map only if there is no mapping already" and my example shows opposite.
You are mistaking what «mapping» here means. If you take a look at the code of imaps.vim you’ll see that it won’t create a mapping if there is a mapping to <Plug>IMAP_JumpForward ({rhs}), not if there is a <C-j> mapping ({lhs}). Thus you should use
nnoremap <SID>I_won’t_ever_type_this <Plug>IMAP_JumpForward
in order to disable <C-j> remapping if you don’t need it (of course you could replace <SID>... part with something more meaningful if you do want to use this functionality).
:map
Shows a list of your current maps.

How to call vim function from within map and ":split"

I would like to map a key using "map" from within my vimrc file like this:
map <C-I> :split ~/some/file
That command actually works fine.
My question is: how do I call a vim function (in this case, "resolve()") on that file path from within the map/split line. This doesn't work, but hopefully you get the point:
map <C-I> :split =resolve("~/some/file")
Perhaps it uses call()? I'm obviously confused about vim scripting in general. Thanks for your help!
There are two additional ways of doing this which will work outside of a mapping and are safer then using <C-r> (POSIX allows filenames with any byte but \x00, including control codes):
nnoremap <C-i> :execute "split" fnameescape(resolve("~/some/file"))<CR>
nnoremap <C-i> :split `=resolve("~/some/file")`<CR>
In second case no escaping is needed, but filename must not contain newline (it won't hurt, just will produce an error).
Another things to consider:
Use nnoremap, it will enable you to, for example, exchange meanings of ; and : without changing maps and also prevent your map from being spoiled by plugins unless they redefine <Tab> mapping (<C-i> is same as <Tab>). Forced normal mode is here because in other modes it will produce unexpected results.
Escape arguments: fnameescape(resolve("~/some/file")), it will prevent errors for filenames with spaces.
You can write <C-r> where #Austin Taylor suggested to write raw control code. I don't like having any of them inside a file because it will make diffs not viewable in a terminal.
map <C-I> :split ^R=resolve("~/some/file")<cr><cr>
If you are putting this in .vimrc, you type C-v C-r to type the ^R character.

Resources