LSP: When supported use snippet insert mode to add closing braces

This commit is contained in:
HolonProduction
2026-01-04 16:22:57 +01:00
parent 64596092ae
commit 7ab735fbbb
5 changed files with 122 additions and 62 deletions
@@ -192,7 +192,26 @@ void GDScriptLanguageProtocol::_bind_methods() {
#endif // !DISABLE_DEPRECATED
}
Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) {
template <typename T>
Variant get_deep(Variant p_dict, Variant p_default, T p_key) {
if (p_dict.get_type() != Variant::DICTIONARY) {
return p_default;
}
return p_dict.operator Dictionary().get(p_key, p_default);
}
template <typename T1, typename... T2>
Variant get_deep(Variant p_dict, Variant p_default, T1 p_key1, T2... p_key2) {
if (p_dict.get_type() != Variant::DICTIONARY || !p_dict.operator Dictionary().has(p_key1)) {
return p_default;
}
return get_deep(p_dict.operator Dictionary()[p_key1], p_default, p_key2...);
}
Variant GDScriptLanguageProtocol::initialize(const Dictionary &p_params) {
LSP_CLIENT_V(Variant());
LSP::InitializeResult ret;
{
@@ -252,6 +271,11 @@ Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) {
_initialized = true;
}
// Handle client capabilities.
Dictionary capabilities = p_params["capabilities"];
client->behavior.use_snippets_for_brace_completion = get_deep(capabilities, false,
"textDocument", "completion", "completionItem", "snippetSupport");
return ret.to_json();
}
@@ -511,6 +535,81 @@ void GDScriptLanguageProtocol::lsp_did_close(const Dictionary &p_params) {
scene_cache.unload(path);
}
Array GDScriptLanguageProtocol::lsp_completion(const Dictionary &p_params) {
Array arr;
LSP_CLIENT_V(arr);
LSP::CompletionParams params;
params.load(p_params);
Dictionary request_data = params.to_json();
List<ScriptLanguage::CodeCompletionOption> options;
get_workspace()->completion(params, &options);
if (!options.is_empty()) {
int i = 0;
arr.resize(options.size());
for (const ScriptLanguage::CodeCompletionOption &option : options) {
LSP::CompletionItem item;
item.label = option.display;
item.data = request_data;
item.insertText = option.insert_text;
// LSP clients won't autoclose brackets.
if (client->behavior.use_snippets_for_brace_completion) {
// Use snippet insert mode to insert closing brace as well.
if (item.insertText.ends_with("(")) {
item.insertText += "$1)";
item.insertTextFormat = LSP::InsertTextFormat::Snippet;
}
} else {
// Trim braces.
item.insertText = item.insertText.trim_suffix("(");
}
switch (option.kind) {
case ScriptLanguage::CODE_COMPLETION_KIND_ENUM:
item.kind = LSP::CompletionItemKind::Enum;
break;
case ScriptLanguage::CODE_COMPLETION_KIND_CLASS:
item.kind = LSP::CompletionItemKind::Class;
break;
case ScriptLanguage::CODE_COMPLETION_KIND_MEMBER:
item.kind = LSP::CompletionItemKind::Property;
break;
case ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION:
item.kind = LSP::CompletionItemKind::Method;
break;
case ScriptLanguage::CODE_COMPLETION_KIND_SIGNAL:
item.kind = LSP::CompletionItemKind::Event;
break;
case ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT:
item.kind = LSP::CompletionItemKind::Constant;
break;
case ScriptLanguage::CODE_COMPLETION_KIND_VARIABLE:
item.kind = LSP::CompletionItemKind::Variable;
break;
case ScriptLanguage::CODE_COMPLETION_KIND_FILE_PATH:
item.kind = LSP::CompletionItemKind::File;
break;
case ScriptLanguage::CODE_COMPLETION_KIND_NODE_PATH:
item.kind = LSP::CompletionItemKind::Snippet;
break;
case ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT:
item.kind = LSP::CompletionItemKind::Text;
break;
default: {
}
}
arr[i] = item.to_json();
i++;
}
}
return arr;
}
void GDScriptLanguageProtocol::resolve_related_symbols(const LSP::TextDocumentPositionParams &p_doc_pos, List<const LSP::DocumentSymbol *> &r_list) {
LSP_CLIENT;