comparison src/insexpand.c @ 26388:8aba638e91eb v8.2.3725

patch 8.2.3725: cannot use a lambda for 'completefunc' and 'omnifunc' Commit: https://github.com/vim/vim/commit/8658c759f05b317707d56e3b65a5ef63930c7498 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Fri Dec 3 11:09:29 2021 +0000 patch 8.2.3725: cannot use a lambda for 'completefunc' and 'omnifunc' Problem: Cannot use a lambda for 'completefunc' and 'omnifunc'. Solution: Implement lambda support. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/9257)
author Bram Moolenaar <Bram@vim.org>
date Fri, 03 Dec 2021 12:15:04 +0100
parents dbe615b75f15
children 65b4109a4297
comparison
equal deleted inserted replaced
26387:b6eb7e295973 26388:8aba638e91eb
2235 ; 2235 ;
2236 return buf; 2236 return buf;
2237 } 2237 }
2238 2238
2239 #ifdef FEAT_COMPL_FUNC 2239 #ifdef FEAT_COMPL_FUNC
2240
2241 # ifdef FEAT_EVAL
2242 static callback_T cfu_cb; // 'completefunc' callback function
2243 static callback_T ofu_cb; // 'omnifunc' callback function
2244 static callback_T tsrfu_cb; // 'thesaurusfunc' callback function
2245 # endif
2246
2247 /*
2248 * Copy a global callback function to a buffer local callback.
2249 */
2250 static void
2251 copy_global_to_buflocal_cb(callback_T *globcb, callback_T *bufcb)
2252 {
2253 free_callback(bufcb);
2254 if (globcb->cb_name != NULL && *globcb->cb_name != NUL)
2255 copy_callback(bufcb, globcb);
2256 }
2257
2258 /*
2259 * Parse the 'completefunc' option value and set the callback function.
2260 * Invoked when the 'completefunc' option is set. The option value can be a
2261 * name of a function (string), or function(<name>) or funcref(<name>) or a
2262 * lambda expression.
2263 */
2264 int
2265 set_completefunc_option(void)
2266 {
2267 int retval;
2268
2269 retval = option_set_callback_func(curbuf->b_p_cfu, &cfu_cb);
2270 if (retval == OK)
2271 set_buflocal_cfu_callback(curbuf);
2272
2273 return retval;
2274 }
2275
2276 /*
2277 * Copy the global 'completefunc' callback function to the buffer-local
2278 * 'completefunc' callback for 'buf'.
2279 */
2280 void
2281 set_buflocal_cfu_callback(buf_T *buf UNUSED)
2282 {
2283 # ifdef FEAT_EVAL
2284 copy_global_to_buflocal_cb(&cfu_cb, &buf->b_cfu_cb);
2285 # endif
2286 }
2287
2288 /*
2289 * Parse the 'omnifunc' option value and set the callback function.
2290 * Invoked when the 'omnifunc' option is set. The option value can be a
2291 * name of a function (string), or function(<name>) or funcref(<name>) or a
2292 * lambda expression.
2293 */
2294 int
2295 set_omnifunc_option(void)
2296 {
2297 int retval;
2298
2299 retval = option_set_callback_func(curbuf->b_p_ofu, &ofu_cb);
2300 if (retval == OK)
2301 set_buflocal_ofu_callback(curbuf);
2302
2303 return retval;
2304 }
2305
2306 /*
2307 * Copy the global 'omnifunc' callback function to the buffer-local 'omnifunc'
2308 * callback for 'buf'.
2309 */
2310 void
2311 set_buflocal_ofu_callback(buf_T *buf UNUSED)
2312 {
2313 # ifdef FEAT_EVAL
2314 copy_global_to_buflocal_cb(&ofu_cb, &buf->b_ofu_cb);
2315 # endif
2316 }
2317
2318 /*
2319 * Parse the 'thesaurusfunc' option value and set the callback function.
2320 * Invoked when the 'thesaurusfunc' option is set. The option value can be a
2321 * name of a function (string), or function(<name>) or funcref(<name>) or a
2322 * lambda expression.
2323 */
2324 int
2325 set_thesaurusfunc_option(void)
2326 {
2327 int retval;
2328
2329 if (*curbuf->b_p_tsrfu != NUL)
2330 {
2331 // buffer-local option set
2332 free_callback(&curbuf->b_tsrfu_cb);
2333 retval = option_set_callback_func(curbuf->b_p_tsrfu,
2334 &curbuf->b_tsrfu_cb);
2335 }
2336 else
2337 {
2338 // global option set
2339 free_callback(&tsrfu_cb);
2340 retval = option_set_callback_func(p_tsrfu, &tsrfu_cb);
2341 }
2342
2343 return retval;
2344 }
2345
2346
2240 /* 2347 /*
2241 * Get the user-defined completion function name for completion 'type' 2348 * Get the user-defined completion function name for completion 'type'
2242 */ 2349 */
2243 static char_u * 2350 static char_u *
2244 get_complete_funcname(int type) 2351 get_complete_funcname(int type)
2255 return (char_u *)""; 2362 return (char_u *)"";
2256 } 2363 }
2257 } 2364 }
2258 2365
2259 /* 2366 /*
2367 * Get the callback to use for insert mode completion.
2368 */
2369 callback_T *
2370 get_insert_callback(int type)
2371 {
2372 if (type == CTRL_X_FUNCTION)
2373 return &curbuf->b_cfu_cb;
2374 if (type == CTRL_X_OMNI)
2375 return &curbuf->b_ofu_cb;
2376 // CTRL_X_THESAURUS
2377 return (*curbuf->b_p_tsrfu != NUL) ? &curbuf->b_tsrfu_cb : &tsrfu_cb;
2378 }
2379
2380 /*
2260 * Execute user defined complete function 'completefunc', 'omnifunc' or 2381 * Execute user defined complete function 'completefunc', 'omnifunc' or
2261 * 'thesaurusfunc', and get matches in "matches". 2382 * 'thesaurusfunc', and get matches in "matches".
2262 * "type" is either CTRL_X_OMNI or CTRL_X_FUNCTION or CTRL_X_THESAURUS. 2383 * "type" is either CTRL_X_OMNI or CTRL_X_FUNCTION or CTRL_X_THESAURUS.
2263 */ 2384 */
2264 static void 2385 static void
2267 list_T *matchlist = NULL; 2388 list_T *matchlist = NULL;
2268 dict_T *matchdict = NULL; 2389 dict_T *matchdict = NULL;
2269 typval_T args[3]; 2390 typval_T args[3];
2270 char_u *funcname; 2391 char_u *funcname;
2271 pos_T pos; 2392 pos_T pos;
2393 callback_T *cb;
2272 typval_T rettv; 2394 typval_T rettv;
2273 int save_State = State; 2395 int save_State = State;
2396 int retval;
2274 2397
2275 funcname = get_complete_funcname(type); 2398 funcname = get_complete_funcname(type);
2276 if (*funcname == NUL) 2399 if (*funcname == NUL)
2277 return; 2400 return;
2278 2401
2287 // Lock the text to avoid weird things from happening. Also disallow 2410 // Lock the text to avoid weird things from happening. Also disallow
2288 // switching to another window, it should not be needed and may end up in 2411 // switching to another window, it should not be needed and may end up in
2289 // Insert mode in another buffer. 2412 // Insert mode in another buffer.
2290 ++textwinlock; 2413 ++textwinlock;
2291 2414
2415 cb = get_insert_callback(type);
2416 retval = call_callback(cb, 0, &rettv, 2, args);
2417
2292 // Call a function, which returns a list or dict. 2418 // Call a function, which returns a list or dict.
2293 if (call_vim_function(funcname, 2, args, &rettv) == OK) 2419 if (retval == OK)
2294 { 2420 {
2295 switch (rettv.v_type) 2421 switch (rettv.v_type)
2296 { 2422 {
2297 case VAR_LIST: 2423 case VAR_LIST:
2298 matchlist = rettv.vval.v_list; 2424 matchlist = rettv.vval.v_list;
3969 typval_T args[3]; 4095 typval_T args[3];
3970 int col; 4096 int col;
3971 char_u *funcname; 4097 char_u *funcname;
3972 pos_T pos; 4098 pos_T pos;
3973 int save_State = State; 4099 int save_State = State;
4100 callback_T *cb;
3974 4101
3975 // Call 'completefunc' or 'omnifunc' and get pattern length as a 4102 // Call 'completefunc' or 'omnifunc' and get pattern length as a
3976 // string 4103 // string
3977 funcname = get_complete_funcname(ctrl_x_mode); 4104 funcname = get_complete_funcname(ctrl_x_mode);
3978 if (*funcname == NUL) 4105 if (*funcname == NUL)
3989 args[1].v_type = VAR_STRING; 4116 args[1].v_type = VAR_STRING;
3990 args[1].vval.v_string = (char_u *)""; 4117 args[1].vval.v_string = (char_u *)"";
3991 args[2].v_type = VAR_UNKNOWN; 4118 args[2].v_type = VAR_UNKNOWN;
3992 pos = curwin->w_cursor; 4119 pos = curwin->w_cursor;
3993 ++textwinlock; 4120 ++textwinlock;
3994 col = call_func_retnr(funcname, 2, args); 4121 cb = get_insert_callback(ctrl_x_mode);
4122 col = call_callback_retnr(cb, 2, args);
3995 --textwinlock; 4123 --textwinlock;
3996 4124
3997 State = save_State; 4125 State = save_State;
3998 curwin->w_cursor = pos; // restore the cursor position 4126 curwin->w_cursor = pos; // restore the cursor position
3999 validate_cursor(); 4127 validate_cursor();
4337 #if defined(EXITFREE) || defined(PROTO) 4465 #if defined(EXITFREE) || defined(PROTO)
4338 void 4466 void
4339 free_insexpand_stuff(void) 4467 free_insexpand_stuff(void)
4340 { 4468 {
4341 VIM_CLEAR(compl_orig_text); 4469 VIM_CLEAR(compl_orig_text);
4470 # ifdef FEAT_EVAL
4471 free_callback(&cfu_cb);
4472 free_callback(&ofu_cb);
4473 free_callback(&tsrfu_cb);
4474 # endif
4342 } 4475 }
4343 #endif 4476 #endif
4344 4477
4345 #ifdef FEAT_SPELL 4478 #ifdef FEAT_SPELL
4346 /* 4479 /*