diff --git a/.cirrus.yml b/.cirrus.yml index a098789c59..4d78085b8d 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -3,6 +3,8 @@ env: FEATURES: huge freebsd_12_task: + only_if: $CIRRUS_TAG == '' + timeout_in: 20m freebsd_instance: image: freebsd-12-1-release-amd64 install_script: diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 0000000000..1157ff2567 --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1 @@ +service_name: github-actions diff --git a/.github/workflows/ci-windows.yaml b/.github/workflows/ci-windows.yaml deleted file mode 100644 index 4a470624b8..0000000000 --- a/.github/workflows/ci-windows.yaml +++ /dev/null @@ -1,230 +0,0 @@ -name: GitHub CI - -on: - push: - branches: - - '**' - pull_request: - -env: - VCVARSALL: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat - - # Interfaces - # Lua - LUA_VER: 54 - LUA_VER_DOT: '5.4' - LUA_RELEASE: 5.4.0 - LUA32_URL: https://downloads.sourceforge.net/luabinaries/lua-%LUA_RELEASE%_Win32_dllw6_lib.zip - LUA64_URL: https://downloads.sourceforge.net/luabinaries/lua-%LUA_RELEASE%_Win64_dllw6_lib.zip - LUA_DIR: D:\Lua - # Python 2 - PYTHON_VER: 27 - PYTHON_VER_DOT: '2.7' - # Python 3 - PYTHON3_VER: 38 - PYTHON3_VER_DOT: '3.8' - - # Other dependencies - # winpty - WINPTY_URL: https://github.com/rprichard/winpty/releases/download/0.4.3/winpty-0.4.3-msvc2015.zip - - # Escape sequences - COL_RED: "\x1b[31m" - COL_GREEN: "\x1b[32m" - COL_YELLOW: "\x1b[33m" - COL_RESET: "\x1b[m" - -jobs: - build: - runs-on: windows-latest - - strategy: - fail-fast: false - matrix: - toolchain: [msvc, mingw] - arch: [x64, x86] - features: [HUGE, NORMAL] - include: - - arch: x64 - vcarch: amd64 - warch: x64 - bits: 64 - msystem: MINGW64 - cygreg: registry - pyreg: "" - - arch: x86 - vcarch: x86 - warch: ia32 - bits: 32 - msystem: MINGW32 - cygreg: registry32 - pyreg: "-32" - exclude: - - toolchain: msvc - arch: x64 - features: NORMAL - - toolchain: mingw - arch: x86 - features: NORMAL - - steps: - - name: Initalize - id: init - shell: bash - run: | - git config --global core.autocrlf input - python_dir=$(cat "/proc/${{ matrix.cygreg }}/HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${PYTHON_VER_DOT}/InstallPath/@") - python3_dir=$(cat "/proc/${{ matrix.cygreg }}/HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${PYTHON3_VER_DOT}${{ matrix.pyreg }}/InstallPath/@") - echo "PYTHON_DIR=$python_dir" >> $GITHUB_ENV - echo "PYTHON3_DIR=$python3_dir" >> $GITHUB_ENV - - - uses: msys2/setup-msys2@v2 - if: matrix.toolchain == 'mingw' - with: - msystem: ${{ matrix.msystem }} - release: false - - - uses: actions/checkout@v2 - - - name: Create a list of download URLs - shell: cmd - run: | - type NUL > urls.txt - echo %LUA_RELEASE%>> urls.txt - echo %WINPTY_URL%>> urls.txt - - - name: Cache downloaded files - uses: actions/cache@v2 - with: - path: downloads - key: ${{ runner.os }}-${{ matrix.bits }}-${{ hashFiles('urls.txt') }} - - - name: Download dependencies - shell: cmd - run: | - path C:\Program Files\7-Zip;%path% - if not exist downloads mkdir downloads - - echo %COL_GREEN%Download Lua%COL_RESET% - call :downloadfile %LUA${{ matrix.bits }}_URL% downloads\lua.zip - 7z x downloads\lua.zip -o%LUA_DIR% > nul || exit 1 - - echo %COL_GREEN%Download winpty%COL_RESET% - call :downloadfile %WINPTY_URL% downloads\winpty.zip - 7z x -y downloads\winpty.zip -oD:\winpty > nul || exit 1 - copy /Y D:\winpty\${{ matrix.warch }}\bin\winpty.dll src\winpty${{ matrix.bits }}.dll - copy /Y D:\winpty\${{ matrix.warch }}\bin\winpty-agent.exe src\ - - goto :eof - - :downloadfile - :: call :downloadfile - if not exist %2 ( - curl -f -L %1 -o %2 - ) - if ERRORLEVEL 1 ( - rem Retry once. - curl -f -L %1 -o %2 || exit 1 - ) - goto :eof - - - name: Copy src directory to src2 - shell: cmd - run: | - xcopy src src2\ /E > nul - - - name: Build (MSVC) - if: matrix.toolchain == 'msvc' - shell: cmd - run: | - call "%VCVARSALL%" ${{ matrix.vcarch }} - cd src - :: Filter out the progress bar from the build log - sed -e "s/@<<$/@<< | sed -e 's#.*\\\\r.*##'/" Make_mvc.mak > Make_mvc2.mak - if "${{ matrix.features }}"=="HUGE" ( - nmake -nologo -f Make_mvc2.mak ^ - FEATURES=${{ matrix.features }} ^ - GUI=yes IME=yes ICONV=yes VIMDLL=yes ^ - DYNAMIC_LUA=yes LUA=%LUA_DIR% ^ - DYNAMIC_PYTHON=yes PYTHON=%PYTHON_DIR% ^ - DYNAMIC_PYTHON3=yes PYTHON3=%PYTHON3_DIR% - ) else ( - nmake -nologo -f Make_mvc2.mak ^ - FEATURES=${{ matrix.features }} ^ - GUI=yes IME=yes ICONV=yes VIMDLL=yes - ) - if not exist vim${{ matrix.bits }}.dll ( - echo %COL_RED%Build failure.%COL_RESET% - exit 1 - ) - - - name: Build (MinGW) - if: matrix.toolchain == 'mingw' - shell: msys2 {0} - run: | - cd src - if [ "${{ matrix.features }}" = "HUGE" ]; then - mingw32-make -f Make_ming.mak -j2 \ - FEATURES=${{ matrix.features }} \ - GUI=yes IME=yes ICONV=yes VIMDLL=yes \ - DYNAMIC_LUA=yes LUA=${LUA_DIR} \ - DYNAMIC_PYTHON=yes PYTHON=${PYTHON_DIR} \ - DYNAMIC_PYTHON3=yes PYTHON3=${PYTHON3_DIR} \ - STATIC_STDCPLUS=yes - else - mingw32-make -f Make_ming.mak -j2 \ - FEATURES=${{ matrix.features }} \ - GUI=yes IME=yes ICONV=yes VIMDLL=yes \ - STATIC_STDCPLUS=yes - fi - -# - name: Prepare Artifact -# shell: cmd -# run: | -# mkdir artifacts -# copy src\*vim.exe artifacts -# copy src\vim*.dll artifacts -# -# - name: Upload Artifact -# uses: actions/upload-artifact@v1 -# with: -# name: vim${{ matrix.bits }}-${{ matrix.toolchain }} -# path: ./artifacts - - - name: Test - shell: cmd - timeout-minutes: 20 - run: | - PATH %LUA_DIR%;C:\msys64\${{ matrix.msystem }}\bin;%PATH%;%PYTHON3_DIR% - call "%VCVARSALL%" ${{ matrix.vcarch }} - cd src - echo. - echo %COL_GREEN%vim version:%COL_RESET% - .\vim --version || exit 1 - - echo %COL_GREEN%Start testing vim in background.%COL_RESET% - start cmd /c "cd ..\src2\testdir & nmake -nologo -f Make_dos.mak VIMPROG=..\..\src\vim > nul & echo done>done.txt" - - echo %COL_GREEN%Test gvim:%COL_RESET% - cd testdir - nmake -nologo -f Make_dos.mak VIMPROG=..\gvim || exit 1 - cd .. - - echo %COL_GREEN%Wait for vim tests to finish.%COL_RESET% - cd ..\src2\testdir - :: Wait about 10 minutes. - for /L %%i in (1,1,60) do ( - if exist done.txt goto exitloop - timeout 10 > NUL 2>&1 - if ERRORLEVEL 1 ping -n 11 localhost > NUL - ) - set timeout=1 - :exitloop - - echo %COL_GREEN%Test results of vim:%COL_RESET% - if exist messages type messages - nmake -nologo -f Make_dos.mak report VIMPROG=..\..\src\vim || exit 1 - if "%timeout%"=="1" ( - echo %COL_RED%Timed out.%COL_RESET% - exit 1 - ) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..25ac92f5dc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,525 @@ +name: GitHub CI + +on: + push: + branches: ['**'] + pull_request: + +jobs: + linux: + runs-on: ubuntu-latest + + env: + CC: ${{ matrix.compiler }} + TEST: test + SRCDIR: ./src + LEAK_CFLAGS: -DEXITFREE + LOG_DIR: ${{ github.workspace }}/logs + TERM: xterm + DISPLAY: ':99' + + strategy: + fail-fast: false + matrix: + features: [tiny, small, normal, huge] + compiler: [clang, gcc] + extra: [none] + include: + - features: tiny + compiler: clang + extra: nogui + - features: tiny + compiler: gcc + extra: nogui + - features: normal + shadow: ./src/shadow + - features: huge + coverage: true + - features: huge + compiler: gcc + coverage: true + extra: testgui + - features: huge + compiler: clang + extra: asan + - features: huge + compiler: gcc + coverage: true + extra: unittests + - features: normal + compiler: gcc + extra: vimtags + + steps: + - uses: actions/checkout@v2 + + - name: Install packages + env: + DEBIAN_FRONTEND: noninteractive + run: | + sudo apt-get install -y \ + autoconf \ + lcov \ + gettext \ + libcanberra-dev \ + libperl-dev \ + python-dev \ + python3-dev \ + liblua5.3-dev \ + lua5.3 \ + ruby-dev \ + tcl-dev \ + cscope \ + libgtk2.0-dev \ + desktop-file-utils \ + libtool-bin + if [[ ${CC} = clang ]]; then + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - + sudo add-apt-repository -y "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-11 main" + sudo apt-get install -y clang-11 + sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-11 100 + sudo update-alternatives --set clang /usr/bin/clang-11 + sudo update-alternatives --install /usr/bin/llvm-cov llvm-cov /usr/bin/llvm-cov-11 100 + fi + + - name: Set up environment + run: | + mkdir -p "${LOG_DIR}" + mkdir -p "${HOME}/bin" + echo "${HOME}/bin" >> $GITHUB_PATH + ( + echo "LINUX_VERSION=$(uname -r)" + echo "NPROC=$(getconf _NPROCESSORS_ONLN)" + echo "SND_DUMMY_DIR=${HOME}/snd-dummy" + echo "TMPDIR=${{ runner.temp }}" + + case "${{ matrix.features }}" in + tiny|small) + echo "TEST=testtiny" + if ${{ contains(matrix.extra, 'nogui') }}; then + echo "CONFOPT=--disable-gui" + fi + ;; + normal) + ;; + huge) + echo "TEST=scripttests test_libvterm" + echo "CONFOPT=--enable-perlinterp --enable-pythoninterp --enable-python3interp --enable-rubyinterp --enable-luainterp --enable-tclinterp" + ;; + esac + + if ${{ matrix.coverage == true }}; then + echo "CFLAGS=--coverage -DUSE_GCOV_FLUSH" + echo "LDFLAGS=--coverage" + fi + if ${{ contains(matrix.extra, 'testgui') }}; then + echo "TEST=-C src testgui" + fi + if ${{ contains(matrix.extra, 'unittests') }}; then + echo "TEST=unittests" + fi + if ${{ contains(matrix.extra, 'asan') }}; then + echo "SANITIZER_CFLAGS=-g -O1 -DABORT_ON_INTERNAL_ERROR -DEXITFREE -fsanitize-recover=all -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer" + echo "ASAN_OPTIONS=print_stacktrace=1 log_path=${LOG_DIR}/asan" + echo "UBSAN_OPTIONS=print_stacktrace=1 log_path=${LOG_DIR}/ubsan" + echo "LSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/src/testdir/lsan-suppress.txt" + fi + if ${{ contains(matrix.extra, 'vimtags') }}; then + echo "TEST=-C runtime/doc vimtags VIMEXE=../../${SRCDIR}/vim" + fi + ) >> $GITHUB_ENV + + - name: Set up system + run: | + if [[ ${CC} = clang ]]; then + # Use llvm-cov instead of gcov when compiler is clang. + ln -fs /usr/bin/llvm-cov ${HOME}/bin/gcov + fi + # Setup lua5.3 manually since its package doesn't provide alternative. + # https://bugs.launchpad.net/ubuntu/+source/lua5.3/+bug/1707212 + if [[ ${CONFOPT} =~ luainterp ]]; then + sudo update-alternatives --install /usr/bin/lua lua /usr/bin/lua5.3 10 + fi + sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=0 + sudo usermod -a -G audio "${USER}" + sudo bash ci/setup-xvfb.sh + + - name: Cache snd-dummy + uses: actions/cache@v2 + with: + path: ${{ env.SND_DUMMY_DIR }} + key: linux-${{ env.LINUX_VERSION }}-snd-dummy + + - name: Set up snd-dummy + run: | + if [[ ! -e ${SND_DUMMY_DIR}/snd-dummy.ko ]]; then + bash ci/build-snd-dummy.sh + fi + cd "${SND_DUMMY_DIR}" + sudo insmod soundcore.ko + sudo insmod snd.ko + sudo insmod snd-pcm.ko + sudo insmod snd-dummy.ko + + - name: Check autoconf + if: contains(matrix.extra, 'unittests') + run: | + make -C src autoconf + + - name: Set up shadow dir + if: matrix.shadow + run: | + make -C src shadow + echo "SRCDIR=${{ matrix.shadow }}" >> $GITHUB_ENV + echo "SHADOWOPT=-C ${{ matrix.shadow }}" >> $GITHUB_ENV + + - name: Configure + run: | + ./configure --with-features=${{ matrix.features }} ${CONFOPT} --enable-fail-if-missing + # Append various warning flags to CFLAGS. + # BSD sed needs backup extension specified. + sed -i.bak -f ci/config.mk.sed ${SRCDIR}/auto/config.mk + sed -i.bak -f ci/config.mk.${CC}.sed ${SRCDIR}/auto/config.mk + + - name: Build + if: (!contains(matrix.extra, 'unittests')) + run: | + make ${SHADOWOPT} -j${NPROC} + + - name: Check version + if: (!contains(matrix.extra, 'unittests')) + run: | + "${SRCDIR}"/vim --version + "${SRCDIR}"/vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-1.vim -c quit + "${SRCDIR}"/vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-2.vim -c quit + + - name: Test + timeout-minutes: 20 + run: | + do_test() { sg audio "sg $(id -gn) '$*'"; } + do_test make ${SHADOWOPT} ${TEST} + + - name: Coveralls + if: matrix.coverage && success() && github.event_name != 'pull_request' + env: + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} + COVERALLS_PARALLEL: true + TRAVIS_JOB_ID: ${{ github.run_id }} + run: | + sudo apt-get install -y python3-setuptools python3-wheel + # needed for https support for coveralls building cffi only works with gcc, not with clang + CC=gcc pip3 install --user cpp-coveralls pyopenssl ndg-httpsclient pyasn1 + ~/.local/bin/coveralls -b "${SRCDIR}" -x .xs -e "${SRCDIR}"/if_perl.c -e "${SRCDIR}"/xxd -e "${SRCDIR}"/libvterm --encodings utf-8 + + - name: Codecov + if: matrix.coverage && success() + uses: codecov/codecov-action@v1 + with: + flags: ${{ matrix.features }}-${{ matrix.compiler }}-${{ matrix.extra }} + fail_ci_if_error: true + working-directory: ${{ env.SRCDIR }} + + - name: ASan logs + if: contains(matrix.extra, 'asan') && !cancelled() + run: | + for f in $(grep -lR '#[[:digit:]]* *0x[[:digit:]a-fA-F]*' "${LOG_DIR}"); do + asan_symbolize-11 -l "$f" + false # in order to fail a job + done + + coveralls: + runs-on: ubuntu-latest + + needs: linux + if: always() && github.event_name != 'pull_request' + + steps: + - name: Parallel finished + env: + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} + run: | + curl -k "https://coveralls.io/webhook?repo_token=${COVERALLS_REPO_TOKEN}" -d "payload[build_num]=${GITHUB_RUN_ID}&payload[status]=done" + + macos: + runs-on: macos-latest + + env: + CC: ${{ matrix.compiler }} + TEST: test + SRCDIR: ./src + LEAK_CFLAGS: -DEXITFREE + TERM: xterm + + strategy: + fail-fast: false + matrix: + features: [tiny, huge] + compiler: [clang, gcc] + + steps: + - uses: actions/checkout@v2 + + - name: Install packages + env: + HOMEBREW_NO_AUTO_UPDATE: 1 + run: | + brew install lua + echo "LUA_PREFIX=/usr/local" >> $GITHUB_ENV + + - name: Set up environment + run: | + ( + echo "NPROC=$(getconf _NPROCESSORS_ONLN)" + case "${{ matrix.features }}" in + tiny) + echo "TEST=testtiny" + echo "CONFOPT=--disable-gui" + ;; + huge) + echo "CONFOPT=--enable-perlinterp --enable-python3interp --enable-rubyinterp --enable-luainterp --enable-tclinterp" + ;; + esac + ) >> $GITHUB_ENV + + - name: Configure + run: | + ./configure --with-features=${{ matrix.features }} ${CONFOPT} --enable-fail-if-missing + # Append various warning flags to CFLAGS. + # BSD sed needs backup extension specified. + sed -i.bak -f ci/config.mk.sed ${SRCDIR}/auto/config.mk + # On macOS, the entity of gcc is clang. + sed -i.bak -f ci/config.mk.clang.sed ${SRCDIR}/auto/config.mk + + - name: Build + run: | + make -j${NPROC} + + - name: Check version + run: | + "${SRCDIR}"/vim --version + "${SRCDIR}"/vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-1.vim -c quit + "${SRCDIR}"/vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-2.vim -c quit + + - name: Test + timeout-minutes: 20 + run: | + make ${TEST} + + windows: + runs-on: windows-latest + + env: + VCVARSALL: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat + # Interfaces + # Lua + LUA_VER: 54 + LUA_VER_DOT: '5.4' + LUA_RELEASE: 5.4.0 + LUA32_URL: https://downloads.sourceforge.net/luabinaries/lua-%LUA_RELEASE%_Win32_dllw6_lib.zip + LUA64_URL: https://downloads.sourceforge.net/luabinaries/lua-%LUA_RELEASE%_Win64_dllw6_lib.zip + LUA_DIR: D:\Lua + # Python 2 + PYTHON_VER: 27 + PYTHON_VER_DOT: '2.7' + # Python 3 + PYTHON3_VER: 38 + PYTHON3_VER_DOT: '3.8' + # Other dependencies + # winpty + WINPTY_URL: https://github.com/rprichard/winpty/releases/download/0.4.3/winpty-0.4.3-msvc2015.zip + # Escape sequences + COL_RED: "\x1b[31m" + COL_GREEN: "\x1b[32m" + COL_YELLOW: "\x1b[33m" + COL_RESET: "\x1b[m" + + strategy: + fail-fast: false + matrix: + toolchain: [msvc, mingw] + arch: [x64, x86] + features: [HUGE, NORMAL] + include: + - arch: x64 + vcarch: amd64 + warch: x64 + bits: 64 + msystem: MINGW64 + cygreg: registry + pyreg: "" + - arch: x86 + vcarch: x86 + warch: ia32 + bits: 32 + msystem: MINGW32 + cygreg: registry32 + pyreg: "-32" + exclude: + - toolchain: msvc + arch: x64 + features: NORMAL + - toolchain: mingw + arch: x86 + features: NORMAL + + steps: + - name: Initalize + id: init + shell: bash + run: | + git config --global core.autocrlf input + python_dir=$(cat "/proc/${{ matrix.cygreg }}/HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${PYTHON_VER_DOT}/InstallPath/@") + python3_dir=$(cat "/proc/${{ matrix.cygreg }}/HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${PYTHON3_VER_DOT}${{ matrix.pyreg }}/InstallPath/@") + echo "PYTHON_DIR=$python_dir" >> $GITHUB_ENV + echo "PYTHON3_DIR=$python3_dir" >> $GITHUB_ENV + + - uses: msys2/setup-msys2@v2 + if: matrix.toolchain == 'mingw' + with: + msystem: ${{ matrix.msystem }} + release: false + + - uses: actions/checkout@v2 + + - name: Create a list of download URLs + shell: cmd + run: | + type NUL > urls.txt + echo %LUA_RELEASE%>> urls.txt + echo %WINPTY_URL%>> urls.txt + + - name: Cache downloaded files + uses: actions/cache@v2 + with: + path: downloads + key: ${{ runner.os }}-${{ matrix.bits }}-${{ hashFiles('urls.txt') }} + + - name: Download dependencies + shell: cmd + run: | + path C:\Program Files\7-Zip;%path% + if not exist downloads mkdir downloads + + echo %COL_GREEN%Download Lua%COL_RESET% + call :downloadfile %LUA${{ matrix.bits }}_URL% downloads\lua.zip + 7z x downloads\lua.zip -o%LUA_DIR% > nul || exit 1 + + echo %COL_GREEN%Download winpty%COL_RESET% + call :downloadfile %WINPTY_URL% downloads\winpty.zip + 7z x -y downloads\winpty.zip -oD:\winpty > nul || exit 1 + copy /Y D:\winpty\${{ matrix.warch }}\bin\winpty.dll src\winpty${{ matrix.bits }}.dll + copy /Y D:\winpty\${{ matrix.warch }}\bin\winpty-agent.exe src\ + + goto :eof + + :downloadfile + :: call :downloadfile + if not exist %2 ( + curl -f -L %1 -o %2 + ) + if ERRORLEVEL 1 ( + rem Retry once. + curl -f -L %1 -o %2 || exit 1 + ) + goto :eof + + - name: Copy src directory to src2 + shell: cmd + run: | + xcopy src src2\ /E > nul + + - name: Build (MSVC) + if: matrix.toolchain == 'msvc' + shell: cmd + run: | + call "%VCVARSALL%" ${{ matrix.vcarch }} + cd src + :: Filter out the progress bar from the build log + sed -e "s/@<<$/@<< | sed -e 's#.*\\\\r.*##'/" Make_mvc.mak > Make_mvc2.mak + if "${{ matrix.features }}"=="HUGE" ( + nmake -nologo -f Make_mvc2.mak ^ + FEATURES=${{ matrix.features }} ^ + GUI=yes IME=yes ICONV=yes VIMDLL=yes ^ + DYNAMIC_LUA=yes LUA=%LUA_DIR% ^ + DYNAMIC_PYTHON=yes PYTHON=%PYTHON_DIR% ^ + DYNAMIC_PYTHON3=yes PYTHON3=%PYTHON3_DIR% + ) else ( + nmake -nologo -f Make_mvc2.mak ^ + FEATURES=${{ matrix.features }} ^ + GUI=yes IME=yes ICONV=yes VIMDLL=yes + ) + if not exist vim${{ matrix.bits }}.dll ( + echo %COL_RED%Build failure.%COL_RESET% + exit 1 + ) + + - name: Build (MinGW) + if: matrix.toolchain == 'mingw' + shell: msys2 {0} + run: | + cd src + if [ "${{ matrix.features }}" = "HUGE" ]; then + mingw32-make -f Make_ming.mak -j2 \ + FEATURES=${{ matrix.features }} \ + GUI=yes IME=yes ICONV=yes VIMDLL=yes \ + DYNAMIC_LUA=yes LUA=${LUA_DIR} \ + DYNAMIC_PYTHON=yes PYTHON=${PYTHON_DIR} \ + DYNAMIC_PYTHON3=yes PYTHON3=${PYTHON3_DIR} \ + STATIC_STDCPLUS=yes + else + mingw32-make -f Make_ming.mak -j2 \ + FEATURES=${{ matrix.features }} \ + GUI=yes IME=yes ICONV=yes VIMDLL=yes \ + STATIC_STDCPLUS=yes + fi + + #- name: Prepare Artifact + # shell: cmd + # run: | + # mkdir artifacts + # copy src\*vim.exe artifacts + # copy src\vim*.dll artifacts + # + #- name: Upload Artifact + # uses: actions/upload-artifact@v1 + # with: + # name: vim${{ matrix.bits }}-${{ matrix.toolchain }} + # path: ./artifacts + + - name: Test + shell: cmd + timeout-minutes: 20 + run: | + PATH %LUA_DIR%;C:\msys64\${{ matrix.msystem }}\bin;%PATH%;%PYTHON3_DIR% + call "%VCVARSALL%" ${{ matrix.vcarch }} + cd src + echo. + echo %COL_GREEN%vim version:%COL_RESET% + .\vim --version || exit 1 + + echo %COL_GREEN%Start testing vim in background.%COL_RESET% + start cmd /c "cd ..\src2\testdir & nmake -nologo -f Make_dos.mak VIMPROG=..\..\src\vim > nul & echo done>done.txt" + + echo %COL_GREEN%Test gvim:%COL_RESET% + cd testdir + nmake -nologo -f Make_dos.mak VIMPROG=..\gvim || exit 1 + cd .. + + echo %COL_GREEN%Wait for vim tests to finish.%COL_RESET% + cd ..\src2\testdir + :: Wait about 10 minutes. + for /L %%i in (1,1,60) do ( + if exist done.txt goto exitloop + timeout 10 > NUL 2>&1 + if ERRORLEVEL 1 ping -n 11 localhost > NUL + ) + set timeout=1 + :exitloop + + echo %COL_GREEN%Test results of vim:%COL_RESET% + if exist messages type messages + nmake -nologo -f Make_dos.mak report VIMPROG=..\..\src\vim || exit 1 + if "%timeout%"=="1" ( + echo %COL_RED%Timed out.%COL_RESET% + exit 1 + ) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e920890215..ef98000f89 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -31,15 +31,6 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v2 - with: - # We must fetch at least the immediate parents so that if this is - # a pull request then we can checkout the head. - fetch-depth: 2 - - # If this run was triggered by a pull request event, then checkout - # the head of the pull request instead of the merge commit. - - run: git checkout HEAD^2 - if: ${{ github.event_name == 'pull_request' }} # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/README_vim.md b/README_vim.md index 4e3d8433c3..9f85416070 100644 --- a/README_vim.md +++ b/README_vim.md @@ -1,5 +1,6 @@ ![Vim Logo](https://github.com/vim/vim/blob/master/runtime/vimlogo.gif) +[![Github Build status](https://github.com/vim/vim/workflows/GitHub%20CI/badge.svg)](https://github.com/vim/vim/actions?query=workflow%3A%22GitHub+CI%22) [![Travis Build Status](https://travis-ci.org/vim/vim.svg?branch=master)](https://travis-ci.org/vim/vim) [![Appveyor Build status](https://ci.appveyor.com/api/projects/status/o2qht2kjm02sgghk?svg=true)](https://ci.appveyor.com/project/chrisbra/vim) [![Cirrus Build Status](https://api.cirrus-ci.com/github/vim/vim.svg)](https://cirrus-ci.com/github/vim/vim) @@ -8,6 +9,7 @@ [![Language Grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/vim/vim.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/vim/vim/context:cpp) [![Debian CI](https://badges.debian.net/badges/debian/testing/vim/version.svg)](https://buildd.debian.org/vim) [![Packages](https://repology.org/badge/tiny-repos/vim.svg)](https://repology.org/metapackage/vim) + For translations of this README see the end. @@ -26,8 +28,8 @@ All commands are given with normal keyboard characters, so those who can type with ten fingers can work very fast. Additionally, function keys can be mapped to commands by the user, and the mouse can be used. -Vim runs under MS-Windows (XP, Vista, 7, 8, 10), macOS, VMS and almost all -flavours of UNIX. Porting to other systems should not be very difficult. +Vim runs under MS-Windows (XP, Vista, 7, 8, 10), macOS, Haiku, VMS and almost +all flavours of UNIX. Porting to other systems should not be very difficult. Older versions of Vim run on MS-DOS, MS-Windows 95/98/Me/NT/2000, Amiga DOS, Atari MiNT, BeOS, RISC OS and OS/2. These are no longer maintained. @@ -72,6 +74,7 @@ archive): README_unix.txt Unix README_dos.txt MS-DOS and MS-Windows README_mac.txt Macintosh + README_haiku.txt Haiku README_vms.txt VMS There are other `README_*.txt` files, depending on the distribution you used. diff --git a/ci/build-snd-dummy.sh b/ci/build-snd-dummy.sh new file mode 100644 index 0000000000..a2380b4b16 --- /dev/null +++ b/ci/build-snd-dummy.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -eu + +LINUX_VERSION=$(uname -r | cut -d. -f1-2) +LINUX_ARCHIVE_FILE=v${LINUX_VERSION}.tar.gz +LINUX_SOURCE_DIR=linux-${LINUX_VERSION} + +mkdir -p "${TMPDIR}" +cd "${TMPDIR}" + +wget -q "https://github.com/torvalds/linux/archive/${LINUX_ARCHIVE_FILE}" + +tar -xf "${LINUX_ARCHIVE_FILE}" "${LINUX_SOURCE_DIR}/sound" +cd "${LINUX_SOURCE_DIR}/sound" + +CC=gcc make -C "/lib/modules/$(uname -r)/build" M="${PWD}" CONFIG_SOUND=m CONFIG_SND=m CONFIG_SND_PCM=m CONFIG_SND_DUMMY=m modules + +mkdir -p "${SND_DUMMY_DIR}" +cp soundcore.ko core/snd.ko core/snd-pcm.ko drivers/snd-dummy.ko "${SND_DUMMY_DIR}" diff --git a/ci/setup-xvfb.sh b/ci/setup-xvfb.sh new file mode 100644 index 0000000000..cfc0f97bba --- /dev/null +++ b/ci/setup-xvfb.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -e + +apt-get install -y xvfb + +cat </etc/systemd/system/xvfb.service +[Unit] +Description=X Virtual Frame Buffer Service +After=network.target +[Service] +ExecStart=/usr/bin/Xvfb :99 -screen 0 1024x768x24 +[Install] +WantedBy=multi-user.target +EOT + +systemctl enable xvfb.service +systemctl start xvfb.service diff --git a/src/auto/configure b/src/auto/configure index 0c95f2d228..d220ffd6e4 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -5544,7 +5544,7 @@ $as_echo "no" >&6; } inc_path="$vi_cv_path_lua_pfx/include" for dir in "$inc_path"/moonjit-[0-9]* ; do if test -d "$dir" ; then - lua_suf=`basename '$dir'` + lua_suf=`basename "$dir"` lua_suf="/$lua_suf" break fi diff --git a/src/bufwrite.c b/src/bufwrite.c index 8d21402794..288b9c4185 100644 --- a/src/bufwrite.c +++ b/src/bufwrite.c @@ -2138,7 +2138,7 @@ restore_backup: if (!checking_conversion) { #if defined(UNIX) && defined(HAVE_FSYNC) - // On many journalling file systems there is a bug that causes both the + // On many journaling file systems there is a bug that causes both the // original and the backup file to be lost when halting the system // right after writing the file. That's because only the meta-data is // journalled. Syncing the file slows down the system, but assures it diff --git a/src/cindent.c b/src/cindent.c index aeecc4b95c..b2fac1a9fb 100644 --- a/src/cindent.c +++ b/src/cindent.c @@ -2121,7 +2121,7 @@ get_c_indent(void) } // #defines and so on go at the left when included in 'cinkeys', - // exluding pragmas when customized in 'cinoptions' + // excluding pragmas when customized in 'cinoptions' if (*theline == '#' && (*linecopy == '#' || in_cinkeys('#', ' ', TRUE))) { char_u *directive = skipwhite(theline + 1); diff --git a/src/cmdexpand.c b/src/cmdexpand.c index 0144b1988b..82d875f814 100644 --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -1049,7 +1049,7 @@ set_one_cmd_context( ++p; } - // If the cursor is touching the command, and it ends in an alpha-numeric + // If the cursor is touching the command, and it ends in an alphanumeric // character, complete the command name. if (*p == NUL && ASCII_ISALNUM(p[-1])) return NULL; diff --git a/src/configure.ac b/src/configure.ac index 4cd7ca1925..54655da169 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -671,7 +671,7 @@ if test "$enable_luainterp" = "yes" -o "$enable_luainterp" = "dynamic"; then inc_path="$vi_cv_path_lua_pfx/include" for dir in "$inc_path"/moonjit-[[0-9]]* ; do if test -d "$dir" ; then - lua_suf=`basename '$dir'` + lua_suf=`basename "$dir"` lua_suf="/$lua_suf" break fi diff --git a/src/eval.c b/src/eval.c index 6ce2ebf68d..06c6adaf85 100644 --- a/src/eval.c +++ b/src/eval.c @@ -4631,7 +4631,7 @@ set_ref_in_item( * "numbuf" is used for a number. * When "copyID" is not NULL replace recursive lists and dicts with "...". * When both "echo_style" and "composite_val" are FALSE, put quotes around - * stings as "string()", otherwise does not put quotes around strings, as + * strings as "string()", otherwise does not put quotes around strings, as * ":echo" displays values. * When "restore_copyID" is FALSE, repeated items in dictionaries and lists * are replaced with "...". diff --git a/src/evalvars.c b/src/evalvars.c index 302e759a91..dc25ed39ca 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -1665,10 +1665,20 @@ do_unlet(char_u *name, int forceit) dict_T *d; dictitem_T *di; + // can't :unlet a script variable in Vim9 script if (in_vim9script() && check_vim9_unlet(name) == FAIL) return FAIL; ht = find_var_ht(name, &varname); + + // can't :unlet a script variable in Vim9 script from a function + if (ht == get_script_local_ht() + && SCRIPT_ID_VALID(current_sctx.sc_sid) + && SCRIPT_ITEM(current_sctx.sc_sid)->sn_version + == SCRIPT_VERSION_VIM9 + && check_vim9_unlet(name) == FAIL) + return FAIL; + if (ht != NULL && *varname != NUL) { d = get_current_funccal_dict(ht); diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 44d8cd8500..e7575f9501 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -2660,7 +2660,7 @@ do_ecmd( if (tlnum <= 0) tlnum = 1L; } - // Add BLN_NOCURWIN to avoid a new wininfo items are assocated + // Add BLN_NOCURWIN to avoid a new wininfo items are associated // with the current window. newbuf = buflist_new(ffname, sfname, tlnum, BLN_LISTED | BLN_NOCURWIN); diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 44c9c1e7c4..9335cb423d 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3526,7 +3526,7 @@ find_ex_command( ++p; p = find_ucmd(eap, p, full, NULL, NULL); } - if (p == eap->cmd) + if (p == NULL || p == eap->cmd) eap->cmdidx = CMD_SIZE; } diff --git a/src/feature.h b/src/feature.h index 92a57082d5..982502232e 100644 --- a/src/feature.h +++ b/src/feature.h @@ -949,7 +949,7 @@ * +mouse_sgr Unix only: Include code for for SGR-styled mouse. * +mouse_sysmouse Unix only: Include code for FreeBSD and DragonFly * console mouse handling. - * +mouse_urxvt Unix only: Include code for for urxvt mosue handling. + * +mouse_urxvt Unix only: Include code for for urxvt mouse handling. * +mouse Any mouse support (any of the above enabled). * Always included, since either FEAT_MOUSE_XTERM or * DOS_MOUSE is defined. diff --git a/src/getchar.c b/src/getchar.c index 10f4534499..fa6c10c321 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -2277,7 +2277,7 @@ at_ctrl_x_key(void) } /* - * Check if typebuf.tb_buf[] contains a modifer plus key that can be changed + * Check if typebuf.tb_buf[] contains a modifier plus key that can be changed * into just a key, apply that. * Check from typebuf.tb_buf[typebuf.tb_off] to typebuf.tb_buf[typebuf.tb_off * + "max_offset"]. diff --git a/src/gui_haiku.cc b/src/gui_haiku.cc index c9294093c7..a1c7e3eb1b 100644 --- a/src/gui_haiku.cc +++ b/src/gui_haiku.cc @@ -3411,7 +3411,7 @@ gui_mch_exit(int vim_exitcode) thread_id tid = gui.vimWindow->Thread(); gui.vimWindow->Lock(); gui.vimWindow->Quit(); - // Wait until it is truely gone + // Wait until it is truly gone int32 exitcode; wait_for_thread(tid, &exitcode); } diff --git a/src/gui_xmdlg.c b/src/gui_xmdlg.c index 04996efece..ad3146a122 100644 --- a/src/gui_xmdlg.c +++ b/src/gui_xmdlg.c @@ -497,7 +497,7 @@ fill_lists(enum ListSpecifier fix, SharedFontSelData *data) } /* - * Now loop trough the remaining lists and set them up. + * Now loop through the remaining lists and set them up. */ for (idx = (int)NAME; idx < (int)NONE; ++idx) { diff --git a/src/help.c b/src/help.c index d6bdcbb70a..ee6ff18512 100644 --- a/src/help.c +++ b/src/help.c @@ -325,7 +325,7 @@ find_help_tags( char_u *s, *d; int i; // Specific tags that either have a specific replacement or won't go - // throught the generic rules. + // through the generic rules. static char *(except_tbl[][2]) = { {"*", "star"}, {"g*", "gstar"}, @@ -647,6 +647,8 @@ prepare_help_buffer(void) // Always set these options after jumping to a help tag, because the // user may have an autocommand that gets in the way. + // When adding an option here, also update the help file helphelp.txt. + // Accept all ASCII chars for keywords, except ' ', '*', '"', '|', and // latin1 word characters (for translated help files). // Only set it when needed, buf_init_chartab() is some work. diff --git a/src/if_ole.cpp b/src/if_ole.cpp index e415a1924d..f7108e4a74 100644 --- a/src/if_ole.cpp +++ b/src/if_ole.cpp @@ -635,7 +635,7 @@ static void GUIDtochar(const GUID &guid, char *GUID, int length) LPOLESTR wGUID = NULL; StringFromCLSID(guid, &wGUID); - // Covert from wide characters to non-wide + // Convert from wide characters to non-wide wcstombs(GUID, wGUID, length); // Free memory diff --git a/src/insexpand.c b/src/insexpand.c index f0773e9d0a..33787dfb49 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -3633,7 +3633,7 @@ ins_complete(int c, int enable_pum) // line (probably) wrapped, set compl_startpos to the // first non_blank in the line, if it is not a wordchar // include it to get a better pattern, but then we don't - // want the "\\<" prefix, check it bellow + // want the "\\<" prefix, check it below compl_col = (colnr_T)getwhitecols(line); compl_startpos.col = compl_col; compl_startpos.lnum = curwin->w_cursor.lnum; diff --git a/src/list.c b/src/list.c index 6285e01d50..1c41f07031 100644 --- a/src/list.c +++ b/src/list.c @@ -2693,7 +2693,7 @@ f_reverse(typval_T *argvars, typval_T *rettv) } /* - * "reduce(list, { accumlator, element -> value } [, initial])" function + * "reduce(list, { accumulator, element -> value } [, initial])" function */ void f_reduce(typval_T *argvars, typval_T *rettv) diff --git a/src/map.c b/src/map.c index fe1e5fe05d..3bcee87094 100644 --- a/src/map.c +++ b/src/map.c @@ -2221,7 +2221,7 @@ get_maparg(typval_T *argvars, typval_T *rettv, int exact) if (did_simplify) { // When the lhs is being simplified the not-simplified keys are - // preferred for priting, like in do_map(). + // preferred for printing, like in do_map(). // The "rhs" and "buffer_local" values are not expected to change. mp_simplified = mp; (void)replace_termcodes(keys, &alt_keys_buf, diff --git a/src/memline.c b/src/memline.c index 19b87d7ee9..4137a66ad8 100644 --- a/src/memline.c +++ b/src/memline.c @@ -5562,7 +5562,7 @@ ml_updatechunk( && buf->b_ml.ml_line_count - line <= 1) { /* - * We are in the last chunk and it is cheap to crate a new one + * We are in the last chunk and it is cheap to create a new one * after this. Do it now to avoid the loop above later on */ curchnk = buf->b_ml.ml_chunksize + curix + 1; diff --git a/src/move.c b/src/move.c index cd903793e5..69091fd3da 100644 --- a/src/move.c +++ b/src/move.c @@ -1247,7 +1247,7 @@ textpos2screenpos( // character is left or right of the window row = scol = ccol = ecol = 0; } - *rowp = wp->w_winrow + row + rowoff; + *rowp = W_WINROW(wp) + row + rowoff; *scolp = scol + coloff; *ccolp = ccol + coloff; *ecolp = ecol + coloff; diff --git a/src/normal.c b/src/normal.c index 72bf18673e..69f8b75f09 100644 --- a/src/normal.c +++ b/src/normal.c @@ -5384,7 +5384,7 @@ v_visop(cmdarg_T *cap) nv_subst(cmdarg_T *cap) { #ifdef FEAT_TERMINAL - // When showing output of term_dumpdiff() swap the top and botom. + // When showing output of term_dumpdiff() swap the top and bottom. if (term_swap_diff() == OK) return; #endif diff --git a/src/os_win32.c b/src/os_win32.c index 2f9ecdc9ea..972f10da5c 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -7113,13 +7113,12 @@ mch_fopen(const char *name, const char *mode) /* * SUB STREAM (aka info stream) handling: * - * NTFS can have sub streams for each file. Normal contents of file is - * stored in the main stream, and extra contents (author information and - * title and so on) can be stored in sub stream. After Windows 2000, user - * can access and store those informations in sub streams via explorer's - * property menuitem in right click menu. Those informations in sub streams - * were lost when copying only the main stream. So we have to copy sub - * streams. + * NTFS can have sub streams for each file. The normal contents of a file is + * stored in the main stream, and extra contents (author information, title and + * so on) can be stored in a sub stream. After Windows 2000, the user can + * access and store this information in sub streams via an explorer's property + * menu item in the right click menu. This information in sub streams was lost + * when copying only the main stream. Therefore we have to copy sub streams. * * Incomplete explanation: * http://msdn.microsoft.com/library/en-us/dnw2k/html/ntfs5.asp diff --git a/src/quickfix.c b/src/quickfix.c index d7a163dfff..89ca2d31eb 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -4431,21 +4431,26 @@ qf_process_qftf_option(void) } /* - * Update the w:quickfix_title variable in the quickfix/location list window + * Update the w:quickfix_title variable in the quickfix/location list window in + * all the tab pages. */ static void qf_update_win_titlevar(qf_info_T *qi) { + qf_list_T *qfl = qf_get_curlist(qi); + tabpage_T *tp; win_T *win; - win_T *curwin_save; + win_T *save_curwin = curwin; - if ((win = qf_find_win(qi)) != NULL) + FOR_ALL_TAB_WINDOWS(tp, win) { - curwin_save = curwin; - curwin = win; - qf_set_title_var(qf_get_curlist(qi)); - curwin = curwin_save; + if (is_qf_win(win, qi)) + { + curwin = win; + qf_set_title_var(qfl); + } } + curwin = save_curwin; } /* diff --git a/src/search.c b/src/search.c index 6a7992110d..a9d637f9ba 100644 --- a/src/search.c +++ b/src/search.c @@ -3762,7 +3762,7 @@ search_line: // we read a line, set "already" to check this "line" later // if depth >= 0 we'll increase files[depth].lnum far - // bellow -- Acevedo + // below -- Acevedo already = aux = p = skipwhite(line); p = find_word_start(p); p = find_word_end(p); diff --git a/src/term.c b/src/term.c index f2ad99e4ff..e10413d59a 100644 --- a/src/term.c +++ b/src/term.c @@ -3750,7 +3750,7 @@ check_terminal_behavior(void) #endif LOG_TR(("Sending xterm compatibility test sequence.")); // Do this in the third row. Second row is used by ambiguous - // chararacter width check. + // character width check. term_windgoto(2, 0); // send the test DCS string. out_str((char_u *)"\033Pzz\033\\"); @@ -4537,7 +4537,7 @@ handle_u7_response(int *arg, char_u *tp UNUSED, int csi_len UNUSED) /* * Handle a response to T_CRV: {lead}{first}{x};{vers};{y}c - * Xterm and alikes use '>' for {first}. + * Xterm and alike use '>' for {first}. * Rxvt sends "{lead}?1;2c". */ static void diff --git a/src/testdir/test_arglist.vim b/src/testdir/test_arglist.vim index f45a0d4d0b..d6c369f0b0 100644 --- a/src/testdir/test_arglist.vim +++ b/src/testdir/test_arglist.vim @@ -524,7 +524,7 @@ func Test_argdo() bwipe Xa.c Xb.c Xc.c endfunc -" Test for quiting Vim with unedited files in the argument list +" Test for quitting Vim with unedited files in the argument list func Test_quit_with_arglist() CheckRunVimInTerminal let buf = RunVimInTerminal('', {'rows': 6}) diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index ff78f82689..b2490d0889 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -2324,7 +2324,7 @@ func Test_autocmd_SafeState() call writefile(lines, 'XSafeState') let buf = RunVimInTerminal('-S XSafeState', #{rows: 6}) - " Sometimes we loop to handle a K_IGNORE, SafeState may be trigered once or + " Sometimes we loop to handle a K_IGNORE, SafeState may be triggered once or " more often. call term_sendkeys(buf, ":echo g:safe\") call WaitForAssert({-> assert_match('^\d ', term_getline(buf, 6))}, 1000) diff --git a/src/testdir/test_cursor_func.vim b/src/testdir/test_cursor_func.vim index bfb908d38c..d914067b26 100644 --- a/src/testdir/test_cursor_func.vim +++ b/src/testdir/test_cursor_func.vim @@ -101,6 +101,11 @@ func Test_screenpos() close call assert_equal({}, screenpos(999, 1, 1)) bwipe! + + call assert_equal({'col': 1, 'row': 1, 'endcol': 1, 'curscol': 1}, screenpos(win_getid(), 1, 1)) + nmenu WinBar.TEST : + call assert_equal({'col': 1, 'row': 2, 'endcol': 1, 'curscol': 1}, screenpos(win_getid(), 1, 1)) + nunmenu WinBar.TEST endfunc func Test_screenpos_number() diff --git a/src/testdir/test_debugger.vim b/src/testdir/test_debugger.vim index b3636408d8..029b9dbc9c 100644 --- a/src/testdir/test_debugger.vim +++ b/src/testdir/test_debugger.vim @@ -974,7 +974,7 @@ func Test_debug_backtrace_level() \ 'line 1: let s:file1_var = ''file1''' \ ], #{msec: 5000}) - " step throught the initial declarations + " step through the initial declarations call RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] ) call RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] ) call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] ) diff --git a/src/testdir/test_increment.vim b/src/testdir/test_increment.vim index abd85bed8a..1a631ec00f 100644 --- a/src/testdir/test_increment.vim +++ b/src/testdir/test_increment.vim @@ -284,7 +284,7 @@ endfunc " 1 " 1 " 1 -" Expexted: +" Expected: " 1) g Ctrl-A on block selected indented lines " 2 " 1 diff --git a/src/testdir/test_menu.vim b/src/testdir/test_menu.vim index a7da1bf926..89e78159ea 100644 --- a/src/testdir/test_menu.vim +++ b/src/testdir/test_menu.vim @@ -434,7 +434,7 @@ func Test_menu_special() nunmenu Test.Sign endfunc -" Test for "icon=filname" in a toolbar +" Test for "icon=filename" in a toolbar func Test_menu_icon() CheckFeature toolbar nmenu icon=myicon.xpm Toolbar.Foo :echo "Foo" diff --git a/src/testdir/test_netbeans.vim b/src/testdir/test_netbeans.vim index d56b4683fb..d792ab97c6 100644 --- a/src/testdir/test_netbeans.vim +++ b/src/testdir/test_netbeans.vim @@ -839,7 +839,7 @@ func Test_nb_file_auth() call s:run_server('Nb_file_auth') endfunc -" Test for quiting Vim with an open netbeans connection +" Test for quitting Vim with an open netbeans connection func Nb_quit_with_conn(port) call delete("Xnetbeans") call writefile([], "Xnetbeans") diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim index cf9536f5e1..b8641fe7d2 100644 --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -2673,13 +2673,14 @@ func Test_popupwin_terminal_buffer() let termbuf = term_start(&shell, #{hidden: 1}) let winid = popup_create(termbuf, #{minwidth: 40, minheight: 10, border: []}) - " Wait for shell to start and show a prompt + " Wait for shell to start call WaitForAssert({-> assert_equal("run", job_status(term_getjob(termbuf)))}) - sleep 20m + " Wait for a prompt (see border char first, then space after prompt) + call WaitForAssert({ -> assert_equal(' ', screenstring(screenrow(), screencol() - 1))}) " When typing a character, the cursor is after it. call feedkeys("x", 'xt') - sleep 10m + call term_wait(termbuf) redraw call WaitForAssert({ -> assert_equal('x', screenstring(screenrow(), screencol() - 1))}) call feedkeys("\", 'xt') @@ -3307,7 +3308,7 @@ func Test_popupmenu_info_border() call term_sendkeys(buf, "cc\\") call VerifyScreenDump(buf, 'Test_popupwin_infopopup_6', {}) - " Hide the info popup, cycle trough buffers, make sure it didn't get + " Hide the info popup, cycle through buffers, make sure it didn't get " deleted. call term_sendkeys(buf, "\") call term_sendkeys(buf, ":set hidden\") @@ -3721,11 +3722,18 @@ func Test_popupwin_latin1_encoding() set encoding=latin1 terminal cat Xmultibyte call popup_create(['one', 'two', 'three', 'four'], #{line: 1, col: 10}) + redraw + " wait for "cat" to finish + while execute('ls!') !~ 'finished' + sleep 10m + endwhile + echo "Done" END call writefile(lines, 'XtestPopupLatin') call writefile([repeat("\u3042 ", 120)], 'Xmultibyte') let buf = RunVimInTerminal('-S XtestPopupLatin', #{rows: 10}) + call WaitForAssert({-> assert_match('Done', term_getline(buf, 10))}) call term_sendkeys(buf, ":q\") call StopVimInTerminal(buf) diff --git a/src/testdir/test_python2.vim b/src/testdir/test_python2.vim index ba73c1232e..afefd10fed 100644 --- a/src/testdir/test_python2.vim +++ b/src/testdir/test_python2.vim @@ -3692,7 +3692,7 @@ func Test_python_import() call assert_equal(expected, getline(2, '$')) close! - " Try to import a non-existing moudle with a dot (.) + " Try to import a non-existing module with a dot (.) call AssertException(['py import a.b.c'], 'ImportError:') endfunc diff --git a/src/testdir/test_python3.vim b/src/testdir/test_python3.vim index 660ac461df..78fe5d4c42 100644 --- a/src/testdir/test_python3.vim +++ b/src/testdir/test_python3.vim @@ -3882,7 +3882,7 @@ func Test_python3_import() call assert_equal(expected, getline(2, '$')) close! - " Try to import a non-existing moudle with a dot (.) + " Try to import a non-existing module with a dot (.) call AssertException(['py3 import a.b.c'], "No module named 'a'") endfunc diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim index d89508f06a..888c2f4bf9 100644 --- a/src/testdir/test_quickfix.vim +++ b/src/testdir/test_quickfix.vim @@ -4165,6 +4165,30 @@ func Test_qftitle() call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]}) call assert_equal('Errors', w:quickfix_title) cclose + + " Switching to another quickfix list in one tab page should update the + " quickfix window title and statusline in all the other tab pages also + call setqflist([], 'f') + %bw! + cgetexpr ['file_one:1:1: error in the first quickfix list'] + call setqflist([], 'a', {'title': 'first quickfix list'}) + cgetexpr ['file_two:2:1: error in the second quickfix list'] + call setqflist([], 'a', {'title': 'second quickfix list'}) + copen + wincmd t + tabnew two + copen + wincmd t + colder + call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title')) + call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title')) + call assert_equal(1, tabpagewinnr(1)) + call assert_equal(1, tabpagewinnr(2)) + tabnew + call setqflist([], 'a', {'title': 'new quickfix title'}) + call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title')) + call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title')) + %bw! endfunc func Test_lbuffer_with_bwipe() diff --git a/src/testdir/test_sort.vim b/src/testdir/test_sort.vim index 07f0d0c0af..39005627c1 100644 --- a/src/testdir/test_sort.vim +++ b/src/testdir/test_sort.vim @@ -1328,7 +1328,7 @@ func Test_sort_cmd() endif endfor - " Needs atleast two lines for this test + " Needs at least two lines for this test call setline(1, ['line1', 'line2']) call assert_fails('sort no', 'E474:') call assert_fails('sort c', 'E475:') diff --git a/src/testdir/test_terminal2.vim b/src/testdir/test_terminal2.vim index 64310f6254..4dc8350240 100644 --- a/src/testdir/test_terminal2.vim +++ b/src/testdir/test_terminal2.vim @@ -287,7 +287,7 @@ func Test_zz1_terminal_in_gui() unlet g:job endfunc -" TODO: reenable when this no longer hangs on Travis +" TODO: re-enable when this no longer hangs on Travis "func Test_zz2_terminal_guioptions_bang() " CheckGui " set guioptions+=! @@ -338,7 +338,7 @@ func Test_terminal_switch_mode() let bnr = bufnr('$') call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))}) " In the GUI the first switch sometimes doesn't work. Switch twice to avoid - " flakyness. + " flakiness. call feedkeys("\N", 'xt') call feedkeys("A", 'xt') call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))}) diff --git a/src/testdir/test_terminal3.vim b/src/testdir/test_terminal3.vim index db6ebc00fb..75882f1d1a 100644 --- a/src/testdir/test_terminal3.vim +++ b/src/testdir/test_terminal3.vim @@ -145,7 +145,7 @@ func Test_terminal_in_popup() call delete('XtermPopup') endfunc -" Check a terminal in popup window uses the default mininum size. +" Check a terminal in popup window uses the default minimum size. func Test_terminal_in_popup_min_size() CheckRunVimInTerminal diff --git a/src/testdir/test_vartabs.vim b/src/testdir/test_vartabs.vim index 7bdcde5eee..0ff1ea8ac9 100644 --- a/src/testdir/test_vartabs.vim +++ b/src/testdir/test_vartabs.vim @@ -97,7 +97,7 @@ func Test_vartabs() .retab! call assert_equal("\t\t\t\tl", getline(1)) - " Test for 'retab' with same vlaues as vts + " Test for 'retab' with same values as vts set ts=8 sts=0 vts=5,3,6,2 vsts= exe "norm! S l" .retab! 5,3,6,2 diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 60c8fe9589..c9872d4e63 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -391,6 +391,16 @@ def Test_extend_list() assert_equal(['a', 'b'], list) END CheckScriptSuccess(lines) + lines =<< trim END + vim9script + var list: list + def Func() + extend(list, ['x', 'b']) + enddef + Func() + assert_equal(['x', 'b'], list) + END + CheckScriptSuccess(lines) lines =<< trim END vim9script @@ -584,8 +594,9 @@ def Test_assignment_dict() return test enddef FillDict() + assert_equal({a: 43}, test) END - CheckScriptFailure(lines, 'E1103:') + CheckScriptSuccess(lines) # assignment to global dict lines =<< trim END @@ -1208,6 +1219,14 @@ def Test_unlet() 'enddef', 'defcompile', ], 'E1081:') + CheckScriptFailure([ + 'vim9script', + 'var svar = 123', + 'func Func()', + ' unlet s:svar', + 'endfunc', + 'Func()', + ], 'E1081:') CheckScriptFailure([ 'vim9script', 'var svar = 123', diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim index 95d696913d..bdc9ad06da 100644 --- a/src/testdir/test_vim9_cmd.vim +++ b/src/testdir/test_vim9_cmd.vim @@ -701,5 +701,14 @@ def Test_cmd_argument_without_colon() delete('Xfile') enddef +def Test_ambiguous_user_cmd() + var lines =<< trim END + com Cmd1 eval 0 + com Cmd2 eval 0 + Cmd + END + CheckScriptFailure(lines, 'E464:') +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vimscript.vim b/src/testdir/test_vimscript.vim index e50e4d5fa3..dba8c73fc8 100644 --- a/src/testdir/test_vimscript.vim +++ b/src/testdir/test_vimscript.vim @@ -7374,7 +7374,7 @@ func Test_invalid_function_names() endtry call assert_equal(1, caught_e884) - " function name folowed by # + " function name followed by # let caught_e128 = 0 try func! test2() "# diff --git a/src/textprop.c b/src/textprop.c index bca0d9e021..5a18f6c734 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -302,7 +302,7 @@ prop_add_common( if (length < 0) length = 0; // zero-width property - // Allocate the new line with space for the new proprety. + // Allocate the new line with space for the new property. newtext = alloc(buf->b_ml.ml_line_len + sizeof(textprop_T)); if (newtext == NULL) return; @@ -1485,7 +1485,7 @@ prepend_joined_props( end = !(prop.tp_flags & TP_FLAG_CONT_NEXT); adjust_prop(&prop, 0, -removed, 0); // Remove leading spaces - adjust_prop(&prop, -1, col, 0); // Make line start at its final colum + adjust_prop(&prop, -1, col, 0); // Make line start at its final column if (add_all || end) mch_memmove(new_props + --(*props_remaining) * sizeof(prop), diff --git a/src/userfunc.c b/src/userfunc.c index 2d71a7fd32..50088e6382 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1409,7 +1409,7 @@ funcdepth_get(void) /* * Restore the function call depth. This is for cases where there is no - * garantee funcdepth_decrement() can be called exactly the same number of + * guarantee funcdepth_decrement() can be called exactly the same number of * times as funcdepth_increment(). */ void diff --git a/src/version.c b/src/version.c index 187dcb9bdb..c6aa90b745 100644 --- a/src/version.c +++ b/src/version.c @@ -765,6 +765,34 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2160, +/**/ + 2159, +/**/ + 2158, +/**/ + 2157, +/**/ + 2156, +/**/ + 2155, +/**/ + 2154, +/**/ + 2153, +/**/ + 2152, +/**/ + 2151, +/**/ + 2150, +/**/ + 2149, +/**/ + 2148, +/**/ + 2147, /**/ 2146, /**/ diff --git a/src/vim9.h b/src/vim9.h index 88cc4fce24..26b208025d 100644 --- a/src/vim9.h +++ b/src/vim9.h @@ -53,7 +53,7 @@ typedef enum { // ISN_STOREOTHER, // pop into other script variable isn_arg.other. ISN_STORENR, // store number into local variable isn_arg.storenr.stnr_idx - ISN_STORELIST, // store into list, value/index/varable on stack + ISN_STORELIST, // store into list, value/index/variable on stack ISN_STOREDICT, // store into dictionary, value/index/variable on stack ISN_UNLET, // unlet variable isn_arg.unlet.ul_name diff --git a/src/vim9compile.c b/src/vim9compile.c index 2db226c8d7..207ceb4eac 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -318,7 +318,7 @@ find_script_var(char_u *name, size_t len, cctx_T *cctx) } /* - * Returnd TRUE if the script context is Vim9 script. + * Return TRUE if the script context is Vim9 script. */ static int script_is_vim9() @@ -1958,7 +1958,7 @@ generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod) if (isn->isn_arg.cmdmod.cf_cmdmod == NULL) return FAIL; mch_memmove(isn->isn_arg.cmdmod.cf_cmdmod, cmod, sizeof(cmdmod_T)); - // filter progam now belongs to the instruction + // filter program now belongs to the instruction cmod->cmod_filter_regmatch.regprog = NULL; } @@ -3507,7 +3507,7 @@ compile_subscript( } } - // Do not skip over white space to find the "(", "exeucte 'x' ()" is + // Do not skip over white space to find the "(", "execute 'x' ()" is // not a function call. if (**arg == '(') { @@ -6835,7 +6835,7 @@ compile_endblock(cctx_T *cctx) * ... try block * " catch {expr}" * JUMP -> finally - * catch1: PUSH exeception + * catch1: PUSH exception * EVAL {expr} * MATCH * JUMP nomatch -> catch2 @@ -7132,7 +7132,7 @@ compile_mult_expr(char_u *arg, int cmdidx, cctx_T *cctx) } /* - * If "eap" has a range that is not a contstant generate an ISN_RANGE + * If "eap" has a range that is not a constant generate an ISN_RANGE * instruction to compute it and return OK. * Otherwise return FAIL, the caller must deal with any range. */ diff --git a/src/vim9execute.c b/src/vim9execute.c index 351ea8b3b1..4fd62ce9ed 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -791,6 +791,26 @@ store_var(char_u *name, typval_T *tv) restore_funccal(); } +/* + * When the value of "sv" is a null list of dict, allocate it. + */ + static void +allocate_if_null(typval_T *tv) +{ + switch (tv->v_type) + { + case VAR_LIST: + if (tv->vval.v_list == NULL) + rettv_list_alloc(tv); + break; + case VAR_DICT: + if (tv->vval.v_dict == NULL) + rettv_dict_alloc(tv); + break; + default: + break; + } +} /* * Execute a function by "name". @@ -1289,6 +1309,7 @@ call_def_function( sv = ((svar_T *)si->sn_var_vals.ga_data) + iptr->isn_arg.script.script_idx; + allocate_if_null(sv->sv_tv); if (GA_GROW(&ectx.ec_stack, 1) == FAIL) goto failed; copy_tv(sv->sv_tv, STACK_TV_BOT(0)); @@ -3116,7 +3137,7 @@ failed_early: } /* - * ":dissassemble". + * ":disassemble". * We don't really need this at runtime, but we do have tests that require it, * so always include this. */