Mercurial > vim
diff src/list.c @ 26578:06693d1afc48
patch 8.2.3818: cannot filter or map characters in a string
Commit: https://github.com/vim/vim/commit/c479ce032f5d4d14bab9e479acbf42d758879893
Author: rbtnn <naru123456789@gmail.com>
Date: Wed Dec 15 19:14:54 2021 +0000
patch 8.2.3818: cannot filter or map characters in a string
Problem: Cannot filter or map characters in a string.
Solution: Make filter() and map() work on a string. (Naruhiko Nishino,
closes #9327)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 15 Dec 2021 20:15:03 +0100 |
parents | 28745eec1dda |
children | 0d2a709e2ff0 |
line wrap: on
line diff
--- a/src/list.c +++ b/src/list.c @@ -2329,9 +2329,15 @@ filter_map(typval_T *argvars, typval_T * && value_check_lock(d->dv_lock, arg_errmsg, TRUE))) goto theend; } + else if (argvars[0].v_type == VAR_STRING) + { + rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; + } else { - semsg(_(e_listdictblobarg), func_name); + semsg(_(e_argument_of_str_must_be_list_string_dictionary_or_blob), + func_name); goto theend; } @@ -2480,6 +2486,66 @@ filter_map(typval_T *argvars, typval_T * ++idx; } } + else if (argvars[0].v_type == VAR_STRING) + { + char_u *p; + typval_T tv; + garray_T ga; + char_u buf[MB_MAXBYTES + 1]; + int len; + + // set_vim_var_nr() doesn't set the type + set_vim_var_type(VV_KEY, VAR_NUMBER); + + ga_init2(&ga, (int)sizeof(char), 80); + for (p = tv_get_string(&argvars[0]); *p != NUL; p += len) + { + typval_T newtv; + + if (has_mbyte) + len = mb_ptr2len(p); + else + len = 1; + + STRNCPY(buf, p, len); + buf[len] = NUL; + + tv.v_type = VAR_STRING; + tv.vval.v_string = vim_strsave(buf); + + set_vim_var_nr(VV_KEY, idx); + if (filter_map_one(&tv, expr, filtermap, &newtv, &rem) == FAIL + || did_emsg) + break; + if (did_emsg) + { + clear_tv(&newtv); + clear_tv(&tv); + break; + } + else if (filtermap != FILTERMAP_FILTER) + { + if (newtv.v_type != VAR_STRING) + { + clear_tv(&newtv); + clear_tv(&tv); + emsg(_(e_stringreq)); + break; + } + else + ga_concat(&ga, newtv.vval.v_string); + } + else if (!rem) + ga_concat(&ga, tv.vval.v_string); + + clear_tv(&newtv); + clear_tv(&tv); + + ++idx; + } + ga_append(&ga, NUL); + rettv->vval.v_string = ga.ga_data; + } else // argvars[0].v_type == VAR_LIST { int prev_lock = l->lv_lock;