1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
package lsp
import (
"github.com/grindlemire/go-tui/internal/tuigen"
)
type NodeKind int
const (
NodeKindUnknown NodeKind = iota
NodeKindComponent
NodeKindElement
NodeKindAttribute
NodeKindRefAttr
NodeKindGoExpr
NodeKindForLoop
NodeKindIfStmt
NodeKindLetBinding
NodeKindStateDecl
NodeKindStateAccess
NodeKindParameter
NodeKindFunction
NodeKindGoDecl
NodeKindComponentCall
NodeKindEventHandler
NodeKindText
NodeKindKeyword
NodeKindTailwindClass
NodeKindImportPath
)
func (k NodeKind) String() string {
switch k {
case NodeKindComponent:
return "Component"
case NodeKindElement:
return "Element"
case NodeKindAttribute:
return "Attribute"
case NodeKindRefAttr:
return "RefAttr"
case NodeKindGoExpr:
return "GoExpr"
case NodeKindForLoop:
return "ForLoop"
case NodeKindIfStmt:
return "IfStmt"
case NodeKindLetBinding:
return "LetBinding"
case NodeKindStateDecl:
return "StateDecl"
case NodeKindStateAccess:
return "StateAccess"
case NodeKindParameter:
return "Parameter"
case NodeKindFunction:
return "Function"
case NodeKindGoDecl:
return "GoDecl"
case NodeKindComponentCall:
return "ComponentCall"
case NodeKindEventHandler:
return "EventHandler"
case NodeKindText:
return "Text"
case NodeKindKeyword:
return "Keyword"
case NodeKindTailwindClass:
return "TailwindClass"
case NodeKindImportPath:
return "ImportPath"
default:
return "Unknown"
}
}
type Scope struct {
Component *tuigen.Component
Function *tuigen.GoFunc
ForLoop *tuigen.ForLoop
IfStmt *tuigen.IfStmt
Refs []tuigen.RefInfo
StateVars []tuigen.StateVar
LetBinds []*tuigen.LetBinding
Params []*tuigen.Param
}
type CursorContext struct {
Document *Document
Position Position
Offset int
Node tuigen.Node
NodeKind NodeKind
Scope *Scope
ParentChain []tuigen.Node
Word string
Line string
InGoExpr bool
InClassAttr bool
InElement bool
AttrTag string
AttrName string
ImportPath string
}
func ResolveCursorContext(doc *Document, pos Position) *CursorContext {
ctx := &CursorContext{
Document: doc,
Position: pos,
Offset: PositionToOffset(doc.Content, pos),
Scope: &Scope{},
}
ctx.Line = getLineText(doc.Content, pos.Line)
ctx.Word = getWordAtOffset(doc.Content, ctx.Offset)
ctx.InGoExpr = isOffsetInGoExpr(doc.Content, ctx.Offset)
ctx.InClassAttr = isOffsetInClassAttr(doc.Content, ctx.Offset)
ctx.InElement = isOffsetInElementTag(doc.Content, ctx.Offset)
if doc.AST == nil {
ctx.NodeKind = classifyFromText(ctx)
return ctx
}
resolveFromAST(ctx, doc.AST)
return ctx
}
|