From 9461c96bb3691bfcc31e4b7d2fbb08b13d33b59b Mon Sep 17 00:00:00 2001 From: mstreeter10 Date: Wed, 24 Jan 2024 21:40:39 -0500 Subject: [PATCH] ulsp: Add dot and dual colon completion support Signed-off-by: mstreeter10 --- uni/ulsp/completion.icn | 12 ++++++--- uni/ulsp/server.icn | 23 +++++++++++----- uni/ulsp/workspace.icn | 60 ++++++++++++++++++++++++++++++++++++----- 3 files changed, 80 insertions(+), 15 deletions(-) diff --git a/uni/ulsp/completion.icn b/uni/ulsp/completion.icn index 366b627e4..0e53d4d88 100644 --- a/uni/ulsp/completion.icn +++ b/uni/ulsp/completion.icn @@ -29,10 +29,16 @@ class CompletionHandler( case _context of { "comment" : { results_table["items"] := [] - } + } + "string" : { + results_table["items"] := [] + } "object" : { workspace.buildObjectCompletionItems(results_table, context.objectName) - } + } + "packdualcolon" : { + workspace.buildPackageConstructorItems(results_table, context.packageName) + } "package" : { addPackageCompletionItems(results_table) } @@ -41,8 +47,8 @@ class CompletionHandler( } default : { buildDefaultCompletionItems(results_table, workspace) - } } + } results := tojson(results_table) return results diff --git a/uni/ulsp/server.icn b/uni/ulsp/server.icn index 36186c68b..afb4910b1 100644 --- a/uni/ulsp/server.icn +++ b/uni/ulsp/server.icn @@ -124,12 +124,23 @@ class Server( # Follow the LSP specifications on how to add a particular capability to your initialize string. method initialize(request_id) - local results, res - results := "{\"capabilities\":{\"completionProvider\":{\"resolveProvider\":true},\"textDocumentSync\":1,\"signatureHelpProvider\":{\"contextSupport\":true,\"triggerCharacters\":\"(\"},\"hoverProvider\":true}}" - - res := build_response(request_id, results) - write(res) - writes(sock, res) + local capabilitiesTable, result + + capabilitiesTable := ["capabilities": [ + "completionProvider": [ + "triggerCharacters": [".", ":"] + ]; + "textDocumentSync": 1; + "signatureHelpProvider": [ + "contextSupport": "__true__"; + "triggerCharacters": ["("] + ]; + "hoverProvider": "__true__" + ]] + + result := build_response(request_id, tojson(capabilitiesTable)) + write(result) + writes(sock, result) end ######################################################## diff --git a/uni/ulsp/workspace.icn b/uni/ulsp/workspace.icn index 9b8c0f820..3f3ac9600 100644 --- a/uni/ulsp/workspace.icn +++ b/uni/ulsp/workspace.icn @@ -518,6 +518,17 @@ class Workspace( } end + method buildPackageConstructorItems(results_table, packageName) + if member(lsp_database.package_db, packageName) then { + every _file := key(lsp_database.package_db[packageName]["files"]) do { + every _class := key(lsp_database.package_db[packageName]["files"][_file]["classes"]) do { + _constructor := lsp_database.package_db[packageName]["files"][_file]["classes"][_class]["constructor"] + put(results_table["items"], table("label", _constructor["name"], "kind", 4)) + } + } + } + end + method getPackages() return lsp_database.package_db end @@ -549,7 +560,7 @@ class Workspace( end -class Context(uniAll, uri, line, lineNum, charNum, objectName, methodName, contextCase) +class Context(uniAll, uri, line, lineNum, charNum, objectName, methodName, contextCase, packageName) method getDesiredLine(lineNum) line := uniAll.getUniFileLine(uri, lineNum) end @@ -598,7 +609,7 @@ class Context(uniAll, uri, line, lineNum, charNum, objectName, methodName, conte end method findContext() - local objectName, single_quote, double_quote, ch + local objectName, single_quote, double_quote, ch, backslash_count, temppos, c #-----------------------------------------------# #----------- Case "start of file" --------------# @@ -627,17 +638,54 @@ class Context(uniAll, uri, line, lineNum, charNum, objectName, methodName, conte } #-----------------------------------------------# - #----------- Case "inside comment" -------------# + #------- Case "inside comment or string" -------# #-----------------------------------------------# line ? { single_quote := 0 double_quote := 0 + backslash_count := 0 while (&pos < charNum) do { ch := move(1) | break - if ch == "\'" then single_quote +:= 1 - if ch == "\"" then double_quote +:= 1 - if (ch == "#") & ((single_quote % 2) = 0 & (double_quote % 2) = 0) then return "comment" + if ch == "\'" then { + temppos := &pos + move(-1) + while move(-1) == "\\" do backslash_count +:= 1 + if (backslash_count % 2) = 0 then single_quote +:= 1 + backslash_count := 0 + &pos := temppos + } + if ch == "\"" then { + temppos := &pos + move(-1) + while move(-1) == "\\" do backslash_count +:= 1 + if (backslash_count % 2) = 0 then double_quote +:= 1 + backslash_count := 0 + &pos := temppos + } + if (ch == "#") & ((single_quote % 2) = 0) & ((double_quote % 2) = 0) then return "comment" + } + if ((single_quote % 2) ~= 0 | (double_quote % 2) ~= 0) then return "string" + } + + #-----------------------------------------------# + #--------- Case "package dual colon" -----------# + #-----------------------------------------------# + + line ? { + tab(charNum) + move(-2) + if move() == ":" & move() == ":" then { + move(-2) + temppos := &pos + while c := move(-1) do { + if (c ** identifiers) ~== c then { + break + } + } + if &pos ~= 1 then move(1) + packageName := tab(temppos) + return "packdualcolon" } }