Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- " Online post: https://stackoverflow.com/a/45579817/490748
- """""""""""
- " A sexy commandline-based search menu can be accessed by <Shift-F>, which makes remembering the functions below pointless.
- "
- " Various functions for searching are implemented below:
- " :GrepBuffer [pattern] [matchCase] [matchWholeWord] [prefix]
- " :GrepTab [pattern] [matchCase] [matchWholeWord] [prefix]
- " :GrepTabs [pattern] [matchCase] [matchWholeWord] [prefix]
- " :GrepBuffers [pattern] [matchCase] [matchWholeWord] [prefix]
- " :GrepFiles [pattern] [matchCase] [matchWholeWord] [prefix]
- "
- " Shorthand versions that use the word that the caret is on as the pattern, or if you have a visual selection then it will use that, and if the caret is not on a word, and their is no visual selection, then you get another sexy menu to type in what you want to search:
- " :SearchBuffer [matchCase] [matchWholeWord] [prefix]
- " :SearchTab [matchCase] [matchWholeWord] [prefix]
- " :SearchTabs [matchCase] [matchWholeWord] [prefix]
- " :SearchBuffers [matchCase] [matchWholeWord] [prefix]
- " :SearchFiles [matchCase] [matchWholeWord] [prefix]
- "
- " Note: matchCase = [0,1]
- " Note: matchWholeWord = [0,1]
- " Note: prefix = 'c' for QuickFix list or 'l' for location list for the current window
- "
- " USAGE: When you see a QuickFix with search results, you will find that the arrow keys will have been mapped to allow navigation of the QuickFix list with easy.
- " When you are done searching, press <F3> to close the QuickFix window and this will restore the default arrow key behavior.
- """""""""""
- " This setting controls the behavior when switching buffers
- " useopen ensures that a new window will not be created if an existing window already contains the specified buffer.
- " usetab ensure that a new tab will not be created if an existing tab already contains the specified buffer.
- " split will open a new vertically-stacked window to display the buffers that are not displayed elsewhere.
- " vsplit will open a new horizontally-stacked window to display the buffers that are not displayed elsewhere.
- " newtab will open a new tab to display the buffers that are not displayed elsewhere.
- " NOTE: QuickFix commands are affected by this setting
- set switchbuf=useopen,usetab,newtab
- " Bind F3 to clear QuickFix windows, location list for the current windows, search highlights, and restore <left> <right> <up> <down> binds {{{
- function! TabCleanup()
- cclose
- lclose
- endfunction
- function! MoreCleanup()
- call s:RestoreArrowKeyBinds()
- call setqflist([])
- redraw!
- endfunction
- nnoremap <F3> :tabdo :call TabCleanup()<CR><BAR>:call MoreCleanup()<CR><BAR>:nohlsearch<CR><BAR>:echo ''<CR>
- " }}} Bind F3 to clear quickfix window, location list for the current window, and search highlights
- " Bind Shift + F to display search menu {{{
- function! DisplaySearchMenu()
- let guicursor = &guicursor
- let &guicursor = 'a:hl-None' "hide the blinking cursor
- try
- let l:enterChar = 13
- let l:escapeChar = 27
- let l:leftChar = "\<Left>"
- let l:rightChar = "\<Right>"
- let l:searchText = ''
- let l:searchLocation = 'W'
- let l:searchOptionMatchCase = 0
- let l:searchOptionMatchWholeWord = 0
- let l:STAGE_DONE = 0
- let l:STAGE_GET_SEARCH_TEXT = 1
- let l:STAGE_GET_SEARCH_LOCATION = 2
- let l:STAGE_GET_SEARCH_OPTIONS = 3
- let l:stage = l:STAGE_GET_SEARCH_TEXT
- while l:stage != l:STAGE_DONE
- if l:stage == l:STAGE_GET_SEARCH_TEXT
- while 1
- let l:searchText = s:GetSearchText(l:searchText)
- if l:searchText != ''
- let l:stage = l:STAGE_GET_SEARCH_LOCATION
- break
- endif
- endwhile
- elseif l:stage == l:STAGE_GET_SEARCH_LOCATION
- while 1
- echohl Question | echon "Search Target: "
- echohl Title | echon l:searchText
- echohl Question | echon " Search Location: "
- if l:searchLocation == 'W'
- echohl WarningMsg | echon "[W]indow "
- else
- echohl SpecialKey | echon "[W]" | echohl Question | echon "indow "
- endif
- if l:searchLocation == 'V'
- echohl WarningMsg | echon "[V]isible "
- else
- echohl SpecialKey | echon "[V]" | echohl Question | echon "isible "
- endif
- if l:searchLocation == 'T'
- echohl WarningMsg | echon "[T]abs "
- else
- echohl SpecialKey | echon "[T]" | echohl Question | echon "abs "
- endif
- if l:searchLocation == 'B'
- echohl WarningMsg | echon "[B]uffers "
- else
- echohl SpecialKey | echon "[B]" | echohl Question | echon "uffers "
- endif
- if l:searchLocation == 'F'
- echohl WarningMsg | echon "[F]iles "
- else
- echohl SpecialKey | echon "[F]" | echohl Question | echon "iles "
- endif
- echohl Normal
- let l:key = getchar()
- let l:char = toupper(nr2char(l:key))
- redraw!
- "echon "\r\r"
- "echon ''
- let l:choice_map = {}
- let l:choice_map['W'] = 's:GrepBuffer'
- let l:choice_map['V'] = 's:GrepTab'
- let l:choice_map['T'] = 's:GrepTabs'
- let l:choice_map['B'] = 's:GrepBuffers'
- let l:choice_map['F'] = 's:GrepFiles'
- if l:key == l:escapeChar
- let l:stage = l:STAGE_GET_SEARCH_TEXT
- break
- elseif l:key == l:enterChar
- let l:stage = l:STAGE_GET_SEARCH_OPTIONS
- break
- elseif l:key == l:leftChar
- if l:searchLocation == 'W'
- let l:searchLocation = 'F'
- elseif l:searchLocation == 'V'
- let l:searchLocation = 'W'
- elseif l:searchLocation == 'T'
- let l:searchLocation = 'V'
- elseif l:searchLocation == 'B'
- let l:searchLocation = 'T'
- elseif l:searchLocation == 'F'
- let l:searchLocation = 'B'
- endif
- elseif l:key == l:rightChar
- if l:searchLocation == 'W'
- let l:searchLocation = 'V'
- elseif l:searchLocation == 'V'
- let l:searchLocation = 'T'
- elseif l:searchLocation == 'T'
- let l:searchLocation = 'B'
- elseif l:searchLocation == 'B'
- let l:searchLocation = 'F'
- elseif l:searchLocation == 'F'
- let l:searchLocation = 'W'
- endif
- elseif has_key(l:choice_map, l:char)
- let l:searchLocation = l:char
- endif
- endwhile
- let l:searchFunction = l:choice_map[l:searchLocation]
- elseif l:stage == l:STAGE_GET_SEARCH_OPTIONS
- while 1
- echohl Question | echon "Search Target: " | echohl Title | echon l:searchText
- echohl Question | echon " Search Location: "
- if l:searchLocation == 'W'
- echohl Title | echon 'WINDOW'
- elseif l:searchLocation == 'V'
- echohl Title | echon 'VISIBLE'
- elseif l:searchLocation == 'T'
- echohl Title | echon 'TABS'
- elseif l:searchLocation == 'B'
- echohl Title | echon 'BUFFERS'
- elseif l:searchLocation == 'F'
- echohl Title | echon 'FILES'
- endif
- echohl Question | echon ' Search Options: '
- if l:searchOptionMatchCase == 0
- echohl SpecialKey | echon "[C]" | echohl Question | echon "ase "
- else
- echohl WarningMsg | echon "[C]ase "
- endif
- if l:searchOptionMatchWholeWord == 0
- echohl SpecialKey | echon "[W]" | echohl Question | echon "hole "
- else
- echohl WarningMsg | echon "[W]hole "
- endif
- echohl Normal
- let l:key = getchar()
- let l:char = toupper(nr2char(l:key))
- redraw!
- "echon "\r\r"
- "echon ''
- let l:choice_map = {}
- let l:choice_map['C'] = 'let l:searchOptionMatchCase = !l:searchOptionMatchCase'
- let l:choice_map['W'] = 'let l:searchOptionMatchWholeWord = !l:searchOptionMatchWholeWord'
- if l:key == l:escapeChar
- let l:stage = l:STAGE_GET_SEARCH_LOCATION
- break
- elseif l:key == l:enterChar
- execute 'call ' . l:searchFunction . '("' . l:searchText . '", ' . l:searchOptionMatchCase . ', ' . l:searchOptionMatchWholeWord . ')'
- let l:stage = l:STAGE_DONE
- break
- elseif l:key == l:leftChar
- if !l:searchOptionMatchCase && !l:searchOptionMatchWholeWord
- let l:searchOptionMatchCase = 0
- let l:searchOptionMatchWholeWord = 1
- elseif l:searchOptionMatchCase && !l:searchOptionMatchWholeWord
- let l:searchOptionMatchCase = 0
- let l:searchOptionMatchWholeWord = 0
- elseif l:searchOptionMatchCase && l:searchOptionMatchWholeWord
- let l:searchOptionMatchCase = 1
- let l:searchOptionMatchWholeWord = 0
- elseif !l:searchOptionMatchCase && l:searchOptionMatchWholeWord
- let l:searchOptionMatchCase = 1
- let l:searchOptionMatchWholeWord = 1
- endif
- elseif l:key == l:rightChar
- if !l:searchOptionMatchCase && !l:searchOptionMatchWholeWord
- let l:searchOptionMatchCase = 1
- let l:searchOptionMatchWholeWord = 0
- elseif l:searchOptionMatchCase && !l:searchOptionMatchWholeWord
- let l:searchOptionMatchCase = 1
- let l:searchOptionMatchWholeWord = 1
- elseif l:searchOptionMatchCase && l:searchOptionMatchWholeWord
- let l:searchOptionMatchCase = 0
- let l:searchOptionMatchWholeWord = 1
- elseif !l:searchOptionMatchCase && l:searchOptionMatchWholeWord
- let l:searchOptionMatchCase = 0
- let l:searchOptionMatchWholeWord = 0
- endif
- elseif has_key(l:choice_map, l:char)
- execute(l:choice_map[l:char])
- endif
- endwhile
- endif
- endwhile
- catch /user\ cancelled\ providing\ input/
- finally
- let &guicursor = guicursor
- endtry
- endfunction
- nnoremap <S-F> :call DisplaySearchMenu()<CR>
- " NOTE: <C-u> removes the '<,'> visual-selection from the command line. See :h c_CTRL-u
- vnoremap <S-F> :<C-u>call DisplaySearchMenu()<CR>
- " }}} Bind Shift + F to display search options
- " Search windows, tabs, and files {{{
- " SOURCE: https://stackoverflow.com/questions/11975174/how-do-i-search-the-open-buffers-in-vim/11978447#11978447
- " This option controls the behavior when switching buffers
- " useopen, and usetab ensure that a new window|tab will not be created if an existing window|tab already contains the specified buffer.
- " newtab will open a new tab to display the buffers that are not open in any other window|tab.
- " NOTE: QuickFix commands are affected by this option
- " set switchbuf=useopen,usetab,newtab
- " Clear QuickFix window with :cclose
- " Clear location list for the current window with :lclose
- " NOTE: These are binded to F3 now, which also clears search highlights.
- " Looks for a pattern in the current buffer.
- " Usage :GrepBuffer [pattern] [matchCase] [matchWholeWord] [prefix]
- " If pattern is not specified then usage instructions will get printed.
- " If matchCase = '1' then exclude matches that do not have the same case. If matchCase = '0' then ignore case.
- " If prefix == 'c' then put results in the QuickFix list. If prefix == 'l' then put results in the location list for the current window.
- function! s:GrepBuffer(...)
- if a:0 > 4
- throw "Too many arguments"
- endif
- if a:0 >= 1
- let l:pattern = a:1
- else
- echo 'Usage :GrepBuffer [pattern] [matchCase] [matchWholeWord] [prefix]'
- return
- endif
- let l:matchCase = 0
- if a:0 >= 2
- if a:2 !~ '^\d\+$' || a:2 > 1 || a:2 < 0
- throw "ArgumentException: matchCase value '" . a:2 . "' is not in the bounds [0,1]."
- endif
- let l:matchCase = a:2
- endif
- let l:matchWholeWord = 0
- if a:0 >= 3
- if a:3 !~ '^\d\+$' || a:3 > 1 || a:3 < 0
- throw "ArgumentException: matchWholeWord value '" . a:3 . "' is not in the bounds [0,1]."
- endif
- let l:matchWholeWord = a:3
- endif
- let l:prefix = 'c'
- if a:0 >= 4
- if a:4 != 'c' && a:4 != 'l'
- throw "ArgumentException: prefix value '" . a:4 . "' is not 'c' or 'l'."
- endif
- let l:prefix = a:4
- endif
- let ignorecase = &ignorecase
- let &ignorecase = l:matchCase == 0
- try
- call s:BindArrowKeysToQuickFixNavigation()
- let str = ''
- if l:prefix == 'l'
- let str = 'l'
- endif
- if l:matchWholeWord
- let str = str . 'silent vimgrep /\<' . l:pattern . '\>/'
- else
- let str = str . 'silent vimgrep /' . l:pattern . '/'
- endif
- let currentBufnr = bufnr('%')
- if buflisted(currentBufnr) " Skips unlisted buffers because they are not used for normal editing
- if !bufexists(currentBufnr)
- throw 'Buffer does not exist: "' . currentBufnr . '"'
- elseif empty(bufname(currentBufnr)) && getbufvar(currentBufnr, '&buftype') != 'quickfix'
- if len(getbufline(currentBufnr, '2')) != 0 || strlen(getbufline(currentBufnr, '1')[0]) != 0
- echohl warningmsg | echomsg 'Skipping unnamed buffer: [' . currentBufnr . ']' | echohl normal
- endif
- else
- let str = str . ' ' . fnameescape(bufname(currentBufnr))
- endif
- endif
- try
- execute str
- catch /^Vim\%((\a\+)\)\=:E\%(683\|480\):/ "E683: File name missing or invalid pattern --- E480: No match:
- call s:RestoreArrowKeyBinds()
- echomsg v:exception
- endtry
- execute l:prefix . 'window'
- finally
- let &ignorecase = ignorecase
- endtry
- endfunction
- " Usage :GrepBuffer [pattern] [matchCase] [matchWholeWord] [prefix]
- command! -nargs=* GrepBuffer call s:GrepBuffer(<f-args>)
- " Usage :SearchBuffer [matchCase] [matchWholeWord] [prefix]
- " Use the word under the cursor as the pattern.
- command! -nargs=* SearchBuffer call s:CatchCancel('call s:GrepBuffer(s:GetSearchText(), <f-args>)')
- " Looks for a pattern in the open windows of the current tab.
- " Usage :GrepTab [pattern] [matchCase] [matchWholeWord] [prefix]
- " If pattern is not specified then usage instructions will get printed.
- " If matchCase = '1' then exclude matches that do not have the same case. If matchCase = '0' then ignore case.
- " If prefix == 'c' then put results in the QuickFix list. If prefix == 'l' then put results in the location list for the current window.
- function! s:GrepTab(...)
- if a:0 > 4
- throw "Too many arguments"
- endif
- if a:0 >= 1
- let l:pattern = a:1
- else
- echo 'Usage :GrepTab [pattern] [matchCase] [matchWholeWord] [prefix]'
- return
- endif
- let l:matchCase = 0
- if a:0 >= 2
- if a:2 !~ '^\d\+$' || a:2 > 1 || a:2 < 0
- throw "ArgumentException: matchCase value '" . a:2 . "' is not in the bounds [0,1]."
- endif
- let l:matchCase = a:2
- endif
- let l:matchWholeWord = 0
- if a:0 >= 3
- if a:3 !~ '^\d\+$' || a:3 > 1 || a:3 < 0
- throw "ArgumentException: matchWholeWord value '" . a:3 . "' is not in the bounds [0,1]."
- endif
- let l:matchWholeWord = a:3
- endif
- let l:prefix = 'c'
- if a:0 >= 4
- if a:4 != 'c' && a:4 != 'l'
- throw "ArgumentException: prefix value '" . a:4 . "' is not 'c' or 'l'."
- endif
- let l:prefix = a:4
- endif
- let ignorecase = &ignorecase
- let &ignorecase = l:matchCase == 0
- try
- call s:BindArrowKeysToQuickFixNavigation()
- let str = ''
- if l:prefix == 'l'
- let str = 'l'
- endif
- if l:matchWholeWord
- let str = str . 'silent vimgrep /\<' . l:pattern . '\>/'
- else
- let str = str . 'silent vimgrep /' . l:pattern . '/'
- endif
- let currentTabnr = tabpagenr()
- for bufnr in tabpagebuflist(currentTabnr)
- if buflisted(bufnr) " Skips unlisted buffers because they are not used for normal editing
- if !bufexists(bufnr)
- throw 'Buffer does not exist: "' . bufnr . '"'
- elseif empty(bufname(bufnr)) && getbufvar(bufnr, '&buftype') != 'quickfix'
- if len(getbufline(bufnr, '2')) != 0 || strlen(getbufline(bufnr, '1')[0]) != 0
- echohl warningmsg | echomsg 'Skipping unnamed buffer: [' . bufnr . ']' | echohl normal
- endif
- else
- let str = str . ' ' . fnameescape(bufname(bufnr))
- endif
- endif
- endfor
- try
- execute str
- catch /^Vim\%((\a\+)\)\=:E\%(683\|480\):/ "E683: File name missing or invalid pattern --- E480: No match:
- call s:RestoreArrowKeyBinds()
- echomsg v:exception
- endtry
- execute l:prefix . 'window'
- finally
- let &ignorecase = ignorecase
- endtry
- endfunction
- " Usage :GrepTab [pattern] [matchCase] [matchWholeWord] [prefix]
- command! -nargs=* GrepTab call s:GrepTab(<f-args>)
- " Usage :SearchTab [matchCase] [matchWholeWord] [prefix]
- " Use the word under the cursor as the pattern.
- command! -nargs=* SearchTab call s:CatchCancel('call s:GrepTab(s:GetSearchText(), <f-args>)')
- " Looks for a pattern in the open windows of every tab.
- " Usage :GrepTabs [pattern] [matchCase] [matchWholeWord] [prefix]
- " If pattern is not specified then usage instructions will get printed.
- " If matchCase = '1' then exclude matches that do not have the same case. If matchCase = '0' then ignore case.
- " If prefix == 'c' then put results in the QuickFix list. If prefix == 'l' then put results in the location list for the current window.
- function! s:GrepTabs(...)
- if a:0 > 4
- throw "Too many arguments"
- endif
- if a:0 >= 1
- let l:pattern = a:1
- else
- echo 'Usage :GrepTabs [pattern] [matchCase] [matchWholeWord] [prefix]'
- return
- endif
- let l:matchCase = 0
- if a:0 >= 2
- if a:2 !~ '^\d\+$' || a:2 > 1 || a:2 < 0
- throw "ArgumentException: matchCase value '" . a:2 . "' is not in the bounds [0,1]."
- endif
- let l:matchCase = a:2
- endif
- let l:matchWholeWord = 0
- if a:0 >= 3
- if a:3 !~ '^\d\+$' || a:3 > 1 || a:3 < 0
- throw "ArgumentException: matchWholeWord value '" . a:3 . "' is not in the bounds [0,1]."
- endif
- let l:matchWholeWord = a:3
- endif
- let l:prefix = 'c'
- if a:0 >= 4
- if a:4 != 'c' && a:4 != 'l'
- throw "ArgumentException: prefix value '" . a:4 . "' is not 'c' or 'l'."
- endif
- let l:prefix = a:4
- endif
- let ignorecase = &ignorecase
- let &ignorecase = l:matchCase == 0
- try
- call s:BindArrowKeysToQuickFixNavigation()
- let str = ''
- if l:prefix == 'l'
- let str = 'l'
- endif
- if l:matchWholeWord
- let str = str . 'silent vimgrep /\<' . l:pattern . '\>/'
- else
- let str = str . 'silent vimgrep /' . l:pattern . '/'
- endif
- for buf in getbufinfo()
- if buflisted(buf.bufnr) " Skips unlisted buffers because they are not used for normal editing
- if !empty(buf.windows) " Skip buffers that have no associated windows
- if !bufexists(buf.bufnr)
- throw 'Buffer does not exist: "' . buf.bufnr . '"'
- elseif empty(bufname(buf.bufnr)) && getbufvar(buf.bufnr, '&buftype') != 'quickfix'
- if len(getbufline(buf.bufnr, '2')) != 0 || strlen(getbufline(buf.bufnr, '1')[0]) != 0
- echohl warningmsg | echomsg 'Skipping unnamed buffer: [' . buf.bufnr . ']' | echohl normal
- endif
- else
- let str = str . ' ' . fnameescape(bufname(buf.bufnr))
- endif
- endif
- endif
- endfor
- try
- execute str
- catch /^Vim\%((\a\+)\)\=:E\%(683\|480\):/ "E683: File name missing or invalid pattern --- E480: No match:
- call s:RestoreArrowKeyBinds()
- echomsg v:exception
- endtry
- execute l:prefix . 'window'
- finally
- let &ignorecase = ignorecase
- endtry
- endfunction
- " Usage :GrepTabs [pattern] [matchCase] [matchWholeWord] [prefix]
- command! -nargs=* GrepTabs call s:GrepTabs(<f-args>)
- " Usage :SearchTabs [matchCase] [matchWholeWord] [prefix]
- " Use the word under the cursor as the pattern.
- command! -nargs=* SearchTabs call s:CatchCancel('call s:GrepTabs(s:GetSearchText(), <f-args>)')
- " Looks for a pattern in the buffers.
- " Usage :GrepBuffers [pattern] [matchCase] [matchWholeWord] [prefix]
- " If pattern is not specified then usage instructions will get printed.
- " If matchCase = '1' then exclude matches that do not have the same case. If matchCase = '0' then ignore case.
- " If prefix == 'c' then put results in the QuickFix list. If prefix == 'l' then put results in the location list for the current window.
- function! s:GrepBuffers(...)
- if a:0 > 4
- throw "Too many arguments"
- endif
- if a:0 >= 1
- let l:pattern = a:1
- else
- echo 'Usage :GrepBuffers [pattern] [matchCase] [matchWholeWord] [prefix]'
- return
- endif
- let l:matchCase = 0
- if a:0 >= 2
- if a:2 !~ '^\d\+$' || a:2 > 1 || a:2 < 0
- throw "ArgumentException: matchCase value '" . a:2 . "' is not in the bounds [0,1]."
- endif
- let l:matchCase = a:2
- endif
- let l:matchWholeWord = 0
- if a:0 >= 3
- if a:3 !~ '^\d\+$' || a:3 > 1 || a:3 < 0
- throw "ArgumentException: matchWholeWord value '" . a:3 . "' is not in the bounds [0,1]."
- endif
- let l:matchWholeWord = a:3
- endif
- let l:prefix = 'c'
- if a:0 >= 4
- if a:4 != 'c' && a:4 != 'l'
- throw "ArgumentException: prefix value '" . a:4 . "' is not 'c' or 'l'."
- endif
- let l:prefix = a:4
- endif
- let ignorecase = &ignorecase
- let &ignorecase = l:matchCase == 0
- try
- call s:BindArrowKeysToQuickFixNavigation()
- let str = ''
- if l:prefix == 'l'
- let str = 'l'
- endif
- if l:matchWholeWord
- let str = str . 'silent vimgrep /\<' . l:pattern . '\>/'
- else
- let str = str . 'silent vimgrep /' . l:pattern . '/'
- endif
- for buf in getbufinfo()
- if buflisted(buf.bufnr) " Skips unlisted buffers because they are not used for normal editing
- if !bufexists(buf.bufnr)
- throw 'Buffer does not exist: "' . buf.bufnr . '"'
- elseif empty(bufname(buf.bufnr)) && getbufvar(buf.bufnr, '&buftype') != 'quickfix'
- if len(getbufline(buf.bufnr, '2')) != 0 || strlen(getbufline(buf.bufnr, '1')[0]) != 0
- echohl warningmsg | echomsg 'Skipping unnamed buffer: [' . buf.bufnr . ']' | echohl normal
- endif
- else
- let str = str . ' ' . fnameescape(bufname(buf.bufnr))
- endif
- endif
- endfor
- try
- execute str
- catch /^Vim\%((\a\+)\)\=:E\%(683\|480\):/ "E683: File name missing or invalid pattern --- E480: No match:
- call s:RestoreArrowKeyBinds()
- echomsg v:exception
- endtry
- execute l:prefix . 'window'
- finally
- let &ignorecase = ignorecase
- endtry
- endfunction
- " Usage :GrepBuffers [pattern] [matchCase] [matchWholeWord] [prefix]
- command! -nargs=* GrepBuffers call s:GrepBuffers(<f-args>)
- " Usage :SearchBuffers [matchCase] [matchWholeWord] [prefix]
- " Use the word under the cursor as the pattern.
- command! -nargs=* SearchBuffers call s:CatchCancel('call s:GrepBuffers(s:GetSearchText(), <f-args>)')
- " Looks for a pattern in the PWD and subdirectories of PWD.
- " Usage :GrepFiles [pattern] [matchCase] [matchWholeWord] [prefix]
- " If pattern is not specified then usage instructions will get printed.
- " If matchCase = '1' then exclude matches that do not have the same case. If matchCase = '0' then ignore case.
- " If prefix == 'c' then put results in the QuickFix list. If prefix == 'l' then put results in the location list for the current window.
- function! s:GrepFiles(...)
- if a:0 > 4
- throw "Too many arguments"
- endif
- if a:0 >= 1
- let l:pattern = a:1
- else
- echo 'Usage :GrepFiles [pattern] [matchCase] [matchWholeWord] [prefix]'
- return
- endif
- let l:matchCase = 0
- if a:0 >= 2
- if a:2 !~ '^\d\+$' || a:2 > 1 || a:2 < 0
- throw "ArgumentException: matchCase value '" . a:2 . "' is not in the bounds [0,1]."
- endif
- let l:matchCase = a:2
- endif
- let l:matchWholeWord = 0
- if a:0 >= 3
- if a:3 !~ '^\d\+$' || a:3 > 1 || a:3 < 0
- throw "ArgumentException: matchWholeWord value '" . a:3 . "' is not in the bounds [0,1]."
- endif
- let l:matchWholeWord = a:3
- endif
- let l:prefix = 'c'
- if a:0 >= 4
- if a:4 != 'c' && a:4 != 'l'
- throw "ArgumentException: prefix value '" . a:4 . "' is not 'c' or 'l'."
- endif
- let l:prefix = a:4
- endif
- let ignorecase = &ignorecase
- let &ignorecase = l:matchCase == 0
- try
- call s:BindArrowKeysToQuickFixNavigation()
- let str = ''
- if l:prefix == 'l'
- let str = 'l'
- endif
- if l:matchWholeWord
- let str = str . 'silent vimgrep /\<' . l:pattern . '\>/**'
- else
- let str = str . 'silent vimgrep /' . l:pattern . '/**'
- endif
- try
- execute str
- catch /^Vim\%((\a\+)\)\=:E\%(683\|480\):/ "E683: File name missing or invalid pattern --- E480: No match:
- call s:RestoreArrowKeyBinds()
- echomsg v:exception
- endtry
- execute l:prefix . 'window'
- finally
- let &ignorecase = ignorecase
- endtry
- endfunction
- " Usage :GrepFiles [pattern] [matchCase] [matchWholeWord] [prefix]
- command! -nargs=* GrepFiles call s:GrepFiles(<f-args>)
- " Usage :SearchFiles [matchCase] [matchWholeWord] [prefix]
- " Use the word under the cursor as the pattern.
- command! -nargs=* SearchFiles call s:CatchCancel('call s:GrepFiles(s:GetSearchText(), <f-args>)')
- function! s:GetSearchText(...)
- if a:0 > 1
- throw "Too many arguments"
- endif
- let l:searchText = ''
- if a:0 >= 1 && l:searchText != a:1
- return s:GetTextInputFromUser("Search Target: ", a:1, 0)
- endif
- let l:visualSelection = s:GetVisualSelection()
- if len(l:visualSelection) > 0
- call s:ClearVisualSelection()
- return s:GetTextInputFromUser("Search Target: ", l:visualSelection, 0)
- else
- let l:wordUnderCursor = expand('<cword>')
- if len(l:wordUnderCursor) > 0
- return s:GetTextInputFromUser("Search Target: ", l:wordUnderCursor, 0)
- else
- return s:GetTextInputFromUser("Search Target: ", '', 0)
- endif
- endif
- endfunction
- function! s:CatchCancel(searchFunction)
- try
- execute a:searchFunction
- catch /user\ cancelled\ providing\ input/
- endtry
- endfunction
- " Provides a way to ask the user for text input.
- " The following editing keys are provided and work as expected in normal editors: Backspace, Delete, Left, Right, Home, End.
- " The user can cancel with Escape and submit text input with Enter.
- " You can also select text and do command-line copy|paste commands.
- "
- " Usage: let userInput = s:GetTextInputFromUser([inputRequest], [suggestedUserInput], [displayButtons])
- " Returns: Whatever the text state was when the user hit Enter. Can be ''.
- "
- " inputRequest - The question you want to ask the user, it can be '', and appears on the commandline left of the users entered text.
- " suggestedUserInput - Allows you to provide an initial version of the text you intend the user to modify and send back.
- " displayButtons - [0, 1] Display the "[Escape] [Enter]" buttons.
- "
- " Note: If the user cancels providing input, you need to handle the thrown exception like so: try | <code> | catch /user\ cancelled\ providing\ input/ | endtry
- "
- " Example: let userInput = s:GetTextInputFromUser("How many times have you been turned down for a job? ")
- " let userInput = s:GetTextInputFromUser("Gender: ", "Attack Helicopter", 1)
- "
- " If you don't like what the user is sending you, then just send it right back with a better request message.
- " let pushTheButton = s:GetTextInputFromUser("Bomb North Korea? Say yes asshole! ", pushTheButton)
- function! s:GetTextInputFromUser(...)
- if a:0 > 3
- throw "Too many arguments"
- endif
- let inputRequest = ''
- if a:0 >= 1
- let inputRequest = a:1
- endif
- let text = ''
- if a:0 >= 2
- let text = a:2
- endif
- let displayButtons = 1
- if a:0 >= 3
- if a:3 !~ '^\d\+$' || a:3 > 1 || a:3 < 0
- throw "ArgumentException: displayButtons value '" . a:3 . "' is not in the bounds [0,1]."
- endif
- let displayButtons = a:3
- endif
- if displayButtons
- echohl SpecialKey | echon "[Escape] "
- echohl SpecialKey | echon "[Enter] "
- endif
- call inputsave()
- echohl Question
- let text = input(inputRequest, text)
- echohl Normal
- call inputrestore()
- " Clear input prompt after input is entered
- redraw!
- " If the user enters '' or hits escape
- if text == ''
- throw "user cancelled providing input"
- endif
- return text
- endfunction
- " SOURCE: https://stackoverflow.com/a/6271254/490748
- function! s:GetVisualSelection()
- " Why is this not a built-in Vim script function?!
- let [line_start, column_start] = getpos("'<")[1:2]
- let [line_end, column_end] = getpos("'>")[1:2]
- let lines = getline(line_start, line_end)
- if len(lines) == 0
- return ''
- endif
- let lines[-1] = lines[-1][: column_end - (&selection == 'inclusive' ? 1 : 2)]
- let lines[0] = lines[0][column_start - 1:]
- return join(lines, "\n")
- endfunction
- function! s:ClearVisualSelection()
- call setpos("'<", [0, 0, 0, 0])
- call setpos("'>", [0, 0, 0, 0])
- endfunction
- function! s:BindArrowKeysToQuickFixNavigation()
- nnoremap <silent> <left> :call WrapCommand('up', 'c')<CR><BAR>:cwindow<CR>|
- nnoremap <silent> <right> :call WrapCommand('down', 'c')<CR><BAR>:cwindow<CR>|
- nnoremap <silent> <up> :call WrapCommand('up', 'c')<CR><BAR>:cwindow<CR>|
- nnoremap <silent> <down> :call WrapCommand('down', 'c')<CR><BAR>:cwindow<CR>|
- inoremap <silent> <left> <Esc>:call WrapCommand('up', 'c')<CR><BAR>:cwindow<CR>|
- inoremap <silent> <right> <Esc>:call WrapCommand('down', 'c')<CR><BAR>:cwindow<CR>|
- inoremap <silent> <up> <Esc>:call WrapCommand('up', 'c')<CR><BAR>:cwindow<CR>|
- inoremap <silent> <down> <Esc>:call WrapCommand('down', 'c')<CR><BAR>:cwindow<CR>|
- endfunction
- function! s:RestoreArrowKeyBinds()
- nnoremap <silent> <left> <left>|
- nnoremap <silent> <right> <right>|
- nnoremap <silent> <up> <up>|
- nnoremap <silent> <down> <down>|
- inoremap <silent> <left> <left>|
- inoremap <silent> <right> <right>|
- inoremap <silent> <up> <up>|
- inoremap <silent> <down> <down>|
- endfunction
- " SOURCE: https://stackoverflow.com/questions/27198612/vim-location-list-how-to-go-to-first-location-if-at-last-location
- " Wrap :cnext/:cprevious and :lnext/:lprevious so that when a limit is encountered that it starts over at the opposite end of the list"
- function! WrapCommand(direction, prefix)
- let l:hidden = &hidden
- set nohidden " Disable to prevent creating lots of empty buffers when doing a vimgrep followed by QuickFix navigation commands
- try
- if a:direction == "up"
- try
- execute a:prefix . "previous"
- catch /^Vim\%((\a\+)\)\=:E553/
- execute a:prefix . "last"
- catch /^Vim\%((\a\+)\)\=:E\%(776\|42\):/
- endtry
- elseif a:direction == "down"
- try
- execute a:prefix . "next"
- catch /^Vim\%((\a\+)\)\=:E553/
- execute a:prefix . "first"
- catch /^Vim\%((\a\+)\)\=:E\%(776\|42\):/
- endtry
- endif
- finally
- let &hidden = l:hidden
- endtry
- endfunction
- "function! s:IsQuickFixAvailable()
- " return !empty(getqflist())
- "endfunction
- "
- "function! IsQuickFixClosed()
- " for win in getwininfo()
- " if win.quickfix
- " return 0
- " endif
- " endfor
- " return 1
- "endfunction
- " }}} Search windows, tabs, and files
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement