Skip to content

Commit

Permalink
Sync with geany-lsp
Browse files Browse the repository at this point in the history
  • Loading branch information
techee committed Dec 11, 2024
1 parent 53002a1 commit 584f299
Show file tree
Hide file tree
Showing 14 changed files with 444 additions and 31 deletions.
28 changes: 28 additions & 0 deletions build/lsp.m4
Original file line number Diff line number Diff line change
@@ -1,7 +1,35 @@
AC_DEFUN([GP_CHECK_LSP],
[
GP_ARG_DISABLE([LSP], [auto])
JSON_GLIB_PACKAGE_NAME=json-glib-1.0
JSON_GLIB_VERSION=1.10
JSONRPC_GLIB_PACKAGE_NAME=jsonrpc-glib-1.0
JSONRPC_GLIB_VERSION=3.44
AC_ARG_ENABLE(system-jsonrpc,
AC_HELP_STRING([--enable-system-jsonrpc],
[Force using system json-glib and jsonrpc-glib libraries for the LSP plugin. [[default=no]]]),,
enable_system_jsonrpc=no)
PKG_CHECK_MODULES([SYSTEM_JSONRPC],
[${JSON_GLIB_PACKAGE_NAME} >= ${JSON_GLIB_VERSION}
${JSONRPC_GLIB_PACKAGE_NAME} >= ${JSONRPC_GLIB_VERSION}],
have_system_jsonrpc=yes
echo "Required system versions of json-glib and jsonrpc-glib found - using them.",
have_system_jsonrpc=no
echo "Required system versions of json-glib and jsonrpc-glib not found - using builtin versions.")
AS_IF([test x"$enable_system_jsonrpc" = "xyes" || test x"$have_system_jsonrpc" = "xyes"],
[GP_CHECK_PLUGIN_DEPS([LSP], [LSP],
[${JSON_GLIB_PACKAGE_NAME} >= ${JSON_GLIB_VERSION}
${JSONRPC_GLIB_PACKAGE_NAME} >= ${JSONRPC_GLIB_VERSION}])],
[])
AM_CONDITIONAL(ENABLE_BUILTIN_JSONRPC, [ test x"$have_system_jsonrpc" = "xno" ])
GP_COMMIT_PLUGIN_STATUS([LSP])
AC_CONFIG_FILES([
lsp/Makefile
lsp/deps/Makefile
Expand Down
23 changes: 15 additions & 8 deletions lsp/README
Original file line number Diff line number Diff line change
Expand Up @@ -101,21 +101,26 @@ LSP diagnostic messages typically include error messages or warnings from
compilers, as well as messages from linters. These messages are highlighted in
the code; the exact style of highlighting can be configured to suit your
preferences. When you hover over the highlighted part with your mouse cursor,
a popup window appears, providing additional details about the issue.
a popup window appears, providing additional details about the issue. It is
also possible to display all diagnostic messages received from the server in
the message window.

Some servers offer auto-fixes of certain issues. For instance, the ``clangd``
server displays ``fix available`` next to the issue in the hover popup window.
To perform the auto-fix, right-click the line with the issue and select the
corresponding option from the Commands submenu.
Code actions
------------

Some servers offer auto-fixes of certain issues or various refactoring options.
For instance, the ``clangd`` server displays ``fix available`` next to the issue
in the hover popup window. To perform the auto-fix, right-click the line with
the issue and select the corresponding option from the Commands submenu. This
popup can also be invoked by a keybinding.

Code lenses
-----------

Code lenses are executable commands that are specific to a particular piece of
code. As Geany's Scintilla component limitations prevent these commands
from being clickable and executable directly in the editor, they are accessible
through the Commands submenu of the context menu, similarly to diagnostic
messages.
through the Commands submenu of the context menu, similarly to code actions.

Semantic token type highlighting
--------------------------------
Expand Down Expand Up @@ -203,7 +208,9 @@ Identical symbol highlighting

When you click on a symbol in the document, this feature highlights all its
occurrences in the document. You can customize the highlighting style to your
preference by configuring it in the configuration file.
preference by configuring it in the configuration file. Also, it is possible
to disable this feature to be performed automatically, but, instead, manually
through a keybinding.

Smart selection expanding/shrinking
-----------------------------------
Expand Down
5 changes: 5 additions & 0 deletions lsp/data/lsp.conf
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ command_on_save_regex=
rpc_log_full=false
# Show server's stderr in Geany's stderr (when started from terminal)
show_server_stderr=false
# Tracing level of the server (when supported). When enabled, tracing messages
# are logged into stdout. Valid values are 'off', 'messages', 'verbose'
trace_value=off
# Enables or disables telemetry notification logging to stdout
telemetry_notifications=false

# Whether LSP should be used for autocompletion
autocomplete_enable=true
Expand Down
4 changes: 4 additions & 0 deletions lsp/deps/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ jsonrpc_glib_srcs = \
jsonrpc-glib/jsonrpc-version.h \
jsonrpc-glib/jsonrpc-version-macros.h

if ENABLE_BUILTIN_JSONRPC

libjsonrpc_la_SOURCES = \
$(json_glib_srcs) \
$(jsonrpc_glib_srcs)
Expand All @@ -72,3 +74,5 @@ libjsonrpc_la_CFLAGS = $(AM_CFLAGS)
# false positives and it's not "our" code anyway
#
# include $(top_srcdir)/build/cppcheck.mk

endif
16 changes: 15 additions & 1 deletion lsp/src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,21 @@ lsp_la_CPPFLAGS = $(AM_CPPFLAGS) \
-I$(top_srcdir)/lsp/deps/jsonrpc-glib \
-I$(top_srcdir)/lsp/deps \
-I$(top_srcdir)/lsp/src
if ENABLE_BUILTIN_JSONRPC
lsp_la_CPPFLAGS += -I$(top_srcdir)/lsp/deps/jsonrpc-glib -I$(top_srcdir)/lsp/deps
endif

if ENABLE_BUILTIN_JSONRPC
lsp_la_CFLAGS = $(AM_CFLAGS)
lsp_la_LIBADD = $(COMMONLIBS) $(top_builddir)/lsp/deps/libjsonrpc.la
else
lsp_la_CFLAGS = $(AM_CFLAGS) $(LSP_CFLAGS)
endif

lsp_la_LIBADD = $(COMMONLIBS)
if ENABLE_BUILTIN_JSONRPC
lsp_la_LIBADD += $(top_builddir)/lsp/deps/libjsonrpc.la
else
lsp_la_LIBADD += $(LSP_LIBS)
endif

include $(top_srcdir)/build/cppcheck.mk
115 changes: 115 additions & 0 deletions lsp/src/lsp-diagnostics.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ typedef struct {
} LspDiag;


typedef struct {
const gchar *fname;
const LspDiag *diag;
} LspFileDiag;


typedef enum {
LSP_DIAG_SEVERITY_MIN = 1,
LspError = 1,
Expand Down Expand Up @@ -518,3 +524,112 @@ void lsp_diagnostics_hide_calltip(GeanyDocument *doc)
calltip_sci = NULL;
}
}


static gint compare_diags(gconstpointer a, gconstpointer b)
{
const LspFileDiag *item_a = *((LspFileDiag **) a);
const LspFileDiag *item_b = *((LspFileDiag **) b);
gint res = g_strcmp0(item_a->fname, item_b->fname);

if (res != 0)
return res;

if (item_a->diag->range.start.line < item_b->diag->range.start.line)
return -1;
if (item_a->diag->range.start.line > item_b->diag->range.start.line)
return 1;

if (item_a->diag->severity < item_b->diag->severity)
return -1;
if (item_a->diag->severity > item_b->diag->severity)
return 1;

return 0;
}


static void replace_char(gchar *str, gchar find, gchar replace)
{
gchar *current_pos = strchr(str, find);
while (current_pos)
{
*current_pos = replace;
current_pos = strchr(current_pos, find);
}
}


static void show_in_msgwin(LspFileDiag *diag)
{
gint lineno = diag->diag->range.start.line;
gchar *fname = g_strdup(diag->fname);
gchar *new_msg = g_strdup(diag->diag->message);
gchar *base_path;

base_path = lsp_utils_get_project_base_path();

if (base_path)
{
gchar *rel_path = lsp_utils_get_relative_path(base_path, fname);
gchar *locale_base_path = utils_get_locale_from_utf8(base_path);

if (rel_path && !g_str_has_prefix(rel_path, ".."))
SETPTR(fname, g_strdup(rel_path));

msgwin_set_messages_dir(locale_base_path);

g_free(locale_base_path);
g_free(rel_path);
}

replace_char(new_msg, '\n', ' ');
replace_char(new_msg, '\r', ' ');
msgwin_msg_add(COLOR_BLACK, -1, NULL, "%s:%d: %s", fname, lineno + 1, new_msg);

g_free(fname);
g_free(new_msg);
g_free(base_path);
}


void lsp_diagnostics_show_all(void)
{
GeanyDocument *doc = document_get_current();
LspServer *srv = lsp_server_get(doc);
GPtrArray *arr, *diags;
LspFileDiag *item;
GHashTableIter iter;
const gchar *key;
guint i;

if (!srv)
return;

arr = g_ptr_array_new_full(100, g_free);

g_hash_table_iter_init(&iter, srv->diag_table);
while (g_hash_table_iter_next(&iter, (gpointer *)&key, (gpointer *)&diags))
{
LspDiag *diag;

foreach_ptr_array(diag, i, diags)
{
item = g_new0(LspFileDiag, 1);
item->fname = key;
item->diag = diag;
g_ptr_array_add(arr, item);
}
}

g_ptr_array_sort(arr, compare_diags);

msgwin_clear_tab(MSG_MESSAGE);
msgwin_switch_tab(MSG_MESSAGE, TRUE);
foreach_ptr_array(item, i, arr)
{
show_in_msgwin(item);
}

g_ptr_array_free(arr, TRUE);
}
2 changes: 2 additions & 0 deletions lsp/src/lsp-diagnostics.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ void lsp_diagnostics_free(LspServer *srv);
void lsp_diagnostics_show_calltip(gint pos);
void lsp_diagnostics_hide_calltip(GeanyDocument *doc);

void lsp_diagnostics_show_all(void);

void lsp_diagnostics_received(LspServer *srv, GVariant* diags);
void lsp_diagnostics_redraw(GeanyDocument *doc);
void lsp_diagnostics_clear(LspServer *srv, GeanyDocument *doc);
Expand Down
40 changes: 38 additions & 2 deletions lsp/src/lsp-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,12 @@ enum {
KB_GOTO_NEXT_DIAG,
KB_GOTO_PREV_DIAG,
KB_SHOW_DIAG,
KB_SHOW_ALL_DIAGS,

KB_FIND_IMPLEMENTATIONS,
KB_FIND_REFERENCES,
KB_HIGHLIGHT_OCCUR,
KB_HIGHLIGHT_CLEAR,

KB_EXPAND_SELECTION,
KB_SHRINK_SELECTION,
Expand Down Expand Up @@ -126,9 +129,12 @@ struct
GtkWidget *goto_next_diag;
GtkWidget *goto_prev_diag;
GtkWidget *show_diag;
GtkWidget *show_all_diags;

GtkWidget *goto_ref;
GtkWidget *goto_impl;
GtkWidget *highlight_occur;
GtkWidget *highlight_clear;

GtkWidget *rename_in_file;
GtkWidget *rename_in_project;
Expand Down Expand Up @@ -1376,13 +1382,22 @@ static void invoke_kb(guint key_id, gint pos)
case KB_SHOW_DIAG:
lsp_diagnostics_show_calltip(pos);
break;
case KB_SHOW_ALL_DIAGS:
lsp_diagnostics_show_all();
break;

case KB_FIND_REFERENCES:
lsp_goto_references(pos);
break;
case KB_FIND_IMPLEMENTATIONS:
lsp_goto_implementations(pos);
break;
case KB_HIGHLIGHT_OCCUR:
lsp_highlight_schedule_request(doc);
break;
case KB_HIGHLIGHT_CLEAR:
lsp_highlight_clear(doc);
break;

case KB_EXPAND_SELECTION:
lsp_selection_range_expand();
Expand Down Expand Up @@ -1528,12 +1543,19 @@ static void create_menu_items()
keybindings_set_item(group, KB_GOTO_PREV_DIAG, NULL, 0, 0, "goto_prev_diag",
_("Go to previous diagnostic"), menu_items.goto_prev_diag);

menu_items.show_diag = gtk_menu_item_new_with_mnemonic(_("_Show Diagnostic"));
menu_items.show_diag = gtk_menu_item_new_with_mnemonic(_("_Show Current Diagnostic"));
gtk_container_add(GTK_CONTAINER(menu), menu_items.show_diag);
g_signal_connect(menu_items.show_diag, "activate", G_CALLBACK(on_menu_invoked),
GUINT_TO_POINTER(KB_SHOW_DIAG));
keybindings_set_item(group, KB_SHOW_DIAG, NULL, 0, 0, "show_diag",
_("Show diagnostic"), menu_items.show_diag);
_("Show current diagnostic"), menu_items.show_diag);

menu_items.show_all_diags = gtk_menu_item_new_with_mnemonic(_("Show _All Diagnostics"));
gtk_container_add(GTK_CONTAINER(menu), menu_items.show_all_diags);
g_signal_connect(menu_items.show_all_diags, "activate", G_CALLBACK(on_menu_invoked),
GUINT_TO_POINTER(KB_SHOW_ALL_DIAGS));
keybindings_set_item(group, KB_SHOW_ALL_DIAGS, NULL, 0, 0, "show_all_diags",
_("Show all diagnostics"), menu_items.show_all_diags);

gtk_container_add(GTK_CONTAINER(menu), gtk_separator_menu_item_new());

Expand All @@ -1551,6 +1573,20 @@ static void create_menu_items()
keybindings_set_item(group, KB_FIND_IMPLEMENTATIONS, NULL, 0, 0, "find_implementations",
_("Find implementations"), menu_items.goto_impl);

menu_items.highlight_occur = gtk_menu_item_new_with_mnemonic(_("_Highlight Symbol Occurrences"));
gtk_container_add(GTK_CONTAINER(menu), menu_items.highlight_occur);
g_signal_connect(menu_items.highlight_occur, "activate", G_CALLBACK(on_menu_invoked),
GUINT_TO_POINTER(KB_HIGHLIGHT_OCCUR));
keybindings_set_item(group, KB_HIGHLIGHT_OCCUR, NULL, 0, 0, "highlight_occurrences",
_("Highlight symbol occurrences"), menu_items.highlight_occur);

menu_items.highlight_clear = gtk_menu_item_new_with_mnemonic(_("_Clear Highlighted"));
gtk_container_add(GTK_CONTAINER(menu), menu_items.highlight_clear);
g_signal_connect(menu_items.highlight_clear, "activate", G_CALLBACK(on_menu_invoked),
GUINT_TO_POINTER(KB_HIGHLIGHT_CLEAR));
keybindings_set_item(group, KB_HIGHLIGHT_CLEAR, NULL, 0, 0, "highlight_clear",
_("Clear highlighted"), menu_items.highlight_clear);

gtk_container_add(GTK_CONTAINER(menu), gtk_separator_menu_item_new());

menu_items.rename_in_file = gtk_menu_item_new_with_mnemonic(_("_Rename Highlighted"));
Expand Down
Loading

0 comments on commit 584f299

Please sign in to comment.