From 39f8aaeb815c2e31cffec12ef36ad4f25df91602 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Fri, 24 Jan 2020 09:48:58 +0100 Subject: fix(status): handle unprintable chars in the statusline --- src/nvim/charset.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 5aec9ccf9d..c4c7c5f387 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -354,14 +354,15 @@ size_t transstr_len(const char *const s, bool untab) /// @param[in] untab remove tab characters /// /// @return length of the resulting string, without the NUL byte. -size_t transstr_buf(const char *const s, char *const buf, const size_t len, bool untab) +size_t transstr_buf(const char *const s, const ssize_t slen, char *const buf, const size_t buflen, + bool untab) FUNC_ATTR_NONNULL_ALL { const char *p = s; char *buf_p = buf; - char *const buf_e = buf_p + len - 1; + char *const buf_e = buf_p + buflen - 1; - while (*p != NUL && buf_p < buf_e) { + while ((slen < 0 || (p - s) < slen) && *p != NUL && buf_p < buf_e) { const size_t l = (size_t)utfc_ptr2len(p); if (l > 1) { if (buf_p + l > buf_e) { @@ -416,7 +417,7 @@ char *transstr(const char *const s, bool untab) // multi-byte characters. const size_t len = transstr_len(s, untab) + 1; char *const buf = xmalloc(len); - transstr_buf(s, buf, len, untab); + transstr_buf(s, -1, buf, len, untab); return buf; } @@ -431,7 +432,7 @@ size_t kv_transstr(StringBuilder *str, const char *const s, bool untab) // multi-byte characters. const size_t len = transstr_len(s, untab); kv_ensure_space(*str, len + 1); - transstr_buf(s, str->items + str->size, len + 1, untab); + transstr_buf(s, -1, str->items + str->size, len + 1, untab); str->size += len; // do not include NUL byte return len; } -- cgit From 0326ef2f41a5c18c6cfd2c1b1dda95f7b309a5c4 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 17 Feb 2023 07:15:24 +0800 Subject: vim-patch:9.0.1314: :messages behavior depends on 'fileformat' of current buffer (#22286) Problem: :messages behavior depends on 'fileformat' of current buffer. Solution: Pass the buffer pointer to where it is used. (Mirko Ceroni, closes vim/vim#11995) https://github.com/vim/vim/commit/1d87e11a1ef201b26ed87585fba70182ad0c468a Co-authored-by: cero1988 --- src/nvim/charset.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index c4c7c5f387..1cfb5350f3 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -547,7 +547,6 @@ char *transchar(int c) } char_u *transchar_buf(const buf_T *buf, int c) - FUNC_ATTR_NONNULL_ALL { int i = 0; if (IS_SPECIAL(c)) { @@ -571,21 +570,34 @@ char_u *transchar_buf(const buf_T *buf, int c) return transchar_charbuf; } -/// Like transchar(), but called with a byte instead of a character +/// Like transchar(), but called with a byte instead of a character. /// -/// Checks for an illegal UTF-8 byte. +/// Checks for an illegal UTF-8 byte. Uses 'fileformat' of the current buffer. /// /// @param[in] c Byte to translate. /// /// @return pointer to translated character in transchar_charbuf. char_u *transchar_byte(const int c) FUNC_ATTR_WARN_UNUSED_RESULT +{ + return transchar_byte_buf(curbuf, c); +} + +/// Like transchar_buf(), but called with a byte instead of a character. +/// +/// Checks for an illegal UTF-8 byte. Uses 'fileformat' of "buf", unless it is NULL. +/// +/// @param[in] c Byte to translate. +/// +/// @return pointer to translated character in transchar_charbuf. +char_u *transchar_byte_buf(const buf_T *buf, const int c) + FUNC_ATTR_WARN_UNUSED_RESULT { if (c >= 0x80) { - transchar_nonprint(curbuf, transchar_charbuf, c); + transchar_nonprint(buf, transchar_charbuf, c); return transchar_charbuf; } - return (char_u *)transchar(c); + return transchar_buf(buf, c); } /// Convert non-printable characters to 2..4 printable ones @@ -598,12 +610,11 @@ char_u *transchar_byte(const int c) /// @param[in] c Character to convert. NUL is assumed to be NL according to /// `:h NL-used-for-NUL`. void transchar_nonprint(const buf_T *buf, char_u *charbuf, int c) - FUNC_ATTR_NONNULL_ALL { if (c == NL) { // we use newline in place of a NUL c = NUL; - } else if ((c == CAR) && (get_fileformat(buf) == EOL_MAC)) { + } else if (buf != NULL && c == CAR && get_fileformat(buf) == EOL_MAC) { // we use CR in place of NL in this case c = NL; } -- cgit From 166b149d5b473f277c63e64ced03c40df44ac3c9 Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 27 Feb 2023 16:30:32 +0100 Subject: refactor(build): remove unused stdlib function and include checks In addition: merge some checks for the same feature into one test_compile. This reduces the total number of test compiles which speeds up the cmake configure stage. --- src/nvim/charset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 1cfb5350f3..bf18d110c0 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1446,7 +1446,7 @@ long getdigits_long(char **pp, bool strict, long def) int32_t getdigits_int32(char **pp, bool strict, long def) { intmax_t number = getdigits(pp, strict, def); -#if SIZEOF_INTMAX_T > SIZEOF_INT32_T +#if SIZEOF_INTMAX_T > 4 if (strict) { assert(number >= INT32_MIN && number <= INT32_MAX); } else if (!(number >= INT32_MIN && number <= INT32_MAX)) { -- cgit From 419819b6245e120aba8897e3ddea711b2cd0246c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 5 Mar 2023 09:18:42 +0800 Subject: vim-patch:9.0.1380: CTRL-X on 2**64 subtracts two (#22530) Problem: CTRL-X on 2**64 subtracts two. (James McCoy) Solution: Correct computation for large number. (closes vim/vim#12103) https://github.com/vim/vim/commit/5fb78c3fa5c996c08a65431d698bd2c251eef5c7 Co-authored-by: Bram Moolenaar --- src/nvim/charset.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index bf18d110c0..b792ae5ece 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1500,9 +1500,10 @@ bool vim_isblankline(char *lbuf) /// @param strict If true, fail if the number has unexpected trailing /// alphanumeric chars: *len is set to 0 and nothing else is /// returned. +/// @param overflow When not NULL, set to true for overflow. void vim_str2nr(const char *const start, int *const prep, int *const len, const int what, varnumber_T *const nptr, uvarnumber_T *const unptr, const int maxlen, - const bool strict) + const bool strict, bool *const overflow) FUNC_ATTR_NONNULL_ARG(1) { const char *ptr = start; @@ -1626,6 +1627,9 @@ void vim_str2nr(const char *const start, int *const prep, int *const len, const un = (base) * un + digit; \ } else { \ un = UVARNUMBER_MAX; \ + if (overflow != NULL) { \ + *overflow = true; \ + } \ } \ ptr++; \ } \ @@ -1664,12 +1668,18 @@ vim_str2nr_proceed: // avoid ubsan error for overflow if (un > VARNUMBER_MAX) { *nptr = VARNUMBER_MIN; + if (overflow != NULL) { + *overflow = true; + } } else { *nptr = -(varnumber_T)un; } } else { if (un > VARNUMBER_MAX) { un = VARNUMBER_MAX; + if (overflow != NULL) { + *overflow = true; + } } *nptr = (varnumber_T)un; } -- cgit From d6ecead36406233cc56353dd05f3380f0497630f Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 14 Mar 2023 11:49:46 +0100 Subject: refactor(screen): screen.c delenda est drawscreen.c vs screen.c makes absolutely no sense. The screen exists only to draw upon it, therefore helper functions are distributed randomly between screen.c and the file that does the redrawing. In addition screen.c does a lot of drawing on the screen. It made more sense for vim/vim as our grid.c is their screen.c Not sure if we want to dump all the code for option chars into optionstr.c, so keep these in a optionchar.c for now. --- src/nvim/charset.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index b792ae5ece..a3aa6783ee 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -660,6 +660,17 @@ size_t transchar_hex(char *const buf, const int c) return i; } +/// Mirror text "str" for right-left displaying. +/// Only works for single-byte characters (e.g., numbers). +void rl_mirror_ascii(char *str) +{ + for (char *p1 = str, *p2 = str + strlen(str) - 1; p1 < p2; p1++, p2--) { + char t = *p1; + *p1 = *p2; + *p2 = t; + } +} + /// Convert the lower 4 bits of byte "c" to its hex character /// /// Lower case letters are used to avoid the confusion of being 0xf1 or -- cgit From d5f6176e6dc4b4e12fc5061ca6e87f4af533e46a Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Sat, 1 Apr 2023 02:49:51 +0200 Subject: refactor: add const and remove unnecessary casts (#22841) --- src/nvim/charset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index a3aa6783ee..63459495f8 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -755,7 +755,7 @@ int ptr2cells(const char *p_in) /// @param s /// /// @return number of character cells. -int vim_strsize(char *s) +int vim_strsize(const char *s) { return vim_strnsize(s, MAXCOL); } @@ -769,7 +769,7 @@ int vim_strsize(char *s) /// @param len /// /// @return Number of character cells. -int vim_strnsize(char *s, int len) +int vim_strnsize(const char *s, int len) { assert(s != NULL); int size = 0; -- cgit From d510bfbc8e447b1a60d5ec7faaa8f440eb4ef56f Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Sun, 2 Apr 2023 10:11:42 +0200 Subject: refactor: remove char_u (#22829) Closes https://github.com/neovim/neovim/issues/459 --- src/nvim/charset.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 63459495f8..2be8ccc456 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -55,7 +55,7 @@ static bool chartab_initialized = false; ((chartab)[(unsigned)(c) >> 6] & (1ull << ((c) & 0x3f))) // Table used below, see init_chartab() for an explanation -static char_u g_chartab[256]; +static uint8_t g_chartab[256]; // Flags for g_chartab[]. #define CT_CELL_MASK 0x07 ///< mask: nr of display cells (1, 2 or 4) @@ -286,7 +286,7 @@ void trans_characters(char *buf, int bufsize) if ((trs_len = utfc_ptr2len(buf)) > 1) { len -= trs_len; } else { - trs = (char *)transchar_byte((uint8_t)(*buf)); + trs = transchar_byte((uint8_t)(*buf)); trs_len = (int)strlen(trs); if (trs_len > 1) { @@ -532,7 +532,7 @@ char *str_foldcase(char *str, int orglen, char *buf, int buflen) // Does NOT work for multi-byte characters, c must be <= 255. // Also doesn't work for the first byte of a multi-byte, "c" must be a // character! -static char_u transchar_charbuf[11]; +static uint8_t transchar_charbuf[11]; /// Translate a character into a printable one, leaving printable ASCII intact /// @@ -543,10 +543,10 @@ static char_u transchar_charbuf[11]; /// @return translated character into a static buffer. char *transchar(int c) { - return (char *)transchar_buf(curbuf, c); + return transchar_buf(curbuf, c); } -char_u *transchar_buf(const buf_T *buf, int c) +char *transchar_buf(const buf_T *buf, int c) { int i = 0; if (IS_SPECIAL(c)) { @@ -560,14 +560,14 @@ char_u *transchar_buf(const buf_T *buf, int c) if ((!chartab_initialized && (c >= ' ' && c <= '~')) || ((c <= 0xFF) && vim_isprintc_strict(c))) { // printable character - transchar_charbuf[i] = (char_u)c; + transchar_charbuf[i] = (uint8_t)c; transchar_charbuf[i + 1] = NUL; } else if (c <= 0xFF) { - transchar_nonprint(buf, transchar_charbuf + i, c); + transchar_nonprint(buf, (char *)transchar_charbuf + i, c); } else { transchar_hex((char *)transchar_charbuf + i, c); } - return transchar_charbuf; + return (char *)transchar_charbuf; } /// Like transchar(), but called with a byte instead of a character. @@ -577,7 +577,7 @@ char_u *transchar_buf(const buf_T *buf, int c) /// @param[in] c Byte to translate. /// /// @return pointer to translated character in transchar_charbuf. -char_u *transchar_byte(const int c) +char *transchar_byte(const int c) FUNC_ATTR_WARN_UNUSED_RESULT { return transchar_byte_buf(curbuf, c); @@ -590,12 +590,12 @@ char_u *transchar_byte(const int c) /// @param[in] c Byte to translate. /// /// @return pointer to translated character in transchar_charbuf. -char_u *transchar_byte_buf(const buf_T *buf, const int c) +char *transchar_byte_buf(const buf_T *buf, const int c) FUNC_ATTR_WARN_UNUSED_RESULT { if (c >= 0x80) { - transchar_nonprint(buf, transchar_charbuf, c); - return transchar_charbuf; + transchar_nonprint(buf, (char *)transchar_charbuf, c); + return (char *)transchar_charbuf; } return transchar_buf(buf, c); } @@ -609,7 +609,7 @@ char_u *transchar_byte_buf(const buf_T *buf, const int c) /// at least 5 bytes (conversion result + NUL). /// @param[in] c Character to convert. NUL is assumed to be NL according to /// `:h NL-used-for-NUL`. -void transchar_nonprint(const buf_T *buf, char_u *charbuf, int c) +void transchar_nonprint(const buf_T *buf, char *charbuf, int c) { if (c == NL) { // we use newline in place of a NUL @@ -622,12 +622,12 @@ void transchar_nonprint(const buf_T *buf, char_u *charbuf, int c) if (dy_flags & DY_UHEX || c > 0x7f) { // 'display' has "uhex" - transchar_hex((char *)charbuf, c); + transchar_hex(charbuf, c); } else { // 0x00 - 0x1f and 0x7f charbuf[0] = '^'; // DEL displayed as ^? - charbuf[1] = (char_u)(c ^ 0x40); + charbuf[1] = (char)(uint8_t)(c ^ 0x40); charbuf[2] = NUL; } -- cgit From 9408f2dcf7cade2631688300e9b58eed6bc5219a Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Fri, 7 Apr 2023 19:40:57 +0200 Subject: refactor: remove redundant const char * casts --- src/nvim/charset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 2be8ccc456..545002a197 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -389,7 +389,7 @@ size_t transstr_buf(const char *const s, const ssize_t slen, char *const buf, co } else if (*p == TAB && !untab) { *buf_p++ = *p++; } else { - const char *const tb = (const char *)transchar_byte((uint8_t)(*p++)); + const char *const tb = transchar_byte((uint8_t)(*p++)); const size_t tb_len = strlen(tb); if (buf_p + tb_len > buf_e) { break; // Exceeded `buf` size. -- cgit From 3b0df1780e2c8526bda5dead18ee7cc45925caba Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Wed, 26 Apr 2023 23:23:44 +0200 Subject: refactor: uncrustify Notable changes: replace all infinite loops to `while(true)` and remove `int` from `unsigned int`. --- src/nvim/charset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 545002a197..3d4e0abda9 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -990,7 +990,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en && *get_showbreak_value(wp) == NUL && !wp->w_p_bri && !cts.cts_has_virt_text) { - for (;;) { + while (true) { head = 0; int c = (uint8_t)(*ptr); @@ -1034,7 +1034,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en MB_PTR_ADV(ptr); } } else { - for (;;) { + while (true) { // A tab gets expanded, depending on the current column // Other things also take up space. head = 0; -- cgit From 7e70a1e44b223a51f4d8f06b9fe4c4ef77601f83 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 4 May 2023 13:43:23 +0800 Subject: vim-patch:9.0.0138: not enough characters accepted for 'spellfile' Problem: Not enough characters accepted for 'spellfile'. Solution: Add vim_is_fname_char() and use it for 'spellfile'. https://github.com/vim/vim/commit/bc49c5f48f89c2d6f4d88ee77f44a11d68293be3 Cherry-pick related doc update from Vim runtime. Co-authored-by: Bram Moolenaar --- src/nvim/charset.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 3d4e0abda9..8cae831881 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -858,8 +858,10 @@ bool vim_iswordp_buf(const char *const p, buf_T *const buf) return vim_iswordc_buf(c, buf); } -/// Check that "c" is a valid file-name character. +/// Check that "c" is a valid file-name character as specified with the +/// 'isfname' option. /// Assume characters above 0x100 are valid (multi-byte). +/// To be used for commands like "gf". /// /// @param c character to check bool vim_isfilec(int c) @@ -868,6 +870,14 @@ bool vim_isfilec(int c) return c >= 0x100 || (c > 0 && (g_chartab[c] & CT_FNAME_CHAR)); } +/// Check if "c" is a valid file-name character, including characters left +/// out of 'isfname' to make "gf" work, such as comma, space, '@', etc. +bool vim_is_fname_char(int c) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT +{ + return vim_isfilec(c) || c == ',' || c == ' ' || c == '@'; +} + /// Check that "c" is a valid file-name character or a wildcard character /// Assume characters above 0x100 are valid (multi-byte). /// Explicitly interpret ']' as a wildcard character as path_has_wildcard("]") -- cgit From 0c7fa3bdcc3761cc851ea0ac37bf692b990044cc Mon Sep 17 00:00:00 2001 From: Ibby <33922797+SleepySwords@users.noreply.github.com> Date: Sun, 19 Mar 2023 20:31:52 +1100 Subject: fix(ui): fix multi-byte characters highlight in virtual text This also fixes insert cursor position around virtual text vim-patch:9.0.0132: multi-byte characters in virtual text not handled correctly Problem: Multi-byte characters in virtual text not handled correctly. Solution: Count screen cells instead of bytes. https://github.com/vim/vim/commit/09ff4b54fb86a64390ba9c609853c6410ea6197c --- src/nvim/charset.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 8cae831881..48a38dd3d3 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1079,8 +1079,10 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en } if (cursor != NULL) { - // cursor is after inserted text - vcol += cts.cts_cur_text_width; + if ((State & MODE_INSERT) == 0) { + // cursor is after inserted text + vcol += cts.cts_cur_text_width; + } if ((*ptr == TAB) && (State & MODE_NORMAL) && !wp->w_p_list -- cgit From 43c2eaada220d5e7d44fa9086655b00ee3e5fbb5 Mon Sep 17 00:00:00 2001 From: Ibby <33922797+SleepySwords@users.noreply.github.com> Date: Sun, 26 Mar 2023 14:49:09 +1100 Subject: vim-patch:9.0.0179: cursor pos wrong with wrapping virtual text in empty line Problem: Cursor position wrong with wrapping virtual text in empty line. Solution: Adjust handling of an empty line. (closes vim/vim#10875) https://github.com/vim/vim/commit/49a90792d950c51608d0459ef8699fe921070718 Co-authored-by: Bram Moolenaar --- src/nvim/charset.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 48a38dd3d3..3b48392d49 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -989,6 +989,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en } chartabsize_T cts; + bool on_NUL = false; init_chartabsize_arg(&cts, wp, pos->lnum, 0, line, line); // This function is used very often, do some speed optimizations. @@ -1054,6 +1055,10 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en if (*cts.cts_ptr == NUL) { // NUL at end of line only takes one column incr = 1; + if (cts.cts_cur_text_width > 0) { + incr = cts.cts_cur_text_width; + } + on_NUL = true; break; } @@ -1079,8 +1084,8 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en } if (cursor != NULL) { - if ((State & MODE_INSERT) == 0) { - // cursor is after inserted text + if ((State & MODE_INSERT) == 0 && !on_NUL) { + // cursor is after inserted text, unless on the NUL vcol += cts.cts_cur_text_width; } if ((*ptr == TAB) -- cgit From dee3af2122d5072d351551ef023d2c177334b332 Mon Sep 17 00:00:00 2001 From: Ibby <33922797+SleepySwords@users.noreply.github.com> Date: Sun, 26 Mar 2023 16:09:09 +1100 Subject: vim-patch:9.0.0178: cursor position wrong with virtual text before Tab Problem: Cursor position wrong with virtual text before Tab. Solution: Use the byte length, not the cell with, to compare the column. Correct tab size after text prop. (closes vim/vim#10866) https://github.com/vim/vim/commit/e428fa04a758cc87ea580c856a796e58e407504b Co-authored-by: Bram Moolenaar --- src/nvim/charset.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 3b48392d49..24267ebd50 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1084,10 +1084,6 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en } if (cursor != NULL) { - if ((State & MODE_INSERT) == 0 && !on_NUL) { - // cursor is after inserted text, unless on the NUL - vcol += cts.cts_cur_text_width; - } if ((*ptr == TAB) && (State & MODE_NORMAL) && !wp->w_p_list @@ -1096,6 +1092,10 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en // cursor at end *cursor = vcol + incr - 1; } else { + if ((State & MODE_INSERT) == 0 && !on_NUL) { + // cursor is after inserted text, unless on the NUL + vcol += cts.cts_cur_text_width; + } // cursor at start *cursor = vcol + head; } -- cgit From be273c3a23cf65665e843cfb13fd5319657cc5c2 Mon Sep 17 00:00:00 2001 From: Ibby <33922797+SleepySwords@users.noreply.github.com> Date: Tue, 28 Mar 2023 01:23:21 +1100 Subject: vim-patch:9.0.0205: cursor in wrong position when inserting after virtual text Problem: Cursor in wrong position when inserting after virtual text. (Ben Jackson) Solution: Put the cursor after the virtual text, where the text will be inserted. (closes vim/vim#10914) https://github.com/vim/vim/commit/28c9f895716cfa8f1220bc41b72a534c0e10cabe Co-authored-by: Bram Moolenaar --- src/nvim/charset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 24267ebd50..2917bb31ee 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1092,7 +1092,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en // cursor at end *cursor = vcol + incr - 1; } else { - if ((State & MODE_INSERT) == 0 && !on_NUL) { + if (((State & MODE_INSERT) == 0 || !cts.cts_has_right_gravity) && !on_NUL) { // cursor is after inserted text, unless on the NUL vcol += cts.cts_cur_text_width; } -- cgit From a78fd18ed92d7474d10b5640dcf7a15728d2e03a Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 9 May 2023 14:26:03 +0200 Subject: fix(extmark): fix cursor position with both left and right gravity inline text --- src/nvim/charset.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 2917bb31ee..49890a460a 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1053,11 +1053,8 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en // make sure we don't go past the end of the line if (*cts.cts_ptr == NUL) { - // NUL at end of line only takes one column - incr = 1; - if (cts.cts_cur_text_width > 0) { - incr = cts.cts_cur_text_width; - } + // NUL at end of line only takes one column, unless there is virtual text + incr = MAX(1, cts.cts_cur_text_width_left + cts.cts_cur_text_width_right); on_NUL = true; break; } @@ -1092,9 +1089,12 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en // cursor at end *cursor = vcol + incr - 1; } else { - if (((State & MODE_INSERT) == 0 || !cts.cts_has_right_gravity) && !on_NUL) { + if (!on_NUL) { // cursor is after inserted text, unless on the NUL - vcol += cts.cts_cur_text_width; + vcol += cts.cts_cur_text_width_left; + if ((State & MODE_INSERT) == 0) { + vcol += cts.cts_cur_text_width_right; + } } // cursor at start *cursor = vcol + head; -- cgit From cd6458123fb4859e47ffcd144ebbddf389a09610 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 26 Jun 2023 11:52:52 +0800 Subject: fix(charset): fix wrong display of 0xffff (#24158) --- src/nvim/charset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 49890a460a..c2745a66a0 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -645,8 +645,8 @@ size_t transchar_hex(char *const buf, const int c) size_t i = 0; buf[i++] = '<'; - if (c > 255) { - if (c > 255 * 256) { + if (c > 0xFF) { + if (c > 0xFFFF) { buf[i++] = (char)nr2hex((unsigned)c >> 20); buf[i++] = (char)nr2hex((unsigned)c >> 16); } -- cgit From 0ce39108684ed7b6af03e47da0a4e0a022e41936 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 13 Jul 2023 08:32:17 +0800 Subject: fix(ui): cursor pos with left gravity inline virt_text at eol (#24329) Problem: Cursor is not after inline virtual text with left gravity when inserting after the end of the line. Solution: Add width of inline virtual text with left gravity to cursor virtcol in Insert mode even if on a NUL. --- src/nvim/charset.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index c2745a66a0..c6efb4b3b4 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1089,12 +1089,11 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en // cursor at end *cursor = vcol + incr - 1; } else { - if (!on_NUL) { - // cursor is after inserted text, unless on the NUL + if (!on_NUL || !(State & MODE_NORMAL)) { vcol += cts.cts_cur_text_width_left; - if ((State & MODE_INSERT) == 0) { - vcol += cts.cts_cur_text_width_right; - } + } + if (!on_NUL && (State & MODE_NORMAL)) { + vcol += cts.cts_cur_text_width_right; } // cursor at start *cursor = vcol + head; -- cgit From 19d7fb8efeaeb84bc639282de1510b7e8962d49a Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 18 Aug 2023 06:20:06 +0800 Subject: vim-patch:9.0.1734: :runtime completion fails for multiple args (#24767) Problem: :runtime completion fails for multiple args Solution: Make it work closes: vim/vim#12616 https://github.com/vim/vim/commit/be5cdd1d634c2dfc7e415499fb18f4d246a8721c --- src/nvim/charset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index c6efb4b3b4..4030d818c8 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1376,7 +1376,7 @@ char *skiptowhite(const char *p) /// @param p /// /// @return Pointer to the next whitespace character. -char *skiptowhite_esc(char *p) +char *skiptowhite_esc(const char *p) FUNC_ATTR_PURE { while (*p != ' ' && *p != '\t' && *p != NUL) { @@ -1385,7 +1385,7 @@ char *skiptowhite_esc(char *p) } p++; } - return p; + return (char *)p; } /// Skip over text until '\n' or NUL. -- cgit From a1d71ad55e0f7149f284178b2d04ac78263b09ff Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 23 Aug 2023 10:12:00 +0800 Subject: vim-patch:9.0.1783: Display issues with virt text smoothscroll and showbreak Problem: Wrong display with wrapping virtual text or unprintable chars, 'showbreak' and 'smoothscroll'. Solution: Don't skip cells taken by 'showbreak' in screen lines before "w_skipcol". Combined "n_skip" and "skip_cells". closes: vim/vim#12597 https://github.com/vim/vim/commit/b557f4898208105b674df605403cac1b1292707b --- src/nvim/charset.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 4030d818c8..d11cbddccf 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -991,6 +991,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en chartabsize_T cts; bool on_NUL = false; init_chartabsize_arg(&cts, wp, pos->lnum, 0, line, line); + cts.cts_max_head_vcol = -1; // This function is used very often, do some speed optimizations. // When 'list', 'linebreak', 'showbreak' and 'breakindent' are not set -- cgit From cefd774fac76b91f5368833555818c80c992c3b1 Mon Sep 17 00:00:00 2001 From: bfredl Date: Thu, 24 Aug 2023 15:14:23 +0200 Subject: refactor(memline): distinguish mutating uses of ml_get_buf() ml_get_buf() takes a third parameters to indicate whether the caller wants to mutate the memline data in place. However the vast majority of the call sites is using this function just to specify a buffer but without any mutation. This makes it harder to grep for the places which actually perform mutation. Solution: Remove the bool param from ml_get_buf(). it now works like ml_get() except for a non-current buffer. Add a new ml_get_buf_mut() function for the mutating use-case, which can be grepped along with the other ml_replace() etc functions which can modify the memline. --- src/nvim/charset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index d11cbddccf..ce49f2ad86 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -971,7 +971,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en int ts = (int)wp->w_buffer->b_p_ts; colnr_T vcol = 0; - char *line = ptr = ml_get_buf(wp->w_buffer, pos->lnum, false); // start of the line + char *line = ptr = ml_get_buf(wp->w_buffer, pos->lnum); // start of the line if (pos->col == MAXCOL) { // continue until the NUL @@ -1141,7 +1141,7 @@ void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *e colnr_T endadd = 0; // Cannot put the cursor on part of a wide character. - char *ptr = ml_get_buf(wp->w_buffer, pos->lnum, false); + char *ptr = ml_get_buf(wp->w_buffer, pos->lnum); if (pos->col < (colnr_T)strlen(ptr)) { int c = utf_ptr2char(ptr + pos->col); -- cgit From 93af6d9ed0af984be7fc383f25ca20b595961c46 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 25 Aug 2023 19:36:43 +0800 Subject: refactor: move virtcol functions to plines.c Problem: Functions for virtcol and chartabsize are similar (both compute horizontal size), but appear in two different source files. Solution: Move virtcol functions to plines.c. --- src/nvim/charset.c | 299 ----------------------------------------------------- 1 file changed, 299 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index ce49f2ad86..2756a60d60 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -18,24 +18,17 @@ #include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cursor.h" -#include "nvim/eval/typval.h" #include "nvim/eval/typval_defs.h" #include "nvim/garray.h" #include "nvim/globals.h" #include "nvim/grid_defs.h" -#include "nvim/indent.h" #include "nvim/keycodes.h" #include "nvim/macros.h" -#include "nvim/mark.h" #include "nvim/mbyte.h" -#include "nvim/memline.h" #include "nvim/memory.h" -#include "nvim/move.h" #include "nvim/option.h" #include "nvim/path.h" -#include "nvim/plines.h" #include "nvim/pos.h" -#include "nvim/state.h" #include "nvim/strings.h" #include "nvim/vim.h" @@ -921,298 +914,6 @@ bool vim_isprintc_strict(int c) return c > 0 && (g_chartab[c] & CT_PRINT_CHAR); } -/// Check that virtual column "vcol" is in the rightmost column of window "wp". -/// -/// @param wp window -/// @param vcol column number -bool in_win_border(win_T *wp, colnr_T vcol) - FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1) -{ - if (wp->w_width_inner == 0) { - // there is no border - return false; - } - int width1 = wp->w_width_inner - win_col_off(wp); // width of first line (after line number) - - if ((int)vcol < width1 - 1) { - return false; - } - - if ((int)vcol == width1 - 1) { - return true; - } - int width2 = width1 + win_col_off2(wp); // width of further lines - - if (width2 <= 0) { - return false; - } - return (vcol - width1) % width2 == width2 - 1; -} - -/// Get virtual column number of pos. -/// start: on the first position of this character (TAB, ctrl) -/// cursor: where the cursor is on this character (first char, except for TAB) -/// end: on the last position of this character (TAB, ctrl) -/// -/// This is used very often, keep it fast! -/// -/// @param wp -/// @param pos -/// @param start -/// @param cursor -/// @param end -void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end) -{ - char *ptr; // points to current char - char *posptr; // points to char at pos->col - int incr; - int head; - long *vts = wp->w_buffer->b_p_vts_array; - int ts = (int)wp->w_buffer->b_p_ts; - - colnr_T vcol = 0; - char *line = ptr = ml_get_buf(wp->w_buffer, pos->lnum); // start of the line - - if (pos->col == MAXCOL) { - // continue until the NUL - posptr = NULL; - } else { - // In a few cases the position can be beyond the end of the line. - for (colnr_T i = 0; i < pos->col; i++) { - if (ptr[i] == NUL) { - pos->col = i; - break; - } - } - posptr = ptr + pos->col; - posptr -= utf_head_off(line, posptr); - } - - chartabsize_T cts; - bool on_NUL = false; - init_chartabsize_arg(&cts, wp, pos->lnum, 0, line, line); - cts.cts_max_head_vcol = -1; - - // This function is used very often, do some speed optimizations. - // When 'list', 'linebreak', 'showbreak' and 'breakindent' are not set - // and there are no virtual text use a simple loop. - // Also use this when 'list' is set but tabs take their normal size. - if ((!wp->w_p_list || (wp->w_p_lcs_chars.tab1 != NUL)) - && !wp->w_p_lbr - && *get_showbreak_value(wp) == NUL - && !wp->w_p_bri - && !cts.cts_has_virt_text) { - while (true) { - head = 0; - int c = (uint8_t)(*ptr); - - // make sure we don't go past the end of the line - if (c == NUL) { - // NUL at end of line only takes one column - incr = 1; - break; - } - - // A tab gets expanded, depending on the current column - if (c == TAB) { - incr = tabstop_padding(vcol, ts, vts); - } else { - // For utf-8, if the byte is >= 0x80, need to look at - // further bytes to find the cell width. - if (c >= 0x80) { - incr = utf_ptr2cells(ptr); - } else { - incr = g_chartab[c] & CT_CELL_MASK; - } - - // If a double-cell char doesn't fit at the end of a line - // it wraps to the next line, it's like this char is three - // cells wide. - if ((incr == 2) - && wp->w_p_wrap - && (MB_BYTE2LEN((uint8_t)(*ptr)) > 1) - && in_win_border(wp, vcol)) { - incr++; - head = 1; - } - } - - if ((posptr != NULL) && (ptr >= posptr)) { - // character at pos->col - break; - } - - vcol += incr; - MB_PTR_ADV(ptr); - } - } else { - while (true) { - // A tab gets expanded, depending on the current column - // Other things also take up space. - head = 0; - incr = win_lbr_chartabsize(&cts, &head); - - // make sure we don't go past the end of the line - if (*cts.cts_ptr == NUL) { - // NUL at end of line only takes one column, unless there is virtual text - incr = MAX(1, cts.cts_cur_text_width_left + cts.cts_cur_text_width_right); - on_NUL = true; - break; - } - - if ((posptr != NULL) && (cts.cts_ptr >= posptr)) { - // character at pos->col - break; - } - - cts.cts_vcol += incr; - MB_PTR_ADV(cts.cts_ptr); - } - vcol = cts.cts_vcol; - ptr = cts.cts_ptr; - } - clear_chartabsize_arg(&cts); - - if (start != NULL) { - *start = vcol + head; - } - - if (end != NULL) { - *end = vcol + incr - 1; - } - - if (cursor != NULL) { - if ((*ptr == TAB) - && (State & MODE_NORMAL) - && !wp->w_p_list - && !virtual_active() - && !(VIsual_active && ((*p_sel == 'e') || ltoreq(*pos, VIsual)))) { - // cursor at end - *cursor = vcol + incr - 1; - } else { - if (!on_NUL || !(State & MODE_NORMAL)) { - vcol += cts.cts_cur_text_width_left; - } - if (!on_NUL && (State & MODE_NORMAL)) { - vcol += cts.cts_cur_text_width_right; - } - // cursor at start - *cursor = vcol + head; - } - } -} - -/// Get virtual cursor column in the current window, pretending 'list' is off. -/// -/// @param posp -/// -/// @retujrn The virtual cursor column. -colnr_T getvcol_nolist(pos_T *posp) -{ - int list_save = curwin->w_p_list; - colnr_T vcol; - - curwin->w_p_list = false; - if (posp->coladd) { - getvvcol(curwin, posp, NULL, &vcol, NULL); - } else { - getvcol(curwin, posp, NULL, &vcol, NULL); - } - curwin->w_p_list = list_save; - return vcol; -} - -/// Get virtual column in virtual mode. -/// -/// @param wp -/// @param pos -/// @param start -/// @param cursor -/// @param end -void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end) -{ - colnr_T col; - - if (virtual_active()) { - // For virtual mode, only want one value - getvcol(wp, pos, &col, NULL, NULL); - - colnr_T coladd = pos->coladd; - colnr_T endadd = 0; - - // Cannot put the cursor on part of a wide character. - char *ptr = ml_get_buf(wp->w_buffer, pos->lnum); - - if (pos->col < (colnr_T)strlen(ptr)) { - int c = utf_ptr2char(ptr + pos->col); - if ((c != TAB) && vim_isprintc(c)) { - endadd = (colnr_T)(char2cells(c) - 1); - if (coladd > endadd) { - // past end of line - endadd = 0; - } else { - coladd = 0; - } - } - } - col += coladd; - - if (start != NULL) { - *start = col; - } - - if (cursor != NULL) { - *cursor = col; - } - - if (end != NULL) { - *end = col + endadd; - } - } else { - getvcol(wp, pos, start, cursor, end); - } -} - -/// Get the leftmost and rightmost virtual column of pos1 and pos2. -/// Used for Visual block mode. -/// -/// @param wp -/// @param pos1 -/// @param pos2 -/// @param left -/// @param right -void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right) -{ - colnr_T from1; - colnr_T from2; - colnr_T to1; - colnr_T to2; - - if (lt(*pos1, *pos2)) { - getvvcol(wp, pos1, &from1, NULL, &to1); - getvvcol(wp, pos2, &from2, NULL, &to2); - } else { - getvvcol(wp, pos2, &from1, NULL, &to1); - getvvcol(wp, pos1, &from2, NULL, &to2); - } - - if (from2 < from1) { - *left = from2; - } else { - *left = from1; - } - - if (to2 > to1) { - if ((*p_sel == 'e') && (from2 - 1 >= to1)) { - *right = from2 - 1; - } else { - *right = to2; - } - } else { - *right = to1; - } -} - /// skipwhite: skip over ' ' and '\t'. /// /// @param[in] p String to skip in. -- cgit From e8dd3fa280f44fa565533b70b37fbb688c54c5b5 Mon Sep 17 00:00:00 2001 From: julio-b Date: Sat, 26 Aug 2023 23:15:33 +0000 Subject: refactor(buf_init_chartab): remove redundant loop (#24891) --- src/nvim/charset.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 2756a60d60..c4ff712f3a 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -112,19 +112,13 @@ int buf_init_chartab(buf_T *buf, int global) while (c < 256) { if (c >= 0xa0) { // UTF-8: bytes 0xa0 - 0xff are printable (latin1) - g_chartab[c++] = CT_PRINT_CHAR + 1; + // Also assume that every multi-byte char is a filename character. + g_chartab[c++] = (CT_PRINT_CHAR | CT_FNAME_CHAR) + 1; } else { // the rest is unprintable by default g_chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2; } } - - // Assume that every multi-byte char is a filename character. - for (c = 1; c < 256; c++) { - if (c >= 0xa0) { - g_chartab[c] |= CT_FNAME_CHAR; - } - } } // Init word char flags all to false -- cgit From cf8b2c0e74fd5e723b0c15c2ce84e6900fd322d3 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 30 Sep 2023 12:05:28 +0800 Subject: build(iwyu): add a few more _defs.h mappings (#25435) --- src/nvim/charset.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index c4ff712f3a..c2722af971 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "auto/config.h" #include "klib/kvec.h" -- cgit From acc646ad8fc3ef11fcc63b69f3d8484e4a91accd Mon Sep 17 00:00:00 2001 From: dundargoc Date: Fri, 29 Sep 2023 14:58:48 +0200 Subject: refactor: the long goodbye long is 32 bits on windows, while it is 64 bits on other architectures. This makes the type suboptimal for a codebase meant to be cross-platform. Replace it with more appropriate integer types. --- src/nvim/charset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index c2722af971..eb858b8d5e 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1167,14 +1167,14 @@ long getdigits_long(char **pp, bool strict, long def) /// Gets a int32_t number from a string. /// /// @see getdigits -int32_t getdigits_int32(char **pp, bool strict, long def) +int32_t getdigits_int32(char **pp, bool strict, int32_t def) { intmax_t number = getdigits(pp, strict, def); #if SIZEOF_INTMAX_T > 4 if (strict) { assert(number >= INT32_MIN && number <= INT32_MAX); } else if (!(number >= INT32_MIN && number <= INT32_MAX)) { - return (int32_t)def; + return def; } #endif return (int32_t)number; -- cgit From 83db9115af94992a2fb32e927b7349283434ff5d Mon Sep 17 00:00:00 2001 From: bfredl Date: Fri, 3 Nov 2023 20:25:52 +0100 Subject: refactor(grid): reimplement 'rightleft' as a post-processing step problem: checks for wp->w_p_rl are all over the place, making simple things like "advance column one cell" incredibly complicated. solution: always fill linebuf_char[] using an incrementing counter, and then mirror the buffer as a post-processing step This was "easier" that I first feared, because the stupid but simple workaround for things like keeping linenumbers still left-right, e.g. "mirror them and them mirror them once more" is more or less what vim did already. So let's just keep doing that. --- src/nvim/charset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index eb858b8d5e..95229c5ffb 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -650,9 +650,9 @@ size_t transchar_hex(char *const buf, const int c) /// Mirror text "str" for right-left displaying. /// Only works for single-byte characters (e.g., numbers). -void rl_mirror_ascii(char *str) +void rl_mirror_ascii(char *str, char *end) { - for (char *p1 = str, *p2 = str + strlen(str) - 1; p1 < p2; p1++, p2--) { + for (char *p1 = str, *p2 = (end ? end : str + strlen(str)) - 1; p1 < p2; p1++, p2--) { char t = *p1; *p1 = *p2; *p2 = t; -- cgit From 353a4be7e84fdc101318215bdcc8a7e780d737fe Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sun, 12 Nov 2023 13:13:58 +0100 Subject: build: remove PVS We already have an extensive suite of static analysis tools we use, which causes a fair bit of redundancy as we get duplicate warnings. PVS is also prone to give false warnings which creates a lot of work to identify and disable. --- src/nvim/charset.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 95229c5ffb..2edf9a87cc 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1,6 +1,3 @@ -// This is an open source non-commercial project. Dear PVS-Studio, please check -// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - /// @file charset.c /// /// Code related to character sets. @@ -1328,7 +1325,6 @@ void vim_str2nr(const char *const start, int *const prep, int *const len, const // Do the conversion manually to avoid sscanf() quirks. abort(); // Should’ve used goto earlier. - // -V:PARSE_NUMBER:560 #define PARSE_NUMBER(base, cond, conv) \ do { \ const char *const after_prefix = ptr; \ -- cgit From 28f4f3c48498086307ed825d1761edb5789ca0e8 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sun, 12 Nov 2023 15:54:54 +0100 Subject: refactor: follow style guide - reduce variable scope - prefer initialization over declaration and assignment - use bool to represent boolean values --- src/nvim/charset.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 2edf9a87cc..0adcc09ec7 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -88,10 +88,6 @@ int init_chartab(void) int buf_init_chartab(buf_T *buf, int global) { int c; - int c2; - int i; - bool tilde; - bool do_isalpha; if (global) { // Set the default size for printable characters: @@ -130,7 +126,7 @@ int buf_init_chartab(buf_T *buf, int global) // Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint' // options Each option is a list of characters, character numbers or // ranges, separated by commas, e.g.: "200-210,x,#-178,-" - for (i = global ? 0 : 3; i <= 3; i++) { + for (int i = global ? 0 : 3; i <= 3; i++) { const char *p; if (i == 0) { // first round: 'isident' @@ -147,8 +143,8 @@ int buf_init_chartab(buf_T *buf, int global) } while (*p) { - tilde = false; - do_isalpha = false; + bool tilde = false; + bool do_isalpha = false; if ((*p == '^') && (p[1] != NUL)) { tilde = true; @@ -160,7 +156,7 @@ int buf_init_chartab(buf_T *buf, int global) } else { c = mb_ptr2char_adv(&p); } - c2 = -1; + int c2 = -1; if ((*p == '-') && (p[1] != NUL)) { p++; @@ -431,7 +427,6 @@ char *str_foldcase(char *str, int orglen, char *buf, int buflen) FUNC_ATTR_NONNULL_RET { garray_T ga; - int i; int len = orglen; #define GA_CHAR(i) ((char *)ga.ga_data)[i] @@ -461,7 +456,7 @@ char *str_foldcase(char *str, int orglen, char *buf, int buflen) } // Make each character lower case. - i = 0; + int i = 0; while (STR_CHAR(i) != NUL) { int c = utf_ptr2char(STR_PTR(i)); int olen = utf_ptr2len(STR_PTR(i)); -- cgit From b522cb1ac3fbdf6e68eed5d0b6e1cbeaf3ac2254 Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 6 Nov 2023 14:52:27 +0100 Subject: refactor(grid): make screen rendering more multibyte than ever before Problem: buffer text with composing chars are converted from UTF-8 to an array of up to seven UTF-32 values and then converted back to UTF-8 strings. Solution: Convert buffer text directly to UTF-8 based schar_T values. The limit of the text size is now in schar_T bytes, which is currently 31+1 but easily could be raised as it no longer multiplies the size of the entire screen grid when not used, the full size is only required for temporary scratch buffers. Also does some general cleanup to win_line text handling, which was unnecessarily complicated due to multibyte rendering being an "opt-in" feature long ago. Nowadays, a char is just a char, regardless if it consists of one ASCII byte or multiple bytes. --- src/nvim/charset.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 0adcc09ec7..5dfc9c444d 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -302,15 +302,13 @@ size_t transstr_len(const char *const s, bool untab) while (*p) { const size_t l = (size_t)utfc_ptr2len(p); if (l > 1) { - int pcc[MAX_MCO + 1]; - pcc[0] = utfc_ptr2char(p, &pcc[1]); - - if (vim_isprintc(pcc[0])) { + if (vim_isprintc(utf_ptr2char(p))) { len += l; } else { - for (size_t i = 0; i < ARRAY_SIZE(pcc) && pcc[i]; i++) { + for (size_t off = 0; off < l; off += (size_t)utf_ptr2len(p + off)) { + int c = utf_ptr2char(p + off); char hexbuf[9]; - len += transchar_hex(hexbuf, pcc[i]); + len += transchar_hex(hexbuf, c); } } p += l; @@ -349,16 +347,15 @@ size_t transstr_buf(const char *const s, const ssize_t slen, char *const buf, co if (buf_p + l > buf_e) { break; // Exceeded `buf` size. } - int pcc[MAX_MCO + 1]; - pcc[0] = utfc_ptr2char(p, &pcc[1]); - if (vim_isprintc(pcc[0])) { + if (vim_isprintc(utf_ptr2char(p))) { memmove(buf_p, p, l); buf_p += l; } else { - for (size_t i = 0; i < ARRAY_SIZE(pcc) && pcc[i]; i++) { + for (size_t off = 0; off < l; off += (size_t)utf_ptr2len(p + off)) { + int c = utf_ptr2char(p + off); char hexbuf[9]; // NUL - const size_t hexlen = transchar_hex(hexbuf, pcc[i]); + const size_t hexlen = transchar_hex(hexbuf, c); if (buf_p + hexlen > buf_e) { break; } -- cgit From 32a4c9f4f92dc9371a1a6ee053223babca89d4a1 Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Thu, 23 Nov 2023 22:26:33 +0100 Subject: perf: remove redundant strlen in skipwhite (#26177) skipwhite was iterating over the input twice and scanning for the null byte character with strlen. this is redundant, because it's already covered by ascii_iswhite that accepts only space or tab character. Co-authored-by: ii14 --- src/nvim/charset.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 5dfc9c444d..9a7de8ecef 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -903,11 +903,14 @@ bool vim_isprintc_strict(int c) /// @param[in] p String to skip in. /// /// @return Pointer to character after the skipped whitespace. -char *skipwhite(const char *const p) +char *skipwhite(const char *p) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET { - return skipwhite_len(p, strlen(p)); + while (ascii_iswhite(*p)) { + p++; + } + return (char *)p; } /// Like `skipwhite`, but skip up to `len` characters. -- cgit From a827003e3052c6d9ee7bdb71518182e9bd76317d Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 25 Nov 2023 11:32:32 +0100 Subject: build: rework IWYU mapping files Create mapping to most of the C spec and some POSIX specific functions. This is more robust than relying files shipped with IWYU. --- src/nvim/charset.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 9a7de8ecef..d3312516c6 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -19,7 +19,6 @@ #include "nvim/eval/typval_defs.h" #include "nvim/garray.h" #include "nvim/globals.h" -#include "nvim/grid_defs.h" #include "nvim/keycodes.h" #include "nvim/macros.h" #include "nvim/mbyte.h" -- cgit From a917da4ca55be8726f26a8305c53bdd5b2c7eea4 Mon Sep 17 00:00:00 2001 From: bfredl Date: Sun, 26 Nov 2023 21:53:07 +0100 Subject: refactor(encoding): remove redundant vim_isprintc_strict This function is identical to vim_isprintc when encoding=utf-8 is used As this is the only internal encoding nvim supports, it is now redundant ref #2905 --- src/nvim/charset.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index d3312516c6..64b2044dc8 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -534,7 +534,7 @@ char *transchar_buf(const buf_T *buf, int c) } if ((!chartab_initialized && (c >= ' ' && c <= '~')) - || ((c <= 0xFF) && vim_isprintc_strict(c))) { + || ((c <= 0xFF) && vim_isprintc(c))) { // printable character transchar_charbuf[i] = (uint8_t)c; transchar_charbuf[i + 1] = NUL; @@ -870,7 +870,6 @@ bool vim_isfilec_or_wc(int c) } /// Check that "c" is a printable character. -/// Assume characters above 0x100 are printable for double-byte encodings. /// /// @param c character to check bool vim_isprintc(int c) @@ -882,21 +881,6 @@ bool vim_isprintc(int c) return c > 0 && (g_chartab[c] & CT_PRINT_CHAR); } -/// Strict version of vim_isprintc(c), don't return true if "c" is the head -/// byte of a double-byte character. -/// -/// @param c character to check -/// -/// @return true if "c" is a printable character. -bool vim_isprintc_strict(int c) - FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT -{ - if (c >= 0x100) { - return utf_printable(c); - } - return c > 0 && (g_chartab[c] & CT_PRINT_CHAR); -} - /// skipwhite: skip over ' ' and '\t'. /// /// @param[in] p String to skip in. -- cgit From f4aedbae4cb1f206f5b7c6142697b71dd473059b Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 18:39:38 +0100 Subject: build(IWYU): fix includes for undo_defs.h --- src/nvim/charset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 64b2044dc8..515c06f2d8 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -25,7 +25,7 @@ #include "nvim/memory.h" #include "nvim/option.h" #include "nvim/path.h" -#include "nvim/pos.h" +#include "nvim/pos_defs.h" #include "nvim/strings.h" #include "nvim/vim.h" -- cgit From 79b6ff28ad1204fbb4199b9092f5c578d88cb28e Mon Sep 17 00:00:00 2001 From: dundargoc Date: Tue, 28 Nov 2023 20:31:00 +0100 Subject: refactor: fix headers with IWYU --- src/nvim/charset.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/charset.c') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 515c06f2d8..48a9808b31 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -12,7 +12,7 @@ #include "auto/config.h" #include "klib/kvec.h" -#include "nvim/ascii.h" +#include "nvim/ascii_defs.h" #include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cursor.h" @@ -20,14 +20,14 @@ #include "nvim/garray.h" #include "nvim/globals.h" #include "nvim/keycodes.h" -#include "nvim/macros.h" +#include "nvim/macros_defs.h" #include "nvim/mbyte.h" #include "nvim/memory.h" #include "nvim/option.h" #include "nvim/path.h" #include "nvim/pos_defs.h" #include "nvim/strings.h" -#include "nvim/vim.h" +#include "nvim/vim_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "charset.c.generated.h" -- cgit