@@ -2173,43 +2173,95 @@ filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap)
21732173 // set_vim_var_nr() doesn't set the type
21742174 set_vim_var_type (VV_KEY , VAR_NUMBER );
21752175
2176- CHECK_LIST_MATERIALIZE (l );
21772176 if (filtermap != FILTERMAP_FILTER && l -> lv_lock == 0 )
21782177 l -> lv_lock = VAR_LOCKED ;
2179- for (li = l -> lv_first ; li != NULL ; li = nli )
2178+
2179+ if (l -> lv_first == & range_list_item )
21802180 {
2181- typval_T newtv ;
2181+ varnumber_T val = l -> lv_u .nonmat .lv_start ;
2182+ int len = l -> lv_len ;
2183+ int stride = l -> lv_u .nonmat .lv_stride ;
21822184
2183- if (filtermap != FILTERMAP_FILTER
2184- && value_check_lock (li -> li_tv .v_lock , arg_errmsg , TRUE))
2185- break ;
2186- nli = li -> li_next ;
2187- set_vim_var_nr (VV_KEY , idx );
2188- if (filter_map_one (& li -> li_tv , expr , filtermap ,
2189- & newtv , & rem ) == FAIL )
2190- break ;
2191- if (did_emsg )
2192- {
2193- clear_tv (& newtv );
2194- break ;
2195- }
2196- if (filtermap == FILTERMAP_MAP )
2185+ // List from range(): loop over the numbers
2186+ l -> lv_first = NULL ;
2187+ l -> lv_u .mat .lv_last = NULL ;
2188+ l -> lv_len = 0 ;
2189+ l -> lv_u .mat .lv_idx_item = NULL ;
2190+
2191+ for (idx = 0 ; idx < len ; ++ idx )
21972192 {
2198- // map(): replace the list item value
2199- clear_tv (& li -> li_tv );
2200- newtv .v_lock = 0 ;
2201- li -> li_tv = newtv ;
2193+ typval_T tv ;
2194+ typval_T newtv ;
2195+
2196+ tv .v_type = VAR_NUMBER ;
2197+ tv .v_lock = 0 ;
2198+ tv .vval .v_number = val ;
2199+ set_vim_var_nr (VV_KEY , idx );
2200+ if (filter_map_one (& tv , expr , filtermap , & newtv , & rem )
2201+ == FAIL )
2202+ break ;
2203+ if (did_emsg )
2204+ {
2205+ clear_tv (& newtv );
2206+ break ;
2207+ }
2208+ if (filtermap != FILTERMAP_FILTER )
2209+ {
2210+ // map(), mapnew(): always append the new value to the
2211+ // list
2212+ if (list_append_tv_move (filtermap == FILTERMAP_MAP
2213+ ? l : l_ret , & newtv ) == FAIL )
2214+ break ;
2215+ }
2216+ else if (!rem )
2217+ {
2218+ // filter(): append the list item value when not rem
2219+ if (list_append_tv_move (l , & tv ) == FAIL )
2220+ break ;
2221+ }
2222+
2223+ val += stride ;
22022224 }
2203- else if (filtermap == FILTERMAP_MAPNEW )
2225+ }
2226+ else
2227+ {
2228+ // Materialized list from range(): loop over the items
2229+ for (li = l -> lv_first ; li != NULL ; li = nli )
22042230 {
2205- // mapnew(): append the list item value
2206- if (list_append_tv_move (l_ret , & newtv ) == FAIL )
2231+ typval_T newtv ;
2232+
2233+ if (filtermap != FILTERMAP_FILTER && value_check_lock (
2234+ li -> li_tv .v_lock , arg_errmsg , TRUE))
2235+ break ;
2236+ nli = li -> li_next ;
2237+ set_vim_var_nr (VV_KEY , idx );
2238+ if (filter_map_one (& li -> li_tv , expr , filtermap ,
2239+ & newtv , & rem ) == FAIL )
22072240 break ;
2241+ if (did_emsg )
2242+ {
2243+ clear_tv (& newtv );
2244+ break ;
2245+ }
2246+ if (filtermap == FILTERMAP_MAP )
2247+ {
2248+ // map(): replace the list item value
2249+ clear_tv (& li -> li_tv );
2250+ newtv .v_lock = 0 ;
2251+ li -> li_tv = newtv ;
2252+ }
2253+ else if (filtermap == FILTERMAP_MAPNEW )
2254+ {
2255+ // mapnew(): append the list item value
2256+ if (list_append_tv_move (l_ret , & newtv ) == FAIL )
2257+ break ;
2258+ }
2259+ else if (filtermap == FILTERMAP_FILTER && rem )
2260+ listitem_remove (l , li );
2261+ ++ idx ;
22082262 }
2209- else if (filtermap == FILTERMAP_FILTER && rem )
2210- listitem_remove (l , li );
2211- ++ idx ;
22122263 }
2264+
22132265 l -> lv_lock = prev_lock ;
22142266 }
22152267
0 commit comments