<commit_before>scriptencoding utf-8

function! proc#import()
  call s:lib.load()
  return s:lib
endfunction

augroup ProcPlug
  autocmd!
  autocmd VimLeave * call s:lib.unload()
augroup END

let s:lib = {}
let s:lib.api = {}
let s:lib.lasterr = []
let s:lib.read_timeout = 100
let s:lib.write_timeout = 100

function! s:lib.load()
  return self.api.load()
endfunction

function! s:lib.unload()
  call self.api.unload()
endfunction

function! s:lib.open(path, flags, ...)
  let mode = get(a:000, 0, 0)
  let fd = self.api.vp_file_open(a:path, a:flags, mode)
  return self.fdopen(fd, self.api.vp_file_close, self.api.vp_file_read, self.api.vp_file_write)
endfunction

function! s:lib.close()
  call self.f_close(self.fd)
  let self.fd = -1
endfunction

function! s:lib.read(...)
  let nr = get(a:000, 0, -1)
  let timeout = get(a:000, 1, self.read_timeout)
  let [hd, eof] = self.f_read(self.fd, nr, timeout)
  let self.eof = eof
  return self.hd2str(hd)
endfunction

function! s:lib.write(str, ...)
  let timeout = get(a:000, 0, self.write_timeout)
  let hd = self.str2hd(a:str)
  return self.f_write(self.fd, hd, timeout)
endfunction

function! s:lib.popen2(args)
  let [pid, fd_stdin, fd_stdout] = self.api.vp_pipe_open(2, s:getfilename(a:args))
  let proc = {}
  let proc.pid = pid
  let proc.stdin = self.fdopen(fd_stdin, self.api.vp_pipe_close, self.api.vp_pipe_read, self.api.vp_pipe_write)
  let proc.stdout = self.fdopen(fd_stdout, self.api.vp_pipe_close, self.api.vp_pipe_read, self.api.vp_pipe_write)
  return proc
endfunction

function! s:lib.popen3(args)
  let [pid, fd_stdin, fd_stdout, fd_stderr] = self.api.vp_pipe_open(3, s:getfilename(a:args))
  let proc = {}
  let proc.pid = pid
  let proc.stdin = self.fdopen(fd_stdin, self.api.vp_pipe_close, self.api.vp_pipe_read, self.api.vp_pipe_write)
  let proc.stdout = self.fdopen(fd_stdout, self.api.vp_pipe_close, self.api.vp_pipe_read, self.api.vp_pipe_write)
  let proc.stderr = self.fdopen(fd_stderr, self.api.vp_pipe_close, self.api.vp_pipe_read, self.api.vp_pipe_write)
  return proc
endfunction

function! s:lib.socket_open(host, port)
  let fd = self.api.vp_socket_open(a:host, a:port)
  return self.fdopen(fd, self.api.vp_socket_close, self.api.vp_socket_read, self.api.vp_socket_write)
endfunction

function! s:lib.fdopen(fd, f_close, f_read, f_write)
  let file = copy(self)
  call extend(file, self.api)
  let file.fd = a:fd
  let file.eof = 0
  let file.f_close = a:f_close
  let file.f_read = a:f_read
  let file.f_write = a:f_write
  return file
endfunction

function! s:lib.ptyopen(args)
  let [pid, fd, ttyname] = self.api.vp_pty_open(&winwidth, &winheight, s:getfilename(a:args))

  let proc =  self.fdopen(fd, self.api.vp_pty_close, self.api.vp_pty_read, self.api.vp_pty_write)
  let proc.pid = pid
  let proc.ttyname = ttyname
  return proc
endfunction


"-----------------------------------------------------------
" UTILS

function! s:lib.str2hd(str)
  return join(map(range(len(a:str)), 'printf("%02X", char2nr(a:str[v:val]))'), "")
endfunction

