Skip to content

Commit d5a2406

Browse files
committed
feat: parse crate path and git declarations
1 parent d0fe35c commit d5a2406

File tree

2 files changed

+310
-186
lines changed

2 files changed

+310
-186
lines changed

lua/crates/toml.lua

Lines changed: 155 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
1-
local M = {Section = {}, Crate = {Vers = {}, Pkg = {}, Def = {}, Feat = {}, }, Feature = {}, Quotes = {}, }
1+
local M = {Section = {}, Crate = {Vers = {}, Path = {}, Git = {}, Pkg = {}, Def = {}, Feat = {}, }, Feature = {}, Quotes = {}, }
2+
3+
4+
5+
6+
7+
8+
9+
10+
11+
12+
13+
14+
15+
16+
17+
18+
19+
220

321

422

@@ -88,6 +106,25 @@ local types = require("crates.types")
88106
local Range = types.Range
89107
local Requirement = types.Requirement
90108

109+
local function inline_table_bool_pattern(name)
110+
return "^%s*([^%s]+)%s*=%s*{.-[,]?()%s*" .. name .. "%s*=%s*()([^%s,]*)()%s*()[,]?.*[}]?%s*$"
111+
end
112+
113+
local function inline_table_str_pattern(name)
114+
return [[^%s*([^%s]+)%s*=%s*{.-[,]?()%s*]] .. name .. [[%s*=%s*(["'])()([^"']*)()(["']?)%s*()[,]?.*[}]?%s*$]]
115+
end
116+
117+
local function inline_table_str_array_pattern(name)
118+
return "^%s*([^%s]+)%s*=%s*{.-[,]?()%s*" .. name .. "%s*=%s*%[()([^%]]*)()[%]]?%s*()[,]?.*[}]?%s*$"
119+
end
120+
121+
local INLINE_TABLE_VERS_PATTERN = inline_table_str_pattern("version")
122+
local INLINE_TABLE_PATH_PATTERN = inline_table_str_pattern("path")
123+
local INLINE_TABLE_GIT_PATTERN = inline_table_str_pattern("git")
124+
local INLINE_TABLE_PKG_PATTERN = inline_table_str_pattern("package")
125+
local INLINE_TABLE_FEAT_PATTERN = inline_table_str_array_pattern("features")
126+
local INLINE_TABLE_DEF_PATTERN = inline_table_bool_pattern("default[_-]features")
127+
91128
function M.parse_crate_features(text)
92129
local feats = {}
93130
for fds, qs, fs, f, fe, qe, fde, c in text:gmatch([[[,]?()%s*(["'])()([^,"']*)()(["']?)%s*()([,]?)]]) do
@@ -204,48 +241,51 @@ function M.parse_section(text)
204241
return nil
205242
end
206243

