mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-06-02 03:26:29 +03:00
Still more WIP
This commit is contained in:
@@ -501,7 +501,8 @@ template <> struct std::hash<ecode::dap::SourceBreakpoint> {
|
||||
};
|
||||
|
||||
template <> struct std::hash<ecode::dap::SourceBreakpointStateful> {
|
||||
std::size_t operator()( ecode::dap::SourceBreakpointStateful const& breakpoint ) const noexcept {
|
||||
std::size_t
|
||||
operator()( ecode::dap::SourceBreakpointStateful const& breakpoint ) const noexcept {
|
||||
size_t h1 = std::hash<int>()( breakpoint.line );
|
||||
size_t h2 = breakpoint.column ? std::hash<int>()( *breakpoint.column ) : 0;
|
||||
size_t h3 = breakpoint.condition ? std::hash<std::string>()( *breakpoint.condition ) : 0;
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
namespace ecode {
|
||||
|
||||
static std::vector<SourceBreakpoint> fromSet( const UnorderedSet<SourceBreakpointStateful>& set ) {
|
||||
std::vector<SourceBreakpoint>
|
||||
DebuggerClientListener::fromSet( const EE::UnorderedSet<SourceBreakpointStateful>& set ) {
|
||||
std::vector<SourceBreakpoint> bps;
|
||||
bps.reserve( set.size() );
|
||||
for ( const auto& bp : set )
|
||||
@@ -13,72 +14,6 @@ static std::vector<SourceBreakpoint> fromSet( const UnorderedSet<SourceBreakpoin
|
||||
return bps;
|
||||
}
|
||||
|
||||
DebuggerClientListener::DebuggerClientListener( DebuggerClient* client, DebuggerPlugin* plugin ) :
|
||||
mClient( client ), mPlugin( plugin ) {
|
||||
eeASSERT( mClient && mPlugin );
|
||||
}
|
||||
|
||||
void DebuggerClientListener::stateChanged( DebuggerClient::State state ) {
|
||||
if ( state == DebuggerClient::State::Initializing ) {
|
||||
mPlugin->getManager()->getUISceneNode()->runOnMainThread( [this] {
|
||||
getStatusDebuggerController()->createWidget();
|
||||
|
||||
mPlugin->getManager()
|
||||
->getPluginContext()
|
||||
->getStatusAppOutputController()
|
||||
->initNewOutput( {}, false );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerClientListener::initialized() {
|
||||
Lock l( mPlugin->mBreakpointsMutex );
|
||||
for ( const auto& fileBps : mPlugin->mBreakpoints )
|
||||
mClient->setBreakpoints( fileBps.first, fromSet( fileBps.second ) );
|
||||
}
|
||||
|
||||
void DebuggerClientListener::launched() {}
|
||||
|
||||
void DebuggerClientListener::configured() {}
|
||||
|
||||
void DebuggerClientListener::failed() {}
|
||||
|
||||
void DebuggerClientListener::debuggeeRunning() {}
|
||||
|
||||
void DebuggerClientListener::debuggeeTerminated() {}
|
||||
|
||||
void DebuggerClientListener::capabilitiesReceived( const Capabilities& /*capabilities*/ ) {}
|
||||
|
||||
void DebuggerClientListener::debuggeeExited( int /*exitCode*/ ) {
|
||||
mPlugin->exitDebugger();
|
||||
}
|
||||
|
||||
void DebuggerClientListener::debuggeeStopped( const StoppedEvent& event ) {
|
||||
Log::debug( "DebuggerClientListener::debuggeeStopped: reason %s", event.reason );
|
||||
mClient->threads();
|
||||
if ( event.threadId )
|
||||
mClient->stackTrace( *event.threadId );
|
||||
}
|
||||
|
||||
void DebuggerClientListener::debuggeeContinued( const ContinuedEvent& ) {}
|
||||
|
||||
void DebuggerClientListener::outputProduced( const Output& output ) {
|
||||
if ( Output::Category::Stdout == output.category ||
|
||||
Output::Category::Stderr == output.category ) {
|
||||
mPlugin->getManager()->getPluginContext()->getStatusAppOutputController()->insertBuffer(
|
||||
output.output );
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerClientListener::debuggingProcess( const ProcessInfo& ) {}
|
||||
|
||||
void DebuggerClientListener::errorResponse( const std::string& /*summary*/,
|
||||
const std::optional<Message>& /*message*/ ) {}
|
||||
|
||||
void DebuggerClientListener::threadChanged( const ThreadEvent& ) {}
|
||||
|
||||
void DebuggerClientListener::moduleChanged( const ModuleEvent& ) {}
|
||||
|
||||
class ThreadsModel : public Model {
|
||||
public:
|
||||
ThreadsModel( const std::vector<Thread>& threads ) : mThreads( threads ) {}
|
||||
@@ -102,16 +37,11 @@ class ThreadsModel : public Model {
|
||||
std::vector<Thread> mThreads;
|
||||
};
|
||||
|
||||
void DebuggerClientListener::threads( const std::vector<Thread>& threads ) {
|
||||
getStatusDebuggerController()->getUIThreads()->setModel(
|
||||
std::make_shared<ThreadsModel>( threads ) );
|
||||
}
|
||||
|
||||
class StackModel : public Model {
|
||||
public:
|
||||
StackModel( const StackTraceInfo& stack ) : mStack( stack ) {}
|
||||
virtual size_t rowCount( const ModelIndex& ) const { return mStack.stackFrames.size(); }
|
||||
virtual size_t columnCount( const ModelIndex& ) const { return 5; }
|
||||
virtual size_t columnCount( const ModelIndex& ) const { return 6; }
|
||||
|
||||
virtual std::string columnName( const size_t& colIdx ) const {
|
||||
switch ( colIdx ) {
|
||||
@@ -160,6 +90,99 @@ class StackModel : public Model {
|
||||
StackTraceInfo mStack;
|
||||
};
|
||||
|
||||
DebuggerClientListener::DebuggerClientListener( DebuggerClient* client, DebuggerPlugin* plugin ) :
|
||||
mClient( client ), mPlugin( plugin ) {
|
||||
eeASSERT( mClient && mPlugin );
|
||||
}
|
||||
|
||||
void DebuggerClientListener::stateChanged( DebuggerClient::State state ) {
|
||||
if ( state == DebuggerClient::State::Initializing ) {
|
||||
mPlugin->getManager()->getUISceneNode()->runOnMainThread( [this] {
|
||||
getStatusDebuggerController()->createWidget();
|
||||
|
||||
mPlugin->getManager()
|
||||
->getPluginContext()
|
||||
->getStatusAppOutputController()
|
||||
->initNewOutput( {}, false );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerClientListener::initialized() {
|
||||
Lock l( mPlugin->mBreakpointsMutex );
|
||||
for ( const auto& fileBps : mPlugin->mBreakpoints )
|
||||
mClient->setBreakpoints( fileBps.first, fromSet( fileBps.second ) );
|
||||
}
|
||||
|
||||
void DebuggerClientListener::launched() {}
|
||||
|
||||
void DebuggerClientListener::configured() {}
|
||||
|
||||
void DebuggerClientListener::failed() {}
|
||||
|
||||
void DebuggerClientListener::debuggeeRunning() {}
|
||||
|
||||
void DebuggerClientListener::debuggeeTerminated() {}
|
||||
|
||||
void DebuggerClientListener::capabilitiesReceived( const Capabilities& /*capabilities*/ ) {}
|
||||
|
||||
void DebuggerClientListener::debuggeeExited( int /*exitCode*/ ) {
|
||||
mPlugin->exitDebugger();
|
||||
}
|
||||
|
||||
void DebuggerClientListener::debuggeeStopped( const StoppedEvent& event ) {
|
||||
Log::debug( "DebuggerClientListener::debuggeeStopped: reason %s", event.reason );
|
||||
|
||||
mStoppedData = event;
|
||||
|
||||
if ( mPausedToRefreshBreakpoints ) {
|
||||
mPlugin->sendPendingBreakpoints();
|
||||
mClient->resume( 1 );
|
||||
mPausedToRefreshBreakpoints = false;
|
||||
return;
|
||||
}
|
||||
|
||||
mClient->threads();
|
||||
|
||||
if ( event.threadId )
|
||||
mClient->stackTrace( *event.threadId );
|
||||
}
|
||||
|
||||
void DebuggerClientListener::debuggeeContinued( const ContinuedEvent& ) {
|
||||
mStoppedData = {};
|
||||
|
||||
// Reset models
|
||||
mScope.clear();
|
||||
|
||||
getStatusDebuggerController()->getUIThreads()->setModel(
|
||||
std::make_shared<ThreadsModel>( std::vector<Thread>{} ) );
|
||||
|
||||
getStatusDebuggerController()->getUIStack()->setModel(
|
||||
std::make_shared<StackModel>( StackTraceInfo{} ) );
|
||||
}
|
||||
|
||||
void DebuggerClientListener::outputProduced( const Output& output ) {
|
||||
if ( Output::Category::Stdout == output.category ||
|
||||
Output::Category::Stderr == output.category ) {
|
||||
mPlugin->getManager()->getPluginContext()->getStatusAppOutputController()->insertBuffer(
|
||||
output.output );
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerClientListener::debuggingProcess( const ProcessInfo& ) {}
|
||||
|
||||
void DebuggerClientListener::errorResponse( const std::string& /*summary*/,
|
||||
const std::optional<Message>& /*message*/ ) {}
|
||||
|
||||
void DebuggerClientListener::threadChanged( const ThreadEvent& ) {}
|
||||
|
||||
void DebuggerClientListener::moduleChanged( const ModuleEvent& ) {}
|
||||
|
||||
void DebuggerClientListener::threads( const std::vector<Thread>& threads ) {
|
||||
getStatusDebuggerController()->getUIThreads()->setModel(
|
||||
std::make_shared<ThreadsModel>( threads ) );
|
||||
}
|
||||
|
||||
void DebuggerClientListener::stackTrace( const int /*threadId*/, const StackTraceInfo& stack ) {
|
||||
getStatusDebuggerController()->getUIStack()->setModel( std::make_shared<StackModel>( stack ) );
|
||||
|
||||
@@ -168,17 +191,27 @@ void DebuggerClientListener::stackTrace( const int /*threadId*/, const StackTrac
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerClientListener::scopes( const int /*frameId**/, const std::vector<Scope>& scopes ) {
|
||||
// if ( !scopes.empty() ) {
|
||||
// mClient->variables( scopes[0].variablesReference );
|
||||
// }
|
||||
void DebuggerClientListener::scopes( const int /*frameId*/, const std::vector<Scope>& scopes ) {
|
||||
if ( !scopes.empty() ) {
|
||||
for ( const auto& scope : scopes ) {
|
||||
ModelScope mscope;
|
||||
mscope.name = scope.name;
|
||||
mscope.variablesReference = scope.variablesReference;
|
||||
mScope.emplace_back( std::move( mscope ) );
|
||||
mClient->variables( scope.variablesReference );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerClientListener::variables( const int /*variablesReference*/,
|
||||
void DebuggerClientListener::variables( const int variablesReference,
|
||||
const std::vector<Variable>& vars ) {
|
||||
// if ( !vars.empty() ) {
|
||||
// mClient->resume( 1 );
|
||||
// }
|
||||
auto scopeIt =
|
||||
std::find_if( mScope.begin(), mScope.end(), [variablesReference]( const ModelScope& cur ) {
|
||||
return cur.variablesReference == variablesReference;
|
||||
} );
|
||||
if ( scopeIt == mScope.end() )
|
||||
return;
|
||||
scopeIt->variables = vars;
|
||||
}
|
||||
|
||||
void DebuggerClientListener::modules( const ModulesInfo& ) {}
|
||||
@@ -199,14 +232,19 @@ void DebuggerClientListener::expressionEvaluated( const std::string& /*expressio
|
||||
void DebuggerClientListener::gotoTargets( const Source& /*source*/, const int /*line*/,
|
||||
const std::vector<GotoTarget>& /*targets*/ ) {}
|
||||
|
||||
StatusDebuggerController* DebuggerClientListener::getStatusDebuggerController() const {
|
||||
bool DebuggerClientListener::isStopped() const {
|
||||
return mStoppedData ? true : false;
|
||||
}
|
||||
|
||||
std::optional<StoppedEvent> DebuggerClientListener::getStoppedData() const {
|
||||
return mStoppedData;
|
||||
}
|
||||
|
||||
StatusDebuggerController* DebuggerClientListener::getStatusDebuggerController() const {
|
||||
auto debuggerElement =
|
||||
mPlugin->getManager()->getPluginContext()->getStatusBar()->getStatusBarElement(
|
||||
"status_app_debugger" );
|
||||
|
||||
if ( !debuggerElement )
|
||||
return nullptr;
|
||||
eeASSERT( debuggerElement );
|
||||
return static_cast<StatusDebuggerController*>( debuggerElement.get() );
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,17 @@ namespace ecode {
|
||||
|
||||
class DebuggerPlugin;
|
||||
|
||||
struct ModelScope {
|
||||
std::string name;
|
||||
int variablesReference;
|
||||
std::vector<Variable> variables;
|
||||
};
|
||||
|
||||
class DebuggerClientListener : public DebuggerClient::Listener {
|
||||
public:
|
||||
static std::vector<SourceBreakpoint>
|
||||
fromSet( const EE::UnorderedSet<SourceBreakpointStateful>& set );
|
||||
|
||||
DebuggerClientListener( DebuggerClient* client, DebuggerPlugin* plugin );
|
||||
|
||||
void stateChanged( DebuggerClient::State );
|
||||
@@ -42,9 +51,18 @@ class DebuggerClientListener : public DebuggerClient::Listener {
|
||||
void gotoTargets( const Source& source, const int line,
|
||||
const std::vector<GotoTarget>& targets );
|
||||
|
||||
bool isStopped() const;
|
||||
|
||||
std::optional<StoppedEvent> getStoppedData() const;
|
||||
|
||||
void setPausedToRefreshBreakpoints() { mPausedToRefreshBreakpoints = true; }
|
||||
|
||||
protected:
|
||||
DebuggerClient* mClient{ nullptr };
|
||||
DebuggerPlugin* mPlugin{ nullptr };
|
||||
std::optional<StoppedEvent> mStoppedData;
|
||||
std::vector<ModelScope> mScope;
|
||||
bool mPausedToRefreshBreakpoints{ false };
|
||||
|
||||
StatusDebuggerController* getStatusDebuggerController() const;
|
||||
};
|
||||
|
||||
@@ -170,11 +170,12 @@ void DebuggerPlugin::loadDAPConfig( const std::string& path, bool updateConfigFi
|
||||
}
|
||||
|
||||
if ( mKeyBindings.empty() ) {
|
||||
mKeyBindings["debugger-continue-interrupt"] = "f5";
|
||||
}
|
||||
|
||||
if ( j.contains( "keybindings" ) ) {
|
||||
auto& kb = j["keybindings"];
|
||||
std::initializer_list<std::string> list = {};
|
||||
std::initializer_list<std::string> list = { "debugger-continue-interrupt" };
|
||||
for ( const auto& key : list ) {
|
||||
if ( kb.contains( key ) ) {
|
||||
if ( !kb[key].empty() )
|
||||
@@ -325,13 +326,45 @@ void DebuggerPlugin::updateSidePanelTab() {
|
||||
if ( mDebugger && mDebugger->started() ) {
|
||||
exitDebugger();
|
||||
} else {
|
||||
runConfig( mUIDebuggerList->getListBox()->getItemSelectedText().toUtf8(),
|
||||
mUIDebuggerConfList->getListBox()->getItemSelectedText().toUtf8() );
|
||||
runCurrentConfig();
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerPlugin::runCurrentConfig() {
|
||||
runConfig( mUIDebuggerList->getListBox()->getItemSelectedText().toUtf8(),
|
||||
mUIDebuggerConfList->getListBox()->getItemSelectedText().toUtf8() );
|
||||
}
|
||||
|
||||
void DebuggerPlugin::sendPendingBreakpoints() {
|
||||
for ( const auto& pbp : mPendingBreakpoints )
|
||||
sendFileBreakpoints( pbp );
|
||||
mPendingBreakpoints.clear();
|
||||
if ( mDebugger )
|
||||
mDebugger->resume( 1 );
|
||||
}
|
||||
|
||||
void DebuggerPlugin::sendFileBreakpoints( const std::string& filePath ) {
|
||||
if ( !mDebugger || !mListener || !mDebugger->isServerConnected() )
|
||||
return;
|
||||
|
||||
if ( !mListener->isStopped() ) {
|
||||
mPendingBreakpoints.insert( filePath );
|
||||
mListener->setPausedToRefreshBreakpoints();
|
||||
mDebugger->pause( 1 );
|
||||
return;
|
||||
}
|
||||
|
||||
Lock l( mBreakpointsMutex );
|
||||
auto fileBps = mBreakpoints.find( filePath );
|
||||
if ( fileBps == mBreakpoints.end() )
|
||||
return;
|
||||
for ( const auto& fileBps : mBreakpoints )
|
||||
mDebugger->setBreakpoints( fileBps.first,
|
||||
DebuggerClientListener::fromSet( fileBps.second ) );
|
||||
}
|
||||
|
||||
void DebuggerPlugin::updateDebuggerConfigurationList() {
|
||||
mUIDebuggerConfList->getListBox()->clear();
|
||||
|
||||
@@ -392,8 +425,26 @@ void DebuggerPlugin::replaceKeysInJson( nlohmann::json& json ) {
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerPlugin::onRegisterDocument( TextDocument* doc ) {
|
||||
doc->setCommand( "debugger-continue-interrupt", [this]() {
|
||||
if ( mDebugger && mListener ) {
|
||||
if ( mListener->isStopped() ) {
|
||||
mDebugger->resume( mListener->getStoppedData()->threadId
|
||||
? *mListener->getStoppedData()->threadId
|
||||
: 1 );
|
||||
} else {
|
||||
mDebugger->pause( 1 );
|
||||
}
|
||||
} else {
|
||||
runCurrentConfig();
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
void DebuggerPlugin::onRegisterEditor( UICodeEditor* editor ) {
|
||||
editor->registerGutterSpace( this, PixelDensity::dpToPx( 8 ), 0 );
|
||||
|
||||
PluginBase::onRegisterEditor( editor );
|
||||
}
|
||||
|
||||
void DebuggerPlugin::onUnregisterEditor( UICodeEditor* editor ) {
|
||||
@@ -441,9 +492,11 @@ void DebuggerPlugin::drawLineNumbersBefore( UICodeEditor* editor,
|
||||
radius );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool DebuggerPlugin::onLineNumberClick( UICodeEditor* editor, Uint32 lineNumber ) {
|
||||
bool DebuggerPlugin::setBreakpoint( UICodeEditor* editor, Uint32 lineNumber ) {
|
||||
if ( !editor->getDocument().hasFilepath() )
|
||||
return false;
|
||||
if ( !isSupportedByAnyDebugger( editor->getDocument().getSyntaxDefinition().getLSPName() ) )
|
||||
@@ -456,6 +509,8 @@ bool DebuggerPlugin::onLineNumberClick( UICodeEditor* editor, Uint32 lineNumber
|
||||
} else {
|
||||
breakpoints.insert( SourceBreakpointStateful( lineNumber ) );
|
||||
}
|
||||
mThreadPool->run(
|
||||
[this, editor] { sendFileBreakpoints( editor->getDocument().getFilePath() ); } );
|
||||
editor->invalidateDraw();
|
||||
return true;
|
||||
}
|
||||
@@ -471,7 +526,7 @@ bool DebuggerPlugin::onMouseDown( UICodeEditor* editor, const Vector2i& position
|
||||
localPos.y > editor->getPluginsTopSpace() ) {
|
||||
if ( editor->getUISceneNode()->getEventDispatcher()->isFirstPress() ) {
|
||||
auto cursorPos( editor->resolveScreenPosition( position.asFloat() ) );
|
||||
onLineNumberClick( editor, cursorPos.line() );
|
||||
setBreakpoint( editor, cursorPos.line() );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ class DebuggerPlugin : public PluginBase {
|
||||
UIDropDownList* mUIDebuggerConfList{ nullptr };
|
||||
UIPushButton* mRunButton{ nullptr };
|
||||
UnorderedMap<std::string, UnorderedSet<SourceBreakpointStateful>> mBreakpoints;
|
||||
UnorderedSet<std::string> mPendingBreakpoints;
|
||||
Mutex mBreakpointsMutex;
|
||||
|
||||
DebuggerPlugin( PluginManager* pluginManager, bool sync );
|
||||
@@ -99,16 +100,23 @@ class DebuggerPlugin : public PluginBase {
|
||||
|
||||
void onUnregisterEditor( UICodeEditor* ) override;
|
||||
|
||||
void onRegisterDocument( TextDocument* doc ) override;
|
||||
|
||||
void drawLineNumbersBefore( UICodeEditor* editor, const DocumentLineRange& lineRange,
|
||||
const Vector2f& startScroll, const Vector2f& screenStart,
|
||||
const Float& lineHeight, const Float& lineNumberWidth,
|
||||
const int& lineNumberDigits, const Float& fontSize ) override;
|
||||
|
||||
bool onLineNumberClick( UICodeEditor* editor, Uint32 lineNumber );
|
||||
bool setBreakpoint( UICodeEditor* editor, Uint32 lineNumber );
|
||||
|
||||
bool onMouseDown( UICodeEditor*, const Vector2i&, const Uint32& flags ) override;
|
||||
|
||||
bool isSupportedByAnyDebugger( const std::string& language );
|
||||
|
||||
void runCurrentConfig();
|
||||
|
||||
void sendFileBreakpoints( const std::string& filePath );
|
||||
void sendPendingBreakpoints();
|
||||
};
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
@@ -56,6 +56,20 @@ void StatusDebuggerController::createContainer() {
|
||||
mContainer->bind( "debugger_threads", mUIThreads );
|
||||
mContainer->bind( "debugger_stack", mUIStack );
|
||||
mContainer->bind( "debugger_breakpoints", mUIBreakpoints );
|
||||
|
||||
mContainer->runOnMainThread( [this] {
|
||||
const Float width = mContainer->getPixelsSize().getWidth();
|
||||
|
||||
mUIThreads->setColumnWidth( 0, width * 0.1 );
|
||||
mUIThreads->setColumnWidth( 1, eefloor( width * 0.88 ) );
|
||||
|
||||
mUIStack->setColumnWidth( 0, width * 0.05 );
|
||||
mUIStack->setColumnWidth( 1, width * 0.3 );
|
||||
mUIStack->setColumnWidth( 2, width * 0.15 );
|
||||
mUIStack->setColumnWidth( 3, eefloor( width * 0.3 ) );
|
||||
mUIStack->setColumnWidth( 4, width * 0.08 );
|
||||
mUIStack->setColumnWidth( 5, width * 0.08 );
|
||||
} );
|
||||
}
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
@@ -635,16 +635,6 @@ void GitPlugin::onRegisterListeners( UICodeEditor* editor, std::vector<Uint32>&
|
||||
} ) );
|
||||
}
|
||||
|
||||
void GitPlugin::onBeforeUnregister( UICodeEditor* editor ) {
|
||||
for ( auto& kb : mKeyBindings )
|
||||
editor->getKeyBindings().removeCommandKeybind( kb.first );
|
||||
}
|
||||
|
||||
void GitPlugin::onUnregisterDocument( TextDocument* doc ) {
|
||||
for ( auto& kb : mKeyBindings )
|
||||
doc->removeCommand( kb.first );
|
||||
}
|
||||
|
||||
Color GitPlugin::getVarColor( const std::string& var ) {
|
||||
return Color::fromString(
|
||||
getUISceneNode()->getRoot()->getUIStyle()->getVariable( var ).getValue() );
|
||||
|
||||
@@ -147,10 +147,6 @@ class GitPlugin : public PluginBase {
|
||||
|
||||
void onRegisterListeners( UICodeEditor*, std::vector<Uint32>& listeners ) override;
|
||||
|
||||
void onBeforeUnregister( UICodeEditor* ) override;
|
||||
|
||||
void onUnregisterDocument( TextDocument* ) override;
|
||||
|
||||
Color getVarColor( const std::string& var );
|
||||
|
||||
void blame( UICodeEditor* editor );
|
||||
|
||||
@@ -195,4 +195,21 @@ void PluginBase::onUnregister( UICodeEditor* editor ) {
|
||||
mDocs.erase( doc );
|
||||
}
|
||||
|
||||
void PluginBase::onBeforeUnregister( UICodeEditor* editor ) {
|
||||
for ( auto& kb : mKeyBindings )
|
||||
editor->getKeyBindings().removeCommandKeybind( kb.first );
|
||||
}
|
||||
|
||||
void PluginBase::onRegisterEditor( UICodeEditor* editor ) {
|
||||
for ( auto& kb : mKeyBindings ) {
|
||||
if ( !kb.second.empty() )
|
||||
editor->getKeyBindings().addKeybindString( kb.second, kb.first );
|
||||
}
|
||||
}
|
||||
|
||||
void PluginBase::onUnregisterDocument( TextDocument* doc ) {
|
||||
for ( auto& kb : mKeyBindings )
|
||||
doc->removeCommand( kb.first );
|
||||
}
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
@@ -91,25 +91,26 @@ class PluginBase : public Plugin {
|
||||
//! If the configuration is stored in a file, keep track of the config hash
|
||||
String::HashType mConfigHash{ 0 };
|
||||
|
||||
virtual void onDocumentLoaded( TextDocument* ) {};
|
||||
virtual void onDocumentLoaded( TextDocument* ) {}
|
||||
|
||||
virtual void onDocumentClosed( TextDocument* ) {};
|
||||
virtual void onDocumentClosed( TextDocument* ) {}
|
||||
|
||||
virtual void onDocumentChanged( UICodeEditor*, TextDocument* /*oldDoc*/ ) {};
|
||||
|
||||
virtual void onRegisterListeners( UICodeEditor*, std::vector<Uint32>& /*listeners*/ ) {};
|
||||
|
||||
//! Usually used to remove keybindings in an editor
|
||||
virtual void onBeforeUnregister( UICodeEditor* ) {};
|
||||
virtual void onBeforeUnregister( UICodeEditor* );
|
||||
|
||||
virtual void onRegisterDocument( TextDocument* ) {};
|
||||
virtual void onRegisterDocument( TextDocument* ) {}
|
||||
|
||||
virtual void onRegisterEditor( UICodeEditor* ) {};
|
||||
virtual void onRegisterEditor( UICodeEditor* );
|
||||
|
||||
virtual void onUnregisterEditor( UICodeEditor* ) {};
|
||||
virtual void onUnregisterEditor( UICodeEditor* ) {}
|
||||
|
||||
//! Usually used to unregister commands in a document
|
||||
virtual void onUnregisterDocument( TextDocument* ) {};
|
||||
virtual void onUnregisterDocument( TextDocument* );
|
||||
;
|
||||
};
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
Reference in New Issue
Block a user