Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions lua/luasnip/_types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
---@field from LuaSnip.BytecolBufferPosition Starting position, included.
---@field to LuaSnip.BytecolBufferPosition Ending position, excluded.

---@alias LuaSnip.NormalizedNodeRef LuaSnip.KeyIndexer|LuaSnip.AbsoluteIndexer
---@alias LuaSnip.NodeRef LuaSnip.KeyIndexer|LuaSnip.AbsoluteIndexer|number
---@alias LuaSnip.NormalizedNodeRef LuaSnip.KeyIndexer|LuaSnip.AbsoluteIndexer|LuaSnip.OptionalNodeRef
---@alias LuaSnip.NodeRef LuaSnip.KeyIndexer|LuaSnip.AbsoluteIndexer|LuaSnip.OptionalNodeRef|number
2 changes: 1 addition & 1 deletion lua/luasnip/nodes/choiceNode.lua
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ function ChoiceNode:subsnip_init()
choice.parent = self.parent
-- only insertNode needs this. (?)
if
util.list_contains(
vim.tbl_contains(
{ types.textNode, types.insertNode, types.functionNode },
choice.type
)
Expand Down
16 changes: 14 additions & 2 deletions lua/luasnip/nodes/node.lua
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ function Node:jumpable(dir)
end
end

---@return string[]?
function Node:get_text()
if not self.visible then
return nil
Expand All @@ -192,11 +193,13 @@ function Node:get_text()
return ok and text or { "" }
end

---@return LuaSnip.SnippetString
function Node:get_snippetstring()
-- if this is not overridden, get_text returns a multiline string.
return snippet_string.new(self:get_text())
end

---@return LuaSnip.SnippetString
function Node:get_static_snippetstring()
-- if this is not overridden, get_static_text() is a multiline string.
return snippet_string.new(self:get_static_text())
Expand Down Expand Up @@ -252,6 +255,11 @@ function Node:init_insert_positions(position_so_far)
self.absolute_insert_position = vim.deepcopy(position_so_far)
end

--- Run event handlers for the given event type.
--- - runs node callback if defined
--- - runs parent callback for the node if defined
--- - fires `User LuaSnip<Event>` autocmd
---
---@param event LuaSnip.EventType
function Node:event(event)
local node_callback = self.node_callbacks[event]
Expand All @@ -277,7 +285,7 @@ function Node:event(event)
})
end

---@return (string[])?
---@return string[]?
local function get_args(node, get_text_func_name, static)
local argnodes_text = {}
for key, arg in ipairs(node.args_absolute) do
Expand Down Expand Up @@ -342,9 +350,11 @@ local function get_args(node, get_text_func_name, static)
return argnodes_text
end

---@return string[]?
function Node:get_args()
return get_args(self, "argnode_text", false)
end
---@return string[]?
function Node:get_static_args()
return get_args(self, "get_static_snippetstring", true)
end
Expand Down Expand Up @@ -431,7 +441,8 @@ function Node:resolve_node_ext_opts(base_prio, parent_ext_opts)
)
end

function Node:is_interactive()
---@param info any (note: this is used in ast_parser)
function Node:is_interactive(info)
-- safe default.
return true
end
Expand Down Expand Up @@ -701,6 +712,7 @@ end
-- those that don't.
function Node:subtree_leave_entered() end

---@return LuaSnip.SnippetString
function Node:argnode_text()
return self:get_snippetstring()
end
Expand Down
8 changes: 7 additions & 1 deletion lua/luasnip/nodes/optional_arg.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
local M = {}

-- FIXME: This is not documented!
---@class LuaSnip.OptionalNodeRef
---@field ref LuaSnip.NodeRef

local opt_mt = {}

--- Create an optional node ref
---@param ref LuaSnip.NodeRef
---@return LuaSnip.OptionalNodeRef
function M.new_opt(ref)
return setmetatable({ ref = ref }, opt_mt)
end

---@return boolean
function M.is_opt(t)
return getmetatable(t) == opt_mt
end
Expand Down
15 changes: 8 additions & 7 deletions lua/luasnip/nodes/snippet.lua
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ local SN
---@class LuaSnip.BareInternalSnippet: LuaSnip.Node
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite get at what point a snippet is a BareInternalSnippet.. In my mind there is Addable for things that can be put into add_snippets, Expandable for stuff that has :matches and condition and the like, and then there is ExpandedSnippet for when the snippet is expanded.

