1
0
mirror of https://github.com/amix/vimrc synced 2025-07-06 16:05:01 +08:00

Add support with Go language.

This commit is contained in:
Kurtis Moxley
2022-05-27 20:16:55 +08:00
parent 71e3f2fa49
commit de80db5969
205 changed files with 29172 additions and 0 deletions

View File

@ -0,0 +1,44 @@
#!/bin/sh
#
# Benchmark the syntax/go.vim file.
#
# The first argument is the Vim version to test (as in run-vim), the rest of the
# agument are g:go_highlight_* settings (without that prefix). You can use "ALL"
# to set all the options.
#
set -euC
vimgodir=$(cd -P "$(dirname "$0")/.." > /dev/null && pwd)
cd "$vimgodir"
if [ -z "${1:-}" ]; then
echo "unknown version: '${1:-}'"
echo "First argument must be 'vim-8.0' or 'nvim'."
exit 1
fi
if [ -z "${2:-}" ]; then
echo "file not set"
echo "Second argument must be a Go file to benchmark, as 'filename:linenr'"
exit 1
fi
vim=$1
file="$(echo "$2" | cut -d : -f 1)"
line="$(echo "$2" | cut -d : -f 2)"
if [ -z "$line" -o "$line" = "$file" ]; then
echo "Second argument must be a Go file to benchmark, as 'filename:linenr'"
exit 1
fi
shift; shift
export RUNBENCH_SETTINGS=$@
export RUNBENCH_OUT="$(mktemp -p "${TMPDIR:-/tmp}" vimgo-bench.XXXXX)"
"$vimgodir/scripts/run-vim" $vim \
+"silent e $file" \
+"normal! ${line}G" \
-S ./scripts/runbench.vim
echo "Report written to:"
echo "$RUNBENCH_OUT"

View File

@ -0,0 +1,15 @@
#!/bin/sh
#
# Run all tests inside a Docker container
#
set -euC
vimgodir=$(cd -P "$(dirname "$0")/.." > /dev/null && pwd)
cd "$vimgodir"
docker build --tag vim-go-test .
# seccomp=confined is required for dlv to run in a container, hence it's
# required for vim-go's debug tests.
docker run -e VIMS --rm --security-opt="seccomp=unconfined" vim-go-test
# vim:ts=2:sts=2:sw=2:et

View File

@ -0,0 +1,35 @@
#!/bin/sh
#
# Install and setup a Vim or Neovim for running tests.
# This should work on both GitHub Actions and people's desktop computers, and
# be 100% independent from any system installed Vim.
#
set -euC
vimgodir=$(cd -P "$(dirname "$0")/.." > /dev/null && pwd)
cd "$vimgodir"
vim=${1:-}
installdir="/tmp/vim-go-test/$1-install"
# Make sure all Go tools and other dependencies are installed.
echo "Installing Go binaries"
export GOPATH=$installdir
export GO111MODULE=on
export PATH="${GOPATH}/bin:$PATH"
"$vimgodir/scripts/run-vim" $vim +':silent :GoUpdateBinaries' +':qa'
echo "Installing lint tools"
(
mkdir -p "$installdir/share/vim/vimgo/pack/vim-go/start/"
cd "$installdir/share/vim/vimgo/pack/vim-go/start/"
[ -d "vim-vimhelplint" ] || git clone --depth 1 --quiet https://github.com/machakann/vim-vimhelplint
[ -d "vim-vimlparser" ] || git clone --depth 1 --quiet https://github.com/ynkdir/vim-vimlparser
[ -d "vim-vimlint" ] || git clone --depth 1 --quiet https://github.com/syngan/vim-vimlint
)
echo "vim-go tools installed to: $installdir/share/vim/vimgo/pack/vim-go/start"
# vim:ts=2:sts=2:sw=2:et

View File

