├── LICENSE ├── README.md └── plugin └── cool.vim /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Romain Lafourcade 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vim-cool 2 | 3 | Vim-cool disables search highlighting when you are done searching and re-enables it when you search again. That's it. No more `:noh`, no more `/sytdstdrsid`, and no more dodgy `` mappings. 4 | 5 | Vim-cool is cool. 6 | 7 | Vim-cool is *experimental*. 8 | 9 | ![cool](https://user-images.githubusercontent.com/344335/226825463-4ff5e352-ac2e-4f4d-94c7-a8109da7b6db.gif) 10 | 11 | ## Requirements 12 | 13 | Vim-cool is intended to be used with Vim, **and only Vim**, 7.4.2008 or later. It may or may not work in other editors but they are not and will not be officially supported. 14 | 15 | ## Installation 16 | 17 | Follow your favorite plugin/runtimepath manager's instructions. 18 | 19 | If you choose manual installation, just put `plugin/cool.vim` where it belongs: 20 | 21 | $HOME/.vim/plugin/cool.vim on Unix-like systems 22 | $HOME\vimfiles\plugin\cool.vim on Windows 23 | 24 | In Vim 8.0 and above, see `:help package`. 25 | 26 | ## Setup 27 | 28 | The whole assumption behind Vim-cool is that the user enabled search highlighting but they don't want the highlighting to linger on when they are done searching. This implies that the user has the following line in their `vimrc`: 29 | 30 | set hlsearch 31 | 32 | That's it. Nothing else to do. 33 | 34 | ## Experimental features 35 | 36 | * Show number of matches in the command-line: 37 | 38 | let g:cool_total_matches = 1 39 | 40 | ![demo](https://user-images.githubusercontent.com/344335/226825418-12931cf3-5f89-4375-89be-c98a57e177df.png) 41 | 42 | * Do something when we are doing `nnnNNnn`, do something else or do nothing when we are not: 43 | 44 | set statusline+=%{get(g:,'cool_is_searching',0)?'Yep':''} 45 | 46 | ## Background 47 | 48 | I wrote the first iteration of vim-cool in about twenty minutes, mostly to test a few ideas I had after a short discussion about `'hlsearch'` and `:nohlsearch` on #vim. 49 | 50 | Because it relied almost exclusively on mappings, that first iteration was way too brittle to be of any use and actually messed with a bunch of my own mappings. 51 | 52 | Then came [@purpleP](https://github.com/purpleP) and [the game-changing approach](https://github.com/romainl/vim-cool/issues/9) he put together with the help of [@chrisbra](https://github.com/chrisbra), [@justinmk](https://github.com/justinmk), [@jamessan](https://github.com/jamessan), and [@ZyX-I](https://github.com/ZyX-I). 53 | 54 | The current version, essentially a weaponized version of @purpleP's code, doesn't rely on mappings anymore and thus should be devoid of nasty side-effects. 55 | 56 | Many thanks to [@bounceme](https://github.com/bounceme) for his help. 57 | 58 | ## What they say about vim-cool 59 | 60 | - **puremourning**, in #vim: 61 | 62 | > vim-cool is by far my favourite plugin 63 | > 64 | > it's just so... cool. 65 | -------------------------------------------------------------------------------- /plugin/cool.vim: -------------------------------------------------------------------------------- 1 | " vim-cool - Disable hlsearch when you are done searching. 2 | " Maintainer: romainl 3 | " Version: 0.0.2 4 | " License: MIT License 5 | " Location: plugin/cool.vim 6 | " Website: https://github.com/romainl/vim-cool 7 | 8 | if exists("g:loaded_cool") || v:version < 704 || &compatible 9 | finish 10 | endif 11 | let g:loaded_cool = 1 12 | 13 | let s:save_cpo = &cpo 14 | set cpo&vim 15 | 16 | augroup Cool 17 | autocmd! 18 | augroup END 19 | 20 | if exists('##OptionSet') 21 | if !exists('*execute') 22 | autocmd Cool OptionSet highlight let saveh = &highlight 23 | endif 24 | " toggle coolness when hlsearch is toggled 25 | autocmd Cool OptionSet hlsearch call PlayItCool(v:option_old, v:option_new) 26 | endif 27 | 28 | function! s:StartHL() 29 | if !v:hlsearch || mode() isnot 'n' 30 | return 31 | endif 32 | let g:cool_is_searching = 1 33 | let [pos, rpos] = [winsaveview(), getpos('.')] 34 | let byte = line2byte('.')+col('.')-(v:searchforward ? 2 : 0) 35 | 36 | if byte <= 0 37 | return 38 | endif 39 | silent! exe "keepjumps go".byte 40 | try 41 | silent keepjumps norm! n 42 | if getpos('.') != rpos 43 | throw 0 44 | endif 45 | catch /^\%(0$\|Vim\%(\w\|:Interrupt$\)\@!\)/ 46 | call StopHL() 47 | return 48 | finally 49 | call winrestview(pos) 50 | endtry 51 | if !get(g:,'cool_total_matches') || !exists('*reltimestr') 52 | return 53 | endif 54 | exe "silent! norm! :let g:cool_char=nr2char(screenchar(screenrow(),1))\" 55 | let cool_char = remove(g:,'cool_char') 56 | if cool_char !~ '[/?]' 57 | return 58 | endif 59 | let [f, ws, now, noOf] = [0, &wrapscan, reltime(), [0,0]] 60 | set nowrapscan 61 | try 62 | while f < 2 63 | if reltimestr(reltime(now))[:-6] =~ '[1-9]' 64 | " time >= 100ms 65 | return 66 | endif 67 | let noOf[v:searchforward ? f : !f] += 1 68 | try 69 | silent exe "keepjumps norm! ".(f ? 'n' : 'N') 70 | catch /^Vim[^)]\+):E38[45]\D/ 71 | call setpos('.',rpos) 72 | let f += 1 73 | endtry 74 | endwhile 75 | finally 76 | call winrestview(pos) 77 | let &wrapscan = ws 78 | endtry 79 | redraw|echo cool_char.@/ 'match' noOf[0] 'of' noOf[0] + noOf[1] - 1 80 | endfunction 81 | 82 | function! s:StopHL() 83 | if !v:hlsearch || mode() isnot 'n' 84 | return 85 | else 86 | let g:cool_is_searching = 0 87 | silent call feedkeys("\(StopHL)", 'm') 88 | endif 89 | endfunction 90 | 91 | if !exists('*execute') 92 | let s:saveh = &highlight 93 | " toggle highlighting, a workaround for :nohlsearch in autocmds 94 | function! s:AuNohlsearch() 95 | noautocmd set highlight+=l:- 96 | autocmd Cool Insertleave * 97 | \ noautocmd let &highlight = s:saveh | autocmd! Cool InsertLeave * 98 | return '' 99 | endfunction 100 | endif 101 | 102 | function! s:PlayItCool(old, new) 103 | if a:old == 0 && a:new == 1 104 | " nohls --> hls 105 | " set up coolness 106 | noremap (StopHL) :nohlsearch 107 | if !exists('*execute') 108 | noremap! (StopHL) AuNohlsearch() 109 | 110 | " If no "execute()", ":tnoremap" isn't probably implemented too. 111 | else 112 | noremap! (StopHL) execute('nohlsearch')[-1] 113 | if exists(':tnoremap') 114 | tnoremap (StopHL) execute('nohlsearch')[-1] 115 | endif 116 | endif 117 | 118 | autocmd Cool CursorMoved * call StartHL() 119 | autocmd Cool InsertEnter * call StopHL() 120 | elseif a:old == 1 && a:new == 0 121 | " hls --> nohls 122 | " tear down coolness 123 | nunmap (StopHL) 124 | unmap! (StopHL) 125 | if exists(':tunmap') 126 | tunmap (StopHL) 127 | endif 128 | 129 | autocmd! Cool CursorMoved 130 | autocmd! Cool InsertEnter 131 | else 132 | " nohls --> nohls 133 | " do nothing 134 | return 135 | endif 136 | endfunction 137 | 138 | " play it cool 139 | call PlayItCool(0, &hlsearch) 140 | 141 | let &cpo = s:save_cpo 142 | --------------------------------------------------------------------------------