More WIP.

This commit is contained in:
Martín Lucas Golini
2025-01-02 01:08:02 -03:00
parent cf84fc7cff
commit 443aead0df
11 changed files with 221 additions and 11 deletions

View File

@@ -23,8 +23,8 @@ bool BusSettings::hasConnection() const {
}
ProtocolSettings::ProtocolSettings( const nlohmann::json& configuration ) :
linesStartAt1( true ),
columnsStartAt1( true ),
linesStartAt1( false ),
columnsStartAt1( false ),
pathFormatURI( false ),
redirectStderr( configuration.value( REDIRECT_STDERR, false ) ),
redirectStdout( configuration.value( REDIRECT_STDOUT, false ) ),

View File

@@ -1,8 +1,8 @@
#pragma once
#include <eepp/core/containers.hpp>
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>
#include <nlohmann/json.hpp>
@@ -169,6 +169,8 @@ struct SourceBreakpoint {
SourceBreakpoint( const int line );
json toJson() const;
bool operator==( const SourceBreakpoint& other ) const { return line == other.line; }
};
struct Breakpoint {
@@ -474,4 +476,16 @@ struct GotoTarget {
static std::vector<GotoTarget> parseList( const json& variables );
};
} // namespace dap
} // namespace ecode::dap
template <> struct std::hash<ecode::dap::SourceBreakpoint> {
std::size_t operator()( ecode::dap::SourceBreakpoint 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;
size_t h4 =
breakpoint.hitCondition ? std::hash<std::string>()( *breakpoint.hitCondition ) : 0;
size_t h5 = breakpoint.logMessage ? std::hash<std::string>()( *breakpoint.logMessage ) : 0;
return hashCombine( h1, h2, h3, h4, h5 );
}
};

View File