@ -0,0 +1,100 @@
#!/bin/sh
#
# Install and setup a Vim or Neovim for running tests.
# This should work on both GitHub Actions and people's desktop computers, and
# be 100% independent from any system installed Vim.
#
# It will echo the full path to a Vim binary, e.g.:
# /some/path/src/vim
set -euC
vimgodir=$(cd -P "$(dirname "$0")/.." > /dev/null && pwd)
cd "$vimgodir"
vim=${1:-}
case "$vim" in
"vim-8.0")
# This follows the version in Ubuntu LTS. Vim's master branch isn't always
# stable, and we don't want to have the build fail because Vim introduced a
# bug.
tag="v8.0.1453"
giturl="https://github.com/vim/vim"
;;
"vim-8.2")
# This is the version that's installed by homebrew currently. It doesn't
# have to stay up to date with homebrew, and is only chosen here because
# that's what homebrew was using at the the time and we need a version to
# vimlint with.
tag="v8.2.0200"
giturl="https://github.com/vim/vim"
;;
"nvim")
# Use latest stable version.
tag="v0.4.0"
giturl="https://github.com/neovim/neovim"
;;
*)
echo "unknown version: '${1:-}'"
echo "First argument must be 'vim-8.0', vim-8.2, or 'nvim'."
exit 1
;;
esac
srcdir="/tmp/vim-go-test/$1-src"
installdir="/tmp/vim-go-test/$1-install"
# Use cached installdir.
if [ -d "$installdir" ]; then
echo "$installdir exists; skipping build."
# The ./scripts/test script relies on this.
echo "installed to: $installdir"
exit 0
fi
mkdir -p "$srcdir"
cd "$srcdir"
# Neovim build requires more deps than Vim and is annoying, so we use the
# binary.
# 0.2.0 doesn't have a binary build for Linux, so we use 0.2.1-dev for now.
if [ "$1" = "nvim" ]; then
# TODO: Use macOS binaries on macOS
curl -Ls https://github.com/neovim/neovim/releases/download/$tag/nvim-linux64.tar.gz |
tar xzf - -C /tmp/vim-go-test/
mv /tmp/vim-go-test/nvim-linux64 /tmp/vim-go-test/nvim-install
mkdir -p "$installdir/share/nvim/runtime/pack/vim-go/start"
ln -s "$vimgodir" "$installdir/share/nvim/runtime/pack/vim-go/start/vim-go"
# Consistent paths makes calling things easier.
mv "$installdir/bin/nvim" "$installdir/bin/vim"
mkdir -p "$installdir/share/vim/vimgo/pack"
ln -s "$installdir/share/nvim/runtime/pack/vim-go" "$installdir/share/vim/vimgo/pack/vim-go"
# Build Vim from source.
else
if [ -d "$srcdir/.git" ]; then
echo "Skipping clone as $srcdir/.git exists"
else
echo "Cloning $tag from $giturl"
git clone --branch "$tag" --depth 1 "$giturl" "$srcdir"
fi
./configure --prefix="$installdir" --with-features=huge --disable-gui
make install
mkdir -p "$installdir/share/vim/vimgo/pack/vim-go/start"
ln -s "$vimgodir" "$installdir/share/vim/vimgo/pack/vim-go/start/vim-go"
fi
# Don't really need source after successful install.
rm -rf "$srcdir"
echo "installed to: $installdir"
# vim:ts=2:sts=2:sw=2:et

View File

