Hi ,
I want to fold set of lines after search as follows,
The mouse can also be used to open and close folds by following steps:
Click on a '+' to open the closed fold at this row.
Click on any other non-blank character to close the open fold at this row
I want to search click and collapse all matching lines.
The mouse can also be used to open and close folds by followingsteps:
+--
There is a method to collapse the patterns which are not matching in vim , after searching a pattern we can collapse non matching patterns by "\z" key .
nnoremap \z :setlocal foldexpr=(getline(v:lnum)=~#/)?0:(getline(v:lnum-1)=~#/)\\|\\|(getline(v:lnum+1)=~#/)?1:2 foldmethod=expr foldlevel=0 foldcolumn=2<CR>
Is there any option to do the opposite? Just find a pattern and collapse?
I'm using below configuration with neovim I think should work with regular vim as well:
nnoremap \Z :setlocal foldexpr=(getline(v:lnum)=~#/)?0:1 foldmethod=expr foldlevel=0 foldcolumn=2 foldminlines=0<CR><CR>
nnoremap \z :setlocal foldexpr=(getline(v:lnum)=~#/)?1:0 foldmethod=expr foldlevel=0 foldcolumn=2 foldminlines=0<CR><CR>
\z: Fold matching expression from last search
\Z: Fold anything that's NOT matching from last search
It's quite useful when I want to see all comments or no comments at all,
First do \ and search for ^# (If that's your language's comment start symbol) hit return, then do the folding as above.
Edit: You might want to add below to reset the folding back to manual if you want:
nnoremap \F :setlocal foldmethod=manual<CR><CR>
I got an answer to this question from reddit user on reddit vim forum.
https://www.reddit.com/r/vim/comments/91qz90/search_a_pattern_and_fold_the_matching_lines_in/
function! FoldSearchPattern() abort
if !exists('w:foldpatterns')
let w:foldpatterns=[]
setlocal foldmethod=expr foldlevel=0 foldcolumn=2
endif
if index(w:foldpatterns, #/) == -1
call add(w:foldpatterns, #/)
setlocal foldexpr=SetFolds(v:lnum)
endif
endfunction
function! SetFolds(lnum) abort
for pattern in w:foldpatterns
if getline(a:lnum) =~ pattern
if getline(a:lnum + 1) !~ pattern
return 's1'
else
return 1
endif
endif
endfor
endfunction
nnoremap \z :call FoldSearchPattern()<CR>
Hope it is helpful.
Related
Using the Ag.vim plugin you can easily search for the word under the cursor by calling :Ag without any arguments, but how can I include the word under the cursor as part of a search pattern? I'm trying to add a bit to my vimrc to search for method definitions in Ruby files. Something like:
autocmd FileType ruby noremap K :Ag! "\bdef <C-R><C-W>\b"<CR>
It doesn't recognize the <C-R><C-W>. Also, I've tried both \b and \<, \> as word boundaries. Ag uses \b outside the context of Vim, but I know it translates \< and \> to \b in some contexts (not sure about this context though).
I usually use one trick, just press * on you current word and then use :AgFromSearch, you could specify concrete path e.g :AgFromSearch /any/path/
If you really want to do word as part of your search pattern, you can use <cword> (current word)
nmap <silent> <D-f> :Ag "def <cword>" /any/path/<CR>
augroup Ruby
" clear this augroup's autocmds
autocmd!
" use this version:
autocmd FileType ruby nnoremap <buffer> K :<C-u>execute 'Ag! "\bdef ' . expand('<cword>') . '\b"'<CR>
" or this one, ^R^W is obtained by pressing <C-v><C-r> then <C-v><C-w>:
autocmd FileType ruby nnoremap <buffer> K :Ag! "\bdef ^R^W\b"<CR>
augroup END
Use augroup and autocmd! as above for a cleaner ~/.vimrc.
nnoremap is better than noremap unless you really want a single mapping for normal, visual and operator-pending mode (which doesn't really make any sense).
<buffer> is needed to ensure that your mapping is limited to the current buffer.
What I'd like is to map one key, e.g. F4, so that pressing F4 will toggle the visibility of search highlights, and so that starting a new search enables visibility no matter the current visibility.
What I've tried:
Mapping F4 to :nohlsearch temporarily disables highlight visibility without turning the hlsearch setting off, but it does not toggle visibility back again.
Mapping F4 to :set hlsearch! does toggle on/off, but I don't want to toggle the hlsearch setting off, just the visibility setting. If hlsearch is off then it doesn't come back automatically with a new search.
There doesn't seem to be an opposite form of :nohlsearch and the command itself has problems being called from a function.
I've found similiar questions, but they don't provide an answer.
Update:
The first comment provides exactly what I was asking for, reproduced below:
let hlstate=0
nnoremap <F4> :if (hlstate == 0) \| nohlsearch \| else \| set hlsearch \| endif \| let hlstate=1-hlstate<cr>
(N.B. for anyone using this --- cramming the map onto one line instead of using a function is necessary since you can't effect a change on highlighting from inside a function.)
Related question for slightly different functionality: https://stackoverflow.com/a/16750393/1176650
Note, recent Vims (7.4.79) have the v:hlsearch variable available. This means you can improve your mapping to:
:nnoremap <silent><expr> <Leader>h (&hls && v:hlsearch ? ':nohls' : ':set hls')."\n"
" ctrl+c to toggle highlight.
let hlstate=0
nnoremap <c-c> :if (hlstate%2 == 0) \| nohlsearch \| else \| set hlsearch \| endif \| let hlstate=hlstate+1<cr>
Now just press ctrl+c to toggle highlight. Only quirk is you gotta press it twice after a search to toggle off highlight because searching doesn't increment the counter.
What I'd like is to map one key, e.g. F4, so that pressing F4 will
toggle the visibility of search highlights, and so that starting a new
search enables visibility no matter the current visibility.
Just tried this and seems to do the trick:
" switch higlight no matter the previous state
nmap <F4> :set hls! <cr>
" hit '/' highlights then enter search mode
nnoremap / :set hlsearch<cr>/
You can toggle with :set invhlsearch
From Highlight all search pattern matches, we can map a key to toggle the highlighting states. Unlike trusktr's answer, here we do use a variable to store the state.
"If you want to be able to enable/disable highlighting quickly, you can map a key to toggle the hlsearch option":
" Press F4 to toggle highlighting on/off, and show current value.
:noremap <F4> :set hlsearch! hlsearch?<CR>
"Or, press return to temporarily get out of the highlighted search":
:nnoremap <CR> :nohlsearch<CR><CR>
Other answer need to toggle highlight search, this is not so good.
Actually you only need to
let #/ = ''
I write a little function to implement this feature, and highlight current word (just like * star key), but not jump to next matched word, and not touch jumplist.
function! HLtoggle()
if (#/ == '')
let #/ = expand("<cword>")
else
let #/ = ''
endif
endfunc
it's simple, but i'm not find it in google.
Have fun with vim! :)
Okay, try this:
:map <F12> :set nohls<CR>:let #/ = ""<CR>:set hls<CR>
Then if you hit F12, it turns of the higlighting, then sets the last search string to an empty one (that is: clears it), and turns back on the highlighting.
Or if you want to save the search string, then you can do something like:
:map <F12> :set nohls<CR>:let #s = #/<CR>:let #/ = ""<CR>:set hls<CR>
:map <SHIFT><F12> :let #/=#s<CR>
Now after pressing SHIFTF12 the original searchstring will be set back and highlighted.
If that still not satisfy you, you can still do it like:
:map <F12> :highlight Search term=None ctermfg=None ctermbg=None guifg=None guibg=None<CR>
:map <SHIFT><F12> :highlight Search term=OV1 ctermfg=OV2 ctermbg=OV3 guifg=OV4 guibg=OV5<CR>
Where OVx are the original values which you can write down when you issue a :highlight Search<CR>. This way it can be turned off then set back on, but with two keyboard shortcuts. If you want it with one, you should create a function for that which toggles it, then create a mapping for that function.
Hmm, isn't :set hlsearch the opposite of :nohlsearch?
The first one turns matches highlighting on, the second one turns matches highlighting off temporarilly.
I don't understand what you mean by "I don't want to toggle the 'hlsearch' setting itself, just the visibility setting.": :set hlsearch and its pendant only deal with the visibility ("highlighting") of search matches, nothing else.
If you want to have matches highlighted each time you do a search just add :set hlsearch to your ~/.vimrc.
If you want the ability to turn highlighting off after a search just map F4 to :nohlsearch, highlighting will be back at your next search.
I use this slightly improved version from trusktr. Note that ctrl+c as used in the example from trusktr is already mapped to Escape by default which is very handy.
" Toggle highlight search
let hlstate=0
nnomap <Leader>b :if (hlstate%2 == 0) \| nohlsearch \| else \| set hlsearch \| endif \| let hlstate=hlstate+1<CR>:echo "toggled visibility for hlsearch"<CR>
inomap <Leader>b <ESC>:if (hlstate%2 == 0) \| nohlsearch \| else \| set hlsearch \| endif \| let hlstate=hlstate+1<CR>:echo "toggled visibility for hlsearch"<CR>a
In order to accomplish this, I added this unsophisticated line in my .vimrc:
nmap <LEADER>h /xxxxx<CR>
I use the following:
augroup onsearch
autocmd!
autocmd VimEnter * set hlsearch
augroup END
nnoremap <leader>/ :set hlsearch!<CR>
The autogroup ensure's that highlighting is enabled when entering vim, but not switched on when re-sourcing your vimrc file(s). The mapping toggles it on and off.
If anyone is looking to do this in neovim (in lua) this is a simple command that I wrote:
HLSTATE = vim.opt.hlsearch
function TOGGLE_SEARCH_HIGHLIGTING()
if HLSTATE == true then
vim.opt.hlsearch = false
HLSTATE = false
else
vim.opt.hlsearch = true
HLSTATE = true
end
end
vim.api.nvim_create_user_command('HighlightToggle', 'lua TOGGLE_SEARCH_HIGHLIGTING()', {})
You can then run it with the command :HighlightToggle (and assign in a keymap if you want).
How can I highlight all occurrence of a selected word in GVim, like in Notepad++?
In Normal mode:
:set hlsearch
Then search for a pattern with the command / in Normal mode, or <Ctrl>o followed by / in Insert mode. * in Normal mode will search for the next occurrence of the word under the cursor. The hlsearch option will highlight all of them if set. # will search for the previous occurrence of the word.
To remove the highlight of the previous search:
:nohlsearch
You might wish to map :nohlsearch<CR> to some convenient key.
The * key will highlight all occurrences of the word that is under the cursor.
I know than it's a really old question, but if someone is interested in this feature, can check this code
http://vim.wikia.com/wiki/Auto_highlight_current_word_when_idle
" Highlight all instances of word under cursor, when idle.
" Useful when studying strange source code.
" Type z/ to toggle highlighting on/off.
nnoremap z/ :if AutoHighlightToggle()<Bar>set hls<Bar>endif<CR>
function! AutoHighlightToggle()
let #/ = ''
if exists('#auto_highlight')
au! auto_highlight
augroup! auto_highlight
setl updatetime=4000
echo 'Highlight current word: off'
return 0
else
augroup auto_highlight
au!
au CursorHold * let #/ = '\V\<'.escape(expand('<cword>'), '\').'\>'
augroup end
setl updatetime=500
echo 'Highlight current word: ON'
return 1
endif
endfunction
the simplest way, type in normal mode *
I also have these mappings to enable and disable
"highligh search enabled by default
set hlsearch
"now you can toggle it
nnoremap <S-F11> <ESC>:set hls! hls?<cr>
inoremap <S-F11> <C-o>:set hls! hls?<cr>
vnoremap <S-F11> <ESC>:set hls! hls?<cr> <bar> gv
Select word by clickin on it
set mouse=a "Enables mouse click
nnoremap <silent> <2-LeftMouse> :let #/='\V\<'.escape(expand('<cword>'), '\').'\>'<cr>:set hls<cr>
Bonus: CountWordFunction
fun! CountWordFunction()
try
let l:win_view = winsaveview()
let l:old_query = getreg('/')
let var = expand("<cword>")
exec "%s/" . var . "//gn"
finally
call winrestview(l:win_view)
call setreg('/', l:old_query)
endtry
endfun
" Bellow we set a command "CountWord" and a mapping to count word
" change as you like it
command! -nargs=0 CountWord :call CountWordFunction()
nnoremap <f3> :CountWord<CR>
Selecting word with mouse and counting occurrences at once:
OBS: Notice that in this version we have "CountWord" command at the end
nnoremap <silent> <2-LeftMouse> :let #/='\V\<'.escape(expand('<cword>'), '\').'\>'<cr>:set hls<cr>:CountWord<cr>
Search based solutions (*, /...) move cursor, which may be unfortunate.
An alternative is to use enhanced mark.vim plugin, then complete your .vimrc to let double-click trigger highlighting (I don't know how a keyboard selection may trigger a command) :
"Use Mark plugin to highlight selected word
map <2-leftmouse> \m
It allows multiple highlightings, persistence, etc.
To remove highlighting, either :
Double click again
:Mark (switch off until next selection)
:MarkClear
First (or in your .vimrc):
:set hlsearch
Then position your cursor over the word you want highlighted, and hit *.
hlsearch means highlight all occurrences of the current search, and * means search for the word under the cursor.
to highlight word without moving cursor, plop
" highlight reg. ex. in #/ register
set hlsearch
" remap `*`/`#` to search forwards/backwards (resp.)
" w/o moving cursor
nnoremap <silent> * :execute "normal! *N"<cr>
nnoremap <silent> # :execute "normal! #n"<cr>
into your vimrc.
What's nice about this is g* and g# will still work like "normal" * and #.
To set hlsearch off, you can use "short-form" (unless you have another function that starts with "noh" in command mode): :noh. Or you can use long version: :nohlsearch
For extreme convenience (I find myself toggling hlsearch maybe 20 times per day), you can map something to toggle hlsearch like so:
" search highlight toggle
nnoremap <silent> <leader>st :set hlsearch!<cr>
.:. if your <leader> is \ (it is by default), you can press \st (quickly) in normal mode to toggle hlsearch.
Or maybe you just want to have :noh mapped:
" search clear
nnoremap <silent> <leader>sc :nohlsearch<cr>
The above simply runs :nohlsearch so (unlike :set hlsearch!) it will still highlight word next time you press * or # in normal mode.
cheers
For example this plugIns:
https://github.com/rrethy/vim-illuminate
https://github.com/itchyny/vim-cursorword
Just search for under cursor in vimawesome.com
The key, as clagccs mentioned, is that the highlight does NOT conflict with your search: https://vim.fandom.com/wiki/Auto_highlight_current_word_when_idle
Screen-shot of how it does NOT conflict with search:
Notes:
vim-illuminate highlights by default, in my screen-shot I switched to underline
vim-illuminate highlights/underlines word under cursor by default, in my screen-shot I unset it
my colorschemes are very grey-ish. Check yours to customize it too.
First ensure that hlsearch is enabled by issuing the following command
:set hlsearch
You can also add this to your .vimrc file as set
set hlsearch
now when you use the quick search mechanism in command mode or a regular search command, all results will be highlighted. To move forward between results, press 'n' to move backwards press 'N'
In normal mode, to perform a quick search for the word under the cursor and to jump to the next occurrence in one command press '*', you can also search for the word under the cursor and move to the previous occurrence by pressing '#'
In normal mode, quick search can also be invoked with the
/searchterm<Enter>
to remove highlights on ocuurences use, I have bound this to a shortcut in my .vimrc
:nohl
set hlsearch
maybe ?
Enable search highlighting:
:set hlsearch
Then search for the word:
/word<Enter>
My favorite for doing this is the mark.vim plugin.
It allows to highlight several words in different colors simultaneously.
Example Screenshot
Use autocmd CursorMoved * exe printf('match IncSearch /\V\<%s\>/', escape(expand('<cword>'), '/\'))
Make sure you have IncSearch set to something. e.g call s:Attr('IncSearch', 'reverse'). Alternatively you can use another highlight group in its place.
This will highlight all occurrences of words under your cursor without a delay. I find that a delay slows me down when I'm wizzing through code. The highlight color will match the color of the word, so it stays consistent with your scheme.
Why not just:
z/
That will highlight the current word under cursor and any other occurrences. And you don't have to give a separate command for each item you're searching for. Perhaps that's not available in the unholy gvim? It's in vim by default.
* is only good if you want the cursor to move to the next occurrence. When comparing two things visually you often don't want the cursor to move, and it's annoying to hit the * key every time.
Add those lines in your ~/.vimrc file
" highlight the searched items
set hlsearch
" F8 search for word under the cursor recursively , :copen , to close -> :ccl
nnoremap <F8> :grep! "\<<cword>\>" . -r<CR>:copen 33<CR>
Reload the settings with :so%
In normal model go over the word.
Press * Press F8 to search recursively bellow your whole project over the word
--> if you want to highlight a text occurrences in gvim
Select the text & copy
then ?paste the selected text (Note: This will not work for insert mode)
I usually edit RUBY files in VIM. I want the methods(def...end) to fold. Could you please help me define the fold syntax?
Assuming you've already got Ruby syntax highlighting setup and working, use the syntax mode for folding:
set foldmethod=syntax
This will give you folds on class .. end and def .. end, etc.
I like to have everything fold by default, and this here will let you tweak a whole bunch of things related to folding. I do mostly Perl and C++ coding and I find it works well with that. Folding and unfolding is mapped to space key.
Here's what I have going in my vimrc:
" Folding stuff
hi Folded guibg=red guifg=Red cterm=bold ctermbg=DarkGrey ctermfg=lightblue
hi FoldColumn guibg=grey78 gui=Bold guifg=DarkBlue
set foldcolumn=2
set foldclose=
set foldmethod=indent
set foldnestmax=10
set foldlevel=0
set fillchars=vert:\|,fold:\
set foldminlines=1
" Toggle fold state between closed and opened.
"
" If there is no fold at current line, just moves forward.
" If it is present, reverse it's state.
fu! ToggleFold()
if foldlevel('.') == 0
normal! l
else
if foldclosed('.') < 0
. foldclose
else
. foldopen
endif
endif
echo
endf
" Map this function to Space key.
noremap <space> :call ToggleFold()<CR>
I think you put the cursor on the first line then zfnj where n is the number of lines to fold (so to fold 10 lines you woudl zf10j). I think it will also recognize syntax so like in PHP I do zf} to fold to the closing bracket. I don't code in Ruby, so I don't know if this works in Ruby.
From then on, to toggle, zo will open and zc will close.
I worked in NetBeans and liked this feature: when you place cursor in a variable name all occurences of the variable are highlighted. This is very useful for quick searching all occurences of the variable. Is it possible to add this behavior to Vim?
This autocommand will do what you want:
:autocmd CursorMoved * exe printf('match IncSearch /\V\<%s\>/', escape(expand('<cword>'), '/\'))
Edit: I have used the IncSearch highlight group in my example, but you can find other colours to use by running this command:
:so $VIMRUNTIME/syntax/hitest.vim
If you set
:set hlsearch
to highlight all occurrences of a search pattern, and then use * or # to find occurrences of the word under your cursor, that will get you some way to what you want. However I think a syntax-aware variable highlighting is beyond the scope of VIM.
This statement will allow a variable to enable/disable highlighting all occurences of the word under the cursor:
:autocmd CursorMoved * exe exists("HlUnderCursor")?HlUnderCursor?printf('match IncSearch /\V\<%s\>/', escape(expand('<cword>'), '/\')):'match none':""
One would activate highlighting with:
:let HlUnderCursor=1
And disable it with:
:let HlUnderCursor=0
One could easily define a shortcut key for enabling/disabling highlighting:
:nnoremap <silent> <F3> :exe "let HlUnderCursor=exists(\"HlUnderCursor\")?HlUnderCursor*-1+1:1"<CR>
Deleting the variable would prevent the match statement from executing, and not clear the current highlight:
:unlet HlUnderCursor
If you do not want to highlight language words (statements / preprocs such as if, #define) when your cursor is on these words, you can put this function in your .vimrc based on the #too_much_php answer :
let g:no_highlight_group_for_current_word=["Statement", "Comment", "Type", "PreProc"]
function s:HighlightWordUnderCursor()
let l:syntaxgroup = synIDattr(synIDtrans(synID(line("."), stridx(getline("."), expand('<cword>')) + 1, 1)), "name")
if (index(g:no_highlight_group_for_current_word, l:syntaxgroup) == -1)
exe printf('match IncSearch /\V\<%s\>/', escape(expand('<cword>'), '/\'))
else
exe 'match IncSearch /\V\<\>/'
endif
endfunction
autocmd CursorMoved * call s:HighlightWordUnderCursor()
i think that what you really want is the following plugin by Shuhei Kubota:
http://www.vim.org/scripts/script.php?script_id=4306
According to the description: 'This script highlights words under the cursor like many IDEs.'
Cheers.
vim_current_word works out of the box, is syntax aware, and allows customisable colours.
To map F2 to toggle highlighting:
map <F2> :set hlsearch!<CR> * #
It is certainly not perfect. '* #' jumps around a bit much...
This variant is optimized for speed (uses CursorHold instead of CursorMoved) and compatibility with hlsearch. The current search word highlighting will not be disrupted.
" autosave delay, cursorhold trigger, default: 4000ms
setl updatetime=300
" highlight the word under cursor (CursorMoved is inperformant)
highlight WordUnderCursor cterm=underline gui=underline
autocmd CursorHold * call HighlightCursorWord()
function! HighlightCursorWord()
" if hlsearch is active, don't overwrite it!
let search = getreg('/')
let cword = expand('<cword>')
if match(cword, search) == -1
exe printf('match WordUnderCursor /\V\<%s\>/', escape(cword, '/\'))
endif
endfunction
Similar to the accepted answer, but this way allows you to set a delay time after holding the cursor over a word before the highlighting will appear. The 1000 is in milliseconds and means that it will highlight after 1 second.
set updatetime=1000
autocmd CursorHold * exe
\ printf('match IncSearch /\V\<%s\>/', escape(expand('<cword>'), '/\'))
See :h CursorHold for more info.
vim-illuminate does the trick for me.
match-up does the trick for me.
vim match-up: even better % navigate and highlight matching words modern matchit and matchparen
Features
jump between matching words
jump to open & close words
jump inside (z%)
full set of text objects
highlight (), [], & {}
highlight all matching words
display matches off-screen
show where you are (breadcrumbs)
(neovim) tree-sitter integration