summaryrefslogtreecommitdiff
path: root/src/main/lsp/help.c
diff options
context:
space:
mode:
authorAlbert Cervin <albert@acervin.com>2024-09-17 08:47:03 +0200
committerAlbert Cervin <albert@acervin.com>2025-11-01 22:11:14 +0100
commit4459b8b3aa9d73895391785a99dcc87134e80601 (patch)
treea5204f447a0b2b05f63504c7fe958ef9bbf1918a /src/main/lsp/help.c
parent4689f3f38277bb64981fc960e8e384e2d065d659 (diff)
downloaddged-4459b8b3aa9d73895391785a99dcc87134e80601.tar.gz
dged-4459b8b3aa9d73895391785a99dcc87134e80601.tar.xz
dged-4459b8b3aa9d73895391785a99dcc87134e80601.zip
More lsp support
This makes the LSP support complete for now: - Completion - Diagnostics - Goto implementation/declaration - Rename - Documentation - Find references
Diffstat (limited to 'src/main/lsp/help.c')
-rw-r--r--src/main/lsp/help.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/main/lsp/help.c b/src/main/lsp/help.c
new file mode 100644
index 0000000..e5bcc28
--- /dev/null
+++ b/src/main/lsp/help.c
@@ -0,0 +1,101 @@
+#include "help.h"
+
+#include "dged/binding.h"
+#include "dged/buffer.h"
+#include "dged/buffer_view.h"
+#include "dged/buffers.h"
+#include "dged/minibuffer.h"
+#include "dged/s8.h"
+#include "dged/window.h"
+
+#include "bindings.h"
+#include "lsp.h"
+
+static int32_t close_help(struct command_ctx ctx, int argc, const char **argv) {
+ (void)argc;
+ (void)argv;
+
+ if (window_has_prev_buffer_view(ctx.active_window)) {
+ window_set_buffer(ctx.active_window,
+ window_prev_buffer_view(ctx.active_window)->buffer);
+ } else {
+ minibuffer_echo_timeout(4, "no previous buffer to go to");
+ }
+
+ return 0;
+}
+
+static void handle_help_response(struct lsp_server *server,
+ struct lsp_response *response,
+ void *userdata) {
+ (void)server;
+
+ struct buffers *buffers = (struct buffers *)userdata;
+ if (response->value.result.type == Json_Null) {
+ minibuffer_echo_timeout(4, "help: no help found");
+ return;
+ }
+
+ struct buffer *b = buffers_find(buffers, "*lsp-help*");
+ if (b == NULL) {
+ b = buffers_add(buffers, buffer_create("*lsp-help*"));
+ static struct command help_close = {
+ .name = "help_close",
+ .fn = close_help,
+ };
+
+ struct binding bindings[] = {
+ ANONYMOUS_BINDING(None, 'q', &help_close),
+ };
+ struct keymap km = keymap_create("help", 2);
+ keymap_bind_keys(&km, bindings, sizeof(bindings) / sizeof(bindings[0]));
+ buffer_add_keymap(b, km);
+ }
+
+ struct hover help = hover_from_json(&response->value.result);
+
+ buffer_set_readonly(b, false);
+ buffer_clear(b);
+ buffer_add(b, buffer_end(b), help.contents.s, help.contents.l);
+ buffer_set_readonly(b, true);
+
+ if (window_find_by_buffer(b) == NULL) {
+ window_set_buffer(windows_get_active(), b);
+ }
+ hover_free(&help);
+}
+
+void lsp_help(struct lsp_server *server, struct buffer *buffer,
+ struct location at, struct buffers *buffers) {
+ uint64_t id = new_pending_request(server, handle_help_response, buffers);
+ struct versioned_text_document_identifier doc =
+ versioned_identifier_from_buffer(buffer);
+
+ struct text_document_position pos = {
+ .uri = doc.uri,
+ .position = at,
+ };
+
+ struct s8 json_payload = document_position_to_json(&pos);
+ lsp_send(lsp_backend(server),
+ lsp_create_request(id, s8("textDocument/hover"), json_payload));
+
+ versioned_text_document_identifier_free(&doc);
+ s8delete(json_payload);
+}
+
+int32_t lsp_help_cmd(struct command_ctx ctx, int argc, const char **argv) {
+ (void)argc;
+ (void)argv;
+
+ struct buffer_view *bv = window_buffer_view(ctx.active_window);
+ struct lsp_server *server = lsp_server_for_lang_id(bv->buffer->lang.id);
+ if (server == NULL) {
+ minibuffer_echo_timeout(4, "no lsp server associated with %s",
+ bv->buffer->name);
+ return 0;
+ }
+
+ lsp_help(server, bv->buffer, bv->dot, ctx.buffers);
+ return 0;
+}