Searching vim history for matching first characters - vim

In bash, adding the lines
"\e[B": history-search-forward
"\e[A": history-search-backward
to my .inputrc, allows me to search the history for expressions that begin with the characters in front of my cursor by using the <page-up>/<page-down> keys.
Can I achieve something similar in vim?
I already know about the possibility of opening a history window with q: and performing even complex searches there, but I am looking for a simple solution for the simplest case of history search.
Thank you!

This is built-in as <Up> and <Down>.
Of course, you can customize this, e.g.:
:cnoremap <PageUp> <Up>

Related

How to use vim easy motion plugin movements with y/c/d commands?

I am using easymotion plugin (https://github.com/easymotion/vim-easymotion) with vim.
If you use f/F motions in VIM (with easymotion plugin), easy motion highlights all possible positions when there are multiple matches, that way you can easily jump to the position you want.
But it doesn't work with y/c/d commands, how can I achive that ?
I have provided an example below for clarification:
This is some line.
Say I am working on the above line in vim and the cursor is at the i in "This". If I do "yfs" in vim, I would like easy motion to mark the three "s"s present to the right of the cursor. That way, I can easily yank/change/delete upto the s I want.
Thanks in advance !
You can, use something like this in your .vimrc:
" Find next occurence of a char using easymotion
map <Leader>f <Plug>(easymotion-bd-f)
nmap <Leader>f <Plug>(easymotion-overwin-f)
Now you can do something like y<Leader>fs and it will highlight the three s-characters. Selecting one will then yank from your cursor's position to that character.
If this does not work
This means that there are other key bindings that are using the same combination. You can check this with :map and then look for the key combination you are trying to map to the easy-motion. Removing that keybinding from your .vimrc or removing the plugin that created the binding should solve the problem.
If it's the YankRing plugin that's hijacking the y/c/d keystrokes, you can add the following to your vimrc to prevent it from doing that (Check :h yankring for more info):
let g:yankring_zap_keys = ''

Search for word under cursor

When I use g* or * or g# it will trigger a search for the word under the cursor. However, the cursor moves to the next/previous occurrence of that word. Is there a way to search for the current word without having the cursor moving away?
It is annoying because often I want to press
*
:.,+5s/foo/bar/g
But this problem forces me to do
*
then shift+* (I want to skip this)
my search and replace.
Is there a way to search for the current word without having the cursor moving away?
The whole point of *, #, and friends is made pretty clear in the documentation: "search forward" or "search backward". Your problem seems to be that you use those commands not for their intended purpose but for a side effect, presumably highlighting all occurrences of the word under the cursor.
Since there's no built-in command for that you will need to map it yourself:
nnoremap <key> *``
nnoremap <anotherkey> #``
...
Instead of pressing * to fill the search pattern copy the word directly to command line using CTRL-R CTRL-W. I.e.:
:.,+5s/<C-R><C-W>/bar/g
Changing the functionality of * / # / g* etc. to not jump (especially without a given [count]) is a frequent request. Therefore, a plethora of plugins changes Vim's default behavior, often together with other search-related commands. My SearchHighlighting plugin is one such plugin. (The plugin page has links to many alternative plugins that could also try out.)
#romainl's accepted answer is a minimal solution with some drawbacks (e.g. flickering of the screen, possible change of window viewport) that most plugins will avoid.
I use the below mapping to search the current word and keep cursor's posistion:
nnoremap <expr> * ':%s/'.expand('<cword>').'//gn<CR>``'
The extra benefit is we got matches count too.
You could map:
nnoremap # #N
nnoremap * *N
noremap * :let #/ = "\\<<C-r><C-w>\\>"<cr>:set hlsearch<cr>
It simply sets the search pattern to the whole word under the cursor and then triggers an update to the search highlighting

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

Where to find a list of special character representations?

For example backspace is <BS> and tab is <Tab>, but where can I look them up if I don't know or remember the sequence for, say, the up or down arrow?
Two :helpful tricks:
In insert mode and in the command line, hitting <C-v> followed by some key inserts that key's internal notation.
For example,
:helpCtrl+v↑
produces
:help <Up>
The :help command supports completion so you can type a keyword related to what you want and hit <Tab> or <C-d>:
:help key<Tab>
I was going to ask this, but then I found the answer by random luck in the help files. So here it is for those who are looking for the same:
:help keycodes

Vimgrep not matching regular expression properly

If I do this:
:vimgrep /do_action\([ ]?'init'/ **/*.php
I get
E54: Unmatched \(
But I know that there are files with matching text. Why?
I would also be very grateful if someone could help me create a key mapping for cmd+l so that this search is initiated with "init" replaced with the word under the cursor, which I understand from various sources is possible.
Building on kev's answer, here is your mapping:
nnoremap <D-i> :vimgrep //do_action([ ]\?'<c-r>=expand('<cword>')<cr>'/ **/*.php<cr>
But I'd advise you to not use the Command key in a mapping: it works only in MacVim and it's a good habit to seek portability everywhere possible.
The <leader> key is perfect for such things.
nnoremap <leader>i :vimgrep //do_action([ ]\?'<c-r>=expand('<cword>')<cr>'/ **/*.php<cr>
See :help c_ctrl-r_= and :help leader.
edit
I went a little too fast on this one. Not only I've added unnecessary cruft to kev's reworking of your command (silly //) but I didn't notice that it could be simplified. This one is tested and working:
nnoremap <leader>i :vim do_action(\s*'<c-r>=expand('<cword>')<cr> **/*.php<cr>
Sorry for the mess.
You don't need to escape ( to match it. But you need to escape ? to match 0~1 previous item. Try:
:vimgrep /do_action([ ]\?'init'/ **/*.php

Resources