Browse Source

lazygit 2022-03-28 11:20

master
Gregory Leeman 3 years ago
parent
commit
6ab18a5edf
  1. 413
      autoload/notecrate.vim
  2. 28
      ftplugin/notecrate.vim
  3. 43
      syntax/notecrate.vim

413
autoload/notecrate.vim

@ -1,3 +1,4 @@
" helper {{{
function! notecrate#get_visual_selection() " {{{
let [line_start, column_start] = getpos("'<")[1:2]
let [line_end, column_end] = getpos("'>")[1:2]
@ -39,76 +40,184 @@ function! notecrate#generate_filename() " {{{
endfunction
" }}}
function! notecrate#apply_template(title) " {{{
let l:template = "\n# " . a:title . "\n\n\n\n\n---\n\n"
call setreg("l", l:template)
silent execute 'normal "lP4j'
call notecrate#update_backlinks()
function! notecrate#get_title(filename) " {{{
let l:regex = '^# \(\S.*\)$'
let l:path = b:notecrate_dir . "/" . a:filename
let l:lines = readfile(expand(l:path))
let l:line = matchstr(l:lines, l:regex)
if l:line != ""
return matchlist(l:line, l:regex)[1]
endif
return ''
endfunction
" }}}
function! notecrate#convert() " {{{
execute "normal! :w!\<CR>:!pushd " . b:notecrate_dir . "; bash convert.sh;\<CR>"
function! notecrate#get_id(filename) " {{{
return = matchstr(a:filename, '^.*\(\.md$\)\@=')
endfunction
" }}}
function! notecrate#save() " {{{
execute "normal! :!cd " . b:notecrate_dir . "; git add -A; git commit -m \"autocommit\"; git push;\<CR>"
function! notecrate#grep(pattern) " {{{
echom b:notecrate_dir
let l:files = []
try
silent execute 'vimgrep /' . a:pattern . '/j ' . b:notecrate_dir . '/*.md'
catch /^Vim\%((\a\+)\)\=:E480/ " No Match
endtry
for d in getqflist()
let l:filename = fnamemodify(bufname(d.bufnr), ":t")
call add(l:files, l:filename)
endfor
call uniq(l:files)
return l:files
endfunction
" }}}
function! notecrate#todo_filter_view() " {{{
execute "normal! :!cd " . b:notecrate_dir . "; git add -A; git commit -m \"autocommit\"; git push;\<CR>"
function! notecrate#grep_links(pattern) " {{{
let l:files = notecrate#grep(a:pattern)
let l:links = []
for filename in l:files
if filename != "index.md"
let l:title = notecrate#get_title(filename)
call add(l:links, "* [" . l:title . "](" . filename . ")")
endif
endfor
return sort(l:links)
endfunction
" }}}
function! notecrate#follow_link() " {{{
let l:link = notecrate#get_link_at_cursor()"
if type(l:link) == 4
if l:link['dest'] =~ '^.*\.md$'
call notecrate#open_note(l:link['dest'])
else
silent execute "open " . l:link['dest']
function! notecrate#fzf_sink(sink_function) " {{{
" let l:additional_options = get(a:, 1, {})
let l:preview_options = {
\ 'sink' : function(a:sink_function),
\ 'down' : '~40%',
\ 'dir' : b:notecrate_dir,
\ 'options' : ['--exact', '--tiebreak=end']
\ }
" call fzf#vim#ag("^(?=.)", fzf#vim#with_preview(l:preview_options))
call fzf#vim#ag("^# ", fzf#vim#with_preview(l:preview_options))
endfunction
" }}}
" }}}
" folding {{{
function! notecrate#indent_level(lnum) " {{{
return indent(a:lnum) / &shiftwidth
endfunction
" }}}
function! notecrate#heading_depth(lnum) " {{{
let l:depth=0
let l:thisLine = getline(a:lnum)
if l:thisLine =~ '^#\+\s\+'
let l:hashCount = len(matchstr(thisLine, '^#\{1,6}'))
if l:hashCount > 0
let l:depth = hashCount - 1
endif
elseif l:thisLine != ''
let l:nextLine = getline(a:lnum + 1)
if l:nextLine =~ '^=\+\s*$'
let l:depth = 1
elseif l:nextLine =~ '^-\+\s*$'
let l:depth = 2
endif
endif
return l:depth
endfunction
" }}}
function! notecrate#new_note(title, filename) " {{{
let l:filename = expand('%:t')
let l:notecrate_dir = b:notecrate_dir
let l:notecrate_history = b:notecrate_history
while !isdirectory(expand(b:notecrate_dir))
let choice = confirm('', b:notecrate_dir . " does not exist. Create? &Yes\n&No\n")
if choice == 1
silent execute "!mkdir " . b:notecrate_dir
else
function! notecrate#nested_markdown_folds(lnum) " {{{
let l:thisLine = getline(a:lnum)
let l:thisDepth = notecrate#heading_depth(a:lnum)
let l:thisIndent = notecrate#indent_level(a:lnum)
let l:prevLine = getline(a:lnum - 1)
let l:prevIndent = notecrate#indent_level(a:lnum - 1)
let l:nextLine = getline(a:lnum + 1)
let l:nextIndent = notecrate#indent_level(a:lnum + 1)
let l:nextDepth = notecrate#heading_depth(a:lnum + 1)
if l:thisLine =~ '^\s*<' && l:prevLine =~ '^\s*$'
return 1
endif
if l:thisLine =~ '^\s*$' && l:prevLine =~ '^\s*<'
return 0
endif
endwhile
let l:path = b:notecrate_dir . "/" . a:filename
call add(b:notecrate_history, l:filename)
silent execute "normal! :w\<CR>:e " . l:path . "\<CR>"
let b:notecrate_dir = l:notecrate_dir
let b:notecrate_history = l:notecrate_history
call notecrate#apply_template(a:title)
call notecrate#update_backlinks()
write
if l:nextLine =~ '^---$' || l:thisLine =~ '^---$'
return 0
endif
if l:thisLine =~ '^\s*$' && l:nextDepth > 0
return -1
endif
if l:thisDepth > 0
return ">".l:thisDepth
endif
if l:nextIndent == l:thisIndent
return "="
endif
if l:nextIndent > l:thisIndent
let l:dif = l:nextIndent - l:thisIndent
return "a".l:dif
endif
if l:nextIndent < l:thisIndent
let l:dif = l:thisIndent - l:nextIndent
return "s".l:dif
endif
endfunction
" }}}
function! notecrate#new_note_from_prompt() " {{{
let l:title = input("Name of new note? ")
let l:filename = notecrate#generate_filename()
call notecrate#new_note(l:title, l:filename)
function! notecrate#fold_text() " {{{
if getline(v:foldstart) =~ "^\s*<"
return "<>" . repeat(" ", winwidth(0))
endif
let l:ret = repeat(" ", indent(v:foldstart)) . trim(getline(v:foldstart))[0:-1] . " +" . repeat(" ", winwidth(0))
let l:ret = substitute(l:ret, ' \S\+:\S\+', '', 'g')
let l:ret = substitute(l:ret, '\*\*', '', 'g')
return l:ret
endfunction
" }}}
function! notecrate#new_note_from_selection() " {{{
let l:title = notecrate#get_visual_selection()
let l:filename = notecrate#generate_filename()
silent execute "normal! :'<,'>s/\\%V.*\\%V/[" . l:title . "](" . l:filename . ")/e\<CR>"
call notecrate#new_note(l:title, l:filename)
" }}}
" git {{{
function! notecrate#push() " {{{
execute "normal! :!cd " . b:notecrate_dir . "; git add -A; git commit -m \"autocommit\"; git push;\<CR>"
endfunction
" }}}
function! notecrate#pull() " {{{
execute "normal! :!cd " . b:notecrate_dir . "; git pull;\<CR>"
endfunction
" }}}
" }}}
" pandoc {{{
function! notecrate#convert() " {{{
execute "normal! :w!\<CR>:!pushd " . b:notecrate_dir . "; bash convert.sh;\<CR>"
endfunction
" }}}
" }}}
" navigation {{{
function! notecrate#follow_link() " {{{
let l:link = notecrate#get_link_at_cursor()"
if type(l:link) == 4
if l:link['dest'] =~ '^.*\.md$'
call notecrate#open_note(l:link['dest'])
else
silent execute "open " . l:link['dest']
endif
endif
endfunction
" }}}
@ -162,36 +271,6 @@ function! notecrate#open_previous() " {{{
call remove(b:notecrate_history, -1)
endfunction
" }}}
function! notecrate#get_title(filename) " {{{
let l:regex = '^# \(\S.*\)$'
let l:path = b:notecrate_dir . "/" . a:filename
let l:lines = readfile(expand(l:path))
let l:line = matchstr(l:lines, l:regex)
if l:line != ""
return matchlist(l:line, l:regex)[1]
endif
return ''
endfunction
" }}}
function! notecrate#get_id(filename) " {{{
return = matchstr(a:filename, '^.*\(\.md$\)\@=')
endfunction
" }}}
function! notecrate#fzf_sink(sink_function) " {{{
" let l:additional_options = get(a:, 1, {})
let l:preview_options = {
\ 'sink' : function(a:sink_function),
\ 'down' : '~40%',
\ 'dir' : b:notecrate_dir,
\ 'options' : ['--exact', '--tiebreak=end']
\ }
" call fzf#vim#ag("^(?=.)", fzf#vim#with_preview(l:preview_options))
call fzf#vim#ag("^# ", fzf#vim#with_preview(l:preview_options))
endfunction
" }}}
function! notecrate#search_open() " {{{
call notecrate#fzf_sink('notecrate#open_from_fzf')
@ -202,55 +281,9 @@ function! notecrate#open_from_fzf(line)
endfunction
" }}}
function! notecrate#search_insert_link() " {{{
call notecrate#fzf_sink('notecrate#insert_link_from_fzf')
endfunction
function! notecrate#insert_link_from_fzf(line)
let l:filename = substitute(a:line, ":[0-9]\*:[0-9]\*:.\*$", "", "")
let l:title = notecrate#get_title(filename)
execute "normal! a[" . l:title . "](" . l:filename . ")\<Esc>"
endfunction
" }}}
function! notecrate#search_insert_link_selection() " {{{
call notecrate#fzf_sink('notecrate#insert_link_from_fzf_selection')
endfunction
function! notecrate#insert_link_from_fzf_selection(line)
let l:filename = substitute(a:line, ":[0-9]\*:[0-9]\*:.\*$", "", "")
let l:title = notecrate#get_visual_selection()
silent execute "normal! :'<,'>s/\\%V.*\\%V/[" . l:title . "](" . l:filename . ")/e\<CR>"
endfunction
" }}}
function! notecrate#grep(pattern) " {{{
echom b:notecrate_dir
let l:files = []
try
silent execute 'vimgrep /' . a:pattern . '/j ' . b:notecrate_dir . '/*.md'
catch /^Vim\%((\a\+)\)\=:E480/ " No Match
endtry
for d in getqflist()
let l:filename = fnamemodify(bufname(d.bufnr), ":t")
call add(l:files, l:filename)
endfor
call uniq(l:files)
return l:files
endfunction
" }}}
function! notecrate#grep_links(pattern) " {{{
let l:files = notecrate#grep(a:pattern)
let l:links = []
for filename in l:files
if filename != "index.md"
let l:title = notecrate#get_title(filename)
call add(l:links, "* [" . l:title . "](" . filename . ")")
endif
endfor
return sort(l:links)
endfunction
" }}}
" notes {{{
function! notecrate#update_backlinks() " {{{
let l:filename = expand('%:t')
if l:filename == "index.md"
@ -270,8 +303,49 @@ function! notecrate#update_backlinks() " {{{
endfunction
" }}}
function! notecrate#delete_links(filename) " {{{
execute "!" . g:gsed_command . " -i 's/\\[\\([^]]*\\)\\](" . a:filename . ")/\\1/g' " . b:notecrate_dir . "/*md"
function! notecrate#apply_template(title) " {{{
let l:template = "\n# " . a:title . "\n\n\n\n\n---\n\n"
call setreg("l", l:template)
silent execute 'normal "lP4j'
call notecrate#update_backlinks()
endfunction
" }}}
function! notecrate#new_note(title, filename) " {{{
let l:filename = expand('%:t')
let l:notecrate_dir = b:notecrate_dir
let l:notecrate_history = b:notecrate_history
while !isdirectory(expand(b:notecrate_dir))
let choice = confirm('', b:notecrate_dir . " does not exist. Create? &Yes\n&No\n")
if choice == 1
silent execute "!mkdir " . b:notecrate_dir
else
return 0
endif
endwhile
let l:path = b:notecrate_dir . "/" . a:filename
call add(b:notecrate_history, l:filename)
silent execute "normal! :w\<CR>:e " . l:path . "\<CR>"
let b:notecrate_dir = l:notecrate_dir
let b:notecrate_history = l:notecrate_history
call notecrate#apply_template(a:title)
call notecrate#update_backlinks()
write
endfunction
" }}}
function! notecrate#new_note_from_prompt() " {{{
let l:title = input("Name of new note? ")
let l:filename = notecrate#generate_filename()
call notecrate#new_note(l:title, l:filename)
endfunction
" }}}
function! notecrate#new_note_from_selection() " {{{
let l:title = notecrate#get_visual_selection()
let l:filename = notecrate#generate_filename()
silent execute "normal! :'<,'>s/\\%V.*\\%V/[" . l:title . "](" . l:filename . ")/e\<CR>"
call notecrate#new_note(l:title, l:filename)
endfunction
" }}}
@ -288,86 +362,33 @@ function! notecrate#delete_note() " {{{
endfunction
" }}}
function! notecrate#indent_level(lnum) " {{{
return indent(a:lnum) / &shiftwidth
endfunction
" }}}
function! notecrate#heading_depth(lnum) " {{{
let l:depth=0
let l:thisLine = getline(a:lnum)
if l:thisLine =~ '^#\+\s\+'
let l:hashCount = len(matchstr(thisLine, '^#\{1,6}'))
if l:hashCount > 0
let l:depth = hashCount - 1
endif
elseif l:thisLine != ''
let l:nextLine = getline(a:lnum + 1)
if l:nextLine =~ '^=\+\s*$'
let l:depth = 1
elseif l:nextLine =~ '^-\+\s*$'
let l:depth = 2
endif
endif
return l:depth
" links {{{
function! notecrate#search_insert_link() " {{{
call notecrate#fzf_sink('notecrate#insert_link_from_fzf')
endfunction
function! notecrate#insert_link_from_fzf(line)
let l:filename = substitute(a:line, ":[0-9]\*:[0-9]\*:.\*$", "", "")
let l:title = notecrate#get_title(filename)
execute "normal! a[" . l:title . "](" . l:filename . ")\<Esc>"
endfunction
" }}}
function! notecrate#nested_markdown_folds(lnum) " {{{
let l:thisLine = getline(a:lnum)
let l:thisDepth = notecrate#heading_depth(a:lnum)
let l:thisIndent = notecrate#indent_level(a:lnum)
let l:prevLine = getline(a:lnum - 1)
let l:prevIndent = notecrate#indent_level(a:lnum - 1)
let l:nextLine = getline(a:lnum + 1)
let l:nextIndent = notecrate#indent_level(a:lnum + 1)
let l:nextDepth = notecrate#heading_depth(a:lnum + 1)
if l:thisLine =~ '^\s*<' && l:prevLine =~ '^\s*$'
return 1
endif
if l:thisLine =~ '^\s*$' && l:prevLine =~ '^\s*<'
return 0
endif
if l:nextLine =~ '^---$' || l:thisLine =~ '^---$'
return 0
endif
if l:thisLine =~ '^\s*$' && l:nextDepth > 0
return -1
endif
if l:thisDepth > 0
return ">".l:thisDepth
endif
if l:nextIndent == l:thisIndent
return "="
endif
if l:nextIndent > l:thisIndent
let l:dif = l:nextIndent - l:thisIndent
return "a".l:dif
endif
if l:nextIndent < l:thisIndent
let l:dif = l:thisIndent - l:nextIndent
return "s".l:dif
endif
function! notecrate#search_insert_link_selection() " {{{
call notecrate#fzf_sink('notecrate#insert_link_from_fzf_selection')
endfunction
function! notecrate#insert_link_from_fzf_selection(line)
let l:filename = substitute(a:line, ":[0-9]\*:[0-9]\*:.\*$", "", "")
let l:title = notecrate#get_visual_selection()
silent execute "normal! :'<,'>s/\\%V.*\\%V/[" . l:title . "](" . l:filename . ")/e\<CR>"
endfunction
" }}}
function! notecrate#fold_text() " {{{
if getline(v:foldstart) =~ "^\s*<"
return "<>" . repeat(" ", winwidth(0))
endif
let l:ret = repeat(" ", indent(v:foldstart)) . trim(getline(v:foldstart))[0:-1] . " +" . repeat(" ", winwidth(0))
let l:ret = substitute(l:ret, ' \S\+:\S\+', '', 'g')
let l:ret = substitute(l:ret, '\*\*', '', 'g')
return l:ret
function! notecrate#delete_links(filename) " {{{
execute "!" . g:gsed_command . " -i 's/\\[\\([^]]*\\)\\](" . a:filename . ")/\\1/g' " . b:notecrate_dir . "/*md"
endfunction
" }}}
" }}}

