Update breakpoints line position if document is edited (added/removed lines).

This commit is contained in:
Martín Lucas Golini
2025-02-04 00:12:15 -03:00
parent 490bd6d8a9
commit 0b7dad2696
6 changed files with 116 additions and 9 deletions

View File

@@ -80,6 +80,12 @@ DebuggerPlugin::~DebuggerPlugin() {
waitUntilLoaded();
mShuttingDown = true;
{
Lock l( mClientsMutex );
for ( const auto& client : mClients )
client.first->unregisterClient( client.second.get() );
}
if ( mSidePanel && mTab ) {
if ( Engine::isRunninMainThread() )
mSidePanel->removeTab( mTab );
@@ -1311,6 +1317,16 @@ void DebuggerPlugin::onRegisterDocument( TextDocument* doc ) {
if ( mTab )
mTab->setTabSelected();
} );
Lock l( mClientsMutex );
mClients[doc] = std::make_unique<DebuggerPluginClient>( this, doc );
doc->registerClient( mClients[doc].get() );
}
void DebuggerPlugin::onUnregisterDocument( TextDocument* doc ) {
Lock l( mClientsMutex );
doc->unregisterClient( mClients[doc].get() );
mClients.erase( doc );
}
void DebuggerPlugin::onRegisterEditor( UICodeEditor* editor ) {
@@ -2214,4 +2230,35 @@ bool DebuggerPlugin::onMouseMove( UICodeEditor* editor, const Vector2i& position
return true;
}
void DebuggerPlugin::onDocumentLineMove( TextDocument* doc, const Int64& fromLine,
const Int64& toLine, const Int64& numLines ) {
Lock l( mBreakpointsMutex );
auto& breakpoints = mBreakpoints[doc->getFilePath()];
if ( breakpoints.empty() )
return;
std::vector<SourceBreakpointStateful> bpToModify;
for ( auto& bp : breakpoints ) {
// bp line numbers start at 1
if ( bp.line - 1 >= fromLine ) {
bpToModify.push_back( bp );
break;
}
}
for ( const auto& bp : bpToModify )
breakpoints.erase( bp );
for ( auto&& bp : bpToModify ) {
bp.line += numLines;
breakpoints.insert( std::move( bp ) );
}
if ( mBreakpointsModel )
mBreakpointsModel->move( doc->getFilePath(), fromLine, toLine, numLines );
}
} // namespace ecode

View File

@@ -129,6 +129,37 @@ class DebuggerPlugin : public PluginBase {
std::string mCurDebugger;
std::string mCurConfiguration;
class DebuggerPluginClient : public TextDocument::Client {
public:
explicit DebuggerPluginClient( DebuggerPlugin* parent, TextDocument* doc ) :
mDoc( doc ), mParent( parent ) {}
virtual void onDocumentTextChanged( const DocumentContentChange& ) {}
virtual void onDocumentUndoRedo( const TextDocument::UndoRedo& ) {}
virtual void onDocumentCursorChange( const TextPosition& ) {}
virtual void onDocumentSelectionChange( const TextRange& ) {}
virtual void onDocumentLineCountChange( const size_t&, const size_t& ) {}
virtual void onDocumentLineChanged( const Int64& ) {}
virtual void onDocumentSaved( TextDocument* ) {}
virtual void onDocumentClosed( TextDocument* doc ) { onDocumentReset( doc ); }
virtual void onDocumentDirtyOnFileSystem( TextDocument* ) {}
virtual void onDocumentMoved( TextDocument* ) {}
virtual void onDocumentReset( TextDocument* ) {}
virtual void onDocumentLineMove( const Int64& fromLine, const Int64& toLine,
const Int64& numLines ) {
mParent->onDocumentLineMove( mDoc, fromLine, toLine, numLines );
}
protected:
TextDocument* mDoc{ nullptr };
DebuggerPlugin* mParent{ nullptr };
};
using ClientsMap = std::unordered_map<TextDocument*, std::unique_ptr<DebuggerPluginClient>>;
ClientsMap mClients;
Mutex mClientsMutex;
DebuggerPlugin( PluginManager* pluginManager, bool sync );
void load( PluginManager* pluginManager );
@@ -240,6 +271,10 @@ class DebuggerPlugin : public PluginBase {
bool resume( int threadId, bool singleThread = false );
virtual void onUnregisterDocument( TextDocument* doc ) override;
void onDocumentLineMove( TextDocument* doc, const Int64& fromLine, const Int64& toLine,
const Int64& numLines );
};
} // namespace ecode

View File

@@ -106,6 +106,24 @@ void BreakpointsModel::enable( const std::string& filePath,
}
}
void BreakpointsModel::move( const std::string& doc, Int64 fromLine, Int64 toLine,
Int64 numLines ) {
Lock l( mResourceLock );
bool modified = false;
for ( auto& [dc, bp] : mBreakpoints ) {
if ( dc != doc )
continue;
if ( bp.line - 1 >= fromLine ) {
bp.line += numLines;
modified = true;
}
}
if ( modified )
invalidate( UpdateFlag::DontInvalidateIndexes );
}
const std::pair<std::string, SourceBreakpointStateful>& BreakpointsModel::get( ModelIndex index ) {
static std::pair<std::string, SourceBreakpointStateful> EMPTY = {};
if ( !index.isValid() || index.row() >= static_cast<Int64>( mBreakpoints.size() ) )

View File

@@ -38,6 +38,8 @@ class BreakpointsModel : public Model {
void enable( const std::string& filePath, const SourceBreakpointStateful& breakpoint,
bool enable );
void move( const std::string& doc, Int64 fromLine, Int64 toLine, Int64 numLines );
const std::pair<std::string, SourceBreakpointStateful>& get( ModelIndex index );
protected:
std::vector<std::pair<std::string, SourceBreakpointStateful>> mBreakpoints;