@ -0,0 +1,88 @@
#!/bin/sh
#
# Run all linting tools.
#
set -euC
vimgodir=$(cd -P "$(dirname "$0")/.." > /dev/null && pwd)
cd "$vimgodir"
### Setup Vim and other dependencies.
#####################################
if [ -z "${1:-}" ]; then
echo "unknown version: '${1:-}'"
echo "First argument must be 'vim-8.0' or 'nvim'."
exit 1
fi
vim=$1
vimdir="/tmp/vim-go-test/$vim-install"
export GOPATH=$vimdir
export PATH="${GOPATH}/bin:$PATH"
if [ ! -f "$vimdir/bin/vim" ]; then
echo "$vimdir/bin/vim doesn't exist; did you install it with the install-vim script?"
exit 1
fi
### Run vint
############
failed=0
printf "Running vint ... "
if [ -x "$(command -v vint)" ]; then
lint=$(vint "$vimgodir" 2>&1 ||:)
if [ -n "$lint" ]; then
echo "FAILED"
echo "$lint"
echo
failed=6
else
echo "PASSED"
fi
else
echo "SKIPPED"
echo "'vint' binary not found; use 'pip install vim-vint' to install it."
fi
### Run vim-vimlint
###################
printf "Running vim-vimlint ... "
lint=$(sh "$vimdir/share/vim/vimgo/pack/vim-go/start/vim-vimlint/bin/vimlint.sh" \
-p "$vimdir/share/vim/vimgo/pack/vim-go/start/vim-vimlparser" \
-l "$vimdir/share/vim/vimgo/pack/vim-go/start/vim-vimlint" \
-u \
-c func_abort=1 \
-e EVL110=1 -e EVL103=1 -e EVL104=1 -e EVL102=1 \
"$vimgodir" \
2>&1 ||:)
if [ -n "$lint" ]; then
echo "FAILED"
echo "$lint"
echo
failed=6
else
echo "PASSED"
fi
### Run vimhelplint.
####################
printf "Running vimhelplint ... "
# set modeline explicitly so that the modeline will be respected when run as root.
lint=$($vimdir/bin/vim -esNR \
--cmd "set rtp+=$vimdir/share/vim/vimgo/pack/vim-go/start/vim-vimhelplint/" \
--cmd 'set modeline' \
+'filetype plugin on' \
+"e $vimgodir/doc/vim-go.txt" \
+'verbose VimhelpLintEcho' \
+q \
2>&1 ||:)
if [ "$lint" ]; then
echo "FAILED"
echo "$lint"
failed=6
else
echo "PASSED"
fi
exit "$failed"

View File

@ -0,0 +1,51 @@
#!/bin/sh
#
# Run a "bare" Vim with just vim-go and ignoring ~/.vim
#
set -euC
vimgodir=$(cd -P "$(dirname "$0")/.." > /dev/null && pwd)
cd "$vimgodir"
coverage=0
while getopts "c" option; do
case "$option" in
c) coverage=1; ;;
esac
done
shift $((OPTIND - 1))
if [ -z "${1:-}" ]; then
echo "unknown version: '${1:-}'"
echo "First argument must be 'vim-8.0', 'vim-8.2', or 'nvim'."
exit 1
fi
dir="/tmp/vim-go-test/$1-install"
export GOPATH=$dir
export GO111MODULE=on
export PATH="${GOPATH}/bin:$PATH"
shift
if [ ! -f "$dir/bin/vim" ]; then
echo "$dir/bin/vim doesn't exist; did you install it with the install-vim script?"
exit 1
fi
if [ $coverage -eq 1 ]; then
covimerage -q run --report-file /tmp/vim-go-test/cov-profile.txt --append \
$dir/bin/vim --noplugin -u NONE -i NONE -N -n \
+"set shm+=WAFI rtp^=$vimgodir packpath=$dir/share/vim/vimgo" \
+'filetype plugin indent on' \
+'packloadall!' \
"$@"
else
$dir/bin/vim --noplugin -u NONE -i NONE -N -n \
+"set shm+=WAFI rtp^=$vimgodir packpath=$dir/share/vim/vimgo" \
+'filetype plugin indent on' \
+'packloadall!' \
"$@"
fi
# vim:ts=2:sts=2:sw=2:et

View File

@ -0,0 +1,37 @@
" vint: -ProhibitSetNoCompatible
" don't spam the user when Vim is started in Vi compatibility mode
let s:cpo_save = &cpo
set cpo&vim
set nocompatible nomore shellslash encoding=utf-8 shortmess+=WIF
lang mess C
if $RUNBENCH_SETTINGS is? 'all'
let $RUNBENCH_SETTINGS = join(['array_whitespace_error', 'build_constraints',
\ 'chan_whitespace_error', 'extra_types', 'fields', 'format_strings',
\ 'function_arguments', 'function_calls', 'functions', 'generate_tags',
\ 'operators', 'space_tab_error', 'string_spellcheck',
\ 'trailing_whitespace_error', 'types', 'variable_assignments',
\ 'variable_declarations'], ' ')
endif
for s:s in split($RUNBENCH_SETTINGS, ' ')
call execute('let g:go_highlight_' . s:s . ' = 1')
endfor
filetype plugin indent on
syntax on
syntime on
redraw!
let s:report = execute('syntime report')
execute ':e ' . fnameescape($RUNBENCH_OUT)
call setline('.', split(s:report, '\n'))
wq
" restore Vi compatibility settings
let &cpo = s:cpo_save
unlet s:cpo_save
" vim: sw=2 ts=2 et

