Skip to content

Commit aa7acef

Browse files
authored
Merge pull request #612 from atticus-sullivan/condition_objects_noMem
[feature] implement condition objects
2 parents 8f8d493 + 4bc3e35 commit aa7acef

File tree

9 files changed

+427
-18
lines changed

9 files changed

+427
-18
lines changed

DOC.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,31 @@ ls.add_snippets("all", {
10641064
})
10651065
```
10661066

1067+
- `conditions.show`: Contains typical predicates/functions used as
1068+
`show`-condition. Currently this is just `line_end`
1069+
- `conditions.expand`: Contains typical predicates/functions used as
1070+
`expand`-condition. Currently this is just `line_begin`
1071+
Contains everything from `conditions.show` as well.
1072+
- `conditions`: Provides a function `make_condition(foo)` which takes a function
1073+
as argument and returns a *condition object* for which several operators are
1074+
defined:
1075+
- `c1 + c2 -> c1 or c2`
1076+
- `c1 * c2 -> c1 and c2`
1077+
- `-c1 -> not c1`
1078+
- `c1 ^ c2 -> c1 xor/!= c2`
1079+
- `c1 % c2 -> c1 xnor/== c2`: This decision may look weird but as we weren't
1080+
able to use `==`, we decided to take something that makes one scratch ones
1081+
head (and thus avoid making false assumptions).
1082+
For more details look at [this comment](https://github.com/L3MON4D3/LuaSnip/pull/612#issuecomment-1264487743).
1083+
1084+
`conditions.show`s and `conditions.expand`s members all are also condition
1085+
objects so you can work with those too.
1086+
1087+
Thus you can easily combine existing predicates. Like in
1088+
`conditions.expand.line_end + conditions.expand.line_begin` instead of doing
1089+
something like
1090+
`function(...) return conditions.expand.line_end(...) or conditions.expand.line_begin(...) end`.
1091+
10671092
<!-- panvimdoc-ignore-start -->
10681093

10691094
extras1: ![extras1](https://user-images.githubusercontent.com/25300418/184359431-50f90599-3db0-4df0-a3a9-27013e663649.gif)

Examples/snippets.lua

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ local dl = require("luasnip.extras").dynamic_lambda
1717
local fmt = require("luasnip.extras.fmt").fmt
1818
local fmta = require("luasnip.extras.fmt").fmta
1919
local types = require("luasnip.util.types")
20-
local conds = require("luasnip.extras.expand_conditions")
20+
local conds = require("luasnip.extras.conditions")
21+
local conds_expand = require("luasnip.extras.conditions.expand")
2122

2223
-- If you're reading this file for the first time, best skip to around line 190
2324
-- where the actual snippet-definitions start.
@@ -320,16 +321,27 @@ ls.add_snippets("all", {
320321
return line_to_cursor:match("%s*//")
321322
end,
322323
}),
323-
-- there's some built-in conditions in "luasnip.extras.expand_conditions".
324+
-- there's some built-in conditions in "luasnip.extras.conditions.expand" and "luasnip.extras.conditions.show".
324325
s("cond2", {
325326
t("will only expand at the beginning of the line"),
326327
}, {
327-
condition = conds.line_begin,
328+
condition = conds_expand.line_begin,
328329
}),
329330
s("cond3", {
330331
t("will only expand at the end of the line"),
331332
}, {
332-
condition = conds.line_end,
333+
condition = conds_expand.line_end,
334+
}),
335+
-- on conditions some logic operators are defined
336+
s("cond4", {
337+
t("will only expand at the end and the start of the line"),
338+
}, {
339+
-- last function is just an example how to make own function objects and apply operators on them
340+
condition = conds_expand.line_end
341+
+ conds_expand.line_begin
342+
* conds.make_condition(function()
343+
return true
344+
end),
333345
}),
334346
-- The last entry of args passed to the user-function is the surrounding snippet.
335347
s(

doc/luasnip.txt

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*luasnip.txt* For NVIM v0.5.0 Last change: 2022 September 28
1+
*luasnip.txt* For NVIM v0.5.0 Last change: 2022 October 08
22

33
==============================================================================
44
Table of Contents *luasnip-table-of-contents*
@@ -1049,6 +1049,31 @@ is only a short outline, their usage is shown more expansively in
10491049
<
10501050

10511051

1052+
1053+
- `conditions.show`: Contains typical predicates/functions used as
1054+
`show`-condition. Currently this is just `line_end`
1055+
- `conditions.expand`: Contains typical predicates/functions used as
1056+
`expand`-condition. Currently this is just `line_begin` Contains everything
1057+
from `conditions.show` as well.
1058+
- `conditions`: Provides a function `make_condition(foo)` which takes a function
1059+
as argument and returns a _condition object_ for which several operators are
1060+
defined:
1061+
- `c1 + c2 -> c1 or c2`
1062+
- `c1 * c2 -> c1 and c2`
1063+
- `-c1 -> not c1`
1064+
- `c1 ^ c2 -> c1 xor/!= c2`
1065+
- `c1 % c2 -> c1 xnor/== c2`: This decision may look weird but as we weren’t
1066+
able to use `==`, we decided to take something that makes one scratch ones
1067+
head (and thus avoid making false assumptions).
1068+
For more details look at this comment <https://github.com/L3MON4D3/LuaSnip/pull/612#issuecomment-1264487743>.
1069+
`conditions.show`s and `conditions.expand`s members all are also condition
1070+
objects so you can work with those too.
1071+
Thus you can easily combine existing predicates. Like in
1072+
`conditions.expand.line_end + conditions.expand.line_begin` instead of doing
1073+
something like `function(...) return conditions.expand.line_end(...) or
1074+
conditions.expand.line_begin(...) end`.
1075+
1076+
10521077
FMT *luasnip-fmt*
10531078

10541079
`require("luasnip.extras.fmt").fmt` can be used to create snippets in a more
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
local cond_obj = require("luasnip.extras.conditions")
2+
3+
-- use the functions from show as basis and extend/overwrite functions specific for expand here
4+
local M = vim.deepcopy(require("luasnip.extras.conditions.show"))
5+
-----------------------
6+
-- PRESET CONDITIONS --
7+
-----------------------
8+
local function line_begin(line_to_cursor, matched_trigger)
9+
-- +1 because `string.sub("abcd", 1, -2)` -> abc
10+
return line_to_cursor:sub(1, -(#matched_trigger + 1)):match("^%s*$")
11+
end
12+
M.line_begin = cond_obj.make_condition(line_begin)
13+
14+
return M
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
local M = {}
2+
3+
-----------------------
4+
-- CONDITION OBJECTS --
5+
-----------------------
6+
local condition_mt = {
7+
-- logic operators
8+
-- not '-'
9+
__unm = function(o1)
10+
return M.make_condition(function(...)
11+
return not o1(...)
12+
end)
13+
end,
14+
-- or '+'
15+
__add = function(o1, o2)
16+
return M.make_condition(function(...)
17+
return o1(...) or o2(...)
18+
end)
19+
end,
20+
-- and '*'
21+
__mul = function(o1, o2)
22+
return M.make_condition(function(...)
23+
return o1(...) and o2(...)
24+
end)
25+
end,
26+
-- xor '^'
27+
__pow = function(o1, o2)
28+
return M.make_condition(function(...)
29+
return o1(...) ~= o2(...)
30+
end)
31+
end,
32+
-- xnor '%'
33+
-- might be counter intuitive, but as we can't use '==' (must return bool)
34+
-- it's best to use something weird (doesn't have to be used)
35+
__mod = function(o1, o2)
36+
return function(...)
37+
return o1(...) == o2(...)
38+
end
39+
end,
40+
-- use table like a function by overloading __call
41+
__call = function(tab, line_to_cursor, matched_trigger, captures)
42+
return tab.func(line_to_cursor, matched_trigger, captures)
43+
end,
44+
}
45+
function M.make_condition(func)
46+
return setmetatable({ func = func }, condition_mt)
47+
end
48+
49+
return M
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
local cond_obj = require("luasnip.extras.conditions")
2+
3+
local M = {}
4+
-----------------------
5+
-- PRESET CONDITIONS --
6+
-----------------------
7+
local function line_end(line_to_cursor)
8+
local line = vim.api.nvim_get_current_line()
9+
-- looks pretty inefficient, but as lue interns strings, this is just a
10+
-- comparision of pointers (which probably is faster than calculate the
11+
-- length and then checking)
12+
return line_to_cursor == line
13+
end
14+
M.line_end = cond_obj.make_condition(line_end)
15+
16+
return M
Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1 @@
1-
local M = {}
2-
3-
function M.line_begin(line_to_cursor, matched_trigger)
4-
-- +1 because `string.sub("abcd", 1, -2)` -> abc
5-
return line_to_cursor:sub(1, -(#matched_trigger + 1)):match("^%s*$")
6-
end
7-
8-
function M.line_end(line_to_cursor)
9-
local line = vim.api.nvim_get_current_line()
10-
return #line_to_cursor == #line
11-
end
12-
13-
return M
1+
return require("luasnip.extras.conditions.expand")

0 commit comments

Comments
 (0)