diff options
34 files changed, 358 insertions, 168 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 907339fea1..97156067f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,8 +2,8 @@ # intro: https://codingnest.com/basic-cmake/ # best practices (3.0+): https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1 -cmake_minimum_required(VERSION 2.8.7) -project(nvim) +cmake_minimum_required(VERSION 2.8.12) +project(nvim C) if(POLICY CMP0059) cmake_policy(SET CMP0059 OLD) # Needed until cmake 2.8.12. #4389 @@ -76,9 +76,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") if(CMAKE_COMPILER_IS_GNUCC) set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ") endif() - if(CMAKE_COMPILER_IS_GNUCXX) - set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem ") - endif() endif() if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Darwin") @@ -210,7 +207,6 @@ if(NOT HAS_ACCEPTABLE_FORTIFY) # -U in add_definitions doesn't end up in the correct spot, so we add it to # the flags variable instead. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_FORTIFY_SOURCE_PREFIX}-U_FORTIFY_SOURCE ${_FORTIFY_SOURCE_PREFIX}-D_FORTIFY_SOURCE=1") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_FORTIFY_SOURCE_PREFIX}-U_FORTIFY_SOURCE ${_FORTIFY_SOURCE_PREFIX}-D_FORTIFY_SOURCE=1") endif() # Remove --sort-common from linker flags, as this seems to cause bugs (see #2641, #3374). @@ -293,7 +289,7 @@ if(HAS_DIAG_COLOR_FLAG) add_definitions(-fdiagnostics-color=auto) endif() -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") +if(CMAKE_C_COMPILER_ID STREQUAL "GNU") # 1. Array-bounds testing is broken in some GCC versions before 4.8.5. # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56273 # 2. But _Pragma("...ignored") is broken (unresolved) in GCC 5+: @@ -326,10 +322,14 @@ option(LOG_LIST_ACTIONS "Add list actions logging" OFF) add_definitions(-DINCLUDE_GENERATED_DECLARATIONS) -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") - set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined") +if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") + set(NO_UNDEFINED "-Wl,--no-undefined -lsocket") + elseif(NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(NO_UNDEFINED "-Wl,--no-undefined") + endif() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${NO_UNDEFINED}") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${NO_UNDEFINED}") # For O_CLOEXEC, O_DIRECTORY, and O_NOFOLLOW flags on older systems # (pre POSIX.1-2008: glibc 2.11 and earlier). #4042 @@ -337,10 +337,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") add_definitions(-D_GNU_SOURCE) endif() -if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_SYSTEM_NAME STREQUAL "SunOS") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined -lsocket") -endif() - if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SIZEOF_VOID_P EQUAL 8) # Required for luajit. set(CMAKE_EXE_LINKER_FLAGS @@ -386,7 +382,7 @@ main(void) } " MSGPACK_HAS_FLOAT32) if(MSGPACK_HAS_FLOAT32) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNVIM_MSGPACK_HAS_FLOAT32") + add_definitions(-DNVIM_MSGPACK_HAS_FLOAT32) endif() option(FEAT_TUI "Enable the Terminal UI" ON) @@ -407,7 +403,7 @@ if(FEAT_TUI) } " UNIBI_HAS_VAR_FROM) if(UNIBI_HAS_VAR_FROM) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNVIM_UNIBI_HAS_VAR_FROM") + add_definitions(-DNVIM_UNIBI_HAS_VAR_FROM) endif() find_package(LibTermkey REQUIRED) @@ -604,31 +600,17 @@ if(BUSTED_PRG) message(WARNING "disabling unit tests: no Luajit FFI in ${LUA_PRG}") endif() - if(${CMAKE_VERSION} VERSION_LESS 2.8.12) - if(CMAKE_GENERATOR MATCHES "Visual Studio") - set(TEST_LIBNVIM_PATH ${CMAKE_BINARY_DIR}/lib/nvim-test.dll) - else() - get_target_property(TEST_LIBNVIM_PATH nvim-test LOCATION) - endif() - configure_file( - ${CMAKE_SOURCE_DIR}/test/config/paths.lua.in - ${CMAKE_BINARY_DIR}/test/config/paths.lua) + if(LUA_HAS_FFI) + set(TEST_LIBNVIM_PATH $<TARGET_FILE:nvim-test>) else() - # To avoid duplicating paths.lua.in while we still support CMake < 2.8.12, - # use configure_file() to add the generator expression and then generate - # the final file - if(LUA_HAS_FFI) - set(TEST_LIBNVIM_PATH $<TARGET_FILE:nvim-test>) - else() - set(TEST_LIBNVIM_PATH "") - endif() - configure_file( - ${CMAKE_SOURCE_DIR}/test/config/paths.lua.in - ${CMAKE_BINARY_DIR}/test/config/paths.lua.gen) - file(GENERATE - OUTPUT ${CMAKE_BINARY_DIR}/test/config/paths.lua - INPUT ${CMAKE_BINARY_DIR}/test/config/paths.lua.gen) + set(TEST_LIBNVIM_PATH "") endif() + configure_file( + ${CMAKE_SOURCE_DIR}/test/config/paths.lua.in + ${CMAKE_BINARY_DIR}/test/config/paths.lua.gen) + file(GENERATE + OUTPUT ${CMAKE_BINARY_DIR}/test/config/paths.lua + INPUT ${CMAKE_BINARY_DIR}/test/config/paths.lua.gen) add_custom_target(functionaltest COMMAND ${CMAKE_COMMAND} diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 0ae7c231af..70e4ca2eec 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -21,17 +21,13 @@ add_custom_command(OUTPUT ${GENERATED_SYN_VIM} ${FUNCS_DATA} ) -if(POLICY CMP0054) - cmake_policy(SET CMP0054 OLD) -endif() - file(GLOB PACKAGES ${PROJECT_SOURCE_DIR}/runtime/pack/dist/opt/*) set(GENERATED_PACKAGE_TAGS) foreach(PACKAGE ${PACKAGES}) get_filename_component(PACKNAME ${PACKAGE} NAME) file(GLOB "${PACKNAME}_DOC_FILES" ${PACKAGE}/doc/*.txt) - if("${PACKNAME}_DOC_FILES") + if(${PACKNAME}_DOC_FILES) file(MAKE_DIRECTORY ${GENERATED_PACKAGE_DIR}/${PACKNAME}) add_custom_target("${PACKNAME}-tags" COMMAND ${CMAKE_COMMAND} -E copy_directory diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 197bc1d2d7..5738ea1446 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -5182,8 +5182,10 @@ line({expr}) The result is a Number, which is the line number of the file $ the last line in the current buffer 'x position of mark x (if the mark is not set, 0 is returned) - w0 first line visible in current window - w$ last line visible in current window + w0 first line visible in current window (one if the + display isn't updated, e.g. in silent Ex mode) + w$ last line visible in current window (this is one + less than "w0" if no lines are visible) v In Visual mode: the start of the Visual area (the cursor is the end). When not in Visual mode returns the cursor position. Differs from |'<| in diff --git a/scripts/vim-patch.sh b/scripts/vim-patch.sh index 5182756d83..95293f9572 100755 --- a/scripts/vim-patch.sh +++ b/scripts/vim-patch.sh @@ -37,11 +37,11 @@ usage() { } msg_ok() { - printf "\e[32m✔\e[0m $@\n" + printf '\e[32m✔\e[0m %s\n' "$@" } msg_err() { - printf "\e[31m✘\e[0m $@\n" + printf '\e[31m✘\e[0m %s\n' "$@" } # Checks if a program is in the user's PATH, and is executable. @@ -218,7 +218,7 @@ stage_patch() { msg_ok "Current branch '${checked_out_branch}' seems to be a vim-patch" echo " branch; not creating a new branch." else - printf "\nFetching '${git_remote}/master'.\n" + printf '\nFetching "%s/master".\n' "${git_remote}" output="$(git fetch "${git_remote}" master 2>&1)" && msg_ok "${output}" || (msg_err "${output}"; false) @@ -248,21 +248,22 @@ stage_patch() { fi printf "\nInstructions:\n Proceed to port the patch.\n" else - printf "\nInstructions:\n Proceed to port the patch.\n Try the 'patch' command (or use '${BASENAME} -P ...' next time):\n patch -p1 < ${patch_file}\n" + printf '\nInstructions:\n Proceed to port the patch.\n Try the "patch" command (or use "%s -P ..." next time):\n patch -p1 < %s\n' "${BASENAME}" "${patch_file}" fi - printf " - Stage your changes ('git add ...'), then use 'git commit --amend' to commit. + printf ' + Stage your changes ("git add ..."), then use "git commit --amend" to commit. - To port more patches (if any) related to ${vim_version}, - run '${BASENAME}' again. + To port more patches (if any) related to %s, + run "%s" again. * Do this only for _related_ patches (otherwise it increases the size of the pull request, making it harder to review) - When you're done, try '${BASENAME} -s' to create the pull request. + When you are done, try "%s -s" to create the pull request. See the wiki for more information: - * https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-vim\n" + * https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-vim +' "${vim_version}" "${BASENAME}" "${BASENAME}" } hub_pr() { @@ -398,24 +399,24 @@ show_vimpatches() { list_missing_vimpatches | while read vim_commit; do if (cd "${VIM_SOURCE_DIR}" && git --no-pager show --color=never --name-only "v${vim_commit}" 2>/dev/null) | grep -q ^runtime; then - printf " • ${vim_commit} (+runtime)\n" + printf ' • %s (+runtime)\n' "${vim_commit}" else - printf " • ${vim_commit}\n" + printf ' • %s\n' "${vim_commit}" fi done - echo - echo "Instructions:" - echo - echo " To port one of the above patches to Neovim, execute" - echo " this script with the patch revision as argument and" - echo " follow the instructions." - echo - echo " Examples: '${BASENAME} -p 7.4.487'" - echo " '${BASENAME} -p 1e8ebf870720e7b671f98f22d653009826304c4f'" - echo - echo " NOTE: Please port the _oldest_ patch if you possibly can." - echo " Out-of-order patches increase the possibility of bugs." + printf "Instructions: + + To port one of the above patches to Neovim, execute + this script with the patch revision as argument and + follow the instructions. + + Examples: '%s -p 7.4.487' + '%s -p 1e8ebf870720e7b671f98f22d653009826304c4f' + + NOTE: Please port the _oldest_ patch if you possibly can. + Out-of-order patches increase the possibility of bugs. +" "${BASENAME}" "${BASENAME}" } review_commit() { @@ -436,7 +437,7 @@ review_commit() { echo " This script assumes that the PR contains only commits" echo " with 'vim-patch:XXX' in their title." echo - printf -- "$(head -n 4 <<< "${nvim_patch}")\n\n" + printf -- '%s\n\n' "$(head -n 4 <<< "${nvim_patch}")" local reply read -p "Continue reviewing (y/N)? " -n 1 -r reply if [[ "${reply}" == y ]]; then diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 2e44f2a030..15eb824d38 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -394,12 +394,6 @@ endif() set(NVIM_EXEC_LINK_LIBRARIES ${NVIM_LINK_LIBRARIES} ${LUA_PREFERRED_LIBRARIES}) -if(CMAKE_VERSION VERSION_LESS "2.8.8") - # Use include_directories() because INCLUDE_DIRECTORIES target property - # is not supported - include_directories(${LUA_PREFERRED_INCLUDE_DIRS}) -endif() - # Don't use jemalloc in the unit test library. if(JEMALLOC_FOUND) list(APPEND NVIM_EXEC_LINK_LIBRARIES ${JEMALLOC_LIBRARIES}) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d8d785395c..5505f5f102 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -17838,11 +17838,14 @@ pos_T *var2fpos(const typval_T *const tv, const int dollar_lnum, pos.col = 0; if (name[1] == '0') { /* "w0": first visible line */ update_topline(); - pos.lnum = curwin->w_topline; + // In silent Ex mode topline is zero, but that's not a valid line + // number; use one instead. + pos.lnum = curwin->w_topline > 0 ? curwin->w_topline : 1; return &pos; } else if (name[1] == '$') { /* "w$": last visible line */ validate_botline(); - pos.lnum = curwin->w_botline - 1; + // In silent Ex mode botline is zero, return zero then. + pos.lnum = curwin->w_botline > 0 ? curwin->w_botline - 1 : 0; return &pos; } } else if (name[0] == '$') { /* last column or line */ @@ -19528,6 +19531,13 @@ void ex_execute(exarg_T *eap) } if (ret != FAIL && ga.ga_data != NULL) { + if (eap->cmdidx == CMD_echomsg || eap->cmdidx == CMD_echoerr) { + // Mark the already saved text as finishing the line, so that what + // follows is displayed on a new line when scrolling back at the + // more prompt. + msg_sb_eol(); + } + if (eap->cmdidx == CMD_echomsg) { MSG_ATTR(ga.ga_data, echo_attr); ui_flush(); diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 98eda8dcb8..d58d006dd0 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -1306,10 +1306,10 @@ filterend: * Call a shell to execute a command. * When "cmd" is NULL start an interactive shell. */ -void -do_shell ( +void +do_shell( char_u *cmd, - int flags /* may be SHELL_DOOUT when output is redirected */ + int flags // may be SHELL_DOOUT when output is redirected ) { int save_nwr; @@ -1789,14 +1789,14 @@ theend: * May set eap->forceit if a dialog says it's OK to overwrite. * Return OK if it's OK, FAIL if it is not. */ -int -check_overwrite ( +int +check_overwrite( exarg_T *eap, buf_T *buf, - char_u *fname, /* file name to be used (can differ from - buf->ffname) */ - char_u *ffname, /* full path version of fname */ - int other /* writing under other name */ + char_u *fname, // file name to be used (can differ from + // buf->ffname) + char_u *ffname, // full path version of fname + int other // writing under other name ) { /* @@ -2823,7 +2823,7 @@ void ex_change(exarg_T *eap) void ex_z(exarg_T *eap) { char_u *x; - int bigness; + int64_t bigness; char_u *kind; int minus = 0; linenr_T start, end, curs, i; @@ -2856,10 +2856,17 @@ void ex_z(exarg_T *eap) EMSG(_("E144: non-numeric argument to :z")); return; } - bigness = atoi((char *)x); + bigness = atol((char *)x); + + // bigness could be < 0 if atol(x) overflows. + if (bigness > 2 * curbuf->b_ml.ml_line_count || bigness < 0) { + bigness = 2 * curbuf->b_ml.ml_line_count; + } + p_window = bigness; - if (*kind == '=') + if (*kind == '=') { bigness += 2; + } } /* the number of '-' and '+' multiplies the distance */ @@ -4587,11 +4594,11 @@ char_u *check_help_lang(char_u *arg) * Assumption is made that the matched_string passed has already been found to * match some string for which help is requested. webb. */ -int -help_heuristic ( +int +help_heuristic( char_u *matched_string, - int offset, /* offset for match */ - int wrong_case /* no matching case */ + int offset, // offset for match + int wrong_case // no matching case ) { int num_letters; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 2f41080a41..f0e4883fdd 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -2315,11 +2315,11 @@ doend: * Check for an Ex command with optional tail. * If there is a match advance "pp" to the argument and return TRUE. */ -int -checkforcmd ( - char_u **pp, /* start of command */ - char *cmd, /* name of command */ - int len /* required length */ +int +checkforcmd( + char_u **pp, // start of command + char *cmd, // name of command + int len // required length ) { int i; @@ -4080,6 +4080,7 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp) && eap->cmdidx != CMD_lgrep && eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd + && eap->cmdidx != CMD_hardcopy && !(eap->argt & NOSPC) ) { char_u *l; @@ -4702,9 +4703,9 @@ char_u *check_nextcmd(char_u *p) * return FAIL and give error message if 'message' TRUE * return OK otherwise */ -static int -check_more ( - int message, /* when FALSE check only, no messages */ +static int +check_more( + int message, // when FALSE check only, no messages int forceit ) { @@ -5371,8 +5372,8 @@ static size_t add_cmd_modifier(char_u *buf, char *mod_str, bool *multi_mods) * Returns the length of the replacement, which has been added to "buf". * Returns -1 if there was no match, and only the "<" has been copied. */ -static size_t -uc_check_code ( +static size_t +uc_check_code( char_u *code, size_t len, char_u *buf, @@ -6033,10 +6034,11 @@ static void ex_cquit(exarg_T *eap) static void ex_quit_all(exarg_T *eap) { if (cmdwin_type != 0) { - if (eap->forceit) - cmdwin_result = K_XF1; /* ex_window() takes care of this */ - else + if (eap->forceit) { + cmdwin_result = K_XF1; // open_cmdwin() takes care of this + } else { cmdwin_result = K_XF2; + } return; } @@ -6103,8 +6105,8 @@ static void ex_pclose(exarg_T *eap) * Close window "win" and take care of handling closing the last window for a * modified buffer. */ -static void -ex_win_close ( +static void +ex_win_close( int forceit, win_T *win, tabpage_T *tp /* NULL or the tab page "win" is in */ @@ -6520,8 +6522,8 @@ void alist_set(alist_T *al, int count, char_u **files, int use_curbuf, int *fnum * Add file "fname" to argument list "al". * "fname" must have been allocated and "al" must have been checked for room. */ -void -alist_add ( +void +alist_add( alist_T *al, char_u *fname, int set_fnum /* 1: set buffer number; 2: re-use curbuf */ @@ -6868,8 +6870,8 @@ static void ex_edit(exarg_T *eap) /* * ":edit <file>" command and alikes. */ -void -do_exedit ( +void +do_exedit( exarg_T *eap, win_T *old_curwin /* curwin before doing a split or NULL */ ) @@ -8611,7 +8613,8 @@ eval_vars ( default: // should not happen *errormsg = (char_u *)""; - return NULL; + result = (char_u *)""; // avoid gcc warning + break; } resultlen = STRLEN(result); /* length of new string */ @@ -8758,8 +8761,8 @@ char_u *expand_sfile(char_u *arg) * Write openfile commands for the current buffers to an .exrc file. * Return FAIL on error, OK otherwise. */ -static int -makeopens ( +static int +makeopens( FILE *fd, char_u *dirnow /* Current directory name */ ) @@ -9205,8 +9208,8 @@ static int ses_do_win(win_T *wp) * Write commands to "fd" to restore the view of a window. * Caller must make sure 'scrolloff' is zero. */ -static int -put_view ( +static int +put_view( FILE *fd, win_T *wp, int add_edit, /* add ":edit" command to view */ @@ -9400,8 +9403,8 @@ put_view ( * Write an argument list to the session file. * Returns FAIL if writing fails. */ -static int -ses_arglist ( +static int +ses_arglist( FILE *fd, char *cmd, garray_T *gap, diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 9b1dcfcafb..774007c66e 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -861,7 +861,7 @@ static int command_line_execute(VimState *state, int key) if (s->c == cedit_key || s->c == K_CMDWIN) { if (ex_normal_busy == 0 && got_int == false) { // Open a window to edit the command line (and history). - s->c = ex_window(); + s->c = open_cmdwin(); s->some_key_typed = true; } } else { @@ -1444,7 +1444,7 @@ static int command_line_handle_key(CommandLineState *s) return command_line_not_changed(s); case K_IGNORE: - // Ignore mouse event or ex_window() result. + // Ignore mouse event or open_cmdwin() result. return command_line_not_changed(s); @@ -6001,7 +6001,7 @@ int cmd_gchar(int offset) * Ctrl_C if it is to be abandoned * K_IGNORE if editing continues */ -static int ex_window(void) +static int open_cmdwin(void) { struct cmdline_info save_ccline; bufref_T old_curbuf; @@ -6034,6 +6034,7 @@ static int ex_window(void) block_autocmds(); /* don't use a new tab page */ cmdmod.tab = 0; + cmdmod.noswapfile = 1; /* Create a window for the command-line buffer. */ if (win_split((int)p_cwh, WSP_BOT) == FAIL) { diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 1c0464b575..a77c467fe5 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -835,7 +835,7 @@ static void init_typebuf(void) typebuf.tb_noremap = noremapbuf_init; typebuf.tb_buflen = TYPELEN_INIT; typebuf.tb_len = 0; - typebuf.tb_off = 0; + typebuf.tb_off = MAXMAPLEN + 4; typebuf.tb_change_cnt = 1; } } @@ -879,9 +879,15 @@ int ins_typebuf(char_u *str, int noremap, int offset, int nottyped, bool silent) // Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off] typebuf.tb_off -= addlen; memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen); + } else if (typebuf.tb_len == 0 + && typebuf.tb_buflen >= addlen + 3 * (MAXMAPLEN + 4)) { + // Buffer is empty and string fits in the existing buffer. + // Leave some space before and after, if possible. + typebuf.tb_off = (typebuf.tb_buflen - addlen - 3 * (MAXMAPLEN + 4)) / 2; + memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen); } else { // Need to allocate a new buffer. - // In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4 + // In typebuf.tb_buf there must always be room for 3 * (MAXMAPLEN + 4) // characters. We add some extra room to avoid having to allocate too // often. newoff = MAXMAPLEN + 4; @@ -1145,7 +1151,7 @@ void alloc_typebuf(void) typebuf.tb_buf = xmalloc(TYPELEN_INIT); typebuf.tb_noremap = xmalloc(TYPELEN_INIT); typebuf.tb_buflen = TYPELEN_INIT; - typebuf.tb_off = 0; + typebuf.tb_off = MAXMAPLEN + 4; // can insert without realloc typebuf.tb_len = 0; typebuf.tb_maplen = 0; typebuf.tb_silent = 0; diff --git a/src/nvim/main.c b/src/nvim/main.c index ea43b93b30..6aed84aba5 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1410,6 +1410,12 @@ static void read_stdin(void) int save_msg_didany = msg_didany; set_buflisted(true); (void)open_buffer(true, NULL, 0); // create memfile and read file + if (BUFEMPTY() && curbuf->b_next != NULL) { + // stdin was empty, go to buffer 2 (e.g. "echo file1 | xargs nvim"). #8561 + do_cmdline_cmd("silent! bnext"); + // Delete the empty stdin buffer. + do_cmdline_cmd("bwipeout 1"); + } no_wait_return = false; msg_didany = save_msg_didany; TIME_MSG("reading stdin"); diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index a8781ffbb8..ea538fb4fc 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -1328,7 +1328,7 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1, #endif /// Reassigns `strw` to a new, allocated pointer to a UTF16 string. -int utf8_to_utf16(const char *str, WCHAR **strw) +int utf8_to_utf16(const char *str, wchar_t **strw) FUNC_ATTR_NONNULL_ALL { ssize_t wchar_len = 0; @@ -1344,7 +1344,7 @@ int utf8_to_utf16(const char *str, WCHAR **strw) return GetLastError(); } - ssize_t buf_sz = wchar_len * sizeof(WCHAR); + ssize_t buf_sz = wchar_len * sizeof(wchar_t); if (buf_sz == 0) { *strw = NULL; @@ -1358,19 +1358,19 @@ int utf8_to_utf16(const char *str, WCHAR **strw) 0, str, -1, - (WCHAR *)pos, + (wchar_t *)pos, wchar_len); assert(r == wchar_len); if (r != wchar_len) { EMSG2("MultiByteToWideChar failed: %d", r); } - *strw = (WCHAR *)pos; + *strw = (wchar_t *)pos; return 0; } /// Reassigns `str` to a new, allocated pointer to a UTF8 string. -int utf16_to_utf8(const WCHAR *strw, char **str) +int utf16_to_utf8(const wchar_t *strw, char **str) FUNC_ATTR_NONNULL_ALL { // Compute the space required to store the string as UTF-8. @@ -2201,7 +2201,7 @@ HINSTANCE vimLoadLib(char *name) // NOTE: Do not use mch_dirname() and mch_chdir() here, they may call // vimLoadLib() recursively, which causes a stack overflow. - WCHAR old_dirw[MAXPATHL]; + wchar_t old_dirw[MAXPATHL]; // Path to exe dir. char *buf = xstrdup((char *)get_vim_var_str(VV_PROGPATH)); diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h index dd8e44b3f9..99aadcacad 100644 --- a/src/nvim/mbyte.h +++ b/src/nvim/mbyte.h @@ -7,8 +7,8 @@ #include "nvim/iconv.h" #include "nvim/func_attr.h" -#include "nvim/os/os_defs.h" // For WCHAR, indirect -#include "nvim/types.h" // for char_u +#include "nvim/os/os_defs.h" // For indirect +#include "nvim/types.h" // for char_u /* * Return byte length of character that starts with byte "b". diff --git a/src/nvim/normal.c b/src/nvim/normal.c index b959ea08f3..a649777ddd 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -3769,14 +3769,17 @@ find_decl ( t = false; /* match after start is failure too */ if (thisblock && t != false) { - pos_T *pos; - - /* Check that the block the match is in doesn't end before the - * position where we started the search from. */ - if ((pos = findmatchlimit(NULL, '}', FM_FORWARD, - (int)(old_pos.lnum - curwin->w_cursor.lnum + 1))) != NULL - && pos->lnum < old_pos.lnum) + const int64_t maxtravel = old_pos.lnum - curwin->w_cursor.lnum + 1; + const pos_T *pos = findmatchlimit(NULL, '}', FM_FORWARD, maxtravel); + + // Check that the block the match is in doesn't end before the + // position where we started the search from. + if (pos != NULL && pos->lnum < old_pos.lnum) { + // There can't be a useful match before the end of this block. + // Skip to the end + curwin->w_cursor = *pos; continue; + } } if (t == false) { @@ -6895,7 +6898,7 @@ static void nv_g_cmd(cmdarg_T *cap) else show_utf8(); break; - + // "g<": show scrollback text case '<': show_sb_text(); break; diff --git a/src/nvim/option.c b/src/nvim/option.c index 0851e6cc5f..68b0a525f1 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -5811,7 +5811,7 @@ void buf_copy_options(buf_T *buf, int flags) buf->b_p_ml = p_ml; buf->b_p_ml_nobin = p_ml_nobin; buf->b_p_inf = p_inf; - buf->b_p_swf = p_swf; + buf->b_p_swf = cmdmod.noswapfile ? false : p_swf; buf->b_p_cpt = vim_strsave(p_cpt); buf->b_p_cfu = vim_strsave(p_cfu); buf->b_p_ofu = vim_strsave(p_ofu); diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 25c4cc4f92..0df857352b 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -56,7 +56,7 @@ int os_setenv(const char *name, const char *value, int overwrite) char *envbuf = xmalloc(envbuflen); snprintf(envbuf, envbuflen, "%s=%s", name, value); - WCHAR *p; + wchar_t *p; utf8_to_utf16(envbuf, &p); xfree(envbuf); if (p == NULL) { @@ -146,7 +146,7 @@ void os_get_hostname(char *hostname, size_t size) xstrlcpy(hostname, vutsname.nodename, size); } #elif defined(WIN32) - WCHAR host_utf16[MAX_COMPUTERNAME_LENGTH + 1]; + wchar_t host_utf16[MAX_COMPUTERNAME_LENGTH + 1]; DWORD host_wsize = sizeof(host_utf16) / sizeof(host_utf16[0]); if (GetComputerNameW(host_utf16, &host_wsize) == 0) { *hostname = '\0'; diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 5412c5daae..cf00fd4f82 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -1052,7 +1052,7 @@ char *os_resolve_shortcut(const char *fname) hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW, (void **)&pslw); if (hr == S_OK) { - WCHAR *p; + wchar_t *p; const int conversion_result = utf8_to_utf16(fname, &p); if (conversion_result != 0) { EMSG2("utf8_to_utf16 failed: %d", conversion_result); @@ -1080,7 +1080,7 @@ char *os_resolve_shortcut(const char *fname) # endif // Get the path to the link target. - ZeroMemory(wsz, MAX_PATH * sizeof(WCHAR)); + ZeroMemory(wsz, MAX_PATH * sizeof(wchar_t)); hr = pslw->lpVtbl->GetPath(pslw, wsz, MAX_PATH, &ffdw, 0); if (hr == S_OK && wsz[0] != NUL) { const int conversion_result = utf16_to_utf8(wsz, &rfname); diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim index c4b4a43ad4..71f3ad1bc0 100644 --- a/src/nvim/testdir/test_alot.vim +++ b/src/nvim/testdir/test_alot.vim @@ -5,6 +5,7 @@ source test_assign.vim source test_changedtick.vim source test_cursor_func.vim source test_ex_undo.vim +source test_ex_z.vim source test_execute_func.vim source test_expr.vim source test_feedkeys.vim @@ -19,8 +20,8 @@ source test_jumps.vim source test_fileformat.vim source test_filetype.vim source test_lambda.vim -source test_menu.vim source test_mapping.vim +source test_menu.vim source test_messages.vim source test_partial.vim source test_popup.vim diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index a998bd90f1..5a43838218 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -430,4 +430,14 @@ func Test_getcmdtype() cunmap <F6> endfunc +func Test_verbosefile() + set verbosefile=Xlog + echomsg 'foo' + echomsg 'bar' + set verbosefile= + let log = readfile('Xlog') + call assert_match("foo\nbar", join(log, "\n")) + call delete('Xlog') +endfunc + set cpo& diff --git a/src/nvim/testdir/test_ex_z.vim b/src/nvim/testdir/test_ex_z.vim new file mode 100644 index 0000000000..608a36c490 --- /dev/null +++ b/src/nvim/testdir/test_ex_z.vim @@ -0,0 +1,78 @@ +" Test :z + +func Test_z() + call setline(1, range(1, 100)) + + let a = execute('20z3') + call assert_equal("\n20\n21\n22", a) + call assert_equal(22, line('.')) + " 'window' should be set to the {count} value. + call assert_equal(3, &window) + + " If there is only one window, then twice the amount of 'scroll' is used. + set scroll=2 + let a = execute('20z') + call assert_equal("\n20\n21\n22\n23", a) + call assert_equal(23, line('.')) + + let a = execute('20z+3') + " FIXME: I would expect the same result as '20z3' but it + " gives "\n21\n22\n23" instead. Bug in Vim or in ":help :z"? + "call assert_equal("\n20\n21\n22", a) + "call assert_equal(22, line('.')) + + let a = execute('20z-3') + call assert_equal("\n18\n19\n20", a) + call assert_equal(20, line('.')) + + let a = execute('20z=3') + call assert_match("^\n18\n19\n-\\+\n20\n-\\+\n21\n22$", a) + call assert_equal(20, line('.')) + + let a = execute('20z^3') + call assert_equal("\n14\n15\n16\n17", a) + call assert_equal(17, line('.')) + + let a = execute('20z.3') + call assert_equal("\n19\n20\n21", a) + call assert_equal(21, line('.')) + + let a = execute('20z#3') + call assert_equal("\n 20 20\n 21 21\n 22 22", a) + call assert_equal(22, line('.')) + + let a = execute('20z#-3') + call assert_equal("\n 18 18\n 19 19\n 20 20", a) + call assert_equal(20, line('.')) + + let a = execute('20z#=3') + call assert_match("^\n 18 18\n 19 19\n-\\+\n 20 20\n-\\+\n 21 21\n 22 22$", a) + call assert_equal(20, line('.')) + + " Test with {count} bigger than the number of lines in buffer. + let a = execute('20z1000') + call assert_match("^\n20\n21\n.*\n99\n100$", a) + call assert_equal(100, line('.')) + + let a = execute('20z-1000') + call assert_match("^\n1\n2\n.*\n19\n20$", a) + call assert_equal(20, line('.')) + + let a = execute('20z=1000') + call assert_match("^\n1\n.*\n-\\+\n20\n-\\\+\n.*\n100$", a) + call assert_equal(20, line('.')) + + call assert_fails('20z=a', 'E144:') + + set window& scroll& + bw! +endfunc + +func Test_z_bug() + " This used to access invalid memory as a result of an integer overflow + " and freeze vim. + normal ox + normal Heat + z777777776666666 + ') +endfunc diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index 8847653498..3028f72fec 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -373,15 +373,18 @@ endfunc " Tests for the mode() function let current_modes = '' -func! Save_mode() +func Save_mode() let g:current_modes = mode(0) . '-' . mode(1) return '' endfunc -func! Test_mode() +func Test_mode() new call append(0, ["Blue Ball Black", "Brown Band Bowl", ""]) + " Only complete from the current buffer. + set complete=. + inoremap <F2> <C-R>=Save_mode()<CR> normal! 3G @@ -490,6 +493,7 @@ func! Test_mode() bwipe! iunmap <F2> + set complete& endfunc func Test_getbufvar() diff --git a/src/nvim/testdir/test_goto.vim b/src/nvim/testdir/test_goto.vim index 2573401707..ea67fe7386 100644 --- a/src/nvim/testdir/test_goto.vim +++ b/src/nvim/testdir/test_goto.vim @@ -288,3 +288,24 @@ func Test_cursorline_keep_col() set nocursorline endfunc +func Test_gd_local_block() + let lines = [ + \ ' int main()', + \ '{', + \ ' char *a = "NOT NULL";', + \ ' if(a)', + \ ' {', + \ ' char *b = a;', + \ ' printf("%s\n", b);', + \ ' }', + \ ' else', + \ ' {', + \ ' char *b = "NULL";', + \ ' return b;', + \ ' }', + \ '', + \ ' return 0;', + \ '}', + \ ] + call XTest_goto_decl('1gd', lines, 11, 11) +endfunc diff --git a/src/nvim/testdir/test_hardcopy.vim b/src/nvim/testdir/test_hardcopy.vim index 7aea704e86..f630556bef 100644 --- a/src/nvim/testdir/test_hardcopy.vim +++ b/src/nvim/testdir/test_hardcopy.vim @@ -61,3 +61,14 @@ func Test_with_syntax() set printoptions& endif endfunc + +func Test_fname_with_spaces() + if has('postscript') + split t\ e\ s\ t.txt + call setline(1, ['just', 'some', 'text']) + hardcopy > %.ps + call assert_true(filereadable('t e s t.txt.ps')) + call delete('t e s t.txt.ps') + bwipe! + endif +endfunc diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 27ac084ef0..c638920dd3 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -847,7 +847,7 @@ func! Test_normal18_z_fold() norm! j call assert_equal('52', getline('.')) - " zA on a opened fold when foldenale is not set + " zA on a opened fold when foldenable is not set 50 set nofoldenable norm! zA @@ -909,7 +909,7 @@ func! Test_normal18_z_fold() norm! j call assert_equal('55', getline('.')) - " 2) do not close fold under curser + " 2) do not close fold under cursor 51 set nofoldenable norm! zx @@ -1829,18 +1829,60 @@ fun! Test_normal34_g_cmd3() if !has("multi_byte") return endif + " Test for g8 new - call append(0, 'abcdefghijklmnopqrstuvwxyzäüö') - let a=execute(':norm! 1gg$g8') - call assert_equal('c3 b6 ', a[1:]) + let a=execute(':norm! 1G0g8') + call assert_equal("\nNUL", a) + + call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö') + let a=execute(':norm! 1G$g8') + call assert_equal("\nc3 b6 ", a) + + call setline(1, "a\u0302") + let a=execute(':norm! 1G0g8') + call assert_equal("\n61 + cc 82 ", a) - " Test for gp gP - call append(1, range(1,10)) " clean up bw! endfunc +func Test_normal_8g8() + if !has("multi_byte") + return + endif + new + + " Test 8g8 which finds invalid utf8 at or after the cursor. + + " With invalid byte. + call setline(1, "___\xff___") + norm! 1G08g8g + call assert_equal([0, 1, 4, 0, 1], getcurpos()) + + " With invalid byte before the cursor. + call setline(1, "___\xff___") + norm! 1G$h8g8g + call assert_equal([0, 1, 6, 0, 9], getcurpos()) + + " With truncated sequence. + call setline(1, "___\xE2\x82___") + norm! 1G08g8g + call assert_equal([0, 1, 4, 0, 1], getcurpos()) + + " With overlong sequence. + call setline(1, "___\xF0\x82\x82\xAC___") + norm! 1G08g8g + call assert_equal([0, 1, 4, 0, 1], getcurpos()) + + " With valid utf8. + call setline(1, "café") + norm! 1G08g8 + call assert_equal([0, 1, 1, 0, 1], getcurpos()) + + bw! +endfunc + fun! Test_normal35_g_cmd4() " Test for g< " Cannot capture its output, diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index ae5e2b4115..2a67453bce 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -122,6 +122,18 @@ describe('startup', function() { 'ohyeah', '' })) end) + it('if stdin is empty: selects buffer 2, deletes buffer 1 #8561', function() + eq('\r\n 2 %a "file1" line 0\r\n 3 "file2" line 0', + funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '--headless', + '+ls!', + '+qall!', + '-', + 'file1', + 'file2', + }, + { '' })) + end) + it('-e/-E interactive #7679', function() clear('-e') local screen = Screen.new(25, 3) diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt index 8aae8ea9e4..cf49a67f60 100644 --- a/third-party/CMakeLists.txt +++ b/third-party/CMakeLists.txt @@ -1,5 +1,5 @@ # This is not meant to be included by the top-level. -cmake_minimum_required (VERSION 2.8.7) +cmake_minimum_required (VERSION 2.8.12) project(NVIM_DEPS) # Needed for: check_c_compiler_flag() diff --git a/third-party/cmake/GettextCMakeLists.txt b/third-party/cmake/GettextCMakeLists.txt index 67ec0d113f..5a6253df3b 100644 --- a/third-party/cmake/GettextCMakeLists.txt +++ b/third-party/cmake/GettextCMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.7) +cmake_minimum_required(VERSION 2.8.12) project(gettext C) # Adds PREFIX to each item in LIST diff --git a/third-party/cmake/GperfCMakeLists.txt b/third-party/cmake/GperfCMakeLists.txt index 32837fc166..15ae305ba8 100644 --- a/third-party/cmake/GperfCMakeLists.txt +++ b/third-party/cmake/GperfCMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.7) +cmake_minimum_required(VERSION 2.8.12) project(gperf LANGUAGES C CXX) add_executable(gperf diff --git a/third-party/cmake/LibiconvCMakeLists.txt b/third-party/cmake/LibiconvCMakeLists.txt index d14b8529d4..8ad3cc9352 100644 --- a/third-party/cmake/LibiconvCMakeLists.txt +++ b/third-party/cmake/LibiconvCMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.7) +cmake_minimum_required(VERSION 2.8.12) project(libiconv C) include_directories( diff --git a/third-party/cmake/LibuvCMakeLists.txt b/third-party/cmake/LibuvCMakeLists.txt index 8b51a101c6..c9b7c56e7b 100644 --- a/third-party/cmake/LibuvCMakeLists.txt +++ b/third-party/cmake/LibuvCMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.7) +cmake_minimum_required(VERSION 2.8.12) project(libuv LANGUAGES C) file(GLOB UV_SOURCES_COMMON src/*.c) diff --git a/third-party/cmake/Libvterm-tbl2inc_c.cmake b/third-party/cmake/Libvterm-tbl2inc_c.cmake index b1ee0246f1..7a82f4248b 100644 --- a/third-party/cmake/Libvterm-tbl2inc_c.cmake +++ b/third-party/cmake/Libvterm-tbl2inc_c.cmake @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.7) +cmake_minimum_required(VERSION 2.8.12) set(HEX_ALPHABET "0123456789abcdef") diff --git a/third-party/cmake/LibvtermCMakeLists.txt b/third-party/cmake/LibvtermCMakeLists.txt index 27d0d11e9f..dad3ef62c2 100644 --- a/third-party/cmake/LibvtermCMakeLists.txt +++ b/third-party/cmake/LibvtermCMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.11) +cmake_minimum_required(VERSION 2.8.12) project(libvterm LANGUAGES C) include(GNUInstallDirs) diff --git a/third-party/cmake/UnibiliumCMakeLists.txt b/third-party/cmake/UnibiliumCMakeLists.txt index 49bc12c6b7..a96482bcbb 100644 --- a/third-party/cmake/UnibiliumCMakeLists.txt +++ b/third-party/cmake/UnibiliumCMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.7) +cmake_minimum_required(VERSION 2.8.12) project(unibilium LANGUAGES C) file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/*.c) diff --git a/third-party/cmake/libtermkeyCMakeLists.txt b/third-party/cmake/libtermkeyCMakeLists.txt index cb57631c1c..c55da7929a 100644 --- a/third-party/cmake/libtermkeyCMakeLists.txt +++ b/third-party/cmake/libtermkeyCMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.7) +cmake_minimum_required(VERSION 2.8.12) project(libtermkey) add_definitions(-D _CRT_SECURE_NO_WARNINGS) |