diff options
| author | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:31:31 +0000 |
|---|---|---|
| committer | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:31:31 +0000 |
| commit | 9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch) | |
| tree | 607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /src/nvim/getchar.c | |
| parent | 9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff) | |
| parent | 3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff) | |
| download | rneovim-usermarks.tar.gz rneovim-usermarks.tar.bz2 rneovim-usermarks.zip | |
Merge remote-tracking branch 'upstream/master' into usermarksusermarks
Diffstat (limited to 'src/nvim/getchar.c')
| -rw-r--r-- | src/nvim/getchar.c | 655 |
1 files changed, 320 insertions, 335 deletions
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 0f55158733..9c5364e1b1 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -7,11 +7,15 @@ #include <assert.h> #include <inttypes.h> #include <stdbool.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> #include <string.h> +#include "lauxlib.h" +#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii.h" -#include "nvim/assert.h" #include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cursor.h" @@ -19,16 +23,21 @@ #include "nvim/edit.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" +#include "nvim/eval/typval_defs.h" #include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/ex_cmds.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" #include "nvim/garray.h" #include "nvim/getchar.h" +#include "nvim/gettext.h" +#include "nvim/globals.h" #include "nvim/input.h" #include "nvim/insexpand.h" #include "nvim/keycodes.h" #include "nvim/lua/executor.h" +#include "nvim/macros.h" #include "nvim/main.h" #include "nvim/mapping.h" #include "nvim/mbyte.h" @@ -44,8 +53,11 @@ #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/plines.h" +#include "nvim/pos.h" +#include "nvim/screen.h" #include "nvim/state.h" #include "nvim/strings.h" +#include "nvim/types.h" #include "nvim/ui.h" #include "nvim/undo.h" #include "nvim/vim.h" @@ -81,33 +93,29 @@ static buffheader_T readbuf2 = { { NULL, { NUL } }, NULL, 0, 0 }; static int typeahead_char = 0; // typeahead char that's not flushed -/* - * when block_redo is TRUE redo buffer will not be changed - * used by edit() to repeat insertions and 'V' command for redoing - */ -static int block_redo = FALSE; +// when block_redo is true redo buffer will not be changed +// used by edit() to repeat insertions and 'V' command for redoing +static int block_redo = false; static int KeyNoremap = 0; // remapping flags -/* - * Variables used by vgetorpeek() and flush_buffers() - * - * typebuf.tb_buf[] contains all characters that are not consumed yet. - * typebuf.tb_buf[typebuf.tb_off] is the first valid character. - * typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len - 1] is the last valid char. - * typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len] must be NUL. - * The head of the buffer may contain the result of mappings, abbreviations - * and @a commands. The length of this part is typebuf.tb_maplen. - * typebuf.tb_silent is the part where <silent> applies. - * After the head are characters that come from the terminal. - * typebuf.tb_no_abbr_cnt is the number of characters in typebuf.tb_buf that - * should not be considered for abbreviations. - * Some parts of typebuf.tb_buf may not be mapped. These parts are remembered - * in typebuf.tb_noremap[], which is the same length as typebuf.tb_buf and - * contains RM_NONE for the characters that are not to be remapped. - * typebuf.tb_noremap[typebuf.tb_off] is the first valid flag. - * (typebuf has been put in globals.h, because check_termcode() needs it). - */ +// Variables used by vgetorpeek() and flush_buffers() +// +// typebuf.tb_buf[] contains all characters that are not consumed yet. +// typebuf.tb_buf[typebuf.tb_off] is the first valid character. +// typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len - 1] is the last valid char. +// typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len] must be NUL. +// The head of the buffer may contain the result of mappings, abbreviations +// and @a commands. The length of this part is typebuf.tb_maplen. +// typebuf.tb_silent is the part where <silent> applies. +// After the head are characters that come from the terminal. +// typebuf.tb_no_abbr_cnt is the number of characters in typebuf.tb_buf that +// should not be considered for abbreviations. +// Some parts of typebuf.tb_buf may not be mapped. These parts are remembered +// in typebuf.tb_noremap[], which is the same length as typebuf.tb_buf and +// contains RM_NONE for the characters that are not to be remapped. +// typebuf.tb_noremap[typebuf.tb_off] is the first valid flag. +// (typebuf has been put in globals.h, because check_termcode() needs it). #define RM_YES 0 // tb_noremap: remap #define RM_NONE 1 // tb_noremap: don't remap #define RM_SCRIPT 2 // tb_noremap: remap local script mappings @@ -126,9 +134,7 @@ static size_t last_recorded_len = 0; // number of last recorded chars # include "getchar.c.generated.h" #endif -/* - * Free and clear a buffer. - */ +// Free and clear a buffer. void free_buff(buffheader_T *buf) { buffblock_T *p, *np; @@ -145,16 +151,16 @@ void free_buff(buffheader_T *buf) /// K_SPECIAL in the returned string is escaped. /// /// @param dozero count == zero is not an error -static char_u *get_buffcont(buffheader_T *buffer, int dozero) +static char *get_buffcont(buffheader_T *buffer, int dozero) { size_t count = 0; - char_u *p = NULL; - char_u *p2; + char *p = NULL; + char *p2; // compute the total length of the string for (const buffblock_T *bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next) { - count += STRLEN(bp->b_str); + count += strlen(bp->b_str); } if (count || dozero) { @@ -162,7 +168,7 @@ static char_u *get_buffcont(buffheader_T *buffer, int dozero) p2 = p; for (const buffblock_T *bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next) { - for (const char_u *str = bp->b_str; *str;) { + for (const char *str = bp->b_str; *str;) { *p2++ = *str++; } } @@ -176,38 +182,34 @@ static char_u *get_buffcont(buffheader_T *buffer, int dozero) /// K_SPECIAL in the returned string is escaped. char_u *get_recorded(void) { - char_u *p; + char *p; size_t len; - p = get_buffcont(&recordbuff, TRUE); + p = get_buffcont(&recordbuff, true); free_buff(&recordbuff); - /* - * Remove the characters that were added the last time, these must be the - * (possibly mapped) characters that stopped the recording. - */ - len = STRLEN(p); + // Remove the characters that were added the last time, these must be the + // (possibly mapped) characters that stopped the recording. + len = strlen(p); if (len >= last_recorded_len) { len -= last_recorded_len; p[len] = NUL; } - /* - * When stopping recording from Insert mode with CTRL-O q, also remove the - * CTRL-O. - */ + // When stopping recording from Insert mode with CTRL-O q, also remove the + // CTRL-O. if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O) { p[len - 1] = NUL; } - return p; + return (char_u *)p; } /// Return the contents of the redo buffer as a single string. /// K_SPECIAL in the returned string is escaped. -char_u *get_inserted(void) +char *get_inserted(void) { - return get_buffcont(&redobuff, FALSE); + return get_buffcont(&redobuff, false); } /// Add string after the current block of the given buffer @@ -235,14 +237,14 @@ static void add_buff(buffheader_T *const buf, const char *const s, ptrdiff_t sle } else if (buf->bh_index != 0) { memmove(buf->bh_first.b_next->b_str, buf->bh_first.b_next->b_str + buf->bh_index, - STRLEN(buf->bh_first.b_next->b_str + buf->bh_index) + 1); + strlen(buf->bh_first.b_next->b_str + buf->bh_index) + 1); } buf->bh_index = 0; size_t len; if (buf->bh_space >= (size_t)slen) { - len = STRLEN(buf->bh_curr->b_str); - STRLCPY(buf->bh_curr->b_str + len, s, slen + 1); + len = strlen(buf->bh_curr->b_str); + xstrlcpy(buf->bh_curr->b_str + len, s, (size_t)slen + 1); buf->bh_space -= (size_t)slen; } else { if (slen < MINIMAL_SIZE) { @@ -252,7 +254,7 @@ static void add_buff(buffheader_T *const buf, const char *const s, ptrdiff_t sle } buffblock_T *p = xmalloc(sizeof(buffblock_T) + len); buf->bh_space = len - (size_t)slen; - STRLCPY(p->b_str, s, slen + 1); + xstrlcpy(p->b_str, s, (size_t)slen + 1); p->b_next = buf->bh_curr->b_next; buf->bh_curr->b_next = p; @@ -269,11 +271,13 @@ static void delete_buff_tail(buffheader_T *buf, int slen) if (buf->bh_curr == NULL) { return; // nothing to delete } - len = (int)STRLEN(buf->bh_curr->b_str); - if (len >= slen) { - buf->bh_curr->b_str[len - slen] = NUL; - buf->bh_space += (size_t)slen; + len = (int)strlen(buf->bh_curr->b_str); + if (len < slen) { + return; } + + buf->bh_curr->b_str[len - slen] = NUL; + buf->bh_space += (size_t)slen; } /// Add number "n" to buffer "buf". @@ -319,7 +323,7 @@ static void add_char_buff(buffheader_T *buf, int c) /// Get one byte from the read buffers. Use readbuf1 one first, use readbuf2 /// if that one is empty. -/// If advance == TRUE go to the next char. +/// If advance == true go to the next char. /// No translation is done K_SPECIAL is escaped. static int read_readbuffers(int advance) { @@ -341,7 +345,7 @@ static int read_readbuf(buffheader_T *buf, int advance) } buffblock_T *const curr = buf->bh_first.b_next; - c = curr->b_str[buf->bh_index]; + c = (char_u)curr->b_str[buf->bh_index]; if (advance) { if (curr->b_str[++buf->bh_index] == NUL) { @@ -353,9 +357,7 @@ static int read_readbuf(buffheader_T *buf, int advance) return c; } -/* - * Prepare the read buffers for reading (if they contain something). - */ +// Prepare the read buffers for reading (if they contain something). static void start_stuff(void) { if (readbuf1.bh_first.b_next != NULL) { @@ -368,38 +370,30 @@ static void start_stuff(void) } } -/* - * Return TRUE if the stuff buffer is empty. - */ +/// Return true if the stuff buffer is empty. int stuff_empty(void) FUNC_ATTR_PURE { return (readbuf1.bh_first.b_next == NULL && readbuf2.bh_first.b_next == NULL); } -/* - * Return TRUE if readbuf1 is empty. There may still be redo characters in - * redbuf2. - */ +/// Return true if readbuf1 is empty. There may still be redo characters in +/// redbuf2. int readbuf1_empty(void) FUNC_ATTR_PURE { return (readbuf1.bh_first.b_next == NULL); } -/* - * Set a typeahead character that won't be flushed. - */ +// Set a typeahead character that won't be flushed. void typeahead_noflush(int c) { typeahead_char = c; } -/* - * Remove the contents of the stuff buffer and the mapped characters in the - * typeahead buffer (used in case of an error). If "flush_typeahead" is true, - * flush all typeahead characters (used when interrupted by a CTRL-C). - */ +// Remove the contents of the stuff buffer and the mapped characters in the +// typeahead buffer (used in case of an error). If "flush_typeahead" is true, +// flush all typeahead characters (used when interrupted by a CTRL-C). void flush_buffers(flush_buffers_T flush_typeahead) { init_typebuf(); @@ -443,32 +437,32 @@ void beep_flush(void) } } -/* - * The previous contents of the redo buffer is kept in old_redobuffer. - * This is used for the CTRL-O <.> command in insert mode. - */ +// The previous contents of the redo buffer is kept in old_redobuffer. +// This is used for the CTRL-O <.> command in insert mode. void ResetRedobuff(void) { - if (!block_redo) { - free_buff(&old_redobuff); - old_redobuff = redobuff; - redobuff.bh_first.b_next = NULL; + if (block_redo) { + return; } + + free_buff(&old_redobuff); + old_redobuff = redobuff; + redobuff.bh_first.b_next = NULL; } -/* - * Discard the contents of the redo buffer and restore the previous redo - * buffer. - */ +// Discard the contents of the redo buffer and restore the previous redo +// buffer. void CancelRedo(void) { - if (!block_redo) { - free_buff(&redobuff); - redobuff = old_redobuff; - old_redobuff.bh_first.b_next = NULL; - start_stuff(); - while (read_readbuffers(true) != NUL) {} + if (block_redo) { + return; } + + free_buff(&redobuff); + redobuff = old_redobuff; + old_redobuff.bh_first.b_next = NULL; + start_stuff(); + while (read_readbuffers(true) != NUL) {} } /// Save redobuff and old_redobuff to save_redobuff and save_old_redobuff. @@ -481,11 +475,13 @@ void saveRedobuff(save_redo_T *save_redo) old_redobuff.bh_first.b_next = NULL; // Make a copy, so that ":normal ." in a function works. - char *const s = (char *)get_buffcont(&save_redo->sr_redobuff, false); - if (s != NULL) { - add_buff(&redobuff, s, -1L); - xfree(s); + char *const s = get_buffcont(&save_redo->sr_redobuff, false); + if (s == NULL) { + return; } + + add_buff(&redobuff, s, -1L); + xfree(s); } /// Restore redobuff and old_redobuff from save_redobuff and save_old_redobuff. @@ -533,7 +529,7 @@ void AppendToRedobuffLit(const char *str, int len) s--; } if (s > start) { - add_buff(&redobuff, start, (long)(s - start)); + add_buff(&redobuff, start, s - start); } if (*s == NUL || (len >= 0 && s - str >= len)) { @@ -542,7 +538,7 @@ void AppendToRedobuffLit(const char *str, int len) // Handle a special or multibyte character. // Composing chars separately are handled separately. - const int c = mb_cptr2char_adv((const char_u **)&s); + const int c = mb_cptr2char_adv(&s); if (c < ' ' || c == DEL || (*s == NUL && (c == '0' || c == '^'))) { add_char_buff(&redobuff, Ctrl_V); } @@ -565,9 +561,7 @@ void AppendCharToRedobuff(int c) } } -/* - * Append a number to the redo buffer. - */ +// Append a number to the redo buffer. void AppendNumberToRedobuff(long n) { if (!block_redo) { @@ -605,7 +599,7 @@ void stuffReadbuffSpec(const char *s) stuffReadbuffLen(s, 3); s += 3; } else { - int c = mb_cptr2char_adv((const char_u **)&s); + int c = mb_cptr2char_adv(&s); if (c == CAR || c == NL || c == ESC) { c = ' '; } @@ -621,14 +615,40 @@ void stuffcharReadbuff(int c) add_char_buff(&readbuf1, c); } -/* - * Append a number to the stuff buffer. - */ +// Append a number to the stuff buffer. void stuffnumReadbuff(long n) { add_num_buff(&readbuf1, n); } +/// Stuff a string into the typeahead buffer, such that edit() will insert it +/// literally ("literally" true) or interpret is as typed characters. +void stuffescaped(const char *arg, bool literally) +{ + while (*arg != NUL) { + // Stuff a sequence of normal ASCII characters, that's fast. Also + // stuff K_SPECIAL to get the effect of a special key when "literally" + // is true. + const char *const start = arg; + while ((*arg >= ' ' && *arg < DEL) || ((uint8_t)(*arg) == K_SPECIAL + && !literally)) { + arg++; + } + if (arg > start) { + stuffReadbuffLen(start, (arg - start)); + } + + // stuff a single special character + if (*arg != NUL) { + const int c = mb_cptr2char_adv(&arg); + if (literally && ((c < ' ' && c != TAB) || c == DEL)) { + stuffcharReadbuff(Ctrl_V); + } + stuffcharReadbuff(c); + } + } +} + /// Read a character from the redo buffer. Translates K_SPECIAL and /// multibyte characters. /// The redo buffer is left as it is. @@ -649,7 +669,7 @@ static int read_redo(bool init, bool old_redo) if (bp == NULL) { return FAIL; } - p = bp->b_str; + p = (char_u *)bp->b_str; return OK; } if ((c = *p) == NUL) { @@ -670,7 +690,7 @@ static int read_redo(bool init, bool old_redo) } if (*++p == NUL && bp->b_next != NULL) { bp = bp->b_next; - p = bp->b_str; + p = (char_u *)bp->b_str; } buf[i] = (char_u)c; if (i == n - 1) { // last byte of a character @@ -761,11 +781,9 @@ int start_redo(long count, bool old_redo) return OK; } -/* - * Repeat the last insert (R, o, O, a, A, i or I command) by stuffing - * the redo buffer into readbuf2. - * return FAIL for failure, OK otherwise - */ +// Repeat the last insert (R, o, O, a, A, i or I command) by stuffing +// the redo buffer into readbuf2. +// return FAIL for failure, OK otherwise int start_redo_ins(void) { int c; @@ -793,24 +811,24 @@ int start_redo_ins(void) void stop_redo_ins(void) { - block_redo = FALSE; + block_redo = false; } -/* - * Initialize typebuf.tb_buf to point to typebuf_init. - * alloc() cannot be used here: In out-of-memory situations it would - * be impossible to type anything. - */ +// Initialize typebuf.tb_buf to point to typebuf_init. +// alloc() cannot be used here: In out-of-memory situations it would +// be impossible to type anything. static void init_typebuf(void) { - if (typebuf.tb_buf == NULL) { - typebuf.tb_buf = typebuf_init; - typebuf.tb_noremap = noremapbuf_init; - typebuf.tb_buflen = TYPELEN_INIT; - typebuf.tb_len = 0; - typebuf.tb_off = MAXMAPLEN + 4; - typebuf.tb_change_cnt = 1; + if (typebuf.tb_buf != NULL) { + return; } + + typebuf.tb_buf = typebuf_init; + typebuf.tb_noremap = noremapbuf_init; + typebuf.tb_buflen = TYPELEN_INIT; + typebuf.tb_len = 0; + typebuf.tb_off = MAXMAPLEN + 4; + typebuf.tb_change_cnt = 1; } /// @return true when keys cannot be remapped. @@ -849,7 +867,7 @@ int ins_typebuf(char *str, int noremap, int offset, bool nottyped, bool silent) typebuf.tb_change_cnt = 1; } - addlen = (int)STRLEN(str); + addlen = (int)strlen(str); if (offset == 0 && addlen <= typebuf.tb_off) { // Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off] @@ -868,7 +886,7 @@ int ins_typebuf(char *str, int noremap, int offset, bool nottyped, bool silent) // often. int newoff = MAXMAPLEN + 4; int extra = addlen + newoff + 4 * (MAXMAPLEN + 4); - if (typebuf.tb_len > 2147483674 - extra) { + if (typebuf.tb_len > INT_MAX - extra) { // string is getting too long for 32 bit int emsg(_(e_toocompl)); // also calls flush_buffers setcursor(); @@ -917,14 +935,12 @@ int ins_typebuf(char *str, int noremap, int offset, bool nottyped, bool silent) val = RM_NONE; } - /* - * Adjust typebuf.tb_noremap[] for the new characters: - * If noremap == REMAP_NONE or REMAP_SCRIPT: new characters are - * (sometimes) not remappable - * If noremap == REMAP_YES: all the new characters are mappable - * If noremap > 0: "noremap" characters are not remappable, the rest - * mappable - */ + // Adjust typebuf.tb_noremap[] for the new characters: + // If noremap == REMAP_NONE or REMAP_SCRIPT: new characters are + // (sometimes) not remappable + // If noremap == REMAP_YES: all the new characters are mappable + // If noremap > 0: "noremap" characters are not remappable, the rest + // mappable if (noremap == REMAP_SKIP) { nrm = 1; } else if (noremap < 0) { @@ -932,9 +948,9 @@ int ins_typebuf(char *str, int noremap, int offset, bool nottyped, bool silent) } else { nrm = noremap; } - for (i = 0; i < addlen; ++i) { + for (i = 0; i < addlen; i++) { typebuf.tb_noremap[typebuf.tb_off + i + offset] = - (char_u)((--nrm >= 0) ? val : RM_YES); + (uint8_t)((--nrm >= 0) ? val : RM_YES); } // tb_maplen and tb_silent only remember the length of mapped and/or @@ -970,7 +986,7 @@ int ins_char_typebuf(int c, int modifiers) return (int)len; } -/// Return TRUE if the typeahead buffer was changed (while waiting for a +/// Return true if the typeahead buffer was changed (while waiting for a /// character to arrive). Happens when a message was received from a client or /// from feedkeys(). /// But check in a more generic way to avoid trouble: When "typebuf.tb_buf" @@ -986,28 +1002,22 @@ bool typebuf_changed(int tb_change_cnt) || typebuf_was_filled); } -/* - * Return TRUE if there are no characters in the typeahead buffer that have - * not been typed (result from a mapping or come from ":normal"). - */ +/// Return true if there are no characters in the typeahead buffer that have +/// not been typed (result from a mapping or come from ":normal"). int typebuf_typed(void) FUNC_ATTR_PURE { return typebuf.tb_maplen == 0; } -/* - * Return the number of characters that are mapped (or not typed). - */ +// Return the number of characters that are mapped (or not typed). int typebuf_maplen(void) FUNC_ATTR_PURE { return typebuf.tb_maplen; } -/* - * remove "len" characters from typebuf.tb_buf[typebuf.tb_off + offset] - */ +// remove "len" characters from typebuf.tb_buf[typebuf.tb_off + offset] void del_typebuf(int len, int offset) { int i; @@ -1018,21 +1028,14 @@ void del_typebuf(int len, int offset) typebuf.tb_len -= len; - /* - * Easy case: Just increase typebuf.tb_off. - */ + // Easy case: Just increase typebuf.tb_off. if (offset == 0 && typebuf.tb_buflen - (typebuf.tb_off + len) >= 3 * MAXMAPLEN + 3) { typebuf.tb_off += len; - } - /* - * Have to move the characters in typebuf.tb_buf[] and typebuf.tb_noremap[] - */ - else { + } else { + // Have to move the characters in typebuf.tb_buf[] and typebuf.tb_noremap[] i = typebuf.tb_off + offset; - /* - * Leave some extra room at the end to avoid reallocation. - */ + // Leave some extra room at the end to avoid reallocation. if (typebuf.tb_off > MAXMAPLEN) { memmove(typebuf.tb_buf + MAXMAPLEN, typebuf.tb_buf + typebuf.tb_off, (size_t)offset); @@ -1081,10 +1084,8 @@ void del_typebuf(int len, int offset) } } -/* - * Write typed characters to script file. - * If recording is on put the character in the recordbuffer. - */ +// Write typed characters to script file. +// If recording is on put the character in the recordbuffer. static void gotchars(const char_u *chars, size_t len) FUNC_ATTR_NONNULL_ALL { @@ -1135,20 +1136,20 @@ static void gotchars(const char_u *chars, size_t len) /// Only affects recorded characters. void ungetchars(int len) { - if (reg_recording != 0) { - delete_buff_tail(&recordbuff, len); - last_recorded_len -= (size_t)len; + if (reg_recording == 0) { + return; } + + delete_buff_tail(&recordbuff, len); + last_recorded_len -= (size_t)len; } -/* - * Sync undo. Called when typed characters are obtained from the typeahead - * buffer, or when a menu is used. - * Do not sync: - * - In Insert mode, unless cursor key has been used. - * - While reading a script file. - * - When no_u_sync is non-zero. - */ +// Sync undo. Called when typed characters are obtained from the typeahead +// buffer, or when a menu is used. +// Do not sync: +// - In Insert mode, unless cursor key has been used. +// - While reading a script file. +// - When no_u_sync is non-zero. void may_sync_undo(void) { if ((!(State & (MODE_INSERT | MODE_CMDLINE)) || arrow_used) @@ -1157,9 +1158,7 @@ void may_sync_undo(void) } } -/* - * Make "typebuf" empty and allocate new buffers. - */ +// Make "typebuf" empty and allocate new buffers. void alloc_typebuf(void) { typebuf.tb_buf = xmalloc(TYPELEN_INIT); @@ -1175,9 +1174,7 @@ void alloc_typebuf(void) } } -/* - * Free the buffers of "typebuf". - */ +// Free the buffers of "typebuf". void free_typebuf(void) { if (typebuf.tb_buf == typebuf_init) { @@ -1192,10 +1189,8 @@ void free_typebuf(void) } } -/* - * When doing ":so! file", the current typeahead needs to be saved, and - * restored when "file" has been read completely. - */ +// When doing ":so! file", the current typeahead needs to be saved, and +// restored when "file" has been read completely. static typebuf_T saved_typebuf[NSCRIPT]; void save_typebuf(void) @@ -1219,9 +1214,7 @@ static bool can_get_old_char(void) return old_char != -1 && (old_KeyStuffed || stuff_empty()); } -/* - * Save all three kinds of typeahead, so that the user must type at a prompt. - */ +// Save all three kinds of typeahead, so that the user must type at a prompt. void save_typeahead(tasave_T *tp) { tp->save_typebuf = typebuf; @@ -1237,10 +1230,8 @@ void save_typeahead(tasave_T *tp) readbuf2.bh_first.b_next = NULL; } -/* - * Restore the typeahead to what it was before calling save_typeahead(). - * The allocated memory is freed, can only be called once! - */ +// Restore the typeahead to what it was before calling save_typeahead(). +// The allocated memory is freed, can only be called once! void restore_typeahead(tasave_T *tp) { if (tp->typebuf_valid) { @@ -1260,7 +1251,7 @@ void restore_typeahead(tasave_T *tp) /// Open a new script file for the ":source!" command. /// /// @param directly when true execute directly -void openscript(char_u *name, bool directly) +void openscript(char *name, bool directly) { if (curscript + 1 == NSCRIPT) { emsg(_(e_nesting)); @@ -1284,7 +1275,7 @@ void openscript(char_u *name, bool directly) // use NameBuff for expanded name expand_env(name, NameBuff, MAXPATHL); int error; - if ((scriptin[curscript] = file_open_new(&error, (char *)NameBuff, + if ((scriptin[curscript] = file_open_new(&error, NameBuff, kFileReadOnly, 0)) == NULL) { semsg(_(e_notopen_2), name, os_strerror(error)); if (curscript) { @@ -1294,12 +1285,10 @@ void openscript(char_u *name, bool directly) } save_typebuf(); - /* - * Execute the commands from the file right now when using ":source!" - * after ":global" or ":argdo" or in a loop. Also when another command - * follows. This means the display won't be updated. Don't do this - * always, "make test" would fail. - */ + // Execute the commands from the file right now when using ":source!" + // after ":global" or ":argdo" or in a loop. Also when another command + // follows. This means the display won't be updated. Don't do this + // always, "make test" would fail. if (directly) { oparg_T oa; int oldcurscript; @@ -1328,9 +1317,7 @@ void openscript(char_u *name, bool directly) } } -/* - * Close the currently active input script. - */ +// Close the currently active input script. static void closescript(void) { free_typebuf(); @@ -1353,9 +1340,7 @@ void close_all_scripts(void) #endif -/* - * Return TRUE when reading keys from a script file. - */ +/// Return true when reading keys from a script file. int using_script(void) FUNC_ATTR_PURE { @@ -1434,10 +1419,8 @@ int vgetc(void) garbage_collect(false); } - /* - * If a character was put back with vungetc, it was already processed. - * Return it directly. - */ + // If a character was put back with vungetc, it was already processed. + // Return it directly. if (can_get_old_char()) { c = old_char; old_char = -1; @@ -1610,11 +1593,9 @@ int vgetc(void) last_vgetc_recorded_len = last_recorded_len; } - /* - * In the main loop "may_garbage_collect" can be set to do garbage - * collection in the first next vgetc(). It's disabled after that to - * avoid internally used Lists and Dicts to be freed. - */ + // In the main loop "may_garbage_collect" can be set to do garbage + // collection in the first next vgetc(). It's disabled after that to + // avoid internally used Lists and Dicts to be freed. may_garbage_collect = false; // Execute Lua on_key callbacks. @@ -1623,10 +1604,8 @@ int vgetc(void) return c; } -/* - * Like vgetc(), but never return a NUL when called recursively, get a key - * directly from the user (ignoring typeahead). - */ +// Like vgetc(), but never return a NUL when called recursively, get a key +// directly from the user (ignoring typeahead). int safe_vgetc(void) { int c; @@ -1638,10 +1617,8 @@ int safe_vgetc(void) return c; } -/* - * Like safe_vgetc(), but loop to handle K_IGNORE. - * Also ignore scrollbar events. - */ +// Like safe_vgetc(), but loop to handle K_IGNORE. +// Also ignore scrollbar events. int plain_vgetc(void) { int c; @@ -1654,12 +1631,10 @@ int plain_vgetc(void) return c; } -/* - * Check if a character is available, such that vgetc() will not block. - * If the next character is a special character or multi-byte, the returned - * character is not valid!. - * Returns NUL if no character is available. - */ +// Check if a character is available, such that vgetc() will not block. +// If the next character is a special character or multi-byte, the returned +// character is not valid!. +// Returns NUL if no character is available. int vpeekc(void) { if (can_get_old_char()) { @@ -1668,11 +1643,9 @@ int vpeekc(void) return vgetorpeek(false); } -/* - * Check if any character is available, also half an escape sequence. - * Trick: when no typeahead found, but there is something in the typeahead - * buffer, it must be an ESC that is recognized as the start of a key code. - */ +// Check if any character is available, also half an escape sequence. +// Trick: when no typeahead found, but there is something in the typeahead +// buffer, it must be an ESC that is recognized as the start of a key code. int vpeekc_any(void) { int c; @@ -1684,10 +1657,8 @@ int vpeekc_any(void) return c; } -/* - * Call vpeekc() without causing anything to be mapped. - * Return TRUE if a character is available, FALSE otherwise. - */ +// Call vpeekc() without causing anything to be mapped. +// Return true if a character is available, false otherwise. int char_avail(void) { int retval; @@ -1708,9 +1679,10 @@ static void getchar_common(typval_T *argvars, typval_T *rettv) no_mapping++; allow_keys++; for (;;) { - // 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 (msg_col > 0) { + // Position the cursor. Needed after a message that ends in a space. + ui_cursor_goto(msg_row, msg_col); + } if (argvars[0].v_type == VAR_UNKNOWN) { // getchar(): blocking wait. @@ -1718,7 +1690,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv) if (!char_avail()) { // flush output before waiting ui_flush(); - (void)os_inchar(NULL, 0, -1, 0, main_loop.events); + (void)os_inchar(NULL, 0, -1, typebuf.tb_change_cnt, main_loop.events); if (!multiqueue_empty(main_loop.events)) { state_handle_k_event(); continue; @@ -1748,11 +1720,6 @@ static void getchar_common(typval_T *argvars, typval_T *rettv) no_mapping--; allow_keys--; - if (!ui_has_messages()) { - // redraw the screen after getchar() - update_screen(CLEAR); - } - set_vim_var_nr(VV_MOUSE_WIN, 0); set_vim_var_nr(VV_MOUSE_WINID, 0); set_vim_var_nr(VV_MOUSE_LNUM, 0); @@ -1760,26 +1727,26 @@ static void getchar_common(typval_T *argvars, typval_T *rettv) rettv->vval.v_number = n; if (n != 0 && (IS_SPECIAL(n) || mod_mask != 0)) { - char_u temp[10]; // modifier: 3, mbyte-char: 6, NUL: 1 + char temp[10]; // modifier: 3, mbyte-char: 6, NUL: 1 int i = 0; // Turn a special key into three bytes, plus modifier. if (mod_mask != 0) { - temp[i++] = K_SPECIAL; - temp[i++] = KS_MODIFIER; - temp[i++] = (char_u)mod_mask; + temp[i++] = (char)K_SPECIAL; + temp[i++] = (char)KS_MODIFIER; + temp[i++] = (char)mod_mask; } if (IS_SPECIAL(n)) { - temp[i++] = K_SPECIAL; - temp[i++] = (char_u)K_SECOND(n); - temp[i++] = K_THIRD(n); + temp[i++] = (char)K_SPECIAL; + temp[i++] = (char)K_SECOND(n); + temp[i++] = (char)K_THIRD(n); } else { - i += utf_char2bytes((int)n, (char *)temp + i); + i += utf_char2bytes((int)n, temp + i); } assert(i < 10); temp[i++] = NUL; rettv->v_type = VAR_STRING; - rettv->vval.v_string = (char *)vim_strsave(temp); + rettv->vval.v_string = xstrdup(temp); if (is_mouse_key((int)n)) { int row = mouse_row; @@ -1810,33 +1777,35 @@ static void getchar_common(typval_T *argvars, typval_T *rettv) } /// "getchar()" function -void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_getchar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { getchar_common(argvars, rettv); } /// "getcharstr()" function -void f_getcharstr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_getcharstr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { getchar_common(argvars, rettv); - if (rettv->v_type == VAR_NUMBER) { - char temp[7]; // mbyte-char: 6, NUL: 1 - const varnumber_T n = rettv->vval.v_number; - int i = 0; + if (rettv->v_type != VAR_NUMBER) { + return; + } - if (n != 0) { - i += utf_char2bytes((int)n, (char *)temp); - } - assert(i < 7); - temp[i++] = NUL; - rettv->v_type = VAR_STRING; - rettv->vval.v_string = xstrdup(temp); + char temp[7]; // mbyte-char: 6, NUL: 1 + const varnumber_T n = rettv->vval.v_number; + int i = 0; + + if (n != 0) { + i += utf_char2bytes((int)n, (char *)temp); } + assert(i < 7); + temp[i++] = NUL; + rettv->v_type = VAR_STRING; + rettv->vval.v_string = xstrdup(temp); } /// "getcharmod()" function -void f_getcharmod(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_getcharmod(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = mod_mask; } @@ -1881,7 +1850,7 @@ static bool at_ins_compl_key(void) c = p[3] & 0x1f; } return (ctrl_x_mode_not_default() && vim_is_ctrl_x_key(c)) - || ((compl_cont_status & CONT_LOCAL) && (c == Ctrl_N || c == Ctrl_P)); + || (compl_status_local() && (c == Ctrl_N || c == Ctrl_P)); } /// Check if typebuf.tb_buf[] contains a modifier plus key that can be changed @@ -1943,7 +1912,7 @@ static int check_simplify_modifier(int max_offset) /// - When there is no match yet, return map_r |