mirror of
				https://github.com/vim/vim.git
				synced 2025-11-03 09:44:48 -05:00 
			
		
		
		
	
		
			
	
	
		
			185 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			VimL
		
	
	
	
	
	
		
		
			
		
	
	
			185 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			VimL
		
	
	
	
	
	
| 
								 | 
							
								" Language:           ConTeXt typesetting engine
							 | 
						||
| 
								 | 
							
								" Maintainer:         Nicola Vitacolonna <nvitacolonna@gmail.com>
							 | 
						||
| 
								 | 
							
								" Latest Revision:    2016 Oct 21
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								let s:keepcpo= &cpo
							 | 
						||
| 
								 | 
							
								set cpo&vim
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								" Helper functions {{{
							 | 
						||
| 
								 | 
							
								function! s:context_echo(message, mode)
							 | 
						||
| 
								 | 
							
								  redraw
							 | 
						||
| 
								 | 
							
								  echo "\r"
							 | 
						||
| 
								 | 
							
								  execute 'echohl' a:mode
							 | 
						||
| 
								 | 
							
								  echomsg '[ConTeXt]' a:message
							 | 
						||
| 
								 | 
							
								  echohl None
							 | 
						||
| 
								 | 
							
								endf
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function! s:sh()
							 | 
						||
| 
								 | 
							
								  return has('win32') || has('win64') || has('win16') || has('win95')
							 | 
						||
| 
								 | 
							
								        \ ? ['cmd.exe', '/C']
							 | 
						||
| 
								 | 
							
								        \ : ['/bin/sh', '-c']
							 | 
						||
| 
								 | 
							
								endfunction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								" For backward compatibility
							 | 
						||
| 
								 | 
							
								if exists('*win_getid')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function! s:win_getid()
							 | 
						||
| 
								 | 
							
								    return win_getid()
							 | 
						||
| 
								 | 
							
								  endf
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function! s:win_id2win(winid)
							 | 
						||
| 
								 | 
							
								    return win_id2win(a:winid)
							 | 
						||
| 
								 | 
							
								  endf
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function! s:win_getid()
							 | 
						||
| 
								 | 
							
								    return winnr()
							 | 
						||
| 
								 | 
							
								  endf
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function! s:win_id2win(winnr)
							 | 
						||
| 
								 | 
							
								    return a:winnr
							 | 
						||
| 
								 | 
							
								  endf
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								endif
							 | 
						||
