From 6ced4d3aaba680ed6d2b22cfed396972612647ed Mon Sep 17 00:00:00 2001 From: atticus-sullivan Date: Thu, 15 Sep 2022 21:05:48 +0200 Subject: [PATCH 1/7] add memoization first draft/idea --- lua/luasnip/extras/expand_conditions.lua | 32 ++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/lua/luasnip/extras/expand_conditions.lua b/lua/luasnip/extras/expand_conditions.lua index 52a6101dc..b5b523c2c 100644 --- a/lua/luasnip/extras/expand_conditions.lua +++ b/lua/luasnip/extras/expand_conditions.lua @@ -10,4 +10,36 @@ function M.line_end(line_to_cursor) return #line_to_cursor == #line end +local memoization_mt = { + __unm = function(o1) return function() return not o1() end end, + __add = function(o1,o2) return function() return o1() or o2() end end, + __mul = function(o1,o2) return function() return o1() and o2() end end, + -- TODO more logic operators + __call = function(tab) + if not tab.mem or tab.invalidate(tab) then + tab.mem = tab.func() + end + return tab.mem + end +} +-- low level factory +-- invalidate(table) -> bool: decides if the memoization should be invalidated, +-- can store state in table +-- TODO provide invalidate defaults (buffer, cursor, changes, none) +function M.memoization_factory(func, invalidate) + -- always invalidare by default + invalidate = invalidate or function() return true end + return setmetatable({func=func, invalidate=invalidate}, memoization_mt) +end + +-- F1 = memoization_factory(function() return true end) +-- F2 = memoization_factory(function() return false end) +-- F3 = F1 + F2 +-- F4 = F1 * -F2 +-- +-- local m = {F1=F1, F2=F2, F3=F3, F4=F4} +-- for _,name in ipairs{"F1", "F2", "F3", "F4"} do +-- print(name, m[name]()) +-- end + return M From d4f8be1e1592545d0ef458967236b18ac6169c7a Mon Sep 17 00:00:00 2001 From: atticus-sullivan Date: Mon, 19 Sep 2022 21:39:01 +0200 Subject: [PATCH 2/7] fix the argument forwarding (comply to the current interfaces) --- lua/luasnip/extras/expand_conditions.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lua/luasnip/extras/expand_conditions.lua b/lua/luasnip/extras/expand_conditions.lua index b5b523c2c..ef7364b7a 100644 --- a/lua/luasnip/extras/expand_conditions.lua +++ b/lua/luasnip/extras/expand_conditions.lua @@ -11,13 +11,13 @@ function M.line_end(line_to_cursor) end local memoization_mt = { - __unm = function(o1) return function() return not o1() end end, - __add = function(o1,o2) return function() return o1() or o2() end end, - __mul = function(o1,o2) return function() return o1() and o2() end end, + __unm = function(o1) return function(...) return not o1(...) end end, + __add = function(o1,o2) return function(...) return o1(...) or o2(...) end end, + __mul = function(o1,o2) return function(...) return o1(...) and o2(...) end end, -- TODO more logic operators - __call = function(tab) - if not tab.mem or tab.invalidate(tab) then - tab.mem = tab.func() + __call = function(tab, line_to_cursor, matched_trigger, captures) + if not tab.mem or tab.invalidate(tab, line_to_cursor, matched_trigger, captures) then + tab.mem = tab.func(line_to_cursor, matched_trigger, captures) end return tab.mem end From 63925f03b2d57b8fe3131719a0929fd9ef0d2c95 Mon Sep 17 00:00:00 2001 From: atticus-sullivan Date: Mon, 19 Sep 2022 21:43:45 +0200 Subject: [PATCH 3/7] add xnor operator --- lua/luasnip/extras/expand_conditions.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lua/luasnip/extras/expand_conditions.lua b/lua/luasnip/extras/expand_conditions.lua index ef7364b7a..c17916a51 100644 --- a/lua/luasnip/extras/expand_conditions.lua +++ b/lua/luasnip/extras/expand_conditions.lua @@ -11,10 +11,16 @@ function M.line_end(line_to_cursor) end local memoization_mt = { + -- logic operators + -- not __unm = function(o1) return function(...) return not o1(...) end end, + -- or __add = function(o1,o2) return function(...) return o1(...) or o2(...) end end, + -- and __mul = function(o1,o2) return function(...) return o1(...) and o2(...) end end, - -- TODO more logic operators + -- xnor + __eq = function(o1,o2) return function(...) return o1(...) == o2(...) end end, + -- use table like a function by overloading __call __call = function(tab, line_to_cursor, matched_trigger, captures) if not tab.mem or tab.invalidate(tab, line_to_cursor, matched_trigger, captures) then tab.mem = tab.func(line_to_cursor, matched_trigger, captures) From 611200870858a9b6d31329101b9feea233f78c1a Mon Sep 17 00:00:00 2001 From: atticus-sullivan Date: Mon, 19 Sep 2022 21:51:02 +0200 Subject: [PATCH 4/7] add condition presets --- lua/luasnip/extras/expand_conditions.lua | 38 ++++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/lua/luasnip/extras/expand_conditions.lua b/lua/luasnip/extras/expand_conditions.lua index c17916a51..a1dd9065a 100644 --- a/lua/luasnip/extras/expand_conditions.lua +++ b/lua/luasnip/extras/expand_conditions.lua @@ -1,15 +1,8 @@ local M = {} -function M.line_begin(line_to_cursor, matched_trigger) - -- +1 because `string.sub("abcd", 1, -2)` -> abc - return line_to_cursor:sub(1, -(#matched_trigger + 1)):match("^%s*$") -end - -function M.line_end(line_to_cursor) - local line = vim.api.nvim_get_current_line() - return #line_to_cursor == #line -end - +----------------------- +-- CONDITION OBJECTS -- +----------------------- local memoization_mt = { -- logic operators -- not @@ -38,14 +31,21 @@ function M.memoization_factory(func, invalidate) return setmetatable({func=func, invalidate=invalidate}, memoization_mt) end --- F1 = memoization_factory(function() return true end) --- F2 = memoization_factory(function() return false end) --- F3 = F1 + F2 --- F4 = F1 * -F2 --- --- local m = {F1=F1, F2=F2, F3=F3, F4=F4} --- for _,name in ipairs{"F1", "F2", "F3", "F4"} do --- print(name, m[name]()) --- end +------------- +-- PRESETS -- +------------- +local function line_begin(line_to_cursor, matched_trigger) + -- +1 because `string.sub("abcd", 1, -2)` -> abc + return line_to_cursor:sub(1, -(#matched_trigger + 1)):match("^%s*$") +end +function M.line_begin() return M.memoization_factory(line_begin, nil) -- TODO invalidation function +end + +local function line_end(line_to_cursor) + local line = vim.api.nvim_get_current_line() + return #line_to_cursor == #line +end +function M.line_end() return M.memoization_factory(line_end, nil) -- TODO invalidation function +end return M From 4e1337443f1a04a1edc88f9b9b755ec4e8e8c228 Mon Sep 17 00:00:00 2001 From: atticus-sullivan Date: Mon, 19 Sep 2022 21:55:54 +0200 Subject: [PATCH 5/7] fiction example for invalidation function --- lua/luasnip/extras/expand_conditions.lua | 26 ++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/lua/luasnip/extras/expand_conditions.lua b/lua/luasnip/extras/expand_conditions.lua index a1dd9065a..9405e16f6 100644 --- a/lua/luasnip/extras/expand_conditions.lua +++ b/lua/luasnip/extras/expand_conditions.lua @@ -24,28 +24,42 @@ local memoization_mt = { -- low level factory -- invalidate(table) -> bool: decides if the memoization should be invalidated, -- can store state in table --- TODO provide invalidate defaults (buffer, cursor, changes, none) function M.memoization_factory(func, invalidate) -- always invalidare by default invalidate = invalidate or function() return true end return setmetatable({func=func, invalidate=invalidate}, memoization_mt) end -------------- --- PRESETS -- -------------- +------------------- +-- INVAL PRESETS -- +------------------- +-- TODO provide invalidate defaults (buffer, cursor, changes, none) +M.inval = {} +-- just a small example to illustrate the usage (will most probably have to be +-- changed) +function M.inval.line(tab, _, _, _, line) + return tab.line ~= line +end + +------------------ +-- COND PRESETS -- +------------------ local function line_begin(line_to_cursor, matched_trigger) -- +1 because `string.sub("abcd", 1, -2)` -> abc return line_to_cursor:sub(1, -(#matched_trigger + 1)):match("^%s*$") end -function M.line_begin() return M.memoization_factory(line_begin, nil) -- TODO invalidation function +function M.line_begin() + -- TODO invalidation function + return M.memoization_factory(line_begin, nil) end local function line_end(line_to_cursor) local line = vim.api.nvim_get_current_line() return #line_to_cursor == #line end -function M.line_end() return M.memoization_factory(line_end, nil) -- TODO invalidation function +function M.line_end() + -- TODO invalidation function + return M.memoization_factory(line_end, nil) end return M From a4939135b3f0858643bec0dd1bbe0326783ee3de Mon Sep 17 00:00:00 2001 From: atticus-sullivan Date: Mon, 19 Sep 2022 19:57:43 +0000 Subject: [PATCH 6/7] Auto generate docs --- doc/luasnip.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/luasnip.txt b/doc/luasnip.txt index 2829104f4..730a871de 100644 --- a/doc/luasnip.txt +++ b/doc/luasnip.txt @@ -1,4 +1,4 @@ -*luasnip.txt* For NVIM v0.5.0 Last change: 2022 September 15 +*luasnip.txt* For NVIM v0.5.0 Last change: 2022 September 19 ============================================================================== Table of Contents *luasnip-table-of-contents* From f37dcd69a600635afaf928177725a4225b668a08 Mon Sep 17 00:00:00 2001 From: atticus-sullivan Date: Mon, 19 Sep 2022 19:57:47 +0000 Subject: [PATCH 7/7] Format with stylua --- lua/luasnip/extras/expand_conditions.lua | 40 +++++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/lua/luasnip/extras/expand_conditions.lua b/lua/luasnip/extras/expand_conditions.lua index 9405e16f6..409fe743a 100644 --- a/lua/luasnip/extras/expand_conditions.lua +++ b/lua/luasnip/extras/expand_conditions.lua @@ -6,28 +6,52 @@ local M = {} local memoization_mt = { -- logic operators -- not - __unm = function(o1) return function(...) return not o1(...) end end, + __unm = function(o1) + return function(...) + return not o1(...) + end + end, -- or - __add = function(o1,o2) return function(...) return o1(...) or o2(...) end end, + __add = function(o1, o2) + return function(...) + return o1(...) or o2(...) + end + end, -- and - __mul = function(o1,o2) return function(...) return o1(...) and o2(...) end end, + __mul = function(o1, o2) + return function(...) + return o1(...) and o2(...) + end + end, -- xnor - __eq = function(o1,o2) return function(...) return o1(...) == o2(...) end end, + __eq = function(o1, o2) + return function(...) + return o1(...) == o2(...) + end + end, -- use table like a function by overloading __call __call = function(tab, line_to_cursor, matched_trigger, captures) - if not tab.mem or tab.invalidate(tab, line_to_cursor, matched_trigger, captures) then + if + not tab.mem + or tab.invalidate(tab, line_to_cursor, matched_trigger, captures) + then tab.mem = tab.func(line_to_cursor, matched_trigger, captures) end return tab.mem - end + end, } -- low level factory -- invalidate(table) -> bool: decides if the memoization should be invalidated, -- can store state in table function M.memoization_factory(func, invalidate) -- always invalidare by default - invalidate = invalidate or function() return true end - return setmetatable({func=func, invalidate=invalidate}, memoization_mt) + invalidate = invalidate or function() + return true + end + return setmetatable( + { func = func, invalidate = invalidate }, + memoization_mt + ) end -------------------