120 lines
3.6 KiB
VimL
120 lines
3.6 KiB
VimL
" Global configurations
|
|
if exists('g:loaded_denote')
|
|
finish
|
|
endif
|
|
let g:loaded_denote = 1
|
|
|
|
" List of denote directories
|
|
if !exists('g:denote_directories')
|
|
let g:denote_directories = []
|
|
endif
|
|
call map(g:denote_directories, {_, d -> fnamemodify(d, ':p')})
|
|
|
|
" Restrict basic operations to these files
|
|
if !exists('g:denote_note_file_extensions')
|
|
let g:denote_note_file_extensions = ['md', 'org', 'txt']
|
|
endif
|
|
|
|
" Number of columns used for the title in the location window
|
|
if !exists('g:denote_loc_title_columns')
|
|
let g:denote_loc_title_columns = 40
|
|
endif
|
|
|
|
" Default filetype for newly created denote entries
|
|
if !exists('g:denote_new_ext')
|
|
let g:denote_new_ext = 'md'
|
|
endif
|
|
|
|
" Default front-matter type for markdown notes, may be one of 'yaml' or 'toml'
|
|
if !exists('g:denote_fm_md_type')
|
|
let g:denote_fm_md_type = 'yaml'
|
|
endif
|
|
|
|
" By using the following global variable, the user may specify a custom
|
|
" function for creating identifiers.
|
|
if !exists('g:Denote_identifier_fun')
|
|
let g:Denote_identifier_fun = function('libdenote#scheme_idgen')
|
|
endif
|
|
|
|
" Transform full path into canonical form WITH trailing '/'
|
|
function s:canonicalFullPath(path)
|
|
let l:parts = split(a:path, '/')
|
|
let l:result = []
|
|
for part in l:parts
|
|
if part == '.' || part == ''
|
|
continue
|
|
elseif part == '..'
|
|
if len(l:result) > 0
|
|
call remove(l:result, len(l:result)-1)
|
|
endif
|
|
else
|
|
call add(l:result, part)
|
|
endif
|
|
endfor
|
|
return empty(l:result) ? '/' : '/' .. join(l:result, '/') .. '/'
|
|
endfunction
|
|
|
|
" Compute the relative path from start to target. Both arguments are given as
|
|
" full paths.
|
|
function s:relativePath(start, target)
|
|
let l:a = s:canonicalFullPath(a:start)
|
|
let l:b = s:canonicalFullPath(a:target)
|
|
" Simple cases first: both paths are the same, or the target is l:a subpath
|
|
" from the start.
|
|
if l:a == l:b[:strlen(l:a)-1]
|
|
return l:b[strlen(l:a):]
|
|
endif
|
|
" Now, we need to go back. If the following match fails, then we need to go
|
|
" back all the way
|
|
let l:l = matchstrpos(l:a .. l:b, '^\(/.*\)/\zs.*/\ze\1')
|
|
return l:l[1] == -1
|
|
\ ? substitute(l:a[1:-2], '[^/]\+', '..', 'g') .. l:b
|
|
\ : substitute(l:l[0], '[^/]\+', '..', 'g') .. l:b[l:l[1]:]
|
|
endfunction
|
|
|
|
" Complete all paths to the denote directories. This functions completes the
|
|
" paths to the configured directories.
|
|
function s:denoteDirectoryCompletion(ArgLead, CmdLine, CursorPos)
|
|
let l:res = []
|
|
let l:bang = match(a:CmdLine, '^\S\+!') >= 0
|
|
let l:argleaddir = isdirectory(expand(a:ArgLead)) ? a:ArgLead : matchstr(a:ArgLead, '^.*/')
|
|
if strlen(l:argleaddir) == 0
|
|
let l:argleaddir = '~'
|
|
endif
|
|
if l:argleaddir !~ '/$'
|
|
let l:argleaddir = l:argleaddir .. '/'
|
|
endif
|
|
if l:bang
|
|
for ldir in (glob(expand(l:argleaddir) .. '/*', v:true, v:true)->filter('isdirectory(v:val)'))
|
|
call add(l:res, l:argleaddir .. fnamemodify(ldir, ':t'))
|
|
endfor
|
|
else
|
|
let l:leaddir = s:canonicalFullPath(fnamemodify(l:argleaddir, ':p'))
|
|
for ldir in g:denote_directories
|
|
if l:leaddir == ldir[:strlen(l:leaddir)-1]
|
|
call add(l:res, l:argleaddir .. s:relativePath(l:leaddir, ldir))
|
|
endif
|
|
endfor
|
|
endif
|
|
return l:res->join("\n")
|
|
endfunction
|
|
|
|
" Setup denote plugin, i.e.,
|
|
" - set the denote directory
|
|
" - register user commands
|
|
" - register auto commands
|
|
function s:setup(dir)
|
|
" Set the denote directory
|
|
let l:tmp = s:canonicalFullPath(fnamemodify(a:dir, ':p'))[:-2]
|
|
if !isdirectory(l:tmp)
|
|
echohl WarningMsg
|
|
echom "The specified argument is not a directory (" .. a:dir .. ")"
|
|
return
|
|
endif
|
|
let g:denote_directory = l:tmp
|
|
" Register user commands and auto commands
|
|
call denote#commands#load()
|
|
endfunction
|
|
|
|
command -nargs=1 -bang -complete=custom,s:denoteDirectoryCompletion DenoteDirectory call s:setup(<f-args>)
|