aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/action.odin87
-rw-r--r--src/server/requests.odin4
2 files changed, 84 insertions, 7 deletions
diff --git a/src/server/action.odin b/src/server/action.odin
index d1608b5..86ce19a 100644
--- a/src/server/action.odin
+++ b/src/server/action.odin
@@ -26,6 +26,11 @@ CodeActionOptions :: struct {
CodeActionParams :: struct {
textDocument: TextDocumentIdentifier,
range: common.Range,
+ context_: CodeActionContext,
+}
+
+CodeActionContext :: struct {
+ only: []CodeActionKind,
}
CodeAction :: struct {
@@ -35,7 +40,15 @@ CodeAction :: struct {
edit: WorkspaceEdit,
}
-get_code_actions :: proc(document: ^Document, range: common.Range, config: ^common.Config) -> ([]CodeAction, bool) {
+get_code_actions :: proc(
+ document: ^Document,
+ ctx: CodeActionContext,
+ range: common.Range,
+ config: ^common.Config,
+) -> (
+ []CodeAction,
+ bool,
+) {
ast_context := make_ast_context(
document.ast,
document.imports,
@@ -45,7 +58,18 @@ get_code_actions :: proc(document: ^Document, range: common.Range, config: ^comm
context.temp_allocator,
)
+ actions := make([dynamic]CodeAction, 0, context.allocator)
+
+ for action in ctx.only {
+ //For some reason on vscode it returns "source", so check for both kinds
+ if action == "source" || action == "source.organizeImports" {
+ source_organize_imports(document, strings.clone(document.uri.uri, context.temp_allocator), config, &actions)
+ return actions[:], true
+ }
+ }
+
position_context, ok := get_document_position_context(document, range.start, .Hover)
+
if !ok {
log.warn("Failed to get position context")
return {}, false
@@ -61,19 +85,72 @@ get_code_actions :: proc(document: ^Document, range: common.Range, config: ^comm
get_locals(document.ast, position_context.function, &ast_context, &position_context)
}
- actions := make([dynamic]CodeAction, 0, context.allocator)
-
if position_context.selector_expr != nil {
if selector, ok := position_context.selector_expr.derived.(^ast.Selector_Expr); ok {
- add_missing_imports(&ast_context, selector, strings.clone(document.uri.uri), config, &actions)
+ add_missing_imports(
+ &ast_context,
+ selector,
+ strings.clone(document.uri.uri, context.temp_allocator),
+ config,
+ &actions,
+ )
}
} else if position_context.import_stmt != nil {
- remove_unused_imports(document, strings.clone(document.uri.uri), config, &actions)
+ remove_unused_imports(document, strings.clone(document.uri.uri, context.temp_allocator), config, &actions)
}
return actions[:], true
}
+source_organize_imports :: proc(
+ document: ^Document,
+ uri: string,
+ config: ^common.Config,
+ actions: ^[dynamic]CodeAction,
+) {
+ unused_imports := find_unused_imports(document, context.temp_allocator)
+
+ if len(unused_imports) == 0 {
+ return
+ }
+
+ textEdits := make([dynamic]TextEdit, context.temp_allocator)
+
+ for imp in unused_imports {
+ range := common.get_token_range(imp.import_decl, document.ast.src)
+
+ import_edit := TextEdit {
+ range = range,
+ newText = "",
+ }
+
+ if (range.start.line != 1) {
+ if column, ok := common.get_last_column(import_edit.range.start.line - 1, document.text); ok {
+ import_edit.range.start.line -= 1
+ import_edit.range.start.character = column
+ }
+
+ }
+
+ append(&textEdits, import_edit)
+ }
+
+ workspaceEdit: WorkspaceEdit
+ workspaceEdit.changes = make(map[string][]TextEdit, 0, context.temp_allocator)
+ workspaceEdit.changes[uri] = textEdits[:]
+
+ append(
+ actions,
+ CodeAction {
+ kind = "source.organizeImports",
+ isPreferred = true,
+ title = fmt.tprint("organize imports"),
+ edit = workspaceEdit,
+ },
+ )
+}
+
+
remove_unused_imports :: proc(
document: ^Document,
uri: string,
diff --git a/src/server/requests.odin b/src/server/requests.odin
index 8f9be06..6a7c9ca 100644
--- a/src/server/requests.odin
+++ b/src/server/requests.odin
@@ -761,7 +761,7 @@ request_initialize :: proc(
hoverProvider = config.enable_hover,
documentFormattingProvider = config.enable_format,
documentLinkProvider = {resolveProvider = false},
- codeActionProvider = {resolveProvider = false, codeActionKinds = {"refactor.rewrite"}},
+ codeActionProvider = {resolveProvider = false, codeActionKinds = {"refactor.rewrite", "source.organizeImports"}},
},
},
id = id,
@@ -1586,7 +1586,7 @@ request_code_action :: proc(
}
code_actions: []CodeAction
- code_actions, ok = get_code_actions(document, code_action_params.range, config)
+ code_actions, ok = get_code_actions(document, code_action_params.context_, code_action_params.range, config)
if !ok {
return .InternalError
}