improve performance using vim async. fixes #32, #35, #53

This commit is contained in:
Alan Hamlett 2017-10-04 08:23:07 -07:00
parent f20a93e778
commit 99ffbf39cf
1 changed files with 59 additions and 33 deletions

View File

@ -49,11 +49,13 @@ let s:VERSION = '5.0.2'
let s:has_reltime = has('reltime') && localtime() - 1 < split(split(reltimestr(reltime()))[0], '\.')[0] let s:has_reltime = has('reltime') && localtime() - 1 < split(split(reltimestr(reltime()))[0], '\.')[0]
let s:config_file_already_setup = s:false let s:config_file_already_setup = s:false
let s:debug_mode_already_setup = s:false let s:debug_mode_already_setup = s:false
let s:is_debug_mode_on = s:false let s:is_debug_on = s:false
let s:local_cache_expire = 10 " seconds between reading s:data_file let s:local_cache_expire = 10 " seconds between reading s:data_file
let s:last_heartbeat = {'last_activity_at': 0, 'last_heartbeat_at': 0, 'file': ''} let s:last_heartbeat = {'last_activity_at': 0, 'last_heartbeat_at': 0, 'file': ''}
let s:heartbeats_buffer = [] let s:heartbeats_buffer = []
let s:send_buffer_seconds = 10 " seconds between sending buffered heartbeats
let s:last_sent = localtime() let s:last_sent = localtime()
let s:has_async = v:version >= 800 && exists('*job_start')
function! s:Init() function! s:Init()
@ -101,6 +103,9 @@ let s:VERSION = '5.0.2'
endif endif
endif endif
" Buffering heartbeats disabled in Windows, unless have async support
let s:buffering_heartbeats_enabled = s:has_async || !s:IsWindows()
endfunction endfunction
" }}} " }}}
@ -137,9 +142,9 @@ let s:VERSION = '5.0.2'
function! s:SetupDebugMode() function! s:SetupDebugMode()
if !s:debug_mode_already_setup if !s:debug_mode_already_setup
if s:GetIniSetting('settings', 'debug') == 'true' if s:GetIniSetting('settings', 'debug') == 'true'
let s:is_debug_mode_on = s:true let s:is_debug_on = s:true
else else
let s:is_debug_mode_on = s:false let s:is_debug_on = s:false
endif endif
let s:debug_mode_already_setup = s:true let s:debug_mode_already_setup = s:true
endif endif
@ -264,9 +269,8 @@ let s:VERSION = '5.0.2'
endif endif
let s:heartbeats_buffer = s:heartbeats_buffer + [heartbeat] let s:heartbeats_buffer = s:heartbeats_buffer + [heartbeat]
call s:SetLastHeartbeat(a:now, a:now, file) call s:SetLastHeartbeat(a:now, a:now, file)
if s:IsWindows() && !s:is_debug_mode_on
" Windows doesn't play nice with system(), so can't pass input if !s:buffering_heartbeats_enabled
" as STDIN and we are forced to send heartbeats individually.
call s:SendHeartbeats() call s:SendHeartbeats()
endif endif
endif endif
@ -274,6 +278,7 @@ let s:VERSION = '5.0.2'
function! s:SendHeartbeats() function! s:SendHeartbeats()
let start_time = localtime() let start_time = localtime()
let stdout = ''
if len(s:heartbeats_buffer) == 0 if len(s:heartbeats_buffer) == 0
let s:last_sent = start_time let s:last_sent = start_time
@ -307,36 +312,51 @@ let s:VERSION = '5.0.2'
if extra_heartbeats != '' if extra_heartbeats != ''
let cmd = cmd + ['--extra-heartbeats'] let cmd = cmd + ['--extra-heartbeats']
endif endif
let stdout = ''
if s:IsWindows() if s:has_async
if s:is_debug_mode_on let async_cmd = s:JoinArgs(cmd)
if extra_heartbeats != '' if s:IsWindows()
let stdout = system('(' . s:JoinArgs(cmd) . ')', extra_heartbeats) let async_cmd = 'cmd.exe /c ' . async_cmd
else endif
let stdout = system('(' . s:JoinArgs(cmd) . ')') let job = job_start([&shell, &shellcmdflag, async_cmd], {
endif \ 'stoponexit': '',
else \ 'callback': {channel, output -> s:AsyncHandler(channel, output, cmd)}})
exec 'silent !start /b cmd /c "' . s:JoinArgs(cmd) . ' > nul 2> nul"' if extra_heartbeats != ''
let channel = job_getchannel(job)
call ch_sendraw(channel, extra_heartbeats . "\n")
endif endif
else else
if s:is_debug_mode_on if s:IsWindows()
if extra_heartbeats != '' if s:is_debug_on
let stdout = system(s:JoinArgs(cmd), extra_heartbeats) if extra_heartbeats != ''
let stdout = system('(' . s:JoinArgs(cmd) . ')', extra_heartbeats)
else
let stdout = system('(' . s:JoinArgs(cmd) . ')')
endif
else else
let stdout = system(s:JoinArgs(cmd)) exec 'silent !start /b cmd /c "' . s:JoinArgs(cmd) . ' > nul 2> nul"'
endif endif
else else
if extra_heartbeats != '' if s:is_debug_on
let stdout = system(s:JoinArgs(cmd) . ' &', extra_heartbeats) if extra_heartbeats != ''
let stdout = system(s:JoinArgs(cmd), extra_heartbeats)
else
let stdout = system(s:JoinArgs(cmd))
endif
else else
let stdout = system(s:JoinArgs(cmd) . ' &') if extra_heartbeats != ''
let stdout = system(s:JoinArgs(cmd) . ' &', extra_heartbeats)
else
let stdout = system(s:JoinArgs(cmd) . ' &')
endif
endif endif
endif endif
endif endif
let s:last_sent = localtime() let s:last_sent = localtime()
" need to repaint in case a key was pressed while sending " need to repaint in case a key was pressed while sending
if s:redraw_setting != 'disabled' if !s:has_async && s:redraw_setting != 'disabled'
if s:redraw_setting == 'auto' if s:redraw_setting == 'auto'
if s:last_sent - start_time > 0 if s:last_sent - start_time > 0
redraw! redraw!
@ -346,8 +366,8 @@ let s:VERSION = '5.0.2'
endif endif
endif endif
if s:is_debug_mode_on && stdout != '' if s:is_debug_on && stdout != ''
echo '[WakaTime] Heartbeat Command: ' . s:JoinArgs(cmd) . "\n[WakaTime] Error: " . stdout echoerr '[WakaTime] Heartbeat Command: ' . s:JoinArgs(cmd) . "\n[WakaTime] Error: " . stdout
endif endif
endfunction endfunction
@ -374,6 +394,12 @@ let s:VERSION = '5.0.2'
return '[' . join(arr, ',') . ']' return '[' . join(arr, ',') . ']'
endfunction endfunction
function! s:AsyncHandler(channel, output, cmd)
if s:is_debug_on && a:output != ''
echoerr '[WakaTime] Heartbeat Command: ' . s:JoinArgs(a:cmd) . "\n[WakaTime] Error: " . a:output
endif
endfunction
function! s:OrderTime(time_str, loop_count) function! s:OrderTime(time_str, loop_count)
" Add a milisecond to a:time. " Add a milisecond to a:time.
" Time prevision doesn't matter, but order of heartbeats does. " Time prevision doesn't matter, but order of heartbeats does.
@ -431,12 +457,12 @@ let s:VERSION = '5.0.2'
function! s:EnableDebugMode() function! s:EnableDebugMode()
call s:SetIniSetting('settings', 'debug', 'true') call s:SetIniSetting('settings', 'debug', 'true')
let s:is_debug_mode_on = s:true let s:is_debug_on = s:true
endfunction endfunction
function! s:DisableDebugMode() function! s:DisableDebugMode()
call s:SetIniSetting('settings', 'debug', 'false') call s:SetIniSetting('settings', 'debug', 'false')
let s:is_debug_mode_on = s:false let s:is_debug_on = s:false
endfunction endfunction
function! s:EnableScreenRedraw() function! s:EnableScreenRedraw()
@ -477,12 +503,12 @@ let s:VERSION = '5.0.2'
endif endif
endif endif
" Windows non-debug mode disables buffering heartbeats, so " When buffering heartbeats disabled, no need to re-check the
" no need to re-send. " heartbeats buffer.
if !s:IsWindows() || s:is_debug_mode_on if s:buffering_heartbeats_enabled
" Only send buffered heartbeats every 10 seconds " Only send buffered heartbeats every s:send_buffer_seconds
if now - s:last_sent > 10 if now - s:last_sent > s:send_buffer_seconds
call s:SendHeartbeats() call s:SendHeartbeats()
endif endif
endif endif