Skip to content

Commit e53ceac

Browse files
author
George Sofianos
authored
Merge pull request #33 from APZelos/fix_multi_visual
Improve performance in visual mode by calling git only once
2 parents 1144204 + fed2139 commit e53ceac

File tree

1 file changed

+70
-35
lines changed

1 file changed

+70
-35
lines changed

autoload/blamer.vim

Lines changed: 70 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,46 @@ function! s:GetLines() abort
9292
endif
9393
endfunction
9494

95-
function! blamer#GetMessage(file, line_number, line_count) abort
95+
function! blamer#CommitDataToMessage(commit_data) abort
96+
let l:message = s:blamer_template
97+
for field in s:blamer_info_fields
98+
let l:message = substitute(l:message, '\m\C<' . field . '>', a:commit_data[field], 'g')
99+
endfor
100+
return l:message
101+
endfunction
102+
103+
function! blamer#ParseCommitDataLine(line) abort
104+
let l:info = {}
105+
let l:words = split(a:line, ' ')
106+
let l:property = l:words[0]
107+
let l:value = join(l:words[1:], ' ')
108+
if l:property =~? 'time'
109+
if(s:blamer_relative_time)
110+
let l:value = s:GetRelativeTime(l:value)
111+
else
112+
let l:value = strftime(s:blamer_date_format, l:value)
113+
endif
114+
endif
115+
let l:value = escape(l:value, '&')
116+
let l:value = escape(l:value, '~')
117+
118+
if l:value ==? s:blamer_user_name
119+
let l:value = 'You'
120+
elseif l:value ==? s:blamer_user_email
121+
let l:value = 'You'
122+
endif
123+
124+
let l:info[l:property] = l:value
125+
return l:info
126+
endfunction
127+
128+
function! blamer#GetMessages(file, line_number, line_count) abort
129+
let l:end_line = a:line_number + a:line_count - 1
96130
let l:file_path_escaped = shellescape(a:file)
97-
let l:command = 'git --no-pager blame -p -L ' . a:line_number . ',' . a:line_count . ' -- ' . l:file_path_escaped
131+
let l:command = 'git --no-pager blame --line-porcelain -L ' . a:line_number . ',' . l:end_line . ' -- ' . l:file_path_escaped
98132
let l:result = system(l:command)
99-
100133
let l:lines = split(l:result, '\n')
134+
101135
let l:info = {}
102136
let l:info['commit-short'] = split(l:lines[0], ' ')[0][:7]
103137
let l:info['commit-long'] = split(l:lines[0], ' ')[0]
@@ -128,41 +162,37 @@ function! blamer#GetMessage(file, line_number, line_count) abort
128162
return ''
129163
endif
130164

131-
for line in l:lines[1:]
132-
let l:words = split(line, ' ')
133-
let l:property = l:words[0]
134-
let l:value = join(l:words[1:], ' ')
135-
if l:property =~? 'time'
136-
if(s:blamer_relative_time)
137-
let l:value = s:GetRelativeTime(l:value)
138-
else
139-
let l:value = strftime(s:blamer_date_format, l:value)
165+
let l:TAB_ASCII = 9
166+
167+
let l:reading_commit_data = 0
168+
let l:commit_data = {}
169+
let l:commit_data_per_line = []
170+
171+
for line in l:lines[0:]
172+
let l:line_words = split(line, ' ')
173+
let l:is_line_hash = !empty(matchstr(l:line_words[0],'\c[0-9a-f]\{40}'))
174+
let l:has_line_tab = char2nr(l:line_words[0][0]) == l:TAB_ASCII
175+
176+
if l:is_line_hash
177+
" line type HASH
178+
let l:commit_data = {}
179+
elseif l:has_line_tab
180+
" line type TAB
181+
" Change messsage when changes are not commited
182+
if l:commit_data.author ==? "Not Committed Yet"
183+
let l:commit_data.author = 'You'
184+
let l:commit_data.committer = 'You'
185+
let l:commit_data.summary = 'Uncommitted changes'
140186
endif
187+
let l:commit_data_per_line = add(l:commit_data_per_line,extend({},l:commit_data))
188+
else
189+
" line type COMMIT DATA
190+
let l:commit_data_chunk = blamer#ParseCommitDataLine(line)
191+
let l:commit_data = extend(l:commit_data,l:commit_data_chunk)
141192
endif
142-
let l:value = escape(l:value, '&')
143-
let l:value = escape(l:value, '~')
144-
145-
if l:value ==? s:blamer_user_name
146-
let l:value = 'You'
147-
elseif l:value ==? s:blamer_user_email
148-
let l:value = 'You'
149-
endif
150-
151-
let l:info[l:property] = l:value
152-
endfor
153-
154-
if l:result =~? 'Not committed yet'
155-
let l:info.author = 'You'
156-
let l:info.committer = 'You'
157-
let l:info.summary = 'Uncommitted changes'
158-
endif
159-
160-
let l:message = s:blamer_template
161-
for field in s:blamer_info_fields
162-
let l:message = substitute(l:message, '\m\C<' . field . '>', l:info[field], 'g')
163193
endfor
164194

165-
return l:message
195+
return map(l:commit_data_per_line,"blamer#CommitDataToMessage(v:val)")
166196
endfunction
167197

168198
function! blamer#SetVirtualText(buffer_number, line_number, message) abort
@@ -224,13 +254,18 @@ function! blamer#Show() abort
224254
" return
225255
" endif
226256

257+
let l:line_count = len(l:line_numbers)
258+
let l:messages = blamer#GetMessages(l:file_path, l:line_numbers[0], l:line_count)
259+
let l:index = 0
260+
227261
for line_number in l:line_numbers
228-
let l:message = blamer#GetMessage(l:file_path, line_number, '+1')
262+
let l:message = l:messages[l:index]
229263
if has('nvim')
230264
call blamer#SetVirtualText(l:buffer_number, line_number, l:message)
231265
else
232266
call blamer#CreatePopup(l:buffer_number, line_number, l:message)
233267
endif
268+
let l:index += 1
234269
endfor
235270
endfunction
236271

0 commit comments

Comments
 (0)