mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-09-26 22:00:01 +03:00
Fixed the autocomplete crash, root cause: getDocumentSymbols() accessed mDocs from a worker thread while document lifecycle callbacks could concurrently modify the same unordered_set, corrupting its internal state.
Added a synthetic “Working Tree / Index” first row whenever the selected repository has local or staged changes. Displays separate changed and staged counts. Updates dynamically from normal status refreshes without reloading commit history. Selecting it opens the shared details view in “Uncommitted changes” mode. Shows tracked changes from HEAD through the working tree, plus untracked-file patches. Supports both sidebar and detached History views. The History shortcut focuses working changes when present, otherwise the newest commit. Added the History button beside Refresh. Added consistent 2dp spacing between the ref dropdown and both buttons. Added translations for the new labels.
This commit is contained in:
@@ -82,9 +82,11 @@ Variant GitHistoryModel::data( const ModelIndex& index, ModelRole role ) const {
|
||||
if ( !item )
|
||||
return {};
|
||||
if ( role == ModelRole::Class ) {
|
||||
if ( item->type == NodeType::WorkingTree )
|
||||
return Variant( "git_history_working_tree" );
|
||||
if ( item->type == NodeType::LoadMore || item->type == NodeType::Error )
|
||||
return Variant( "git_history_action" );
|
||||
if ( item->type != NodeType::Commit )
|
||||
if ( item->type != NodeType::Commit && item->type != NodeType::WorkingTree )
|
||||
return Variant( "git_history_secondary" );
|
||||
if ( item->commit.isMerge() )
|
||||
return Variant( "git_history_merge" );
|
||||
@@ -99,7 +101,7 @@ Variant GitHistoryModel::data( const ModelIndex& index, ModelRole role ) const {
|
||||
}
|
||||
if ( role != ModelRole::Display )
|
||||
return {};
|
||||
if ( item->type != NodeType::Commit )
|
||||
if ( item->type != NodeType::Commit && item->type != NodeType::WorkingTree )
|
||||
return index.column() == Subject ? Variant( &item->message ) : Variant( "" );
|
||||
switch ( index.column() ) {
|
||||
case Subject:
|
||||
@@ -138,6 +140,29 @@ GitHistoryModel::commitNode( Git::Commit commit, Node* parent,
|
||||
return item;
|
||||
}
|
||||
|
||||
std::unique_ptr<GitHistoryModel::Node>
|
||||
GitHistoryModel::workingTreeNode( const Git::Status& status, const std::string& repoName ) const {
|
||||
auto repo = status.files.find( repoName );
|
||||
if ( repo == status.files.end() || repo->second.empty() )
|
||||
return {};
|
||||
size_t changed = 0;
|
||||
size_t staged = 0;
|
||||
for ( const auto& file : repo->second ) {
|
||||
if ( file.report.type == Git::GitStatusType::Staged )
|
||||
++staged;
|
||||
else
|
||||
++changed;
|
||||
}
|
||||
auto item = std::make_unique<Node>();
|
||||
item->type = NodeType::WorkingTree;
|
||||
item->subject = mPlugin->i18n( "git_working_tree_index", "Working Tree / Index" );
|
||||
item->message = String::format(
|
||||
mPlugin->i18n( "git_working_tree_summary", "%zu changed, %zu staged" ).toUtf8(), changed,
|
||||
staged );
|
||||
item->tooltip = item->subject + String{ "\n" } + item->message;
|
||||
return item;
|
||||
}
|
||||
|
||||
void GitHistoryModel::fillPage( Nodes& nodes, Node* parent, Git::HistoryPage page,
|
||||
const Git::HistoryQuery& query ) {
|
||||
for ( auto& commit : page.commits )
|
||||
@@ -179,8 +204,11 @@ void GitHistoryModel::setRootLoading() {
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void GitHistoryModel::setRootPage( Git::HistoryPage page, const Git::HistoryQuery& query ) {
|
||||
void GitHistoryModel::setRootPage( Git::HistoryPage page, const Git::HistoryQuery& query,
|
||||
const Git::Status& status, const std::string& repoName ) {
|
||||
mRoots.clear();
|
||||
if ( auto item = workingTreeNode( status, repoName ) )
|
||||
mRoots.emplace_back( std::move( item ) );
|
||||
fillPage( mRoots, nullptr, std::move( page ), query );
|
||||
if ( mRoots.empty() ) {
|
||||
auto item = std::make_unique<Node>();
|
||||
@@ -191,6 +219,25 @@ void GitHistoryModel::setRootPage( Git::HistoryPage page, const Git::HistoryQuer
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void GitHistoryModel::setWorkingTreeStatus( const Git::Status& status,
|
||||
const std::string& repoName ) {
|
||||
auto item = workingTreeNode( status, repoName );
|
||||
const bool hasItem = !mRoots.empty() && mRoots.front()->type == NodeType::WorkingTree;
|
||||
if ( hasItem && !item ) {
|
||||
beginDeleteRows( {}, 0, 0 );
|
||||
mRoots.erase( mRoots.begin() );
|
||||
endDeleteRows();
|
||||
} else if ( !hasItem && item ) {
|
||||
beginInsertRows( {}, 0, 0 );
|
||||
mRoots.insert( mRoots.begin(), std::move( item ) );
|
||||
endInsertRows();
|
||||
} else if ( hasItem && item ) {
|
||||
mRoots.front()->message = std::move( item->message );
|
||||
mRoots.front()->tooltip = std::move( item->tooltip );
|
||||
}
|
||||
invalidate( Model::DontInvalidateIndexes );
|
||||
}
|
||||
|
||||
void GitHistoryModel::setRootError( std::string error ) {
|
||||
mRoots.clear();
|
||||
auto item = std::make_unique<Node>();
|
||||
|
||||
Reference in New Issue
Block a user