<commit_before>" vimtex - LaTeX plugin for Vim
"
" Maintainer: <NAME>
" Email:      <EMAIL>
"

function! vimtex#compiler#latexmk#init(options) abort " {{{1
  let l:compiler = deepcopy(s:compiler)

  call l:compiler.init(extend(a:options,
        \ get(g:, 'vimtex_compiler_latexmk', {}), 'keep'))

  return l:compiler
endfunction

" }}}1
function! vimtex#compiler#latexmk#wrap_option(name, value) abort " {{{1
  if has('win32')
    return ' -e "$' . a:name . ' = ''' . a:value . '''"'
  else
    return ' -e ''$' . a:name . ' = "' . a:value . '"'''
  endif
endfunction

"}}}1

let s:compiler = {
      \ 'name' : 'latexmk',
      \ 'executable' : 'latexmk',
      \ 'backend' : has('nvim') ? 'nvim'
      \                         : v:version >= 800 ? 'jobs' : 'process',
      \ 'root' : '',
      \ 'target' : '',
      \ 'target_path' : '',
      \ 'background' : 1,
      \ 'build_dir' : '',
      \ 'callback' : 1,
      \ 'continuous' : 1,
      \ 'engine' : b:vimtex.engine,
      \ 'output' : tempname(),
      \ 'options' : [
      \   '-verbose',
      \   '-pdf',
      \   '-file-line-error',
      \   '-synctex=1',
      \   '-interaction=nonstopmode',
      \ ],
      \ 'shell' : fnamemodify(&shell, ':t'),
      \}

function! s:compiler.init(options) abort dict " {{{1
  call extend(self, a:options)

  call self.init_check_requirements()
  call self.init_build_dir_option()

  call extend(self, deepcopy(s:compiler_{self.backend}))

  " Continuous processes can't run in foreground, neither can processes run
  " with the new jobs api
  if self.continuous || self.backend !=# 'process'
    let self.background = 1
  endif

  if self.backend !=# 'process'
    let self.shell = 'sh'
  endif
endfunction

" }}}1
function! s:compiler.init_build_dir_option() abort dict " {{{1
  "
  " Check if .latexmkrc sets the build_dir - if so this should be respected
  "

  let l:pattern = '^\s*\$out_dir\s*=\s*[''"]\(.\+\)[''"]\s*;\?\s*$'
  let l:files = [
        \ self.root . '/latexmkrc',
        \ self.root . '/.latexmkrc',
        \ fnamemodify('~/.latexmkrc', ':p'),
        \]

  for l:file in l:files
    if filereadable(l:file)
      let l:out_dir = matchlist(readfile(l:file), l:pattern)
      if len(l:out_dir) > 1
        if !empty(self.build_dir)
          call vimtex#echo#warning(
                \ 'compiler.build_dir changed to: ' . self.build_dir)
          call vimtex#echo#wait()
        endif
        let self.build_dir = l:out_dir[1]
        return
      endif
    endif
  endfor
endfunction

" }}}1
function! s:compiler.init_check_requirements() abort dict " {{{1
  " Check option validity
  if self.callback
    if !(has('clientserver') || has('nvim'))
      let self.callback = 0
      call vimtex#echo#warning('Can''t use callbacks without +clientserver')
      call vimtex#echo#wait()
    endif
  endif

  " Check for required executables
  let l:required = [self.executable]
  if self.continuous && !has('win32')
    let l:required += ['pgrep']
  endif
  let l:missing = filter(l:required, '!executable(v:val)')

  " Disable latexmk if required programs are missing
  if len(l:missing) > 0
    for l:cmd in l:missing
      call vimtex#echo#warning(l:cmd . ' is not executable')
    endfor
    throw 'vimtex: Requirements not met'
  endif
endfunction

" }}}1

