buffer heartbeats in memory and send to wakatime-cli every 10 seconds
This commit is contained in:
parent
d350a97b72
commit
8a72498e13
1 changed files with 116 additions and 44 deletions
|
@ -45,6 +45,8 @@ let s:VERSION = '4.0.15'
|
||||||
let s:is_debug_mode_on = s:false
|
let s:is_debug_mode_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 = [0, 0, '']
|
let s:last_heartbeat = [0, 0, '']
|
||||||
|
let s:heartbeats_buffer = []
|
||||||
|
let s:last_sent = 0
|
||||||
|
|
||||||
" For backwards compatibility, rename wakatime.conf to wakatime.cfg
|
" For backwards compatibility, rename wakatime.conf to wakatime.cfg
|
||||||
if !filereadable(s:config_file)
|
if !filereadable(s:config_file)
|
||||||
|
@ -176,7 +178,6 @@ let s:VERSION = '4.0.15'
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
call writefile(output, s:config_file)
|
call writefile(output, s:config_file)
|
||||||
return
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:GetCurrentFile()
|
function! s:GetCurrentFile()
|
||||||
|
@ -187,6 +188,10 @@ let s:VERSION = '4.0.15'
|
||||||
return substitute(shellescape(a:arg), '!', '\\!', '')
|
return substitute(shellescape(a:arg), '!', '\\!', '')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:JsonEscape(str)
|
||||||
|
return substitute(a:str, '"', '\\"', 'g')
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:JoinArgs(args)
|
function! s:JoinArgs(args)
|
||||||
let safeArgs = []
|
let safeArgs = []
|
||||||
for arg in a:args
|
for arg in a:args
|
||||||
|
@ -202,12 +207,46 @@ let s:VERSION = '4.0.15'
|
||||||
return s:false
|
return s:false
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:SendHeartbeat(file, time, is_write, last)
|
function! s:AppendHeartbeat(file, now, is_write, last)
|
||||||
let file = a:file
|
let file = a:file
|
||||||
if file == ''
|
if file == ''
|
||||||
let file = a:last[2]
|
let file = a:last[2]
|
||||||
endif
|
endif
|
||||||
if file != ''
|
if file != ''
|
||||||
|
let heartbeat = {}
|
||||||
|
let heartbeat.entity = file
|
||||||
|
let heartbeat.time = reltimestr(reltime())
|
||||||
|
let heartbeat.is_write = a:is_write
|
||||||
|
if !empty(&syntax)
|
||||||
|
let heartbeat.language = &syntax
|
||||||
|
else
|
||||||
|
if !empty(&filetype)
|
||||||
|
let heartbeat.language = &filetype
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
let s:heartbeats_buffer = s:heartbeats_buffer + [heartbeat]
|
||||||
|
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
|
||||||
|
" as STDIN and we are forced to send heartbeats individually.
|
||||||
|
call s:SendHeartbeats()
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:SendHeartbeats()
|
||||||
|
if len(s:heartbeats_buffer) == 0
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let heartbeat = s:heartbeats_buffer[0]
|
||||||
|
let s:heartbeats_buffer = s:heartbeats_buffer[1:-1]
|
||||||
|
if len(s:heartbeats_buffer) > 0
|
||||||
|
let extra_heartbeats = s:GetHeartbeatsJson()
|
||||||
|
else
|
||||||
|
let extra_heartbeats = ''
|
||||||
|
endif
|
||||||
|
|
||||||
let python_bin = g:wakatime_PythonBinary
|
let python_bin = g:wakatime_PythonBinary
|
||||||
if s:IsWindows()
|
if s:IsWindows()
|
||||||
if python_bin == 'python'
|
if python_bin == 'python'
|
||||||
|
@ -215,38 +254,70 @@ let s:VERSION = '4.0.15'
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
let cmd = [python_bin, '-W', 'ignore', s:cli_location]
|
let cmd = [python_bin, '-W', 'ignore', s:cli_location]
|
||||||
let cmd = cmd + ['--entity', file]
|
let cmd = cmd + ['--entity', heartbeat.entity]
|
||||||
|
let cmd = cmd + ['--time', heartbeat.time]
|
||||||
let cmd = cmd + ['--plugin', printf('vim/%d vim-wakatime/%s', v:version, s:VERSION)]
|
let cmd = cmd + ['--plugin', printf('vim/%d vim-wakatime/%s', v:version, s:VERSION)]
|
||||||
if a:is_write
|
if heartbeat.is_write
|
||||||
let cmd = cmd + ['--write']
|
let cmd = cmd + ['--write']
|
||||||
endif
|
endif
|
||||||
if !empty(&syntax)
|
if has_key(heartbeat, 'language')
|
||||||
let cmd = cmd + ['--language', &syntax]
|
let cmd = cmd + ['--language', heartbeat.language]
|
||||||
else
|
|
||||||
if !empty(&filetype)
|
|
||||||
let cmd = cmd + ['--language', &filetype]
|
|
||||||
endif
|
endif
|
||||||
|
if extra_heartbeats != ''
|
||||||
|
let cmd = cmd + ['--extra-heartbeats']
|
||||||
endif
|
endif
|
||||||
let stdout = ''
|
let stdout = ''
|
||||||
if s:IsWindows()
|
if s:IsWindows()
|
||||||
if s:is_debug_mode_on
|
if s:is_debug_mode_on
|
||||||
|
if extra_heartbeats != ''
|
||||||
|
let stdout = system('(' . s:JoinArgs(cmd) . ')', extra_heartbeats)
|
||||||
|
else
|
||||||
let stdout = system('(' . s:JoinArgs(cmd) . ')')
|
let stdout = system('(' . s:JoinArgs(cmd) . ')')
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
exec 'silent !start /min cmd /c "' . s:JoinArgs(cmd) . '"'
|
exec 'silent !start /min cmd /c "' . s:JoinArgs(cmd) . '"'
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
if s:is_debug_mode_on
|
if s:is_debug_mode_on
|
||||||
|
if extra_heartbeats != ''
|
||||||
|
let stdout = system(s:JoinArgs(cmd), extra_heartbeats)
|
||||||
|
else
|
||||||
let stdout = system(s:JoinArgs(cmd))
|
let stdout = system(s:JoinArgs(cmd))
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
if extra_heartbeats != ''
|
||||||
|
let stdout = system(s:JoinArgs(cmd) . ' &', extra_heartbeats)
|
||||||
else
|
else
|
||||||
let stdout = system(s:JoinArgs(cmd) . ' &')
|
let stdout = system(s:JoinArgs(cmd) . ' &')
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
call s:SetLastHeartbeat(a:time, a:time, file)
|
endif
|
||||||
|
let s:last_sent = localtime()
|
||||||
|
redraw! " need to repaint in case a key was pressed while sending
|
||||||
if s:is_debug_mode_on && stdout != ''
|
if s:is_debug_mode_on && stdout != ''
|
||||||
echo '[WakaTime] Heartbeat Command: ' . s:JoinArgs(cmd)
|
echo '[WakaTime] Heartbeat Command: ' . s:JoinArgs(cmd) . "\n[WakaTime] Error: " . stdout
|
||||||
echo '[WakaTime] Error: ' . stdout
|
|
||||||
endif
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:GetHeartbeatsJson()
|
||||||
|
let arr = []
|
||||||
|
for heartbeat in s:heartbeats_buffer
|
||||||
|
let heartbeat_str = '{"entity": "' . s:JsonEscape(heartbeat.entity) . '", '
|
||||||
|
let heartbeat_str = heartbeat_str . '"timestamp": ' . heartbeat.time . ', '
|
||||||
|
let heartbeat_str = heartbeat_str . '"is_write": '
|
||||||
|
if heartbeat.is_write
|
||||||
|
let heartbeat_str = heartbeat_str . 'true'
|
||||||
|
else
|
||||||
|
let heartbeat_str = heartbeat_str . 'false'
|
||||||
endif
|
endif
|
||||||
|
if has_key(heartbeat, 'language')
|
||||||
|
let heartbeat_str = heartbeat_str . ', "language": "' . s:JsonEscape(heartbeat.language) . '"'
|
||||||
|
endif
|
||||||
|
let heartbeat_str = heartbeat_str . '}'
|
||||||
|
let arr = arr + [heartbeat_str]
|
||||||
|
endfor
|
||||||
|
let s:heartbeats_buffer = []
|
||||||
|
return '[' . join(arr, ',') . ']'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:GetLastHeartbeat()
|
function! s:GetLastHeartbeat()
|
||||||
|
@ -262,12 +333,12 @@ let s:VERSION = '4.0.15'
|
||||||
return s:last_heartbeat
|
return s:last_heartbeat
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:SetLastHeartbeatLocally(time, last_update, file)
|
function! s:SetLastHeartbeatInMemory(time, last_update, file)
|
||||||
let s:last_heartbeat = [a:time, a:last_update, a:file]
|
let s:last_heartbeat = [a:time, a:last_update, a:file]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:SetLastHeartbeat(time, last_update, file)
|
function! s:SetLastHeartbeat(time, last_update, file)
|
||||||
call s:SetLastHeartbeatLocally(a:time, a:last_update, a:file)
|
call s:SetLastHeartbeatInMemory(a:time, a:last_update, a:file)
|
||||||
call writefile([substitute(printf('%d', a:time), ',', '.', ''), substitute(printf('%d', a:last_update), ',', '.', ''), a:file], s:data_file)
|
call writefile([substitute(printf('%d', a:time), ',', '.', ''), substitute(printf('%d', a:last_update), ',', '.', ''), a:file], s:data_file)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@ -300,25 +371,27 @@ let s:VERSION = '4.0.15'
|
||||||
let s:is_debug_mode_on = s:false
|
let s:is_debug_mode_on = s:false
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" }}}
|
function! s:InitAndHandleActivity(is_write)
|
||||||
|
|
||||||
|
|
||||||
" Event Handlers {{{
|
|
||||||
|
|
||||||
function! s:handleActivity(is_write)
|
|
||||||
call s:SetupDebugMode()
|
call s:SetupDebugMode()
|
||||||
call s:SetupConfigFile()
|
call s:SetupConfigFile()
|
||||||
|
call s:HandleActivity(a:is_write)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:HandleActivity(is_write)
|
||||||
let file = s:GetCurrentFile()
|
let file = s:GetCurrentFile()
|
||||||
let now = localtime()
|
|
||||||
let last = s:GetLastHeartbeat()
|
|
||||||
if !empty(file) && file !~ "-MiniBufExplorer-" && file !~ "--NO NAME--" && file !~ "^term:"
|
if !empty(file) && file !~ "-MiniBufExplorer-" && file !~ "--NO NAME--" && file !~ "^term:"
|
||||||
|
let last = s:GetLastHeartbeat()
|
||||||
|
let now = localtime()
|
||||||
if a:is_write || s:EnoughTimePassed(now, last) || file != last[2]
|
if a:is_write || s:EnoughTimePassed(now, last) || file != last[2]
|
||||||
call s:SendHeartbeat(file, now, a:is_write, last)
|
call s:AppendHeartbeat(file, now, a:is_write, last)
|
||||||
else
|
else
|
||||||
if now - s:last_heartbeat[0] > s:local_cache_expire
|
if now - s:last_heartbeat[0] > s:local_cache_expire
|
||||||
call s:SetLastHeartbeatLocally(now, last[1], last[2])
|
call s:SetLastHeartbeatInMemory(now, last[1], last[2])
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
if now - s:last_sent > 10
|
||||||
|
call s:SendHeartbeats()
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@ -328,11 +401,10 @@ let s:VERSION = '4.0.15'
|
||||||
" Autocommand Events {{{
|
" Autocommand Events {{{
|
||||||
|
|
||||||
augroup Wakatime
|
augroup Wakatime
|
||||||
autocmd!
|
autocmd BufEnter,VimEnter * call s:InitAndHandleActivity(s:false)
|
||||||
autocmd BufEnter * call s:handleActivity(s:false)
|
autocmd CursorMoved,CursorMovedI * call s:HandleActivity(s:false)
|
||||||
autocmd VimEnter * call s:handleActivity(s:false)
|
autocmd BufWritePost * call s:HandleActivity(s:true)
|
||||||
autocmd BufWritePost * call s:handleActivity(s:true)
|
autocmd QuitPre * call s:SendHeartbeats()
|
||||||
autocmd CursorMoved,CursorMovedI * call s:handleActivity(s:false)
|
|
||||||
augroup END
|
augroup END
|
||||||
|
|
||||||
" }}}
|
" }}}
|
||||||
|
|
Loading…
Reference in a new issue