Mercurial > vim
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 /* |