Skip to content

Commit

Permalink
File locator now displays the relative path to the open folder instea…
Browse files Browse the repository at this point in the history
…d of the full path of a file.

Improve universal locator options when no folder is open (fixes SpartanJ/ecode#303).
  • Loading branch information
SpartanJ committed Jul 31, 2024
1 parent 9f35eaa commit 7442aa4
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 74 deletions.
2 changes: 1 addition & 1 deletion src/tools/ecode/ecode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
52 changes: 32 additions & 20 deletions src/tools/ecode/projectdirectorytree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<GitIgnoreMatcher>( mPath, PRJ_ALLOWED_PATH, false );
mAllowedMatcher =
std::make_unique<GitIgnoreMatcher>( mPath, PRJ_ALLOWED_PATH, false );

if ( !acceptedPatterns.empty() ) {
std::vector<std::string> files;
Expand Down Expand Up @@ -104,8 +105,8 @@ void ProjectDirectoryTree::scan( const ProjectDirectoryTree::ScanCompleteEvent&
}

std::shared_ptr<FileListModel>
ProjectDirectoryTree::fuzzyMatchTree( const std::vector<std::string>& matches,
const size_t& max ) const {
ProjectDirectoryTree::fuzzyMatchTree( const std::vector<std::string>& matches, const size_t& max,
const std::string& basePath ) const {
Lock rl( mMatchingMutex );
std::multimap<int, int, std::greater<int>> matchesMap;
std::vector<std::string> files;
Expand All @@ -123,11 +124,14 @@ ProjectDirectoryTree::fuzzyMatchTree( const std::vector<std::string>& matches,
files.emplace_back( mFiles[res.second] );
}
}
return std::make_shared<FileListModel>( files, names );
auto model = std::make_shared<FileListModel>( files, names );
model->setBasePath( basePath );
return model;
}

std::shared_ptr<FileListModel> ProjectDirectoryTree::fuzzyMatchTree( const std::string& match,
const size_t& max ) const {
std::shared_ptr<FileListModel>
ProjectDirectoryTree::fuzzyMatchTree( const std::string& match, const size_t& max,
const std::string& basePath ) const {
Lock rl( mMatchingMutex );
std::multimap<int, int, std::greater<int>> matchesMap;
std::vector<std::string> files;
Expand All @@ -143,11 +147,14 @@ std::shared_ptr<FileListModel> ProjectDirectoryTree::fuzzyMatchTree( const std::
files.emplace_back( mFiles[res.second] );
}
}
return std::make_shared<FileListModel>( files, names );
auto model = std::make_shared<FileListModel>( files, names );
model->setBasePath( basePath );
return model;
}

std::shared_ptr<FileListModel> ProjectDirectoryTree::matchTree( const std::string& match,
const size_t& max ) const {
std::shared_ptr<FileListModel>
ProjectDirectoryTree::matchTree( const std::string& match, const size_t& max,
const std::string& basePath ) const {
Lock rl( mMatchingMutex );
std::vector<std::string> files;
std::vector<std::string> names;
Expand All @@ -160,25 +167,27 @@ std::shared_ptr<FileListModel> ProjectDirectoryTree::matchTree( const std::strin
return std::make_shared<FileListModel>( files, names );
}
}
return std::make_shared<FileListModel>( files, names );
auto model = std::make_shared<FileListModel>( 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<FileListModel>
ProjectDirectoryTree::asModel( const size_t& max,
const std::vector<CommandInfo>& prependCommands ) const {
if ( mNames.empty() )
return std::make_shared<FileListModel>( std::vector<std::string>(),
std::vector<std::string>() );
ProjectDirectoryTree::asModel( const size_t& max, const std::vector<CommandInfo>& prependCommands,
const std::string& basePath ) const {
size_t rmax = eemin( mNames.size(), max );
std::vector<std::string> files( rmax );
std::vector<std::string> names( rmax );
Expand All @@ -195,6 +204,7 @@ ProjectDirectoryTree::asModel( const size_t& max,
}
}
auto model = std::make_shared<FileListModel>( files, names );
model->setBasePath( basePath );

if ( !prependCommands.empty() ) {
for ( size_t i = 0; i < prependCommands.size(); ++i )
Expand All @@ -205,7 +215,8 @@ ProjectDirectoryTree::asModel( const size_t& max,
}

std::shared_ptr<FileListModel>
ProjectDirectoryTree::emptyModel( const std::vector<CommandInfo>& prependCommands ) {
ProjectDirectoryTree::emptyModel( const std::vector<CommandInfo>& prependCommands,
const std::string& basePath ) {
std::vector<std::string> files;
std::vector<std::string> names;
if ( !prependCommands.empty() ) {
Expand All @@ -217,6 +228,7 @@ ProjectDirectoryTree::emptyModel( const std::vector<CommandInfo>& prependCommand
}
}
auto model = std::make_shared<FileListModel>( files, names );
model->setBasePath( basePath );

if ( !prependCommands.empty() ) {
for ( size_t i = 0; i < prependCommands.size(); ++i )
Expand Down
37 changes: 26 additions & 11 deletions src/tools/ecode/projectdirectorytree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -57,9 +64,12 @@ class FileListModel : public Model {
mIcons[idx] = icon;
}

void setBasePath( const std::string& basePath ) { mBasePath = basePath; }

protected:
std::vector<std::string> mFiles;
std::vector<std::string> mNames;
std::string mBasePath;
mutable std::vector<UIIcon*> mIcons;

UIIcon* iconFor( const ModelIndex& index ) const {
Expand Down Expand Up @@ -106,29 +116,34 @@ class ProjectDirectoryTree {
const bool& ignoreHidden = true );

std::shared_ptr<FileListModel> fuzzyMatchTree( const std::vector<std::string>& matches,
const size_t& max ) const;
const size_t& max,
const std::string& basePath = "" ) const;

std::shared_ptr<FileListModel> fuzzyMatchTree( const std::string& match,
const size_t& max ) const;
std::shared_ptr<FileListModel> fuzzyMatchTree( const std::string& match, const size_t& max,
const std::string& basePath = "" ) const;

std::shared_ptr<FileListModel> matchTree( const std::string& match, const size_t& max ) const;
std::shared_ptr<FileListModel> 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;
std::string desc;
UIIcon* icon{ nullptr };
};

std::shared_ptr<FileListModel>
asModel( const size_t& max, const std::vector<CommandInfo>& prependCommands = {} ) const;
std::shared_ptr<FileListModel> asModel( const size_t& max,
const std::vector<CommandInfo>& prependCommands = {},
const std::string& basePath = "" ) const;

static std::shared_ptr<FileListModel>
emptyModel( const std::vector<CommandInfo>& prependCommands = {} );
emptyModel( const std::vector<CommandInfo>& prependCommands = {},
const std::string& basePath = "" );

size_t getFilesCount() const;

Expand Down
94 changes: 54 additions & 40 deletions src/tools/ecode/universallocator.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "universallocator.hpp"
#include "ecode.hpp"
#include "pathhelper.hpp"
#include "settingsmenu.hpp"
#include "universallocator.hpp"

#include <algorithm>

Expand Down Expand Up @@ -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" ),
Expand Down Expand Up @@ -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" ),
Expand Down Expand Up @@ -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 ) );
}
}
Expand Down Expand Up @@ -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" );
}
Expand Down Expand Up @@ -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 ) );
}

Expand Down Expand Up @@ -1130,8 +1140,12 @@ void UniversalLocator::asyncFuzzyMatchTextDocumentSymbol(
std::vector<ProjectDirectoryTree::CommandInfo> UniversalLocator::getLocatorCommands() const {
std::vector<ProjectDirectoryTree::CommandInfo> 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;
}

Expand Down
7 changes: 5 additions & 2 deletions src/tools/ecode/universallocator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,23 @@ class UniversalLocator {
LocatorProvider(
String&& symbol, String&& description, std::function<bool( const String& )> switchFn,
std::function<void( const Variant& var, const ModelEvent* modelEvent )> openFn,
std::function<bool( const String& )> pressEnterFn = nullptr ) :
std::function<bool( const String& )> 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;
String description;
std::function<bool( const String& )> switchFn;
std::function<void( const Variant&, const ModelEvent* )> openFn;
std::function<bool( const String& )> pressEnterFn{ nullptr };
bool projectNeeded{ true };
};

UniversalLocator( UICodeEditorSplitter* editorSplitter, UISceneNode* sceneNode, App* app );
Expand Down

0 comments on commit 7442aa4

Please sign in to comment.