@@ -4,6 +4,7 @@
#include "busprocess.hpp"
#include "dap/debuggerclientdap.hpp"
#include "statusdebuggercontroller.hpp"
#include <eepp/graphics/primitives.hpp>
#include <eepp/system/filesystem.hpp>
#include <eepp/system/scopedop.hpp>
#include <eepp/ui/uidropdownlist.hpp>
@@ -151,6 +152,16 @@ void DebuggerPlugin::loadDAPConfig( const std::string& path, bool updateConfigFi
dapTool.configurations.emplace_back( std::move( dapConfig ) );
}
}
if ( dap.contains( "languages" ) && dap["languages"].is_array() ) {
auto& languages = dap["languages"];
dapTool.languagesSupported.reserve( languages.size() );
for ( const auto& lang : languages ) {
if ( lang.is_string() )
dapTool.languagesSupported.emplace_back( lang.get<std::string>() );
}
}
mDaps.emplace_back( std::move( dapTool ) );
}
}
@@ -381,6 +392,101 @@ void DebuggerPlugin::replaceKeysInJson( nlohmann::json& json ) {
}
}
void DebuggerPlugin::onRegisterEditor( UICodeEditor* editor ) {
editor->registerGutterSpace( this, PixelDensity::dpToPx( 8 ), 0 );
}
void DebuggerPlugin::onUnregisterEditor( UICodeEditor* editor ) {
editor->unregisterGutterSpace( this );
}
void DebuggerPlugin::drawLineNumbersBefore( UICodeEditor* editor,
const DocumentLineRange& lineRange,
const Vector2f& startScroll,
const Vector2f& screenStart, const Float& lineHeight,
const Float&, const int&, const Float& ) {
if ( !editor->getDocument().hasFilepath() )
return;
auto docIt = mBreakpoints.find( editor->getDocument().getFilePath() );
if ( docIt == mBreakpoints.end() || docIt->second.empty() )
return;
const auto& breakpoints = docIt->second;
Primitives p;
Float lineOffset = editor->getLineOffset();
p.setColor( Color( editor->getColorScheme().getEditorColor( SyntaxStyleTypes::Error ) )
.blendAlpha( editor->getAlpha() ) );
Float gutterSpace = editor->getGutterSpace( this );
Float radius = PixelDensity::dpToPx( 3 );
Float offset = editor->getGutterLocalStartOffset( this );
for ( const SourceBreakpoint& breakpoint : breakpoints ) {
if ( breakpoint.line >= lineRange.first && breakpoint.line <= lineRange.second ) {
if ( !editor->getDocumentView().isLineVisible( breakpoint.line ) )
continue;
auto lnPos( Vector2f(
screenStart.x - editor->getPluginsGutterSpace() + offset,
startScroll.y +
editor->getDocumentView().getLineYOffset( breakpoint.line, lineHeight ) +
lineOffset ) );
// p.setColor( Color::Gray );
// p.drawRectangle( { lnPos, Sizef{ gutterSpace, lineHeight } } );
p.setColor( Color( editor->getColorScheme().getEditorColor( SyntaxStyleTypes::Error ) )
.blendAlpha( editor->getAlpha() ) );
p.drawCircle( { lnPos.x + radius + eefloor( ( gutterSpace - radius ) * 0.5f ),
lnPos.y + lineHeight * 0.5f },
radius );
}
}
}
bool DebuggerPlugin::onLineNumberClick( UICodeEditor* editor, Uint32 lineNumber ) {
if ( !editor->getDocument().hasFilepath() )
return false;
if ( !isSupportedByAnyDebugger( editor->getDocument().getSyntaxDefinition().getLSPName() ) )
return false;
Lock l( mBreakpointsMutex );
auto& breakpoints = mBreakpoints[editor->getDocument().getFilePath()];
auto breakpointIt = breakpoints.find( SourceBreakpoint( lineNumber ) );
if ( breakpointIt != breakpoints.end() ) {
breakpoints.erase( breakpointIt );
} else {
breakpoints.insert( SourceBreakpoint( lineNumber ) );
}
editor->invalidateDraw();
return true;
}
bool DebuggerPlugin::onMouseDown( UICodeEditor* editor, const Vector2i& position,
const Uint32& flags ) {
if ( !( flags & EE_BUTTON_LMASK ) )
return false;
Float offset = editor->getGutterLocalStartOffset( this );
Vector2f localPos( editor->convertToNodeSpace( position.asFloat() ) );
if ( localPos.x >= editor->getPixelsPadding().Left + offset &&
localPos.x < editor->getPixelsPadding().Left + offset + editor->getGutterSpace( this ) &&
localPos.y > editor->getPluginsTopSpace() ) {
if ( editor->getUISceneNode()->getEventDispatcher()->isFirstPress() ) {
auto cursorPos( editor->resolveScreenPosition( position.asFloat() ) );
onLineNumberClick( editor, cursorPos.line() );
}
return true;
}
return false;
}
bool DebuggerPlugin::isSupportedByAnyDebugger( const std::string& language ) {
for ( const auto& dap : mDaps ) {
if ( std::any_of( dap.languagesSupported.begin(), dap.languagesSupported.end(),
[&language]( const auto& l ) { return l == language; } ) )
return true;
}
return false;
}
void DebuggerPlugin::runConfig( const std::string& debugger, const std::string& configuration ) {
auto debuggerIt = std::find_if( mDaps.begin(), mDaps.end(), [&debugger]( const DapTool& dap ) {
return dap.name == debugger;

View File

@@ -23,6 +23,7 @@ struct DapConfig {
struct DapTool {
std::string name;
std::string url;
std::vector<std::string> languagesSupported;
DapRunConfig run;
std::vector<DapConfig> configurations;
};
@@ -63,6 +64,8 @@ class DebuggerPlugin : public PluginBase {
UIDropDownList* mUIDebuggerList{ nullptr };
UIDropDownList* mUIDebuggerConfList{ nullptr };
UIPushButton* mRunButton{ nullptr };
UnorderedMap<std::string, UnorderedSet<SourceBreakpoint>> mBreakpoints;
Mutex mBreakpointsMutex;
DebuggerPlugin( PluginManager* pluginManager, bool sync );
@@ -91,6 +94,21 @@ class DebuggerPlugin : public PluginBase {
void exitDebugger();
void replaceKeysInJson( nlohmann::json& json );
void onRegisterEditor( UICodeEditor* ) override;
void onUnregisterEditor( UICodeEditor* ) 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 onMouseDown( UICodeEditor*, const Vector2i&, const Uint32& flags ) override;
bool isSupportedByAnyDebugger( const std::string& language );
};
} // namespace ecode

View File

@@ -170,6 +170,8 @@ void PluginBase::onRegister( UICodeEditor* editor ) {
onRegisterDocument( editor->getDocumentRef().get() );
}
mEditorDocs[editor] = editor->getDocumentRef().get();
onRegisterEditor( editor );
}
void PluginBase::onUnregister( UICodeEditor* editor ) {

View File

@@ -104,6 +104,8 @@ class PluginBase : public Plugin {
virtual void onRegisterDocument( TextDocument* ) {};
virtual void onRegisterEditor( UICodeEditor* ) {};
virtual void onUnregisterEditor( UICodeEditor* ) {};
//! Usually used to unregister commands in a document