diff --git a/autoload/denote/commands.vim b/autoload/denote/commands.vim index 9d42aa5..f64ffab 100644 --- a/autoload/denote/commands.vim +++ b/autoload/denote/commands.vim @@ -15,9 +15,9 @@ function denote#commands#load() return endif " Register user commands - command -nargs=* Denote call denote#notes#list() | lcl | lw - command -nargs=1 -complete=custom,s:tagList DenoteByTag call denote#notes#bytag() | lcl | lw - command -nargs=+ DenoteGrep call denote#notes#grep() | lcl | lw + command -nargs=* Denote call denote#notes#list() | lcl | lopen + command -nargs=1 -complete=custom,s:tagList DenoteByTag call denote#notes#bytag() | lcl | lopen + command -nargs=+ DenoteGrep call denote#notes#grep() | lcl | lopen command -nargs=1 DenoteNew call denote#notes#new() " Register auto commands @@ -31,8 +31,8 @@ function denote#commands#load() let g:denote_commands_loaded = v:true endfunction -" " Public commands for the denote-list location list -" function denote#commands#loadll() -" command DenoteReload call denote# -" " command -nargs=1 DenoteSetTitle call denote#notes#settitle() -" endfunction +" Public commands for the denote-list location list +function denote#commands#loadll() + command DenoteReload call denote# + " command -nargs=1 DenoteSetTitle call denote#notes#settitle() +endfunction diff --git a/autoload/denote/frontmatter.vim b/autoload/denote/frontmatter.vim index f76396e..fcd10e2 100644 --- a/autoload/denote/frontmatter.vim +++ b/autoload/denote/frontmatter.vim @@ -1,4 +1,5 @@ -" Functions to create the front matter +" Functions to manipulate and query the front matter + " Helper function to put string in double quotes, and remove inside double " quotes. function s:escapeDQ(s) @@ -57,3 +58,21 @@ function denote#frontmatter#new(ft, id, title, tags=[]) \ : g:denote_fm_md_type == 'toml' ? s:md_new_toml(a:id, a:title, a:tags) \ : s:md_new_yaml(a:id, a:title, a:tags) endfunction + +" Return the frontmatter of the specified file (as a list) +function s:getFrontmatter(filename) + let l:ft = fnamemodify(a:filename, ':e') + let l:cnt = l:ft == 'org' ? 4 + \ : l:ft == 'txt' ? 5 + \ : 6 + call bufload(a:filename) + return getbufline(a:filename, 1, 1 + l:cnt) +endfunction + +" Get title from front matter +function denote#frontmatter#setTitle(filename, title) + " Retrieve front matter (number of lines depends on ft), and replace title + let l:frontmatter = s:getFrontmatter(a:filename) + call map(l:frontmatter, { _, v -> substitute(v, '^#\?+\?title:\?\s*"\?\zs.\{-\}\ze\"\?$', a:title, '')}) + call setbufline(a:filename, 1, l:frontmatter) +endfunction diff --git a/autoload/denote/ft.vim b/autoload/denote/ft.vim index 57749e7..da42768 100644 --- a/autoload/denote/ft.vim +++ b/autoload/denote/ft.vim @@ -20,7 +20,7 @@ function denote#ft#denote() setlocal includeexpr=s:gotofile() " Back references command let l:noteid = denote#meta#noteIdFromFile(expand('%:t')) - exe 'command! DenoteBackReferences DenoteGrep /\/gj' + exe 'command! -buffer DenoteBackReferences DenoteGrep /\/gj' endfunction " Location-list specifics @@ -41,7 +41,7 @@ function denote#ft#qf() nnoremap r :call denote#loclist#reload() endif " Denote-list specific configuration - " if l:context == 'denote-list' - " call denote#commands#loadll() - " endif + if l:context['denote'] == 'list' + command! -nargs=1 -range -buffer DenoteSetTitle :call denote#notes#settitle(, ) + endif endfunction diff --git a/autoload/denote/loclist.vim b/autoload/denote/loclist.vim index 87a4455..4609517 100644 --- a/autoload/denote/loclist.vim +++ b/autoload/denote/loclist.vim @@ -86,3 +86,18 @@ function denote#loclist#reload() execute ':lwindow' endif endfunction + +" Jump to window this location list belongs to +function denote#loclist#jumptowindow() + let l:locprop = getloclist(0, {'filewinid': 0}) + if type(l:locprop) != v:t_dict || !has_key(l:locprop, 'filewinid') + return + endif + let l:winid = l:locprop['filewinid'] + if l:winid == 0 + exe 'new' + exe 'wincmd K' + else + call win_gotoid(l:winid) + endif +endfunction diff --git a/autoload/denote/meta.vim b/autoload/denote/meta.vim index cf38a8d..b5f89dd 100644 --- a/autoload/denote/meta.vim +++ b/autoload/denote/meta.vim @@ -25,12 +25,22 @@ endfunction " Return the note title from the filename. function denote#meta#noteTitleFromFile(file) - return a:file->fnamemodify(':t')->matchstr('--\zs.\{-\}\ze\(==\|@@\|__\|\..\)')->substitute('-', ' ', 'g') + return a:file->fnamemodify(':t') + \ ->matchstr('--\zs.\{-\}\ze\(==\|@@\|__\|\..\)') + \ ->substitute('-', ' ', 'g') endfunction " Return the note tags from the filename as a list. function denote#meta#noteTagsFromFile(file) - return a:file->fnamemodify(':t')->matchstr('__\zs.\{-\}\ze\(==\|@@\|--\|\..\)')->split('_') + return a:file->fnamemodify(':t') + \ ->matchstr('__\zs.\{-\}\ze\(==\|@@\|--\|\..\)') + \ ->split('_') +endfunction + +" Return the note signature from the filename. +function denote#meta#noteSignatureFromFile(file) + return a:file->fnamemodify(':t') + \ ->matchstr('==\zs.\{-\}\ze\(==\|@@\|__\|\..\)') endfunction " Identifier creation @@ -39,3 +49,24 @@ function denote#meta#identifier_generate() \ ? strftime('%Y%m%dT%H%M%S') \ : rand() endfunction + +" This function removes illegal characters in parts of the filename. +function s:santizefnpart(part) + return a:part->tolower() + \ ->substitute('[^[:alnum:]]', '-', 'g') + \ ->substitute('-\+', '-', 'g') + \ ->substitute('_\+', '_', 'g') + \ ->substitute('=\+', '=', 'g') + \ ->substitute('@\+', '@', 'g') + \ ->trim('-_@=') +endfunction + +" Function that returns the filename give all metadata. The filename is +" returned with the path to the denote directory. +function denote#meta#filename(ext, identifier, title='', tags=[], signature='') + let l:f = g:denote_directory .. '/' .. s:santizefnpart(a:identifier) + let l:f ..= len(a:signature) > 0 ? ('==' .. s:santizefnpart(a:signature)) : '' + let l:f ..= len(a:title) > 0 ? ('--' .. s:santizefnpart(a:title)) : '' + let l:f ..= len(a:tags) > 0 ? ('__' .. map(copy(a:tags), {_, v -> s:santizefnpart(v)})->join('_')) : '' + return l:f .. '.' .. a:ext +endfunction diff --git a/autoload/denote/notes.vim b/autoload/denote/notes.vim index 7b7b225..886e0ad 100644 --- a/autoload/denote/notes.vim +++ b/autoload/denote/notes.vim @@ -29,15 +29,46 @@ endfunction " This creates a new denote entry with the given title and of the given " filetype. The title may be empty. function denote#notes#new(title, ft=g:denote_new_ft) - let l:identifier=g:Denote_identifier_fun() - let l:fn=l:identifier .. '--' .. a:title - \ ->tolower() - \ ->substitute('[^[:fname:]]\|/', '-', 'g') - \ ->substitute('-\+', '-', 'g') - \ ->substitute('_\+', '_', 'g') - \ ->substitute('=\+', '=', 'g') - \ ->substitute('@\+', '@', 'g') - \ ->trim('-_@=') .. '.' .. a:ft - execute 'edit ' .. g:denote_directory .. '/' .. l:fn + let l:identifier = g:Denote_identifier_fun() + let l:fn = denote#meta#filename(a:ft, l:identifier, a:title) + " Jump to window this location list belongs to + call denote#loclist#jumptowindow() + " Open file and write front matter + execute 'edit ' l:fn call setline(1, denote#frontmatter#new(a:ft, l:identifier, a:title)) endfunction + +" Function to set the title of the selected entry +function denote#notes#settitle(linenr, title) + " Get file first! + let l:items = getloclist(0, {'items': 1})['items'] + if empty(l:items) + return + endif + let l:item = l:items[a:linenr-1] + let l:bufnr = l:item['bufnr'] + let l:filename = bufname(l:bufnr) + let l:noteid = denote#meta#noteIdFromFile(l:filename) + let l:notetags = denote#meta#noteTagsFromFile(l:filename) + let l:notesignature = denote#meta#noteSignatureFromFile(l:filename) + let l:oldtitle = denote#meta#noteTitleFromFile (l:filename) + let l:ext = fnamemodify(l:filename, ':e') + let l:newfilename = denote#meta#filename(l:ext, l:noteid, a:title, l:notetags, l:notesignature) + " If this note has a front matter, we rewrite the front matter and rename the + " file. Otherwise, we rename the file only. + if index(g:denote_note_file_extensions, l:ext) >= 0 + " Handle front matter + call denote#frontmatter#setTitle(l:filename, a:title) + call denote#loclist#jumptowindow() + exe l:bufnr .. 'buf' + exe 'silent file ' .. l:newfilename + exe 'silent w' + exe 'lopen' + call delete(l:filename) + else + if fnamemodify(l:filename, ':t') == fnamemodify(l:newfilename, ':t') + return + endif + call rename(l:filename, l:newfilename) + endif +endfunction