diff --git a/include/eepp/ui/doc/textdocument.hpp b/include/eepp/ui/doc/textdocument.hpp index 4ce4caa60..ff8df9fb3 100644 --- a/include/eepp/ui/doc/textdocument.hpp +++ b/include/eepp/ui/doc/textdocument.hpp @@ -713,6 +713,7 @@ class EE_API TextDocument { Client* mActiveClient{ nullptr }; mutable Mutex mLoadingMutex; mutable Mutex mLoadingFilePathMutex; + mutable Mutex mSyntaxDefinitionMutex; size_t mLastSelection{ 0 }; std::unique_ptr mHighlighter; Mutex mStopFlagsMutex; diff --git a/src/eepp/ui/doc/languages/css.cpp b/src/eepp/ui/doc/languages/css.cpp index aa4b92151..8f10c999d 100644 --- a/src/eepp/ui/doc/languages/css.cpp +++ b/src/eepp/ui/doc/languages/css.cpp @@ -264,6 +264,118 @@ void addCSS() { { "magenta", "literal" }, { "textinputpassword", "keyword" }, { "important", "literal" }, + { "a", "keyword" }, + { "abbr", "keyword" }, + { "address", "keyword" }, + { "area", "keyword" }, + { "article", "keyword" }, + { "aside", "keyword" }, + { "audio", "keyword" }, + { "b", "keyword" }, + { "base", "keyword" }, + { "bdi", "keyword" }, + { "bdo", "keyword" }, + { "blockquote", "keyword" }, + { "body", "keyword" }, + { "br", "keyword" }, + { "button", "keyword" }, + { "canvas", "keyword" }, + { "caption", "keyword" }, + { "cite", "keyword" }, + { "code", "keyword" }, + { "col", "keyword" }, + { "colgroup", "keyword" }, + { "data", "keyword" }, + { "datalist", "keyword" }, + { "dd", "keyword" }, + { "del", "keyword" }, + { "details", "keyword" }, + { "dfn", "keyword" }, + { "dialog", "keyword" }, + { "div", "keyword" }, + { "dl", "keyword" }, + { "dt", "keyword" }, + { "em", "keyword" }, + { "embed", "keyword" }, + { "fieldset", "keyword" }, + { "figcaption", "keyword" }, + { "figure", "keyword" }, + { "footer", "keyword" }, + { "form", "keyword" }, + { "h1", "keyword" }, + { "h2", "keyword" }, + { "h3", "keyword" }, + { "h4", "keyword" }, + { "h5", "keyword" }, + { "h6", "keyword" }, + { "head", "keyword" }, + { "header", "keyword" }, + { "hr", "keyword" }, + { "html", "keyword" }, + { "i", "keyword" }, + { "iframe", "keyword" }, + { "img", "keyword" }, + { "input", "keyword" }, + { "ins", "keyword" }, + { "kbd", "keyword" }, + { "label", "keyword" }, + { "legend", "keyword" }, + { "li", "keyword" }, + { "link", "keyword" }, + { "main", "keyword" }, + { "map", "keyword" }, + { "mark", "keyword" }, + { "menu", "keyword" }, + { "meta", "keyword" }, + { "meter", "keyword" }, + { "nav", "keyword" }, + { "noscript", "keyword" }, + { "object", "keyword" }, + { "ol", "keyword" }, + { "optgroup", "keyword" }, + { "option", "keyword" }, + { "output", "keyword" }, + { "p", "keyword" }, + { "param", "keyword" }, + { "picture", "keyword" }, + { "pre", "keyword" }, + { "progress", "keyword" }, + { "q", "keyword" }, + { "rp", "keyword" }, + { "rt", "keyword" }, + { "ruby", "keyword" }, + { "s", "keyword" }, + { "samp", "keyword" }, + { "script", "keyword" }, + { "section", "keyword" }, + { "select", "keyword" }, + { "slot", "keyword" }, + { "small", "keyword" }, + { "source", "keyword" }, + { "span", "keyword" }, + { "strong", "keyword" }, + { "style", "keyword" }, + { "sub", "keyword" }, + { "summary", "keyword" }, + { "sup", "keyword" }, + { "table", "keyword" }, + { "tbody", "keyword" }, + { "td", "keyword" }, + { "template", "keyword" }, + { "textarea", "keyword" }, + { "tfoot", "keyword" }, + { "th", "keyword" }, + { "thead", "keyword" }, + { "time", "keyword" }, + { "title", "keyword" }, + { "tr", "keyword" }, + { "track", "keyword" }, + { "u", "keyword" }, + { "ul", "keyword" }, + { "var", "keyword" }, + { "video", "keyword" }, + { "wbr", "keyword" }, + { "Widget", "keyword" }, { "LinearLayout", "keyword" }, { "RelativeLayout", "keyword" }, diff --git a/src/eepp/ui/doc/syntaxhighlighter.cpp b/src/eepp/ui/doc/syntaxhighlighter.cpp index 9a46f823b..5388b0976 100644 --- a/src/eepp/ui/doc/syntaxhighlighter.cpp +++ b/src/eepp/ui/doc/syntaxhighlighter.cpp @@ -199,8 +199,8 @@ Int64 SyntaxHighlighter::getMaxWantedLine() const { } bool SyntaxHighlighter::updateDirty( int visibleLinesCount ) { - if ( visibleLinesCount <= 0 ) - return 0; + if ( visibleLinesCount <= 0 || mTokenizeAsync ) + return false; if ( mFirstInvalidLine > mMaxWantedLine ) { mMaxWantedLine = 0; } else { diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index 6effb81f0..a47993c05 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -100,7 +100,10 @@ void TextDocument::reset() { mLastSelection = 0; mLines.clear(); mLines.emplace_back( String( "\n" ) ); - mSyntaxDefinition = SyntaxDefinitionManager::instance()->getPlainDefinition(); + { + Lock l( mSyntaxDefinitionMutex ); + mSyntaxDefinition = SyntaxDefinitionManager::instance()->getPlainDefinition(); + } mUndoStack.clear(); cleanChangeId(); notifySyntaxDefinitionChange(); @@ -403,6 +406,7 @@ void TextDocument::mergeSelection() { } bool TextDocument::hasSyntaxDefinition() const { + Lock l( mSyntaxDefinitionMutex ); return !mSyntaxDefinition.getPatterns().empty(); } @@ -414,7 +418,10 @@ const SyntaxDefinition& TextDocument::guessSyntax() const { void TextDocument::resetSyntax() { String header( getText( { { 0, 0 }, positionOffset( { 0, 0 }, 128 ) } ) ); std::string oldDef = mSyntaxDefinition.getLSPName(); - mSyntaxDefinition = SyntaxDefinitionManager::instance()->find( mFilePath, header, mHAsCpp ); + { + Lock l( mSyntaxDefinitionMutex ); + mSyntaxDefinition = SyntaxDefinitionManager::instance()->find( mFilePath, header, mHAsCpp ); + } if ( mSyntaxDefinition.getLSPName() != oldDef ) notifySyntaxDefinitionChange(); } @@ -2421,12 +2428,16 @@ void TextDocument::redo() { } const SyntaxDefinition& TextDocument::getSyntaxDefinition() const { + Lock l( mSyntaxDefinitionMutex ); return mSyntaxDefinition; } void TextDocument::setSyntaxDefinition( const SyntaxDefinition& definition ) { if ( mSyntaxDefinition.getLSPName() != definition.getLSPName() ) { - mSyntaxDefinition = definition; + { + Lock l( mSyntaxDefinitionMutex ); + mSyntaxDefinition = definition; + } notifySyntaxDefinitionChange(); } } diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index 55c5945e9..51f13fb3e 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -448,7 +448,8 @@ void UICodeEditor::scheduledUpdate( const Time& ) { if ( !mVisible ) return; - if ( mDoc && !mDoc->isLoading() && + if ( mDoc && !mDoc->isLoading() && !mDoc->isEmpty() && + !mDoc->getSyntaxDefinition().getPatterns().empty() && mDoc->getHighlighter()->updateDirty( getVisibleLinesCount() ) ) { invalidateDraw(); } diff --git a/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/svelte.cpp b/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/svelte.cpp new file mode 100644 index 000000000..6ada658cb --- /dev/null +++ b/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/svelte.cpp @@ -0,0 +1,72 @@ +#include +#include + +namespace EE { namespace UI { namespace Doc { namespace Language { + +void addSvelte() { + + SyntaxDefinitionManager::instance() + ->add( + + { "Svelte", + { "%.svelte$" }, + { + { { "<%s*[sS][cC][rR][iI][pP][tT]%s+[tT][yY][pP][eE]%s*=%s*['\"]%a+/" + "[jJ][aA][vV][aA][sS][cC][rR][iI][pP][tT]['\"]%s*>", + "<%s*/[sS][cC][rR][iI][pP][tT]>" }, + "function", + "JavaScript" }, + { { "<%s*[sS][cC][rR][iI][pP][tT]%s+([lL][aA][nN][gG])%s*(=)%s*(['\"][tT][sS]['" + "\"])%s*>", + "<%s*/[sS][cC][rR][iI][pP][tT]>" }, + { "function", "keyword", "operator", "string" }, + "TypeScript" }, + { { "<%s*[sS][cC][rR][iI][pP][tT]%s*>", "<%s*/%s*[sS][cC][rR][iI][pP][tT]>" }, + "function", + "JavaScript" }, + { { "<%s*[sS][tT][yY][lL][eE][^>]*>", "<%s*/%s*[sS][tT][yY][lL][eE]%s*>" }, + "function", + "CSS" }, + { { "" }, "comment" }, + { { "\"", "\"", "\\" }, "string" }, + { { "'", "'", "\\" }, "string" }, + { { "{@html[^}]*}" }, "keyword", "", true }, + { { "{@debug[^}]*}" }, "keyword", "", true }, + { { "{(:else|:then|:catch)}" }, + std::vector{ "keyword", "keyword2" }, + "", + true }, + { { "{(/if|/each|/await|/key)}" }, + std::vector{ "keyword", "keyword2" }, + "", + true }, + { { "{(#if|#each|#await|#key)", "}", "\\" }, + { "keyword", "keyword2", "normal" }, + "JavaScript", + true }, + { { "{", "}", "\\" }, "keyword", "JavaScript" }, + { { "([%a_][%w_-]*)(:)([%a_][%w_-]*)(=)" }, + { "keyword", "keyword2", "normal", "keyword", "operator" } }, + { { "([%a_][%w_-]*)(=)" }, { "keyword", "keyword", "operator" } }, + { { "0x[%da-fA-F]+" }, "number" }, + { { "-?%d+[%d%.]*f?" }, "number" }, + { { "-?%.?%d+f?" }, "number" }, + { { "%f[^<][%a_][%w%_%-]*(:)([%w_-]+)" }, { "function", "normal", "keyword" } }, + { { "%f[^<]/[%a_][%w%_%-]*(:)([%w_-]+)" }, { "function", "normal", "keyword" } }, + { { "%f[^<]![%a_][%w%_%-]*" }, "keyword2" }, + { { "%f[^<][%a_][%w%_%-]*" }, "function" }, + { { "%f[^<]/[%a_][%w%_%-]*" }, "function" }, + { { "[/<>=]" }, "operator" }, + + }, + { + + }, + "", + {} + + } ) + .setAutoCloseXMLTags( true ); +} + +}}}} // namespace EE::UI::Doc::Language diff --git a/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/svelte.hpp b/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/svelte.hpp new file mode 100644 index 000000000..4cb1dabb4 --- /dev/null +++ b/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/svelte.hpp @@ -0,0 +1,10 @@ +#ifndef EE_UI_DOC_Svelte +#define EE_UI_DOC_Svelte + +namespace EE { namespace UI { namespace Doc { namespace Language { + +extern void addSvelte(); + +}}}} // 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 1767f6f1b..7b5c65078 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 @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -163,6 +164,7 @@ void LanguagesSyntaxHighlighting::load() { addSmallBASIC(); addSolidity(); addSQL(); + addSvelte(); addSwift(); addTeal(); addToml(); diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 35b2a8ce4..a2b734874 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -2767,6 +2767,33 @@ void App::renameFile( const FileInfo& file ) { } ); } +void App::openAllFilesInFolder( const FileInfo& folder ) { + auto files = + FileSystem::filesInfoGetInPath( folder.getDirectoryPath(), true, false, true, + getFileSystemModel()->getDisplayConfig().ignoreHidden ); + + std::vector supportedExts( + SyntaxDefinitionManager::instance()->getExtensionsPatternsSupported() ); + std::vector acceptedPatterns; + acceptedPatterns.reserve( supportedExts.size() ); + for ( const auto& strPattern : supportedExts ) + acceptedPatterns.emplace_back( std::string{ strPattern } ); + + for ( const auto& file : files ) { + if ( file.isRegularFile() ) { + bool foundPattern = acceptedPatterns.empty(); + for ( auto& pattern : acceptedPatterns ) { + if ( pattern.matches( file.getFilepath() ) ) { + foundPattern = true; + break; + } + } + if ( foundPattern ) + loadFileFromPath( file.getFilepath() ); + } + } +} + void App::toggleHiddenFiles() { mFileSystemModel = FileSystemModel::New( mFileSystemModel->getRootPath(), FileSystemModel::Mode::FilesAndDirectories, @@ -3497,7 +3524,7 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe mThreadPool->run( [this] { // Load language definitions Clock defClock; - SyntaxDefinitionManager::createSingleton( 107 ); + SyntaxDefinitionManager::createSingleton( 108 ); Language::LanguagesSyntaxHighlighting::load(); SyntaxDefinitionManager::instance()->setLanguageExtensionsPriority( mConfig.languagesExtensions.priorities ); diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp index 6a0039ed2..7f6122b12 100644 --- a/src/tools/ecode/ecode.hpp +++ b/src/tools/ecode/ecode.hpp @@ -390,6 +390,8 @@ class App : public UICodeEditorSplitter::Client, public PluginContextProvider { void renameFile( const FileInfo& file ); + void openAllFilesInFolder( const FileInfo& folder ); + UIMessageBox* newInputMsgBox( const String& title, const String& msg ); std::string getNewFilePath( const FileInfo& file, UIMessageBox* msgBox, bool keepDir = true ); diff --git a/src/tools/ecode/settingsmenu.cpp b/src/tools/ecode/settingsmenu.cpp index 1bd1d89f2..7515366b9 100644 --- a/src/tools/ecode/settingsmenu.cpp +++ b/src/tools/ecode/settingsmenu.cpp @@ -2153,6 +2153,10 @@ void SettingsMenu::createProjectTreeMenu( const FileInfo& file ) { mProjectTreeMenu ->add( i18n( "open_folder_ellipsis", "Open Folder..." ), findIcon( "folder-open" ) ) ->setId( "open_folder" ); + mProjectTreeMenu + ->add( i18n( "open_all_files_in_folder", "Open All Files in Folder" ), + findIcon( "folder-open" ) ) + ->setId( "open_all_files_in_folder" ); } else { if ( file.isRegularFile() ) { auto curDir( mApp->getCurrentWorkingDir() ); @@ -2260,6 +2264,8 @@ void SettingsMenu::createProjectTreeMenu( const FileInfo& file ) { Engine::instance()->openURI( file.getDirectoryPath() ); } else if ( "open_folder" == id ) { Engine::instance()->openURI( file.getFilepath() ); + } else if ( "open_all_files_in_folder" == id ) { + mApp->openAllFilesInFolder( file ); } else if ( "show-hidden-files" == id ) { mApp->toggleHiddenFiles(); } else if ( "execute_in_terminal" == id ) {