How to set a hotkey to write some code - vim

I want to write the following code when I press mapleader+r. Having read a bunch of tutorials I'm still a wee bit confused how I'd achieve this.
file_put_contents(ini_get('error_log'), '');
error_log(print_r(, true));
I've already mapped my mapleader to space bar.

Two options:
Either you define an abbreviation (:h iab) or an insert mode mapping (:h imap)
or you install one of the snippet plugins (which are abbreviations on steroids)
I recommend the later approach.

you can just map:
nnoremap <leader>r ifile_put_......;<cr>error_log....;<esc>
Or create a defined macro.
I don't suggest imap (insert mapping). Imagine that, you have space as leader, when you type <space>r in INSERT mode, those codes will fill... how annoying is it! E.g. you type I really like read the book. It will insert twice!
However for those code snippets, you may want to create a snippet. There are many plugins, which supports code snippets.

Let me assume that you've set your leader key, then all you need is to put the following line into your .vimrc file so that you can insert it in Insert mode by <leader>r.
inoremap <leader>r file_put_contents(ini_get('error_log'), '');<cr>error_log(print_r(, true));<cr>
or
if you want to insert the code you want in Normal mode, you just need to change above line as following:
nnoremap <leader>r ifile_put_contents(ini_get('error_log'), '');<cr>error_log(print_r(, true));<esc>
Then you can insert the code by <leader>r.

Related

Vim function to find pattern, replace, and visual mode

So I use Vim to write reports at work, reports are basically a bunch of "common issues" that we write over and over, so they are templated. These templates have placeholder blocks {==BLOCK==} to ensure people modify things as/when needed, so this is an example:
The test revealed that it was possible to access {==sensitive data==},
as shown in the examples below...
That block may need to be modified, or not. So the idea is, I am editing the common issue, and I see there are 3 or 4 blocks like the one in the example, I'd like to press let's say [leader]b and then end up having the template text for the first block selected in visual mode without the {== and ==} that are around it.
I have tried a few things but I didn't get too far, any suggestions?
Thanks!
You could define the following function:
function! VisualSelect()
call search("==}")
norm hvT=
endfunction
nnoremap <leader>b :call VisualSelect()<cr>
vnoremap <leader>b Ol<esc>:call VisualSelect()<cr>
This will visually select the contents between {== and ==}. Typing <leader>b repeatedly will select the next occurrence.
Most template/snippet expand plugins support this.
With my lh-brackets plugin, you can execute
:SetMarkers {== ==}
and then jump from one placeholder to the next with CTRL+J with vim, or META-DEL with gvim. lh-brackets doesn't take care of loading/expanding templates. mu-template will add this layer.
If instead you choose to use one of the more popular snippet plugin, there will certainly be an option to change the syntax of the placeholders, but I don't know it.
The poor man's solution would look like:
nnoremap <c-j> <c-\><c-n>/{==.*==}<cr>v/==}/e<cr><c-g>
snoremap <c-j> <c-\><c-n>/{==.*==}<cr>v/==}/e<cr><c-g>
but it won't take care of restoring the search pattern, of the cases where the cursor is already within a placeholder, and so on...
EDIT: the version that automatically deletes the placeholder marks is
nnoremap <c-j> <c-\><c-n>/{==.*==}<cr>v/==}/e<cr>s<c-r>=matchstr(#", '{==\zs.*\ze==}')<cr><esc>gv6h<c-g>
the same in snoremap
In short:
nnoremap <leader>b /{==.*==}<cr>xxxvt=<esc>/==}<cr>xxxgv
What it does:
1.) find the pattern
/{==.*==}<cr>
2.) Remove the first "{=="
xxx
3.) Visual select your text until the first = (maybe this could be also optimized for using a regex instead of simple searching for the next =)
vt=
4.) Go to the end sequence
/==}<cr>
5.) Remove it
xxx
6.) Select again your last selection
gv
I have figured out a way based on what #snap said, I ended up adding the code to a Python plugin to run it through it, as that fits better with what I am trying to do, snippet below:
#neovim.command('VimisEditTemplateBlock')
def urlify(self):
"""Search next codify block and prepare for editing"""
[...]
self.nvim.command('call search("{==")') # Find beginning of codify block
self.nvim.command('norm xxx') # Delete {==
self.nvim.command('norm vf=') # Select the inner text
self.nvim.command('norm v')
self.nvim.command('norm xxxgvh') #Delete ==} and leave the inner text selected in Visual Mode

