refacotred and split

This commit is contained in:
2026-02-25 15:32:05 +01:00
parent d4ad71543d
commit caf21ab060
10 changed files with 207 additions and 157 deletions

View File

@@ -1,21 +1,21 @@
" Global configurations {{{1
" Global configurations
" List of denote directories:
" List of denote directories
if !exists('g:denote_directories')
let g:denote_directories=[]
endif
call map(g:denote_directories, {_, d -> fnamemodify(d, ':p')})
" If only one directory has been specified, use that as denote directory
if ! empty(g:denote_directories)
let t:denote_directory = g:denote_directories[0]
endif
" if len(g:denote_directories) == 1
" let g:denote_directory = g:denote_directories[0]
" endif
" Restrict basic operations to these files:
" 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.
" 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
@@ -36,169 +36,84 @@ if !exists('g:denote_identifier_fun')
let g:denote_identifier_fun=''
endif
" Local functions {{{1
" Put all notes of the given tag to the location list. The tag argument is
" mandatory.
function s:DenoteNotesByTag(tag)
if !exists('t:denote_directory')
echohl WarningMsg
echom "Denote directory not specified, see |vim-denote|."
return
endif
" Clear location list
call denote#loclist#clear()
" Find files
let files = glob(t:denote_directory .. "*_" .. a:tag .. "*", 0, v:true)->filter('v:val->split("/")[-1] =~ "_' .. a:tag .. '\\(==\\|@@\\|__\\|_\\|\\.\\)"')
" Populate location list
let locTitle="Denote notes: " .. a:tag
call setloclist(0, [], 'r',
\ {'title': locTitle,
\ 'quickfixtextfunc' : 'denote#loclist#textNoteList'})
let notes=[]
for f in files
call add(notes, {
\ 'filename' : f,
\ 'lnum' : 1
\ })
endfor
call setloclist(0, notes, 'a')
endfunction
" Put all notes of the given tag to the location list. The search argument may be
" empty. For improving search, white spaces are replaced by the * |wildcard|.
function s:DenoteNotes(search)
if !exists('t:denote_directory')
echohl WarningMsg
echom "Denote directory not specified, see |vim-denote|."
return
endif
" Clear location list
call denote#loclist#clear()
" Find files
let s = substitute(" " .. a:search .. " ", " ", "*", "g")
let files = glob(t:denote_directory .. s, 0, v:true)
" Populate location list
let locTitle="Denote notes search:" .. a:search
call setloclist(0, [], 'r',
\ {'title': locTitle,
\ 'quickfixtextfunc' : 'denote#loclist#textNoteList'})
let notes=[]
for f in files
call add(notes, {
\ 'filename' : f,
\ 'lnum' : 1
\ })
endfor
call setloclist(0, notes, 'a')
endfunction
" This function implements the similar functionality of :vimgrep, but for
" denote notes.
function s:DenoteGrep(search)
if !exists('t:denote_directory')
echohl WarningMsg
echom "Denote directory not specified, see |vim-denote|."
return
endif
" Clear location list
call denote#loclist#clear()
" Grep all greppable files
let fpat=map(copy(g:denote_note_file_extensions), {_, e -> t:denote_directory .. "*." .. e})->join()
execute "silent! lvimgrep " .. a:search .. " " .. fpat
" Adjust location list: set title and specify display function
call setloclist(0, [], 'r',
\ {'title': 'Denote grep: ' .. a:search,
\ 'quickfixtextfunc' : 'denote#loclist#textReferences'})
lclose
lopen
endfunction
" This function is used to autocomplete the tags in user commands.
function s:tagList(ArgLead, cmdLine, CursorPos)
let files=glob(t:denote_directory .. "*", 0, v:true)
let tags=[]
for f in files
let tags=extend(tags, denote#meta#noteTagsFromFile(f))
endfor
return uniq(sort(tags))->join("\n")
endfunction
" This creates a new denote entry with the given title and of the given
" filetype. The title may be empty.
function s:DenoteNew(title, ft=g:denote_new_ft)
if !exists('t:denote_directory')
echohl WarningMsg
echom "Denote directory not specified, see |vim-denote|."
return
endif
let identifier=denote#meta#identifier_generate()
let fn=identifier .. '--' .. a:title
\ ->tolower()
\ ->substitute('[^[:fname:]]\|/', '-', 'g')
\ ->substitute('-\+', '-', 'g')
\ ->trim('-') .. '.' .. a:ft
execute "edit " .. t:denote_directory .. fn
call setline(1, denote#frontmatter#new(a:ft, identifier, a:title))
endfunction
" Transform full path into canonical form WITH trailing '/'
function s:canonicalFullPath(path)
let parts = split(a:path, '/')
let result = []
for part in parts
let l:parts = split(a:path, '/')
let l:result = []
for part in l:parts
if part == '.' || part == ''
continue
elseif part == '..'
if len(result) > 0
call remove(result, len(result)-1)
if len(l:result) > 0
call remove(l:result, len(l:result)-1)
endif
else
call add(result, part)
call add(l:result, part)
endif
endfor
return empty(result) ? '/' : '/' .. join(result, '/') .. '/'
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 a = s:canonicalFullPath(a:start)
let b = s:canonicalFullPath(a:target)
" Simple cases first: both paths are the same, or the target is a subpath
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 a == b[:strlen(a)-1]
return b[strlen(a):]
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 = matchstrpos(a .. b, '^\(/.*\)/\zs.*/\ze\1')
return l[1] == -1
\ ? substitute(a[1:-2], '[^/]\+', '..', 'g') .. b
\ : substitute(l[0], '[^/]\+', '..', 'g') .. b[l[1]:]
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, TODO: but also shows the directories
" accessible from the current position.
function s:denoteDirectoryList(ArgLead, CmdLine, CursorPos)
let prefix = fnamemodify(a:ArgLead ?? '/', ':p')
let res = []
for dendir in g:denote_directories
if prefix == dendir[:strlen(prefix)-1]
call add(res, substitute(a:ArgLead .. '/' .. s:relativePath(prefix, dendir), '/\+', '/', 'g'))
endif
endfor
" TODO: Append all subdirectories (default directory completion)
return res->join("\n")
" 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
" Public commands and key mappings {{{1
command -nargs=1 -complete=custom,<SID>denoteDirectoryList Denote let t:denote_directory = fnamemodify(<q-args>, ':p')
command -nargs=* DenoteSearch call <SID>DenoteNotes(<q-args>)
command -nargs=1 -complete=custom,<SID>tagList DenoteTag call <SID>DenoteNotesByTag(<q-args>)
command -nargs=+ DenoteGrep call <SID>DenoteGrep(<q-args>)
command -nargs=1 DenoteNew call <SID>DenoteNew(<q-args>)
" 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
" Useful key mappings
nnoremap <silent> <Plug>DenoteList :DenoteSearch<CR>:lclose<CR>:lopen<CR>:resize 20<CR>
nnoremap <silent> <Plug>DenoteBackReferences :DenoteBackReferences<CR>:lclose<CR>:lopen<CR>:resize 20<CR>
command -nargs=1 -bang -complete=custom,s:denoteDirectoryCompletion DenoteDirectory call s:setup(<f-args>)