Is there a n[vim]
function to get the list of modified lines? A clunky way is to parse the output of :changes
but I only require the changes since last write. I have to use it in a python-based plugin.
1 Answer
Here's how I would handle this, riffing on :help diff-original-file
and Vimdiff line count of different lines :
- Get the original file in a diff
:vertical new | set bt=nofile | read ++edit # | 0 delete _ | diffthis | wincmd p | diffthis
- For both windows, collect the lines with
Diff*
highlighting (deleted lines don't show up, so we need both):
function GetDiffLines() abort
return range(1, line('$'))->filter({_, v -> diff_hlID(v, 1)->synIDattr('name') =~# 'Diff*'})
endfunction
const current_diffs = GetDiffLines()
wincmd p
const original_diffs = GetDiffLines()
- Do a "set union" to know what's what overall; if you need the diff groups (say, to know whether it's deleted or added or changed), you'll need to add some steps here to process
synIDattr({id}, 'name')
, which may differ for some lines in the respective buffers.
const diff_lines = (current_diffs + original_diffs)->sort('n')->uniq()
It may actually be worth not doing step (3), as you lose the information of where each line came from. This is particularly relevant when lines are added in one buffer, which is equivalent to them being deleted in the other.
:help diff-original-file
and vi.stackexchange.com/q/29568/10604 ought to get someone started:help listener_add()
. It is far from straightforward, but the idea is you would set up a listener callback and accumulate the changes, then clearing them on writes. How to best do this depends greatly on the end use-case (not specified in the question). One obvious gotcha is the line numbers are changing constantly due to editing so there is some necessary bookkeeping overhead.