summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2023-01-03 17:29:19 -0500
committerpommicket <pommicket@gmail.com>2023-01-03 17:29:19 -0500
commit87c8bd6eb27edb4bfc539967235c3a1e2f8d77e4 (patch)
tree4dbcb24ce4fca226e5b70bc5f01d71158d891426
parent0d92c03f3998fe4d16f3ba928d3a94583755e1ce (diff)
go to declaration
-rw-r--r--buffer.c12
-rw-r--r--command.c10
-rw-r--r--command.h1
-rw-r--r--ide-definitions.c18
-rw-r--r--lsp-parse.c7
-rw-r--r--lsp-write.c6
-rw-r--r--lsp.c4
-rw-r--r--lsp.h4
-rw-r--r--main.c4
-rw-r--r--ted.cfg3
-rw-r--r--ted.h9
11 files changed, 63 insertions, 15 deletions
diff --git a/buffer.c b/buffer.c
index 515ceb3..4645f75 100644
--- a/buffer.c
+++ b/buffer.c
@@ -2532,11 +2532,11 @@ u32 buffer_last_rendered_line(TextBuffer *buffer) {
return clamp_u32(line, 0, buffer->nlines);
}
-void buffer_goto_word_at_cursor(TextBuffer *buffer) {
+void buffer_goto_word_at_cursor(TextBuffer *buffer, GotoType type) {
char *word = buffer_word_at_cursor_utf8(buffer);
if (*word) {
LSPDocumentPosition pos = buffer_pos_to_lsp_document_position(buffer, buffer->cursor_pos);
- definition_goto(buffer->ted, buffer_lsp(buffer), word, pos);
+ definition_goto(buffer->ted, buffer_lsp(buffer), word, pos, type);
}
free(word);
}
@@ -2562,10 +2562,14 @@ bool buffer_handle_click(Ted *ted, TextBuffer *buffer, vec2 click, u8 times) {
buffer_select_to_pos(buffer, buffer_pos);
break;
case KEY_MODIFIER_CTRL:
+ case KEY_MODIFIER_CTRL | KEY_MODIFIER_SHIFT:
if (!buffer->is_line_buffer) {
- // go to definition
+ // go to definition/declaration
buffer_cursor_move_to_pos(buffer, buffer_pos);
- buffer_goto_word_at_cursor(buffer);
+ GotoType type = GOTO_DEFINITION;
+ if (ted->key_modifier & KEY_MODIFIER_SHIFT)
+ type = GOTO_DECLARATION;
+ buffer_goto_word_at_cursor(buffer, type);
}
break;
case 0:
diff --git a/command.c b/command.c
index fb9a390..bf26b3a 100644
--- a/command.c
+++ b/command.c
@@ -66,6 +66,7 @@ static CommandName const command_names[] = {
{"find-usages", CMD_FIND_USAGES},
{"goto-definition", CMD_GOTO_DEFINITION},
{"goto-definition-at-cursor", CMD_GOTO_DEFINITION_AT_CURSOR},
+ {"goto-declaration-at-cursor", CMD_GOTO_DECLARATION_AT_CURSOR},
{"find", CMD_FIND},
{"find-replace", CMD_FIND_REPLACE},
{"tab-close", CMD_TAB_CLOSE},
@@ -405,10 +406,15 @@ void command_execute(Ted *ted, Command c, i64 argument) {
break;
case CMD_GOTO_DEFINITION:
menu_open(ted, MENU_GOTO_DEFINITION);
- break;
+ break;
case CMD_GOTO_DEFINITION_AT_CURSOR: {
if (buffer && buffer_is_named_file(buffer)) {
- buffer_goto_word_at_cursor(buffer);
+ buffer_goto_word_at_cursor(buffer, GOTO_DEFINITION);
+ }
+ } break;
+ case CMD_GOTO_DECLARATION_AT_CURSOR: {
+ if (buffer && buffer_is_named_file(buffer)) {
+ buffer_goto_word_at_cursor(buffer, GOTO_DECLARATION);
}
} break;
case CMD_FIND_USAGES:
diff --git a/command.h b/command.h
index 2edd207..3f7d155 100644
--- a/command.h
+++ b/command.h
@@ -75,6 +75,7 @@ ENUM_U16 {
CMD_FIND_USAGES,
CMD_GOTO_DEFINITION, // "go to definition of..." menu
CMD_GOTO_DEFINITION_AT_CURSOR,
+ CMD_GOTO_DECLARATION_AT_CURSOR,
CMD_COPY,
CMD_CUT,
diff --git a/ide-definitions.c b/ide-definitions.c
index 0152376..7873630 100644
--- a/ide-definitions.c
+++ b/ide-definitions.c
@@ -51,13 +51,22 @@ static SymbolKind symbol_kind_to_ted(LSPSymbolKind kind) {
return SYMBOL_OTHER;
}
-void definition_goto(Ted *ted, LSP *lsp, const char *name, LSPDocumentPosition position) {
+void definition_goto(Ted *ted, LSP *lsp, const char *name, LSPDocumentPosition position, GotoType type) {
Definitions *defs = &ted->definitions;
if (lsp) {
// cancel old request
ted_cancel_lsp_request(ted, defs->last_request_lsp, defs->last_request_id);
+ LSPRequestType request_type = LSP_REQUEST_DEFINITION;
+ switch (type) {
+ case GOTO_DEFINITION:
+ request_type = LSP_REQUEST_DEFINITION;
+ break;
+ case GOTO_DECLARATION:
+ request_type = LSP_REQUEST_DECLARATION;
+ break;
+ }
// send that request
- LSPRequest request = {.type = LSP_REQUEST_DEFINITION};
+ LSPRequest request = {.type = request_type};
request.data.definition.position = position;
LSPRequestID id = lsp_send_request(lsp, &request);
defs->last_request_id = id;
@@ -132,8 +141,9 @@ void definitions_process_lsp_response(Ted *ted, LSP *lsp, const LSPResponse *res
defs->last_request_id = 0;
switch (response->request.type) {
- case LSP_REQUEST_DEFINITION: {
- // handle textDocument/definition response
+ case LSP_REQUEST_DEFINITION:
+ case LSP_REQUEST_DECLARATION: {
+ // handle textDocument/definition or textDocument/declaration response
const LSPResponseDefinition *response_def = &response->data.definition;
if (!arr_len(response_def->locations)) {
diff --git a/lsp-parse.c b/lsp-parse.c
index 14db651..9c22fe4 100644
--- a/lsp-parse.c
+++ b/lsp-parse.c
@@ -163,6 +163,12 @@ static void parse_capabilities(LSP *lsp, const JSON *json, JSONObject capabiliti
cap->definition_support = true;
}
+ // check for declaration support
+ JSONValue declaration_value = json_object_get(json, capabilities, "declarationProvider");
+ if (declaration_value.type != JSON_UNDEFINED && declaration_value.type != JSON_FALSE) {
+ cap->declaration_support = true;
+ }
+
// check for textDocument/documentHighlight support
JSONValue highlight_value = json_object_get(json, capabilities, "documentHighlightProvider");
if (highlight_value.type != JSON_UNDEFINED && highlight_value.type != JSON_FALSE) {
@@ -883,6 +889,7 @@ void process_message(LSP *lsp, JSON *json) {
add_to_messages = parse_hover(lsp, json, &response);
break;
case LSP_REQUEST_DEFINITION:
+ case LSP_REQUEST_DECLARATION:
add_to_messages = parse_definition(lsp, json, &response);
break;
case LSP_REQUEST_HIGHLIGHT:
diff --git a/lsp-write.c b/lsp-write.c
index ecb8527..691bcba 100644
--- a/lsp-write.c
+++ b/lsp-write.c
@@ -1,5 +1,6 @@
#define LSP_INTERNAL 1
#include "lsp.h"
+#include "util.h"
#define write_bool lsp_write_bool // prevent naming conflict
@@ -278,6 +279,8 @@ static const char *lsp_request_method(LSPRequest *request) {
return "textDocument/references";
case LSP_REQUEST_DEFINITION:
return "textDocument/definition";
+ case LSP_REQUEST_DECLARATION:
+ return "textDocument/declaration";
case LSP_REQUEST_HIGHLIGHT:
return "textDocument/documentHighlight";
case LSP_REQUEST_RENAME:
@@ -545,7 +548,8 @@ void write_request(LSP *lsp, LSPRequest *request) {
write_document_position(o, hover->position);
write_obj_end(o);
} break;
- case LSP_REQUEST_DEFINITION: {
+ case LSP_REQUEST_DEFINITION:
+ case LSP_REQUEST_DECLARATION: {
const LSPRequestDefinition *def = &request->data.definition;
write_key_obj_start(o, "params");
write_document_position(o, def->position);
diff --git a/lsp.c b/lsp.c
index 1bee23f..bd01bbd 100644
--- a/lsp.c
+++ b/lsp.c
@@ -48,6 +48,7 @@ void lsp_request_free(LSPRequest *r) {
case LSP_REQUEST_SIGNATURE_HELP:
case LSP_REQUEST_HOVER:
case LSP_REQUEST_DEFINITION:
+ case LSP_REQUEST_DECLARATION:
case LSP_REQUEST_REFERENCES:
case LSP_REQUEST_HIGHLIGHT:
case LSP_REQUEST_DID_CLOSE:
@@ -176,6 +177,8 @@ static bool lsp_supports_request(LSP *lsp, const LSPRequest *request) {
return cap->hover_support;
case LSP_REQUEST_DEFINITION:
return cap->definition_support;
+ case LSP_REQUEST_DECLARATION:
+ return cap->declaration_support;
case LSP_REQUEST_WORKSPACE_SYMBOLS:
return cap->workspace_symbols_support;
case LSP_REQUEST_RENAME:
@@ -216,6 +219,7 @@ static bool request_type_is_notification(LSPRequestType type) {
case LSP_REQUEST_SIGNATURE_HELP:
case LSP_REQUEST_HOVER:
case LSP_REQUEST_DEFINITION:
+ case LSP_REQUEST_DECLARATION:
case LSP_REQUEST_REFERENCES:
case LSP_REQUEST_RENAME:
case LSP_REQUEST_WORKSPACE_SYMBOLS:
diff --git a/lsp.h b/lsp.h
index c256ec7..f5404b1 100644
--- a/lsp.h
+++ b/lsp.h
@@ -65,6 +65,7 @@ typedef enum {
LSP_REQUEST_SIGNATURE_HELP, // textDocument/signatureHelp
LSP_REQUEST_HOVER, // textDocument/hover
LSP_REQUEST_DEFINITION, // textDocument/definition
+ LSP_REQUEST_DECLARATION, // textDocument/declaration
LSP_REQUEST_HIGHLIGHT, // textDocument/documentHighlight
LSP_REQUEST_REFERENCES, // textDocument/references
LSP_REQUEST_RENAME, // textDocument/rename
@@ -200,6 +201,7 @@ typedef struct {
LSPRequestCompletion completion;
LSPRequestSignatureHelp signature_help;
LSPRequestHover hover;
+ // LSP_REQUEST_DEFINITION, LSP_REQUEST_DECLARATION, or LSP_REQUEST_TYPE_DEFINITION
LSPRequestDefinition definition;
LSPRequestHighlight highlight;
LSPRequestReferences references;
@@ -454,6 +456,7 @@ typedef struct {
LSPResponseCompletion completion;
LSPResponseSignatureHelp signature_help;
LSPResponseHover hover;
+ // LSP_REQUEST_DEFINITION, LSP_REQUEST_DECLARATION, or LSP_REQUEST_TYPE_DEFINITION
LSPResponseDefinition definition;
LSPResponseWorkspaceSymbols workspace_symbols;
LSPResponseRename rename;
@@ -480,6 +483,7 @@ typedef struct {
bool completion_support;
bool hover_support;
bool definition_support;
+ bool declaration_support;
bool workspace_symbols_support;
bool highlight_support;
// support for multiple root folders
diff --git a/main.c b/main.c
index 9967bd6..d4535a0 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,8 @@
/*
@TODO:
-- go to declaration with LSP
+- go to type definition
+- why does asking for a definition in ted.h send us to the wrong place?
+ (vscode doesn't experience this problem)
- ted.h documentation
- handle multiple symbols with same name in go-to-definition menu
- better non-error window/showMessage(Request)
diff --git a/ted.cfg b/ted.cfg
index 7e94d19..bca3276 100644
--- a/ted.cfg
+++ b/ted.cfg
@@ -264,7 +264,8 @@ Ctrl+t = :generate-tags
Ctrl+d = :goto-definition
# alternative to ctrl+click
-Ctrl+Shift+d = :goto-definition-at-cursor
+Ctrl+' = :goto-definition-at-cursor
+Ctrl+Shift+' = :goto-declaration-at-cursor
Ctrl+g = :goto-line
Ctrl+\ = :split-horizontal
diff --git a/ted.h b/ted.h
index 0688f40..19a975c 100644
--- a/ted.h
+++ b/ted.h
@@ -464,6 +464,11 @@ typedef struct {
LSPDocumentPosition position; // only set if from_lsp = true
} SymbolInfo;
+typedef enum {
+ GOTO_DECLARATION,
+ GOTO_DEFINITION,
+} GotoType;
+
typedef struct {
LSPID last_request_lsp; // used for cancellation
// ID of the last request which was sent out.
@@ -754,7 +759,7 @@ bool buffer_save(TextBuffer *buffer);
bool buffer_save_as(TextBuffer *buffer, const char *new_filename);
u32 buffer_first_rendered_line(TextBuffer *buffer);
u32 buffer_last_rendered_line(TextBuffer *buffer);
-void buffer_goto_word_at_cursor(TextBuffer *buffer);
+void buffer_goto_word_at_cursor(TextBuffer *buffer, GotoType type);
bool buffer_handle_click(Ted *ted, TextBuffer *buffer, vec2 click, u8 times);
void buffer_render(TextBuffer *buffer, Rect r);
void buffer_indent_lines(TextBuffer *buffer, u32 first_line, u32 last_line);
@@ -951,7 +956,7 @@ void autocomplete_frame(Ted *ted);
// if `lsp` is NULL, tags will be used.
// Note: the document position is required for LSP requests because of overloading (where the name
// alone isn't sufficient)
-void definition_goto(Ted *ted, LSP *lsp, const char *name, LSPDocumentPosition pos);
+void definition_goto(Ted *ted, LSP *lsp, const char *name, LSPDocumentPosition pos, GotoType type);
void definition_cancel_lookup(Ted *ted);
void definitions_process_lsp_response(Ted *ted, LSP *lsp, const LSPResponse *response);
void definitions_selector_open(Ted *ted);