├── .assets └── example.png ├── .coverage.json ├── LICENSE ├── README.md ├── coverage_highlight.vim └── coverage_parser.py /.assets/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gamozolabs/coverage_highlight/a19c0675817ce6769ac0d72e4e3e33c71d699f03/.assets/example.png -------------------------------------------------------------------------------- /.coverage.json: -------------------------------------------------------------------------------- 1 | { 2 | "coverage_parser.py": [10, 13, 18, 23, 24, 29, 30, 32, 34, 37, 38] 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 gamozolabs 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 | # Summary 2 | 3 | This is a very simple source line highlighter for VIM. It takes in a basic 4 | json file located at `.coverage.json` in the CWD, and displays highlights 5 | lines indicated by the json! 6 | 7 | # Coverage format 8 | 9 | This uses an extremely simple coverage format. Just a JSON dictionary with 10 | filenames as keys, and arrays of line numbers as values. 11 | 12 | For example: 13 | 14 | ``` 15 | { 16 | "coverage_parser.py": [2, 3, 6] 17 | } 18 | ``` 19 | 20 | The coverage file loaded is always from `.coverage.json`. I didn't even bother 21 | making it configurable, cause it's never something that I would see myself 22 | configuring. 23 | 24 | The filenames are fuzzily matched between the VIM filenames and the coverage 25 | file filenames. The comparison is just `a.endswith(b) or b.endswith(a)`. Thus, 26 | the paths may be relative or absolute, and partial matches also will occur. 27 | 28 | # Example 29 | 30 | ![Example image](.assets/example.png) 31 | 32 | # Install 33 | 34 | To install this, place the `coverage_parser.py` and `coverage_highlight.vim` 35 | files into your `~/.vim/plugin/` folder. It's that easy. 36 | 37 | -------------------------------------------------------------------------------- /coverage_highlight.vim: -------------------------------------------------------------------------------- 1 | " The main entry point of our VIM stuff. We add a hook for when every file is 2 | " read, eg, `BufWinEnter *.*` 3 | " 4 | " Just put the `coverage_parser.py` and `coverage_highlight.vim` into 5 | " `~/.vim/plugin` 6 | 7 | " Save the CPO 8 | let s:cpo_save = &cpo 9 | set cpo&vim 10 | 11 | " Check that we have python3 support compiled into VIM 12 | if !has('python3') 13 | echo "For the coverage_highlight plugin to work, VIM must be configured with python3 support" 14 | else 15 | " Define the colors to use for covered and uncovered lines Effectively for 16 | " 256-color terminals, colors 232 through 255 are very dark greys 17 | " rgb(8,8,8), through nearly white rgb(238,238,238), in rgb(10,10,10) 18 | " increments 19 | " This might require that you have TERM=xterm-256color _shrug_ 20 | highlight CoveredLineColor ctermbg=233 21 | 22 | " Define the sign we will use for covered lines 23 | execute 'sign define covered_line_color linehl=CoveredLineColor' 24 | 25 | " Load the python file we actually implement the parser and highlighting in 26 | py3file :p:h/coverage_parser.py 27 | 28 | " Create a function which will be invoked upon our auto group 29 | function! s:startup() abort 30 | " Just invoke our python plugin code 31 | python3 coverage_highlight() 32 | endfunction 33 | 34 | " Register an auto group for when a file has been loaded, this will cause 35 | " the `s:startup()` function to get invoked every time you finish reading 36 | " a file in VIM 37 | augroup coverage_highlight_augroup 38 | autocmd BufWinEnter *.* call s:startup() 39 | augroup END 40 | end 41 | 42 | " Restore the CPO 43 | let &cpo = s:cpo_save 44 | unlet s:cpo_save 45 | 46 | -------------------------------------------------------------------------------- /coverage_parser.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import json 5 | import binascii 6 | 7 | # Perform coverage highlighting 8 | def coverage_highlight(): 9 | # The json coverage format 10 | coverage_filename = ".coverage.json" 11 | 12 | # Get the filename for this vim buffer 13 | current_buffer_fn = os.path.basename(vim.current.buffer.name) 14 | 15 | # Assign the first sign identifier. These will be allocated for each line 16 | # as we notice coverage on them. This is effectively a unique identifier 17 | # for the sign we create on each covered line 18 | sign_id = 1 19 | 20 | # Establish a group name based on the current vim buffer name 21 | # Hexlify it to remove all special characters, spaces, etc. This is a 22 | # simple way to "escape" the name to make a unique identifier 23 | sign_group = \ 24 | binascii.hexlify(f"coverage_highlight_{current_buffer_fn}".encode()) 25 | 26 | # Clear all signs which match the sign group for this file. This will 27 | # delete all previous coverage highlights which allows a file to be 28 | # refreshed and coverage will also be refreshed 29 | vim.command(f"exe \":sign unplace * group={sign_group} \ 30 | file=\".expand(\"%:p\")") 31 | 32 | try: 33 | # Enumerate all of the lines in the lcov 34 | for (fn, lines) in json.load(open(coverage_filename)).items(): 35 | # Make sure the coverage file matches our current file open in the 36 | # VIM buffer 37 | if fn.endswith(current_buffer_fn) or \ 38 | current_buffer_fn.endswith(fn): 39 | # Go and highlight each line! 40 | for line_number in lines: 41 | vim.command(f"exe \":sign place {sign_id} \ 42 | line={line_number} \ 43 | group={sign_group} priority=9999 \ 44 | name=covered_line_color file=\".expand(\"%:p\")") 45 | sign_id += 1 46 | except FileNotFoundError: 47 | pass 48 | 49 | --------------------------------------------------------------------------------