diff options
| author | ckelsel <ckelsel@hotmail.com> | 2017-07-10 08:10:15 +0800 |
|---|---|---|
| committer | ckelsel <ckelsel@hotmail.com> | 2017-07-10 08:10:15 +0800 |
| commit | 465bbee520d1b1b57477fd7d80fbdeaf5e1e1e77 (patch) | |
| tree | edae38568202ba41dee4a49f78884da313fd114b /src | |
| parent | 1514cdc7d8863eeee6b04883b1c50aac40048b49 (diff) | |
| parent | 6725667d31591e8025589c4c1df34469f3bfdb52 (diff) | |
| download | rneovim-465bbee520d1b1b57477fd7d80fbdeaf5e1e1e77.tar.gz rneovim-465bbee520d1b1b57477fd7d80fbdeaf5e1e1e77.tar.bz2 rneovim-465bbee520d1b1b57477fd7d80fbdeaf5e1e1e77.zip | |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'src')
36 files changed, 1270 insertions, 519 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index d401ae52a0..1ed2bc013e 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -95,7 +95,7 @@ Object dict_get_value(dict_T *dict, String key, Error *err) dictitem_T *const di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size); if (di == NULL) { - api_set_error(err, kErrorTypeValidation, "Key not found"); + api_set_error(err, kErrorTypeValidation, "Key '%s' not found", key.data); return (Object)OBJECT_INIT; } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 80efe86ea3..2bc31b2812 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -136,9 +136,13 @@ Integer nvim_input(String keys) return (Integer)input_enqueue(keys); } -/// Replaces terminal codes and key codes (<CR>, <Esc>, ...) in a string with +/// Replaces terminal codes and |keycodes| (<CR>, <Esc>, ...) in a string with /// the internal representation. /// +/// @param str String to be converted. +/// @param from_part Legacy Vim parameter. Usually true. +/// @param do_lt Also translate <lt>. Ignored if `special` is false. +/// @param special Replace |keycodes|, e.g. <CR> becomes a "\n" char. /// @see replace_termcodes /// @see cpoptions String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, @@ -151,12 +155,6 @@ String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, } char *ptr = NULL; - // Set 'cpoptions' the way we want it. - // FLAG_CPO_BSLASH set - backslashes are *not* treated specially - // FLAG_CPO_KEYCODE set - keycodes are *not* reverse-engineered - // FLAG_CPO_SPECI unset - <Key> sequences *are* interpreted - // The third from end parameter of replace_termcodes() is true so that the - // <lt> sequence is recognised - needed for a real backslash. replace_termcodes((char_u *)str.data, str.size, (char_u **)&ptr, from_part, do_lt, special, CPO_TO_CPO_FLAGS); return cstr_as_string(ptr); diff --git a/src/nvim/bufhl_defs.h b/src/nvim/bufhl_defs.h index 24bd6b7f29..14b1afa7d9 100644 --- a/src/nvim/bufhl_defs.h +++ b/src/nvim/bufhl_defs.h @@ -29,6 +29,6 @@ typedef struct { } BufhlLineInfo; #define BUFHL_CMP(a, b) ((int)(((a)->line - (b)->line))) -KBTREE_INIT(bufhl, BufhlLine *, BUFHL_CMP, 10) +KBTREE_INIT(bufhl, BufhlLine *, BUFHL_CMP, 10) // -V512 typedef kbtree_t(bufhl) BufhlInfo; #endif // NVIM_BUFHL_DEFS_H diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 48db1030a6..403ef65c4f 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -981,10 +981,8 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he mb_ptr_adv(s); c = *s; - if (!((c != NUL) - && (vim_isbreak(c) - || (!vim_isbreak(c) - && ((col2 == col) || !vim_isbreak(*ps)))))) { + if (!(c != NUL + && (vim_isbreak(c) || col2 == col || !vim_isbreak(*ps)))) { break; } diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 08a2f42f74..ca62679fab 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -462,7 +462,7 @@ static void insert_enter(InsertState *s) // Always update o_lnum, so that a "CTRL-O ." that adds a line // still puts the cursor back after the inserted text. - if (ins_at_eol && gchar_cursor() == NUL) { + if (ins_at_eol) { o_lnum = curwin->w_cursor.lnum; } diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 18aa5bf763..7e9c006f33 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -12111,15 +12111,17 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) mode = get_map_mode((char_u **)&which, 0); - keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, false, + keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, true, CPO_TO_CPO_FLAGS); rhs = check_map(keys, mode, exact, false, abbr, &mp, &buffer_local); xfree(keys_buf); if (!get_dict) { - /* Return a string. */ - if (rhs != NULL) - rettv->vval.v_string = str2special_save(rhs, FALSE); + // Return a string. + if (rhs != NULL) { + rettv->vval.v_string = (char_u *)str2special_save( + (const char *)rhs, false, false); + } } else { tv_dict_alloc_ret(rettv); @@ -12154,7 +12156,8 @@ void mapblock_fill_dict(dict_T *const dict, bool compatible) FUNC_ATTR_NONNULL_ALL { - char_u *lhs = str2special_save(mp->m_keys, true); + char *const lhs = str2special_save((const char *)mp->m_keys, + compatible, !compatible); char *const mapmode = map_mode_to_chars(mp->m_mode); varnumber_T noremap_value; @@ -12168,18 +12171,21 @@ void mapblock_fill_dict(dict_T *const dict, noremap_value = mp->m_noremap == REMAP_SCRIPT ? 2 : !!mp->m_noremap; } - tv_dict_add_str(dict, S_LEN("lhs"), (const char *)lhs); - tv_dict_add_str(dict, S_LEN("rhs"), (const char *)mp->m_orig_str); + if (compatible) { + tv_dict_add_str(dict, S_LEN("rhs"), (const char *)mp->m_orig_str); + } else { + tv_dict_add_allocated_str(dict, S_LEN("rhs"), + str2special_save((const char *)mp->m_str, false, + true)); + } + tv_dict_add_allocated_str(dict, S_LEN("lhs"), lhs); tv_dict_add_nr(dict, S_LEN("noremap"), noremap_value); tv_dict_add_nr(dict, S_LEN("expr"), mp->m_expr ? 1 : 0); tv_dict_add_nr(dict, S_LEN("silent"), mp->m_silent ? 1 : 0); tv_dict_add_nr(dict, S_LEN("sid"), (varnumber_T)mp->m_script_ID); tv_dict_add_nr(dict, S_LEN("buffer"), (varnumber_T)buffer_value); tv_dict_add_nr(dict, S_LEN("nowait"), mp->m_nowait ? 1 : 0); - tv_dict_add_str(dict, S_LEN("mode"), mapmode); - - xfree(lhs); - xfree(mapmode); + tv_dict_add_allocated_str(dict, S_LEN("mode"), mapmode); } /* diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 4521085519..c339a5cdd2 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1387,11 +1387,32 @@ int tv_dict_add_str(dict_T *const d, const char *const val) FUNC_ATTR_NONNULL_ALL { + return tv_dict_add_allocated_str(d, key, key_len, xstrdup(val)); +} + +/// Add a string entry to dictionary +/// +/// Unlike tv_dict_add_str() saves val to the new dictionary item in place of +/// creating a new copy. +/// +/// @warning String will be freed even in case addition fails. +/// +/// @param[out] d Dictionary to add entry to. +/// @param[in] key Key to add. +/// @param[in] key_len Key length. +/// @param[in] val String to add. +/// +/// @return OK in case of success, FAIL when key already exists. +int tv_dict_add_allocated_str(dict_T *const d, + const char *const key, const size_t key_len, + char *const val) + FUNC_ATTR_NONNULL_ALL +{ dictitem_T *const item = tv_dict_item_alloc_len(key, key_len); item->di_tv.v_lock = VAR_UNLOCKED; item->di_tv.v_type = VAR_STRING; - item->di_tv.vval.v_string = (char_u *)xstrdup(val); + item->di_tv.vval.v_string = (char_u *)val; if (tv_dict_add(d, item) == FAIL) { tv_dict_item_free(item); return FAIL; diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index cad49e2007..c936583841 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -21,9 +21,9 @@ # include "event/process.c.generated.h" #endif -// Time (ns) for a process to exit cleanly before we send TERM/KILL. -#define TERM_TIMEOUT 1000000000 -#define KILL_TIMEOUT (TERM_TIMEOUT * 2) +// Time for a process to exit cleanly before we send KILL. +// For pty processes SIGTERM is sent first (in case SIGHUP was not enough). +#define KILL_TIMEOUT_MS 2000 #define CLOSE_PROC_STREAM(proc, stream) \ do { \ @@ -125,8 +125,6 @@ void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL // Close handles to process without killing it. CREATE_EVENT(loop->events, process_close_handles, 1, proc); } else { - uv_kill(proc->pid, SIGTERM); - proc->term_sent = true; process_stop(proc); } } @@ -238,6 +236,8 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL // stdout/stderr, they will be closed when it exits(possibly due to being // terminated after a timeout) process_close_in(proc); + ILOG("Sending SIGTERM to pid %d", proc->pid); + uv_kill(proc->pid, SIGTERM); break; case kProcessTypePty: // close all streams for pty processes to send SIGHUP to the process @@ -251,9 +251,10 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL Loop *loop = proc->loop; if (!loop->children_stop_requests++) { // When there's at least one stop request pending, start a timer that - // will periodically check if a signal should be send to a to the job - DLOG("Starting job kill timer"); - uv_timer_start(&loop->children_kill_timer, children_kill_cb, 100, 100); + // will periodically check if a signal should be send to the job. + ILOG("Starting job kill timer"); + uv_timer_start(&loop->children_kill_timer, children_kill_cb, + KILL_TIMEOUT_MS, KILL_TIMEOUT_MS); } } @@ -269,15 +270,15 @@ static void children_kill_cb(uv_timer_t *handle) if (!proc->stopped_time) { continue; } - uint64_t elapsed = now - proc->stopped_time; - - if (!proc->term_sent && elapsed >= TERM_TIMEOUT) { - ILOG("Sending SIGTERM to pid %d", proc->pid); - uv_kill(proc->pid, SIGTERM); - proc->term_sent = true; - } else if (elapsed >= KILL_TIMEOUT) { - ILOG("Sending SIGKILL to pid %d", proc->pid); - uv_kill(proc->pid, SIGKILL); + uint64_t elapsed = (now - proc->stopped_time) / 1000000 + 1; + + if (elapsed >= KILL_TIMEOUT_MS) { + int sig = proc->type == kProcessTypePty && elapsed < KILL_TIMEOUT_MS * 2 + ? SIGTERM + : SIGKILL; + ILOG("Sending %s to pid %d", sig == SIGTERM ? "SIGTERM" : "SIGKILL", + proc->pid); + uv_kill(proc->pid, sig); } } } diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index 26d70a5e6d..5c00e8e7ec 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -26,7 +26,7 @@ struct process { Stream *in, *out, *err; process_exit_cb cb; internal_process_cb internal_exit_cb, internal_close_cb; - bool closed, term_sent, detach; + bool closed, detach; MultiQueue *events; }; @@ -48,7 +48,6 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data) .err = NULL, .cb = NULL, .closed = false, - .term_sent = false, .internal_close_cb = NULL, .internal_exit_cb = NULL, .detach = false diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c index a796f303ab..6f45b09fce 100644 --- a/src/nvim/event/socket.c +++ b/src/nvim/event/socket.c @@ -105,9 +105,10 @@ int socket_watcher_start(SocketWatcher *watcher, int backlog, socket_cb cb) // contain 0 in this case, unless uv_tcp_getsockname() is used first. uv_tcp_getsockname(&watcher->uv.tcp.handle, (struct sockaddr *)&sas, &(int){ sizeof(sas) }); - uint16_t port = (uint16_t)((sas.ss_family == AF_INET) - ? ((struct sockaddr_in *)&sas)->sin_port - : ((struct sockaddr_in6 *)&sas)->sin6_port); + uint16_t port = (uint16_t)( + (sas.ss_family == AF_INET) + ? (STRUCT_CAST(struct sockaddr_in, &sas))->sin_port + : (STRUCT_CAST(struct sockaddr_in6, &sas))->sin6_port); // v:servername uses the string from watcher->addr size_t len = strlen(watcher->addr); snprintf(watcher->addr+len, sizeof(watcher->addr)-len, ":%" PRIu16, @@ -247,7 +248,7 @@ tcp_retry: uv_pipe_t *pipe = &stream->uv.pipe; uv_pipe_init(&loop->uv, pipe, 0); uv_pipe_connect(&req, pipe, address, connect_cb); - uv_stream = (uv_stream_t *)pipe; + uv_stream = STRUCT_CAST(uv_stream_t, pipe); } status = 1; LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, timeout, status != 1); diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 8dcb3ac449..b550e9a9c6 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -3332,7 +3332,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout) // Check for a match on each line. linenr_T line2 = eap->line2; for (linenr_T lnum = eap->line1; - lnum <= line2 && !(got_quit || aborting()); + lnum <= line2 && !(got_quit || aborting()) + && (!preview || matched_lines.size <= (size_t)p_cwh); lnum++) { long nmatch = vim_regexec_multi(®match, curwin, curbuf, lnum, (colnr_T)0, NULL); diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index af8845de87..5d7246581c 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -4747,7 +4747,7 @@ static int uc_add_command(char_u *name, size_t name_len, char_u *rep, char_u *rep_buf = NULL; garray_T *gap; - replace_termcodes(rep, STRLEN(rep), &rep_buf, false, false, false, + replace_termcodes(rep, STRLEN(rep), &rep_buf, false, false, true, CPO_TO_CPO_FLAGS); if (rep_buf == NULL) { /* Can't replace termcodes - try using the string as is */ diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 7793081957..0ba6c79a71 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -306,7 +306,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent) curwin->w_cursor = s->save_cursor; setpcmark(); } - curwin->w_cursor = s->search_start; + curwin->w_cursor = s->search_start; // -V519 } curwin->w_curswant = s->old_curswant; curwin->w_leftcol = s->old_leftcol; diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 4e42042959..a22b716bb6 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1806,7 +1806,7 @@ static int vgetorpeek(int advance) * <M-a> and then changing 'encoding'. Beware * that 0x80 is escaped. */ char_u *p1 = mp->m_keys; - char_u *p2 = mb_unescape(&p1); + char_u *p2 = (char_u *)mb_unescape((const char **)&p1); if (has_mbyte && p2 != NULL && MB_BYTE2LEN(c1) > MB_PTR2LEN(p2)) mlen = 0; @@ -2537,7 +2537,6 @@ do_map ( bool unique = false; bool nowait = false; bool silent = false; - bool special = false; bool expr = false; int noremap; char_u *orig_rhs; @@ -2583,12 +2582,9 @@ do_map ( continue; } - /* - * Check for "<special>": accept special keys in <> - */ + // Ignore obsolete "<special>" modifier. if (STRNCMP(keys, "<special>", 9) == 0) { keys = skipwhite(keys + 9); - special = true; continue; } @@ -2657,7 +2653,7 @@ do_map ( // needs to be freed later (*keys_buf and *arg_buf). // replace_termcodes() also removes CTRL-Vs and sometimes backslashes. if (haskey) { - keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, special, + keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, true, CPO_TO_CPO_FLAGS); } orig_rhs = rhs; @@ -2665,7 +2661,7 @@ do_map ( if (STRICMP(rhs, "<nop>") == 0) { // "<Nop>" means nothing rhs = (char_u *)""; } else { - rhs = replace_termcodes(rhs, STRLEN(rhs), &arg_buf, false, true, special, + rhs = replace_termcodes(rhs, STRLEN(rhs), &arg_buf, false, true, true, CPO_TO_CPO_FLAGS); } } @@ -3245,7 +3241,7 @@ bool map_to_exists(const char *const str, const char *const modechars, char_u *buf; char_u *const rhs = replace_termcodes((const char_u *)str, strlen(str), &buf, - false, true, false, + false, true, true, CPO_TO_CPO_FLAGS); #define MAPMODE(mode, modechars, chr, modeflags) \ @@ -3999,12 +3995,10 @@ int put_escstr(FILE *fd, char_u *strstart, int what) return OK; } - for (; *str != NUL; ++str) { - char_u *p; - - /* Check for a multi-byte character, which may contain escaped - * K_SPECIAL and CSI bytes */ - p = mb_unescape(&str); + for (; *str != NUL; str++) { + // Check for a multi-byte character, which may contain escaped + // K_SPECIAL and CSI bytes. + const char *p = mb_unescape((const char **)&str); if (p != NULL) { while (*p != NUL) if (fputc(*p++, fd) < 0) @@ -4160,8 +4154,7 @@ void add_map(char_u *map, int mode) } // Translate an internal mapping/abbreviation representation into the -// corresponding external one recognized by :map/:abbrev commands; -// respects the current B/k/< settings of 'cpoption'. +// corresponding external one recognized by :map/:abbrev commands. // // This function is called when expanding mappings/abbreviations on the // command-line, and for building the "Ambiguous mapping..." error message. @@ -4181,7 +4174,6 @@ static char_u * translate_mapping ( ga_init(&ga, 1, 40); bool cpo_bslash = !(cpo_flags&FLAG_CPO_BSLASH); - bool cpo_special = !(cpo_flags&FLAG_CPO_SPECI); for (; *str; ++str) { int c = *str; @@ -4194,7 +4186,7 @@ static char_u * translate_mapping ( } if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) { - if (expmap && cpo_special) { + if (expmap) { ga_clear(&ga); return NULL; } @@ -4205,8 +4197,8 @@ static char_u * translate_mapping ( } str += 2; } - if (IS_SPECIAL(c) || modifiers) { /* special key */ - if (expmap && cpo_special) { + if (IS_SPECIAL(c) || modifiers) { // special key + if (expmap) { ga_clear(&ga); return NULL; } @@ -4216,7 +4208,7 @@ static char_u * translate_mapping ( } if (c == ' ' || c == '\t' || c == Ctrl_J || c == Ctrl_V - || (c == '<' && !cpo_special) || (c == '\\' && !cpo_bslash)) { + || (c == '\\' && !cpo_bslash)) { ga_append(&ga, cpo_bslash ? Ctrl_V : '\\'); } diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c index ee67b4c19d..3d7ebb6382 100644 --- a/src/nvim/keymap.c +++ b/src/nvim/keymap.c @@ -756,9 +756,9 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag) /// Replace any terminal code strings with the equivalent internal /// representation /// -/// This is used for the "from" and "to" part of a mapping, and the "to" part of +/// Used for the "from" and "to" part of a mapping, and the "to" part of /// a menu command. Any strings like "<C-UP>" are also replaced, unless -/// 'cpoptions' contains '<'. K_SPECIAL by itself is replaced by K_SPECIAL +/// `special` is false. K_SPECIAL by itself is replaced by K_SPECIAL /// KS_SPECIAL KE_FILLER. /// /// @param[in] from What characters to replace. @@ -771,7 +771,7 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag) /// When cpo_flags contains #FLAG_CPO_BSLASH, a backslash /// can be used in place of <C-v>. All other <C-v> /// characters are removed. -/// @param[in] special If true, always accept <key> notation. +/// @param[in] special Replace keycodes, e.g. <CR> becomes a "\n" char. /// @param[in] cpo_flags Relevant flags derived from p_cpo, see /// #CPO_TO_CPO_FLAGS. /// @@ -790,11 +790,9 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len, const char_u *src; const char_u *const end = from + from_len - 1; int do_backslash; // backslash is a special character - int do_special; // recognize <> key codes char_u *result; // buffer for resulting string do_backslash = !(cpo_flags&FLAG_CPO_BSLASH); - do_special = !(cpo_flags&FLAG_CPO_SPECI) || special; // Allocate space for the translation. Worst case a single character is // replaced by 6 bytes (shifted special key), plus a NUL at the end. @@ -817,10 +815,9 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len, // Copy each byte from *from to result[dlen] while (src <= end) { - // If 'cpoptions' does not contain '<', check for special key codes, - // like "<C-S-LeftMouse>" - if (do_special && (do_lt || ((end - src) >= 3 - && STRNCMP(src, "<lt>", 4) != 0))) { + // Check for special <> keycodes, like "<C-S-LeftMouse>" + if (special && (do_lt || ((end - src) >= 3 + && STRNCMP(src, "<lt>", 4) != 0))) { // Replace <SID> by K_SNR <script-nr> _. // (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14) if (end - src >= 4 && STRNICMP(src, "<SID>", 5) == 0) { @@ -846,7 +843,7 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len, } } - if (do_special) { + if (special) { char_u *p, *s, len; // Replace <Leader> by the value of "mapleader". diff --git a/src/nvim/keymap.h b/src/nvim/keymap.h index bb8ba84a6a..b8fed77a90 100644 --- a/src/nvim/keymap.h +++ b/src/nvim/keymap.h @@ -464,13 +464,9 @@ enum key_extra { #define MAX_KEY_CODE_LEN 6 #define FLAG_CPO_BSLASH 0x01 -#define FLAG_CPO_SPECI 0x02 -#define CPO_TO_CPO_FLAGS (((vim_strchr(p_cpo, CPO_BSLASH) == NULL) \ - ? 0 \ - : FLAG_CPO_BSLASH)| \ - (vim_strchr(p_cpo, CPO_SPECI) == NULL \ - ? 0 \ - : FLAG_CPO_SPECI)) +#define CPO_TO_CPO_FLAGS ((vim_strchr(p_cpo, CPO_BSLASH) == NULL) \ + ? 0 \ + : FLAG_CPO_BSLASH) #ifdef INCLUDE_GENERATED_DECLARATIONS # include "keymap.h.generated.h" diff --git a/src/nvim/main.c b/src/nvim/main.c index 19a661d7db..7dcf00c26b 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -57,6 +57,7 @@ #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/os/time.h" +#include "nvim/os/fileio.h" #include "nvim/event/loop.h" #include "nvim/os/signal.h" #include "nvim/event/process.h" @@ -766,16 +767,26 @@ static void command_line_scan(mparm_T *parmp) version(); mch_exit(0); } else if (STRICMP(argv[0] + argv_idx, "api-info") == 0) { - msgpack_sbuffer* b = msgpack_sbuffer_new(); - msgpack_packer* p = msgpack_packer_new(b, msgpack_sbuffer_write); - Object md = DICTIONARY_OBJ(api_metadata()); - msgpack_rpc_from_object(md, p); + FileDescriptor fp; + const int fof_ret = file_open_fd(&fp, OS_STDOUT_FILENO, true); + msgpack_packer *p = msgpack_packer_new(&fp, msgpack_file_write); + + if (fof_ret != 0) { + emsgf(_("E5421: Failed to open stdin: %s"), os_strerror(fof_ret)); + } - for (size_t i = 0; i < b->size; i++) { - putchar(b->data[i]); + if (p == NULL) { + emsgf(_(e_outofmem)); } + Object md = DICTIONARY_OBJ(api_metadata()); + msgpack_rpc_from_object(md, p); + msgpack_packer_free(p); + const int ff_ret = file_flush(&fp); + if (ff_ret < 0) { + msgpack_file_write_error(ff_ret); + } mch_exit(0); } else if (STRICMP(argv[0] + argv_idx, "headless") == 0) { parmp->headless = true; diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index d5907da2ed..2acfb896d8 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -1739,52 +1739,55 @@ int mb_charlen_len(char_u *str, int len) return count; } -/* - * Try to un-escape a multi-byte character. - * Used for the "to" and "from" part of a mapping. - * Return the un-escaped string if it is a multi-byte character, and advance - * "pp" to just after the bytes that formed it. - * Return NULL if no multi-byte char was found. - */ -char_u * mb_unescape(char_u **pp) -{ - static char_u buf[6]; - int n; - int m = 0; - char_u *str = *pp; - - /* Must translate K_SPECIAL KS_SPECIAL KE_FILLER to K_SPECIAL and CSI - * KS_EXTRA KE_CSI to CSI. - * Maximum length of a utf-8 character is 4 bytes. */ - for (n = 0; str[n] != NUL && m < 4; ++n) { - if (str[n] == K_SPECIAL - && str[n + 1] == KS_SPECIAL - && str[n + 2] == KE_FILLER) { - buf[m++] = K_SPECIAL; - n += 2; - } else if ((str[n] == K_SPECIAL - ) - && str[n + 1] == KS_EXTRA - && str[n + 2] == (int)KE_CSI) { - buf[m++] = CSI; - n += 2; - } else if (str[n] == K_SPECIAL - ) - break; /* a special key can't be a multibyte char */ - else - buf[m++] = str[n]; - buf[m] = NUL; +/// Try to unescape a multibyte character +/// +/// Used for the rhs and lhs of the mappings. +/// +/// @param[in,out] pp String to unescape. Is advanced to just after the bytes +/// that form a multibyte character. +/// +/// @return Unescaped string if it is a multibyte character, NULL if no +/// multibyte character was found. Returns a static buffer, always one +/// and the same. +const char *mb_unescape(const char **const pp) + FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL +{ + static char buf[6]; + size_t buf_idx = 0; + |