diff --git a/include/eepp/ui/doc/textdocument.hpp b/include/eepp/ui/doc/textdocument.hpp index 05ebf46a1..74d68a0ae 100644 --- a/include/eepp/ui/doc/textdocument.hpp +++ b/include/eepp/ui/doc/textdocument.hpp @@ -593,6 +593,8 @@ class EE_API TextDocument { bool isInsertingText() const; + void resetUndoRedo(); + protected: friend class UndoStack; diff --git a/include/eepp/ui/tools/uicodeeditorsplitter.hpp b/include/eepp/ui/tools/uicodeeditorsplitter.hpp index f52d41325..56ca25cc9 100644 --- a/include/eepp/ui/tools/uicodeeditorsplitter.hpp +++ b/include/eepp/ui/tools/uicodeeditorsplitter.hpp @@ -118,6 +118,8 @@ class EE_API UICodeEditorSplitter { bool loadDocument( std::shared_ptr doc, UICodeEditor* codeEditor = nullptr ); + std::pair createEditorInNewTab(); + std::pair loadDocumentInNewTab( std::shared_ptr doc ); bool loadFileFromPath( const std::string& path, UICodeEditor* codeEditor = nullptr ); diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user index 8cec10f6c..4c2e7d5e9 100644 --- a/projects/linux/ee.creator.user +++ b/projects/linux/ee.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/projects/linux/ee.files b/projects/linux/ee.files index 7fa0271ea..43774063d 100644 --- a/projects/linux/ee.files +++ b/projects/linux/ee.files @@ -1378,8 +1378,12 @@ ../../src/tools/ecode/pathhelper.hpp ../../src/tools/ecode/plugins/git/git.cpp ../../src/tools/ecode/plugins/git/git.hpp +../../src/tools/ecode/plugins/git/gitbranchmodel.cpp +../../src/tools/ecode/plugins/git/gitbranchmodel.hpp ../../src/tools/ecode/plugins/git/gitplugin.cpp ../../src/tools/ecode/plugins/git/gitplugin.hpp +../../src/tools/ecode/plugins/git/gitstatusmodel.cpp +../../src/tools/ecode/plugins/git/gitstatusmodel.hpp ../../src/tools/ecode/plugins/linter/linterplugin.cpp ../../src/tools/ecode/plugins/linter/linterplugin.hpp ../../src/tools/ecode/plugins/lsp/lspclientplugin.cpp diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index 14d443cc8..240df6a72 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -2078,7 +2078,7 @@ const std::string& TextDocument::getDefaultFileName() const { } void TextDocument::setDefaultFileName( const std::string& defaultFileName ) { - mDefaultFileName = defaultFileName; + mFilePath = mDefaultFileName = defaultFileName; } const std::string& TextDocument::getFilePath() const { @@ -2574,6 +2574,13 @@ void TextDocument::cleanChangeId() { mCleanChangeId = getCurrentChangeId(); } +void TextDocument::resetUndoRedo() { + mUndoStack.clear(); + cleanChangeId(); + notifyCursorChanged(); + notifySelectionChanged(); +} + static inline void changeDepth( SyntaxHighlighter* highlighter, int& depth, const TextPosition& pos, int dir ) { if ( highlighter ) { diff --git a/src/eepp/ui/tools/uicodeeditorsplitter.cpp b/src/eepp/ui/tools/uicodeeditorsplitter.cpp index 380ce8119..0dfc942b1 100644 --- a/src/eepp/ui/tools/uicodeeditorsplitter.cpp +++ b/src/eepp/ui/tools/uicodeeditorsplitter.cpp @@ -325,6 +325,22 @@ bool UICodeEditorSplitter::loadDocument( std::shared_ptr doc, return true; } +std::pair UICodeEditorSplitter::createEditorInNewTab() { + auto d = createCodeEditorInTabWidget( tabWidgetFromWidget( mCurWidget ) ); + if ( d.first == nullptr || d.second == nullptr ) { + if ( !mTabWidgets.empty() && mTabWidgets[0]->getTabCount() > 0 ) { + d = createCodeEditorInTabWidget( mTabWidgets[0] ); + } else { + Log::error( "Couldn't createCodeEditorInTabWidget in " + "UICodeEditorSplitter::createEditorInNewTab" ); + return d; + } + } + UITabWidget* tabWidget = d.first->getTabWidget(); + tabWidget->setTabSelected( d.first ); + return d; +} + std::pair UICodeEditorSplitter::loadDocumentInNewTab( std::shared_ptr doc ) { auto d = createCodeEditorInTabWidget( tabWidgetFromWidget( mCurWidget ) ); diff --git a/src/tools/ecode/plugins/git/git.cpp b/src/tools/ecode/plugins/git/git.cpp index babadc398..03891ea28 100644 --- a/src/tools/ecode/plugins/git/git.cpp +++ b/src/tools/ecode/plugins/git/git.cpp @@ -219,6 +219,10 @@ 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::createBranch( const std::string& branchName, bool _checkout, const std::string& projectDir ) { auto res = gitSimple( String::format( "branch --no-track %s", branchName ), projectDir ); diff --git a/src/tools/ecode/plugins/git/git.hpp b/src/tools/ecode/plugins/git/git.hpp index a2cda1e6e..49e95cc23 100644 --- a/src/tools/ecode/plugins/git/git.hpp +++ b/src/tools/ecode/plugins/git/git.hpp @@ -75,11 +75,11 @@ class Git { }; enum class GitStatusType { - Staged, - Changed, - Untracked, - Unmerged, - Ignored, + Staged = 1 << 1, + Changed = 1 << 2, + Untracked = 1 << 3, + Unmerged = 1 << 4, + Ignored = 1 << 5, }; static constexpr auto ANY = 0; @@ -237,6 +237,8 @@ class Git { Result reset( std::vector files, const std::string& projectDir = "" ); + Result diff( const std::string& file, const std::string& projectDir = "" ); + Result createBranch( const std::string& branchName, bool checkout = false, const std::string& projectDir = "" ); diff --git a/src/tools/ecode/plugins/git/gitplugin.cpp b/src/tools/ecode/plugins/git/gitplugin.cpp index 3f8c9351b..19b5cb2c4 100644 --- a/src/tools/ecode/plugins/git/gitplugin.cpp +++ b/src/tools/ecode/plugins/git/gitplugin.cpp @@ -241,7 +241,7 @@ void GitPlugin::updateStatusBarSync() { if ( childCount > 2 ) mStatusButton->toPosition( mStatusBar->getChildCount() - 2 ); - mStatusButton->on( Event::MouseClick, [this]( const Event* ) { + mStatusButton->onClick( [this]( const Event* ) { if ( mTab ) { mTab->setTabSelected(); if ( mGitStatus.totalInserts || mGitStatus.totalDeletions ) @@ -736,6 +736,14 @@ static bool isPath( const std::string& file ) { return ret; } +std::string GitPlugin::fixFilePath( const std::string& file ) { + std::string path; + if ( !isPath( file ) ) { + path = ( mProjectPath + file ); + } + return file; +} + std::vector GitPlugin::fixFilePaths( const std::vector& files ) { std::vector paths; paths.reserve( files.size() ); @@ -766,7 +774,6 @@ void GitPlugin::unstage( const std::vector& files ) { }, true, false ); } -// File operations void GitPlugin::discard( const std::string& file ) { UIMessageBox* msgBox = UIMessageBox::New( @@ -792,6 +799,26 @@ 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 ) ); + if ( res.fail() ) + return; + + getUISceneNode()->runOnMainThread( [this, file, res] { + auto ret = mManager->getSplitter()->createEditorInNewTab(); + auto doc = ret.second->getDocumentRef(); + doc->setDefaultFileName( FileSystem::fileNameFromPath( file ) + ".diff" ); + doc->setSyntaxDefinition( SyntaxDefinitionManager::instance()->getByLSPName( "diff" ) ); + doc->textInput( res.result, false ); + doc->moveToStartOfDoc(); + doc->resetUndoRedo(); + } ); + } ); +} + +// File operations + void GitPlugin::onRegister( UICodeEditor* editor ) { PluginBase::onRegister( editor ); @@ -1019,14 +1046,15 @@ void GitPlugin::buildSidePanelTab() { node->bind( "git_panel_loader", mLoader ); node->bind( "git_repo", mRepoDropDown ); - node->find( "branch_pull" )->on( Event::MouseClick, [this]( auto ) { pull(); } ); - node->find( "branch_push" )->on( Event::MouseClick, [this]( auto ) { push(); } ); - node->find( "branch_add" )->on( Event::MouseClick, [this]( auto ) { branchCreate(); } ); + node->find( "branch_pull" )->onClick( [this]( auto ) { pull(); } ); + node->find( "branch_push" )->onClick( [this]( auto ) { push(); } ); + node->find( "branch_add" )->onClick( [this]( auto ) { branchCreate(); } ); mBranchesTree->setAutoExpandOnSingleColumn( true ); mBranchesTree->setHeadersVisible( false ); mBranchesTree->setExpandersAsIcons( true ); mBranchesTree->setIndentWidth( PixelDensity::dpToPx( 16 ) ); + mBranchesTree->setScrollViewType( UIScrollableWidget::Inclusive ); mBranchesTree->on( Event::OnModelEvent, [this]( const Event* event ) { const ModelEvent* modelEvent = static_cast( event ); if ( !modelEvent->getModelIndex().hasParent() ) @@ -1086,6 +1114,7 @@ void GitPlugin::buildSidePanelTab() { mStatusTree->setAutoColumnsWidth( true ); mStatusTree->setHeadersVisible( false ); mStatusTree->setExpandersAsIcons( true ); + mStatusTree->setScrollViewType( UIScrollableWidget::Inclusive ); mStatusTree->on( Event::OnRowCreated, [this]( const Event* event ) { UITableRow* row = event->asRowCreatedEvent()->getRow(); row->on( Event::MouseUp, [this, row]( const Event* event ) { @@ -1113,6 +1142,10 @@ void GitPlugin::buildSidePanelTab() { openFileStatusMenu( *file ); break; } + case Abstract::ModelEventType::Open: { + diff( file->file ); + break; + } default: break; } @@ -1245,6 +1278,7 @@ void GitPlugin::openFileStatusMenu( const Git::DiffFile& file ) { menu->setId( "git_file_status_menu" ); addMenuItem( menu, "git-open-file", "Open File" ); + addMenuItem( menu, "git-diff", "Open Diff" ); if ( file.report.type != Git::GitStatusType::Staged ) { addMenuItem( menu, "git-stage", "Stage" ); @@ -1269,6 +1303,8 @@ void GitPlugin::openFileStatusMenu( const Git::DiffFile& file ) { discard( file.file ); } else if ( id == "git-open-file" ) { openFile( file.file ); + } else if ( id == "git-diff" ) { + diff( file.file ); } } ); @@ -1288,7 +1324,7 @@ void GitPlugin::runAsync( std::function fn, bool _updateStatus, b return; } if ( _updateBranches ) - updateBranches(); + updateBranches( true ); if ( _updateStatus ) updateStatus( true ); diff --git a/src/tools/ecode/plugins/git/gitplugin.hpp b/src/tools/ecode/plugins/git/gitplugin.hpp index 78a06488c..fe73a53b3 100644 --- a/src/tools/ecode/plugins/git/gitplugin.hpp +++ b/src/tools/ecode/plugins/git/gitplugin.hpp @@ -166,6 +166,8 @@ class GitPlugin : public PluginBase { void discard( const std::string& file ); + void diff( const std::string& file ); + void openFile( const std::string& file ); void updateStatus( bool force = false ); @@ -195,6 +197,8 @@ class GitPlugin : public PluginBase { std::string repoSelected(); + std::string fixFilePath( const std::string& file ); + std::vector fixFilePaths( const std::vector& files ); };