diff options
-rw-r--r-- | .github/workflows/ci.yml | 5 | ||||
-rw-r--r-- | .github/workflows/release.yml | 7 | ||||
-rw-r--r-- | ci/build.ps1 | 3 | ||||
-rw-r--r-- | runtime/doc/api.txt | 28 | ||||
-rwxr-xr-x | scripts/gen_vimdoc.py | 2 | ||||
-rwxr-xr-x | src/nvim/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 33 | ||||
-rw-r--r-- | src/nvim/lua/executor.c | 6 | ||||
-rw-r--r-- | src/nvim/memline.c | 208 | ||||
-rw-r--r-- | src/nvim/normal.c | 7 | ||||
-rw-r--r-- | src/nvim/testdir/test_excmd.vim | 120 | ||||
-rw-r--r-- | test/functional/legacy/excmd_spec.lua | 620 | ||||
-rw-r--r-- | test/functional/lua/vim_spec.lua | 35 | ||||
-rw-r--r-- | test/functional/ui/statusline_spec.lua | 30 | ||||
-rw-r--r-- | test/functional/vimscript/system_spec.lua | 23 |
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) |