function! s:lib.hd2str(hd)
  " Since Vim can not handle \x00 byte, remove it.
  " do not use nr2char()
  " nr2char(255) => "\xc3\xbf" (utf8)
  return join(map(split(a:hd, '..\zs'), 'v:val == "00" ? "" : eval(''"\x'' . v:val . ''"'')'), "")
endfunction

function! s:lib.str2list(str)
  return map(range(len(a:str)), 'char2nr(a:str[v:val])')
endfunction

function! s:lib.list2str(lis)
  return self.hd2str(self.list2hd(a:lis))
endfunction

function! s:lib.hd2list(hd)
  return map(split(a:hd, '..\zs'), 'str2nr(v:val, 16)')
endfunction

function! s:lib.list2hd(lis)
  return join(map(a:lis, 'printf("%02X", v:val)'), "")
endfunction

function! s:getfilename(args)
    let l:PATH_SEPARATOR = (has('win32') || has('win64')) ? '/\\' : '/'
    let l:pattern = printf('[/~]\?\f\+[%s]\f*$', l:PATH_SEPARATOR)
    if a:args[0] =~ l:pattern
        let l:args = a:args
    else
        " Command search.
        if has('win32') || has('win64')
            let l:path = substitute($PATH, '\\\?;', ',', 'g')
            let l:ext = fnamemodify(a:args[0], ':e')
            if l:ext != ''
                let l:files = globpath(l:path, a:args[0])
            else
                for ext in ['.bat', '.cmd', '.exe']
                    let l:files = globpath(l:path, a:args[0].ext)
                    if !empty(l:files)
                        break
                    endif
                endfor
            endif
            let l:args = insert(a:args[1:], split(l:files, '\n')[0])
        else
            let l:path = substitute($PATH, '/\?:', ',', 'g')
            let l:args = insert(a:args[1:], split(globpath(l:path, a:args[0]), '\n')[0])
        endif
    endif

    " Convert encoding for system().<commit_msg>Use $PATHEXT.<commit_after>scriptencoding utf-8

function! proc#import()
  call s:lib.load()
  return s:lib
endfunction

augroup ProcPlug
  autocmd!
  autocmd VimLeave * call s:lib.unload()
augroup END

let s:lib = {}
let s:lib.api = {}
let s:lib.lasterr = []
let s:lib.read_timeout = 100
let s:lib.write_timeout = 100

function! s:lib.load()
  return self.api.load()
endfunction

function! s:lib.unload()
  call self.api.unload()
endfunction

function! s:lib.open(path, flags, ...)
  let mode = get(a:000, 0, 0)
  let fd = self.api.vp_file_open(a:path, a:flags, mode)
  return self.fdopen(fd, self.api.vp_file_close, self.api.vp_file_read, self.api.vp_file_write)
endfunction

function! s:lib.close()
  call self.f_close(self.fd)
  let self.fd = -1
endfunction

function! s:lib.read(...)
  let nr = get(a:000, 0, -1)
  let timeout = get(a:000, 1, self.read_timeout)
  let [hd, eof] = self.f_read(self.fd, nr, timeout)
  let self.eof = eof
  return self.hd2str(hd)
endfunction

function! s:lib.write(str, ...)
  let timeout = get(a:000, 0, self.write_timeout)
  let hd = self.str2hd(a:str)
  return self.f_write(self.fd, hd, timeout)
endfunction

function! s:lib.popen2(args)
  let [pid, fd_stdin, fd_stdout] = self.api.vp_pipe_open(2, s:getfilename(a:args))
  let proc = {}
  let proc.pid = pid
  let proc.stdin = self.fdopen(fd_stdin, self.api.vp_pipe_close, self.api.vp_pipe_read, self.api.vp_pipe_write)
  let proc.stdout = self.fdopen(fd_stdout, self.api.vp_pipe_close, self.api.vp_pipe_read, self.api.vp_pipe_write)
  return proc
endfunction

