<commit_before>function! s:_vital_loaded(V) abort
  let s:Prelude = a:V.import('Prelude')
  let s:Process = a:V.import('Vim.Process')
  let s:Dict = a:V.import('Data.Dict')
  let s:StringExt = a:V.import('Data.StringExt')
  let s:config = {
        \ 'executable': 'git',
        \ 'arguments': ['-c', 'color.ui=false', '--no-pager'],
        \}
  let s:is_windows = s:Prelude.is_windows()
endfunction
function! s:_vital_depends() abort
  return [
        \ 'Prelude',
        \ 'Vim.Process',
        \ 'Data.Dict',
        \ 'Data.StringExt',
        \]
endfunction
function! s:_vital_created(module) abort
  call extend(a:module, {
        \ 'schemes': s:schemes,
        \})
endfunction

function! s:_shellescape(val) abort
  let val = shellescape(a:val)
  if val !~# '\s'
    if !s:is_windows || (exists('&shellslash') && &shellslash)
      let val = substitute(val, "^'", '', 'g')
      let val = substitute(val, "'$", '', 'g')
    else
      " Windows without shellslash enclose value with double quote
      let val = substitute(val, '^"', '', 'g')
      let val = substitute(val, '"$', '', 'g')
    endif
  endif
  return val
endfunction

function! s:get_config() abort
  return copy(s:config)
endfunction
function! s:set_config(config) abort
  let config = s:Dict.pick(a:config, [
        \ 'executable',
        \ 'arguments',
        \])
  call extend(s:config, config)
endfunction

function! s:throw(msg) abort
  if s:Prelude.is_dict(a:msg)
    let msg = printf("%s: %s\n%s",
          \ a:msg.status == 0 ? 'OK' : 'Fail',
          \ join(a:msg.args), a:msg.stdout,
          \)
  else
    let msg = a:msg
  endif
  throw 'vital: Git.Process: ' . msg
endfunction

function! s:translate_option(key, val, pattern) abort
  if s:Prelude.is_number(a:val)
    if a:val == 0
      return ''
    endif
    let val = ''
  else
    let val = a:val
  endif
  if len(a:key) == 1
    let format = empty(a:pattern) ? '-%k%v' : a:pattern
  else
    let format = empty(a:pattern) ? '--%K%{=}V' : a:pattern
  endif
  let format_map = {
        \ 'k': 'key',
        \ 'v': 'val',
        \ 'K': 'escaped_key',
        \ 'V': 'escaped_val',
        \}
  let data = {
        \ 'key': a:key,
        \ 'val': val,
        \ 'escaped_key': substitute(a:key, '_', '-', 'g'),
        \ 'escaped_val': len(val)
        \   ? s:_shellescape(val)
        \   : '',
        \}
  return s:StringExt.format(format, format_map, data)
