1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 06:50:05 +08:00
SpaceVim/bundle/calendar.vim/autoload/calendar/argument.vim
2022-05-28 15:29:51 +08:00

321 lines
11 KiB
VimL
Vendored

" =============================================================================
" Filename: autoload/calendar/argument.vim
" Author: itchyny
" License: MIT License
" Last Change: 2020/10/17 01:28:50.
" =============================================================================
let s:save_cpo = &cpo
set cpo&vim
" Deal with argument for the :Calendar command.
let s:calendars = filter(map(split(globpath(&rtp, 'autoload/calendar/day/**.vim'), '\n'),
\ "substitute(v:val, '.*/\\|.vim', '', 'g')"),
\ 'v:val !~# "^\(default\\|gregorian\\|julian\)$"')
let s:all_value_options = {
\ '-year': [],
\ '-month': [],
\ '-day': [],
\ '-locale': [ 'default', 'en', 'ja' ],
\ '-calendar': ['default', 'gregorian', 'julian'] + sort(s:calendars),
\ '-calendar_candidates': [],
\ '-first_day': [ 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday' ],
\ '-time_zone': map(range(-12, 12), 'printf("%+03d00", v:val)'),
\ '-date_endian': [ 'little', 'big', 'middle' ],
\ '-date_separator': [ '/', '-', '.', '" "' ],
\ '-event_start_time_minwidth': [],
\ '-cache_directory': [],
\ '-updatetime': [],
\ '-view': [ 'year', 'month', 'week', 'days', 'day', 'clock', 'event', 'agenda' ],
\ '-frame': [ 'default', 'unicode', 'space', 'unicode_bold', 'unicode_round', 'unicode_double' ],
\ '-position': [ 'here', 'below', 'tab', 'left', 'right', 'topleft', 'topright' ],
\ '-split': [ 'horizontal', 'vertical' ],
\ '-width': [],
\ '-height': [],
\ '-message_prefix': [],
\ '-task_width': [],
\ }
let s:all_novalue_options = [
\ '-google_calendar',
\ '-google_task',
\ '-date_month_name',
\ '-date_full_month_name',
\ '-cyclic_view',
\ '-task',
\ '-event_start_time',
\ '-skip_event_delete_confirm',
\ '-skip_task_delete_confirm',
\ '-skip_task_clear_completed_confirm',
\ '-yank_deleting',
\ '-task_delete',
\ '-clock_12hour',
\ '-week_number',
\ '-debug' ]
let s:value_options = deepcopy(s:all_value_options)
let s:novalue_options = deepcopy(s:all_novalue_options)
if has_key(g:, 'calendar_hide_options') && type(g:calendar_hide_options) == type([]) && len(g:calendar_hide_options)
for s:k in g:calendar_hide_options
if has_key(s:value_options, s:k)
unlet s:value_options[s:k]
elseif has_key(s:value_options, '-' . s:k)
unlet s:value_options['-' . s:k]
endif
let s:i = index(s:novalue_options, s:k)
if s:i >= 0
call remove(s:novalue_options, s:i)
endif
let s:i = index(s:novalue_options, '-' . s:k)
if s:i >= 0
call remove(s:novalue_options, s:i)
endif
endfor
unlet s:k s:i
endif
let s:options = copy(s:novalue_options) + map(keys(deepcopy(s:value_options)), 'v:val . "="')
let s:all_options = copy(s:novalue_options)
for [s:key, s:val] in items(deepcopy(s:value_options))
call extend(s:all_options, map(s:val, 's:key . "=" . v:val'))
endfor
unlet s:key s:val
" Completion function.
function! calendar#argument#complete(arglead, cmdline, cursorpos) abort
try
for key in keys(s:value_options)
if a:cmdline =~# key
if a:cmdline =~# key . '=$'
return &wildmode =~# 'full'
\ ? map(copy(s:value_options[key]), 'key . "=" . v:val')
\ : copy(s:value_options[key])
elseif a:cmdline =~# key . '=\S\+$'
let lead = '^' . substitute(a:cmdline, '.*=', '', '')
let list = filter(copy(s:value_options[key]), 'v:val =~# lead')
if !len(list)
let lead = substitute(a:cmdline, '.*=', '', '')
let list = filter(copy(s:value_options[key]), 'v:val =~# lead')
endif
let arglead = substitute(a:arglead, '=.*', '=', '')
return map(list, 'arglead . v:val')
endif
endif
endfor
let s:options = copy(s:novalue_options)
\ + map(keys(deepcopy(s:value_options)), &wildmode =~# 'full' ? 'v:val' : 'v:val . "="')
let options = copy(s:options)
if a:arglead != ''
let options = sort(filter(copy(s:options), 'stridx(v:val, a:arglead) != -1'))
if len(options) == 0
let arglead = substitute(a:arglead, '^-\+', '', '')
let options = sort(filter(copy(s:options), 'stridx(v:val, arglead) != -1'))
if len(options) == 0
try
let argl = substitute(a:arglead, '\(.\)', '.*\1', 'g') . '.*'
let options = sort(filter(copy(s:options), 'v:val =~? argl'))
if len(options) == 0
let options = sort(filter(copy(s:all_options), 'stridx(v:val, arglead) != -1'))
endif
catch
let options = copy(s:options)
endtry
endif
endif
endif
return sort(filter(options, 'stridx(a:cmdline, v:val) == -1'))
catch
return s:options
endtry
endfunction
" Splitting the argument.
" This function deals with quotes.
function! calendar#argument#split(args) abort
let args = ['']
let quoteflag = 0
let quote = ''
for i in range(len(a:args))
if a:args[i] ==# ' '
if quoteflag
let args[-1] .= a:args[i]
elseif args[-1] !=# ''
call add(args, '')
endif
elseif (a:args[i] ==# '"' || a:args[i] ==# "'")
if quoteflag && quote ==# a:args[i]
call add(args, '')
let quoteflag = 0
let quote = ''
elseif quoteflag
let args[-1] .= a:args[i]
else
let quoteflag = 1
let quote = a:args[i]
endif
else
let args[-1] .= a:args[i]
endif
endfor
return filter(args, 'len(v:val)')
endfunction
" Option parsing and constructing the buffer-creating command.
function! calendar#argument#parse(args) abort
let args = calendar#argument#split(a:args)
let isnewbuffer = bufname('%') != '' || &l:filetype != '' || &modified
let name = " `='" . calendar#argument#buffername('calendar') . "'`"
let command = 'tabnew'
let commandprefix = ''
let addname = 1
let ymd = []
let variables = {}
let [width, height] = [-1, -1]
let [arg_year, flg_year] = [0, 0]
let [arg_month, flg_month] = [0, 0]
let [arg_day, flg_day] = [0, 0]
let flg_ymd = 0
for arg in args
let novalue = 0
if arg !~# '=' && arg !~# '^\d\+$'
if index(s:novalue_options, substitute(arg, '!$', '', '')) >= 0
let bang = arg =~# '!$'
let arg = substitute(arg, '!$', '', '') . '=' . (!bang)
let novalue = 1
else
let pat = substitute(substitute(arg, '^-', '=', ''), '!$', '', '') . '$'
let opts = filter(copy(s:all_options), 'v:val =~# pat')
let bang = arg =~# '!$' ? '!' : ''
if len(opts) == 1
let arg = opts[0] . bang
elseif len(opts) > 1
call calendar#echo#error(calendar#message#get('multiple_argument') . ': ' . join(opts, ', '))
endif
endif
endif
if arg =~# '='
let optvar = split(arg, '=')
if len(optvar) == 2 && (has_key(s:value_options, optvar[0]) || novalue)
let option = substitute(optvar[0], '^-\+', '', '')
if option ==# 'position'
if optvar[1] ==# 'here'
let command = 'try | edit' . name . ' | catch | tabnew' . name . ' | endtry'
let addname = 0
elseif optvar[1] ==# 'here!'
let command = 'edit!'
elseif optvar[1] ==# 'below'
if command ==# 'tabnew'
let command = 'new'
endif
let commandprefix = 'below '
let isnewbuffer = 1
elseif index(['left', 'right', 'topleft', 'topright'], optvar[1]) >= 0
if command ==# 'tabnew'
let command = 'vnew'
endif
let commandprefix = optvar[1] ==# 'left' ? 'leftabove '
\ : optvar[1] ==# 'right' ? 'rightbelow '
\ : optvar[1] ==# 'topleft' ? 'topleft '
\ : optvar[1] ==# 'topright' ? 'botright '
\ : ''
let isnewbuffer = 1
elseif optvar[1] ==# 'tab'
let command = 'tabnew'
let isnewbuffer = 1
endif
elseif option ==# 'split'
if optvar[1] ==# 'horizontal'
let command = 'new'
let isnewbuffer = 1
elseif optvar[1] ==# 'vertical'
let command = 'vnew'
let isnewbuffer = 1
endif
elseif option ==# 'width'
let width = optvar[1] + 0
elseif option ==# 'height'
let height = optvar[1] + 0
elseif option ==# 'year'
let [arg_year, flg_year, flg_ymd] = [optvar[1], 1, 1]
elseif option ==# 'month'
let [arg_month, flg_month, flg_ymd] = [optvar[1], 1, 1]
elseif option ==# 'day'
let [arg_day, flg_day, flg_ymd] = [optvar[1], 1, 1]
endif
let variables[option] = optvar[1]
endif
elseif arg =~# '^\d\+$'
call add(ymd, arg)
endif
endfor
if command ==# 'new' && height > 0
let command = height . ' ' . command
elseif command ==# 'vnew' && width > 0
let command = width . ' ' . command
endif
let cmd1 = 'keepalt '. commandprefix . command . (addname ? name : '')
let cmd2 = 'keepalt edit' . name
let command = 'if isnewbuffer | ' . cmd1 . ' | else | ' . cmd2 . '| endif'
if flg_ymd
let ymd = [arg_year, arg_month, arg_day, flg_year, flg_month, flg_day]
endif
return [isnewbuffer, command, variables, ymd]
endfunction
" :Calendar [year month day]
" The order is properly dealt with based on the endian setting.
function! calendar#argument#day(day, default) abort
let [y, m, d] = a:default
let l = len(a:day)
let endian = calendar#setting#get('date_endian')
if l == 1
let day0 = a:day[0] * 1
if 0 < day0 && day0 < 13
let [m, d] = [day0, 1]
else
let [y, m, d] = [day0, 1, 1]
endif
elseif l == 2
let [day0, day1] = [a:day[0] * 1, a:day[1] * 1]
if 0 < day0 && day0 < 13 && 0 < day1 && day1 < 32 && (endian ==# 'big' || endian ==# 'middle')
let [m, d] = [day0, day1]
elseif 0 < day0 && day0 < 32 && 0 < day1 && day1 < 13 && (endian ==# 'little')
let [m, d] = [day1, day0]
elseif 0 < day1 && day1 < 13 && endian ==# 'big'
let [y, m, d] = [day0, day1, 1]
elseif 0 < day0 && day0 < 13 && (endian ==# 'middle' || endian ==# 'little')
let [y, m, d] = [day1, day0, 1]
endif
elseif l == 3
if endian ==# 'big'
let [y, m, d] = [a:day[0] * 1, a:day[1] * 1, a:day[2] * 1]
elseif endian ==# 'middle'
let [m, d, y] = [a:day[0] * 1, a:day[1] * 1, a:day[2] * 1]
else
let [d, m, y] = [a:day[0] * 1, a:day[1] * 1, a:day[2] * 1]
endif
elseif l == 6
if a:day[3] | let y = a:day[0] | endif
if a:day[4] | let m = a:day[1] | endif
if a:day[5] | let d = a:day[2] | endif
endif
return calendar#day#new(y, m, d)
endfunction
" Decision of the buffer name.
function! calendar#argument#buffername(name) abort
let buflist = []
for i in range(tabpagenr('$'))
call extend(buflist, tabpagebuflist(i + 1))
endfor
let matcher = 'bufname(v:val) =~# ("\\[" . a:name . "\\( \\d\\+\\)\\?\\]") && index(buflist, v:val) >= 0'
let substituter = 'substitute(bufname(v:val), ".*\\(\\d\\+\\).*", "\\1", "") + 0'
let bufs = map(filter(range(1, bufnr('$')), matcher), substituter)
let i = 0
while index(bufs, i) >= 0
let i += 1
endwhile
return '[' . a:name . (len(bufs) && i ? ' ' . i : '') . ']'
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo