Skip to content

lsp: Update to the latest version from the geany-lsp project #1421

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions lsp/README
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Autocompletion
Autocompletion works similarly to Geany's autocompletion feature. You can
configure keybindings triggering the autocompletion popup.

Function signagure
Function signature
------------------

When you type an open brace after a function name, the plugin displays the
Expand Down Expand Up @@ -240,9 +240,19 @@ checks and does not show any preview of the changes so it is best to use this
feature only after committing all modified files so you can
easily revert to a working state if needed. Since this is potentially a
dangerous operation, to prevent accidental renames, the "Rename" button in the
dialog is not selected by defalut and simply pressing enter just cancels the
dialog is not selected by default and simply pressing enter just cancels the
dialog.

Performance implications
========================

To provide all the features, this plugin needs to react on various events
(e.g. keystrokes) and also communicates heavily with the LSP server to send the
current document text and what kind of event happened.
These additional tasks cause more CPU usage of the Geany process and especially
the LSP server process, so they require also more power which might be
relevant if you are using a laptop on battery power.

Limitations
===========

Expand Down
23 changes: 19 additions & 4 deletions lsp/data/lsp.conf
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,13 @@ initialization_options={"compilationDatabasePath": "/home/some_user/"}
# communication between the client plugin and the server will be stored (can
# also be 'stdout' or 'stderr')
rpc_log=stdout
# Additional files and their mappings to LSP language IDs for which the server
# is used as well. The Nth item in the list is always a LSP language ID and the
# (N+1)th item is a glob pattern defining files for which the language ID is
# used
# Files and their mappings to LSP language IDs for which the server is used
# (in addition to the implicit mapping defined by the filetype name and the
# patterns assigned to this filetype in filetype_extensions.conf). The Nth
# item in the list is always the LSP language ID and the (N+1)th item is a glob
# pattern defining files for which the language ID is used
# To find supported language IDs consult the documentation of the respective
# LSP (or source code).
lang_id_mappings=dummylanguage;*.dummy


Expand Down Expand Up @@ -349,6 +352,18 @@ progress_bar_enable=false
#show_server_stderr=true


[HCL]
# For HCL/Terraform/OpenTofu LSP to work, first configure the corresponding filetype in Geany,
# see https://wiki.geany.org/config/hcl-terraform for details.
cmd=terraform-ls serve
semantic_tokens_enable=true
#rpc_log=stdout
#rpc_log_full=false
#show_server_stderr=true
# See https://github.com/hashicorp/terraform-ls/blob/main/docs/USAGE.md
lang_id_mappings=terraform;*.tf;terraform-vars;*.tfvars;terraform-stack;*.tfstack.hcl;terraform-deploy;*.tfdeploy.hcl


