Some snippets improvements to support insertTextFormat (SpartanJ/ecode/discussions#929).

Closes SpartanJ/ecode#933
This commit is contained in:
Martín Lucas Golini
2026-07-18 13:31:06 -03:00
parent 0a7984b17d
commit f5ce1589e3
6 changed files with 40 additions and 24 deletions

View File

@@ -12,9 +12,9 @@ SyntaxDefinition& addObjectiveC() {
{
{ { "//.-\n" }, "comment" },
{ { "/%*", "%*/" }, "comment" },
{ { "(#%s*include)%s+([<%\"][%w%d%.%\\%/%_%-]+[>%\"])" },
{ { "(#%s*include)%s+([<%\"][%w%d%.%\\%/%_%-%+]+[>%\"])" },
{ "keyword", "keyword", "literal" } },
{ { "(#%s*import)%s+([<%\"][%w%d%.%\\%/%_%-]+[>%\"])" },
{ { "(#%s*import)%s+([<%\"][%w%d%.%\\%/%_%-%+]+[>%\"])" },
{ "keyword", "keyword", "literal" } },
{ { "\"", "[\"\n]", "\\" }, "string" },
{ { "'", "'", "\\" }, "string" },

View File

@@ -20,9 +20,9 @@ SyntaxDefinition& addObjectiveCPP() {
{ { "/%*", "%*/" }, "comment" },
{ { "\"", "[\"\n]", "\\" }, "string" },
{ { "'", "'", "\\" }, "string" },
{ { "(#%s*include)%s+([<%\"][%w%d%.%\\%/%_%-]+[>%\"])" },
{ { "(#%s*include)%s+([<%\"][%w%d%.%\\%/%_%-%+]+[>%\"])" },
{ "keyword", "keyword", "literal" } },
{ { "(#%s*import)%s+([<%\"][%w%d%.%\\%/%_%-]+[>%\"])" },
{ { "(#%s*import)%s+([<%\"][%w%d%.%\\%/%_%-%+]+[>%\"])" },
{ "keyword", "keyword", "literal" } },
{ { "cpp_number_parser" }, "number", "", SyntaxPatternMatchType::Parser },
{ { "[%+%-=/%*%^%%<>!~|&]" }, "operator" },

View File

@@ -21,7 +21,7 @@ using namespace std::literals;
namespace ecode {
static constexpr auto SNIPPET_PTRN1 = "%$%{%d+%}"sv;
static constexpr auto SNIPPET_PTRN2 = "%$%{%d+%:([%w,.%s%+%-]+)}"sv;
static constexpr auto SNIPPET_PTRN2 = "%$%{%d+%:([%w,.%s%+%-_]+)}"sv;
static constexpr auto SNIPPET_PTRN3 = "%$%d+"sv;
static json getURIJSON( TextDocument* doc, const PluginIDType& id ) {
@@ -789,12 +789,13 @@ void AutoCompletePlugin::tryStartSnippetNav( const Suggestion& suggestion, UICod
}
bool AutoCompletePlugin::hasCompleteSteps( const Suggestion& suggestion ) {
if ( suggestion.kind != LSPCompletionItemKind::Snippet )
return false;
if ( LuaPattern::hasMatches( suggestion.insertText, SNIPPET_PTRN1 ) ||
LuaPattern::hasMatches( suggestion.insertText, SNIPPET_PTRN2 ) ||
LuaPattern::hasMatches( suggestion.insertText, SNIPPET_PTRN3 ) ) {
return true;
if ( suggestion.kind == LSPCompletionItemKind::Snippet ||
suggestion.insertTextFormat == LSPInsertTextFormat::Snippet ) {
if ( LuaPattern::hasMatches( suggestion.insertText, SNIPPET_PTRN1 ) ||
LuaPattern::hasMatches( suggestion.insertText, SNIPPET_PTRN2 ) ||
LuaPattern::hasMatches( suggestion.insertText, SNIPPET_PTRN3 ) ) {
return true;
}
}
return false;
}
@@ -809,15 +810,17 @@ AutoCompletePlugin::processCodeCompletion( const LSPCompletionList& completion )
LSPCompletionList& wcompletion = const_cast<LSPCompletionList&>( completion );
for ( auto& item : wcompletion.items ) {
if ( !item.textEdit.text.empty() ) {
suggestions.push_back(
{ item.kind, std::move( item.label.empty() ? item.insertText : item.label ),
std::move( item.detail ), std::move( item.sortText ), item.textEdit.range,
std::move( item.textEdit.text ), std::move( item.documentation ) } );
suggestions.push_back( { item.kind,
std::move( item.label.empty() ? item.insertText : item.label ),
std::move( item.detail ), std::move( item.sortText ),
item.textEdit.range, std::move( item.textEdit.text ),
std::move( item.documentation ), item.insertTextFormat } );
} else if ( !item.insertText.empty() ) {
suggestions.push_back(
{ item.kind, std::move( item.label.empty() ? item.insertText : item.label ),
std::move( item.detail ), std::move( item.sortText ), item.textEdit.range,
std::string{ item.insertText }, std::move( item.documentation ) } );
suggestions.push_back( { item.kind,
std::move( item.label.empty() ? item.insertText : item.label ),
std::move( item.detail ), std::move( item.sortText ),
item.textEdit.range, std::string{ item.insertText },
std::move( item.documentation ), item.insertTextFormat } );
} else {
suggestions.push_back( { item.kind,
std::move( item.filterText ),
@@ -825,7 +828,8 @@ AutoCompletePlugin::processCodeCompletion( const LSPCompletionList& completion )
std::move( item.sortText ),
{},
"",
std::move( item.documentation ) } );
std::move( item.documentation ),
item.insertTextFormat } );
}
}
if ( suggestions.empty() || !mSuggestionsEditor )

View File

@@ -27,6 +27,7 @@ class AutoCompletePlugin : public Plugin {
std::string sortText;
TextRange range;
std::string insertText;
LSPInsertTextFormat insertTextFormat{ LSPInsertTextFormat::PlainText };
double score{ 0 };
LSPMarkupContent documentation;
@@ -38,13 +39,15 @@ class AutoCompletePlugin : public Plugin {
Suggestion( LSPCompletionItemKind kind, std::string&& text, std::string&& detail,
std::string&& sortText, const TextRange& range, std::string&& insertText,
LSPMarkupContent&& doc ) :
LSPMarkupContent&& doc,
LSPInsertTextFormat insertTextFormat ) :
kind( kind ),
text( std::move( text ) ),
detail( std::move( detail ) ),
sortText( sortText.empty() ? std::string{ this->text } : std::move( sortText ) ),
range( range ),
insertText( std::move( insertText ) ),
insertTextFormat( insertTextFormat ),
documentation( doc ) {};
bool operator<( const Suggestion& other ) const { return getCmpStr() < other.getCmpStr(); }

View File

@@ -86,6 +86,7 @@ static const char* MEMBER_SUCCESS = "success";
static const char* MEMBER_LIMIT = "limit";
static const char* MEMBER_OPTIONS = "options";
static const char* MEMBER_PREVIOUS_RESULT_IDS = "previousResultIds";
static const char* MEMBER_INSERT_TEXT_FORMAT = "insertTextFormat";
static json newRequest( const std::string& method, const json& params = json{} ) {
json j;
@@ -885,9 +886,11 @@ static LSPCompletionList parseDocumentCompletion( const json& result ) {
item.contains( "additionalTextEdits" )
? parseTextEditArray( item.at( "additionalTextEdits" ) )
: std::vector<LSPTextEdit>{};
ret.items.push_back( { label, kind, detail, doc, sortText, insertText, filterText,
textEdit, additionalTextEdits } );
auto itf = item.value( MEMBER_INSERT_TEXT_FORMAT, 1 );
LSPInsertTextFormat insertTextFormat =
itf == 2 ? LSPInsertTextFormat::Snippet : LSPInsertTextFormat::PlainText;
ret.items.push_back( { label, kind, detail, doc, sortText, insertText, insertTextFormat,
filterText, textEdit, additionalTextEdits } );
}
#ifndef EE_DEBUG
} catch ( const json::exception& err ) {

View File

@@ -531,6 +531,11 @@ class LSPCompletionItemHelper {
}
};
enum class LSPInsertTextFormat {
PlainText = 1,
Snippet = 2,
};
struct LSPCompletionItem {
std::string label;
LSPCompletionItemKind kind;
@@ -538,6 +543,7 @@ struct LSPCompletionItem {
LSPMarkupContent documentation;
std::string sortText;
std::string insertText;
LSPInsertTextFormat insertTextFormat{ LSPInsertTextFormat::PlainText };
std::string filterText;
LSPTextEdit textEdit;
std::vector<LSPTextEdit> additionalTextEdits;