View File

@ -0,0 +1,157 @@
" Make sure some options are set to sane defaults and output all messages in
" English.
" vint: -ProhibitSetNoCompatible
" don't spam the user when Vim is started in Vi compatibility mode
let s:cpo_save = &cpo
set cpo&vim
set nocompatible nomore shellslash encoding=utf-8 shortmess+=WIF
lang mess C
" Initialize variables.
let s:total_started = reltime()
let s:fail = 0
let s:done = 0
let s:logs = []
let s:gopath = $GOPATH
if !exists('g:test_verbose')
let g:test_verbose = 0
endif
function! s:logmessages() abort
" Add all messages (usually errors).
redir => s:mess
silent messages
redir END
let s:logs = s:logs + filter(split(s:mess, "\n"), 'v:val !~ "^Messages maintainer"')
silent messages clear
endfunction
function! s:clearOptions() abort
" clear all the vim-go options
for l:k in keys(g:)
if l:k =~ '^go_' && l:k !~ '^go_loaded_'
call execute(printf('unlet g:%s', l:k))
endif
endfor
endfunction
" Source the passed test file.
source %
" cd into the folder of the test file.
let s:testfile = expand('%:t')
let s:dir = expand('%:p:h')
call go#util#Chdir(s:dir)
" Export root path to vim-go dir.
let g:vim_go_root = fnamemodify(getcwd(), ':p')
" Get a list of all Test_ functions for the given file.
redir @q
silent function /^Test_
redir END
let s:tests = split(substitute(@q, 'function \(\k\+()\)', '\1', 'g'))
" log any messages already accumulated.
call s:logmessages()
" Iterate over all tests and execute them.
for s:test in sort(s:tests)
" Since we extract the tests from a regexp the "abort" keyword is also in
" the list, which is not a test name :-)
if s:test == 'abort'
continue
endif
" make sure g:go_echo_command_info is not set so that we don't get
" unexpected messages when commands are executed.
let g:go_echo_command_info = 0
" make sure gopls doesn't use multi-client mode; there seem to be some racy
" conditions when trying to shutdown the server after each test when
" multi-client mode is used.
let g:go_gopls_options = []
let s:started = reltime()
if g:test_verbose is 1
call add(s:logs, printf("=== RUN %s", s:test[:-3]))
endif
try
exe 'call ' . s:test
" sleep to give events a chance to be processed. This is especially
" important for the LSP code to have a chance to run before Vim exits, in
" order to avoid errors trying to write to the gopls channels since Vim
" would otherwise stop gopls before the event handlers were run and result
" in 'stream closed' errors when the events were run _after_ gopls exited.
sleep 50m
catch
call assert_report(printf('at %s: %s', v:throwpoint, v:exception))
finally
call s:clearOptions()
endtry
let s:elapsed_time = substitute(reltimestr(reltime(s:started)), '^\s*\(.\{-}\)\s*$', '\1', '')
" Restore GOPATH after each test.
let $GOPATH = s:gopath
" Restore the working directory after each test.
call go#util#Chdir(s:dir)
try
" exit gopls after each test
call go#lsp#Exit()
catch /^Vim(call):E900: Invalid channel id/
" do nothing - gopls has stopped
endtry
let s:done += 1
if len(v:errors) > 0
let s:fail += 1
call add(s:logs, printf("--- FAIL %s (%ss)", s:test[:-3], s:elapsed_time))
call s:logmessages()
call extend(s:logs, map(v:errors, '" ". v:val'))
" Reset so we can capture failures of the next test.
let v:errors = []
else
if g:test_verbose is 1
call s:logmessages()
call add(s:logs, printf("--- PASS %s (%ss)", s:test[:-3], s:elapsed_time))
else
silent messages clear
endif
endif
endfor
" Create an empty fail to indicate that at least one test failed.
if s:fail > 0
split /tmp/vim-go-test/FAILED
silent write
endif
let s:total_elapsed_time = substitute(reltimestr(reltime(s:total_started)), '^\s*\(.\{-}\)\s*$', '\1', '')
" Also store all internal messages from s:logs as well.
silent! split /tmp/vim-go-test/test.tmp
call append(line('$'), s:logs)
call append(line('$'), printf("%s %s %s %ss / %s tests",
\ (s:fail > 0 ? 'FAIL' : 'ok '),
\ s:testfile,
\ repeat(' ', 25 - len(s:testfile)),
\ s:total_elapsed_time, s:done))
if g:test_verbose is 0
silent :g/^$/d
endif
silent! write
" Our work here is done.
qall!
" restore Vi compatibility settings
let &cpo = s:cpo_save
unlet s:cpo_save
" vim:ts=2:sts=2:sw=2:et

