<commit_before>" -*- text -*-
"  oracle.vim -- Vim integration for the Go oracle.
"
"  Load with (e.g.)  :source oracle.vim
"  Call with (e.g.)  :GoOracleDescribe
"  while cursor or selection is over syntax of interest.
"  Run :copen to show the quick-fix file.
"
" This is an absolutely rudimentary integration of the Go Oracle into
" Vim's quickfix mechanism and it needs a number of usability
" improvements before it can be practically useful to Vim users.
" Voluntary contributions welcomed!
"
" TODO(adonovan):
" - reject buffers with no filename.
" - hide all filenames in quickfix buffer.
"
"
func! s:qflist(output)
    let qflist = []
    " Parse GNU-style 'file:line.col-line.col: message' format.
    let mx = '^\(\a:[\\/][^:]\+\|[^:]\+\):\(\d\+\):\(\d\+\):\(.*\)$'
    for line in split(a:output, "\n")
        let ml = matchlist(line, mx)
        " Ignore non-match lines or warnings
        if ml == [] || ml[4] =~ '^ warning:'
            continue
        endif
        let item = {
                    \  'filename': ml[1],
                    \  'text': ml[4],
                    \  'lnum': ml[2],
                    \  'col': ml[3],
                    \}
        let bnr = bufnr(fnameescape(ml[1]))
        if bnr != -1
            let item['bufnr'] = bnr
        endif
        call add(qflist, item)
    endfor
    call setqflist(qflist)
    cwindow
endfun

func! s:getpos(l, c)
    if &encoding != 'utf-8'
        let buf = a:l == 1 ? '' : (join(getline(1, a:l-1), "\n") . "\n")
        let buf .= a:c == 1 ? '' : getline('.')[:a:c-2]
        return len(iconv(buf, &encoding, 'utf-8'))
    endif
    return line2byte(a:l) + (a:c-2)
endfun

