Mercurial > vim
comparison src/userfunc.c @ 21006:ae185f35e256 v8.2.1054
patch 8.2.1054: not so easy to pass a lua function to Vim
Commit: https://github.com/vim/vim/commit/801ab069341c8652680d63c174530fd4feb2911e
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Jun 25 19:27:56 2020 +0200
patch 8.2.1054: not so easy to pass a lua function to Vim
Problem: Not so easy to pass a lua function to Vim.
Solution: Convert a Lua function and closure to a Vim funcref. (Prabir
Shrestha, closes #6246)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 25 Jun 2020 19:30:21 +0200 |
parents | 3af71cbcfdbe |
children | f80e822a310d |
comparison
equal
deleted
inserted
replaced
21005:3f0abea9bed2 | 21006:ae185f35e256 |
---|---|
339 | 339 |
340 sprintf((char*)name, "<lambda>%d", ++lambda_no); | 340 sprintf((char*)name, "<lambda>%d", ++lambda_no); |
341 return name; | 341 return name; |
342 } | 342 } |
343 | 343 |
344 #if defined(FEAT_LUA) || defined(PROTO) | |
345 /* | |
346 * Registers a native C callback which can be called from Vim script. | |
347 * Returns the name of the Vim script function. | |
348 */ | |
349 char_u * | |
350 register_cfunc(cfunc_T cb, cfunc_free_T cb_free, void *state) | |
351 { | |
352 char_u *name = get_lambda_name(); | |
353 ufunc_T *fp = NULL; | |
354 garray_T newargs; | |
355 garray_T newlines; | |
356 | |
357 ga_init(&newargs); | |
358 ga_init(&newlines); | |
359 | |
360 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1); | |
361 if (fp == NULL) | |
362 goto errret; | |
363 | |
364 fp->uf_dfunc_idx = UF_NOT_COMPILED; | |
365 fp->uf_refcount = 1; | |
366 fp->uf_varargs = TRUE; | |
367 fp->uf_flags = FC_CFUNC; | |
368 fp->uf_calls = 0; | |
369 fp->uf_script_ctx = current_sctx; | |
370 fp->uf_lines = newlines; | |
371 fp->uf_args = newargs; | |
372 fp->uf_cb = cb; | |
373 fp->uf_cb_free = cb_free; | |
374 fp->uf_cb_state = state; | |
375 | |
376 set_ufunc_name(fp, name); | |
377 hash_add(&func_hashtab, UF2HIKEY(fp)); | |
378 | |
379 return name; | |
380 | |
381 errret: | |
382 ga_clear_strings(&newargs); | |
383 ga_clear_strings(&newlines); | |
384 vim_free(fp); | |
385 return NULL; | |
386 } | |
387 #endif | |
388 | |
344 /* | 389 /* |
345 * Parse a lambda expression and get a Funcref from "*arg". | 390 * Parse a lambda expression and get a Funcref from "*arg". |
346 * Return OK or FAIL. Returns NOTDONE for dict or {expr}. | 391 * Return OK or FAIL. Returns NOTDONE for dict or {expr}. |
347 */ | 392 */ |
348 int | 393 int |
1025 VIM_CLEAR(fp->uf_va_name); | 1070 VIM_CLEAR(fp->uf_va_name); |
1026 while (fp->uf_type_list.ga_len > 0) | 1071 while (fp->uf_type_list.ga_len > 0) |
1027 vim_free(((type_T **)fp->uf_type_list.ga_data) | 1072 vim_free(((type_T **)fp->uf_type_list.ga_data) |
1028 [--fp->uf_type_list.ga_len]); | 1073 [--fp->uf_type_list.ga_len]); |
1029 ga_clear(&fp->uf_type_list); | 1074 ga_clear(&fp->uf_type_list); |
1075 | |
1076 #ifdef FEAT_LUA | |
1077 if (fp->uf_cb_free != NULL) | |
1078 { | |
1079 fp->uf_cb_free(fp->uf_cb_state); | |
1080 fp->uf_cb_free = NULL; | |
1081 } | |
1082 | |
1083 fp->uf_cb_state = NULL; | |
1084 fp->uf_cb = NULL; | |
1085 #endif | |
1030 #ifdef FEAT_PROFILE | 1086 #ifdef FEAT_PROFILE |
1031 VIM_CLEAR(fp->uf_tml_count); | 1087 VIM_CLEAR(fp->uf_tml_count); |
1032 VIM_CLEAR(fp->uf_tml_total); | 1088 VIM_CLEAR(fp->uf_tml_total); |
1033 VIM_CLEAR(fp->uf_tml_self); | 1089 VIM_CLEAR(fp->uf_tml_self); |
1034 #endif | 1090 #endif |
1971 fp = find_func(p, FALSE, NULL); | 2027 fp = find_func(p, FALSE, NULL); |
1972 } | 2028 } |
1973 | 2029 |
1974 if (fp != NULL && (fp->uf_flags & FC_DELETED)) | 2030 if (fp != NULL && (fp->uf_flags & FC_DELETED)) |
1975 error = FCERR_DELETED; | 2031 error = FCERR_DELETED; |
2032 #ifdef FEAT_LUA | |
2033 else if (fp != NULL && (fp->uf_flags & FC_CFUNC)) | |
2034 { | |
2035 cfunc_T cb = fp->uf_cb; | |
2036 | |
2037 error = (*cb)(argcount, argvars, rettv, fp->uf_cb_state); | |
2038 } | |
2039 #endif | |
1976 else if (fp != NULL) | 2040 else if (fp != NULL) |
1977 { | 2041 { |
1978 if (funcexe->argv_func != NULL) | 2042 if (funcexe->argv_func != NULL) |
1979 // postponed filling in the arguments, do it now | 2043 // postponed filling in the arguments, do it now |
1980 argcount = funcexe->argv_func(argcount, argvars, argv_clear, | 2044 argcount = funcexe->argv_func(argcount, argvars, argv_clear, |