Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] implement condition objects #612

Merged
merged 4 commits into from
Oct 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
L3MON4D3 marked this conversation as resolved.
Show resolved Hide resolved

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