diff --git a/include/eepp/core/string.hpp b/include/eepp/core/string.hpp index efa8c7025..71786d54b 100644 --- a/include/eepp/core/string.hpp +++ b/include/eepp/core/string.hpp @@ -247,7 +247,7 @@ class EE_API String { static bool contains( const String& haystack, const String& needle ); static int fuzzyMatch( const std::string& string, const std::string& pattern, - bool allowUneven = false ); + bool allowUneven = false, bool permissive = false ); /** Replace all occurrences of the search string with the replacement string. */ static void replaceAll( std::string& target, const std::string& that, const std::string& with ); diff --git a/src/eepp/core/string.cpp b/src/eepp/core/string.cpp index 4edb1be8e..ba5909a17 100644 --- a/src/eepp/core/string.cpp +++ b/src/eepp/core/string.cpp @@ -640,7 +640,8 @@ String::StringBaseType String::lastChar() const { } // Lite (https://github.com/rxi/lite) fuzzy match implementation -template constexpr int tFuzzyMatch( const T* str, const T* ptn, bool allowUneven ) { +template +constexpr int tFuzzyMatch( const T* str, const T* ptn, bool allowUneven, bool permissive ) { int score = 0; int run = 0; while ( *str && *ptn ) { @@ -660,11 +661,12 @@ template constexpr int tFuzzyMatch( const T* str, const T* ptn, boo } if ( *ptn && !allowUneven ) return INT_MIN; - return score - strlen( str ); + return score - ( permissive ? 0 : strlen( str ) ); } -int String::fuzzyMatch( const std::string& string, const std::string& pattern, bool allowUneven ) { - return tFuzzyMatch( string.c_str(), pattern.c_str(), allowUneven ); +int String::fuzzyMatch( const std::string& string, const std::string& pattern, bool allowUneven, + bool permissive ) { + return tFuzzyMatch( string.c_str(), pattern.c_str(), allowUneven, permissive ); } std::vector String::stringToUint8( const std::string& str ) { diff --git a/src/eepp/ui/doc/syntaxdefinitionmanager.cpp b/src/eepp/ui/doc/syntaxdefinitionmanager.cpp index 3b87d8b69..47176f0fe 100644 --- a/src/eepp/ui/doc/syntaxdefinitionmanager.cpp +++ b/src/eepp/ui/doc/syntaxdefinitionmanager.cpp @@ -546,7 +546,8 @@ static void addTypeScript() { { "throw", "keyword" }, { "true", "literal" }, { "try", "keyword" }, { "type", "keyword2" }, { "typeof", "keyword" }, { "undefined", "literal" }, { "var", "keyword" }, { "void", "keyword" }, { "while", "keyword" }, - { "with", "keyword" }, { "yield", "keyword" }, { "unknown", "keyword2" } }, + { "with", "keyword" }, { "yield", "keyword" }, { "unknown", "keyword2" }, + { "namespace", "keyword" } }, "//" } ); SyntaxDefinitionManager::instance()->add( diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index 6115a4a37..ff9c8ffad 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -2513,7 +2513,7 @@ void TextDocument::toggleLineComments() { std::string commentText = comment + " "; TextRange selection = getSelection( true ); bool uncomment = true; - for ( Int64 i = selection.start().line(); i < selection.end().line(); i++ ) { + for ( Int64 i = selection.start().line(); i <= selection.end().line(); i++ ) { const String& text = mLines[i].getText(); if ( text.find_first_not_of( " \t\n" ) != std::string::npos && text.find( commentText ) == std::string::npos ) { diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 1cf91efa0..37dfa910d 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -664,7 +664,7 @@ void App::updateRecentFiles() { menu->removeEventsOfType( Event::OnItemClicked ); if ( mRecentFiles.empty() ) return; - menu->add( i18n( "reopen_closed_editor", "Reopen Closed Editor" ), nullptr, + menu->add( i18n( "reopen_closed_document", "Reopen Closed Document" ), nullptr, getKeybind( "reopen-closed-tab" ) ) ->setId( "reopen-closed-tab" ) ->setEnabled( !mRecentClosedFiles.empty() ); diff --git a/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp b/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp index fad34c507..39951fc14 100644 --- a/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp +++ b/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp @@ -45,7 +45,9 @@ fuzzyMatchSymbols( const std::vector& sy int score; for ( const auto& symbols : symbolsVec ) { for ( const auto& symbol : *symbols ) { - if ( ( score = String::fuzzyMatch( symbol.text, match ) ) > 0 ) { + if ( ( score = String::fuzzyMatch( symbol.text, match, false, + symbol.kind != LSPCompletionItemKind::Text ) ) > + 0 ) { if ( std::find( matches.begin(), matches.end(), symbol ) == matches.end() ) { symbol.setScore( score ); matches.push_back( symbol ); @@ -496,6 +498,13 @@ AutoCompletePlugin::processCodeCompletion( const LSPCompletionList& completion ) fuzzySuggestions = fuzzyMatchSymbols( { &suggestions, &symbols }, symbol, eemax( 100UL, suggestions.size() ) ); } + + if ( fuzzySuggestions.empty() && !suggestions.empty() ) { + for ( const auto& suggestion : suggestions ) + if ( String::startsWith( suggestion.text, symbol ) ) + fuzzySuggestions.emplace_back( std::move( suggestion ) ); + } + Lock l( mSuggestionsMutex ); mSuggestions = fuzzySuggestions; } diff --git a/src/tools/ecode/plugins/autocomplete/autocompleteplugin.hpp b/src/tools/ecode/plugins/autocomplete/autocompleteplugin.hpp index ef9a58aa2..f416c375b 100644 --- a/src/tools/ecode/plugins/autocomplete/autocompleteplugin.hpp +++ b/src/tools/ecode/plugins/autocomplete/autocompleteplugin.hpp @@ -58,7 +58,7 @@ class AutoCompletePlugin : public Plugin { "Auto complete shows the completion popup as you type, so you can fill " "in long words by typing only a few characters.", AutoCompletePlugin::New, - { 0, 2, 1 } }; + { 0, 2, 2 } }; } static UICodeEditorPlugin* New( PluginManager* pluginManager ); diff --git a/src/tools/ecode/plugins/formatter/formatterplugin.hpp b/src/tools/ecode/plugins/formatter/formatterplugin.hpp index b3fce220a..94cda90eb 100644 --- a/src/tools/ecode/plugins/formatter/formatterplugin.hpp +++ b/src/tools/ecode/plugins/formatter/formatterplugin.hpp @@ -34,7 +34,7 @@ class FormatterPlugin : public Plugin { static PluginDefinition Definition() { return { "autoformatter", "Auto Formatter", "Enables the code formatter/prettifier plugin.", - FormatterPlugin::New, { 0, 2, 1 }, FormatterPlugin::NewSync }; + FormatterPlugin::New, { 0, 2, 2 }, FormatterPlugin::NewSync }; } static UICodeEditorPlugin* New( PluginManager* pluginManager ); diff --git a/src/tools/ecode/plugins/linter/linterplugin.hpp b/src/tools/ecode/plugins/linter/linterplugin.hpp index 9b2739d64..df8c59afa 100644 --- a/src/tools/ecode/plugins/linter/linterplugin.hpp +++ b/src/tools/ecode/plugins/linter/linterplugin.hpp @@ -56,7 +56,7 @@ class LinterPlugin : public Plugin { "Use static code analysis tool used to flag programming errors, bugs, " "stylistic errors, and suspicious constructs.", LinterPlugin::New, - { 0, 2, 1 }, + { 0, 2, 2 }, LinterPlugin::NewSync }; } diff --git a/src/tools/ecode/plugins/lsp/lspclientplugin.hpp b/src/tools/ecode/plugins/lsp/lspclientplugin.hpp index 309312944..9efebb112 100644 --- a/src/tools/ecode/plugins/lsp/lspclientplugin.hpp +++ b/src/tools/ecode/plugins/lsp/lspclientplugin.hpp @@ -26,7 +26,7 @@ class LSPClientPlugin : public Plugin { public: static PluginDefinition Definition() { return { "lspclient", "LSP Client", "Language Server Protocol Client.", - LSPClientPlugin::New, { 0, 2, 1 }, LSPClientPlugin::NewSync }; + LSPClientPlugin::New, { 0, 2, 2 }, LSPClientPlugin::NewSync }; } static UICodeEditorPlugin* New( PluginManager* pluginManager );