207-
function M.parse_crate_table_vers(line)
208-
local qs, vs, vers_text, ve, qe = line:match([[^%s*version%s*=%s*(["'])()([^"']*)()(["']?)%s*$]])
209-
if qs and vs and vers_text and ve then
244+
local function parse_crate_table_str(entry, line, pattern)
245+
local quote_s, str_s, text, str_e, quote_e = line:match(pattern)
246+
if text then
210247
return {
211248
syntax = "table",
212-
vers = {
213-
text = vers_text,
214-
col = Range.new(vs - 1, ve - 1),
249+
[entry] = {
250+
text = text,
251+
col = Range.new(str_s - 1, str_e - 1),
215252
decl_col = Range.new(0, line:len()),
216-
quote = { s = qs, e = qe ~= "" and qe or nil },
253+
quote = { s = quote_s, e = quote_e ~= "" and quote_e or nil },
217254
},
218255
}
219256
end
220257

221258
return nil
222259
end
223260

224-
function M.parse_crate_table_pkg(line)
225-
local qs, ps, pkg_text, pe, qe = line:match([[^%s*package%s*=%s*(["'])()([^"']*)()(["']?)%s*$]])
226-
if qs and ps and pkg_text and pe then
227-
return {
228-
syntax = "table",
229-
pkg = {
230-
text = pkg_text,
231-
col = Range.new(ps - 1, pe - 1),
232-
decl_col = Range.new(0, line:len()),
233-
quote = { s = qs, e = qe ~= "" and qe or nil },
234-
},
235-
}
236-
end
261+
function M.parse_crate_table_vers(line)
262+
local pat = [[^%s*version%s*=%s*(["'])()([^"']*)()(["']?)%s*$]]
263+
return parse_crate_table_str("vers", line, pat)
264+
end
237265

238-
return nil
266+
function M.parse_crate_table_path(line)
267+
local pat = [[^%s*path%s*=%s*(["'])()([^"']*)()(["']?)%s*$]]
268+
return parse_crate_table_str("path", line, pat)
269+
end
270+
271+
function M.parse_crate_table_git(line)
272+
local pat = [[^%s*git%s*=%s*(["'])()([^"']*)()(["']?)%s*$]]
273+
return parse_crate_table_str("git", line, pat)
274+
end
275+
276+
function M.parse_crate_table_pkg(line)
277+
local pat = [[^%s*package%s*=%s*(["'])()([^"']*)()(["']?)%s*$]]
278+
return parse_crate_table_str("pkg", line, pat)
239279
end
240280

241281
function M.parse_crate_table_feat(line)
242-
local fs, feat_text, fe = line:match("%s*features%s*=%s*%[()([^%]]*)()[%]]?%s*$")
243-
if fs and feat_text and fe then
282+
local array_s, text, array_e = line:match("%s*features%s*=%s*%[()([^%]]*)()[%]]?%s*$")
283+
if text then
244284
return {
245285
syntax = "table",
246286
feat = {
247-
text = feat_text,
248-
col = Range.new(fs - 1, fe - 1),
287+
text = text,
288+
col = Range.new(array_s - 1, array_e - 1),
249289
decl_col = Range.new(0, line:len()),
250290
},
251291
}
@@ -255,13 +295,13 @@ function M.parse_crate_table_feat(line)
255295
end
256296

257297
function M.parse_crate_table_def(line)
258-
local ds, def_text, de = line:match("^%s*default[_-]features%s*=%s*()([^%s]*)()%s*$")
259-
if ds and def_text and de then
298+
local bool_s, text, bool_e = line:match("^%s*default[_-]features%s*=%s*()([^%s]*)()%s*$")
299+
if text then
260300
return {
261301
syntax = "table",
262302
def = {
263-
text = def_text,
264-
col = Range.new(ds - 1, de - 1),
303+
text = text,
304+
col = Range.new(bool_s - 1, bool_e - 1),
265305
decl_col = Range.new(0, line:len()),
266306
},
267307
}
@@ -270,80 +310,85 @@ function M.parse_crate_table_def(line)
270310
return nil
271311
end
272312

273-
function M.parse_crate(line)
274-
local name
275-
local vds, qs, vs, vers_text, ve, qe, vde
276-
local pds, ps, pkg_text, pe, pde
277-
local fds, fs, feat_text, fe, fde
278-
local dds, ds, def_text, de, dde
313+
local function parse_inline_table_str(crate, entry, line, pattern)
314+
local name, decl_s, quote_s, str_s, text, str_e, quote_e, decl_e = line:match(pattern)
315+
if name then
316+
crate.name = name
317+
crate.syntax = "inline_table"
318+
crate[entry] = {
319+
text = text,
320+
col = Range.new(str_s - 1, str_e - 1),
321+
decl_col = Range.new(decl_s - 1, decl_e - 1),
322+
quote = { s = quote_s, e = quote_e ~= "" and quote_e or nil },
323+
}
324+
end
325+
end
279326

327+
function M.parse_crate(line)
280328

281-
name, qs, vs, vers_text, ve, qe = line:match([[^%s*([^%s]+)%s*=%s*(["'])()([^"']*)()(["']?)%s*$]])
282-
if name and qs and vs and vers_text and ve then
283-
return {
284-
name = name,
285-
syntax = "plain",
286-
vers = {
287-
text = vers_text,
288-
col = Range.new(vs - 1, ve - 1),
289-
decl_col = Range.new(0, line:len()),
290-
quote = { s = qs, e = qe ~= "" and qe or nil },
291-
},
292-
}
329+
do
330+
local name, quote_s, str_s, text, str_e, quote_e = line:match([[^%s*([^%s]+)%s*=%s*(["'])()([^"']*)()(["']?)%s*$]])
331+
if name then
332+
return {
333+
name = name,
334+
syntax = "plain",
335+
vers = {
336+
text = text,
337+
col = Range.new(str_s - 1, str_e - 1),
338+
decl_col = Range.new(0, line:len()),
339+
quote = { s = quote_s, e = quote_e ~= "" and quote_e or nil },
340+
},
341+
}
342+
end
293343
end
294344

295345

296346
local crate = {}
297347

298-
local vers_pat = [[^%s*([^%s]+)%s*=%s*{.-[,]?()%s*version%s*=%s*(["'])()([^"']*)()(["']?)%s*()[,]?.*[}]?%s*$]]
299-
name, vds, qs, vs, vers_text, ve, qe, vde = line:match(vers_pat)
300-
if name and vds and qs and vs and vers_text and ve and qe and vde then
301-
crate.name = name
302-
crate.syntax = "inline_table"
303-
crate.vers = {
304-
text = vers_text,
305-
col = Range.new(vs - 1, ve - 1),
306-
decl_col = Range.new(vds - 1, vde - 1),
307-
quote = { s = qs, e = qe ~= "" and qe or nil },
308-
}
348+
parse_inline_table_str(crate, "vers", line, INLINE_TABLE_VERS_PATTERN)
349+
parse_inline_table_str(crate, "path", line, INLINE_TABLE_PATH_PATTERN)
350+
parse_inline_table_str(crate, "git", line, INLINE_TABLE_GIT_PATTERN)
351+
352+
do
353+
local name, decl_s, array_s, text, array_e, decl_e = line:match(INLINE_TABLE_FEAT_PATTERN)
354+
if name then
355+
crate.name = name
356+
crate.syntax = "inline_table"
357+
crate.feat = {
358+
text = text,
359+
col = Range.new(array_s - 1, array_e - 1),
360+
decl_col = Range.new(decl_s - 1, decl_e - 1),
361+
}
362+
end
309363
end
310364

311-
local feat_pat = "^%s*([^%s]+)%s*=%s*{.-[,]?()%s*features%s*=%s*%[()([^%]]*)()[%]]?%s*()[,]?.*[}]?%s*$"
312-
name, fds, fs, feat_text, fe, fde = line:match(feat_pat)
313-
if name and fds and fs and feat_text and fe and fde then
314-
crate.name = name
315-
crate.syntax = "inline_table"
316-
crate.feat = {
317-
text = feat_text,
318-
col = Range.new(fs - 1, fe - 1),
319-
decl_col = Range.new(fds - 1, fde - 1),
320-
}
365+
do
366+
local name, decl_s, bool_s, text, bool_e, decl_e = line:match(INLINE_TABLE_DEF_PATTERN)
367+
if name then
368+
crate.name = name
369+
crate.syntax = "inline_table"
370+
crate.def = {
371+
text = text,
372+
col = Range.new(bool_s - 1, bool_e - 1),
373+
decl_col = Range.new(decl_s - 1, decl_e - 1),
374+
}
375+
end
321376
end
322377

323-
local def_pat = "^%s*([^%s]+)%s*=%s*{.-[,]?()%s*default[_-]features%s*=%s*()([a-zA-Z]*)()%s*()[,]?.*[}]?%s*$"
324-
name, dds, ds, def_text, de, dde = line:match(def_pat)
325-
if name and dds and ds and def_text and de and dde then
326-
crate.name = name
327-
crate.syntax = "inline_table"
328-
crate.def = {
329-
text = def_text,
330-
col = Range.new(ds - 1, de - 1),
331-
decl_col = Range.new(dds - 1, dde - 1),
332-
}
333-
end
334378

335-
local pkg_pat = [[^%s*([^%s]+)%s*=%s*{.-[,]?()%s*package%s*=%s*(["'])()([^"']*)()(["']?)%s*()[,]?.*[}]?%s*$]]
336-
name, pds, qs, ps, pkg_text, pe, qe, pde = line:match(pkg_pat)
337-
if name and pds and qs and ps and pkg_text and pe and qe and pde then
338-
crate.name = pkg_text
339-
crate.rename = name
340-
crate.syntax = "inline_table"
341-
crate.pkg = {
342-
text = pkg_text,
343-
col = Range.new(ps - 1, pe - 1),
344-
decl_col = Range.new(pds - 1, pde - 1),
345-
quote = { s = qs, e = qe ~= "" and qe or nil },
346-
}
379+
do
380+
local name, decl_s, quote_s, str_s, text, str_e, quote_e, decl_e = line:match(INLINE_TABLE_PKG_PATTERN)
381+
if name then
382+
crate.name = text
383+
crate.rename = name
384+
crate.syntax = "inline_table"
385+
crate.pkg = {
386+
text = text,
387+
col = Range.new(str_s - 1, str_e - 1),
388+
decl_col = Range.new(decl_s - 1, decl_e - 1),
389+
quote = { s = quote_s, e = quote_e ~= "" and quote_e or nil },
390+
}
391+
end
347392
end
348393

349394
if crate.name then
@@ -404,6 +449,22 @@ function M.parse_crates(buf)
404449
dep_section_crate = vim.tbl_extend("keep", dep_section_crate or {}, crate_vers)
405450
end
406451

452+
local crate_path = M.parse_crate_table_path(l)
453+
if crate_path then
454+
crate_path.name = dep_section.name
455+
crate_path.path.line = i - 1
456+
crate_path.section = dep_section
457+
dep_section_crate = vim.tbl_extend("keep", dep_section_crate or {}, crate_path)
458+
end
459+
460+
local crate_git = M.parse_crate_table_git(l)
461+
if crate_git then
462+
crate_git.name = dep_section.name
463+
crate_git.git.line = i - 1
464+
crate_git.section = dep_section
465+
dep_section_crate = vim.tbl_extend("keep", dep_section_crate or {}, crate_git)
466+
end
467+
407468
local crate_feat = M.parse_crate_table_feat(l)
408469
if crate_feat then
409470
crate_feat.name = dep_section.name
@@ -420,11 +481,12 @@ function M.parse_crates(buf)
420481
dep_section_crate = vim.tbl_extend("keep", dep_section_crate or {}, crate_def)
421482
end
422483

484+
423485
local crate_pkg = M.parse_crate_table_pkg(l)
424486
if crate_pkg then
425487
local crate = dep_section_crate or {}
488+
crate.rename = dep_section.name
426489
crate.name = crate_pkg.pkg.text
427-
crate.rename = crate.name
428490

429491
crate_pkg.pkg.line = i - 1
430492
crate_pkg.section = dep_section

0 commit comments

Comments
 (0)