问题
I want to implement a loose version of Niklas Luhmann's Zettelkasten in Vim. At the core of his method are note snippets that Continue the current note or Brahch off from it, introducing a slightly different topic or concept. In the note name, letters indicate branches and numerals indicate continuations. Like so:
note100
note101
note101a # branches off from note100 (related topic)
note101b # also branches off from note100 (related topic)
note101b01 # continues note101b (same topic)
note101b02 # also continues note101b (same topic)
note101c
note102
To implement this in Vim, I need new file names that are automatically enumerated either as a "continuation" or a "branch" of the note in current buffer. As a non-coder making first "real" steps in Vimscript, this is where I'm at with the Branching Note function:
function! ZettelkastenNewBranchingNote()
let b:current_note_name = expand('%:t:r')
let b:new_branching_note = call(BranchingFunctionThatReturnsNewNoteName)
silent execute 'edit' b:new_branching_note
echomsg 'New branching note ' b:new_branching_note 'created.'
endfunction
The BranchingFunctionThatReturnsNewNoteName()
should take
b:current_note_name
and extend it with automatic alphabetical(!)
index (counting alphabetically upwards). How could I accomplish this?
Also, for my New Continued Note function: how could I numerically
count upwards from the last numeric part of the current file name? (E.g. 100a01 > 100a02
.)
Thanks for any advice!
(Somewhat relatedly, here the Nexus plugin is suggested, but I'd prefer to keep my script self-contained.)
回答1:
You provide a great deal of context (which is great), but are light on the needed algorithm. To me, it looks like this: If the current file ends with a letter, increase it, else (it's a number), append an a
to start the alphabetical sequence.
Checks are done in Vim with regular expressions; \a
is a short form for [A-Za-z]
(you could also write [[:alpha:]]
; yes it's that flexible), and $
anchors it to the end of the name:
if b:current_note_name =~ '\a$'
...
Extract the last character with matchstr()
.
let lastAlpha = matchstr(b:current_note_name, '\a$')
if lastAlpha ==? 'z'
" TODO: Handle overflow
endif
To "increase" an alphabetical character, convert it first to a number, increase, then back:
let newAlpha = nr2char(char2nr(lastAlpha) + 1)
To replace, you use substitute()
, again with the same regexp.
let b:new_branching_note = substitute(b:current_note_name, '\a$', newAlpha, '')
Appending is simple:
else
let b:new_branching_note = b:current_note_name . 'a'
endif
来源:https://stackoverflow.com/questions/20457901/vim-adding-automatic-alphabetic-and-or-numeric-index-to-current-file-name