[Haskell]
cmd=haskell-language-server-wrapper --lsp
# Full semantic tokens work but are kind of useless as Scintilla already
Expand Down
23 changes: 13 additions & 10 deletions lsp/src/lsp-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,12 @@ static gboolean goto_provided(GeanyDocument *doc, gpointer user_data)
static gboolean goto_perform(GeanyDocument *doc, gint pos, gboolean definition, gpointer user_data)
{
LspServer *srv = lsp_server_get(doc);
gchar *iden = lsp_utils_get_current_iden(doc, pos, srv->config.word_chars);
gchar *iden;

if (!srv)
return FALSE;

iden = lsp_utils_get_current_iden(doc, pos, srv->config.word_chars);
if (!iden)
return FALSE;

Expand Down Expand Up @@ -618,6 +622,7 @@ static void on_document_filetype_set(G_GNUC_UNUSED GObject *obj, GeanyDocument *
return;

srv_old = lsp_server_get_for_ft(filetype_old);
lsp_server_clear_cached_ft(doc);
srv_new = lsp_server_get(doc);

if (srv_old == srv_new)
Expand Down Expand Up @@ -831,11 +836,6 @@ static gboolean on_editor_notify(G_GNUC_UNUSED GObject *obj, GeanyEditor *editor
}
else if (nt->nmhdr.code == SCN_UPDATEUI)
{
LspServer *srv = lsp_server_get_if_running(doc);

if (!srv)
return FALSE;

if (nt->updated & (SC_UPDATE_H_SCROLL | SC_UPDATE_V_SCROLL | SC_UPDATE_SELECTION /* when caret moves */))
{
lsp_signature_hide_calltip(doc);
Expand All @@ -848,12 +848,15 @@ static gboolean on_editor_notify(G_GNUC_UNUSED GObject *obj, GeanyEditor *editor
lsp_selection_clear_selections();
}

if (srv->config.highlighting_enable && perform_highlight &&
(nt->updated & SC_UPDATE_SELECTION))
if (perform_highlight && (nt->updated & SC_UPDATE_SELECTION))
{
lsp_highlight_schedule_request(doc);
LspServer *srv = lsp_server_get_if_running(doc);
if (srv && srv->config.highlighting_enable)
lsp_highlight_schedule_request(doc);
}
perform_highlight = TRUE;

if (nt->updated & SC_UPDATE_SELECTION)
perform_highlight = TRUE;
}
else if (nt->nmhdr.code == SCN_CHARADDED)
{
Expand Down
52 changes: 44 additions & 8 deletions lsp/src/lsp-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
# include "spawn/lspunixoutputstream.h"
#endif

#include <unistd.h>

#define CACHED_FILETYPE_KEY "lsp_server_cached_filetype"
#define CACHED_LANG_ID_KEY "lsp_server_cached_lang_id"

static void start_lsp_server(LspServer *server);
static LspServer *lsp_server_init(gint ft);
Expand Down Expand Up @@ -1178,15 +1182,14 @@ static gboolean is_lsp_valid_for_doc(LspServerConfig *cfg, GeanyDocument *doc)
#define g_pattern_spec_match_string g_pattern_match_string
#endif

GeanyFiletype *lsp_server_get_ft(GeanyDocument *doc, gchar **lsp_lang_id)
static GeanyFiletype *lsp_server_get_ft_impl(GeanyDocument *doc, gchar **lsp_lang_id)
{
LspServer *srv;
guint i;

if (!lsp_servers || (!doc->real_path || doc->file_type->id != GEANY_FILETYPES_NONE))
if (!lsp_servers || !doc->real_path)
{
if (lsp_lang_id)
*lsp_lang_id = lsp_utils_get_lsp_lang_id(doc);
*lsp_lang_id = lsp_utils_get_lsp_lang_id(doc);
return doc->file_type;
}

Expand Down Expand Up @@ -1217,8 +1220,7 @@ GeanyFiletype *lsp_server_get_ft(GeanyDocument *doc, gchar **lsp_lang_id)

if (ret)
{
if (lsp_lang_id)
*lsp_lang_id = g_strdup(lang_id);
*lsp_lang_id = g_strdup(lang_id);
return ret;
}
}
Expand All @@ -1227,10 +1229,38 @@ GeanyFiletype *lsp_server_get_ft(GeanyDocument *doc, gchar **lsp_lang_id)
}
}

*lsp_lang_id = lsp_utils_get_lsp_lang_id(doc);
return doc->file_type;
}


void lsp_server_clear_cached_ft(GeanyDocument *doc)
{
plugin_set_document_data(geany_plugin, doc, CACHED_FILETYPE_KEY, NULL);
plugin_set_document_data_full(geany_plugin, doc, CACHED_LANG_ID_KEY, NULL, g_free);
}


GeanyFiletype *lsp_server_get_ft(GeanyDocument *doc, gchar **lsp_lang_id)
{
GeanyFiletype *ft = plugin_get_document_data(geany_plugin, doc, CACHED_FILETYPE_KEY);
gchar *lang_id;

if (ft)
{
if (lsp_lang_id)
*lsp_lang_id = g_strdup(plugin_get_document_data(geany_plugin, doc, CACHED_LANG_ID_KEY));
return ft;
}

ft = lsp_server_get_ft_impl(doc, &lang_id);
if (lsp_lang_id)
*lsp_lang_id = lsp_utils_get_lsp_lang_id(doc);
*lsp_lang_id = g_strdup(lang_id);

return doc->file_type;
plugin_set_document_data(geany_plugin, doc, CACHED_FILETYPE_KEY, ft);
plugin_set_document_data_full(geany_plugin, doc, CACHED_LANG_ID_KEY, lang_id, g_free);

return ft;
}


Expand Down Expand Up @@ -1399,6 +1429,12 @@ void lsp_server_init_all(void)
if (!servers_in_shutdown)
servers_in_shutdown = g_ptr_array_new_full(0, (GDestroyNotify)free_server);

foreach_document(i)
{
GeanyDocument *doc = documents[i];
lsp_server_clear_cached_ft(doc);
}

lsp_servers = g_ptr_array_new_full(0, (GDestroyNotify)stop_and_free_server);

for (i = 0; (ft = filetypes_index(i)); i++)
Expand Down
1 change: 1 addition & 0 deletions lsp/src/lsp-server.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ LspServer *lsp_server_get_if_running(GeanyDocument *doc);
LspServerConfig *lsp_server_get_all_section_config(void);
gboolean lsp_server_is_usable(GeanyDocument *doc);
GeanyFiletype *lsp_server_get_ft(GeanyDocument *doc, gchar **lsp_lang_id);
void lsp_server_clear_cached_ft(GeanyDocument *doc);

void lsp_server_stop_all(gboolean wait);
void lsp_server_init_all(void);
Expand Down