diff --git a/bin/assets/ui/breeze.css b/bin/assets/ui/breeze.css index ae874668f..a8f070d19 100644 --- a/bin/assets/ui/breeze.css +++ b/bin/assets/ui/breeze.css @@ -306,6 +306,7 @@ ListView::row:selected { DropDownList::ListBox::item, ComboBox::DropDownList::ListBox::item { padding-left: 4dp; + background-color: transparent; } DropDownList::ListBox::item:hover, diff --git a/src/tools/ecode/plugins/git/git.cpp b/src/tools/ecode/plugins/git/git.cpp index 03891ea28..6c83d99d3 100644 --- a/src/tools/ecode/plugins/git/git.cpp +++ b/src/tools/ecode/plugins/git/git.cpp @@ -70,8 +70,11 @@ int Git::git( const std::string& args, const std::string& projectDir, std::strin p.readAllStdOut( buf ); int retCode = 0; p.join( &retCode ); - Log::info( "GitPlugin cmd in %s (%d): %s %s", clock.getElapsedTime().toString(), retCode, - mGitPath, args ); + if ( mLogLevel == LogLevel::Info || + ( mLogLevel >= LogLevel::Warning && retCode != EXIT_SUCCESS ) ) { + Log::instance()->writef( mLogLevel, "GitPlugin cmd in %s (%d): %s %s", + clock.getElapsedTime().toString(), retCode, mGitPath, args ); + } return retCode; } @@ -219,8 +222,9 @@ Git::Result Git::reset( std::vector files, const std::string& proje return gitSimple( String::format( "reset -q HEAD -- %s", asList( files ) ), projectDir ); } -Git::Result Git::diff( const std::string& file, const std::string& projectDir ) { - return gitSimple( String::format( "diff \"%s\"", file ), projectDir ); +Git::Result Git::diff( const std::string& file, bool isStaged, const std::string& projectDir ) { + return gitSimple( String::format( "diff%s \"%s\"", isStaged ? " --staged" : "", file ), + projectDir ); } Git::Result Git::createBranch( const std::string& branchName, bool _checkout, diff --git a/src/tools/ecode/plugins/git/git.hpp b/src/tools/ecode/plugins/git/git.hpp index 49e95cc23..40ffd46cf 100644 --- a/src/tools/ecode/plugins/git/git.hpp +++ b/src/tools/ecode/plugins/git/git.hpp @@ -7,6 +7,7 @@ #include #include +#include #include using namespace EE::System; @@ -237,7 +238,7 @@ class Git { Result reset( std::vector files, const std::string& projectDir = "" ); - Result diff( const std::string& file, const std::string& projectDir = "" ); + Result diff( const std::string& file, bool isStaged, const std::string& projectDir = "" ); Result createBranch( const std::string& branchName, bool checkout = false, const std::string& projectDir = "" ); @@ -315,11 +316,16 @@ class Git { GitStatusReport statusFromShortStatusStr( const std::string_view& statusStr ); + void setLogLevel( LogLevel logLevel ) { mLogLevel = logLevel; } + + LogLevel getLogLevel() const { return mLogLevel; } + protected: std::string mGitPath; std::string mProjectPath; std::string mGitFolder; std::vector mSubModules; + LogLevel mLogLevel{ LogLevel::Error }; Mutex mSubModulesMutex; bool mSubModulesUpdated{ false }; }; diff --git a/src/tools/ecode/plugins/git/gitplugin.cpp b/src/tools/ecode/plugins/git/gitplugin.cpp index eb5bcc7a5..82efd27fb 100644 --- a/src/tools/ecode/plugins/git/gitplugin.cpp +++ b/src/tools/ecode/plugins/git/gitplugin.cpp @@ -143,6 +143,13 @@ void GitPlugin::load( PluginManager* pluginManager ) { config["status_recurse_submodules"] = mStatusRecurseSubmodules; updateConfigFile = true; } + + if ( config.contains( "silent" ) ) + mSilence = config.value( "silent", true ); + else { + config["silent"] = mSilence; + updateConfigFile = true; + } } if ( mKeyBindings.empty() ) { @@ -172,6 +179,7 @@ void GitPlugin::load( PluginManager* pluginManager ) { } mGit = std::make_unique( pluginManager->getWorkspaceFolder() ); + mGit->setLogLevel( mSilence ? LogLevel::Warning : LogLevel::Info ); mGitFound = !mGit->getGitPath().empty(); mProjectPath = mRepoSelected = mGit->getProjectPath(); @@ -653,6 +661,8 @@ void GitPlugin::commit( const std::string& repoPath ) { UIMessageBox* msgBox = UIMessageBox::New( UIMessageBox::TEXT_EDIT, i18n( "git_commit_message", "Commit Message:" ) ); + msgBox->getTextEdit()->setText( mLastCommitMsg ); + UICheckBox* chkAmmend = UICheckBox::New(); chkAmmend->setLayoutMargin( Rectf( 0, 8, 0, 0 ) ) ->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::WrapContent ) @@ -698,10 +708,21 @@ void GitPlugin::commit( const std::string& repoPath ) { bool bypassHook = chkBypassHook->isChecked(); msgBox->closeWindow(); runAsync( - [this, msg, ammend, bypassHook]() { return mGit->commit( msg, ammend, bypassHook ); }, + [this, msg, ammend, bypassHook, msgBox]() { + auto res = mGit->commit( msg, ammend, bypassHook ); + if ( res.success() ) + mLastCommitMsg.clear(); + else + mLastCommitMsg = msgBox->getTextEdit()->getText(); + return res; + }, true, true ); } ); + msgBox->on( Event::OnCancel, [this, msgBox]( const Event* ) { + mLastCommitMsg = msgBox->getTextEdit()->getText(); + } ); + msgBox->setCloseShortcut( { KEY_ESCAPE, KEYMOD_NONE } ); msgBox->setTitle( i18n( "git_commit", "Commit" ) ); msgBox->center(); @@ -799,9 +820,9 @@ void GitPlugin::openFile( const std::string& file ) { } ); } -void GitPlugin::diff( const std::string& file ) { - mThreadPool->run( [this, file] { - auto res = mGit->diff( fixFilePath( file ), mGit->repoPath( file ) ); +void GitPlugin::diff( const std::string& file, bool isStaged ) { + mThreadPool->run( [this, file, isStaged] { + auto res = mGit->diff( fixFilePath( file ), isStaged, mGit->repoPath( file ) ); if ( res.fail() ) return; @@ -950,12 +971,12 @@ void GitPlugin::updateRepos() { auto subModules = mGit->getSubModules(); std::sort( subModules.begin(), subModules.end() ); - std::unordered_map repos; + std::vector> repos; repos.clear(); - repos.insert( { mProjectPath, FileSystem::fileNameFromPath( mProjectPath ) } ); + repos.emplace_back( mProjectPath, FileSystem::fileNameFromPath( mProjectPath ) ); for ( auto& subModule : subModules ) { std::string subModulePath = mProjectPath + subModule; - repos.insert( { std::move( subModulePath ), FileSystem::fileNameFromPath( subModule ) } ); + repos.emplace_back( std::move( subModulePath ), FileSystem::fileNameFromPath( subModule ) ); } Lock l( mReposMutex ); @@ -979,7 +1000,7 @@ void GitPlugin::updateBranchesUI( std::shared_ptr model ) { updateRepos(); std::vector items; - std::unordered_map repos; + decltype( mRepos ) repos; { Lock l( mReposMutex ); repos = mRepos; @@ -997,7 +1018,7 @@ void GitPlugin::updateBranchesUI( std::shared_ptr model ) { if ( mRepoDropDown->getListBox()->getItemsText() != items ) { mRepoDropDown->getListBox()->clear(); mRepoDropDown->getListBox()->addListBoxItems( items ); - mRepoDropDown->getListBox()->setSelected( mRepos[repoSelected()] ); + mRepoDropDown->getListBox()->setSelected( repoName( repoSelected() ) ); } } @@ -1009,6 +1030,22 @@ void GitPlugin::buildSidePanelTab() { UIIcon* icon = findIcon( "source-control" ); UIWidget* node = getUISceneNode()->loadLayoutFromString( R"html( + @@ -1143,7 +1180,7 @@ void GitPlugin::buildSidePanelTab() { break; } case Abstract::ModelEventType::Open: { - diff( file->file ); + diff( file->file, file->report.type == Git::GitStatusType::Staged ); break; } default: @@ -1304,7 +1341,7 @@ void GitPlugin::openFileStatusMenu( const Git::DiffFile& file ) { } else if ( id == "git-open-file" ) { openFile( file.file ); } else if ( id == "git-diff" ) { - diff( file.file ); + diff( file.file, file.report.type == Git::GitStatusType::Staged ); } } ); @@ -1350,4 +1387,12 @@ std::string GitPlugin::repoSelected() { return mRepoSelected; } +std::string GitPlugin::repoName( const std::string& repoPath ) { + Lock l( mRepoMutex ); + for ( const auto& repo : mRepos ) + if ( repo.first == repoPath ) + return repo.second; + return ""; +} + } // namespace ecode diff --git a/src/tools/ecode/plugins/git/gitplugin.hpp b/src/tools/ecode/plugins/git/gitplugin.hpp index ea2d04fb5..048757a23 100644 --- a/src/tools/ecode/plugins/git/gitplugin.hpp +++ b/src/tools/ecode/plugins/git/gitplugin.hpp @@ -73,11 +73,13 @@ class GitPlugin : public PluginBase { void updateRepos(); + bool isSilent() const { return mSilence; } + protected: std::unique_ptr mGit; std::unordered_map mGitBranches; Git::Status mGitStatus; - std::unordered_map mRepos; + std::vector> mRepos; std::string mProjectPath; std::string mRepoSelected; @@ -90,6 +92,7 @@ class GitPlugin : public PluginBase { bool mOldDontAutoHideOnMouseMove{ false }; bool mOldUsingCustomStyling{ false }; bool mInitialized{ false }; + bool mSilence{ true }; Uint32 mOldTextStyle{ 0 }; Uint32 mOldTextAlign{ 0 }; Color mOldBackgroundColor; @@ -114,6 +117,7 @@ class GitPlugin : public PluginBase { Mutex mGitStatusMutex; Mutex mRepoMutex; Mutex mReposMutex; + String mLastCommitMsg; struct CustomTokenizer { SyntaxDefinition def; @@ -166,7 +170,7 @@ class GitPlugin : public PluginBase { void discard( const std::string& file ); - void diff( const std::string& file ); + void diff( const std::string& file, bool isStaged ); void openFile( const std::string& file ); @@ -197,6 +201,8 @@ class GitPlugin : public PluginBase { std::string repoSelected(); + std::string repoName( const std::string& repoPath ); + std::string fixFilePath( const std::string& file ); std::vector fixFilePaths( const std::vector& files );