func! s:RunOracle(mode, selected) range abort
    let fname = expand('%:p')
    let dname = expand('%:p:h')
    let pkg = go#package#ImportPath(dname)

    if exists('g:go_oracle_scope_file')
        " let the user defines the scope
        let sname = shellescape(get(g:, 'go_oracle_scope_file'))
    elseif exists('g:go_oracle_include_tests') && pkg != -1
        " give import path so it includes all _test.go files too
        let sname = shellescape(pkg)
    else
        " best usable way, only pass the package itself, without the test
        " files
        let sname = join(go#tool#Files(), ' ')
    endif

    if a:selected != -1
        let pos1 = s:getpos(line("'<"), col("'<"))
        let pos2 = s:getpos(line("'>"), col("'>"))
        let cmd = printf('%s -format json -pos=%s:#%d,#%d %s %s',
                    \  g:go_oracle_bin,
                    \  shellescape(fname), pos1, pos2, a:mode, sname)
    else
        let pos = s:getpos(line('.'), col('.'))
        let cmd = printf('%s -format json -pos=%s:#%d %s %s',
                    \  g:go_oracle_bin,
                    \  shellescape(fname), pos, a:mode, sname)
    endif

    echon "vim-go: " | echohl Identifier | echon "analysing ..." | echohl None

    let out = system(cmd)
    if v:shell_error
        " unfortunaly oracle outputs a very long stack trace that is not
        " parsable to show the real error. But the main issue is usually the
        " package which doesn't build. 
        redraw | echon 'vim-go: could not run static analyser (does it build?)'
        return {}
    else
        let json_decoded = webapi#json#decode(out)
        return json_decoded
    endif
endfun

let s:buf_nr = -1

" Show 'implements' relation for selected package
function! go#oracle#Implements(selected)
    let out = s:RunOracle('implements', a:selected)
    if empty(out)
        return
    endif

    " be sure they exists before we retrieve them from the map
    if !has_key(out, "implements")
        return
    endif<commit_msg>oracle: show errors now<commit_after>" -*- text -*-
"  oracle.vim -- Vim integration for the Go oracle.
"
"  Load with (e.g.)  :source oracle.vim
"  Call with (e.g.)  :GoOracleDescribe
"  while cursor or selection is over syntax of interest.
"  Run :copen to show the quick-fix file.
"
" This is an absolutely rudimentary integration of the Go Oracle into
" Vim's quickfix mechanism and it needs a number of usability
" improvements before it can be practically useful to Vim users.
" Voluntary contributions welcomed!
"
" TODO(adonovan):
" - reject buffers with no filename.
" - hide all filenames in quickfix buffer.
"
"
func! s:qflist(output)
    let qflist = []
    " Parse GNU-style 'file:line.col-line.col: message' format.
    let mx = '^\(\a:[\\/][^:]\+\|[^:]\+\):\(\d\+\):\(\d\+\):\(.*\)$'
    for line in split(a:output, "\n")
        let ml = matchlist(line, mx)
        " Ignore non-match lines or warnings
        if ml == [] || ml[4] =~ '^ warning:'
            continue
        endif
        let item = {
                    \  'filename': ml[1],
                    \  'text': ml[4],
                    \  'lnum': ml[2],
                    \  'col': ml[3],
                    \}
        let bnr = bufnr(fnameescape(ml[1]))
        if bnr != -1
            let item['bufnr'] = bnr
        endif
        call add(qflist, item)
    endfor
    call setqflist(qflist)
    cwindow
endfun

func! s:getpos(l, c)
    if &encoding != 'utf-8'
        let buf = a:l == 1 ? '' : (join(getline(1, a:l-1), "\n") . "\n")
        let buf .= a:c == 1 ? '' : getline('.')[:a:c-2]
        return len(iconv(buf, &encoding, 'utf-8'))
    endif
    return line2byte(a:l) + (a:c-2)
endfun

func! s:RunOracle(mode, selected) range abort
    let fname = expand('%:p')
    let dname = expand('%:p:h')
    let pkg = go#package#ImportPath(dname)

    if exists('g:go_oracle_scope_file')
        " let the user defines the scope
        let sname = shellescape(get(g:, 'go_oracle_scope_file'))
    elseif exists('g:go_oracle_include_tests') && pkg != -1
        " give import path so it includes all _test.go files too
        let sname = shellescape(pkg)
    else
        " best usable way, only pass the package itself, without the test
        " files
        let sname = join(go#tool#Files(), ' ')
    endif

    if a:selected != -1
        let pos1 = s:getpos(line("'<"), col("'<"))
        let pos2 = s:getpos(line("'>"), col("'>"))
        let cmd = printf('%s -format json -pos=%s:#%d,#%d %s %s',
                    \  g:go_oracle_bin,
                    \  shellescape(fname), pos1, pos2, a:mode, sname)
    else
        let pos = s:getpos(line('.'), col('.'))
        let cmd = printf('%s -format json -pos=%s:#%d %s %s',
                    \  g:go_oracle_bin,
                    \  shellescape(fname), pos, a:mode, sname)
    endif

    echon "vim-go: " | echohl Identifier | echon "analysing ..." | echohl None

    let out = system(cmd)
    if v:shell_error
        " unfortunaly oracle outputs a very long stack trace that is not
        " parsable to show the real error. But the main issue is usually the
        " package which doesn't build. 
        " echo out
        " redraw | echon 'vim-go: could not run static analyser (does it build?)'
        redraw | echon "vim-go: " | echohl SpecialComment | echon out | echohl None
        return {}
    else
        let json_decoded = webapi#json#decode(out)
        return json_decoded
    endif
endfun

let s:buf_nr = -1

" Show 'implements' relation for selected package
function! go#oracle#Implements(selected)
    let out = s:RunOracle('implements', a:selected)
    if empty(out)
        return
    endif

    " be sure they exists before we retrieve them from the map
    if !has_key(out, "implements")
        return
    endif
{'fraction_non_alphanumeric': 0.14102049015668944, 'fraction_numerical': 0.006160439266104192, 'mean_word_length': 2.1523849725622624, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '1268528', 'n_tokens_mistral': 2569, 'n_tokens_neox': 2448, 'n_words': 749}