@@ -2,6 +2,7 @@ package langsrv
2
2
3
3
import (
4
4
"fmt"
5
+ "strings"
5
6
6
7
"github.com/tliron/glsp"
7
8
protocol "github.com/tliron/glsp/protocol_3_16"
@@ -14,63 +15,123 @@ func textDocumentCompletion(context *glsp.Context, params *protocol.CompletionPa
14
15
if sourceFile == nil {
15
16
return nil , nil
16
17
}
17
-
18
- completionItems := []protocol.CompletionItem {}
19
- for _ , decl := range sourceFile .Declarations {
20
- var docs string
21
- if documented , ok := decl .(ast.Documented ); ok {
22
- docs = documented .ProvidedDocs ().Content + "\n \n "
18
+ globalDeclarations := sourceFile .Declarations
19
+ for _ , sameModuleFile := range rc .textDocumentEntry .module .Files {
20
+ fileUrl := "file://" + sameModuleFile
21
+ if rc .item .URI == fileUrl {
22
+ continue
23
23
}
24
- var overview string
25
- if overviewable , ok := decl .(ast. Overviewable ); ok {
26
- overview = "```lithia \n " + overviewable . DeclOverview () + " \n ``` \n \n "
24
+ docEntry := langserver . documentCache . documents [ fileUrl ]
25
+ if docEntry == nil || docEntry . sourceFile == nil {
26
+ continue
27
27
}
28
+
29
+ globalDeclarations = append (globalDeclarations , docEntry .sourceFile .ExportedDeclarations ()... )
30
+ }
31
+
32
+ completionItems := []protocol.CompletionItem {}
33
+ for _ , decl := range globalDeclarations {
34
+ insertText := insertTextForDecl (decl )
28
35
var detail string
29
36
if decl .Meta ().ModuleName != "" {
30
37
detail = string (decl .Meta ().ModuleName ) +
31
38
"." +
32
39
string (decl .DeclName ())
33
40
}
34
- var kind protocol.CompletionItemKind
35
- switch decl .(type ) {
36
- case ast.DeclEnum :
37
- kind = protocol .CompletionItemKindEnum
38
- case ast.DeclEnumCase :
39
- kind = protocol .CompletionItemKindEnumMember
40
- case ast.DeclConstant :
41
- kind = protocol .CompletionItemKindConstant
42
- case ast.DeclData :
43
- kind = protocol .CompletionItemKindStruct
44
- case ast.DeclExternFunc :
45
- kind = protocol .CompletionItemKindFunction
46
- case ast.DeclExternType :
47
- kind = protocol .CompletionItemKindClass
48
- case ast.DeclField :
49
- kind = protocol .CompletionItemKindField
50
- case ast.DeclFunc :
51
- kind = protocol .CompletionItemKindFunction
52
- case ast.DeclImport :
53
- kind = protocol .CompletionItemKindModule
54
- case ast.DeclImportMember :
55
- kind = protocol .CompletionItemKindValue
56
- case ast.DeclModule :
57
- kind = protocol .CompletionItemKindModule
58
- case ast.DeclParameter :
59
- kind = protocol .CompletionItemKindVariable
60
- default :
61
- kind = protocol .CompletionItemKindText
62
- }
63
- insertText := string (decl .DeclName ())
64
41
completionItems = append (completionItems , protocol.CompletionItem {
65
- Label : string (decl .DeclName ()),
66
- Kind : & kind ,
67
- InsertText : & insertText ,
68
- Detail : & detail ,
69
- Documentation : & protocol.MarkupContent {
70
- Kind : protocol .MarkupKindMarkdown ,
71
- Value : overview + fmt .Sprintf ("_module %s_\n \n " , decl .Meta ().ModuleName ) + docs ,
72
- },
42
+ Label : string (decl .DeclName ()),
43
+ Kind : completionItemKindForDecl (decl ),
44
+ InsertText : & insertText ,
45
+ Detail : & detail ,
46
+ Documentation : documentationMarkupContentForDecl (decl ),
73
47
})
74
48
}
75
49
return & completionItems , nil
76
50
}
51
+
52
+ func insertTextForDecl (decl ast.Decl ) string {
53
+ switch decl := decl .(type ) {
54
+ case ast.DeclFunc :
55
+ return insertTextForCallableDeclParams (decl , decl .Impl .Parameters )
56
+ case ast.DeclExternFunc :
57
+ return insertTextForCallableDeclParams (decl , decl .Parameters )
58
+ case ast.DeclData :
59
+ return insertTextForCallableDeclFields (decl , decl .Fields )
60
+ default :
61
+ return string (decl .DeclName ())
62
+ }
63
+ }
64
+
65
+ func insertTextForCallableDeclParams (decl ast.Decl , parameters []ast.DeclParameter ) string {
66
+ paramNames := make ([]string , len (parameters ))
67
+ for i , param := range parameters {
68
+ paramNames [i ] = string (param .DeclName ())
69
+ }
70
+ return insertTextForCallableDecl (decl , paramNames )
71
+ }
72
+
73
+ func insertTextForCallableDeclFields (decl ast.Decl , fields []ast.DeclField ) string {
74
+ fieldNames := make ([]string , len (fields ))
75
+ for i , param := range fields {
76
+ fieldNames [i ] = string (param .DeclName ())
77
+ }
78
+ return insertTextForCallableDecl (decl , fieldNames )
79
+ }
80
+
81
+ func insertTextForCallableDecl (decl ast.Decl , parameters []string ) string {
82
+ if len (parameters ) == 0 {
83
+ return string (decl .DeclName ())
84
+ }
85
+ if len (parameters ) == 1 {
86
+ return fmt .Sprintf ("%s %s" , decl .DeclName (), parameters [0 ])
87
+ }
88
+ return fmt .Sprintf ("(%s %s)" , decl .DeclName (), strings .Join (parameters , ", " ))
89
+ }
90
+
91
+ func documentationMarkupContentForDecl (decl ast.Decl ) * protocol.MarkupContent {
92
+ var docs string
93
+ if documented , ok := decl .(ast.Documented ); ok {
94
+ docs = documented .ProvidedDocs ().Content + "\n \n "
95
+ }
96
+ var overview string
97
+ if overviewable , ok := decl .(ast.Overviewable ); ok {
98
+ overview = "```lithia\n " + overviewable .DeclOverview () + "\n ```\n \n "
99
+ }
100
+ return & protocol.MarkupContent {
101
+ Kind : protocol .MarkupKindMarkdown ,
102
+ Value : overview + fmt .Sprintf ("_module %s_\n \n " , decl .Meta ().ModuleName ) + docs ,
103
+ }
104
+ }
105
+
106
+ func completionItemKindForDecl (decl ast.Decl ) * protocol.CompletionItemKind {
107
+ var kind protocol.CompletionItemKind
108
+ switch decl .(type ) {
109
+ case ast.DeclEnum :
110
+ kind = protocol .CompletionItemKindEnum
111
+ case ast.DeclEnumCase :
112
+ kind = protocol .CompletionItemKindEnumMember
113
+ case ast.DeclConstant :
114
+ kind = protocol .CompletionItemKindConstant
115
+ case ast.DeclData :
116
+ kind = protocol .CompletionItemKindStruct
117
+ case ast.DeclExternFunc :
118
+ kind = protocol .CompletionItemKindFunction
119
+ case ast.DeclExternType :
120
+ kind = protocol .CompletionItemKindClass
121
+ case ast.DeclField :
122
+ kind = protocol .CompletionItemKindField
123
+ case ast.DeclFunc :
124
+ kind = protocol .CompletionItemKindFunction
125
+ case ast.DeclImport :
126
+ kind = protocol .CompletionItemKindModule
127
+ case ast.DeclImportMember :
128
+ kind = protocol .CompletionItemKindValue
129
+ case ast.DeclModule :
130
+ kind = protocol .CompletionItemKindModule
131
+ case ast.DeclParameter :
132
+ kind = protocol .CompletionItemKindVariable
133
+ default :
134
+ kind = protocol .CompletionItemKindText
135
+ }
136
+ return & kind
137
+ }
0 commit comments