diff --git a/init.vim b/init.vim index a5d6e69..183d93e 100644 --- a/init.vim +++ b/init.vim @@ -54,6 +54,9 @@ call plug#begin(g:plugged_home) " vim-plug bundles {{{ + " VimScript Library + Plug 'inkarkat/vim-ingo-library' + " UI related Plug 'chriskempson/base16-vim' Plug 'itchyny/lightline.vim' @@ -209,6 +212,9 @@ tnoremap " autocmd BufWinEnter,InsertLeave,CursorMovedI * if index(HighlightWhitespacesBlacklist, &ft) < 0 | match ExtraWhitespace /\s\+\%#\@) nnoremap :nohl @@ -836,3 +842,61 @@ function! InsertSnip(snip_name) endfunction command! -nargs=1 R call InsertSnip() + +function! GenerateMarkdownHeaderAnchors() + let l:winview = winsaveview() " save cursor position + exec 'normal! gg' + + let l:match = ingo#area#frompattern#Get(0, line('$'), '\v(^#+\s+)@<=.*') + + for i in range(0, len(l:match)-1) + let l:line_nr = l:match[i][0][0] + let l:valid = 0 == len(ingo#area#frompattern#Get(l:line_nr, l:line_nr, '\v')) + if l:valid + let l:line = getbufline(bufname(), l:line_nr)[0] + let l:title = join(split(l:line)[1:-1], '-') + let l:title = tolower(l:title) + let l:title = substitute(l:title, '\V%', '%25', 'g') " MUST be first! + let l:title = substitute(l:title, '\V\', '%5C', 'g') + let l:title = substitute(l:title, '\V^', '%5E', 'g') + let l:title = substitute(l:title, '\V&\|.\|/\|,\|=\|!\|@\|#\|(\|)\|*\|$\|<\|>\|"\|', '', 'g') + let l:title = substitute(l:title, "'", '', 'g') + let l:anchor = '' + let l:next_line = l:line_nr+1 + let l:failed = append(l:line_nr, l:anchor) + exec ':' . l:line_nr . ',' . l:next_line .'j' + " use append for appending to the line? + endif + endfor + + call winrestview(l:winview) " restore cursor position +endfunction + +function! RemoveMarkdownHeaderAnchors() + let l:winview = winsaveview() " save cursor position + exec 'normal! gg' + + let l:match = ingo#area#frompattern#Get(0, line('$'), '\v(^#+\s+.*)@<=\s\\') + for i in range(0, len(l:match)-1) + call winrestview({'lnum': l:match[i][0][0], 'col': l:match[i][0][1]-1}) + let l:string_length = l:match[i][1][1] - l:match[i][0][1] + 1 + exec "normal" '"_d' . l:string_length . "l" + endfor + + call winrestview(l:winview) " restore cursor position +endfunction + +function! GenerateMarkdownTOC() + " We need remove the anchors before we run doctoc. Otherwise it would + " include the anchors in the link, and the anchors would become incorrect + call RemoveMarkdownHeaderAnchors() + exec ":w" + silent exec "!doctoc " . bufname() + exec ":e" + call GenerateMarkdownHeaderAnchors() +endfunction + +augroup MarkdownKeyBinds + autocmd! + autocmd FileType markdown nmap lt :call GenerateMarkdownTOC() +augroup END