summaryrefslogtreecommitdiff
path: root/ide-code-action.c
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2025-09-30 11:09:43 -0400
committerpommicket <pommicket@gmail.com>2025-09-30 11:09:43 -0400
commitd2fba7af36c6ae76c954da76ed64e3383e0d64f9 (patch)
treee5e3f51f543606e41d719a289c43b7cdf9261058 /ide-code-action.c
parent3a1af93e9c0f983da64070d3774596844c2a26e1 (diff)
code_action_select_best
Diffstat (limited to 'ide-code-action.c')
-rw-r--r--ide-code-action.c78
1 files changed, 62 insertions, 16 deletions
diff --git a/ide-code-action.c b/ide-code-action.c
index 93b95a9..3f67121 100644
--- a/ide-code-action.c
+++ b/ide-code-action.c
@@ -1,8 +1,15 @@
#include "ted-internal.h"
+typedef struct {
+ const char *name;
+ const LSPCodeAction *lsp;
+ bool is_best;
+} Action;
+
struct CodeAction {
LSPServerRequestID last_request;
LSPResponse response;
+ Action *actions;
};
static bool ranges_touch(BufferPos p1, BufferPos p2, BufferPos q1, BufferPos q2) {
@@ -68,6 +75,7 @@ bool code_action_is_open(Ted *ted) {
void code_action_close(Ted *ted) {
CodeAction *c = ted->code_action;
lsp_response_free(&c->response);
+ arr_free(c->actions);
memset(&c->response, 0, sizeof c->response);
}
@@ -85,6 +93,30 @@ bool code_action_process_lsp_response(Ted *ted, const LSPResponse *response) {
}
lsp_response_free(&c->response);
c->response = *response;
+ arr_free(c->actions);
+ int best_score = -1;
+ Action *best_action = NULL;
+ arr_foreach_ptr(response->data.code_action.actions, const LSPCodeAction, action) {
+ Action *action_out = arr_addp(c->actions);
+ action_out->lsp = action;
+ action_out->name = lsp_response_string(response, action->name);
+ int score = 0;
+ if (action->is_preferred)
+ score += 10;
+ if (action->kind == LSP_CODE_ACTION_QUICKFIX)
+ score += 1;
+ if (score > best_score) {
+ best_action = action_out;
+ best_score = score;
+ }
+ }
+ best_action->is_best = true;
+ if (best_action != c->actions) {
+ // move to top
+ Action best = *best_action;
+ memmove(c->actions + 1, c->actions, (size_t)(best_action - c->actions) * sizeof *c->actions);
+ *c->actions = best;
+ }
return true;
}
@@ -101,13 +133,22 @@ static void code_action_perform(Ted *ted, const LSPCodeAction *action) {
LSPServerRequestID request_id = c->last_request;
LSP *lsp = ted_get_lsp_by_id(ted, request_id.lsp);
ted_perform_workspace_edit(ted, lsp, response, &action->edit);
+ code_action_close(ted);
+}
+
+void code_action_select_best(Ted *ted) {
+ CodeAction *c = ted->code_action;
+ const Action *best = NULL;
+ arr_foreach_ptr(c->actions, const Action, action)
+ if (action->is_best)
+ best = action;
+ if (best)
+ code_action_perform(ted, best->lsp);
}
void code_action_frame(Ted *ted) {
CodeAction *c = ted->code_action;
- LSPResponse *response = &c->response;
- const LSPCodeAction *code_actions = response->data.code_action.actions;
- if (arr_len(code_actions) == 0)
+ if (arr_len(c->actions) == 0)
return;
TextBuffer *buffer = ted_active_buffer(ted);
if (!buffer) {
@@ -117,14 +158,13 @@ void code_action_frame(Ted *ted) {
const Settings *settings = ted_active_settings(ted);
vec2 cursor_pos = buffer_pos_to_pixels(buffer, buffer_cursor_pos(buffer));
float x = cursor_pos.x, y = cursor_pos.y;
- Font *font = ted->font;
+ Font *font = ted->font, *font_bold = ted->font_bold;
float char_height = text_font_char_height(font);
float padding = settings->padding;
float border_thickness = settings->border_thickness;
- float panel_width = 0, panel_height = (char_height + border_thickness) * (float)arr_len(code_actions);
- arr_foreach_ptr(code_actions, const LSPCodeAction, action) {
- const char *name = lsp_response_string(response, action->name);
- float row_width = text_get_size_vec2(font, name).x
+ float panel_width = 0, panel_height = (char_height + border_thickness) * (float)arr_len(c->actions);
+ arr_foreach_ptr(c->actions, const Action, action) {
+ float row_width = text_get_size_vec2(font, action->name).x
+ char_height * 6 + padding * 2;
if (row_width > panel_width)
panel_width = row_width;
@@ -140,10 +180,9 @@ void code_action_frame(Ted *ted) {
Rect panel_rect = {{x,y},{panel_width,panel_height}};
gl_geometry_rect(panel_rect, settings_color(settings, COLOR_BG));
gl_geometry_rect_border(panel_rect, border_thickness, settings_color(settings, COLOR_AUTOCOMPLETE_BORDER));
- const LSPCodeAction *selected_action = NULL;
- arr_foreach_ptr(code_actions, const LSPCodeAction, action) {
- const char *name = lsp_response_string(response, action->name);
- Rect entry_rect = {{x, y}, {panel_width, border_thickness + char_height}};
+ const Action *selected_action = NULL;
+ arr_foreach_ptr(c->actions, const Action, action) {
+ Rect entry_rect = {{x, y}, {panel_width, char_height}};
if (rect_contains_point(entry_rect, ted->mouse_pos)) {
ted->cursor = ted->cursor_hand;
gl_geometry_rect(entry_rect, settings_color(settings, COLOR_AUTOCOMPLETE_HL));
@@ -151,19 +190,26 @@ void code_action_frame(Ted *ted) {
arr_foreach_ptr(ted->mouse_clicks[SDL_BUTTON_LEFT], const MouseClick, click)
if (rect_contains_point(entry_rect, click->pos))
selected_action = action;
- if (action != code_actions) {
+ if (action != c->actions) {
Rect border = {{x, y}, {panel_width, border_thickness}};
gl_geometry_rect(border, settings_color(settings, COLOR_AUTOCOMPLETE_BORDER));
y += border_thickness;
};
- text_utf8(font, name, x + padding, y, settings_color(settings, COLOR_TEXT));
+ text_utf8(action->is_best ? font_bold : font,
+ action->name, x + padding, y, settings_color(settings, COLOR_TEXT));
+ if (action->is_best) {
+ text_utf8_anchored(font, "(Enter)",
+ panel_rect.pos.x + panel_rect.size.x - padding, y,
+ settings_color(settings, COLOR_COMMENT),
+ ANCHOR_TOP_RIGHT);
+ }
y += char_height;
}
gl_geometry_draw();
text_render(font);
+ text_render(font_bold);
if (selected_action) {
- code_action_perform(ted, selected_action);
- code_action_close(ted);
+ code_action_perform(ted, selected_action->lsp);
} else {
arr_foreach_ptr(ted->mouse_clicks[SDL_BUTTON_LEFT], const MouseClick, click) {
if (!rect_contains_point(panel_rect, click->pos)) {