diff --git a/premake4.lua b/premake4.lua index 9f5e4947d..55875304c 100644 --- a/premake4.lua +++ b/premake4.lua @@ -160,7 +160,6 @@ newoption { trigger = "with-gles2", description = "Compile with GLES2 support" } newoption { trigger = "with-gles1", description = "Compile with GLES1 support" } newoption { trigger = "without-mojoal", description = "Compile without mojoAL as OpenAL implementation (that requires SDL2 backend). Instead it will use openal-soft." } newoption { trigger = "use-frameworks", description = "In macOS it will try to link the external libraries from its frameworks. For example, instead of linking against SDL2 it will link agains SDL2.framework." } -newoption { trigger = "with-emscripten-pthreads", description = "Enables emscripten build to use posix threads" } newoption { trigger = "with-mold-linker", description = "Tries to use the mold linker instead of the default linker of the toolchain" } newoption { trigger = "with-debug-symbols", description = "Release builds are built with debug symbols." } newoption { trigger = "thread-sanitizer", description ="Compile with ThreadSanitizer." } @@ -396,9 +395,7 @@ function build_base_configuration( package_name ) configuration "emscripten" buildoptions { "-s USE_SDL=2" } - if _OPTIONS["with-emscripten-pthreads"] then - buildoptions { "-s USE_PTHREADS=1" } - end + buildoptions { "-s USE_PTHREADS=1" } end function build_base_cpp_configuration( package_name ) @@ -447,9 +444,7 @@ function build_base_cpp_configuration( package_name ) configuration "emscripten" buildoptions { "-s USE_SDL=2" } - if _OPTIONS["with-emscripten-pthreads"] then - buildoptions { "-s USE_PTHREADS=1" } - end + buildoptions { "-s USE_PTHREADS=1" } end function add_cross_config_links() @@ -610,10 +605,8 @@ function build_link_configuration( package_name, use_ee_icon ) if os.is_real("emscripten") then linkoptions{ "--profiling --profiling-funcs -s DEMANGLE_SUPPORT=1 -s NO_DISABLE_EXCEPTION_CATCHING -sALLOW_MEMORY_GROWTH=1" } - if _OPTIONS["with-emscripten-pthreads"] then - buildoptions { "-s USE_PTHREADS=1" } - linkoptions { "-s USE_PTHREADS=1 -sPTHREAD_POOL_SIZE=8" } - end + buildoptions { "-s USE_PTHREADS=1" } + linkoptions { "-s USE_PTHREADS=1 -sPTHREAD_POOL_SIZE=8" } end fix_shared_lib_linking_path( package_name, "libeepp-debug" ) @@ -645,11 +638,8 @@ function build_link_configuration( package_name, use_ee_icon ) configuration "emscripten" linkoptions { "-s TOTAL_MEMORY=536870912 -s ALLOW_MEMORY_GROWTH=1 -s USE_SDL=2" } buildoptions { "-s USE_SDL=2" } - - if _OPTIONS["with-emscripten-pthreads"] then - buildoptions { "-s USE_PTHREADS=1" } - linkoptions { "-s USE_PTHREADS=1 -sPTHREAD_POOL_SIZE=8" } - end + buildoptions { "-s USE_PTHREADS=1" } + linkoptions { "-s USE_PTHREADS=1 -sPTHREAD_POOL_SIZE=8" } if _OPTIONS["with-gles1"] and ( not _OPTIONS["with-gles2"] or _OPTIONS["force-gles1"] ) then linkoptions{ "-s LEGACY_GL_EMULATION=1" } diff --git a/premake5.lua b/premake5.lua index af83b23c6..841469795 100644 --- a/premake5.lua +++ b/premake5.lua @@ -12,7 +12,6 @@ newoption { trigger = "without-mojoal", description = "Compile without mojoAL as newoption { trigger = "use-frameworks", description = "In macOS it will try to link the external libraries from its frameworks. For example, instead of linking against SDL2 it will link against SDL2.framework." } newoption { trigger = "windows-vc-build", description = "This is used to build the framework in Visual Studio downloading its external dependencies and making them available to the VS project without having to install them manually." } newoption { trigger = "windows-mingw-build", description = "This is used to build the framework with mingw downloading its external dependencies." } -newoption { trigger = "with-emscripten-pthreads", description = "Enables emscripten build to use posix threads" } newoption { trigger = "with-mold-linker", description = "Tries to use the mold linker instead of the default linker of the toolchain" } newoption { trigger = "with-debug-symbols", description = "Release builds are built with debug symbols." } newoption { trigger = "thread-sanitizer", description = "Compile with ThreadSanitizer." } @@ -269,9 +268,7 @@ function build_base_configuration( package_name ) filter "system:emscripten" buildoptions { "-O3 -s USE_SDL=2 -s PRECISE_F32=1 -s ENVIRONMENT=worker,web" } - if _OPTIONS["with-emscripten-pthreads"] then - buildoptions { "-s USE_PTHREADS=1" } - end + buildoptions { "-s USE_PTHREADS=1" } filter {} end @@ -311,9 +308,7 @@ function build_base_cpp_configuration( package_name ) filter "system:emscripten" buildoptions { "-O3 -s USE_SDL=2 -s PRECISE_F32=1 -s ENVIRONMENT=worker,web" } - if _OPTIONS["with-emscripten-pthreads"] then - buildoptions { "-s USE_PTHREADS=1" } - end + buildoptions { "-s USE_PTHREADS=1" } filter {} end @@ -464,11 +459,8 @@ function build_link_configuration( package_name, use_ee_icon ) targetname ( package_name .. extension ) linkoptions { "-O3 -s TOTAL_MEMORY=536870912 -s ALLOW_MEMORY_GROWTH=1 -s USE_SDL=2" } buildoptions { "-O3 -s USE_SDL=2 -s PRECISE_F32=1 -s ENVIRONMENT=worker,web" } - - if _OPTIONS["with-emscripten-pthreads"] then - buildoptions { "-s USE_PTHREADS=1" } - linkoptions { "-s USE_PTHREADS=1 -sPTHREAD_POOL_SIZE=8" } - end + buildoptions { "-s USE_PTHREADS=1" } + linkoptions { "-s USE_PTHREADS=1 -sPTHREAD_POOL_SIZE=8" } if _OPTIONS["with-gles1"] and ( not _OPTIONS["with-gles2"] or _OPTIONS["force-gles1"] ) then linkoptions{ "-s LEGACY_GL_EMULATION=1" } diff --git a/projects/emscripten/make_mt.sh b/projects/emscripten/make_mt.sh deleted file mode 100755 index c656a276a..000000000 --- a/projects/emscripten/make_mt.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# Currently latest emsdk tested and working version: latest-fastcomp -# remember to first set the environment -# source /path/to/emsdk/emsdk_env.sh -cd $(dirname "$0") || exit -unset CPLUS_INCLUDE_PATH -premake4 --file=../../premake4.lua --with-emscripten-pthreads --with-gles2 --with-static-eepp --platform=emscripten --with-backend=SDL2 gmake -cd ../../make/emscripten/ || exit -rm -rf ./assets -cp -r ../../bin/assets/ . -rm assets/fonts/NotoColorEmoji.ttf assets/fonts/DejaVuSansMonoNerdFontComplete.ttf assets/fonts/DroidSansFallbackFull.ttf -rm -rf ./ecode -mkdir ecode -cp -r ../../bin/assets/ ecode/assets/ -rm ecode/assets/fonts/DejaVuSansMonoNerdFontComplete.ttf ecode/assets/fonts/DroidSansFallbackFull.ttf ecode/assets/fonts/NotoColorEmoji.ttf ecode/assets/test.zip ecode/assets/ca-bundle.pem ecode/assets/icon/ee.icns ecode/assets/icon/ee.rc ecode/assets/icon/ee.res ecode/assets/icon/ee.ico ecode/assets/fonts/*.png ecode/assets/fonts/*.fnt ecode/assets/fonts/OpenSans-Regular.ttf ecode/assets/icon/ecode.icns ecode/assets/icon/eterm* ecode/assets/icon/*.svg -rm -r ecode/assets/atlases ecode/assets/screenshots ecode/assets/cursors ecode/assets/layouts ecode/assets/maps ecode/assets/sounds ecode/assets/sprites ecode/assets/tiles ecode/assets/shaders ecode/assets/ui/uitheme* -emmake make -j"$(nproc)" "$@" diff --git a/src/eepp/ui/tools/uicodeeditorsplitter.cpp b/src/eepp/ui/tools/uicodeeditorsplitter.cpp index 5180716a6..31cab5bed 100644 --- a/src/eepp/ui/tools/uicodeeditorsplitter.cpp +++ b/src/eepp/ui/tools/uicodeeditorsplitter.cpp @@ -385,7 +385,6 @@ bool UICodeEditorSplitter::loadFileFromPath( const std::string& path, UICodeEdit void UICodeEditorSplitter::loadAsyncFileFromPath( const std::string& path, UICodeEditor* codeEditor, std::function onLoaded ) { -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) if ( !mThreadPool ) { Log::error( "UICodeEditorSplitter::loadAsyncFileFromPath loading file async " "without thread pool." ); @@ -417,15 +416,6 @@ void UICodeEditorSplitter::loadAsyncFileFromPath( onLoaded( codeEditor, path ); } ); } -#else - loadFileFromPath( path, codeEditor ); - if ( nullptr == codeEditor ) - codeEditor = mCurEditor; - if ( nullptr == codeEditor && !mTabWidgets.empty() ) - codeEditor = createCodeEditorInTabWidget( mTabWidgets[0] ).second; - if ( onLoaded ) - onLoaded( codeEditor, path ); -#endif } std::pair diff --git a/src/tools/ecode/appconfig.cpp b/src/tools/ecode/appconfig.cpp index c0432cc0e..a0a6f8cda 100644 --- a/src/tools/ecode/appconfig.cpp +++ b/src/tools/ecode/appconfig.cpp @@ -208,6 +208,8 @@ void AppConfig::load( const std::string& confPath, std::string& keybindingsPath, globalSearchBarConfig.wholeWord = ini.getValueB( "global_search_bar", "whole_word", false ); globalSearchBarConfig.escapeSequence = ini.getValueB( "global_search_bar", "escape_sequence", false ); + globalSearchBarConfig.bufferOnlyMode = + ini.getValueB( "global_search_bar", "buffer_only_mode", false ); term.shell = ini.getValue( "terminal", "shell" ); term.fontSize = ini.getValue( "terminal", "font_size", "11dp" ); @@ -362,6 +364,7 @@ void AppConfig::save( const std::vector& recentFiles, ini.setValueB( "global_search_bar", "regex", globalSearchBarConfig.regex ); ini.setValueB( "global_search_bar", "whole_word", globalSearchBarConfig.wholeWord ); ini.setValueB( "global_search_bar", "escape_sequence", globalSearchBarConfig.escapeSequence ); + ini.setValueB( "global_search_bar", "buffer_only_mode", globalSearchBarConfig.bufferOnlyMode ); ini.setValue( "terminal", "shell", term.shell ); ini.setValue( "terminal", "font_size", term.fontSize.toString() ); diff --git a/src/tools/ecode/appconfig.hpp b/src/tools/ecode/appconfig.hpp index f2c9b26aa..a85100a07 100644 --- a/src/tools/ecode/appconfig.hpp +++ b/src/tools/ecode/appconfig.hpp @@ -124,6 +124,7 @@ struct GlobalSearchBarConfig { bool luaPattern{ false }; bool wholeWord{ false }; bool escapeSequence{ false }; + bool bufferOnlyMode{ false }; }; struct ProjectDocumentConfig { diff --git a/src/tools/ecode/applayout.xml.hpp b/src/tools/ecode/applayout.xml.hpp index 41d2b5dc3..26ac77ac9 100644 --- a/src/tools/ecode/applayout.xml.hpp +++ b/src/tools/ecode/applayout.xml.hpp @@ -614,6 +614,7 @@ R"html( + diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 9a9e2f330..ded1b2e68 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -241,24 +241,28 @@ void App::updateEditorTabTitle( UICodeEditor* editor ) { return; if ( editor->getData() ) { UITab* tab = (UITab*)editor->getData(); - auto doc = editor->getDocumentRef(); - std::string fileName( doc->getFilename() ); + tab->ensureMainThread( [editor, isUniqueTabTitle, getTabWithSameTitle, getUniqueNameForTabs, + tab] { + auto doc = editor->getDocumentRef(); + std::string fileName( doc->getFilename() ); - if ( fileName != doc->getDefaultFileName() && !isUniqueTabTitle( tab ) ) { - auto tabsTitles = getUniqueNameForTabs( getTabWithSameTitle( tab ) ); - for ( auto [ntab, title] : tabsTitles ) { - ntab->setText( title ); - if ( ntab->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) ) - ntab->getOwnedWidget()->asType()->addClass( NOT_UNIQUE_FILENAME ); + if ( fileName != doc->getDefaultFileName() && !isUniqueTabTitle( tab ) ) { + auto tabsTitles = getUniqueNameForTabs( getTabWithSameTitle( tab ) ); + for ( auto [ntab, title] : tabsTitles ) { + ntab->setText( title ); + if ( ntab->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) ) + ntab->getOwnedWidget()->asType()->addClass( + NOT_UNIQUE_FILENAME ); + } + } else if ( tab->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) ) { + tab->getOwnedWidget()->asType()->removeClass( NOT_UNIQUE_FILENAME ); + tab->setText( fileName ); } - } else if ( tab->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) ) { - tab->getOwnedWidget()->asType()->removeClass( NOT_UNIQUE_FILENAME ); - tab->setText( fileName ); - } - bool dirty = doc->isDirty(); - tab->removeClass( dirty ? "tab_clear" : "tab_modified" ); - tab->addClass( dirty ? "tab_modified" : "tab_clear" ); + bool dirty = doc->isDirty(); + tab->removeClass( dirty ? "tab_clear" : "tab_modified" ); + tab->addClass( dirty ? "tab_modified" : "tab_clear" ); + } ); } } @@ -886,14 +890,9 @@ void App::onTextDropped( String text ) { App::App( const size_t& jobs, const std::vector& args ) : mArgs( args ), -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN - mThreadPool( ThreadPool::createShared( jobs > 0 ? jobs : eemax( 2, Sys::getCPUCount() ) ) ) -#elif defined( __EMSCRIPTEN_PTHREADS__ ) - mThreadPool( ThreadPool::createShared( jobs > 0 ? jobs : eemin( 8, Sys::getCPUCount() ) ) ) -#endif - , - mSettingsActions( std::make_unique( this ) ) { -} + mThreadPool( + ThreadPool::createShared( jobs > 0 ? jobs : eemax( 4, Sys::getCPUCount() ) ) ), + mSettingsActions( std::make_unique( this ) ) {} static void fsRemoveAll( const std::string& fpath ) { #if EE_PLATFORM == EE_PLATFORM_WIN @@ -2182,9 +2181,7 @@ void App::loadImageFromMedium( const std::string& path, bool isMemory ) { if ( imageView ) { mImageLayout->setEnabled( true )->setVisible( true ); loaderView->setVisible( true ); -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) mThreadPool->run( [this, imageView, loaderView, path, isMemory]() { -#endif Image::Format format = isMemory ? Image::getFormat( reinterpret_cast( path.c_str() ), path.size() ) @@ -2221,9 +2218,7 @@ void App::loadImageFromMedium( const std::string& path, bool isMemory ) { imageView->setDrawable( nullptr ); loaderView->setVisible( false ); } -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) } ); -#endif } } diff --git a/src/tools/ecode/globalsearchcontroller.cpp b/src/tools/ecode/globalsearchcontroller.cpp index ec4df2786..07596c9e8 100644 --- a/src/tools/ecode/globalsearchcontroller.cpp +++ b/src/tools/ecode/globalsearchcontroller.cpp @@ -1,5 +1,5 @@ -#include "ecode.hpp" #include "globalsearchcontroller.hpp" +#include "ecode.hpp" #include "uitreeviewglobalsearch.hpp" namespace ecode { @@ -53,18 +53,127 @@ static bool replaceInFile( const std::string& path, const std::vector model ) { - size_t count = 0; +static std::string getReplaceText( const ProjectSearch::ResultData::Result& result, + const std::string& replaceText ) { + std::string newText( replaceText ); + LuaPattern ptrn( "$(%d+)" ); + for ( auto& match : ptrn.gmatch( replaceText ) ) { + std::string matchSubStr( match.group( 0 ) ); // $1, $2, etc. + std::string matchNum( match.group( 1 ) ); // 1, 2, etc. + int num; + if ( String::fromString( num, matchNum ) && num > 0 && + num - 1 < static_cast( result.captures.size() ) ) { + String::replaceAll( newText, matchSubStr, result.captures[num - 1] ); + } + } + return newText; +} + +void GlobalSearchController::processNextReplaceInBuffer( + std::string&& replaceText, ProjectSearch::SearchConfig&& searchConfig, + std::function&& onDoneCb, int count, + std::vector&& pendingRes, bool hasCaptures ) { + if ( pendingRes.empty() ) { + onDoneCb( count ); + return; + } + auto current = std::move( pendingRes.back() ); + pendingRes.pop_back(); + auto doc = mSplitter->findDocFromPath( current.file ); + if ( doc ) { + auto results = + ProjectSearch::fileResFromDoc( searchConfig.searchString, searchConfig.caseSensitive, + searchConfig.wholeWord, searchConfig.type, doc ); + for ( const auto& result : results ) { + if ( result.selected ) { + auto oldSel = doc->getSelections(); + doc->setSelection( result.position ); + doc->replaceSelection( hasCaptures ? getReplaceText( result, replaceText ) + : replaceText ); + count++; + } + } + processNextReplaceInBuffer( std::move( replaceText ), std::move( searchConfig ), + std::move( onDoneCb ), count, std::move( pendingRes ), + hasCaptures ); + } else { + mSplitter->loadAsyncFileFromPathInNewTab( + current.file, + [this, current, count, pendingRes = std::move( pendingRes ), + replaceText = std::move( replaceText ), searchConfig = std::move( searchConfig ), + onDoneCb = std::move( onDoneCb ), + hasCaptures]( UICodeEditor* editor, const std::string& ) mutable { + auto doc = editor->getDocumentRef(); + auto results = ProjectSearch::fileResFromDoc( + searchConfig.searchString, searchConfig.caseSensitive, searchConfig.wholeWord, + searchConfig.type, doc ); + for ( const auto& result : results ) { + if ( result.selected ) { + auto oldSel = doc->getSelections(); + doc->setSelection( result.position ); + doc->replaceSelection( hasCaptures ? getReplaceText( result, replaceText ) + : replaceText ); + count++; + } + } + editor->scrollToCursor( true ); + processNextReplaceInBuffer( std::move( replaceText ), std::move( searchConfig ), + std::move( onDoneCb ), count, std::move( pendingRes ), + hasCaptures ); + } ); + } +} + +void GlobalSearchController::replaceInFiles( std::string replaceText, + std::shared_ptr model, + std::function onDoneCb, + bool bufferOnlyMode, + ProjectSearch::SearchConfig searchConfig ) { + int count = 0; if ( model->isResultFromSymbolReference() ) { // TODO Implement replacement from result from symbol reference - return count; + return onDoneCb( count ); } const ProjectSearch::Result& res = model->getResult(); bool hasCaptures = model->isResultFromPatternMatch() && LuaPattern::hasMatches( replaceText, "$%d+" ); + if ( bufferOnlyMode ) { + std::vector pendingResults; + + for ( const auto& fileResult : res ) { + if ( !fileResult.selected ) + continue; + + if ( fileResult.openDoc ) { + for ( const auto& result : fileResult.results ) { + if ( !result.selected ) + continue; + + auto oldSel = fileResult.openDoc->getSelections(); + fileResult.openDoc->setSelection( result.position ); + fileResult.openDoc->replaceSelection( + hasCaptures ? getReplaceText( result, replaceText ) : replaceText ); + fileResult.openDoc->setSelection( oldSel ); + count++; + } + } else { + pendingResults.push_back( fileResult ); + } + } + + if ( pendingResults.empty() ) { + onDoneCb( count ); + } else { + processNextReplaceInBuffer( std::move( replaceText ), std::move( searchConfig ), + std::move( onDoneCb ), count, std::move( pendingResults ), + hasCaptures ); + } + + return; + } + if ( hasCaptures ) { for ( const auto& fileResult : res ) { std::vector> replacements; @@ -73,24 +182,14 @@ size_t GlobalSearchController::replaceInFiles( const std::string& replaceText, for ( const auto& result : fileResult.results ) { if ( !result.selected ) continue; - std::string newText( replaceText ); - LuaPattern ptrn( "$(%d+)" ); - for ( auto& match : ptrn.gmatch( replaceText ) ) { - std::string matchSubStr( match.group( 0 ) ); // $1 $2 ... - std::string matchNum( match.group( 1 ) ); // 1 2 ... - int num; - if ( String::fromString( num, matchNum ) && num > 0 && - num - 1 < static_cast( result.captures.size() ) ) { - String::replaceAll( newText, matchSubStr, result.captures[num - 1] ); - replaceTexts.emplace_back( std::move( newText ) ); - } - } - if ( result.openDoc ) { - auto oldSel = result.openDoc->getSelections(); - result.openDoc->setSelection( result.position ); - result.openDoc->replaceSelection( replaceTexts[replaceTexts.size() - 1] ); - result.openDoc->setSelection( oldSel ); + replaceTexts.emplace_back( getReplaceText( result, replaceText ) ); + + if ( fileResult.openDoc ) { + auto oldSel = fileResult.openDoc->getSelections(); + fileResult.openDoc->setSelection( result.position ); + fileResult.openDoc->replaceSelection( replaceTexts.back() ); + fileResult.openDoc->setSelection( oldSel ); count++; } else { replacements.push_back( { result.start, result.end } ); @@ -99,33 +198,33 @@ size_t GlobalSearchController::replaceInFiles( const std::string& replaceText, if ( replacements.size() == replaceTexts.size() && replaceInFile( fileResult.file, replaceTexts, replacements ) ) - count += replacements.size(); + count += static_cast( replacements.size() ); } - return count; + return onDoneCb( count ); } for ( const auto& fileResult : res ) { std::vector> replacements; - - for ( const auto& result : fileResult.results ) + for ( const auto& result : fileResult.results ) { if ( result.selected ) { - if ( result.openDoc ) { - auto oldSel = result.openDoc->getSelections(); - result.openDoc->setSelection( result.position ); - result.openDoc->replaceSelection( replaceText ); - result.openDoc->setSelection( oldSel ); + if ( fileResult.openDoc ) { + auto oldSel = fileResult.openDoc->getSelections(); + fileResult.openDoc->setSelection( result.position ); + fileResult.openDoc->replaceSelection( replaceText ); + fileResult.openDoc->setSelection( oldSel ); count++; } else { replacements.push_back( { result.start, result.end } ); } } + } if ( !replacements.empty() && replaceInFile( fileResult.file, replaceText, replacements ) ) - count += replacements.size(); + count += static_cast( replacements.size() ); } - return count; + onDoneCb( count ); } void GlobalSearchController::showGlobalSearch() { @@ -178,6 +277,12 @@ void GlobalSearchController::initGlobalSearchBar( escapeSequenceChk->setTooltipText( escapeSequenceChk->getTooltipText() + " (" + kbindEscape + ")" ); + UICheckBox* bufferOnlyModeChk = mGlobalSearchBarLayout->find( "buffer_only_mode" ); + std::string kbindBufferOnlyMode = kbind.getCommandKeybindString( "buffer-only-mode" ); + if ( !kbindBufferOnlyMode.empty() ) + bufferOnlyModeChk->setTooltipText( bufferOnlyModeChk->getTooltipText() + " (" + + kbindBufferOnlyMode + ")" ); + UIWidget* searchBarClose = mGlobalSearchBarLayout->find( "global_searchbar_close" ); caseSensitiveChk->setChecked( globalSearchBarConfig.caseSensitive ); @@ -185,6 +290,7 @@ void GlobalSearchController::initGlobalSearchBar( luaPatternChk->setChecked( globalSearchBarConfig.luaPattern ); wholeWordChk->setChecked( globalSearchBarConfig.wholeWord ); escapeSequenceChk->setChecked( globalSearchBarConfig.escapeSequence ); + bufferOnlyModeChk->setChecked( globalSearchBarConfig.bufferOnlyMode ); mGlobalSearchInput = mGlobalSearchBarLayout->find( "global_search_find" ); mGlobalSearchWhereInput = mGlobalSearchBarLayout->find( "global_search_where" ); @@ -192,20 +298,20 @@ void GlobalSearchController::initGlobalSearchBar( mGlobalSearchHistoryList = mGlobalSearchBarLayout->find( "global_search_history" ); mGlobalSearchBarLayout->setCommand( "global-search-clear-history", [this] { clearHistory(); } ); - mGlobalSearchBarLayout->setCommand( - "search-in-files", - [this, caseSensitiveChk, wholeWordChk, luaPatternChk, escapeSequenceChk, regexChk] { - doGlobalSearch( mGlobalSearchInput->getText(), mGlobalSearchWhereInput->getText(), - caseSensitiveChk->isChecked(), wholeWordChk->isChecked(), - luaPatternChk->isChecked() - ? TextDocument::FindReplaceType::LuaPattern - : ( regexChk->isChecked() ? TextDocument::FindReplaceType::RegEx - : TextDocument::FindReplaceType::Normal ), - escapeSequenceChk->isChecked(), false ); - } ); + mGlobalSearchBarLayout->setCommand( "search-in-files", [this, caseSensitiveChk, wholeWordChk, + luaPatternChk, escapeSequenceChk, + regexChk, bufferOnlyModeChk] { + doGlobalSearch( mGlobalSearchInput->getText(), mGlobalSearchWhereInput->getText(), + caseSensitiveChk->isChecked(), wholeWordChk->isChecked(), + luaPatternChk->isChecked() + ? TextDocument::FindReplaceType::LuaPattern + : ( regexChk->isChecked() ? TextDocument::FindReplaceType::RegEx + : TextDocument::FindReplaceType::Normal ), + escapeSequenceChk->isChecked(), bufferOnlyModeChk->isChecked(), false ); + } ); mGlobalSearchBarLayout->setCommand( "search-again", [this, caseSensitiveChk, wholeWordChk, luaPatternChk, escapeSequenceChk, - regexChk] { + bufferOnlyModeChk, regexChk] { auto listBox = mGlobalSearchHistoryList->getListBox(); if ( listBox->getItemSelectedIndex() < mGlobalSearchHistory.size() ) { const auto& item = mGlobalSearchHistory[mGlobalSearchHistory.size() - 1 - @@ -216,7 +322,7 @@ void GlobalSearchController::initGlobalSearchBar( ? TextDocument::FindReplaceType::LuaPattern : ( regexChk->isChecked() ? TextDocument::FindReplaceType::RegEx : TextDocument::FindReplaceType::Normal ), - escapeSequenceChk->isChecked(), + escapeSequenceChk->isChecked(), bufferOnlyModeChk->isChecked(), mGlobalSearchTreeReplace == mGlobalSearchTree, true ); } } ); @@ -254,6 +360,9 @@ void GlobalSearchController::initGlobalSearchBar( mGlobalSearchBarLayout->setCommand( "change-escape-sequence", [escapeSequenceChk] { escapeSequenceChk->setChecked( !escapeSequenceChk->isChecked() ); } ); + mGlobalSearchBarLayout->setCommand( "buffer-only-mode", [bufferOnlyModeChk] { + bufferOnlyModeChk->setChecked( !bufferOnlyModeChk->isChecked() ); + } ); mGlobalSearchBarLayout->setCommand( "find-replace", [this] { mApp->showFindView(); } ); const auto pressEnterCb = [this]( const Event* event ) { if ( event->getNode()->hasFocus() ) { @@ -362,35 +471,35 @@ void GlobalSearchController::initGlobalSearchBar( } mGlobalSearchBarLayout->forceKeyDown( *keyEvent ); } ); - mGlobalSearchBarLayout->setCommand( "search-replace-in-files", [this, caseSensitiveChk, - wholeWordChk, luaPatternChk, - escapeSequenceChk, replaceInput, - regexChk] { - if ( mGlobalSearchTreeReplace == mGlobalSearchTree ) { - replaceInput->setFocus(); - replaceInput->getDocument().selectAll(); - return; - } - - // TODO Implement replacement from result from symbol reference - /*if ( mGlobalSearchHistory.back().second->isResultFromSymbolReference() ) { - mGlobalSearchTreeReplace->setModel( mGlobalSearchHistory.back().second ); - showGlobalSearch( true ); - updateGlobalSearchBarResults( mGlobalSearchHistory.back().first, - mGlobalSearchHistory.back().second, true, false ); - } else*/ - { - doGlobalSearch( mGlobalSearchInput->getText(), mGlobalSearchWhereInput->getText(), - caseSensitiveChk->isChecked(), wholeWordChk->isChecked(), - luaPatternChk->isChecked() - ? TextDocument::FindReplaceType::LuaPattern - : ( regexChk->isChecked() ? TextDocument::FindReplaceType::RegEx - : TextDocument::FindReplaceType::Normal ), - escapeSequenceChk->isChecked(), true ); - } - } ); mGlobalSearchBarLayout->setCommand( - "replace-in-files", [this, replaceInput, escapeSequenceChk] { + "search-replace-in-files", [this, caseSensitiveChk, wholeWordChk, luaPatternChk, + escapeSequenceChk, bufferOnlyModeChk, replaceInput, regexChk] { + if ( mGlobalSearchTreeReplace == mGlobalSearchTree ) { + replaceInput->setFocus(); + replaceInput->getDocument().selectAll(); + return; + } + + // TODO Implement replacement from result from symbol reference + /*if ( mGlobalSearchHistory.back().second->isResultFromSymbolReference() ) { + mGlobalSearchTreeReplace->setModel( mGlobalSearchHistory.back().second ); + showGlobalSearch( true ); + updateGlobalSearchBarResults( mGlobalSearchHistory.back().first, + mGlobalSearchHistory.back().second, true, false ); + } else*/ + { + doGlobalSearch( + mGlobalSearchInput->getText(), mGlobalSearchWhereInput->getText(), + caseSensitiveChk->isChecked(), wholeWordChk->isChecked(), + luaPatternChk->isChecked() + ? TextDocument::FindReplaceType::LuaPattern + : ( regexChk->isChecked() ? TextDocument::FindReplaceType::RegEx + : TextDocument::FindReplaceType::Normal ), + escapeSequenceChk->isChecked(), bufferOnlyModeChk->isChecked(), true ); + } + } ); + mGlobalSearchBarLayout->setCommand( + "replace-in-files", [this, replaceInput, escapeSequenceChk, bufferOnlyModeChk] { auto listBox = mGlobalSearchHistoryList->getListBox(); if ( listBox->getItemSelectedIndex() < mGlobalSearchHistory.size() ) { const auto& replaceData = mGlobalSearchHistory[mGlobalSearchHistory.size() - 1 - @@ -398,11 +507,17 @@ void GlobalSearchController::initGlobalSearchBar( String text( replaceInput->getText() ); if ( escapeSequenceChk->isChecked() ) text.unescape(); - size_t count = replaceInFiles( text.toUtf8(), replaceData.result ); - mGlobalSearchBarLayout->execute( "search-again" ); - mGlobalSearchBarLayout->execute( "close-global-searchbar" ); - mApp->getNotificationCenter()->addNotification( - String::format( "Replaced %zu occurrences.", count ) ); + replaceInFiles( + text.toUtf8(), replaceData.result, + [this]( int count ) { + mGlobalSearchBarLayout->ensureMainThread( [this, count] { + mGlobalSearchBarLayout->execute( "search-again" ); + mGlobalSearchBarLayout->execute( "close-global-searchbar" ); + mApp->getNotificationCenter()->addNotification( + String::format( "Replaced %zu occurrences.", count ) ); + } ); + }, + bufferOnlyModeChk->isChecked(), mLastSearchConfig ); } } ); mGlobalSearchTreeSearch = @@ -483,6 +598,7 @@ void GlobalSearchController::showGlobalSearch( bool searchReplace ) { loader->setVisible( true ); if ( !searchReplace ) { mGlobalSearchLayout->findByClass( "replace_box" )->setVisible( searchReplace ); + mGlobalSearchBarLayout->find( "buffer_only_mode" )->setVisible( searchReplace ); if ( wasReplaceTree ) { updateGlobalSearchBarResults( mGlobalSearchTreeReplace->getSearchStr(), std::static_pointer_cast( @@ -523,12 +639,14 @@ GlobalSearchBarConfig GlobalSearchController::getGlobalSearchBarConfig() const { UICheckBox* regexChk = mGlobalSearchBarLayout->find( "regex" ); UICheckBox* luaPatternChk = mGlobalSearchBarLayout->find( "lua_pattern" ); UICheckBox* escapeSequenceChk = mGlobalSearchBarLayout->find( "escape_sequence" ); + UICheckBox* bufferOnlyModeChk = mGlobalSearchBarLayout->find( "buffer_only_mode" ); GlobalSearchBarConfig globalSeachBarConfig; globalSeachBarConfig.caseSensitive = caseSensitiveChk->isChecked(); globalSeachBarConfig.regex = regexChk->isChecked(); globalSeachBarConfig.luaPattern = luaPatternChk->isChecked(); globalSeachBarConfig.wholeWord = wholeWordChk->isChecked(); globalSeachBarConfig.escapeSequence = escapeSequenceChk->isChecked(); + globalSeachBarConfig.bufferOnlyMode = bufferOnlyModeChk->isChecked(); return globalSeachBarConfig; } @@ -581,6 +699,7 @@ void GlobalSearchController::updateGlobalSearchBarResults( ->setText( String::format( "%zu matches found.", model->resultCount() ) ); mGlobalSearchLayout->findByClass( "status_box" )->setVisible( true ); mGlobalSearchLayout->findByClass( "replace_box" )->setVisible( searchReplace ); + mGlobalSearchBarLayout->find( "buffer_only_mode" )->setVisible( searchReplace ); if ( searchReplace && mGlobalSearchBarLayout->isVisible() ) { auto* replaceInput = mGlobalSearchLayout->find( "global_search_replace_input" ); @@ -641,8 +760,8 @@ std::vector GlobalSearchController::parseGlobMatches( const String& s void GlobalSearchController::doGlobalSearch( String text, String filter, bool caseSensitive, bool wholeWord, TextDocument::FindReplaceType searchType, - bool escapeSequence, bool searchReplace, - bool searchAgain ) { + bool escapeSequence, bool bufferOnlyMode, + bool searchReplace, bool searchAgain ) { if ( mApp->getDirTree() && mApp->getDirTree()->getFilesCount() > 0 && !text.empty() ) { mGlobalSearchTree = searchReplace ? mGlobalSearchTreeReplace : mGlobalSearchTreeSearch; mGlobalSearchTreeSearch->setVisible( !searchReplace ); @@ -684,17 +803,16 @@ void GlobalSearchController::doGlobalSearch( String text, String filter, bool ca } ProjectSearch::find( - mApp->getDirTree()->getFiles(), search, -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) - mApp->getThreadPool(), -#endif + mApp->getDirTree()->getFiles(), search, mApp->getThreadPool(), [this, clock, search, loader, searchReplace, searchAgain, escapeSequence, searchType, - filter]( const ProjectSearch::Result& res ) { + filter]( const ProjectSearch::ConsolidatedResult& res ) { Log::info( "Global search for \"%s\" took %s", search.c_str(), clock.getElapsedTime().toString() ); - mUISceneNode->runOnMainThread( [this, loader, res, search, searchReplace, - searchAgain, escapeSequence, searchType, filter] { - auto model = ProjectSearch::asModel( res ); + mUISceneNode->runOnMainThread( [this, loader, res = std::move( res ), search, + searchReplace, searchAgain, escapeSequence, + searchType, filter] { + mLastSearchConfig = std::move( res.first ); + auto model = ProjectSearch::asModel( res.second ); model->setOpType( searchType ); updateGlobalSearchHistory( model, search, filter, searchReplace, searchAgain, escapeSequence ); diff --git a/src/tools/ecode/globalsearchcontroller.hpp b/src/tools/ecode/globalsearchcontroller.hpp index da875d7a0..4b372c74c 100644 --- a/src/tools/ecode/globalsearchcontroller.hpp +++ b/src/tools/ecode/globalsearchcontroller.hpp @@ -27,6 +27,7 @@ class GlobalSearchController { { "mod+shift+e", "collapse-all" }, { "mod+e", "change-escape-sequence" }, { "mod+h", "global-search-clear-history" }, + { "mod+b", "buffer-only-mode" }, }; } @@ -50,10 +51,7 @@ class GlobalSearchController { void doGlobalSearch( String text, String filter, bool caseSensitive, bool wholeWord, TextDocument::FindReplaceType searchType, bool escapeSequence, - bool searchReplace, bool searchAgain = false ); - - size_t replaceInFiles( const std::string& replaceText, - std::shared_ptr model ); + bool bufferOnlyMode, bool searchReplace, bool searchAgain = false ); void showGlobalSearch(); @@ -88,6 +86,7 @@ class GlobalSearchController { }; std::deque mGlobalSearchHistory; bool mValueChanging{ false }; + ProjectSearch::SearchConfig mLastSearchConfig; void onLoadDone( const Variant& lineNum, const Variant& colNum ); @@ -98,6 +97,16 @@ class GlobalSearchController { bool searchReplace, bool searchAgain, bool escapeSequence ); std::vector parseGlobMatches( const String& str ); + + void replaceInFiles( std::string replaceText, std::shared_ptr model, + std::function onDoneCb, bool bufferOnlyMode, + ProjectSearch::SearchConfig searchConfig ); + + void processNextReplaceInBuffer( std::string&& replaceText, + ProjectSearch::SearchConfig&& searchConfig, + std::function&& onDoneCb, int count, + std::vector&& pendingRes, + bool hasCaptures ); }; } // namespace ecode diff --git a/src/tools/ecode/plugins/aiassistant/aiassistantplugin.cpp b/src/tools/ecode/plugins/aiassistant/aiassistantplugin.cpp index badfd313d..0f2e917a5 100644 --- a/src/tools/ecode/plugins/aiassistant/aiassistantplugin.cpp +++ b/src/tools/ecode/plugins/aiassistant/aiassistantplugin.cpp @@ -10,12 +10,6 @@ using json = nlohmann::json; -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) -#define AIASSISTANT_THREADED 1 -#else -#define AIASSISTANT_THREADED 0 -#endif - namespace ecode { static std::initializer_list AIAssistantUnlockedCommandList = { @@ -126,11 +120,7 @@ AIAssistantPlugin::AIAssistantPlugin( PluginManager* pluginManager, bool sync ) if ( sync ) { load( pluginManager ); } else { -#if defined( AIASSISTANT_THREADED ) && AIASSISTANT_THREADED == 1 mThreadPool->run( [this, pluginManager] { load( pluginManager ); } ); -#else - load( pluginManager ); -#endif } if ( getUISceneNode() ) { diff --git a/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp b/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp index e2c545601..803e9c873 100644 --- a/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp +++ b/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp @@ -23,12 +23,6 @@ static constexpr auto SNIPPET_PTRN1 = "%$%{%d+%}"sv; static constexpr auto SNIPPET_PTRN2 = "%$%{%d+%:([%w,.%s%+%-]+)}"sv; static constexpr auto SNIPPET_PTRN3 = "%$%d+"sv; -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) -#define AUTO_COMPLETE_THREADED 1 -#else -#define AUTO_COMPLETE_THREADED 0 -#endif - static json getURIJSON( TextDocument* doc, const PluginIDType& id ) { json data; data["uri"] = doc->getURI().toString(); @@ -102,11 +96,7 @@ AutoCompletePlugin::AutoCompletePlugin( PluginManager* pluginManager, bool sync if ( sync ) { load( pluginManager ); } else { -#if defined( AUTO_COMPLETE_THREADED ) && AUTO_COMPLETE_THREADED == 1 mThreadPool->run( [this, pluginManager] { load( pluginManager ); } ); -#else - load( pluginManager ); -#endif } } @@ -317,15 +307,10 @@ void AutoCompletePlugin::onRegister( UICodeEditor* editor ) { const DocSyntaxDefEvent* event = static_cast( ev ); std::string oldLang = event->getOldLang(); std::string newLang = event->getNewLang(); -#if defined( AUTO_COMPLETE_THREADED ) && AUTO_COMPLETE_THREADED == 1 mThreadPool->run( [this, oldLang, newLang] { updateLangCache( oldLang ); updateLangCache( newLang ); } ); -#else - updateLangCache( oldLang ); - updateLangCache( newLang ); -#endif } ) ); if ( editor->hasDocument() ) { @@ -1009,11 +994,7 @@ void AutoCompletePlugin::update( UICodeEditor* ) { if ( du != mDocsUpdating.end() && du->second == true ) continue; } -#if AUTO_COMPLETE_THREADED mThreadPool->run( [this, doc] { updateDocCache( doc ); } ); -#else - updateDocCache( doc ); -#endif } } } @@ -1475,13 +1456,9 @@ void AutoCompletePlugin::updateSuggestions( const std::string& symbol, UICodeEdi return; const auto& symbols = docCache->second.symbols; { -#if AUTO_COMPLETE_THREADED mThreadPool->run( [this, symbol, &symbols, editor] { runUpdateSuggestions( symbol, symbols, editor, true ); } ); -#else - runUpdateSuggestions( symbol, symbols, editor, true ); -#endif } } @@ -1492,13 +1469,9 @@ void AutoCompletePlugin::updateSuggestions( const std::string& symbol, UICodeEdi return; const auto& symbols = langSuggestions->second; { -#if AUTO_COMPLETE_THREADED mThreadPool->run( [this, symbol, &symbols, editor] { runUpdateSuggestions( symbol, symbols, editor, false ); } ); -#else - runUpdateSuggestions( symbol, symbols, editor, false ); -#endif } } diff --git a/src/tools/ecode/plugins/debugger/debuggerplugin.cpp b/src/tools/ecode/plugins/debugger/debuggerplugin.cpp index 9352c3fc0..1dda055eb 100644 --- a/src/tools/ecode/plugins/debugger/debuggerplugin.cpp +++ b/src/tools/ecode/plugins/debugger/debuggerplugin.cpp @@ -28,12 +28,6 @@ using json = nlohmann::json; static constexpr auto REQUEST_TYPE_LAUNCH = "launch"; static constexpr auto REQUEST_TYPE_ATTACH = "attach"; -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) -#define DEBUGGER_THREADED 1 -#else -#define DEBUGGER_THREADED 0 -#endif - namespace ecode { static constexpr auto INPUT_PATTERN = "%$%{input%:([%w_]+)%}"sv; @@ -143,11 +137,7 @@ DebuggerPlugin::DebuggerPlugin( PluginManager* pluginManager, bool sync ) : if ( sync ) { load( pluginManager ); } else { -#if defined( DEBUGGER_THREADED ) && DEBUGGER_THREADED == 1 mThreadPool->run( [this, pluginManager] { load( pluginManager ); } ); -#else - load( pluginManager ); -#endif } } diff --git a/src/tools/ecode/plugins/discordRPC/discordRPCplugin.cpp b/src/tools/ecode/plugins/discordRPC/discordRPCplugin.cpp index b2a47dff2..38344aa0a 100644 --- a/src/tools/ecode/plugins/discordRPC/discordRPCplugin.cpp +++ b/src/tools/ecode/plugins/discordRPC/discordRPCplugin.cpp @@ -1,11 +1,6 @@ #include "discordRPCplugin.hpp" using json = nlohmann::json; -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) -#define dcRPC_THREADED 1 -#else -#define dcRPC_THREADED 0 -#endif namespace ecode { @@ -29,11 +24,7 @@ DiscordRPCplugin::DiscordRPCplugin( PluginManager* pluginManager, bool sync ) : if ( sync ) { load( pluginManager ); } else { -#if defined( dcRPC_THREADED ) && dcRPC_THREADED == 1 mThreadPool->run( [this, pluginManager] { load( pluginManager ); } ); -#else - load( pluginManager ); -#endif } } diff --git a/src/tools/ecode/plugins/formatter/formatterplugin.cpp b/src/tools/ecode/plugins/formatter/formatterplugin.cpp index a6c12e3ed..c9351880e 100644 --- a/src/tools/ecode/plugins/formatter/formatterplugin.cpp +++ b/src/tools/ecode/plugins/formatter/formatterplugin.cpp @@ -17,12 +17,6 @@ using json = nlohmann::json; namespace ecode { -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) -#define FORMATTER_THREADED 1 -#else -#define FORMATTER_THREADED 0 -#endif - Plugin* FormatterPlugin::New( PluginManager* pluginManager ) { return eeNew( FormatterPlugin, ( pluginManager, false ) ); } @@ -36,11 +30,7 @@ FormatterPlugin::FormatterPlugin( PluginManager* pluginManager, bool sync ) : if ( sync ) { load( pluginManager ); } else { -#if defined( FORMATTER_THREADED ) && FORMATTER_THREADED == 1 mThreadPool->run( [this, pluginManager] { load( pluginManager ); } ); -#else - load( pluginManager ); -#endif } } diff --git a/src/tools/ecode/plugins/git/gitplugin.cpp b/src/tools/ecode/plugins/git/gitplugin.cpp index dcaee7d0d..7d2d5f0f6 100644 --- a/src/tools/ecode/plugins/git/gitplugin.cpp +++ b/src/tools/ecode/plugins/git/gitplugin.cpp @@ -26,11 +26,6 @@ using namespace EE::UI::Doc; using namespace std::literals; using json = nlohmann::json; -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) -#define GIT_THREADED 1 -#else -#define GIT_THREADED 0 -#endif namespace ecode { @@ -74,11 +69,7 @@ GitPlugin::GitPlugin( PluginManager* pluginManager, bool sync ) : if ( sync ) { load( pluginManager ); } else { -#if defined( GIT_THREADED ) && GIT_THREADED == 1 mThreadPool->run( [this, pluginManager] { load( pluginManager ); } ); -#else - load( pluginManager ); -#endif } } diff --git a/src/tools/ecode/plugins/linter/linterplugin.cpp b/src/tools/ecode/plugins/linter/linterplugin.cpp index 3a1633184..5216b3e8d 100644 --- a/src/tools/ecode/plugins/linter/linterplugin.cpp +++ b/src/tools/ecode/plugins/linter/linterplugin.cpp @@ -20,12 +20,6 @@ using json = nlohmann::json; namespace ecode { -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) -#define LINTER_THREADED 1 -#else -#define LINTER_THREADED 0 -#endif - Plugin* LinterPlugin::New( PluginManager* pluginManager ) { return eeNew( LinterPlugin, ( pluginManager, false ) ); } @@ -38,11 +32,7 @@ LinterPlugin::LinterPlugin( PluginManager* pluginManager, bool sync ) : Plugin( if ( sync ) { load( pluginManager ); } else { -#if defined( LINTER_THREADED ) && LINTER_THREADED == 1 mThreadPool->run( [this, pluginManager] { load( pluginManager ); } ); -#else - load( pluginManager ); -#endif } } @@ -713,11 +703,7 @@ void LinterPlugin::update( UICodeEditor* editor ) { auto it = mDirtyDoc.find( doc.get() ); if ( it != mDirtyDoc.end() && it->second->getElapsedTime() >= mDelayTime ) { mDirtyDoc.erase( doc.get() ); -#if LINTER_THREADED mThreadPool->run( [this, doc] { lintDoc( doc ); } ); -#else - lintDoc( doc ); -#endif } } diff --git a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp index 1a07b575b..a08807687 100644 --- a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp @@ -25,12 +25,6 @@ using json = nlohmann::json; namespace ecode { -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) -#define LSPCLIENT_THREADED 1 -#else -#define LSPCLIENT_THREADED 0 -#endif - static Action::UniqueID getMouseMoveHash( UICodeEditor* editor ) { return hashCombine( String::hash( "LSPClientPlugin::onMouseMove-" ), reinterpret_cast( editor ) ); @@ -245,11 +239,7 @@ LSPClientPlugin::LSPClientPlugin( PluginManager* pluginManager, bool sync ) : if ( sync ) { load( pluginManager ); } else { -#if defined( LSPCLIENT_THREADED ) && LSPCLIENT_THREADED == 1 mThreadPool->run( [this, pluginManager] { load( pluginManager ); } ); -#else - load( pluginManager ); -#endif } } diff --git a/src/tools/ecode/plugins/xmltools/xmltoolsplugin.cpp b/src/tools/ecode/plugins/xmltools/xmltoolsplugin.cpp index d421de3dd..0373ad78c 100644 --- a/src/tools/ecode/plugins/xmltools/xmltoolsplugin.cpp +++ b/src/tools/ecode/plugins/xmltools/xmltoolsplugin.cpp @@ -5,11 +5,6 @@ #include using json = nlohmann::json; -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) -#define XMLTOOLS_THREADED 1 -#else -#define XMLTOOLS_THREADED 0 -#endif namespace ecode { @@ -26,11 +21,7 @@ XMLToolsPlugin::XMLToolsPlugin( PluginManager* pluginManager, bool sync ) : if ( sync ) { load( pluginManager ); } else { -#if defined( XMLTOOLS_THREADED ) && XMLTOOLS_THREADED == 1 mThreadPool->run( [this, pluginManager] { load( pluginManager ); } ); -#else - load( pluginManager ); -#endif } } diff --git a/src/tools/ecode/projectdirectorytree.cpp b/src/tools/ecode/projectdirectorytree.cpp index cd518386a..0e85f1bb2 100644 --- a/src/tools/ecode/projectdirectorytree.cpp +++ b/src/tools/ecode/projectdirectorytree.cpp @@ -39,10 +39,8 @@ ProjectDirectoryTree::~ProjectDirectoryTree() { void ProjectDirectoryTree::scan( const ProjectDirectoryTree::ScanCompleteEvent& scanComplete, const std::vector& acceptedPatterns, const bool& ignoreHidden ) { -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) mPool->run( [this, acceptedPatterns = std::move( acceptedPatterns ), ignoreHidden] { -#endif Lock l( mFilesMutex ); mRunning = true; mIgnoreHidden = ignoreHidden; @@ -93,11 +91,6 @@ void ProjectDirectoryTree::scan( const ProjectDirectoryTree::ScanCompleteEvent& return processMessage( msg ); } ); } -#if EE_PLATFORM == EE_PLATFORM_EMSCRIPTEN && !defined( __EMSCRIPTEN_PTHREADS__ ) - if ( scanComplete ) - scanComplete( *this ); -#endif -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) }, [scanComplete, this]( const auto& ) { if ( !mClosing && scanComplete ) { @@ -106,7 +99,6 @@ void ProjectDirectoryTree::scan( const ProjectDirectoryTree::ScanCompleteEvent& } mRunning = false; } ); -#endif } std::shared_ptr diff --git a/src/tools/ecode/projectsearch.cpp b/src/tools/ecode/projectsearch.cpp index 3f3186632..af29cd7c2 100644 --- a/src/tools/ecode/projectsearch.cpp +++ b/src/tools/ecode/projectsearch.cpp @@ -159,44 +159,6 @@ static std::vector searchInFileRegEx( const s return searchInFilePatternMatch( file, pattern, caseSensitive, wholeWord ); } -void ProjectSearch::find( const std::vector files, const std::string& string, - ResultCb result, bool caseSensitive, bool wholeWord, - const TextDocument::FindReplaceType& type, - const std::vector& pathFilters, std::string basePath, - std::vector> ) { - Result res; - const auto occ = - type == TextDocument::FindReplaceType::Normal - ? String::BMH::createOccTable( (const unsigned char*)string.c_str(), string.size() ) - : std::vector(); - for ( auto& file : files ) { - bool skip = false; - std::string_view fsv( file ); - if ( !basePath.empty() && String::startsWith( file, basePath ) ) - fsv = fsv.substr( basePath.size() ); - - for ( const auto& filter : pathFilters ) { - bool matches = String::globMatch( fsv, filter.first ); - if ( ( matches && filter.second ) || ( !matches && !filter.second ) ) { - skip = true; - break; - } - } - if ( skip ) - continue; - - auto fileRes = - type == TextDocument::FindReplaceType::Normal - ? searchInFileHorspool( file, string, caseSensitive, wholeWord, occ ) - : ( type == TextDocument::FindReplaceType::LuaPattern - ? searchInFileLuaPattern( file, string, caseSensitive, wholeWord ) - : searchInFileRegEx( file, string, caseSensitive, wholeWord ) ); - if ( !fileRes.empty() ) - res.push_back( { file, fileRes } ); - } - result( res ); -} - struct FindData { Mutex resMutex; Mutex countMutex; @@ -204,6 +166,32 @@ struct FindData { ProjectSearch::Result res; }; +std::vector +ProjectSearch::fileResFromDoc( const std::string& string, bool caseSensitive, bool wholeWord, + TextDocument::FindReplaceType type, + std::shared_ptr doc ) { + auto res = doc->findAll( string, caseSensitive, wholeWord, type ); + std::vector fileRes; + for ( const auto& r : res ) { + ProjectSearch::ResultData::Result f; + f.position = r.result; + const auto& line = doc->line( r.result.start().line() ); + if ( line.size() > EE_1KB ) + f.line = line.substr( 0, EE_1KB ); + else + f.line = line.getTextWithoutNewLine(); + f.start = r.result.start().column(); + f.end = r.result.end().column(); + std::vector captures; + for ( const auto& capture : r.captures ) + captures.emplace_back( doc->getText( capture ).toUtf8() ); + f.captures = std::move( captures ); + fileRes.emplace_back( std::move( f ) ); + } + + return fileRes; +} + void ProjectSearch::find( const std::vector files, std::string string, std::shared_ptr pool, ResultCb result, bool caseSensitive, bool wholeWord, const TextDocument::FindReplaceType& type, @@ -216,6 +204,7 @@ void ProjectSearch::find( const std::vector files, std::string stri result = std::move( result ), caseSensitive, wholeWord, type, pathFilters = std::move( pathFilters ), basePath = std::move( basePath ), openDocs = std::move( openDocs )]() mutable { + SearchConfig searchConfig( string, caseSensitive, wholeWord, type ); FindData* findData = eeNew( FindData, () ); findData->resCount = files.size(); if ( !caseSensitive ) @@ -267,7 +256,7 @@ void ProjectSearch::find( const std::vector files, std::string stri findData->resCount = count; if ( count == 0 ) { - result( findData->res ); + result( { searchConfig, findData->res } ); eeDelete( findData ); return; } @@ -286,7 +275,7 @@ void ProjectSearch::find( const std::vector files, std::string stri pos++; - const auto onSearchEnd = [result, findData]( const auto& ) { + const auto onSearchEnd = [result, findData, searchConfig]( const auto& ) { int count; { Lock l( findData->countMutex ); @@ -294,7 +283,7 @@ void ProjectSearch::find( const std::vector files, std::string stri count = findData->resCount; } if ( count == 0 ) { - result( findData->res ); + result( { searchConfig, findData->res } ); eeDelete( findData ); #if EE_PLATFORM == EE_PLATFORM_LINUX && defined( __GLIBC__ ) malloc_trim( 0 ); @@ -311,30 +300,14 @@ void ProjectSearch::find( const std::vector files, std::string stri if ( openDoc && openPath->second->isDirty() ) { pool->run( [findData, doc, string, caseSensitive, wholeWord, type] { - auto res = doc->findAll( string, caseSensitive, wholeWord, type ); - std::vector fileRes; - for ( const auto& r : res ) { - ProjectSearch::ResultData::Result f; - f.openDoc = doc; - f.position = r.result; - const auto& line = doc->line( r.result.start().line() ); - if ( line.size() > EE_1KB ) - f.line = line.substr( 0, EE_1KB ); - else - f.line = line.getTextWithoutNewLine(); - f.start = r.result.start().column(); - f.end = r.result.end().column(); - std::vector captures; - for ( const auto& capture : r.captures ) - captures.emplace_back( doc->getText( capture ).toUtf8() ); - f.captures = std::move( captures ); - fileRes.emplace_back( std::move( f ) ); - } + std::vector fileRes = + fileResFromDoc( string, caseSensitive, wholeWord, type, doc ); if ( !fileRes.empty() ) { Lock l( findData->resMutex ); std::string file( doc->getFilePath() ); - findData->res.push_back( { std::move( file ), std::move( fileRes ) } ); + findData->res.push_back( + { std::move( file ), std::move( fileRes ), doc } ); } }, onSearchEnd ); diff --git a/src/tools/ecode/projectsearch.hpp b/src/tools/ecode/projectsearch.hpp index f341a989f..d8df9cfc2 100644 --- a/src/tools/ecode/projectsearch.hpp +++ b/src/tools/ecode/projectsearch.hpp @@ -21,6 +21,13 @@ using GlobMatch = std::pair; // where string is the glob and class ProjectSearch { public: + struct SearchConfig { + std::string searchString; + bool caseSensitive; + bool wholeWord; + TextDocument::FindReplaceType type; + }; + struct ResultData { struct Result { Result( const String& line, const TextRange& pos, Int64 s, Int64 e ) : @@ -32,10 +39,10 @@ class ProjectSearch { Int64 end{ 0 }; bool selected{ true }; std::vector captures; - std::shared_ptr openDoc; }; std::string file; std::vector results; + std::shared_ptr openDoc{ nullptr }; bool selected{ true }; void setResultsSelected( bool selected ) { @@ -61,8 +68,9 @@ class ProjectSearch { } }; - typedef std::vector Result; - typedef std::function ResultCb; + using Result = std::vector; + using ConsolidatedResult = std::pair; + using ResultCb = std::function; class ResultModel : public Model { public: @@ -213,12 +221,9 @@ class ProjectSearch { return std::make_shared( result ); } - static void - find( const std::vector files, const std::string& string, ResultCb result, - bool caseSensitive, bool wholeWord = false, - const TextDocument::FindReplaceType& type = TextDocument::FindReplaceType::Normal, - const std::vector& pathFilters = {}, std::string basePath = "", - std::vector> openDocs = {} ); + static std::vector + fileResFromDoc( const std::string& string, bool caseSensitive, bool wholeWord, + TextDocument::FindReplaceType type, std::shared_ptr doc ); static void find( const std::vector files, std::string string, diff --git a/src/tools/ecode/statusbuildoutputcontroller.cpp b/src/tools/ecode/statusbuildoutputcontroller.cpp index 55a84800e..505ae640a 100644 --- a/src/tools/ecode/statusbuildoutputcontroller.cpp +++ b/src/tools/ecode/statusbuildoutputcontroller.cpp @@ -493,7 +493,6 @@ void StatusBuildOutputController::createContainer() { onLoadDone( lineNum, colNum ); } ); } else { -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) removeRelativeSubPaths( path ); mContext->getDirTree()->asyncMatchTree( ProjectDirectoryTree::MatchType::Fuzzy, path, 1, @@ -518,7 +517,6 @@ void StatusBuildOutputController::createContainer() { } } ); } ); -#endif } } else { tab->getTabWidget()->setTabSelected( tab ); diff --git a/src/tools/ecode/universallocator.cpp b/src/tools/ecode/universallocator.cpp index 3162a46db..4a425eeb8 100644 --- a/src/tools/ecode/universallocator.cpp +++ b/src/tools/ecode/universallocator.cpp @@ -355,7 +355,6 @@ void UniversalLocator::updateFilesTable( bool useGlob ) { ProjectDirectoryTree::emptyModel( getLocatorCommands(), mApp->getCurrentProject() ) ); mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); } else if ( !mLocateInput->getText().empty() ) { -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) mApp->getDirTree()->asyncMatchTree( useGlob ? ProjectDirectoryTree::MatchType::Glob : ProjectDirectoryTree::MatchType::Fuzzy, @@ -369,15 +368,6 @@ void UniversalLocator::updateFilesTable( bool useGlob ) { } ); }, mApp->getCurrentProject() ); -#else - mLocateTable->setModel( - useGlob ? mApp->getDirTree()->globMatchTree( text, LOCATEBAR_MAX_RESULTS, - mApp->getCurrentProject() ) - : mApp->getDirTree()->fuzzyMatchTree( text, LOCATEBAR_MAX_RESULTS, - mApp->getCurrentProject() ) ); - mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); - mLocateTable->scrollToTop(); -#endif } else { mLocateTable->setModel( mApp->getDirTree()->asModel( LOCATEBAR_MAX_RESULTS, getLocatorCommands(), mApp->getCurrentProject(), @@ -403,7 +393,6 @@ void UniversalLocator::updateCommandPaletteTable() { txt.trim(); if ( txt.size() > 1 ) { -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) mCommandPalette.asyncFuzzyMatch( txt.substr( 1 ).trim(), 10000, [this]( auto res ) { mUISceneNode->runOnMainThread( [this, res] { mLocateTable->setModel( res ); @@ -412,12 +401,6 @@ void UniversalLocator::updateCommandPaletteTable() { mLocateTable->scrollToTop(); } ); } ); -#else - mLocateTable->setModel( mCommandPalette.fuzzyMatch( txt.substr( 1 ).trim(), 10000 ) ); - if ( mLocateTable->getModel()->hasChilds() ) - mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); - mLocateTable->scrollToTop(); -#endif } else if ( mCommandPalette.getCurModel() ) { mLocateTable->setModel( mCommandPalette.getCurModel() ); if ( mLocateTable->getModel()->hasChilds() ) @@ -1097,7 +1080,6 @@ void UniversalLocator::requestDocumentSymbol() { } void UniversalLocator::updateDocumentSymbol( const LSPSymbolInformationList& res ) { -#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) if ( mCurDocQuery.empty() ) { mTextDocumentSymbolModel = LSPSymbolInfoModel::create( mApp->getUISceneNode(), mCurDocQuery, res, true ); @@ -1114,21 +1096,6 @@ void UniversalLocator::updateDocumentSymbol( const LSPSymbolInformationList& res } ); } ); } -#else - mUISceneNode->runOnMainThread( [this, res] { - if ( mCurDocQuery.empty() ) { - mTextDocumentSymbolModel = - LSPSymbolInfoModel::create( mApp->getUISceneNode(), mCurDocQuery, res, true ); - } else { - mTextDocumentSymbolModel = LSPSymbolInfoModel::create( - mApp->getUISceneNode(), mCurDocQuery, - fuzzyMatchTextDocumentSymbol( res, mCurDocQuery, 100 ), true ); - } - mLocateTable->setModel( mTextDocumentSymbolModel ); - mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); - mLocateTable->scrollToTop(); - } ); -#endif } std::string UniversalLocator::getCurDocURI() {