vimsidian icon indicating copy to clipboard operation
vimsidian copied to clipboard

Insert Template Functionality

Open dlitvakb opened this issue 1 year ago • 0 comments

Here's a snippet that allows to insert a template into the current file, including path expanding completions:

function! VimsidianTemplatePaths()
  return split(globpath(g:vimsidian_path . '/Templates', '**/*.md'), '\n')
endfunction

function! VimsidianAllTemplateCompletions(ArgLead, CmdLine, CursorPos)
  return filter(copy(VimsidianTemplatePaths()), 'v:val =~ ".*'. a:ArgLead .'.*"')
endfunction

function! VimsidianInsertTemplateCommand(...)
  if a:0 != 0
    call VimsidianInsertTemplate(a:1)
    return
  endif

  let templateName = input('Template Name? ', '', 'customlist,VimsidianAllTemplateCompletions')

  let templateFilter = 'v:val =~ "(.*/?)*' . templateName . '.md"'
  if stridx(templateName, 'Templates')
    let templateFilter = 'v:val =~ "^' . templateName . '"'
  endif

  let matchedTemplates = filter(copy(VimsidianTemplatePaths()), templateFilter)
  if len(matchedTemplates) == 1
    call VimsidianInsertTemplate(matchedTemplates[0])
    return
  endif

  redraw!

  if len(matchedTemplates) == 0
    echo 'Template not found for: "' . templateName . '"'
    return
  endif

  echo 'Too many templates match. Select the correct one:'
  let index = 0
  for template in matchedTemplates
    echo '  [' . index  . '] ' . template
    let index += 1
  endfor

  let selectedIndex = input('Selected Template Index? ')
  try
    call VimsidianInsertTemplate(matchedTemplates[str2nr(selectedIndex)])
  catch
    redraw!
    echo 'Invalid Index.'
  endtry
endfunction

function! VimsidianReplaceTemplateVariables()
  let now = localtime()
  let aday = (60 * 60 * 24)

  let s:replacements = [
    \ {'from': '{{date}}', 'to': '[[' . strftime(g:vimsidian_daily_note_date_format) . ']]'},
    \ {'from': '{{previous_date}}', 'to': '[[' . strftime(g:vimsidian_daily_note_date_format, now - aday) . ']]'},
    \ {'from': '{{next_date}}', 'to': '[[' . strftime(g:vimsidian_daily_note_date_format, now + aday) . ']]'},
    \ {'from': '{{title}}', 'to': '[[' . expand('%:t:r') . ']]'},
  \ ]

  for replacement in s:replacements
    silent execute '%s/' . replacement['from'] . '/' . replacement['to'] . '/ge'
  endfor
endfunction

function! VimsidianInsertTemplate(...)
  execute ':.-1r ' . a:1
  call VimsidianReplaceTemplateVariables()
endfunction

command! -bang -complete=customlist,VimsidianAllTemplateCompletions -nargs=? VimsidianInsertTemplate call VimsidianInsertTemplateCommand(<f-args>)

augroup vimsidian_mappings
  au!
  " other mappings
  au BufNewFile,BufReadPost $VIMSIDIAN_PATH_PATTERN nn <silent> <C-a> :VimsidianInsertTemplate<CR>
augroup END

Feel free to consider it, and modify at will.

Cheers

edit: Added support for template variables that get auto replaced (inspired by your daily note)

dlitvakb avatar Jul 30 '24 10:07 dlitvakb