diff --git a/src/languageserverinstance.jl b/src/languageserverinstance.jl index 8294fc5a..240ec2f4 100644 --- a/src/languageserverinstance.jl +++ b/src/languageserverinstance.jl @@ -37,6 +37,7 @@ mutable struct LanguageServerInstance global_env::StaticLint.ExternalEnv roots_env_map::Dict{Document,StaticLint.ExternalEnv} symbol_store_ready::Bool + workspacepackages::Dict{String,Document} runlinter::Bool lint_options::StaticLint.LintOptions @@ -75,6 +76,7 @@ mutable struct LanguageServerInstance StaticLint.ExternalEnv(deepcopy(SymbolServer.stdlibs), SymbolServer.collect_extended_methods(SymbolServer.stdlibs), collect(keys(SymbolServer.stdlibs))), Dict(), false, + Dict{String,Document}(), true, StaticLint.LintOptions(), :all, @@ -123,9 +125,31 @@ end function setdocument!(server::LanguageServerInstance, uri::URI2, doc::Document) server._documents[uri] = doc + # Add possible workspace packages + path = uri2filepath(uri._uri) + for wk_folder in server.workspaceFolders + if startswith(path, wk_folder) && normpath(wk_folder) == normpath(server.env_path) + sub_path = splitpath(path) + first(sub_path) == "/" && popfirst!(sub_path) + length(sub_path) < 3 && continue + fname = splitext(last(sub_path))[1] + if sub_path[end-1] == "src" && sub_path[end-2] == fname + @info "Setting $path as source of 'live' package" + server.workspacepackages[fname] = doc + end + end + end + return doc end function deletedocument!(server::LanguageServerInstance, uri::URI2) + # clear reference to doc from workspacepackages + for (n,d) in server.workspacepackages + if d._uri == uri._uri + delete!(server.workspacepackages, n) + break + end + end doc = getdocument(server, uri) StaticLint.clear_meta(getcst(doc)) delete!(server._documents, uri) diff --git a/src/requests/completions.jl b/src/requests/completions.jl index e660fa2f..202db480 100644 --- a/src/requests/completions.jl +++ b/src/requests/completions.jl @@ -285,6 +285,7 @@ function is_rebinding_of_module(x) StaticLint.hasref(refof(x).val.args[2]) && refof(refof(x).val.args[2]).type === StaticLint.CoreTypes.Module && refof(refof(x).val.args[2]).val isa EXPR && CSTParser.defines_module(refof(refof(x).val.args[2]).val)# double check the rhs points to a module end +get_overlapped_binding(b::StaticLint.Binding) = b.val isa StaticLint.Binding ? get_overlapped_binding(b.val) : b function _get_dot_completion(px, spartial, state::CompletionState) end function _get_dot_completion(px::EXPR, spartial, state::CompletionState) @@ -303,8 +304,8 @@ function _get_dot_completion(px::EXPR, spartial, state::CompletionState) add_completion_item(state, CompletionItem(a, CompletionItemKinds.Method, get_typed_definition(a), MarkupContent(a), texteditfor(state, spartial, a))) end end - elseif refof(px).type isa StaticLint.Binding && refof(px).type.val isa SymbolServer.DataTypeStore - for a in refof(px).type.val.fieldnames + elseif binding.type isa StaticLint.Binding && binding.type.val isa SymbolServer.DataTypeStore + for a in binding.type.val.fieldnames a = String(a) if is_completion_match(a, spartial) add_completion_item(state, CompletionItem(a, CompletionItemKinds.Method, get_typed_definition(a), MarkupContent(a), texteditfor(state, spartial, a))) @@ -456,7 +457,14 @@ function import_completions(ppt, pt, t, is_at_end, x, state::CompletionState) end end else + for (n,doc1) in server.workspacepackages + if StaticLint.has_workspace_package(server, n) + push!(CIs, CompletionItem(n, 9, MarkupContent("Workspace package: $n"), TextEdit(rng, n))) + end + end + for (n, m) in StaticLint.getsymbols(getenv(state)) + n = String(n) (startswith(n, ".") || startswith(n, "#")) && continue add_completion_item(state, CompletionItem(n, CompletionItemKinds.Module, get_typed_definition(m), MarkupContent(sanitize_docstring(m.doc)), TextEdit(state.range, n))) @@ -488,6 +496,12 @@ function import_completions(ppt, pt, t, is_at_end, x, state::CompletionState) end end else + for (n,doc1) in server.workspacepackages + if startswith(n, t.val) && StaticLint.has_workspace_package(server, n) + push!(CIs, CompletionItem(n, 9, MarkupContent("Workspace package: $n"), TextEdit(rng, n[nextind(n,sizeof(t.val)):end]))) # AUDIT: nextind(n,sizeof(n)) equiv to nextind(n, lastindex(n)) + end + end + for (n, m) in StaticLint.getsymbols(getenv(state)) n = String(n) if is_completion_match(n, t.val)