-" Time Handler {{{1
-
-function! s:timestamp(utc,count)
- for handler in s:time_handlers
- let [start,end,string;caps] = s:findinline('\C'.join(handler.groups,''))
- if string != ""
- let format = substitute(handler.strftime,'\\\([1-9]\)','\=caps[submatch(1)-1]','g')
- if a:utc
- let newstring = s:strftime(format,localtime()+a:count*60*15)
- elseif a:count
- let newstring = s:strftime(format,localtime()-a:count*60*15)
- else
- let newstring = s:strftime(format,{
- \ 'y': strftime('%Y'),
- \ 'b': strftime('%m'),
- \ 'd': strftime('%d'),
- \ 'h': strftime('%H'),
- \ 'm': strftime('%M'),
- \ 's': strftime('%S')})
- endif
- call s:replaceinline(start,end,newstring)
- call setpos('.',[0,line('.'),start+strlen(newstring),0])
- silent! call repeat#set("\<Plug>SpeedDatingNow".(a:utc ? "UTC" : "Local"),a:count)
- return ""
- endif
- endfor
- let [start,end,string;caps] = s:findinline('-\=\<\d\+\>')
- if string != ""
- let newstring = localtime() + (a:utc ? 1 : -1) * a:count * 60*15
- call s:replaceinline(start,end,newstring)
- call setpos('.',[0,line('.'),start+strlen(newstring),0])
- silent! call repeat#set("\<Plug>SpeedDatingNow".(a:utc ? "UTC" : "Local"),a:count)
- endif
-endfunction
-
-function! s:dateincrement(string,offset,increment) dict
- let [start,end,string;caps] = s:match(a:string,'\C'.join(self.groups,''))
- let string = a:string
- let offset = a:offset
- let cursor_capture = 1
- let idx = 0
- while idx < len(self.groups)
- let partial_matchend = matchend(string,join(self.groups[0:idx],''))
- if partial_matchend > offset
- break
- endif
- let idx += 1
- endwhile
- while get(self.targets,idx,"") == " "
- let idx += 1
- endwhile
- while get(self.targets,idx," ") == " "
- let idx -= 1
- endwhile
- let partial_pattern = join(self.groups[0:idx],'')
- let char = self.targets[idx]
- let i = 0
- let time = {}
- for cap in caps
- if get(self.reader,i," ") !~ '^\s\=$'
- let time[self.reader[i]] = substitute(cap,'^\s*','','')
- endif
- let i += 1
- endfor
- call s:initializetime(time)
- let time[char] += a:increment
- let format = substitute(self.strftime,'\\\([1-9]\)','\=caps[submatch(1)-1]','g')
- let time_string = s:strftime(format,time)
- return [time_string, matchend(time_string,partial_pattern)]
-endfunction
-
-let s:strftime_items = {
- \ "a": ['d','w',s:ary2pat(s:days_abbr), 'weekday (abbreviation)',s:days_abbr],
- \ "A": ['d','w',s:ary2pat(s:days_full), 'weekday (full name)',s:days_full],
- \ "i": ['d','w',s:ary2pat(s:days_engl), 'weekday (English abbr)',s:days_engl],
- \ "b": ['b','b',s:ary2pat(s:months_abbr), 'month (abbreviation)',[""]+s:months_abbr],
- \ "B": ['b','b',s:ary2pat(s:months_full), 'month (full name)',[""]+s:months_full],
- \ "h": ['b','b',s:ary2pat(s:months_engl), 'month (English abbr)',[""]+s:months_engl],
- \ "d": ['d','d','[ 0-3]\=\d', 'day (01-31)',2],
- \ "H": ['h','h','[ 0-2]\=\d', 'hour (00-23)',2],
- \ "I": ['h','h','[ 0-2]\=\d', 'hour (01-12)',['12', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11']],
- \ "m": ['b','b','[ 0-1]\=\d', 'month (01-12)',2],
- \ "M": ['m','m','[ 0-5]\=\d', 'minutes',2],
- \ "o": ['d','d','[ 0-3]\=\d\%(st\|nd\|rd\|th\)','day (1st-31st)',s:function("s:ordinalize")],
- \ "P": ['h','p','[ap]m', 'am/pm',repeat(['am'],12) + repeat(['pm'],12)],
- \ "S": ['s','s','[ 0-5]\=\d', 'seconds',2],
- \ "v": ['y','y','[ivxlcdmn]\+','year (roman numerals)',s:function("s:arabic2roman")],
- \ "y": ['y','y','\d\d','year (00-99)',s:function("s:modyear")],
- \ "Y": ['y','y','-\=\d\d\d\=\d\=','year',4]}
-
-function! s:timeregexp() dict
- return join(self.groups,'')
-endfunction
-
-function! s:createtimehandler(format)
- let pattern = '^\%(%?\=\[.\{-\}\]\|%[-_0^]\=.\|[^%]*\)'
- let regexp = ['\%(\<\|-\@=\)']
- let reader = []
- let targets = [' ']
- let template = ""
- let default = ""
- let remaining = substitute(a:format,'\C%\@<!%p','%^P','g')
- let group = 0
- let usergroups = []
- let userdefaults = []
- while remaining != ""
- let fragment = matchstr(remaining,pattern)
- let remaining = matchstr(remaining,pattern.'\zs.*')
- if fragment =~ '^%\*\W'
- let suffix = '*'
- let fragment = '%' . strpart(fragment,2)
- elseif fragment =~ '^%?\W'
- let suffix = '\='
- let fragment = '%' . strpart(fragment,2)
- else
- let suffix = ''
- endif
- let targets += [' ']
- if fragment =~ '^%' && has_key(s:strftime_items,matchstr(fragment,'.$'))
- let item = s:strftime_items[matchstr(fragment,'.$')]
- let modifier = matchstr(fragment,'^%\zs.\ze.$')
- let targets[-1] = item[0]
- let reader += [item[1]]
- if modifier == '^'
- let pat = substitute(item[2],'\C\\\@<![[:lower:]]','\u&','g')
- elseif modifier == '0'
- let pat = substitute(item[2],' \|-\@<!\\=','','g')
- else
- let pat = item[2]
- endif
- let regexp += ['\('.pat.'\)']
- let group += 1
- let template .= fragment
- let default .= fragment
- elseif fragment =~ '^%\[.*\]$'
- let reader += [' ']
- let regexp += ['\('.matchstr(fragment,'\[.*').suffix.'\)']
- let group += 1
- let usergroups += [group]
- let template .= "\\".group
- if suffix == ""
- let default .= strpart(fragment,2,1)
- let userdefaults += [strpart(fragment,2,1)]
- else
- let userdefaults += [""]
- endif
- elseif fragment =~ '^%\d'
- let regexp += ["\\".usergroups[strpart(fragment,1)-1]]
- let template .= regexp[-1]
- let default .= userdefaults[strpart(fragment,1)-1]
- elseif fragment == '%*'
- if len(regexp) == 1
- let regexp = []
- let targets = []
- else
- let regexp += ['\(.*\)']
- endif
- else
- let regexp += [fragment]
- let template .= fragment
- let default .= fragment
- endif
- endwhile
- if regexp[-1] == '\(.*\)'
- call remove(regexp,-1)
- call remove(targets,-1)
- else
- let regexp += ['\>']
- endif
- return {'source': a:format, 'strftime': template, 'groups': regexp, 'regexp': s:function('s:timeregexp'), 'reader': reader, 'targets': targets, 'default': default, 'increment': s:function('s:dateincrement')}
-endfunction
-
-function! s:comparecase(i1, i2)
- if a:i1 ==? a:i2
- return a:i1 ==# a:i2 ? 0 : a:i1 ># a:i2 ? 1 : -1
- else
- return tolower(a:i1) > tolower(a:i2) ? 1 : -1
- endif
-endfunction
-
-function! s:adddate(master,count,bang)
- if a:master == ""
- if a:bang && a:count
- silent! call remove(s:time_handlers,a:count - 1)
- elseif a:bang
- echo "SpeedDatingFormat List defined formats"
- echo "SpeedDatingFormat! This help"
- echo "SpeedDatingFormat %Y-%m-%d Add a format"
- echo "1SpeedDatingFormat %Y-%m-%d Add a format before first format"
- echo "SpeedDatingFormat! %Y-%m-%d Remove a format"
- echo "1SpeedDatingFormat! Remove first format"
- echo " "
- echo "Expansions:"
- for key in sort(keys(s:strftime_items),s:function("s:comparecase"))
- echo printf("%2s %-25s %s",'%'.key,s:strftime_items[key][3],s:strftime('%'.key,localtime()))
- endfor
- echo '%0x %x with mandatory leading zeros'
- echo '%_x %x with spaces rather than leading zeros'
- echo '%-x %x with no leading spaces or zeros'
- echo '%^x %x in uppercase'
- echo '%* at beginning/end, surpress \</\> respectively'
- echo '%[..] any one character \([..]\)'
- echo '%?[..] up to one character \([..]\=\)'
- echo '%1 character from first collection match \1'
- echo " "
- echo "Examples:"
- echo 'SpeedDatingFormat %m%[/-]%d%1%Y " American 12/25/2007'
- echo 'SpeedDatingFormat %d%[/-]%m%1%Y " European 25/12/2007'
- echo " "
- echo "Define formats in ".s:install_dir."/after/plugin/speeddating.vim"
- elseif a:count
- echo get(s:time_handlers,a:count-1,{'source':''}).source
- else
- let i = 0
- for handler in s:time_handlers
- let i += 1
- echo printf("%3d %-32s %-32s",i,handler.source,s:strftime(handler.default,localtime()))
- endfor
- endif
- elseif a:bang
- call filter(s:time_handlers,'v:val.source != a:master')
- else
- let handler = s:createtimehandler(a:master)
- if a:count
- call insert(s:time_handlers,handler,a:count - 1)
- else
- let s:time_handlers += [handler]
- endif
- endif
-endfunction