aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml5
-rw-r--r--.github/workflows/release.yml7
-rw-r--r--ci/build.ps13
-rw-r--r--runtime/doc/api.txt28
-rwxr-xr-xscripts/gen_vimdoc.py2
-rwxr-xr-xsrc/nvim/CMakeLists.txt1
-rw-r--r--src/nvim/ex_cmds.c33
-rw-r--r--src/nvim/lua/executor.c6
-rw-r--r--src/nvim/memline.c208
-rw-r--r--src/nvim/normal.c7
-rw-r--r--src/nvim/testdir/test_excmd.vim120
-rw-r--r--test/functional/legacy/excmd_spec.lua620
-rw-r--r--test/functional/lua/vim_spec.lua35
-rw-r--r--test/functional/ui/statusline_spec.lua30
-rw-r--r--test/functional/vimscript/system_spec.lua23
15 files changed, 780 insertions, 348 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1393b987d9..d670db5fac 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -161,10 +161,7 @@ jobs:
runner: ubuntu-20.04
os: linux
- cc: clang
- runner: macos-10.15
- os: osx
- - cc: clang
- runner: macos-11.0
+ runner: macos-11
os: osx
# functionaltest-lua is our dumping ground for non-mainline configurations.
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 11cc1ab03d..2d57c09ab8 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -127,7 +127,7 @@ jobs:
env:
DEPS_BUILD_DIR: ${{ format('{0}/nvim-deps', github.workspace) }}
DEPS_PREFIX: ${{ format('{0}/nvim-deps/usr', github.workspace) }}
- CONFIGURATION: ${{ matrix.config }}
+ CMAKE_BUILD_TYPE: "RelWithDebInfo"
strategy:
matrix:
include:
@@ -138,7 +138,10 @@ jobs:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- - run: powershell ci\build.ps1 -Package
+ - name: Build deps
+ run: .\ci\build.ps1 -BuildDeps
+ - name: build package
+ run: .\ci\build.ps1 -Package
- uses: actions/upload-artifact@v3
with:
name: ${{ matrix.archive }}
diff --git a/ci/build.ps1 b/ci/build.ps1
index f5ebe10b87..6c042f9116 100644
--- a/ci/build.ps1
+++ b/ci/build.ps1
@@ -134,7 +134,8 @@ function TestOld {
function Package {
- cmake --build $buildDir --target package
+ cmake -S $projectDir -B $buildDir $(convertToCmakeArgs($nvimCmakeVars)) -G Ninja; exitIfFailed
+ cmake --build $buildDir --target package; exitIfFailed
}
if ($PSCmdlet.ParameterSetName) {
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index c67187d857..9758959f4e 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -536,12 +536,6 @@ created for extmark changes.
==============================================================================
Global Functions *api-global*
-nvim__get_hl_defs({ns_id}) *nvim__get_hl_defs()*
- TODO: Documentation
-
-nvim__get_lib_dir() *nvim__get_lib_dir()*
- TODO: Documentation
-
nvim__get_runtime({pat}, {all}, {*opts}) *nvim__get_runtime()*
Find files in runtime directories
@@ -608,15 +602,6 @@ nvim__inspect_cell({grid}, {row}, {col}) *nvim__inspect_cell()*
NB: if your UI doesn't use hlstate, this will not return
hlstate first time.
-nvim__runtime_inspect() *nvim__runtime_inspect()*
- TODO: Documentation
-
-nvim__screenshot({path}) *nvim__screenshot()*
- TODO: Documentation
-
- Attributes: ~
- |api-fast|
-
nvim__set_hl_ns({ns_id}) *nvim__set_hl_ns()*
Set active namespace for highlights.
@@ -638,12 +623,6 @@ nvim__stats() *nvim__stats()*
Return: ~
Map of various internal stats.
-nvim__unpack({str}) *nvim__unpack()*
- TODO: Documentation
-
- Attributes: ~
- |api-fast|
-
nvim_call_atomic({calls}) *nvim_call_atomic()*
Calls many API methods atomically.
@@ -2124,13 +2103,6 @@ affected.
You can use |nvim_buf_is_loaded()| or |nvim_buf_line_count()|
to check whether a buffer is loaded.
- *nvim__buf_redraw_range()*
-nvim__buf_redraw_range({buffer}, {first}, {last})
- TODO: Documentation
-
-nvim__buf_stats({buffer}) *nvim__buf_stats()*
- TODO: Documentation
-
nvim_buf_attach({buffer}, {send_buffer}, {opts}) *nvim_buf_attach()*
Activates buffer-update events on a channel, or as Lua
callbacks.
diff --git a/scripts/gen_vimdoc.py b/scripts/gen_vimdoc.py
index 9ab80991b7..c17742ddaf 100755
--- a/scripts/gen_vimdoc.py
+++ b/scripts/gen_vimdoc.py
@@ -897,6 +897,8 @@ def fmt_doxygen_xml_as_vimhelp(filename, target):
doc = fmt_node_as_vimhelp(fn['desc_node'], fmt_vimhelp=True)
if not doc and fn['brief_desc_node']:
doc = fmt_node_as_vimhelp(fn['brief_desc_node'])
+ if not doc and name.startswith("nvim__"):
+ continue
if not doc:
doc = 'TODO: Documentation'
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 360993de68..384e672529 100755
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -160,7 +160,6 @@ list(REMOVE_ITEM NVIM_SOURCES ${to_remove})
set(CONV_SOURCES
lua/treesitter.c
mbyte.c
- memline.c
regexp.c
screen.c
search.c
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 28e1893b31..550fe1eb25 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -1583,22 +1583,39 @@ char *make_filter_cmd(char *cmd, char *itmp, char *otmp)
if (otmp != NULL) {
len += STRLEN(otmp) + STRLEN(p_srr) + 2; // two extra spaces (" "),
}
+
+ const char *const cmd_args = strchr(cmd, ' ');
+ len += (is_pwsh && cmd_args)
+ ? STRLEN(" -ArgumentList ") + 2 // two extra quotes
+ : 0;
+
char *const buf = xmalloc(len);
-#if defined(UNIX)
- // Put delimiters around the command (for concatenated commands) when
- // redirecting input and/or output.
if (is_pwsh) {
xstrlcpy(buf, "Start-Process ", len);
- xstrlcat(buf, cmd, len);
+ if (cmd_args == NULL) {
+ xstrlcat(buf, cmd, len);
+ } else {
+ xstrlcpy(buf + STRLEN(buf), cmd, (size_t)(cmd_args - cmd + 1));
+ xstrlcat(buf, " -ArgumentList \"", len);
+ xstrlcat(buf, cmd_args + 1, len); // +1 to skip the leading space.
+ xstrlcat(buf, "\"", len);
+ }
+#if defined(UNIX)
+ // Put delimiters around the command (for concatenated commands) when
+ // redirecting input and/or output.
} else if (itmp != NULL || otmp != NULL) {
char *fmt = is_fish_shell ? "begin; %s; end"
: "(%s)";
vim_snprintf(buf, len, fmt, cmd);
+#endif
+ // For shells that don't understand braces around commands, at least allow
+ // the use of commands in a pipe.
} else {
xstrlcpy(buf, cmd, len);
}
+#if defined(UNIX)
if (itmp != NULL) {
if (is_pwsh) {
xstrlcat(buf, " -RedirectStandardInput ", len - 1);
@@ -1608,14 +1625,6 @@ char *make_filter_cmd(char *cmd, char *itmp, char *otmp)
xstrlcat(buf, itmp, len - 1);
}
#else
- // For shells that don't understand braces around commands, at least allow
- // the use of commands in a pipe.
- if (is_pwsh) {
- xstrlcpy(buf, "Start-Process ", len);
- xstrlcat(buf, cmd, len);
- } else {
- xstrlcpy(buf, cmd, len);
- }
if (itmp != NULL) {
// If there is a pipe, we have to put the '<' in front of it.
// Don't do this when 'shellquote' is not empty, otherwise the
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index ad03ebd1ed..fcbf36c711 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -416,9 +416,9 @@ static int nlua_wait(lua_State *lstate)
LOOP_PROCESS_EVENTS_UNTIL(&main_loop,
loop_events,
(int)timeout,
- is_function ? nlua_wait_condition(lstate,
- &pcall_status,
- &callback_result) : false || got_int);
+ got_int || (is_function ? nlua_wait_condition(lstate,
+ &pcall_status,
+ &callback_result) : false));
// Stop dummy timer
time_watcher_stop(tw);
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 5f74440747..1ea5e2ccdc 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -309,7 +309,7 @@ int ml_open(buf_T *buf)
if (!buf->b_spell) {
b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
- b0p->b0_flags = get_fileformat(buf) + 1;
+ b0p->b0_flags = (uint8_t)(get_fileformat(buf) + 1);
set_b0_fname(b0p, buf);
(void)os_get_username((char *)b0p->b0_uname, B0_UNAME_SIZE);
b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL;
@@ -359,7 +359,7 @@ int ml_open(buf_T *buf)
dp = hp->bh_data;
dp->db_index[0] = --dp->db_txt_start; // at end of block
- dp->db_free -= 1 + INDEX_SIZE;
+ dp->db_free -= 1 + (unsigned)INDEX_SIZE;
dp->db_line_count = 1;
*((char_u *)dp + dp->db_txt_start) = NUL; // empty line
@@ -711,7 +711,7 @@ static void set_b0_dir_flag(ZERO_BL *b0p, buf_T *buf)
if (same_directory(buf->b_ml.ml_mfp->mf_fname, (char_u *)buf->b_ffname)) {
b0p->b0_flags |= B0_SAME_DIR;
} else {
- b0p->b0_flags &= ~B0_SAME_DIR;
+ b0p->b0_flags &= (uint8_t) ~B0_SAME_DIR;
}
}
@@ -723,7 +723,7 @@ static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf)
n = (int)STRLEN(buf->b_p_fenc);
if ((int)STRLEN(b0p->b0_fname) + n + 1 > size) {
- b0p->b0_flags &= ~B0_HAS_FENC;
+ b0p->b0_flags &= (uint8_t) ~B0_HAS_FENC;
} else {
memmove((char *)b0p->b0_fname + size - n,
(char *)buf->b_p_fenc, (size_t)n);
@@ -750,7 +750,6 @@ void ml_recover(bool checkext)
DATA_BL *dp;
infoptr_T *ip;
blocknr_T bnum;
- int page_count;
int len;
bool directly;
linenr_T lnum;
@@ -971,7 +970,7 @@ void ml_recover(bool checkext)
int fnsize = B0_FNAME_SIZE_NOCRYPT;
for (p = b0p->b0_fname + fnsize; p > b0p->b0_fname && p[-1] != NUL; p--) {}
- b0_fenc = vim_strnsave(p, b0p->b0_fname + fnsize - p);
+ b0_fenc = vim_strnsave(p, (size_t)(b0p->b0_fname + fnsize - p));
}
mf_put(mfp, hp, false, false); // release block 0
@@ -1004,11 +1003,11 @@ void ml_recover(bool checkext)
}
unchanged(curbuf, true, true);
- bnum = 1; // start with block 1
- page_count = 1; // which is 1 page
- lnum = 0; // append after line 0 in curbuf
+ bnum = 1; // start with block 1
+ unsigned page_count = 1; // which is 1 page
+ lnum = 0; // append after line 0 in curbuf
line_count = 0;
- idx = 0; // start with first index in block 1
+ idx = 0; // start with first index in block 1
error = 0;
buf->b_ml.ml_stack_top = 0; // -V1048
buf->b_ml.ml_stack = NULL;
@@ -1091,7 +1090,7 @@ void ml_recover(bool checkext)
bnum = pp->pb_pointer[idx].pe_bnum;
line_count = pp->pb_pointer[idx].pe_line_count;
- page_count = pp->pb_pointer[idx].pe_page_count;
+ page_count = (unsigned)pp->pb_pointer[idx].pe_page_count;
idx = 0;
continue;
}
@@ -1518,7 +1517,7 @@ static time_t swapfile_info(char_u *fname)
if (os_fileinfo((char *)fname, &file_info)) {
#ifdef UNIX
// print name of owner of the file
- if (os_get_uname(file_info.stat.st_uid, uname, B0_UNAME_SIZE) == OK) {
+ if (os_get_uname((uv_uid_t)file_info.stat.st_uid, uname, B0_UNAME_SIZE) == OK) {
msg_puts(_(" owned by: "));
msg_outtrans(uname);
msg_puts(_(" dated: "));
@@ -1970,12 +1969,9 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
int line_count; // number of indexes in current block
int offset;
int from, to;
- int space_needed; // space needed for new line
- int page_size;
int page_count;
int db_idx; // index for lnum in data block
bhdr_T *hp;
- memfile_T *mfp;
DATA_BL *dp;
PTR_BL *pp;
infoptr_T *ip;
@@ -1992,10 +1988,10 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
if (len == 0) {
len = (colnr_T)STRLEN(line) + 1; // space needed for the text
}
- space_needed = len + INDEX_SIZE; // space needed for text + index
+ int space_needed = len + (int)INDEX_SIZE; // space needed for text + index
- mfp = buf->b_ml.ml_mfp;
- page_size = mfp->mf_page_size;
+ memfile_T *mfp = buf->b_ml.ml_mfp;
+ int page_size = (int)mfp->mf_page_size;
/*
* find the data block containing the previous line
@@ -2053,9 +2049,9 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
/*
* Insert new line in existing data block, or in data block allocated above.
*/
- dp->db_txt_start -= len;
- dp->db_free -= space_needed;
- ++(dp->db_line_count);
+ dp->db_txt_start -= (unsigned)len;
+ dp->db_free -= (unsigned)space_needed;
+ dp->db_line_count++;
/*
* move the text of the lines that follow to the front
@@ -2067,17 +2063,17 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
* This will become the character just after the new line.
*/
if (db_idx < 0) {
- offset = dp->db_txt_end;
+ offset = (int)dp->db_txt_end;
} else {
offset = ((dp->db_index[db_idx]) & DB_INDEX_MASK);
}
memmove((char *)dp + dp->db_txt_start,
(char *)dp + dp->db_txt_start + len,
- (size_t)(offset - (dp->db_txt_start + len)));
- for (i = line_count - 1; i > db_idx; --i) {
- dp->db_index[i + 1] = dp->db_index[i] - len;
+ (size_t)offset - (dp->db_txt_start + (size_t)len));
+ for (i = line_count - 1; i > db_idx; i--) {
+ dp->db_index[i + 1] = dp->db_index[i] - (unsigned)len;
}
- dp->db_index[db_idx + 1] = offset - len;
+ dp->db_index[db_idx + 1] = (unsigned)(offset - len);
} else { // add line at the end
dp->db_index[db_idx + 1] = dp->db_txt_start;
}
@@ -2107,7 +2103,7 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
* The line counts in the pointer blocks have already been adjusted by
* ml_find_line().
*/
- long line_count_left, line_count_right;
+ int line_count_left, line_count_right;
int page_count_left, page_count_right;
bhdr_T *hp_left;
bhdr_T *hp_right;
@@ -2142,9 +2138,9 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
in_left = false; // put new line in right block
// space_needed does not change
} else {
- data_moved = ((dp->db_index[db_idx]) & DB_INDEX_MASK) -
- dp->db_txt_start;
- total_moved = data_moved + lines_moved * INDEX_SIZE;
+ data_moved = (int)(((dp->db_index[db_idx]) & DB_INDEX_MASK) -
+ dp->db_txt_start);
+ total_moved = data_moved + lines_moved * (int)INDEX_SIZE;
if ((int)dp->db_free + total_moved >= space_needed) {
in_left = true; // put new line in left block
space_needed = total_moved;
@@ -2155,7 +2151,7 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
}
}
- page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size;
+ page_count = ((space_needed + (int)HEADER_SIZE) + page_size - 1) / page_size;
hp_new = ml_new_data(mfp, newfile, page_count);
if (db_idx < 0) { // left block is new
hp_left = hp_new;
@@ -2172,15 +2168,15 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
dp_left = hp_left->bh_data;
bnum_left = hp_left->bh_bnum;
bnum_right = hp_right->bh_bnum;
- page_count_left = hp_left->bh_page_count;
- page_count_right = hp_right->bh_page_count;
+ page_count_left = (int)hp_left->bh_page_count;
+ page_count_right = (int)hp_right->bh_page_count;
/*
* May move the new line into the right/new block.
*/
if (!in_left) {
- dp_right->db_txt_start -= len;
- dp_right->db_free -= len + INDEX_SIZE;
+ dp_right->db_txt_start -= (unsigned)len;
+ dp_right->db_free -= (unsigned)len + (unsigned)INDEX_SIZE;
dp_right->db_index[0] = dp_right->db_txt_start;
if (mark) {
dp_right->db_index[0] |= DB_MARKED;
@@ -2196,21 +2192,21 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
if (lines_moved) {
/*
*/
- dp_right->db_txt_start -= data_moved;
- dp_right->db_free -= total_moved;
+ dp_right->db_txt_start -= (unsigned)data_moved;
+ dp_right->db_free -= (unsigned)total_moved;
memmove((char *)dp_right + dp_right->db_txt_start,
(char *)dp_left + dp_left->db_txt_start,
(size_t)data_moved);
- offset = dp_right->db_txt_start - dp_left->db_txt_start;
- dp_left->db_txt_start += data_moved;
- dp_left->db_free += total_moved;
+ offset = (int)(dp_right->db_txt_start - dp_left->db_txt_start);
+ dp_left->db_txt_start += (unsigned)data_moved;
+ dp_left->db_free += (unsigned)total_moved;
/*
* update indexes in the new block
*/
for (to = line_count_right, from = db_idx + 1;
- from < line_count_left; ++from, ++to) {
- dp_right->db_index[to] = dp->db_index[from] + offset;
+ from < line_count_left; from++, to++) {
+ dp_right->db_index[to] = dp->db_index[from] + (unsigned)offset;
}
line_count_right += lines_moved;
line_count_left -= lines_moved;
@@ -2220,8 +2216,8 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
* May move the new line into the left (old or new) block.
*/
if (in_left) {
- dp_left->db_txt_start -= len;
- dp_left->db_free -= len + INDEX_SIZE;
+ dp_left->db_txt_start -= (unsigned)len;
+ dp_left->db_free -= (unsigned)len + (unsigned)INDEX_SIZE;
dp_left->db_index[line_count_left] = dp_left->db_txt_start;
if (mark) {
dp_left->db_index[line_count_left] |= DB_MARKED;
@@ -2369,8 +2365,8 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
memmove(&pp_new->pb_pointer[0],
&pp->pb_pointer[pb_idx + 1],
(size_t)(total_moved) * sizeof(PTR_EN));
- pp_new->pb_count = total_moved;
- pp->pb_count -= total_moved - 1;
+ pp_new->pb_count = (uint16_t)total_moved;
+ pp->pb_count = (uint16_t)(pp->pb_count - (total_moved - 1));
pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
@@ -2436,12 +2432,12 @@ void ml_add_deleted_len_buf(buf_T *buf, char_u *ptr, ssize_t len)
return;
}
if (len == -1) {
- len = STRLEN(ptr);
+ len = (ssize_t)STRLEN(ptr);
}
- curbuf->deleted_bytes += len + 1;
- curbuf->deleted_bytes2 += len + 1;
+ curbuf->deleted_bytes += (size_t)len + 1;
+ curbuf->deleted_bytes2 += (size_t)len + 1;
if (curbuf->update_need_codepoints) {
- mb_utflen(ptr, len, &curbuf->deleted_codepoints,
+ mb_utflen(ptr, (size_t)len, &curbuf->deleted_codepoints,
&curbuf->deleted_codeunits);
curbuf->deleted_codepoints++; // NL char
curbuf->deleted_codeunits++;
@@ -2525,7 +2521,6 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
int count; // number of entries in block
int idx;
int stack_idx;
- int text_start;
int line_start;
long line_size;
int i;
@@ -2568,17 +2563,16 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
dp = hp->bh_data;
// compute line count before the delete
- count = (long)(buf->b_ml.ml_locked_high)
- - (long)(buf->b_ml.ml_locked_low) + 2;
+ count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 2;
idx = lnum - buf->b_ml.ml_locked_low;
--buf->b_ml.ml_line_count;
line_start = ((dp->db_index[idx]) & DB_INDEX_MASK);
if (idx == 0) { // first line in block, text at the end
- line_size = dp->db_txt_end - line_start;
+ line_size = dp->db_txt_end - (unsigned)line_start;
} else {
- line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start;
+ line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - (unsigned)line_start;
}
// Line should always have an NL char internally (represented as NUL),
@@ -2636,24 +2630,20 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
}
CHECK(stack_idx < 0, _("deleted block 1?"));
} else {
- /*
- * delete the text by moving the next lines forwards
- */
- text_start = dp->db_txt_start;
+ // delete the text by moving the next lines forwards
+ int text_start = (int)dp->db_txt_start;
memmove((char *)dp + text_start + line_size,
(char *)dp + text_start, (size_t)(line_start - text_start));
- /*
- * delete the index by moving the next indexes backwards
- * Adjust the indexes for the text movement.
- */
- for (i = idx; i < count - 1; ++i) {
- dp->db_index[i] = dp->db_index[i + 1] + line_size;
+ // delete the index by moving the next indexes backwards
+ // Adjust the indexes for the text movement.
+ for (i = idx; i < count - 1; i++) {
+ dp->db_index[i] = dp->db_index[i + 1] + (unsigned)line_size;
}
- dp->db_free += line_size + INDEX_SIZE;
- dp->db_txt_start += line_size;
- --(dp->db_line_count);
+ dp->db_free += (unsigned)line_size + (unsigned)INDEX_SIZE;
+ dp->db_txt_start += (unsigned)line_size;
+ dp->db_line_count--;
/*
* mark the block dirty and make sure it is in the file (for recovery)
@@ -2823,9 +2813,9 @@ static void ml_flush_line(buf_T *buf)
start = ((dp->db_index[idx]) & DB_INDEX_MASK);
old_line = (char_u *)dp + start;
if (idx == 0) { // line is last in block
- old_len = dp->db_txt_end - start;
+ old_len = (int)dp->db_txt_end - start;
} else { // text of previous line follows
- old_len = (dp->db_index[idx - 1] & DB_INDEX_MASK) - start;
+ old_len = (int)(dp->db_index[idx - 1] & DB_INDEX_MASK) - start;
}
new_len = (colnr_T)STRLEN(new_line) + 1;
extra = new_len - old_len; // negative if lines gets smaller
@@ -2840,18 +2830,18 @@ static void ml_flush_line(buf_T *buf)
// move text of following lines
memmove((char *)dp + dp->db_txt_start - extra,
(char *)dp + dp->db_txt_start,
- (size_t)(start - dp->db_txt_start));
+ (size_t)(start - (int)dp->db_txt_start));
// adjust pointers of this and following lines
- for (i = idx + 1; i < count; ++i) {
- dp->db_index[i] -= extra;
+ for (i = idx + 1; i < count; i++) {
+ dp->db_index[i] -= (unsigned)extra;
}
}
- dp->db_index[idx] -= extra;
+ dp->db_index[idx] -= (unsigned)extra;
// adjust free space
- dp->db_free -= extra;
- dp->db_txt_start -= extra;
+ dp->db_free -= (unsigned)extra;
+ dp->db_txt_start -= (unsigned)extra;
// copy new line into the data block
memmove(old_line - extra, new_line, (size_t)new_len);
@@ -2866,7 +2856,7 @@ static void ml_flush_line(buf_T *buf)
// Don't forget to copy the mark!
// How about handling errors???
(void)ml_append_int(buf, lnum, new_line, new_len, false,
- (dp->db_index[idx] & DB_MARKED));
+ (int)(dp->db_index[idx] & DB_MARKED));
(void)ml_delete_int(buf, lnum, false);
}
}
@@ -2886,8 +2876,8 @@ static bhdr_T *ml_new_data(memfile_T *mfp, bool negative, int page_count)
bhdr_T *hp = mf_new(mfp, negative, (unsigned)page_count);
DATA_BL *dp = hp->bh_data;
dp->db_id = DATA_ID;
- dp->db_txt_start = dp->db_txt_end = page_count * mfp->mf_page_size;
- dp->db_free = dp->db_txt_start - HEADER_SIZE;
+ dp->db_txt_start = dp->db_txt_end = (unsigned)page_count * mfp->mf_page_size;
+ dp->db_free = dp->db_txt_start - (unsigned)HEADER_SIZE;
dp->db_line_count = 0;
return hp;
@@ -2900,7 +2890,7 @@ static bhdr_T *ml_new_ptr(memfile_T *mfp)
PTR_BL *pp = hp->bh_data;
pp->pb_id = PTR_ID;
pp->pb_count = 0;
- pp->pb_count_max = (mfp->mf_page_size - sizeof(PTR_BL)) / sizeof(PTR_EN) + 1;
+ pp->pb_count_max = (uint16_t)((mfp->mf_page_size - sizeof(PTR_BL)) / sizeof(PTR_EN) + 1);
return hp;
}
@@ -3000,7 +2990,7 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
* search downwards in the tree until a data block is found
*/
for (;;) {
- if ((hp = mf_get(mfp, bnum, page_count)) == NULL) {
+ if ((hp = mf_get(mfp, bnum, (unsigned)page_count)) == NULL) {
goto error_noblock;
}
@@ -3110,7 +3100,7 @@ static int ml_add_stack(buf_T *buf)
CHECK(top > 0, _("Stack size increases")); // more than 5 levels???
buf->b_ml.ml_stack_size += STACK_INCR;
- size_t new_size = sizeof(infoptr_T) * buf->b_ml.ml_stack_size;
+ size_t new_size = sizeof(infoptr_T) * (size_t)buf->b_ml.ml_stack_size;
buf->b_ml.ml_stack = xrealloc(buf->b_ml.ml_stack, new_size);
}
@@ -3179,7 +3169,7 @@ int resolve_symlink(const char_u *fname, char_u *buf)
return FAIL;
}
- ret = readlink((char *)tmp, (char *)buf, MAXPATHL - 1);
+ ret = (int)readlink((char *)tmp, (char *)buf, MAXPATHL - 1);
if (ret <= 0) {
if (errno == EINVAL || errno == ENOENT) {
// Found non-symlink or not existing file, stop here.
@@ -3294,9 +3284,9 @@ char_u *get_file_in_dir(char_u *fname, char_u *dname)
} else {
save_char = *tail;
*tail = NUL;
- t = (char_u *)concat_fnames((char *)fname, (char *)dname + 2, TRUE);
- *tail = save_char;
- retval = (char_u *)concat_fnames((char *)t, (char *)tail, TRUE);
+ t = (char_u *)concat_fnames((char *)fname, (char *)dname + 2, true);
+ *tail = (uint8_t)save_char;
+ retval = (char_u *)concat_fnames((char *)t, (char *)tail, true);
xfree(t);
}
} else {
@@ -3798,8 +3788,7 @@ void ml_setflags(buf_T *buf)
if (hp->bh_bnum == 0) {
b0p = hp->bh_data;
b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
- b0p->b0_flags = (b0p->b0_flags & ~B0_FF_MASK)
- | (get_fileformat(buf) + 1);
+ b0p->b0_flags = (uint8_t)((b0p->b0_flags & ~B0_FF_MASK) | (uint8_t)(get_fileformat(buf) + 1));
add_b0_fenc(b0p, buf);
hp->bh_flags |= BH_DIRTY;
mf_sync(buf->b_ml.ml_mfp, MFS_ZERO);
@@ -3887,7 +3876,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
if (buf->b_ml.ml_usedchunks + 1 >= buf->b_ml.ml_numchunks) {
buf->b_ml.ml_numchunks = buf->b_ml.ml_numchunks * 3 / 2;
buf->b_ml.ml_chunksize = xrealloc(buf->b_ml.ml_chunksize,
- sizeof(chunksize_T) * buf->b_ml.ml_numchunks);
+ sizeof(chunksize_T) * (size_t)buf->b_ml.ml_numchunks);
}
if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL) {
@@ -3898,8 +3887,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
memmove(buf->b_ml.ml_chunksize + curix + 1,
buf->b_ml.ml_chunksize + curix,
- (buf->b_ml.ml_usedchunks - curix) *
- sizeof(chunksize_T));
+ (size_t)(buf->b_ml.ml_usedchunks - curix) * sizeof(chunksize_T));
// Compute length of first half of lines in the split chunk
size = 0;
linecnt = 0;
@@ -3910,12 +3898,11 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
return;
}
dp = hp->bh_data;
- count = (long)(buf->b_ml.ml_locked_high) -
- (long)(buf->b_ml.ml_locked_low) + 1;
+ count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1;
idx = curline - buf->b_ml.ml_locked_low;
curline = buf->b_ml.ml_locked_high + 1;
if (idx == 0) { // first line in block, text at the end
- text_end = dp->db_txt_end;
+ text_end = (int)dp->db_txt_end;
} else {
text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
}
@@ -3928,7 +3915,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
idx = count - 1;
linecnt += rest;
}
- size += text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
+ size += text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK);
}
buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt;
buf->b_ml.ml_chunksize[curix + 1].mlcs_numlines -= linecnt;
@@ -3959,11 +3946,10 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
}
dp = hp->bh_data;
if (dp->db_line_count == 1) {
- rest = dp->db_txt_end - dp->db_txt_start;
+ rest = (int)(dp->db_txt_end - dp->db_txt_start);
} else {
- rest =
- ((dp->db_index[dp->db_line_count - 2]) & DB_INDEX_MASK)
- - dp->db_txt_start;
+ rest = (int)((dp->db_index[dp->db_line_count - 2]) & DB_INDEX_MASK)
+ - (int)dp->db_txt_start;
}
curchnk->mlcs_totalsize = rest;
curchnk->mlcs_numlines = 1;
@@ -3982,7 +3968,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
} else if (curix == 0 && curchnk->mlcs_numlines <= 0) {
buf->b_ml.ml_usedchunks--;
memmove(buf->b_ml.ml_chunksize, buf->b_ml.ml_chunksize + 1,
- buf->b_ml.ml_usedchunks * sizeof(chunksize_T));
+ (size_t)buf->b_ml.ml_usedchunks * sizeof(chunksize_T));
return;
} else if (curix == 0 || (curchnk->mlcs_numlines > 10
&& (curchnk->mlcs_numlines +
@@ -3998,8 +3984,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
if (curix < buf->b_ml.ml_usedchunks) {
memmove(buf->b_ml.ml_chunksize + curix,
buf->b_ml.ml_chunksize + curix + 1,
- (buf->b_ml.ml_usedchunks - curix) *
- sizeof(chunksize_T));
+ (size_t)(buf->b_ml.ml_usedchunks - curix) * sizeof(chunksize_T));
}
return;
}
@@ -4049,7 +4034,7 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
if (lnum == 0 || buf->b_ml.ml_line_lnum < lnum || !no_ff) {
ml_flush_line(curbuf);
} else if (can_cache && buf->b_ml.ml_line_offset > 0) {
- return buf->b_ml.ml_line_offset;
+ return (long)buf->b_ml.ml_line_offset;
}
if (buf->b_ml.ml_usedchunks == -1
@@ -4071,7 +4056,8 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
* special because it will never qualify
*/
curline = 1;
- curix = size = 0;
+ curix = 0;
+ size = 0;
while (curix < buf->b_ml.ml_usedchunks - 1
&& ((lnum != 0
&& lnum >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines)
@@ -4093,11 +4079,10 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
return -1;
}
dp = hp->bh_data;
- count = (long)(buf->b_ml.ml_locked_high) -
- (long)(buf->b_ml.ml_locked_low) + 1;
+ count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1;
start_idx = idx = curline - buf->b_ml.ml_locked_low;
if (idx == 0) { // first line in block, text at the end
- text_end = dp->db_txt_end;
+ text_end = (int)dp->db_txt_end;
} else {
text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
}
@@ -4123,7 +4108,7 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
idx++;
}
}
- len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
+ len = text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK);
size += len;
if (offset != 0 && size >= offset) {
if (size + ffdos == offset) {
@@ -4132,7 +4117,7 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
*offp = offset - size + len;
} else {
*offp = offset - size + len
- - (text_end - ((dp->db_index[idx - 1]) & DB_INDEX_MASK));
+ - (text_end - (int)((dp->db_index[idx - 1]) & DB_INDEX_MASK));
}
curline += idx - start_idx + extra;
if (curline > buf->b_ml.ml_line_count) {
@@ -4158,7 +4143,7 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
}
if (can_cache && size > 0) {
- buf->b_ml.ml_line_offset = size;
+ buf->b_ml.ml_line_offset = (size_t)size;
}
return size;
@@ -4168,14 +4153,13 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
void goto_byte(long cnt)
{
long boff = cnt;
- linenr_T lnum;
ml_flush_line(curbuf); // cached line may be dirty
setpcmark();
if (boff) {
boff--;
}
- lnum = ml_find_line_or_offset(curbuf, (linenr_T)0, &boff, false);
+ linenr_T lnum = (linenr_T)ml_find_line_or_offset(curbuf, (linenr_T)0, &boff, false);
if (lnum < 1) { // past the end
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
curwin->w_curswant = MAXCOL;
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index b675abfb7d..a842bb20a9 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -1908,6 +1908,13 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent)
StlClickDefinition *click_defs = in_status_line ? wp->w_status_click_defs
: wp->w_winbar_click_defs;
+ if (in_status_line && global_stl_height() > 0) {
+ // global statusline is displayed for the current window,
+ // and spans the whole screen.
+ click_defs = curwin->w_status_click_defs;
+ click_col = mouse_col;
+ }
+
if (click_defs != NULL) {
switch (click_defs[click_col].type) {
case kStlClickDisabled:
diff --git a/src/nvim/testdir/test_excmd.vim b/src/nvim/testdir/test_excmd.vim
index 7d581d5efd..f844999d8d 100644
--- a/src/nvim/testdir/test_excmd.vim
+++ b/src/nvim/testdir/test_excmd.vim
@@ -242,49 +242,58 @@ func Test_confirm_cmd()
CheckNotGui
CheckRunVimInTerminal
- call writefile(['foo1'], 'foo')
- call writefile(['bar1'], 'bar')
+ call writefile(['foo1'], 'Xfoo')
+ call writefile(['bar1'], 'Xbar')
" Test for saving all the modified buffers
- let buf = RunVimInTerminal('', {'rows': 20})
- call term_sendkeys(buf, ":set nomore\n")
- call term_sendkeys(buf, ":new foo\n")
- call term_sendkeys(buf, ":call setline(1, 'foo2')\n")
- call term_sendkeys(buf, ":new bar\n")
- call term_sendkeys(buf, ":call setline(1, 'bar2')\n")
- call term_sendkeys(buf, ":wincmd b\n")
+ let lines =<< trim END
+ set nomore
+ new Xfoo
+ call setline(1, 'foo2')
+ new Xbar
+ call setline(1, 'bar2')
+ wincmd b
+ END
+ call writefile(lines, 'Xscript')
+ let buf = RunVimInTerminal('-S Xscript', {'rows': 20})
call term_sendkeys(buf, ":confirm qall\n")
call WaitForAssert({-> assert_match('\[Y\]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: ', term_getline(buf, 20))}, 1000)
call term_sendkeys(buf, "A")
call StopVimInTerminal(buf)
- call assert_equal(['foo2'], readfile('foo'))
- call assert_equal(['bar2'], readfile('bar'))
+ call assert_equal(['foo2'], readfile('Xfoo'))
+ call assert_equal(['bar2'], readfile('Xbar'))
" Test for discarding all the changes to modified buffers
- let buf = RunVimInTerminal('', {'rows': 20})
- call term_sendkeys(buf, ":set nomore\n")
- call term_sendkeys(buf, ":new foo\n")
- call term_sendkeys(buf, ":call setline(1, 'foo3')\n")
- call term_sendkeys(buf, ":new bar\n")
- call term_sendkeys(buf, ":call setline(1, 'bar3')\n")
- call term_sendkeys(buf, ":wincmd b\n")
+ let lines =<< trim END
+ set nomore
+ new Xfoo
+ call setline(1, 'foo3')
+ new Xbar
+ call setline(1, 'bar3')
+ wincmd b
+ END
+ call writefile(lines, 'Xscript')
+ let buf = RunVimInTerminal('-S Xscript', {'rows': 20})
call term_sendkeys(buf, ":confirm qall\n")
call WaitForAssert({-> assert_match('\[Y\]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: ', term_getline(buf, 20))}, 1000)
call term_sendkeys(buf, "D")
call StopVimInTerminal(buf)
- call assert_equal(['foo2'], readfile('foo'))
- call assert_equal(['bar2'], readfile('bar'))
+ call assert_equal(['foo2'], readfile('Xfoo'))
+ call assert_equal(['bar2'], readfile('Xbar'))
" Test for saving and discarding changes to some buffers
- let buf = RunVimInTerminal('', {'rows': 20})
- call term_sendkeys(buf, ":set nomore\n")
- call term_sendkeys(buf, ":new foo\n")
- call term_sendkeys(buf, ":call setline(1, 'foo4')\n")
- call term_sendkeys(buf, ":new bar\n")
- call term_sendkeys(buf, ":call setline(1, 'bar4')\n")
- call term_sendkeys(buf, ":wincmd b\n")
+ let lines =<< trim END
+ set nomore
+ new Xfoo
+ call setline(1, 'foo4')
+ new Xbar
+ call setline(1, 'bar4')
+ wincmd b
+ END
+ call writefile(lines, 'Xscript')
+ let buf = RunVimInTerminal('-S Xscript', {'rows': 20})
call term_sendkeys(buf, ":confirm qall\n")
call WaitForAssert({-> assert_match('\[Y\]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: ', term_getline(buf, 20))}, 1000)
call term_sendkeys(buf, "N")
@@ -292,11 +301,12 @@ func Test_confirm_cmd()
call term_sendkeys(buf, "Y")
call StopVimInTerminal(buf)
- call assert_equal(['foo4'], readfile('foo'))
- call assert_equal(['bar2'], readfile('bar'))
+ call assert_equal(['foo4'], readfile('Xfoo'))
+ call assert_equal(['bar2'], readfile('Xbar'))
- call delete('foo')
- call delete('bar')
+ call delete('Xscript')
+ call delete('Xfoo')
+ call delete('Xbar')
endfunc
func Test_confirm_cmd_cancel()
@@ -304,10 +314,13 @@ func Test_confirm_cmd_cancel()
CheckRunVimInTerminal
" Test for closing a window with a modified buffer
- let buf = RunVimInTerminal('', {'rows': 20})
- call term_sendkeys(buf, ":set nomore\n")
- call term_sendkeys(buf, ":new\n")
- call term_sendkeys(buf, ":call setline(1, 'abc')\n")
+ let lines =<< trim END
+ set nomore
+ new
+ call setline(1, 'abc')
+ END
+ call writefile(lines, 'Xscript')
+ let buf = RunVimInTerminal('-S Xscript', {'rows': 20})
call term_sendkeys(buf, ":confirm close\n")
call WaitForAssert({-> assert_match('^\[Y\]es, (N)o, (C)ancel: *$',
\ term_getline(buf, 20))}, 1000)
@@ -320,6 +333,43 @@ func Test_confirm_cmd_cancel()
call WaitForAssert({-> assert_match('^ *0,0-1 All$',
\ term_getline(buf, 20))}, 1000)
call StopVimInTerminal(buf)
+ call delete('Xscript')
+endfunc
+
+" The ":confirm" prompt was sometimes used with the terminal in cooked mode.
+" This test verifies that a "\<CR>" character is NOT required to respond to a
+" prompt from the ":conf q" and ":conf wq" commands.
+func Test_confirm_q_wq()
+ CheckNotGui
+ CheckRunVimInTerminal
+
+ call writefile(['foo'], 'Xfoo')
+
+ let lines =<< trim END
+ set hidden nomore
+ call setline(1, 'abc')
+ edit Xfoo
+ END
+ call writefile(lines, 'Xscript')
+ let buf = RunVimInTerminal('-S Xscript', {'rows': 20})
+ call term_sendkeys(buf, ":confirm q\n")
+ call WaitForAssert({-> assert_match('^\[Y\]es, (N)o, (C)ancel: *$',
+ \ term_getline(buf, 20))}, 1000)
+ call term_sendkeys(buf, 'C')
+ call WaitForAssert({-> assert_notmatch('^\[Y\]es, (N)o, (C)ancel: C*$',
+ \ term_getline(buf, 20))}, 1000)
+
+ call term_sendkeys(buf, ":edit Xfoo\n")
+ call term_sendkeys(buf, ":confirm wq\n")
+ call WaitForAssert({-> assert_match('^\[Y\]es, (N)o, (C)ancel: *$',
+ \ term_getline(buf, 20))}, 1000)
+ call term_sendkeys(buf, 'C')
+ call WaitForAssert({-> assert_notmatch('^\[Y\]es, (N)o, (C)ancel: C*$',
+ \ term_getline(buf, 20))}, 1000)
+ call StopVimInTerminal(buf)
+
+ call delete('Xscript')
+ call delete('Xfoo')
endfunc
func Test_confirm_write_ro()
diff --git a/test/functional/legacy/excmd_spec.lua b/test/functional/legacy/excmd_spec.lua
index 6b3b265579..549f412e24 100644
--- a/test/functional/legacy/excmd_spec.lua
+++ b/test/functional/legacy/excmd_spec.lua
@@ -2,8 +2,11 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local command = helpers.command
+local exec = helpers.exec
local exec_lua = helpers.exec_lua
local feed = helpers.feed
+local funcs = helpers.funcs
+local iswin = helpers.iswin
local meths = helpers.meths
local poke_eventloop = helpers.poke_eventloop
local read_file = helpers.read_file
@@ -37,152 +40,487 @@ describe('Ex command', function()
end)
end)
-it(':confirm command dialog', function()
+describe(':confirm command dialog', function()
local screen
local function start_new()
clear()
- screen = Screen.new(60, 20)
+ screen = Screen.new(75, 20)
+ screen:set_default_attr_ids({
+ [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
+ [1] = {bold = true, reverse = true}, -- StatusLine, MsgSeparator
+ [2] = {reverse = true}, -- StatusLineNC
+ [3] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg
+ })
screen:attach()
end
- write_file('foo', 'foo1\n')
- write_file('bar', 'bar1\n')
-
- -- Test for saving all the modified buffers
- start_new()
- command("set nomore")
- command("new foo")
- command("call setline(1, 'foo2')")
- command("new bar")
- command("call setline(1, 'bar2')")
- command("wincmd b")
- feed(':confirm qall\n')
- screen:expect([[
- bar2 |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- bar [+] |
- foo2 |
- ~ |
- ~ |
- ~ |
- ~ |
- foo [+] |
- |
- ~ |
- ~ |
- |
- :confirm qall |
- Save changes to "bar"? |
- [Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: ^ |
- ]])
- feed('A')
- poke_eventloop()
-
- eq('foo2\n', read_file('foo'))
- eq('bar2\n', read_file('bar'))
-
- -- Test for discarding all the changes to modified buffers
- start_new()
- command("set nomore")
- command("new foo")
- command("call setline(1, 'foo3')")
- command("new bar")
- command("call setline(1, 'bar3')")
- command("wincmd b")
- feed(':confirm qall\n')
- screen:expect([[
- bar3 |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- bar [+] |
- foo3 |
- ~ |
- ~ |
- ~ |
- ~ |
- foo [+] |
- |
- ~ |
- ~ |
- |
- :confirm qall |
- Save changes to "bar"? |
- [Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: ^ |
- ]])
- feed('D')
- poke_eventloop()
-
- eq('foo2\n', read_file('foo'))
- eq('bar2\n', read_file('bar'))
-
- -- Test for saving and discarding changes to some buffers
- start_new()
- command("set nomore")
- command("new foo")
- command("call setline(1, 'foo4')")
- command("new bar")
- command("call setline(1, 'bar4')")
- command("wincmd b")
- feed(':confirm qall\n')
- screen:expect([[
- bar4 |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- bar [+] |
- foo4 |
- ~ |
- ~ |
- ~ |
- ~ |
- foo [+] |
- |
- ~ |
- ~ |
- |
- :confirm qall |
- Save changes to "bar"? |
- [Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: ^ |
- ]])
- feed('N')
- screen:expect([[
- bar4 |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- bar [+] |
- foo4 |
- ~ |
- ~ |
- ~ |
- ~ |
- foo [+] |
- |
- |
- :confirm qall |
- Save changes to "bar"? |
- |
- Save changes to "foo"? |
- [Y]es, (N)o, (C)ancel: ^ |
- ]])
- feed('Y')
- poke_eventloop()
-
- eq('foo4\n', read_file('foo'))
- eq('bar2\n', read_file('bar'))
-
- os.remove('foo')
- os.remove('bar')
+ -- Test for the :confirm command dialog
+ -- oldtest: Test_confirm_cmd()
+ it('works', function()
+ write_file('Xfoo', 'foo1\n')
+ write_file('Xbar', 'bar1\n')
+
+ -- Test for saving all the modified buffers
+ start_new()
+ exec([[
+ set nomore
+ new Xfoo
+ call setline(1, 'foo2')
+ new Xbar
+ call setline(1, 'bar2')
+ wincmd b
+ ]])
+ feed(':confirm qall\n')
+ screen:expect([[
+ bar2 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xbar [+] }|
+ foo2 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xfoo [+] }|
+ |
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ :confirm qall |
+ {3:Save changes to "Xbar"?} |
+ {3:[Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: }^ |
+ ]])
+ feed('A')
+ poke_eventloop()
+
+ eq('foo2\n', read_file('Xfoo'))
+ eq('bar2\n', read_file('Xbar'))
+
+ -- Test for discarding all the changes to modified buffers
+ start_new()
+ exec([[
+ set nomore
+ new Xfoo
+ call setline(1, 'foo3')
+ new Xbar
+ call setline(1, 'bar3')
+ wincmd b
+ ]])
+ feed(':confirm qall\n')
+ screen:expect([[
+ bar3 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xbar [+] }|
+ foo3 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xfoo [+] }|
+ |
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ :confirm qall |
+ {3:Save changes to "Xbar"?} |
+ {3:[Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: }^ |
+ ]])
+ feed('D')
+ poke_eventloop()
+
+ eq('foo2\n', read_file('Xfoo'))
+ eq('bar2\n', read_file('Xbar'))
+
+ -- Test for saving and discarding changes to some buffers
+ start_new()
+ exec([[
+ set nomore
+ new Xfoo
+ call setline(1, 'foo4')
+ new Xbar
+ call setline(1, 'bar4')
+ wincmd b
+ ]])
+ feed(':confirm qall\n')
+ screen:expect([[
+ bar4 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xbar [+] }|
+ foo4 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xfoo [+] }|
+ |
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ :confirm qall |
+ {3:Save changes to "Xbar"?} |
+ {3:[Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: }^ |
+ ]])
+ feed('N')
+ screen:expect([[
+ bar4 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xbar [+] }|
+ foo4 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xfoo [+] }|
+ |
+ {1: }|
+ :confirm qall |
+ {3:Save changes to "Xbar"?} |
+ |
+ {3:Save changes to "Xfoo"?} |
+ {3:[Y]es, (N)o, (C)ancel: }^ |
+ ]])
+ feed('Y')
+ poke_eventloop()
+
+ eq('foo4\n', read_file('Xfoo'))
+ eq('bar2\n', read_file('Xbar'))
+
+ os.remove('Xfoo')
+ os.remove('Xbar')
+ end)
+
+ -- oldtest: Test_confirm_cmd_cancel()
+ it('can be cancelled', function()
+ -- Test for closing a window with a modified buffer
+ start_new()
+ screen:try_resize(75, 10)
+ exec([[
+ set nohidden nomore
+ new
+ call setline(1, 'abc')
+ ]])
+ feed(':confirm close\n')
+ screen:expect([[
+ abc |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1:[No Name] [+] }|
+ |
+ {1: }|
+ :confirm close |
+ {3:Save changes to "Untitled"?} |
+ {3:[Y]es, (N)o, (C)ancel: }^ |
+ ]])
+ feed('C')
+ screen:expect([[
+ ^abc |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1:[No Name] [+] }|
+ |
+ {0:~ }|
+ {0:~ }|
+ {2:[No Name] }|
+ |
+ ]])
+ feed(':confirm close\n')
+ screen:expect([[
+ abc |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1:[No Name] [+] }|
+ |
+ {1: }|
+ :confirm close |
+ {3:Save changes to "Untitled"?} |
+ {3:[Y]es, (N)o, (C)ancel: }^ |
+ ]])
+ feed('N')
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ end)
+
+ -- oldtest: Test_confirm_q_wq()
+ it('works with :q and :wq', function()
+ write_file('Xfoo', 'foo')
+ start_new()
+ screen:try_resize(75, 8)
+ exec([[
+ set hidden nomore
+ call setline(1, 'abc')
+ edit Xfoo
+ set nofixendofline
+ ]])
+ feed(':confirm q\n')
+ screen:expect([[
+ foo |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ :confirm q |
+ {3:Save changes to "Untitled"?} |
+ {3:[Y]es, (N)o, (C)ancel: }^ |
+ ]])
+ feed('C')
+ screen:expect([[
+ ^abc |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+
+ command('edit Xfoo')
+ feed(':confirm wq\n')
+ screen:expect([[
+ foo |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ "Xfoo" [noeol] 1L, 3B written |
+ {3:Save changes to "Untitled"?} |
+ {3:[Y]es, (N)o, (C)ancel: }^ |
+ ]])
+ feed('C')
+ screen:expect([[
+ ^abc |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ "Xfoo" [noeol] 1L, 3B written |
+ ]])
+
+ os.remove('Xfoo')
+ end)
+
+ -- oldtest: Test_confirm_write_ro()
+ it('works when writing a read-only file', function()
+ write_file('Xconfirm_write_ro', 'foo\n')
+ start_new()
+ screen:try_resize(75, 8)
+ exec([[
+ set ruler
+ set nobackup ff=unix cmdheight=2
+ edit Xconfirm_write_ro
+ norm Abar
+ ]])
+
+ -- Try to write with 'ro' option.
+ feed(':set ro | confirm w\n')
+ screen:expect([[
+ foobar |
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ :set ro | confirm w |
+ {3:'readonly' option is set for "Xconfirm_write_ro".} |
+ {3:Do you wish to write anyway?} |
+ {3:(Y)es, [N]o: }^ |
+ ]])
+ feed('N')
+ screen:expect([[
+ fooba^r |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ 1,6 All |
+ ]])
+ eq('foo\n', read_file('Xconfirm_write_ro'))
+
+ feed(':confirm w\n')
+ screen:expect([[
+ foobar |
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ :confirm w |
+ {3:'readonly' option is set for "Xconfirm_write_ro".} |
+ {3:Do you wish to write anyway?} |
+ {3:(Y)es, [N]o: }^ |
+ ]])
+ feed('Y')
+ if iswin() then
+ screen:expect([[
+ foobar |
+ {0:~ }|
+ {1: }|
+ :confirm w |
+ {3:'readonly' option is set for "Xconfirm_write_ro".} |
+ {3:Do you wish to write anyway?} |
+ "Xconfirm_write_ro" [unix] 1L, 7B written |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ else
+ screen:expect([[
+ foobar |
+ {0:~ }|
+ {1: }|
+ :confirm w |
+ {3:'readonly' option is set for "Xconfirm_write_ro".} |
+ {3:Do you wish to write anyway?} |
+ "Xconfirm_write_ro" 1L, 7B written |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ end
+ eq('foobar\n', read_file('Xconfirm_write_ro'))
+ feed('<CR>') -- suppress hit-enter prompt
+
+ -- Try to write with read-only file permissions.
+ funcs.setfperm('Xconfirm_write_ro', 'r--r--r--')
+ feed(':set noro | undo | confirm w\n')
+ screen:expect([[
+ foobar |
+ {0:~ }|
+ {1: }|
+ 1 change; before #1 0 seconds ago |
+ {3:File permissions of "Xconfirm_write_ro" are read-only.} |
+ {3:It may still be possible to write it.} |
+ {3:Do you wish to try?} |
+ {3:(Y)es, [N]o: }^ |
+ ]])
+ feed('Y')
+ if iswin() then
+ screen:expect([[
+ foobar |
+ {1: }|
+ 1 change; before #1 0 seconds ago |
+ {3:File permissions of "Xconfirm_write_ro" are read-only.} |
+ {3:It may still be possible to write it.} |
+ {3:Do you wish to try?} |
+ "Xconfirm_write_ro" [unix] 1L, 4B written |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ else
+ screen:expect([[
+ foobar |
+ {1: }|
+ 1 change; before #1 0 seconds ago |
+ {3:File permissions of "Xconfirm_write_ro" are read-only.} |
+ {3:It may still be possible to write it.} |
+ {3:Do you wish to try?} |
+ "Xconfirm_write_ro" 1L, 4B written |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ end
+ eq('foo\n', read_file('Xconfirm_write_ro'))
+ feed('<CR>') -- suppress hit-enter prompt
+
+ os.remove('Xconfirm_write_ro')
+ end)
+
+ -- oldtest: Test_confirm_write_partial_file()
+ it('works when writing a partial file', function()
+ write_file('Xwrite_partial', 'a\nb\nc\nd\n')
+ start_new()
+ screen:try_resize(75, 8)
+ exec([[
+ set ruler
+ set nobackup ff=unix cmdheight=2
+ edit Xwrite_partial
+ ]])
+
+ feed(':confirm 2,3w\n')
+ screen:expect([[
+ a |
+ b |
+ c |
+ d |
+ {1: }|
+ :confirm 2,3w |
+ {3:Write partial file?} |
+ {3:(Y)es, [N]o: }^ |
+ ]])
+ feed('N')
+ screen:expect([[
+ ^a |
+ b |
+ c |
+ d |
+ {0:~ }|
+ {0:~ }|
+ |
+ 1,1 All |
+ ]])
+ eq('a\nb\nc\nd\n', read_file('Xwrite_partial'))
+ os.remove('Xwrite_partial')
+
+ feed(':confirm 2,3w\n')
+ screen:expect([[
+ a |
+ b |
+ c |
+ d |
+ {1: }|
+ :confirm 2,3w |
+ {3:Write partial file?} |
+ {3:(Y)es, [N]o: }^ |
+ ]])
+ feed('Y')
+ if iswin() then
+ screen:expect([[
+ a |
+ b |
+ c |
+ {1: }|
+ :confirm 2,3w |
+ {3:Write partial file?} |
+ "Xwrite_partial" [New][unix] 2L, 4B written |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ else
+ screen:expect([[
+ a |
+ b |
+ c |
+ {1: }|
+ :confirm 2,3w |
+ {3:Write partial file?} |
+ "Xwrite_partial" [New] 2L, 4B written |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ end
+ eq('b\nc\n', read_file('Xwrite_partial'))
+
+ os.remove('Xwrite_partial')
+ end)
end)
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index 883e0e373b..e2347c3c11 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -2493,6 +2493,41 @@ describe('lua stdlib', function()
eq(false, pcall_result)
end)
+
+ describe('returns -2 when interrupted', function()
+ before_each(function()
+ local channel = meths.get_api_info()[1]
+ meths.set_var('channel', channel)
+ end)
+
+ it('without callback', function()
+ exec_lua([[
+ function _G.Wait()
+ vim.rpcnotify(vim.g.channel, 'ready')
+ local _, interrupted = vim.wait(4000)
+ vim.rpcnotify(vim.g.channel, 'wait', interrupted)
+ end
+ ]])
+ feed(':lua _G.Wait()<CR>')
+ eq({'notification', 'ready', {}}, next_msg(500))
+ feed('<C-C>')
+ eq({'notification', 'wait', {-2}}, next_msg(500))
+ end)
+
+ it('with callback', function()
+ exec_lua([[
+ function _G.Wait()
+ vim.rpcnotify(vim.g.channel, 'ready')
+ local _, interrupted = vim.wait(4000, function() end)
+ vim.rpcnotify(vim.g.channel, 'wait', interrupted)
+ end
+ ]])
+ feed(':lua _G.Wait()<CR>')
+ eq({'notification', 'ready', {}}, next_msg(500))
+ feed('<C-C>')
+ eq({'notification', 'wait', {-2}}, next_msg(500))
+ end)
+ end)
end)
it('vim.notify_once', function()
diff --git a/test/functional/ui/statusline_spec.lua b/test/functional/ui/statusline_spec.lua
index 1e1066d48a..2ffd3149a6 100644
--- a/test/functional/ui/statusline_spec.lua
+++ b/test/functional/ui/statusline_spec.lua
@@ -98,13 +98,41 @@ describe('statusline clicks', function()
eq('0 2 r', eval("g:testvar"))
end)
- it("click works with modifiers #18994", function()
+ it("works with modifiers #18994", function()
meths.set_option('statusline', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T')
meths.input_mouse('right', 'press', 's', 0, 6, 17)
eq('0 1 r s', eval("g:testvar"))
meths.input_mouse('left', 'press', 's', 0, 6, 17)
eq('0 1 l s', eval("g:testvar"))
end)
+
+ it("works for global statusline with vertical splits #19186", function()
+ command('set laststatus=3')
+ meths.set_option('statusline', '%0@MyClickFunc@Clicky stuff%T %= %0@MyClickFunc@Clicky stuff%T')
+ command('vsplit')
+ screen:expect([[
+ ^ │ |
+ ~ │~ |
+ ~ │~ |
+ ~ │~ |
+ ~ │~ |
+ ~ │~ |
+ Clicky stuff Clicky stuff|
+ |
+ ]])
+
+ -- clickable area on the right
+ meths.input_mouse('left', 'press', '', 0, 6, 35)
+ eq('0 1 l', eval("g:testvar"))
+ meths.input_mouse('right', 'press', '', 0, 6, 35)
+ eq('0 1 r', eval("g:testvar"))
+
+ -- clickable area on the left
+ meths.input_mouse('left', 'press', '', 0, 6, 5)
+ eq('0 1 l', eval("g:testvar"))
+ meths.input_mouse('right', 'press', '', 0, 6, 5)
+ eq('0 1 r', eval("g:testvar"))
+ end)
end)
describe('global statusline', function()
diff --git a/test/functional/vimscript/system_spec.lua b/test/functional/vimscript/system_spec.lua
index c915556c57..a778e2f435 100644
--- a/test/functional/vimscript/system_spec.lua
+++ b/test/functional/vimscript/system_spec.lua
@@ -630,7 +630,7 @@ end)
describe('shell :!', function()
before_each(clear)
- it(':{range}! with powershell filter/redirect #16271', function()
+ it(':{range}! with powershell filter/redirect #16271 #19250', function()
local screen = Screen.new(500, 8)
screen:attach()
local found = helpers.set_shell_powershell(true)
@@ -639,18 +639,25 @@ describe('shell :!', function()
1
4
2]])
- feed(':4verbose %!sort<cr>')
- screen:expect{
- any=[[Executing command: .?Start%-Process sort %-RedirectStandardInput .* %-RedirectStandardOutput .* %-NoNewWindow %-Wait]]
- }
+ if iswin() then
+ feed(':4verbose %!sort /R<cr>')
+ screen:expect{
+ any=[[Executing command: .?Start%-Process sort %-ArgumentList "/R" %-RedirectStandardInput .* %-RedirectStandardOutput .* %-NoNewWindow %-Wait]]
+ }
+ else
+ feed(':4verbose %!sort -r<cr>')
+ screen:expect{
+ any=[[Executing command: .?Start%-Process sort %-ArgumentList "%-r" %-RedirectStandardInput .* %-RedirectStandardOutput .* %-NoNewWindow %-Wait]]
+ }
+ end
feed('<CR>')
if found then
-- Not using fake powershell, so we can test the result.
expect([[
- 1
- 2
+ 4
3
- 4]])
+ 2
+ 1]])
end
end)
end)