├── .gitignore ├── MIT-LICENSE ├── README.md ├── autoload └── hlchunk.vim ├── plugin └── hlchunk.vim └── screenshots └── 01.gif /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode/ 3 | node_modules/ 4 | dist/ 5 | tmp/ 6 | temp/ 7 | logs/ 8 | *.log 9 | **/dump.rdb 10 | **/.DS_Store 11 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022-2022 YC Chen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VIM HL CHUNK 2 | 3 | hignlight chunk signcolumn plug of nvim 4 | 5 | vim version: [vim-hlchunk](https://github.com/yaocccc/vim-hlchunk) 6 | 7 | ![sc](./screenshots/01.gif) 8 | 9 | ## OPTIONS 10 | 11 | ```options 12 | ENGLISH 13 | " what files are supported, default '*.ts,*.js,*.json,*.go,*.c,*.cpp,*.rs,*.h,*.hpp,*.lua' 14 | let g:hlchunk_files = '*.ts,*.js,*.json,*.go,*.c,*.cpp,*.rs,*.h,*.hpp,*.lua' 15 | " hlchunk indentline highlight 16 | au VimEnter * hi HLIndentLine ctermfg=244 17 | " delay default 50 18 | let g:hlchunk_time_delay = 50 19 | " indentline chars(Anti-Clockwise) default ['─', '─', '╭', '│', '╰', '─', '>'] 20 | let g:hlchunk_chars=['─', '─', '╭', '│', '╰', '─', '>'] 21 | " hlchunk_line_limit default 5000 22 | let g:hlchunk_line_limit = 5000 23 | " hlchunk_col_limit default 500 24 | let g:hlchunk_col_limit = 500 25 | " hi style default 'ctermfg=244' 26 | let g:hlchunk_hi_style = 'ctermfg=244' 27 | 28 | 中文 29 | " 支持哪些文件 默认为 '*.ts,*.js,*.json,*.go,*.c,*.cpp,*.rs,*.h,*.hpp,*.lua' 30 | let g:hlchunk_files = '*.ts,*.js,*.json,*.go,*.c,*.cpp,*.rs,*.h,*.hpp,*.lua' 31 | " 缩进线的高亮 32 | au VimEnter * hi HLIndentLine ctermfg=244 33 | " 延时 默认为50 34 | let g:hlchunk_time_delay = 50 35 | " 高亮线符号(逆时针) 默认为 ['─', '─', '╭', '│', '╰', '─', '>'] 36 | let g:hlchunk_chars=['─', '─', '╭', '│', '╰', '─', '>'] 37 | " 最大支持行数 默认3000(超过5000行的文件不使用hlchunk) 38 | let g:hlchunk_line_limit = 5000 39 | " 最大支持列数 默认100(超过500列的文件不使用hlchunk) 40 | let g:hlchunk_col_limit = 500 41 | " 高亮线的hi样式 默认为 'ctermfg=244' 42 | let g:hlchunk_hi_style = 'ctermfg=244' 43 | ``` 44 | 45 | ## Support 46 | 47 | 48 | 49 | 50 | 51 |
52 | 53 | 54 | Buy Me A Coffee 55 | 56 | -------------------------------------------------------------------------------- /autoload/hlchunk.vim: -------------------------------------------------------------------------------- 1 | let s:hlchunk_chars=get(g:, 'hlchunk_chars', ['─', '─', '╭', '│', '╰', '─', '>']) 2 | let s:opt = {'virt_text_pos': 'overlay', 'hl_mode': 'replace'} 3 | 4 | func! s:getpairpos() " [int, int] 5 | let c = getline('.')[col('.') - 1] 6 | let l:beg = searchpair('{', '', '}', 'znWb' . (c == '{' ? 'c' : '')) 7 | let l:end = searchpair('{', '', '}', 'znW' . (c == '}' ? 'c' : '')) 8 | return [beg, end] 9 | endf 10 | 11 | func! s:getchars(len, char) 12 | let result = '' 13 | for idx in range(1, a:len) 14 | let result = result . a:char 15 | endfor 16 | return result 17 | endf 18 | 19 | func! hlchunk#hl_chunk(...) 20 | call hlchunk#clear_hl_chunk() 21 | let s:ns = nvim_create_namespace('hlchunk') 22 | 23 | let [beg, end] = s:getpairpos() 24 | if beg == end | return | endif 25 | if beg == 0 || end == 0 | return | endif 26 | 27 | " 避免渲染行数过长造成的卡顿 - 只渲染屏幕展示行+-50行的区域 28 | let [startl, endl] = end - beg > 100 29 | \ ? [max([beg, line('w0') - 50]), min([end, line('w$') + 50])] 30 | \ : [beg, end] 31 | 32 | " 解析起始位置 33 | let space_text = s:getchars(&shiftwidth, ' ') 34 | let [beg_line, end_line] = [getline(beg), getline(end)] 35 | let [beg_line, end_line] = [substitute(beg_line, '\v^(\s*).*', '\1', ''), substitute(end_line, '\v^(\s*).*', '\1', '')] 36 | let [beg_line, end_line] = [substitute(beg_line, '\t', space_text, 'g'), substitute(end_line, '\t', space_text, 'g')] 37 | let [beg_space_len, end_space_len] = [len(beg_line), len(end_line)] 38 | let space_len = min([beg_space_len - &shiftwidth, end_space_len - &shiftwidth]) 39 | let space_len = max([space_len, 0]) 40 | let s:opt.virt_text_win_col = space_len - winsaveview().leftcol 41 | if s:opt.virt_text_win_col < 0 | return | endif 42 | 43 | " 渲染beg行 44 | if beg_space_len == 1 45 | let s:virt_text = s:hlchunk_chars[2] 46 | let s:opt.virt_text = [[s:virt_text, 'HLIndentLine']] 47 | call nvim_buf_set_extmark(0, s:ns, beg - 1, 0, s:opt) 48 | endif 49 | if beg_space_len >= 2 50 | let s:virt_text = s:hlchunk_chars[2] . s:getchars(beg_space_len - 2 - space_len, s:hlchunk_chars[1]) . s:hlchunk_chars[0] 51 | let s:opt.virt_text = [[s:virt_text, 'HLIndentLine']] 52 | call nvim_buf_set_extmark(0, s:ns, beg - 1, 0, s:opt) 53 | endif 54 | 55 | " 渲染end行 56 | if end_space_len == 1 57 | let s:virt_text = s:hlchunk_chars[4] 58 | let s:opt.virt_text = [[s:virt_text, 'HLIndentLine']] 59 | call nvim_buf_set_extmark(0, s:ns, end - 1, 0, s:opt) 60 | endif 61 | if end_space_len >= 2 62 | let s:virt_text = s:hlchunk_chars[4] . s:getchars(end_space_len - 2 - space_len, s:hlchunk_chars[5]) . s:hlchunk_chars[6] 63 | let s:opt.virt_text = [[s:virt_text, 'HLIndentLine']] 64 | call nvim_buf_set_extmark(0, s:ns, end - 1, 0, s:opt) 65 | endif 66 | 67 | " 渲染中间行 68 | for idx in range(startl + 1, endl - 1) 69 | let current_line = getline(idx) 70 | let current_line = substitute(current_line, '\t', space_text, 'g') 71 | if current_line[space_len] =~ '\s' || len(current_line) <= space_len 72 | let s:opt.virt_text = [[s:hlchunk_chars[3], 'HLIndentLine']] 73 | call nvim_buf_set_extmark(0, s:ns, idx - 1, 0, s:opt) 74 | endif 75 | endfor 76 | endf 77 | 78 | func! hlchunk#clear_hl_chunk(...) 79 | if exists('s:ns') 80 | call nvim_buf_clear_namespace(0, s:ns, 0, -1) 81 | endif 82 | endf 83 | -------------------------------------------------------------------------------- /plugin/hlchunk.vim: -------------------------------------------------------------------------------- 1 | let s:timerid = -1 2 | let s:delay = get(g:, 'hlchunk_time_delay', 50) 3 | let s:hlchunk_files = get(g:, 'hlchunk_files', '*.ts,*.js,*.json,*.go,*.c,*.cpp,*.rs,*.h,*.hpp,*.lua') 4 | let s:hlchunk_line_limit = get(g:, 'hlchunk_line_limit', 5000) 5 | let s:hlchunk_col_limit = get(g:, 'hlchunk_col_limit', 500) 6 | let s:hlchunk_hi_style = get(g:, 'hlchunk_hi_style', 'ctermfg=244') 7 | 8 | exec('au CursorMoved,CursorMovedI,TextChanged,TextChangedI,TextChangedP ' .. s:hlchunk_files .. ' call hlchunk()') 9 | exec('au BufEnter,TextChanged,TextChangedI,TextChangedP ' .. s:hlchunk_files .. ' let b:hlchunk_enabled=check()') 10 | exec('au WinScrolled * call hlchunk()') 11 | exec('hi HLIndentLine ' .. s:hlchunk_hi_style) 12 | 13 | func s:hlchunk() 14 | if get(b:, 'hlchunk_enabled', 0) == 1 15 | call timer_stop(s:timerid) 16 | let s:timerid = timer_start(s:delay, 'hlchunk#hl_chunk', {'repeat': 1}) 17 | else 18 | call hlchunk#clear_hl_chunk() 19 | endif 20 | endf 21 | 22 | func s:check() 23 | if line("$") > s:hlchunk_line_limit 24 | return 0 25 | endif 26 | for idx in range(1, line("$")) 27 | if len(getline(idx)) > s:hlchunk_col_limit 28 | return 0 29 | endif 30 | endfor 31 | return 1 32 | endf 33 | -------------------------------------------------------------------------------- /screenshots/01.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yaocccc/nvim-hlchunk/269ccdb61818c28a3d53b4851f76aed81bbd22fc/screenshots/01.gif --------------------------------------------------------------------------------