As far as I remember snippet, dependents_dict, child_snippets, static_text, and indentstr are only used by snippets once they are expanded, maybe ExpandedSnippet is a better place for them? (And maybe it'd be a good idea to initialize them in trigger_expand?)

Copy link
Contributor Author

@bew bew Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to make something for the return type of _S, which is used in different places for defining different types.
And it's made to have the common fields for all other classes that are derived from it.

It's used as the common base for Snippet & SnippetNode:

  • ---@class LuaSnip.SnippetNode: LuaSnip.BareInternalSnippet, LuaSnip.NormalizedSnippetNodeOpts
  • ---@class LuaSnip.Snippet: LuaSnip.BareInternalSnippet, LuaSnip.NormalizedSnippetContext, LuaSnip.NormalizedSnippetOpts, LuaSnip.Addable

Those two don't share all the same fields nor the same parent classes, so we need a kind of base class for all their common fields πŸ€”


As far as I remember snippet, dependents_dict, child_snippets, static_text, and indentstr are only used by snippets once they are expanded, maybe ExpandedSnippet is a better place for them? (And maybe it'd be a good idea to initialize them in trigger_expand?)

Interesting, I'll have to explore that!

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to make something for the return type of _S, which is used in different places for defining different types.
And it's made to have the common fields for all other classes that are derived from it.

It's used as the common base for Snippet & SnippetNode

Ahh I see.. this seems fine πŸ‘
So far I'd thought of snippet as a specialization of snippetNode, but it's possible that, rigourously, there are some conflicts there πŸ˜…

--- To be used as a base for all snippet-like nodes (Snippet, SnippetProxy, ..)
---
---@field _source? {file: string, line: integer}
---@field _source? LuaSnip.Source
---@field nodes LuaSnip.Node[]
---@field insert_nodes LuaSnip.InsertNode[]
---@field snippet LuaSnip.Snippet
Expand Down Expand Up @@ -113,7 +113,8 @@ local Snippet = node_mod.Node:new()
---@field docTrig? string
---@field trig_matcher LuaSnip.SnipContext.TrigMatcher
---@field resolveExpandParams LuaSnip.ResolveExpandParamsFn
---@field show_condition fun(line_to_cursor: string): boolean
---@field show_condition LuaSnip.SnipContext.ShowCondition
---@field condition LuaSnip.SnipContext.Condition
---@field invalidated boolean

---@class LuaSnip.NormalizedSnippetNodeOpts
Expand Down Expand Up @@ -638,18 +639,19 @@ end
local function S(context, nodes, opts)
opts = opts or {}

local snip = init_snippet_context(node_util.wrap_context(context), opts)
local snip = vim.tbl_extend("error", snip, init_snippet_opts(opts))
local snip_with_ctx = init_snippet_context(node_util.wrap_context(context), opts)
local snip_with_opts = init_snippet_opts(opts)

local snip = _S(snip, nodes, opts)
local base_snip = vim.tbl_extend("error", snip_with_ctx, snip_with_opts)
local snip = _S(base_snip, nodes, opts)
---@cast snip LuaSnip.Snippet

if __luasnip_get_loaded_file_frame_debuginfo ~= nil then
-- this snippet is being lua-loaded, and the source should be recorded.
snip._source =
source.from_debuginfo(__luasnip_get_loaded_file_frame_debuginfo())
end

---@type LuaSnip.Snippet
return snip
end
extend_decorator.register(
Expand Down Expand Up @@ -1160,7 +1162,6 @@ function Snippet:del_marks()
end
end

-- FIXME: `info` is _never_ used anywhere?
function Snippet:is_interactive(info)
for _, node in ipairs(self.nodes) do
-- return true if any node depends on another node or is an insertNode.
Expand Down
7 changes: 5 additions & 2 deletions lua/luasnip/nodes/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ end
---@param args LuaSnip.NodeRef[]
---@param parent_insert_position integer[]
---@param target LuaSnip.NormalizedNodeRef[] Target for the normalized node refs
-- FIXME(@bew): Why is the `target` param updated instead of returning a new table?
local function make_args_absolute(args, parent_insert_position, target)
for i, arg in ipairs(args) do
if type(arg) == "number" then
Expand Down Expand Up @@ -188,6 +189,8 @@ local function snippet_extend_context(arg, extend)
return vim.tbl_extend("keep", arg or {}, extend or {})
end

---@param context LuaSnip.SnipContext|string
---@return LuaSnip.SnipContext
local function wrap_context(context)
if type(context) == "string" then
return { trig = context }
Expand Down Expand Up @@ -863,8 +866,8 @@ local function collect_dependents(node, which, static)
return tbl_util.set_to_list(dependents_set)
end

---@param args (string[])?
---@return ((string[])[])?
---@param args string[]?
---@return string[][]?
local function str_args(args)
return args
and vim.tbl_map(function(arg)
Expand Down
6 changes: 2 additions & 4 deletions lua/luasnip/nodes/util/snippet_string.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ local str_util = require("luasnip.util.str")
local util = require("luasnip.util.util")

---@class LuaSnip.SnippetString.Mark
--- A kind-of extmark to the text in this buffer.
--- A kind of extmark, but for a string not a Neovim buffer.
---
--- It moves with inserted text, and has a gravity to control into which
--- direction it shifts. pos is 1-based and refers to one character in the
Expand All @@ -11,8 +11,6 @@ local util = require("luasnip.util.util")
--- If the edge is in the middle of multiple characters (for example rgrav=true,
--- and chars at pos and pos+1 are replaced), the mark is removed.
---
--- FIXME(@bew): How is it different than extmarks? (-> why not use them?)
---
---@field id string ID of the mark
---@field pos integer 1-based, refers to one character in the string
---@field rgrav boolean The gravity of the mark.
Expand Down Expand Up @@ -152,7 +150,7 @@ function SnippetString:put(pos)
end
end

-- FIXME(@bew): what is the return type here?
---@return LuaSnip.SnippetString
function SnippetString:copy()
-- on 0.7 vim.deepcopy does not behave correctly on snippets => have to manually copy.
return setmetatable(
Expand Down
10 changes: 5 additions & 5 deletions lua/luasnip/session/snippet_collection/source.lua
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
---@class LuaSnip._Source
---@class LuaSnip.Source
---@field file string
---@field line? integer
---@field line_end? integer

---@type {[integer]: LuaSnip._Source}
---@type {[integer]: LuaSnip.Source}
local id_to_source = {}

local M = {}

---@return LuaSnip._Source
---@return LuaSnip.Source
function M.from_debuginfo(debuginfo)
assert(debuginfo.source, "debuginfo contains source")
assert(
Expand All @@ -25,7 +25,7 @@ end

---@param file string
---@param opts? {line: integer, line_end: integer}
---@return LuaSnip._Source
---@return LuaSnip.Source
function M.from_location(file, opts)
assert(file, "source needs file")
opts = opts or {}
Expand All @@ -34,7 +34,7 @@ function M.from_location(file, opts)
end

---@param snippet LuaSnip.Snippet
---@param source LuaSnip._Source
---@param source LuaSnip.Source
function M.set(snippet, source)
-- snippets only get their id after being added, make sure this is the
-- case.
Expand Down
2 changes: 1 addition & 1 deletion lua/luasnip/util/table.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---Convert set of values to a list of those values.
---@generic T
---@param tbl T[]|{[T]: boolean}
---@param tbl {[T]: boolean}
---@return T[]
local function set_to_list(tbl)
local ls = {}
Expand Down
16 changes: 0 additions & 16 deletions lua/luasnip/util/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -479,21 +479,6 @@ local function copy3(obj, seen)
return setmetatable(res, getmetatable(obj))
end

--- Checks if a list-like table (integer keys without gaps) contains `needle`.
---@param t table Table to check (must be list-like, not validated)
---@param needle any Value to compare
---@return boolean _ `true` if `t` contains `needle`
local function list_contains(t, needle)
vim.validate("t", t, "table")

for _, v in ipairs(t) do
if v == needle then
return true
end
end
return false
end

return {
get_cursor_0ind = get_cursor_0ind,
set_cursor_0ind = set_cursor_0ind,
Expand Down Expand Up @@ -540,5 +525,4 @@ return {
pos_from_offset = pos_from_offset,
shallow_copy = shallow_copy,
copy3 = copy3,
list_contains = list_contains,
}
Loading