function! s:lib.popen3(args)
  let [pid, fd_stdin, fd_stdout, fd_stderr] = self.api.vp_pipe_open(3, s:getfilename(a:args))
  let proc = {}
  let proc.pid = pid
  let proc.stdin = self.fdopen(fd_stdin, self.api.vp_pipe_close, self.api.vp_pipe_read, self.api.vp_pipe_write)
  let proc.stdout = self.fdopen(fd_stdout, self.api.vp_pipe_close, self.api.vp_pipe_read, self.api.vp_pipe_write)
  let proc.stderr = self.fdopen(fd_stderr, self.api.vp_pipe_close, self.api.vp_pipe_read, self.api.vp_pipe_write)
  return proc
endfunction

function! s:lib.socket_open(host, port)
  let fd = self.api.vp_socket_open(a:host, a:port)
  return self.fdopen(fd, self.api.vp_socket_close, self.api.vp_socket_read, self.api.vp_socket_write)
endfunction

function! s:lib.fdopen(fd, f_close, f_read, f_write)
  let file = copy(self)
  call extend(file, self.api)
  let file.fd = a:fd
  let file.eof = 0
  let file.f_close = a:f_close
  let file.f_read = a:f_read
  let file.f_write = a:f_write
  return file
endfunction

function! s:lib.ptyopen(args)
  let [pid, fd, ttyname] = self.api.vp_pty_open(&winwidth, &winheight, s:getfilename(a:args))

  let proc =  self.fdopen(fd, self.api.vp_pty_close, self.api.vp_pty_read, self.api.vp_pty_write)
  let proc.pid = pid
  let proc.ttyname = ttyname
  return proc
endfunction


"-----------------------------------------------------------
" UTILS

function! s:lib.str2hd(str)
  return join(map(range(len(a:str)), 'printf("%02X", char2nr(a:str[v:val]))'), "")
endfunction

function! s:lib.hd2str(hd)
  " Since Vim can not handle \x00 byte, remove it.
  " do not use nr2char()
  " nr2char(255) => "\xc3\xbf" (utf8)
  return join(map(split(a:hd, '..\zs'), 'v:val == "00" ? "" : eval(''"\x'' . v:val . ''"'')'), "")
endfunction

function! s:lib.str2list(str)
  return map(range(len(a:str)), 'char2nr(a:str[v:val])')
endfunction

function! s:lib.list2str(lis)
  return self.hd2str(self.list2hd(a:lis))
endfunction

function! s:lib.hd2list(hd)
  return map(split(a:hd, '..\zs'), 'str2nr(v:val, 16)')
endfunction

function! s:lib.list2hd(lis)
  return join(map(a:lis, 'printf("%02X", v:val)'), "")
endfunction

function! s:getfilename(args)
    let l:PATH_SEPARATOR = (has('win32') || has('win64')) ? '/\\' : '/'
    let l:pattern = printf('[/~]\?\f\+[%s]\f*$', l:PATH_SEPARATOR)
    if a:args[0] =~ l:pattern
        let l:args = a:args
    else
        " Command search.
        if has('win32') || has('win64')
            let l:path = substitute($PATH, '\\\?;', ',', 'g')
            let l:ext = fnamemodify(a:args[0], ':e')
            if l:ext != ''
                let l:files = globpath(l:path, a:args[0])
            else
                for ext in split($PATHEXT, ';')
                    let l:files = globpath(l:path, a:args[0].ext)
                    if !empty(l:files)
                        break
                    endif
                endfor
            endif
            let l:args = insert(a:args[1:], split(l:files, '\n')[0])
        else
            let l:path = substitute($PATH, '/\?:', ',', 'g')
            let l:args = insert(a:args[1:], split(globpath(l:path, a:args[0]), '\n')[0])
        endif
    endif

    " Convert encoding for system().
{'fraction_non_alphanumeric': 0.17496834107218234, 'fraction_numerical': 0.01646264246517518, 'mean_word_length': 3.263157894736842, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '2709435', 'n_tokens_mistral': 3831, 'n_tokens_neox': 3719, 'n_words': 738}