mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-02 11:19:22 +02:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 778c734416 | |||
| a4252b3856 | |||
| 08d4327852 | |||
| 17f700ac8b | |||
| 13656f02e4 | |||
| 03290b8444 | |||
| 5bf293e79e | |||
| 1f33e0a7c4 | |||
| ec55b8d482 | |||
| 3db996fa3c | |||
| c70b172aeb | |||
| b9058dda72 | |||
| 7caffe5c20 | |||
| 2ab21ac8e6 | |||
| 486aca4ffc | |||
| e79bce037e | |||
| 5939c3e8f9 | |||
| 8e7d6223f6 | |||
| 3beaf9cd8e | |||
| 6e562fcc07 | |||
| 9aed729fe9 | |||
| b5b77378bc | |||
| 18f69229c5 | |||
| 0353f56ddb | |||
| b125b535bb | |||
| 8dd46e72cf | |||
| a79a8944da | |||
| 8ea05de6aa | |||
| 4c5bdb99ad | |||
| 1c0aa97827 | |||
| 530bed993e | |||
| 4e76524534 | |||
| 9987fb0b4b | |||
| 399ea8108c | |||
| 025cb1ca86 | |||
| ec792290eb | |||
| fffdf4754f | |||
| 8143a53c53 | |||
| 2a3cd3af45 | |||
| acbae18df5 | |||
| b5b9480ee9 | |||
| e498429087 | |||
| c530852315 | |||
| 93f82cbee5 | |||
| 57f799e6a4 | |||
| 2a9d5d386b | |||
| 3ae50c775c | |||
| 709664cca0 | |||
| cc2335896b | |||
| f539a147c1 | |||
| 1f8d90334b | |||
| 3123f01324 | |||
| db650bbf43 | |||
| 0ea7421ae6 | |||
| 100118c73a |
@@ -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:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
service_name: github-actions
|
||||
@@ -0,0 +1,227 @@
|
||||
name: MacVim GitHub CI
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.9
|
||||
|
||||
CC: clang
|
||||
|
||||
VERSIONER_PERL_VERSION: 5.18
|
||||
VERSIONER_PYTHON_VERSION: 2.7
|
||||
vi_cv_path_python: /usr/bin/python
|
||||
vi_cv_path_python3: /usr/local/bin/python3
|
||||
vi_cv_path_plain_lua: /usr/local/bin/lua
|
||||
vi_cv_path_ruby: /usr/local/opt/ruby/bin/ruby
|
||||
vi_cv_dll_name_perl: /System/Library/Perl/5.18/darwin-thread-multi-2level/CORE/libperl.dylib
|
||||
vi_cv_dll_name_python: /System/Library/Frameworks/Python.framework/Versions/2.7/Python
|
||||
vi_cv_dll_name_python3: /usr/local/Frameworks/Python.framework/Versions/3.9/Python
|
||||
vi_cv_dll_name_ruby: /usr/local/opt/ruby/lib/libruby.dylib
|
||||
|
||||
VIM_BIN: src/MacVim/build/Release/MacVim.app/Contents/MacOS/Vim
|
||||
MACVIM_BIN: src/MacVim/build/Release/MacVim.app/Contents/MacOS/MacVim
|
||||
|
||||
TERM: xterm
|
||||
BASH_SILENCE_DEPRECATION_WARNING: 1
|
||||
|
||||
jobs:
|
||||
# Builds and test MacVim
|
||||
build-and-test:
|
||||
|
||||
# Test on macOS 10.15 / 11.0, and also older version of Xcode for compatibility testing.
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: macos-10.15
|
||||
xcode: 11.7
|
||||
- os: macos-10.15
|
||||
publish: true
|
||||
- os: macos-11.0
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
# Set up and install gettext for localization.
|
||||
# Instead of using the default binary installed by Homebrew, need to build our own because gettext is statically
|
||||
# linked in MacVim, and need to be built against MACOSX_DEPLOYMENT_TARGET to ensure the built binary will work on
|
||||
# supported macOS versions.
|
||||
- name: Set up gettext
|
||||
if: matrix.publish
|
||||
run: |
|
||||
# Patch the official Homebrew gettext formula to explicitly build for min deployment target
|
||||
cp /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/gettext.rb gettext.rb
|
||||
|
||||
cat << EOF > gettext_diff.patch
|
||||
--- gettext_orig.rb
|
||||
+++ gettext.rb
|
||||
@@ -24,2 +24,3 @@
|
||||
def install
|
||||
+ ENV["MACOSX_DEPLOYMENT_TARGET"] = "${MACOSX_DEPLOYMENT_TARGET}"
|
||||
args = [
|
||||
EOF
|
||||
|
||||
patch gettext.rb gettext_diff.patch
|
||||
|
||||
# Uninstall the already installed gettext because we want to build our own
|
||||
brew uninstall --ignore-dependencies gettext
|
||||
|
||||
- name: Cache gettext
|
||||
if: matrix.publish
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /usr/local/Cellar/gettext
|
||||
key: gettext-homebrew-cache-${{ runner.os }}-${{ hashFiles('gettext.rb') }}
|
||||
|
||||
- name: Install gettext
|
||||
if: matrix.publish
|
||||
env:
|
||||
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||
run: |
|
||||
brew install -s gettext.rb # This will be a no-op if gettext was cached
|
||||
brew link gettext # If gettext was cached, this step is necessary to relink it to /usr/local/
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.publish
|
||||
env:
|
||||
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||
run: |
|
||||
brew install python
|
||||
brew install ruby
|
||||
brew install lua
|
||||
brew unlink perl # We just use system perl to reduce dependencies
|
||||
|
||||
- name: Set up Xcode
|
||||
if: matrix.xcode != ''
|
||||
run: |
|
||||
sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer
|
||||
xcode-select -p
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
set -o verbose
|
||||
|
||||
CONFOPT=(
|
||||
--with-features=huge
|
||||
--enable-netbeans
|
||||
--with-tlib=ncurses
|
||||
--enable-cscope
|
||||
--enable-gui=macvim
|
||||
--with-macarchs=x86_64
|
||||
)
|
||||
if ${{ matrix.publish == true }}; then
|
||||
CONFOPT+=(
|
||||
--enable-perlinterp=dynamic
|
||||
--enable-pythoninterp=dynamic
|
||||
--enable-python3interp=dynamic
|
||||
--enable-rubyinterp=dynamic
|
||||
--enable-luainterp=dynamic
|
||||
--with-lua-prefix=/usr/local
|
||||
)
|
||||
fi
|
||||
echo "CONFOPT: ${CONFOPT[@]}"
|
||||
|
||||
./configure "${CONFOPT[@]}" --enable-fail-if-missing
|
||||
|
||||
sed -i.bak -f ci/config.mk.sed -f ci/config.mk.clang.sed src/auto/config.mk
|
||||
|
||||
- name: Modify configure result
|
||||
if: matrix.publish
|
||||
run: |
|
||||
# Ruby is keg-only in Homebrew, so need to manually link in the path so Vim will know where to look for the binaries.
|
||||
perl -p -i -e "s#(?<=-DDYNAMIC_RUBY_DLL=\\\\\").*?(?=\\\\\")#${vi_cv_dll_name_ruby}#" src/auto/config.mk
|
||||
grep -q -- "-DDYNAMIC_PERL_DLL=\\\\\"${vi_cv_dll_name_perl}\\\\\"" src/auto/config.mk
|
||||
grep -q -- "-DDYNAMIC_PYTHON_DLL=\\\\\"${vi_cv_dll_name_python}\\\\\"" src/auto/config.mk
|
||||
grep -q -- "-DDYNAMIC_PYTHON3_DLL=\\\\\"${vi_cv_dll_name_python3}\\\\\"" src/auto/config.mk
|
||||
grep -q -- "-DDYNAMIC_RUBY_DLL=\\\\\"${vi_cv_dll_name_ruby}\\\\\"" src/auto/config.mk
|
||||
|
||||
- name: Show configure output
|
||||
run: |
|
||||
cat src/auto/config.mk
|
||||
cat src/auto/config.h
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
set -o verbose
|
||||
|
||||
NPROC=$(getconf _NPROCESSORS_ONLN)
|
||||
echo "Building MacVim with ${NPROC} cores"
|
||||
|
||||
make -j${NPROC}
|
||||
|
||||
- name: Check version
|
||||
run: |
|
||||
${VIM_BIN} --version
|
||||
${VIM_BIN} -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-1.vim -c quit
|
||||
${VIM_BIN} -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-2.vim -c quit
|
||||
|
||||
- name: Smoketest
|
||||
if: matrix.publish
|
||||
run: |
|
||||
set -o verbose
|
||||
|
||||
macvim_excmd() {
|
||||
${VIM_BIN} -u NONE -i NONE -g -f -X -V1 -es "$@" -c 'echo ""' -c 'qall!' 2>&1
|
||||
}
|
||||
|
||||
# Smoketest scripting languages
|
||||
macvim_excmd -c 'lua print("Test")'
|
||||
macvim_excmd -c 'perl VIM::Msg("Test")'
|
||||
macvim_excmd -c 'py import sys; print("Test")'
|
||||
macvim_excmd -c 'py3 import sys; print("Test")'
|
||||
macvim_excmd -c 'ruby puts("Test")'
|
||||
|
||||
# Check that localized messages work by printing ':version' and checking against localized word
|
||||
macvim_excmd -c 'lang es_ES' -c 'version' | grep Enlazado
|
||||
|
||||
# Make sure there isn't any dynamic linkage to third-party dependencies in the built binary, as we should only use
|
||||
# static linkage to avoid dependency hell. Test that all those dylib's are in /usr/lib which is bundled with macOS and not third-party.
|
||||
if otool -L ${VIM_BIN} | grep '\.dylib\s' | grep -v '^\s*/usr/lib/'; then
|
||||
echo 'Found external dynamic linkage!'; false
|
||||
fi
|
||||
|
||||
# Make sure we are building x86_64 only. arm64 builds don't work properly now, so we don't want to accidentally build
|
||||
# it as it will get prioritized by Apple Silicon Macs.
|
||||
check_arch() {
|
||||
local archs=($(lipo -archs "$1"))
|
||||
if [[ ${archs[@]} != x86_64 ]]; then
|
||||
echo "Found unexpected arch(s) in $1: ${archs[@]}"; false
|
||||
fi
|
||||
}
|
||||
check_arch "${VIM_BIN}"
|
||||
check_arch "${MACVIM_BIN}"
|
||||
|
||||
- name: Update Vim help tags
|
||||
if: matrix.publish
|
||||
run: make -C runtime/doc vimtags VIMEXE=../../${VIM_BIN}
|
||||
|
||||
- name: Test
|
||||
timeout-minutes: 20
|
||||
run: make test
|
||||
|
||||
- name: Test GUI
|
||||
timeout-minutes: 20
|
||||
run: |
|
||||
make -C src/testdir clean
|
||||
make -C src testgui
|
||||
|
||||
# Creates a DMG package of MacVim. Note that this doesn't create a GitHub release for us, because we would prefer to
|
||||
# do it manually, for two reasons: 1) signing / notarization are currently done out of CI, 2) we want to manually
|
||||
# format our release notes and add pictures to make them look nice.
|
||||
- name: Build MacVim dmg image
|
||||
if: startsWith(github.ref, 'refs/tags/') && matrix.publish
|
||||
run: |
|
||||
# Use the --skip-jenkins flag to skip the prettify osascript calls which could fail due to permission issues in
|
||||
# CI environment.
|
||||
make -C src macvim-dmg CREATEDMG_FLAGS=--skip-jenkins
|
||||
|
||||
- name: Upload MacVim image
|
||||
if: startsWith(github.ref, 'refs/tags/') && matrix.publish
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: MacVim.dmg
|
||||
path: src/MacVim/build/Release/MacVim.dmg
|
||||
@@ -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 <URL> <localfile>
|
||||
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
|
||||
)
|
||||
@@ -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
|
||||
|
||||
+6
-1
@@ -18,7 +18,8 @@ env:
|
||||
vi_cv_dll_name_python3=/usr/local/Frameworks/Python.framework/Versions/3.9/Python
|
||||
vi_cv_dll_name_ruby=/usr/local/opt/ruby/lib/libruby.dylib
|
||||
VIMCMD=src/MacVim/build/Release/MacVim.app/Contents/MacOS/Vim
|
||||
CONFOPT="--with-features=huge --enable-netbeans --with-tlib=ncurses --enable-cscope --enable-gui=macvim"
|
||||
MACVIM_BIN=src/MacVim/build/Release/MacVim.app/Contents/MacOS/MacVim
|
||||
CONFOPT="--with-features=huge --enable-netbeans --with-tlib=ncurses --enable-cscope --enable-gui=macvim --with-macarchs=x86_64"
|
||||
BASH_SILENCE_DEPRECATION_WARNING=1
|
||||
|
||||
_anchors:
|
||||
@@ -85,6 +86,10 @@ script:
|
||||
# Make sure there isn't any dynamic linkage to third-party dependencies in the built binary, as we should only use
|
||||
# static linkage to avoid dependency hell. Test that all those dylib's are in /usr/lib which is bundled with macOS and not third-party.
|
||||
- (! otool -L ${VIMCMD} | grep '\.dylib\s' | grep -v '^\s*/usr/lib/')
|
||||
# Make sure we are building x86_64 only. arm64 builds don't work properly now, so we don't want to accidentally build
|
||||
# it as it will get prioritized by Apple Silicon Macs.
|
||||
- (lipo -archs ${VIMCMD} | grep '^x86_64$')
|
||||
- (lipo -archs ${MACVIM_BIN} | grep '^x86_64$')
|
||||
- echo -en "travis_fold:end:smoketest\\r\\033[0K"
|
||||
|
||||
# Run standard test suites.
|
||||
|
||||
@@ -7,7 +7,7 @@ Vim - the text editor - for macOS
|
||||
|
||||
- Vim README: [README_vim.md](README_vim.md)
|
||||
|
||||
- Travis CI <a href="https://travis-ci.com/macvim-dev/macvim"><img src="https://travis-ci.com/macvim-dev/macvim.svg?branch=master" alt="Build Status"></a>
|
||||
- [](https://github.com/macvim-dev/macvim/actions?query=workflow%3A%22MacVim+GitHub+CI%22)
|
||||
|
||||
- Packaged in [](https://repology.org/metapackage/macvim/versions) [](https://repology.org/metapackage/macvim/versions)
|
||||
|
||||
|
||||
+5
-2
@@ -1,5 +1,6 @@
|
||||

|
||||
|
||||
[](https://github.com/vim/vim/actions?query=workflow%3A%22GitHub+CI%22)
|
||||
[](https://travis-ci.org/vim/vim)
|
||||
[](https://ci.appveyor.com/project/chrisbra/vim)
|
||||
[](https://cirrus-ci.com/github/vim/vim)
|
||||
@@ -8,6 +9,7 @@
|
||||
[](https://lgtm.com/projects/g/vim/vim/context:cpp)
|
||||
[](https://buildd.debian.org/vim)
|
||||
[](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.
|
||||
|
||||
@@ -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}"
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
apt-get install -y xvfb
|
||||
|
||||
cat <<EOT >/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
|
||||
@@ -308,6 +308,9 @@ Name triggered by ~
|
||||
|VimLeavePre| before exiting Vim, before writing the viminfo file
|
||||
|VimLeave| before exiting Vim, after writing the viminfo file
|
||||
|
||||
|VimSuspend| when suspending Vim
|
||||
|VimResume| when Vim is resumed after being suspended
|
||||
|
||||
Terminal
|
||||
|TerminalOpen| after a terminal buffer was created
|
||||
|TerminalWinOpen| after a terminal buffer was created in a new window
|
||||
@@ -1238,6 +1241,17 @@ VimLeavePre Before exiting Vim, just before writing the
|
||||
VimResized After the Vim window was resized, thus 'lines'
|
||||
and/or 'columns' changed. Not when starting
|
||||
up though.
|
||||
*VimResume*
|
||||
VimResume When the Vim instance is resumed after being
|
||||
suspended and |VimSuspend| was triggered.
|
||||
Useful for triggering |:checktime| and ensure
|
||||
the buffers content did not change while Vim
|
||||
was suspended: >
|
||||
:autocmd VimResume * checktime
|
||||
< *VimSuspend*
|
||||
VimSuspend When the Vim instance is suspended. Only when
|
||||
CTRL-Z was typed inside Vim, not when the
|
||||
SIGSTOP or SIGTSTP signal was sent to Vim.
|
||||
*WinEnter*
|
||||
WinEnter After entering another window. Not done for
|
||||
the first window, when Vim has just started.
|
||||
|
||||
@@ -1255,7 +1255,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>167</string>
|
||||
<string>169</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.productivity</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
@@ -1312,7 +1312,7 @@
|
||||
<key>SUPublicDSAKeyFile</key>
|
||||
<string>dsa_pub.pem</string>
|
||||
<key>SUPublicEDKey</key>
|
||||
<string>EnnNZOR1zR6TmKXohjTNWbToLYNE4/1qd/dtkuTE2zc=</string>
|
||||
<string>Pt4zsg/8S3/mxKW7Cmt0cZFw/+2LOuXOYS93evP+Mfc=</string>
|
||||
<key>NSAppleEventsUsageDescription</key>
|
||||
<string>MacVim uses Apple Events to allow you to communicate with other apps using Apple Script, and to support working as an ODB external editor.</string>
|
||||
<key>NSAppleScriptEnabled</key>
|
||||
|
||||
+1
-1
@@ -1400,7 +1400,7 @@ MACVIMGUI_OBJ = objects/gui.o objects/gui_beval.o \
|
||||
MACVIMGUI_DEFS = -DFEAT_GUI_MACVIM -Wall -Wno-unknown-pragmas -pipe
|
||||
MACVIMGUI_IPATH =
|
||||
MACVIMGUI_LIBS_DIR =
|
||||
MACVIMGUI_LIBS1 = -framework Cocoa -framework Carbon
|
||||
MACVIMGUI_LIBS1 =
|
||||
MACVIMGUI_LIBS2 =
|
||||
MACVIMGUI_INSTALL = install_normal
|
||||
MACVIMGUI_TARGETS =
|
||||
|
||||
Vendored
+10
-2
@@ -4758,7 +4758,15 @@ fi
|
||||
$as_echo_n "checking if architectures are supported... " >&6; }
|
||||
save_cflags="$CFLAGS"
|
||||
save_ldflags="$LDFLAGS"
|
||||
archflags=`echo "$ARCHS" | sed -e 's/[[:<:]]/-arch /g'`
|
||||
|
||||
# Apple's sed is supposed to treat [[:<:]] as word beginning, but seems
|
||||
# like that broke some time ago and means *any* word character (but
|
||||
# [[:>:]] still seems to work as word end).
|
||||
# Use a more convoluted regex in order to properly to split the archs by
|
||||
# word and prefix each with "-arch" to pass to the compiler.
|
||||
#archflags=`echo "$ARCHS" | sed -e 's/[[[:<:]]]/-arch /g'`
|
||||
archflags=`echo "$ARCHS" | sed 's/[[:>:]][ ][ ]*[[:<:]]/ -arch /g' | sed 's/^/-arch /g'`
|
||||
|
||||
CFLAGS="$CFLAGS $archflags"
|
||||
LDFLAGS="$LDFLAGS $archflags"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
@@ -5536,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
|
||||
|
||||
@@ -192,6 +192,8 @@ static struct event_name
|
||||
{"WinLeave", EVENT_WINLEAVE},
|
||||
{"VimResized", EVENT_VIMRESIZED},
|
||||
{"TextYankPost", EVENT_TEXTYANKPOST},
|
||||
{"VimSuspend", EVENT_VIMSUSPEND},
|
||||
{"VimResume", EVENT_VIMRESUME},
|
||||
{NULL, (event_T)0}
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+10
-2
@@ -273,7 +273,15 @@ if test "`(uname) 2>/dev/null`" = Darwin; then
|
||||
AC_MSG_CHECKING(if architectures are supported)
|
||||
save_cflags="$CFLAGS"
|
||||
save_ldflags="$LDFLAGS"
|
||||
archflags=`echo "$ARCHS" | sed -e 's/[[[:<:]]]/-arch /g'`
|
||||
|
||||
# Apple's sed is supposed to treat [[:<:]] as word beginning, but seems
|
||||
# like that broke some time ago and means *any* word character (but
|
||||
# [[:>:]] still seems to work as word end).
|
||||
# Use a more convoluted regex in order to properly to split the archs by
|
||||
# word and prefix each with "-arch" to pass to the compiler.
|
||||
#archflags=`echo "$ARCHS" | sed -e 's/[[[:<:]]]/-arch /g'`
|
||||
archflags=`echo "$ARCHS" | sed 's/[[[:>:]]][[ ]][[ ]]*[[[:<:]]]/ -arch /g' | sed 's/^/-arch /g'`
|
||||
|
||||
CFLAGS="$CFLAGS $archflags"
|
||||
LDFLAGS="$LDFLAGS $archflags"
|
||||
AC_TRY_LINK([ ], [ ],
|
||||
@@ -663,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
|
||||
|
||||
+6
-1
@@ -951,6 +951,11 @@ eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal)
|
||||
}
|
||||
if (evaluate)
|
||||
{
|
||||
if (vim9script && check_for_string(&tvkey) == FAIL)
|
||||
{
|
||||
clear_tv(&tvkey);
|
||||
goto failret;
|
||||
}
|
||||
key = tv_get_string_buf_chk(&tvkey, buf);
|
||||
if (key == NULL)
|
||||
{
|
||||
@@ -1068,7 +1073,7 @@ dict_extend(dict_T *d1, dict_T *d2, char_u *action)
|
||||
&& HI2DI(hi2)->di_tv.v_type == VAR_FUNC
|
||||
&& var_wrong_func_name(hi2->hi_key, di1 == NULL))
|
||||
break;
|
||||
if (!valid_varname(hi2->hi_key))
|
||||
if (!valid_varname(hi2->hi_key, TRUE))
|
||||
break;
|
||||
}
|
||||
if (di1 == NULL)
|
||||
|
||||
+9
-1
@@ -61,7 +61,7 @@ EXTERN char e_argument_nr_type_mismatch_expected_str_but_got_str[]
|
||||
INIT(= N_("E1013: Argument %d: type mismatch, expected %s but got %s"));
|
||||
EXTERN char e_invalid_key_str[]
|
||||
INIT(= N_("E1014: Invalid key: %s"));
|
||||
EXTERN char e_name_expected[]
|
||||
EXTERN char e_name_expected_str[]
|
||||
INIT(= N_("E1015: Name expected: %s"));
|
||||
EXTERN char e_cannot_declare_a_scope_variable[]
|
||||
INIT(= N_("E1016: Cannot declare a %s variable: %s"));
|
||||
@@ -313,3 +313,11 @@ EXTERN char e_for_argument_must_be_sequence_of_lists[]
|
||||
INIT(= N_("E1140: For argument must be a sequence of lists"));
|
||||
EXTERN char e_indexable_type_required[]
|
||||
INIT(= N_("E1141: Indexable type required"));
|
||||
EXTERN char e_non_empty_string_required[]
|
||||
INIT(= N_("E1142: Non-empty string required"));
|
||||
EXTERN char e_empty_expression_str[]
|
||||
INIT(= N_("E1143: Empty expression: \"%s\""));
|
||||
EXTERN char e_command_not_followed_by_white_space_str[]
|
||||
INIT(= N_("E1144: Command is not followed by white space: %s"));
|
||||
EXTERN char e_missing_heredoc_end_marker_str[]
|
||||
INIT(= N_("E1145: Missing heredoc end marker: %s"));
|
||||
|
||||
+6
-3
@@ -1049,7 +1049,7 @@ get_lval(
|
||||
wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE
|
||||
&& rettv->v_type == VAR_FUNC
|
||||
&& var_wrong_func_name(key, lp->ll_di == NULL))
|
||||
|| !valid_varname(key);
|
||||
|| !valid_varname(key, TRUE);
|
||||
if (len != -1)
|
||||
key[len] = prevval;
|
||||
if (wrong)
|
||||
@@ -2158,7 +2158,10 @@ eval0(
|
||||
semsg(_(e_invexpr2), arg);
|
||||
|
||||
// Some of the expression may not have been consumed. Do not check for
|
||||
// a next command to avoid more errors.
|
||||
// a next command to avoid more errors, unless "|" is following, which
|
||||
// could only be a command separator.
|
||||
if (eap != NULL && skipwhite(p)[0] == '|' && skipwhite(p)[1] != '|')
|
||||
eap->nextcmd = check_nextcmd(p);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@@ -4628,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 "...".
|
||||
|
||||
+31
-16
@@ -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);
|
||||
@@ -2723,19 +2733,23 @@ get_script_local_ht(void)
|
||||
|
||||
/*
|
||||
* Look for "name[len]" in script-local variables.
|
||||
* Return a non-NULL pointer when found, NULL when not found.
|
||||
* Return OK when found, FAIL when not found.
|
||||
*/
|
||||
void *
|
||||
lookup_scriptvar(char_u *name, size_t len, cctx_T *dummy UNUSED)
|
||||
int
|
||||
lookup_scriptvar(
|
||||
char_u *name,
|
||||
size_t len,
|
||||
void *lvar UNUSED,
|
||||
cctx_T *dummy UNUSED)
|
||||
{
|
||||
hashtab_T *ht = get_script_local_ht();
|
||||
char_u buffer[30];
|
||||
char_u *p;
|
||||
void *res;
|
||||
int res;
|
||||
hashitem_T *hi;
|
||||
|
||||
if (ht == NULL)
|
||||
return NULL;
|
||||
return FAIL;
|
||||
if (len < sizeof(buffer) - 1)
|
||||
{
|
||||
// avoid an alloc/free for short names
|
||||
@@ -2746,20 +2760,19 @@ lookup_scriptvar(char_u *name, size_t len, cctx_T *dummy UNUSED)
|
||||
{
|
||||
p = vim_strnsave(name, len);
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
hi = hash_find(ht, p);
|
||||
res = HASHITEM_EMPTY(hi) ? NULL : hi;
|
||||
res = HASHITEM_EMPTY(hi) ? FAIL : OK;
|
||||
|
||||
// if not script-local, then perhaps imported
|
||||
if (res == NULL && find_imported(p, 0, NULL) != NULL)
|
||||
res = p;
|
||||
if (res == FAIL && find_imported(p, 0, NULL) != NULL)
|
||||
res = OK;
|
||||
|
||||
if (p != buffer)
|
||||
vim_free(p);
|
||||
// Don't return "buffer", gcc complains.
|
||||
return res == NULL ? NULL : IObuff;
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3184,8 +3197,10 @@ set_var_const(
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// Make sure the variable name is valid.
|
||||
if (!valid_varname(varname))
|
||||
// Make sure the variable name is valid. In Vim9 script an autoload
|
||||
// variable must be prefixed with "g:".
|
||||
if (!valid_varname(varname, !vim9script
|
||||
|| STRNCMP(name, "g:", 2) == 0))
|
||||
goto failed;
|
||||
|
||||
di = alloc(sizeof(dictitem_T) + STRLEN(varname));
|
||||
@@ -3338,17 +3353,17 @@ value_check_lock(int lock, char_u *name, int use_gettext)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if a variable name is valid.
|
||||
* Check if a variable name is valid. When "autoload" is true "#" is allowed.
|
||||
* Return FALSE and give an error if not.
|
||||
*/
|
||||
int
|
||||
valid_varname(char_u *varname)
|
||||
valid_varname(char_u *varname, int autoload)
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
for (p = varname; *p != NUL; ++p)
|
||||
if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))
|
||||
&& *p != AUTOLOAD_CHAR)
|
||||
&& !(autoload && *p == AUTOLOAD_CHAR))
|
||||
{
|
||||
semsg(_(e_illvar), varname);
|
||||
return FALSE;
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+9
-8
@@ -55,6 +55,7 @@
|
||||
#define EX_LOCK_OK 0x1000000 // command can be executed when textlock is
|
||||
// set; when missing disallows editing another
|
||||
// buffer when curbuf_lock is set
|
||||
#define EX_NONWHITE_OK 0x2000000 // command can be followed by non-white
|
||||
|
||||
#define EX_FILES (EX_XFILE | EX_EXTRA) // multiple extra files allowed
|
||||
#define EX_FILE1 (EX_FILES | EX_NOSPC) // 1 file, defaults to current file
|
||||
@@ -632,7 +633,7 @@ EXCMD(CMD_function, "function", ex_function,
|
||||
EX_EXTRA|EX_BANG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_NONE),
|
||||
EXCMD(CMD_global, "global", ex_global,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_EXTRA|EX_DFLALL|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_EXTRA|EX_DFLALL|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
|
||||
ADDR_LINES),
|
||||
EXCMD(CMD_goto, "goto", ex_goto,
|
||||
EX_RANGE|EX_COUNT|EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
|
||||
@@ -1283,7 +1284,7 @@ EXCMD(CMD_rviminfo, "rviminfo", ex_viminfo,
|
||||
EX_BANG|EX_FILE1|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_NONE),
|
||||
EXCMD(CMD_substitute, "substitute", ex_substitute,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
|
||||
ADDR_LINES),
|
||||
EXCMD(CMD_sNext, "sNext", ex_previous,
|
||||
EX_EXTRA|EX_RANGE|EX_COUNT|EX_BANG|EX_CMDARG|EX_ARGOPT|EX_TRLBAR,
|
||||
@@ -1658,7 +1659,7 @@ EXCMD(CMD_update, "update", ex_update,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_FILE1|EX_ARGOPT|EX_DFLALL|EX_TRLBAR,
|
||||
ADDR_LINES),
|
||||
EXCMD(CMD_vglobal, "vglobal", ex_global,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_DFLALL|EX_CMDWIN|EX_LOCK_OK,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_DFLALL|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
|
||||
ADDR_LINES),
|
||||
EXCMD(CMD_var, "var", ex_var,
|
||||
EX_EXTRA|EX_NOTRLCOM|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
|
||||
@@ -1798,16 +1799,16 @@ EXCMD(CMD_z, "z", ex_z,
|
||||
|
||||
// commands that don't start with a letter
|
||||
EXCMD(CMD_bang, "!", ex_bang,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_FILES|EX_CMDWIN|EX_LOCK_OK,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_FILES|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
|
||||
ADDR_LINES),
|
||||
EXCMD(CMD_pound, "#", ex_print,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_COUNT|EX_FLAGS|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_LINES),
|
||||
EXCMD(CMD_and, "&", ex_substitute,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY|EX_NONWHITE_OK,
|
||||
ADDR_LINES),
|
||||
EXCMD(CMD_star, "*", ex_at,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
|
||||
ADDR_LINES),
|
||||
EXCMD(CMD_lshift, "<", ex_operators,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_COUNT|EX_FLAGS|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY,
|
||||
@@ -1819,7 +1820,7 @@ EXCMD(CMD_rshift, ">", ex_operators,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_COUNT|EX_FLAGS|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY,
|
||||
ADDR_LINES),
|
||||
EXCMD(CMD_at, "@", ex_at,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
|
||||
ADDR_LINES),
|
||||
EXCMD(CMD_block, "{{{{{{{{", ex_block, // not found normally
|
||||
0,
|
||||
@@ -1828,7 +1829,7 @@ EXCMD(CMD_endblock, "}", ex_endblock,
|
||||
EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_NONE),
|
||||
EXCMD(CMD_tilde, "~", ex_substitute,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY,
|
||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY|EX_NONWHITE_OK,
|
||||
ADDR_LINES),
|
||||
|
||||
// commands that start with an uppercase letter
|
||||
|
||||
+17
-6
@@ -1689,7 +1689,7 @@ comment_start(char_u *p, int starts_with_colon UNUSED)
|
||||
{
|
||||
#ifdef FEAT_EVAL
|
||||
if (in_vim9script())
|
||||
return p[0] == '#' && p[1] != '{' && !starts_with_colon;
|
||||
return p[0] == '#' && !starts_with_colon;
|
||||
#endif
|
||||
return *p == '"';
|
||||
}
|
||||
@@ -3277,7 +3277,7 @@ skip_option_env_lead(char_u *start)
|
||||
find_ex_command(
|
||||
exarg_T *eap,
|
||||
int *full UNUSED,
|
||||
void *(*lookup)(char_u *, size_t, cctx_T *) UNUSED,
|
||||
int (*lookup)(char_u *, size_t, void *, cctx_T *) UNUSED,
|
||||
cctx_T *cctx UNUSED)
|
||||
{
|
||||
int len;
|
||||
@@ -3393,7 +3393,7 @@ find_ex_command(
|
||||
|| *eap->cmd == '&'
|
||||
|| *eap->cmd == '$'
|
||||
|| *eap->cmd == '@'
|
||||
|| lookup(eap->cmd, p - eap->cmd, cctx) != NULL)
|
||||
|| lookup(eap->cmd, p - eap->cmd, NULL, cctx) == OK)
|
||||
{
|
||||
eap->cmdidx = CMD_var;
|
||||
return eap->cmd;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -3534,6 +3534,16 @@ find_ex_command(
|
||||
if (eap->cmdidx == CMD_final && p - eap->cmd == 4)
|
||||
eap->cmdidx = CMD_finally;
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
if (eap->cmdidx != CMD_SIZE && in_vim9script()
|
||||
&& !IS_WHITE_OR_NUL(*p) && !ends_excmd(*p) && *p != '!'
|
||||
&& (cmdnames[eap->cmdidx].cmd_argt & EX_NONWHITE_OK) == 0)
|
||||
{
|
||||
semsg(_(e_command_not_followed_by_white_space_str), eap->cmd);
|
||||
eap->cmdidx = CMD_SIZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -4786,7 +4796,6 @@ separate_nextcmd(exarg_T *eap)
|
||||
|| (*p == '#'
|
||||
&& in_vim9script()
|
||||
&& !(eap->argt & EX_NOTRLCOM)
|
||||
&& p[1] != '{'
|
||||
&& p > eap->cmd && VIM_ISWHITE(p[-1]))
|
||||
#endif
|
||||
|| *p == '|' || *p == '\n')
|
||||
@@ -5121,7 +5130,7 @@ ex_blast(exarg_T *eap)
|
||||
|
||||
/*
|
||||
* Check if "c" ends an Ex command.
|
||||
* In Vim9 script does not check for white space before # or #{.
|
||||
* In Vim9 script does not check for white space before #.
|
||||
*/
|
||||
int
|
||||
ends_excmd(int c)
|
||||
@@ -5870,6 +5879,7 @@ ex_stop(exarg_T *eap)
|
||||
{
|
||||
if (!eap->forceit)
|
||||
autowrite_all();
|
||||
apply_autocmds(EVENT_VIMSUSPEND, NULL, NULL, FALSE, NULL);
|
||||
windgoto((int)Rows - 1, 0);
|
||||
out_char('\n');
|
||||
out_flush();
|
||||
@@ -5887,6 +5897,7 @@ ex_stop(exarg_T *eap)
|
||||
scroll_start(); // scroll screen before redrawing
|
||||
redraw_later_clear();
|
||||
shell_resized(); // may have resized window
|
||||
apply_autocmds(EVENT_VIMRESUME, NULL, NULL, FALSE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-5
@@ -606,6 +606,8 @@ discard_exception(except_T *excp, int was_finished)
|
||||
{
|
||||
char_u *saved_IObuff;
|
||||
|
||||
if (current_exception == excp)
|
||||
current_exception = NULL;
|
||||
if (excp == NULL)
|
||||
{
|
||||
internal_error("discard_exception()");
|
||||
@@ -654,10 +656,7 @@ discard_exception(except_T *excp, int was_finished)
|
||||
discard_current_exception(void)
|
||||
{
|
||||
if (current_exception != NULL)
|
||||
{
|
||||
discard_exception(current_exception, FALSE);
|
||||
current_exception = NULL;
|
||||
}
|
||||
did_throw = FALSE;
|
||||
need_rethrow = FALSE;
|
||||
}
|
||||
@@ -2284,8 +2283,8 @@ cleanup_conditionals(
|
||||
// Cancel the pending exception. This is in the
|
||||
// finally clause, so that the stack of the
|
||||
// caught exceptions is not involved.
|
||||
discard_exception((except_T *)
|
||||
cstack->cs_exception[idx],
|
||||
discard_exception(
|
||||
(except_T *)cstack->cs_exception[idx],
|
||||
FALSE);
|
||||
}
|
||||
else
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+6
-5
@@ -876,7 +876,7 @@ f_exepath(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
char_u *p = NULL;
|
||||
|
||||
if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
|
||||
if (in_vim9script() && check_for_nonempty_string(&argvars[0]) == FAIL)
|
||||
return;
|
||||
(void)mch_can_exe(tv_get_string(&argvars[0]), &p, TRUE);
|
||||
rettv->v_type = VAR_STRING;
|
||||
@@ -942,7 +942,7 @@ findfilendir(
|
||||
|
||||
rettv->vval.v_string = NULL;
|
||||
rettv->v_type = VAR_STRING;
|
||||
if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
|
||||
if (in_vim9script() && check_for_nonempty_string(&argvars[0]) == FAIL)
|
||||
return;
|
||||
|
||||
#ifdef FEAT_SEARCHPATH
|
||||
@@ -1019,7 +1019,7 @@ f_fnamemodify(typval_T *argvars, typval_T *rettv)
|
||||
char_u *fname;
|
||||
char_u *mods;
|
||||
int usedlen = 0;
|
||||
int len;
|
||||
int len = 0;
|
||||
char_u *fbuf = NULL;
|
||||
char_u buf[NUMBUFLEN];
|
||||
|
||||
@@ -1028,12 +1028,13 @@ f_fnamemodify(typval_T *argvars, typval_T *rettv)
|
||||
return;
|
||||
fname = tv_get_string_chk(&argvars[0]);
|
||||
mods = tv_get_string_buf_chk(&argvars[1], buf);
|
||||
if (fname == NULL || mods == NULL)
|
||||
if (mods == NULL || fname == NULL)
|
||||
fname = NULL;
|
||||
else
|
||||
{
|
||||
len = (int)STRLEN(fname);
|
||||
(void)modify_fname(mods, FALSE, &usedlen, &fname, &fbuf, &len);
|
||||
if (mods != NULL && *mods != NUL)
|
||||
(void)modify_fname(mods, FALSE, &usedlen, &fname, &fbuf, &len);
|
||||
}
|
||||
|
||||
rettv->v_type = VAR_STRING;
|
||||
|
||||
+1
-1
@@ -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"].
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
+1
-1
@@ -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)
|
||||
{
|
||||
|
||||
+3
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+10
-1
@@ -1298,6 +1298,7 @@ ins_compl_files(
|
||||
fp = mch_fopen((char *)files[i], "r"); // open dictionary file
|
||||
if (flags != DICT_EXACT)
|
||||
{
|
||||
msg_hist_off = TRUE; // reset in msg_trunc_attr()
|
||||
vim_snprintf((char *)IObuff, IOSIZE,
|
||||
_("Scanning dictionary: %s"), (char *)files[i]);
|
||||
(void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R));
|
||||
@@ -2783,6 +2784,7 @@ ins_compl_get_exp(pos_T *ini)
|
||||
dict = ins_buf->b_fname;
|
||||
dict_f = DICT_EXACT;
|
||||
}
|
||||
msg_hist_off = TRUE; // reset in msg_trunc_attr()
|
||||
vim_snprintf((char *)IObuff, IOSIZE, _("Scanning: %s"),
|
||||
ins_buf->b_fname == NULL
|
||||
? buf_spname(ins_buf)
|
||||
@@ -2817,6 +2819,7 @@ ins_compl_get_exp(pos_T *ini)
|
||||
#endif
|
||||
else if (*e_cpt == ']' || *e_cpt == 't')
|
||||
{
|
||||
msg_hist_off = TRUE; // reset in msg_trunc_attr()
|
||||
type = CTRL_X_TAGS;
|
||||
vim_snprintf((char *)IObuff, IOSIZE, _("Scanning tags."));
|
||||
(void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R));
|
||||
@@ -3428,9 +3431,11 @@ ins_compl_next(
|
||||
MB_PTR_ADV(s);
|
||||
}
|
||||
}
|
||||
msg_hist_off = TRUE;
|
||||
vim_snprintf((char *)IObuff, IOSIZE, "%s %s%s", lead,
|
||||
s > compl_shown_match->cp_fname ? "<" : "", s);
|
||||
msg((char *)IObuff);
|
||||
msg_hist_off = FALSE;
|
||||
redraw_cmdline = FALSE; // don't overwrite!
|
||||
}
|
||||
}
|
||||
@@ -3628,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;
|
||||
@@ -4110,9 +4115,13 @@ ins_complete(int c, int enable_pum)
|
||||
if (edit_submode_extra != NULL)
|
||||
{
|
||||
if (!p_smd)
|
||||
{
|
||||
msg_hist_off = TRUE;
|
||||
msg_attr((char *)edit_submode_extra,
|
||||
edit_submode_highl < HLF_COUNT
|
||||
? HL_ATTR(edit_submode_highl) : 0);
|
||||
msg_hist_off = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
msg_clr_cmdline(); // necessary for "noshowmode"
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+2
-2
@@ -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
|
||||
@@ -5799,7 +5799,7 @@ nv_suspend(cmdarg_T *cap)
|
||||
clearop(cap->oap);
|
||||
if (VIsual_active)
|
||||
end_visual_mode(); // stop Visual mode
|
||||
do_cmdline_cmd((char_u *)"st");
|
||||
do_cmdline_cmd((char_u *)"stop");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+7
-15
@@ -387,21 +387,13 @@ mch_FullName(
|
||||
int
|
||||
mch_isFullName(char_u *fname)
|
||||
{
|
||||
// WinNT and later can use _MAX_PATH wide characters for a pathname, which
|
||||
// means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is
|
||||
// UTF-8.
|
||||
char szName[_MAX_PATH * 3 + 1];
|
||||
|
||||
// A name like "d:/foo" and "//server/share" is absolute
|
||||
if ((fname[0] && fname[1] == ':' && (fname[2] == '/' || fname[2] == '\\'))
|
||||
|| (fname[0] == fname[1] && (fname[0] == '/' || fname[0] == '\\')))
|
||||
return TRUE;
|
||||
|
||||
// A name that can't be made absolute probably isn't absolute.
|
||||
if (mch_FullName(fname, (char_u *)szName, sizeof(szName) - 1, FALSE) == FAIL)
|
||||
return FALSE;
|
||||
|
||||
return pathcmp((const char *)fname, (const char *)szName, -1) == 0;
|
||||
// A name like "d:/foo" and "//server/share" is absolute. "d:foo" is not.
|
||||
// Another way to check is to use mch_FullName() and see if the result is
|
||||
// the same as the name or mch_FullName() fails. However, this has quite a
|
||||
// bit of overhead, so let's not do that.
|
||||
return ((ASCII_ISALPHA(fname[0]) && fname[1] == ':'
|
||||
&& (fname[2] == '/' || fname[2] == '\\'))
|
||||
|| (fname[0] == fname[1] && (fname[0] == '/' || fname[0] == '\\')));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+6
-7
@@ -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
|
||||
|
||||
+7
-8
@@ -3868,20 +3868,19 @@ update_popups(void (*win_update)(win_T *wp))
|
||||
}
|
||||
if (top_padding > 0)
|
||||
{
|
||||
// top padding; do not draw over the title
|
||||
row = wp->w_winrow + wp->w_popup_border[0];
|
||||
if (title_len > 0)
|
||||
if (title_len > 0 && row == wp->w_winrow)
|
||||
{
|
||||
screen_fill(row, row + top_padding, padcol, title_wincol,
|
||||
// top padding and no border; do not draw over the title
|
||||
screen_fill(row, row + 1, padcol, title_wincol,
|
||||
' ', ' ', popup_attr);
|
||||
screen_fill(row, row + top_padding, title_wincol + title_len,
|
||||
screen_fill(row, row + 1, title_wincol + title_len,
|
||||
padendcol, ' ', ' ', popup_attr);
|
||||
row += 1;
|
||||
top_padding -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
screen_fill(row, row + top_padding, padcol, padendcol,
|
||||
screen_fill(row, row + top_padding, padcol, padendcol,
|
||||
' ', ' ', popup_attr);
|
||||
}
|
||||
}
|
||||
|
||||
// Compute scrollbar thumb position and size.
|
||||
|
||||
@@ -59,7 +59,7 @@ void check_vars(char_u *name, int len);
|
||||
dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload);
|
||||
dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload);
|
||||
hashtab_T *get_script_local_ht(void);
|
||||
void *lookup_scriptvar(char_u *name, size_t len, cctx_T *dummy);
|
||||
int lookup_scriptvar(char_u *name, size_t len, void *lvar, cctx_T *dummy);
|
||||
hashtab_T *find_var_ht(char_u *name, char_u **varname);
|
||||
char_u *get_var_value(char_u *name);
|
||||
void new_script_vars(scid_T id);
|
||||
@@ -75,7 +75,7 @@ int var_check_lock(int flags, char_u *name, int use_gettext);
|
||||
int var_check_fixed(int flags, char_u *name, int use_gettext);
|
||||
int var_wrong_func_name(char_u *name, int new_var);
|
||||
int value_check_lock(int lock, char_u *name, int use_gettext);
|
||||
int valid_varname(char_u *varname);
|
||||
int valid_varname(char_u *varname, int autoload);
|
||||
void reset_v_option_vars(void);
|
||||
void assert_error(garray_T *gap);
|
||||
int var_exists(char_u *var);
|
||||
|
||||
@@ -13,7 +13,7 @@ void undo_cmdmod(cmdmod_T *cmod);
|
||||
int parse_cmd_address(exarg_T *eap, char **errormsg, int silent);
|
||||
int checkforcmd(char_u **pp, char *cmd, int len);
|
||||
char_u *skip_option_env_lead(char_u *start);
|
||||
char_u *find_ex_command(exarg_T *eap, int *full, void *(*lookup)(char_u *, size_t, cctx_T *), cctx_T *cctx);
|
||||
char_u *find_ex_command(exarg_T *eap, int *full, int (*lookup)(char_u *, size_t, void *, cctx_T *), cctx_T *cctx);
|
||||
int modifier_len(char_u *cmd);
|
||||
int cmd_exists(char_u *name);
|
||||
cmdidx_T excmd_get_cmdidx(char_u *cmd, int len);
|
||||
|
||||
@@ -10,6 +10,7 @@ varnumber_T tv_get_bool(typval_T *varp);
|
||||
varnumber_T tv_get_bool_chk(typval_T *varp, int *denote);
|
||||
float_T tv_get_float(typval_T *varp);
|
||||
int check_for_string(typval_T *tv);
|
||||
int check_for_nonempty_string(typval_T *tv);
|
||||
char_u *tv_get_string(typval_T *varp);
|
||||
char_u *tv_get_string_buf(typval_T *varp, char_u *buf);
|
||||
char_u *tv_get_string_chk(typval_T *varp);
|
||||
|
||||
+12
-7
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
>1+0&#ffffff0| @73
|
||||
|2| @73
|
||||
|3| @27| +0#0000001#ffd7ff255|T|i|t|l|e| @9| +0#0000000#ffffff0@29
|
||||
|4| @27| +0#0000001#ffd7ff255@15| +0#0000000#ffffff0@29
|
||||
|5| @27| +0#0000001#ffd7ff255@1|a@2| @10| +0#0000000#ffffff0@29
|
||||
|6| @27| +0#0000001#ffd7ff255@1|b@2| @10| +0#0000000#ffffff0@29
|
||||
|7| @27| +0#0000001#ffd7ff255@15| +0#0000000#ffffff0@29
|
||||
|8| @27| +0#0000001#ffd7ff255@15| +0#0000000#ffffff0@29
|
||||
|9| @73
|
||||
|:| @55|1|,|1| @10|T|o|p|
|
||||
@@ -0,0 +1,10 @@
|
||||
>1+0&#ffffff0| @73
|
||||
|2| @26|╔+0#0000001#ffd7ff255|T|i|t|l|e|═@10|╗| +0#0000000#ffffff0@28
|
||||
|3| @26|║+0#0000001#ffd7ff255| @15|║| +0#0000000#ffffff0@28
|
||||
|4| @26|║+0#0000001#ffd7ff255| @15|║| +0#0000000#ffffff0@28
|
||||
|5| @26|║+0#0000001#ffd7ff255| @1|a@2| @10|║| +0#0000000#ffffff0@28
|
||||
|6| @26|║+0#0000001#ffd7ff255| @1|b@2| @10|║| +0#0000000#ffffff0@28
|
||||
|7| @26|║+0#0000001#ffd7ff255| @15|║| +0#0000000#ffffff0@28
|
||||
|8| @26|║+0#0000001#ffd7ff255| @15|║| +0#0000000#ffffff0@28
|
||||
|9| @26|╚+0#0000001#ffd7ff255|═@15|╝| +0#0000000#ffffff0@28
|
||||
|:| @55|1|,|1| @10|T|o|p|
|
||||
@@ -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})
|
||||
|
||||
@@ -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\<CR>")
|
||||
call WaitForAssert({-> assert_match('^\d ', term_getline(buf, 6))}, 1000)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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' ] )
|
||||
|
||||
@@ -284,7 +284,7 @@ endfunc
|
||||
" 1
|
||||
" 1
|
||||
" 1
|
||||
" Expexted:
|
||||
" Expected:
|
||||
" 1) g Ctrl-A on block selected indented lines
|
||||
" 2
|
||||
" 1
|
||||
|
||||
@@ -114,7 +114,7 @@ func Test_omni_dash()
|
||||
set omnifunc=Omni
|
||||
new
|
||||
exe "normal Gofind -\<C-x>\<C-o>"
|
||||
call assert_equal("\n-\nmatch 1 of 2", execute(':2mess'))
|
||||
call assert_equal("find -help", getline('$'))
|
||||
|
||||
bwipe!
|
||||
delfunc Omni
|
||||
@@ -714,4 +714,16 @@ func Test_issue_7021()
|
||||
set completeslash=
|
||||
endfunc
|
||||
|
||||
" Test to ensure 'Scanning...' messages are not recorded in messages history
|
||||
func Test_z1_complete_no_history()
|
||||
new
|
||||
messages clear
|
||||
let currmess = execute('messages')
|
||||
setlocal dictionary=README.txt
|
||||
exe "normal owh\<C-X>\<C-K>"
|
||||
exe "normal owh\<C-N>"
|
||||
call assert_equal(currmess, execute('messages'))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -338,7 +338,7 @@ func Test_let_heredoc_fails()
|
||||
endfunc
|
||||
END
|
||||
call writefile(text, 'XheredocFail')
|
||||
call assert_fails('source XheredocFail', 'E126:')
|
||||
call assert_fails('source XheredocFail', 'E1145:')
|
||||
call delete('XheredocFail')
|
||||
|
||||
let text =<< trim CodeEnd
|
||||
@@ -347,7 +347,7 @@ func Test_let_heredoc_fails()
|
||||
endfunc
|
||||
CodeEnd
|
||||
call writefile(text, 'XheredocWrong')
|
||||
call assert_fails('source XheredocWrong', 'E126:')
|
||||
call assert_fails('source XheredocWrong', 'E1145:')
|
||||
call delete('XheredocWrong')
|
||||
|
||||
let text =<< trim TEXTend
|
||||
|
||||
@@ -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"<CR>
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -1766,6 +1766,16 @@ func Test_popup_title()
|
||||
call term_sendkeys(buf, ":\<CR>")
|
||||
call VerifyScreenDump(buf, 'Test_popupwin_longtitle_2', {})
|
||||
|
||||
call term_sendkeys(buf, ":call popup_clear()\<CR>")
|
||||
call term_sendkeys(buf, ":call popup_create(['aaa', 'bbb'], #{title: 'Title', minwidth: 12, padding: [2, 2, 2, 2]})\<CR>")
|
||||
call term_sendkeys(buf, ":\<CR>")
|
||||
call VerifyScreenDump(buf, 'Test_popupwin_longtitle_3', {})
|
||||
|
||||
call term_sendkeys(buf, ":call popup_clear()\<CR>")
|
||||
call term_sendkeys(buf, ":call popup_create(['aaa', 'bbb'], #{title: 'Title', minwidth: 12, border: [], padding: [2, 2, 2, 2]})\<CR>")
|
||||
call term_sendkeys(buf, ":\<CR>")
|
||||
call VerifyScreenDump(buf, 'Test_popupwin_longtitle_4', {})
|
||||
|
||||
" clean up
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('XtestPopupTitle')
|
||||
@@ -2663,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("\<BS>", 'xt')
|
||||
@@ -3297,7 +3308,7 @@ func Test_popupmenu_info_border()
|
||||
call term_sendkeys(buf, "cc\<C-X>\<C-U>")
|
||||
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, "\<Esc>")
|
||||
call term_sendkeys(buf, ":set hidden\<CR>")
|
||||
@@ -3711,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\<CR>")
|
||||
call StopVimInTerminal(buf)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:')
|
||||
|
||||
@@ -743,6 +743,53 @@ func Test_t_arg()
|
||||
call delete('Xfile1')
|
||||
endfunc
|
||||
|
||||
" Test the '-T' argument which sets the 'term' option.
|
||||
func Test_T_arg()
|
||||
CheckNotGui
|
||||
let after =<< trim [CODE]
|
||||
call writefile([&term], "Xtest_T_arg")
|
||||
qall
|
||||
[CODE]
|
||||
|
||||
for t in ['builtin_dumb', 'builtin_ansi']
|
||||
if RunVim([], after, '-T ' .. t)
|
||||
let lines = readfile('Xtest_T_arg')
|
||||
call assert_equal([t], lines)
|
||||
endif
|
||||
endfor
|
||||
|
||||
call delete('Xtest_T_arg')
|
||||
endfunc
|
||||
|
||||
" Test the '-x' argument to read/write encrypted files.
|
||||
func Test_x_arg()
|
||||
CheckRunVimInTerminal
|
||||
CheckFeature cryptv
|
||||
|
||||
" Create an encrypted file Xtest_x_arg.
|
||||
let buf = RunVimInTerminal('-n -x Xtest_x_arg', #{rows: 10, wait_for_ruler: 0})
|
||||
call WaitForAssert({-> assert_match('^Enter encryption key: ', term_getline(buf, 10))})
|
||||
call term_sendkeys(buf, "foo\n")
|
||||
call WaitForAssert({-> assert_match('^Enter same key again: ', term_getline(buf, 10))})
|
||||
call term_sendkeys(buf, "foo\n")
|
||||
call WaitForAssert({-> assert_match(' All$', term_getline(buf, 10))})
|
||||
call term_sendkeys(buf, "itest\<Esc>:w\<Enter>")
|
||||
call WaitForAssert({-> assert_match('"Xtest_x_arg" \[New\]\[blowfish2\] 1L, 5B written',
|
||||
\ term_getline(buf, 10))})
|
||||
call StopVimInTerminal(buf)
|
||||
|
||||
" Read the encrypted file and check that it contains the expected content "test"
|
||||
let buf = RunVimInTerminal('-n -x Xtest_x_arg', #{rows: 10, wait_for_ruler: 0})
|
||||
call WaitForAssert({-> assert_match('^Enter encryption key: ', term_getline(buf, 10))})
|
||||
call term_sendkeys(buf, "foo\n")
|
||||
call WaitForAssert({-> assert_match('^Enter same key again: ', term_getline(buf, 10))})
|
||||
call term_sendkeys(buf, "foo\n")
|
||||
call WaitForAssert({-> assert_match('^test', term_getline(buf, 1))})
|
||||
call StopVimInTerminal(buf)
|
||||
|
||||
call delete('Xtest_x_arg')
|
||||
endfunc
|
||||
|
||||
" Test for entering the insert mode on startup
|
||||
func Test_start_insertmode()
|
||||
let before =<< trim [CODE]
|
||||
|
||||
@@ -61,4 +61,48 @@ func Test_suspend()
|
||||
call delete('Xfoo')
|
||||
endfunc
|
||||
|
||||
func Test_suspend_autocmd()
|
||||
CheckFeature terminal
|
||||
CheckExecutable /bin/sh
|
||||
|
||||
let buf = term_start('/bin/sh', #{term_rows: 6})
|
||||
" Wait for shell prompt.
|
||||
call WaitForAssert({-> assert_match('[$#] $', term_getline(buf, '.'))})
|
||||
|
||||
call term_sendkeys(buf, v:progpath
|
||||
\ . " --clean -X"
|
||||
\ . " -c 'set nu'"
|
||||
\ . " -c 'let g:count = 0'"
|
||||
\ . " -c 'au VimSuspend * let g:count += 1'"
|
||||
\ . " -c 'au VimResume * let g:count += 1'"
|
||||
\ . " -c 'call setline(1, \"foo\")'"
|
||||
\ . " Xfoo\<CR>")
|
||||
" Cursor in terminal buffer should be on first line in spawned vim.
|
||||
call WaitForAssert({-> assert_equal(' 1 foo', term_getline(buf, '.'))})
|
||||
|
||||
for suspend_cmd in [":suspend\<CR>",
|
||||
\ ":stop\<CR>",
|
||||
\ ":suspend!\<CR>",
|
||||
\ ":stop!\<CR>",
|
||||
\ "\<C-Z>"]
|
||||
" Suspend and wait for shell prompt. Then "fg" will restore Vim.
|
||||
call term_sendkeys(buf, suspend_cmd)
|
||||
call CheckSuspended(buf, 0)
|
||||
endfor
|
||||
|
||||
call term_sendkeys(buf, ":echo g:count\<CR>")
|
||||
call TermWait(buf)
|
||||
call WaitForAssert({-> assert_match('^10', term_getline(buf, 6))})
|
||||
|
||||
" Quit gracefully to dump coverage information.
|
||||
call term_sendkeys(buf, ":qall!\<CR>")
|
||||
call TermWait(buf)
|
||||
" Wait until Vim actually exited and shell shows a prompt
|
||||
call WaitForAssert({-> assert_match('[$#] $', term_getline(buf, '.'))})
|
||||
call StopShellInTerminal(buf)
|
||||
|
||||
exe buf . 'bwipe!'
|
||||
call delete('Xfoo')
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -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("\<C-W>N", 'xt')
|
||||
call feedkeys("A", 'xt')
|
||||
call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))})
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -2199,5 +2199,30 @@ func Test_BufEnter_exception()
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
" Test for using try/catch in a user command with a failing expression {{{1
|
||||
func Test_user_command_try_catch()
|
||||
let lines =<< trim END
|
||||
function s:throw() abort
|
||||
throw 'error'
|
||||
endfunction
|
||||
|
||||
command! Execute
|
||||
\ try
|
||||
\ | let s:x = s:throw()
|
||||
\ | catch
|
||||
\ | let g:caught = 'caught'
|
||||
\ | endtry
|
||||
|
||||
let g:caught = 'no'
|
||||
Execute
|
||||
call assert_equal('caught', g:caught)
|
||||
END
|
||||
call writefile(lines, 'XtestTryCatch')
|
||||
source XtestTryCatch
|
||||
|
||||
call delete('XtestTryCatch')
|
||||
unlet g:caught
|
||||
endfunc
|
||||
|
||||
" Modeline {{{1
|
||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -326,6 +326,18 @@ def Test_assign_index()
|
||||
END
|
||||
CheckDefFailure(lines, 'E1012: Type mismatch; expected number but got dict<unknown>', 3)
|
||||
|
||||
lines =<< trim END
|
||||
var lines: list<string>
|
||||
lines['a'] = 'asdf'
|
||||
END
|
||||
CheckDefFailure(lines, 'E39:', 2)
|
||||
|
||||
lines =<< trim END
|
||||
var lines: string
|
||||
lines[9] = 'asdf'
|
||||
END
|
||||
CheckDefFailure(lines, 'E1141:', 2)
|
||||
|
||||
# list of dict
|
||||
var ld: list<dict<number>>
|
||||
ld[0] = {}
|
||||
@@ -379,6 +391,16 @@ def Test_extend_list()
|
||||
assert_equal(['a', 'b'], list)
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
var list: list<string>
|
||||
def Func()
|
||||
extend(list, ['x', 'b'])
|
||||
enddef
|
||||
Func()
|
||||
assert_equal(['x', 'b'], list)
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
@@ -572,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
|
||||
@@ -982,6 +1005,17 @@ def Test_heredoc()
|
||||
var&lines =<< trim END
|
||||
x
|
||||
x
|
||||
enddef
|
||||
defcompile
|
||||
[END]
|
||||
CheckScriptFailure(lines, 'E1145: Missing heredoc end marker: END')
|
||||
delfunc! g:Func
|
||||
|
||||
lines =<< trim [END]
|
||||
def Func()
|
||||
var lines =<< trim END
|
||||
x
|
||||
x
|
||||
x
|
||||
x
|
||||
x
|
||||
@@ -991,7 +1025,7 @@ def Test_heredoc()
|
||||
enddef
|
||||
call Func()
|
||||
[END]
|
||||
CheckScriptFailure(lines, 'E990:')
|
||||
CheckScriptFailure(lines, 'E1145: Missing heredoc end marker: END')
|
||||
delfunc! g:Func
|
||||
enddef
|
||||
|
||||
@@ -1185,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',
|
||||
|
||||
@@ -186,15 +186,17 @@ def Test_count()
|
||||
enddef
|
||||
|
||||
def Test_executable()
|
||||
assert_false(executable(""))
|
||||
assert_false(executable(test_null_string()))
|
||||
|
||||
CheckDefExecFailure(['echo executable(123)'], 'E928:')
|
||||
CheckDefExecFailure(['echo executable(true)'], 'E928:')
|
||||
CheckDefExecFailure(['echo executable(v:null)'], 'E928:')
|
||||
CheckDefExecFailure(['echo executable("")'], 'E928:')
|
||||
enddef
|
||||
|
||||
def Test_exepath()
|
||||
CheckDefExecFailure(['echo exepath(true)'], 'E928:')
|
||||
CheckDefExecFailure(['echo exepath(v:null)'], 'E928:')
|
||||
CheckDefExecFailure(['echo exepath("")'], 'E928:')
|
||||
CheckDefExecFailure(['echo exepath("")'], 'E1142:')
|
||||
enddef
|
||||
|
||||
def Test_expand()
|
||||
@@ -254,36 +256,42 @@ def Test_map_function_arg()
|
||||
enddef
|
||||
|
||||
def Test_filereadable()
|
||||
assert_false(filereadable(""))
|
||||
assert_false(filereadable(test_null_string()))
|
||||
|
||||
CheckDefExecFailure(['echo filereadable(123)'], 'E928:')
|
||||
CheckDefExecFailure(['echo filereadable(true)'], 'E928:')
|
||||
CheckDefExecFailure(['echo filereadable(v:null)'], 'E928:')
|
||||
CheckDefExecFailure(['echo filereadable("")'], 'E928:')
|
||||
enddef
|
||||
|
||||
def Test_filewritable()
|
||||
assert_false(filewritable(""))
|
||||
assert_false(filewritable(test_null_string()))
|
||||
|
||||
CheckDefExecFailure(['echo filewritable(123)'], 'E928:')
|
||||
CheckDefExecFailure(['echo filewritable(true)'], 'E928:')
|
||||
CheckDefExecFailure(['echo filewritable(v:null)'], 'E928:')
|
||||
CheckDefExecFailure(['echo filewritable("")'], 'E928:')
|
||||
enddef
|
||||
|
||||
def Test_finddir()
|
||||
CheckDefExecFailure(['echo finddir(true)'], 'E928:')
|
||||
CheckDefExecFailure(['echo finddir(v:null)'], 'E928:')
|
||||
CheckDefExecFailure(['echo finddir("")'], 'E928:')
|
||||
CheckDefExecFailure(['echo finddir("")'], 'E1142:')
|
||||
enddef
|
||||
|
||||
def Test_findfile()
|
||||
CheckDefExecFailure(['echo findfile(true)'], 'E928:')
|
||||
CheckDefExecFailure(['echo findfile(v:null)'], 'E928:')
|
||||
CheckDefExecFailure(['echo findfile("")'], 'E928:')
|
||||
CheckDefExecFailure(['echo findfile("")'], 'E1142:')
|
||||
enddef
|
||||
|
||||
def Test_fnamemodify()
|
||||
CheckDefSuccess(['echo fnamemodify(test_null_string(), ":p")'])
|
||||
CheckDefSuccess(['echo fnamemodify("", ":p")'])
|
||||
CheckDefSuccess(['echo fnamemodify("file", test_null_string())'])
|
||||
CheckDefSuccess(['echo fnamemodify("file", "")'])
|
||||
|
||||
CheckDefExecFailure(['echo fnamemodify(true, ":p")'], 'E928:')
|
||||
CheckDefExecFailure(['echo fnamemodify(v:null, ":p")'], 'E928:')
|
||||
CheckDefExecFailure(['echo fnamemodify("", ":p")'], 'E928:')
|
||||
CheckDefExecFailure(['echo fnamemodify("file", true)'], 'E928:')
|
||||
CheckDefExecFailure(['echo fnamemodify("file", v:null)'], 'E928:')
|
||||
CheckDefExecFailure(['echo fnamemodify("file", "")'], 'E928:')
|
||||
enddef
|
||||
|
||||
def Test_filter_wrong_dict_key_type()
|
||||
@@ -359,27 +367,35 @@ def Test_getloclist_return_type()
|
||||
enddef
|
||||
|
||||
def Test_getfperm()
|
||||
assert_equal('', getfperm(""))
|
||||
assert_equal('', getfperm(test_null_string()))
|
||||
|
||||
CheckDefExecFailure(['echo getfperm(true)'], 'E928:')
|
||||
CheckDefExecFailure(['echo getfperm(v:null)'], 'E928:')
|
||||
CheckDefExecFailure(['echo getfperm("")'], 'E928:')
|
||||
enddef
|
||||
|
||||
def Test_getfsize()
|
||||
assert_equal(-1, getfsize(""))
|
||||
assert_equal(-1, getfsize(test_null_string()))
|
||||
|
||||
CheckDefExecFailure(['echo getfsize(true)'], 'E928:')
|
||||
CheckDefExecFailure(['echo getfsize(v:null)'], 'E928:')
|
||||
CheckDefExecFailure(['echo getfsize("")'], 'E928:')
|
||||
enddef
|
||||
|
||||
def Test_getftime()
|
||||
assert_equal(-1, getftime(""))
|
||||
assert_equal(-1, getftime(test_null_string()))
|
||||
|
||||
CheckDefExecFailure(['echo getftime(true)'], 'E928:')
|
||||
CheckDefExecFailure(['echo getftime(v:null)'], 'E928:')
|
||||
CheckDefExecFailure(['echo getftime("")'], 'E928:')
|
||||
enddef
|
||||
|
||||
def Test_getftype()
|
||||
assert_equal('', getftype(""))
|
||||
assert_equal('', getftype(test_null_string()))
|
||||
|
||||
CheckDefExecFailure(['echo getftype(true)'], 'E928:')
|
||||
CheckDefExecFailure(['echo getftype(v:null)'], 'E928:')
|
||||
CheckDefExecFailure(['echo getftype("")'], 'E928:')
|
||||
enddef
|
||||
|
||||
def Test_getqflist_return_type()
|
||||
|
||||
@@ -20,6 +20,9 @@ def Test_edit_wildcards()
|
||||
|
||||
edit X`=filename`xx`=filenr`yy
|
||||
assert_equal('XXtestxx77yy', bufname())
|
||||
|
||||
CheckDefFailure(['edit `=xxx`'], 'E1001:')
|
||||
CheckDefFailure(['edit `="foo"'], 'E1083:')
|
||||
enddef
|
||||
|
||||
def Test_hardcopy_wildcards()
|
||||
@@ -626,6 +629,20 @@ def Test_put_command()
|
||||
assert_equal('aaa', getline(4))
|
||||
|
||||
bwipe!
|
||||
|
||||
CheckDefFailure(['put =xxx'], 'E1001:')
|
||||
enddef
|
||||
|
||||
def Test_put_with_linebreak()
|
||||
new
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
pu =split('abc', '\zs')
|
||||
->join()
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
getline(2)->assert_equal('a b c')
|
||||
bwipe!
|
||||
enddef
|
||||
|
||||
def Test_command_star_range()
|
||||
@@ -684,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
|
||||
|
||||
@@ -15,6 +15,7 @@ let t:tabpagevar = 't'
|
||||
def s:ScriptFuncLoad(arg: string)
|
||||
var local = 1
|
||||
buffers
|
||||
echo
|
||||
echo arg
|
||||
echo local
|
||||
echo &lines
|
||||
@@ -22,6 +23,7 @@ def s:ScriptFuncLoad(arg: string)
|
||||
echo s:scriptvar
|
||||
echo g:globalvar
|
||||
echo get(g:, "global")
|
||||
echo g:auto#var
|
||||
echo b:buffervar
|
||||
echo get(b:, "buffer")
|
||||
echo w:windowvar
|
||||
@@ -43,19 +45,38 @@ def Test_disassemble_load()
|
||||
|
||||
var res = execute('disass s:ScriptFuncLoad')
|
||||
assert_match('<SNR>\d*_ScriptFuncLoad.*' ..
|
||||
'buffers.*' ..
|
||||
' EXEC \+buffers.*' ..
|
||||
' LOAD arg\[-1\].*' ..
|
||||
' LOAD $0.*' ..
|
||||
' LOADOPT &lines.*' ..
|
||||
' LOADV v:version.*' ..
|
||||
' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*' ..
|
||||
' LOADG g:globalvar.*' ..
|
||||
'buffers\_s*' ..
|
||||
'\d\+ EXEC \+buffers\_s*' ..
|
||||
'echo\_s*' ..
|
||||
'echo arg\_s*' ..
|
||||
'\d\+ LOAD arg\[-1\]\_s*' ..
|
||||
'\d\+ ECHO 1\_s*' ..
|
||||
'echo local\_s*' ..
|
||||
'\d\+ LOAD $0\_s*' ..
|
||||
'\d\+ ECHO 1\_s*' ..
|
||||
'echo &lines\_s*' ..
|
||||
'\d\+ LOADOPT &lines\_s*' ..
|
||||
'\d\+ ECHO 1\_s*' ..
|
||||
'echo v:version\_s*' ..
|
||||
'\d\+ LOADV v:version\_s*' ..
|
||||
'\d\+ ECHO 1\_s*' ..
|
||||
'echo s:scriptvar\_s*' ..
|
||||
'\d\+ LOADS s:scriptvar from .*test_vim9_disassemble.vim\_s*' ..
|
||||
'\d\+ ECHO 1\_s*' ..
|
||||
'echo g:globalvar\_s*' ..
|
||||
'\d\+ LOADG g:globalvar\_s*' ..
|
||||
'\d\+ ECHO 1\_s*' ..
|
||||
'echo get(g:, "global")\_s*' ..
|
||||
'\d\+ LOAD g:\_s*' ..
|
||||
'\d\+ PUSHS "global"\_s*' ..
|
||||
'\d\+ BCALL get(argc 2).*' ..
|
||||
' LOADB b:buffervar.*' ..
|
||||
'\d\+ BCALL get(argc 2)\_s*' ..
|
||||
'\d\+ ECHO 1\_s*' ..
|
||||
'echo g:auto#var\_s*' ..
|
||||
'\d\+ LOADAUTO g:auto#var\_s*' ..
|
||||
'\d\+ ECHO 1\_s*' ..
|
||||
'echo b:buffervar\_s*' ..
|
||||
'\d\+ LOADB b:buffervar\_s*' ..
|
||||
'\d\+ ECHO 1\_s*' ..
|
||||
'echo get(b:, "buffer")\_s*' ..
|
||||
'\d\+ LOAD b:\_s*' ..
|
||||
'\d\+ PUSHS "buffer"\_s*' ..
|
||||
@@ -183,6 +204,7 @@ def s:ScriptFuncStore()
|
||||
v:char = 'abc'
|
||||
s:scriptvar = 'sv'
|
||||
g:globalvar = 'gv'
|
||||
g:auto#var = 'av'
|
||||
b:buffervar = 'bv'
|
||||
w:windowvar = 'wv'
|
||||
t:tabpagevar = 'tv'
|
||||
@@ -206,6 +228,8 @@ def Test_disassemble_store()
|
||||
' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
|
||||
'g:globalvar = ''gv''.*' ..
|
||||
' STOREG g:globalvar.*' ..
|
||||
'g:auto#var = ''av''.*' ..
|
||||
' STOREAUTO g:auto#var.*' ..
|
||||
'b:buffervar = ''bv''.*' ..
|
||||
' STOREB b:buffervar.*' ..
|
||||
'w:windowvar = ''wv''.*' ..
|
||||
|
||||
@@ -1317,6 +1317,23 @@ func Test_expr5_fails_channel()
|
||||
call CheckDefFailure(["var x = 'a' .. test_null_channel()"], 'E1105:', 1)
|
||||
endfunc
|
||||
|
||||
def Test_expr5_list_add()
|
||||
# concatenating two lists with same member types is OK
|
||||
var d = {}
|
||||
for i in ['a'] + ['b']
|
||||
d = {[i]: 0}
|
||||
endfor
|
||||
|
||||
# concatenating two lists with different member types results in "any"
|
||||
var lines =<< trim END
|
||||
var d = {}
|
||||
for i in ['a'] + [0]
|
||||
d = {[i]: 0}
|
||||
endfor
|
||||
END
|
||||
CheckDefExecFailure(lines, 'E1012:')
|
||||
enddef
|
||||
|
||||
" test multiply, divide, modulo
|
||||
def Test_expr6()
|
||||
var lines =<< trim END
|
||||
@@ -1972,6 +1989,14 @@ def Test_expr7_dict()
|
||||
|
||||
CheckDefFailure(['var x = ({'], 'E723:', 2)
|
||||
CheckDefExecFailure(['{}[getftype("file")]'], 'E716: Key not present in Dictionary: ""', 1)
|
||||
|
||||
# no automatic conversion from number to string
|
||||
lines =<< trim END
|
||||
var n = 123
|
||||
var d = {[n]: 1}
|
||||
END
|
||||
CheckDefFailure(lines, 'E1012:', 2)
|
||||
CheckScriptFailure(['vim9script'] + lines, 'E928:', 3)
|
||||
enddef
|
||||
|
||||
def Test_expr7_dict_vim9script()
|
||||
|
||||
@@ -481,6 +481,12 @@ def Test_call_lambda_args()
|
||||
CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
|
||||
enddef
|
||||
|
||||
def Test_lambda_uses_assigned_var()
|
||||
CheckDefSuccess([
|
||||
'var x: any = "aaa"'
|
||||
'x = filter(["bbb"], {_, v -> v =~ x})'])
|
||||
enddef
|
||||
|
||||
" Default arg and varargs
|
||||
def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
|
||||
var res = one .. ',' .. two
|
||||
@@ -1818,6 +1824,26 @@ def Test_reset_did_emsg()
|
||||
delfunc! g:Func
|
||||
enddef
|
||||
|
||||
def Test_did_emsg_reset()
|
||||
# executing an autocommand resets did_emsg, this should not result in a
|
||||
# builtin function considered failing
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
au BufWinLeave * #
|
||||
def Func()
|
||||
popup_menu('', {callback: {-> popup_create('', {})->popup_close()}})
|
||||
eval [][0]
|
||||
enddef
|
||||
nno <F3> <cmd>call <sid>Func()<cr>
|
||||
feedkeys("\<F3>\e", 'xt')
|
||||
END
|
||||
writefile(lines, 'XemsgReset')
|
||||
assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
|
||||
delete('XemsgReset')
|
||||
nunmap <F3>
|
||||
au! BufWinLeave
|
||||
enddef
|
||||
|
||||
def Test_abort_with_silent_call()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
|
||||
@@ -23,6 +23,11 @@ def Test_range_only()
|
||||
list
|
||||
assert_equal('three$', Screenline(&lines))
|
||||
bwipe!
|
||||
|
||||
# won't generate anything
|
||||
if false
|
||||
:123
|
||||
endif
|
||||
enddef
|
||||
|
||||
let g:alist = [7]
|
||||
@@ -620,7 +625,7 @@ def Test_try_catch_fails()
|
||||
CheckDefFailure(['if 1', 'endtry'], 'E171:')
|
||||
CheckDefFailure(['try', 'echo 1', 'endtry'], 'E1032:')
|
||||
|
||||
CheckDefFailure(['throw'], 'E1015:')
|
||||
CheckDefFailure(['throw'], 'E1143:')
|
||||
CheckDefFailure(['throw xxx'], 'E1001:')
|
||||
enddef
|
||||
|
||||
@@ -1719,6 +1724,10 @@ def Test_nested_if()
|
||||
enddef
|
||||
|
||||
def Test_execute_cmd()
|
||||
# missing argument is ignored
|
||||
execute
|
||||
execute # comment
|
||||
|
||||
new
|
||||
setline(1, 'default')
|
||||
execute 'setline(1, "execute-string")'
|
||||
@@ -1886,6 +1895,9 @@ def Test_for_loop()
|
||||
enddef
|
||||
|
||||
def Test_for_loop_fails()
|
||||
CheckDefFailure(['for '], 'E1097:')
|
||||
CheckDefFailure(['for x'], 'E1097:')
|
||||
CheckDefFailure(['for x in'], 'E1097:')
|
||||
CheckDefFailure(['for # in range(5)'], 'E690:')
|
||||
CheckDefFailure(['for i In range(5)'], 'E690:')
|
||||
CheckDefFailure(['var x = 5', 'for x in range(5)'], 'E1017:')
|
||||
@@ -2069,7 +2081,21 @@ def Test_vim9_comment()
|
||||
CheckScriptSuccess([
|
||||
'vim9script',
|
||||
'# something',
|
||||
'#something',
|
||||
'#{something',
|
||||
])
|
||||
|
||||
split Xfile
|
||||
CheckScriptSuccess([
|
||||
'vim9script',
|
||||
'edit #something',
|
||||
])
|
||||
CheckScriptSuccess([
|
||||
'vim9script',
|
||||
'edit #{something',
|
||||
])
|
||||
close
|
||||
|
||||
CheckScriptFailure([
|
||||
'vim9script',
|
||||
':# something',
|
||||
@@ -2123,9 +2149,6 @@ def Test_vim9_comment()
|
||||
'vim9script',
|
||||
'exe "echo"# something',
|
||||
], 'E121:')
|
||||
CheckDefFailure([
|
||||
'exe # comment',
|
||||
], 'E1015:')
|
||||
CheckScriptFailure([
|
||||
'vim9script',
|
||||
'exe# something',
|
||||
@@ -2150,7 +2173,7 @@ def Test_vim9_comment()
|
||||
' throw#comment',
|
||||
'catch',
|
||||
'endtry',
|
||||
], 'E1015:')
|
||||
], 'E1143:')
|
||||
CheckDefFailure([
|
||||
'try',
|
||||
' throw "yes"#comment',
|
||||
@@ -2756,8 +2779,42 @@ def Test_vim9_copen()
|
||||
quit
|
||||
enddef
|
||||
|
||||
" test using a vim9script that is auto-loaded from an autocmd
|
||||
" test using an auto-loaded function and variable
|
||||
def Test_vim9_autoload()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
def some#gettest(): string
|
||||
return 'test'
|
||||
enddef
|
||||
g:some#name = 'name'
|
||||
END
|
||||
|
||||
mkdir('Xdir/autoload', 'p')
|
||||
writefile(lines, 'Xdir/autoload/some.vim')
|
||||
var save_rtp = &rtp
|
||||
exe 'set rtp^=' .. getcwd() .. '/Xdir'
|
||||
|
||||
assert_equal('test', g:some#gettest())
|
||||
assert_equal('name', g:some#name)
|
||||
g:some#other = 'other'
|
||||
assert_equal('other', g:some#other)
|
||||
|
||||
# upper case script name works
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
def Other#getOther(): string
|
||||
return 'other'
|
||||
enddef
|
||||
END
|
||||
writefile(lines, 'Xdir/autoload/Other.vim')
|
||||
assert_equal('other', g:Other#getOther())
|
||||
|
||||
delete('Xdir', 'rf')
|
||||
&rtp = save_rtp
|
||||
enddef
|
||||
|
||||
" test using a vim9script that is auto-loaded from an autocmd
|
||||
def Test_vim9_aucmd_autoload()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
def foo#test()
|
||||
@@ -2819,6 +2876,12 @@ def Test_vim9_autoload_error()
|
||||
delete('Xdidit')
|
||||
delete('Xscript')
|
||||
delete('Xruntime', 'rf')
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
var foo#bar = 'asdf'
|
||||
END
|
||||
CheckScriptFailure(lines, 'E461: Illegal variable name: foo#bar', 2)
|
||||
enddef
|
||||
|
||||
def Test_script_var_in_autocmd()
|
||||
@@ -3039,18 +3102,6 @@ def Test_no_unknown_error_after_error()
|
||||
delete('Xdef')
|
||||
enddef
|
||||
|
||||
def Test_put_with_linebreak()
|
||||
new
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
pu=split('abc', '\zs')
|
||||
->join()
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
getline(2)->assert_equal('a b c')
|
||||
bwipe!
|
||||
enddef
|
||||
|
||||
def InvokeNormal()
|
||||
exe "norm! :m+1\r"
|
||||
enddef
|
||||
@@ -3064,6 +3115,13 @@ def Test_invoke_normal_in_visual_mode()
|
||||
xunmap <F3>
|
||||
enddef
|
||||
|
||||
def Test_white_space_after_command()
|
||||
var lines =<< trim END
|
||||
exit_cb: Func})
|
||||
END
|
||||
CheckDefAndScriptFailure(lines, 'E1144:', 1)
|
||||
enddef
|
||||
|
||||
" Keep this last, it messes up highlighting.
|
||||
def Test_substitute_cmd()
|
||||
new
|
||||
|
||||
@@ -6825,7 +6825,7 @@ func Test_script_lines()
|
||||
\ ])
|
||||
call assert_report("Shouldn't be able to define function")
|
||||
catch
|
||||
call assert_exception('Vim(function):E126: Missing :endfunction')
|
||||
call assert_exception('Vim(function):E1145: Missing heredoc end marker: .')
|
||||
endtry
|
||||
|
||||
" :change
|
||||
@@ -6845,7 +6845,7 @@ func Test_script_lines()
|
||||
\ ])
|
||||
call assert_report("Shouldn't be able to define function")
|
||||
catch
|
||||
call assert_exception('Vim(function):E126: Missing :endfunction')
|
||||
call assert_exception('Vim(function):E1145: Missing heredoc end marker: .')
|
||||
endtry
|
||||
|
||||
" :insert
|
||||
@@ -6865,7 +6865,7 @@ func Test_script_lines()
|
||||
\ ])
|
||||
call assert_report("Shouldn't be able to define function")
|
||||
catch
|
||||
call assert_exception('Vim(function):E126: Missing :endfunction')
|
||||
call assert_exception('Vim(function):E1145: Missing heredoc end marker: .')
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
@@ -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() "#
|
||||
|
||||
+2
-2
@@ -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),
|
||||
|
||||
+18
-4
@@ -341,14 +341,12 @@ tv_get_float(typval_T *varp)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Give an error and return FAIL unless "tv" is a non-empty string.
|
||||
* Give an error and return FAIL unless "tv" is a string.
|
||||
*/
|
||||
int
|
||||
check_for_string(typval_T *tv)
|
||||
{
|
||||
if (tv->v_type != VAR_STRING
|
||||
|| tv->vval.v_string == NULL
|
||||
|| *tv->vval.v_string == NUL)
|
||||
if (tv->v_type != VAR_STRING)
|
||||
{
|
||||
emsg(_(e_stringreq));
|
||||
return FAIL;
|
||||
@@ -356,6 +354,22 @@ check_for_string(typval_T *tv)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Give an error and return FAIL unless "tv" is a non-empty string.
|
||||
*/
|
||||
int
|
||||
check_for_nonempty_string(typval_T *tv)
|
||||
{
|
||||
if (check_for_string(tv) == FAIL)
|
||||
return FAIL;
|
||||
if (tv->vval.v_string == NULL || *tv->vval.v_string == NUL)
|
||||
{
|
||||
emsg(_(e_non_empty_string_required));
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the string value of a variable.
|
||||
* If it is a Number variable, the number is converted into a string.
|
||||
|
||||
+25
-6
@@ -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
|
||||
@@ -2654,8 +2654,18 @@ trans_function_name(
|
||||
goto theend;
|
||||
}
|
||||
|
||||
// In Vim9 script a user function is script-local by default.
|
||||
// In Vim9 script a user function is script-local by default, unless it
|
||||
// starts with a lower case character: dict.func().
|
||||
vim9script = ASCII_ISUPPER(*start) && in_vim9script();
|
||||
if (vim9script)
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
// SomeScript#func() is a global function.
|
||||
for (p = start; *p != NUL && *p != '('; ++p)
|
||||
if (*p == AUTOLOAD_CHAR)
|
||||
vim9script = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the function name to allocated memory.
|
||||
@@ -3185,7 +3195,9 @@ define_function(exarg_T *eap, char_u *name_arg)
|
||||
lines_left = Rows - 1;
|
||||
if (theline == NULL)
|
||||
{
|
||||
if (eap->cmdidx == CMD_def)
|
||||
if (skip_until != NULL)
|
||||
semsg(_(e_missing_heredoc_end_marker_str), skip_until);
|
||||
else if (eap->cmdidx == CMD_def)
|
||||
emsg(_(e_missing_enddef));
|
||||
else
|
||||
emsg(_("E126: Missing :endfunction"));
|
||||
@@ -3352,18 +3364,24 @@ define_function(exarg_T *eap, char_u *name_arg)
|
||||
|
||||
// Check for ":cmd v =<< [trim] EOF"
|
||||
// and ":cmd [a, b] =<< [trim] EOF"
|
||||
// and "lines =<< [trim] EOF" for Vim9
|
||||
// Where "cmd" can be "let", "var", "final" or "const".
|
||||
arg = skipwhite(skiptowhite(p));
|
||||
if (*arg == '[')
|
||||
arg = vim_strchr(arg, ']');
|
||||
if (arg != NULL)
|
||||
{
|
||||
arg = skipwhite(skiptowhite(arg));
|
||||
if (arg[0] == '=' && arg[1] == '<' && arg[2] =='<'
|
||||
int found = (eap->cmdidx == CMD_def && arg[0] == '='
|
||||
&& arg[1] == '<' && arg[2] =='<');
|
||||
|
||||
if (!found)
|
||||
// skip over the argument after "cmd"
|
||||
arg = skipwhite(skiptowhite(arg));
|
||||
if (found || (arg[0] == '=' && arg[1] == '<' && arg[2] =='<'
|
||||
&& (checkforcmd(&p, "let", 2)
|
||||
|| checkforcmd(&p, "var", 3)
|
||||
|| checkforcmd(&p, "final", 5)
|
||||
|| checkforcmd(&p, "const", 5)))
|
||||
|| checkforcmd(&p, "const", 5))))
|
||||
{
|
||||
p = skipwhite(arg + 3);
|
||||
if (STRNCMP(p, "trim", 4) == 0)
|
||||
@@ -3697,6 +3715,7 @@ errret_2:
|
||||
ret_free:
|
||||
ga_clear_strings(&argtypes);
|
||||
vim_free(skip_until);
|
||||
vim_free(heredoc_trimmed);
|
||||
vim_free(line_to_free);
|
||||
vim_free(fudi.fd_newkey);
|
||||
if (name != name_arg)
|
||||
|
||||
@@ -765,6 +765,80 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2164,
|
||||
/**/
|
||||
2163,
|
||||
/**/
|
||||
2162,
|
||||
/**/
|
||||
2161,
|
||||
/**/
|
||||
2160,
|
||||
/**/
|
||||
2159,
|
||||
/**/
|
||||
2158,
|
||||
/**/
|
||||
2157,
|
||||
/**/
|
||||
2156,
|
||||
/**/
|
||||
2155,
|
||||
/**/
|
||||
2154,
|
||||
/**/
|
||||
2153,
|
||||
/**/
|
||||
2152,
|
||||
/**/
|
||||
2151,
|
||||
/**/
|
||||
2150,
|
||||
/**/
|
||||
2149,
|
||||
/**/
|
||||
2148,
|
||||
/**/
|
||||
2147,
|
||||
/**/
|
||||
2146,
|
||||
/**/
|
||||
2145,
|
||||
/**/
|
||||
2144,
|
||||
/**/
|
||||
2143,
|
||||
/**/
|
||||
2142,
|
||||
/**/
|
||||
2141,
|
||||
/**/
|
||||
2140,
|
||||
/**/
|
||||
2139,
|
||||
/**/
|
||||
2138,
|
||||
/**/
|
||||
2137,
|
||||
/**/
|
||||
2136,
|
||||
/**/
|
||||
2135,
|
||||
/**/
|
||||
2134,
|
||||
/**/
|
||||
2133,
|
||||
/**/
|
||||
2132,
|
||||
/**/
|
||||
2131,
|
||||
/**/
|
||||
2130,
|
||||
/**/
|
||||
2129,
|
||||
/**/
|
||||
2128,
|
||||
/**/
|
||||
2127,
|
||||
/**/
|
||||
|
||||
@@ -1353,6 +1353,8 @@ enum auto_event
|
||||
EVENT_WINENTER, // after entering a window
|
||||
EVENT_WINLEAVE, // before leaving a window
|
||||
EVENT_WINNEW, // when entering a new window
|
||||
EVENT_VIMSUSPEND, // before Vim is suspended
|
||||
EVENT_VIMRESUME, // after Vim is resumed
|
||||
|
||||
NUM_EVENTS // MUST be the last one
|
||||
};
|
||||
|
||||
+3
-1
@@ -24,6 +24,7 @@ typedef enum {
|
||||
ISN_LOAD, // push local variable isn_arg.number
|
||||
ISN_LOADV, // push v: variable isn_arg.number
|
||||
ISN_LOADG, // push g: variable isn_arg.string
|
||||
ISN_LOADAUTO, // push g: autoload variable isn_arg.string
|
||||
ISN_LOADB, // push b: variable isn_arg.string
|
||||
ISN_LOADW, // push w: variable isn_arg.string
|
||||
ISN_LOADT, // push t: variable isn_arg.string
|
||||
@@ -41,6 +42,7 @@ typedef enum {
|
||||
ISN_STORE, // pop into local variable isn_arg.number
|
||||
ISN_STOREV, // pop into v: variable isn_arg.number
|
||||
ISN_STOREG, // pop into global variable isn_arg.string
|
||||
ISN_STOREAUTO, // pop into global autoload variable isn_arg.string
|
||||
ISN_STOREB, // pop into buffer-local variable isn_arg.string
|
||||
ISN_STOREW, // pop into window-local variable isn_arg.string
|
||||
ISN_STORET, // pop into tab-local variable isn_arg.string
|
||||
@@ -53,7 +55,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
|
||||
|
||||
+100
-70
@@ -148,45 +148,51 @@ struct cctx_S {
|
||||
static void delete_def_function_contents(dfunc_T *dfunc);
|
||||
|
||||
/*
|
||||
* Lookup variable "name" in the local scope and return it.
|
||||
* Return NULL if not found.
|
||||
* Lookup variable "name" in the local scope and return it in "lvar".
|
||||
* "lvar->lv_from_outer" is set accordingly.
|
||||
* If "lvar" is NULL only check if the variable can be found.
|
||||
* Return FAIL if not found.
|
||||
*/
|
||||
static lvar_T *
|
||||
lookup_local(char_u *name, size_t len, cctx_T *cctx)
|
||||
static int
|
||||
lookup_local(char_u *name, size_t len, lvar_T *lvar, cctx_T *cctx)
|
||||
{
|
||||
int idx;
|
||||
lvar_T *lvar;
|
||||
lvar_T *lvp;
|
||||
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
return FAIL;
|
||||
|
||||
// Find local in current function scope.
|
||||
for (idx = 0; idx < cctx->ctx_locals.ga_len; ++idx)
|
||||
{
|
||||
lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
|
||||
if (STRNCMP(name, lvar->lv_name, len) == 0
|
||||
&& STRLEN(lvar->lv_name) == len)
|
||||
lvp = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
|
||||
if (STRNCMP(name, lvp->lv_name, len) == 0
|
||||
&& STRLEN(lvp->lv_name) == len)
|
||||
{
|
||||
lvar->lv_from_outer = FALSE;
|
||||
return lvar;
|
||||
if (lvar != NULL)
|
||||
{
|
||||
*lvar = *lvp;
|
||||
lvar->lv_from_outer = FALSE;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Find local in outer function scope.
|
||||
if (cctx->ctx_outer != NULL)
|
||||
{
|
||||
lvar = lookup_local(name, len, cctx->ctx_outer);
|
||||
if (lvar != NULL)
|
||||
if (lookup_local(name, len, lvar, cctx->ctx_outer) == OK)
|
||||
{
|
||||
// TODO: are there situations we should not mark the outer scope as
|
||||
// used?
|
||||
cctx->ctx_outer_used = TRUE;
|
||||
lvar->lv_from_outer = TRUE;
|
||||
return lvar;
|
||||
if (lvar != NULL)
|
||||
{
|
||||
cctx->ctx_outer_used = TRUE;
|
||||
lvar->lv_from_outer = TRUE;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -312,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()
|
||||
@@ -377,7 +383,7 @@ check_defined(char_u *p, size_t len, cctx_T *cctx)
|
||||
p[len] = NUL;
|
||||
if (script_var_exists(p, len, FALSE, cctx) == OK
|
||||
|| (cctx != NULL
|
||||
&& (lookup_local(p, len, cctx) != NULL
|
||||
&& (lookup_local(p, len, NULL, cctx) == OK
|
||||
|| arg_exists(p, len, NULL, NULL, NULL, cctx) == OK))
|
||||
|| find_imported(p, len, cctx) != NULL
|
||||
|| (ufunc = find_func_even_dead(p, FALSE, cctx)) != NULL)
|
||||
@@ -532,14 +538,15 @@ generate_add_instr(
|
||||
type_T *type1,
|
||||
type_T *type2)
|
||||
{
|
||||
isn_T *isn = generate_instr_drop(cctx,
|
||||
vartype == VAR_NUMBER ? ISN_OPNR
|
||||
: vartype == VAR_LIST ? ISN_ADDLIST
|
||||
: vartype == VAR_BLOB ? ISN_ADDBLOB
|
||||
garray_T *stack = &cctx->ctx_type_stack;
|
||||
isn_T *isn = generate_instr_drop(cctx,
|
||||
vartype == VAR_NUMBER ? ISN_OPNR
|
||||
: vartype == VAR_LIST ? ISN_ADDLIST
|
||||
: vartype == VAR_BLOB ? ISN_ADDBLOB
|
||||
#ifdef FEAT_FLOAT
|
||||
: vartype == VAR_FLOAT ? ISN_OPFLOAT
|
||||
: vartype == VAR_FLOAT ? ISN_OPFLOAT
|
||||
#endif
|
||||
: ISN_OPANY, 1);
|
||||
: ISN_OPANY, 1);
|
||||
|
||||
if (vartype != VAR_LIST && vartype != VAR_BLOB
|
||||
&& type1->tt_type != VAR_ANY
|
||||
@@ -550,6 +557,14 @@ generate_add_instr(
|
||||
|
||||
if (isn != NULL)
|
||||
isn->isn_arg.op.op_type = EXPR_ADD;
|
||||
|
||||
// When concatenating two lists with different member types the member type
|
||||
// becomes "any".
|
||||
if (vartype == VAR_LIST
|
||||
&& type1->tt_type == VAR_LIST && type2->tt_type == VAR_LIST
|
||||
&& type1->tt_member != type2->tt_member)
|
||||
(((type_T **)stack->ga_data)[stack->ga_len - 1]) = &t_list_any;
|
||||
|
||||
return isn == NULL ? FAIL : OK;
|
||||
}
|
||||
|
||||
@@ -1943,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;
|
||||
}
|
||||
|
||||
@@ -2520,7 +2535,17 @@ compile_load(
|
||||
case 's': res = compile_load_scriptvar(cctx, name,
|
||||
NULL, NULL, error);
|
||||
break;
|
||||
case 'g': isn_type = ISN_LOADG; break;
|
||||
case 'g': if (vim_strchr(name, AUTOLOAD_CHAR) == NULL)
|
||||
isn_type = ISN_LOADG;
|
||||
else
|
||||
{
|
||||
isn_type = ISN_LOADAUTO;
|
||||
vim_free(name);
|
||||
name = vim_strnsave(*arg, end - *arg);
|
||||
if (name == NULL)
|
||||
return FAIL;
|
||||
}
|
||||
break;
|
||||
case 'w': isn_type = ISN_LOADW; break;
|
||||
case 't': isn_type = ISN_LOADT; break;
|
||||
case 'b': isn_type = ISN_LOADB; break;
|
||||
@@ -2555,13 +2580,13 @@ compile_load(
|
||||
}
|
||||
else
|
||||
{
|
||||
lvar_T *lvar = lookup_local(*arg, len, cctx);
|
||||
lvar_T lvar;
|
||||
|
||||
if (lvar != NULL)
|
||||
if (lookup_local(*arg, len, &lvar, cctx) == OK)
|
||||
{
|
||||
type = lvar->lv_type;
|
||||
idx = lvar->lv_idx;
|
||||
if (lvar->lv_from_outer)
|
||||
type = lvar.lv_type;
|
||||
idx = lvar.lv_idx;
|
||||
if (lvar.lv_from_outer)
|
||||
gen_load_outer = TRUE;
|
||||
else
|
||||
gen_load = TRUE;
|
||||
@@ -2723,7 +2748,7 @@ compile_call(
|
||||
if (compile_arguments(arg, cctx, &argcount) == FAIL)
|
||||
goto theend;
|
||||
|
||||
is_autoload = vim_strchr(name, '#') != NULL;
|
||||
is_autoload = vim_strchr(name, AUTOLOAD_CHAR) != NULL;
|
||||
if (ASCII_ISLOWER(*name) && name[1] != ':' && !is_autoload)
|
||||
{
|
||||
int idx;
|
||||
@@ -2763,7 +2788,7 @@ compile_call(
|
||||
|
||||
// An argument or local variable can be a function reference, this
|
||||
// overrules a function name.
|
||||
if (lookup_local(namebuf, varlen, cctx) == NULL
|
||||
if (lookup_local(namebuf, varlen, NULL, cctx) == FAIL
|
||||
&& arg_exists(namebuf, varlen, NULL, NULL, NULL, cctx) != OK)
|
||||
{
|
||||
// If we can find the function by name generate the right call.
|
||||
@@ -3492,7 +3517,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 == '(')
|
||||
{
|
||||
@@ -3969,7 +3994,10 @@ compile_expr7(
|
||||
|
||||
if (!eval_isnamec1(**arg))
|
||||
{
|
||||
semsg(_(e_name_expected), *arg);
|
||||
if (ends_excmd(*skipwhite(*arg)))
|
||||
semsg(_(e_empty_expression_str), *arg);
|
||||
else
|
||||
semsg(_(e_name_expected_str), *arg);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@@ -4968,7 +4996,10 @@ generate_loadvar(
|
||||
generate_LOAD(cctx, ISN_LOADOPT, 0, name, type);
|
||||
break;
|
||||
case dest_global:
|
||||
generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
|
||||
if (vim_strchr(name, AUTOLOAD_CHAR) == NULL)
|
||||
generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
|
||||
else
|
||||
generate_LOAD(cctx, ISN_LOADAUTO, 0, name, type);
|
||||
break;
|
||||
case dest_buffer:
|
||||
generate_LOAD(cctx, ISN_LOADB, 0, name + 2, type);
|
||||
@@ -5180,7 +5211,8 @@ generate_store_var(
|
||||
opt_flags);
|
||||
case dest_global:
|
||||
// include g: with the name, easier to execute that way
|
||||
return generate_STORE(cctx, ISN_STOREG, 0, name);
|
||||
return generate_STORE(cctx, vim_strchr(name, AUTOLOAD_CHAR) == NULL
|
||||
? ISN_STOREG : ISN_STOREAUTO, 0, name);
|
||||
case dest_buffer:
|
||||
// include b: with the name, easier to execute that way
|
||||
return generate_STORE(cctx, ISN_STOREB, 0, name);
|
||||
@@ -5366,6 +5398,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
assign_dest_T dest = dest_local;
|
||||
int opt_flags = 0;
|
||||
int vimvaridx = -1;
|
||||
lvar_T local_lvar;
|
||||
lvar_T *lvar = NULL;
|
||||
lvar_T arg_lvar;
|
||||
int has_type = FALSE;
|
||||
@@ -5424,8 +5457,10 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
goto theend;
|
||||
}
|
||||
|
||||
lvar = lookup_local(var_start, varlen, cctx);
|
||||
if (lvar == NULL)
|
||||
|
||||
if (lookup_local(var_start, varlen, &local_lvar, cctx) == OK)
|
||||
lvar = &local_lvar;
|
||||
else
|
||||
{
|
||||
CLEAR_FIELD(arg_lvar);
|
||||
if (arg_exists(var_start, varlen,
|
||||
@@ -5844,8 +5879,6 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
int r;
|
||||
|
||||
// Compile the "idx" in "var[idx]" or "key" in "var.key".
|
||||
if (new_local)
|
||||
--cctx->ctx_locals.ga_len;
|
||||
p = var_start + varlen;
|
||||
if (*p == '[')
|
||||
{
|
||||
@@ -5865,8 +5898,6 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
|
||||
r = generate_PUSHS(cctx, key);
|
||||
}
|
||||
if (new_local)
|
||||
++cctx->ctx_locals.ga_len;
|
||||
if (r == FAIL)
|
||||
goto theend;
|
||||
|
||||
@@ -5985,7 +6016,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
// for "[var, var] = expr" drop the "expr" value
|
||||
if (var_count > 0 && !semicolon)
|
||||
{
|
||||
if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL)
|
||||
if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL)
|
||||
goto theend;
|
||||
}
|
||||
|
||||
@@ -6066,12 +6097,6 @@ compile_unletlock(char_u *arg, exarg_T *eap, cctx_T *cctx)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (*p == '!')
|
||||
{
|
||||
p = skipwhite(p + 1);
|
||||
eap->forceit = TRUE;
|
||||
}
|
||||
|
||||
ex_unletlock(eap, p, 0, GLV_NO_AUTOLOAD, compile_unlet, cctx);
|
||||
return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
|
||||
}
|
||||
@@ -6579,8 +6604,7 @@ compile_for(char_u *arg_start, cctx_T *cctx)
|
||||
}
|
||||
else
|
||||
{
|
||||
var_lvar = lookup_local(arg, varlen, cctx);
|
||||
if (var_lvar != NULL)
|
||||
if (lookup_local(arg, varlen, NULL, cctx) == OK)
|
||||
{
|
||||
semsg(_(e_variable_already_declared), arg);
|
||||
goto failed;
|
||||
@@ -6825,7 +6849,7 @@ compile_endblock(cctx_T *cctx)
|
||||
* ... try block
|
||||
* " catch {expr}"
|
||||
* JUMP -> finally
|
||||
* catch1: PUSH exeception
|
||||
* catch1: PUSH exception
|
||||
* EVAL {expr}
|
||||
* MATCH
|
||||
* JUMP nomatch -> catch2
|
||||
@@ -7093,33 +7117,36 @@ compile_throw(char_u *arg, cctx_T *cctx UNUSED)
|
||||
compile_mult_expr(char_u *arg, int cmdidx, cctx_T *cctx)
|
||||
{
|
||||
char_u *p = arg;
|
||||
char_u *prev;
|
||||
char_u *prev = arg;
|
||||
int count = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (ends_excmd2(prev, p))
|
||||
break;
|
||||
if (compile_expr0(&p, cctx) == FAIL)
|
||||
return NULL;
|
||||
++count;
|
||||
prev = p;
|
||||
p = skipwhite(p);
|
||||
if (ends_excmd2(prev, p))
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmdidx == CMD_echo || cmdidx == CMD_echon)
|
||||
generate_ECHO(cctx, cmdidx == CMD_echo, count);
|
||||
else if (cmdidx == CMD_execute)
|
||||
generate_MULT_EXPR(cctx, ISN_EXECUTE, count);
|
||||
else if (cmdidx == CMD_echomsg)
|
||||
generate_MULT_EXPR(cctx, ISN_ECHOMSG, count);
|
||||
else
|
||||
generate_MULT_EXPR(cctx, ISN_ECHOERR, count);
|
||||
if (count > 0)
|
||||
{
|
||||
if (cmdidx == CMD_echo || cmdidx == CMD_echon)
|
||||
generate_ECHO(cctx, cmdidx == CMD_echo, count);
|
||||
else if (cmdidx == CMD_execute)
|
||||
generate_MULT_EXPR(cctx, ISN_EXECUTE, count);
|
||||
else if (cmdidx == CMD_echomsg)
|
||||
generate_MULT_EXPR(cctx, ISN_ECHOMSG, count);
|
||||
else
|
||||
generate_MULT_EXPR(cctx, ISN_ECHOERR, count);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
@@ -7168,6 +7195,7 @@ compile_put(char_u *arg, exarg_T *eap, cctx_T *cctx)
|
||||
// Either no range or a number.
|
||||
// "errormsg" will not be set because the range is ADDR_LINES.
|
||||
if (parse_cmd_address(eap, &errormsg, FALSE) == FAIL)
|
||||
// cannot happen
|
||||
return NULL;
|
||||
if (eap->addr_count == 0)
|
||||
lnum = -1;
|
||||
@@ -7584,7 +7612,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
|
||||
|| *ea.cmd == '$'
|
||||
|| *ea.cmd == '@'
|
||||
|| ((len) > 2 && ea.cmd[1] == ':')
|
||||
|| lookup_local(ea.cmd, len, &cctx) != NULL
|
||||
|| lookup_local(ea.cmd, len, NULL, &cctx) == OK
|
||||
|| arg_exists(ea.cmd, len, NULL, NULL,
|
||||
NULL, &cctx) == OK
|
||||
|| script_var_exists(ea.cmd, len,
|
||||
@@ -7637,7 +7665,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
|
||||
}
|
||||
}
|
||||
p = find_ex_command(&ea, NULL, starts_with_colon ? NULL
|
||||
: (void *(*)(char_u *, size_t, cctx_T *))lookup_local,
|
||||
: (int (*)(char_u *, size_t, void *, cctx_T *))lookup_local,
|
||||
&cctx);
|
||||
|
||||
if (p == ea.cmd && ea.cmdidx != CMD_SIZE)
|
||||
@@ -7993,6 +8021,7 @@ delete_instr(isn_T *isn)
|
||||
{
|
||||
case ISN_DEF:
|
||||
case ISN_EXEC:
|
||||
case ISN_LOADAUTO:
|
||||
case ISN_LOADB:
|
||||
case ISN_LOADENV:
|
||||
case ISN_LOADG:
|
||||
@@ -8003,6 +8032,7 @@ delete_instr(isn_T *isn)
|
||||
case ISN_PUSHFUNC:
|
||||
case ISN_PUSHS:
|
||||
case ISN_RANGE:
|
||||
case ISN_STOREAUTO:
|
||||
case ISN_STOREB:
|
||||
case ISN_STOREENV:
|
||||
case ISN_STOREG:
|
||||
|
||||
+52
-2
@@ -583,7 +583,7 @@ call_bfunc(int func_idx, int argcount, ectx_T *ectx)
|
||||
for (idx = 0; idx < argcount; ++idx)
|
||||
clear_tv(&argvars[idx]);
|
||||
|
||||
if (did_emsg != did_emsg_before)
|
||||
if (did_emsg > did_emsg_before)
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
@@ -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));
|
||||
@@ -1370,6 +1391,21 @@ call_def_function(
|
||||
}
|
||||
break;
|
||||
|
||||
// load autoload variable
|
||||
case ISN_LOADAUTO:
|
||||
{
|
||||
char_u *name = iptr->isn_arg.string;
|
||||
|
||||
if (GA_GROW(&ectx.ec_stack, 1) == FAIL)
|
||||
goto failed;
|
||||
SOURCING_LNUM = iptr->isn_lnum;
|
||||
if (eval_variable(name, STRLEN(name),
|
||||
STACK_TV_BOT(0), NULL, TRUE, FALSE) == FAIL)
|
||||
goto on_error;
|
||||
++ectx.ec_stack.ga_len;
|
||||
}
|
||||
break;
|
||||
|
||||
// load g:/b:/w:/t: namespace
|
||||
case ISN_LOADGDICT:
|
||||
case ISN_LOADBDICT:
|
||||
@@ -1590,6 +1626,14 @@ call_def_function(
|
||||
}
|
||||
break;
|
||||
|
||||
// store an autoload variable
|
||||
case ISN_STOREAUTO:
|
||||
SOURCING_LNUM = iptr->isn_lnum;
|
||||
set_var(iptr->isn_arg.string, STACK_TV_BOT(-1), TRUE);
|
||||
clear_tv(STACK_TV_BOT(-1));
|
||||
--ectx.ec_stack.ga_len;
|
||||
break;
|
||||
|
||||
// store number in local variable
|
||||
case ISN_STORENR:
|
||||
tv = STACK_TV_VAR(iptr->isn_arg.storenr.stnr_idx);
|
||||
@@ -3116,7 +3160,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.
|
||||
*/
|
||||
@@ -3265,6 +3309,9 @@ ex_disassemble(exarg_T *eap)
|
||||
iptr->isn_arg.loadstore.ls_name, si->sn_name);
|
||||
}
|
||||
break;
|
||||
case ISN_LOADAUTO:
|
||||
smsg("%4d LOADAUTO %s", current, iptr->isn_arg.string);
|
||||
break;
|
||||
case ISN_LOADG:
|
||||
smsg("%4d LOADG g:%s", current, iptr->isn_arg.string);
|
||||
break;
|
||||
@@ -3316,6 +3363,9 @@ ex_disassemble(exarg_T *eap)
|
||||
smsg("%4d STOREV v:%s", current,
|
||||
get_vim_var_name(iptr->isn_arg.number));
|
||||
break;
|
||||
case ISN_STOREAUTO:
|
||||
smsg("%4d STOREAUTO %s", current, iptr->isn_arg.string);
|
||||
break;
|
||||
case ISN_STOREG:
|
||||
smsg("%4d STOREG %s", current, iptr->isn_arg.string);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user