aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.ci/before_script.sh6
-rw-r--r--.ci/common/build.sh11
-rw-r--r--.ci/common/test.sh7
-rwxr-xr-x.ci/install.sh2
-rwxr-xr-x.ci/script.sh3
-rw-r--r--Makefile2
-rw-r--r--man/nvim.12
-rw-r--r--runtime/autoload/remote/host.vim2
-rw-r--r--runtime/doc/eval.txt32
-rw-r--r--runtime/doc/nvim.txt9
-rw-r--r--runtime/doc/starting.txt41
-rw-r--r--runtime/doc/various.txt2
-rw-r--r--runtime/doc/vim_diff.txt2
-rw-r--r--runtime/plugin/matchit.vim30
-rw-r--r--src/nvim/eval.c66
-rw-r--r--src/nvim/globals.h2
-rw-r--r--src/nvim/memline.c7
-rw-r--r--src/nvim/message.c2
-rw-r--r--src/nvim/mouse.c76
-rw-r--r--src/nvim/os/fileio.c1
-rw-r--r--src/nvim/os/fs.c1
-rw-r--r--src/nvim/os/pty_process_unix.c1
-rw-r--r--src/nvim/syntax.c18
-rw-r--r--src/nvim/testdir/Makefile1
-rw-r--r--src/nvim/testdir/test30.in230
-rw-r--r--src/nvim/testdir/test30.ok130
-rw-r--r--src/nvim/version.c2
-rw-r--r--test/functional/eval/execute_spec.lua (renamed from test/functional/eval/capture_spec.lua)32
-rw-r--r--test/functional/legacy/030_fileformats_spec.lua375
-rw-r--r--test/functional/ui/mouse_spec.lua317
30 files changed, 933 insertions, 479 deletions
diff --git a/.ci/before_script.sh b/.ci/before_script.sh
index 6babc582ea..23940ab2e2 100755
--- a/.ci/before_script.sh
+++ b/.ci/before_script.sh
@@ -29,10 +29,10 @@ if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
# That allows to test changing the group of the file by `os_fchown`.
sudo dscl . -create /Groups/chown_test
sudo dscl . -append /Groups/chown_test GroupMembership "${USER}"
-else
- # Compile dependencies.
- build_deps
fi
+# Compile dependencies.
+build_deps
+
rm -rf "${LOG_DIR}"
mkdir -p "${LOG_DIR}"
diff --git a/.ci/common/build.sh b/.ci/common/build.sh
index 06bdab707f..c89d4c559b 100644
--- a/.ci/common/build.sh
+++ b/.ci/common/build.sh
@@ -14,10 +14,15 @@ build_deps() {
# If there is a valid cache and we're not forced to recompile,
# use cached third-party dependencies.
if [[ -f "${CACHE_MARKER}" ]] && [[ "${BUILD_NVIM_DEPS}" != true ]]; then
- echo "Using third-party dependencies from Travis's cache (last updated: $(stat -c '%y' "${CACHE_MARKER}"))."
+ if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
+ local statcmd="stat -f '%Sm'"
+ else
+ local statcmd="stat -c '%y'"
+ fi
+ echo "Using third-party dependencies from Travis's cache (last updated: $(${statcmd} "${CACHE_MARKER}"))."
mkdir -p "$(dirname "${DEPS_BUILD_DIR}")"
- mv -T "${HOME}/.cache/nvim-deps" "${DEPS_BUILD_DIR}"
+ mv "${HOME}/.cache/nvim-deps" "${DEPS_BUILD_DIR}"
else
mkdir -p "${DEPS_BUILD_DIR}"
fi
@@ -26,7 +31,7 @@ build_deps() {
# update CMake configuration and update to newer deps versions.
cd "${DEPS_BUILD_DIR}"
echo "Configuring with '${DEPS_CMAKE_FLAGS}'."
- cmake ${DEPS_CMAKE_FLAGS} "${TRAVIS_BUILD_DIR}/third-party/"
+ CC= cmake ${DEPS_CMAKE_FLAGS} "${TRAVIS_BUILD_DIR}/third-party/"
if ! ${MAKE_CMD}; then
exit 1
diff --git a/.ci/common/test.sh b/.ci/common/test.sh
index 1e66ecb239..dc59f4f793 100644
--- a/.ci/common/test.sh
+++ b/.ci/common/test.sh
@@ -49,11 +49,11 @@ asan_check() {
}
run_unittests() {
- ${MAKE_CMD} unittest
+ ${MAKE_CMD} -C "${BUILD_DIR}" unittest
}
run_functionaltests() {
- if ! ${MAKE_CMD} ${FUNCTIONALTEST}; then
+ if ! ${MAKE_CMD} -C "${BUILD_DIR}" ${FUNCTIONALTEST}; then
asan_check "${LOG_DIR}"
valgrind_check "${LOG_DIR}"
exit 1
@@ -63,7 +63,8 @@ run_functionaltests() {
}
run_oldtests() {
- if ! make oldtest; then
+ ${MAKE_CMD} -C "${BUILD_DIR}" helptags
+ if ! make -C "${TRAVIS_BUILD_DIR}/src/nvim/testdir"; then
reset
asan_check "${LOG_DIR}"
valgrind_check "${LOG_DIR}"
diff --git a/.ci/install.sh b/.ci/install.sh
index 93c9a930ac..f809bb06ea 100755
--- a/.ci/install.sh
+++ b/.ci/install.sh
@@ -9,6 +9,7 @@ fi
if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
brew install gettext
+ brew reinstall -s libtool
elif [[ "${BUILD_MINGW}" == ON ]]; then
# TODO: When Travis gets a recent version of Mingw-w64 use packages:
# binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686 mingw-w64-dev mingw-w64-tools
@@ -16,7 +17,6 @@ elif [[ "${BUILD_MINGW}" == ON ]]; then
echo "Downloading MinGW..."
curl -sSL "https://github.com/neovim/deps/raw/master/opt/i686-w64-mingw32-gcc-4.8.0-linux64_rubenvb.tar.xz" \
| tar xJf - -C "${HOME}/.local"
-
fi
# Use default CC to avoid compilation problems when installing Python modules.
diff --git a/.ci/script.sh b/.ci/script.sh
index c3c7b8dfa9..46c4eecf38 100755
--- a/.ci/script.sh
+++ b/.ci/script.sh
@@ -12,9 +12,6 @@ fi
# as $USER, while retaining the environment variables defined and belonging
# to secondary groups given above in usermod.
if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
- # Set up precompiled third-party dependencies.
- eval "$(curl -Ss https://raw.githubusercontent.com/neovim/bot-ci/master/scripts/travis-setup.sh) deps-x64"
-
sudo -E su "${USER}" -c ".ci/run_tests.sh"
else
.ci/run_tests.sh
diff --git a/Makefile b/Makefile
index 552a79466b..8fdf007260 100644
--- a/Makefile
+++ b/Makefile
@@ -89,7 +89,7 @@ oldtest: | nvim helptags
+$(SINGLE_MAKE) -C src/nvim/testdir $(MAKEOVERRIDES)
helptags: | nvim
- +$(BUILD_CMD) -C build runtime/doc/tags
+ +$(BUILD_CMD) -C build helptags
functionaltest: | nvim
+$(BUILD_CMD) -C build functionaltest
diff --git a/man/nvim.1 b/man/nvim.1
index 2fa3ab8ff5..70bf480f2b 100644
--- a/man/nvim.1
+++ b/man/nvim.1
@@ -353,7 +353,7 @@ Like
but used to store data not generally edited by the user,
namely swap, backup, and ShaDa files.
Defaults to
-.Pa ~/.local/share/nvim
+.Pa ~/.local/share
if not set.
.It Ev VIMINIT
A string of Ex commands to be executed at startup.
diff --git a/runtime/autoload/remote/host.vim b/runtime/autoload/remote/host.vim
index 4ec2eeb5b7..eb5e87d7e1 100644
--- a/runtime/autoload/remote/host.vim
+++ b/runtime/autoload/remote/host.vim
@@ -121,7 +121,7 @@ endfunction
function! s:GetManifest() abort
let prefix = exists('$MYVIMRC')
\ ? $MYVIMRC
- \ : matchstr(get(split(capture('scriptnames'), '\n'), 0, ''), '\f\+$')
+ \ : matchstr(get(split(execute('scriptnames'), '\n'), 0, ''), '\f\+$')
return fnamemodify(expand(prefix, 1), ':h')
\.'/.'.fnamemodify(prefix, ':t').'-rplugin~'
endfunction
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index ba38a140d1..9ff97436bb 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1809,7 +1809,6 @@ byteidx({expr}, {nr}) Number byte index of {nr}'th char in {expr}
byteidxcomp({expr}, {nr}) Number byte index of {nr}'th char in {expr}
call({func}, {arglist} [, {dict}])
any call {func} with arguments {arglist}
-capture({command}) String capture output of {command}
ceil({expr}) Float round {expr} up
changenr() Number current change number
char2nr({expr}[, {utf8}]) Number ASCII/UTF8 value of first char in {expr}
@@ -1845,6 +1844,7 @@ escape({string}, {chars}) String escape {chars} in {string} with '\'
eval({string}) any evaluate {string} into its value
eventhandler() Number TRUE if inside an event handler
executable({expr}) Number 1 if executable {expr} exists
+execute({command}) String execute and capture output of {command}
exepath({expr}) String full path of the command {expr}
exists({expr}) Number TRUE if {expr} exists
extend({expr1}, {expr2} [, {expr3}])
@@ -2524,21 +2524,6 @@ call({func}, {arglist} [, {dict}]) *call()* *E699*
{dict} is for functions with the "dict" attribute. It will be
used to set the local variable "self". |Dictionary-function|
-capture({command}) *capture()*
- Capture output of {command}.
- If {command} is a |String|, returns {command} output.
- If {command} is a |List|, returns concatenated outputs.
- Examples: >
- echo capture('echon "foo"')
-< foo >
- echo capture(['echon "foo"', 'echon "bar"'])
-< foobar
- This function is not available in the |sandbox|.
- Note: {command} executes as if prepended with |:silent|
- (output is collected, but not displayed). If nested, an outer
- capture() will not observe the output of inner calls.
- Note: Text attributes (highlights) are not captured.
-
ceil({expr}) *ceil()*
Return the smallest integral value greater than or equal to
{expr} as a |Float| (round up).
@@ -2989,6 +2974,21 @@ executable({expr}) *executable()*
0 does not exist
-1 not implemented on this system
+execute({command}) *execute()*
+ Execute {command} and capture its output.
+ If {command} is a |String|, returns {command} output.
+ If {command} is a |List|, returns concatenated outputs.
+ Examples: >
+ echo execute('echon "foo"')
+< foo >
+ echo execute(['echon "foo"', 'echon "bar"'])
+< foobar
+ This function is not available in the |sandbox|.
+ Note: {command} executes as if prepended with |:silent|
+ (output is collected but not displayed). If nested, an outer
+ execute() will not observe output of the inner calls.
+ Note: Text attributes (highlights) are not captured.
+
exepath({expr}) *exepath()*
If {expr} is an executable and is either an absolute path, a
relative path or found in $PATH, return the full path.
diff --git a/runtime/doc/nvim.txt b/runtime/doc/nvim.txt
index 904fb3c16c..7dfbbd0cf0 100644
--- a/runtime/doc/nvim.txt
+++ b/runtime/doc/nvim.txt
@@ -18,10 +18,13 @@ Transitioning from Vim *nvim-from-vim*
To start the transition, link your previous configuration so Nvim can use it:
>
- mkdir -p ${XDG_CONFIG_HOME:=$HOME/.config}
- ln -s ~/.vim $XDG_CONFIG_HOME/nvim
- ln -s ~/.vimrc $XDG_CONFIG_HOME/nvim/init.vim
+ mkdir ~/.config
+ ln -s ~/.vim ~/.config/nvim
+ ln -s ~/.vimrc ~/.config/nvim/init.vim
<
+Note: If your system sets `$XDG_CONFIG_HOME`, use that instead of `~/.config`
+in the code above. Nvim follows the XDG |base-directories| convention.
+
See |provider-python| and |provider-clipboard| for additional software you
might need to use some features.
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index 236ed65f46..8249f8e71f 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -14,6 +14,7 @@ Starting Vim *starting*
6. Saving settings |save-settings|
7. Views and Sessions |views-sessions|
8. The ShaDa file |shada-file|
+9. Base Directories |base-directories|
==============================================================================
1. Vim arguments *vim-arguments*
@@ -382,7 +383,7 @@ accordingly. Vim proceeds in this order:
name, "init.vim" is Neovim specific location for vimrc file. Also see
|vimrc-intro|.
- Places for your personal initializations:
+ Places for your personal initializations (see |base-directories|):
Unix $XDG_CONFIG_HOME/nvim/init.vim
(default for $XDG_CONFIG_HOME is ~/.config)
Windows $XDG_CONFIG_HOME/nvim/init.vim
@@ -1083,7 +1084,7 @@ even if other entries (with known name/type/etc) are merged. |shada-merging|
SHADA FILE NAME *shada-file-name*
- The default name of the ShaDa file is "$XDG_DATA_HOME/nvim/shada/main.shada"
- for Unix. Default for $XDG_DATA_HOME is ~/.local/share.
+ for Unix. Default for $XDG_DATA_HOME is ~/.local/share. |base-directories|
- The 'n' flag in the 'shada' option can be used to specify another ShaDa
file name |'shada'|.
- The "-i" Vim argument can be used to set another file name, |-i|. When the
@@ -1370,4 +1371,40 @@ file when reading and include:
either contains more then one MessagePack object or it does not contain
complete MessagePack object.
+==============================================================================
+9. Base Directories *base-directories* *xdg*
+
+Nvim conforms to the XDG Base Directory Specification for application
+configuration and data file locations. This just means Nvim looks for some
+optional settings and uses them if they exist, otherwise defaults are chosen.
+https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
+
+CONFIGURATION DIRECTORY *$XDG_CONFIG_HOME*
+
+ Base directory default:
+ Unix: ~/.config
+ Windows: ~/AppData/Local
+
+ Nvim directory:
+ Unix: ~/.config/nvim/
+ Windows: ~/AppData/Local/nvim/
+
+DATA DIRECTORY *$XDG_DATA_HOME*
+
+ Base directory default:
+ Unix: ~/.local/share
+ Windows: ~/AppData/Local
+
+ Nvim directory:
+ Unix: ~/.local/share/nvim/
+ Windows: ~/AppData/Local/nvim-data/
+
+Note on Windows the configuration and data directory defaults are the same
+(for lack of an alternative), but the sub-directory for data is named
+"nvim-data" to separate it from the configuration sub-directory "nvim".
+
+Throughout other sections of the user manual, the defaults are used as generic
+placeholders, e.g. where "~/.config" is mentioned it should be understood to
+mean "$XDG_CONFIG_HOME or ~/.config".
+
vim:tw=78:ts=8:ft=help:norl:
diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt
index eb813866da..a1bf379d86 100644
--- a/runtime/doc/various.txt
+++ b/runtime/doc/various.txt
@@ -417,7 +417,7 @@ m *+xpm_w32* Win32 GUI only: pixmap support |w32-xpm-support|
the screen, put the commands in a function and call it
with ":silent call Function()".
Alternatives are the 'verbosefile' option or
- |capture()| function, these can be used in combination
+ |execute()| function, these can be used in combination
with ":redir".
:redi[r] >> {file} Redirect messages to file {file}. Append if {file}
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index a5b1cbf9b1..937ed9e8ba 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -98,7 +98,7 @@ Commands:
|:CheckHealth|
Functions:
- |capture()|
+ |execute()| works with |:redir|
Events:
|TabNew|
diff --git a/runtime/plugin/matchit.vim b/runtime/plugin/matchit.vim
index 70867b1f93..8053b080e1 100644
--- a/runtime/plugin/matchit.vim
+++ b/runtime/plugin/matchit.vim
@@ -1,7 +1,8 @@
" matchit.vim: (global plugin) Extended "%" matching
-" Last Change: Fri Jan 25 10:00 AM 2008 EST
+" Last Change: Fri Jul 29 01:20 AM 2016 EST
" Maintainer: Benji Fisher PhD <benji@member.AMS.org>
" Version: 1.13.2, for Vim 6.3+
+" Fix from Tommy Allen included.
" URL: http://www.vim.org/script.php?script_id=39
" Documentation:
@@ -254,12 +255,7 @@ function! s:Match_wrapper(word, forward, mode) range
" Fifth step: actually start moving the cursor and call searchpair().
" Later, :execute restore_cursor to get to the original screen.
- let restore_cursor = virtcol(".") . "|"
- normal! g0
- let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor
- normal! H
- let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
- execute restore_cursor
+ let view = winsaveview()
call cursor(0, curcol + 1)
" normal! 0
" if curcol
@@ -273,7 +269,7 @@ function! s:Match_wrapper(word, forward, mode) range
let sp_return = searchpair(ini, mid, fin, flag, skip)
let final_position = "call cursor(" . line(".") . "," . col(".") . ")"
" Restore cursor position and original screen.
- execute restore_cursor
+ call winrestview(view)
normal! m'
if sp_return > 0
execute final_position
@@ -634,7 +630,7 @@ endfun
" idea to give it its own matching patterns.
fun! s:MultiMatch(spflag, mode)
if !exists("b:match_words") || b:match_words == ""
- return ""
+ return {}
end
let restore_options = (&ic ? "" : "no") . "ignorecase"
if exists("b:match_ignorecase")
@@ -694,15 +690,7 @@ fun! s:MultiMatch(spflag, mode)
let skip = 's:comment\|string'
endif
let skip = s:ParseSkip(skip)
- " let restore_cursor = line(".") . "G" . virtcol(".") . "|"
- " normal! H
- " let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
- let restore_cursor = virtcol(".") . "|"
- normal! g0
- let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor
- normal! H
- let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
- execute restore_cursor
+ let view = winsaveview()
" Third step: call searchpair().
" Replace '\('--but not '\\('--with '\%(' and ',' with '\|'.
@@ -720,14 +708,14 @@ fun! s:MultiMatch(spflag, mode)
while level
if searchpair(openpat, '', closepat, a:spflag, skip) < 1
call s:CleanUp(restore_options, a:mode, startline, startcol)
- return ""
+ return {}
endif
let level = level - 1
endwhile
- " Restore options and return a string to restore the original position.
+ " Restore options and return view dict to restore the original position.
call s:CleanUp(restore_options, a:mode, startline, startcol)
- return restore_cursor
+ return view
endfun
" Search backwards for "if" or "while" or "<tag>" or ...
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 7fb7969783..824b298592 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -6727,7 +6727,6 @@ static struct fst {
{ "byteidx", 2, 2, f_byteidx },
{ "byteidxcomp", 2, 2, f_byteidxcomp },
{ "call", 2, 3, f_call },
- { "capture", 1, 1, f_capture },
{ "ceil", 1, 1, f_ceil },
{ "changenr", 0, 0, f_changenr },
{ "char2nr", 1, 2, f_char2nr },
@@ -6756,6 +6755,7 @@ static struct fst {
{ "eval", 1, 1, f_eval },
{ "eventhandler", 0, 0, f_eventhandler },
{ "executable", 1, 1, f_executable },
+ { "execute", 1, 1, f_execute },
{ "exepath", 1, 1, f_exepath },
{ "exists", 1, 1, f_exists },
{ "exp", 1, 1, f_exp },
@@ -8153,38 +8153,6 @@ static void f_call(typval_T *argvars, typval_T *rettv)
(void)func_call(func, &argvars[1], selfdict, rettv);
}
-// "capture(command)" function
-static void f_capture(typval_T *argvars, typval_T *rettv)
-{
- int save_msg_silent = msg_silent;
- garray_T *save_capture_ga = capture_ga;
-
- if (check_secure()) {
- return;
- }
-
- garray_T capture_local;
- capture_ga = &capture_local;
- ga_init(capture_ga, (int)sizeof(char), 80);
-
- msg_silent++;
- if (argvars[0].v_type != VAR_LIST) {
- do_cmdline_cmd((char *)get_tv_string(&argvars[0]));
- } else if (argvars[0].vval.v_list != NULL) {
- for (listitem_T *li = argvars[0].vval.v_list->lv_first;
- li != NULL; li = li->li_next) {
- do_cmdline_cmd((char *)get_tv_string(&li->li_tv));
- }
- }
- msg_silent = save_msg_silent;
-
- ga_append(capture_ga, NUL);
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = capture_ga->ga_data;
-
- capture_ga = save_capture_ga;
-}
-
/*
* "ceil({float})" function
*/
@@ -8869,6 +8837,38 @@ static void f_executable(typval_T *argvars, typval_T *rettv)
|| (gettail_dir(name) != name && os_can_exe(name, NULL, false));
}
+// "execute(command)" function
+static void f_execute(typval_T *argvars, typval_T *rettv)
+{
+ int save_msg_silent = msg_silent;
+ garray_T *save_capture_ga = capture_ga;
+
+ if (check_secure()) {
+ return;
+ }
+
+ garray_T capture_local;
+ capture_ga = &capture_local;
+ ga_init(capture_ga, (int)sizeof(char), 80);
+
+ msg_silent++;
+ if (argvars[0].v_type != VAR_LIST) {
+ do_cmdline_cmd((char *)get_tv_string(&argvars[0]));
+ } else if (argvars[0].vval.v_list != NULL) {
+ for (listitem_T *li = argvars[0].vval.v_list->lv_first;
+ li != NULL; li = li->li_next) {
+ do_cmdline_cmd((char *)get_tv_string(&li->li_tv));
+ }
+ }
+ msg_silent = save_msg_silent;
+
+ ga_append(capture_ga, NUL);
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = capture_ga->ga_data;
+
+ capture_ga = save_capture_ga;
+}
+
/// "exepath()" function
static void f_exepath(typval_T *argvars, typval_T *rettv)
{
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index f2610ac868..950ceb4c74 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -986,7 +986,7 @@ EXTERN int redir_off INIT(= false); // no redirection for a moment
EXTERN FILE *redir_fd INIT(= NULL); // message redirection file
EXTERN int redir_reg INIT(= 0); // message redirection register
EXTERN int redir_vname INIT(= 0); // message redirection variable
-EXTERN garray_T *capture_ga INIT(= NULL); // capture() buffer
+EXTERN garray_T *capture_ga INIT(= NULL); // captured output for execute()
EXTERN char_u langmap_mapchar[256]; /* mapping for language keys */
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 673205f08f..08e82071d7 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -3165,9 +3165,10 @@ attention_message (
}
/* Some of these messages are long to allow translation to
* other languages. */
- MSG_PUTS(_(
- "\n(1) Another program may be editing the same file. If this is the case,\n be careful not to end up with two different instances of the same\n file when making changes."));
- MSG_PUTS(_(" Quit, or continue with caution.\n"));
+ MSG_PUTS(_("\n(1) Another program may be editing the same file. If this is"
+ " the case,\n be careful not to end up with two different"
+ " instances of the same\n file when making changes."
+ " Quit, or continue with caution.\n"));
MSG_PUTS(_("(2) An edit session for this file crashed.\n"));
MSG_PUTS(_(" If this is the case, use \":recover\" or \"vim -r "));
msg_outtrans(buf->b_fname);
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 77e8f0e4f2..3c310ed309 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -2396,7 +2396,7 @@ static void redir_write(char_u *str, int maxlen)
return;
}
- // Append output to capture().
+ // Append output for execute().
if (capture_ga) {
size_t len = 0;
while (str[len] && (maxlen < 0 ? 1 : (len < (size_t)maxlen))) {
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c
index 2f499e477c..5efac2623c 100644
--- a/src/nvim/mouse.c
+++ b/src/nvim/mouse.c
@@ -6,6 +6,7 @@
#include "nvim/window.h"
#include "nvim/strings.h"
#include "nvim/screen.h"
+#include "nvim/syntax.h"
#include "nvim/ui.h"
#include "nvim/os_unix.h"
#include "nvim/fold.h"
@@ -303,6 +304,10 @@ retnomove:
mouse_past_bottom = true;
}
+ if (!(flags & MOUSE_RELEASED) && which_button == MOUSE_LEFT) {
+ col = mouse_adjust_click(curwin, row, col);
+ }
+
// Start Visual mode before coladvance(), for when 'sel' != "old"
if ((flags & MOUSE_MAY_VIS) && !VIsual_active) {
check_visual_highlight();
@@ -597,3 +602,74 @@ bool mouse_scroll_horiz(int dir)
return leftcol_changed();
}
+
+// Adjust the clicked column position if there are concealed characters
+// before the current column. But only when it's absolutely necessary.
+static int mouse_adjust_click(win_T *wp, int row, int col)
+{
+ if (!(wp->w_p_cole > 0 && curbuf->b_p_smc > 0
+ && wp->w_leftcol < curbuf->b_p_smc && conceal_cursor_line(wp))) {
+ return col;
+ }
+
+ int end = (colnr_T)STRLEN(ml_get(wp->w_cursor.lnum));
+ int vend = getviscol2(end, 0);
+
+ if (col >= vend) {
+ return col;
+ }
+
+ int i = wp->w_leftcol;
+
+ if (row > 0) {
+ i += row * (wp->w_width - win_col_off(wp) - win_col_off2(wp)
+ - wp->w_leftcol) + wp->w_skipcol;
+ }
+
+ int start_col = i;
+ int matchid;
+ int last_matchid;
+ int bcol = end - (vend - col);
+
+ while (i < bcol) {
+ matchid = syn_get_concealed_id(wp, wp->w_cursor.lnum, i);
+
+ if (matchid != 0) {
+ if (wp->w_p_cole == 3) {
+ bcol++;
+ } else {
+ if (row > 0 && i == start_col) {
+ // Check if the current concealed character is actually part of
+ // the previous wrapped row's conceal group.
+ last_matchid = syn_get_concealed_id(wp, wp->w_cursor.lnum,
+ i - 1);
+ if (last_matchid == matchid) {
+ bcol++;
+ }
+ } else if (wp->w_p_cole == 1
+ || (wp->w_p_cole == 2
+ && (lcs_conceal != NUL
+ || syn_get_sub_char() != NUL))) {
+ // At least one placeholder character will be displayed.
+ bcol--;
+ }
+
+ last_matchid = matchid;
+
+ // Adjust for concealed text that spans more than one character.
+ do {
+ i++;
+ bcol++;
+ matchid = syn_get_concealed_id(wp, wp->w_cursor.lnum, i);
+ } while (last_matchid == matchid);
+
+ continue;
+ }
+ }
+
+ i++;
+ }
+
+ return getviscol2(bcol, 0);
+}
+
diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c
index 6cee102305..cf5bfd60ae 100644
--- a/src/nvim/os/fileio.c
+++ b/src/nvim/os/fileio.c
@@ -4,7 +4,6 @@
/// Neovim stuctures for buffer, with autocommands, etc: just fopen/fread/fwrite
/// replacement.
-#include <unistd.h>
#include <assert.h>
#include <stddef.h>
#include <stdbool.h>
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index d12d34d595..8c1c80bfad 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -3,7 +3,6 @@
#include <stddef.h>
#include <assert.h>
#include <limits.h>
-#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c
index 436de030ba..b57a69b82b 100644
--- a/src/nvim/os/pty_process_unix.c
+++ b/src/nvim/os/pty_process_unix.c
@@ -3,7 +3,6 @@
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/wait.h>
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index 27855184df..3215f7ea14 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -5661,6 +5661,24 @@ int get_syntax_info(int *seqnrp)
return current_flags;
}
+
+/// Get the sequence number of the concealed file position.
+///
+/// @return seqnr if the file position is concealed, 0 otherwise.
+int syn_get_concealed_id(win_T *wp, linenr_T lnum, colnr_T col)
+{
+ int seqnr;
+ int syntax_flags;
+
+ (void)syn_get_id(wp, lnum, col, false, NULL, false);
+ syntax_flags = get_syntax_info(&seqnr);
+
+ if (syntax_flags & HL_CONCEAL) {
+ return seqnr;
+ }
+ return 0;
+}
+
/*
* Return conceal substitution character
*/
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index fb0079111c..9a0bba83fe 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -14,7 +14,6 @@ SCRIPTS := \
test14.out \
test17.out \
test24.out \
- test30.out \
test32.out \
test37.out \
test40.out \
diff --git a/src/nvim/testdir/test30.in b/src/nvim/testdir/test30.in
deleted file mode 100644
index 56d5d5c6c2..0000000000
--- a/src/nvim/testdir/test30.in
+++ /dev/null
@@ -1,230 +0,0 @@
-Test for a lot of variations of the 'fileformats' option
-
-Note: This test will fail if "cat" is not available.
-
-STARTTEST
-:" first write three test files, one in each format
-:set fileformat=unix
-:set fileformats=
-:/^unix/;/eof/-1w! XXUnix
-:/^dos/;/eof/-1w! XXDos
-:set bin noeol
-:$w! XXMac
-Gonoeol
-:$w! XXEol
-:set nobin eol
-:enew!
-:bwipe XXUnix XXDos XXMac
-:" create mixed format files
-:if has("win32")
-: !copy /b XXUnix+XXDos XXUxDs
-: !copy /b XXUnix+XXMac XXUxMac
-: !copy /b XXDos+XXMac XXDosMac
-: !copy /b XXMac+XXEol XXMacEol
-: !copy /b XXUnix+XXDos+XXMac XXUxDsMc
-:else
-: !cat XXUnix XXDos >XXUxDs
-: !cat XXUnix XXMac >XXUxMac
-: !cat XXDos XXMac >XXDosMac
-: !cat XXMac XXEol >XXMacEol
-: !cat XXUnix XXDos XXMac >XXUxDsMc
-:endif
-:"
-:" try reading and writing with 'fileformats' empty
-:set fileformat=unix
-:e! XXUnix
-:w! test.out
-:e! XXDos
-:w! XXtt01
-:e! XXMac
-:w! XXtt02
-:bwipe XXUnix XXDos XXMac
-:set fileformat=dos
-:e! XXUnix
-:w! XXtt11
-:e! XXDos
-:w! XXtt12
-:e! XXMac
-:w! XXtt13
-:bwipe XXUnix XXDos XXMac
-:set fileformat=mac
-:e! XXUnix
-:w! XXtt21
-:e! XXDos
-:w! XXtt22
-:e! XXMac
-:w! XXtt23
-:bwipe XXUnix XXDos XXMac
-:"
-:" try reading and writing with 'fileformats' set to one format
-:set fileformats=unix
-:e! XXUxDsMc
-:w! XXtt31
-:bwipe XXUxDsMc
-:set fileformats=dos
-:e! XXUxDsMc
-:w! XXtt32
-:bwipe XXUxDsMc
-:set fileformats=mac
-:e! XXUxDsMc
-:w! XXtt33
-:bwipe XXUxDsMc
-:"
-:" try reading and writing with 'fileformats' set to two formats
-:set fileformats=unix,dos
-:e! XXUxDsMc
-:w! XXtt41
-:bwipe XXUxDsMc
-:e! XXUxMac
-:w! XXtt42
-:bwipe XXUxMac
-:e! XXDosMac
-:w! XXtt43
-:bwipe XXDosMac
-:set fileformats=unix,mac
-:e! XXUxDs
-:w! XXtt51
-:bwipe XXUxDs
-:e! XXUxDsMc
-:w! XXtt52
-:bwipe XXUxDsMc
-:e! XXDosMac
-:w! XXtt53
-:bwipe XXDosMac
-:e! XXEol
-ggO=&ffs
-:=&ff
-:w! XXtt54
-:bwipe XXEol
-:set fileformats=dos,mac
-:e! XXUxDs
-:w! XXtt61
-:bwipe XXUxDs
-:e! XXUxMac
-ggO=&ffs
-:=&ff
-:w! XXtt62
-:bwipe XXUxMac
-:e! XXUxDsMc
-:w! XXtt63
-:bwipe XXUxDsMc
-:e! XXMacEol
-ggO=&ffs
-:=&ff
-:w! XXtt64
-:bwipe XXMacEol
-:"
-:" try reading and writing with 'fileformats' set to three formats
-:set fileformats=unix,dos,mac
-:e! XXUxDsMc
-:w! XXtt71
-:bwipe XXUxDsMc
-:e! XXEol
-ggO=&ffs
-:=&ff
-:w! XXtt72
-:bwipe XXEol
-:set fileformats=mac,dos,unix
-:e! XXUxDsMc
-:w! XXtt81
-:bwipe XXUxDsMc
-:e! XXEol
-ggO=&ffs
-:=&ff
-:w! XXtt82
-:bwipe XXEol
-:" try with 'binary' set
-:set fileformats=mac,unix,dos
-:set binary
-:e! XXUxDsMc
-:w! XXtt91
-:bwipe XXUxDsMc
-:set fileformats=mac
-:e! XXUxDsMc
-:w! XXtt92
-:bwipe XXUxDsMc
-:set fileformats=dos
-:e! XXUxDsMc
-:w! XXtt93
-:"
-:" Append "END" to each file so that we can see what the last written char was.
-:set fileformat=unix nobin
-ggdGaEND:w >>XXtt01
-:w >>XXtt02
-:w >>XXtt11
-:w >>XXtt12
-:w >>XXtt13
-:w >>XXtt21
-:w >>XXtt22
-:w >>XXtt23
-:w >>XXtt31
-:w >>XXtt32
-:w >>XXtt33
-:w >>XXtt41
-:w >>XXtt42
-:w >>XXtt43
-:w >>XXtt51
-:w >>XXtt52
-:w >>XXtt53
-:w >>XXtt54
-:w >>XXtt61
-:w >>XXtt62
-:w >>XXtt63
-:w >>XXtt64
-:w >>XXtt71
-:w >>XXtt72
-:w >>XXtt81
-:w >>XXtt82
-:w >>XXtt91
-:w >>XXtt92
-:w >>XXtt93
-:"
-:" Concatenate the results.
-:" Make fileformat of test.out the native fileformat.
-:" Add a newline at the end.
-:set binary
-:e! test.out
-:$r XXtt01
-:$r XXtt02
-Go1:$r XXtt11
-:$r XXtt12
-:$r XXtt13
-Go2:$r XXtt21
-:$r XXtt22
-:$r XXtt23
-Go3:$r XXtt31
-:$r XXtt32
-:$r XXtt33
-Go4:$r XXtt41
-:$r XXtt42
-:$r XXtt43
-Go5:$r XXtt51
-:$r XXtt52
-:$r XXtt53
-:$r XXtt54
-Go6:$r XXtt61
-:$r XXtt62
-:$r XXtt63
-:$r XXtt64
-Go7:$r XXtt71
-:$r XXtt72
-Go8:$r XXtt81
-:$r XXtt82
-Go9:$r XXtt91
-:$r XXtt92
-:$r XXtt93
-Go10:$r XXUnix
-:set nobinary ff&
-:w
-:qa!
-ENDTEST
-
-unix
-unix
-eof
-
-dos
-dos
-eof
-
-mac mac
diff --git a/src/nvim/testdir/test30.ok b/src/nvim/testdir/test30.ok
deleted file mode 100644
index b35f4f5904..0000000000
--- a/src/nvim/testdir/test30.ok
+++ /dev/null
@@ -1,130 +0,0 @@
-unix
-unix
-dos
-dos
-END
-mac mac
-END
-1
-unix
-unix
-END
-dos
-dos
-END
-mac mac
-END
-2
-unix
-unix
- END
-dos
-dos
- END
-mac mac END
-3
-unix
-unix
-dos
-dos
-mac mac
-END
-unix
-unix
-dos
-dos
-mac mac
-END
-unix
-unix
-dos
-dos
-mac mac END
-4
-unix
-unix
-dos
-dos
-mac mac
-END
-unix
-unix
-mac mac
-END
-dos
-dos
-mac mac
-END
-5
-unix
-unix
-dos
-dos
-END
-unix
-unix
-dos
-dos
-mac mac
-END
-dos
-dos
-mac mac END
-unix,mac:unix
-noeol
-END
-6
-unix
-unix
-dos
-dos
-END
-dos,mac:dos
-unix
-unix
-mac mac
-END
-unix
-unix
-dos
-dos
-mac mac
-END
-dos,mac:mac mac mac noeol END
-7
-unix
-unix
-dos
-dos
-mac mac
-END
-unix,dos,mac:unix
-noeol
-END
-8
-unix
-unix
-dos
-dos
-mac mac
-END
-mac,dos,unix:mac noeol END
-9
-unix
-unix
-dos
-dos
-mac mac END
-unix
-unix
-dos
-dos
-mac mac END
-unix
-unix
-dos
-dos
-mac mac END
-10
-unix
-unix
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 4cb3717133..d0af76ac8b 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -1040,7 +1040,7 @@ static int included_patches[] = {
// 1240 NA
// 1239 NA
// 1238 NA
- // 1237,
+ 1237,
1236,
// 1235 NA
// 1234 NA
diff --git a/test/functional/eval/capture_spec.lua b/test/functional/eval/execute_spec.lua
index d9265f1b5b..a91a04341f 100644
--- a/test/functional/eval/capture_spec.lua
+++ b/test/functional/eval/execute_spec.lua
@@ -9,16 +9,16 @@ local funcs = helpers.funcs
local Screen = require('test.functional.ui.screen')
local feed = helpers.feed
-describe('capture()', function()
+describe('execute()', function()
before_each(clear)
it('returns the same result with :redir', function()
- eq(redir_exec('messages'), funcs.capture('messages'))
+ eq(redir_exec('messages'), funcs.execute('messages'))
end)
it('returns the output of the commands if the argument is List', function()
- eq("foobar", funcs.capture({'echon "foo"', 'echon "bar"'}))
- eq("\nfoo\nbar", funcs.capture({'echo "foo"', 'echo "bar"'}))
+ eq("foobar", funcs.execute({'echon "foo"', 'echon "bar"'}))
+ eq("\nfoo\nbar", funcs.execute({'echo "foo"', 'echo "bar"'}))
end)
it('supports the nested redirection', function()
@@ -38,34 +38,34 @@ describe('capture()', function()
return a
endfunction
]])
- eq('foo', funcs.capture('call g:Bar()'))
+ eq('foo', funcs.execute('call g:Bar()'))
- eq('42', funcs.capture([[echon capture("echon capture('echon 42')")]]))
+ eq('42', funcs.execute([[echon execute("echon execute('echon 42')")]]))
end)
it('returns the transformed string', function()
- eq('^A', funcs.capture('echon "\\<C-a>"'))
+ eq('^A', funcs.execute('echon "\\<C-a>"'))
end)
it('returns the empty string if the argument list is empty', function()
- eq('', funcs.capture({}))
- eq(0, exc_exec('let g:ret = capture(v:_null_list)'))
+ eq('', funcs.execute({}))
+ eq(0, exc_exec('let g:ret = execute(v:_null_list)'))
eq('', eval('g:ret'))
end)
it('returns the errors', function()
local ret
- ret = exc_exec('call capture(0.0)')
+ ret = exc_exec('call execute(0.0)')
eq('Vim(call):E806: using Float as a String', ret)
- ret = exc_exec('call capture(v:_null_dict)')
+ ret = exc_exec('call execute(v:_null_dict)')
eq('Vim(call):E731: using Dictionary as a String', ret)
- ret = exc_exec('call capture(function("tr"))')
+ ret = exc_exec('call execute(function("tr"))')
eq('Vim(call):E729: using Funcref as a String', ret)
- ret = exc_exec('call capture(["echo 42", 0.0, "echo 44"])')
+ ret = exc_exec('call execute(["echo 42", 0.0, "echo 44"])')
eq('Vim(call):E806: using Float as a String', ret)
- ret = exc_exec('call capture(["echo 42", v:_null_dict, "echo 44"])')
+ ret = exc_exec('call execute(["echo 42", v:_null_dict, "echo 44"])')
eq('Vim(call):E731: using Dictionary as a String', ret)
- ret = exc_exec('call capture(["echo 42", function("tr"), "echo 44"])')
+ ret = exc_exec('call execute(["echo 42", function("tr"), "echo 44"])')
eq('Vim(call):E729: using Funcref as a String', ret)
end)
@@ -73,7 +73,7 @@ describe('capture()', function()
local screen = Screen.new(20, 5)
screen:attach()
screen:set_default_attr_ignore({{bold=true, foreground=255}})
- feed(':let g:mes = capture("echon 42")<CR>')
+ feed(':let g:mes = execute("echon 42")<CR>')
screen:expect([[
^ |
~ |
diff --git a/test/functional/legacy/030_fileformats_spec.lua b/test/functional/legacy/030_fileformats_spec.lua
new file mode 100644
index 0000000000..9bc62a375e
--- /dev/null
+++ b/test/functional/legacy/030_fileformats_spec.lua
@@ -0,0 +1,375 @@
+-- Test for a lot of variations of the 'fileformats' option
+
+local helpers = require('test.functional.helpers')(after_each)
+local feed, clear, execute = helpers.feed, helpers.clear, helpers.execute
+local eq, write_file = helpers.eq, helpers.write_file
+
+describe('fileformats option', function()
+ setup(function()
+ clear()
+ local dos = 'dos\r\ndos\r\n'
+ local mac = 'mac\rmac\r'
+ local unix = 'unix\nunix\n'
+ local eol = 'noeol'
+ write_file('XXDos', dos)
+ write_file('XXMac', mac)
+ write_file('XXUnix', unix)
+ write_file('XXEol', eol)
+ write_file('XXDosMac', dos..mac)
+ write_file('XXMacEol', mac..eol)
+ write_file('XXUxDs', unix..dos)
+ write_file('XXUxDsMc', unix..dos..mac)
+ write_file('XXUxMac', unix..mac)
+ end)
+
+ teardown(function()
+ os.remove('test.out')
+ os.remove('XXDos')
+ os.remove('XXMac')
+ os.remove('XXUnix')
+ os.remove('XXEol')
+ os.remove('XXDosMac')
+ os.remove('XXMacEol')
+ os.remove('XXUxDs')
+ os.remove('XXUxDsMc')
+ os.remove('XXUxMac')
+ for i = 0, 9 do
+ for j = 1, 4 do
+ os.remove('XXtt'..i..j)
+ end
+ end
+ end)
+
+ it('is working', function()
+
+ -- Try reading and writing with 'fileformats' empty.
+ execute('set fileformats=')
+ execute('set fileformat=unix')
+ execute('e! XXUnix')
+ execute('w! test.out')
+ execute('e! XXDos')
+ execute('w! XXtt01')
+ execute('e! XXMac')
+ execute('w! XXtt02')
+ execute('bwipe XXUnix XXDos XXMac')
+ execute('set fileformat=dos')
+ execute('e! XXUnix')
+ execute('w! XXtt11')
+ execute('e! XXDos')
+ execute('w! XXtt12')
+ execute('e! XXMac')
+ execute('w! XXtt13')
+ execute('bwipe XXUnix XXDos XXMac')
+ execute('set fileformat=mac')
+ execute('e! XXUnix')
+ execute('w! XXtt21')
+ execute('e! XXDos')
+ execute('w! XXtt22')
+ execute('e! XXMac')
+ execute('w! XXtt23')
+ execute('bwipe XXUnix XXDos XXMac')
+
+ -- Try reading and writing with 'fileformats' set to one format.
+ execute('set fileformats=unix')
+ execute('e! XXUxDsMc')
+ execute('w! XXtt31')
+ execute('bwipe XXUxDsMc')
+ execute('set fileformats=dos')
+ execute('e! XXUxDsMc')
+ execute('w! XXtt32')
+ execute('bwipe XXUxDsMc')
+ execute('set fileformats=mac')
+ execute('e! XXUxDsMc')
+ execute('w! XXtt33')
+ execute('bwipe XXUxDsMc')
+
+ -- Try reading and writing with 'fileformats' set to two formats.
+ execute('set fileformats=unix,dos')
+ execute('e! XXUxDsMc')
+ execute('w! XXtt41')
+ execute('bwipe XXUxDsMc')
+ execute('e! XXUxMac')
+ execute('w! XXtt42')
+ execute('bwipe XXUxMac')
+ execute('e! XXDosMac')
+ execute('w! XXtt43')
+ execute('bwipe XXDosMac')
+ execute('set fileformats=unix,mac')
+ execute('e! XXUxDs')
+ execute('w! XXtt51')
+ execute('bwipe XXUxDs')
+ execute('e! XXUxDsMc')
+ execute('w! XXtt52')
+ execute('bwipe XXUxDsMc')
+ execute('e! XXDosMac')
+ execute('w! XXtt53')
+ execute('bwipe XXDosMac')
+ execute('e! XXEol')
+ feed('ggO<C-R>=&ffs<CR>:<C-R>=&ff<CR><ESC>')
+ execute('w! XXtt54')
+ execute('bwipe XXEol')
+ execute('set fileformats=dos,mac')
+ execute('e! XXUxDs')
+ execute('w! XXtt61')
+ execute('bwipe XXUxDs')
+ execute('e! XXUxMac')
+ feed('ggO<C-R>=&ffs<CR>:<C-R>=&ff<CR><ESC>')
+ execute('w! XXtt62')
+ execute('bwipe XXUxMac')
+ execute('e! XXUxDsMc')
+ execute('w! XXtt63')
+ execute('bwipe XXUxDsMc')
+ execute('e! XXMacEol')
+ feed('ggO<C-R>=&ffs<CR>:<C-R>=&ff<CR><ESC>')
+ execute('w! XXtt64')
+ execute('bwipe XXMacEol')
+
+ -- Try reading and writing with 'fileformats' set to three formats.
+ execute('set fileformats=unix,dos,mac')
+ execute('e! XXUxDsMc')
+ execute('w! XXtt71')
+ execute('bwipe XXUxDsMc')
+ execute('e! XXEol')
+ feed('ggO<C-R>=&ffs<CR>:<C-R>=&ff<CR><ESC>')
+ execute('w! XXtt72')
+ execute('bwipe XXEol')
+ execute('set fileformats=mac,dos,unix')
+ execute('e! XXUxDsMc')
+ execute('w! XXtt81')
+ execute('bwipe XXUxDsMc')
+ execute('e! XXEol')
+ feed('ggO<C-R>=&ffs<CR>:<C-R>=&ff<CR><ESC>')
+ execute('w! XXtt82')
+ execute('bwipe XXEol')
+ -- Try with 'binary' set.
+ execute('set fileformats=mac,unix,dos')
+ execute('set binary')
+ execute('e! XXUxDsMc')
+ execute('w! XXtt91')
+ execute('bwipe XXUxDsMc')
+ execute('set fileformats=mac')
+ execute('e! XXUxDsMc')
+ execute('w! XXtt92')
+ execute('bwipe XXUxDsMc')
+ execute('set fileformats=dos')
+ execute('e! XXUxDsMc')
+ execute('w! XXtt93')
+
+ -- Append "END" to each file so that we can see what the last written
+ -- char was.
+ execute('set fileformat=unix nobin')
+ feed('ggdGaEND<esc>')
+ execute('w >>XXtt01')
+ execute('w >>XXtt02')
+ execute('w >>XXtt11')
+ execute('w >>XXtt12')
+ execute('w >>XXtt13')
+ execute('w >>XXtt21')
+ execute('w >>XXtt22')
+ execute('w >>XXtt23')
+ execute('w >>XXtt31')
+ execute('w >>XXtt32')
+ execute('w >>XXtt33')
+ execute('w >>XXtt41')
+ execute('w >>XXtt42')
+ execute('w >>XXtt43')
+ execute('w >>XXtt51')
+ execute('w >>XXtt52')
+ execute('w >>XXtt53')
+ execute('w >>XXtt54')
+ execute('w >>XXtt61')
+ execute('w >>XXtt62')
+ execute('w >>XXtt63')
+ execute('w >>XXtt64')
+ execute('w >>XXtt71')
+ execute('w >>XXtt72')
+ execute('w >>XXtt81')
+ execute('w >>XXtt82')
+ execute('w >>XXtt91')
+ execute('w >>XXtt92')
+ execute('w >>XXtt93')
+
+ -- Concatenate the results.
+ -- Make fileformat of test.out the native fileformat.
+ -- Add a newline at the end.
+ execute('set binary')
+ execute('e! test.out')
+ execute('$r XXtt01')
+ execute('$r XXtt02')
+ feed('Go1<esc>')
+ execute('$r XXtt11')
+ execute('$r XXtt12')
+ execute('$r XXtt13')
+ feed('Go2<esc>')
+ execute('$r XXtt21')
+ execute('$r XXtt22')
+ execute('$r XXtt23')
+ feed('Go3<esc>')
+ execute('$r XXtt31')
+ execute('$r XXtt32')
+ execute('$r XXtt33')
+ feed('Go4<esc>')
+ execute('$r XXtt41')
+ execute('$r XXtt42')
+ execute('$r XXtt43')
+ feed('Go5<esc>')
+ execute('$r XXtt51')
+ execute('$r XXtt52')
+ execute('$r XXtt53')
+ execute('$r XXtt54')
+ feed('Go6<esc>')
+ execute('$r XXtt61')
+ execute('$r XXtt62')
+ execute('$r XXtt63')
+ execute('$r XXtt64')
+ feed('Go7<esc>')
+ execute('$r XXtt71')
+ execute('$r XXtt72')
+ feed('Go8<esc>')
+ execute('$r XXtt81')
+ execute('$r XXtt82')
+ feed('Go9<esc>')
+ execute('$r XXtt91')
+ execute('$r XXtt92')
+ execute('$r XXtt93')
+ feed('Go10<esc>')
+ execute('$r XXUnix')
+ execute('set nobinary ff&')
+
+ -- Assert buffer contents. This has to be done manually as
+ -- helpers.expect() calls helpers.dedent() which messes up the white space
+ -- and carrige returns.
+ eq(
+ 'unix\n'..
+ 'unix\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'END\n'..
+ 'mac\rmac\r\n'..
+ 'END\n'..
+ '1\n'..
+ 'unix\r\n'..
+ 'unix\r\n'..
+ 'END\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'END\n'..
+ 'mac\rmac\r\r\n'..
+ 'END\n'..
+ '2\n'..
+ 'unix\n'..
+ 'unix\n'..
+ '\rEND\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ '\rEND\n'..
+ 'mac\rmac\rEND\n'..
+ '3\n'..
+ 'unix\n'..
+ 'unix\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'mac\rmac\r\n'..
+ 'END\n'..
+ 'unix\r\n'..
+ 'unix\r\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'mac\rmac\r\r\n'..
+ 'END\n'..
+ 'unix\n'..
+ 'unix\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'mac\rmac\rEND\n'..
+ '4\n'..
+ 'unix\n'..
+ 'unix\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'mac\rmac\r\n'..
+ 'END\n'..
+ 'unix\n'..
+ 'unix\n'..
+ 'mac\rmac\r\n'..
+ 'END\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'mac\rmac\r\r\n'..
+ 'END\n'..
+ '5\n'..
+ 'unix\n'..
+ 'unix\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'END\n'..
+ 'unix\n'..
+ 'unix\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'mac\rmac\r\n'..
+ 'END\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'mac\rmac\rEND\n'..
+ 'unix,mac:unix\n'..
+ 'noeol\n'..
+ 'END\n'..
+ '6\n'..
+ 'unix\r\n'..
+ 'unix\r\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'END\n'..
+ 'dos,mac:dos\r\n'..
+ 'unix\r\n'..
+ 'unix\r\n'..
+ 'mac\rmac\r\r\n'..
+ 'END\n'..
+ 'unix\r\n'..
+ 'unix\r\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'mac\rmac\r\r\n'..
+ 'END\n'..
+ 'dos,mac:mac\rmac\rmac\rnoeol\rEND\n'..
+ '7\n'..
+ 'unix\n'..
+ 'unix\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'mac\rmac\r\n'..
+ 'END\n'..
+ 'unix,dos,mac:unix\n'..
+ 'noeol\n'..
+ 'END\n'..
+ '8\n'..
+ 'unix\n'..
+ 'unix\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'mac\rmac\r\n'..
+ 'END\n'..
+ 'mac,dos,unix:mac\rnoeol\rEND\n'..
+ '9\n'..
+ 'unix\n'..
+ 'unix\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'mac\rmac\rEND\n'..
+ 'unix\n'..
+ 'unix\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'mac\rmac\rEND\n'..
+ 'unix\n'..
+ 'unix\n'..
+ 'dos\r\n'..
+ 'dos\r\n'..
+ 'mac\rmac\rEND\n'..
+ '10\n'..
+ 'unix\n'..
+ 'unix',
+ helpers.curbuf_contents())
+ end)
+end)
diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua
index a433143266..7b820347ac 100644
--- a/test/functional/ui/mouse_spec.lua
+++ b/test/functional/ui/mouse_spec.lua
@@ -462,4 +462,321 @@ describe('Mouse input', function()
|
]])
end)
+
+ describe('on concealed text', function()
+ -- Helpful for reading the test expectations:
+ -- :match Error /\^/
+ local concealed = {
+ c = { foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGray }
+ }
+
+ before_each(function()
+ screen:try_resize(25, 7)
+ feed('ggdG')
+
+ execute('set concealcursor=n')
+ execute('set nowrap')
+ execute('syntax match NonText "\\<amet\\>" conceal')
+ execute('syntax match NonText "\\cs\\|g." conceal cchar=X')
+ execute('syntax match NonText "\\%(lo\\|cl\\)." conceal')
+ execute('syntax match NonText "Lo" conceal cchar=Y')
+
+ insert([[
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
+ Stet clita kasd gubergren, no sea takimata sanctus est.
+ ]])
+
+ feed('gg')
+ end)
+
+ it('(level 1) click on non-wrapped lines', function()
+ execute('let &conceallevel=1', 'echo')
+
+ feed('<esc><LeftMouse><0,0>')
+ screen:expect([[
+ {c:^Y}rem ip{c:X}um do{c: } {c:X}it {c: }, con|
+ {c:X}tet {c: }ta ka{c:X}d {c:X}ber{c:X}en, no|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><1,0>')
+ screen:expect([[
+ {c:Y}^rem ip{c:X}um do{c: } {c:X}it {c: }, con|
+ {c:X}tet {c: }ta ka{c:X}d {c:X}ber{c:X}en, no|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,0>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do{c: } {c:^X}it {c: }, con|
+ {c:X}tet {c: }ta ka{c:X}d {c:X}ber{c:X}en, no|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,1>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do{c: } {c:X}it {c: }, con|
+ {c:X}tet {c: }ta ka{c:X}d {c:X}^ber{c:X}en, no|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+ end) -- level 1 - non wrapped
+
+ it('(level 1) click on wrapped lines', function()
+ execute('let &conceallevel=1', 'let &wrap=1', 'echo')
+
+ feed('<esc><LeftMouse><0,0>')
+ screen:expect([[
+ {c:^Y}rem ip{c:X}um do{c: } {c:X}it {c: } |
+ , con{c:X}etetur {c:X}adip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet {c: }ta ka{c:X}d {c:X}ber{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><6,1>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do{c: } {c:X}it {c: } |
+ , con{c:X}^etetur {c:X}adip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet {c: }ta ka{c:X}d {c:X}ber{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,1>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do{c: } {c:X}it {c: } |
+ , con{c:X}etetur {c:X}a^dip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet {c: }ta ka{c:X}d {c:X}ber{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,3>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do{c: } {c:X}it {c: } |
+ , con{c:X}etetur {c:X}adip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet {c: }ta ka{c:X}d {c:X}^ber{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+ end) -- level 1 - wrapped
+
+
+ it('(level 2) click on non-wrapped lines', function()
+ execute('let &conceallevel=2', 'echo')
+
+ feed('<esc><LeftMouse><0,0>')
+ screen:expect([[
+ {c:^Y}rem ip{c:X}um do {c:X}it , con{c:X}e|
+ {c:X}tet ta ka{c:X}d {c:X}ber{c:X}en, no |
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><1,0>')
+ screen:expect([[
+ {c:Y}^rem ip{c:X}um do {c:X}it , con{c:X}e|
+ {c:X}tet ta ka{c:X}d {c:X}ber{c:X}en, no |
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,0>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do {c:X}^it , con{c:X}e|
+ {c:X}tet ta ka{c:X}d {c:X}ber{c:X}en, no |
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,1>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do {c:X}it , con{c:X}e|
+ {c:X}tet ta ka{c:X}d {c:X}b^er{c:X}en, no |
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+ end) -- level 2 - non wrapped
+
+ it('(level 2) click on wrapped lines', function()
+ execute('let &conceallevel=2', 'let &wrap=1', 'echo')
+
+ feed('<esc><LeftMouse><0,0>')
+ screen:expect([[
+ {c:^Y}rem ip{c:X}um do {c:X}it |
+ , con{c:X}etetur {c:X}adip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet ta ka{c:X}d {c:X}ber{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><6,1>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do {c:X}it |
+ , con{c:X}^etetur {c:X}adip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet ta ka{c:X}d {c:X}ber{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,1>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do {c:X}it |
+ , con{c:X}etetur {c:X}a^dip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet ta ka{c:X}d {c:X}ber{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,3>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do {c:X}it |
+ , con{c:X}etetur {c:X}adip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet ta ka{c:X}d {c:X}b^er{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+ end) -- level 2 - wrapped
+
+
+ it('(level 3) click on non-wrapped lines', function()
+ execute('let &conceallevel=3', 'echo')
+
+ feed('<esc><LeftMouse><0,0>')
+ screen:expect([[
+ ^rem ipum do it , conetetu|
+ tet ta kad beren, no ea t|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><1,0>')
+ screen:expect([[
+ r^em ipum do it , conetetu|
+ tet ta kad beren, no ea t|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,0>')
+ screen:expect([[
+ rem ipum do it ^, conetetu|
+ tet ta kad beren, no ea t|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,1>')
+ screen:expect([[
+ rem ipum do it , conetetu|
+ tet ta kad bere^n, no ea t|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+ end) -- level 3 - non wrapped
+
+ it('(level 3) click on wrapped lines', function()
+ execute('let &conceallevel=3', 'let &wrap=1', 'echo')
+
+ feed('<esc><LeftMouse><0,0>')
+ screen:expect([[
+ ^rem ipum do it |
+ , conetetur adipcin |
+ elitr. |
+ tet ta kad beren |
+ , no ea takimata anctu |
+ et. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><6,1>')
+ screen:expect([[
+ rem ipum do it |
+ , cone^tetur adipcin |
+ elitr. |
+ tet ta kad beren |
+ , no ea takimata anctu |
+ et. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,1>')
+ screen:expect([[
+ rem ipum do it |
+ , conetetur adi^pcin |
+ elitr. |
+ tet ta kad beren |
+ , no ea takimata anctu |
+ et. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,3>')
+ screen:expect([[
+ rem ipum do it |
+ , conetetur adipcin |
+ elitr. |
+ tet ta kad bere^n |
+ , no ea takimata anctu |
+ et. |
+ |
+ ]], concealed)
+ end) -- level 3 - wrapped
+ end)
end)