diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2020-11-07 18:25:28 +0100 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2020-11-07 18:25:28 +0100 |
| commit | 5f5e855af2473bf5ff12ecac296dad37b5d923ac (patch) | |
| tree | ff99477b52673ce33d69ba2f3b21c9990db511a0 /src/server | |
| parent | 6ec424ed8d34cf8a5f51e277a20429741b33ee96 (diff) | |
started on fuzzy searching on the naive indexer.
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/analysis.odin | 79 | ||||
| -rw-r--r-- | src/server/requests.odin | 49 | ||||
| -rw-r--r-- | src/server/types.odin | 54 |
3 files changed, 167 insertions, 15 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin index e88532f..8027e6d 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -13,13 +13,17 @@ import "shared:index" -DocumentPositionContextDottedValue :: struct { +DocumentPositionContextVariableDotVariableValue :: struct { prefix: string, postfix: string, }; DocumentPositionContextGlobalValue :: struct { + name: string, +}; +DocumentPositionContextVariableDotValue :: struct { + prefix: string, }; DocumentPositionContextUnknownValue :: struct { @@ -27,9 +31,10 @@ DocumentPositionContextUnknownValue :: struct { } DocumentPositionContextValue :: union { - DocumentPositionContextDottedValue, + DocumentPositionContextVariableDotValue, DocumentPositionContextGlobalValue, - DocumentPositionContextUnknownValue + DocumentPositionContextUnknownValue, + DocumentPositionContextVariableDotVariableValue, }; DocumentPositionContext :: struct { @@ -69,6 +74,8 @@ get_document_position_context :: proc(document: ^Document, position: common.Posi struct_or_package_dotted: bool; struct_or_package: tokenizer.Token; + last_label: bool; + /* Idea is to push and pop into braces, brackets, etc, and use the final stack to infer context */ @@ -84,11 +91,13 @@ get_document_position_context :: proc(document: ^Document, position: common.Posi struct_or_package = last_token; } case .Ident: + last_label = true; case .EOF: + last_label = false; break; case: struct_or_package_dotted = false; - + last_label = false; } if current_token.pos.offset+len(current_token.text) >= absolute_position { @@ -101,21 +110,35 @@ get_document_position_context :: proc(document: ^Document, position: common.Posi #partial switch current_token.kind { case .Ident: if struct_or_package_dotted { - position_context.value = DocumentPositionContextDottedValue { + position_context.value = DocumentPositionContextVariableDotVariableValue { prefix = struct_or_package.text, postfix = current_token.text, }; } else { + position_context.value = DocumentPositionContextGlobalValue { + name = current_token.text, + }; + } + case .Period: + if last_label { + position_context.value = DocumentPositionContextVariableDotValue { + prefix = last_token.text, + }; + } + else { + position_context.value = DocumentPositionContextUnknownValue { + }; } + case: position_context.value = DocumentPositionContextUnknownValue { }; } - //fmt.println(position_context); + log.info(position_context); return position_context, true; } @@ -123,11 +146,8 @@ get_document_position_context :: proc(document: ^Document, position: common.Posi get_definition_location :: proc(document: ^Document, position: common.Position) -> (common.Location, bool) { - location: common.Location; - - position_context, ok := get_document_position_context(document, position); if !ok { @@ -137,14 +157,14 @@ get_definition_location :: proc(document: ^Document, position: common.Position) symbol: index.Symbol; #partial switch v in position_context.value { - case DocumentPositionContextDottedValue: + case DocumentPositionContextVariableDotVariableValue: symbol, ok = index.lookup(strings.concatenate({v.prefix, v.postfix}, context.temp_allocator)); + case DocumentPositionContextGlobalValue: + symbol, ok = index.lookup(strings.concatenate({document.ast.pkg_name, v.name}, context.temp_allocator)); case: return location, false; } - //fmt.println(indexer.symbol_table); - if !ok { return location, false; } @@ -156,3 +176,38 @@ get_definition_location :: proc(document: ^Document, position: common.Position) return location, true; } +get_completion_list :: proc(document: ^Document, position: common.Position) -> (CompletionList, bool) { + + list: CompletionList; + + + position_context, ok := get_document_position_context(document, position); + symbols: [] index.Symbol; + empty_dot := false; + + + #partial switch v in position_context.value { + case DocumentPositionContextVariableDotVariableValue: + symbols, ok = index.fuzzy_search(v.postfix, {v.prefix}); + case DocumentPositionContextVariableDotValue: + empty_dot = true; + } + + if empty_dot { + list.isIncomplete = true; + return list, true; + } + + if !ok { + return list, false; + } + + list.items = make([] CompletionItem, len(symbols), context.temp_allocator); + + for symbol, i in symbols { + list.items[i].label = symbol.name; + list.items[i].kind = .Function; + } + + return list, true; +}
\ No newline at end of file diff --git a/src/server/requests.odin b/src/server/requests.odin index cd8e734..587e444 100644 --- a/src/server/requests.odin +++ b/src/server/requests.odin @@ -167,7 +167,8 @@ handle_request :: proc(request: json.Value, config: ^common.Config, writer: ^Wri "textDocument/didChange" = notification_did_change, "textDocument/didClose" = notification_did_close, "textDocument/didSave" = notification_did_save, - "textDocument/definition" = request_definition }; + "textDocument/definition" = request_definition, + "textDocument/completion" = request_completion}; fn: proc(json.Value, RequestId, ^common.Config, ^Writer) -> common.Error; fn, ok = call_map[method]; @@ -225,11 +226,17 @@ request_initialize :: proc(params: json.Value, id: RequestId, config: ^common.Co } } + triggerCharacters := [] string { "." }; + response := make_response_message( params = ResponseInitializeParams { capabilities = ServerCapabilities { textDocumentSync = 2, //incremental definitionProvider = true, + completionProvider = CompletionOptions { + resolveProvider = false, + triggerCharacters = triggerCharacters, + }, }, }, id = id, @@ -295,6 +302,46 @@ request_definition :: proc(params: json.Value, id: RequestId, config: ^common.Co return .None; } + +request_completion :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error { + + params_object, ok := params.value.(json.Object); + + if !ok { + return .ParseError; + } + + completition_params: CompletionParams; + + if unmarshal(params, completition_params, context.temp_allocator) != .None { + return .ParseError; + } + + + document := document_get(completition_params.textDocument.uri); + + if document == nil { + return .InternalError; + } + + list: CompletionList; + list, ok = get_completion_list(document, completition_params.position); + + if !ok { + return .InternalError; + } + + response := make_response_message( + params = list, + id = id, + ); + + send_response(response, writer); + + return .None; +} + + notification_exit :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error { config.running = false; return .None; diff --git a/src/server/types.odin b/src/server/types.odin index 262f464..61f2cba 100644 --- a/src/server/types.odin +++ b/src/server/types.odin @@ -19,6 +19,7 @@ ResponseParams :: union { ResponseInitializeParams, rawptr, common.Location, + CompletionList, }; ResponseMessage :: struct { @@ -78,10 +79,12 @@ MarkupKind :: enum { ServerCapabilities :: struct { textDocumentSync: int, definitionProvider: bool, + completionProvider: CompletionOptions, }; -CompletionClientCapabilities :: struct { - +CompletionOptions :: struct { + resolveProvider: bool, + triggerCharacters: [] string, }; HoverClientCapabilities :: struct { @@ -94,6 +97,10 @@ TextDocumentClientCapabilities :: struct { hover: HoverClientCapabilities, }; +CompletionClientCapabilities :: struct { + +}; + ClientCapabilities :: struct { textDocument: TextDocumentClientCapabilities, }; @@ -151,4 +158,47 @@ DidCloseTextDocumentParams :: struct { TextDocumentPositionParams :: struct { textDocument: TextDocumentIdentifier, position: common.Position, +}; + +CompletionParams :: struct { + textDocument: TextDocumentIdentifier, + position: common.Position, +}; + +CompletionItemKind :: enum { + Text = 1, + Method = 2, + Function = 3, + Constructor = 4, + Field = 5, + Variable = 6, + Class = 7, + Interface = 8, + Module = 9, + Property = 10, + Unit = 11, + Value = 12, + Enum = 13, + Keyword = 14, + Snippet = 15, + Color = 16, + File = 17, + Reference = 18, + Folder = 19, + EnumMember = 20, + Constant = 21, + Struct = 22, + Event = 23, + Operator = 24, + TypeParameter = 25, +}; + +CompletionItem :: struct { + label: string, + kind: CompletionItemKind, +}; + +CompletionList :: struct { + isIncomplete: bool, + items: [] CompletionItem, };
\ No newline at end of file |