Show comments for specific mappings in .vimrc

I know that I can use :nmap, :vmap, :imap commands to display all the mapping for those 3 modes. However, I would like to display comments that I have for a single mapping.
So suppose I have the following entry in my vimrc:
" Execute current line in bash
nmap <F9> :exec '!'.getline('.')<CR>
This could also look like this:
nmap <F9> :exec '!'.getline('.')<CR> " Execute current line in bash
I would like to have a command that for this mapping that would look something like this:
<F9> Execute current line in bash
As this probably can only be done using custom function, where do I start? How do I parse .vimrc to strip only key mappings and their corresponding comments (I have only done some very basic Vim scripts)?
Do I understand correctly from :help map-comments that I should avoid inline comments in .vimrc?
It's very hard to "embed" comments into a mapping without affecting its functionality. And this would only help with our own mappings, not the ones from plugins.
Rather, I'd suggest to learn from (well-written) plugins, which provide :help targets for their (default) key mappings. So, to document your mapping(s), create a help file ~/.vim/doc/mymappings.txt with:
*<F9>*
<F9> Execute current line in bash
After :helptags ~/.vim/doc, you will be able to look up the comments via :h <F9>. By using the help file, you can use syntax highlighting, longer multi-line comments, and even examples, so I think that'a better and more straightforward solution.
Personally, I wouldn't have much use for such a feature for two reasons: the first one, is that I always have a vim session with a note taking buffer that contains all the tips/commands not yet in my muscle memory. Secondly, you can list all the maps using :map, and it's always a great exercise for your brain in learning vim to literally read vim commands.
That being said…
As this probably can only be done using custom function, where do I start?
…well I guess you could imagine using a function with a prototype such as:
AddMap(op, key, cmd, comment)
used like:
call AddMap("nmap", "<F9>", ":exec '!'.getline('.')<CR>", "Execute current line in shell")
which implementation would add key and comment to an array, so that you could list the array to get your own mappings declared. Using a function like ListMap().
let map_list = []
function! AddMap(op, key, cmd, comment)
" add to map list
insert(map_list, [op, key, comment])
" execute map assign
exec op.' '.key.' '.cmd
endfunction
function! ListMap()
for it in map_list
echo it[0] . '\t' . it[1] . '\t' . it[2]
endfor
endfunction
Of course, one could elaborate on the ListMap() function implementation to generate a more "proper" help file that you could open in a buffer. But that's an idea of how you could do an implementation for a feature close to what you're looking for.
N.B.: this snippet is mostly an idea of how I'd tackle this problem, and it's a one shot write that I did not actually try.
How do I parse .vimrc to strip only key mappings and their corresponding comments (I have only done some very basic Vim scripts)?
I don't think that would be a good solution, I think the better way to achieve your goal is my suggestion. Simpler and more explicit, though it won't show off all mappings. But you don't have all your mappings in your .vimrc.
Do I understand correctly from :help map-comments that I should avoid inline comments in .vimrc?
To be more precise you shall not use inline comments after maps, because they will be interpreted part of the mapping.
how to get mapping created by plugins?
Besides, using :map, you just don't. You look at the sources/documenation of your plugins and find out about them. There's no such thing as a reverse lookup from runtime to declaration point.

VIM keybinding to jump back to initial position after indenting the whole file

