Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions autoload/vimtex/compiler.vim
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ function! vimtex#compiler#compile_selected(type) abort range " {{{1
" Create and initialize temporary compiler
let l:compiler = s:init_compiler({
\ 'state': l:file,
\ 'build_dir': '',
\ 'out_dir': '',
\ 'continuous': 0,
\ 'callback': 0,
\})
Expand Down Expand Up @@ -266,7 +266,7 @@ function! vimtex#compiler#clean(full) abort " {{{1

call b:vimtex.compiler.clean(a:full)
sleep 100m
call b:vimtex.compiler.remove_build_dir()
call b:vimtex.compiler.remove_dirs()
call vimtex#log#info('Compiler clean finished' . (a:full ? ' (full)' : ''))


Expand Down
185 changes: 84 additions & 101 deletions autoload/vimtex/compiler/_template.vim
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ endfunction
let s:compiler = {
\ 'name': '__template__',
\ 'enabled': v:true,
\ 'build_dir': '',
\ 'out_dir': '',
\ 'continuous': 0,
\ 'hooks': [],
\ 'output': tempname(),
Expand All @@ -30,9 +30,21 @@ function! s:compiler.new(options) abort dict " {{{1

call l:compiler.__check_requirements()

call s:build_dir_materialize(l:compiler)
call vimtex#util#materialize_property(l:compiler, 'out_dir')
call l:compiler.__init()
call s:build_dir_respect_envvar(l:compiler)

" $VIMTEX_OUTPUT_DIRECTORY overrides configured compiler.out_dir
if !empty($VIMTEX_OUTPUT_DIRECTORY)
if !empty(l:compiler.out_dir)
\ && (l:compiler.out_dir !=# $VIMTEX_OUTPUT_DIRECTORY)
call vimtex#log#warning(
\ 'Setting VIMTEX_OUTPUT_DIRECTORY overrides out_dir!',
\ 'Changed out_dir from: ' . l:compiler.out_dir,
\ 'Changed out_dir to: ' . $VIMTEX_OUTPUT_DIRECTORY)
endif

let l:compiler.out_dir = $VIMTEX_OUTPUT_DIRECTORY
endif

" Remove init methods
unlet l:compiler.new
Expand Down Expand Up @@ -74,8 +86,8 @@ function! s:compiler.__pprint() abort dict " {{{1
call add(l:list, ['options', self.options])
endif

if !empty(self.build_dir)
call add(l:list, ['build_dir', self.build_dir])
if !empty(self.out_dir)
call add(l:list, ['out_dir', self.out_dir])
endif

if has_key(self, '__pprint_append')
Expand All @@ -98,16 +110,75 @@ endfunction

" }}}1

function! s:compiler._create_build_dir(path) abort dict " {{{1
" Create build dir "path" if it does not exist
" Note: This may need to create a hierarchical structure!
if empty(a:path) | return | endif

if has_key(self.state, 'get_sources')
let l:dirs = self.state.get_sources()
call filter(map(
\ l:dirs, "fnamemodify(v:val, ':h')"),
\ {_, x -> x !=# '.'})
call filter(l:dirs, {_, x -> stridx(x, '../') != 0})
else
let l:dirs = glob(self.state.root . '/**/*.tex', v:false, v:true)
call map(l:dirs, "fnamemodify(v:val, ':h')")
call map(l:dirs, 'strpart(v:val, strlen(self.state.root) + 1)')
endif
call uniq(sort(filter(l:dirs, '!empty(v:val)')))

call map(l:dirs, {_, x ->
\ (vimtex#paths#is_abs(a:path) ? '' : self.state.root . '/')
\ . a:path . '/' . x})
call filter(l:dirs, '!isdirectory(v:val)')
if empty(l:dirs) | return | endif

" Create the non-existing directories
call vimtex#log#warning(["Creating directorie(s):"]
\ + map(copy(l:dirs), {_, x -> '* ' . x}))

for l:dir in l:dirs
call mkdir(l:dir, 'p')
endfor
endfunction

" }}}1
function! s:compiler._remove_dir(path) abort dict " {{{1
if empty(a:path) | return | endif

let l:out_dir = vimtex#paths#is_abs(a:path)
\ ? a:path
\ : self.state.root . '/' . a:path
if !isdirectory(l:out_dir) | return | endif

let l:tree = glob(l:out_dir . '/**/*', 0, 1)
let l:files = filter(copy(l:tree), 'filereadable(v:val)')

if empty(l:files)
for l:dir in sort(l:tree) + [l:out_dir]
call delete(l:dir, 'd')
endfor
endif
endfunction

" }}}1

function! s:compiler.create_dirs() abort dict " {{{1
call self._create_build_dir(self.out_dir)
endfunction

" }}}1
function! s:compiler.remove_dirs() abort dict " {{{1
call self._remove_dir(self.out_dir)
endfunction

" }}}1

function! s:compiler.get_file(ext) abort dict " {{{1
" Check for various output directories
" * Environment variable VIMTEX_OUTPUT_DIRECTORY. Note that this overrides
" any VimTeX settings like g:vimtex_compiler_latexmk.build_dir!
" * Compiler settings, such as g:vimtex_compiler_latexmk.build_dir, which is
" available as b:vimtex.compiler.build_dir.
" * Fallback to the main root directory
for l:root in [
\ $VIMTEX_OUTPUT_DIRECTORY,
\ self.build_dir,
\ self.out_dir,
\ self.state.root
\]
if empty(l:root) | continue | endif
Expand Down Expand Up @@ -143,7 +214,7 @@ endfunction
function! s:compiler.start(...) abort dict " {{{1
if self.is_running() | return | endif

call self.create_build_dir()
call self.create_dirs()

" Initialize output file
call writefile([], self.output, 'a')
Expand Down Expand Up @@ -211,62 +282,6 @@ endfunction

" }}}1

function! s:compiler.create_build_dir() abort dict " {{{1
" Create build dir if it does not exist
" Note: This may need to create a hierarchical structure!
if empty(self.build_dir) | return | endif

if has_key(self.state, 'get_sources')
let l:dirs = self.state.get_sources()
call filter(map(
\ l:dirs, "fnamemodify(v:val, ':h')"),
\ {_, x -> x !=# '.'})
call filter(l:dirs, {_, x -> stridx(x, '../') != 0})
else
let l:dirs = glob(self.state.root . '/**/*.tex', v:false, v:true)
call map(l:dirs, "fnamemodify(v:val, ':h')")
call map(l:dirs, 'strpart(v:val, strlen(self.state.root) + 1)')
endif
call uniq(sort(filter(l:dirs, '!empty(v:val)')))

call map(l:dirs, {_, x ->
\ (vimtex#paths#is_abs(self.build_dir) ? '' : self.state.root . '/')
\ . self.build_dir . '/' . x})
call filter(l:dirs, '!isdirectory(v:val)')
if empty(l:dirs) | return | endif

" Create the non-existing directories
call vimtex#log#warning(["Creating build_dir directorie(s):"]
\ + map(copy(l:dirs), {_, x -> '* ' . x}))

for l:dir in l:dirs
call mkdir(l:dir, 'p')
endfor
endfunction

" }}}1
function! s:compiler.remove_build_dir() abort dict " {{{1
" Remove auxilliary output directories (only if they are empty)
if empty(self.build_dir) | return | endif

if vimtex#paths#is_abs(self.build_dir)
let l:build_dir = self.build_dir
else
let l:build_dir = self.state.root . '/' . self.build_dir
endif

let l:tree = glob(l:build_dir . '/**/*', 0, 1)
let l:files = filter(copy(l:tree), 'filereadable(v:val)')

if empty(l:files)
for l:dir in sort(l:tree) + [l:build_dir]
call delete(l:dir, 'd')
endfor
endif
endfunction

" }}}1


let s:compiler_jobs = {}
function! s:compiler_jobs.exec(cmd) abort dict " {{{1
Expand Down Expand Up @@ -461,38 +476,6 @@ endfunction
" }}}1


function! s:build_dir_materialize(compiler) abort " {{{1
if type(a:compiler.build_dir) != v:t_func | return | endif

try
let a:compiler.build_dir = a:compiler.build_dir()
catch
call vimtex#log#error(
\ 'Could not expand build_dir function!',
\ v:exception)
let a:compiler.build_dir = ''
endtry
endfunction

" }}}1
function! s:build_dir_respect_envvar(compiler) abort " {{{1
" Specifying the build_dir by environment variable should override the
" current value.
if empty($VIMTEX_OUTPUT_DIRECTORY) | return | endif

if !empty(a:compiler.build_dir)
\ && (a:compiler.build_dir !=# $VIMTEX_OUTPUT_DIRECTORY)
call vimtex#log#warning(
\ 'Setting VIMTEX_OUTPUT_DIRECTORY overrides build_dir!',
\ 'Changed build_dir from: ' . a:compiler.build_dir,
\ 'Changed build_dir to: ' . $VIMTEX_OUTPUT_DIRECTORY)
endif

let a:compiler.build_dir = $VIMTEX_OUTPUT_DIRECTORY
endfunction

" }}}1

function! s:check_callback(line) abort " {{{1
let l:status = get(s:callbacks, substitute(a:line, '\r', '', ''))
if l:status <= 0 | return | endif
Expand Down
Loading