Compare commits

...

55 Commits

Author SHA1 Message Date
Yee Cheng Chin 778c734416 MacVim Snapshot 169
Updated to Vim 8.2.2164.

This release (r169) is a minor update to fix the issue that r168 would
not launch on macOS 10.13 (High Sierra) or below. #1138

Compatibility
====================

Requires macOS 10.9 or above.

Script interfaces have compatibility with these versions:

- Lua 5.4
- Perl 5.18
- Python2 2.7
- Python3 3.9
- Ruby 2.7
2020-12-19 16:58:43 -08:00
Yee Cheng Chin a4252b3856 Merge remote-tracking branch 'vim/master' 2020-12-19 16:58:43 -08:00
Yee Cheng Chin 08d4327852 Merge pull request #1148 from ichizok/fix/ci
CI: Organize GitHub Actions
2020-12-19 16:08:08 -08:00
Bram Moolenaar 17f700ac8b patch 8.2.2164: Vim9: autoload function doesn't work in uppercased script
Problem:    Vim9: autoload function doesn't work in script that starts with
            an upper case letter.
Solution:   Check for the autoload character. (closes #7502)
2020-12-19 21:23:42 +01:00
Bram Moolenaar 13656f02e4 patch 8.2.2163: crash when discarded exception is the current exception
Problem:    Crash when discarded exception is the current exception.
Solution:   Compare the execption with current_exception. (closes #7499)
2020-12-19 17:55:54 +01:00
Bram Moolenaar 03290b8444 patch 8.2.2162: Vim9: Cannot load or store autoload variables
Problem:    Vim9: Cannot load or store autoload variables.
Solution:   Add ISN_LOADAUTO and ISN_STOREAUTO. (closes #7485)
2020-12-19 16:30:44 +01:00
ichizok 5bf293e79e CI: Organize GitHub Actions 2020-12-19 22:07:06 +09:00
Bram Moolenaar 1f33e0a7c4 patch 8.2.2161: arguments -T and -x not tested yet
Problem:    Arguments -T and -x not tested yet.
Solution:   Add a test. (Dominique Pellé, closes #7490
2020-12-19 13:32:07 +01:00
Yee Cheng Chin ec55b8d482 Merge pull request #1147 from ychin/github-actions-matrix
Add matrix testing to GitHub Actions CI
2020-12-19 03:15:58 -08:00
Yee Cheng Chin 3db996fa3c Add matrix testing to GitHub Actions CI
GitHub Actions runners choices are relatively limited, so do matrix
testing on the two OS versions they support, and Xcode 11 to test
compatibility with Catalina (10.15) SDKs.

Remove the standard Vim's CI file, to make it less confusing and to
prevent GitHub Actions from running it accidentally (the UI has the
ability to disable certain workflows but it seems a little buggy at
times).

Also fixed up how terminal Vim was linking against Carbon and Cocoa
which are unnecessary. It only needs AppKit for communicating between
MMBackend and the GUI.

Also switch to using clang to match what we had in Travis CI.
2020-12-19 03:00:15 -08:00
Yee Cheng Chin c70b172aeb Merge pull request #1146 from ychin/github-actions-fix-tests
Fix MacVim GitHub Actions CI tests
2020-12-18 21:00:11 -08:00
Yee Cheng Chin b9058dda72 Fix MacVim GitHub Actions CI tests
Part of #1127
2020-12-18 20:19:07 -08:00
Yee Cheng Chin 7caffe5c20 Merge remote-tracking branch 'vim/master' 2020-12-18 19:38:57 -08:00
Yee Cheng Chin 2ab21ac8e6 Merge pull request #1145 from ychin/update-readme-github-actions-badge
Update README to point to GitHub Actions instead of Travis CI badge
2020-12-18 18:20:40 -08:00
Yee Cheng Chin 486aca4ffc Update README to point to GitHub Actions instead of Travis CI badge 2020-12-18 18:17:03 -08:00
Yee Cheng Chin e79bce037e Merge pull request #1144 from ychin/macvim-github-actions-ci-initial
Add Github Actions CI for MacVim
2020-12-18 17:56:46 -08:00
Yee Cheng Chin 5939c3e8f9 Add Github Actions CI for MacVim
This is the initial work to migrate to Github Actions from Travis CI for
MacVim CI (see #1127). Sets up a MacVim-specific workflow that builds
and test MacVim, and also publishes built artifacts for releases.

Some notest on implementation:

- Testing is currently disabled as it seems to be failing on a few
  tests.
- gettext is now custom built instead using the Homebrew version. The
  latest versions of the binary were built with later SDKs and would
  cause MacVim to not work in older macOS versions (10.13), see #1138.
  To fix this, we need to manually build gettext with min SDK set to
  10.9 (the current MacVim target) before we link it with MacVim. We do
  this by copying the brew formula and manually patch in the min SDK and
  then install from source.
- When publishing a build when a tag is pushed, simply have the workflow
  publish a dmg artifact, instead of pushing it to the release like
  Travis CI. Currently, releases are manual and requires offline
  signing/notarization steps that are out of CI, and also release notes
  formatting that also requires manual work. As such, there is no point
  in automating releases other than building a dmg that we can then
  sign and publish.

Features to add later:

- Test matrix. We should test on the available OS versions (currently
  10.15 and 11.0) and also different Xcode / macOS SDKs to try catch
  backwards compatibility issues.
- Enable testing once the tests are fixed.
2020-12-18 15:01:47 -08:00
Bram Moolenaar 8e7d6223f6 patch 8.2.2160: various typos
Problem:    Various typos.
Solution:   Fix spelling mistakes. (closes #7494)
2020-12-18 19:49:56 +01:00
Bram Moolenaar 3beaf9cd8e patch 8.2.2159: Vim9: when declaring a list it is not allocated yet
Problem:    Vim9: when declaring a list it is not allocated yet, causing a
            following extend() to fail.
Solution:   When fetching a variable value for a list or dict that is null
            allocate the list or dict, so it can be used. (closes #7491)
2020-12-18 17:23:14 +01:00
Bram Moolenaar 6e562fcc07 patch 8.2.2158: CI on cirrus times out, coveralls doesn't always run
Problem:    CI on cirrus times out, coveralls doesn't always run.
Solution:   Set timeout to 20 minutes. Adjust condition. (closes #7493)
2020-12-18 16:29:25 +01:00
Bram Moolenaar 9aed729fe9 patch 8.2.2157: Vim9: can delete a Vim9 script variable from a function
Problem:    Vim9: can delete a Vim9 script variable from a function.
Solution:   Check the variable is defined in Vim9 script. (closes #7483)
2020-12-18 15:38:00 +01:00
Bram Moolenaar b5b77378bc patch 8.2.2156: Github actions run on pusing a tag
Problem:    Github actions run on pusing a tag.
Solution:   Don't run CI on tag push. Omit coveralls on pull-request.
            (Ozaki Kiichi, closes #7489)
2020-12-18 13:31:31 +01:00
Bram Moolenaar 18f69229c5 patch 8.2.2155: warning from Github actions for code analysis
Problem:    Warning from Github actions for code analysis.
Solution:   Remove the "git checkout HEAD^2" block.
2020-12-18 13:15:20 +01:00
Bram Moolenaar 0353f56ddb patch 8.2.2154: popupwin test for terminal buffer fails sometimes
Problem:    Popupwin test for terminal buffer fails sometimes.
Solution:   Wait for the prompt to appear.
2020-12-17 22:27:38 +01:00
Bram Moolenaar b125b535bb patch 8.2.2153: popupwin test for latin1 still fails sometimes
Problem:    Popupwin test for latin1 still fails sometimes.
Solution:   Wait for the "cat" command to finish.
2020-12-17 21:56:09 +01:00
Bram Moolenaar 8dd46e72cf patch 8.2.2152: screenpos() does not include the WinBar offset
Problem:    screenpos() does not include the WinBar offset.
Solution:   Use W_WINROW() instead of directly using w_window. (closes #7487)
2020-12-17 21:35:29 +01:00
Bram Moolenaar a79a8944da patch 8.2.2151: $dir not expanded when configure checks for moonjit
Problem:    $dir not expanded when configure checks for moonjit.
Solution:   Use double quotes instead of single quotes. (closes #7478)
2020-12-17 20:50:25 +01:00
Bram Moolenaar 8ea05de6aa patch 8.2.2150: Github actions CI isn't used for all available platforms
Problem:    Github actions CI isn't used for all available platforms.
Solution:   Update the github workflows. (Ozaki Kiichi, closes #7433)
2020-12-17 20:27:26 +01:00
Bram Moolenaar 4c5bdb99ad patch 8.2.2149: popupwin test for latin1 sometimes fails
Problem:    Popupwin test for latin1 sometimes fails.
Solution:   Wait for the script to finish.
2020-12-17 17:45:59 +01:00
Bram Moolenaar 1c0aa97827 patch 8.2.2148: Vim9: crash when user command doesn't match
Problem:    Vim9: crash when user command doesn't match.
Solution:   Adjust command index. (closes #7479)
2020-12-16 21:43:54 +01:00
Bram Moolenaar 530bed993e patch 8.2.2147: quickfix window title not updated in all tab pages
Problem:    Quickfix window title not updated in all tab pages.
Solution:   Update the quickfix window title in all tab pages. (Yegappan
            Lakshmanan, closes #7481, closes #7466)
2020-12-16 21:02:56 +01:00
ichizok 4e76524534 Merge remote-tracking branch 'vim/master' 2020-12-16 15:06:03 +09:00
Bram Moolenaar 9987fb0b4b patch 8.2.2146: Vim9: automatic conversion of number to string for dict key
Problem:    Vim9: automatic conversion of number to string for dict key.
Solution:   Do not convert number to string. (closes #7474)
2020-12-15 21:41:56 +01:00
Bram Moolenaar 399ea8108c patch 8.2.2145: Vim9: concatenating lists does not adjust type of result
Problem:    Vim9: concatenating lists does not adjust type of result.
Solution:   When list member types differ use "any" member type.
            (closes #7473)
2020-12-15 21:28:57 +01:00
Bram Moolenaar 025cb1ca86 patch 8.2.2144: Vim9: some corner cases not tested
Problem:    Vim9: some corner cases not tested.
Solution:   Add a few tests.
2020-12-14 18:31:27 +01:00
Bram Moolenaar ec792290eb patch 8.2.2143: Vim9: dead code in compiling :unlet
Problem:    Vim9: dead code in compiling :unlet.
Solution:   Don't check for "!" a second time.
2020-12-13 21:26:56 +01:00
Bram Moolenaar fffdf4754f patch 8.2.2142: memory leak when heredoc is not terminated
Problem:    Memory leak when heredoc is not terminated.
Solution:   Free heredoc_trimmed.
2020-12-13 21:16:55 +01:00
Bram Moolenaar 8143a53c53 patch 8.2.2141: a user command with try/catch may not catch an expression error
Problem:    A user command with try/catch may not catch an expression error.
Solution:   When an expression fails check for following "|". (closes #7469)
2020-12-13 20:26:29 +01:00
Bram Moolenaar 2a3cd3af45 patch 8.2.2140: build failure with tiny features
Problem:    Build failure with tiny features.
Solution:   Add #ifdef.
2020-12-13 19:22:27 +01:00
Bram Moolenaar acbae18df5 patch 8.2.2139: Vim9: unreachable code in assignment
Problem:    Vim9: unreachable code in assignment.
Solution:   Don't check "new_local" when "has_index" is set.  Add test for
            wrong type of list index.
2020-12-13 18:44:43 +01:00
Bram Moolenaar b5b9480ee9 patch 8.2.2138: Vim9: "exit_cb" causes Vim to exit
Problem:    Vim9: "exit_cb" causes Vim to exit.
Solution:   Require white space after a command in Vim9 script. (closes #7467)
            Also fix that Vim9 style heredoc was not always recognized.
2020-12-13 17:50:20 +01:00
Bram Moolenaar e498429087 patch 8.2.2137: Vim9: :echo and :execute give error for empty argument
Problem:    Vim9: :echo and :execute give error for empty argument.
Solution:   Ignore an empty argument. (closes #7468)
2020-12-13 14:19:25 +01:00
Bram Moolenaar c530852315 patch 8.2.2136: Vim9: Using uninitialized variable
Problem:    Vim9: Using uninitialized variable.
Solution:   Initialize "len" to zero.  Clean up fnamemodify().
2020-12-13 12:25:35 +01:00
Bram Moolenaar 93f82cbee5 patch 8.2.2135: Vim9: #{ still seen as start of dict in some places
Problem:    Vim9: #{ still seen as start of dict in some places.
Solution:   Remove check for { after #. (closes #7456)
2020-12-12 21:25:56 +01:00
Bram Moolenaar 57f799e6a4 patch 8.2.2134: Vim9: get E1099 when autocmd triggered in builtin function
Problem:    Vim9: get E1099 when autocmd triggered in builtin function.
Solution:   Check that did_emsg increased instead of checking that it changed.
            (closes #7448)
2020-12-12 20:42:19 +01:00
Bram Moolenaar 2a9d5d386b patch 8.2.2133: Vim9: checking for a non-empty string is too strict
Problem:    Vim9: checking for a non-empty string is too strict.
Solution:   Check for any string. (closes #7447)
2020-12-12 18:58:40 +01:00
Bram Moolenaar 3ae50c775c patch 8.2.2132: padding not drawn properly for popup window with title
Problem:    Padding not drawn properly for popup window with title.
Solution:   Draw the padding below the title. (closes #7460)
2020-12-12 18:18:06 +01:00
Bram Moolenaar 709664cca0 patch 8.2.2131: Vim9: crash when lambda uses same var as assignment
Problem:    Vim9: crash when lambda uses same var as assignment.
Solution:   Do not let lookup_local change lv_from_outer, make a copy.
            (closes #7461)
2020-12-12 14:33:41 +01:00
Bram Moolenaar cc2335896b patch 8.2.2130: Insert mode completion messages end up in message history
Problem:    Insert mode completion messages end up in message history.
Solution:   Set msg_hist_off. (closes #7452
2020-12-12 13:32:07 +01:00
Yee Cheng Chin f539a147c1 MacVim Snapshot 168
Updated to Vim 8.2.2127.

*Note*: This release doesn't natively support Apple Silicon / M1 yet, but
does work under Rosetta. See below.

Features
====================

Big Sur / macOS 11
--------------------

- MacVim now has an updated app icon (#1054), and preference pane / toolbars
  have been updated to match Big Sur's interface guidelines. (#1128)
- Fixed Touch Bar warnings when launching MacVim from the terminal.
  #1114
- SF Symbol characters will show up properly as double-width as most of
  these icons would take up more than one column. Note that these
  characters are specific to macOS and would not work in other
  platforms. #1129

Renderer / scrolling performance improvements
--------------------

The Core Text renderer has been rewritten and is now much faster!
Scrolling should not stutter and lag like before and generally it should
feel a lot smoother now. Thanks to Sidney San Martín (@s4y) for the
contribution. #858

With this change, the non-Core-Text renderer is now considered
deprecated. The old renderer is accessible either through the Preference
Pane (under Advanced) or by setting the defaults "MMRenderer" to 0. It
works for now, but it will be removed in a future update as it has known
bugs.

Menu Localization
--------------------

Menus are now localized, see `:h langmenu` for how Vim menu localization
works. You can use `set langmenu=none` to turn it off if you would like. #1099

There still exists a few menu items that are not localized, and the
general MacVim GUI is not localized as well. If you would like to help,
please use #1102 to coordinate with MacVim dev team.

Getting help / Help menu
--------------------

- Help menu's search bar now searches Vim documentation as well! See
  #1095.
- Vimtutor is now bundled with MacVim, and you can access vimtutor from
  the Help menu (#1096). There is also a link to the latest release
  notes as well (#1131).

General
====================

- This release does not contain a native universal app for Apple Silicon
  / M1 Macs yet. The release binary will still work under Rosetta, which
  should provide enough performance, but if you use Python/etc plugins,
  you need to make sure you have x86 versions of Python/etc installed
  (which is still the default for Homebrew as of this release).

  MacVim is buildable under Apple Silicon, so if you need a native
  binary, you could build it yourself by downloading the source from the
  Github repository. See #1136 for progress on releasing a universal app
  for Apple Silicon.

- MacVim has enabled the Github Discussions feature, which serves as a
  good spot for general discussions and questions. See
  https://github.com/macvim-dev/macvim/discussions/1130 and check it
  out!

Fixes
====================

- Launching MacVim from the Dock with locales that use "," for decimal
  separators now works correctly. #11 (Vim 8.2.1738)
- `WinBar` menus (which are used by plugins like vimspector) now work
  properly and don't create dummy menu items. #918
- Using `:browse tabnew` no longer crashes MacVim in terminal mode.
  #1107 (Vim 8.2.1842)

Misc
====================

- Scripting languages versions:
    - Python is now built against 3.9, up from 3.8.
    - Lua is now built against 5.4, up from 5.3.

Compatibility
====================

Requires macOS 10.9 or above.

Script interfaces have compatibility with these versions:

- Lua 5.4
- Perl 5.18
- Python2 2.7
- Python3 3.9
- Ruby 2.7
2020-12-11 21:34:07 -08:00
Yee Cheng Chin 1f8d90334b Merge pull request #1137 from ychin/fix-travis-ci-x86-only-configure-with-macarchs
Fix Travis CI to only build x86_64, and fix --with-macarchs flag
2020-12-11 21:31:52 -08:00
Yee Cheng Chin 3123f01324 Update EdDSA key for Sparkle updater, as the old one was wrong
The EdDSA public key added in last release (snapshot-166) was wrong.
Simply re-generate a new pair. This is not fatal as Sparkle allows for
DSA-only updates for now, but fix it to have the right key so future
MacVim updates can be done via EdDSA. It won't work if someone is
updating directly from 166, but given enough time, that should not be very likely
as people woudl have updated to the newer versions.
2020-12-11 21:01:48 -08:00
Yee Cheng Chin db650bbf43 Fix Travis CI to only build x86_64, and fix --with-macarchs flag
Apple Silicon build doesn't work in CI yet, and as such we don't want CI
to build it, as accidentaly Apple Silicon builds will mean an Apple
Silicon Mac prioritize that over Rosetta build which will crash (since
we are only building `MacVim` as universal, but the raw `Vim` process is
not). Also, add a CI smoketest step to make sure we only build x86_64.

Also, fix up the `--with-macarchs` flag for `configure`. For some
reason, Apple seems to have broken sed's word boundary parsing, so need
to work around it and use a more convoluted regex to do the word
splitting.
2020-12-11 21:01:12 -08:00
Bram Moolenaar 0ea7421ae6 patch 8.2.2129: MS-Windows: Checking if a file name is absolute is slow
Problem:    MS-Windows: Checking if a file name is absolute is slow.
Solution:   Do not use mch_FullName(). (closes #7033)
2020-12-11 20:10:50 +01:00
Bram Moolenaar 100118c73a patch 8.2.2128: there is no way to do something on CTRL-Z
Problem:    There is no way to do something on CTRL-Z.
Solution:   Add VimSuspend and VimResume autocommand events. (closes #7450)
2020-12-11 19:30:34 +01:00
87 changed files with 1230 additions and 510 deletions
+2
View File
@@ -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:
+1
View File
@@ -0,0 +1 @@
service_name: github-actions
+227
View File
@@ -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
-230
View File
@@ -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
)
-9
View File
@@ -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
View File
@@ -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.
+1 -1
View File
@@ -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>
- [![MacVim GitHub CI](https://github.com/macvim-dev/macvim/workflows/MacVim%20GitHub%20CI/badge.svg)](https://github.com/macvim-dev/macvim/actions?query=workflow%3A%22MacVim+GitHub+CI%22)
- Packaged in [![Homebrew package](https://repology.org/badge/version-for-repo/homebrew/macvim.svg)](https://repology.org/metapackage/macvim/versions) [![MacPorts package](https://repology.org/badge/version-for-repo/macports/macvim.svg)](https://repology.org/metapackage/macvim/versions)
+5 -2
View File
@@ -1,5 +1,6 @@
![Vim Logo](https://github.com/vim/vim/blob/master/runtime/vimlogo.gif)
[![Github Build status](https://github.com/vim/vim/workflows/GitHub%20CI/badge.svg)](https://github.com/vim/vim/actions?query=workflow%3A%22GitHub+CI%22)
[![Travis Build Status](https://travis-ci.org/vim/vim.svg?branch=master)](https://travis-ci.org/vim/vim)
[![Appveyor Build status](https://ci.appveyor.com/api/projects/status/o2qht2kjm02sgghk?svg=true)](https://ci.appveyor.com/project/chrisbra/vim)
[![Cirrus Build Status](https://api.cirrus-ci.com/github/vim/vim.svg)](https://cirrus-ci.com/github/vim/vim)
@@ -8,6 +9,7 @@
[![Language Grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/vim/vim.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/vim/vim/context:cpp)
[![Debian CI](https://badges.debian.net/badges/debian/testing/vim/version.svg)](https://buildd.debian.org/vim)
[![Packages](https://repology.org/badge/tiny-repos/vim.svg)](https://repology.org/metapackage/vim)
For translations of this README see the end.
@@ -26,8 +28,8 @@ All commands are given with normal keyboard characters, so those who can type
with ten fingers can work very fast. Additionally, function keys can be
mapped to commands by the user, and the mouse can be used.
Vim runs under MS-Windows (XP, Vista, 7, 8, 10), macOS, VMS and almost all
flavours of UNIX. Porting to other systems should not be very difficult.
Vim runs under MS-Windows (XP, Vista, 7, 8, 10), macOS, Haiku, VMS and almost
all flavours of UNIX. Porting to other systems should not be very difficult.
Older versions of Vim run on MS-DOS, MS-Windows 95/98/Me/NT/2000, Amiga DOS,
Atari MiNT, BeOS, RISC OS and OS/2. These are no longer maintained.
@@ -72,6 +74,7 @@ archive):
README_unix.txt Unix
README_dos.txt MS-DOS and MS-Windows
README_mac.txt Macintosh
README_haiku.txt Haiku
README_vms.txt VMS
There are other `README_*.txt` files, depending on the distribution you used.
+19
View File
@@ -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}"
+17
View File
@@ -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
+14
View File
@@ -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.
+2 -2
View File
@@ -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
View File
@@ -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 =
+10 -2
View File
@@ -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
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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.
+2 -2
View File
@@ -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);
+1 -1
View File
@@ -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);
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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|
+1 -1
View File
@@ -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})
+1 -1
View File
@@ -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)
+5
View File
@@ -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()
+1 -1
View File
@@ -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' ] )
+1 -1
View File
@@ -284,7 +284,7 @@ endfunc
" 1
" 1
" 1
" Expexted:
" Expected:
" 1) g Ctrl-A on block selected indented lines
" 2
" 1
+13 -1
View File
@@ -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
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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>
+1 -1
View File
@@ -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")
+22 -4
View File
@@ -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)
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+24
View File
@@ -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()
+1 -1
View File
@@ -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:')
+47
View File
@@ -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]
+44
View File
@@ -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
+2 -2
View File
@@ -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))})
+1 -1
View File
@@ -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
+25
View File
@@ -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
+1 -1
View File
@@ -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
+44 -2
View File
@@ -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',
+32 -16
View File
@@ -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()
+26
View File
@@ -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
+34 -10
View File
@@ -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''.*' ..
+25
View File
@@ -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()
+26
View File
@@ -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
+76 -18
View File
@@ -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
+4 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+74
View File
@@ -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,
/**/
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;