diff options
Diffstat (limited to 'src')
29 files changed, 336 insertions, 182 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 59582d0734..cbea6a05c9 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -156,7 +156,7 @@ foreach(sfile ${NEOVIM_SOURCES} ${GENERATED_API_DISPATCH}) get_filename_component(full_d ${sfile} PATH) file(RELATIVE_PATH d "${PROJECT_SOURCE_DIR}/src/nvim" "${full_d}") - if(${d} MATCHES "^[.][.]") + if(${d} MATCHES "^([.][.]|auto/)") file(RELATIVE_PATH d "${GENERATED_DIR}" "${full_d}") endif() get_filename_component(f ${sfile} NAME) diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index fc114bae16..d80ee7dc67 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -368,11 +368,10 @@ static inline void typval_encode_list_start(EncodedData *const edata, const size_t len) FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL { - const Object obj = OBJECT_INIT; kv_push(edata->stack, ARRAY_OBJ(((Array) { .capacity = len, .size = 0, - .items = xmalloc(len * sizeof(*obj.data.array.items)), + .items = xmalloc(len * sizeof(*((Object *)NULL)->data.array.items)), }))); } @@ -409,11 +408,10 @@ static inline void typval_encode_dict_start(EncodedData *const edata, const size_t len) FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL { - const Object obj = OBJECT_INIT; kv_push(edata->stack, DICTIONARY_OBJ(((Dictionary) { .capacity = len, .size = 0, - .items = xmalloc(len * sizeof(*obj.data.dictionary.items)), + .items = xmalloc(len * sizeof(*((Object *)NULL)->data.dictionary.items)), }))); } diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index b42ad1c18a..5fb011885e 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -276,30 +276,25 @@ bool buf_valid(buf_T *buf) return false; } -/* - * Close the link to a buffer. - * "action" is used when there is no longer a window for the buffer. - * It can be: - * 0 buffer becomes hidden - * DOBUF_UNLOAD buffer is unloaded - * DOBUF_DELETE buffer is unloaded and removed from buffer list - * DOBUF_WIPE buffer is unloaded and really deleted - * When doing all but the first one on the current buffer, the caller should - * get a new buffer very soon! - * - * The 'bufhidden' option can force freeing and deleting. - * - * When "abort_if_last" is TRUE then do not close the buffer if autocommands - * cause there to be only one window with this buffer. e.g. when ":quit" is - * supposed to close the window but autocommands close all other windows. - */ -void -close_buffer ( - win_T *win, /* if not NULL, set b_last_cursor */ - buf_T *buf, - int action, - int abort_if_last -) +/// Close the link to a buffer. +/// +/// @param win If not NULL, set b_last_cursor. +/// @param buf +/// @param action Used when there is no longer a window for the buffer. +/// Possible values: +/// 0 buffer becomes hidden +/// DOBUF_UNLOAD buffer is unloaded +/// DOBUF_DELETE buffer is unloaded and removed from buffer list +/// DOBUF_WIPE buffer is unloaded and really deleted +/// When doing all but the first one on the current buffer, the +/// caller should get a new buffer very soon! +/// The 'bufhidden' option can force freeing and deleting. +/// @param abort_if_last +/// If TRUE, do not close the buffer if autocommands cause +/// there to be only one window with this buffer. e.g. when +/// ":quit" is supposed to close the window but autocommands +/// close all other windows. +void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) { bool unload_buf = (action != 0); bool del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE); diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 892748ff5c..51c9fb1556 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1286,10 +1286,9 @@ bool edit(int cmdchar, bool startln, long count) { if (curbuf->terminal) { if (ex_normal_busy) { - // don't enter terminal mode from `ex_normal`, which can result in all - // kinds of havoc(such as terminal mode recursiveness). Instead, set a - // flag that allow us to force-set the value of `restart_edit` before - // `ex_normal` returns + // Do not enter terminal mode from ex_normal(), which would cause havoc + // (such as terminal-mode recursiveness). Instead set a flag to force-set + // the value of `restart_edit` before `ex_normal` returns. restart_edit = 'i'; force_restart_edit = true; } else { diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 0b1fd6670e..dce2f32707 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -405,7 +405,7 @@ typedef struct { LibuvProcess uv; PtyProcess pty; } proc; - Stream in, out, err; + Stream in, out, err; // Initialized in common_job_start(). Terminal *term; bool stopped; bool exited; @@ -6709,7 +6709,6 @@ static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate) # include "funcs.generated.h" #endif - /* * Function given to ExpandGeneric() to obtain the list of internal * or user defined function names. @@ -7712,26 +7711,47 @@ static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = -1; } -/* - * "bufwinnr(nr)" function - */ -static void f_bufwinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void buf_win_common(typval_T *argvars, typval_T *rettv, bool get_nr) { - (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ - ++emsg_off; + int error = false; + (void)get_tv_number_chk(&argvars[0], &error); // issue errmsg if type error + if (error) { // the argument has an invalid type + rettv->vval.v_number = -1; + return; + } + + emsg_off++; + buf_T *buf = get_buf_tv(&argvars[0], true); + if (buf == NULL) { // no need to search if buffer was not found + rettv->vval.v_number = -1; + goto end; + } - buf_T *buf = get_buf_tv(&argvars[0], TRUE); int winnr = 0; + int winid; bool found_buf = false; FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - ++winnr; + winnr++; if (wp->w_buffer == buf) { found_buf = true; + winid = wp->handle; break; } } - rettv->vval.v_number = (found_buf ? winnr : -1); - --emsg_off; + rettv->vval.v_number = (found_buf ? (get_nr ? winnr : winid) : -1); +end: + emsg_off--; +} + +/// "bufwinid(nr)" function +static void f_bufwinid(typval_T *argvars, typval_T *rettv, FunPtr fptr) { + buf_win_common(argvars, rettv, false); +} + +/// "bufwinnr(nr)" function +static void f_bufwinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + buf_win_common(argvars, rettv, true); } /* @@ -9507,24 +9527,35 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) varnumber_T n; int error = FALSE; - /* Position the cursor. Needed after a message that ends in a space. */ - ui_cursor_goto(msg_row, msg_col); - ++no_mapping; ++allow_keys; for (;; ) { - if (argvars[0].v_type == VAR_UNKNOWN) - /* getchar(): blocking wait. */ + // Position the cursor. Needed after a message that ends in a space, + // or if event processing caused a redraw. + ui_cursor_goto(msg_row, msg_col); + + if (argvars[0].v_type == VAR_UNKNOWN) { + // getchar(): blocking wait. + if (!(char_avail() || using_script() || input_available())) { + input_enable_events(); + (void)os_inchar(NULL, 0, -1, 0); + input_disable_events(); + if (!multiqueue_empty(main_loop.events)) { + multiqueue_process_events(main_loop.events); + continue; + } + } n = safe_vgetc(); - else if (get_tv_number_chk(&argvars[0], &error) == 1) - /* getchar(1): only check if char avail */ + } else if (get_tv_number_chk(&argvars[0], &error) == 1) { + // getchar(1): only check if char avail n = vpeekc_any(); - else if (error || vpeekc_any() == NUL) - /* illegal argument or getchar(0) and no char avail: return zero */ + } else if (error || vpeekc_any() == NUL) { + // illegal argument or getchar(0) and no char avail: return zero n = 0; - else - /* getchar(0) and char avail: return char */ + } else { + // getchar(0) and char avail: return char n = safe_vgetc(); + } if (n == K_IGNORE) continue; @@ -9648,13 +9679,23 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr) { char_u *pat; expand_T xpc; + bool filtered = false; int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH | WILD_NO_BEEP; + if (argvars[2].v_type != VAR_UNKNOWN) { + filtered = get_tv_number_chk(&argvars[2], NULL); + } + if (p_wic) { options |= WILD_ICASE; } + // For filtered results, 'wildignore' is used + if (!filtered) { + options |= WILD_KEEP_ALL; + } + ExpandInit(&xpc); xpc.xp_pattern = get_tv_string(&argvars[0]); xpc.xp_pattern_len = STRLEN(xpc.xp_pattern); @@ -9673,6 +9714,16 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr) xpc.xp_pattern_len = STRLEN(xpc.xp_pattern); } + if (xpc.xp_context == EXPAND_CSCOPE) { + set_context_in_cscope_cmd(&xpc, xpc.xp_pattern, CMD_cscope); + xpc.xp_pattern_len = STRLEN(xpc.xp_pattern); + } + + if (xpc.xp_context == EXPAND_SIGN) { + set_context_in_sign_cmd(&xpc, xpc.xp_pattern); + xpc.xp_pattern_len = STRLEN(xpc.xp_pattern); + } + pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context); rettv_list_alloc(rettv); if (pat != NULL) { @@ -10259,7 +10310,11 @@ find_win_by_nr ( } FOR_ALL_WINDOWS_IN_TAB(wp, tp) { - if (--nr <= 0) { + if (nr >= LOWEST_WIN_ID) { + if (wp->handle == nr) { + return wp; + } + } else if (--nr <= 0) { return wp; } } @@ -21739,7 +21794,7 @@ static inline TerminalJobData *common_job_init(char **argv, if (!pty) { proc->err = &data->err; } - proc->cb = on_process_exit; + proc->cb = eval_job_process_exit_cb; proc->events = data->events; proc->detach = detach; proc->cwd = cwd; @@ -21923,7 +21978,7 @@ static void on_job_output(Stream *stream, TerminalJobData *data, RBuffer *buf, rbuffer_consumed(buf, count); } -static void on_process_exit(Process *proc, int status, void *d) +static void eval_job_process_exit_cb(Process *proc, int status, void *d) { TerminalJobData *data = d; if (data->term && !data->exited) { @@ -21947,9 +22002,15 @@ static void on_process_exit(Process *proc, int status, void *d) static void term_write(char *buf, size_t size, void *d) { - TerminalJobData *data = d; + TerminalJobData *job = d; + if (job->in.closed) { + // If the backing stream was closed abruptly, there may be write events + // ahead of the terminal close event. Just ignore the writes. + ILOG("write failed: stream is closed"); + return; + } WBuffer *wbuf = wstream_new_buffer(xmemdup(buf, size), size, 1, xfree); - wstream_write(&data->in, wbuf); + wstream_write(&job->in, wbuf); } static void term_resize(uint16_t width, uint16_t height, void *d) diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 3c371fc264..eaaee81533 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -45,6 +45,7 @@ return { bufloaded={args=1}, bufname={args=1}, bufnr={args={1, 2}}, + bufwinid={args=1}, bufwinnr={args=1}, byte2line={args=1}, byteidx={args=2}, @@ -114,7 +115,7 @@ return { getcmdpos={}, getcmdtype={}, getcmdwintype={}, - getcompletion={args=2}, + getcompletion={args={2, 3}}, getcurpos={}, getcwd={args={0,2}}, getfontname={args={0, 1}}, diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 0226499e78..6205daf0cb 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -2116,6 +2116,14 @@ do_ecmd ( } } + // Re-editing a terminal buffer: skip most buffer re-initialization. + if (!other_file && curbuf->terminal) { + check_arg_idx(curwin); // Needed when called from do_argfile(). + maketitle(); // Title may show the arg index, e.g. "(2 of 5)". + retval = OK; + goto theend; + } + /* * if the file was changed we may not be allowed to abandon it * - if we are going to re-edit the same file diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 45407b7f12..9f83688e1e 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6726,11 +6726,6 @@ do_exedit ( old_curwin == NULL ? curwin : NULL); } else if ((eap->cmdidx != CMD_split && eap->cmdidx != CMD_vsplit) || *eap->arg != NUL) { - // ":edit <blank>" is a no-op in terminal buffers. #2822 - if (curbuf->terminal != NULL && eap->cmdidx == CMD_edit && *eap->arg == NUL) { - return; - } - /* Can't edit another file when "curbuf_lock" is set. Only ":edit" * can bring us here, others are stopped earlier. */ if (*eap->arg != NUL && curbuf_locked()) @@ -7921,9 +7916,8 @@ static void ex_normal(exarg_T *eap) if (force_restart_edit) { force_restart_edit = false; } else { - // some function called was aware of ex_normal and decided to override the - // value of restart_edit anyway. So far only used in terminal mode(see - // terminal_enter() in edit.c) + // Some function (terminal_enter()) was aware of ex_normal and decided to + // override the value of restart_edit anyway. restart_edit = save_restart_edit; } p_im = save_insertmode; diff --git a/src/nvim/ex_eval.h b/src/nvim/ex_eval.h index 30871c7711..f61e01d25b 100644 --- a/src/nvim/ex_eval.h +++ b/src/nvim/ex_eval.h @@ -23,19 +23,19 @@ struct eslist_elem { #define CSTACK_LEN 50 struct condstack { - short cs_flags[CSTACK_LEN]; /* CSF_ flags */ - char cs_pending[CSTACK_LEN]; /* CSTP_: what's pending in ":finally"*/ + int cs_flags[CSTACK_LEN]; // CSF_ flags + char cs_pending[CSTACK_LEN]; // CSTP_: what's pending in ":finally" union { - void *csp_rv[CSTACK_LEN]; /* return typeval for pending return */ - void *csp_ex[CSTACK_LEN]; /* exception for pending throw */ + void *csp_rv[CSTACK_LEN]; // return typeval for pending return + void *csp_ex[CSTACK_LEN]; // exception for pending throw } cs_pend; - void *cs_forinfo[CSTACK_LEN]; /* info used by ":for" */ - int cs_line[CSTACK_LEN]; /* line nr of ":while"/":for" line */ - int cs_idx; /* current entry, or -1 if none */ - int cs_looplevel; /* nr of nested ":while"s and ":for"s */ - int cs_trylevel; /* nr of nested ":try"s */ - eslist_T *cs_emsg_silent_list; /* saved values of "emsg_silent" */ - char cs_lflags; /* loop flags: CSL_ flags */ + void *cs_forinfo[CSTACK_LEN]; // info used by ":for" + int cs_line[CSTACK_LEN]; // line nr of ":while"/":for" line + int cs_idx; // current entry, or -1 if none + int cs_looplevel; // nr of nested ":while"s and ":for"s + int cs_trylevel; // nr of nested ":try"s + eslist_T *cs_emsg_silent_list; // saved values of "emsg_silent" + int cs_lflags; // loop flags: CSL_ flags }; # define cs_rettv cs_pend.csp_rv # define cs_exception cs_pend.csp_ex diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index 7d4bfd0290..6acf7f395a 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -2105,7 +2105,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) props = enc_canon_props(p_encoding); if (!(props & ENC_8BIT) && ((*p_pmcs != NUL) || !(props & ENC_UNICODE))) { p_mbenc_first = NULL; - int effective_cmap; + int effective_cmap = 0; for (cmap = 0; cmap < (int)ARRAY_SIZE(prt_ps_mbfonts); cmap++) if (prt_match_encoding((char *)p_encoding, &prt_ps_mbfonts[cmap], &p_mbenc)) { diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index 3ed85677fc..0b20647771 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -1761,8 +1761,8 @@ static void cs_print_tags_priv(char **matches, char **cntxts, */ static int cs_read_prompt(size_t i) { - char ch; - char *buf = NULL; /* buffer for possible error message from cscope */ + int ch; + char *buf = NULL; // buffer for possible error message from cscope size_t bufpos = 0; char *cs_emsg = _("E609: Cscope error: %s"); size_t cs_emsg_len = strlen(cs_emsg); @@ -1774,35 +1774,34 @@ static int cs_read_prompt(size_t i) size_t maxlen = IOSIZE - cs_emsg_len; for (;; ) { - while ((ch = (char)getc(csinfo[i].fr_fp)) != EOF && ch != CSCOPE_PROMPT[0]) - /* if there is room and char is printable */ + while ((ch = getc(csinfo[i].fr_fp)) != EOF && ch != CSCOPE_PROMPT[0]) { + // if there is room and char is printable if (bufpos < maxlen - 1 && vim_isprintc(ch)) { // lazy buffer allocation if (buf == NULL) { buf = xmalloc(maxlen); } - { - /* append character to the message */ - buf[bufpos++] = ch; - buf[bufpos] = NUL; - if (bufpos >= epromptlen - && strcmp(&buf[bufpos - epromptlen], eprompt) == 0) { - /* remove eprompt from buf */ - buf[bufpos - epromptlen] = NUL; - - /* print message to user */ - (void)EMSG2(cs_emsg, buf); + // append character to the message + buf[bufpos++] = (char)ch; + buf[bufpos] = NUL; + if (bufpos >= epromptlen + && strcmp(&buf[bufpos - epromptlen], eprompt) == 0) { + // remove eprompt from buf + buf[bufpos - epromptlen] = NUL; + + // print message to user + (void)EMSG2(cs_emsg, buf); - /* send RETURN to cscope */ - (void)putc('\n', csinfo[i].to_fp); - (void)fflush(csinfo[i].to_fp); + // send RETURN to cscope + (void)putc('\n', csinfo[i].to_fp); + (void)fflush(csinfo[i].to_fp); - /* clear buf */ - bufpos = 0; - buf[bufpos] = NUL; - } + // clear buf + bufpos = 0; + buf[bufpos] = NUL; } } + } for (size_t n = 0; n < strlen(CSCOPE_PROMPT); ++n) { if (n > 0) diff --git a/src/nvim/main.c b/src/nvim/main.c index 005f4dcc77..eb67483d08 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -270,11 +270,6 @@ int main(int argc, char **argv) setbuf(stdout, NULL); - /* This message comes before term inits, but after setting "silent_mode" - * when the input is not a tty. */ - if (GARGCOUNT > 1 && !silent_mode) - printf(_("%d files to edit\n"), GARGCOUNT); - full_screen = true; check_tty(¶ms); @@ -320,14 +315,18 @@ int main(int argc, char **argv) // open terminals when opening files that start with term:// #define PROTO "term://" + do_cmdline_cmd("augroup nvim_terminal"); + do_cmdline_cmd("autocmd!"); do_cmdline_cmd("autocmd BufReadCmd " PROTO "* nested " - ":call termopen( " + ":if !exists('b:term_title')|call termopen( " // Capture the command string "matchstr(expand(\"<amatch>\"), " "'\\c\\m" PROTO "\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), " // capture the working directory "{'cwd': get(matchlist(expand(\"<amatch>\"), " - "'\\c\\m" PROTO "\\(.\\{-}\\)//'), 1, '')})"); + "'\\c\\m" PROTO "\\(.\\{-}\\)//'), 1, '')})" + "|endif"); + do_cmdline_cmd("augroup END"); #undef PROTO /* Execute --cmd arguments. */ diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index c08b9e8fcf..e6312f9c00 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -1724,7 +1724,7 @@ int utf_class(int c) return 2; } -int utf_ambiguous_width(int c) +bool utf_ambiguous_width(int c) { return c >= 0x80 && (intable(ambiguous, ARRAY_SIZE(ambiguous), c) || intable(emoji_all, ARRAY_SIZE(emoji_all), c)); diff --git a/src/nvim/path.c b/src/nvim/path.c index a79b7139f1..6149e1ab99 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -903,17 +903,30 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern) /* Shorten the filename while maintaining its uniqueness */ path_cutoff = get_path_cutoff(path, &path_ga); - /* we start at the end of the path */ - pathsep_p = path + len - 1; - - while (find_previous_pathsep(path, &pathsep_p)) - if (vim_regexec(®match, pathsep_p + 1, (colnr_T)0) - && is_unique(pathsep_p + 1, gap, i) - && path_cutoff != NULL && pathsep_p + 1 >= path_cutoff) { - sort_again = true; - memmove(path, pathsep_p + 1, STRLEN(pathsep_p)); - break; + // Don't assume all files can be reached without path when search + // pattern starts with **/, so only remove path_cutoff + // when possible. + if (pattern[0] == '*' && pattern[1] == '*' + && vim_ispathsep_nocolon(pattern[2]) + && path_cutoff != NULL + && vim_regexec(®match, path_cutoff, (colnr_T)0) + && is_unique(path_cutoff, gap, i)) { + sort_again = true; + memmove(path, path_cutoff, STRLEN(path_cutoff) + 1); + } else { + // Here all files can be reached without path, so get shortest + // unique path. We start at the end of the path. */ + pathsep_p = path + len - 1; + while (find_previous_pathsep(path, &pathsep_p)) { + if (vim_regexec(®match, pathsep_p + 1, (colnr_T)0) + && is_unique(pathsep_p + 1, gap, i) + && path_cutoff != NULL && pathsep_p + 1 >= path_cutoff) { + sort_again = true; + memmove(path, pathsep_p + 1, STRLEN(pathsep_p)); + break; + } } + } if (path_is_absolute_path(path)) { /* diff --git a/src/nvim/po/eo.po b/src/nvim/po/eo.po index 153eacc7b8..8a3cd50406 100644 --- a/src/nvim/po/eo.po +++ b/src/nvim/po/eo.po @@ -23,8 +23,8 @@ msgid "" msgstr "" "Project-Id-Version: Vim(Esperanto)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-02-13 23:42+0100\n" -"PO-Revision-Date: 2016-02-13 23:45+0100\n" +"POT-Creation-Date: 2016-03-29 23:03+0200\n" +"PO-Revision-Date: 2016-03-29 23:05+0200\n" "Last-Translator: Dominique PELLÉ <dominique.pelle@gmail.com>\n" "Language-Team: \n" "Language: eo\n" @@ -1346,7 +1346,6 @@ msgstr "E670: Miksaĵo de kodoprezento de helpa dosiero en lingvo: %s" msgid "E154: Duplicate tag \"%s\" in file %s/%s" msgstr "E154: Ripetita etikedo \"%s\" en dosiero %s/%s" -#: ../ex_cmds.c:5687 #, c-format msgid "E160: Unknown sign command: %s" msgstr "E160: Nekonata simbola komando: %s" @@ -1482,8 +1481,8 @@ msgstr "Serĉado de \"%s\"" #: ../ex_cmds2.c:2307 #, c-format -msgid "not found in 'runtimepath': \"%s\"" -msgstr "ne trovita en 'runtimepath': \"%s\"" +msgid "not found in '%s': \"%s\"" +msgstr "ne trovita en '%s: \"%s\"" #: ../ex_cmds2.c:2472 #, c-format @@ -6686,6 +6685,12 @@ msgstr "E446: Neniu dosiernomo sub la kursoro" #~ msgid "E232: Cannot create BalloonEval with both message and callback" #~ msgstr "E232: Ne eblas krei BalloonEval kun ambaŭ mesaĝo kaj reagfunkcio" +msgid "Yes" +msgstr "Jes" + +msgid "No" +msgstr "Ne" + # todo '_' is for hotkey, i guess? #~ msgid "Input _Methods" #~ msgstr "Enigaj _metodoj" diff --git a/src/nvim/po/fr.po b/src/nvim/po/fr.po index a16a939117..cd9f5a7eb2 100644 --- a/src/nvim/po/fr.po +++ b/src/nvim/po/fr.po @@ -645,7 +645,7 @@ msgstr "E708: [:] ne peut tre spcifi qu'en dernier" #: ../eval.c:2439 msgid "E709: [:] requires a List value" -msgstr "E709: [:] requiert une Liste" +msgstr "E709: [:] n?cessite une Liste" #: ../eval.c:2674 msgid "E710: List value has more items than target" @@ -1639,8 +1639,8 @@ msgstr "Recherche de \"%s\"" #: ../ex_cmds2.c:2307 #, c-format -msgid "not found in 'runtimepath': \"%s\"" -msgstr "introuvable dans 'runtimepath' : \"%s\"" +msgid "not found in '%s': \"%s\"" +msgstr "introuvable dans '%s' : \"%s\"" #: ../ex_cmds2.c:2472 #, c-format @@ -6877,6 +6877,12 @@ msgstr "E446: Aucun nom de fichier sous le curseur" #~ msgid "E232: Cannot create BalloonEval with both message and callback" #~ msgstr "E232: Impossible de crer un BalloonEval avec message ET callback" +msgid "Yes" +msgstr "Oui" + +msgid "No" +msgstr "Non" + # todo '_' is for hotkey, i guess? #~ msgid "Input _Methods" #~ msgstr "_Mthodes de saisie" diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 8401343d7a..499716a7a8 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -366,10 +366,10 @@ void terminal_resize(Terminal *term, uint16_t width, uint16_t height) void terminal_enter(void) { buf_T *buf = curbuf; + assert(buf->terminal); // Should only be called when curbuf has a terminal. TerminalState state, *s = &state; memset(s, 0, sizeof(TerminalState)); s->term = buf->terminal; - assert(s->term && "should only be called when curbuf has a terminal"); // Ensure the terminal is properly sized. terminal_resize(s->term, 0, 0); diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim index 0a4aa1dc50..7169b6076f 100644 --- a/src/nvim/testdir/test_alot.vim +++ b/src/nvim/testdir/test_alot.vim @@ -3,6 +3,7 @@ source test_assign.vim source test_cursor_func.vim +source test_ex_undo.vim source test_feedkeys.vim source test_cmdline.vim source test_menu.vim diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index 902ec1c05d..21bb057fe1 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -89,6 +89,10 @@ func Test_getcompletion() call assert_true(index(l, 'runtest.vim') >= 0) let l = getcompletion('walk', 'file') call assert_equal([], l) + set wildignore=*.vim + let l = getcompletion('run', 'file', 1) + call assert_true(index(l, 'runtest.vim') < 0) + set wildignore& let l = getcompletion('ha', 'filetype') call assert_true(index(l, 'hamster') >= 0) @@ -121,12 +125,35 @@ func Test_getcompletion() let l = getcompletion('dark', 'highlight') call assert_equal([], l) + if has('cscope') + let l = getcompletion('', 'cscope') + let cmds = ['add', 'find', 'help', 'kill', 'reset', 'show'] + call assert_equal(cmds, l) + " using cmdline completion must not change the result + call feedkeys(":cscope find \<c-d>\<c-c>", 'xt') + let l = getcompletion('', 'cscope') + call assert_equal(cmds, l) + let keys = ['a', 'c', 'd', 'e', 'f', 'g', 'i', 's', 't'] + let l = getcompletion('find ', 'cscope') + call assert_equal(keys, l) + endif + + if has('signs') + sign define Testing linehl=Comment + let l = getcompletion('', 'sign') + let cmds = ['define', 'jump', 'list', 'place', 'undefine', 'unplace'] + call assert_equal(cmds, l) + " using cmdline completion must not change the result + call feedkeys(":sign list \<c-d>\<c-c>", 'xt') + let l = getcompletion('', 'sign') + call assert_equal(cmds, l) + let l = getcompletion('list ', 'sign') + call assert_equal(['Testing'], l) + endif + " For others test if the name is recognized. let names = ['buffer', 'environment', 'file_in_path', \ 'mapping', 'shellcmd', 'tag', 'tag_listfiles', 'user'] - if has('cscope') - call add(names, 'cscope') - endif if has('cmdline_hist') call add(names, 'history') endif @@ -136,9 +163,6 @@ func Test_getcompletion() if has('profile') call add(names, 'syntime') endif - if has('signs') - call add(names, 'sign') - endif set tags=Xtags call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", "word\tfile\tcmd"], 'Xtags') @@ -152,3 +176,11 @@ func Test_getcompletion() call assert_fails('call getcompletion("", "burp")', 'E475:') endfunc + +func Test_expand_star_star() + call mkdir('a/b', 'p') + call writefile(['asdfasdf'], 'a/b/fileXname') + call feedkeys(":find **/fileXname\<Tab>\<CR>", 'xt') + call assert_equal('find a/b/fileXname', getreg(':')) + call delete('a', 'rf') +endfunc diff --git a/src/nvim/testdir/test_ex_undo.vim b/src/nvim/testdir/test_ex_undo.vim new file mode 100644 index 0000000000..44feb3680a --- /dev/null +++ b/src/nvim/testdir/test_ex_undo.vim @@ -0,0 +1,19 @@ +" Tests for :undo + +func Test_ex_undo() + new ex-undo + setlocal ul=10 + exe "normal ione\n\<Esc>" + setlocal ul=10 + exe "normal itwo\n\<Esc>" + setlocal ul=10 + exe "normal ithree\n\<Esc>" + call assert_equal(4, line('$')) + undo + call assert_equal(3, line('$')) + undo 1 + call assert_equal(2, line('$')) + undo 0 + call assert_equal(1, line('$')) + quit! +endfunc diff --git a/src/nvim/testdir/test_syn_attr.vim b/src/nvim/testdir/test_syn_attr.vim index 809442eb94..94d6b8735f 100644 --- a/src/nvim/testdir/test_syn_attr.vim +++ b/src/nvim/testdir/test_syn_attr.vim @@ -16,9 +16,13 @@ func Test_missing_attr() call assert_equal('', synIDattr(hlID("Mine"), "undercurl", 'gui')) if has('gui') - hi Mine guifg=blue guibg=red font=something + let fontname = getfontname() + if fontname == '' + let fontname = 'something' + endif + exe 'hi Mine guifg=blue guibg=red font=' . escape(fontname, ' \') call assert_equal('blue', synIDattr(hlID("Mine"), "fg", 'gui')) call assert_equal('red', synIDattr(hlID("Mine"), "bg", 'gui')) - call assert_equal('something', synIDattr(hlID("Mine"), "font", 'gui')) + call assert_equal(fontname, synIDattr(hlID("Mine"), "font", 'gui')) endif endfunc diff --git a/src/nvim/testdir/test_window_id.vim b/src/nvim/testdir/test_window_id.vim index fa3ebd757e..66656e1d0a 100644 --- a/src/nvim/testdir/test_window_id.vim +++ b/src/nvim/testdir/test_window_id.vim @@ -3,17 +3,22 @@ func Test_win_getid() edit one let id1 = win_getid() + let w:one = 'one' split two let id2 = win_getid() let bufnr2 = bufnr('%') + let w:two = 'two' split three let id3 = win_getid() + let w:three = 'three' tabnew edit four let id4 = win_getid() + let w:four = 'four' split five let id5 = win_getid() let bufnr5 = bufnr('%') + let w:five = 'five' tabnext wincmd w @@ -28,6 +33,9 @@ func Test_win_getid() call assert_equal("three", expand("%")) call assert_equal(id3, win_getid()) let nr3 = winnr() + call assert_equal('one', getwinvar(id1, 'one')) + call assert_equal('two', getwinvar(id2, 'two')) + call assert_equal('three', getwinvar(id3, 'three')) tabnext call assert_equal("five", expand("%")) call assert_equal(id5, win_getid()) @@ -36,7 +44,14 @@ func Test_win_getid() call assert_equal("four", expand("%")) call assert_equal(id4, win_getid()) let nr4 = winnr() + call assert_equal('four', getwinvar(id4, 'four')) + call assert_equal('five', getwinvar(id5, 'five')) + call settabwinvar(1, id2, 'two', '2') + call setwinvar(id4, 'four', '4') tabnext + call assert_equal('4', gettabwinvar(2, id4, 'four')) + call assert_equal('five', gettabwinvar(2, id5, 'five')) + call assert_equal('2', getwinvar(id2, 'two')) exe nr1 . "wincmd w" call assert_equal(id1, win_getid()) diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 04b5868d2c..f252b00be2 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -22,10 +22,10 @@ #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/strings.h" +#include "nvim/ui_bridge.h" #include "nvim/ugrid.h" #include "nvim/tui/input.h" #include "nvim/tui/tui.h" -#include "nvim/tui/ui_bridge.h" // Space reserved in the output buffer to restore the cursor to normal when // flushing. No existing terminal will require 32 bytes to do that. @@ -174,7 +174,7 @@ static void terminfo_stop(UI *ui) unibi_out(ui, data->unibi_ext.disable_bracketed_paste); // Disable focus reporting unibi_out(ui, data->unibi_ext.disable_focus_reporting); - flush_buf(ui); + flush_buf(ui, true); uv_tty_reset_mode(); uv_close((uv_handle_t *)&data->output_handle, NULL); uv_run(&data->write_loop, UV_RUN_DEFAULT); @@ -601,7 +601,7 @@ static void tui_flush(UI *ui) unibi_goto(ui, grid->row, grid->col); - flush_buf(ui); + flush_buf(ui, true); } static void suspend_event(void **argv) @@ -774,7 +774,7 @@ static void out(void *ctx, const char *str, size_t len) size_t available = data->bufsize - data->bufpos; if (len > available) { - flush_buf(ui); + flush_buf(ui, false); } memcpy(data->buf + data->bufpos, str, len); @@ -910,13 +910,13 @@ end: unibi_set_if_empty(ut, unibi_clr_eos, "\x1b[J"); } -static void flush_buf(UI *ui) +static void flush_buf(UI *ui, bool toggle_cursor) { uv_write_t req; uv_buf_t buf; TUIData *data = ui->data; - if (!data->busy) { + if (toggle_cursor && !data->busy) { // not busy and the cursor is invisible(see below). Append a "cursor // normal" command to the end of the buffer. data->bufsize += CNORM_COMMAND_MAX_SIZE; @@ -930,7 +930,7 @@ static void flush_buf(UI *ui) uv_run(&data->write_loop, UV_RUN_DEFAULT); data->bufpos = 0; - if (!data->busy) { + if (toggle_cursor && !data->busy) { // not busy and cursor is visible(see above), append a "cursor invisible" // command to the beginning of the buffer for the next flush unibi_out(ui, unibi_cursor_invisible); diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 648d633e07..eb500414a7 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -397,14 +397,14 @@ static void send_output(uint8_t **ptr) size_t clen = (size_t)mb_ptr2len(p); UI_CALL(put, p, (size_t)clen); col++; - if (utf_ambiguous_width(*p)) { - pending_cursor_update = true; - flush_cursor_update(); - } else if (mb_ptr2cells(p) > 1) { + if (mb_ptr2cells(p) > 1) { // double cell character, blank the next cell UI_CALL(put, NULL, 0); col++; } + if (utf_ambiguous_width(utf_ptr2char(p))) { + pending_cursor_update = true; + } if (col >= width) { ui_linefeed(); } diff --git a/src/nvim/tui/ui_bridge.c b/src/nvim/ui_bridge.c index 48f4b1bda6..cc27c734e0 100644 --- a/src/nvim/tui/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -1,4 +1,5 @@ -// UI wrapper for the built-in TUI. Sends UI requests to the TUI thread. +// UI wrapper that sends UI requests to the UI thread. +// Used by the built-in TUI and external libnvim-based UIs. #include <assert.h> #include <stdbool.h> @@ -9,11 +10,11 @@ #include "nvim/vim.h" #include "nvim/ui.h" #include "nvim/memory.h" +#include "nvim/ui_bridge.h" #include "nvim/ugrid.h" -#include "nvim/tui/ui_bridge.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "tui/ui_bridge.c.generated.h" +# include "ui_bridge.c.generated.h" #endif #define UI(b) (((UIBridgeData *)b)->ui) diff --git a/src/nvim/tui/ui_bridge.h b/src/nvim/ui_bridge.h index 003ed3c2c1..9e4bf9f2a7 100644 --- a/src/nvim/tui/ui_bridge.h +++ b/src/nvim/ui_bridge.h @@ -1,6 +1,7 @@ -// Bridge used for communication between a builtin UI thread and nvim core -#ifndef NVIM_TUI_UI_BRIDGE_H -#define NVIM_TUI_UI_BRIDGE_H +// Bridge for communication between a UI thread and nvim core. +// Used by the built-in TUI and external libnvim-based UIs. +#ifndef NVIM_UI_BRIDGE_H +#define NVIM_UI_BRIDGE_H #include <uv.h> @@ -39,6 +40,6 @@ struct ui_bridge_data { #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "tui/ui_bridge.h.generated.h" +# include "ui_bridge.h.generated.h" #endif -#endif // NVIM_TUI_UI_BRIDGE_H +#endif // NVIM_UI_BRIDGE_H diff --git a/src/nvim/version.c b/src/nvim/version.c index 9f8fcd1232..e6ef600f8c 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -122,7 +122,7 @@ static int included_patches[] = { // 2322, // 2321, // 2320, - // 2319, + // 2319 NA // 2318, // 2317, // 2316 NA @@ -163,11 +163,11 @@ static int included_patches[] = { // 2281 NA // 2280, // 2279, - // 2278, + // 2278 NA // 2277, // 2276, // 2275, - // 2274, + 2274, // 2273, // 2272, // 2271 NA @@ -209,7 +209,7 @@ static int included_patches[] = { // 2235, // 2234 NA // 2233, - // 2232, + // 2232 NA // 2231, // 2230, // 2229, @@ -236,7 +236,7 @@ static int included_patches[] = { // 2208, // 2207 NA // 2206 NA - // 2205, + 2205, // 2204, // 2203 NA // 2202 NA @@ -279,11 +279,11 @@ static int included_patches[] = { // 2165, // 2164, // 2163, - // 2162, + 2162, // 2161, // 2160, // 2159, - // 2158, + 2158, // 2157 NA // 2156 NA // 2155 NA @@ -326,7 +326,7 @@ static int included_patches[] = { // 2118 NA // 2117, // 2116 NA - // 2115, + // 2115 NA // 2114 NA // 2113, 2112, @@ -496,7 +496,7 @@ static int included_patches[] = { // 1948, // 1947 NA // 1946 NA - // 1945, + // 1945 NA // 1944 NA // 1943 NA // 1942 NA @@ -546,9 +546,9 @@ static int included_patches[] = { 1898, // 1897, 1896, - // 1895, + 1895, // 1894 NA - // 1893, + 1893, // 1892 NA // 1891 NA // 1890 NA @@ -630,14 +630,14 @@ static int included_patches[] = { // 1814 NA // 1813, // 1812, - // 1811, + // 1811 NA // 1810 NA 1809, 1808, // 1807 NA 1806, - // 1805, - // 1804, + // 1805 NA + // 1804 NA // 1803 NA // 1802, // 1801 NA @@ -647,7 +647,7 @@ static int included_patches[] = { // 1797 NA // 1796 NA // 1795 NA - // 1794, + // 1794 NA // 1793, // 1792 NA // 1791 NA @@ -672,14 +672,14 @@ static int included_patches[] = { // 1773 NA // 1772 NA // 1771 NA - // 1770, + // 1770 NA // 1769, // 1768, // 1767 NA // 1766 NA - // 1765, + 1765, // 1764 NA - // 1763, + 1763, // 1762, // 1761, // 1760 NA @@ -693,7 +693,7 @@ static int included_patches[] = { // 1753, // 1752, // 1751, - // 1750, + // 1750 NA // 1749 NA // 1748, // 1747 NA @@ -729,7 +729,7 @@ static int included_patches[] = { // 1717 NA 1716, // 1715, - // 1714, + 1714, // 1713 NA 1712, // 1711, @@ -790,7 +790,7 @@ static int included_patches[] = { // 1656, // 1655 NA 1654, - // 1653, + // 1653 NA 1652, // 1651 NA // 1650, @@ -894,7 +894,7 @@ static int included_patches[] = { 1552, 1551, 1550, - // 1549, + 1549, 1548, 1547, 1546, diff --git a/src/nvim/vim.h b/src/nvim/vim.h index 09e9e850a7..6bbd9b58ef 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -316,4 +316,7 @@ enum { #define DIP_OPT 0x10 // also use "opt" directory in 'packpath' #define DIP_NORTP 0x20 // do not use 'runtimepath' +// Lowest number used for window ID. Cannot have this many windows per tab. +#define LOWEST_WIN_ID 1000 + #endif /* NVIM_VIM_H */ diff --git a/src/nvim/window.c b/src/nvim/window.c index 2cc99b8dfa..29c670322a 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -482,7 +482,7 @@ wingotofile: } static void cmd_with_count(char *cmd, char_u *bufp, size_t bufsize, - long Prenum) + int64_t Prenum) { size_t len = xstrlcpy((char *)bufp, cmd, bufsize); @@ -3694,7 +3694,7 @@ win_T *buf_jump_open_tab(buf_T *buf) */ static win_T *win_alloc(win_T *after, int hidden) { - static int last_win_id = 0; + static int last_win_id = LOWEST_WIN_ID - 1; // allocate window structure and linesizes arrays win_T *new_wp = xcalloc(1, sizeof(win_T)); |