Compare commits

...

42 Commits

Author SHA1 Message Date
edad360800 NVIM v0.3.8
FIXES:

5b47e4dc38 #10341 security: 'modeline', 'modelineexpr'
e4ecb70d08 #10345 Disallow API calls in the sandbox.
2019-07-03 03:11:42 +02:00
e4ecb70d08 Merge #10345 from bfredl/apisandbox-0.3
eval/api: don't allow the API to be called in the sandbox.
2019-06-27 00:13:18 +02:00
413b313ad2 eval/api: don't allow the API to be called in the sandbox.
Identifying and maintaining a "secure" subset of the API would be too
much busywork. So just disable the entire thing.
2019-06-26 21:04:20 +02:00
5b47e4dc38 Merge #10341 from jamessan/modeline-backports
Modeline fix backports
2019-06-26 21:02:24 +02:00
959ff84e04 vim-patch:8.1.1401: misspelled mkspellmem as makespellmem
Problem:    Misspelled mkspellmem as makespellmem.
Solution:   Drop duplicate help entry, fix test. (Naruhiko Nishino, Ken
            Takata, closes vim/vim#4437)
076073950c
2019-06-26 00:15:41 -04:00
13f3a21226 vim-patch:8.1.1382: error when editing test file
Problem:    Error when editing test file.
Solution:   Remove part of modeline.
3020a87cb1
2019-06-26 00:15:23 -04:00
1bb1b5087e vim-patch:8.1.1368: modeline test fails with python but without pythonhome
Problem:    Modeline test fails with python but without pythonhome.
Solution:   Correct test argument.
e09244ee35
2019-06-26 00:15:16 -04:00
536e9320a0 vim-patch:8.1.1367: can set 'modelineexpr' in modeline
Problem:    can set 'modelineexpr' in modeline.
Solution:   Add P_SECURE flag.
7e800c6047
2019-06-26 00:15:06 -04:00
3bd532ad15 vim-patch:8.1.1366: using expressions in a modeline is unsafe
Problem:    Using expressions in a modeline is unsafe.
Solution:   Disallow using expressions in a modeline, unless the
            'modelineexpr' option is set.  Update help, add more tests.
110289e781
2019-06-26 00:14:33 -04:00
2c5eede368 vim-patch:8.1.0547: modeline test with keymap still fails
Problem:    Modeline test with keymap still fails.
Solution:   Check that the keymap feature is available for the failure assert.
3067a4dd0d
2019-06-26 00:14:29 -04:00
9ab48aac20 vim-patch:8.1.0546: modeline test with keymap fails
Problem:    Modeline test with keymap fails.
Solution:   Check that the keymap feature is available.
4ace6ab7e7
2019-06-26 00:14:25 -04:00
5cca6f61bb vim-patch:8.1.0506: modeline test fails when run by root
Problem:    Modeline test fails when run by root.
Solution:   Set 'modeline' for the test. (James McCoy, closes vim/vim#3592)
9691f82f86

N/A patches:

vim-patch:8.1.0208: file left behind after running individual test
2019-06-26 00:14:20 -04:00
6683cb60b8 vim-patch:8.1.0206: duplicate test function name
Problem:    Duplicate test function name.
Solution:   Rename both functions.
cd96eef3a8
2019-06-26 00:14:16 -04:00
a72c05a6f6 vim-patch:8.1.0205: invalid memory access with invalid modeline
Problem:    Invalid memory access with invalid modeline.
Solution:   Pass pointer limit. Add a test. (closes vim/vim#3241)
9cf4b5005f
2019-06-26 00:14:00 -04:00
ad8bba10c4 vim-patch:8.1.1046: the "secure" variable is used inconsistently
Problem:    the "secure" variable is used inconsistently. (Justin M. Keyes)
Solution:   Set it to one instead of incrementing.
82b033eff8
2019-06-26 00:13:54 -04:00
9dca0b27df vim-patch:8.1.0613: when executing an insecure function the secure flag is stuck
Problem:    When executing an insecure function the secure flag is stuck.
            (Gabriel Barta)
Solution:   Restore "secure" instead of decrementing it. (closes vim/vim#3705)
48f377a476
2019-06-26 00:13:48 -04:00
0ec8da4387 fixup: use vim_snprintf, ASCII_ISALNUM
ASCII_ISALNUM is part of vim-patch:8.1.0540
2019-06-26 00:13:27 -04:00
1d3a1b55d1 vim-patch:8.1.0544: setting 'filetype' in a modeline causes an error
Problem:    Setting 'filetype' in a modeline causes an error (Hirohito
            Higashi).
Solution:   Don't add the P_INSECURE flag when setting 'filetype' from a
            modeline.  Also for 'syntax'.
916a818cea
2019-06-25 22:28:41 -04:00
7ddb102292 vim-patch:8.1.0540: may evaluate insecure value when appending to option
Problem:    May evaluate insecure value when appending to option.
Solution:   Set the secure flag when changing an option that was previously
            set insecurely.  Also allow numbers for the characters from
            'spelllang' that are used for LANG.vim.
247bb7e43b
2019-06-25 22:28:41 -04:00
adff3f4dee vim-patch:8.1.0539: cannot build without the sandbox
Problem:    Cannot build without the sandbox.
Solution:   Set the secure option instead of using the sandbox.  Also restrict
            the characters from 'spelllang' that are used for LANG.vim.
            (suggested by Yasuhiro Matsumoto)
82e8c92ebe
2019-06-25 22:28:41 -04:00
fee1880ea7 vim-patch:8.1.0538: evaluating a modeline might invoke using a shell command
Problem:    Evaluating a modeline might invoke using a shell command. (Paul
            Huber)
Solution:   Set the sandbox flag when setting options from a modeline.
5958f95a40
2019-06-25 22:28:41 -04:00
f514b7fbbc vim-patch:8.1.0189: function defined in sandbox not tested
Problem:    Function defined in sandbox not tested.
Solution:   Add a text.
d90a144eda
2019-06-25 22:28:41 -04:00
c202e4a868 vim-patch:8.1.0177: defining function in sandbox is inconsistent
Problem:    Defining function in sandbox is inconsistent, cannot use :function
            but can define a lambda.
Solution:   Allow defining a function in the sandbox, but also use the sandbox
            when executing it. (closes vim/vim#3182)
93343725b5
2019-06-25 22:28:31 -04:00
154765e4bf version bump 2019-05-29 10:58:40 +02:00
ede21f9518 NVIM v0.3.7
OTHER:
361d4be588 dist: update nvim.png
2019-05-29 10:57:53 +02:00
361d4be588 dist: update nvim.png
fix appimage failure:

    -- Deploying icons --
    Deploying icon /home/travis/build/neovim/bot-ci/build/neovim/runtime/nvim.png
    WARNING: x and y resolution of icon are not equal: /home/travis/build/neovim/bot-ci/build/neovim/runtime/nvim.png
    ERROR: Icon /home/travis/build/neovim/bot-ci/build/neovim/runtime/nvim.png has invalid x resolution: 104
    ERROR: Valid resolutions for icons are: 8x8, 16x16, ...
    Failed to deploy icon: /home/travis/build/neovim/bot-ci/build/neovim/runtime/nvim.png
    mv: cannot stat '/home/travis/build/neovim/bot-ci/build/neovim/build/nvim.appimage*': No such file or directory

ref https://github.com/neovim/bot-ci/issues/144
2019-05-29 01:29:24 +02:00
bd4bb61f35 version bump 2019-05-29 00:35:51 +02:00
8a6bb66e80 NVIM v0.3.6
FIXES:
4553fc5e6c #10082 vim-patch:8.1.1365: :source should check sandbox

OTHER:
877d539904 #10027 genappimage.sh: migrate to linuxdeploy
2019-05-29 00:34:46 +02:00
4553fc5e6c vim-patch:8.1.1365: :source should check sandbox #10082
Problem:    Source command doesn't check for the sandbox. (Armin Razmjou)
Solution:   Check for the sandbox when sourcing a file.
5357552140
2019-05-29 00:33:22 +02:00
877d539904 genappimage.sh: migrate to linuxdeploy #10027
generate_type2_appimage is unmaintained, and lacks a way to rename the appimage file.

fix #9893
2019-05-18 21:34:37 +02:00
60c3c92db1 release.sh 2019-04-28 22:19:18 +02:00
d7cf93ce34 version bump 2019-04-28 22:12:54 +02:00
1060bfd033 NVIM v0.3.5
Maintenance release to fix issues found in v0.3.4.

FIXES:

f891131c6b #9894 options: properly reset directories on 'autochdir'
9a5488c2a6 Remove MSVC optimization workaround for SHM_ALL
1793ba8176 Make SHM_ALL to a variable instead of a compound literal #define
947069ba14 doc: mention "pynvim" module rename
46c7e12f27 #9629 screen: don't crash when drawing popupmenu with 'rightleft' option
f1843c0035 vim-patch:8.1.0677: look-behind match may use the wrong line number
1204421888 #8325 :terminal : set topline based on window height
aaa8c3d711 #9504 :recover : Fix crash on non-existent *.swp
2019-04-28 22:10:12 +02:00
f891131c6b options: properly reset directories on 'autochdir' (#9894)
Fixes https://github.com/neovim/neovim/issues/9892
2019-04-15 21:04:16 +02:00
9a5488c2a6 Remove MSVC optimization workaround for SHM_ALL 2019-04-12 02:44:35 +02:00
1793ba8176 Make SHM_ALL to a variable instead of a compound literal #define
gcc-9 has [improved compliance] with the C spec for lifetime of compound
literals, tying their lifetime to block scope instead of function scope.
This makes the behavior comparable to all other automatic variables.

Using the SHM_ALL #define instantiated a compound literal local to an if
clause and assigned the address to a "char_u *".  Since the pointer was
then being used outside of the if clause, it was using an invalid
address.

[improved compliance]: https://gcc.gnu.org/gcc-9/porting_to.html#complit

Closes #9855
2019-04-12 02:43:59 +02:00
947069ba14 doc: mention "pynvim" module rename
closes #9764
2019-03-26 23:07:04 +01:00
46c7e12f27 Merge pull request #9629 from bfredl/pumfix
screen: don't crash when drawing popupmenu with 'rightleft' option
2019-02-19 19:30:35 +01:00
b98be54148 screen: don't crash when drawing popupmenu with 'rightleft' option 2019-02-19 17:46:21 +01:00
f1843c0035 vim-patch:8.1.0677: look-behind match may use the wrong line number
crash reported in #9584

Problem:    Look-behind match may use the wrong line number. (Dominique Pelle)
Solution:   Use the line number in regsave instead of the one in behind_pos,
            we may be looking at the previous line. (closes vim/vim#3749)
866f355814
2019-02-07 22:43:38 +01:00
1204421888 :terminal : set topline based on window height #8325 2019-02-06 04:12:14 +01:00
aaa8c3d711 :recover : Fix crash on non-existent *.swp #9504
Reverts d2944e6a29. mf_open() _can_ fail if the file does not exist.

closes #9503
closes #9504
2019-01-15 00:49:11 +01:00
41 changed files with 605 additions and 182 deletions

View File

@ -112,8 +112,8 @@ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
# version string, else they are combined with the result of `git describe`.
set(NVIM_VERSION_MAJOR 0)
set(NVIM_VERSION_MINOR 3)
set(NVIM_VERSION_PATCH 5)
set(NVIM_VERSION_PRERELEASE "-dev") # for package maintainers
set(NVIM_VERSION_PATCH 8)
set(NVIM_VERSION_PRERELEASE "") # for package maintainers
# API level
set(NVIM_API_LEVEL 5) # Bump this after any API change.

View File

@ -478,14 +478,17 @@ backslash in front of the ':' will be removed. Example:
/* vi:set dir=c\:\tmp: */ ~
This sets the 'dir' option to "c:\tmp". Only a single backslash before the
':' is removed. Thus to include "\:" you have to specify "\\:".
*E992*
No other commands than "set" are supported, for security reasons (somebody
might create a Trojan horse text file with modelines). And not all options
can be set. For some options a flag is set, so that when it's used the
|sandbox| is effective. Still, there is always a small risk that a modeline
causes trouble. E.g., when some joker sets 'textwidth' to 5 all your lines
are wrapped unexpectedly. So disable modelines before editing untrusted text.
The mail ftplugin does this, for example.
can be set. For some options a flag is set, so that when the value is used
the |sandbox| is effective. Some options can only be set from the modeline
when 'modelineexpr' is set (the default is off).
Still, there is always a small risk that a modeline causes trouble. E.g.,
when some joker sets 'textwidth' to 5 all your lines are wrapped unexpectedly.
So disable modelines before editing untrusted text. The mail ftplugin does
this, for example.
Hint: If you would like to do something else than setting an option, you could
define an autocommand that checks the file for a specific string. For
@ -2439,7 +2442,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The expression will be evaluated in the |sandbox| if set from a
modeline, see |sandbox-option|.
This option can't be set from a |modeline| when the 'diff' option is
on.
on or the 'modelineexpr' option is off.
It is not allowed to change text or jump to another window while
evaluating 'foldexpr' |textlock|.
@ -2554,6 +2557,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The expression will be evaluated in the |sandbox| if set from a
modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.
It is not allowed to change text or jump to another window while
evaluating 'foldtext' |textlock|.
@ -2589,16 +2593,8 @@ A jump table for the options with a short description can be found at |Q_op|.
The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|. That stops the option from working,
since changing the buffer text is not allowed.
*'formatoptions'* *'fo'*
'formatoptions' 'fo' string (default: "tcqj", Vi default: "vt")
local to buffer
This is a sequence of letters which describes how automatic
formatting is to be done. See |fo-table|. When the 'paste' option is
on, no formatting is done (like 'formatoptions' is empty). Commas can
be inserted for readability.
To avoid problems with flags that are added in the future, use the
"+=" and "-=" feature of ":set" |add-option-flags|.
This option cannot be set in a modeline when 'modelineexpr' is off.
NOTE: This option is set to "" when 'compatible' is set.
*'formatlistpat'* *'flp'*
'formatlistpat' 'flp' string (default: "^\s*\d\+[\]:.)}\t ]\s*")
@ -2613,6 +2609,16 @@ A jump table for the options with a short description can be found at |Q_op|.
The default recognizes a number, followed by an optional punctuation
character and white space.
*'formatoptions'* *'fo'*
'formatoptions' 'fo' string (default: "tcqj", Vi default: "vt")
local to buffer
This is a sequence of letters which describes how automatic
formatting is to be done. See |fo-table|. When the 'paste' option is
on, no formatting is done (like 'formatoptions' is empty). Commas can
be inserted for readability.
To avoid problems with flags that are added in the future, use the
"+=" and "-=" feature of ":set" |add-option-flags|.
*'formatprg'* *'fp'*
'formatprg' 'fp' string (default "")
global or local to buffer |global-local|
@ -2643,6 +2649,9 @@ A jump table for the options with a short description can be found at |Q_op|.
- system signals low battery life
- Nvim exits abnormally
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
*'gdefault'* *'gd'* *'nogdefault'* *'nogd'*
'gdefault' 'gd' boolean (default off)
global
@ -2978,6 +2987,7 @@ A jump table for the options with a short description can be found at |Q_op|.
'guitabtooltip' is used for the tooltip, see below.
The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.
Only used when the GUI tab pages line is displayed. 'e' must be
present in 'guioptions'. For the non-GUI tab pages line 'tabline' is
@ -3106,6 +3116,7 @@ A jump table for the options with a short description can be found at |Q_op|.
When this option contains printf-style '%' items, they will be
expanded according to the rules used for 'statusline'. See
'titlestring' for example settings.
This option cannot be set in a modeline when 'modelineexpr' is off.
*'ignorecase'* *'ic'* *'noignorecase'* *'noic'*
'ignorecase' 'ic' boolean (default off)
@ -3209,6 +3220,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.
It is not allowed to change text or jump to another window while
evaluating 'includeexpr' |textlock|.
@ -3277,6 +3289,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.
It is not allowed to change text or jump to another window while
evaluating 'indentexpr' |textlock|.
@ -3879,10 +3892,23 @@ A jump table for the options with a short description can be found at |Q_op|.
< If you have less than 512 Mbyte |:mkspell| may fail for some
languages, no matter what you set 'mkspellmem' to.
This option cannot be set from a |modeline| or in the |sandbox|.
*'modeline'* *'ml'* *'nomodeline'* *'noml'*
'modeline' 'ml' boolean (Vim default: on (off for root),
Vi default: off)
local to buffer
If 'modeline' is on 'modelines' gives the number of lines that is
checked for set commands. If 'modeline' is off or 'modelines' is zero
no lines are checked. See |modeline|.
*'modelineexpr'* *'mle'* *'nomodelineexpr'* *'nomle'*
'modelineexpr' 'mle' boolean (default: off)
global
When on allow some options that are an expression to be set in the
modeline. Check the option for whether it is affected by
'modelineexpr'. Also see |modeline|.
*'modelines'* *'mls'*
'modelines' 'mls' number (default 5)
global
@ -4622,6 +4648,8 @@ A jump table for the options with a short description can be found at |Q_op|.
When this option is not empty, it determines the content of the ruler
string, as displayed for the 'ruler' option.
The format of this option is like that of 'statusline'.
This option cannot be set in a modeline when 'modelineexpr' is off.
The default ruler width is 17 characters. To make the ruler 15
characters wide, put "%15(" at the start and "%)" at the end.
Example: >
@ -5252,7 +5280,8 @@ A jump table for the options with a short description can be found at |Q_op|.
"Pattern not found", "Back at original", etc.
q use "recording" instead of "recording @a"
F don't give the file info when editing a file, like `:silent`
was used for the command
was used for the command; note that this also affects messages
from autocommands
This gives you the opportunity to avoid that a change between buffers
requires you to hit <Enter>, but still gives as useful a message as
@ -5527,7 +5556,7 @@ A jump table for the options with a short description can be found at |Q_op|.
After this option has been set successfully, Vim will source the files
"spell/LANG.vim" in 'runtimepath'. "LANG" is the value of 'spelllang'
up to the first comma, dot or underscore.
up to the first character that is not an ASCII letter and not a dash.
Also see |set-spc-auto|.
@ -5773,6 +5802,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The 'statusline' option will be evaluated in the |sandbox| if set from
a modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.
It is not allowed to change text or jump to another window while
evaluating 'statusline' |textlock|.
@ -5927,6 +5957,8 @@ A jump table for the options with a short description can be found at |Q_op|.
the text to be displayed. Use "%1T" for the first label, "%2T" for
the second one, etc. Use "%X" items for closing labels.
This option cannot be set in a modeline when 'modelineexpr' is off.
Keep in mind that only one of the tab pages is the current one, others
are invisible and you can't jump to their windows.
@ -6203,8 +6235,11 @@ A jump table for the options with a short description can be found at |Q_op|.
global
When this option is not empty, it will be used for the title of the
window. This happens only when the 'title' option is on.
When this option contains printf-style '%' items, they will be
expanded according to the rules used for 'statusline'.
This option cannot be set in a modeline when 'modelineexpr' is off.
Example: >
:auto BufEnter * let &titlestring = hostname() . "/" . expand("%:p")
:set title titlestring=%<%F%=%l/%L-%P titlelen=70
@ -6238,6 +6273,8 @@ A jump table for the options with a short description can be found at |Q_op|.
undo file that exists is used. When it cannot be read an error is
given, no further entry is used.
See |undo-persistence|.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
*'undofile'* *'noundofile'* *'udf'* *'noudf'*
'undofile' 'udf' boolean (default off)

View File

@ -24,29 +24,34 @@ Nvim supports Python |remote-plugin|s and the Vim legacy |python2| and
|python3| interfaces (which are implemented as remote-plugins).
Note: Only the Vim 7.3 API is supported; bindeval (Vim 7.4) is not.
PYTHON QUICKSTART ~
Install the "pynvim" Python package:
To use Python plugins, you need the "pynvim" module. Run |:checkhealth| to see
if you already have it (some package managers install the module with Nvim
itself).
- Run |:checkhealth| to see if you already have the package (some package
managers install the "pynvim" Python package with Nvim itself).
For Python 3 plugins:
1. Make sure Python 3.4+ is available in your $PATH.
2. Install the module (try "pip" if "pip3" is missing): >
pip3 install --user --upgrade pynvim
- For Python 2 plugins, make sure Python 2.7 is available in your $PATH, then
install the package systemwide: >
sudo pip2 install --upgrade pynvim
< or for the current user: >
pip2 install --user --upgrade pynvim
< If "pip2" is missing, try "pip".
For Python 2 plugins:
1. Make sure Python 2.7 is available in your $PATH.
2. Install the module (try "pip" if "pip2" is missing): >
pip2 install --user --upgrade pynvim
- For Python 3 plugins, make sure Python 3.4+ is available in your $PATH, then
install the package systemwide: >
sudo pip3 install --upgrade pynvim
< or for the current user: >
pip3 install --user --upgrade pynvim
< If "pip3" is missing, try "pip".
The pip `--upgrade` flag ensures that you get the latest version even if
a previous version was already installed.
See also |python-virtualenv|.
Note: The old "neovim" module was renamed to "pynvim".
https://github.com/neovim/neovim/wiki/Following-HEAD#20181118
If you run into problems, uninstall _both_ then install "pynvim" again: >
pip uninstall neovim pynvim
pip install pynvim
- The `--upgrade` flag ensures you have the latest version even if a previous
version was already installed.
PYTHON PROVIDER CONFIGURATION ~
*g:python_host_prog*
@ -67,8 +72,9 @@ To disable Python 2 support: >
To disable Python 3 support: >
let g:loaded_python3_provider = 1
PYTHON VIRTUALENVS ~
PYTHON VIRTUALENVS ~
*python-virtualenv*
If you plan to use per-project virtualenvs often, you should assign one
virtualenv for Neovim and hard-code the interpreter path via
|g:python3_host_prog| (or |g:python_host_prog|) so that the "pynvim" package
@ -91,6 +97,7 @@ Ruby integration *provider-ruby*
Nvim supports Ruby |remote-plugin|s and the Vim legacy |ruby-vim| interface
(which is itself implemented as a Nvim remote-plugin).
RUBY QUICKSTART ~
To use Ruby plugins with Nvim, install the latest "neovim" RubyGem: >
@ -98,6 +105,7 @@ To use Ruby plugins with Nvim, install the latest "neovim" RubyGem: >
Run |:checkhealth| to see if your system is up-to-date.
RUBY PROVIDER CONFIGURATION ~
*g:loaded_ruby_provider*
To disable Ruby support: >
@ -120,6 +128,7 @@ Node.js integration *provider-nodejs*
Nvim supports Node.js |remote-plugin|s.
https://github.com/neovim/node-client/
NODEJS QUICKSTART~
To use javascript remote-plugins with Nvim, install the "neovim" npm package: >
@ -127,6 +136,7 @@ To use javascript remote-plugins with Nvim, install the "neovim" npm package: >
Run |:checkhealth| to see if your system is up-to-date.
NODEJS PROVIDER CONFIGURATION~
*g:loaded_node_provider*
To disable Node.js support: >

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -37,29 +37,24 @@ VERSION=$("$ROOT_DIR"/build/bin/nvim --version | head -n 1 | grep -o 'v.*')
cd "$APP_BUILD_DIR"
curl -Lo "$APP_BUILD_DIR"/appimage_functions.sh https://github.com/AppImage/AppImages/raw/master/functions.sh
. ./appimage_functions.sh
# Only downloads linuxdeploy if the remote file is different from local
if [ -e "$APP_BUILD_DIR"/linuxdeploy-x86_64.AppImage ]; then
curl -Lo "$APP_BUILD_DIR"/linuxdeploy-x86_64.AppImage \
-z "$APP_BUILD_DIR"/linuxdeploy-x86_64.AppImage \
https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
else
curl -Lo "$APP_BUILD_DIR"/linuxdeploy-x86_64.AppImage \
https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
fi
# Copy desktop and icon file to AppDir for AppRun to pick them up.
# get_apprun
# get_desktop
cp "$ROOT_DIR/runtime/nvim.desktop" "$APP_DIR/"
cp "$ROOT_DIR/runtime/nvim.png" "$APP_DIR/"
chmod +x "$APP_BUILD_DIR"/linuxdeploy-x86_64.AppImage
# metainfo is not packaged automatically by linuxdeploy
mkdir "$APP_DIR/usr/share/metainfo/"
cp "$ROOT_DIR/runtime/nvim.appdata.xml" "$APP_DIR/usr/share/metainfo/"
cd "$APP_DIR"
# copy dependencies
copy_deps
# Move the libraries to usr/bin
move_lib
# Delete stuff that should not go into the AppImage.
# Delete dangerous libraries; see
# https://github.com/AppImage/AppImages/blob/master/excludelist
delete_blacklisted
########################################################################
# AppDir complete. Now package it as an AppImage.
########################################################################
@ -78,21 +73,24 @@ chmod 755 AppRun
cd "$APP_BUILD_DIR" # Get out of AppImage directory.
# Set the name of the file generated by appimage
export OUTPUT=nvim.appimage
# If it's a release generate the zsync file
if [ -n "$TAG" ]; then
export UPDATE_INFORMATION="gh-releases-zsync|neovim|neovim|$TAG|nvim.appimage.zsync"
fi
# Generate AppImage.
# - Expects: $ARCH, $APP, $VERSION env vars
# - Expects: ./$APP.AppDir/ directory
# - Produces: ../out/$APP-$VERSION.glibc$GLIBC_NEEDED-$ARCH.AppImage
if [ -n "$TAG" ]; then
generate_type2_appimage -u "gh-releases-zsync|neovim|neovim|$TAG|nvim.appimage.zsync"
else
generate_type2_appimage
fi
# - Produces: ./nvim.appimage
./linuxdeploy-x86_64.AppImage --appdir $APP.AppDir -d $ROOT_DIR/runtime/nvim.desktop -i \
"$ROOT_DIR/runtime/nvim.png" --output appimage
# Moving the final executable to a different folder so it isn't in the
# way for a subsequent build.
mv "$ROOT_DIR"/out/*.AppImage* "$ROOT_DIR"/build/bin
# Remove the (now empty) folder the AppImage was built in
rmdir "$ROOT_DIR"/out
mv "$ROOT_DIR"/build/nvim.appimage* "$ROOT_DIR"/build/bin
echo 'genappimage.sh: finished'

View File

@ -15,10 +15,6 @@
# - Tag the commit.
# Create the "version bump" commit:
# - CMakeLists.txt: Set NVIM_VERSION_PRERELEASE to "-dev"
#
# Manual steps:
# - CMakeLists.txt: Bump NVIM_VERSION_* as appropriate.
# - git push --follow-tags
set -e
set -u
@ -95,5 +91,9 @@ _do_bump_commit
echo "
Next steps:
- Double-check NVIM_VERSION_* in CMakeLists.txt
- git push --follow-tags
- update website: index.html"
- Push the tag:
git push --follow-tags
- Update the 'stable' tag:
git push --force upstream HEAD^:refs/tags/stable
git fetch --tags
- Update website: index.html"

View File

@ -594,7 +594,7 @@ void nvim_set_current_dir(String dir, Error *err)
return;
}
post_chdir(kCdScopeGlobal);
post_chdir(kCdScopeGlobal, true);
try_end(err);
}

View File

@ -1559,6 +1559,7 @@ void do_autochdir(void)
if (starting == 0
&& curbuf->b_ffname != NULL
&& vim_chdirfile(curbuf->b_ffname) == OK) {
post_chdir(kCdScopeGlobal, false);
shorten_fnames(true);
}
}
@ -4923,9 +4924,15 @@ chk_modeline (
*e = NUL; /* truncate the set command */
if (*s != NUL) { /* skip over an empty "::" */
const int secure_save = secure;
save_SID = current_SID;
current_SID = SID_MODELINE;
// Make sure no risky things are executed as a side effect.
secure = 1;
retval = do_set(s, OPT_MODELINE | OPT_LOCAL | flags);
secure = secure_save;
current_SID = save_SID;
if (retval == FAIL) /* stop if error found */
break;

View File

@ -241,13 +241,14 @@ typedef enum {
///< the value (prevents error message).
} GetLvalFlags;
// function flags
// flags used in uf_flags
#define FC_ABORT 0x01 // abort function on error
#define FC_RANGE 0x02 // function accepts range
#define FC_DICT 0x04 // Dict function, uses "self"
#define FC_CLOSURE 0x08 // closure, uses outer scope variables
#define FC_DELETED 0x10 // :delfunction used while uf_refcount > 0
#define FC_REMOVED 0x20 // function redefined while uf_refcount > 0
#define FC_SANDBOX 0x40 // function defined in the sandbox
// The names of packages that once were loaded are remembered.
static garray_T ga_loaded = { 0, 0, sizeof(char_u *), 4, NULL };
@ -5853,6 +5854,9 @@ static int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate)
if (prof_def_func()) {
func_do_profile(fp);
}
if (sandbox) {
flags |= FC_SANDBOX;
}
fp->uf_varargs = true;
fp->uf_flags = flags;
fp->uf_calls = 0;
@ -6512,6 +6516,10 @@ static void float_op_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_restricted() || check_secure()) {
return;
}
ApiDispatchWrapper fn = (ApiDispatchWrapper)fptr;
Array args = ARRAY_DICT_INIT;
@ -20315,6 +20323,9 @@ void ex_function(exarg_T *eap)
if (prof_def_func())
func_do_profile(fp);
fp->uf_varargs = varargs;
if (sandbox) {
flags |= FC_SANDBOX;
}
fp->uf_flags = flags;
fp->uf_calls = 0;
fp->uf_script_ID = current_SID;
@ -21305,6 +21316,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
char_u *save_sourcing_name;
linenr_T save_sourcing_lnum;
scid_T save_current_SID;
bool using_sandbox = false;
funccall_T *fc;
int save_did_emsg;
static int depth = 0;
@ -21462,6 +21474,12 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
save_sourcing_name = sourcing_name;
save_sourcing_lnum = sourcing_lnum;
sourcing_lnum = 1;
if (fp->uf_flags & FC_SANDBOX) {
using_sandbox = true;
sandbox++;
}
// need space for new sourcing_name:
// * save_sourcing_name
// * "["number"].." or "function "
@ -21622,6 +21640,9 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
if (do_profiling_yes) {
script_prof_restore(&wait_start);
}
if (using_sandbox) {
sandbox--;
}
if (p_verbose >= 12 && sourcing_name != NULL) {
++no_wait_return;

View File

@ -1004,7 +1004,7 @@ return {
},
{
command='function',
flags=bit.bor(EXTRA, BANG, CMDWIN),
flags=bit.bor(EXTRA, BANG, SBOXOK, CMDWIN),
addr_type=ADDR_LINES,
func='ex_function',
},

View File

@ -7218,7 +7218,7 @@ void free_cd_dir(void)
/// Deal with the side effects of changing the current directory.
///
/// @param scope Scope of the function call (global, tab or window).
void post_chdir(CdScope scope)
void post_chdir(CdScope scope, bool trigger_dirchanged)
{
// Always overwrite the window-local CWD.
xfree(curwin->w_localdir);
@ -7258,7 +7258,10 @@ void post_chdir(CdScope scope)
}
shorten_fnames(true);
do_autocmd_dirchanged(cwd, scope);
if (trigger_dirchanged) {
do_autocmd_dirchanged(cwd, scope);
}
}
/// `:cd`, `:tcd`, `:lcd`, `:chdir`, `:tchdir` and `:lchdir`.
@ -7320,7 +7323,7 @@ void ex_cd(exarg_T *eap)
if (vim_chdir(new_dir, scope)) {
EMSG(_(e_failed));
} else {
post_chdir(scope);
post_chdir(scope, true);
// Echo the new current directory if the command was typed.
if (KeyTyped || p_verbose >= 5) {
ex_pwd(eap);

View File

@ -79,6 +79,7 @@ local get_flags = function(o)
{'pri_mkrc'},
{'deny_in_modelines', 'P_NO_ML'},
{'deny_duplicates', 'P_NODUP'},
{'modelineexpr', 'P_MLE'},
}) do
local key_name = flag_desc[1]
local def_name = flag_desc[2] or ('P_' .. key_name:upper())

View File

@ -1244,6 +1244,13 @@ openscript (
EMSG(_(e_nesting));
return;
}
// Disallow sourcing a file in the sandbox, the commands would be executed
// later, possibly outside of the sandbox.
if (check_secure()) {
return;
}
if (ignore_script)
/* Not reading from script, also don't open one. Warning message? */
return;

View File

@ -76,7 +76,8 @@
/// @param flags Flags for open() call.
///
/// @return The open memory file.
/// @return - The open memory file, on success.
/// - NULL, on failure (e.g. file does not exist).
memfile_T *mf_open(char_u *fname, int flags)
{
memfile_T *mfp = xmalloc(sizeof(memfile_T));

View File

@ -277,6 +277,9 @@ int ml_open(buf_T *buf)
// Open the memfile. No swap file is created yet.
memfile_T *mfp = mf_open(NULL, 0);
if (mfp == NULL) {
goto error;
}
buf->b_ml.ml_mfp = mfp;
buf->b_ml.ml_flags = ML_EMPTY;
@ -360,10 +363,12 @@ int ml_open(buf_T *buf)
return OK;
error:
if (hp) {
mf_put(mfp, hp, false, false);
if (mfp != NULL) {
if (hp) {
mf_put(mfp, hp, false, false);
}
mf_close(mfp, true); // will also xfree(mfp->mf_fname)
}
mf_close(mfp, true); // will also xfree(mfp->mf_fname)
buf->b_ml.ml_mfp = NULL;
return FAIL;
}
@ -839,7 +844,7 @@ void ml_recover(void)
mf_open() will consume "fname_used"! */
mfp = mf_open(fname_used, O_RDONLY);
fname_used = p;
if (mfp->mf_fd < 0) {
if (mfp == NULL || mfp->mf_fd < 0) {
EMSG2(_("E306: Cannot open %s"), fname_used);
goto theend;
}

View File

@ -251,6 +251,7 @@ typedef struct vimoption {
#define P_RWINONLY 0x10000000U ///< only redraw current window
#define P_NDNAME 0x20000000U ///< only normal dir name chars allowed
#define P_UI_OPTION 0x40000000U ///< send option to remote ui
#define P_MLE 0x80000000U ///< under control of 'modelineexpr'
#define HIGHLIGHT_INIT \
"8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText," \
@ -306,6 +307,15 @@ static char *(p_cot_values[]) = { "menu", "menuone", "longest", "preview",
static char *(p_icm_values[]) = { "nosplit", "split", NULL };
static char *(p_scl_values[]) = { "yes", "no", "auto", NULL };
/// All possible flags for 'shm'.
static char_u SHM_ALL[] = {
SHM_RO, SHM_MOD, SHM_FILE, SHM_LAST, SHM_TEXT, SHM_LINES, SHM_NEW, SHM_WRI,
SHM_ABBREVIATIONS, SHM_WRITE, SHM_TRUNC, SHM_TRUNCALL, SHM_OVER,
SHM_OVERALL, SHM_SEARCH, SHM_ATTENTION, SHM_INTRO, SHM_COMPLETIONMENU,
SHM_RECORDING, SHM_FILEINFO,
0,
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "option.c.generated.h"
#endif
@ -1200,7 +1210,7 @@ do_set (
}
len++;
if (opt_idx == -1) {
key = find_key_option(arg + 1);
key = find_key_option(arg + 1, true);
}
} else {
len = 0;
@ -1214,7 +1224,7 @@ do_set (
}
opt_idx = findoption_len((const char *)arg, (size_t)len);
if (opt_idx == -1) {
key = find_key_option(arg);
key = find_key_option(arg, false);
}
}
@ -1281,6 +1291,11 @@ do_set (
errmsg = (char_u *)_("E520: Not allowed in a modeline");
goto skip;
}
if ((flags & P_MLE) && !p_mle) {
errmsg = (char_u *)_(
"E992: Not allowed in a modeline when 'modelineexpr' is off");
goto skip;
}
/* In diff mode some options are overruled. This avoids that
* 'foldmethod' becomes "marker" instead of "diff" and that
* "wrap" gets set. */
@ -1355,6 +1370,10 @@ do_set (
&& nextchar != NUL && !ascii_iswhite(afterchar))
errmsg = e_trailing;
} else {
int value_is_replaced = !prepending && !adding && !removing;
int value_checked = false;
if (flags & P_BOOL) { /* boolean */
if (nextchar == '=' || nextchar == ':') {
errmsg = e_invarg;
@ -1774,12 +1793,32 @@ do_set (
// buffer is closed by autocommands.
saved_newval = (newval != NULL) ? xstrdup((char *)newval) : 0;
// Handle side effects, and set the global value for
// ":set" on local options. Note: when setting 'syntax'
// or 'filetype' autocommands may be triggered that can
// cause havoc.
errmsg = did_set_string_option(opt_idx, (char_u **)varp,
new_value_alloced, oldval, errbuf, opt_flags);
{
uint32_t *p = insecure_flag(opt_idx, opt_flags);
const int secure_saved = secure;
// When an option is set in the sandbox, from a
// modeline or in secure mode, then deal with side
// effects in secure mode. Also when the value was
// set with the P_INSECURE flag and is not
// completely replaced.
if ((opt_flags & OPT_MODELINE)
|| sandbox != 0
|| (!value_is_replaced && (*p & P_INSECURE))) {
secure = 1;
}
// Handle side effects, and set the global value
// for ":set" on local options. Note: when setting
// 'syntax' or 'filetype' autocommands may be
// triggered that can cause havoc.
errmsg = did_set_string_option(opt_idx, (char_u **)varp,
new_value_alloced, oldval,
errbuf, sizeof(errbuf),
opt_flags, &value_checked);
secure = secure_saved;
}
if (errmsg == NULL) {
if (!starting) {
@ -1806,8 +1845,7 @@ do_set (
}
if (opt_idx >= 0)
did_set_option(opt_idx, opt_flags,
!prepending && !adding && !removing);
did_set_option(opt_idx, opt_flags, value_is_replaced, value_checked);
}
skip:
@ -1872,7 +1910,9 @@ static void
did_set_option (
int opt_idx,
int opt_flags, /* possibly with OPT_MODELINE */
int new_value /* value was replaced completely */
int new_value, /* value was replaced completely */
int value_checked /* value was checked to be safe, no need to
set P_INSECURE */
)
{
options[opt_idx].flags |= P_WAS_SET;
@ -1881,20 +1921,22 @@ did_set_option (
* set the P_INSECURE flag. Otherwise, if a new value is stored reset the
* flag. */
uint32_t *p = insecure_flag(opt_idx, opt_flags);
if (secure
|| sandbox != 0
|| (opt_flags & OPT_MODELINE))
if (!value_checked && (secure
|| sandbox != 0
|| (opt_flags & OPT_MODELINE))) {
*p = *p | P_INSECURE;
else if (new_value)
} else if (new_value) {
*p = *p & ~P_INSECURE;
}
}
static char_u *illegal_char(char_u *errbuf, int c)
static char_u *illegal_char(char_u *errbuf, size_t errbuflen, int c)
{
if (errbuf == NULL)
if (errbuf == NULL) {
return (char_u *)"";
sprintf((char *)errbuf, _("E539: Illegal character <%s>"),
(char *)transchar(c));
}
vim_snprintf((char *)errbuf, errbuflen, _("E539: Illegal character <%s>"),
(char *)transchar(c));
return errbuf;
}
@ -1904,10 +1946,12 @@ static char_u *illegal_char(char_u *errbuf, int c)
*/
static int string_to_key(char_u *arg)
{
if (*arg == '<')
return find_key_option(arg + 1);
if (*arg == '^')
if (*arg == '<') {
return find_key_option(arg + 1, true);
}
if (*arg == '^') {
return Ctrl_chr(arg[1]);
}
return *arg;
}
@ -2383,10 +2427,12 @@ static char *set_string_option(const int opt_idx, const char *const value,
char *const saved_oldval = xstrdup(oldval);
char *const saved_newval = xstrdup(s);
int value_checked = false;
char *const r = (char *)did_set_string_option(
opt_idx, (char_u **)varp, (int)true, (char_u *)oldval, NULL, opt_flags);
opt_idx, (char_u **)varp, (int)true, (char_u *)oldval,
NULL, 0, opt_flags, &value_checked);
if (r == NULL) {
did_set_option(opt_idx, opt_flags, true);
did_set_option(opt_idx, opt_flags, true, value_checked);
}
// call autocommand after handling side effects
@ -2417,23 +2463,21 @@ static bool valid_filetype(char_u *val)
return true;
}
#ifdef _MSC_VER
// MSVC optimizations are disabled for this function because it
// incorrectly generates an empty string for SHM_ALL.
#pragma optimize("", off)
#endif
/*
* Handle string options that need some action to perform when changed.
* Returns NULL for success, or an error message for an error.
*/
static char_u *
did_set_string_option (
int opt_idx, /* index in options[] table */
char_u **varp, /* pointer to the option variable */
int new_value_alloced, /* new value was allocated */
char_u *oldval, /* previous value of the option */
char_u *errbuf, /* buffer for errors, or NULL */
int opt_flags /* OPT_LOCAL and/or OPT_GLOBAL */
did_set_string_option(
int opt_idx, // index in options[] table
char_u **varp, // pointer to the option variable
int new_value_alloced, // new value was allocated
char_u *oldval, // previous value of the option
char_u *errbuf, // buffer for errors, or NULL
size_t errbuflen, // length of errors buffer
int opt_flags, // OPT_LOCAL and/or OPT_GLOBAL
int *value_checked // value was checked to be safe, no
// need to set P_INSECURE
)
{
char_u *errmsg = NULL;
@ -2651,8 +2695,20 @@ did_set_string_option (
if (!valid_filetype(*varp)) {
errmsg = e_invarg;
} else {
int secure_save = secure;
// Reset the secure flag, since the value of 'keymap' has
// been checked to be safe.
secure = 0;
// load or unload key mapping tables
errmsg = keymap_init();
secure = secure_save;
// Since we check the value, there is no need to set P_INSECURE,
// even when the value comes from a modeline.
*value_checked = true;
}
if (errmsg == NULL) {
@ -2738,7 +2794,7 @@ did_set_string_option (
while (*s && *s != ':') {
if (vim_strchr((char_u *)COM_ALL, *s) == NULL
&& !ascii_isdigit(*s) && *s != '-') {
errmsg = illegal_char(errbuf, *s);
errmsg = illegal_char(errbuf, errbuflen, *s);
break;
}
++s;
@ -2790,7 +2846,7 @@ did_set_string_option (
for (s = p_shada; *s; ) {
/* Check it's a valid character */
if (vim_strchr((char_u *)"!\"%'/:<@cfhnrs", *s) == NULL) {
errmsg = illegal_char(errbuf, *s);
errmsg = illegal_char(errbuf, errbuflen, *s);
break;
}
if (*s == 'n') { /* name is always last one */
@ -2810,9 +2866,9 @@ did_set_string_option (
if (!ascii_isdigit(*(s - 1))) {
if (errbuf != NULL) {
sprintf((char *)errbuf,
_("E526: Missing number after <%s>"),
transchar_byte(*(s - 1)));
vim_snprintf((char *)errbuf, errbuflen,
_("E526: Missing number after <%s>"),
transchar_byte(*(s - 1)));
errmsg = errbuf;
} else
errmsg = (char_u *)"";
@ -2990,7 +3046,7 @@ did_set_string_option (
if (!*s)
break;
if (vim_strchr((char_u *)".wbuksid]tU", *s) == NULL) {
errmsg = illegal_char(errbuf, *s);
errmsg = illegal_char(errbuf, errbuflen, *s);
break;
}
if (*++s != NUL && *s != ',' && *s != ' ') {
@ -3004,9 +3060,9 @@ did_set_string_option (
}
} else {
if (errbuf != NULL) {
sprintf((char *)errbuf,
_("E535: Illegal character after <%c>"),
*--s);
vim_snprintf((char *)errbuf, errbuflen,
_("E535: Illegal character after <%c>"),
*--s);
errmsg = errbuf;
} else
errmsg = (char_u *)"";
@ -3163,12 +3219,20 @@ did_set_string_option (
errmsg = e_invarg;
} else {
value_changed = STRCMP(oldval, *varp) != 0;
// Since we check the value, there is no need to set P_INSECURE,
// even when the value comes from a modeline.
*value_checked = true;
}
} else if (gvarp == &p_syn) {
if (!valid_filetype(*varp)) {
errmsg = e_invarg;
} else {
value_changed = STRCMP(oldval, *varp) != 0;
// Since we check the value, there is no need to set P_INSECURE,
// even when the value comes from a modeline.
*value_checked = true;
}
} else if (varp == &curwin->w_p_winhl) {
if (!parse_winhl_opt(curwin)) {
@ -3194,7 +3258,7 @@ did_set_string_option (
if (p != NULL) {
for (s = *varp; *s; ++s)
if (vim_strchr(p, *s) == NULL) {
errmsg = illegal_char(errbuf, *s);
errmsg = illegal_char(errbuf, errbuflen, *s);
break;
}
}
@ -3258,6 +3322,11 @@ did_set_string_option (
// already set to this value.
if (!(opt_flags & OPT_MODELINE) || value_changed) {
static int ft_recursive = 0;
int secure_save = secure;
// Reset the secure flag, since the value of 'filetype' has
// been checked to be safe.
secure = 0;
ft_recursive++;
did_filetype = true;
@ -3270,6 +3339,7 @@ did_set_string_option (
if (varp != &(curbuf->b_p_ft)) {
varp = NULL;
}
secure = secure_save;
}
}
if (varp == &(curwin->w_s->b_p_spl)) {
@ -3287,11 +3357,13 @@ did_set_string_option (
* '.encoding'.
*/
for (p = q; *p != NUL; ++p)
if (vim_strchr((char_u *)"_.,", *p) != NULL)
if (!ASCII_ISALNUM(*p) && *p != '-')
break;
vim_snprintf((char *)fname, sizeof(fname), "spell/%.*s.vim",
(int)(p - q), q);
source_runtime(fname, DIP_ALL);
if (p > q) {
vim_snprintf((char *)fname, sizeof(fname), "spell/%.*s.vim",
(int)(p - q), q);
source_runtime(fname, DIP_ALL);
}
}
}
@ -3311,9 +3383,6 @@ did_set_string_option (
return errmsg;
}
#ifdef _MSC_VER
#pragma optimize("", on)
#endif
/*
* Simple int comparison function for use with qsort()
@ -3553,7 +3622,7 @@ char_u *check_stl_option(char_u *s)
continue;
}
if (vim_strchr(STL_ALL, *s) == NULL) {
return illegal_char(errbuf, *s);
return illegal_char(errbuf, sizeof(errbuf), *s);
}
if (*s == '{') {
s++;
@ -4892,19 +4961,20 @@ char *set_option_value(const char *const name, const long number,
return NULL;
}
/*
* Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
*/
int find_key_option_len(const char_u *arg, size_t len)
// Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
// When "has_lt" is true there is a '<' before "*arg_arg".
// Returns 0 when the key is not recognized.
int find_key_option_len(const char_u *arg_arg, size_t len, bool has_lt)
{
int key;
int key = 0;
int modifiers;
const char_u *arg = arg_arg;
// Don't use get_special_key_code() for t_xx, we don't want it to call
// add_termcap_entry().
if (len >= 4 && arg[0] == 't' && arg[1] == '_') {
key = TERMCAP2KEY(arg[2], arg[3]);
} else {
} else if (has_lt) {
arg--; // put arg at the '<'
modifiers = 0;
key = find_special_key(&arg, len + 1, &modifiers, true, true, false);
@ -4915,9 +4985,9 @@ int find_key_option_len(const char_u *arg, size_t len)
return key;
}
static int find_key_option(const char_u *arg)
static int find_key_option(const char_u *arg, bool has_lt)
{
return find_key_option_len(arg, STRLEN(arg));
return find_key_option_len(arg, STRLEN(arg), has_lt);
}
/*

View File

@ -178,14 +178,6 @@ enum {
SHM_RO, SHM_MOD, SHM_FILE, SHM_LAST, SHM_TEXT, SHM_LINES, SHM_NEW, SHM_WRI, \
0, \
})
/// All possible flags for 'shm'.
#define SHM_ALL ((char_u[]) { \
SHM_RO, SHM_MOD, SHM_FILE, SHM_LAST, SHM_TEXT, SHM_LINES, SHM_NEW, SHM_WRI, \
SHM_ABBREVIATIONS, SHM_WRITE, SHM_TRUNC, SHM_TRUNCALL, SHM_OVER, \
SHM_OVERALL, SHM_SEARCH, SHM_ATTENTION, SHM_INTRO, SHM_COMPLETIONMENU, \
SHM_RECORDING, SHM_FILEINFO, \
0, \
})
/* characters for p_go: */
#define GO_ASEL 'a' /* autoselect */
@ -503,6 +495,7 @@ EXTERN long p_mmd; // 'maxmapdepth'
EXTERN long p_mmp; // 'maxmempattern'
EXTERN long p_mis; // 'menuitems'
EXTERN char_u *p_msm; // 'mkspellmem'
EXTERN long p_mle; // 'modelineexpr'
EXTERN long p_mls; // 'modelines'
EXTERN char_u *p_mouse; // 'mouse'
EXTERN char_u *p_mousem; // 'mousemodel'

View File

@ -8,6 +8,7 @@
-- defaults={condition=nil, if_true={vi=224, vim=0}, if_false=nil},
-- secure=nil, gettext=nil, noglob=nil, normal_fname_chars=nil,
-- pri_mkrc=nil, deny_in_modelines=nil, normal_dname_chars=nil,
-- modelineexpr=nil,
-- expand=nil, nodefault=nil, no_mkrc=nil, vi_def=true, vim=true,
-- alloced=nil,
-- save_pv_indir=nil,
@ -286,6 +287,7 @@ return {
deny_duplicates=true,
vi_def=true,
expand=true,
secure=true,
varname='p_cdpath',
defaults={if_true={vi=",,"}}
},
@ -856,6 +858,7 @@ return {
type='string', scope={'window'},
vi_def=true,
vim=true,
modelineexpr=true,
alloced=true,
redraw={'current_window'},
defaults={if_true={vi="0"}}
@ -931,6 +934,7 @@ return {
type='string', scope={'window'},
vi_def=true,
vim=true,
modelineexpr=true,
alloced=true,
redraw={'current_window'},
defaults={if_true={vi="foldtext()"}}
@ -940,6 +944,7 @@ return {
type='string', scope={'buffer'},
vi_def=true,
vim=true,
modelineexpr=true,
alloced=true,
varname='p_fex',
defaults={if_true={vi=""}}
@ -1053,6 +1058,7 @@ return {
full_name='guitablabel', abbreviation='gtl',
type='string', scope={'global'},
vi_def=true,
modelineexpr=true,
redraw={'current_window'},
enable_if=false,
},
@ -1143,6 +1149,7 @@ return {
full_name='iconstring',
type='string', scope={'global'},
vi_def=true,
modelineexpr=true,
varname='p_iconstring',
defaults={if_true={vi=""}}
},
@ -1209,6 +1216,7 @@ return {
full_name='includeexpr', abbreviation='inex',
type='string', scope={'buffer'},
vi_def=true,
modelineexpr=true,
alloced=true,
varname='p_inex',
defaults={if_true={vi=""}}
@ -1225,6 +1233,7 @@ return {
type='string', scope={'buffer'},
vi_def=true,
vim=true,
modelineexpr=true,
alloced=true,
varname='p_inde',
defaults={if_true={vi=""}}
@ -1538,6 +1547,14 @@ return {
varname='p_ml',
defaults={if_true={vi=false, vim=true}}
},
{
full_name='modelineexpr', abbreviation='mle',
type='bool', scope={'global'},
vi_def=true,
secure=true,
varname='p_mle',
defaults={if_true={vi=false}}
},
{
full_name='modelines', abbreviation='mls',
type='number', scope={'global'},
@ -1898,6 +1915,7 @@ return {
type='string', scope={'global'},
vi_def=true,
alloced=true,
modelineexpr=true,
redraw={'statuslines'},
varname='p_ruf',
defaults={if_true={vi=""}}
@ -2293,6 +2311,7 @@ return {
type='string', scope={'global', 'window'},
vi_def=true,
alloced=true,
modelineexpr=true,
redraw={'statuslines'},
varname='p_stl',
defaults={if_true={vi=""}}
@ -2352,6 +2371,7 @@ return {
full_name='tabline', abbreviation='tal',
type='string', scope={'global'},
vi_def=true,
modelineexpr=true,
redraw={'all_windows'},
varname='p_tal',
defaults={if_true={vi=""}}
@ -2511,6 +2531,7 @@ return {
full_name='titlestring',
type='string', scope={'global'},
vi_def=true,
modelineexpr=true,
varname='p_titlestring',
defaults={if_true={vi=""}}
},

View File

@ -4920,7 +4920,7 @@ regmatch (
}
} else {
const char_u *const line =
reg_getline(behind_pos.rs_u.pos.lnum);
reg_getline(rp->rs_un.regsave.rs_u.pos.lnum);
rp->rs_un.regsave.rs_u.pos.col -=
utf_head_off(line,

View File

@ -5338,10 +5338,11 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
schar_from_ascii(ScreenLines[off - 1], ' ');
ScreenAttrs[off - 1] = 0;
// redraw the previous cell, make it empty
if (put_dirty_first == -1) {
if (put_dirty_first == -1 || col-1 < put_dirty_first) {
put_dirty_first = col-1;
}
put_dirty_last = col+1;
put_dirty_last = MAX(put_dirty_last, col+1);
// force the cell at "col" to be redrawn
force_redraw_next = true;
}
@ -5422,10 +5423,10 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
ScreenLines[off + 1][0] = 0;
ScreenAttrs[off + 1] = attr;
}
if (put_dirty_first == -1) {
if (put_dirty_first == -1 || col < put_dirty_first) {
put_dirty_first = col;
}
put_dirty_last = col+mbyte_cells;
put_dirty_last = MAX(put_dirty_last, col+mbyte_cells);
}
off += mbyte_cells;

View File

@ -2510,7 +2510,7 @@ buf_T *open_spellbuf(void)
buf->b_spell = true;
buf->b_p_swf = true; // may create a swap file
if (ml_open(buf) == FAIL) {
abort();
ELOG("Error opening a new memline");
}
ml_open_file(buf); // create swap file now

View File

@ -1304,8 +1304,6 @@ static void redraw(bool restore_cursor)
static void adjust_topline(Terminal *term, buf_T *buf, long added)
{
int height, width;
vterm_get_size(term->vt, &height, &width);
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_buffer == buf) {
linenr_T ml_end = buf->b_ml.ml_line_count;
@ -1314,7 +1312,7 @@ static void adjust_topline(Terminal *term, buf_T *buf, long added)
if (following || (wp == curwin && is_focused(term))) {
// "Follow" the terminal output
wp->w_cursor.lnum = ml_end;
set_topline(wp, MAX(wp->w_cursor.lnum - height + 1, 1));
set_topline(wp, MAX(wp->w_cursor.lnum - wp->w_height + 1, 1));
} else {
// Ensure valid cursor for each window displaying this terminal.
wp->w_cursor.lnum = MIN(wp->w_cursor.lnum, ml_end);

View File

@ -1,6 +1,6 @@
" Vim script language tests
" Author: Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com>
" Last Change: 2016 Feb 07
" Last Change: 2019 May 24
"-------------------------------------------------------------------------------
" Test environment {{{1
@ -9005,5 +9005,4 @@ Xcheck 50443995
"-------------------------------------------------------------------------------
" Modelines {{{1
" vim: ts=8 sw=4 tw=80 fdm=marker
" vim: fdt=substitute(substitute(foldtext(),\ '\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\ \\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\ '\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "")
"-------------------------------------------------------------------------------

View File

@ -28,6 +28,7 @@ source test_lambda.vim
source test_mapping.vim
source test_menu.vim
source test_messages.vim
source test_modeline.vim
source test_move.vim
source test_partial.vim
source test_popup.vim

View File

@ -652,6 +652,29 @@ func Test_OptionSet_diffmode_close()
"delfunc! AutoCommandOptionSet
endfunc
func Test_OptionSet_modeline()
throw 'skipped: Nvim does not support test_override()'
call test_override('starting', 1)
au! OptionSet
augroup set_tabstop
au OptionSet tabstop call timer_start(1, {-> execute("echo 'Handler called'", "")})
augroup END
call writefile(['vim: set ts=7 sw=5 :', 'something'], 'XoptionsetModeline')
set modeline
let v:errmsg = ''
call assert_fails('split XoptionsetModeline', 'E12:')
call assert_equal(7, &ts)
call assert_equal('', v:errmsg)
augroup set_tabstop
au!
augroup END
bwipe!
set ts&
call delete('XoptionsetModeline')
call test_override('starting', 0)
endfunc
" Test for Bufleave autocommand that deletes the buffer we are about to edit.
func Test_BufleaveWithDelete()
new | edit Xfile1

View File

@ -1037,3 +1037,19 @@ func Test_func_range_with_edit()
call delete('Xfuncrange2')
bwipe!
endfunc
sandbox function Fsandbox()
normal ix
endfunc
func Test_func_sandbox()
sandbox let F = {-> 'hello'}
call assert_equal('hello', F())
sandbox let F = {-> execute("normal ix\<Esc>")}
call assert_fails('call F()', 'E48:')
unlet F
call assert_fails('call Fsandbox()', 'E48:')
delfunc Fsandbox
endfunc

View File

@ -1,12 +1,12 @@
" Test glob2regpat()
func Test_invalid()
func Test_glob2regpat_invalid()
call assert_fails('call glob2regpat(1.33)', 'E806:')
call assert_fails('call glob2regpat("}")', 'E219:')
call assert_fails('call glob2regpat("{")', 'E220:')
endfunc
func Test_valid()
func Test_glob2regpat_valid()
call assert_equal('^foo\.', glob2regpat('foo.*'))
call assert_equal('^foo.$', glob2regpat('foo?'))
call assert_equal('\.vim$', glob2regpat('*.vim'))

View File

@ -0,0 +1,173 @@
" Tests for parsing the modeline.
func Test_modeline_invalid()
" This was reading allocated memory in the past.
call writefile(['vi:0', 'nothing'], 'Xmodeline')
let modeline = &modeline
set modeline
call assert_fails('set Xmodeline', 'E518:')
let &modeline = modeline
bwipe!
call delete('Xmodeline')
endfunc
func Test_modeline_filetype()
call writefile(['vim: set ft=c :', 'nothing'], 'Xmodeline_filetype')
let modeline = &modeline
set modeline
filetype plugin on
split Xmodeline_filetype
call assert_equal("c", &filetype)
call assert_equal(1, b:did_ftplugin)
call assert_equal("ccomplete#Complete", &ofu)
bwipe!
call delete('Xmodeline_filetype')
let &modeline = modeline
filetype plugin off
endfunc
func Test_modeline_syntax()
call writefile(['vim: set syn=c :', 'nothing'], 'Xmodeline_syntax')
let modeline = &modeline
set modeline
syntax enable
split Xmodeline_syntax
call assert_equal("c", &syntax)
call assert_equal("c", b:current_syntax)
bwipe!
call delete('Xmodeline_syntax')
let &modeline = modeline
syntax off
endfunc
func Test_modeline_keymap()
if !has('keymap')
return
endif
call writefile(['vim: set keymap=greek :', 'nothing'], 'Xmodeline_keymap')
let modeline = &modeline
set modeline
split Xmodeline_keymap
call assert_equal("greek", &keymap)
call assert_match('greek\|grk', b:keymap_name)
bwipe!
call delete('Xmodeline_keymap')
let &modeline = modeline
set keymap= iminsert=0 imsearch=-1
endfunc
func s:modeline_fails(what, text, error)
if !exists('+' . a:what)
return
endif
let fname = "Xmodeline_fails_" . a:what
call writefile(['vim: set ' . a:text . ' :', 'nothing'], fname)
let modeline = &modeline
set modeline
filetype plugin on
syntax enable
call assert_fails('split ' . fname, a:error)
call assert_equal("", &filetype)
call assert_equal("", &syntax)
bwipe!
call delete(fname)
let &modeline = modeline
filetype plugin off
syntax off
endfunc
func Test_modeline_filetype_fails()
call s:modeline_fails('filetype', 'ft=evil$CMD', 'E474:')
endfunc
func Test_modeline_syntax_fails()
call s:modeline_fails('syntax', 'syn=evil$CMD', 'E474:')
endfunc
func Test_modeline_keymap_fails()
call s:modeline_fails('keymap', 'keymap=evil$CMD', 'E474:')
endfunc
func Test_modeline_fails_always()
call s:modeline_fails('backupdir', 'backupdir=Something()', 'E520:')
call s:modeline_fails('cdpath', 'cdpath=Something()', 'E520:')
call s:modeline_fails('charconvert', 'charconvert=Something()', 'E520:')
call s:modeline_fails('completefunc', 'completefunc=Something()', 'E520:')
call s:modeline_fails('cscopeprg', 'cscopeprg=Something()', 'E520:')
call s:modeline_fails('diffexpr', 'diffexpr=Something()', 'E520:')
call s:modeline_fails('directory', 'directory=Something()', 'E520:')
call s:modeline_fails('equalprg', 'equalprg=Something()', 'E520:')
call s:modeline_fails('errorfile', 'errorfile=Something()', 'E520:')
call s:modeline_fails('exrc', 'exrc=Something()', 'E520:')
call s:modeline_fails('formatprg', 'formatprg=Something()', 'E520:')
call s:modeline_fails('fsync', 'fsync=Something()', 'E520:')
call s:modeline_fails('grepprg', 'grepprg=Something()', 'E520:')
call s:modeline_fails('helpfile', 'helpfile=Something()', 'E520:')
call s:modeline_fails('imactivatefunc', 'imactivatefunc=Something()', 'E520:')
call s:modeline_fails('imstatusfunc', 'imstatusfunc=Something()', 'E520:')
call s:modeline_fails('imstyle', 'imstyle=Something()', 'E520:')
call s:modeline_fails('keywordprg', 'keywordprg=Something()', 'E520:')
call s:modeline_fails('langmap', 'langmap=Something()', 'E520:')
call s:modeline_fails('luadll', 'luadll=Something()', 'E520:')
call s:modeline_fails('makeef', 'makeef=Something()', 'E520:')
call s:modeline_fails('makeprg', 'makeprg=Something()', 'E520:')
call s:modeline_fails('mkspellmem', 'mkspellmem=Something()', 'E520:')
call s:modeline_fails('mzschemedll', 'mzschemedll=Something()', 'E520:')
call s:modeline_fails('mzschemegcdll', 'mzschemegcdll=Something()', 'E520:')
call s:modeline_fails('modelineexpr', 'modelineexpr=Something()', 'E520:')
call s:modeline_fails('omnifunc', 'omnifunc=Something()', 'E520:')
call s:modeline_fails('operatorfunc', 'operatorfunc=Something()', 'E520:')
call s:modeline_fails('perldll', 'perldll=Something()', 'E520:')
call s:modeline_fails('printdevice', 'printdevice=Something()', 'E520:')
call s:modeline_fails('patchexpr', 'patchexpr=Something()', 'E520:')
call s:modeline_fails('printexpr', 'printexpr=Something()', 'E520:')
call s:modeline_fails('pythondll', 'pythondll=Something()', 'E520:')
call s:modeline_fails('pythonhome', 'pythonhome=Something()', 'E520:')
call s:modeline_fails('pythonthreedll', 'pythonthreedll=Something()', 'E520:')
call s:modeline_fails('pythonthreehome', 'pythonthreehome=Something()', 'E520:')
call s:modeline_fails('pyxversion', 'pyxversion=Something()', 'E520:')
call s:modeline_fails('rubydll', 'rubydll=Something()', 'E520:')
call s:modeline_fails('runtimepath', 'runtimepath=Something()', 'E520:')
call s:modeline_fails('secure', 'secure=Something()', 'E520:')
call s:modeline_fails('shell', 'shell=Something()', 'E520:')
call s:modeline_fails('shellcmdflag', 'shellcmdflag=Something()', 'E520:')
call s:modeline_fails('shellpipe', 'shellpipe=Something()', 'E520:')
call s:modeline_fails('shellquote', 'shellquote=Something()', 'E520:')
call s:modeline_fails('shellredir', 'shellredir=Something()', 'E520:')
call s:modeline_fails('shellxquote', 'shellxquote=Something()', 'E520:')
call s:modeline_fails('spellfile', 'spellfile=Something()', 'E520:')
call s:modeline_fails('spellsuggest', 'spellsuggest=Something()', 'E520:')
call s:modeline_fails('tcldll', 'tcldll=Something()', 'E520:')
call s:modeline_fails('titleold', 'titleold=Something()', 'E520:')
call s:modeline_fails('viewdir', 'viewdir=Something()', 'E520:')
call s:modeline_fails('viminfo', 'viminfo=Something()', 'E520:')
call s:modeline_fails('viminfofile', 'viminfofile=Something()', 'E520:')
call s:modeline_fails('winptydll', 'winptydll=Something()', 'E520:')
call s:modeline_fails('undodir', 'undodir=Something()', 'E520:')
" only check a few terminal options
" Skip these since nvim doesn't support termcodes as options
"call s:modeline_fails('t_AB', 't_AB=Something()', 'E520:')
"call s:modeline_fails('t_ce', 't_ce=Something()', 'E520:')
"call s:modeline_fails('t_sr', 't_sr=Something()', 'E520:')
"call s:modeline_fails('t_8b', 't_8b=Something()', 'E520:')
endfunc
func Test_modeline_fails_modelineexpr()
call s:modeline_fails('balloonexpr', 'balloonexpr=Something()', 'E992:')
call s:modeline_fails('foldexpr', 'foldexpr=Something()', 'E992:')
call s:modeline_fails('foldtext', 'foldtext=Something()', 'E992:')
call s:modeline_fails('formatexpr', 'formatexpr=Something()', 'E992:')
call s:modeline_fails('guitablabel', 'guitablabel=Something()', 'E992:')
call s:modeline_fails('iconstring', 'iconstring=Something()', 'E992:')
call s:modeline_fails('includeexpr', 'includeexpr=Something()', 'E992:')
call s:modeline_fails('indentexpr', 'indentexpr=Something()', 'E992:')
call s:modeline_fails('rulerformat', 'rulerformat=Something()', 'E992:')
call s:modeline_fails('statusline', 'statusline=Something()', 'E992:')
call s:modeline_fails('tabline', 'tabline=Something()', 'E992:')
call s:modeline_fails('titlestring', 'titlestring=Something()', 'E992:')
endfunc

View File

@ -1297,5 +1297,4 @@ endfunc
"-------------------------------------------------------------------------------
" Modelines {{{1
" vim: ts=8 sw=4 tw=80 fdm=marker
" vim: fdt=substitute(substitute(foldtext(),\ '\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\ \\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\ '\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "")
"-------------------------------------------------------------------------------

View File

@ -4,7 +4,8 @@ local lfs = require('lfs')
local neq, eq, command = helpers.neq, helpers.eq, helpers.command
local clear, curbufmeths = helpers.clear, helpers.curbufmeths
local exc_exec, expect, eval = helpers.exc_exec, helpers.expect, helpers.eval
local insert = helpers.insert
local insert, meth_pcall = helpers.insert, helpers.meth_pcall
local meths = helpers.meths
describe('api functions', function()
before_each(clear)
@ -145,4 +146,10 @@ describe('api functions', function()
]])
screen:detach()
end)
it('cannot be called from sandbox', function()
eq({false, 'Vim(call):E48: Not allowed in sandbox'},
meth_pcall(command, "sandbox call nvim_input('ievil')"))
eq({''}, meths.buf_get_lines(0, 0, -1, true))
end)
end)

View File

@ -286,6 +286,15 @@ describe("getcwd()", function ()
command("call delete('../"..directories.global.."', 'd')")
eq("", helpers.eval("getcwd()"))
end)
it("works with 'autochdir' after local directory was set (#9892)", function()
local curdir = cwd()
command('lcd ' .. directories.global)
command('lcd -')
command('set autochdir')
command('edit ' .. directories.global .. '/foo')
eq(curdir .. pathsep .. directories.global, cwd())
end)
end)

View File

@ -1,10 +1,11 @@
local Screen = require('test.functional.ui.screen')
local helpers = require('test.functional.helpers')(after_each)
local lfs = require('lfs')
local feed_command, eq, eval, expect, source =
helpers.feed_command, helpers.eq, helpers.eval, helpers.expect, helpers.source
local eq, eval, expect, source =
helpers.eq, helpers.eval, helpers.expect, helpers.source
local clear = helpers.clear
local command = helpers.command
local expect_err = helpers.expect_err
local feed = helpers.feed
local nvim_prog = helpers.nvim_prog
local ok = helpers.ok
@ -17,9 +18,14 @@ describe(':recover', function()
before_each(clear)
it('fails if given a non-existent swapfile', function()
local swapname = 'bogus-swapfile'
feed_command('recover '..swapname) -- This should not segfault. #2117
eq('E305: No swap file found for '..swapname, eval('v:errmsg'))
local swapname = 'bogus_swapfile'
local swapname2 = 'bogus_swapfile.swp'
expect_err('E305: No swap file found for '..swapname,
command, 'recover '..swapname) -- Should not segfault. #2117
-- Also check filename ending with ".swp". #9504
expect_err('Vim%(recover%):E306: Cannot open '..swapname2,
command, 'recover '..swapname2) -- Should not segfault. #2117
eq(2, eval('1+1')) -- Still alive?
end)
end)

View File

@ -8,7 +8,7 @@ local exit_altscreen = thelpers.exit_altscreen
if helpers.pending_win32(pending) then return end
describe('terminal altscreen', function()
describe(':terminal altscreen', function()
local screen
before_each(function()

View File

@ -6,7 +6,7 @@ local eval, feed_command, source = helpers.eval, helpers.feed_command, helpers.s
local eq, neq = helpers.eq, helpers.neq
local write_file = helpers.write_file
describe('terminal buffer', function()
describe(':terminal buffer', function()
local screen
before_each(function()

View File

@ -7,7 +7,7 @@ local feed_command = helpers.feed_command
local hide_cursor = thelpers.hide_cursor
local show_cursor = thelpers.show_cursor
describe('terminal cursor', function()
describe(':terminal cursor', function()
local screen
before_each(function()

View File

@ -5,7 +5,7 @@ local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
local nvim_dir, command = helpers.nvim_dir, helpers.command
local eq, eval = helpers.eq, helpers.eval
describe('terminal window highlighting', function()
describe(':terminal window highlighting', function()
local screen
before_each(function()

View File

@ -4,7 +4,7 @@ local clear, eq, eval = helpers.clear, helpers.eq, helpers.eval
local feed, nvim = helpers.feed, helpers.nvim
local feed_data = thelpers.feed_data
describe('terminal mouse', function()
describe(':terminal mouse', function()
local screen
before_each(function()

View File

@ -12,7 +12,7 @@ local curbufmeths = helpers.curbufmeths
local nvim = helpers.nvim
local feed_data = thelpers.feed_data
describe('terminal scrollback', function()
describe(':terminal scrollback', function()
local screen
before_each(function()
@ -344,7 +344,7 @@ describe('terminal scrollback', function()
end)
end)
describe('terminal prints more lines than the screen height and exits', function()
describe(':terminal prints more lines than the screen height and exits', function()
it('will push extra lines to scrollback', function()
clear()
local screen = Screen.new(30, 7)
@ -460,7 +460,7 @@ describe("'scrollback' option", function()
screen:detach()
end)
it('defaults to 10000 in terminal buffers', function()
it('defaults to 10000 in :terminal buffers', function()
set_fake_shell()
command('terminal')
eq(10000, curbufmeths.get_option('scrollback'))

View File

@ -20,7 +20,7 @@ local read_file = helpers.read_file
if helpers.pending_win32(pending) then return end
describe('tui', function()
describe('TUI', function()
local screen
before_each(function()

View File

@ -3,8 +3,12 @@ local thelpers = require('test.functional.terminal.helpers')
local feed, clear = helpers.feed, helpers.clear
local wait = helpers.wait
local iswin = helpers.iswin
local command = helpers.command
local retry = helpers.retry
local eq = helpers.eq
local eval = helpers.eval
describe('terminal window', function()
describe(':terminal window', function()
local screen
before_each(function()
@ -12,6 +16,19 @@ describe('terminal window', function()
screen = thelpers.screen_setup()
end)
it('sets topline correctly #8556', function()
-- Test has hardcoded assumptions of dimensions.
eq(7, eval('&lines'))
command('set shell=sh')
command('terminal')
retry(nil, nil, function() assert(nil ~= eval('b:terminal_job_pid')) end)
-- Terminal/shell contents must exceed the height of this window.
command('topleft 1split')
feed([[i<cr>]])
-- Check topline _while_ in terminal-mode.
retry(nil, nil, function() eq(6, eval('winsaveview()["topline"]')) end)
end)
describe("with 'number'", function()
it('wraps text', function()
feed([[<C-\><C-N>]])

View File

@ -9,7 +9,7 @@ local eval = helpers.eval
local iswin = helpers.iswin
local retry = helpers.retry
describe('terminal', function()
describe(':terminal', function()
local screen
before_each(function()