let s:Process = vital#plantuml_previewer#new().import('System.Process') let s:Job = vital#plantuml_previewer#new().import('System.Job') let s:is_win = has('win32') || has('win64') || has('win95') let s:base_path = fnameescape(expand(":p:h")) . '/..' let s:default_jar_path = s:base_path . '/lib/plantuml.jar' let s:tmp_path = s:base_path . '/tmp' let s:save_as_script_path = s:base_path . '/script/save-as' . (s:is_win ? '.cmd' : '.sh') let s:update_viewer_script_path = s:base_path . '/script/update-viewer' . (s:is_win ? '.cmd' : '.sh') let s:watched_bufnr = 0 let s:started = v:false let s:java = get(g:, 'plantuml_java_command', 'java') function! plantuml_previewer#start() "{{{ if !executable(s:java) echoerr 'require java command' return v:false endif let viewer_path = s:viewer_path() if !isdirectory(viewer_path) && !filereadable(viewer_path) call plantuml_previewer#copy_viewer_directory() endif call delete(s:viewer_tmp_puml_path()) call delete(s:viewer_tmp_svg_path()) let s:watched_bufnr = bufnr('%') call plantuml_previewer#refresh(s:watched_bufnr) augroup plantuml_previewer autocmd! autocmd BufWritePost *.pu,*.uml,*.plantuml,*.puml,*.iuml call plantuml_previewer#refresh(s:watched_bufnr) augroup END return v:true endfunction "}}} function! plantuml_previewer#open() "{{{ if !exists('*OpenBrowser') echoerr 'require open-browser.vim' return v:false endif let start_result = plantuml_previewer#start() if !start_result return v:false endif call OpenBrowser(s:viewer_html_path()) let s:started = v:true return v:true endfunction "}}} function! plantuml_previewer#stop() "{{{ augroup plantuml_previewer autocmd! augroup END let s:started = v:false endfunction "}}} function! plantuml_previewer#toggle() abort if s:started call plantuml_previewer#stop() echo 'plantuml-previewer stopped' else let open_result = plantuml_previewer#open() if open_result echo 'plantuml-previewer opened' endif endif endfunction function! s:is_zero(val) "{{{ return type(a:val) == type(0) && a:val == 0 endfunction "}}} function! plantuml_previewer#copy_viewer_directory() "{{{ let viewer_path = s:viewer_path() let default_viewer_path = plantuml_previewer#default_viewer_path() if viewer_path != default_viewer_path if s:is_win call system('xcopy ' . default_viewer_path . ' ' . g:plantuml_previewer#viewer_path . ' /O /X /E /H /K') else call system('cp -r ' . default_viewer_path . ' ' . g:plantuml_previewer#viewer_path) endif echom 'copy ' . default_viewer_path . ' -> ' . viewer_path endif endfunction "}}} function! plantuml_previewer#default_viewer_path() "{{{ return s:base_path . '/viewer' endfunction "}}} function! s:viewer_path() "{{{ let path = get(g:, 'plantuml_previewer#viewer_path', 0) return s:is_zero(path) ? plantuml_previewer#default_viewer_path() : fnameescape(path) endfunction "}}} function! s:viewer_tmp_puml_path() "{{{ return s:viewer_path() . '/tmp.puml' endfunction "}}} function! s:viewer_tmp_svg_path() "{{{ return s:viewer_path() . '/tmp.svg' endfunction "}}} function! s:viewer_tmp_js_path() "{{{ return s:viewer_path() . '/tmp.js' endfunction "}}} function! s:viewer_html_path() "{{{ return s:viewer_path() . '/index.html' endfunction "}}} function! s:jar_path() "{{{ let path = get(g:, 'plantuml_previewer#plantuml_jar_path', 0) return s:is_zero(path) ? s:default_jar_path : path endfunction "}}} function! s:save_format() "{{{ return get(g:, 'plantuml_previewer#save_format', 'png') endfunction "}}} function! s:ext_to_fmt(ext) "{{{ return a:ext == 'tex' ? 'latex' : a:ext endfunction "}}} function! s:fmt_to_ext(fmt) "{{{ return a:fmt == 'latex' ? 'tex' : a:fmt endfunction "}}} function! s:run_in_background(cmd) "{{{ if s:Job.is_available() call s:Job.start(a:cmd) else try call s:Process.execute(a:cmd, { \ 'background': 1, \}) catch call s:Process.execute(a:cmd) endtry endif endfunction "}}} function! s:normalize_path(path) "{{{ return simplify(expand(a:path, 1)) endfunction "}}} function! plantuml_previewer#refresh(bufnr) "{{{ let puml_src_path = fnamemodify(bufname(a:bufnr), ':p') let puml_filename = fnamemodify(puml_src_path, ':t:r') let image_type = 'svg' let image_ext = s:fmt_to_ext(image_type) let output_dir_path = s:tmp_path let output_path = output_dir_path . '/' . puml_filename . '.' . image_ext let finial_path = s:viewer_path() . '/tmp.' . image_ext let cmd = [ \ s:update_viewer_script_path, \ s:java, \ s:jar_path(), \ puml_src_path, \ s:normalize_path(output_dir_path), \ s:normalize_path(output_path), \ s:normalize_path(finial_path), \ image_type, \ localtime(), \ s:normalize_path(s:viewer_tmp_js_path()), \ ] call s:run_in_background(cmd) endfunction "}}} function! plantuml_previewer#save_as(...) "{{{ if !executable('java') echoerr 'require java command' return endif let save_path = get(a:000, 0, 0) let image_type = get(a:000, 1, 0) if s:is_zero(save_path) let source_name = expand('%:t:r') let save_path = printf("%s.%s", source_name, s:fmt_to_ext(s:save_format())) else let save_path = fnamemodify(save_path, ':p') endif if s:is_zero(image_type) let ext = fnamemodify(save_path, ':e') let image_type = ext == '' ? s:save_format() : s:ext_to_fmt(ext) endif let puml_src_path = expand('%:p') let puml_filename = fnamemodify(puml_src_path, ':t:r') let image_ext = s:fmt_to_ext(image_type) let output_dir_path = s:tmp_path let output_path = output_dir_path . '/' . puml_filename . '.' . image_ext call mkdir(fnamemodify(save_path, ':p:h'), 'p') let cmd = [ \ s:save_as_script_path, \ s:java, \ s:jar_path(), \ puml_src_path, \ s:normalize_path(output_dir_path), \ s:normalize_path(output_path), \ s:normalize_path(save_path), \ image_type, \ ] call s:run_in_background(cmd) endfunction "}}}