scriptencoding utf-8 if $LANG ==# 'C' let s:frames = ['-', '\', '|', '/'] else let s:frames = ['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'] endif function! gina#core#spinner#new(expr, ...) abort let options = extend({ \ 'frames': g:gina#core#spinner#frames, \ 'message': g:gina#core#spinner#message, \ 'delaytime': g:gina#core#spinner#delaytime, \ 'updatetime': g:gina#core#spinner#updatetime, \}, a:0 ? a:1 : {}) let spinner = deepcopy(s:spinner) let spinner._bufnr = bufnr(a:expr) let spinner._frames = options.frames let spinner._message = options.message let spinner._delaytime = options.delaytime let spinner._updatetime = options.updatetime return spinner endfunction function! gina#core#spinner#start(expr, ...) abort let spinner = gina#core#spinner#new(a:expr, a:0 ? a:1 : {}) call spinner.start_delay() return spinner endfunction function! s:_spinner_next() abort dict let index = self._index + 1 let self._index = index >= len(self._frames) ? 0 : index return self._index endfunction function! s:_spinner_text() abort dict let face = self._frames[self._index] return ' ' . face . ' ' . self._message endfunction function! s:_spinner_start_delay() abort dict if self._timer isnot# v:null || self._timer_delay isnot# v:null || self._delaytime < 0 return endif let self._timer_delay = timer_start( \ self._delaytime, \ self.start, \) endfunction function! s:_spinner_start(...) abort dict if self._timer isnot# v:null || self._delaytime < 0 return endif silent! call timer_stop(self._timer_delay) let self._statusline = getbufvar(self._bufnr, '&statusline') let self._timer = timer_start( \ self._updatetime, \ function('s:update_spinner', [self]), \ { 'repeat': -1 } \) let self._timer_delay = v:null endfunction function! s:_spinner_stop() abort dict if self._timer_delay isnot# v:null call timer_stop(self._timer_delay) let self._timer_delay = v:null endif if self._timer is# v:null return endif call timer_stop(self._timer) call setbufvar(self._bufnr, '&statusline', self._statusline) let self._timer = v:null endfunction function! s:update_spinner(spinner, timer) abort if !bufexists(a:spinner._bufnr) call a:spinner.stop() elseif bufwinnr(a:spinner._bufnr) >= 0 call a:spinner.next() call setbufvar(a:spinner._bufnr, '&statusline', a:spinner.text()) endif endfunction let s:spinner = { \ '_timer': v:null, \ '_timer_delay': v:null, \ '_bufnr': 0, \ '_index': 0, \ 'next': function('s:_spinner_next'), \ 'text': function('s:_spinner_text'), \ 'start': function('s:_spinner_start'), \ 'start_delay': function('s:_spinner_start_delay'), \ 'stop': function('s:_spinner_stop'), \} call gina#config(expand(''), { \ 'frames': s:frames, \ 'message': 'Loading ...', \ 'delaytime': 500, \ 'updatetime': 100, \})