function! s:compiler.build_cmd() abort dict " {{{1
  if has('win32')
    let l:cmd = 'set max_print_line=2000 & ' . self.executable
  else
    if self.shell ==# 'fish'
      let l:cmd = 'set max_print_line 2000; and ' . self.executable
    else
      let l:cmd = 'max_print_line=2000 ' . self.executable
    endif
  endif

  for l:opt in self.options
    let l:cmd .= ' ' . l:opt
  endfor

  if !empty(self.engine)
    let l:cmd .= ' ' . self.engine
  endif

  if !empty(self.build_dir)
    let l:cmd .= ' -outdir=' . self.build_dir
  endif

  if self.continuous
    let l:cmd .= ' -pvc'

    " Set viewer options
    if !get(g:, 'vimtex_view_automatic', 1)
          \ || get(get(b:vimtex, 'viewer', {}), 'xwin_id') > 0
          \ || get(s:, 'silence_next_callback', 0)
      let l:cmd .= ' -view=none'
    elseif g:vimtex_view_enabled
          \ && has_key(b:vimtex.viewer, 'latexmk_append_argument')
      let l:cmd .= b:vimtex.viewer.latexmk_append_argument()
    endif

    if self.callback
      if empty(v:servername)
        call vimtex#echo#warning('Can''t use callbacks with empty v:servername')
        call vimtex#echo#wait()
      else
        let l:cb = '""""""'
              \ . g:vimtex_compiler_progname
              \ . '""""""'
              \ . ' --servername ' . v:servername

        " This seems more complicated than it is!
        " - The succes_cmd and fail_cmd are the same, except for the callback
        "   status value (1 and 0)
        " - We need to escape the parantheses on windows, but not on unix
        for [l:opt, l:val] in items({'success_cmd' : 1, 'failure_cmd' : 0})
          let l:func = l:cb . ' --remote-expr '
                \ . (has('win32')
                \   ? '"vimtex#compiler#callback(' . l:val . ')"'
                \   : '\"vimtex\#compiler\#callback(' . l:val . ')\"')
          let l:cmd .= vimtex#compiler#latexmk#wrap_option(l:opt, l:func)
        endfor
      endif<commit_msg>Cleaned up latexmk build_cmd callback part<commit_after>" vimtex - LaTeX plugin for Vim
"
" Maintainer: <NAME>
" Email:      <EMAIL>
"

function! vimtex#compiler#latexmk#init(options) abort " {{{1
  let l:compiler = deepcopy(s:compiler)

  call l:compiler.init(extend(a:options,
        \ get(g:, 'vimtex_compiler_latexmk', {}), 'keep'))

  return l:compiler
endfunction

" }}}1
function! vimtex#compiler#latexmk#wrap_option(name, value) abort " {{{1
  if has('win32')
    return ' -e "$' . a:name . ' = ''' . a:value . '''"'
  else
    return ' -e ''$' . a:name . ' = "' . a:value . '"'''
  endif
endfunction

"}}}1

let s:compiler = {
      \ 'name' : 'latexmk',
      \ 'executable' : 'latexmk',
      \ 'backend' : has('nvim') ? 'nvim'
      \                         : v:version >= 800 ? 'jobs' : 'process',
      \ 'root' : '',
      \ 'target' : '',
      \ 'target_path' : '',
      \ 'background' : 1,
      \ 'build_dir' : '',
      \ 'callback' : 1,
      \ 'continuous' : 1,
      \ 'engine' : b:vimtex.engine,
      \ 'output' : tempname(),
      \ 'options' : [
      \   '-verbose',
      \   '-pdf',
      \   '-file-line-error',
      \   '-synctex=1',
      \   '-interaction=nonstopmode',
      \ ],
      \ 'shell' : fnamemodify(&shell, ':t'),
      \}

function! s:compiler.init(options) abort dict " {{{1
  call extend(self, a:options)

  call self.init_check_requirements()
  call self.init_build_dir_option()

  call extend(self, deepcopy(s:compiler_{self.backend}))

  " Continuous processes can't run in foreground, neither can processes run
  " with the new jobs api
  if self.continuous || self.backend !=# 'process'
    let self.background = 1
  endif

  if self.backend !=# 'process'
    let self.shell = 'sh'
  endif
endfunction

