Skip to content

Commit 42a83b0

Browse files
committed
feat(dart): init dart
1 parent 4fe7846 commit 42a83b0

File tree

5 files changed

+491
-1
lines changed

5 files changed

+491
-1
lines changed

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,28 @@ ls.setup({
194194
| `.println` | Wraps with `println!("{:?}", ?)`. | `expr` |
195195

196196
</details>
197+
198+
<details>
199+
<summary>Dart</summary>
200+
201+
#### Normal Snippets
202+
203+
| Trig | Desc | Context Required |
204+
| :---: | ------------------------------------------------ | :--------------: |
205+
| `fn` | Expands to function definition. | No |
206+
| `wfn` | Expands to function definition returns a widget. | No |
207+
| `afn` | Expands to an async function definition. | No |
208+
209+
#### Auto-snippets
210+
211+
| Trig | Desc | Context Required |
212+
| :-----: | ----------------------------------------- | :--------------: |
213+
| `ctor!` | Expands to class constructor function. | In Class |
214+
| `js!` | Expands to json-related methods. | In Class |
215+
| `init!` | Expands to `initState` override function. | No |
216+
| `dis!` | Expands to `dispose` override function. | No |
217+
| `for!` | Expands to for-loop. | No |
218+
| `sfw!` | Expands to `StatefulWidget` class. | No |
219+
| `slw!` | Expands to `StatelessWidget` class. | No |
220+
221+
</details>

lua/luasnip-snippets/init.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ function M.setup(opts)
4747
"cpp",
4848
"rust",
4949
"lua",
50+
"dart",
5051
"all",
5152
}
5253
end

lua/luasnip-snippets/snippets/cpp/statements.lua

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ local t = ls.text_node
66
local fmta = require("luasnip.extras.fmt").fmta
77
local snippet = require("luasnip-snippets.nodes").construct_snippet
88
local i = require("luasnip-snippets.nodes").insert_node
9-
local c = require("luasnip-snippets.nodes").choice_node
109
local rep = require("luasnip.extras").rep
1110

1211
local function inject_class_name(_, line_to_cursor, match, captures)
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
local UtilsTS = require("luasnip-snippets.utils.treesitter")
2+
3+
---@class LSSnippets.snippet.dart.Declaration
4+
---@field ty string
5+
---@field nullable boolean
6+
---@field identifier string
7+
---@field final boolean
8+
9+
--[[
10+
declaration [11, 2] - [11, 23]
11+
type_identifier [11, 2] - [11, 6]
12+
type_arguments [11, 6] - [11, 11]
13+
type_identifier [11, 7] - [11, 10]
14+
nullable_type [11, 11] - [11, 12]
15+
initialized_identifier_list [11, 13] - [11, 23]
16+
initialized_identifier [11, 13] - [11, 17]
17+
identifier [11, 13] - [11, 17]
18+
initialized_identifier [11, 19] - [11, 23]
19+
identifier [11, 19] - [11, 23]
20+
]]
21+
22+
---@param node TSNode
23+
---@param source string|number
24+
---@return LSSnippets.snippet.dart.Declaration[]
25+
local function _handle_declaration(node, source)
26+
local ty
27+
local nullable = false
28+
local final = false
29+
local fields = {}
30+
31+
for c in node:iter_children() do
32+
if c:type() == "type_identifier" then
33+
ty = vim.treesitter.get_node_text(c, source)
34+
elseif c:type() == "type_arguments" then
35+
ty = ty .. vim.treesitter.get_node_text(c, source)
36+
elseif c:type() == "nullable_type" then
37+
nullable = true
38+
elseif c:type() == "final_builtin" then
39+
final = true
40+
elseif c:type() == "initialized_identifier_list" then
41+
for cc in c:iter_children() do
42+
if cc:type() == "initialized_identifier" then
43+
local id_node = cc:child(0)
44+
assert(id_node ~= nil)
45+
fields[#fields + 1] = vim.treesitter.get_node_text(id_node, source)
46+
end
47+
end
48+
end
49+
end
50+
51+
local ret = {}
52+
for _, field in ipairs(fields) do
53+
ret[#ret + 1] = {
54+
ty = ty,
55+
nullable = nullable,
56+
final = final,
57+
identifier = field,
58+
}
59+
end
60+
61+
return ret
62+
end
63+
64+
---@param _ any
65+
---@param line_to_cursor string
66+
---@param match string
67+
---@param captures any
68+
local function resolve_class_decls(_, line_to_cursor, match, captures)
69+
-- check if at the line begin
70+
if not line_to_cursor:sub(1, -(#match + 1)):match("^%s*$") then
71+
return nil
72+
end
73+
74+
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
75+
local buf = vim.api.nvim_get_current_buf()
76+
---@param parser LanguageTree
77+
---@param source number|string
78+
return UtilsTS.invoke_after_reparse_buffer(
79+
buf,
80+
match,
81+
function(parser, source)
82+
local pos = {
83+
row - 1,
84+
col - #match,
85+
}
86+
local node =
87+
parser:named_node_for_range { pos[1], pos[2], pos[1], pos[2] }
88+
if node == nil then
89+
return nil
90+
end
91+
local class_node = UtilsTS.find_first_parent(node, "class_definition")
92+
if class_node == nil then
93+
return nil
94+
end
95+
96+
local name = class_node:field("name")
97+
if name == nil or #name == 0 then
98+
return nil
99+
end
100+
local class_name = vim.treesitter.get_node_text(name[1], source)
101+
102+
local body = class_node:field("body")
103+
if body == nil or #body == 0 then
104+
return nil
105+
end
106+
107+
local decls = {}
108+
109+
for c in body[1]:iter_children() do
110+
if c:type() == "declaration" then
111+
vim.list_extend(decls, _handle_declaration(c, source))
112+
end
113+
end
114+
115+
return {
116+
trigger = match,
117+
captures = captures,
118+
env_override = {
119+
CLASS_NAME = class_name,
120+
CLASS_DECLS = decls,
121+
},
122+
}
123+
end
124+
)
125+
end
126+
127+
---@param _ any
128+
---@param line_to_cursor string
129+
---@param match string
130+
---@param captures any
131+
local function resolve_maybe_class_decl(_, line_to_cursor, match, captures)
132+
-- check if at the line begin
133+
if not line_to_cursor:sub(1, -(#match + 1)):match("^%s*$") then
134+
return nil
135+
end
136+
137+
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
138+
local buf = vim.api.nvim_get_current_buf()
139+
---@param parser LanguageTree
140+
---@param source number|string
141+
return UtilsTS.invoke_after_reparse_buffer(
142+
buf,
143+
match,
144+
function(parser, source)
145+
local pos = {
146+
row - 1,
147+
col - #match,
148+
}
149+
local node =
150+
parser:named_node_for_range { pos[1], pos[2], pos[1], pos[2] }
151+
if node == nil then
152+
return nil
153+
end
154+
155+
local env = {}
156+
157+
local class_node = UtilsTS.find_first_parent(node, "class_definition")
158+
if class_node == nil then
159+
env.IN_CLASS = false
160+
else
161+
env.IN_CLASS = true
162+
local name = class_node:field("name")
163+
if name == nil or #name == 0 then
164+
return nil
165+
end
166+
env.CLASS_NAME = vim.treesitter.get_node_text(name[1], source)
167+
168+
local body = class_node:field("body")
169+
if body == nil or #body == 0 then
170+
return nil
171+
end
172+
173+
local decls = {}
174+
for c in body[1]:iter_children() do
175+
if c:type() == "declaration" then
176+
vim.list_extend(decls, _handle_declaration(c, source))
177+
end
178+
end
179+
env.CLASS_DECLS = decls
180+
end
181+
182+
return {
183+
trigger = match,
184+
captures = captures,
185+
env_override = env,
186+
}
187+
end
188+
)
189+
end
190+
191+
return {
192+
resolve_class_decls = resolve_class_decls,
193+
resolve_maybe_class_decl = resolve_maybe_class_decl,
194+
}

0 commit comments

Comments
 (0)