| 
								 | 
							
								" }}}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								" ConTeXt jobs {{{
							 | 
						||
| 
								 | 
							
								if has('job')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  let g:context_jobs = []
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  " Print the status of ConTeXt jobs
							 | 
						||
| 
								 | 
							
								  function! context#job_status()
							 | 
						||
| 
								 | 
							
								    let l:jobs = filter(g:context_jobs, 'job_status(v:val) == "run"')
							 | 
						||
| 
								 | 
							
								    let l:n = len(l:jobs)
							 | 
						||
| 
								 | 
							
								    call s:context_echo(
							 | 
						||
| 
								 | 
							
								          \ 'There '.(l:n == 1 ? 'is' : 'are').' '.(l:n == 0 ? 'no' : l:n)
							 | 
						||
| 
								 | 
							
								          \ .' job'.(l:n == 1 ? '' : 's').' running'
							 | 
						||
| 
								 | 
							
								          \ .(l:n == 0 ? '.' : ' (' . join(l:jobs, ', ').').'),
							 | 
						||
| 
								 | 
							
								          \ 'ModeMsg')
							 | 
						||
| 
								 | 
							
								  endfunction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  " Stop all ConTeXt jobs
							 | 
						||
| 
								 | 
							
								  function! context#stop_jobs()
							 | 
						||
| 
								 | 
							
								    let l:jobs = filter(g:context_jobs, 'job_status(v:val) == "run"')
							 | 
						||
| 
								 | 
							
								    for job in l:jobs
							 | 
						||
| 
								 | 
							
								      call job_stop(job)
							 | 
						||
| 
								 | 
							
								    endfor
							 | 
						||
| 
								 | 
							
								    sleep 1
							 | 
						||
| 
								 | 
							
								    let l:tmp = []
							 | 
						||
| 
								 | 
							
								    for job in l:jobs
							 | 
						||
| 
								 | 
							
								      if job_status(job) == "run"
							 | 
						||
| 
								 | 
							
								        call add(l:tmp, job)
							 | 
						||
| 
								 | 
							
								      endif
							 | 
						||
| 
								 | 
							
								    endfor
							 | 
						||
| 
								 | 
							
								    let g:context_jobs = l:tmp
							 | 
						||
| 
								 | 
							
								    if empty(g:context_jobs)
							 | 
						||
| 
								 | 
							
								      call s:context_echo('Done. No jobs running.', 'ModeMsg')
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								      call s:context_echo('There are still some jobs running. Please try again.', 'WarningMsg')
							 | 
						||
| 
								 | 
							
								    endif
							 | 
						||
| 
								 | 
							
								  endfunction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function! context#callback(path, job, status)
							 | 
						||
| 
								 | 
							
								    if index(g:context_jobs, a:job) != -1 && job_status(a:job) != 'run' " just in case
							 | 
						||
| 
								 | 
							
								      call remove(g:context_jobs, index(g:context_jobs, a:job))
							 | 
						||
| 
								 | 
							
								    endif
							 | 
						||
| 
								 | 
							
								    call s:callback(a:path, a:job, a:status)
							 | 
						||
| 
								 | 
							
								  endfunction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function! context#close_cb(channel)
							 | 
						||
| 
								 | 
							
								    call job_status(ch_getjob(a:channel)) " Trigger exit_cb's callback for faster feedback
							 | 
						||
| 
								 | 
							
								  endfunction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function! s:typeset(path)
							 | 
						||
| 
								 | 
							
								    call add(g:context_jobs,
							 | 
						||
| 
								 | 
							
								          \ job_start(add(s:sh(), context#command() . ' ' . shellescape(fnamemodify(a:path, ":t"))), {
							 | 
						||
| 
								 | 
							
								          \   'close_cb' : 'context#close_cb',
							 | 
						||
| 
								 | 
							
								          \   'exit_cb'  : function(get(b:, 'context_callback', get(g:, 'context_callback', 'context#callback')),
							 | 
						||
| 
								 | 
							
								          \                         [a:path]),
							 | 
						||
| 
								 | 
							
								          \   'in_io'    : 'null'
							 | 
						||
| 
								 | 
							
								          \ }))
							 | 
						||
| 
								 | 
							
								  endfunction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								else " No jobs
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function! context#job_status()
							 | 
						||
| 
								 | 
							
								    call s:context_echo('Not implemented', 'WarningMsg')
							 | 
						||
| 
								 | 
							
								  endfunction!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function! context#stop_jobs()
							 | 
						||
| 
								 | 
							
								    call s:context_echo('Not implemented', 'WarningMsg')
							 | 
						||
| 
								 | 
							
								  endfunction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function! context#callback(path, job, status)
							 | 
						||
| 
								 | 
							
								    call s:callback(a:path, a:job, a:status)
							 | 
						||
| 
								 | 
							
								  endfunction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function! s:typeset(path)
							 | 
						||
| 
								 | 
							
								    execute '!' . context#command() . ' ' . shellescape(fnamemodify(a:path, ":t"))
							 | 
						||
| 
								 | 
							
								    call call(get(b:, 'context_callback', get(g:, 'context_callback', 'context#callback')),
							 | 
						||
| 
								 | 
							
								          \ [a:path, 0, v:shell_error])
							 | 
						||
| 
								 | 
							
								  endfunction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								endif " has('job')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function! s:callback(path, job, status) abort
							 | 
						||
| 
								 | 
							
								  if a:status < 0 " Assume the job was terminated
							 | 
						||
| 
								 | 
							
								    return
							 | 
						||
| 
								 | 
							
								  endif
							 | 
						||
| 
								 | 
							
								  " Get info about the current window
							 | 
						||
| 
								 | 
							
								  let l:winid = s:win_getid()             " Save window id
							 | 
						||
| 
								 | 
							
								  let l:efm = &l:errorformat              " Save local errorformat
							 | 
						||
| 
								 | 
							
								  let l:cwd = fnamemodify(getcwd(), ":p") " Save local working directory
							 | 
						||
| 
								 | 
							
								  " Set errorformat to parse ConTeXt errors
							 | 
						||
| 
								 | 
							
								  execute 'setl efm=' . escape(b:context_errorformat, ' ')
							 | 
						||
| 
								 | 
							
								  try " Set cwd to expand error file correctly
							 | 
						||
| 
								 | 
							
								    execute 'lcd' fnameescape(fnamemodify(a:path, ':h'))
							 | 
						||
| 
								 | 
							
								  catch /.*/
							 | 
						||
| 
								 | 
							
								    execute 'setl efm=' . escape(l:efm, ' ')
							 | 
						||
| 
								 | 
							
								    throw v:exception
							 | 
						||
| 
								 | 
							
								  endtry
							 | 
						||
| 
								 | 
							
								  try
							 | 
						||
| 
								 | 
							
								    execute 'cgetfile' fnameescape(fnamemodify(a:path, ':r') . '.log')
							 | 
						||
| 
								 | 
							
								    botright cwindow
							 | 
						||
| 
								 | 
							
								  finally " Restore cwd and errorformat
							 | 
						||
| 
								 | 
							
								    execute s:win_id2win(l:winid) . 'wincmd w'
							 | 
						||
| 
								 | 
							
								    execute 'lcd ' . fnameescape(l:cwd)
							 | 
						||
| 
								 | 
							
								    execute 'setl efm=' . escape(l:efm, ' ')
							 | 
						||
| 
								 | 
							
								  endtry
							 | 
						||
| 
								 | 
							
								  if a:status == 0
							 | 
						||
| 
								 | 
							
								    call s:context_echo('Success!', 'ModeMsg')
							 | 
						||
| 
								 | 
							
								  else
							 | 
						||
| 
								 | 
							
								    call s:context_echo('There are errors. ', 'ErrorMsg')
							 | 
						||
| 
								 | 
							
								  endif
							 | 
						||
| 
								 | 
							
								endfunction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function! context#command()
							 | 
						||
| 
								 | 
							
								  return get(b:, 'context_mtxrun', get(g:, 'context_mtxrun', 'mtxrun'))
							 | 
						||
| 
								 | 
							
								        \ . ' --script context --autogenerate --nonstopmode'
							 | 
						||
| 
								 | 
							
								        \ . ' --synctex=' . (get(b:, 'context_synctex', get(g:, 'context_synctex', 0)) ? '1' : '0')
							 | 
						||
| 
								 | 
							
								        \ . ' ' . get(b:, 'context_extra_options', get(g:, 'context_extra_options', ''))
							 | 
						||
| 
								 | 
							
								endfunction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								" Accepts an optional path (useful for big projects, when the file you are
							 | 
						||
| 
								 | 
							
								" editing is not the project's root document). If no argument is given, uses
							 | 
						||
| 
								 | 
							
								" the path of the current buffer.
							 | 
						||
| 
								 | 
							
								function! context#typeset(...) abort
							 | 
						||
| 
								 | 
							
								  let l:path = fnamemodify(strlen(a:000[0]) > 0 ? a:1 : expand("%"), ":p")
							 | 
						||
| 
								 | 
							
								  let l:cwd = fnamemodify(getcwd(), ":p") " Save local working directory
							 | 
						||
| 
								 | 
							
								  call s:context_echo('Typesetting...',  'ModeMsg')
							 | 
						||
| 
								 | 
							
								  execute 'lcd' fnameescape(fnamemodify(l:path, ":h"))
							 | 
						||
| 
								 | 
							
								  try
							 | 
						||
| 
								 | 
							
								    call s:typeset(l:path)
							 | 
						||
| 
								 | 
							
								  finally " Restore local working directory
							 | 
						||
| 
								 | 
							
								    execute 'lcd ' . fnameescape(l:cwd)
							 | 
						||
| 
								 | 
							
								  endtry
							 | 
						||
| 
								 | 
							
								endfunction!
							 | 
						||
| 
								 | 
							
								"}}}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								let &cpo = s:keepcpo
							 | 
						||
| 
								 | 
							
								unlet s:keepcpo
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								" vim: sw=2 fdm=marker
							 |