diff --git a/bin/assets/plugins/formatters.json b/bin/assets/plugins/formatters.json index 819d74315..ecced69f4 100644 --- a/bin/assets/plugins/formatters.json +++ b/bin/assets/plugins/formatters.json @@ -13,8 +13,8 @@ "url": "https://prettier.io" }, { - "language": ["c", "cpp", "objective-c", "java"], - "file_patterns": ["%.inl$", "%.cpp$", "%.hpp$", "%.cc$", "%.cxx$", "%.c++$", "%.hh$", "%.hxx$", "%.h++$", "%.objcpp$", "%.m$", "%.java$"], + "language": ["c", "cpp", "objective-c", "objective-cpp", "java"], + "file_patterns": ["%.inl$", "%.cpp$", "%.hpp$", "%.cc$", "%.cxx$", "%.c++$", "%.hh$", "%.hxx$", "%.h++$", "%.objcpp$", "%.m$", "%.mm$", "%.java$"], "command": "clang-format --style=file $FILENAME", "url": "https://clang.llvm.org/docs/ClangFormat.html", "prefer_lsp_formatter": true diff --git a/bin/assets/plugins/lspclient.json b/bin/assets/plugins/lspclient.json index 321e8e406..d86d8238b 100644 --- a/bin/assets/plugins/lspclient.json +++ b/bin/assets/plugins/lspclient.json @@ -92,6 +92,12 @@ "share_process": true, "file_patterns": ["%.m$"] }, + { + "language": "objective-cpp", + "use": "clangd", + "share_process": true, + "file_patterns": ["%.mm$"] + }, { "language": "d", "name": "serve-d", diff --git a/include/eepp/ui/doc/hextlanguagetype.hpp b/include/eepp/ui/doc/hextlanguagetype.hpp new file mode 100644 index 000000000..32e6a1f24 --- /dev/null +++ b/include/eepp/ui/doc/hextlanguagetype.hpp @@ -0,0 +1,16 @@ +#pragma once +#include + +namespace EE { namespace UI { namespace Doc { + +enum class HExtLanguageType { AutoDetect, C, CPP, ObjectiveC, ObjectiveCPP }; + +struct HExtLanguageTypeHelper { + static HExtLanguageType detectLanguage( const std::string& buffer ); + + static std::string toString( HExtLanguageType langType ); + + static HExtLanguageType fromString( const std::string& langType ); +}; + +}}} // namespace EE::UI::Doc diff --git a/include/eepp/ui/doc/syntaxdefinitionmanager.hpp b/include/eepp/ui/doc/syntaxdefinitionmanager.hpp index 015b65c77..b906c2957 100644 --- a/include/eepp/ui/doc/syntaxdefinitionmanager.hpp +++ b/include/eepp/ui/doc/syntaxdefinitionmanager.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -33,13 +34,14 @@ class EE_API SyntaxDefinitionManager { bool extensionCanRepresentManyLanguages( std::string extension ) const; - const SyntaxDefinition& getByExtension( const std::string& filePath, - bool hFileAsCPP = false ) const; + const SyntaxDefinition& getByExtension( const std::string& filePath ) const; - const SyntaxDefinition& getByHeader( const std::string& header, bool hFileAsCPP = false ) const; + const SyntaxDefinition& + getByHeader( const std::string& header, const std::string& filePath = "", + HExtLanguageType hLangType = HExtLanguageType::AutoDetect ) const; const SyntaxDefinition& find( const std::string& filePath, const std::string& header, - bool hFileAsCPP = false ); + HExtLanguageType hLangType = HExtLanguageType::AutoDetect ); const SyntaxDefinition& findFromString( const std::string_view& str ) const; @@ -91,6 +93,10 @@ class EE_API SyntaxDefinitionManager { mutable Mutex mMutex; std::optional getLanguageIndex( const std::string& langName ); + + const SyntaxDefinition* needsHFallback( HExtLanguageType langType, const std::string& lspName, + const std::string& ext, + const std::string& buffer ) const; }; }}} // namespace EE::UI::Doc diff --git a/include/eepp/ui/doc/textdocument.hpp b/include/eepp/ui/doc/textdocument.hpp index 6768978a1..d7ba953fe 100644 --- a/include/eepp/ui/doc/textdocument.hpp +++ b/include/eepp/ui/doc/textdocument.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -650,9 +651,9 @@ class EE_API TextDocument { TextRange getActiveClientVisibleRange() const; - bool hAsCpp() const; + HExtLanguageType hExtLanguageType() const; - void setHAsCpp( bool hAsCpp ); + void setHExtLanguageType( HExtLanguageType hExtLanguageType ); const Uint64& getModificationId() const; @@ -728,7 +729,7 @@ class EE_API TextDocument { bool mSaving{ false }; bool mDeleteOnClose{ false }; bool mMightBeBinary{ false }; - bool mHAsCpp{ false }; + HExtLanguageType mHExtLanguageType{ false }; bool mLastCursorChangeWasInteresting{ false }; bool mDoingTextInput{ false }; bool mInsertingText{ false }; diff --git a/projects/linux/ee.files b/projects/linux/ee.files index 0471e1f3e..a80e97b99 100644 --- a/projects/linux/ee.files +++ b/projects/linux/ee.files @@ -975,6 +975,9 @@ ../../src/eepp/ui/css/stylesheetvariable.cpp ../../src/eepp/ui/css/timingfunction.cpp ../../src/eepp/ui/css/transitiondefinition.cpp +../../src/eepp/ui/doc/documentview.cpp +../../src/eepp/ui/doc/foldrangeservice.cpp +../../src/eepp/ui/doc/hextlanguagetype.cpp ../../src/eepp/ui/doc/languages/cmake.cpp ../../src/eepp/ui/doc/languages/cmake.hpp ../../src/eepp/ui/doc/languages/configfile.cpp @@ -1483,6 +1486,8 @@ ../../src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objeck.hpp ../../src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objective-c.cpp ../../src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objective-c.hpp +../../src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objective-cpp.cpp +../../src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objective-cpp.hpp ../../src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/ocaml.cpp ../../src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/ocaml.hpp ../../src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/odin.cpp diff --git a/src/eepp/ui/doc/hextlanguagetype.cpp b/src/eepp/ui/doc/hextlanguagetype.cpp new file mode 100644 index 000000000..2e27139e0 --- /dev/null +++ b/src/eepp/ui/doc/hextlanguagetype.cpp @@ -0,0 +1,174 @@ +#include +#include + +#include + +namespace EE { namespace UI { namespace Doc { + +// Checks if a character is a "word boundary". +inline bool isWordBoundary( char c ) { + return !std::isalnum( static_cast( c ) ) && c != '_'; +} + +// Finds a keyword as a whole word (e.g., finds "class" but not "subclass"). +bool findStandaloneWord( const std::string& line, std::string_view keyword ) { + size_t pos = 0; + while ( ( pos = line.find( keyword, pos ) ) != std::string::npos ) { + // Check character before the keyword + bool preBoundary = ( pos == 0 ) || isWordBoundary( line[pos - 1] ); + + // Check character after the keyword + size_t endPos = pos + keyword.length(); + bool postBoundary = ( endPos == line.length() ) || isWordBoundary( line[endPos] ); + + if ( preBoundary && postBoundary ) { + return true; // Found a standalone occurrence + } + pos = endPos; // Continue search after this instance + } + return false; +} + +/** + * @brief Analyzes the content of a header file to determine its programming language. + * + * This function scans a string buffer for language-specific keywords and syntax + * to distinguish between C, C++, Objective-C, and Objective-C++. It uses a + * fast, heuristic-based approach optimized with std::array and std::string_view. + * + * @param buffer A std::string containing the source code from the .h file. + * @return HExtLanguageType The detected language. + */ +HExtLanguageType HExtLanguageTypeHelper::detectLanguage( const std::string& buffer ) { + bool hasCppFeature = false; + bool hasObjcFeature = false; + + // Objective-C features + static constexpr std::array objcKeywords = { + "@interface", "@protocol", "@property", "@implementation", "@end", "@class" }; + static constexpr std::string_view objcDirective = "#import"; + + // C++ features + static constexpr std::array cppStandaloneKeywords = { + "class", "namespace", "template", "virtual", "override", + "final", "public", "private", "protected" }; + static constexpr std::array cppTokens = { "::", "template<" }; + + std::stringstream ss( buffer ); + std::string line; + bool inMultilineComment = false; + + while ( std::getline( ss, line ) ) { + std::string processedLine = line; + + if ( inMultilineComment ) { + size_t endCommentPos = processedLine.find( "*/" ); + if ( endCommentPos != std::string::npos ) { + processedLine = processedLine.substr( endCommentPos + 2 ); + inMultilineComment = false; + } else { + continue; + } + } + + size_t startCommentPos = processedLine.find( "/*" ); + if ( startCommentPos != std::string::npos ) { + size_t endCommentPos = processedLine.find( "*/", startCommentPos ); + if ( endCommentPos != std::string::npos ) { + processedLine.erase( startCommentPos, endCommentPos - startCommentPos + 2 ); + } else { + inMultilineComment = true; + processedLine = processedLine.substr( 0, startCommentPos ); + } + } + + size_t commentPos = processedLine.find( "//" ); + if ( commentPos != std::string::npos ) { + processedLine = processedLine.substr( 0, commentPos ); + } + + if ( !hasObjcFeature ) { + std::string_view lineView = processedLine; + lineView.remove_prefix( + std::min( lineView.find_first_not_of( " \t" ), lineView.size() ) ); + if ( lineView.rfind( objcDirective, 0 ) == 0 ) { + hasObjcFeature = true; + } else { + for ( const auto& keyword : objcKeywords ) { + if ( processedLine.find( keyword ) != std::string::npos ) { + hasObjcFeature = true; + break; + } + } + } + } + + if ( !hasCppFeature ) { + for ( const auto& keyword : cppStandaloneKeywords ) { + if ( findStandaloneWord( processedLine, keyword ) ) { + hasCppFeature = true; + break; + } + } + if ( !hasCppFeature ) { + for ( const auto& token : cppTokens ) { + if ( processedLine.find( token ) != std::string::npos ) { + hasCppFeature = true; + break; + } + } + } + if ( !hasCppFeature ) { + size_t ampPos = processedLine.find( '&' ); + if ( ampPos != std::string::npos && ampPos + 1 < processedLine.length() && + processedLine[ampPos + 1] != '&' ) { + hasCppFeature = true; + } + } + } + + if ( hasCppFeature && hasObjcFeature ) + break; + } + + if ( hasCppFeature && hasObjcFeature ) + return HExtLanguageType::ObjectiveCPP; + + if ( hasObjcFeature ) + return HExtLanguageType::ObjectiveC; + + if ( hasCppFeature ) + return HExtLanguageType::CPP; + + return HExtLanguageType::C; +} + +std::string HExtLanguageTypeHelper::toString( HExtLanguageType langType ) { + switch ( langType ) { + case HExtLanguageType::AutoDetect: + return "autodetect"; + case HExtLanguageType::C: + return "c"; + case HExtLanguageType::CPP: + return "cpp"; + case HExtLanguageType::ObjectiveC: + return "objective-c"; + case HExtLanguageType::ObjectiveCPP: + return "objective-cpp"; + } + return "autodetect"; +} + +HExtLanguageType HExtLanguageTypeHelper::fromString( const std::string& langType ) { + if ( langType == "c" ) + return HExtLanguageType::C; + if ( langType == "cpp" ) + return HExtLanguageType::CPP; + if ( langType == "objective-c" ) + return HExtLanguageType::ObjectiveC; + if ( langType == "objective-cpp" ) + return HExtLanguageType::ObjectiveCPP; + return HExtLanguageType::AutoDetect; +} + +}}} // namespace EE::UI::Doc diff --git a/src/eepp/ui/doc/syntaxdefinitionmanager.cpp b/src/eepp/ui/doc/syntaxdefinitionmanager.cpp index 548531394..8c1aa34dd 100644 --- a/src/eepp/ui/doc/syntaxdefinitionmanager.cpp +++ b/src/eepp/ui/doc/syntaxdefinitionmanager.cpp @@ -1231,8 +1231,31 @@ bool SyntaxDefinitionManager::extensionCanRepresentManyLanguages( std::string ex return false; } -const SyntaxDefinition& SyntaxDefinitionManager::getByExtension( const std::string& filePath, - bool hFileAsCPP ) const { +const SyntaxDefinition* SyntaxDefinitionManager::needsHFallback( HExtLanguageType langType, + const std::string& lspName, + const std::string& ext, + const std::string& buffer ) const { + if ( lspName != "c" || !( ext == "h" || ext == ".h" || ext == "%.h$" || ext == "%.h%.in$" ) ) + return nullptr; + switch ( langType ) { + case HExtLanguageType::AutoDetect: { + return &getByLSPName( HExtLanguageTypeHelper::toString( + HExtLanguageTypeHelper::detectLanguage( buffer ) ) ); + } + case HExtLanguageType::C: + return &getByLSPName( "c" ); + case HExtLanguageType::CPP: + return &getByLSPName( "cpp" ); + case HExtLanguageType::ObjectiveC: + return &getByLSPName( "objective-c" ); + case HExtLanguageType::ObjectiveCPP: + return &getByLSPName( "objective-cpp" ); + } + return nullptr; +} + +const SyntaxDefinition& +SyntaxDefinitionManager::getByExtension( const std::string& filePath ) const { std::string extension( FileSystem::fileExtension( filePath ) ); std::string fileName( FileSystem::fileNameFromPath( filePath ) ); @@ -1266,10 +1289,6 @@ const SyntaxDefinition& SyntaxDefinitionManager::getByExtension( const std::stri LuaPattern words( ext ); int start, end; if ( words.find( fileName, start, end ) ) { - if ( hFileAsCPP && definition->getLSPName() == "c" && - ( ext == "%.h$" || ext == "%.h%.in$" ) ) - return getByLSPName( "cpp" ); - if ( extHasMultipleLangs && !definition->hasExtensionPriority() ) { def = definition.get(); continue; @@ -1278,9 +1297,6 @@ const SyntaxDefinition& SyntaxDefinitionManager::getByExtension( const std::stri return *definition.get(); } } else if ( extension == ext ) { - if ( hFileAsCPP && definition->getLSPName() == "c" && ext == ".h" ) - return getByLSPName( "cpp" ); - if ( extHasMultipleLangs && !definition->hasExtensionPriority() ) { def = definition.get(); continue; @@ -1299,10 +1315,6 @@ const SyntaxDefinition& SyntaxDefinitionManager::getByExtension( const std::stri LuaPattern words( ext ); int start, end; if ( words.find( fileName, start, end ) ) { - if ( hFileAsCPP && preDefinition.getLSPName() == "c" && - ( ext == "%.h$" || ext == "%.h%.in$" ) ) - return getByLSPName( "cpp" ); - if ( extHasMultipleLangs && !preDefinition.hasExtensionPriority() ) { def = &preDefinition.load(); continue; @@ -1311,9 +1323,6 @@ const SyntaxDefinition& SyntaxDefinitionManager::getByExtension( const std::stri return preDefinition.load(); } } else if ( extension == ext ) { - if ( hFileAsCPP && preDefinition.getLSPName() == "c" && ext == ".h" ) - return getByLSPName( "cpp" ); - if ( extHasMultipleLangs && !preDefinition.hasExtensionPriority() ) { def = &preDefinition.load(); continue; @@ -1329,12 +1338,19 @@ const SyntaxDefinition& SyntaxDefinitionManager::getByExtension( const std::stri } const SyntaxDefinition& SyntaxDefinitionManager::getByHeader( const std::string& header, - bool /*hFileAsCPP*/ ) const { + const std::string& filePath, + HExtLanguageType langType ) const { if ( !header.empty() ) { + { Lock l( mMutex ); for ( auto definition = mDefinitions.rbegin(); definition != mDefinitions.rend(); ++definition ) { + auto needsHDef = needsHFallback( langType, definition->get()->getLSPName(), + FileSystem::fileExtension( filePath ), header ); + if ( needsHDef ) + return *needsHDef; + for ( const auto& hdr : definition->get()->getHeaders() ) { LuaPattern words( hdr ); int start, end; @@ -1347,6 +1363,11 @@ const SyntaxDefinition& SyntaxDefinitionManager::getByHeader( const std::string& for ( auto preDefinition = mPreDefinitions.rbegin(); preDefinition != mPreDefinitions.rend(); ++preDefinition ) { + auto needsHDef = needsHFallback( langType, preDefinition->getLSPName(), + FileSystem::fileExtension( filePath ), header ); + if ( needsHDef ) + return *needsHDef; + for ( const auto& hdr : preDefinition->getHeaders() ) { LuaPattern words( hdr ); int start, end; @@ -1361,10 +1382,10 @@ const SyntaxDefinition& SyntaxDefinitionManager::getByHeader( const std::string& const SyntaxDefinition& SyntaxDefinitionManager::find( const std::string& filePath, const std::string& header, - bool hFileAsCPP ) { - const SyntaxDefinition& def = getByHeader( header ); + HExtLanguageType langType ) { + const SyntaxDefinition& def = getByHeader( header, filePath, langType ); if ( def.getLanguageName() == mDefinitions[0]->getLanguageName() ) - return getByExtension( filePath, hFileAsCPP ); + return getByExtension( filePath ); return def; } diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index dd41eb41c..7d7b2f641 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -519,16 +519,23 @@ bool TextDocument::hasSyntaxDefinition() const { } const SyntaxDefinition& TextDocument::guessSyntax() const { - String header( getText( { { 0, 0 }, positionOffset( { 0, 0 }, 128 ) } ) ); - return SyntaxDefinitionManager::instance()->find( mFilePath, header, mHAsCpp ); + String header( getText( + { { 0, 0 }, + positionOffset( { 0, 0 }, + FileSystem::fileExtension( mFilePath ) == "h" ? 5 * 1024 : 128 ) } ) ); + return SyntaxDefinitionManager::instance()->find( mFilePath, header, mHExtLanguageType ); } void TextDocument::resetSyntax() { - String header( getText( { { 0, 0 }, positionOffset( { 0, 0 }, 128 ) } ) ); + String header( getText( + { { 0, 0 }, + positionOffset( { 0, 0 }, + FileSystem::fileExtension( mFilePath ) == "h" ? 5 * 1024 : 128 ) } ) ); std::string oldDef = mSyntaxDefinition.getLSPName(); { Lock l( mSyntaxDefinitionMutex ); - mSyntaxDefinition = SyntaxDefinitionManager::instance()->find( mFilePath, header, mHAsCpp ); + mSyntaxDefinition = + SyntaxDefinitionManager::instance()->find( mFilePath, header, mHExtLanguageType ); } if ( mSyntaxDefinition.getLSPName() != oldDef ) notifySyntaxDefinitionChange(); @@ -2238,12 +2245,12 @@ TextRange TextDocument::getActiveClientVisibleRange() const { return {}; } -bool TextDocument::hAsCpp() const { - return mHAsCpp; +HExtLanguageType TextDocument::hExtLanguageType() const { + return mHExtLanguageType; } -void TextDocument::setHAsCpp( bool hAsCpp ) { - mHAsCpp = hAsCpp; +void TextDocument::setHExtLanguageType( HExtLanguageType hExtLanguageType ) { + mHExtLanguageType = hExtLanguageType; } const Uint64& TextDocument::getModificationId() const { diff --git a/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objective-c.cpp b/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objective-c.cpp index 115c10a26..e73e298a3 100644 --- a/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objective-c.cpp +++ b/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objective-c.cpp @@ -12,34 +12,131 @@ SyntaxDefinition& addObjectiveC() { { { { "//.-\n" }, "comment" }, { { "/%*", "%*/" }, "comment" }, - { { "#", "\n" }, "comment" }, - { { "\"", "\"", "\\" }, "string" }, + { { "(#%s*include)%s+([<%\"][%w%d%.%\\%/%_%-]+[>%\"])" }, + { "keyword", "keyword", "literal" } }, + { { "(#%s*import)%s+([<%\"][%w%d%.%\\%/%_%-]+[>%\"])" }, + { "keyword", "keyword", "literal" } }, + { { "\"", "[\"\n]", "\\" }, "string" }, { { "'", "'", "\\" }, "string" }, - { { "-?0x%x+" }, "number" }, - { { "-?%d+[%d%.eE]*f?" }, "number" }, - { { "-?%.?%d+f?" }, "number" }, + { { "c_number_parser" }, "number", "", SyntaxPatternMatchType::Parser }, { { "[%+%-=/%*%^%%<>!~|&]" }, "operator" }, + { { "(if|for|while|switch|sizeof|_Alignof|defined)\\s*(?=\\()" }, + { "normal", "keyword", "keyword" }, + "", + SyntaxPatternMatchType::RegEx }, { { "[%a_][%w_]*%f[(]" }, "function" }, - { { "@[%a_][%w_]*" }, "type" }, - { { "[%a_][%w_]*" }, "symbol" }, + { { "[@#]?[%a_][%w_]*" }, "symbol" }, }, { - { "elseif", "keyword" }, { "int", "type" }, { "then", "keyword" }, - { "unsigned", "type" }, { "continue", "keyword" }, { "default", "keyword" }, - { "volatile", "keyword" }, { "switch", "keyword" }, { "char", "type" }, - { "double", "type" }, { "auto", "keyword" }, { "bool", "type" }, - { "return", "keyword" }, { "extern", "keyword" }, { "NULL", "literal" }, - { "long", "type" }, { "void", "keyword" }, { "union", "keyword" }, - { "short", "type" }, { "static", "keyword" }, { "inline", "keyword" }, - { "false", "literal" }, { "for", "keyword" }, { "goto", "keyword" }, - { "while", "keyword" }, { "const", "keyword" }, { "typedef", "keyword" }, - { "true", "literal" }, { "else", "keyword" }, { "enum", "keyword" }, - { "nil", "literal" }, { "float", "type" }, { "struct", "keyword" }, - { "break", "keyword" }, { "case", "keyword" }, { "if", "keyword" }, + + // C + { "elseif", "keyword" }, + { "int", "type" }, + { "then", "keyword" }, + { "unsigned", "type" }, + { "continue", "keyword" }, + { "default", "keyword" }, + { "volatile", "keyword" }, + { "switch", "keyword" }, + { "char", "type" }, + { "double", "type" }, + { "auto", "keyword" }, + { "bool", "type" }, + { "return", "keyword" }, + { "extern", "keyword" }, + { "NULL", "literal" }, + { "long", "type" }, + { "void", "keyword" }, + { "union", "keyword" }, + { "short", "type" }, + { "static", "keyword" }, + { "inline", "keyword" }, + { "false", "literal" }, + { "for", "keyword" }, + { "goto", "keyword" }, + { "while", "keyword" }, + { "const", "keyword" }, + { "int32_t", "type" }, + { "int16_t", "type" }, + { "uint16_t", "type" }, + { "typedef", "keyword" }, + { "true", "literal" }, + { "else", "keyword" }, + { "uint32_t", "type" }, + { "enum", "keyword" }, + { "int8_t", "type" }, + { "int64_t", "type" }, + { "float", "type" }, + { "struct", "keyword" }, + { "break", "keyword" }, + { "uint8_t", "type" }, + { "uint64_t", "type" }, + { "case", "keyword" }, + { "if", "keyword" }, { "do", "keyword" }, - }, + { "#if", "keyword" }, + { "#ifdef", "keyword" }, + { "#ifndef", "keyword" }, + { "#elif", "keyword" }, + { "#else", "keyword" }, + { "#endif", "keyword" }, + { "#define", "keyword" }, + { "#undef", "keyword" }, + { "#include", "keyword" }, + { "#line", "keyword" }, + { "#error", "keyword" }, + { "#pragma", "keyword" }, + { "#warning ", "keyword" }, + { "#elifdef ", "keyword" }, + { "#elifndef ", "keyword" }, + + // Objective-C + { "retain", "keyword" }, + { "release", "keyword" }, + { "autorelease", "keyword" }, + { "@interface", "keyword" }, + { "@implementation", "keyword" }, + { "@protocol", "keyword" }, + { "@end", "keyword" }, + { "@class", "keyword" }, + { "@property", "keyword" }, + { "@synthesize", "keyword" }, + { "@dynamic", "keyword" }, + { "@autoreleasepool", "keyword" }, + { "@try", "keyword" }, + { "@catch", "keyword" }, + { "@finally", "keyword" }, + { "@throw", "keyword" }, + { "@public", "keyword" }, + { "@protected", "keyword" }, + { "@private", "keyword" }, + { "@package", "keyword" }, + { "@selector", "keyword" }, + { "@synchronized", "keyword" }, + { "@optional", "keyword" }, + { "@required", "keyword" }, + { "@encode", "keyword" }, + { "id", "type" }, + { "Class", "type" }, + { "SEL", "type" }, + { "nil", "literal" }, + { "Nil", "literal" }, + { "YES", "literal" }, + { "NO", "literal" }, + { "strong", "keyword" }, + { "weak", "keyword" }, + { "copy", "keyword" }, + { "nonatomic", "keyword" }, + { "assign", "keyword" }, + { "unsafe_unretained", "keyword" }, + { "bycopy", "keyword" }, + { "byref", "keyword" }, + { "in", "keyword" }, + { "out", "keyword" }, + { "inout", "keyword" } }, + "//", {} diff --git a/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objective-cpp.cpp b/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objective-cpp.cpp new file mode 100644 index 000000000..4d4a9ea54 --- /dev/null +++ b/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objective-cpp.cpp @@ -0,0 +1,234 @@ +#include +#include + +namespace EE { namespace UI { namespace Doc { namespace Language { + +SyntaxDefinition& addObjectiveCPP() { + + auto& sd = SyntaxDefinitionManager::instance()->add( + + { "Objective-C++", + { "%.mm$" }, + { + { { "R%\"(xml)%(", "%)(xml)%\"" }, { "string", "type", "type" }, "XML" }, + { { "R%\"(css)%(", "%)(css)%\"" }, { "string", "type", "type" }, "CSS" }, + { { "R%\"(html)%(", "%)(html)%\"" }, { "string", "type", "type" }, "HTML" }, + { { "R%\"(json)%(", "%)(json)%\"" }, { "string", "type", "type" }, "JSON" }, + { { "R\"[%a-\"]+%(", "%)[%a-\"]+%\"" }, "string" }, + { { "R\"%(", "%)\"" }, "string" }, + { { "//.-\n" }, "comment" }, + { { "/%*", "%*/" }, "comment" }, + { { "\"", "[\"\n]", "\\" }, "string" }, + { { "'", "'", "\\" }, "string" }, + { { "(#%s*include)%s+([<%\"][%w%d%.%\\%/%_%-]+[>%\"])" }, + { "keyword", "keyword", "literal" } }, + { { "(#%s*import)%s+([<%\"][%w%d%.%\\%/%_%-]+[>%\"])" }, + { "keyword", "keyword", "literal" } }, + { { "cpp_number_parser" }, "number", "", SyntaxPatternMatchType::Parser }, + { { "[%+%-=/%*%^%%<>!~|&]" }, "operator" }, + { { "(if|for|while|switch|catch|sizeof|typeid|defined|return|throw|alignof|noexcept|" + "new|delete)" + "\\s*(?=\\()" }, + { "normal", "keyword", "keyword" }, + "", + SyntaxPatternMatchType::RegEx }, + { { "[%a_][%w_]*%f[(]" }, "function" }, + { { "std%:%:[%w_]*" }, "type" }, + { { "(%[)(%[)(%a[%w_]+)(%])(%])" }, + { "normal", "keyword", "parameter", "type", "parameter", "keyword" } }, + { { "[@#]?[%a_][%w_]*" }, "symbol" }, + }, + { + + // C++ + { "int", "type" }, + { "then", "keyword" }, + { "new", "keyword" }, + { "reinterpret_cast", "keyword" }, + { "this", "keyword" }, + { "long", "type" }, + { "Uint64", "type" }, + { "Vector2i", "type" }, + { "String", "type" }, + { "Int8", "type" }, + { "short", "type" }, + { "nullptr", "keyword" }, + { "dynamic_cast", "keyword" }, + { "for", "keyword" }, + { "goto", "keyword" }, + { "while", "keyword" }, + { "const", "keyword" }, + { "enum", "keyword" }, + { "break", "keyword" }, + { "Uint32", "type" }, + { "Uint8", "type" }, + { "or", "keyword" }, + { "compl", "keyword" }, + { "char8_t", "type" }, + { "friend", "keyword" }, + { "alignof", "keyword" }, + { "volatile", "keyword" }, + { "noexcept", "keyword" }, + { "decltype", "keyword" }, + { "auto", "type" }, + { "constinit", "keyword" }, + { "class", "keyword" }, + { "constexpr", "keyword" }, + { "void", "keyword" }, + { "char16_t", "type" }, + { "static", "keyword" }, + { "inline", "keyword" }, + { "typedef", "keyword" }, + { "const_cast", "keyword" }, + { "co_return", "keyword" }, + { "throw", "keyword" }, + { "true", "type" }, + { "float", "type" }, + { "Vector2f", "type" }, + { "bitand", "keyword" }, + { "size_t", "type" }, + { "Uint16", "type" }, + { "case", "keyword" }, + { "mutable", "keyword" }, + { "protected", "keyword" }, + { "do", "keyword" }, + { "continue", "keyword" }, + { "asm", "keyword" }, + { "default", "keyword" }, + { "Recti", "type" }, + { "char", "type" }, + { "bool", "type" }, + { "Rectf", "type" }, + { "requires", "keyword" }, + { "extern", "keyword" }, + { "not_eq", "keyword" }, + { "static_cast", "keyword" }, + { "namespace", "keyword" }, + { "union", "keyword" }, + { "xor", "keyword" }, + { "Int64", "type" }, + { "false", "type" }, + { "int32_t", "type" }, + { "int16_t", "type" }, + { "uint16_t", "type" }, + { "concept", "keyword" }, + { "typename", "keyword" }, + { "else", "keyword" }, + { "co_yield", "keyword" }, + { "uint32_t", "type" }, + { "operator", "keyword" }, + { "Int32", "type" }, + { "struct", "keyword" }, + { "if", "keyword" }, + { "and_eq", "keyword" }, + { "Int16", "type" }, + { "xor_eq", "keyword" }, + { "elseif", "keyword" }, + { "public", "keyword" }, + { "virtual", "keyword" }, + { "unsigned", "type" }, + { "and", "keyword" }, + { "Float", "type" }, + { "private", "keyword" }, + { "or_eq", "keyword" }, + { "switch", "keyword" }, + { "using", "keyword" }, + { "double", "type" }, + { "typeid", "keyword" }, + { "delete", "keyword" }, + { "return", "keyword" }, + { "NULL", "literal" }, + { "static_assert", "keyword" }, + { "try", "keyword" }, + { "consteval", "keyword" }, + { "Color", "type" }, + { "register", "keyword" }, + { "explicit", "keyword" }, + { "catch", "keyword" }, + { "co_wait", "keyword" }, + { "override", "keyword" }, + { "not", "keyword" }, + { "template", "keyword" }, + { "int64_t", "type" }, + { "wchar_t", "type" }, + { "bitor", "keyword" }, + { "thread_local", "keyword" }, + { "uint64_t", "type" }, + { "char32_t", "type" }, + { "alignas", "keyword" }, + { "export", "keyword" }, + { "ssize_t", "type" }, + { "signed", "type" }, + + { "#if", "keyword" }, + { "#ifdef", "keyword" }, + { "#ifndef", "keyword" }, + { "#else", "keyword" }, + { "#elif", "keyword" }, + { "#elifdef", "keyword" }, // C++23 + { "#elifndef", "keyword" }, // C++23 + { "#endif", "keyword" }, + { "#include", "keyword" }, + { "#define", "keyword" }, + { "#undef", "keyword" }, + { "#line", "keyword" }, + { "#error", "keyword" }, + { "#pragma", "keyword" }, + { "#warning", "keyword" }, + + // Objective-C + { "retain", "keyword" }, + { "release", "keyword" }, + { "autorelease", "keyword" }, + { "@interface", "keyword" }, + { "@implementation", "keyword" }, + { "@protocol", "keyword" }, + { "@end", "keyword" }, + { "@class", "keyword" }, + { "@property", "keyword" }, + { "@synthesize", "keyword" }, + { "@dynamic", "keyword" }, + { "@autoreleasepool", "keyword" }, + { "@try", "keyword" }, + { "@catch", "keyword" }, + { "@finally", "keyword" }, + { "@throw", "keyword" }, + { "@public", "keyword" }, + { "@protected", "keyword" }, + { "@private", "keyword" }, + { "@package", "keyword" }, + { "@selector", "keyword" }, + { "@synchronized", "keyword" }, + { "@optional", "keyword" }, + { "@required", "keyword" }, + { "@encode", "keyword" }, + { "id", "type" }, + { "Class", "type" }, + { "SEL", "type" }, + { "nil", "literal" }, + { "Nil", "literal" }, + { "YES", "literal" }, + { "NO", "literal" }, + { "strong", "keyword" }, + { "weak", "keyword" }, + { "copy", "keyword" }, + { "nonatomic", "keyword" }, + { "assign", "keyword" }, + { "unsafe_unretained", "keyword" }, + { "bycopy", "keyword" }, + { "byref", "keyword" }, + { "in", "keyword" }, + { "out", "keyword" }, + { "inout", "keyword" } }, + + "//", + {}, + "objective-cpp" + + } ); + + sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } ); + return sd; +} + +}}}} // namespace EE::UI::Doc::Language diff --git a/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objective-cpp.hpp b/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objective-cpp.hpp new file mode 100644 index 000000000..df4823bbd --- /dev/null +++ b/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/objective-cpp.hpp @@ -0,0 +1,12 @@ +#ifndef EE_UI_DOC_ObjectiveCPP +#define EE_UI_DOC_ObjectiveCPP + +#include + +namespace EE { namespace UI { namespace Doc { namespace Language { + +extern SyntaxDefinition& addObjectiveCPP(); + +}}}} // namespace EE::UI::Doc::Language + +#endif diff --git a/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languagessyntaxhighlighting.cpp b/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languagessyntaxhighlighting.cpp index 274863e9a..759e825e4 100644 --- a/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languagessyntaxhighlighting.cpp +++ b/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languagessyntaxhighlighting.cpp @@ -72,6 +72,7 @@ #include #include #include +#include #include #include #include @@ -522,6 +523,12 @@ void LanguagesSyntaxHighlighting::load() { { "%.m$" }, } ); + sdm->addPreDefinition( { "Objective-C++", + []() -> SyntaxDefinition& { return addObjectiveCPP(); }, + { "%.mm$" }, + {}, + "objective-cpp" } ); + sdm->addPreDefinition( { "OCaml", []() -> SyntaxDefinition& { return addOCaml(); }, diff --git a/src/tools/ecode/appconfig.cpp b/src/tools/ecode/appconfig.cpp index e9b404c1f..b068207fa 100644 --- a/src/tools/ecode/appconfig.cpp +++ b/src/tools/ecode/appconfig.cpp @@ -497,7 +497,8 @@ void AppConfig::saveProject( std::string projectFolder, UICodeEditorSplitter* ed IniFile cfg( projectCfgPath, false ); cfg.setValue( "path", "folder_path", projectFolder ); cfg.setValueB( "document", "use_global_settings", docConfig.useGlobalSettings ); - cfg.setValueB( "document", "h_as_cpp", docConfig.hAsCPP ); + cfg.setValue( "document", "h_ext_language_type", + HExtLanguageTypeHelper::toString( docConfig.hExtLanguageType ) ); cfg.setValueB( "document", "trim_trailing_whitespaces", docConfig.doc.trimTrailingWhitespaces ); cfg.setValueB( "document", "force_new_line_at_end_of_file", docConfig.doc.forceNewLineAtEndOfFile ); @@ -761,7 +762,14 @@ void AppConfig::loadProject( std::string projectFolder, UICodeEditorSplitter* ed IniFile cfg( projectCfgPath ); docConfig.useGlobalSettings = cfg.getValueB( "document", "use_global_settings", true ); - docConfig.hAsCPP = cfg.getValueB( "document", "h_as_cpp", false ); + + if ( cfg.getValue( "document", "h_ext_language_type", "" ) == "" && + cfg.getValueB( "document", "h_as_cpp", false ) == true ) { + docConfig.hExtLanguageType = HExtLanguageType::CPP; + } else { + docConfig.hExtLanguageType = HExtLanguageTypeHelper::fromString( + cfg.getValue( "document", "h_ext_language_type", "autodetect" ) ); + } docConfig.doc.trimTrailingWhitespaces = cfg.getValueB( "document", "trim_trailing_whitespaces", false ); docConfig.doc.forceNewLineAtEndOfFile = diff --git a/src/tools/ecode/appconfig.hpp b/src/tools/ecode/appconfig.hpp index e5117dcfa..0307befa1 100644 --- a/src/tools/ecode/appconfig.hpp +++ b/src/tools/ecode/appconfig.hpp @@ -129,7 +129,7 @@ struct GlobalSearchBarConfig { struct ProjectDocumentConfig { bool useGlobalSettings{ true }; - bool hAsCPP{ false }; + HExtLanguageType hExtLanguageType{ HExtLanguageType::AutoDetect }; DocumentConfig doc; ProjectDocumentConfig() {} ProjectDocumentConfig( const DocumentConfig& doc ) { this->doc = doc; } diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index cb1a00a8b..bffe69857 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -2577,7 +2577,7 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) { UITab* tab = (UITab*)editor->getData(); tab->setIcon( icon->getSize( mMenuIconSize ) ); } - editor->getDocument().setHAsCpp( mProjectDocConfig.hAsCPP ); + editor->getDocument().setHExtLanguageType( mProjectDocConfig.hExtLanguageType ); auto ext = editor->getDocument().getFileInfo().getExtension(); if ( SyntaxDefinitionManager::instance()->extensionCanRepresentManyLanguages( ext ) ) { diff --git a/src/tools/ecode/globalsearchcontroller.cpp b/src/tools/ecode/globalsearchcontroller.cpp index 1fd2e0027..5626045bf 100644 --- a/src/tools/ecode/globalsearchcontroller.cpp +++ b/src/tools/ecode/globalsearchcontroller.cpp @@ -695,7 +695,7 @@ void GlobalSearchController::updateGlobalSearchBarResults( const std::string& search, std::shared_ptr model, bool searchReplace, bool isEscaped ) { updateGlobalSearchBar(); - mGlobalSearchTree->hAsCPP = mApp->getProjectDocConfig().hAsCPP; + mGlobalSearchTree->hExtLanguageType = mApp->getProjectDocConfig().hExtLanguageType; mGlobalSearchTree->setSearchStr( search ); mGlobalSearchTree->setModel( model ); if ( mGlobalSearchTree->getModel()->rowCount() < 50 ) diff --git a/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp b/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp index 830360681..3b3dbf3bf 100644 --- a/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp +++ b/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp @@ -103,6 +103,10 @@ void LSPDocumentClient::onDocumentClosed( TextDocument* ) { void LSPDocumentClient::onDocumentDirtyOnFileSystem( TextDocument* ) {} +void LSPDocumentClient::onDocumentSyntaxDefinitionChange( const SyntaxDefinition& ) { + requestSemanticHighlightingDelayed( true ); +} + void LSPDocumentClient::onDocumentMoved( TextDocument* ) { refreshTag(); } diff --git a/src/tools/ecode/plugins/lsp/lspdocumentclient.hpp b/src/tools/ecode/plugins/lsp/lspdocumentclient.hpp index a9c216a00..537cfcc3d 100644 --- a/src/tools/ecode/plugins/lsp/lspdocumentclient.hpp +++ b/src/tools/ecode/plugins/lsp/lspdocumentclient.hpp @@ -39,6 +39,7 @@ class LSPDocumentClient : public TextDocument::Client, public FoldRangeProvider virtual void onDocumentMoved( TextDocument* ); virtual void onDocumentReloaded( TextDocument* ); virtual void onDocumentReset( TextDocument* ); + virtual void onDocumentSyntaxDefinitionChange( const SyntaxDefinition& ); Client::Type getTextDocumentClientType() { return TextDocument::Client::Auxiliary; } void notifyOpen(); diff --git a/src/tools/ecode/settingsmenu.cpp b/src/tools/ecode/settingsmenu.cpp index d543df25c..aeae07391 100644 --- a/src/tools/ecode/settingsmenu.cpp +++ b/src/tools/ecode/settingsmenu.cpp @@ -1986,11 +1986,10 @@ void SettingsMenu::updateProjectSettingsMenu() { mSettingsMenu->getItemId( "project_settings" ) ->setEnabled( !mApp->getCurrentProject().empty() ); - mProjectMenu->getItemId( "h_as_cpp" ) - ->asType() - ->setActive( mApp->getProjectDocConfig().hAsCPP ); - - mDocMenu->getItemId( "project_doc_settings" )->setEnabled( !mApp->getCurrentProject().empty() ); + auto item = mHExtLanguageTypeMenu->find( + HExtLanguageTypeHelper::toString( mApp->getProjectDocConfig().hExtLanguageType ) ); + if ( item && item->isType( UI_TYPE_MENURADIOBUTTON ) ) + item->asType()->setActive( true ); for ( size_t i = 0; i < mProjectDocMenu->getCount(); i++ ) { mProjectDocMenu->getItem( i )->setEnabled( !mApp->getCurrentProject().empty() && @@ -2516,31 +2515,47 @@ void SettingsMenu::createProjectMenu() { owner->on( Event::OnMenuShow, [owner, this]( auto ) { mProjectDocMenu->setOwnerNode( owner ); } ); - mProjectMenu - ->addCheckBox( i18n( "h_as_cpp", "Treat .h files as C++ code." ), - mApp->getProjectDocConfig().hAsCPP ) - ->setId( "h_as_cpp" ); + HExtLanguageType hExtLanguageType = mApp->getProjectDocConfig().hExtLanguageType; + mHExtLanguageTypeMenu = UIPopUpMenu::New(); + mHExtLanguageTypeMenu->setId( "h_ext_files_submenu" ); + mHExtLanguageTypeMenu + ->addRadioButton( i18n( "auto-detect", "Auto-Detect" ), + hExtLanguageType == HExtLanguageType::AutoDetect ) + ->setId( "autodetect" ); + mHExtLanguageTypeMenu->addRadioButton( "C", hExtLanguageType == HExtLanguageType::C ) + ->setId( "c" ); + mHExtLanguageTypeMenu->addRadioButton( "C++", hExtLanguageType == HExtLanguageType::CPP ) + ->setId( "cpp" ); + mHExtLanguageTypeMenu + ->addRadioButton( "Objective-C", hExtLanguageType == HExtLanguageType::ObjectiveC ) + ->setId( "objective-c" ); + mHExtLanguageTypeMenu + ->addRadioButton( "Objective-C++", hExtLanguageType == HExtLanguageType::ObjectiveCPP ) + ->setId( "objective-cpp" ); - mProjectMenu->on( Event::OnItemClicked, [this]( const Event* event ) { + mProjectMenu->addSubMenu( i18n( "treat_h_files_as_ellipsis", "Treat .h files as..." ), nullptr, + mHExtLanguageTypeMenu ); + + mHExtLanguageTypeMenu->on( Event::OnItemClicked, [this]( const Event* event ) { if ( event->getNode()->isType( UI_TYPE_MENU_SEPARATOR ) || event->getNode()->isType( UI_TYPE_MENUSUBMENU ) ) return; const String& id = event->getNode()->getId(); - if ( event->getNode()->isType( UI_TYPE_MENUCHECKBOX ) ) { + if ( event->getNode()->isType( UI_TYPE_MENURADIOBUTTON ) ) { UIMenuCheckBox* item = event->getNode()->asType(); - if ( "h_as_cpp" == id ) { - mApp->getProjectDocConfig().hAsCPP = item->isActive(); - mApp->getSplitter()->forEachEditor( [this]( UICodeEditor* editor ) { - editor->getDocument().setHAsCpp( mApp->getProjectDocConfig().hAsCPP ); - if ( editor->getDocument().getFileInfo().getExtension() == "h" ) { - editor->resetSyntaxDefinition(); - if ( mSplitter->isCurEditor( editor ) ) - updateCurrentFileType(); - } - } ); - updateProjectSettingsMenu(); - } + mApp->getProjectDocConfig().hExtLanguageType = + HExtLanguageTypeHelper::fromString( item->getId() ); + mApp->getSplitter()->forEachEditor( [this]( UICodeEditor* editor ) { + editor->getDocument().setHExtLanguageType( + mApp->getProjectDocConfig().hExtLanguageType ); + if ( editor->getDocument().getFileInfo().getExtension() == "h" ) { + editor->resetSyntaxDefinition(); + if ( mSplitter->isCurEditor( editor ) ) + updateCurrentFileType(); + } + } ); + updateProjectSettingsMenu(); } } ); } diff --git a/src/tools/ecode/settingsmenu.hpp b/src/tools/ecode/settingsmenu.hpp index d1b5b0976..0348539eb 100644 --- a/src/tools/ecode/settingsmenu.hpp +++ b/src/tools/ecode/settingsmenu.hpp @@ -113,6 +113,7 @@ class SettingsMenu { UIPopUpMenu* mProjectTreeMenu{ nullptr }; UIPopUpMenu* mProjectDocMenu{ nullptr }; UIPopUpMenu* mProjectMenu{ nullptr }; + UIPopUpMenu* mHExtLanguageTypeMenu{ nullptr }; UIPopUpMenu* mEditMenu{ nullptr }; UIPopUpMenu* mHelpMenu{ nullptr }; UIPopUpMenu* mLineWrapMenu{ nullptr }; diff --git a/src/tools/ecode/uitreeviewglobalsearch.cpp b/src/tools/ecode/uitreeviewglobalsearch.cpp index cc5776308..6c9974887 100644 --- a/src/tools/ecode/uitreeviewglobalsearch.cpp +++ b/src/tools/ecode/uitreeviewglobalsearch.cpp @@ -39,7 +39,7 @@ UITreeViewGlobalSearch::UITreeViewGlobalSearch( const SyntaxColorScheme& colorSc UIWidget* UITreeViewGlobalSearch::createCell( UIWidget* rowWidget, const ModelIndex& index ) { UITableCell* widget = index.column() == (Int64)getModel()->treeColumn() - ? UITreeViewCellGlobalSearch::New( mSearchReplace, hAsCPP ) + ? UITreeViewCellGlobalSearch::New( mSearchReplace, hExtLanguageType ) : UITableCell::New(); return setupCell( widget, rowWidget, index ); } @@ -128,8 +128,10 @@ ProjectSearch::ResultData* UITreeViewCellGlobalSearch::getResultDataPtr() { #define CELL_GLOBAL_SEARCH_PADDING ( 12 ) -UITreeViewCellGlobalSearch::UITreeViewCellGlobalSearch( bool selectionEnabled, bool hAsCPP ) : - UITreeViewCell( selectionEnabled ? getCheckBoxFn() : nullptr ), mHAsCpp( hAsCPP ) {} +UITreeViewCellGlobalSearch::UITreeViewCellGlobalSearch( bool selectionEnabled, + HExtLanguageType hExtLanguageType ) : + UITreeViewCell( selectionEnabled ? getCheckBoxFn() : nullptr ), + mHExtLanguageType( hExtLanguageType ) {} UIPushButton* UITreeViewCellGlobalSearch::setText( const String& text ) { auto* result = getResultPtr(); @@ -154,7 +156,7 @@ UIPushButton* UITreeViewCellGlobalSearch::updateText( const std::string& text ) (ProjectSearch::ResultData*)getCurIndex().parent().internalData(); const auto& styleDef = - SyntaxDefinitionManager::instance()->getByExtension( res->file, mHAsCpp ); + SyntaxDefinitionManager::instance()->getByExtension( res->file ); Uint32 from = text.find_first_not_of( ' ' ); Uint32 to = from; diff --git a/src/tools/ecode/uitreeviewglobalsearch.hpp b/src/tools/ecode/uitreeviewglobalsearch.hpp index f25da1b0b..e1535d4d3 100644 --- a/src/tools/ecode/uitreeviewglobalsearch.hpp +++ b/src/tools/ecode/uitreeviewglobalsearch.hpp @@ -12,11 +12,12 @@ namespace ecode { class UITreeViewCellGlobalSearch : public UITreeViewCell { public: - static UITreeViewCellGlobalSearch* New( bool selectionEnabled, bool hAsCPP ) { - return eeNew( UITreeViewCellGlobalSearch, ( selectionEnabled, hAsCPP ) ); + static UITreeViewCellGlobalSearch* New( bool selectionEnabled, + HExtLanguageType hExtLanguageType ) { + return eeNew( UITreeViewCellGlobalSearch, ( selectionEnabled, hExtLanguageType ) ); } - explicit UITreeViewCellGlobalSearch( bool selectionEnabled, bool hAsCPP ); + explicit UITreeViewCellGlobalSearch( bool selectionEnabled, HExtLanguageType hExtLanguageType ); UIPushButton* setText( const String& text ); @@ -29,7 +30,7 @@ class UITreeViewCellGlobalSearch : public UITreeViewCell { protected: std::pair mSearchStrPos; String mResultStr; - bool mHAsCpp{ false }; + HExtLanguageType mHExtLanguageType{ HExtLanguageType::AutoDetect }; std::function getCheckBoxFn(); @@ -62,7 +63,8 @@ class UITreeViewGlobalSearch : public UITreeView { const String& getSearchStr() const { return mSearchStr; } - bool hAsCPP = false; + HExtLanguageType hExtLanguageType{ HExtLanguageType::AutoDetect }; + protected: Color mLineNumColor; SyntaxColorScheme mColorScheme;