diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index ba397a445..c7d7e7395 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -230,7 +230,7 @@ void App::openFileDialog() { } std::string App::getLastUsedFolder() { - if ( !mCurrentProject.empty() ) + if ( !mCurrentProject.empty() && mCurrentProject != getPlaygroundPath() ) return mCurrentProject; if ( !mRecentFolders.empty() ) return mRecentFolders.front(); diff --git a/src/tools/ecode/projectdirectorytree.cpp b/src/tools/ecode/projectdirectorytree.cpp index cbdde6013..9944ff942 100644 --- a/src/tools/ecode/projectdirectorytree.cpp +++ b/src/tools/ecode/projectdirectorytree.cpp @@ -47,7 +47,8 @@ void ProjectDirectoryTree::scan( const ProjectDirectoryTree::ScanCompleteEvent& mDirectories.push_back( mPath ); if ( !mAllowedMatcher && FileSystem::fileExists( mPath + PRJ_ALLOWED_PATH ) ) - mAllowedMatcher = std::make_unique( mPath, PRJ_ALLOWED_PATH, false ); + mAllowedMatcher = + std::make_unique( mPath, PRJ_ALLOWED_PATH, false ); if ( !acceptedPatterns.empty() ) { std::vector files; @@ -104,8 +105,8 @@ void ProjectDirectoryTree::scan( const ProjectDirectoryTree::ScanCompleteEvent& } std::shared_ptr -ProjectDirectoryTree::fuzzyMatchTree( const std::vector& matches, - const size_t& max ) const { +ProjectDirectoryTree::fuzzyMatchTree( const std::vector& matches, const size_t& max, + const std::string& basePath ) const { Lock rl( mMatchingMutex ); std::multimap> matchesMap; std::vector files; @@ -123,11 +124,14 @@ ProjectDirectoryTree::fuzzyMatchTree( const std::vector& matches, files.emplace_back( mFiles[res.second] ); } } - return std::make_shared( files, names ); + auto model = std::make_shared( files, names ); + model->setBasePath( basePath ); + return model; } -std::shared_ptr ProjectDirectoryTree::fuzzyMatchTree( const std::string& match, - const size_t& max ) const { +std::shared_ptr +ProjectDirectoryTree::fuzzyMatchTree( const std::string& match, const size_t& max, + const std::string& basePath ) const { Lock rl( mMatchingMutex ); std::multimap> matchesMap; std::vector files; @@ -143,11 +147,14 @@ std::shared_ptr ProjectDirectoryTree::fuzzyMatchTree( const std:: files.emplace_back( mFiles[res.second] ); } } - return std::make_shared( files, names ); + auto model = std::make_shared( files, names ); + model->setBasePath( basePath ); + return model; } -std::shared_ptr ProjectDirectoryTree::matchTree( const std::string& match, - const size_t& max ) const { +std::shared_ptr +ProjectDirectoryTree::matchTree( const std::string& match, const size_t& max, + const std::string& basePath ) const { Lock rl( mMatchingMutex ); std::vector files; std::vector names; @@ -160,25 +167,27 @@ std::shared_ptr ProjectDirectoryTree::matchTree( const std::strin return std::make_shared( files, names ); } } - return std::make_shared( files, names ); + auto model = std::make_shared( files, names ); + model->setBasePath( basePath ); + return model; } void ProjectDirectoryTree::asyncFuzzyMatchTree( const std::string& match, const size_t& max, - ProjectDirectoryTree::MatchResultCb res ) const { - mPool->run( [this, match, max, res]() { res( fuzzyMatchTree( match, max ) ); } ); + ProjectDirectoryTree::MatchResultCb res, + const std::string& basePath ) const { + mPool->run( + [this, match, max, res, basePath]() { res( fuzzyMatchTree( match, max, basePath ) ); } ); } void ProjectDirectoryTree::asyncMatchTree( const std::string& match, const size_t& max, - ProjectDirectoryTree::MatchResultCb res ) const { - mPool->run( [this, match, max, res]() { res( matchTree( match, max ) ); } ); + ProjectDirectoryTree::MatchResultCb res, + const std::string& basePath ) const { + mPool->run( [this, match, max, res, basePath]() { res( matchTree( match, max, basePath ) ); } ); } std::shared_ptr -ProjectDirectoryTree::asModel( const size_t& max, - const std::vector& prependCommands ) const { - if ( mNames.empty() ) - return std::make_shared( std::vector(), - std::vector() ); +ProjectDirectoryTree::asModel( const size_t& max, const std::vector& prependCommands, + const std::string& basePath ) const { size_t rmax = eemin( mNames.size(), max ); std::vector files( rmax ); std::vector names( rmax ); @@ -195,6 +204,7 @@ ProjectDirectoryTree::asModel( const size_t& max, } } auto model = std::make_shared( files, names ); + model->setBasePath( basePath ); if ( !prependCommands.empty() ) { for ( size_t i = 0; i < prependCommands.size(); ++i ) @@ -205,7 +215,8 @@ ProjectDirectoryTree::asModel( const size_t& max, } std::shared_ptr -ProjectDirectoryTree::emptyModel( const std::vector& prependCommands ) { +ProjectDirectoryTree::emptyModel( const std::vector& prependCommands, + const std::string& basePath ) { std::vector files; std::vector names; if ( !prependCommands.empty() ) { @@ -217,6 +228,7 @@ ProjectDirectoryTree::emptyModel( const std::vector& prependCommand } } auto model = std::make_shared( files, names ); + model->setBasePath( basePath ); if ( !prependCommands.empty() ) { for ( size_t i = 0; i < prependCommands.size(); ++i ) diff --git a/src/tools/ecode/projectdirectorytree.hpp b/src/tools/ecode/projectdirectorytree.hpp index c4e2636a1..7d516e4c7 100644 --- a/src/tools/ecode/projectdirectorytree.hpp +++ b/src/tools/ecode/projectdirectorytree.hpp @@ -42,7 +42,14 @@ class FileListModel : public Model { switch ( role ) { case ModelRole::Icon: return Variant( iconFor( index ) ); - case ModelRole::Display: + case ModelRole::Display: { + if ( !mBasePath.empty() && index.column() == 1 && + mBasePath.size() < mFiles[index.row()].size() ) + return Variant( mFiles[index.row()].substr( mBasePath.size() ) ); + return Variant( index.column() == 0 ? mNames[index.row()].c_str() + : mFiles[index.row()].c_str() ); + } + case ModelRole::Custom: return Variant( index.column() == 0 ? mNames[index.row()].c_str() : mFiles[index.row()].c_str() ); default: @@ -57,9 +64,12 @@ class FileListModel : public Model { mIcons[idx] = icon; } + void setBasePath( const std::string& basePath ) { mBasePath = basePath; } + protected: std::vector mFiles; std::vector mNames; + std::string mBasePath; mutable std::vector mIcons; UIIcon* iconFor( const ModelIndex& index ) const { @@ -106,17 +116,20 @@ class ProjectDirectoryTree { const bool& ignoreHidden = true ); std::shared_ptr fuzzyMatchTree( const std::vector& matches, - const size_t& max ) const; + const size_t& max, + const std::string& basePath = "" ) const; - std::shared_ptr fuzzyMatchTree( const std::string& match, - const size_t& max ) const; + std::shared_ptr fuzzyMatchTree( const std::string& match, const size_t& max, + const std::string& basePath = "" ) const; - std::shared_ptr matchTree( const std::string& match, const size_t& max ) const; + std::shared_ptr matchTree( const std::string& match, const size_t& max, + const std::string& basePath = "" ) const; - void asyncFuzzyMatchTree( const std::string& match, const size_t& max, - MatchResultCb res ) const; + void asyncFuzzyMatchTree( const std::string& match, const size_t& max, MatchResultCb res, + const std::string& basePath = "" ) const; - void asyncMatchTree( const std::string& match, const size_t& max, MatchResultCb res ) const; + void asyncMatchTree( const std::string& match, const size_t& max, MatchResultCb res, + const std::string& basePath = "" ) const; struct CommandInfo { std::string name; @@ -124,11 +137,13 @@ class ProjectDirectoryTree { UIIcon* icon{ nullptr }; }; - std::shared_ptr - asModel( const size_t& max, const std::vector& prependCommands = {} ) const; + std::shared_ptr asModel( const size_t& max, + const std::vector& prependCommands = {}, + const std::string& basePath = "" ) const; static std::shared_ptr - emptyModel( const std::vector& prependCommands = {} ); + emptyModel( const std::vector& prependCommands = {}, + const std::string& basePath = "" ); size_t getFilesCount() const; diff --git a/src/tools/ecode/universallocator.cpp b/src/tools/ecode/universallocator.cpp index 917234960..8679a0c10 100644 --- a/src/tools/ecode/universallocator.cpp +++ b/src/tools/ecode/universallocator.cpp @@ -1,7 +1,7 @@ -#include "universallocator.hpp" #include "ecode.hpp" #include "pathhelper.hpp" #include "settingsmenu.hpp" +#include "universallocator.hpp" #include @@ -118,33 +118,33 @@ UniversalLocator::UniversalLocator( UICodeEditorSplitter* editorSplitter, UIScen mApp( app ), mCommandPalette( mApp->getThreadPool() ) { - mLocatorProviders.push_back( { - ">", - mUISceneNode->i18n( "search_in_command_palette", "Search in Command Palette" ), - [this]( auto ) { - showCommandPalette(); - return true; - }, - [this]( const Variant&, const ModelEvent* modelEvent ) { - ModelIndex idx( modelEvent->getModel()->index( modelEvent->getModelIndex().row(), 2 ) ); - if ( idx.isValid() ) { - String cmd = modelEvent->getModel()->data( idx, ModelRole::Display ).toString(); - mApp->runCommand( cmd ); - if ( !mSplitter->getCurWidget()->isType( UI_TYPE_TERMINAL ) ) { - if ( mSplitter->curEditorIsNotNull() && - mSplitter->getCurEditor()->getDocument().hasCommand( cmd ) ) - mSplitter->getCurEditor()->setFocus(); - } - if ( cmd != "open-locatebar" && cmd != "open-workspace-symbol-search" && - cmd != "open-document-symbol-search" && cmd != "go-to-line" && - cmd != "show-open-documents" ) { - hideLocateBar(); - } else { - mLocateInput->setFocus(); - } - } - }, - } ); + mLocatorProviders.push_back( + { ">", mUISceneNode->i18n( "search_in_command_palette", "Search in Command Palette" ), + [this]( auto ) { + showCommandPalette(); + return true; + }, + [this]( const Variant&, const ModelEvent* modelEvent ) { + ModelIndex idx( + modelEvent->getModel()->index( modelEvent->getModelIndex().row(), 2 ) ); + if ( idx.isValid() ) { + String cmd = modelEvent->getModel()->data( idx, ModelRole::Display ).toString(); + mApp->runCommand( cmd ); + if ( !mSplitter->getCurWidget()->isType( UI_TYPE_TERMINAL ) ) { + if ( mSplitter->curEditorIsNotNull() && + mSplitter->getCurEditor()->getDocument().hasCommand( cmd ) ) + mSplitter->getCurEditor()->setFocus(); + } + if ( cmd != "open-locatebar" && cmd != "open-workspace-symbol-search" && + cmd != "open-document-symbol-search" && cmd != "go-to-line" && + cmd != "show-open-documents" ) { + hideLocateBar(); + } else { + mLocateInput->setFocus(); + } + } + }, + nullptr, false } ); mLocatorProviders.push_back( { ":", mUISceneNode->i18n( "search_for_workspace_symbols", "Search for Workspace Symbols" ), @@ -217,14 +217,15 @@ UniversalLocator::UniversalLocator( UICodeEditorSplitter* editorSplitter, UIScen } } return false; - } } ); + }, + false } ); mLocatorProviders.push_back( { "o", mUISceneNode->i18n( "open_documents", "Open Documents" ), [this]( auto ) { showOpenDocuments(); return true; }, - nullptr } ); + nullptr, nullptr, false } ); // clang-format off mLocatorProviders.push_back( { "sb", mUISceneNode->i18n( "switch_build", "Switch Build" ), @@ -339,27 +340,31 @@ void UniversalLocator::updateFilesTable() { } if ( !mApp->isDirTreeReady() ) { - mLocateTable->setModel( ProjectDirectoryTree::emptyModel( getLocatorCommands() ) ); + mLocateTable->setModel( + 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()->asyncFuzzyMatchTree( - text, LOCATEBAR_MAX_RESULTS, [this, text]( auto res ) { + text, LOCATEBAR_MAX_RESULTS, + [this, text]( auto res ) { mUISceneNode->runOnMainThread( [this, res] { mLocateTable->setModel( res ); mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); mLocateTable->scrollToTop(); updateLocateBarSync(); } ); - } ); + }, + mApp->getCurrentProject() ); #else - mLocateTable->setModel( mApp->getDirTree()->fuzzyMatchTree( text, LOCATEBAR_MAX_RESULTS ) ); + mLocateTable->setModel( 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() ) ); + mLocateTable->setModel( mApp->getDirTree()->asModel( + LOCATEBAR_MAX_RESULTS, getLocatorCommands(), mApp->getCurrentProject() ) ); mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); } } @@ -554,6 +559,10 @@ void UniversalLocator::initLocateBar( UILocateBar* locateBar, UITextInput* locat auto pathAndPos = getPathAndPosition( mLocateInput->getText() ); range = { pathAndPos.second, pathAndPos.second }; } + + if ( FileSystem::isRelativePath( path ) ) + path = mApp->getCurrentProject() + path; + focusOrLoadFile( path, range ); mLocateBarLayout->execute( "close-locatebar" ); } @@ -618,11 +627,12 @@ void UniversalLocator::showLocateBar() { mLocateInput->setText( "" ); if ( mApp->getDirTree() && !mLocateTable->getModel() ) { - mLocateTable->setModel( - mApp->getDirTree()->asModel( LOCATEBAR_MAX_RESULTS, getLocatorCommands() ) ); + mLocateTable->setModel( mApp->getDirTree()->asModel( + LOCATEBAR_MAX_RESULTS, getLocatorCommands(), mApp->getCurrentProject() ) ); mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); } else if ( !mLocateTable->getModel() ) { - mLocateTable->setModel( ProjectDirectoryTree::emptyModel( getLocatorCommands() ) ); + mLocateTable->setModel( + ProjectDirectoryTree::emptyModel( getLocatorCommands(), mApp->getCurrentProject() ) ); mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); } @@ -1130,8 +1140,12 @@ void UniversalLocator::asyncFuzzyMatchTextDocumentSymbol( std::vector UniversalLocator::getLocatorCommands() const { std::vector vec; UIIcon* icon = mUISceneNode->findIcon( "chevron-right" ); - for ( const auto& locator : mLocatorProviders ) + bool isOpenFolder = mApp->getCurrentProject().empty(); + for ( const auto& locator : mLocatorProviders ) { + if ( !isOpenFolder && locator.projectNeeded ) + continue; vec.push_back( { locator.symbolTrigger, locator.description, icon } ); + } return vec; } diff --git a/src/tools/ecode/universallocator.hpp b/src/tools/ecode/universallocator.hpp index 604708cfe..d7d6f5b3f 100644 --- a/src/tools/ecode/universallocator.hpp +++ b/src/tools/ecode/universallocator.hpp @@ -19,13 +19,15 @@ class UniversalLocator { LocatorProvider( String&& symbol, String&& description, std::function switchFn, std::function openFn, - std::function pressEnterFn = nullptr ) : + std::function pressEnterFn = nullptr, + bool projectNeeded = true ) : symbol( std::move( symbol ) ), symbolTrigger( this->symbol + " " ), description( std::move( description ) ), switchFn( std::move( switchFn ) ), openFn( std::move( openFn ) ), - pressEnterFn( std::move( pressEnterFn ) ) {} + pressEnterFn( std::move( pressEnterFn ) ), + projectNeeded( projectNeeded ) {} String symbol; String symbolTrigger; @@ -33,6 +35,7 @@ class UniversalLocator { std::function switchFn; std::function openFn; std::function pressEnterFn{ nullptr }; + bool projectNeeded{ true }; }; UniversalLocator( UICodeEditorSplitter* editorSplitter, UISceneNode* sceneNode, App* app );