1*46fceaaaSBram Moolenaar" Language: ConTeXt typesetting engine 2*46fceaaaSBram Moolenaar" Maintainer: Nicola Vitacolonna <[email protected]> 3*46fceaaaSBram Moolenaar" Latest Revision: 2016 Oct 21 4*46fceaaaSBram Moolenaar 5*46fceaaaSBram Moolenaarlet s:keepcpo= &cpo 6*46fceaaaSBram Moolenaarset cpo&vim 7*46fceaaaSBram Moolenaar 8*46fceaaaSBram Moolenaar" Helper functions {{{ 9*46fceaaaSBram Moolenaarfunction! s:context_echo(message, mode) 10*46fceaaaSBram Moolenaar redraw 11*46fceaaaSBram Moolenaar echo "\r" 12*46fceaaaSBram Moolenaar execute 'echohl' a:mode 13*46fceaaaSBram Moolenaar echomsg '[ConTeXt]' a:message 14*46fceaaaSBram Moolenaar echohl None 15*46fceaaaSBram Moolenaarendf 16*46fceaaaSBram Moolenaar 17*46fceaaaSBram Moolenaarfunction! s:sh() 18*46fceaaaSBram Moolenaar return has('win32') || has('win64') || has('win16') || has('win95') 19*46fceaaaSBram Moolenaar \ ? ['cmd.exe', '/C'] 20*46fceaaaSBram Moolenaar \ : ['/bin/sh', '-c'] 21*46fceaaaSBram Moolenaarendfunction 22*46fceaaaSBram Moolenaar 23*46fceaaaSBram Moolenaar" For backward compatibility 24*46fceaaaSBram Moolenaarif exists('*win_getid') 25*46fceaaaSBram Moolenaar 26*46fceaaaSBram Moolenaar function! s:win_getid() 27*46fceaaaSBram Moolenaar return win_getid() 28*46fceaaaSBram Moolenaar endf 29*46fceaaaSBram Moolenaar 30*46fceaaaSBram Moolenaar function! s:win_id2win(winid) 31*46fceaaaSBram Moolenaar return win_id2win(a:winid) 32*46fceaaaSBram Moolenaar endf 33*46fceaaaSBram Moolenaar 34*46fceaaaSBram Moolenaarelse 35*46fceaaaSBram Moolenaar 36*46fceaaaSBram Moolenaar function! s:win_getid() 37*46fceaaaSBram Moolenaar return winnr() 38*46fceaaaSBram Moolenaar endf 39*46fceaaaSBram Moolenaar 40*46fceaaaSBram Moolenaar function! s:win_id2win(winnr) 41*46fceaaaSBram Moolenaar return a:winnr 42*46fceaaaSBram Moolenaar endf 43*46fceaaaSBram Moolenaar 44*46fceaaaSBram Moolenaarendif 45*46fceaaaSBram Moolenaar" }}} 46*46fceaaaSBram Moolenaar 47*46fceaaaSBram Moolenaar" ConTeXt jobs {{{ 48*46fceaaaSBram Moolenaarif has('job') 49*46fceaaaSBram Moolenaar 50*46fceaaaSBram Moolenaar let g:context_jobs = [] 51*46fceaaaSBram Moolenaar 52*46fceaaaSBram Moolenaar " Print the status of ConTeXt jobs 53*46fceaaaSBram Moolenaar function! context#job_status() 54*46fceaaaSBram Moolenaar let l:jobs = filter(g:context_jobs, 'job_status(v:val) == "run"') 55*46fceaaaSBram Moolenaar let l:n = len(l:jobs) 56*46fceaaaSBram Moolenaar call s:context_echo( 57*46fceaaaSBram Moolenaar \ 'There '.(l:n == 1 ? 'is' : 'are').' '.(l:n == 0 ? 'no' : l:n) 58*46fceaaaSBram Moolenaar \ .' job'.(l:n == 1 ? '' : 's').' running' 59*46fceaaaSBram Moolenaar \ .(l:n == 0 ? '.' : ' (' . join(l:jobs, ', ').').'), 60*46fceaaaSBram Moolenaar \ 'ModeMsg') 61*46fceaaaSBram Moolenaar endfunction 62*46fceaaaSBram Moolenaar 63*46fceaaaSBram Moolenaar " Stop all ConTeXt jobs 64*46fceaaaSBram Moolenaar function! context#stop_jobs() 65*46fceaaaSBram Moolenaar let l:jobs = filter(g:context_jobs, 'job_status(v:val) == "run"') 66*46fceaaaSBram Moolenaar for job in l:jobs 67*46fceaaaSBram Moolenaar call job_stop(job) 68*46fceaaaSBram Moolenaar endfor 69*46fceaaaSBram Moolenaar sleep 1 70*46fceaaaSBram Moolenaar let l:tmp = [] 71*46fceaaaSBram Moolenaar for job in l:jobs 72*46fceaaaSBram Moolenaar if job_status(job) == "run" 73*46fceaaaSBram Moolenaar call add(l:tmp, job) 74*46fceaaaSBram Moolenaar endif 75*46fceaaaSBram Moolenaar endfor 76*46fceaaaSBram Moolenaar let g:context_jobs = l:tmp 77*46fceaaaSBram Moolenaar if empty(g:context_jobs) 78*46fceaaaSBram Moolenaar call s:context_echo('Done. No jobs running.', 'ModeMsg') 79*46fceaaaSBram Moolenaar else 80*46fceaaaSBram Moolenaar call s:context_echo('There are still some jobs running. Please try again.', 'WarningMsg') 81*46fceaaaSBram Moolenaar endif 82*46fceaaaSBram Moolenaar endfunction 83*46fceaaaSBram Moolenaar 84*46fceaaaSBram Moolenaar function! context#callback(path, job, status) 85*46fceaaaSBram Moolenaar if index(g:context_jobs, a:job) != -1 && job_status(a:job) != 'run' " just in case 86*46fceaaaSBram Moolenaar call remove(g:context_jobs, index(g:context_jobs, a:job)) 87*46fceaaaSBram Moolenaar endif 88*46fceaaaSBram Moolenaar call s:callback(a:path, a:job, a:status) 89*46fceaaaSBram Moolenaar endfunction 90*46fceaaaSBram Moolenaar 91*46fceaaaSBram Moolenaar function! context#close_cb(channel) 92*46fceaaaSBram Moolenaar call job_status(ch_getjob(a:channel)) " Trigger exit_cb's callback for faster feedback 93*46fceaaaSBram Moolenaar endfunction 94*46fceaaaSBram Moolenaar 95*46fceaaaSBram Moolenaar function! s:typeset(path) 96*46fceaaaSBram Moolenaar call add(g:context_jobs, 97*46fceaaaSBram Moolenaar \ job_start(add(s:sh(), context#command() . ' ' . shellescape(fnamemodify(a:path, ":t"))), { 98*46fceaaaSBram Moolenaar \ 'close_cb' : 'context#close_cb', 99*46fceaaaSBram Moolenaar \ 'exit_cb' : function(get(b:, 'context_callback', get(g:, 'context_callback', 'context#callback')), 100*46fceaaaSBram Moolenaar \ [a:path]), 101*46fceaaaSBram Moolenaar \ 'in_io' : 'null' 102*46fceaaaSBram Moolenaar \ })) 103*46fceaaaSBram Moolenaar endfunction 104*46fceaaaSBram Moolenaar 105*46fceaaaSBram Moolenaarelse " No jobs 106*46fceaaaSBram Moolenaar 107*46fceaaaSBram Moolenaar function! context#job_status() 108*46fceaaaSBram Moolenaar call s:context_echo('Not implemented', 'WarningMsg') 109*46fceaaaSBram Moolenaar endfunction! 110*46fceaaaSBram Moolenaar 111*46fceaaaSBram Moolenaar function! context#stop_jobs() 112*46fceaaaSBram Moolenaar call s:context_echo('Not implemented', 'WarningMsg') 113*46fceaaaSBram Moolenaar endfunction 114*46fceaaaSBram Moolenaar 115*46fceaaaSBram Moolenaar function! context#callback(path, job, status) 116*46fceaaaSBram Moolenaar call s:callback(a:path, a:job, a:status) 117*46fceaaaSBram Moolenaar endfunction 118*46fceaaaSBram Moolenaar 119*46fceaaaSBram Moolenaar function! s:typeset(path) 120*46fceaaaSBram Moolenaar execute '!' . context#command() . ' ' . shellescape(fnamemodify(a:path, ":t")) 121*46fceaaaSBram Moolenaar call call(get(b:, 'context_callback', get(g:, 'context_callback', 'context#callback')), 122*46fceaaaSBram Moolenaar \ [a:path, 0, v:shell_error]) 123*46fceaaaSBram Moolenaar endfunction 124*46fceaaaSBram Moolenaar 125*46fceaaaSBram Moolenaarendif " has('job') 126*46fceaaaSBram Moolenaar 127*46fceaaaSBram Moolenaarfunction! s:callback(path, job, status) abort 128*46fceaaaSBram Moolenaar if a:status < 0 " Assume the job was terminated 129*46fceaaaSBram Moolenaar return 130*46fceaaaSBram Moolenaar endif 131*46fceaaaSBram Moolenaar " Get info about the current window 132*46fceaaaSBram Moolenaar let l:winid = s:win_getid() " Save window id 133*46fceaaaSBram Moolenaar let l:efm = &l:errorformat " Save local errorformat 134*46fceaaaSBram Moolenaar let l:cwd = fnamemodify(getcwd(), ":p") " Save local working directory 135*46fceaaaSBram Moolenaar " Set errorformat to parse ConTeXt errors 136*46fceaaaSBram Moolenaar execute 'setl efm=' . escape(b:context_errorformat, ' ') 137*46fceaaaSBram Moolenaar try " Set cwd to expand error file correctly 138*46fceaaaSBram Moolenaar execute 'lcd' fnameescape(fnamemodify(a:path, ':h')) 139*46fceaaaSBram Moolenaar catch /.*/ 140*46fceaaaSBram Moolenaar execute 'setl efm=' . escape(l:efm, ' ') 141*46fceaaaSBram Moolenaar throw v:exception 142*46fceaaaSBram Moolenaar endtry 143*46fceaaaSBram Moolenaar try 144*46fceaaaSBram Moolenaar execute 'cgetfile' fnameescape(fnamemodify(a:path, ':r') . '.log') 145*46fceaaaSBram Moolenaar botright cwindow 146*46fceaaaSBram Moolenaar finally " Restore cwd and errorformat 147*46fceaaaSBram Moolenaar execute s:win_id2win(l:winid) . 'wincmd w' 148*46fceaaaSBram Moolenaar execute 'lcd ' . fnameescape(l:cwd) 149*46fceaaaSBram Moolenaar execute 'setl efm=' . escape(l:efm, ' ') 150*46fceaaaSBram Moolenaar endtry 151*46fceaaaSBram Moolenaar if a:status == 0 152*46fceaaaSBram Moolenaar call s:context_echo('Success!', 'ModeMsg') 153*46fceaaaSBram Moolenaar else 154*46fceaaaSBram Moolenaar call s:context_echo('There are errors. ', 'ErrorMsg') 155*46fceaaaSBram Moolenaar endif 156*46fceaaaSBram Moolenaarendfunction 157*46fceaaaSBram Moolenaar 158*46fceaaaSBram Moolenaarfunction! context#command() 159*46fceaaaSBram Moolenaar return get(b:, 'context_mtxrun', get(g:, 'context_mtxrun', 'mtxrun')) 160*46fceaaaSBram Moolenaar \ . ' --script context --autogenerate --nonstopmode' 161*46fceaaaSBram Moolenaar \ . ' --synctex=' . (get(b:, 'context_synctex', get(g:, 'context_synctex', 0)) ? '1' : '0') 162*46fceaaaSBram Moolenaar \ . ' ' . get(b:, 'context_extra_options', get(g:, 'context_extra_options', '')) 163*46fceaaaSBram Moolenaarendfunction 164*46fceaaaSBram Moolenaar 165*46fceaaaSBram Moolenaar" Accepts an optional path (useful for big projects, when the file you are 166*46fceaaaSBram Moolenaar" editing is not the project's root document). If no argument is given, uses 167*46fceaaaSBram Moolenaar" the path of the current buffer. 168*46fceaaaSBram Moolenaarfunction! context#typeset(...) abort 169*46fceaaaSBram Moolenaar let l:path = fnamemodify(strlen(a:000[0]) > 0 ? a:1 : expand("%"), ":p") 170*46fceaaaSBram Moolenaar let l:cwd = fnamemodify(getcwd(), ":p") " Save local working directory 171*46fceaaaSBram Moolenaar call s:context_echo('Typesetting...', 'ModeMsg') 172*46fceaaaSBram Moolenaar execute 'lcd' fnameescape(fnamemodify(l:path, ":h")) 173*46fceaaaSBram Moolenaar try 174*46fceaaaSBram Moolenaar call s:typeset(l:path) 175*46fceaaaSBram Moolenaar finally " Restore local working directory 176*46fceaaaSBram Moolenaar execute 'lcd ' . fnameescape(l:cwd) 177*46fceaaaSBram Moolenaar endtry 178*46fceaaaSBram Moolenaarendfunction! 179*46fceaaaSBram Moolenaar"}}} 180*46fceaaaSBram Moolenaar 181*46fceaaaSBram Moolenaarlet &cpo = s:keepcpo 182*46fceaaaSBram Moolenaarunlet s:keepcpo 183*46fceaaaSBram Moolenaar 184*46fceaaaSBram Moolenaar" vim: sw=2 fdm=marker 185