From 4c2e10a43ae87000bf2a94109b6178e747f1c050 Mon Sep 17 00:00:00 2001 From: Alon Swartz Date: Sun, 25 May 2025 15:27:15 +0300 Subject: [PATCH] vim: note deletion with verification checks and user confirmation --- README.md | 1 + vim/doc/notesium.txt | 3 +- vim/plugin/notesium.vim | 87 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d3b8ca..4923693 100644 --- a/README.md +++ b/README.md @@ -568,6 +568,7 @@ Note: These settings should be set prior to the plugin being sourced. | `:NotesiumLinks! [LINKS_OPTS]` | Open finder: links of the active note | `:NotesiumInsertLink [LIST_OPTS]` | Open finder: insert selection as markdown link | `:NotesiumWeb [WEB_OPTS]` | Start web server, open browser (stop on idle) +| `:NotesiumDeleteNote` | Delete current note (with verify and confirm) Note: `NotesiumWeekly` depends on `g:notesium_weekstart`. diff --git a/vim/doc/notesium.txt b/vim/doc/notesium.txt index 5221ef7..a95ce9f 100644 --- a/vim/doc/notesium.txt +++ b/vim/doc/notesium.txt @@ -1,4 +1,4 @@ -notesium.txt Notesium Vim Plugin Last change: Feb 06 2025 +notesium.txt Notesium Vim Plugin Last change: May 25 2025 TABLE OF CONTENTS *notesium* *notesium-toc* ============================================================================== @@ -65,6 +65,7 @@ COMMANDS *notesium-commands* `:NotesiumLinks! [LINKS_OPTS]` Open finder: links of the active `note` `:NotesiumInsertLink [LIST_OPTS]` Open finder: insert selection as markdown link `:NotesiumWeb [WEB_OPTS]` Start web server, open browser (stop on idle) +`:NotesiumDeleteNote` Delete current note (with verify and confirm) Note: `NotesiumWeekly` depends on `g:notesium_weekstart`. diff --git a/vim/plugin/notesium.vim b/vim/plugin/notesium.vim index 78626d7..1288c1e 100644 --- a/vim/plugin/notesium.vim +++ b/vim/plugin/notesium.vim @@ -150,12 +150,99 @@ function! notesium#finder_callback_insertlink(filename, linenumber, text) abort call feedkeys((mode() == 'i' ? '' : 'a') . l:link, 'n') endfunction +" Notesium note deletion {{{1 +" ---------------------------------------------------------------------------- + +function! notesium#delete_note_check_file(filepath, filename, bufnr) abort + if !filereadable(a:filepath) + throw "The file does not exist:\n" . a:filepath + endif + if !(a:filename =~# '^[0-9a-f]\{8\}\.md$') + throw "The file does not match the filename format: " . a:filename + endif +endfunction + +function! notesium#delete_note_check_buffer(filepath, filename, bufnr) abort + if a:bufnr == -1 + throw "The file is not associated with an active buffer: " . a:filepath + endif + if getbufvar(a:bufnr, '&modified') + throw "The file has unsaved changes. Save or discard before deleting." + endif + + let l:buflines = getbufline(a:bufnr, 1, '$') + let l:filelines = readfile(a:filepath) + if l:buflines ==# [''] | let l:buflines = [] | endif + if empty(l:filelines) | let l:filelines = [] | endif + if l:buflines !=# l:filelines + throw "The file on disk differs from the loaded buffer." + endif +endfunction + +function! notesium#delete_note_check_path(filepath, filename, bufnr) abort + let l:expected = fnamemodify(expand($NOTESIUM_DIR) . '/' . a:filename, ':p') + let l:expected = simplify(resolve(l:expected)) + let l:current = simplify(resolve(a:filepath)) + if l:current !=# l:expected + throw join([ + \ 'The file is not located in the expected path per NOTESIUM_DIR.', + \ 'Expected: ' . l:expected, + \ 'Current: ' . l:current + \ ], "\n") + endif +endfunction + +function! notesium#delete_note_check_links(filepath, filename, bufnr) abort + let l:cmd = g:notesium_bin.' links ' . shellescape(a:filename) . ' --incoming' + let l:output = systemlist(l:cmd) + if v:shell_error || !empty(l:output) + let l:reason = v:shell_error + \ ? 'Failed to check for IncomingLinks' + \ : 'Refusing to delete. Note has IncomingLinks' + throw l:reason . ":\n" . join(l:output, "\n") + endif +endfunction + +function! notesium#delete_note() abort + let l:filepath = expand('%:p') + let l:filename = fnamemodify(l:filepath, ':t') + let l:bufnr = bufnr(l:filepath) + + try + call notesium#delete_note_check_file(l:filepath, l:filename, l:bufnr) + call notesium#delete_note_check_buffer(l:filepath, l:filename, l:bufnr) + call notesium#delete_note_check_path(l:filepath, l:filename, l:bufnr) + call notesium#delete_note_check_links(l:filepath, l:filename, l:bufnr) + catch /^.*/ + echoerr v:exception + return + endtry + + " User confirmation + let l:info = getbufline(l:bufnr, 1)[0] . "\n" . l:filepath + if confirm("Delete note?\n" . l:info, "&Yes\n&No", 2) != 1 + echo "User aborted" + return + endif + + " Proceed with deletion + if delete(l:filepath) != 0 + echoerr "Failed to delete file: " . l:filepath + return + endif + execute 'bdelete!' l:bufnr + echo "Deleted: " . l:filepath +endfunction + " Notesium commands {{{1 " ---------------------------------------------------------------------------- command! NotesiumNew \ execute ":e" system(g:notesium_bin . ' new') +command! NotesiumDeleteNote + \ call notesium#delete_note() + command! -nargs=* NotesiumInsertLink \ call notesium#finder({ \ 'input': 'list ' . join(map(split(), 'shellescape(v:val)'), ' '),