1 -- SPDX-License-Identifier: GPL-3.0-or-later
2 -- © 2020 Georgi Kirilov
6 local function get_special(words
, list
)
7 local head
= list
[1] and list
[1].text
8 return head
and (words
[head
] or words
[0] and words
[0]:match(head
))
11 local function adjust_bracket_p(self
, indices
, nodes
, range
)
12 local parent
= nodes
[#nodes
- 1]
13 if not parent
then return true end
14 local nth
= indices
[#indices
]
16 local _
, nxt
= parent
.find_after(range
, function() return true end)
17 nth
= nxt
or #parent
+ 1
19 local sexp
= parent
[nth
] or parent
[#parent
]
20 local distance
= nth
- (sexp
and range
.start
== sexp
.finish
+ 1 and 0 or 1)
21 local rule
= get_special(self
.squarewords
, parent
)
22 if type(rule
) == "number" then
24 return -rule
> distance
26 -- XXX: the "[" check is because in Fennel fn has optional name
27 return rule
< distance
or sexp
.d
== "["
30 local grandparent
, pnth
= nodes
[#nodes
- 2], indices
[#indices
- 1]
31 if not grandparent
then return true end
32 rule
= get_special(self
.squarewords
, grandparent
)
33 if not rule
or type(rule
) ~= "table" then return true end
34 local _
, first_list_arg
= grandparent
.find_after(grandparent
[1], function(t
) return t
.is_list
end)
35 local first_nonlist_uncle
= first_list_arg
- 1
36 -- TODO: handle negative rule[1] and rule[2] (just for consistency with the scalar rules)
37 -- first_nonlist_uncle is checked so we can handle both let and named let:
38 if (not rule
[1] or first_nonlist_uncle
+ rule
[1] >= pnth
) then
39 if (not rule
[2] or rule
[2] >= distance
+ 1) then
40 if parent
[distance
] then
41 -- allows mixing [clauses] with #:when conditions in Racket for loops:
42 if parent
[distance
].is_list
then
54 local function last_distinguished(self
, list
)
55 return get_special(self
.lispwords
, list
)
58 function M
.new(lispwords
, squarewords
)
60 lispwords
= lispwords
,
61 squarewords
= squarewords
,
62 last_distinguished
= last_distinguished
,
63 adjust_bracket_p
= adjust_bracket_p
,