diff options
Diffstat (limited to 'src')
41 files changed, 977 insertions, 2344 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 47782e8b6b..09b709b6ce 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -58,9 +58,7 @@ set(CONV_SOURCES ex_cmds.c ex_docmd.c ex_getln.c - farsi.c fileio.c - fold.c getchar.c if_cscope.c mbyte.c @@ -68,11 +66,9 @@ set(CONV_SOURCES menu.c message.c misc1.c - move.c normal.c ops.c path.c - popupmnu.c quickfix.c regexp.c screen.c diff --git a/src/nvim/edit.c b/src/nvim/edit.c index c60d987ddd..b860ce8898 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -7354,9 +7354,9 @@ static int ins_bs(int c, int mode, int *inserted_space_p) *inserted_space_p = FALSE; if (p_sta && in_indent) - ts = (int)get_sw_value(curbuf); + ts = get_sw_value(curbuf); else - ts = (int)get_sts_value(); + ts = get_sts_value(); /* Compute the virtual column where we want to be. Since * 'showbreak' may get in the way, need to get the last column of * the previous character. */ @@ -7826,9 +7826,9 @@ static int ins_tab(void) AppendToRedobuff((char_u *)"\t"); if (p_sta && ind) /* insert tab in indent, use 'shiftwidth' */ - temp = (int)get_sw_value(curbuf); + temp = get_sw_value(curbuf); else if (curbuf->b_p_sts != 0) /* use 'softtabstop' when set */ - temp = (int)get_sts_value(); + temp = get_sts_value(); else /* otherwise use 'tabstop' */ temp = (int)curbuf->b_p_ts; temp -= get_nolist_virtcol() % temp; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 4ab31985b5..231b92db3c 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -5942,18 +5942,23 @@ dictitem_T *dict_find(dict_T *d, char_u *key, int len) return HI2DI(hi); } -// Get a function from a dictionary -static ufunc_T *get_dict_callback(dict_T *d, char *key) +/// Get a function from a dictionary +/// @param[out] result The address where a pointer to the wanted callback +/// will be left. +/// @return true/false on success/failure. +static bool get_dict_callback(dict_T *d, char *key, ufunc_T **result) { dictitem_T *di = dict_find(d, (uint8_t *)key, -1); if (di == NULL) { - return NULL; + *result = NULL; + return true; } if (di->di_tv.v_type != VAR_FUNC && di->di_tv.v_type != VAR_STRING) { EMSG(_("Argument is not a function or function name")); - return NULL; + *result = NULL; + return false; } uint8_t *name = di->di_tv.vval.v_string; @@ -5970,11 +5975,13 @@ static ufunc_T *get_dict_callback(dict_T *d, char *key) if (!rv) { EMSG2(_("Function %s doesn't exist"), name); - return NULL; + *result = NULL; + return false; } rv->uf_refcount++; - return rv; + *result = rv; + return true; } /* @@ -10810,6 +10817,8 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv) return; } + assert(args->lv_first); + if (!os_can_exe(args->lv_first->li_tv.vval.v_string, NULL)) { // String is not executable EMSG2(e_jobexe, args->lv_first->li_tv.vval.v_string); @@ -10820,8 +10829,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv) ufunc_T *on_stdout = NULL, *on_stderr = NULL, *on_exit = NULL; if (argvars[1].v_type == VAR_DICT) { job_opts = argvars[1].vval.v_dict; - common_job_callbacks(job_opts, &on_stdout, &on_stderr, &on_exit); - if (did_emsg) { + if (!common_job_callbacks(job_opts, &on_stdout, &on_stderr, &on_exit)) { return; } } @@ -15077,8 +15085,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv) dict_T *job_opts = NULL; if (argvars[1].v_type == VAR_DICT) { job_opts = argvars[1].vval.v_dict; - common_job_callbacks(job_opts, &on_stdout, &on_stderr, &on_exit); - if (did_emsg) { + if (!common_job_callbacks(job_opts, &on_stdout, &on_stderr, &on_exit)) { return; } } @@ -20051,27 +20058,27 @@ static inline JobOptions common_job_options(char **argv, ufunc_T *on_stdout, return opts; } -static inline void common_job_callbacks(dict_T *vopts, ufunc_T **on_stdout, - ufunc_T **on_stderr, ufunc_T **on_exit) +/// Return true/false on success/failure. +static inline bool common_job_callbacks(dict_T *vopts, ufunc_T **on_stdout, + ufunc_T **on_stderr, ufunc_T **on_exit) { - *on_stdout = get_dict_callback(vopts, "on_stdout"); - *on_stderr = get_dict_callback(vopts, "on_stderr"); - *on_exit = get_dict_callback(vopts, "on_exit"); - if (did_emsg) { - if (*on_stdout) { - user_func_unref(*on_stdout); - } - if (*on_stderr) { - user_func_unref(*on_stderr); - } - if (*on_exit) { - user_func_unref(*on_exit); - } - return; + if (get_dict_callback(vopts, "on_stdout", on_stdout) + && get_dict_callback(vopts, "on_stderr", on_stderr) + && get_dict_callback(vopts, "on_exit", on_exit)) { + vopts->internal_refcount++; + vopts->dv_refcount++; + return true; } - - vopts->internal_refcount++; - vopts->dv_refcount++; + if (*on_stdout) { + user_func_unref(*on_stdout); + } + if (*on_stderr) { + user_func_unref(*on_stderr); + } + if (*on_exit) { + user_func_unref(*on_exit); + } + return false; } static inline Job *common_job_start(JobOptions opts, typval_T *rettv) diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index d430509cfd..6b74e85acb 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -10,7 +10,6 @@ * ex_getln.c: Functions for entering and editing an Ex command line. */ -#include <assert.h> #include <errno.h> #include <stdbool.h> #include <string.h> @@ -1785,7 +1784,7 @@ getexmodeline ( } if (c1 == Ctrl_T) { - long sw = get_sw_value(curbuf); + int sw = get_sw_value(curbuf); p = (char_u *)line_ga.ga_data; p[line_ga.ga_len] = NUL; @@ -3629,6 +3628,7 @@ ExpandFromContext ( } if (xp->xp_context == EXPAND_SHELLCMD) { + *file = NULL; expand_shellcmd(pat, num_file, file, flags); return OK; } @@ -3810,16 +3810,17 @@ void ExpandGeneric( reset_expand_highlight(); } -/* - * Complete a shell command. - */ -static void -expand_shellcmd ( - char_u *filepat, /* pattern to match with command names */ - int *num_file, /* return: number of matches */ - char_u ***file, /* return: array with matches */ - int flagsarg /* EW_ flags */ -) +/// Complete a shell command. +/// +/// @param filepat is a pattern to match with command names. +/// @param[out] num_file is pointer to number of matches. +/// @param[out] file is pointer to array of pointers to matches. +/// *file will either be set to NULL or point to +/// allocated memory. +/// @param flagsarg is a combination of EW_* flags. +static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, + int flagsarg) + FUNC_ATTR_NONNULL_ALL { char_u *pat; int i; @@ -3875,10 +3876,8 @@ expand_shellcmd ( STRLCPY(buf + l, pat, MAXPATHL - l); /* Expand matches in one directory of $PATH. */ - char_u **prev_file = *file; ret = expand_wildcards(1, &buf, num_file, file, flags); if (ret == OK) { - assert(*file != prev_file); ga_grow(&ga, *num_file); { for (i = 0; i < *num_file; ++i) { diff --git a/src/nvim/farsi.c b/src/nvim/farsi.c index 2ca581ebd3..f9d6b14edc 100644 --- a/src/nvim/farsi.c +++ b/src/nvim/farsi.c @@ -2,6 +2,7 @@ /// /// Functions for Farsi language +#include <assert.h> #include <stdbool.h> #include "nvim/cursor.h" @@ -29,26 +30,23 @@ // Special Farsi text messages const char_u farsi_text_1[] = { - YE_, _SIN, RE, ALEF_, _FE, ' ', 'V', 'I', 'M', - ' ', F_HE, _BE, ' ', SHIN, RE, _GAF, DAL, ' ', NOON, - ALEF_, _YE, ALEF_, _PE, '\0' + YE_, _SIN, RE, ALEF_, _FE, ' ', 'V', 'I', 'M', ' ', F_HE, _BE, ' ', SHIN, RE, + _GAF, DAL, ' ', NOON, ALEF_, _YE, ALEF_, _PE, '\0' }; const char_u farsi_text_2[] = { - YE_, _SIN, RE, ALEF_, _FE, ' ', FARSI_3, FARSI_3, - FARSI_4, FARSI_2, ' ', DAL, RE, ALEF, DAL, _NOON, - ALEF_, _TE, _SIN, ALEF, ' ', F_HE, _BE, ' ', SHIN, - RE, _GAF, DAL, ' ', NOON, ALEF_, _YE, ALEF_, _PE, '\0' + YE_, _SIN, RE, ALEF_, _FE, ' ', FARSI_3, FARSI_3, FARSI_4, FARSI_2, ' ', DAL, + RE, ALEF, DAL, _NOON, ALEF_, _TE, _SIN, ALEF, ' ', F_HE, _BE, ' ', SHIN, RE, + _GAF, DAL, ' ', NOON, ALEF_, _YE, ALEF_, _PE, '\0' }; const char_u farsi_text_3[] = { - DAL, WAW, _SHIN, _YE, _MIM, _NOON, ' ', YE_, _NOON, - ALEF_, _BE, _YE, _TE, _SHIN, _PE, ' ', 'R', 'E', 'P', 'L', - 'A', 'C', 'E', ' ', NOON, ALEF_, _MIM, RE, _FE, ZE, ALEF, - ' ', 'R', 'E', 'V', 'E', 'R', 'S', 'E', ' ', 'I', 'N', - 'S', 'E', 'R', 'T', ' ', SHIN, WAW, RE, ' ', ALEF_, _BE, - ' ', YE_, _SIN, RE, ALEF_, _FE, ' ', RE, DAL, ' ', RE, - ALEF_, _KAF, ' ', MIM, ALEF_, _GAF, _NOON, _HE, '\0' + DAL, WAW, _SHIN, _YE, _MIM, _NOON, ' ', YE_, _NOON, ALEF_, _BE, _YE, _TE, + _SHIN, _PE, ' ', 'R', 'E', 'P', 'L', 'A', 'C', 'E', ' ', NOON, ALEF_, _MIM, + RE, _FE, ZE, ALEF, ' ', 'R', 'E', 'V', 'E', 'R', 'S', 'E', ' ', 'I', 'N', 'S', + 'E', 'R', 'T', ' ', SHIN, WAW, RE, ' ', ALEF_, _BE, ' ', YE_, _SIN, RE, ALEF_, + _FE, ' ', RE, DAL, ' ', RE, ALEF_, _KAF, ' ', MIM, ALEF_, _GAF, _NOON, _HE, + '\0' }; const char_u farsi_text_5[] = { @@ -65,93 +63,41 @@ const char_u farsi_text_5[] = { /// @param c The character to convert. /// /// @return Farsi character converted to a _X or _X_ type. -static int toF_Xor_X_(int c) +static char_u toF_Xor_X_(int c) { - int tempc; + char_u tempc; switch (c) { - case BE: - return _BE; - - case PE: - return _PE; - - case TE: - return _TE; - - case SE: - return _SE; - - case JIM: - return _JIM; - - case CHE: - return _CHE; - - case HE_J: - return _HE_J; - - case XE: - return _XE; - - case SIN: - return _SIN; - - case SHIN: - return _SHIN; - - case SAD: - return _SAD; - - case ZAD: - return _ZAD; - - case AYN: - return _AYN; - - case AYN_: - return _AYN_; - - case GHAYN: - return _GHAYN; - - case GHAYN_: - return _GHAYN_; - - case FE: - return _FE; - - case GHAF: - return _GHAF; - - case KAF: - return _KAF; - - case GAF: - return _GAF; - - case LAM: - return _LAM; - - case MIM: - return _MIM; - - case NOON: - return _NOON; - - case YE: - case YE_: - return _YE; - - case YEE: - case YEE_: - return _YEE; - - case IE: - case IE_: - return _IE; - - case F_HE: + case BE : tempc = _BE ; break; + case PE : tempc = _PE ; break; + case TE : tempc = _TE ; break; + case SE : tempc = _SE ; break; + case JIM : tempc = _JIM ; break; + case CHE : tempc = _CHE ; break; + case HE_J : tempc = _HE_J ; break; + case XE : tempc = _XE ; break; + case SIN : tempc = _SIN ; break; + case SHIN : tempc = _SHIN ; break; + case SAD : tempc = _SAD ; break; + case ZAD : tempc = _ZAD ; break; + case AYN : tempc = _AYN ; break; + case AYN_ : tempc = _AYN_ ; break; + case GHAYN : tempc = _GHAYN ; break; + case GHAYN_ : tempc = _GHAYN_ ; break; + case FE : tempc = _FE ; break; + case GHAF : tempc = _GHAF ; break; + case KAF : tempc = _KAF ; break; + case GAF : tempc = _GAF ; break; + case LAM : tempc = _LAM ; break; + case MIM : tempc = _MIM ; break; + case NOON : tempc = _NOON ; break; + case YE : + case YE_ : tempc = _YE ; break; + case YEE : + case YEE_ : tempc = _YEE ; break; + case IE : + case IE_ : tempc = _IE ; break; + case F_HE : tempc = _HE; if (p_ri && @@ -171,9 +117,13 @@ static int toF_Xor_X_(int c) inc_cursor(); } - return tempc; + break; + + default: + tempc = 0; } - return 0; + + return tempc; } /// Convert the given Farsi character into Farsi capital character. @@ -181,104 +131,51 @@ static int toF_Xor_X_(int c) /// @param c The character to convert. /// /// @return Character converted to the Farsi capital leter. -int toF_TyA(int c) +char_u toF_TyA(char_u c) { - switch (c) { - case ALEF_: - return ALEF; - - case ALEF_U_H_: - return ALEF_U_H; - - case _BE: - return BE; - - case _PE: - return PE; - - case _TE: - return TE; - - case _SE: - return SE; - - case _JIM: - return JIM; - - case _CHE: - return CHE; - - case _HE_J: - return HE_J; - - case _XE: - return XE; - - case _SIN: - return SIN; - - case _SHIN: - return SHIN; - - case _SAD: - return SAD; - - case _ZAD: - return ZAD; - - case _AYN: - case AYN_: - case _AYN_: - return AYN; - - case _GHAYN: - case GHAYN_: - case _GHAYN_: - return GHAYN; - - case _FE: - return FE; + char_u tempc; - case _GHAF: - return GHAF; - - // I am not sure what it is !!! - // case _KAF_H: - case _KAF: - return KAF; - - case _GAF: - return GAF; - - case _LAM: - return LAM; - - case _MIM: - return MIM; - - case _NOON: - return NOON; - - case _YE: - case YE_: - return YE; - - case _YEE: - case YEE_: - return YEE; - - case TEE_: - return TEE; - - case _IE: - case IE_: - return IE; - - case _HE: - case _HE_: - return F_HE; + switch (c) { + case ALEF_ : tempc = ALEF ; break; + case ALEF_U_H_ : tempc = ALEF_U_H ; break; + case _BE : tempc = BE ; break; + case _PE : tempc = PE ; break; + case _TE : tempc = TE ; break; + case _SE : tempc = SE ; break; + case _JIM : tempc = JIM ; break; + case _CHE : tempc = CHE ; break; + case _HE_J : tempc = HE_J ; break; + case _XE : tempc = XE ; break; + case _SIN : tempc = SIN ; break; + case _SHIN : tempc = SHIN ; break; + case _SAD : tempc = SAD ; break; + case _ZAD : tempc = ZAD ; break; + case _AYN : + case AYN_ : + case _AYN_ : tempc = AYN ; break; + case _GHAYN : + case GHAYN_ : + case _GHAYN_ : tempc = GHAYN ; break; + case _FE : tempc = FE ; break; + case _GHAF : tempc = GHAF ; break; + case _KAF : tempc = KAF ; break; + case _GAF : tempc = GAF ; break; + case _LAM : tempc = LAM ; break; + case _MIM : tempc = MIM ; break; + case _NOON : tempc = NOON ; break; + case _YE : + case YE_ : tempc = YE ; break; + case _YEE : + case YEE_ : tempc = YEE ; break; + case TEE_ : tempc = TEE ; break; + case _IE : + case IE_ : tempc = IE ; break; + case _HE : + case _HE_ : tempc = F_HE ; break; + default : tempc = c ; } - return c; + + return tempc; } /// Is the character under the cursor+offset in the given buffer a join type. @@ -388,51 +285,34 @@ static bool F_is_TyC_TyD(int c) /// @param c The character to convert. /// /// @return The character converted into a leading type. -static int toF_TyB(int c) +static char_u toF_TyB(int c) { - switch (c) { - case ALEF_: - return ALEF; - - case ALEF_U_H_: - return ALEF_U_H; - - case _AYN_: - return _AYN; - - case AYN_: - // exception - there are many of them - return AYN; - - case _GHAYN_: - return _GHAYN; - - case GHAYN_: - // exception - there are many of them - return GHAYN; - - case _HE_: - return _HE; - - case YE_: - return YE; - - case IE_: - return IE; - - case TEE_: - return TEE; + char_u tempc; - case YEE_: - return YEE; + switch (c) { + case ALEF_ : tempc = ALEF ; break; + case ALEF_U_H_ : tempc = ALEF_U_H ; break; + case _AYN_ : tempc = _AYN ; break; + case AYN_ : tempc = AYN ; break; // exception - there are many + case _GHAYN_ : tempc = _GHAYN ; break; + case GHAYN_ : tempc = GHAYN ; break; // exception - there are many + case _HE_ : tempc = _HE ; break; + case YE_ : tempc = YE ; break; + case IE_ : tempc = IE ; break; + case TEE_ : tempc = TEE ; break; + case YEE_ : tempc = YEE ; break; + default: + assert(c >= 0 && c <= UCHAR_MAX); + tempc = (char_u)c; } - return c; + + return tempc; } /// Overwrite the current redo and cursor characters + left adjust /// /// @param c -static void put_curr_and_l_to_X(int c) +static void put_curr_and_l_to_X(char_u c) { int tempc; @@ -465,7 +345,7 @@ static void put_curr_and_l_to_X(int c) put_and_redo(c); } -static void put_and_redo(int c) +static void put_and_redo(char_u c) { pchar_cursor(c); AppendCharToRedobuff(K_BS); @@ -475,110 +355,39 @@ static void put_and_redo(int c) /// Change the char. under the cursor to a X_ or X type static void chg_c_toX_orX(void) { - int tempc, curc; + int curc; + char_u tempc; switch ((curc = gchar_cursor())) { - case _BE: - tempc = BE; - break; - - case _PE: - tempc = PE; - break; - - case _TE: - tempc = TE; - break; - - case _SE: - tempc = SE; - break; - - case _JIM: - tempc = JIM; - break; - - case _CHE: - tempc = CHE; - break; - - case _HE_J: - tempc = HE_J; - break; - - case _XE: - tempc = XE; - break; - - case _SIN: - tempc = SIN; - break; - - case _SHIN: - tempc = SHIN; - break; - - case _SAD: - tempc = SAD; - break; - - case _ZAD: - tempc = ZAD; - break; - - case _FE: - tempc = FE; - break; - - case _GHAF: - tempc = GHAF; - break; - - case _KAF_H: - case _KAF: - tempc = KAF; - break; - - case _GAF: - tempc = GAF; - break; - - case _AYN: - tempc = AYN; - break; - - case _AYN_: - tempc = AYN_; - break; - - case _GHAYN: - tempc = GHAYN; - break; - - case _GHAYN_: - tempc = GHAYN_; - break; - - case _LAM: - tempc = LAM; - break; - - case _MIM: - tempc = MIM; - break; - - case _NOON: - tempc = NOON; - break; - - case _HE: - case _HE_: - tempc = F_HE; - break; - - case _YE: - case _IE: - case _YEE: + case _BE : tempc = BE ; break ; + case _PE : tempc = PE ; break ; + case _TE : tempc = TE ; break ; + case _SE : tempc = SE ; break ; + case _JIM : tempc = JIM ; break ; + case _CHE : tempc = CHE ; break ; + case _HE_J : tempc = HE_J ; break ; + case _XE : tempc = XE ; break ; + case _SIN : tempc = SIN ; break ; + case _SHIN : tempc = SHIN ; break ; + case _SAD : tempc = SAD ; break ; + case _ZAD : tempc = ZAD ; break ; + case _FE : tempc = FE ; break ; + case _GHAF : tempc = GHAF ; break ; + case _KAF_H : + case _KAF : tempc = KAF ; break ; + case _GAF : tempc = GAF ; break ; + case _AYN : tempc = AYN ; break ; + case _AYN_ : tempc = AYN_ ; break ; + case _GHAYN : tempc = GHAYN ; break ; + case _GHAYN_ : tempc = GHAYN_ ; break ; + case _LAM : tempc = LAM ; break ; + case _MIM : tempc = MIM ; break ; + case _NOON : tempc = NOON ; break ; + case _HE : + case _HE_ : tempc = F_HE ; break; + case _YE : + case _IE : + case _YEE : if (p_ri) { inc_cursor(); @@ -621,55 +430,21 @@ static void chg_c_toX_orX(void) /// Change the char. under the cursor to a _X_ or X_ type static void chg_c_to_X_orX_(void) { - int tempc; + char_u tempc; switch (gchar_cursor()) { - case ALEF: - tempc = ALEF_; - break; - - case ALEF_U_H: - tempc = ALEF_U_H_; - break; - - case _AYN: - tempc = _AYN_; - break; - - case AYN: - tempc = AYN_; - break; - - case _GHAYN: - tempc = _GHAYN_; - break; - - case GHAYN: - tempc = GHAYN_; - break; - - case _HE: - tempc = _HE_; - break; - - case YE: - tempc = YE_; - break; - - case IE: - tempc = IE_; - break; - - case TEE: - tempc = TEE_; - break; - - case YEE: - tempc = YEE_; - break; - - default: - tempc = 0; + case ALEF : tempc = ALEF_ ; break; + case ALEF_U_H : tempc = ALEF_U_H_ ; break; + case _AYN : tempc = _AYN_ ; break; + case AYN : tempc = AYN_ ; break; + case _GHAYN : tempc = _GHAYN_ ; break; + case GHAYN : tempc = GHAYN_ ; break; + case _HE : tempc = _HE_ ; break; + case YE : tempc = YE_ ; break; + case IE : tempc = IE_ ; break; + case TEE : tempc = TEE_ ; break; + case YEE : tempc = YEE_ ; break; + default : tempc = 0 ; } if (tempc) { @@ -689,15 +464,14 @@ static void chg_c_to_X_or_X(void) if ((tempc == F_HE) && (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))) { tempc = _HE_; dec_cursor(); - put_and_redo(tempc); + put_and_redo((char_u)tempc); return; } - dec_cursor(); } if ((tempc = toF_Xor_X_(tempc)) != 0) { - put_and_redo(tempc); + put_and_redo((char_u)tempc); } } @@ -722,56 +496,22 @@ static void chg_l_to_X_orX_(void) } switch (gchar_cursor()) { - case ALEF: - tempc = ALEF_; - break; - - case ALEF_U_H: - tempc = ALEF_U_H_; - break; - - case _AYN: - tempc = _AYN_; - break; - - case AYN: - tempc = AYN_; - break; - - case _GHAYN: - tempc = _GHAYN_; - break; - - case GHAYN: - tempc = GHAYN_; - break; - - case _HE: - tempc = _HE_; - break; - - case YE: - tempc = YE_; - break; - - case IE: - tempc = IE_; - break; - - case TEE: - tempc = TEE_; - break; - - case YEE: - tempc = YEE_; - break; - - default: - tempc = 0; + case ALEF : tempc = ALEF_ ; break; + case ALEF_U_H : tempc = ALEF_U_H_ ; break; + case _AYN : tempc = _AYN_ ; break; + case AYN : tempc = AYN_ ; break; + case _GHAYN : tempc = _GHAYN_ ; break; + case GHAYN : tempc = GHAYN_ ; break; + case _HE : tempc = _HE_ ; break; + case YE : tempc = YE_ ; break; + case IE : tempc = IE_ ; break; + case TEE : tempc = TEE_ ; break; + case YEE : tempc = YEE_ ; break; + default : tempc = 0 ; } if (tempc) { - put_and_redo(tempc); + put_and_redo((char_u)tempc); } if (p_ri) { @@ -784,7 +524,7 @@ static void chg_l_to_X_orX_(void) /// Change the character left to the cursor to a X or _X type static void chg_l_toXor_X(void) { - int tempc; + char_u tempc; if ((curwin->w_cursor.col != 0) && (curwin->w_cursor.col + 1 == (colnr_T)STRLEN(get_cursor_line_ptr()))) { @@ -802,52 +542,18 @@ static void chg_l_toXor_X(void) } switch (gchar_cursor()) { - case ALEF_: - tempc = ALEF; - break; - - case ALEF_U_H_: - tempc = ALEF_U_H; - break; - - case _AYN_: - tempc = _AYN; - break; - - case AYN_: - tempc = AYN; - break; - - case _GHAYN_: - tempc = _GHAYN; - break; - - case GHAYN_: - tempc = GHAYN; - break; - - case _HE_: - tempc = _HE; - break; - - case YE_: - tempc = YE; - break; - - case IE_: - tempc = IE; - break; - - case TEE_: - tempc = TEE; - break; - - case YEE_: - tempc = YEE; - break; - - default: - tempc = 0; + case ALEF_ : tempc = ALEF ; break; + case ALEF_U_H_ : tempc = ALEF_U_H ; break; + case _AYN_ : tempc = _AYN ; break; + case AYN_ : tempc = AYN ; break; + case _GHAYN_ : tempc = _GHAYN ; break; + case GHAYN_ : tempc = GHAYN ; break; + case _HE_ : tempc = _HE ; break; + case YE_ : tempc = YE ; break; + case IE_ : tempc = IE ; break; + case TEE_ : tempc = TEE ; break; + case YEE_ : tempc = YEE ; break; + default : tempc = 0 ; } if (tempc) { @@ -864,7 +570,8 @@ static void chg_l_toXor_X(void) /// Change the character right to the cursor to a _X or _X_ type static void chg_r_to_Xor_X_(void) { - int tempc, c; + int tempc; + char_u c; if (curwin->w_cursor.col) { if (!p_ri) { @@ -893,13 +600,13 @@ int fkmap(int c) } if (VIM_ISDIGIT(c) - || (((c == '.') - || (c == '+') - || (c == '-') - || (c == '^') - || (c == '%') - || (c == '#') - || (c == '=')) + || ((c == '.' + || c == '+' + || c == '-' + || c == '^' + || c == '%' + || c == '#' + || c == '=') && revins)) { if (!revins) { if (curwin->w_cursor.col) { @@ -1060,158 +767,57 @@ int fkmap(int c) if (!p_ri) { if (!curwin->w_cursor.col) { switch (c) { - case '0': - return FARSI_0; - - case '1': - return FARSI_1; - - case '2': - return FARSI_2; - - case '3': - return FARSI_3; - - case '4': - return FARSI_4; - - case '5': - return FARSI_5; - - case '6': - return FARSI_6; - - case '7': - return FARSI_7; - - case '8': - return FARSI_8; - - case '9': - return FARSI_9; - - case 'B': - return F_PSP; - - case 'E': - return JAZR_N; - - case 'F': - return ALEF_D_H; - - case 'H': - return ALEF_A; - - case 'I': - return TASH; - - case 'K': - return F_LQUOT; - - case 'L': - return F_RQUOT; - - case 'M': - return HAMZE; - - case 'O': - return '['; - - case 'P': - return ']'; - - case 'Q': - return OO; - - case 'R': - return MAD_N; - - case 'T': - return OW; - - case 'U': - return MAD; - - case 'W': - return OW_OW; - - case 'Y': - return JAZR; - - case '`': - return F_PCN; - - case '!': - return F_EXCL; - - case '@': - return F_COMMA; - - case '#': - return F_DIVIDE; - - case '$': - return F_CURRENCY; - - case '%': - return F_PERCENT; - - case '^': - return F_MUL; - - case '&': - return F_BCOMMA; - - case '*': - return F_STAR; - - case '(': - return F_LPARENT; - - case ')': - return F_RPARENT; - - case '-': - return F_MINUS; - - case '_': - return F_UNDERLINE; - - case '=': - return F_EQUALS; - - case '+': - return F_PLUS; - - case '\\': - return F_BSLASH; - - case '|': - return F_PIPE; - - case ':': - return F_DCOLON; - - case '"': - return F_SEMICOLON; - - case '.': - return F_PERIOD; - - case '/': - return F_SLASH; - - case '<': - return F_LESS; - - case '>': - return F_GREATER; - - case '?': - return F_QUESTION; - - case ' ': - return F_BLANK; + case '0' : return FARSI_0 ; + case '1' : return FARSI_1 ; + case '2' : return FARSI_2 ; + case '3' : return FARSI_3 ; + case '4' : return FARSI_4 ; + case '5' : return FARSI_5 ; + case '6' : return FARSI_6 ; + case '7' : return FARSI_7 ; + case '8' : return FARSI_8 ; + case '9' : return FARSI_9 ; + case 'B' : return F_PSP ; + case 'E' : return JAZR_N ; + case 'F' : return ALEF_D_H ; + case 'H' : return ALEF_A ; + case 'I' : return TASH ; + case 'K' : return F_LQUOT ; + case 'L' : return F_RQUOT ; + case 'M' : return HAMZE ; + case 'O' : return '[' ; + case 'P' : return ']' ; + case 'Q' : return OO ; + case 'R' : return MAD_N ; + case 'T' : return OW ; + case 'U' : return MAD ; + case 'W' : return OW_OW ; + case 'Y' : return JAZR ; + case '`' : return F_PCN ; + case '!' : return F_EXCL ; + case '@' : return F_COMMA ; + case '#' : return F_DIVIDE ; + case '$' : return F_CURRENCY ; + case '%' : return F_PERCENT ; + case '^' : return F_MUL ; + case '&' : return F_BCOMMA ; + case '*' : return F_STAR ; + case '(' : return F_LPARENT ; + case ')' : return F_RPARENT ; + case '-' : return F_MINUS ; + case '_' : return F_UNDERLINE ; + case '=' : return F_EQUALS ; + case '+' : return F_PLUS ; + case '\\' : return F_BSLASH ; + case '|' : return F_PIPE ; + case ':' : return F_DCOLON ; + case '"' : return F_SEMICOLON ; + case '.' : return F_PERIOD ; + case '/' : return F_SLASH ; + case '<' : return F_LESS ; + case '>' : return F_GREATER ; + case '?' : return F_QUESTION ; + case ' ' : return F_BLANK ; } break; } @@ -1246,7 +852,7 @@ int fkmap(int c) case _HE_: case _TA: case _ZA: - put_curr_and_l_to_X(toF_TyA(tempc)); + put_curr_and_l_to_X(toF_TyA((char_u)tempc)); break; case _AYN: @@ -1276,7 +882,7 @@ int fkmap(int c) inc_cursor(); } - put_curr_and_l_to_X(tempc); + put_curr_and_l_to_X((char_u)tempc); break; case _GHAYN: @@ -1307,7 +913,7 @@ int fkmap(int c) inc_cursor(); } - put_curr_and_l_to_X(tempc); + put_curr_and_l_to_X((char_u)tempc); break; case _YE: @@ -1316,8 +922,8 @@ int fkmap(int c) if (!p_ri) { if (!curwin->w_cursor.col) { - put_curr_and_l_to_X((tempc == _YE ? YE : - (tempc == _IE ? IE : YEE))); + put_curr_and_l_to_X( + (tempc == _YE ? YE : tempc == _IE ? IE : YEE)); break; } } @@ -1329,11 +935,9 @@ int fkmap(int c) } if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) { - tempc = (tempc == _YE ? YE_ : - (tempc == _IE ? IE_ : YEE_)); + tempc = (tempc == _YE ? YE_ : tempc == _IE ? IE_ : YEE_); } else { - tempc = (tempc == _YE ? YE : - (tempc == _IE ? IE : YEE)); + tempc = (tempc == _YE ? YE : tempc == _IE ? IE : YEE); } if (p_ri) { @@ -1342,7 +946,7 @@ int fkmap(int c) inc_cursor(); } - put_curr_and_l_to_X(tempc); + put_curr_and_l_to_X((char_u)tempc); break; } @@ -1353,200 +957,70 @@ int fkmap(int c) tempc = 0; switch (c) { - case '0': - return FARSI_0; - - case '1': - return FARSI_1; - - case '2': - return FARSI_2; - - case '3': - return FARSI_3; - - case '4': - return FARSI_4; - - case '5': - return FARSI_5; - - case '6': - return FARSI_6; - - case '7': - return FARSI_7; - - case '8': - return FARSI_8; - - case '9': - return FARSI_9; - - case 'B': - return F_PSP; - - case 'E': - return JAZR_N; - - case 'F': - return ALEF_D_H; - - case 'H': - return ALEF_A; - - case 'I': - return TASH; - - case 'K': - return F_LQUOT; - - case 'L': - return F_RQUOT; - - case 'M': - return HAMZE; - - case 'O': - return '['; - - case 'P': - return ']'; - - case 'Q': - return OO; - - case 'R': - return MAD_N; - - case 'T': - return OW; - - case 'U': - return MAD; - - case 'W': - return OW_OW; - - case 'Y': - return JAZR; - - case '`': - return F_PCN; - - case '!': - return F_EXCL; - - case '@': - return F_COMMA; - - case '#': - return F_DIVIDE; - - case '$': - return F_CURRENCY; - - case '%': - return F_PERCENT; - - case '^': - return F_MUL; - - case '&': - return F_BCOMMA; - - case '*': - return F_STAR; - - case '(': - return F_LPARENT; - - case ')': - return F_RPARENT; - - case '-': - return F_MINUS; - - case '_': - return F_UNDERLINE; - - case '=': - return F_EQUALS; - - case '+': - return F_PLUS; - - case '\\': - return F_BSLASH; - - case '|': - return F_PIPE; - - case ':': - return F_DCOLON; - - case '"': - return F_SEMICOLON; - - case '.': - return F_PERIOD; - - case '/': - return F_SLASH; - - case '<': - return F_LESS; - - case '>': - return F_GREATER; - - case '?': - return F_QUESTION; - - case ' ': - return F_BLANK; + case '0' : return FARSI_0 ; + case '1' : return FARSI_1 ; + case '2' : return FARSI_2 ; + case '3' : return FARSI_3 ; + case '4' : return FARSI_4 ; + case '5' : return FARSI_5 ; + case '6' : return FARSI_6 ; + case '7' : return FARSI_7 ; + case '8' : return FARSI_8 ; + case '9' : return FARSI_9 ; + case 'B' : return F_PSP ; + case 'E' : return JAZR_N ; + case 'F' : return ALEF_D_H ; + case 'H' : return ALEF_A ; + case 'I' : return TASH ; + case 'K' : return F_LQUOT ; + case 'L' : return F_RQUOT ; + case 'M' : return HAMZE ; + case 'O' : return '[' ; + case 'P' : return ']' ; + case 'Q' : return OO ; + case 'R' : return MAD_N ; + case 'T' : return OW ; + case 'U' : return MAD ; + case 'W' : return OW_OW ; + case 'Y' : return JAZR ; + case '`' : return F_PCN ; + case '!' : return F_EXCL ; + case '@' : return F_COMMA ; + case '#' : return F_DIVIDE ; + case '$' : return F_CURRENCY ; + case '%' : return F_PERCENT ; + case '^' : return F_MUL ; + case '&' : return F_BCOMMA ; + case '*' : return F_STAR ; + case '(' : return F_LPARENT ; + case ')' : return F_RPARENT ; + case '-' : return F_MINUS ; + case '_' : return F_UNDERLINE ; + case '=' : return F_EQUALS ; + case '+' : return F_PLUS ; + case '\\' : return F_BSLASH ; + case '|' : return F_PIPE ; + case ':' : return F_DCOLON ; + case '"' : return F_SEMICOLON ; + case '.' : return F_PERIOD ; + case '/' : return F_SLASH ; + case '<' : return F_LESS ; + case '>' : return F_GREATER ; + case '?' : return F_QUESTION ; + case ' ' : return F_BLANK ; } break; - case 'a': - tempc = _SHIN; - break; - - case 'A': - tempc = WAW_H; - break; - - case 'b': - tempc = ZAL; - break; - - case 'c': - tempc = ZE; - break; - - case 'C': - tempc = JE; - break; - - case 'd': - tempc = _YE; - break; - - case 'D': - tempc = _YEE; - break; - - case 'e': - tempc = _SE; - break; - - case 'f': - tempc = _BE; - break; - - case 'g': - tempc = _LAM; - break; + case 'a' : tempc = _SHIN ; break; + case 'A' : tempc = WAW_H ; break; + case 'b' : tempc = ZAL ; break; + case 'c' : tempc = ZE ; break; + case 'C' : tempc = JE ; break; + case 'd' : tempc = _YE ; break; + case 'D' : tempc = _YEE ; break; + case 'e' : tempc = _SE ; break; + case 'f' : tempc = _BE ; break; + case 'g' : tempc = _LAM ; break; case 'G': if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) { @@ -1621,7 +1095,6 @@ int fkmap(int c) return tempc; case 'i': - if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) { if (!p_ri && !F_is_TyE(tempc)) { chg_c_to_X_orX_(); @@ -1656,7 +1129,6 @@ int fkmap(int c) break; case 'J': - if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) { if (p_ri) { chg_c_to_X_or_X(); @@ -1683,50 +1155,18 @@ int fkmap(int c) return tempc; - case 'k': - tempc = _NOON; - break; - - case 'l': - tempc = _MIM; - break; - - case 'm': - tempc = _PE; - break; - - case 'n': - case 'N': - tempc = DAL; - break; - - case 'o': - tempc = _XE; - break; - - case 'p': - tempc = _HE_J; - break; - - case 'q': - tempc = _ZAD; - break; - - case 'r': - tempc = _GHAF; - break; - - case 's': - tempc = _SIN; - break; - - case 'S': - tempc = _IE; - break; - - case 't': - tempc = _FE; - break; + case 'k' : tempc = _NOON ; break; + case 'l' : tempc = _MIM ; break; + case 'm' : tempc = _PE ; break; + case 'n' : + case 'N' : tempc = DAL ; break; + case 'o' : tempc = _XE ; break; + case 'p' : tempc = _HE_J ; break; + case 'q' : tempc = _ZAD ; break; + case 'r' : tempc = _GHAF ; break; + case 's' : tempc = _SIN ; break; + case 'S' : tempc = _IE ; break; + case 't' : tempc = _FE ; break; case 'u': if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) { @@ -1758,19 +1198,11 @@ int fkmap(int c) } break; - case 'v': - case 'V': - tempc = RE; - break; - - case 'w': - tempc = _SAD; - break; - - case 'x': - case 'X': - tempc = _TA; - break; + case 'v' : + case 'V' : tempc = RE ; break; + case 'w' : tempc = _SAD ; break; + case 'x' : + case 'X' : tempc = _TA ; break; case 'y': if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) { @@ -1803,33 +1235,13 @@ int fkmap(int c) break; - case 'z': - tempc = _ZA; - break; - - case 'Z': - tempc = _KAF_H; - break; - - case ';': - tempc = _KAF; - break; - - case '\'': - tempc = _GAF; - break; - - case ',': - tempc = WAW; - break; - - case '[': - tempc = _JIM; - break; - - case ']': - tempc = _CHE; - break; + case 'z' : tempc = _ZA ; break; + case 'Z' : tempc = _KAF_H ; break; + case ';' : tempc = _KAF ; break; + case '\'' : tempc = _GAF ; break; + case ',' : tempc = WAW ; break; + case '[' : tempc = _JIM ; break; + case ']' : tempc = _CHE ; break; } if ((F_isalpha(tempc) || F_isdigit(tempc))) { @@ -1871,99 +1283,50 @@ int fkmap(int c) /// @param c The character to convert. /// /// @return The non-leading Farsi character converted to a leading type. -static int toF_leading(int c) +static char_u toF_leading(char_u c) { - switch (c) { - case ALEF_: - return ALEF; - - case ALEF_U_H_: - return ALEF_U_H; - - case BE: - return _BE; - - case PE: - return _PE; + char_u tempc; - case TE: - return _TE; - - case SE: - return _SE; - - case JIM: - return _JIM; - - case CHE: - return _CHE; - - case HE_J: - return _HE_J; - - case XE: - return _XE; - - case SIN: - return _SIN; - - case SHIN: - return _SHIN; - - case SAD: - return _SAD; - - case ZAD: - return _ZAD; - - case AYN: - case AYN_: - case _AYN_: - return _AYN; - - case GHAYN: - case GHAYN_: - case _GHAYN_: - return _GHAYN; - - case FE: - return _FE; - - case GHAF: - return _GHAF; - - case KAF: - return _KAF; - - case GAF: - return _GAF; - - case LAM: - return _LAM; - - case MIM: - return _MIM; - - case NOON: - return _NOON; - - case _HE_: - case F_HE: - return _HE; - - case YE: - case YE_: - return _YE; - - case IE_: - case IE: - return _IE; - - case YEE: - case YEE_: - return _YEE; + switch (c) { + case ALEF_ : tempc = ALEF ; break; + case ALEF_U_H_ : tempc = ALEF_U_H ; break; + case BE : tempc = _BE ; break; + case PE : tempc = _PE ; break; + case TE : tempc = _TE ; break; + case SE : tempc = _SE ; break; + case JIM : tempc = _JIM ; break; + case CHE : tempc = _CHE ; break; + case HE_J : tempc = _HE_J ; break; + case XE : tempc = _XE ; break; + case SIN : tempc = _SIN ; break; + case SHIN : tempc = _SHIN ; break; + case SAD : tempc = _SAD ; break; + case ZAD : tempc = _ZAD ; break; + case AYN : + case AYN_ : + case _AYN_ : tempc = _AYN ; break; + case GHAYN : + case GHAYN_ : + case _GHAYN_ : tempc = _GHAYN ; break; + case FE : tempc = _FE ; break; + case GHAF : tempc = _GHAF ; break; + case KAF : tempc = _KAF ; break; + case GAF : tempc = _GAF ; break; + case LAM : tempc = _LAM ; break; + case MIM : tempc = _MIM ; break; + case NOON : tempc = _NOON ; break; + case _HE_ : + case F_HE : tempc = _HE ; break; + case YE : + case YE_ : tempc = _YE ; break; + case IE_ : + case IE : tempc = _IE ; break; + case YEE : + case YEE_ : tempc = _YEE ; break; + default : tempc = c; } - return c; + + return tempc; } /// Convert a given Farsi char into right joining type. @@ -1971,102 +1334,51 @@ static int toF_leading(int c) /// @param c The character to convert. /// /// @return The Farsi character converted into a right joining type -static int toF_Rjoin(int c) +static char_u toF_Rjoin(char_u c) { - switch (c) { - case ALEF: - return ALEF_; - - case ALEF_U_H: - return ALEF_U_H_; - - case BE: - return _BE; - - case PE: - return _PE; - - case TE: - return _TE; - - case SE: - return _SE; - - case JIM: - return _JIM; + char_u tempc; - case CHE: - return _CHE; - - case HE_J: - return _HE_J; - - case XE: - return _XE; - - case SIN: - return _SIN; - - case SHIN: - return _SHIN; - - case SAD: - return _SAD; - - case ZAD: - return _ZAD; - - case AYN: - case AYN_: - case _AYN: - return _AYN_; - - case GHAYN: - case GHAYN_: - case _GHAYN_: - return _GHAYN_; - - case FE: - return _FE; - - case GHAF: - return _GHAF; - - case KAF: - return _KAF; - - case GAF: - return _GAF; - - case LAM: - return _LAM; - - case MIM: - return _MIM; - - case NOON: - return _NOON; - - case _HE: - case F_HE: - return _HE_; - - case YE: - case YE_: - return _YE; - - case IE_: - case IE: - return _IE; - - case TEE: - return TEE_; - - case YEE: - case YEE_: - return _YEE; + switch (c) { + case ALEF : tempc = ALEF_ ; break; + case ALEF_U_H : tempc = ALEF_U_H_ ; break; + case BE : tempc = _BE ; break; + case PE : tempc = _PE ; break; + case TE : tempc = _TE ; break; + case SE : tempc = _SE ; break; + case JIM : tempc = _JIM ; break; + case CHE : tempc = _CHE ; break; + case HE_J : tempc = _HE_J ; break; + case XE : tempc = _XE ; break; + case SIN : tempc = _SIN ; break; + case SHIN : tempc = _SHIN ; break; + case SAD : tempc = _SAD ; break; + case ZAD : tempc = _ZAD ; break; + case AYN : + case AYN_ : + case _AYN : tempc = _AYN_ ; break; + case GHAYN : + case GHAYN_ : + case _GHAYN_ : tempc = _GHAYN_ ; break; + case FE : tempc = _FE ; break; + case GHAF : tempc = _GHAF ; break; + case KAF : tempc = _KAF ; break; + case GAF : tempc = _GAF ; break; + case LAM : tempc = _LAM ; break; + case MIM : tempc = _MIM ; break; + case NOON : tempc = _NOON ; break; + case _HE : + case F_HE : tempc = _HE_ ; break; + case YE : + case YE_ : tempc = _YE ; break; + case IE_ : + case IE : tempc = _IE ; break; + case TEE : tempc = TEE_ ; break; + case YEE : + case YEE_ : tempc = _YEE ; break; + default : tempc = c ; } - return c; + + return tempc; } /// Can a given Farsi character join via its left edj. @@ -2074,7 +1386,7 @@ static int toF_Rjoin(int c) /// @param c The character to check. /// /// @return true if the character can join via its left edj. -static bool canF_Ljoin(int c) +static bool canF_Ljoin(char_u c) { switch (c) { case _BE: @@ -2148,7 +1460,7 @@ static bool canF_Ljoin(int c) /// @param c /// /// @return true if the character can join via its right edj. -static bool canF_Rjoin(int c) +static bool canF_Rjoin(char_u c) { switch (c) { case ALEF: @@ -2174,7 +1486,7 @@ static bool canF_Rjoin(int c) /// @param c /// /// @return true if the character is a terminating type. -static bool F_isterm(int c) +static bool F_isterm(char_u c) { switch (c) { case ALEF: @@ -2200,105 +1512,48 @@ static bool F_isterm(int c) /// @param c The character to convert. /// /// @return The character converted into an ending type. -static int toF_ending(int c) +static char_u toF_ending(char_u c) { - switch (c) { - case _BE: - return BE; - - case _PE: - return PE; - - case _TE: - return TE; - - case _SE: - return SE; - - case _JIM: - return JIM; - - case _CHE: - return CHE; - - case _HE_J: - return HE_J; - - case _XE: - return XE; - - case _SIN: - return SIN; - - case _SHIN: - return SHIN; - - case _SAD: - return SAD; + char_u tempc; - case _ZAD: - return ZAD; - - case _AYN: - return AYN; - - case _AYN_: - return AYN_; - - case _GHAYN: - return GHAYN; - - case _GHAYN_: - return GHAYN_; - - case _FE: - return FE; - - case _GHAF: - return GHAF; - - case _KAF_H: - case _KAF: - return KAF; - - case _GAF: - return GAF; - - case _LAM: - return LAM; - - case _MIM: - return MIM; - - case _NOON: - return NOON; - - case _YE: - return YE_; - - case YE_: - return YE; - - case _YEE: - return YEE_; - - case YEE_: - return YEE; - - case TEE: - return TEE_; - - case _IE: - return IE_; - - case IE_: - return IE; - - case _HE: - case _HE_: - return F_HE; + switch (c) { + case _BE : tempc = BE ; break; + case _PE : tempc = PE ; break; + case _TE : tempc = TE ; break; + case _SE : tempc = SE ; break; + case _JIM : tempc = JIM ; break; + case _CHE : tempc = CHE ; break; + case _HE_J : tempc = HE_J ; break; + case _XE : tempc = XE ; break; + case _SIN : tempc = SIN ; break; + case _SHIN : tempc = SHIN ; break; + case _SAD : tempc = SAD ; break; + case _ZAD : tempc = ZAD ; break; + case _AYN : tempc = AYN ; break; + case _AYN_ : tempc = AYN_ ; break; + case _GHAYN : tempc = GHAYN ; break; + case _GHAYN_ : tempc = GHAYN_ ; break; + case _FE : tempc = FE ; break; + case _GHAF : tempc = GHAF ; break; + case _KAF_H : + case _KAF : tempc = KAF ; break; + case _GAF : tempc = GAF ; break; + case _LAM : tempc = LAM ; break; + case _MIM : tempc = MIM ; break; + case _NOON : tempc = NOON ; break; + case _YE : tempc = YE_ ; break; + case YE_ : tempc = YE ; break; + case _YEE : tempc = YEE_ ; break; + case YEE_ : tempc = YEE ; break; + case TEE : tempc = TEE_ ; break; + case _IE : tempc = IE_ ; break; + case IE_ : tempc = IE ; break; + case _HE : + case _HE_ : tempc = F_HE ; break; + default : tempc = c ; } - return c; + + return tempc; } /// Convert the Farsi 3342 standard into Farsi VIM. @@ -2369,7 +1624,7 @@ void conv_to_pstd(void) static void lrswapbuf(char_u *buf, int len) { char_u *s, *e; - int c; + char_u c; s = buf; e = buf + len - 1; @@ -2442,6 +1697,7 @@ char_u* lrF_sub(char_u *ibuf) // Find the boundary of the search path while (((p = vim_strchr(p + 1, '/')) != NULL) && p[-1] == '\\') { + // empty } if (p == NULL) { @@ -2560,15 +1816,15 @@ int cmdl_fkmap(int c) case _NOON: case _HE: case _HE_: - cmd_pchar(toF_TyA(tempc), AT_CURSOR); + cmd_pchar(toF_TyA((char_u)tempc), AT_CURSOR); break; case _AYN_: - cmd_pchar(AYN_, AT_CURSOR); + cmd_pchar(AYN_, AT_CURSOR); break; case _GHAYN_: - cmd_pchar(GHAYN_, AT_CURSOR); + cmd_pchar(GHAYN_, AT_CURSOR); break; case _IE: @@ -2596,190 +1852,70 @@ int cmdl_fkmap(int c) } switch (c) { - case '0': - return FARSI_0; - - case '1': - return FARSI_1; - - case '2': - return FARSI_2; - - case '3': - return FARSI_3; - - case '4': - return FARSI_4; - - case '5': - return FARSI_5; - - case '6': - return FARSI_6; - - case '7': - return FARSI_7; - - case '8': - return FARSI_8; - - case '9': - return FARSI_9; - - case 'B': - return F_PSP; - - case 'E': - return JAZR_N; - - case 'F': - return ALEF_D_H; - - case 'H': - return ALEF_A; - - case 'I': - return TASH; - - case 'K': - return F_LQUOT; - - case 'L': - return F_RQUOT; - - case 'M': - return HAMZE; - - case 'O': - return '['; - - case 'P': - return ']'; - - case 'Q': - return OO; - - case 'R': - return MAD_N; - - case 'T': - return OW; - - case 'U': - return MAD; - - case 'W': - return OW_OW; - - case 'Y': - return JAZR; - - case '`': - return F_PCN; - - case '!': - return F_EXCL; - - case '@': - return F_COMMA; - - case '#': - return F_DIVIDE; - - case '$': - return F_CURRENCY; - - case '%': - return F_PERCENT; - - case '^': - return F_MUL; - - case '&': - return F_BCOMMA; - - case '*': - return F_STAR; - - case '(': - return F_LPARENT; - - case ')': - return F_RPARENT; - - case '-': - return F_MINUS; - - case '_': - return F_UNDERLINE; - - case '=': - return F_EQUALS; - - case '+': - return F_PLUS; - - case '\\': - return F_BSLASH; - - case '|': - return F_PIPE; - - case ':': - return F_DCOLON; - - case '"': - return F_SEMICOLON; - - case '.': - return F_PERIOD; - - case '/': - return F_SLASH; - - case '<': - return F_LESS; - - case '>': - return F_GREATER; - - case '?': - return F_QUESTION; - - case ' ': - return F_BLANK; + case '0' : return FARSI_0 ; + case '1' : return FARSI_1 ; + case '2' : return FARSI_2 ; + case '3' : return FARSI_3 ; + case '4' : return FARSI_4 ; + case '5' : return FARSI_5 ; + case '6' : return FARSI_6 ; + case '7' : return FARSI_7 ; + case '8' : return FARSI_8 ; + case '9' : return FARSI_9 ; + case 'B' : return F_PSP ; + case 'E' : return JAZR_N ; + case 'F' : return ALEF_D_H ; + case 'H' : return ALEF_A ; + case 'I' : return TASH ; + case 'K' : return F_LQUOT ; + case 'L' : return F_RQUOT ; + case 'M' : return HAMZE ; + case 'O' : return '[' ; + case 'P' : return ']' ; + case 'Q' : return OO ; + case 'R' : return MAD_N ; + case 'T' : return OW ; + case 'U' : return MAD ; + case 'W' : return OW_OW ; + case 'Y' : return JAZR ; + case '`' : return F_PCN ; + case '!' : return F_EXCL ; + case '@' : return F_COMMA ; + case '#' : return F_DIVIDE ; + case '$' : return F_CURRENCY ; + case '%' : return F_PERCENT ; + case '^' : return F_MUL ; + case '&' : return F_BCOMMA ; + case '*' : return F_STAR ; + case '(' : return F_LPARENT ; + case ')' : return F_RPARENT ; + case '-' : return F_MINUS ; + case '_' : return F_UNDERLINE ; + case '=' : return F_EQUALS ; + case '+' : return F_PLUS ; + case '\\' : return F_BSLASH ; + case '|' : return F_PIPE ; + case ':' : return F_DCOLON ; + case '"' : return F_SEMICOLON ; + case '.' : return F_PERIOD ; + case '/' : return F_SLASH ; + case '<' : return F_LESS ; + case '>' : return F_GREATER ; + case '?' : return F_QUESTION ; + case ' ' : return F_BLANK ; } break; - case 'a': - return _SHIN; - - case 'A': - return WAW_H; - - case 'b': - return ZAL; - - case 'c': - return ZE; - - case 'C': - return JE; - - case 'd': - return _YE; - - case 'D': - return _YEE; - - case 'e': - return _SE; - - case 'f': - return _BE; - - case 'g': - return _LAM; + case 'a' : return _SHIN ; + case 'A' : return WAW_H ; + case 'b' : return ZAL ; + case 'c' : return ZE ; + case 'C' : return JE ; + case 'd' : return _YE ; + case 'D' : return _YEE ; + case 'e' : return _SE ; + case 'f' : return _BE ; + case 'g' : return _LAM ; case 'G': if (cmd_gchar(AT_CURSOR) == _LAM) { @@ -2823,39 +1959,18 @@ int cmdl_fkmap(int c) return TEE; } - case 'k': - return _NOON; - - case 'l': - return _MIM; - - case 'm': - return _PE; - - case 'n': - case 'N': - return DAL; - - case 'o': - return _XE; - - case 'p': - return _HE_J; - - case 'q': - return _ZAD; - - case 'r': - return _GHAF; - - case 's': - return _SIN; - - case 'S': - return _IE; - - case 't': - return _FE; + case 'k' : return _NOON ; + case 'l' : return _MIM ; + case 'm' : return _PE ; + case 'n' : + case 'N' : return DAL ; + case 'o' : return _XE ; + case 'p' : return _HE_J ; + case 'q' : return _ZAD ; + case 'r' : return _GHAF ; + case 's' : return _SIN ; + case 'S' : return _IE ; + case 't' : return _FE ; case 'u': if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR)) { @@ -2864,16 +1979,11 @@ int cmdl_fkmap(int c) return _AYN; } - case 'v': - case 'V': - return RE; - - case 'w': - return _SAD; - - case 'x': - case 'X': - return _TA; + case 'v' : + case 'V' : return RE ; + case 'w' : return _SAD ; + case 'x' : + case 'X' : return _TA ; case 'y': if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR)) { @@ -2882,24 +1992,13 @@ int cmdl_fkmap(int c) return _GHAYN; } - case 'z': - case 'Z': - return _ZA; - - case ';': - return _KAF; - - case '\'': - return _GAF; - - case ',': - return WAW; - - case '[': - return _JIM; - - case ']': - return _CHE; + case 'z' : + case 'Z' : return _ZA ; + case ';' : return _KAF ; + case '\'' : return _GAF ; + case ',' : return WAW ; + case '[' : return _JIM ; + case ']' : return _CHE ; } return c; diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 267c586543..281e5b5768 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -114,9 +114,9 @@ static int prev_lnum_lvl = -1; #define DONE_ACTION 1 /* did close or open a fold */ #define DONE_FOLD 2 /* did find a fold */ -static int foldstartmarkerlen; +static size_t foldstartmarkerlen; static char_u *foldendmarker; -static int foldendmarkerlen; +static size_t foldendmarkerlen; /* Exported folding functions. {{{1 */ /* copyFoldingState() {{{2 */ @@ -622,7 +622,7 @@ void foldCreate(linenr_T start, linenr_T end) if (end_rel < fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1) end_rel = fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1; /* Move contained folds to inside new fold. */ - memmove(fold_ga.ga_data, fp, sizeof(fold_T) * cont); + memmove(fold_ga.ga_data, fp, sizeof(fold_T) * (size_t)cont); fold_ga.ga_len += cont; i += cont; @@ -634,7 +634,7 @@ void foldCreate(linenr_T start, linenr_T end) /* Move remaining entries to after the new fold. */ if (i < gap->ga_len) memmove(fp + 1, (fold_T *)gap->ga_data + i, - sizeof(fold_T) * (gap->ga_len - i)); + sizeof(fold_T) * (size_t)(gap->ga_len - i)); gap->ga_len = gap->ga_len + 1 - cont; /* insert new fold */ @@ -1051,7 +1051,7 @@ static int foldFind(garray_T *gap, linenr_T lnum, fold_T **fpp) low = 0; high = gap->ga_len - 1; while (low <= high) { - int i = (low + high) / 2; + linenr_T i = (low + high) / 2; if (fp[i].fd_top > lnum) /* fold below lnum, adjust high */ high = i - 1; @@ -1292,7 +1292,6 @@ static void deleteFoldEntry(garray_T *gap, int idx, int recursive) { fold_T *fp; int i; - long moved; fold_T *nfp; fp = (fold_T *)gap->ga_data + idx; @@ -1301,12 +1300,12 @@ static void deleteFoldEntry(garray_T *gap, int idx, int recursive) deleteFoldRecurse(&fp->fd_nested); --gap->ga_len; if (idx < gap->ga_len) - memmove(fp, fp + 1, sizeof(fold_T) * (gap->ga_len - idx)); + memmove(fp, fp + 1, sizeof(fold_T) * (size_t)(gap->ga_len - idx)); } else { /* Move nested folds one level up, to overwrite the fold that is * deleted. */ - moved = fp->fd_nested.ga_len; - ga_grow(gap, (int)(moved - 1)); + int moved = fp->fd_nested.ga_len; + ga_grow(gap, moved - 1); { /* Get "fp" again, the array may have been reallocated. */ fp = (fold_T *)gap->ga_data + idx; @@ -1324,9 +1323,9 @@ static void deleteFoldEntry(garray_T *gap, int idx, int recursive) /* move the existing folds down to make room */ if (idx + 1 < gap->ga_len) memmove(fp + moved, fp + 1, - sizeof(fold_T) * (gap->ga_len - (idx + 1))); + sizeof(fold_T) * (size_t)(gap->ga_len - (idx + 1))); /* move the contained folds one level up */ - memmove(fp, nfp, (size_t)(sizeof(fold_T) * moved)); + memmove(fp, nfp, sizeof(fold_T) * (size_t)moved); free(nfp); gap->ga_len += moved - 1; } @@ -1584,17 +1583,16 @@ static void foldCreateMarkers(linenr_T start, linenr_T end) /* * Add "marker[markerlen]" in 'commentstring' to line "lnum". */ -static void foldAddMarker(linenr_T lnum, char_u *marker, int markerlen) +static void foldAddMarker(linenr_T lnum, char_u *marker, size_t markerlen) { char_u *cms = curbuf->b_p_cms; char_u *line; - int line_len; char_u *newline; char_u *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s"); /* Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end */ line = ml_get(lnum); - line_len = (int)STRLEN(line); + size_t line_len = STRLEN(line); if (u_save(lnum - 1, lnum + 1) == OK) { newline = xmalloc(line_len + markerlen + STRLEN(cms) + 1); @@ -1629,8 +1627,8 @@ deleteFoldMarkers ( } } foldDelMarker(fp->fd_top + lnum_off, curwin->w_p_fmr, foldstartmarkerlen); - foldDelMarker(fp->fd_top + lnum_off + fp->fd_len - 1, - foldendmarker, foldendmarkerlen); + foldDelMarker(fp->fd_top + lnum_off + fp->fd_len - 1, foldendmarker, + foldendmarkerlen); } /* foldDelMarker() {{{2 */ @@ -1640,7 +1638,7 @@ deleteFoldMarkers ( * If the marker is not found, there is no error message. Could a missing * close-marker. */ -static void foldDelMarker(linenr_T lnum, char_u *marker, int markerlen) +static void foldDelMarker(linenr_T lnum, char_u *marker, size_t markerlen) { char_u *newline; char_u *cms = curbuf->b_p_cms; @@ -1652,7 +1650,7 @@ static void foldDelMarker(linenr_T lnum, char_u *marker, int markerlen) continue; } /* Found the marker, include a digit if it's there. */ - int len = markerlen; + size_t len = markerlen; if (VIM_ISDIGIT(p[len])) ++len; if (*cms != NUL) { @@ -1662,7 +1660,7 @@ static void foldDelMarker(linenr_T lnum, char_u *marker, int markerlen) && STRNCMP(p - (cms2 - cms), cms, cms2 - cms) == 0 && STRNCMP(p + len, cms2 + 2, STRLEN(cms2 + 2)) == 0) { p -= cms2 - cms; - len += (int)STRLEN(cms) - 2; + len += STRLEN(cms) - 2; } } if (u_save(lnum - 1, lnum + 1) == OK) { @@ -1781,27 +1779,23 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, */ void foldtext_cleanup(char_u *str) { - char_u *cms_start; /* first part or the whole comment */ - int cms_slen = 0; /* length of cms_start */ - char_u *cms_end; /* last part of the comment or NULL */ - int cms_elen = 0; /* length of cms_end */ char_u *s; char_u *p; - int len; int did1 = FALSE; int did2 = FALSE; /* Ignore leading and trailing white space in 'commentstring'. */ - cms_start = skipwhite(curbuf->b_p_cms); - cms_slen = (int)STRLEN(cms_start); + char_u *cms_start = skipwhite(curbuf->b_p_cms); + size_t cms_slen = STRLEN(cms_start); while (cms_slen > 0 && vim_iswhite(cms_start[cms_slen - 1])) --cms_slen; /* locate "%s" in 'commentstring', use the part before and after it. */ - cms_end = (char_u *)strstr((char *)cms_start, "%s"); + char_u *cms_end = (char_u *)strstr((char *)cms_start, "%s"); + size_t cms_elen = 0; if (cms_end != NULL) { - cms_elen = cms_slen - (int)(cms_end - cms_start); - cms_slen = (int)(cms_end - cms_start); + cms_elen = cms_slen - (size_t)(cms_end - cms_start); + cms_slen = (size_t)(cms_end - cms_start); /* exclude white space before "%s" */ while (cms_slen > 0 && vim_iswhite(cms_start[cms_slen - 1])) @@ -1809,13 +1803,13 @@ void foldtext_cleanup(char_u *str) /* skip "%s" and white space after it */ s = skipwhite(cms_end + 2); - cms_elen -= (int)(s - cms_end); + cms_elen -= (size_t)(s - cms_end); cms_end = s; } parseMarker(curwin); for (s = str; *s != NUL; ) { - len = 0; + size_t len = 0; if (STRNCMP(s, curwin->w_p_fmr, foldstartmarkerlen) == 0) len = foldstartmarkerlen; else if (STRNCMP(s, foldendmarker, foldendmarkerlen) == 0) @@ -1830,7 +1824,7 @@ void foldtext_cleanup(char_u *str) ; if (p >= str + cms_slen && STRNCMP(p - cms_slen, cms_start, cms_slen) == 0) { - len += (int)(s - p) + cms_slen; + len += (size_t)(s - p) + cms_slen; s = p - cms_slen; } } else if (cms_end != NULL) { @@ -2035,8 +2029,8 @@ static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot) if (fline.lvl > 0) { invalid_top = fline.lnum; invalid_bot = end; - end = foldUpdateIEMSRecurse(&wp->w_folds, - 1, start, &fline, getlevel, end, FD_LEVEL); + end = foldUpdateIEMSRecurse(&wp->w_folds, 1, start, &fline, getlevel, end, + FD_LEVEL); start = fline.lnum; } else { if (fline.lnum == wp->w_buffer->b_ml.ml_line_count) @@ -2095,7 +2089,7 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level, linenr_T startlnum, fline_T *flp, LevelGetter getlevel, linenr_T bot, - int topflags /* flags used by containing fold */ + char topflags /* containing fold flags */ ) { linenr_T ll; @@ -2333,8 +2327,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level, flp->off += fp->fd_top; i = (int)(fp - (fold_T *)gap->ga_data); bot = foldUpdateIEMSRecurse(&fp->fd_nested, level + 1, - startlnum2 - fp->fd_top, flp, getlevel, - bot - fp->fd_top, fp->fd_flags); + startlnum2 - fp->fd_top, flp, getlevel, + bot - fp->fd_top, fp->fd_flags); fp = (fold_T *)gap->ga_data + i; flp->lnum += fp->fd_top; flp->lnum_save += fp->fd_top; @@ -2468,7 +2462,7 @@ static void foldInsert(garray_T *gap, int i) fp = (fold_T *)gap->ga_data + i; if (i < gap->ga_len) - memmove(fp + 1, fp, sizeof(fold_T) * (gap->ga_len - i)); + memmove(fp + 1, fp, sizeof(fold_T) * (size_t)(gap->ga_len - i)); ++gap->ga_len; ga_init(&fp->fd_nested, (int)sizeof(fold_T), 10); } @@ -2649,9 +2643,7 @@ static void foldlevelIndent(fline_T *flp) } else flp->lvl = get_indent_buf(buf, lnum) / get_sw_value(curbuf); if (flp->lvl > flp->wp->w_p_fdn) { - flp->lvl = flp->wp->w_p_fdn; - if (flp->lvl < 0) - flp->lvl = 0; + flp->lvl = (int) MAX(0, flp->wp->w_p_fdn); } } @@ -2768,8 +2760,8 @@ static void foldlevelExpr(fline_T *flp) static void parseMarker(win_T *wp) { foldendmarker = vim_strchr(wp->w_p_fmr, ','); - foldstartmarkerlen = (int)(foldendmarker++ - wp->w_p_fmr); - foldendmarkerlen = (int)STRLEN(foldendmarker); + foldstartmarkerlen = (size_t)(foldendmarker++ - wp->w_p_fmr); + foldendmarkerlen = STRLEN(foldendmarker); } /* foldlevelMarker() {{{2 */ @@ -2822,9 +2814,8 @@ static void foldlevelMarker(fline_T *flp) ++flp->lvl_next; ++flp->start; } - } else if (*s == cend - && STRNCMP(s + 1, foldendmarker + 1, - foldendmarkerlen - 1) == 0) { + } else if (*s == cend && STRNCMP(s + 1, foldendmarker + 1, + foldendmarkerlen - 1) == 0) { /* found endmarker: set flp->lvl_next */ s += foldendmarkerlen; if (VIM_ISDIGIT(*s)) { diff --git a/src/nvim/fold.h b/src/nvim/fold.h index 1cbd7af5da..2ff10c0e91 100644 --- a/src/nvim/fold.h +++ b/src/nvim/fold.h @@ -1,14 +1,16 @@ #ifndef NVIM_FOLD_H #define NVIM_FOLD_H +#include "nvim/pos.h" + /* * Info used to pass info about a fold from the fold-detection code to the * code that displays the foldcolumn. */ typedef struct foldinfo { + linenr_T fi_lnum; /* line number where fold starts */ int fi_level; /* level of the fold; when this is zero the other fields are invalid */ - int fi_lnum; /* line number where fold starts */ int fi_low_level; /* lowest fold level that starts in the same line */ } foldinfo_T; diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c index 8310f635c9..3b9214abc1 100644 --- a/src/nvim/indent_c.c +++ b/src/nvim/indent_c.c @@ -1332,7 +1332,7 @@ void parse_cino(buf_T *buf) char_u *l; int divider; int fraction = 0; - int sw = (int)get_sw_value(buf); + int sw = get_sw_value(buf); /* * Set the default values. diff --git a/src/nvim/menu.c b/src/nvim/menu.c index 95cc33e4d9..8d9b5045b9 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -300,8 +300,6 @@ add_menu_path ( } else en_name = NULL; dname = menu_text(name, NULL, NULL); - if (dname == NULL) - goto erret; if (*dname == NUL) { /* Only a mnemonic or accelerator is not valid. */ EMSG(_("E792: Empty menu name")); @@ -1156,14 +1154,20 @@ static char_u *popup_mode_name(char_u *name, int idx) } -/* - * Duplicate the menu item text and then process to see if a mnemonic key - * and/or accelerator text has been identified. - * Returns a pointer to allocated memory, or NULL for failure. - * If mnemonic != NULL, *mnemonic is set to the character after the first '&'. - * If actext != NULL, *actext is set to the text after the first TAB. - */ -static char_u *menu_text(char_u *str, int *mnemonic, char_u **actext) +/// Duplicate the menu item text and then process to see if a mnemonic key +/// and/or accelerator text has been identified. +/// +/// @param str The menu item text. +/// @param[out] mnemonic If non-NULL, *mnemonic is set to the character after +/// the first '&'. +/// @param[out] actext If non-NULL, *actext is set to the text after the first +/// TAB, but only if a TAB was found. Memory pointed to is newly +/// allocated. +/// +/// @return a pointer to allocated memory. +static char_u *menu_text(const char_u *str, int *mnemonic, char_u **actext) + FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT + FUNC_ATTR_NONNULL_ARG(1) { char_u *p; char_u *text; @@ -1463,19 +1467,14 @@ void ex_menutranslate(exarg_T *eap) from = vim_strsave(from); from_noamp = menu_text(from, NULL, NULL); to = vim_strnsave(to, (int)(arg - to)); - if (from_noamp != NULL) { - menu_translate_tab_and_shift(from); - menu_translate_tab_and_shift(to); - menu_unescape_name(from); - menu_unescape_name(to); - menutrans_T* tp = GA_APPEND_VIA_PTR(menutrans_T, &menutrans_ga); - tp->from = from; - tp->from_noamp = from_noamp; - tp->to = to; - } else { - free(from); - free(to); - } + menu_translate_tab_and_shift(from); + menu_translate_tab_and_shift(to); + menu_unescape_name(from); + menu_unescape_name(to); + menutrans_T* tp = GA_APPEND_VIA_PTR(menutrans_T, &menutrans_ga); + tp->from = from; + tp->from_noamp = from_noamp; + tp->to = to; } } } @@ -1502,7 +1501,7 @@ static char_u *menutrans_lookup(char_u *name, int len) menutrans_T *tp = (menutrans_T *)menutrans_ga.ga_data; char_u *dname; - for (int i = 0; i < menutrans_ga.ga_len; ++i) { + for (int i = 0; i < menutrans_ga.ga_len; i++) { if (STRNCMP(name, tp[i].from, len) == 0 && tp[i].from[len] == NUL) { return tp[i].to; } @@ -1513,15 +1512,13 @@ static char_u *menutrans_lookup(char_u *name, int len) name[len] = NUL; dname = menu_text(name, NULL, NULL); name[len] = c; - if (dname != NULL) { - for (int i = 0; i < menutrans_ga.ga_len; ++i) { - if (STRCMP(dname, tp[i].from_noamp) == 0) { - free(dname); - return tp[i].to; - } + for (int i = 0; i < menutrans_ga.ga_len; i++) { + if (STRCMP(dname, tp[i].from_noamp) == 0) { + free(dname); + return tp[i].to; } - free(dname); } + free(dname); return NULL; } diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index 5d8b88601e..e58ec71e77 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -796,7 +796,7 @@ open_line ( ) { ++curwin->w_cursor.lnum; if (did_si) { - int sw = (int)get_sw_value(curbuf); + int sw = get_sw_value(curbuf); if (p_sr) newindent -= newindent % sw; diff --git a/src/nvim/move.c b/src/nvim/move.c index 1ba064c65f..65f2853073 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -16,6 +16,7 @@ * The 'scrolloff' option makes this a bit complicated. */ +#include <assert.h> #include <inttypes.h> #include <stdbool.h> @@ -135,13 +136,13 @@ void update_topline(void) { long line_count; int halfheight; - int n; + long n; linenr_T old_topline; int old_topfill; linenr_T lnum; int check_topline = FALSE; int check_botline = FALSE; - int save_so = p_so; + long save_so = p_so; if (!screen_valid(TRUE)) return; @@ -342,9 +343,9 @@ void update_topline_win(win_T* win) */ static int scrolljump_value(void) { - if (p_sj >= 0) - return (int)p_sj; - return (curwin->w_height * -p_sj) / 100; + long result = p_sj >= 0 ? p_sj : (curwin->w_height * -p_sj) / 100; + assert(result <= INT_MAX); + return (int)result; } /* @@ -711,7 +712,7 @@ int win_col_off(win_T *wp) { return ((wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) + 1 : 0) + (cmdwin_type == 0 || wp != curwin ? 0 : 1) - + wp->w_p_fdc + + (int)wp->w_p_fdc + (wp->w_buffer->b_signlist != NULL ? 2 : 0) ; } @@ -831,9 +832,9 @@ curs_columns ( * If we get closer to the edge than 'sidescrolloff', scroll a little * extra */ - off_left = (int)startcol - (int)curwin->w_leftcol - p_siso; - off_right = (int)endcol - (int)(curwin->w_leftcol + curwin->w_width - - p_siso) + 1; + assert(p_siso <= INT_MAX); + off_left = startcol - curwin->w_leftcol - (int)p_siso; + off_right = endcol - curwin->w_leftcol - curwin->w_width + (int)p_siso + 1; if (off_left < 0 || off_right > 0) { if (off_left < 0) diff = -off_left; @@ -845,8 +846,10 @@ curs_columns ( if (p_ss == 0 || diff >= textwidth / 2 || off_right >= off_left) new_leftcol = curwin->w_wcol - extra - textwidth / 2; else { - if (diff < p_ss) - diff = p_ss; + if (diff < p_ss) { + assert(p_ss <= INT_MAX); + diff = (int)p_ss; + } if (off_left < 0) new_leftcol = curwin->w_leftcol - diff; else @@ -902,8 +905,10 @@ curs_columns ( if (p_lines == 0) p_lines = plines_win(curwin, curwin->w_cursor.lnum, FALSE); --p_lines; - if (p_lines > curwin->w_wrow + p_so) - n = curwin->w_wrow + p_so; + if (p_lines > curwin->w_wrow + p_so) { + assert(p_so <= INT_MAX); + n = curwin->w_wrow + (int)p_so; + } else n = p_lines; if ((colnr_T)n >= curwin->w_height + curwin->w_skipcol / width) @@ -922,7 +927,8 @@ curs_columns ( curwin->w_skipcol = n * width; } else if (extra == 1) { /* less then 'scrolloff' lines above, decrease skipcol */ - extra = (curwin->w_skipcol + p_so * width - curwin->w_virtcol + assert(p_so <= INT_MAX); + extra = (curwin->w_skipcol + (int)p_so * width - curwin->w_virtcol + width - 1) / width; if (extra > 0) { if ((colnr_T)(extra * width) > curwin->w_skipcol) @@ -974,7 +980,7 @@ scrolldown ( int byfold /* TRUE: count a closed fold as one line */ ) { - long done = 0; /* total # of physical lines done */ + int done = 0; /* total # of physical lines done */ int wrow; int moved = FALSE; @@ -1331,7 +1337,8 @@ void scroll_cursor_top(int min_scroll, int always) linenr_T old_topline = curwin->w_topline; linenr_T old_topfill = curwin->w_topfill; linenr_T new_topline; - int off = p_so; + assert(p_so <= INT_MAX); + int off = (int)p_so; if (mouse_dragging > 0) off = mouse_dragging - 1; @@ -1472,7 +1479,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) int old_topfill = curwin->w_topfill; int fill_below_window; linenr_T old_botline = curwin->w_botline; - linenr_T old_valid = curwin->w_valid; + int old_valid = curwin->w_valid; int old_empty_rows = curwin->w_empty_rows; linenr_T cln; /* Cursor Line Number */ @@ -1708,8 +1715,9 @@ void cursor_correct(void) * How many lines we would like to have above/below the cursor depends on * whether the first/last line of the file is on screen. */ - above_wanted = p_so; - below_wanted = p_so; + assert(p_so <= INT_MAX); + above_wanted = (int)p_so; + below_wanted = (int)p_so; if (mouse_dragging > 0) { above_wanted = mouse_dragging - 1; below_wanted = mouse_dragging - 1; @@ -2040,14 +2048,14 @@ void halfpage(bool flag, linenr_T Prenum) { long scrolled = 0; int i; - int n; int room; if (Prenum) curwin->w_p_scr = (Prenum > curwin->w_height) ? curwin->w_height : Prenum; - n = (curwin->w_p_scr <= curwin->w_height) ? - curwin->w_p_scr : curwin->w_height; + assert(curwin->w_p_scr <= INT_MAX); + int n = curwin->w_p_scr <= curwin->w_height ? (int)curwin->w_p_scr + : curwin->w_height; validate_botline(); room = curwin->w_empty_rows; diff --git a/src/nvim/normal.c b/src/nvim/normal.c index e26f5a3d77..c210c8fe8f 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -4361,7 +4361,7 @@ static void nv_ident(cmdarg_T *cap) /* put pattern in search history */ init_history(); add_to_history(HIST_SEARCH, buf, true, NUL); - normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0); + (void)normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0); } else do_cmdline_cmd(buf); @@ -4785,7 +4785,7 @@ static void nv_search(cmdarg_T *cap) return; } - normal_search(cap, cap->cmdchar, cap->searchbuf, + (void)normal_search(cap, cap->cmdchar, cap->searchbuf, (cap->arg ? 0 : SEARCH_MARK)); } @@ -4795,15 +4795,25 @@ static void nv_search(cmdarg_T *cap) */ static void nv_next(cmdarg_T *cap) { - normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg); + pos_T old = curwin->w_cursor; + int i = normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg); + + if (i == 1 && equalpos(old, curwin->w_cursor)) { + // Avoid getting stuck on the current cursor position, which can happen when + // an offset is given and the cursor is on the last char in the buffer: + // Repeat with count + 1. + cap->count1 += 1; + (void)normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg); + cap->count1 -= 1; + } } /* * Search for "pat" in direction "dir" ('/' or '?', 0 for repeat). * Uses only cap->count1 and cap->oap from "cap". + * Return 0 for failure, 1 for found, 2 for found and line offset added. */ -static void -normal_search ( +static int normal_search( cmdarg_T *cap, int dir, char_u *pat, @@ -4832,6 +4842,7 @@ normal_search ( /* "/$" will put the cursor after the end of the line, may need to * correct that here */ check_cursor(); + return i; } /* diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 5921e27282..4c5a002f81 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -278,7 +278,7 @@ shift_line ( { int count; int i, j; - int p_sw = (int)get_sw_value(curbuf); + int p_sw = get_sw_value(curbuf); count = get_indent(); /* get current indent */ @@ -321,7 +321,7 @@ static void shift_block(oparg_T *oap, int amount) int total; char_u *newp, *oldp; int oldcol = curwin->w_cursor.col; - int p_sw = (int)get_sw_value(curbuf); + int p_sw = get_sw_value(curbuf); int p_ts = (int)curbuf->b_p_ts; struct block_def bd; int incr; diff --git a/src/nvim/option.c b/src/nvim/option.c index 2d016d8350..929b96a3f8 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -7653,18 +7653,22 @@ int check_ff_value(char_u *p) * Return the effective shiftwidth value for current buffer, using the * 'tabstop' value when 'shiftwidth' is zero. */ -long get_sw_value(buf_T *buf) +int get_sw_value(buf_T *buf) { - return buf->b_p_sw ? buf->b_p_sw : buf->b_p_ts; + long result = buf->b_p_sw ? buf->b_p_sw : buf->b_p_ts; + assert(result >= 0 && result <= INT_MAX); + return (int)result; } /* * Return the effective softtabstop value for the current buffer, using the * 'tabstop' value when 'softtabstop' is negative. */ -long get_sts_value(void) +int get_sts_value(void) { - return curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts; + long result = curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts; + assert(result >= 0 && result <= INT_MAX); + return (int)result; } /* diff --git a/src/nvim/os/event.c b/src/nvim/os/event.c index fd9ff5b230..9bc509bb16 100644 --- a/src/nvim/os/event.c +++ b/src/nvim/os/event.c @@ -28,12 +28,6 @@ #define _destroy_event(x) // do nothing KLIST_INIT(Event, Event, _destroy_event) -typedef struct { - bool timed_out; - int ms; - uv_timer_t *timer; -} TimerData; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/event.c.generated.h" #endif @@ -107,19 +101,12 @@ void event_poll(int ms) uv_run_mode run_mode = UV_RUN_ONCE; uv_timer_t timer; - uv_prepare_t timer_prepare; - TimerData timer_data = {.ms = ms, .timed_out = false, .timer = &timer}; if (ms > 0) { uv_timer_init(uv_default_loop(), &timer); - // This prepare handle that actually starts the timer - uv_prepare_init(uv_default_loop(), &timer_prepare); - // Timeout passed as argument to the timer - timer.data = &timer_data; - // We only start the timer after the loop is running, for that we - // use a prepare handle(pass the interval as data to it) - timer_prepare.data = &timer_data; - uv_prepare_start(&timer_prepare, timer_prepare_cb); + // Use a repeating timeout of ms milliseconds to make sure + // we do not block indefinitely for I/O. + uv_timer_start(&timer, timer_cb, (uint64_t)ms, (uint64_t)ms); } else if (ms == 0) { // For ms == 0, we need to do a non-blocking event poll by // setting the run mode to UV_RUN_NOWAIT. @@ -129,12 +116,10 @@ void event_poll(int ms) loop(run_mode); if (ms > 0) { - // Ensure the timer-related handles are closed and run the event loop + // Ensure the timer handle is closed and run the event loop // once more to let libuv perform it's cleanup uv_timer_stop(&timer); - uv_prepare_stop(&timer_prepare); uv_close((uv_handle_t *)&timer, NULL); - uv_close((uv_handle_t *)&timer_prepare, NULL); loop(UV_RUN_NOWAIT); } @@ -183,19 +168,8 @@ static void process_events_from(klist_t(Event) *queue) } } -// Set a flag in the `event_poll` loop for signaling of a timeout static void timer_cb(uv_timer_t *handle) { - TimerData *data = handle->data; - data->timed_out = true; -} - -static void timer_prepare_cb(uv_prepare_t *handle) -{ - TimerData *data = handle->data; - assert(data->ms > 0); - uv_timer_start(data->timer, timer_cb, (uint32_t)data->ms, 0); - uv_prepare_stop(handle); } static void loop(uv_run_mode run_mode) diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 70cafc62ca..26a4cdb083 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -189,19 +189,6 @@ void mch_exit(int r) exit(r); } -/* - * mch_expand_wildcards() - this code does wild-card pattern matching using - * the shell - * - * return OK for success, FAIL for error (you may lose some memory) and put - * an error message in *file. - * - * num_pat is number of input patterns - * pat is array of pointers to input patterns - * num_file is pointer to number of matched file names - * file is pointer to array of pointers to matched file names - */ - #ifndef SEEK_SET # define SEEK_SET 0 #endif @@ -211,10 +198,27 @@ void mch_exit(int r) #define SHELL_SPECIAL (char_u *)"\t \"&'$;<>()\\|" +/// Does wildcard pattern matching using the shell. +/// +/// @param num_pat is the number of input patterns. +/// @param pat is an array of pointers to input patterns. +/// @param[out] num_file is pointer to number of matched file names. +/// Set to the number of pointers in *file. +/// @param[out] file is pointer to array of pointers to matched file names. +/// Memory pointed to by the initial value of *file will +/// not be freed. +/// Set to NULL if FAIL is returned. Otherwise points to +/// allocated memory. +/// @param flags is a combination of EW_* flags used in +/// expand_wildcards(). +/// If matching fails but EW_NOTFOUND is set in flags or +/// there are no wildcards, the patterns from pat are +/// copied into *file. +/// +/// @returns OK for success or FAIL for error. int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file, - char_u ***file, - int flags /* EW_* flags */ - ) + char_u ***file, int flags) FUNC_ATTR_NONNULL_ARG(3) + FUNC_ATTR_NONNULL_ARG(4) { int i; size_t len; diff --git a/src/nvim/path.c b/src/nvim/path.c index e83b4e44ed..9515205643 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -1029,25 +1029,26 @@ static int has_special_wildchar(char_u *p) } #endif -/* - * Generic wildcard expansion code. - * - * Characters in "pat" that should not be expanded must be preceded with a - * backslash. E.g., "/path\ with\ spaces/my\*star*" - * - * Return FAIL when no single file was found. In this case "num_file" is not - * set, and "file" may contain an error message. - * Return OK when some files found. "num_file" is set to the number of - * matches, "file" to the array of matches. Call FreeWild() later. - */ -int -gen_expand_wildcards ( - int num_pat, /* number of input patterns */ - char_u **pat, /* array of input patterns */ - int *num_file, /* resulting number of files */ - char_u ***file, /* array of resulting files */ - int flags /* EW_* flags */ -) +/// Generic wildcard expansion code. +/// +/// Characters in pat that should not be expanded must be preceded with a +/// backslash. E.g., "/path\ with\ spaces/my\*star*". +/// +/// @param num_pat is number of input patterns. +/// @param pat is an array of pointers to input patterns. +/// @param[out] num_file is pointer to number of matched file names. +/// @param[out] file is pointer to array of pointers to matched file names. +/// @param flags is a combination of EW_* flags used in +/// expand_wildcards(). +/// +/// @returns OK when some files were found. *num_file is set to the +/// number of matches, *file to the allocated array of +/// matches. Call FreeWild() later. +/// If FAIL is returned, *num_file and *file are either +/// unchanged or *num_file is set to 0 and *file is set +/// to NULL or points to "". +int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file, + char_u ***file, int flags) { int i; garray_T ga; @@ -1863,19 +1864,23 @@ int expand_wildcards_eval(char_u **pat, int *num_file, char_u ***file, return ret; } -/* - * Expand wildcards. Calls gen_expand_wildcards() and removes files matching - * 'wildignore'. - * Returns OK or FAIL. When FAIL then "num_file" won't be set. - */ -int -expand_wildcards ( - int num_pat, /* number of input patterns */ - char_u **pat, /* array of input patterns */ - int *num_file, /* resulting number of files */ - char_u ***file, /* array of resulting files */ - int flags /* EW_DIR, etc. */ -) +/// Expand wildcards. Calls gen_expand_wildcards() and removes files matching +/// 'wildignore'. +/// +/// @param num_pat is number of input patterns. +/// @param pat is an array of pointers to input patterns. +/// @param[out] num_file is pointer to number of matched file names. +/// @param[out] file is pointer to array of pointers to matched file names. +/// @param flags is a combination of EW_* flags. +/// +/// @returns OK when some files were found. *num_file is set to the +/// number of matches, *file to the allocated array of +/// matches. +/// If FAIL is returned, *num_file and *file are either +/// unchanged or *num_file is set to 0 and *file is set to +/// NULL or points to "". +int expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u ***file, + int flags) { int retval; int i, j; diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index 1ea12d6862..7ef962fa2f 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -2,6 +2,7 @@ /// /// Popup menu (PUM) // +#include <assert.h> #include <inttypes.h> #include <stdbool.h> @@ -101,7 +102,7 @@ redo: } if ((p_ph > 0) && (pum_height > p_ph)) { - pum_height = p_ph; + pum_height = (int)p_ph; } // Put the pum below "row" if possible. If there are few lines decide on @@ -126,8 +127,8 @@ redo: } if ((p_ph > 0) && (pum_height > p_ph)) { - pum_row += pum_height - p_ph; - pum_height = p_ph; + pum_row += pum_height - (int)p_ph; + pum_height = (int)p_ph; } } else { // pum below "row" @@ -148,7 +149,7 @@ redo: } if ((p_ph > 0) && (pum_height > p_ph)) { - pum_height = p_ph; + pum_height = (int)p_ph; } } @@ -219,7 +220,9 @@ redo: if (curwin->w_p_rl) { pum_width = pum_col - pum_scrollbar + 1; } else { - pum_width = Columns - pum_col - pum_scrollbar; + assert(Columns - pum_col - pum_scrollbar >= INT_MIN + && Columns - pum_col - pum_scrollbar <= INT_MAX); + pum_width = (int)(Columns - pum_col - pum_scrollbar); } if ((pum_width > max_width + kind_width + extra_width + 1) @@ -233,11 +236,13 @@ redo: } else if (Columns < def_width) { // not enough room, will use what we have if (curwin->w_p_rl) { - pum_col = Columns - 1; + assert(Columns - 1 >= INT_MIN); + pum_col = (int)(Columns - 1); } else { pum_col = 0; } - pum_width = Columns - 1; + assert(Columns - 1 >= INT_MIN); + pum_width = (int)(Columns - 1); } else { if (max_width > PUM_DEF_WIDTH) { // truncate @@ -247,7 +252,8 @@ redo: if (curwin->w_p_rl) { pum_col = max_width - 1; } else { - pum_col = Columns - max_width; + assert(Columns - max_width >= INT_MIN && Columns - max_width <= INT_MAX); + pum_col = (int)(Columns - max_width); } pum_width = max_width - pum_scrollbar; } @@ -345,7 +351,7 @@ void pum_redraw(void) // Display the text that fits or comes before a Tab. // First convert it to printable characters. char_u *st; - int saved = *p; + char_u saved = *p; *p = NUL; st = transstr(s); @@ -535,7 +541,7 @@ static int pum_set_selected(int n, int repeat) g_do_tagpreview = 3; if ((p_pvh > 0) && (p_pvh < g_do_tagpreview)) { - g_do_tagpreview = p_pvh; + g_do_tagpreview = (int)p_pvh; } RedrawingDisabled++; resized = prepare_tagpreview(false); diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 8b7033b64b..d5e963c2f8 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -6914,13 +6914,8 @@ static regengine_T bt_regengine = bt_regcomp, bt_regfree, bt_regexec_nl, - bt_regexec_multi -#ifdef REGEXP_DEBUG - ,(char_u *)"" -#endif -#ifdef DEBUG - ,NULL -#endif + bt_regexec_multi, + (char_u *)"" }; @@ -6934,21 +6929,14 @@ static regengine_T nfa_regengine = nfa_regcomp, nfa_regfree, nfa_regexec_nl, - nfa_regexec_multi -#ifdef REGEXP_DEBUG - ,(char_u *)"" -#endif -#ifdef DEBUG - , NULL -#endif + nfa_regexec_multi, + (char_u *)"" }; /* Which regexp engine to use? Needed for vim_regcomp(). * Must match with 'regexpengine'. */ static int regexp_engine = 0; -#define AUTOMATIC_ENGINE 0 -#define BACKTRACKING_ENGINE 1 -#define NFA_ENGINE 2 + #ifdef REGEXP_DEBUG static char_u regname[][30] = { "AUTOMATIC Regexp Engine", @@ -6990,10 +6978,8 @@ regprog_T *vim_regcomp(char_u *expr_arg, int re_flags) regexp_engine = AUTOMATIC_ENGINE; } } -#ifdef REGEXP_DEBUG bt_regengine.expr = expr; nfa_regengine.expr = expr; -#endif /* * First try the NFA engine, unless backtracking was requested. @@ -7003,11 +6989,12 @@ regprog_T *vim_regcomp(char_u *expr_arg, int re_flags) else prog = bt_regengine.regcomp(expr, re_flags); - if (prog == NULL) { /* error compiling regexp with initial engine */ + // Check for error compiling regexp with initial engine. + if (prog == NULL) { #ifdef BT_REGEXP_DEBUG_LOG - if (regexp_engine != BACKTRACKING_ENGINE) { /* debugging log for NFA */ - FILE *f; - f = fopen(BT_REGEXP_DEBUG_LOG_NAME, "a"); + // Debugging log for NFA. + if (regexp_engine != BACKTRACKING_ENGINE) { + FILE *f = fopen(BT_REGEXP_DEBUG_LOG_NAME, "a"); if (f) { fprintf(f, "Syntax error in \"%s\"\n", expr); fclose(f); @@ -7016,12 +7003,22 @@ regprog_T *vim_regcomp(char_u *expr_arg, int re_flags) BT_REGEXP_DEBUG_LOG_NAME); } #endif - /* - * If the NFA engine failed, the backtracking engine won't work either. - * - if (regexp_engine == AUTOMATIC_ENGINE) - prog = bt_regengine.regcomp(expr, re_flags); - */ + // If the NFA engine failed, try the backtracking engine. + // Disabled for now, both engines fail on the same patterns. + // Re-enable when regcomp() fails when the pattern would work better + // with the other engine. + // + // if (regexp_engine == AUTOMATIC_ENGINE) { + // prog = bt_regengine.regcomp(expr, re_flags); + // regexp_engine = BACKTRACKING_ENGINE; + // } + } + + if (prog != NULL) { + // Store the info needed to call regcomp() again when the engine turns out + // to be very slow when executing it. + prog->re_engine = regexp_engine; + prog->re_flags = re_flags; } return prog; @@ -7036,29 +7033,62 @@ void vim_regfree(regprog_T *prog) prog->engine->regfree(prog); } -/* - * Match a regexp against a string. - * "rmp->regprog" is a compiled regexp as returned by vim_regcomp(). - * Uses curbuf for line count and 'iskeyword'. - * - * Return TRUE if there is a match, FALSE if not. - */ -int -vim_regexec ( - regmatch_T *rmp, - char_u *line, /* string to match against */ - colnr_T col /* column to start looking for match */ -) +static void report_re_switch(char_u *pat) { - return rmp->regprog->engine->regexec_nl(rmp, line, col, false); + if (p_verbose > 0) { + verbose_enter(); + MSG_PUTS(_("Switching to backtracking RE engine for pattern: ")); + MSG_PUTS(pat); + verbose_leave(); + } } -/* - * Like vim_regexec(), but consider a "\n" in "line" to be a line break. - */ +/// Matches a regexp against a string. +/// "rmp->regprog" is a compiled regexp as returned by vim_regcomp(). +/// Uses curbuf for line count and 'iskeyword'. +/// When "nl" is true consider a "\n" in "line" to be a line break. +/// +/// @param rmp +/// @param line the string to match against +/// @param col the column to start looking for match +/// @param nl +/// +/// @return TRUE if there is a match, FALSE if not. +static int vim_regexec_both(regmatch_T *rmp, char_u *line, colnr_T col, bool nl) +{ + int result = rmp->regprog->engine->regexec_nl(rmp, line, col, nl); + + // NFA engine aborted because it's very slow, use backtracking engine instead. + if (rmp->regprog->re_engine == AUTOMATIC_ENGINE + && result == NFA_TOO_EXPENSIVE) { + int save_p_re = p_re; + int re_flags = rmp->regprog->re_flags; + char_u *pat = vim_strsave(((nfa_regprog_T *)rmp->regprog)->pattern); + + p_re = BACKTRACKING_ENGINE; + vim_regfree(rmp->regprog); + report_re_switch(pat); + rmp->regprog = vim_regcomp(pat, re_flags); + if (rmp->regprog != NULL) { + result = rmp->regprog->engine->regexec_nl(rmp, line, col, nl); + } + + free(pat); + p_re = save_p_re; + } + + return result; +} + +int vim_regexec(regmatch_T *rmp, char_u *line, colnr_T col) +{ + return vim_regexec_both(rmp, line, col, false); +} + +// Like vim_regexec(), but consider a "\n" in "line" to be a line break. int vim_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col) { - return rmp->regprog->engine->regexec_nl(rmp, line, col, true); + return vim_regexec_both(rmp, line, col, true); } /* @@ -7078,5 +7108,28 @@ long vim_regexec_multi( proftime_T *tm /* timeout limit or NULL */ ) { - return rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col, tm); + int result = rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col, + tm); + + // NFA engine aborted because it's very slow, use backtracking engine instead. + if (rmp->regprog->re_engine == AUTOMATIC_ENGINE + && result == NFA_TOO_EXPENSIVE) { + int save_p_re = p_re; + int re_flags = rmp->regprog->re_flags; + char_u *pat = vim_strsave(((nfa_regprog_T *)rmp->regprog)->pattern); + + p_re = BACKTRACKING_ENGINE; + vim_regfree(rmp->regprog); + report_re_switch(pat); + rmp->regprog = vim_regcomp(pat, re_flags); + if (rmp->regprog != NULL) { + result = rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col, + tm); + } + + free(pat); + p_re = save_p_re; + } + + return result; } diff --git a/src/nvim/regexp_defs.h b/src/nvim/regexp_defs.h index 1e00f14ac6..6426ee441b 100644 --- a/src/nvim/regexp_defs.h +++ b/src/nvim/regexp_defs.h @@ -30,6 +30,16 @@ */ #define NFA_MAX_BRACES 20 +// In the NFA engine: how many states are allowed. +#define NFA_MAX_STATES 100000 +#define NFA_TOO_EXPENSIVE -1 + +// Which regexp engine to use? Needed for vim_regcomp(). +// Must match with 'regexpengine'. +#define AUTOMATIC_ENGINE 0 +#define BACKTRACKING_ENGINE 1 +#define NFA_ENGINE 2 + typedef struct regengine regengine_T; /* @@ -38,8 +48,10 @@ typedef struct regengine regengine_T; * structures are used. See code below. */ typedef struct regprog { - regengine_T *engine; + regengine_T *engine; unsigned regflags; + unsigned re_engine; ///< Automatic, backtracking or NFA engine. + unsigned re_flags; ///< Second argument for vim_regcomp(). } regprog_T; /* @@ -48,9 +60,11 @@ typedef struct regprog { * See regexp.c for an explanation. */ typedef struct { - /* These two members implement regprog_T */ - regengine_T *engine; + // These four members implement regprog_T. + regengine_T *engine; unsigned regflags; + unsigned re_engine; + unsigned re_flags; ///< Second argument for vim_regcomp(). int regstart; char_u reganch; @@ -78,9 +92,11 @@ struct nfa_state { * Structure used by the NFA matcher. */ typedef struct { - /* These two members implement regprog_T */ - regengine_T *engine; + // These four members implement regprog_T. + regengine_T *engine; unsigned regflags; + unsigned re_engine; + unsigned re_flags; ///< Second argument for vim_regcomp(). nfa_state_T *start; /* points into state[] */ @@ -91,9 +107,7 @@ typedef struct { int has_zend; /* pattern contains \ze */ int has_backref; /* pattern contains \1 .. \9 */ int reghasz; -#ifdef DEBUG char_u *pattern; -#endif int nsubexp; /* number of () */ int nstate; nfa_state_T state[1]; /* actually longer.. */ @@ -143,9 +157,7 @@ struct regengine { int (*regexec_nl)(regmatch_T*, char_u*, colnr_T, bool); long (*regexec_multi)(regmmatch_T*, win_T*, buf_T*, linenr_T, colnr_T, proftime_T*); -#ifdef DEBUG char_u *expr; -#endif }; #endif // NVIM_REGEXP_DEFS_H diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 6ed42303ef..1de167c40f 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -2347,7 +2347,6 @@ static void nfa_set_code(int c) } -#ifdef REGEXP_DEBUG static FILE *log_fd; /* @@ -2468,7 +2467,6 @@ static void nfa_dump(nfa_regprog_T *prog) } } #endif /* REGEXP_DEBUG */ -#endif /* REGEXP_DEBUG */ /* * Parse r.e. @expr and convert it into postfix form. @@ -4908,6 +4906,12 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm nextlist->n = 0; /* clear nextlist */ nextlist->has_pim = FALSE; ++nfa_listid; + if (prog->re_engine == AUTOMATIC_ENGINE && nfa_listid >= NFA_MAX_STATES) { + // Too many states, retry with old engine. + nfa_match = NFA_TOO_EXPENSIVE; + goto theend; + } + thislist->id = nfa_listid; nextlist->id = nfa_listid + 1; @@ -5082,6 +5086,10 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm */ result = recursive_regmatch(t->state, NULL, prog, submatch, m, &listids); + if (result == NFA_TOO_EXPENSIVE) { + nfa_match = result; + goto theend; + } /* for \@! and \@<! it is a match when the result is * FALSE */ @@ -5180,6 +5188,10 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm /* First try matching the pattern. */ result = recursive_regmatch(t->state, NULL, prog, submatch, m, &listids); + if (result == NFA_TOO_EXPENSIVE) { + nfa_match = result; + goto theend; + } if (result) { int bytelen; @@ -6019,6 +6031,7 @@ nextchar: log_fd = NULL; #endif +theend: /* Free memory */ free(list[0].t); free(list[1].t); @@ -6068,8 +6081,12 @@ static long nfa_regtry(nfa_regprog_T *prog, colnr_T col) clear_sub(&subs.synt); clear_sub(&m.synt); - if (nfa_regmatch(prog, start, &subs, &m) == FALSE) + int result = nfa_regmatch(prog, start, &subs, &m); + if (result == FALSE) { return 0; + } else if (result == NFA_TOO_EXPENSIVE) { + return result; + } cleanup_subexpr(); if (REG_MULTI) { @@ -6186,9 +6203,7 @@ nfa_regexec_both ( nfa_nsubexpr = prog->nsubexp; nfa_listid = 1; nfa_alt_listid = 2; -#ifdef REGEXP_DEBUG nfa_regengine.expr = prog->pattern; -#endif if (prog->reganch && col > 0) return 0L; @@ -6228,9 +6243,7 @@ nfa_regexec_both ( retval = nfa_regtry(prog, col); -#ifdef REGEXP_DEBUG nfa_regengine.expr = NULL; -#endif theend: return retval; @@ -6248,9 +6261,7 @@ static regprog_T *nfa_regcomp(char_u *expr, int re_flags) if (expr == NULL) return NULL; -#ifdef REGEXP_DEBUG nfa_regengine.expr = expr; -#endif init_class_tab(); @@ -6325,10 +6336,8 @@ static regprog_T *nfa_regcomp(char_u *expr, int re_flags) #endif /* Remember whether this pattern has any \z specials in it. */ prog->reghasz = re_has_z; -#ifdef REGEXP_DEBUG prog->pattern = vim_strsave(expr); nfa_regengine.expr = NULL; -#endif out: free(post_start); @@ -6342,9 +6351,7 @@ fail: #ifdef REGEXP_DEBUG nfa_postfix_dump(expr, FAIL); #endif -#ifdef REGEXP_DEBUG nfa_regengine.expr = NULL; -#endif goto out; } @@ -6355,9 +6362,7 @@ static void nfa_regfree(regprog_T *prog) { if (prog != NULL) { free(((nfa_regprog_T *)prog)->match_text); -#ifdef REGEXP_DEBUG free(((nfa_regprog_T *)prog)->pattern); -#endif free(prog); } } diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index d603a6a877..2149f0f998 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -1071,7 +1071,7 @@ static void redraw(bool restore_cursor) setcursor(); } else if (restore_cursor) { ui_cursor_goto(save_row, save_col); - } else { + } else if (term) { // exiting terminal focus, put the window cursor in a valid position int height, width; vterm_get_size(term->vt, &height, &width); @@ -1123,28 +1123,30 @@ static bool is_focused(Terminal *term) do { \ Error err; \ o = dict_get_value(t->buf->b_vars, cstr_as_string(k), &err); \ - if (obj.type == kObjectTypeNil) { \ + if (o.type == kObjectTypeNil) { \ o = dict_get_value(&globvardict, cstr_as_string(k), &err); \ } \ } while (0) static char *get_config_string(Terminal *term, char *key) { - Object obj = OBJECT_INIT; + Object obj; GET_CONFIG_VALUE(term, key, obj); if (obj.type == kObjectTypeString) { return obj.data.string.data; } + api_free_object(obj); return NULL; } static int get_config_int(Terminal *term, char *key) { - Object obj = OBJECT_INIT; + Object obj; GET_CONFIG_VALUE(term, key, obj); if (obj.type == kObjectTypeInteger) { return (int)obj.data.integer; } + api_free_object(obj); return 0; } diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index 70e6f8ee4c..a530e3cf23 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -16,19 +16,18 @@ SCRIPTS := test_autoformat_join.out \ test24.out \ test26.out test27.out test29.out test30.out \ test31.out test32.out test34.out \ - test36.out test37.out test38.out test39.out test40.out \ - test42.out test43.out test44.out test45.out \ + test36.out test37.out test39.out test40.out \ + test42.out test43.out test45.out \ test46.out test47.out test48.out test49.out \ test52.out test53.out test55.out \ test57.out test58.out test59.out test60.out \ test61.out test62.out test63.out test64.out test65.out \ - test68.out test69.out test70.out \ + test68.out test69.out \ test71.out test73.out test74.out \ test76.out test78.out test79.out test80.out \ - test82.out test83.out test85.out \ + test82.out test83.out \ test86.out test87.out test88.out \ - test92.out test93.out \ - test96.out test99.out \ + test96.out \ test_listlbr.out \ test_breakindent.out @@ -86,7 +85,7 @@ test1.out: $(VIMPROG) $(SCRIPTS) $(SCRIPTS_GUI): $(VIMPROG) test1.out RM_ON_RUN := test.out X* viminfo -RM_ON_START := tiny.vim small.vim mbyte.vim mzscheme.vim lua.vim test.ok +RM_ON_START := tiny.vim small.vim mbyte.vim test.ok RUN_VIM := VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(TOOL) $(VIMPROG) -u unix.vim -U NONE -i viminfo --noplugin -s dotest.in clean: diff --git a/src/nvim/testdir/test1.in b/src/nvim/testdir/test1.in index 735d539673..85ff1b4db2 100644 --- a/src/nvim/testdir/test1.in +++ b/src/nvim/testdir/test1.in @@ -14,8 +14,6 @@ set like small.vim above. tiny.vim is sourced by tests that require the If Vim was not compiled with the +multi_byte feature, the mbyte.vim script will be set like small.vim above. mbyte.vim is sourced by tests that require the +multi_byte feature. -Similar logic is applied to the +mzscheme feature, using mzscheme.vim. -Similar logic is applied to the +lua feature, using lua.vim. STARTTEST :" If columns or lines are too small, create wrongtermsize. @@ -32,18 +30,10 @@ ae! test.ok w! test.out qa! :w! mbyte.vim -:w! mzscheme.vim -:w! lua.vim :" :" If +multi_byte feature supported, make mbyte.vim empty. :if has("multi_byte") | sp another | w! mbyte.vim | q | endif :" -:" If +mzscheme feature supported, make mzscheme.vim empty. -:if has("mzscheme") | sp another | w! mzscheme.vim | q | endif -:" -:" If +lua feature supported, make lua.vim empty. -:if has("lua") | sp another | w! lua.vim | q | endif -:" :" If +eval feature supported quit here, leaving tiny.vim and small.vim empty. :" Otherwise write small.vim to skip the test. :if 1 | q! | endif diff --git a/src/nvim/testdir/test38.in b/src/nvim/testdir/test38.in deleted file mode 100644 index 3e0236251b..0000000000 --- a/src/nvim/testdir/test38.in +++ /dev/null @@ -1,35 +0,0 @@ - -Test Virtual replace mode. - -STARTTEST -:so small.vim -:" make sure that backspace works, no matter what termcap is used -:set t_kD=x7f t_kb=x08 -ggdGa -abcdefghi -jk lmn - opq rst -uvwxyz -gg:set ai -:set bs=2 -gR0 1 -A -BCDEFGHIJ - KL -MNO -PQRG:ka -o0 -abcdefghi -jk lmn - opq rst -uvwxyz -'ajgR0 1 -A -BCDEFGHIJ - KL -MNO -PQR:$ -iab cdefghi jkl0gRAB......CDEFGHI.Jo: -iabcdefghijklmnopqrst0gRAB IJKLMNO QR:wq! test.out -ENDTEST - diff --git a/src/nvim/testdir/test38.ok b/src/nvim/testdir/test38.ok deleted file mode 100644 index e10209667b..0000000000 --- a/src/nvim/testdir/test38.ok +++ /dev/null @@ -1,13 +0,0 @@ - 1 - A - BCDEFGHIJ - KL - MNO - PQR - 1 -abcdefghi -jk lmn - opq rst -uvwxyz -AB......CDEFGHI.Jkl -AB IJKLMNO QRst diff --git a/src/nvim/testdir/test44.in b/src/nvim/testdir/test44.in deleted file mode 100644 index 65b08b08b8..0000000000 --- a/src/nvim/testdir/test44.in +++ /dev/null @@ -1,68 +0,0 @@ -Tests for regexp with multi-byte encoding and various magic settings. -Test matchstr() with a count and multi-byte chars. -See test99 for exactly the same test with re=2. - -STARTTEST -:so mbyte.vim -:set encoding=utf-8 termencoding=latin1 -:set re=1 -/^1 -/a*b\{2}c\+/e -x/\Md\*e\{2}f\+/e -x:set nomagic -/g\*h\{2}i\+/e -x/\mj*k\{2}l\+/e -x/\vm*n{2}o+/e -x/\V^aa$ -x:set magic -/\v(a)(b)\2\1\1/e -x/\V[ab]\(\[xy]\)\1 -x:" Now search for multi-byte without composing char -/ม -x:" Now search for multi-byte with composing char -/ม่ -x:" find word by change of word class -/ち\<カヨ\>は -x:" Test \%u, [\u] and friends -/\%u20ac -x/[\u4f7f\u5929]\+ -x/\%U12345678 -x/[\U1234abcd\u1234\uabcd] -x/\%d21879b -x/ [[=A=]]* [[=B=]]* [[=C=]]* [[=D=]]* [[=E=]]* [[=F=]]* [[=G=]]* [[=H=]]* [[=I=]]* [[=J=]]* [[=K=]]* [[=L=]]* [[=M=]]* [[=N=]]* [[=O=]]* [[=P=]]* [[=Q=]]* [[=R=]]* [[=S=]]* [[=T=]]* [[=U=]]* [[=V=]]* [[=W=]]* [[=X=]]* [[=Y=]]* [[=Z=]]*/e -x/ [[=a=]]* [[=b=]]* [[=c=]]* [[=d=]]* [[=e=]]* [[=f=]]* [[=g=]]* [[=h=]]* [[=i=]]* [[=j=]]* [[=k=]]* [[=l=]]* [[=m=]]* [[=n=]]* [[=o=]]* [[=p=]]* [[=q=]]* [[=r=]]* [[=s=]]* [[=t=]]* [[=u=]]* [[=v=]]* [[=w=]]* [[=x=]]* [[=y=]]* [[=z=]]*/e -x:" Test backwards search from a multi-byte char -/x -x?. -x:let @w=':%s#comb[i]nations#œ̄ṣ́m̥̄ᾱ̆́#g' -:@w -:?^1?,$w! test.out -:e! test.out -G:put =matchstr(\"אבגד\", \".\", 0, 2) " ב -:put =matchstr(\"אבגד\", \"..\", 0, 2) " בג -:put =matchstr(\"אבגד\", \".\", 0, 0) " א -:put =matchstr(\"אבגד\", \".\", 4, -1) " ג -:w! -:qa! -ENDTEST - -1 a aa abb abbccc -2 d dd dee deefff -3 g gg ghh ghhiii -4 j jj jkk jkklll -5 m mm mnn mnnooo -6 x ^aa$ x -7 (a)(b) abbaa -8 axx [ab]xx -9 หม่x อมx -a อมx หม่x -b ちカヨは -c x ¬€x -d 天使x -e y -f z -g a啷bb -h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐẔ -i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑẕ -j 0123❤x -k combinations diff --git a/src/nvim/testdir/test44.ok b/src/nvim/testdir/test44.ok deleted file mode 100644 index 0bd0b8ab73..0000000000 --- a/src/nvim/testdir/test44.ok +++ /dev/null @@ -1,24 +0,0 @@ -1 a aa abb abbcc -2 d dd dee deeff -3 g gg ghh ghhii -4 j jj jkk jkkll -5 m mm mnn mnnoo -6 x aa$ x -7 (a)(b) abba -8 axx ab]xx -9 หม่x อx -a อมx หx -b カヨは -c x ¬x -d 使x -e y -f z -g abb -h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐ -i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑ -j 012❤ -k œ̄ṣ́m̥̄ᾱ̆́ -ב -בג -א -ג diff --git a/src/nvim/testdir/test70.in b/src/nvim/testdir/test70.in deleted file mode 100644 index 24d2e4c446..0000000000 --- a/src/nvim/testdir/test70.in +++ /dev/null @@ -1,62 +0,0 @@ -Smoke test for MzScheme interface and mzeval() function - -STARTTEST -:so mzscheme.vim -:function! MzRequire() -:redir => l:mzversion -:mz (version) -:redir END -:if strpart(l:mzversion, 1, 1) < "4" -:" MzScheme versions < 4.x: -:mz (require (prefix vim- vimext)) -:else -:" newer versions: -:mz (require (prefix-in vim- 'vimext)) -:mz (require r5rs) -:endif -:endfunction -:silent call MzRequire() -:mz (define l '("item0" "dictionary with list OK" "item2")) -:mz (define h (make-hash)) -:mz (hash-set! h "list" l) -/^1 -:" change buffer contents -:mz (vim-set-buff-line (vim-eval "line('.')") "1 changed line 1") -:" scalar test -:let tmp_string = mzeval('"string"') -:let tmp_1000 = mzeval('1000') -:if tmp_string . tmp_1000 == "string1000" -:let scalar_res = "OK" -:else -:let scalar_res = "FAILED" -:endif -:call append(search("^1"), "scalar test " . scalar_res) -:" dictionary containing a list -:let tmp = mzeval("h")["list"][1] -:/^2/put =tmp -:" circular list (at the same time test lists containing lists) -:mz (set-car! (cddr l) l) -:let l2 = mzeval("h")["list"] -:if l2[2] == l2 -:let res = "OK" -:else -:let res = "FAILED: " . l2[2] -:endif -:call setline(search("^3"), "circular test " . res) -:" funcrefs -:mz (define vim:max (vim-eval "function('max')")) -:mz (define m (vim:max '(1 100 8))) -:let m = mzeval('m') -:if m == 100 -:let fref_res = "OK" -:else -:let fref_res = "FAILED: " . m -:end -:call append(line('$'), 'funcrefs '. fref_res) -:?^1?,$w! test.out -:qa! -ENDTEST - -1 line 1 -2 line 2 -3 line 3 diff --git a/src/nvim/testdir/test70.ok b/src/nvim/testdir/test70.ok deleted file mode 100644 index 9c82a86f2d..0000000000 --- a/src/nvim/testdir/test70.ok +++ /dev/null @@ -1,6 +0,0 @@ -1 changed line 1 -scalar test OK -2 line 2 -dictionary with list OK -circular test OK -funcrefs OK diff --git a/src/nvim/testdir/test85.in b/src/nvim/testdir/test85.in deleted file mode 100644 index f7112792e9..0000000000 --- a/src/nvim/testdir/test85.in +++ /dev/null @@ -1,84 +0,0 @@ -Test for Lua interface and luaeval() function - -STARTTEST -:so small.vim -:so lua.vim -:lua l = vim.list():add"item0":add"dictionary with list OK":add"item2" -:lua h = vim.dict(); h.list = l -:call garbagecollect() -/^1 -:" change buffer contents -:lua curbuf = vim.buffer() -:lua curline = vim.eval"line('.')" -:lua curbuf[curline] = "1 changed line 1" -:" scalar test -:let tmp_string = luaeval('"string"') -:let tmp_1000 = luaeval('1000') -:if printf("%s%.0f", tmp_string, tmp_1000) == "string1000" -:let scalar_res = "OK" -:else -:let scalar_res = "FAILED" -:endif -:call append(search("^1"), "scalar test " . scalar_res) -:" dictionary containing a list -:let tmp = luaeval("h").list[1] -:/^2/put =tmp -:" circular list (at the same time test lists containing lists) -:lua l[2] = l -:let l2 = luaeval("h").list -:if l2[2] == l2 -:let res = "OK" -:else -:let res = "FAILED" -:endif -:call setline(search("^3"), "circular test " . res) - -:let l = [] -:lua l = vim.eval("l") -:lua l:add(123) -:lua l:add("abc") -:lua l:add(vim.eval("[1, 2, 3]")) -:lua l:add(vim.eval("{'a':1, 'b':2, 'c':3}")) -:lua l:insert(123) -:lua l:insert("abc") -:lua l:insert(vim.eval("[1, 2, 3]")) -:lua l:insert(vim.eval("{'a':1, 'b':2, 'c':3}")) -:lua l[0] = l[0] -:lua l[1] = l[1] -:lua l[2] = l[2] -:lua l[3] = l[3] -:lua l[0] = 123 -:lua l[1] = "abc" -:lua l[2] = vim.eval("[1, 2, 3]") -:lua l[3] = vim.eval("{'a':1, 'b':2, 'c':3}") -:lua l[3] = nil -:lua l[2] = nil -:lua l[1] = nil -:lua l[0] = nil -:lua l = nil -:$put =string(l) - -:let d = {} -:lua d = vim.eval("d") -:lua d[0] = 123 -:lua d[1] = "abc" -:lua d[2] = vim.eval("[1, 2, 3]") -:lua d[3] = vim.eval("{'a':1, 'b':2, 'c':3}") -:lua d[4] = d[0] -:lua d[5] = d[1] -:lua d[6] = d[2] -:lua d[7] = d[3] -:lua d[3] = nil -:lua d[2] = nil -:lua d[1] = nil -:lua d[0] = nil -:lua d = nil -:$put =string(d) - -:?^1?,$w! test.out -:qa! -ENDTEST - -1 line 1 -2 line 2 -3 line 3 diff --git a/src/nvim/testdir/test85.ok b/src/nvim/testdir/test85.ok deleted file mode 100644 index 4753483240..0000000000 --- a/src/nvim/testdir/test85.ok +++ /dev/null @@ -1,7 +0,0 @@ -1 changed line 1 -scalar test OK -2 line 2 -dictionary with list OK -circular test OK -[123.0, 'abc', [1, 2, 3], {'a': 1, 'b': 2, 'c': 3}] -{'4': 123.0, '5': 'abc', '6': [1, 2, 3], '7': {'a': 1, 'b': 2, 'c': 3}} diff --git a/src/nvim/testdir/test92.in b/src/nvim/testdir/test92.in deleted file mode 100644 index 9593aec4c7..0000000000 --- a/src/nvim/testdir/test92.in +++ /dev/null @@ -1,48 +0,0 @@ -vim: set ft=vim fenc=utf-8: - -Tests if :mksession saves cursor columns correctly in presence of tab and -multibyte characters when fileencoding=utf-8. - -STARTTEST -:so mbyte.vim -:if !has('mksession') -: e! test.ok -: wq! test.out -:endif -:set sessionoptions=buffers splitbelow fileencoding=utf-8 -/^start: -:vsplit -j16|:split -j16|:split -j16|:split -j8|:split -j8|:split -j16|:split -j16|:split -j16|:wincmd l -/^start: -:set nowrap -j16|3zl:split -j016|3zl:split -j016|3zl:split -j08|3zl:split -j08|3zl:split -j016|3zl:split -j016|3zl:split -j016|3zl:split -:mksession! test.out -:new test.out -:v/\(^ *normal! 0\|^ *exe 'normal!\)/d -:w! test.out -:qa! -ENDTEST - -start: -no multibyte chAracter - one leaDing tab - four leadinG spaces -two consecutive tabs -two tabs in one line -one … multibyteCharacter -a “b” two multiByte characters -“c”1€ three mulTibyte characters diff --git a/src/nvim/testdir/test92.ok b/src/nvim/testdir/test92.ok deleted file mode 100644 index cca5ec487c..0000000000 --- a/src/nvim/testdir/test92.ok +++ /dev/null @@ -1,26 +0,0 @@ -normal! 016| -normal! 016| -normal! 016| -normal! 08| -normal! 08| -normal! 016| -normal! 016| -normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| - exe 'normal! ' . s:c . '|zs' . 8 . '|' - normal! 08| - exe 'normal! ' . s:c . '|zs' . 8 . '|' - normal! 08| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| diff --git a/src/nvim/testdir/test93.in b/src/nvim/testdir/test93.in deleted file mode 100644 index 877838ce1b..0000000000 --- a/src/nvim/testdir/test93.in +++ /dev/null @@ -1,48 +0,0 @@ -vim: set ft=vim fenc=latin1: - -Tests if :mksession saves cursor columns correctly in presence of tab and -multibyte characters when fileencoding=latin1. - -STARTTEST -:so mbyte.vim -:if !has('mksession') -: e! test.ok -: wq! test.out -:endif -:set sessionoptions=buffers splitbelow fileencoding=latin1 -/^start: -:vsplit -j16|:split -j16|:split -j16|:split -j8|:split -j8|:split -j16|:split -j16|:split -j16|:wincmd l -/^start: -:set nowrap -j16|3zl:split -j016|3zl:split -j016|3zl:split -j08|3zl:split -j08|3zl:split -j016|3zl:split -j016|3zl:split -j016|3zl:split -:mksession! test.out -:new test.out -:v/\(^ *normal! 0\|^ *exe 'normal!\)/d -:w! test.out -:qa! -ENDTEST - -start: -no multibyte chAracter - one leaDing tab - four leadinG spaces -two consecutive tabs -two tabs in one line -one multibyteCharacter -a two multiByte characters -A three mulTibyte characters diff --git a/src/nvim/testdir/test93.ok b/src/nvim/testdir/test93.ok deleted file mode 100644 index cca5ec487c..0000000000 --- a/src/nvim/testdir/test93.ok +++ /dev/null @@ -1,26 +0,0 @@ -normal! 016| -normal! 016| -normal! 016| -normal! 08| -normal! 08| -normal! 016| -normal! 016| -normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| - exe 'normal! ' . s:c . '|zs' . 8 . '|' - normal! 08| - exe 'normal! ' . s:c . '|zs' . 8 . '|' - normal! 08| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| diff --git a/src/nvim/testdir/test99.in b/src/nvim/testdir/test99.in deleted file mode 100644 index 32bc68cce4..0000000000 --- a/src/nvim/testdir/test99.in +++ /dev/null @@ -1,68 +0,0 @@ -Tests for regexp with multi-byte encoding and various magic settings. -Test matchstr() with a count and multi-byte chars. -See test44 for exactly the same test with re=1. - -STARTTEST -:so mbyte.vim -:set encoding=utf-8 termencoding=latin1 -:set re=2 -/^1 -/a*b\{2}c\+/e -x/\Md\*e\{2}f\+/e -x:set nomagic -/g\*h\{2}i\+/e -x/\mj*k\{2}l\+/e -x/\vm*n{2}o+/e -x/\V^aa$ -x:set magic -/\v(a)(b)\2\1\1/e -x/\V[ab]\(\[xy]\)\1 -x:" Now search for multi-byte without composing char -/ม -x:" Now search for multi-byte with composing char -/ม่ -x:" find word by change of word class -/ち\<カヨ\>は -x:" Test \%u, [\u] and friends -/\%u20ac -x/[\u4f7f\u5929]\+ -x/\%U12345678 -x/[\U1234abcd\u1234\uabcd] -x/\%d21879b -x/ [[=A=]]* [[=B=]]* [[=C=]]* [[=D=]]* [[=E=]]* [[=F=]]* [[=G=]]* [[=H=]]* [[=I=]]* [[=J=]]* [[=K=]]* [[=L=]]* [[=M=]]* [[=N=]]* [[=O=]]* [[=P=]]* [[=Q=]]* [[=R=]]* [[=S=]]* [[=T=]]* [[=U=]]* [[=V=]]* [[=W=]]* [[=X=]]* [[=Y=]]* [[=Z=]]*/e -x/ [[=a=]]* [[=b=]]* [[=c=]]* [[=d=]]* [[=e=]]* [[=f=]]* [[=g=]]* [[=h=]]* [[=i=]]* [[=j=]]* [[=k=]]* [[=l=]]* [[=m=]]* [[=n=]]* [[=o=]]* [[=p=]]* [[=q=]]* [[=r=]]* [[=s=]]* [[=t=]]* [[=u=]]* [[=v=]]* [[=w=]]* [[=x=]]* [[=y=]]* [[=z=]]*/e -x:" Test backwards search from a multi-byte char -/x -x?. -x:let @w=':%s#comb[i]nations#œ̄ṣ́m̥̄ᾱ̆́#g' -:@w -:?^1?,$w! test.out -:e! test.out -G:put =matchstr(\"אבגד\", \".\", 0, 2) " ב -:put =matchstr(\"אבגד\", \"..\", 0, 2) " בג -:put =matchstr(\"אבגד\", \".\", 0, 0) " א -:put =matchstr(\"אבגד\", \".\", 4, -1) " ג -:w! -:qa! -ENDTEST - -1 a aa abb abbccc -2 d dd dee deefff -3 g gg ghh ghhiii -4 j jj jkk jkklll -5 m mm mnn mnnooo -6 x ^aa$ x -7 (a)(b) abbaa -8 axx [ab]xx -9 หม่x อมx -a อมx หม่x -b ちカヨは -c x ¬€x -d 天使x -e y -f z -g a啷bb -h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐẔ -i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑẕ -j 0123❤x -k combinations diff --git a/src/nvim/testdir/test99.ok b/src/nvim/testdir/test99.ok deleted file mode 100644 index 0bd0b8ab73..0000000000 --- a/src/nvim/testdir/test99.ok +++ /dev/null @@ -1,24 +0,0 @@ -1 a aa abb abbcc -2 d dd dee deeff -3 g gg ghh ghhii -4 j jj jkk jkkll -5 m mm mnn mnnoo -6 x aa$ x -7 (a)(b) abba -8 axx ab]xx -9 หม่x อx -a อมx หx -b カヨは -c x ¬x -d 使x -e y -f z -g abb -h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐ -i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑ -j 012❤ -k œ̄ṣ́m̥̄ᾱ̆́ -ב -בג -א -ג diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 72f93976c1..6d23c2cf74 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -50,6 +50,7 @@ typedef struct { int out_fd; int old_height; bool can_use_terminal_scroll; + bool mouse_enabled; bool busy; HlAttrs attrs, print_attrs; Cell **screen; @@ -84,7 +85,7 @@ typedef struct { } while (0) -void tui_start(void) +UI *tui_start(void) { TUIData *data = xcalloc(1, sizeof(TUIData)); UI *ui = xcalloc(1, sizeof(UI)); @@ -119,7 +120,6 @@ void tui_start(void) unibi_out(ui, unibi_clear_screen); // Enable bracketed paste unibi_out(ui, data->unibi_ext.enable_bracketed_paste); - // setup output handle in a separate event loop(we wanna do synchronous // write to the tty) data->write_loop = xmalloc(sizeof(uv_loop_t)); @@ -162,6 +162,7 @@ void tui_start(void) ui->set_icon = tui_set_icon; // Attach ui_attach(ui); + return ui; } static void tui_stop(UI *ui) @@ -384,12 +385,14 @@ static void tui_mouse_on(UI *ui) { TUIData *data = ui->data; unibi_out(ui, data->unibi_ext.enable_mouse); + data->mouse_enabled = true; } static void tui_mouse_off(UI *ui) { TUIData *data = ui->data; unibi_out(ui, data->unibi_ext.disable_mouse); + data->mouse_enabled = false; } static void tui_insert_mode(UI *ui) @@ -561,9 +564,14 @@ static void tui_flush(UI *ui) static void tui_suspend(UI *ui) { + TUIData *data = ui->data; + bool enable_mouse = data->mouse_enabled; tui_stop(ui); kill(0, SIGTSTP); - tui_start(); + ui = tui_start(); + if (enable_mouse) { + tui_mouse_on(ui); + } } static void tui_set_title(UI *ui, char *title) diff --git a/src/nvim/version.c b/src/nvim/version.c index 8cdc06dba5..1a5eb523fa 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -104,7 +104,7 @@ static int included_patches[] = { //639, //638, 637, - //636, + 636, //635, //634, //633, @@ -243,7 +243,7 @@ static int included_patches[] = { 500, 499, //498 NA - //497, + 497, //496 NA //495 NA 494, diff --git a/src/nvim/window.c b/src/nvim/window.c index 9f07f2bddc..9c56cc5b82 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1766,7 +1766,7 @@ static int close_last_window_tabpage(win_T *win, int free_buf, tabpage_T *prev_c } buf_T *old_curbuf = curbuf; - Terminal *term = win->w_buffer->terminal; + Terminal *term = win->w_buffer ? win->w_buffer->terminal : NULL; if (term) { // Don't free terminal buffers free_buf = false; |