Mercurial > vim
comparison src/if_lua.c @ 20441:86dde5c4b375 v8.2.0775
patch 8.2.0775: not easy to call a Vim function from Lua
Commit: https://github.com/vim/vim/commit/eb04f0893afe01faff272ef84c70d8cc16d8e80a
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun May 17 14:32:35 2020 +0200
patch 8.2.0775: not easy to call a Vim function from Lua
Problem: Not easy to call a Vim function from Lua.
Solution: Add vim.call() and vim.fn(). (Prabir Shrestha, closes https://github.com/vim/vim/issues/6063)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 17 May 2020 14:45:04 +0200 |
parents | 4acb165ed0bc |
children | 070c8a22261d |
comparison
equal
deleted
inserted
replaced
20440:74db00344bf6 | 20441:86dde5c4b375 |
---|---|
566 tv->v_type = VAR_STRING; | 566 tv->v_type = VAR_STRING; |
567 tv->vval.v_string = vim_strsave((char_u *) lua_tostring(L, pos)); | 567 tv->vval.v_string = vim_strsave((char_u *) lua_tostring(L, pos)); |
568 break; | 568 break; |
569 case LUA_TNUMBER: | 569 case LUA_TNUMBER: |
570 #ifdef FEAT_FLOAT | 570 #ifdef FEAT_FLOAT |
571 tv->v_type = VAR_FLOAT; | 571 { |
572 tv->vval.v_float = (float_T) lua_tonumber(L, pos); | 572 const lua_Number n = lua_tonumber(L, pos); |
573 | |
574 if (n > (lua_Number)INT64_MAX || n < (lua_Number)INT64_MIN | |
575 || ((lua_Number)((varnumber_T)n)) != n) | |
576 { | |
577 tv->v_type = VAR_FLOAT; | |
578 tv->vval.v_float = (float_T)n; | |
579 } | |
580 else | |
581 { | |
582 tv->v_type = VAR_NUMBER; | |
583 tv->vval.v_number = (varnumber_T)n; | |
584 } | |
585 } | |
573 #else | 586 #else |
574 tv->v_type = VAR_NUMBER; | 587 tv->v_type = VAR_NUMBER; |
575 tv->vval.v_number = (varnumber_T) lua_tointeger(L, pos); | 588 tv->vval.v_number = (varnumber_T) lua_tointeger(L, pos); |
576 #endif | 589 #endif |
577 break; | 590 break; |
1901 } | 1914 } |
1902 lua_pushstring(L, luaL_typename(L, 1)); // fallback | 1915 lua_pushstring(L, luaL_typename(L, 1)); // fallback |
1903 return 1; | 1916 return 1; |
1904 } | 1917 } |
1905 | 1918 |
1919 static int | |
1920 luaV_call(lua_State *L) | |
1921 { | |
1922 int argc = lua_gettop(L) - 1; | |
1923 size_t funcname_len; | |
1924 char_u *funcname; | |
1925 char *error = NULL; | |
1926 typval_T rettv; | |
1927 typval_T argv[MAX_FUNC_ARGS + 1]; | |
1928 int i = 0; | |
1929 | |
1930 if (argc > MAX_FUNC_ARGS) | |
1931 return luaL_error(L, "Function called with too many arguments"); | |
1932 | |
1933 funcname = (char_u *)luaL_checklstring(L, 1, &funcname_len); | |
1934 | |
1935 for (; i < argc; i++) | |
1936 { | |
1937 if (luaV_totypval(L, i + 2, &argv[i]) == FAIL) | |
1938 { | |
1939 error = "lua: cannot convert value"; | |
1940 goto free_vim_args; | |
1941 } | |
1942 } | |
1943 | |
1944 argv[argc].v_type = VAR_UNKNOWN; | |
1945 | |
1946 if (call_vim_function(funcname, argc, argv, &rettv) == FAIL) | |
1947 { | |
1948 error = "lua: call_vim_function failed"; | |
1949 goto free_vim_args; | |
1950 } | |
1951 | |
1952 luaV_pushtypval(L, &rettv); | |
1953 clear_tv(&rettv); | |
1954 | |
1955 free_vim_args: | |
1956 while (i > 0) | |
1957 clear_tv(&argv[--i]); | |
1958 | |
1959 if (error == NULL) | |
1960 return 1; | |
1961 else | |
1962 return luaL_error(L, error); | |
1963 } | |
1964 | |
1906 static const luaL_Reg luaV_module[] = { | 1965 static const luaL_Reg luaV_module[] = { |
1907 {"command", luaV_command}, | 1966 {"command", luaV_command}, |
1908 {"eval", luaV_eval}, | 1967 {"eval", luaV_eval}, |
1909 {"beep", luaV_beep}, | 1968 {"beep", luaV_beep}, |
1910 {"line", luaV_line}, | 1969 {"line", luaV_line}, |
1914 {"funcref", luaV_funcref}, | 1973 {"funcref", luaV_funcref}, |
1915 {"buffer", luaV_buffer}, | 1974 {"buffer", luaV_buffer}, |
1916 {"window", luaV_window}, | 1975 {"window", luaV_window}, |
1917 {"open", luaV_open}, | 1976 {"open", luaV_open}, |
1918 {"type", luaV_type}, | 1977 {"type", luaV_type}, |
1978 {"call", luaV_call}, | |
1919 {NULL, NULL} | 1979 {NULL, NULL} |
1920 }; | 1980 }; |
1921 | 1981 |
1922 /* | 1982 /* |
1923 * for freeing list, dict, buffer and window objects; lightuserdata as arg | 1983 * for freeing list, dict, buffer and window objects; lightuserdata as arg |
1994 lua_pop(L, 2); // metatable and value | 2054 lua_pop(L, 2); // metatable and value |
1995 } | 2055 } |
1996 lua_pushinteger(L, abort); | 2056 lua_pushinteger(L, abort); |
1997 return 1; | 2057 return 1; |
1998 } | 2058 } |
2059 | |
2060 #define LUA_VIM_FN_CODE \ | |
2061 "vim.fn = setmetatable({}, {"\ | |
2062 " __index = function (t, key)"\ | |
2063 " local function _fn(...)"\ | |
2064 " return vim.call(key, ...)"\ | |
2065 " end"\ | |
2066 " t[key] = _fn"\ | |
2067 " return _fn"\ | |
2068 " end"\ | |
2069 "})" | |
1999 | 2070 |
2000 static int | 2071 static int |
2001 luaopen_vim(lua_State *L) | 2072 luaopen_vim(lua_State *L) |
2002 { | 2073 { |
2003 // set cache table | 2074 // set cache table |
2050 luaV_openlib(L, luaV_Window_mt, 1); | 2121 luaV_openlib(L, luaV_Window_mt, 1); |
2051 lua_newtable(L); // vim table | 2122 lua_newtable(L); // vim table |
2052 lua_pushvalue(L, 1); // cache table | 2123 lua_pushvalue(L, 1); // cache table |
2053 luaV_openlib(L, luaV_module, 1); | 2124 luaV_openlib(L, luaV_module, 1); |
2054 lua_setglobal(L, LUAVIM_NAME); | 2125 lua_setglobal(L, LUAVIM_NAME); |
2126 // custom code | |
2127 luaL_dostring(L, LUA_VIM_FN_CODE); | |
2055 return 0; | 2128 return 0; |
2056 } | 2129 } |
2057 | 2130 |
2058 static lua_State * | 2131 static lua_State * |
2059 luaV_newstate(void) | 2132 luaV_newstate(void) |