mirror of
https://github.com/neovim/neovim
synced 2025-07-22 06:12:21 +00:00
Compare commits
42 Commits
Author | SHA1 | Date | |
---|---|---|---|
edad360800 | |||
e4ecb70d08 | |||
413b313ad2 | |||
5b47e4dc38 | |||
959ff84e04 | |||
13f3a21226 | |||
1bb1b5087e | |||
536e9320a0 | |||
3bd532ad15 | |||
2c5eede368 | |||
9ab48aac20 | |||
5cca6f61bb | |||
6683cb60b8 | |||
a72c05a6f6 | |||
ad8bba10c4 | |||
9dca0b27df | |||
0ec8da4387 | |||
1d3a1b55d1 | |||
7ddb102292 | |||
adff3f4dee | |||
fee1880ea7 | |||
f514b7fbbc | |||
c202e4a868 | |||
154765e4bf | |||
ede21f9518 | |||
361d4be588 | |||
bd4bb61f35 | |||
8a6bb66e80 | |||
4553fc5e6c | |||
877d539904 | |||
60c3c92db1 | |||
d7cf93ce34 | |||
1060bfd033 | |||
f891131c6b | |||
9a5488c2a6 | |||
1793ba8176 | |||
947069ba14 | |||
46c7e12f27 | |||
b98be54148 | |||
f1843c0035 | |||
1204421888 | |||
aaa8c3d711 |
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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: >
|
||||
|
BIN
runtime/nvim.png
BIN
runtime/nvim.png
Binary file not shown.
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 5.7 KiB |
@ -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'
|
||||
|
@ -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"
|
||||
|
@ -594,7 +594,7 @@ void nvim_set_current_dir(String dir, Error *err)
|
||||
return;
|
||||
}
|
||||
|
||||
post_chdir(kCdScopeGlobal);
|
||||
post_chdir(kCdScopeGlobal, true);
|
||||
try_end(err);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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',
|
||||
},
|
||||
|
@ -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);
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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'
|
||||
|
@ -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=""}}
|
||||
},
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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',\ "")
|
||||
"-------------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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'))
|
||||
|
173
src/nvim/testdir/test_modeline.vim
Normal file
173
src/nvim/testdir/test_modeline.vim
Normal 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
|
@ -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',\ "")
|
||||
"-------------------------------------------------------------------------------
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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'))
|
||||
|
@ -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()
|
||||
|
@ -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>]])
|
||||
|
@ -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()
|
||||
|
Reference in New Issue
Block a user