28
ftplugin/notecrate.vim

@ -4,31 +4,27 @@ setlocal comments+=b:*
setlocal foldlevel=3
setlocal formatoptions=cro
command! SearchOpen :call notecrate#search_open()
command! SearchInsertLink :call notecrate#search_insert_link()
command! UpdateBacklinks :call notecrate#update_backlinks()
command! NewNote :call notecrate#new_note_from_prompt()
command! DeleteNote :call notecrate#delete_note()
command! Convert :call notecrate#convert()
command! Save :call notecrate#save()
nnoremap <buffer> <leader>c :call notecrate#convert()<CR>
nnoremap <buffer> <leader>o :call notecrate#search_open()<CR>
nnoremap <buffer> <leader>i :call notecrate#search_insert_link()<CR>
nnoremap <buffer> <leader>b :call notecrate#update_backlinks()<CR>
nnoremap <buffer> <leader>n :call notecrate#new_note_from_prompt()<CR>
nnoremap <buffer> <leader>d :call notecrate#delete_note()<CR>
nnoremap <buffer> <leader>s :call notecrate#push()<CR>
nnoremap <buffer> <leader>u :call notecrate#pull()<CR>
" inoremap <buffer> <Esc> <Esc>mmgqis`m
nnoremap <buffer> <leader>c :Convert<CR>
nnoremap <buffer> <leader>o :SearchOpen<CR>
nnoremap <buffer> <leader>i :SearchInsertLink<CR>
nnoremap <buffer> <leader>b :UpdateBacklinks<CR>
nnoremap <buffer> <leader>n :NewNote<CR>
nnoremap <buffer> <leader>d :DeleteNote<CR>
nnoremap <buffer> <leader>s :Save<CR>
nnoremap <buffer> <CR> :call notecrate#follow_link()<CR>
vnoremap <buffer> <CR> :call notecrate#new_note_from_selection()<CR>
nnoremap <buffer> <backspace> :call notecrate#open_previous()<CR>
nnoremap <buffer> <S-j> /\[[^\]]*\]([^)]*)<CR>:noh<CR>
nnoremap <buffer> <S-l> /\[[^\]]*\]([^)]*)<CR>:noh<CR>
nnoremap <buffer> <Tab> /\[[^\]]*\]([^)]*)<CR>:noh<CR>
nnoremap <buffer> <S-Tab> /\[[^\]]*\]([^)]*)<CR>NN:noh<CR>
nnoremap <buffer> <S-h> /\[[^\]]*\]([^)]*)<CR>NN:noh<CR>
nnoremap <buffer> <S-k> /\[[^\]]*\]([^)]*)<CR>NN:noh<CR>
vnoremap <buffer> <leader>i :call notecrate#search_insert_link_selection()<CR>
vnoremap <buffer> <CR> :call notecrate#new_note_from_selection()<CR>
inoremap <buffer> <Tab> <C-t>
inoremap <buffer> <S-Tab> <C-d>

