statusline.vim 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. " Statusline
  2. """"""""""""""""""""""""""""""""
  3. " s:statuses is a global reference to all statuses. It stores the statuses per
  4. " import paths (map[string]status), where each status is unique per its
  5. " type. Current status dict is in form:
  6. " {
  7. " 'desc' : 'Job description',
  8. " 'state' : 'Job state, such as success, failure, etc..',
  9. " 'type' : 'Job type, such as build, test, etc..'
  10. " 'created_at' : 'Time it was created as seconds since 1st Jan 1970'
  11. " }
  12. let s:statuses = {}
  13. " timer_id for cleaner
  14. let s:timer_id = 0
  15. " last_status stores the last generated text per status
  16. let s:last_status = ""
  17. " Show returns the current status of the job for 20 seconds (configurable). It
  18. " displays it in form of 'desc: [type|state]' if there is any state available,
  19. " if not it returns an empty string. This function should be plugged directly
  20. " into the statusline.
  21. function! go#statusline#Show() abort
  22. " lazy initialiation of the cleaner
  23. if !s:timer_id
  24. " clean every 60 seconds all statuses
  25. let interval = get(g:, 'go_statusline_duration', 60000)
  26. let s:timer_id = timer_start(interval, function('go#statusline#Clear'), {'repeat': -1})
  27. endif
  28. " nothing to show
  29. if empty(s:statuses)
  30. return ''
  31. endif
  32. let status_dir = expand('%:p:h')
  33. if !has_key(s:statuses, status_dir)
  34. return ''
  35. endif
  36. let status = s:statuses[status_dir]
  37. if !has_key(status, 'desc') || !has_key(status, 'state') || !has_key(status, 'type')
  38. return ''
  39. endif
  40. let status_text = printf("[%s|%s]", status.type, status.state)
  41. if empty(status_text)
  42. return ''
  43. endif
  44. " only update highlight if status has changed.
  45. if status_text != s:last_status
  46. if status.state =~ "success" || status.state =~ "finished" || status.state =~ "pass"
  47. hi goStatusLineColor cterm=bold ctermbg=76 ctermfg=22
  48. elseif status.state =~ "started" || status.state =~ "analysing" || status.state =~ "compiling"
  49. hi goStatusLineColor cterm=bold ctermbg=208 ctermfg=88
  50. elseif status.state =~ "failed"
  51. hi goStatusLineColor cterm=bold ctermbg=196 ctermfg=52
  52. endif
  53. endif
  54. let s:last_status = status_text
  55. return status_text
  56. endfunction
  57. " Update updates (adds) the statusline for the given status_dir with the
  58. " given status dict. It overrides any previously set status.
  59. function! go#statusline#Update(status_dir, status) abort
  60. let a:status.created_at = reltime()
  61. let s:statuses[a:status_dir] = a:status
  62. " force to update the statusline, otherwise the user needs to move the
  63. " cursor
  64. exe 'let &ro = &ro'
  65. " before we stop the timer, check if we have any previous jobs to be cleaned
  66. " up. Otherwise every job will reset the timer when this function is called
  67. " and thus old jobs will never be cleaned
  68. call go#statusline#Clear(0)
  69. " also reset the timer, so the user has time to see it in the statusline.
  70. " Setting the timer_id to 0 will trigger a new cleaner routine.
  71. call timer_stop(s:timer_id)
  72. let s:timer_id = 0
  73. endfunction
  74. " Clear clears all currently stored statusline data. The timer_id argument is
  75. " just a placeholder so we can pass it to a timer_start() function if needed.
  76. function! go#statusline#Clear(timer_id) abort
  77. for [status_dir, status] in items(s:statuses)
  78. let elapsed_time = reltimestr(reltime(status.created_at))
  79. " strip whitespace
  80. let elapsed_time = substitute(elapsed_time, '^\s*\(.\{-}\)\s*$', '\1', '')
  81. if str2nr(elapsed_time) > 10
  82. call remove(s:statuses, status_dir)
  83. endif
  84. endfor
  85. if len(s:statuses) == 0
  86. let s:statuses = {}
  87. endif
  88. " force to update the statusline, otherwise the user needs to move the
  89. " cursor
  90. exe 'let &ro = &ro'
  91. endfunction
  92. " vim: sw=2 ts=2 et