├── LICENSE ├── README.md └── plugin └── slash.vim /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Junegunn Choi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | vim-slash 2 | ========= 3 | 4 | vim-slash provides a set of mappings for enhancing in-buffer search experience 5 | in Vim. 6 | 7 | - Automatically clears search highlight when cursor is moved 8 | - Improved star-search (visual-mode, highlighting without moving) 9 | 10 | Installation 11 | ------------ 12 | 13 | Using [vim-plug](https://github.com/junegunn/vim-plug): 14 | 15 | ```vim 16 | Plug 'junegunn/vim-slash' 17 | ``` 18 | 19 | Comparison with vim-oblique 20 | --------------------------- 21 | 22 | vim-slash is a smaller alternative to [vim-oblique][ob]. vim-oblique depends 23 | on [a reimplementation of Vim command-line interface][pcl] which is incomplete 24 | and has a number of issues that cannot be easily fixed. vim-oblique is also 25 | much slower than the native /-search when working with large files. 26 | 27 | Many features of vim-oblique are missing in vim-slash, but [frankly, my dear, 28 | I don't give a damn][damn]. 29 | 30 | [ob]: https://github.com/junegunn/vim-oblique 31 | [pcl]: https://github.com/junegunn/vim-pseudocl 32 | [damn]: https://en.wikipedia.org/wiki/Frankly,_my_dear,_I_don%27t_give_a_damn 33 | 34 | Customization 35 | ------------- 36 | 37 | #### `zz` after search 38 | 39 | Places the current match at the center of the window. 40 | 41 | ```vim 42 | noremap (slash-after) zz 43 | ``` 44 | 45 | #### Blinking cursor after search using Vim 8 timer 46 | 47 | ```vim 48 | if has('timers') 49 | " Blink 2 times with 50ms interval 50 | noremap (slash-after) slash#blink(2, 50) 51 | endif 52 | ``` 53 | 54 | You can prepend `zz` to the expression: `'zz'.slash#blink(2, 50)` 55 | -------------------------------------------------------------------------------- /plugin/slash.vim: -------------------------------------------------------------------------------- 1 | " The MIT License (MIT) 2 | " 3 | " Copyright (c) 2016 Junegunn Choi 4 | " 5 | " Permission is hereby granted, free of charge, to any person obtaining a copy 6 | " of this software and associated documentation files (the "Software"), to deal 7 | " in the Software without restriction, including without limitation the rights 8 | " to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | " copies of the Software, and to permit persons to whom the Software is 10 | " furnished to do so, subject to the following conditions: 11 | " 12 | " The above copyright notice and this permission notice shall be included in 13 | " all copies or substantial portions of the Software. 14 | " 15 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | " IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | " FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | " AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | " LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | " OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | " THE SOFTWARE. 22 | 23 | function! s:wrap(seq) 24 | if mode() == 'c' && stridx('/?', getcmdtype()) < 0 25 | return a:seq 26 | endif 27 | silent! autocmd! slash 28 | set hlsearch 29 | return a:seq."\(slash-trailer)" 30 | endfunction 31 | 32 | function! s:immobile(seq) 33 | let s:winline = winline() 34 | let s:pos = getpos('.') 35 | return a:seq."\(slash-prev)" 36 | endfunction 37 | 38 | function! s:trailer() 39 | augroup slash 40 | autocmd! 41 | autocmd CursorMoved,CursorMovedI * set nohlsearch | autocmd! slash 42 | augroup END 43 | 44 | let seq = foldclosed('.') != -1 ? 'zv' : '' 45 | if exists('s:winline') 46 | let sdiff = winline() - s:winline 47 | unlet s:winline 48 | if sdiff > 0 49 | let seq .= sdiff."\" 50 | elseif sdiff < 0 51 | let seq .= -sdiff."\" 52 | endif 53 | endif 54 | let after = len(maparg("(slash-after)", mode())) ? "\(slash-after)" : '' 55 | return seq . after 56 | endfunction 57 | 58 | function! s:trailer_on_leave() 59 | augroup slash 60 | autocmd! 61 | autocmd InsertLeave * call trailer() 62 | augroup END 63 | return '' 64 | endfunction 65 | 66 | function! s:prev() 67 | return getpos('.') == s:pos ? '' : '``' 68 | endfunction 69 | 70 | function! s:escape(backward) 71 | return '\V'.substitute(escape(@", '\' . (a:backward ? '?' : '/')), "\n", '\\n', 'g') 72 | endfunction 73 | 74 | function! slash#blink(times, delay) 75 | let s:blink = { 'ticks': 2 * a:times, 'delay': a:delay } 76 | 77 | function! s:blink.tick(_) 78 | let self.ticks -= 1 79 | let active = self == s:blink && self.ticks > 0 80 | 81 | if !self.clear() && active && &hlsearch 82 | let [line, col] = [line('.'), col('.')] 83 | let w:blink_id = matchadd('IncSearch', 84 | \ printf('\%%%dl\%%>%dc\%%<%dc', line, max([0, col-2]), col+2)) 85 | endif 86 | if active 87 | call timer_start(self.delay, self.tick) 88 | if has('nvim') 89 | call feedkeys("\(slash-nop)") 90 | endif 91 | endif 92 | endfunction 93 | 94 | function! s:blink.clear() 95 | if exists('w:blink_id') 96 | call matchdelete(w:blink_id) 97 | unlet w:blink_id 98 | return 1 99 | endif 100 | endfunction 101 | 102 | call s:blink.clear() 103 | call s:blink.tick(0) 104 | return '' 105 | endfunction 106 | 107 | map (slash-trailer) trailer() 108 | imap (slash-trailer) trailer_on_leave() 109 | cnoremap (slash-cr) 110 | noremap (slash-prev) prev() 111 | inoremap (slash-prev) 112 | noremap! (slash-nop) 113 | 114 | cmap wrap("\") 115 | map n wrap('n') 116 | map N wrap('N') 117 | map gd wrap('gd') 118 | map gD wrap('gD') 119 | map * wrap(immobile('*')) 120 | map # wrap(immobile('#')) 121 | map g* wrap(immobile('g*')) 122 | map g# wrap(immobile('g#')) 123 | xmap * wrap(immobile("y/\=escape(0)\(slash-cr)\(slash-cr)")) 124 | xmap # wrap(immobile("y?\=escape(1)\(slash-cr)\(slash-cr)")) 125 | --------------------------------------------------------------------------------