""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Extended search tools for Vim
" Maintainers: Barry Arthur <barry.arthur@gmail.com>
" Israel Chauca F. <israelchauca@gmail.com>
" Version: 0.7
" Description: Commands and maps for extended searches in Vim
" License: Vim License (see :help license)
" Website: https://github.com/dahu/SearchParty
"
" See SearchParty.txt for help. This can be accessed by doing:
"
" :helptags ~/.vim/doc
" :help SearchParty
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let s:SearchParty_version = '0.7' " Allow custom user maps
" Vimscript Setup: {{{1
" Allow use of line continuation.
let s:save_cpo = &cpo
set cpo&vim
" load guard {{{2
" uncomment after plugin development
"if exists("g:loaded_SearchParty")
" \ || v:version < 700
" \ || v:version == 703 && !has('patch338')
" \ || &compatible
" let &cpo = s:save_cpo
" finish
"endif
let g:loaded_SearchParty = 1
let s:plugin_root = expand('<sfile>:p:h:h')
" Global Options: {{{1
if !exists('g:searchparty_visual_find_sets_search')
let g:searchparty_visual_find_sets_search = 0
endif
if !exists('g:searchparty_load_user_maps')
let g:searchparty_load_user_maps = 1
endif
" Load User Maps: {{{1
function! s:Carp(msg)
echohl WarningMsg
echomsg a:msg
echohl None
return 0
endfunction
function! SPLoadUserMaps()
if ! g:searchparty_load_user_maps
return
endif
let sp_default_maps_file = s:plugin_root . '/searchparty_default_maps.vim'
let sp_user_maps_file = s:plugin_root . '/searchparty_user_maps.vim'
if ! filereadable(sp_user_maps_file)
if ! filereadable(sp_default_maps_file)
return s:Carp('SPLoadUserMaps: Cannot find default maps file (' . sp_default_maps_file .')')
endif
if writefile(readfile(sp_default_maps_file), sp_user_maps_file) == -1
return s:Carp('SPLoadUserMaps: Cannot copy default maps to user maps file (' . sp_user_maps_file .')')
endif
endif
for line in readfile(sp_user_maps_file)
if line =~ '^\s*\(".*\)\?$'
continue
endif
if line !~ '^\s*.\(nore\)\?map'
call s:Carp('SPLoadUserMaps: Not a map command! (' . line . ')')
continue
endif
let lhs = matchstr(line, '\c<unique>\s*\(<silent>\)\?\s*\zs\S\+')
let plug = matchstr(line, '\c<plug>\S\+')
let mode = matchstr(line, '^\s*\zs.')
let existing = maparg(lhs, mode)
if existing != ''
call s:Carp('SPLoadUserMaps: Mapping ' . lhs . ' already mapped to ' . existing)
continue
endif
if !hasmapto(plug, mode)
exe line
endif
endfor
endfunction
" Autocommands: {{{1
augroup SearchPartySearching
au!
au VimEnter * call SPInitialiseSearchMaps()
au BufEnter * let b:searching = 0
au CursorHold * call SPAfterSearch()
augroup END
function! SPInitialiseSearchMaps()
let rhs = ':call searchparty#mash#unmash()<bar>let b:searching=1'
if exists(':ShowSearchIndex')
let ssi = '<bar>ShowSearchIndex<cr>'
else
let ssi = '<cr>'
endif
exe 'nnoremap <Plug>SearchPartySearchFwd ' . rhs . ssi . '/'
exe 'nnoremap <Plug>SearchPartySearchBkwd ' . rhs . ssi . '?'
nmap / <Plug>SearchPartySearchFwd
nmap ? <Plug>SearchPartySearchBkwd
call SPLoadUserMaps()
endfunction
" After Search Callbacks: {{{1
function! SPAfterSearch()
if exists('b:searching') && b:searching
call searchparty#mash#mash()
for x in range(10)
if exists('*AfterSearch_' . x)
call call('AfterSearch_' . x, [])
endif
endfor
endif
let b:searching = 0
endfunction
" Plug Maps: {{{1
" Literal Search: {{{2
nnoremap <silent> <Plug>SearchPartyFindLiteralFwd
\ :<C-U>call searchparty#literal_search#find_literal(1)<CR>
nnoremap <silent> <Plug>SearchPartyFindLiteralBkwd
\ :<C-U>call searchparty#literal_search#find_literal(0)<CR>
" SearchParty Arbitrary Matches: {{{2
nnoremap <Plug>SearchPartySetMatch
\ :call searchparty#arbitrary_matches#match()<cr>
nnoremap <Plug>SearchPartyDeleteMatch
\ :call searchparty#arbitrary_matches#match_delete()<CR>
command! -bar -nargs=0 SearchPartyMatchList
\ call searchparty#arbitrary_matches#match_list()
command! -bar -nargs=? SearchPartyMatchDelete
\ call searchparty#arbitrary_matches#match_delete(<args>)
command! -bar -nargs=1 SearchPartyMatchNumber
\ call searchparty#arbitrary_matches#match_number(<args>)
" MASH Movement Activated Search Highlight: {{{2
hi MashFOW ctermfg=black ctermbg=NONE guifg=black guibg=NONE
augroup SP_MASH
au!
autocmd BufRead,BufNew * let b:mash_use_fow = 0
augroup END
" Shadow Maps
for lhs in ['n', 'N', '#', '*', 'g#', 'g*']
exec 'nnoremap <silent> <Plug>SearchPartyMashShadow' . lhs . ' ' . lhs
\ . ':call searchparty#mash#mash()<CR>'
if !hasmapto('<Plug>SearchPartyMashShadow' . lhs)
exec 'silent! nmap <unique> ' . lhs . ' <Plug>SearchPartyMashShadow'.lhs
endif
endfor
nnoremap <silent> <Plug>SearchPartyMashFOWToggle
\ :let b:mash_use_fow = b:mash_use_fow ? 0 : 1<CR>
\:call searchparty#mash#mash()<CR>
" backwards compatible to my deprecated vim-MASH plugin
nmap <silent> <Plug>MashFOWToggle <Plug>SearchPartyMashFOWToggle
" Multiple Replacements: {{{2
nnoremap <Plug>SearchPartyMultipleReplace
\ :call searchparty#multiple_replacements#multiply_replace()<CR>
" Search Highlighting: {{{2
" Temporarily clear highlighting
nnoremap <Plug>SearchPartyHighlightClear
\ :let b:mash_use_fow = 0<cr>
\:call searchparty#mash#unmash()<bar>noh<cr>
" Toggle search highlighting
nnoremap <Plug>SearchPartyHighlightToggle :let &hlsearch = searchparty#mash#toggle()<bar>set hlsearch?<cr>
" Highlight all occurrences of word under cursor
nnoremap <silent> <Plug>SearchPartyHighlightWord
\ :let @/='\<'.expand('<cword>').'\>'<bar>set hlsearch<cr>viwo<esc>
" Highlight all occurrences of visual selection
xnoremap <Plug>SearchPartyHighlightVisual
\ :<c-U>let @/=searchparty#visual#element()<bar>set hlsearch<cr>
" Highlight all occurrences of WORD under cursor
nnoremap <silent> <Plug>SearchPartyHighlightWORD
\ :let @/='\V'.escape(expand('<cWORD>'), '\\')<bar>set hlsearch<cr>viWo<esc>
" Manual Search Term From Input
nnoremap <Plug>SearchPartySetSearch
\ :let @/=input("set search: ")<bar>set hlsearch<cr>
" Visual Search And Replace: {{{2
" The default expected mappings:
" Use * and # in visual mode to search for visual selection
" Use & in visual mode to prime a substitute based on visual selection
" Use g& in visual mode to repeat the prior change
xnoremap <Plug>SearchPartyVisualFindNext :<c-u>call searchparty#visual#find('/')<cr>
xnoremap <Plug>SearchPartyVisualFindPrev :<c-u>call searchparty#visual#find('?')<cr>
xnoremap <Plug>SearchPartyVisualSubstitute :<c-u>%s/<c-r>=searchparty#visual#element()<cr>
xnoremap <Plug>SearchPartyVisualChangeAll :s/\<<c-r>-\>/\=@./g<cr>
xnoremap <Plug>SearchPartyVisualChangeAllBare :s/<c-r>-/\=@./g<cr>
" Toggle Auto Highlight Cursor Word: {{{2
nnoremap <Plug>SearchPartyToggleAutoHighlightWord
\ :call searchparty#search_highlights#toggle_AHCW()<CR>
" Print With Highlighting: {{{2
command! -range=% -nargs=* P
\ <line1>,<line2>call searchparty#search_highlights#print(<q-args>)
" Replace Within Search Highlights: {{{2
noremap <Plug>SearchPartySearchHighlightReplace
\ :call searchparty#search_highlights#replace()<CR>
command! -range=% -nargs=0 SearchHighlightReplace
\ <line1>,<line2>call searchparty#search_highlights#replace()
" Search Within A Range: {{{2
command! -range=% -nargs=* RSearch
\ exe '/\%(\%>'.(<line1>-1).'l\%<'.(<line2>+1).'l\)\&\%(<args>\)/'
" Teardown:{{{1
let &cpo = s:save_cpo
" vim: set sw=2 sts=2 et fdm=marker: