1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 16:50:05 +08:00
SpaceVim/bundle/calendar.vim/autoload/calendar/constructor/view_clock.vim

222 lines
6.4 KiB
VimL
Raw Normal View History

" =============================================================================
" Filename: autoload/calendar/constructor/view_clock.vim
" Author: itchyny
" License: MIT License
" Last Change: 2015/03/29 06:26:59.
" =============================================================================
let s:save_cpo = &cpo
set cpo&vim
function! calendar#constructor#view_clock#new(instance) abort
return extend({ 'instance': a:instance }, s:constructor)
endfunction
let s:constructor = {}
function! s:constructor.new(source) dict abort
return extend(extend(s:super_constructor.new(a:source), s:instance), self.instance)
endfunction
let s:instance = {}
let s:instance.letters = []
let s:instance.prevscale = 0
let s:instance.syntax = []
let s:instance.diffs = []
let s:instance.smaller = 0
let s:instance.offsetx_start = 0
let s:instance.colnum = 1
let s:instance.winwidth = 0
let s:instance.winheight = 0
let s:instance.str = ''
let s:instance.len = 0
let s:instance._colnum = 0
function! s:instance.get_scale(...) dict abort
let colnum = a:0 ? a:1 : self.colnum
let [h, w] = [self.maxheight(), self.maxwidth()]
if self.winwidth == w && self.winheight == h && self._colnum == colnum
return self.scale
endif
let str = self.max_letter()[0]
let len = calendar#pixel#len(str) + 2 * (len(str) - 1)
let scale = 0
while w >= len * (scale + 1) * (15 + scale) / 15 + 1 &&
\ h >= 6 * (scale + 1) * self.y_height * colnum + 1
let scale += 1
endwhile
if scale > 1 && self.smaller
let scale -= 1
endif
let self.scale = scale
let self.winwidth = w
let self.winheight = h
let self._colnum = colnum
return scale
endfunction
function! s:instance.width() dict abort
let str = self.get_letter()[0]
if self.str !=# str
let self.len = calendar#pixel#len(str) + 2 * (len(str) - 1)
endif
let [h, w] = [self.maxheight(), self.maxwidth()]
if self.winwidth != w || self.winheight != h
let scale = self.get_scale()
endif
let self.winwidth = w
let self.winheight = h
let self.str = str
return self.scale ? self.len * self.scale : len(str)
endfunction
function! s:instance.height() dict abort
if self.winwidth != self.maxwidth() || self.winheight != self.maxheight()
let scale = self.get_scale()
endif
let self.one_height = self.scale ? 5 * self.scale : 1
return self.scale ? self.one_height * self.y_height : 1
endfunction
function! s:instance.gen_syn(chr, offsetx, offsety, syn) dict abort
if !len(a:chr)
return [[], 0]
endif
if !self.scale
return [[calendar#text#new(a:chr, a:offsetx, a:offsety, '')], 1]
endif
let pixel = calendar#pixel#get(a:chr)
if type(pixel) != type([])
return [[], 0]
endif
let syn = []
let max = 0
let j = 0
let scale = self.scale
let pp = ''
let above_num = 0
for p in pixel
if pp ==# p && above_num && len(syn)
let h = syn[-1].syn[0][4]
for i in range(above_num)
call syn[- 1 - i].height((h ? h : scale) + scale)
endfor
else
let max = max([max, (len(p) + 2) * scale])
let i = 0
let num = 0
while i < len(p)
let i += len(matchstr(p, '^\.*', i))
let matchlen = len(matchstr(p, '^[^.]*', i))
if matchlen
if num
call add(syn[-1].syn, [a:syn, a:offsety + j * scale, a:offsetx + i * scale, a:offsetx + i * scale + matchlen * scale, scale])
else
call add(syn, calendar#text#new(matchlen * scale, a:offsetx + i * scale, a:offsety + j * scale, a:syn).height(scale))
let num += 1
endif
endif
let i += matchlen
endwhile
let pp = p
let above_num = num
endif
let j += 1
endfor
return [syn, max]
endfunction
function! s:instance.set_contents() dict abort
let cs = self.get_letter()
let syntax = []
let diffs = []
let syn = 'NormalSpace'
let offsetx_start = 0
for j in range(len(cs))
if j >= self.y_height
break
endif
if self.prevscale == self.scale && len(self.letters) == len(cs) && self.letters[j] ==# cs[j]
let syntax_oneline = self.syntax[j]
let diffsj = self.diffs[j]
else
let syntax_oneline = []
let diffsj = []
let offsetx = len(cs[j]) ? - calendar#pixel#whitelen(cs[j][0]) * self.scale : 0
let offsetx_start = offsetx
let offsety = j * (5 + self.scale + 1)
let css = split(cs[j], '\zs')
for i in range(len(css))
if self.prevscale == self.scale && len(self.letters) == len(cs) && len(self.letters[j]) == len(css) &&
\ self.letters[j][i] ==# css[i] && diffsj == (i ? self.diffs[j][:i - 1] : []) && offsetx_start == self.offsetx_start
call add(syntax_oneline, self.syntax[j][i])
let diffx = self.diffs[j][i]
else
let [syns, diffx] = self.gen_syn(css[i], offsetx, offsety, syn)
call add(syntax_oneline, syns)
endif
let offsetx += diffx
call add(diffsj, diffx)
endfor
endif
call add(syntax, syntax_oneline)
call add(diffs, diffsj)
endfor
let self.letters = cs
let self.syntax = syntax
let self.prevscale = self.scale
let self.diffs = diffs
let self.offsetx_start = offsetx_start
let self.syn = []
let ydict = {}
let j = 0
for ss in syntax
for sss in ss
if self.scale
for ssss in sss
if has_key(ydict, ssss.y)
call extend(self.syn[ydict[ssss.y]].syn, ssss.syn)
else
call add(self.syn, deepcopy(ssss))
let ydict[ssss.y] = j
let j += 1
endif
endfor
else
call extend(self.syn, sss)
endif
endfor
endfor
endfunction
function! s:instance.on_resize() dict abort
let self.letters = []
let self.syntax = []
endfunction
function! s:instance.contents() dict abort
if self.letters != self.get_letter()
call self.set_contents()
endif
let syn = deepcopy(self.syn)
if self.is_selected() && len(self.syntax) && len(self.syntax[-1]) && len(self.syntax[-1][-1])
let cur = deepcopy(self.syntax[-1][-1][-1])
if len(cur.syn) && len(cur.syn[0]) > 3
let cur.syn[0][0] = 'Cursor'
let cur.t = 1
call cur.move(cur.syn[0][3] - cur.syn[0][2] - !!self.scale, cur.syn[0][4] ? cur.syn[0][4] - 1 : 0)
call add(syn, cur)
endif
endif
return syn
endfunction
function! s:instance.updated() dict abort
return self.letters != self.get_letter()
endfunction
let s:super_constructor = calendar#constructor#view#new(s:instance)
let &cpo = s:save_cpo
unlet s:save_cpo