Do a visual select on search in Vim - search

What is a simple way to do a visual select on the item I searched for in Vim?
I would like to map my n key to not only go to the next search item but also select it. Similarly for p, * and #.
Looking this up gave me answers to searching for selected items, but I want to select searched items.

You can try something like
nnoremap ,n //b<CR>v//e<CR>
vnoremap ,n <Esc>//b<CR>//e<CR>n
. This does not work for one-character matches. For * it will look like this:
nnoremap ,* *v//e<CR>
. None of the solutions work with one character matches, you may try adding h before //e, but this won’t work at the start of the line. I would not suggest to remap default keys due to the mentioned problems.

http://vim.wikia.com/wiki/Copy_or_change_search_hit

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

Cycling and/or highlighting through a vim selection

The feature I am thinking of is kind of inspired by a feature that I really like about sublime text.
In sublime text, if you select a sequence of characters, it automatically puts a little box around it (to distinguish it from the word that you just highlighted). For me, this is very helpful because I can see and find specific things of the code much faster.
It would be awesome to have something similar to my vim environment. It does not have to be exactly the same as the one in sublime though, but it would be awesome if it were as similar as possible plus the additional feature to easy cycling through similar words.
Currently, what I am doing is highlight the work I want and then manually typing it to the search command /. It would be much better if I can just highlight it in visual mode and then automatically highlight similar words on the current screen with a different colour from the highlighting in visual mode and then have a quick key short cut to cycling through them, if I wished to do that.
I am not sure if a there exists a plugin or something that already does that, but that would cool! Ideally, I would want to to know as many details of the commands/changes to the vimrc file, so that I have the most control over this feature and be able to customize it as I wish.
You can get the highlighting you are looking for by enabling the hlsearch option:
:set hlsearch
It will highlight every occurrence of the last search pattern and thus work after all the following commands (and their relatives):
/foo<CR>
?bar<CR>
:s/fizz/buzz/g
*
#
You can use n to jump to the next occurrence in the direction of your search and N to do the same in the opposite direction.
To highlight every occurrence of the current word "without" moving the cursor, you can simply do:
*N
or:
*``
to jump to the next occurrence and jump back immediately.
Doing the same for visually selected text is a bit trickier but still possible…
either via a lightweight plugin like visualstar or The Search Party,
or with a tiny bit of crude vimscript in your ~/.vimrc:
" this function cleans up the search pattern
function! GetVisualSelection()
let old_reg = #v
normal! gv"vy
let raw_search = #v
let #v = old_reg
return substitute(escape(raw_search, '\/.*$^~[]'), "\n", '\\n', "g")
endfunction
" map * and # in visual mode so that they do the same as *N and #N in normal mode
xnoremap * :<C-u>/<C-r>=GetVisualSelection()<CR><CR>N
xnoremap # :<C-u>?<C-r>=GetVisualSelection()<CR><CR>N
My SearchHighlighting plugin changes the * command so that it just toggles the highlighting for the current word, without the movement to the next match (for which you can press n, or pass a count). This also works in visual mode, using the selection. I find this very handy for highlighting all matches.
There's also a mode that automatically highlights the current word / selection, like what many IDEs offer.
Other plugins
If you want more permanent highlighting, separate from searching, the Mark plugin offers that.
To get an orientation about the number of matches (without highlighting them), I have the SearchPosition plugin.

Not highlighting search in vim if it is a part of a command

