Is it possible to visibly mark lines of a file in Vim without altering the file itself?

Viewed 98

I often review C/C++/... code (esp. my own). What I found effective to understand and review such code is to comment out each source code line (e.g., in case of C++, by prepending a supposedly unique comment marker (like '//!') to each line). I then uncomment the lines piece by piece after having understood what the author meant by a particular code snippet and if I think everything is okay. By that I work through the set of given files. Code (e.g., header files, functions, constants) that is still commented out afterwards might then possibly be removed.

However, I often want to "play around" with some of the code (e.g., rework a function and compile and run everything). For that, I obviously need to remove my comment marker from the lines that are still commented out. After the little test I then need to 'undo' the uncommenting.

Now to my question:

Is it possible in Vim to simply mark lines of a file visible somehow but not alter the file itself (so compiler, Make, ... see no difference unless the file was really edited). Such a mark should stay attached to its line if that line is edited or is moved within the file (e.g., if new code was inserted before that line or if code before that line was removed). Only if I decide so or if the line is removed, should the mark disappear. Newly added lines should be marked by default.

1 Answers

I saw someone had done this with ability to have a few highlighting colours. Anyway link in one of the comments gave me an idea...

if !exists('g:hl_default_group')
    let g:hl_default_group = 'hlYellow'
endif

if !exists('g:hl_group_config')
    let g:hl_group_config = {}
    let g:hl_group_config['hlGreen'] = 'ctermbg=121 guibg=#60ff60'
    let g:hl_group_config['hlYellow'] = 'ctermfg=0 ctermbg=11'
    let g:hl_group_config['hlGrey'] = 'ctermbg=242 guibg=DarkGrey'
    let g:hl_group_config['hlDarkBlue'] = 'ctermbg=4 guibg=DarkBlue'
    let g:hl_group_config['hlDarkMage'] = 'ctermbg=5 guibg=DarkMage'
endif

if !exists("g:hl_marked_lines")
    let g:hl_marked_lines = {}
endif

for group in keys(g:hl_group_config)
    execute 'highlight ' . group . ' ' . get(g:hl_group_config, group)
endfor

command! -nargs=? -range HighlightLines <line1>,<line2>call HighlightLines(<f-args>)
command! -nargs=0 -range RemoveHighlighting <line1>,<line2>call RemoveHighlighting()

function! HighlightLines(...) range
    if a:0 == 1
        let l:group = a:1
    else
        let l:group = g:hl_default_group
    endif

    let l:lines = getline(a:firstline, a:lastline)
    for line in l:lines
        call AddLineToMatchGroup(l:group, line)
    endfor
endfunction

function! RemoveHighlighting() range
    let l:lines = getline(a:firstline, a:lastline)
    for line in l:lines
        call DeleteLineToMatchGroup(line)
    endfor
endfunction

function! AddLineToMatchGroup(group, line) abort
    if !has_key(g:hl_group_config, a:group)
        echo 'error: group ' . a:group . ' not found'
        return
    endif
    if has_key(g:hl_marked_lines, a:line)
        echo 'error: line is already highlighted'
    endif
    let l:id = matchadd(a:group, a:line)
    let g:hl_marked_lines[a:line] = l:id
    return
endfunction

function! DeleteLineToMatchGroup(line) abort
    let l:id = get(g:hl_marked_lines, a:line)
    if l:id > 0
        call matchdelete(l:id)
        unlet g:hl_marked_lines[a:line]
    else
        echo 'info: not highlighted'
    endif
    return
endfunction

And then as a plugin... vim-highlight

Only real benefit of plugin over copy and pasting the above is plugin is self contained and has command completion

Related