Skip to content

Commit

Permalink
Merge pull request #612 from atticus-sullivan/condition_objects_noMem
Browse files Browse the repository at this point in the history
[feature] implement condition objects
  • Loading branch information
L3MON4D3 authored Oct 8, 2022
2 parents 8f8d493 + 4bc3e35 commit aa7acef
Show file tree
Hide file tree
Showing 9 changed files with 427 additions and 18 deletions.
25 changes: 25 additions & 0 deletions DOC.md
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,31 @@ ls.add_snippets("all", {
})
```

- `conditions.show`: Contains typical predicates/functions used as
`show`-condition. Currently this is just `line_end`
- `conditions.expand`: Contains typical predicates/functions used as
`expand`-condition. Currently this is just `line_begin`
Contains everything from `conditions.show` as well.
- `conditions`: Provides a function `make_condition(foo)` which takes a function
as argument and returns a *condition object* for which several operators are
defined:
- `c1 + c2 -> c1 or c2`
- `c1 * c2 -> c1 and c2`
- `-c1 -> not c1`
- `c1 ^ c2 -> c1 xor/!= c2`
- `c1 % c2 -> c1 xnor/== c2`: This decision may look weird but as we weren't
able to use `==`, we decided to take something that makes one scratch ones
head (and thus avoid making false assumptions).
For more details look at [this comment](https://github.com/L3MON4D3/LuaSnip/pull/612#issuecomment-1264487743).

`conditions.show`s and `conditions.expand`s members all are also condition
objects so you can work with those too.

Thus you can easily combine existing predicates. Like in
`conditions.expand.line_end + conditions.expand.line_begin` instead of doing
something like
`function(...) return conditions.expand.line_end(...) or conditions.expand.line_begin(...) end`.

<!-- panvimdoc-ignore-start -->

extras1: ![extras1](https://user-images.githubusercontent.com/25300418/184359431-50f90599-3db0-4df0-a3a9-27013e663649.gif)
Expand Down
20 changes: 16 additions & 4 deletions Examples/snippets.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ local dl = require("luasnip.extras").dynamic_lambda
local fmt = require("luasnip.extras.fmt").fmt
local fmta = require("luasnip.extras.fmt").fmta
local types = require("luasnip.util.types")
local conds = require("luasnip.extras.expand_conditions")
local conds = require("luasnip.extras.conditions")
local conds_expand = require("luasnip.extras.conditions.expand")

-- If you're reading this file for the first time, best skip to around line 190
-- where the actual snippet-definitions start.
Expand Down Expand Up @@ -320,16 +321,27 @@ ls.add_snippets("all", {
return line_to_cursor:match("%s*//")
end,
}),
-- there's some built-in conditions in "luasnip.extras.expand_conditions".
-- there's some built-in conditions in "luasnip.extras.conditions.expand" and "luasnip.extras.conditions.show".
s("cond2", {
t("will only expand at the beginning of the line"),
}, {
condition = conds.line_begin,
condition = conds_expand.line_begin,
}),
s("cond3", {
t("will only expand at the end of the line"),
}, {
condition = conds.line_end,
condition = conds_expand.line_end,
}),
-- on conditions some logic operators are defined
s("cond4", {
t("will only expand at the end and the start of the line"),
}, {
-- last function is just an example how to make own function objects and apply operators on them
condition = conds_expand.line_end
+ conds_expand.line_begin
* conds.make_condition(function()
return true
end),
}),
-- The last entry of args passed to the user-function is the surrounding snippet.
s(
Expand Down
27 changes: 26 additions & 1 deletion doc/luasnip.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*luasnip.txt* For NVIM v0.5.0 Last change: 2022 September 28
*luasnip.txt* For NVIM v0.5.0 Last change: 2022 October 08

==============================================================================
Table of Contents *luasnip-table-of-contents*
Expand Down Expand Up @@ -1049,6 +1049,31 @@ is only a short outline, their usage is shown more expansively in
<



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


FMT *luasnip-fmt*

`require("luasnip.extras.fmt").fmt` can be used to create snippets in a more
Expand Down
14 changes: 14 additions & 0 deletions lua/luasnip/extras/conditions/expand.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
local cond_obj = require("luasnip.extras.conditions")

-- use the functions from show as basis and extend/overwrite functions specific for expand here
local M = vim.deepcopy(require("luasnip.extras.conditions.show"))
-----------------------
-- PRESET CONDITIONS --
-----------------------
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
M.line_begin = cond_obj.make_condition(line_begin)

return M
49 changes: 49 additions & 0 deletions lua/luasnip/extras/conditions/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
local M = {}

-----------------------
-- CONDITION OBJECTS --
-----------------------
local condition_mt = {
-- logic operators
-- not '-'
__unm = function(o1)
return M.make_condition(function(...)
return not o1(...)
end)
end,
-- or '+'
__add = function(o1, o2)
return M.make_condition(function(...)
return o1(...) or o2(...)
end)
end,
-- and '*'
__mul = function(o1, o2)
return M.make_condition(function(...)
return o1(...) and o2(...)
end)
end,
-- xor '^'
__pow = function(o1, o2)
return M.make_condition(function(...)
return o1(...) ~= o2(...)
end)
end,
-- xnor '%'
-- might be counter intuitive, but as we can't use '==' (must return bool)
-- it's best to use something weird (doesn't have to be used)
__mod = 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)
return tab.func(line_to_cursor, matched_trigger, captures)
end,
}
function M.make_condition(func)
return setmetatable({ func = func }, condition_mt)
end

return M
16 changes: 16 additions & 0 deletions lua/luasnip/extras/conditions/show.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
local cond_obj = require("luasnip.extras.conditions")

local M = {}
-----------------------
-- PRESET CONDITIONS --
-----------------------
local function line_end(line_to_cursor)
local line = vim.api.nvim_get_current_line()
-- looks pretty inefficient, but as lue interns strings, this is just a
-- comparision of pointers (which probably is faster than calculate the
-- length and then checking)
return line_to_cursor == line
end
M.line_end = cond_obj.make_condition(line_end)

return M
14 changes: 1 addition & 13 deletions lua/luasnip/extras/expand_conditions.lua
Original file line number Diff line number Diff line change
@@ -1,13 +1 @@
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

return M
return require("luasnip.extras.conditions.expand")
Loading

0 comments on commit aa7acef

Please sign in to comment.