--- /dev/null
+Project
+ [ Project
+ [ Unit
+ [ FunctionDeclaration
+ { functionBang = True
+ , functionName = "loupe#private#very_magic_slash"
+ , functionArguments = ArgumentList []
+ , functionAttributes = [ "abort" ]
+ , functionBody =
+ [ GenericStatement "if getcmdtype() != ':'"
+ , GenericStatement "return '/'"
+ , GenericStatement "endif"
+ , LetStatement { letLexpr = "l:pos" , letValue = "getcmdpos()" }
+ , LetStatement { letLexpr = "l:cmd" , letValue = "getcmdline()" }
+ , GenericStatement "if len(l:cmd) + 1 != l:pos"
+ , GenericStatement "return '/'"
+ , GenericStatement "endif"
+ , GenericStatement "while 1"
+ , LetStatement
+ { letLexpr = "l:stripped" , letValue = "s:strip_ranges(l:cmd)" }
+ , GenericStatement "if l:stripped ==# l:cmd"
+ , GenericStatement "break"
+ , GenericStatement "else"
+ , LetStatement { letLexpr = "l:cmd" , letValue = "l:stripped" }
+ , GenericStatement "endif"
+ , GenericStatement "endwhile"
+ , GenericStatement "if index(['g', 's', 'v'], l:cmd) != -1"
+ , GenericStatement "return loupe#private#prepare_highlight('/\\v')"
+ , GenericStatement "endif"
+ , GenericStatement "return '/'"
+ ]
+ }
+ , FunctionDeclaration
+ { functionBang = True
+ , functionName = "s:strip_ranges"
+ , functionArguments = ArgumentList [ Argument "cmdline" ]
+ , functionAttributes = []
+ , functionBody =
+ [ LetStatement { letLexpr = "l:cmdline" , letValue = "a:cmdline" }
+ , LetStatement
+ { letLexpr = "l:modifier" , letValue = "'\\([+-]\\d*\\)*'" }
+ , LetStatement
+ { letLexpr = "l:cmdline"
+ , letValue =
+ "substitute(l:cmdline, '^\\d\\+' . l:modifier, '', '') \" line number"
+ }
+ , LetStatement
+ { letLexpr = "l:cmdline"
+ , letValue =
+ "substitute(l:cmdline, '^\\.' . l:modifier, '', '') \" current line"
+ }
+ , LetStatement
+ { letLexpr = "l:cmdline"
+ , letValue =
+ "substitute(l:cmdline, '^$' . l:modifier, '', '') \" last line in file"
+ }
+ , LetStatement
+ { letLexpr = "l:cmdline"
+ , letValue =
+ "substitute(l:cmdline, '^%' . l:modifier, '', '') \" entire file"
+ }
+ , LetStatement
+ { letLexpr = "l:cmdline"
+ , letValue =
+ "substitute(l:cmdline, \"^'[a-z]\\\\c\" . l:modifier, '', '') \" mark t (or T)"
+ }
+ , LetStatement
+ { letLexpr = "l:cmdline"
+ , letValue =
+ "substitute(l:cmdline, \"^'[<>]\" . l:modifier, '', '') \" visual selection marks"
+ }
+ , LetStatement
+ { letLexpr = "l:cmdline"
+ , letValue =
+ "substitute(l:cmdline, '^/[^/]\\+/' . l:modifier, '', '') \" /{pattern}/"
+ }
+ , LetStatement
+ { letLexpr = "l:cmdline"
+ , letValue =
+ "substitute(l:cmdline, '^?[^?]\\+?' . l:modifier, '', '') \" ?{pattern}?"
+ }
+ , LetStatement
+ { letLexpr = "l:cmdline"
+ , letValue =
+ "substitute(l:cmdline, '^\\\\/' . l:modifier, '', '') \" \\/ (next match of previous pattern)"
+ }
+ , LetStatement
+ { letLexpr = "l:cmdline"
+ , letValue =
+ "substitute(l:cmdline, '^\\\\?' . l:modifier, '', '') \" \\? (last match of previous pattern)"
+ }
+ , LetStatement
+ { letLexpr = "l:cmdline"
+ , letValue =
+ "substitute(l:cmdline, '^\\\\&' . l:modifier, '', '') \" \\& (last match of previous substitution)"
+ }
+ , LetStatement
+ { letLexpr = "l:cmdline"
+ , letValue = "substitute(l:cmdline, '^,', '', '') \" , (separator)"
+ }
+ , LetStatement
+ { letLexpr = "l:cmdline"
+ , letValue = "substitute(l:cmdline, '^;', '', '') \" ; (separator)"
+ }
+ , GenericStatement "return l:cmdline"
+ ]
+ }
+ , FunctionDeclaration
+ { functionBang = True
+ , functionName = "loupe#private#prepare_highlight"
+ , functionArguments = ArgumentList [ Argument "result" ]
+ , functionAttributes = [ "abort" ]
+ , functionBody =
+ [ GenericStatement "if has('autocmd')"
+ , GenericStatement "augroup LoupeHightlightMatch"
+ , GenericStatement "autocmd!"
+ , GenericStatement
+ "autocmd CursorMoved * :call loupe#private#hlmatch()"
+ , GenericStatement "augroup END"
+ , GenericStatement "endif"
+ , GenericStatement "return a:result"
+ ]
+ }
+ , FunctionDeclaration
+ { functionBang = True
+ , functionName = "loupe#private#clear_highlight"
+ , functionArguments = ArgumentList []
+ , functionAttributes = [ "abort" ]
+ , functionBody =
+ [ GenericStatement "if exists('w:loupe_hlmatch')"
+ , GenericStatement "try"
+ , GenericStatement "call matchdelete(w:loupe_hlmatch)"
+ , GenericStatement "catch /\\v<(E802|E803)>/"
+ , GenericStatement "finally"
+ , UnletStatement
+ { unletBang = False , unletBody = "w:loupe_hlmatch" }
+ , GenericStatement "endtry"
+ , GenericStatement "endif"
+ ]
+ }
+ , FunctionDeclaration
+ { functionBang = True
+ , functionName = "loupe#private#cleanup"
+ , functionArguments = ArgumentList []
+ , functionAttributes = [ "abort" ]
+ , functionBody =
+ [ GenericStatement "if !v:hlsearch"
+ , GenericStatement "call loupe#private#clear_highlight()"
+ , GenericStatement "endif"
+ ]
+ }
+ , FunctionDeclaration
+ { functionBang = True
+ , functionName = "loupe#private#hlmatch"
+ , functionArguments = ArgumentList []
+ , functionAttributes = [ "abort" ]
+ , functionBody =
+ [ LetStatement
+ { letLexpr = "l:highlight"
+ , letValue = "get(g:, 'LoupeHighlightGroup', 'IncSearch')"
+ }
+ , GenericStatement "if empty(l:highlight)"
+ , GenericStatement "return"
+ , GenericStatement "endif"
+ , GenericStatement "if has('autocmd')"
+ , GenericStatement "augroup LoupeHightlightMatch"
+ , GenericStatement "autocmd!"
+ , GenericStatement "augroup END"
+ , GenericStatement "endif"
+ , GenericStatement "call loupe#private#clear_highlight()"
+ , LetStatement
+ { letLexpr = "l:pattern" , letValue = "'\\c\\%#' . @/" }
+ , GenericStatement "if exists('*matchadd')"
+ , LetStatement
+ { letLexpr = "w:loupe_hlmatch"
+ , letValue = "matchadd(l:highlight, l:pattern)"
+ }
+ , GenericStatement "endif"
+ ]
+ }
+ ]
+ , Unit
+ [ GenericStatement
+ "if exists('g:LoupeLoaded') || &compatible || v:version < 700"
+ , GenericStatement "finish"
+ , GenericStatement "endif"
+ , LetStatement { letLexpr = "g:LoupeLoaded" , letValue = "1" }
+ , LetStatement
+ { letLexpr = "s:cpoptions" , letValue = "&cpoptions" }
+ , GenericStatement "set cpoptions&vim"
+ , GenericStatement "if &history < 1000"
+ , GenericStatement
+ "set history=1000 \" Longer search and command history (default is 50)."
+ , GenericStatement "endif"
+ , GenericStatement "if has('extra_search')"
+ , GenericStatement "set hlsearch \" Highlight search strings."
+ , GenericStatement
+ "set incsearch \" Incremental search (\"find as you type\")."
+ , GenericStatement "endif"
+ , GenericStatement "set ignorecase \" Ignore case when searching."
+ , GenericStatement
+ "set shortmess+=s \" Don't echo search wrap messages."
+ , GenericStatement
+ "set smartcase \" Case-sensitive search if search string includes a capital letter."
+ , LetStatement
+ { letLexpr = "s:map"
+ , letValue = "get(g:, 'LoupeClearHighlightMap', 1)"
+ }
+ , GenericStatement "if s:map"
+ , GenericStatement
+ "if !hasmapto('<Plug>(LoupeClearHighlight)') && maparg('<leader>n', 'n') ==# ''"
+ , GenericStatement
+ "nmap <silent> <unique> <leader>n <Plug>(LoupeClearHighlight)"
+ , GenericStatement "endif"
+ , GenericStatement "endif"
+ , GenericStatement
+ "nnoremap <silent> <Plug>(LoupeClearHighlight) :nohlsearch<CR> :call loupe#private#clear_highlight()<CR>"
+ , GenericStatement
+ "cabbrev <silent> <expr> noh (getcmdtype() == ':' && getcmdpos() == 4 ? 'noh <bar> call loupe#private#clear_highlight()<CR>' : 'noh')"
+ , GenericStatement
+ "cabbrev <silent> <expr> nohl (getcmdtype() == ':' && getcmdpos() == 5 ? 'nohl <bar> call loupe#private#clear_highlight()<CR>' : 'nohl')"
+ , GenericStatement
+ "cabbrev <silent> <expr> nohls (getcmdtype() == ':' && getcmdpos() == 6 ? 'nohls <bar> call loupe#private#clear_highlight()<CR>' : 'nohls')"
+ , GenericStatement
+ "cabbrev <silent> <expr> nohlse (getcmdtype() == ':' && getcmdpos() == 7 ? 'nohlse <bar> call loupe#private#clear_highlight()<CR>' : 'nohlse')"
+ , GenericStatement
+ "cabbrev <silent> <expr> nohlsea (getcmdtype() == ':' && getcmdpos() == 8 ? 'nohlsea <bar> call loupe#private#clear_highlight()<CR>' : 'nohlsea')"
+ , GenericStatement
+ "cabbrev <silent> <expr> nohlsear (getcmdtype() == ':' && getcmdpos() == 9 ? 'nohlsear <bar> call loupe#private#clear_highlight()<CR>' : 'nohlsear')"
+ , GenericStatement
+ "cabbrev <silent> <expr> nohlsearc (getcmdtype() == ':' && getcmdpos() == 10 ? 'nohlsearc <bar> call loupe#private#clear_highlight()<CR>' : 'nohlsearc')"
+ , GenericStatement
+ "cabbrev <silent> <expr> nohlsearch (getcmdtype() == ':' && getcmdpos() == 11 ? 'nohlsearch <bar> call loupe#private#clear_highlight()<CR>' : 'nohlsearch')"
+ , FunctionDeclaration
+ { functionBang = False
+ , functionName = "s:MagicString"
+ , functionArguments = ArgumentList []
+ , functionAttributes = []
+ , functionBody =
+ [ LetStatement
+ { letLexpr = "s:magic"
+ , letValue = "get(g:, 'LoupeVeryMagic', 1)"
+ }
+ , GenericStatement "return s:magic ? '\\v' : ''"
+ ]
+ }
+ , GenericStatement
+ "nnoremap <expr> / loupe#private#prepare_highlight('/' . <SID>MagicString())"
+ , GenericStatement
+ "nnoremap <expr> ? loupe#private#prepare_highlight('?' . <SID>MagicString())"
+ , GenericStatement
+ "xnoremap <expr> / loupe#private#prepare_highlight('/' . <SID>MagicString())"
+ , GenericStatement
+ "xnoremap <expr> ? loupe#private#prepare_highlight('?' . <SID>MagicString())"
+ , GenericStatement "if !empty(s:MagicString())"
+ , GenericStatement
+ "cnoremap <expr> / loupe#private#very_magic_slash()"
+ , GenericStatement "endif"
+ , LetStatement
+ { letLexpr = "s:center"
+ , letValue = "get(g:, 'LoupeCenterResults', 1)"
+ }
+ , LetStatement
+ { letLexpr = "s:center_string"
+ , letValue = "s:center ? 'zz' : ''"
+ }
+ , GenericStatement
+ "execute 'nnoremap <silent> # #' . s:center_string . ':call loupe#private#hlmatch()<CR>'"
+ , GenericStatement
+ "execute 'nnoremap <silent> * *' . s:center_string . ':call loupe#private#hlmatch()<CR>'"
+ , GenericStatement
+ "execute 'nnoremap <silent> N N' . s:center_string . ':call loupe#private#hlmatch()<CR>'"
+ , GenericStatement
+ "execute 'nnoremap <silent> g# g#' . s:center_string . ':call loupe#private#hlmatch()<CR>'"
+ , GenericStatement
+ "execute 'nnoremap <silent> g* g*' . s:center_string . ':call loupe#private#hlmatch()<CR>'"
+ , GenericStatement
+ "execute 'nnoremap <silent> n n' . s:center_string . ':call loupe#private#hlmatch()<CR>'"
+ , GenericStatement "if has('autocmd') && has('extra_search')"
+ , GenericStatement "augroup LoupeCleanUp"
+ , GenericStatement "autocmd!"
+ , GenericStatement
+ "autocmd WinEnter * :call loupe#private#cleanup()"
+ , GenericStatement "augroup END"
+ , GenericStatement "endif"
+ , LetStatement
+ { letLexpr = "&cpoptions" , letValue = "s:cpoptions" }
+ , UnletStatement { unletBang = False , unletBody = "s:cpoptions" }
+ ]
+ ]
+ ]
--- /dev/null
+" Copyright 2015-present Greg Hurrell. All rights reserved.
+" Licensed under the terms of the BSD 2-clause license.
+
+" Dynamically returns "/" or "/\v" depending on the location of the just-typed
+" "/" within the command-line. Only "/" that looks to be at the start of a
+" command gets replaced.
+"
+" Doesn't handle the full list of possible range types (specified in `:h
+" cmdline-ranges`), but catches the most common ones.
+function! loupe#private#very_magic_slash() abort
+ if getcmdtype() != ':'
+ return '/'
+ endif
+
+ " For simplicity, only consider "/" typed at the end of the command-line.
+ let l:pos=getcmdpos()
+ let l:cmd=getcmdline()
+ if len(l:cmd) + 1 != l:pos
+ return '/'
+ endif
+
+ " Skip over ranges
+ while 1
+ let l:stripped=s:strip_ranges(l:cmd)
+ if l:stripped ==# l:cmd
+ break
+ else
+ let l:cmd=l:stripped
+ endif
+ endwhile
+
+ if index(['g', 's', 'v'], l:cmd) != -1
+ return loupe#private#prepare_highlight('/\v')
+ endif
+
+ return '/'
+endfunction
+
+function! s:strip_ranges(cmdline)
+ let l:cmdline=a:cmdline
+
+ " All the range tokens may be followed (several times) by '+' or '-' and an
+ " optional number.
+ let l:modifier='\([+-]\d*\)*'
+
+ " Range tokens as specified in `:h cmdline-ranges`.
+ let l:cmdline=substitute(l:cmdline, '^\d\+' . l:modifier, '', '') " line number
+ let l:cmdline=substitute(l:cmdline, '^\.' . l:modifier, '', '') " current line
+ let l:cmdline=substitute(l:cmdline, '^$' . l:modifier, '', '') " last line in file
+ let l:cmdline=substitute(l:cmdline, '^%' . l:modifier, '', '') " entire file
+ let l:cmdline=substitute(l:cmdline, "^'[a-z]\\c" . l:modifier, '', '') " mark t (or T)
+ let l:cmdline=substitute(l:cmdline, "^'[<>]" . l:modifier, '', '') " visual selection marks
+ let l:cmdline=substitute(l:cmdline, '^/[^/]\+/' . l:modifier, '', '') " /{pattern}/
+ let l:cmdline=substitute(l:cmdline, '^?[^?]\+?' . l:modifier, '', '') " ?{pattern}?
+ let l:cmdline=substitute(l:cmdline, '^\\/' . l:modifier, '', '') " \/ (next match of previous pattern)
+ let l:cmdline=substitute(l:cmdline, '^\\?' . l:modifier, '', '') " \? (last match of previous pattern)
+ let l:cmdline=substitute(l:cmdline, '^\\&' . l:modifier, '', '') " \& (last match of previous substitution)
+
+ " Separators (see: `:h :,` and `:h :;`).
+ let l:cmdline=substitute(l:cmdline, '^,', '', '') " , (separator)
+ let l:cmdline=substitute(l:cmdline, '^;', '', '') " ; (separator)
+
+ return l:cmdline
+endfunction
+
+" Prepare to highlight the match as soon as the cursor moves to it.
+function! loupe#private#prepare_highlight(result) abort
+ if has('autocmd')
+ augroup LoupeHightlightMatch
+ autocmd!
+ autocmd CursorMoved * :call loupe#private#hlmatch()
+ augroup END
+ endif
+ return a:result
+endfunction
+
+" Clear previously applied match highlighting.
+function! loupe#private#clear_highlight() abort
+ if exists('w:loupe_hlmatch')
+ try
+ call matchdelete(w:loupe_hlmatch)
+ catch /\v<(E802|E803)>/
+ " https://github.com/wincent/loupe/issues/1
+ finally
+ unlet w:loupe_hlmatch
+ endtry
+ endif
+endfunction
+
+" Called from WinEnter autocmd to clean up stray `matchadd()` vestiges.
+" If we switch into a window and there is no 'hlsearch' in effect but we do have
+" a `w:loupe_hlmatch` variable, it means that `:nohighight` was probably run
+" from another window and we should clean up the straggling match and the
+" window-local variable.
+function! loupe#private#cleanup() abort
+ if !v:hlsearch
+ call loupe#private#clear_highlight()
+ endif
+endfunction
+
+" Apply highlighting to the current search match.
+function! loupe#private#hlmatch() abort
+ " When g:loupeHighlight is set (and it is set to "IncSearch" by default), use
+ " that highlight group to make the current search result stand out.
+ let l:highlight=get(g:, 'LoupeHighlightGroup', 'IncSearch')
+ if empty(l:highlight)
+ return
+ endif
+
+ if has('autocmd')
+ augroup LoupeHightlightMatch
+ autocmd!
+ augroup END
+ endif
+
+ call loupe#private#clear_highlight()
+
+ " \c case insensitive
+ " \%# current cursor position
+ " @/ current search pattern
+ let l:pattern='\c\%#' . @/
+
+ if exists('*matchadd')
+ let w:loupe_hlmatch=matchadd(l:highlight, l:pattern)
+ endif
+endfunction
--- /dev/null
+" Copyright 2015-present Greg Hurrell. All rights reserved.
+" Licensed under the terms of the BSD 2-clause license.
+
+" Provide users with means to prevent loading, as recommended in `:h
+" write-plugin`.
+if exists('g:LoupeLoaded') || &compatible || v:version < 700
+ finish
+endif
+let g:LoupeLoaded=1
+
+" Temporarily set 'cpoptions' to Vim default as per `:h use-cpo-save`.
+let s:cpoptions=&cpoptions
+set cpoptions&vim
+
+" Reasonable defaults for search-related settings.
+if &history < 1000
+ set history=1000 " Longer search and command history (default is 50).
+endif
+if has('extra_search')
+ set hlsearch " Highlight search strings.
+ set incsearch " Incremental search ("find as you type").
+endif
+set ignorecase " Ignore case when searching.
+set shortmess+=s " Don't echo search wrap messages.
+set smartcase " Case-sensitive search if search string includes a capital letter.
+
+" Map <leader>n to clear search highlighting.
+let s:map=get(g:, 'LoupeClearHighlightMap', 1)
+if s:map
+ if !hasmapto('<Plug>(LoupeClearHighlight)') && maparg('<leader>n', 'n') ==# ''
+ nmap <silent> <unique> <leader>n <Plug>(LoupeClearHighlight)
+ endif
+endif
+nnoremap <silent> <Plug>(LoupeClearHighlight)
+ \ :nohlsearch<CR>
+ \ :call loupe#private#clear_highlight()<CR>
+
+" Make `:nohlsearch` behave like <Plug>(LoupeClearHighlight).
+cabbrev <silent> <expr> noh (getcmdtype() == ':' && getcmdpos() == 4 ? 'noh <bar> call loupe#private#clear_highlight()<CR>' : 'noh')
+cabbrev <silent> <expr> nohl (getcmdtype() == ':' && getcmdpos() == 5 ? 'nohl <bar> call loupe#private#clear_highlight()<CR>' : 'nohl')
+cabbrev <silent> <expr> nohls (getcmdtype() == ':' && getcmdpos() == 6 ? 'nohls <bar> call loupe#private#clear_highlight()<CR>' : 'nohls')
+cabbrev <silent> <expr> nohlse (getcmdtype() == ':' && getcmdpos() == 7 ? 'nohlse <bar> call loupe#private#clear_highlight()<CR>' : 'nohlse')
+cabbrev <silent> <expr> nohlsea (getcmdtype() == ':' && getcmdpos() == 8 ? 'nohlsea <bar> call loupe#private#clear_highlight()<CR>' : 'nohlsea')
+cabbrev <silent> <expr> nohlsear (getcmdtype() == ':' && getcmdpos() == 9 ? 'nohlsear <bar> call loupe#private#clear_highlight()<CR>' : 'nohlsear')
+cabbrev <silent> <expr> nohlsearc (getcmdtype() == ':' && getcmdpos() == 10 ? 'nohlsearc <bar> call loupe#private#clear_highlight()<CR>' : 'nohlsearc')
+cabbrev <silent> <expr> nohlsearch (getcmdtype() == ':' && getcmdpos() == 11 ? 'nohlsearch <bar> call loupe#private#clear_highlight()<CR>' : 'nohlsearch')
+
+" When g:LoupeVeryMagic is true (and it is by default), make Vim's regexen more
+" Perl-like.
+function s:MagicString()
+ let s:magic=get(g:, 'LoupeVeryMagic', 1)
+ return s:magic ? '\v' : ''
+endfunction
+
+nnoremap <expr> / loupe#private#prepare_highlight('/' . <SID>MagicString())
+nnoremap <expr> ? loupe#private#prepare_highlight('?' . <SID>MagicString())
+xnoremap <expr> / loupe#private#prepare_highlight('/' . <SID>MagicString())
+xnoremap <expr> ? loupe#private#prepare_highlight('?' . <SID>MagicString())
+if !empty(s:MagicString())
+ cnoremap <expr> / loupe#private#very_magic_slash()
+endif
+
+" When g:LoupeCenterResults is true (and it is by default), remain vertically
+" centered when moving to next/previous search.
+let s:center=get(g:, 'LoupeCenterResults', 1)
+let s:center_string=s:center ? 'zz' : ''
+
+execute 'nnoremap <silent> # #' . s:center_string . ':call loupe#private#hlmatch()<CR>'
+execute 'nnoremap <silent> * *' . s:center_string . ':call loupe#private#hlmatch()<CR>'
+execute 'nnoremap <silent> N N' . s:center_string . ':call loupe#private#hlmatch()<CR>'
+execute 'nnoremap <silent> g# g#' . s:center_string . ':call loupe#private#hlmatch()<CR>'
+execute 'nnoremap <silent> g* g*' . s:center_string . ':call loupe#private#hlmatch()<CR>'
+execute 'nnoremap <silent> n n' . s:center_string . ':call loupe#private#hlmatch()<CR>'
+
+" Clean-up stray `matchadd()` vestiges.
+if has('autocmd') && has('extra_search')
+ augroup LoupeCleanUp
+ autocmd!
+ autocmd WinEnter * :call loupe#private#cleanup()
+ augroup END
+endif
+
+" Restore 'cpoptions' to its former value.
+let &cpoptions=s:cpoptions
+unlet s:cpoptions