endfunction
function! s:translate_options(options, scheme) abort
  let args = []
  for key  in sort(keys(a:options))
    if key !~# '^__.\+__$' && key !=# '--'
      let pattern = get(a:scheme, key, '')
      call extend(args, s:StringExt.splitargs(
            \ s:translate_option(key, a:options[key], pattern)
            \))
    endif
  endfor
  if has_key(a:options, '--')
    call add(args, '--')
    for str in a:options['--']
      call add(args, str ==# '-' ? '-' : fnameescape(expand(str)))
    endfor
  endif
  return args
endfunction

" s:build_args({name}[, {options}])
function! s:build_args(name, ...) abort
  let options = get(a:000, 0, {})
  let l:Scheme = get(s:schemes, a:name, {})
  if s:Prelude.is_funcref(l:Scheme)
    let args = call(l:Scheme, [a:name, options], s:schemes)
  else
    let args = s:translate_options(options, l:Scheme)
  endif
  return filter(extend([a:name], args), '!empty(v:val)')
endfunction

" s:execute({git}, {name}[, {options}, {config}])
" s:execute({name}[, {options}, {config}])
function! s:execute(...) abort
  if s:Prelude.is_dict(a:1)
    let worktree = get(a:1, 'worktree', '')
    let args = s:build_args(a:2, get(a:000, 2, {}))
    let args = (empty(worktree) ? [] : ['-C', worktree]) + args
    let config = get(a:000, 4, {})
  else
    let args = s:build_args(a:1, get(a:000, 3, {}))<commit_msg>Escape worktree via fnameescape<commit_after>function! s:_vital_loaded(V) abort
  let s:Prelude = a:V.import('Prelude')
  let s:Process = a:V.import('Vim.Process')
  let s:Dict = a:V.import('Data.Dict')
  let s:StringExt = a:V.import('Data.StringExt')
  let s:config = {
        \ 'executable': 'git',
        \ 'arguments': ['-c', 'color.ui=false', '--no-pager'],
        \}
  let s:is_windows = s:Prelude.is_windows()
endfunction
function! s:_vital_depends() abort
  return [
        \ 'Prelude',
        \ 'Vim.Process',
        \ 'Data.Dict',
        \ 'Data.StringExt',
        \]
endfunction
function! s:_vital_created(module) abort
  call extend(a:module, {
        \ 'schemes': s:schemes,
        \})
endfunction

function! s:_shellescape(val) abort
  let val = shellescape(a:val)
  if val !~# '\s'
    if !s:is_windows || (exists('&shellslash') && &shellslash)
      let val = substitute(val, "^'", '', 'g')
      let val = substitute(val, "'$", '', 'g')
    else
      " Windows without shellslash enclose value with double quote
      let val = substitute(val, '^"', '', 'g')
      let val = substitute(val, '"$', '', 'g')
    endif
  endif
  return val
endfunction

function! s:get_config() abort
  return copy(s:config)
endfunction
function! s:set_config(config) abort
  let config = s:Dict.pick(a:config, [
        \ 'executable',
        \ 'arguments',
        \])
  call extend(s:config, config)
endfunction

function! s:throw(msg) abort
  if s:Prelude.is_dict(a:msg)
    let msg = printf("%s: %s\n%s",
          \ a:msg.status == 0 ? 'OK' : 'Fail',
          \ join(a:msg.args), a:msg.stdout,
          \)
  else
    let msg = a:msg
  endif
  throw 'vital: Git.Process: ' . msg
endfunction

function! s:translate_option(key, val, pattern) abort
  if s:Prelude.is_number(a:val)
    if a:val == 0
      return ''
    endif
    let val = ''
  else
    let val = a:val
  endif
  if len(a:key) == 1
    let format = empty(a:pattern) ? '-%k%v' : a:pattern
  else
    let format = empty(a:pattern) ? '--%K%{=}V' : a:pattern
  endif
  let format_map = {
        \ 'k': 'key',
        \ 'v': 'val',
        \ 'K': 'escaped_key',
        \ 'V': 'escaped_val',
        \}
  let data = {
        \ 'key': a:key,
        \ 'val': val,
        \ 'escaped_key': substitute(a:key, '_', '-', 'g'),
        \ 'escaped_val': len(val)
        \   ? s:_shellescape(val)
        \   : '',
        \}
  return s:StringExt.format(format, format_map, data)
endfunction
function! s:translate_options(options, scheme) abort
  let args = []
  for key  in sort(keys(a:options))
    if key !~# '^__.\+__$' && key !=# '--'
      let pattern = get(a:scheme, key, '')
      call extend(args, s:StringExt.splitargs(
            \ s:translate_option(key, a:options[key], pattern)
            \))
    endif
  endfor
  if has_key(a:options, '--')
    call add(args, '--')
    for str in a:options['--']
      call add(args, str ==# '-' ? '-' : fnameescape(expand(str)))
    endfor
  endif
  return args
endfunction

" s:build_args({name}[, {options}])
function! s:build_args(name, ...) abort
  let options = get(a:000, 0, {})
  let l:Scheme = get(s:schemes, a:name, {})
  if s:Prelude.is_funcref(l:Scheme)
    let args = call(l:Scheme, [a:name, options], s:schemes)
  else
    let args = s:translate_options(options, l:Scheme)
  endif
  return filter(extend([a:name], args), '!empty(v:val)')
endfunction

" s:execute({git}, {name}[, {options}, {config}])
" s:execute({name}[, {options}, {config}])
function! s:execute(...) abort
  if s:Prelude.is_dict(a:1)
    let worktree = get(a:1, 'worktree', '')
    let args = s:build_args(a:2, get(a:000, 2, {}))
    let args = (empty(worktree) ? [] : ['-C', fnameescape(worktree)]) + args
    let config = get(a:000, 4, {})
  else
    let args = s:build_args(a:1, get(a:000, 3, {}))
{'fraction_non_alphanumeric': 0.18693069306930693, 'fraction_numerical': 0.0060726072607260725, 'mean_word_length': 2.765407554671968, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1873971', 'n_tokens_mistral': 2877, 'n_tokens_neox': 2814, 'n_words': 607}