" }}}1
function! s:compiler.init_build_dir_option() abort dict " {{{1
  "
  " Check if .latexmkrc sets the build_dir - if so this should be respected
  "

  let l:pattern = '^\s*\$out_dir\s*=\s*[''"]\(.\+\)[''"]\s*;\?\s*$'
  let l:files = [
        \ self.root . '/latexmkrc',
        \ self.root . '/.latexmkrc',
        \ fnamemodify('~/.latexmkrc', ':p'),
        \]

  for l:file in l:files
    if filereadable(l:file)
      let l:out_dir = matchlist(readfile(l:file), l:pattern)
      if len(l:out_dir) > 1
        if !empty(self.build_dir)
          call vimtex#echo#warning(
                \ 'compiler.build_dir changed to: ' . self.build_dir)
          call vimtex#echo#wait()
        endif
        let self.build_dir = l:out_dir[1]
        return
      endif
    endif
  endfor
endfunction

" }}}1
function! s:compiler.init_check_requirements() abort dict " {{{1
  " Check option validity
  if self.callback
    if !(has('clientserver') || has('nvim'))
      let self.callback = 0
      call vimtex#echo#warning('Can''t use callbacks without +clientserver')
      call vimtex#echo#wait()
    endif
  endif

  " Check for required executables
  let l:required = [self.executable]
  if self.continuous && !has('win32')
    let l:required += ['pgrep']
  endif
  let l:missing = filter(l:required, '!executable(v:val)')

  " Disable latexmk if required programs are missing
  if len(l:missing) > 0
    for l:cmd in l:missing
      call vimtex#echo#warning(l:cmd . ' is not executable')
    endfor
    throw 'vimtex: Requirements not met'
  endif
endfunction

" }}}1

function! s:compiler.build_cmd() abort dict " {{{1
  if has('win32')
    let l:cmd = 'set max_print_line=2000 & ' . self.executable
  else
    if self.shell ==# 'fish'
      let l:cmd = 'set max_print_line 2000; and ' . self.executable
    else
      let l:cmd = 'max_print_line=2000 ' . self.executable
    endif
  endif

  for l:opt in self.options
    let l:cmd .= ' ' . l:opt
  endfor

  if !empty(self.engine)
    let l:cmd .= ' ' . self.engine
  endif

  if !empty(self.build_dir)
    let l:cmd .= ' -outdir=' . self.build_dir
  endif

  if self.continuous
    let l:cmd .= ' -pvc'

    " Set viewer options
    if !get(g:, 'vimtex_view_automatic', 1)
          \ || get(get(b:vimtex, 'viewer', {}), 'xwin_id') > 0
          \ || get(s:, 'silence_next_callback', 0)
      let l:cmd .= ' -view=none'
    elseif g:vimtex_view_enabled
          \ && has_key(b:vimtex.viewer, 'latexmk_append_argument')
      let l:cmd .= b:vimtex.viewer.latexmk_append_argument()
    endif

    if self.callback
      if empty(v:servername)
        call vimtex#echo#warning('Can''t use callbacks with empty v:servername')
        call vimtex#echo#wait()
      else
        for [l:opt, l:val] in items({'success_cmd' : 1, 'failure_cmd' : 0})
          let l:callback = has('win32')
                \   ? '"vimtex#compiler#callback(' . l:val . ')"'
                \   : '\"vimtex#compiler#callback(' . l:val . ')\"'
          let l:func = vimtex#util#shellescape('""')
                \ . g:vimtex_compiler_progname
                \ . vimtex#util#shellescape('""')
                \ . ' --servername ' . v:servername
                \ . ' --remote-expr ' . l:callback
          let l:cmd .= vimtex#compiler#latexmk#wrap_option(l:opt, l:func)
        endfor
      endif
{'fraction_non_alphanumeric': 0.15909751137794131, 'fraction_numerical': 0.00948968722765566, 'mean_word_length': 2.3751633986928105, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2998236', 'n_tokens_mistral': 3825, 'n_tokens_neox': 3622, 'n_words': 809}