" ============================================================================= " 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