mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-03 06:50:05 +08:00
321 lines
11 KiB
VimL
Vendored
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
|