From 94ce74b998ad019e2307e4b69f006127dba775e2 Mon Sep 17 00:00:00 2001 From: pommicket Date: Fri, 30 Dec 2022 22:07:03 -0500 Subject: document highlights! --- buffer.c | 2 +- ide-highlights.c | 38 +++++++++++++++++++++++++++++++++----- ide-hover.c | 41 ++++------------------------------------- main.c | 6 +++++- ted.c | 37 +++++++++++++++++++++++++++++++++++++ ted.h | 5 +++-- 6 files changed, 83 insertions(+), 46 deletions(-) diff --git a/buffer.c b/buffer.c index b4c85d5..13d3310 100644 --- a/buffer.c +++ b/buffer.c @@ -1430,7 +1430,7 @@ static Status buffer_insert_lines(TextBuffer *buffer, u32 where, u32 number) { LSPDocumentID buffer_lsp_document_id(TextBuffer *buffer) { LSP *lsp = buffer_lsp(buffer); - return lsp_document_id(lsp, buffer->filename); + return lsp ? lsp_document_id(lsp, buffer->filename) : 0; } // LSP uses UTF-16 indices because Microsoft fucking loves UTF-16 and won't let it die diff --git a/ide-highlights.c b/ide-highlights.c index 4246c66..239f4ec 100644 --- a/ide-highlights.c +++ b/ide-highlights.c @@ -1,16 +1,29 @@ -void highlights_send_request(Ted *ted, TextBuffer *buffer) { +static void highlights_clear(Highlights *hls) { + arr_clear(hls->highlights); +} + +void highlights_send_request(Ted *ted) { + TextBuffer *buffer = ted->active_buffer; Highlights *hls = &ted->highlights; - if (!buffer) return; + if (!buffer) { + highlights_clear(hls); + return; + } LSP *lsp = buffer_lsp(buffer); - if (!lsp) return; + if (!lsp) { + highlights_clear(hls); + return; + } LSPDocumentPosition pos = buffer_cursor_pos_as_lsp_document_position(buffer); LSPRequest request = {.type = LSP_REQUEST_HIGHLIGHT}; request.data.highlight.position = pos; hls->last_request_id = lsp_send_request(lsp, &request); + hls->last_request_lsp = lsp->id; + hls->requested_position = pos; } void highlights_close(Ted *ted) { - arr_clear(ted->highlights.highlights); + highlights_clear(&ted->highlights); } void highlights_process_lsp_response(Ted *ted, LSPResponse *response) { @@ -28,5 +41,20 @@ void highlights_process_lsp_response(Ted *ted, LSPResponse *response) { void highlights_frame(Ted *ted) { Highlights *hls = &ted->highlights; - + TextBuffer *buffer = ted->active_buffer; + if (!buffer) { + highlights_clear(hls); + return; + } + LSPDocumentPosition pos = buffer_cursor_pos_as_lsp_document_position(buffer); + if (!lsp_document_position_eq(pos, hls->requested_position)) { + // cursor moved or something. let's resend the request. + highlights_clear(hls); + highlights_send_request(ted); + } + + arr_foreach_ptr(hls->highlights, LSPHighlight, hl) { + ted_highlight_lsp_range(ted, buffer, hl->range); + } + gl_geometry_draw(); } diff --git a/ide-hover.c b/ide-hover.c index 5136d79..80f2a09 100644 --- a/ide-hover.c +++ b/ide-hover.c @@ -56,10 +56,8 @@ void hover_process_lsp_response(Ted *ted, LSPResponse *response) { free(hover->text); hover->text = NULL; - if (buffer) { - hover->range_start = buffer_pos_from_lsp(buffer, hover_response->range.start); - hover->range_end = buffer_pos_from_lsp(buffer, hover_response->range.end); - } + hover->range = hover_response->range; + const char *contents = lsp_response_string(response, hover_response->contents); if (*contents) { hover->text = str_dup(contents); @@ -119,39 +117,8 @@ void hover_frame(Ted *ted, double dt) { float x = ted->mouse_pos.x, y = ted->mouse_pos.y + font->char_height; float char_height = font->char_height; - BufferPos range_start = hover->range_start, range_end = hover->range_end; - if (!buffer_pos_eq(range_start, range_end)) { - // draw the highlight - if (range_start.line == range_end.line) { - v2 a = buffer_pos_to_pixels(buffer, range_start); - v2 b = buffer_pos_to_pixels(buffer, range_end); - b.y += char_height; - gl_geometry_rect(rect_endpoints(a, b), colors[COLOR_HOVER_HL]); - } else if (range_end.line - range_start.line < 1000) { // prevent gigantic highlights from slowing things down - // multiple lines. - v2 a = buffer_pos_to_pixels(buffer, range_start); - v2 b = buffer_pos_to_pixels(buffer, buffer_pos_end_of_line(buffer, range_start.line)); - b.y += char_height; - gl_geometry_rect(rect_endpoints(a, b), colors[COLOR_HOVER_HL]); - - for (u32 line = range_start.line + 1; line < range_end.line; ++line) { - // these lines are fully contained in the range. - BufferPos start = buffer_pos_start_of_line(buffer, line); - BufferPos end = buffer_pos_end_of_line(buffer, line); - a = buffer_pos_to_pixels(buffer, start); - b = buffer_pos_to_pixels(buffer, end); - b.y += char_height; - gl_geometry_rect(rect_endpoints(a, b), colors[COLOR_HOVER_HL]); - } - - // last line - a = buffer_pos_to_pixels(buffer, buffer_pos_start_of_line(buffer, range_end.line)); - b = buffer_pos_to_pixels(buffer, range_end); - b.y += char_height; - gl_geometry_rect(rect_endpoints(a, b), colors[COLOR_HOVER_HL]); - } - - } + ted_highlight_lsp_range(ted, buffer, hover->range); + if (hover->text) { float max_width = 400; TextRenderState state = text_render_state_default; diff --git a/main.c b/main.c index daf483f..b1bb6e5 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,9 @@ /* @TODO: +- clip highlight to buffer rect +- different highlight colors +- highlight-enabled, and highlight-auto - more LSP stuff: - - document highlight (textDocument/documentHighlight) - find usages (textDocument/references) - handle multiple symbols with same name in go-to-definition menu - :go-to-cursor-definition @@ -910,6 +912,7 @@ int main(int argc, char **argv) { signature_help_process_lsp_response(ted, r); hover_process_lsp_response(ted, r); definitions_process_lsp_response(ted, lsp, r); + highlights_process_lsp_response(ted, r); } break; } lsp_message_free(&message); @@ -1017,6 +1020,7 @@ int main(int argc, char **argv) { signature_help_frame(ted); hover_frame(ted, frame_dt); definitions_frame(ted); + highlights_frame(ted); } else { autocomplete_close(ted); text_utf8_anchored(font, "Press Ctrl+O to open a file or Ctrl+N to create a new one.", diff --git a/ted.c b/ted.c index 831242d..5941f9a 100644 --- a/ted.c +++ b/ted.c @@ -567,3 +567,40 @@ void ted_go_to_lsp_document_position(Ted *ted, LSP *lsp, LSPDocumentPosition pos u32 character = position.pos.character; ted_go_to_position(ted, path, line, character, true); } + +void ted_highlight_lsp_range(Ted *ted, TextBuffer *buffer, LSPRange range) { + Font *font = buffer_font(buffer); + const u32 *colors = buffer_settings(buffer)->colors; + float char_height = font->char_height; + BufferPos range_start = buffer_pos_from_lsp(buffer, range.start); + BufferPos range_end = buffer_pos_from_lsp(buffer, range.end); + // draw the highlight + if (range_start.line == range_end.line) { + v2 a = buffer_pos_to_pixels(buffer, range_start); + v2 b = buffer_pos_to_pixels(buffer, range_end); + b.y += char_height; + gl_geometry_rect(rect_endpoints(a, b), colors[COLOR_HOVER_HL]); + } else if (range_end.line - range_start.line < 1000) { // prevent gigantic highlights from slowing things down + // multiple lines. + v2 a = buffer_pos_to_pixels(buffer, range_start); + v2 b = buffer_pos_to_pixels(buffer, buffer_pos_end_of_line(buffer, range_start.line)); + b.y += char_height; + gl_geometry_rect(rect_endpoints(a, b), colors[COLOR_HOVER_HL]); + + for (u32 line = range_start.line + 1; line < range_end.line; ++line) { + // these lines are fully contained in the range. + BufferPos start = buffer_pos_start_of_line(buffer, line); + BufferPos end = buffer_pos_end_of_line(buffer, line); + a = buffer_pos_to_pixels(buffer, start); + b = buffer_pos_to_pixels(buffer, end); + b.y += char_height; + gl_geometry_rect(rect_endpoints(a, b), colors[COLOR_HOVER_HL]); + } + + // last line + a = buffer_pos_to_pixels(buffer, buffer_pos_start_of_line(buffer, range_end.line)); + b = buffer_pos_to_pixels(buffer, range_end); + b.y += char_height; + gl_geometry_rect(rect_endpoints(a, b), colors[COLOR_HOVER_HL]); + } +} diff --git a/ted.h b/ted.h index 7a3dddd..0f2dfe6 100644 --- a/ted.h +++ b/ted.h @@ -411,8 +411,7 @@ typedef struct { // we use this to check if we need to refresh it. LSPDocumentPosition requested_position; LSPID requested_lsp; - BufferPos range_start; - BufferPos range_end; + LSPRange range; } Hover; typedef struct { @@ -440,6 +439,8 @@ typedef struct { typedef struct { LSPHighlight *highlights; LSPRequestID last_request_id; + LSPID last_request_lsp; + LSPDocumentPosition requested_position; } Highlights; typedef struct Ted { -- cgit v1.2.3