In my .vimrc I've enabled highlighting the searched text (which I find to be a handy feature and wouldn't want to disable it).
set hlsearch
And, following answers to this question, I've made a mapping to be able to clear the highlight:
nmap <silent> ,/ :nohlsearch<CR>
The problem comes with commands which include search. For example, delete to next character 'x':
d/x
This will automatically highlight all the instances of 'x'. To remove this highlight I have to punch ,/ to clear it, which is quite annoying.
The question. Is it possible to enforce :nohl if the search is a part of a preceding command? Maybe, it is possible at least for a selected list of commands (say, d, y and c) before / character is hit?
d/x does not work for me as you describe. (I'm on vim 7.3 here and it can't make sense of the / following d in normal mode, so disregards the d and starts a regular / search.)
If you want to delete to the next x, then dfx or dtx are what I would use (depending on whether you want to also delete the x itself or not).
No highlighting involved.
Hope that helps.
[Following some clarification in the comments.]
I'm thinking that it should be possible to write a custom function to do what you want, and then assign a custom key sequence to call that function.
I played around a little, but am not very well versed in vim functions and couldn't make it work.
Here's what I tried:
function! g:DeleteToSearchAndNohls(term)
:normal d/a:term
:nohlsearch
endfunc
If 'x' is on the same line than the cursor, you can use dtx (meaning delete to x).

mapping # in vim

In my .vimrc I have mapped the #-key to a macro for commenting out/in lines of code.
Unfortunately # in vim already has a function - it searches backwards for the word beneath the cursor.
What I would now like to have is a way to map this functionality to another key-sequence (ideally I would like to have Control-* for that as * alone searches forward).
Does anyone know how to achieve this?
Many thanks!
Unfortunately, Ctrl + * cannot be used; I would propose \*; it's longer to type, but backwards searches are probably not that common.
:nnoremap <Leader>* #
Like Ingo Karkat said, mapping Ctrl+certain keys is impossible in vim. However, you can map Alt+8 instead:
noremap <A-8> #
I suggest Alt+8 instead of Alt+* because if you wanted to bend your hand in unnatural ways to press more than one modifier keys to perform a command, you would probably be using Emacs instead of Vim.
I use \+c for commenting and \+d for removing comments. The mappings are following :
:map \c <ESC>:s,^\(\s*\)[^/ \t]\#=,\1// <ESC>,e<CR>j$a
:map \d <ESC>:s,^\(\s*\)// \s\#!,\1<ESC>,e<CR>j$a
Above mappings are used in command mode. Taken from one answer on SO, which I am currently unable to find.

"Find next" in Vim

To search forward in Vim for cake, I'd type /cake, but the cursor jumps to the first match when I press return. Is there a Vim command analogous to "find next"?
It is n for next and N for previous.
And if you use reverse search with ? (for example, ?cake) instead of /, it is the other way round.
If it is installed on your system, you should try to run vimtutor command from your terminal, which will start a tutorial of the basic Vim commands.
Rob Wells advice about * and # is also very pertinent.
The most useful shortcut in Vim, IMHO, is the * key.
Put the cursor on a word and hit the * key and you will jump to the next instance of that word.
The # key does the same, but it jumps to the previous instance of the word.
It is truly a time saver.
When I was beginning I needed to watch a demo.
How to search in Vim
type /
type search term e.g. "var"
press enter
for next instance press n (for previous N)
You may be looking for the n key.
Typing n will go to the next match.
As discussed, there are several ways to search:
/pattern
?pattern
* (and g*, which I sometimes use in macros)
# (and g#)
plus, navigating prev/next with N and n.
You can also edit/recall your search history by pulling up the search prompt with / and then cycle with C-p/C-n. Even more useful is q/, which takes you to a window where you can navigate the search history.
Also for consideration is the all-important 'hlsearch' (type :hls to enable). This makes it much easier to find multiple instances of your pattern. You might even want make your matches extra bright with something like:
hi Search ctermfg=yellow ctermbg=red guifg=...
But then you might go crazy with constant yellow matches all over your screen. So you’ll often find yourself using :noh. This is so common that a mapping is in order:
nmap <leader>z :noh<CR>
I easily remember this one as z since I used to constantly type /zz<CR> (which is a fast-to-type uncommon occurrence) to clear my highlighting. But the :noh mapping is way better.
If you press Ctrl + Enter after you press something like "/wordforsearch", then you can find the word "wordforsearch" in the current line. Then press n for the next match; press N for previous match.

Resources