diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2024-11-25 19:15:05 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2024-11-25 19:27:38 +0000 |
commit | c5d770d311841ea5230426cc4c868e8db27300a8 (patch) | |
tree | dd21f70127b4b8b5f109baefc8ecc5016f507c91 /src/nvim/charset.c | |
parent | 9be89f131f87608f224f0ee06d199fcd09d32176 (diff) | |
parent | 081beb3659bd6d8efc3e977a160b1e72becbd8a2 (diff) | |
download | rneovim-c5d770d311841ea5230426cc4c868e8db27300a8.tar.gz rneovim-c5d770d311841ea5230426cc4c868e8db27300a8.tar.bz2 rneovim-c5d770d311841ea5230426cc4c868e8db27300a8.zip |
Merge remote-tracking branch 'upstream/master' into mix_20240309
Diffstat (limited to 'src/nvim/charset.c')
-rw-r--r-- | src/nvim/charset.c | 196 |
1 files changed, 106 insertions, 90 deletions
diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 430f6b15fe..1afd590b0e 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -88,13 +88,11 @@ int init_chartab(void) /// an error, OK otherwise. int buf_init_chartab(buf_T *buf, bool global) { - int c; - if (global) { // Set the default size for printable characters: // From <Space> to '~' is 1 (printable), others are 2 (not printable). // This also inits all 'isident' and 'isfname' flags to false. - c = 0; + int c = 0; while (c < ' ') { g_chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2; @@ -124,9 +122,7 @@ int buf_init_chartab(buf_T *buf, bool global) SET_CHARTAB(buf, '-'); } - // 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,-" + // Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint' options. for (int i = global ? 0 : 3; i <= 3; i++) { const char *p; if (i == 0) { @@ -142,110 +138,130 @@ int buf_init_chartab(buf_T *buf, bool global) // fourth round: 'iskeyword' p = buf->b_p_isk; } + if (parse_isopt(p, buf, false) == FAIL) { + return FAIL; + } + } - while (*p) { - bool tilde = false; - bool do_isalpha = false; + chartab_initialized = true; + return OK; +} - if ((*p == '^') && (p[1] != NUL)) { - tilde = true; - p++; - } +/// Checks the format for the option settings 'iskeyword', 'isident', 'isfname' +/// or 'isprint'. +/// Returns FAIL if has an error, OK otherwise. +int check_isopt(char *var) +{ + return parse_isopt(var, NULL, true); +} + +/// @param only_check if false: refill g_chartab[] +static int parse_isopt(const char *var, buf_T *buf, bool only_check) +{ + const char *p = var; + + // Parses 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,-" + while (*p) { + bool tilde = false; + bool do_isalpha = false; + + if (*p == '^' && p[1] != NUL) { + tilde = true; + p++; + } + + int c; + if (ascii_isdigit(*p)) { + c = getdigits_int((char **)&p, true, 0); + } else { + c = mb_ptr2char_adv(&p); + } + int c2 = -1; + + if (*p == '-' && p[1] != NUL) { + p++; if (ascii_isdigit(*p)) { - c = getdigits_int((char **)&p, true, 0); + c2 = getdigits_int((char **)&p, true, 0); } else { - c = mb_ptr2char_adv(&p); + c2 = mb_ptr2char_adv(&p); } - int c2 = -1; + } - if ((*p == '-') && (p[1] != NUL)) { - p++; + if (c <= 0 || c >= 256 || (c2 < c && c2 != -1) || c2 >= 256 + || !(*p == NUL || *p == ',')) { + return FAIL; + } - if (ascii_isdigit(*p)) { - c2 = getdigits_int((char **)&p, true, 0); - } else { - c2 = mb_ptr2char_adv(&p); - } - } + bool trail_comma = *p == ','; + p = skip_to_option_part(p); + if (trail_comma && *p == NUL) { + // Trailing comma is not allowed. + return FAIL; + } - if ((c <= 0) - || (c >= 256) - || ((c2 < c) && (c2 != -1)) - || (c2 >= 256) - || !((*p == NUL) || (*p == ','))) { - return FAIL; - } + if (only_check) { + continue; + } - if (c2 == -1) { // not a range - // A single '@' (not "@-@"): - // Decide on letters being ID/printable/keyword chars with - // standard function isalpha(). This takes care of locale for - // single-byte characters). - if (c == '@') { - do_isalpha = true; - c = 1; - c2 = 255; - } else { - c2 = c; - } + if (c2 == -1) { // not a range + // A single '@' (not "@-@"): + // Decide on letters being ID/printable/keyword chars with + // standard function isalpha(). This takes care of locale for + // single-byte characters). + if (c == '@') { + do_isalpha = true; + c = 1; + c2 = 255; + } else { + c2 = c; } + } - while (c <= c2) { - // Use the MB_ functions here, because isalpha() doesn't - // work properly when 'encoding' is "latin1" and the locale is - // "C". - if (!do_isalpha - || mb_islower(c) - || mb_isupper(c)) { - if (i == 0) { - // (re)set ID flag - if (tilde) { - g_chartab[c] &= (uint8_t) ~CT_ID_CHAR; - } else { - g_chartab[c] |= CT_ID_CHAR; - } - } else if (i == 1) { - // (re)set printable - if (c < ' ' || c > '~') { - if (tilde) { - g_chartab[c] = (uint8_t)((g_chartab[c] & ~CT_CELL_MASK) - + ((dy_flags & DY_UHEX) ? 4 : 2)); - g_chartab[c] &= (uint8_t) ~CT_PRINT_CHAR; - } else { - g_chartab[c] = (uint8_t)((g_chartab[c] & ~CT_CELL_MASK) + 1); - g_chartab[c] |= CT_PRINT_CHAR; - } - } - } else if (i == 2) { - // (re)set fname flag - if (tilde) { - g_chartab[c] &= (uint8_t) ~CT_FNAME_CHAR; - } else { - g_chartab[c] |= CT_FNAME_CHAR; - } - } else { // i == 3 - // (re)set keyword flag + while (c <= c2) { + // Use the MB_ functions here, because isalpha() doesn't + // work properly when 'encoding' is "latin1" and the locale is + // "C". + if (!do_isalpha + || mb_islower(c) + || mb_isupper(c)) { + if (var == p_isi) { // (re)set ID flag + if (tilde) { + g_chartab[c] &= (uint8_t) ~CT_ID_CHAR; + } else { + g_chartab[c] |= CT_ID_CHAR; + } + } else if (var == p_isp) { // (re)set printable + if (c < ' ' || c > '~') { if (tilde) { - RESET_CHARTAB(buf, c); + g_chartab[c] = (uint8_t)((g_chartab[c] & ~CT_CELL_MASK) + + ((dy_flags & DY_UHEX) ? 4 : 2)); + g_chartab[c] &= (uint8_t) ~CT_PRINT_CHAR; } else { - SET_CHARTAB(buf, c); + g_chartab[c] = (uint8_t)((g_chartab[c] & ~CT_CELL_MASK) + 1); + g_chartab[c] |= CT_PRINT_CHAR; } } + } else if (var == p_isf) { // (re)set fname flag + if (tilde) { + g_chartab[c] &= (uint8_t) ~CT_FNAME_CHAR; + } else { + g_chartab[c] |= CT_FNAME_CHAR; + } + } else { // (var == p_isk || var == buf->b_p_isk) (re)set keyword flag + if (tilde) { + RESET_CHARTAB(buf, c); + } else { + SET_CHARTAB(buf, c); + } } - c++; - } - - c = (uint8_t)(*p); - p = skip_to_option_part(p); - - if ((c == ',') && (*p == NUL)) { - // Trailing comma is not allowed. - return FAIL; } + c++; } } - chartab_initialized = true; + return OK; } |