43
syntax/notecrate.vim

@ -6,32 +6,43 @@ set comments=b:*
setlocal nowrap
syn match NotecrateLinkInternal /\(\](\)\@<=[^()]*\()\)\@=/
hi def link NotecrateLinkInternal orangeu
" syn match NotecrateBoldConceal /\*\*/ containedin=ALL
syn match NotecrateBoldConceal /\*\*/ conceal containedin=ALL
syn match NotecrateLinkConceal /!*\[\+\([^\]]*](\)\@=/ conceal
syn match NotecrateLinkConceal /\]\+\((\)\@=/ conceal
syn match NotecrateLinkConceal /\(\[[^\]]*\]\)\@<=([^)]*)/ conceal contains=NotecrateLinkInternal
hi def link NotecrateLinkConceal blue
syn match NotecrateLink /\(\[\)\@<=[^\[\]]*\(\](\)\@=/
" syn match NotecrateLinkImage /\(!\[\+\)\@<=[^\[\]]*\(\]\+\)\@=/
hi def link NotecrateLink blueu
syn match NotecrateLinkImage /!\[\]/ containedin=ALL
hi def link NotecrateLinkImage redu
syn match NotecrateHeader1 /\(^# \)\@<=.*/
hi def link NotecrateHeader1 base3u
syn match NotecrateHeader2 /\(^##\+ \)\@<=.*/
hi def link NotecrateHeader2 base1u
syn match NotecrateRule /^---\+/
hi def link NotecrateRule base01
syn region NotecrateFrontCustomMatter start=/\%^---/ end=/^---/
hi def link NotecrateFrontCustomMatter base01
syn region NotecrateCode start=/^```/ end=/^```/
" syn match NotecrateBoldConceal /\*\*/ conceal containedin=ALL
syn match NotecrateBoldConceal /\*\*/ containedin=ALL
hi def link NotecrateCode red
syn region NotecrateBold start=/\*\*/ end=/\*\*/ contains=NotecrateBoldConceal keepend
hi def link NotecrateBold base2
syn match NotecrateQuote /^>.*$/
syn match NotecrateTag /#[^# ]\S*/
hi def link NotecrateQuote cyan
hi def link NotecrateBold base2
syn match NotecrateTag /#[^# ]\S*/
hi def link NotecrateTag cyanu
hi def link NotecrateCode red
hi def link NotecrateFrontCustomMatter base01
hi def link NotecrateHeader1 base3u
hi def link NotecrateHeader2 base1u
hi def link NotecrateLink blueu
hi def link NotecrateLinkConceal blue
hi def link NotecrateLinkImage redu
hi def link NotecrateLinkInternal orangeu
hi def link NotecrateList base2
hi def link NotecrateQuote cyan
hi def link NotecrateRule base01