" Vim filetype plugin " Language: asciidoctor " Maintainer: Maxim Kim " Filenames: *.adoc " vim: et sw=4 if exists("b:did_ftplugin") finish endif let b:did_ftplugin = 1 let s:undo_opts = "setl cms< com< fo< flp< inex< efm< cfu< fde< fdm<" let s:undo_cmds = "| delcommand Asciidoctor2PDF" \. "| delcommand Asciidoctor2HTML" \. "| delcommand Asciidoctor2DOCX" \. "| delcommand AsciidoctorOpenRAW" \. "| delcommand AsciidoctorOpenPDF" \. "| delcommand AsciidoctorOpenHTML" \. "| delcommand AsciidoctorOpenDOCX" \. "| delcommand AsciidoctorPasteImage" let s:undo_maps = "| execute 'nunmap ]]'" \. "| execute 'nunmap [['" \. "| execute 'xunmap ]]'" \. "| execute 'xunmap [['" \. "| execute 'ounmap ih'" \. "| execute 'ounmap ah'" \. "| execute 'xunmap ih'" \. "| execute 'xunmap ah'" \. "| execute 'ounmap il'" \. "| execute 'ounmap al'" \. "| execute 'xunmap il'" \. "| execute 'xunmap al'" \. "| execute 'nunmap gx'" \. "| execute 'nunmap gf'" \. "| execute 'nunmap (AsciidoctorFold)'" \. "| execute 'nunmap (AsciidoctorSectionPromote)'" \. "| execute 'nunmap (AsciidoctorSectionDemote)'" let s:undo_vars = "| unlet! b:commentary_startofline" if exists('b:undo_ftplugin') let b:undo_ftplugin .= "|" . s:undo_opts . s:undo_cmds . s:undo_maps . s:undo_vars else let b:undo_ftplugin = s:undo_opts . s:undo_cmds . s:undo_maps . s:undo_vars endif " see https://github.com/asciidoctor/asciidoctor-pdf/issues/1273 setlocal errorformat=asciidoctor:\ ERROR:\ %f:\ line\ %l:\ %m " gf to open include::file.ext[] and link:file.ext[] files setlocal includeexpr=substitute(v:fname,'\\(link:\\\|include::\\)\\(.\\{-}\\)\\[.*','\\2','g') setlocal comments= setlocal commentstring=//\ %s " vim-commentary plugin setup let b:commentary_startofline = 1 setlocal formatoptions+=cqn setlocal formatlistpat=^\\s* setlocal formatlistpat+=[ setlocal formatlistpat+=\\[({]\\? setlocal formatlistpat+=\\( setlocal formatlistpat+=[0-9]\\+ setlocal formatlistpat+=\\\| setlocal formatlistpat+=[a-zA-Z] setlocal formatlistpat+=\\) setlocal formatlistpat+=[\\]:.)} setlocal formatlistpat+=] setlocal formatlistpat+=\\s\\+ setlocal formatlistpat+=\\\| setlocal formatlistpat+=^\\s*-\\s\\+ setlocal formatlistpat+=\\\| setlocal formatlistpat+=^\\s*[*]\\+\\s\\+ setlocal formatlistpat+=\\\| setlocal formatlistpat+=^\\s*[.]\\+\\s\\+ setlocal completefunc=asciidoctor#complete_bibliography """ """ Commands """ " Use vim-dispatch if available if exists(':Make') == 2 let s:make = ':Make' else let s:make = ':make' endif exe 'command! -buffer Asciidoctor2PDF :compiler asciidoctor2pdf | ' . s:make exe 'command! -buffer Asciidoctor2HTML :compiler asciidoctor2html | ' . s:make exe 'command! -buffer Asciidoctor2DOCX :compiler asciidoctor2docx | ' . s:make command! -buffer AsciidoctorOpenRAW call asciidoctor#open_file(s:get_fname()) command! -buffer AsciidoctorOpenPDF call asciidoctor#open_file(s:get_fname(".pdf")) command! -buffer AsciidoctorOpenHTML call asciidoctor#open_file(s:get_fname(".html")) command! -buffer AsciidoctorOpenDOCX call asciidoctor#open_file(s:get_fname(".docx")) command! -buffer AsciidoctorPasteImage :call asciidoctor#pasteImage() """ """ Mappings """ nnoremap ]] :call section(0, v:count1) nnoremap [[ :call section(1, v:count1) xmap ]] "\".v:count1.']]m>gv' xmap [[ "\".v:count1.'[[m>gv' "" header textobject onoremap ih :call asciidoctor#header_textobj(v:true) onoremap ah :call asciidoctor#header_textobj(v:false) xnoremap ih :call asciidoctor#header_textobj(v:true) xnoremap ah :call asciidoctor#header_textobj(v:false) "" delimited bLock textobject onoremap il :call asciidoctor#delimited_block_textobj(v:true) onoremap al :call asciidoctor#delimited_block_textobj(v:false) xnoremap il :call asciidoctor#delimited_block_textobj(v:true) xnoremap al :call asciidoctor#delimited_block_textobj(v:false) nnoremap gx :call asciidoctor#open_url() nnoremap gf :call asciidoctor#open_url("edit") "" Useful with "" let g:asciidoctor_folding = 1 "" let g:asciidoctor_foldnested = 0 "" let g:asciidoctor_foldtitle_as_h1 = 1 "" Fold up to count foldlevel in a special way: "" * no count is provided, toggle current fold; "" * count is n, open folds of up to foldlevel n. func! s:asciidoctor_fold(count) abort if !get(g:, 'asciidoctor_folding', 0) return endif if a:count == 0 normal! za else let &foldlevel = a:count endif endfunc "" fold up to v:count foldlevel in a special way nnoremap (AsciidoctorFold) :call asciidoctor_fold(v:count) "" promote/demote sections nnoremap (AsciidoctorSectionPromote) :call asciidoctor#promote_section() nnoremap (AsciidoctorSectionDemote) :call asciidoctor#demote_section() """ """ Global options processing """ if get(g:, 'asciidoctor_opener', '') == '' if has("win32") || has("win32unix") if has("nvim") let g:asciidoctor_opener = ':silent !start ""' else let g:asciidoctor_opener = ':silent !start' endif elseif has("osx") let g:asciidoctor_opener = ":!open" elseif exists("$WSLENV") let g:asciidoctor_opener = ":silent !cmd.exe /C start" else let g:asciidoctor_opener = ":!xdg-open" endif endif if has("folding") && get(g:, 'asciidoctor_folding', 0) function! AsciidoctorFold() "{{{ let line = getline(v:lnum) if (v:lnum == 1) && (line =~ '^----*$') return ">1" endif let nested = get(g:, "asciidoctor_foldnested", v:true) " Regular headers let depth = match(line, '\(^=\+\)\@<=\( .*$\)\@=') " Do not fold nested regular headers if depth > 1 && !nested let depth = 1 endif " Setext style headings if depth < 0 let prevline = getline(v:lnum - 1) let nextline = getline(v:lnum + 1) if (line =~ '^.\+$') && (nextline =~ '^=\+$') && (prevline =~ '^\s*$') let depth = nested ? 2 : 1 endif if (line =~ '^.\+$') && (nextline =~ '^-\+$') && (prevline =~ '^\s*$') let depth = nested ? 3 : 1 endif if (line =~ '^.\+$') && (nextline =~ '^\~\+$') && (prevline =~ '^\s*$') let depth = nested ? 4 : 1 endif if (line =~ '^.\+$') && (nextline =~ '^^\+$') && (prevline =~ '^\s*$') let depth = nested ? 5 : 1 endif if (line =~ '^.\+$') && (nextline =~ '^+\+$') && (prevline =~ '^\s*$') let depth = nested ? 5 : 1 endif endif if depth > 0 " fold all sections under title if depth > 1 && get(g:, "asciidoctor_foldtitle_as_h1", v:true) let depth -= 1 endif " check syntax, it should be asciidoctorTitle or asciidoctorH let syncode = synstack(v:lnum, 1) if len(syncode) > 0 && synIDattr(syncode[0], 'name') =~ 'asciidoctor\%(H[1-6]\)\|Title\|SetextHeader' return ">" . depth endif endif " Fold options if s:asciidoctor_fold_options let opt_regex = '^:[[:alnum:]-!]\{-}:.*$' if (line =~ opt_regex) let prevline = getline(v:lnum - 1) let nextline = getline(v:lnum + 1) if (prevline !~ opt_regex) && (nextline =~ opt_regex) return "a1" endif if (nextline !~ opt_regex) && (prevline =~ opt_regex) return "s1" endif endif endif return "=" endfunction "}}} setlocal foldexpr=AsciidoctorFold() setlocal foldmethod=expr let s:asciidoctor_fold_options = get(g:, 'asciidoctor_fold_options', 0) endif if get(g:, 'asciidoctor_img_paste_command', '') == '' " first `%s` is a path " second `%s` is an image file name if has('win32') let g:asciidoctor_img_paste_command = 'gm convert clipboard: %s%s' elseif has('osx') let g:asciidoctor_img_paste_command = 'pngpaste %s%s' else " there is probably a better tool for linux? let g:asciidoctor_img_paste_command = 'gm convert clipboard: %s%s' endif endif if get(g:, 'asciidoctor_img_paste_pattern', '') == '' " first `%s` is a base document name: " (~/docs/hello-world.adoc => hello-world) " second `%s` is a number of the image. let g:asciidoctor_img_paste_pattern = 'img_%s_%s.png' endif """ """ Detect default source code language """ call asciidoctor#detect_source_language() augroup asciidoctor_source_language au! au bufwrite *.adoc,*.asciidoc call asciidoctor#refresh_source_language_hl() augroup END """ """ Helper functions """ func! s:get_fname(...) let ext = get(a:, 1, '') if ext == '' return expand("%") else return expand("%:r").ext endif endfunc "" Next/Previous section mappings func! s:section(back, cnt) for n in range(a:cnt) call search('^=\+\s\+\S\+\|\_^\%(\n\|\%^\)\@<=\k.*\n\%(==\+\|\-\-\+\|\~\~\+\|\^\^\+\|++\+\)$', a:back ? 'bW' : 'W') endfor endfunc