View File

@ -0,0 +1,108 @@
#!/bin/sh
#
# Run all tests.
#
set -euC
vimgodir=$(cd -P "$(dirname "$0")/.." > /dev/null && pwd)
cd "$vimgodir"
_usage() {
echo "Usage: ${0##*/} [-hvc] [-r file] vim_version"
echo
echo "Options:"
echo " -h Show this help"
echo " -v Enable verbose output"
echo " -r Run only the tests from this file"
echo " -c Generate code coverage reports"
echo " -u Submit code coverage reports"
echo
}
verbose=0
run=""
coverage=""
uploadcoverage=""
while getopts "hvcur:" option; do
case "$option" in
h) _usage; exit 0 ;;
v) verbose=1; ;;
r) run=$OPTARG ;;
c) coverage="-c" ;;
u) uploadcoverage=1 ;;
*)
echo "error: unknown option '$option'"
_usage
exit 1
;;
esac
done
shift $((OPTIND - 1))
### Setup Vim and other dependencies.
#####################################
if [ -z "${1:-}" ]; then
echo "unknown version: '${1:-}'"
echo "First argument must be 'vim-8.0' or 'nvim'."
exit 1
fi
vim=$1
vimdir="/tmp/vim-go-test/$vim-install"
export GOPATH=$vimdir
export PATH="${GOPATH}/bin:$PATH"
if [ ! -f "$vimdir/bin/vim" ]; then
echo "$vimdir/bin/vim doesn't exist; did you install it with the install-vim script?"
exit 1
fi
### Run tests.
##############
# Clean stale log file.
[ -f '/tmp/vim-go-test/test.log' ] && rm '/tmp/vim-go-test/test.log'
[ -f '/tmp/vim-go-test/FAILED' ] && rm '/tmp/vim-go-test/FAILED'
[ -f '/tmp/vim-go-test/cov-profile.txt' ] && rm '/tmp/vim-go-test/cov-profile.txt'
[ -f '/tmp/vim-go-test/cov-report.txt' ] && rm '/tmp/vim-go-test/cov-report.txt'
# Run the actual tests.
find "$vimgodir" -name '*_test.vim' | sort | while read test_file; do
[ -n "$run" -a "$(basename "$test_file")" != "$run" ] && continue
"$vimgodir/scripts/run-vim" $coverage $vim -e \
+"silent e $test_file" \
+"let g:test_verbose=$verbose" \
+"let g:go_echo_command_info=0" \
-S ./scripts/runtest.vim < /dev/null || (
# If Vim exits with non-0 it's almost certainly a bug in the test runner;
# should very rarely happen in normal usage.
echo 'test runner failure'
cat '/tmp/vim-go-test/test.tmp'
rm '/tmp/vim-go-test/test.tmp'
exit 5
)
# Append logs
cat '/tmp/vim-go-test/test.tmp' | tee '/tmp/vim-go-test/test.log'
rm '/tmp/vim-go-test/test.tmp'
done
echo
if [ -f "/tmp/vim-go-test/FAILED" ]; then
echo 2>&1 "Some ($vim) tests FAILED"
exit 1
fi
echo 2>&1 "All ($vim) tests PASSED"
# Generate coverage reports
if [ -n "$coverage" ]; then
coverage xml --omit '*_test.vim'
if [ -n "$uploadcoverage" ]; then
codecov -X search gcov pycov -f coverage.xml --required \
--flags "$(echo "$vim" | sed -s 's/[-.]//g')"
rm coverage.xml
fi
fi
# vim:ts=2:sts=2:sw=2:et