@@ -64,6 +64,7 @@ local function get_range(code, start, stop)
6464end
6565
6666local editor_helper = EditorHelper .New ()
67+ lsp .editor_helper = editor_helper
6768editor_helper .debug = false
6869
6970local function to_fs_path (url )
@@ -128,10 +129,15 @@ function editor_helper:OnDiagnostics(path, data)
128129
129130 for i , v in ipairs (data ) do
130131 local range = get_range (v .code , v .start , v .stop )
132+ local tags
133+
134+ if v .message :find (" is never used" ) then tags = {1 } end
135+
131136 diagnostics [i ] = {
132137 severity = DiagnosticSeverity [v .severity ],
133138 range = range ,
134139 message = v .message .. " \n " .. (v .trace or " no trace??" ),
140+ tags = tags ,
135141 }
136142 end
137143
@@ -147,7 +153,12 @@ function editor_helper:OnDiagnostics(path, data)
147153end
148154
149155lsp .methods [" initialize" ] = function (params )
150- editor_helper :SetWorkingDirectory (to_fs_path (params .workspaceFolders [1 ].uri ))
156+ if params .workspaceFolders and params .workspaceFolders [1 ] then
157+ editor_helper :SetWorkingDirectory (to_fs_path (params .workspaceFolders [1 ].uri ))
158+ elseif params .rootUri then
159+ editor_helper :SetWorkingDirectory (to_fs_path (params .rootUri ))
160+ end
161+
151162 return {
152163 clientInfo = {name = " NattLua" , version = " 1.0" },
153164 capabilities = {
@@ -182,30 +193,68 @@ lsp.methods["initialize"] = function(params)
182193 resolveProvider = true,
183194 },]]
184195 documentSymbolProvider = true ,
185- -- for symbols like all functions within a file
186- -- highlighting equal upvalues
187- -- documentHighlightProvider = true,
188- --[[
196+ documentHighlightProvider = true ,
189197 signatureHelpProvider = {
190- triggerCharacters = { "(" },
198+ triggerCharacters = {" (" , " , " },
191199 },
192-
193- workspaceSymbolProvider = true,
194- codeActionProvider = true,
195- documentFormattingProvider = true,
196- documentRangeFormattingProvider = true,
197- documentOnTypeFormattingProvider = {
198- firstTriggerCharacter = "}",
199- moreTriggerCharacter = { "end" },
200+ codeActionProvider = {
201+ codeActionKinds = {" quickfix" , " source.fixAll.unusedImports" },
200202 },
201- renameProvider = true,
202- ]]
203+ documentFormattingProvider = true ,
203204 },
204205 }
205206end
206207lsp .methods [" initialized" ] = function (params )
207208 editor_helper :Initialize ()
208209end
210+ lsp .methods [" textDocument/codeAction" ] = function (params )
211+ local actions = {}
212+ local has_unused = false
213+
214+ for _ , diagnostic in ipairs (params .context .diagnostics ) do
215+ if diagnostic .tags then
216+ for _ , tag in ipairs (diagnostic .tags ) do
217+ if tag == 1 then
218+ has_unused = true
219+
220+ break
221+ end
222+ end
223+ end
224+ end
225+
226+ if has_unused then
227+ local path = to_fs_path (params .textDocument .uri )
228+ local code = editor_helper :GetFileContent (path )
229+ local new_code = editor_helper :Format (code , path , {remove_unused = true })
230+
231+ if new_code ~= code then
232+ table.insert (
233+ actions ,
234+ {
235+ title = " Remove all unused code" ,
236+ kind = " source.fixAll.unusedImports" ,
237+ edit = {
238+ changes = {
239+ [params .textDocument .uri ] = {
240+ {
241+ range = {
242+ start = {line = 0 , character = 0 },
243+ [" end" ] = {line = 100000 , character = 0 },
244+ },
245+ newText = new_code ,
246+ },
247+ },
248+ },
249+ },
250+ }
251+ )
252+ end
253+ end
254+
255+ return actions
256+ end
257+
209258lsp .methods [" nattlua/format" ] = function (params )
210259 local path = to_fs_path (params .textDocument .uri )
211260 local code = editor_helper :Format (params .code , path )
@@ -216,6 +265,25 @@ lsp.methods["nattlua/format"] = function(params)
216265 code = b64 .encode (code ),
217266 }
218267end
268+ lsp .methods [" textDocument/formatting" ] = function (params )
269+ local path = to_fs_path (params .textDocument .uri )
270+ local code = editor_helper :GetFileContent (path )
271+ local new_code = editor_helper :Format (code , path )
272+
273+ if new_code ~= code then
274+ return {
275+ {
276+ range = {
277+ start = {line = 0 , character = 0 },
278+ [" end" ] = {line = 100000 , character = 0 },
279+ },
280+ newText = new_code ,
281+ },
282+ }
283+ end
284+
285+ return {}
286+ end
219287lsp .methods [" shutdown" ] = function (params )
220288 table .print (params )
221289end
@@ -234,8 +302,9 @@ lsp.methods["$/cancelRequest"] = function(params)
234302 table .print (params )
235303end
236304lsp .methods [" workspace/didChangeConfiguration" ] = function (params )
237- print (" configuration changed" )
238- table .print (params )
305+ if params .settings and params .settings .nattlua then
306+ editor_helper .workspace_config = params .settings .nattlua
307+ end
239308end
240309lsp .methods [" textDocument/didOpen" ] = function (params )
241310 local path = to_fs_path (params .textDocument .uri )
@@ -255,21 +324,32 @@ lsp.methods["textDocument/references"] = function(params)
255324
256325 if not editor_helper :IsLoaded (path ) then return {} end
257326
258- local data = editor_helper :GetFile (path )
259- local nodes = editor_helper :GetReferences (path , params .position .line , params .position .character - 1 )
327+ local items = editor_helper :GetReferences (path , params .position .line , params .position .character )
260328
261- if not nodes then return {} end
329+ if not items then return {} end
262330
263331 local result = {}
264332
265- for k , node in pairs (nodes ) do
266- local path = node :GetSourcePath () or to_fs_path (path )
267- editor_helper :OpenFile (path , node .Code :GetString ())
333+ for k , item in pairs (items ) do
334+ local start , stop
335+ local source_path
336+
337+ if item .GetStartStop then
338+ start , stop = item :GetStartStop ()
339+ source_path = item :GetSourcePath ()
340+ else
341+ start , stop = item .start , item .stop
342+ source_path = item .lexer .Code :GetName ()
343+ end
344+
345+ source_path = source_path or path
346+ local fs_path = to_fs_path (source_path )
347+ local lsp_path = to_lsp_path (source_path )
268348 table.insert (
269349 result ,
270350 {
271- uri = to_fs_path ( path ) ,
272- range = get_range (editor_helper :GetCode (path ), node : GetStartStop () ),
351+ uri = lsp_path ,
352+ range = get_range (editor_helper :GetCode (fs_path ), start , stop ),
273353 }
274354 )
275355 end
@@ -483,6 +563,44 @@ if false then
483563 end
484564end
485565
566+ lsp .methods [" textDocument/documentHighlight" ] = function (params )
567+ local path = to_fs_path (params .textDocument .uri )
568+
569+ if not editor_helper :IsLoaded (path ) then return {} end
570+
571+ local highlights = editor_helper :GetUpvalueHighlightRanges (path , params .position .line , params .position .character )
572+
573+ if not highlights then return {} end
574+
575+ local result = {}
576+
577+ for i , range_data in ipairs (highlights ) do
578+ local range = {
579+ start = {
580+ line = range_data .line_start - 1 ,
581+ character = range_data .character_start - 1 ,
582+ },
583+ [" end" ] = {
584+ line = range_data .line_stop - 1 ,
585+ character = range_data .character_stop ,
586+ },
587+ }
588+ table.insert (result , {
589+ range = range ,
590+ kind = 1 , -- Text
591+ })
592+ end
593+
594+ return result
595+ end
596+ lsp .methods [" textDocument/signatureHelp" ] = function (params )
597+ local path = to_fs_path (params .textDocument .uri )
598+
599+ if not editor_helper :IsLoaded (path ) then return {} end
600+
601+ local result = editor_helper :GetSignatureHelp (path , params .position .line , params .position .character )
602+ return result or {signatures = {}, activeSignature = 0 , activeParameter = 0 }
603+ end
486604lsp .methods [" textDocument/rename" ] = function (params )
487605 local fs_path = to_fs_path (params .textDocument .uri )
488606
@@ -517,7 +635,7 @@ lsp.methods["textDocument/definition"] = function(params)
517635
518636 local node = editor_helper :GetDefinition (path , params .position .line , params .position .character )
519637
520- if node then
638+ if node and node . GetStartStop then
521639 local start , stop = node :GetStartStop ()
522640 local path = node :GetSourcePath () or path
523641 path = to_fs_path (path )
0 commit comments