I have created a keybinding that should indent a whole file.
My first solution looked like this:
map <F4> gg=G
The problem is that after pressing F4, the cursor jumped to the first line of the file. So I have tried to improve my solution with the feature of markers, look like this:
map <F4> mzgg=G'z<CR>
I expected this would have resolved my problem, but the command do the same as the first. When I try to jump to the z marker manually vim told me "marker not set".
After changing the keybinding, I have or course restarted vim! I am using the GVIM 7.3 on a WIN 7 machine.
Thank you in advance for your Help!
Edit:
After trying to get my keybinding working by tipping it directly to vim commandline. I find out that the keybinding was working quite nice. I think problem is that I create a session some times ago (with mksession) and if you load a session I think vim ignores the vimrc-file. Is this assumption right?
Solution:
In these thread I find a soultion to make mksession save less options.
Another lightweight approach: set the ` mark, format the buffer and jump back to the mark afterwards.
:nnoremap <key> m`gg=G``
I would recommend the use of CTRLo and CTRLi which allow to go respectively backward and forward in the jump list. See :help jumps.
The following mapping
map <F4> gg=G2<C-o>
works. (It jumps back two times in the jump list)
But generally, the jump list is a great way to navigate in a file, this is likely the shortcuts that use the most in my daily use. It is also works if you jump to a tag to go back to your original location.
You might also want to use nnoremap rather than map, this way it will only work in normal mode, and you could potentially reuse F4 in combination in another key binding without having recursive mappings.
so
nnoremap <F4> gg=G2<C-o>

How to refer to key combinations in vim keybinding that works on the query line

I use pandoc markdown in text files and want to automate links that refer to internal textnodes. For example I have a link like [\%110lund] going to the word "und" in line 110. To automate the jumping process I defined a keybinding:
nnoremap <Leader>l vi[y/<ctrl+r>0<CR>
Unfortunately <ctrl+r> is written as the query string instead of performed to copy the visual selection.
So my question is how do I have to notate <ctrl+r>0 at this location so that it is actually performed instead of written out
Use c+r instead of ctrl+r.
In order to avoid confusion, I am striking out the incorrect edit that someone else made, rather than reverting it. In the context of a vim mapping (such as the :nnoremap of this question) the following should be typed literally. For example, <c-r> really means 5 characters.
Use <c-r> instead of <ctrl+r>.
See :help keycodes for more options.

How can I map these five keyboard actions to a single key in Vim?

I want to map a key so that it will do the following actions in Vim. Suppose I am editing a file; I want it set up so that if I press F2, I will accomplish the same thing I would if I did the following:
press ESC
type colon (:)
type w
press Enter
press ESC again
type i to go back to insert mode
Is this possible?
Yes it's possible, but it doesn't do what you want if the cursor is at the end of line.
To get file saved on F2 in insert mode, use the following mapping:
:imap <F2> <C-O>:w<CR>
Literal answer: Yes. You can use this:
:inoremap <F2> <Esc>:w<CR>I
but it won’t do exactly what you want (the cursor will be at the wrong place).
Anton beat me to the less literal (but correct) answer.
The best answer, though, is this: Don't use Vim incorrectly. You should never spend so much time in insert mode that you need a shortcut to get out of it, save the file, and then get back in. With all other editors, you’re in “insert mode” all the time, and only temporarily pop into a menu or dialog or whatever; in Vim, you should learn to reverse this. Only pop into insert mode to edit or add something; never use arrow keys to move the cursor while in insert mode; spend the majority of your time in command (normal) mode, and after a bit of adjustment to the new paradigm, you will find that your editing speed has increased.
Writing the mapping is almost easier than your description.
First, you need to determine from which mode the mapping will be used, because that determines what :map variant you will use. You’ll probably want to use this in insert mode, so you’ll use :inoremap.
The format of the mapping is:
:..noremap {keys} {rhs}
You want <F2> (see :help key-notation) for keys. For {rhs}, just concatenate the keys listed in your description.
To persist the mapping, add it to ~/.vimrc. (See :help vimrc.)
P.S. The alternative given by Anton Kovalenko is probably better for what you’re trying to do, but here I’ve given you the general recipe for future key mappings.

Resources