mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-07-23 03:02:50 +03:00
Some debugger improvements for node dap.
Fixed a bug in TextDocument that created new history in the undo/redo stack when not doing any operation when trying to cut.
This commit is contained in:
@@ -245,11 +245,7 @@
|
||||
"type": "pwa-node",
|
||||
"run": {
|
||||
"command": "node",
|
||||
"command_arguments": [
|
||||
"${env:VSCODE_JS_DEBUG_PATH}/src/dapDebugServer.js",
|
||||
"${randPort}",
|
||||
"127.0.0.1"
|
||||
]
|
||||
"command_arguments": [ "${env:VSCODE_JS_DEBUG_PATH}/src/dapDebugServer.js", "${randPort}", "127.0.0.1" ]
|
||||
},
|
||||
"languages": ["javascript", "typescript"],
|
||||
"configurations": [
|
||||
|
||||
@@ -275,7 +275,7 @@ class EE_API TextDocument {
|
||||
|
||||
void deleteTo( const size_t& cursorIdx, int offset );
|
||||
|
||||
void deleteSelection();
|
||||
bool deleteSelection();
|
||||
|
||||
void selectTo( TextPosition position );
|
||||
|
||||
@@ -578,7 +578,7 @@ class EE_API TextDocument {
|
||||
|
||||
void popSelection();
|
||||
|
||||
void deleteSelection( const size_t& cursorIdx );
|
||||
bool deleteSelection( const size_t& cursorIdx );
|
||||
|
||||
String getSelectedText( const size_t& cursorIdx ) const;
|
||||
|
||||
|
||||
@@ -1237,6 +1237,8 @@ TextPosition TextDocument::insert( const size_t& cursorIdx, TextPosition positio
|
||||
}
|
||||
|
||||
size_t TextDocument::remove( const size_t& cursorIdx, TextRange range ) {
|
||||
if ( !range.hasSelection() )
|
||||
return 0;
|
||||
size_t lineCount = mLines.size();
|
||||
mUndoStack.clearRedoStack();
|
||||
size_t linesRemoved = remove( cursorIdx, sanitizeRange( range.normalized() ),
|
||||
@@ -1249,7 +1251,7 @@ size_t TextDocument::remove( const size_t& cursorIdx, TextRange range ) {
|
||||
|
||||
size_t TextDocument::remove( const size_t& cursorIdx, TextRange range,
|
||||
UndoStackContainer& undoStack, const Time& time, bool fromUndoRedo ) {
|
||||
if ( !range.isValid() )
|
||||
if ( !range.hasSelection() )
|
||||
return 0;
|
||||
|
||||
mModificationId++;
|
||||
@@ -1601,16 +1603,21 @@ void TextDocument::deleteTo( const size_t& cursorIdx, int offset ) {
|
||||
setSelection( cursorIdx, cursorPos );
|
||||
}
|
||||
|
||||
void TextDocument::deleteSelection( const size_t& cursorIdx ) {
|
||||
bool TextDocument::deleteSelection( const size_t& cursorIdx ) {
|
||||
BoolScopedOpOptional op( !mDoingTextInput, mDoingTextInput, true );
|
||||
if ( !getSelectionIndex( cursorIdx ).hasSelection() )
|
||||
return false;
|
||||
TextPosition cursorPos = getSelectionIndex( cursorIdx ).normalized().start();
|
||||
remove( cursorIdx, getSelectionIndex( cursorIdx ) );
|
||||
setSelection( cursorIdx, cursorPos );
|
||||
return true;
|
||||
}
|
||||
|
||||
void TextDocument::deleteSelection() {
|
||||
bool TextDocument::deleteSelection() {
|
||||
bool somethingWasDeleted = false;
|
||||
for ( size_t i = 0; i < mSelection.size(); ++i )
|
||||
deleteSelection( i );
|
||||
somethingWasDeleted |= deleteSelection( i );
|
||||
return somethingWasDeleted;
|
||||
}
|
||||
|
||||
void TextDocument::selectTo( TextPosition position ) {
|
||||
|
||||
40
src/tools/ecode/jsonhelper.hpp
Normal file
40
src/tools/ecode/jsonhelper.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
template <typename T> static constexpr nlohmann::detail::value_t json_get_value_type() {
|
||||
if constexpr ( std::is_same_v<T, std::string> ) {
|
||||
return nlohmann::detail::value_t::string;
|
||||
} else if constexpr ( std::is_same_v<T, bool> ) {
|
||||
return nlohmann::detail::value_t::boolean;
|
||||
} else if constexpr ( std::is_same_v<T, int64_t> || std::is_same_v<T, int32_t> ||
|
||||
std::is_same_v<T, int16_t> || std::is_same_v<T, int8_t> ) {
|
||||
return nlohmann::detail::value_t::number_integer;
|
||||
} else if constexpr ( std::is_same_v<T, uint64_t> || std::is_same_v<T, uint32_t> ||
|
||||
std::is_same_v<T, uint16_t> || std::is_same_v<T, uint8_t> ) {
|
||||
return nlohmann::detail::value_t::number_unsigned;
|
||||
} else if constexpr ( std::is_same_v<T, double> || std::is_same_v<T, float> ) {
|
||||
return nlohmann::detail::value_t::number_float;
|
||||
} else if constexpr ( std::is_same_v<T, nlohmann::json> ) {
|
||||
return nlohmann::detail::value_t::object;
|
||||
} else if constexpr ( std::is_same_v<T, std::vector<std::uint8_t>> ) {
|
||||
return nlohmann::detail::value_t::binary;
|
||||
} else {
|
||||
return nlohmann::detail::value_t::null;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static std::optional<T> json_get_if( nlohmann::json& json, std::string_view key, T defVal ) {
|
||||
if ( json.contains( key ) && json[key].type() == json_get_value_type<T>() ) {
|
||||
return json.value( key, defVal );
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static std::optional<T> json_get_if( nlohmann::json& json, std::string_view key ) {
|
||||
if ( json.contains( key ) && json[key].type() == json_get_value_type<T>() )
|
||||
return json[key].get<T>();
|
||||
return {};
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "debuggerplugin.hpp"
|
||||
#include "../../jsonhelper.hpp"
|
||||
#include "../../notificationcenter.hpp"
|
||||
#include "../../terminalmanager.hpp"
|
||||
#include "../../uistatusbar.hpp"
|
||||
@@ -16,7 +17,6 @@
|
||||
#include <eepp/system/scopedop.hpp>
|
||||
#include <eepp/ui/uidropdownlist.hpp>
|
||||
#include <eepp/ui/uitooltip.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace EE::UI;
|
||||
using namespace EE::UI::Doc;
|
||||
@@ -97,23 +97,31 @@ static void replaceExecutableArgs( std::string& arg ) {
|
||||
};
|
||||
}
|
||||
|
||||
static void replaceEnvVars( std::string& arg ) {
|
||||
static bool replaceEnvVars( std::string& arg, PluginContextProvider* ctx ) {
|
||||
PatternMatcher::Range match[4];
|
||||
while ( envPtrn.matches( arg, match ) ) {
|
||||
auto envCall = arg.substr( match[0].start, match[0].end - match[0].start );
|
||||
if ( envCall.size() > 6 ) {
|
||||
auto envName = envCall.substr( 6, envCall.size() - 7 );
|
||||
const char* env = getenv( envName.c_str() );
|
||||
if ( env ) {
|
||||
if ( env && strlen( env ) != 0 ) {
|
||||
std::string out{ env };
|
||||
String::trimInPlace( out, '\n' );
|
||||
String::trimInPlace( out, '\t' );
|
||||
String::replaceAll( arg, envCall, out );
|
||||
} else {
|
||||
arg = "";
|
||||
ctx->getNotificationCenter()->addNotification( String::format(
|
||||
ctx->i18n( "command_parameter_env_var_not_found",
|
||||
"The environment variable \"%s\" was not found but it's needed in "
|
||||
"order to run the debugger." )
|
||||
.toUtf8(),
|
||||
envName ) );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
// Mouse Hover Tooltip
|
||||
@@ -1120,7 +1128,7 @@ void DebuggerPlugin::updateDebuggerConfigurationList() {
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerPlugin::replaceInVal( std::string& val,
|
||||
bool DebuggerPlugin::replaceInVal( std::string& val,
|
||||
const std::optional<ProjectBuildStep>& runConfig,
|
||||
ProjectBuild* buildConfig, int randomPort ) {
|
||||
|
||||
@@ -1174,10 +1182,10 @@ void DebuggerPlugin::replaceInVal( std::string& val,
|
||||
if ( String::contains( val, KEY_RANDPORT ) )
|
||||
String::replaceAll( val, KEY_RANDPORT, String::toString( randomPort ) );
|
||||
|
||||
replaceEnvVars( val );
|
||||
return replaceEnvVars( val, this->getPluginContext() );
|
||||
}
|
||||
|
||||
std::vector<std::string> DebuggerPlugin::replaceKeyInString(
|
||||
std::pair<bool, std::vector<std::string>> DebuggerPlugin::replaceKeyInString(
|
||||
std::string val, int randomPort,
|
||||
const std::unordered_map<std::string, std::string>& solvedInputs ) {
|
||||
auto pbm = getPluginContext()->getProjectBuildManager();
|
||||
@@ -1185,8 +1193,9 @@ std::vector<std::string> DebuggerPlugin::replaceKeyInString(
|
||||
auto buildConfig = pbm ? pbm->getCurrentBuild() : nullptr;
|
||||
|
||||
const auto replaceVal = [this, &runConfig, &buildConfig, &solvedInputs,
|
||||
randomPort]( std::string& val ) {
|
||||
replaceInVal( val, runConfig, buildConfig, randomPort );
|
||||
randomPort]( std::string& val ) -> bool {
|
||||
if ( !replaceInVal( val, runConfig, buildConfig, randomPort ) )
|
||||
return false;
|
||||
|
||||
LuaPattern::Range matches[2];
|
||||
if ( inputPtrn.matches( val, matches ) ) {
|
||||
@@ -1204,6 +1213,8 @@ std::vector<std::string> DebuggerPlugin::replaceKeyInString(
|
||||
if ( solvedIdIt != solvedInputs.end() )
|
||||
val = solvedIdIt->second;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
if ( runConfig && val == KEY_ARGS ) {
|
||||
@@ -1213,12 +1224,13 @@ std::vector<std::string> DebuggerPlugin::replaceKeyInString(
|
||||
replaceVal( arg );
|
||||
argsArr.push_back( arg );
|
||||
}
|
||||
return argsArr;
|
||||
return { true, argsArr };
|
||||
}
|
||||
|
||||
replaceVal( val );
|
||||
if ( !replaceVal( val ) )
|
||||
return { false, {} };
|
||||
|
||||
return { val };
|
||||
return { true, { val } };
|
||||
}
|
||||
|
||||
void DebuggerPlugin::replaceKeysInJson(
|
||||
@@ -1873,6 +1885,26 @@ void DebuggerPlugin::resolveInputsBeforeRun(
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<Connection> getDebugServer( nlohmann::json& json ) {
|
||||
auto debugServerInt = json_get_if<int>( json, KEY_DEBUG_SERVER );
|
||||
|
||||
if ( debugServerInt )
|
||||
return Connection{ *debugServerInt, "localhost" };
|
||||
|
||||
auto debugServerStr = json_get_if<std::string>( json, KEY_DEBUG_SERVER );
|
||||
if ( debugServerStr ) {
|
||||
int port;
|
||||
if ( String::isNumber( *debugServerStr ) && String::fromString( port, *debugServerStr ) )
|
||||
return Connection( port, "localhost" );
|
||||
|
||||
auto split = String::split( *debugServerStr, ':' );
|
||||
if ( split.size() == 2 && String::fromString( port, split[1] ) )
|
||||
return Connection( port, split[1] );
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void DebuggerPlugin::prepareAndRun( DapTool debugger, DapConfig config,
|
||||
std::unordered_map<std::string, std::string> solvedInputs ) {
|
||||
int randomPort = Math::randi( 44000, 45000 );
|
||||
@@ -1889,7 +1921,13 @@ void DebuggerPlugin::prepareAndRun( DapTool debugger, DapConfig config,
|
||||
bool usesPorts = false;
|
||||
|
||||
for ( auto& arg : debugger.run.args ) {
|
||||
auto res( replaceKeyInString( arg, randomPort, solvedInputs ) );
|
||||
auto ret( replaceKeyInString( arg, randomPort, solvedInputs ) );
|
||||
|
||||
// No success? Abort
|
||||
if ( !ret.first )
|
||||
return;
|
||||
|
||||
auto res( ret.second );
|
||||
if ( res.size() == 1 && res[0] != arg ) {
|
||||
if ( String::contains( arg, KEY_RANDPORT ) )
|
||||
usesPorts = true;
|
||||
@@ -1901,18 +1939,19 @@ void DebuggerPlugin::prepareAndRun( DapTool debugger, DapConfig config,
|
||||
if ( cmdArg == KEY_FILE || cmdArg == KEY_ARGS || cmdArg == CMD_PICK_PROCESS ||
|
||||
cmdArg == CMD_PROMPT_STRING )
|
||||
forceUseProgram = true;
|
||||
auto args = replaceKeyInString( cmdArg, randomPort, solvedInputs );
|
||||
auto ret = replaceKeyInString( cmdArg, randomPort, solvedInputs );
|
||||
|
||||
// No success? Abort
|
||||
if ( !ret.first )
|
||||
return;
|
||||
|
||||
auto args = ret.second;
|
||||
for ( const auto& arg : args )
|
||||
debugger.run.args.emplace_back( arg );
|
||||
}
|
||||
|
||||
if ( protocolSettings.launchArgs.contains( KEY_DEBUG_SERVER ) &&
|
||||
( protocolSettings.launchArgs[KEY_DEBUG_SERVER].is_number_integer() ||
|
||||
( protocolSettings.launchArgs[KEY_DEBUG_SERVER].is_string() &&
|
||||
String::isNumber(
|
||||
protocolSettings.launchArgs[KEY_DEBUG_SERVER].get<std::string>() ) ) ) ) {
|
||||
if ( getDebugServer( protocolSettings.launchArgs ) )
|
||||
usesPorts = true;
|
||||
}
|
||||
|
||||
mThreadPool->run(
|
||||
[this, protocolSettings = std::move( protocolSettings ), randomPort,
|
||||
@@ -2087,22 +2126,18 @@ void DebuggerPlugin::run( const std::string& debugger, ProtocolSettings&& protoc
|
||||
for ( auto& arg : cmd.arguments )
|
||||
replaceExecutableArgs( arg );
|
||||
|
||||
int port = randPort;
|
||||
if ( protocolSettings.launchArgs.contains( KEY_DEBUG_SERVER ) &&
|
||||
( protocolSettings.launchArgs[KEY_DEBUG_SERVER].is_number_integer() ||
|
||||
( protocolSettings.launchArgs[KEY_DEBUG_SERVER].is_string() &&
|
||||
String::isNumber(
|
||||
protocolSettings.launchArgs[KEY_DEBUG_SERVER].get<std::string>() ) ) ) ) {
|
||||
Connection con;
|
||||
con.host = protocolSettings.launchArgs.value( "host", "localhost" );
|
||||
con.port = randPort;
|
||||
|
||||
auto debugServer = getDebugServer( protocolSettings.launchArgs );
|
||||
if ( debugServer ) {
|
||||
runsDapServer = true;
|
||||
if ( protocolSettings.launchArgs[KEY_DEBUG_SERVER].is_string() ) {
|
||||
String::fromString( port,
|
||||
protocolSettings.launchArgs[KEY_DEBUG_SERVER].get<std::string>() );
|
||||
} else if ( protocolSettings.launchArgs[KEY_DEBUG_SERVER].is_number_integer() ) {
|
||||
port = protocolSettings.launchArgs.value( KEY_DEBUG_SERVER, randPort );
|
||||
}
|
||||
con.host = debugServer->host;
|
||||
con.port = debugServer->port;
|
||||
} else if ( protocolSettings.launchArgs.contains( "port" ) &&
|
||||
protocolSettings.launchArgs["port"].is_number_integer() ) {
|
||||
port = protocolSettings.launchArgs.value( "port", randPort );
|
||||
con.port = protocolSettings.launchArgs.value( "port", randPort );
|
||||
}
|
||||
|
||||
std::string localRoot = mProjectPath;
|
||||
@@ -2110,9 +2145,6 @@ void DebuggerPlugin::run( const std::string& debugger, ProtocolSettings&& protoc
|
||||
|
||||
if ( protocolSettings.launchRequestType == REQUEST_TYPE_LAUNCH ) {
|
||||
if ( usesPorts ) {
|
||||
Connection con;
|
||||
con.host = protocolSettings.launchArgs.value( "host", "localhost" );
|
||||
con.port = port;
|
||||
auto bus = std::make_unique<BusSocketProcess>( cmd, con );
|
||||
mDebugger = std::make_unique<DebuggerClientDap>( protocolSettings, std::move( bus ) );
|
||||
} else {
|
||||
@@ -2124,9 +2156,6 @@ void DebuggerPlugin::run( const std::string& debugger, ProtocolSettings&& protoc
|
||||
if ( mode.empty() )
|
||||
mode = "local";
|
||||
|
||||
Connection con;
|
||||
con.host = protocolSettings.launchArgs.value( "host", "localhost" );
|
||||
con.port = port;
|
||||
bool useSocket = !con.host.empty() && con.port != 0;
|
||||
if ( ( protocolSettings.launchArgs.contains( "host" ) ||
|
||||
protocolSettings.launchArgs.contains( "port" ) ) &&
|
||||
|
||||
@@ -198,7 +198,7 @@ class DebuggerPlugin : public PluginBase {
|
||||
void replaceKeysInJson( nlohmann::json& json, int randomPort,
|
||||
const std::unordered_map<std::string, std::string>& solvedInputs );
|
||||
|
||||
std::vector<std::string>
|
||||
std::pair<bool, std::vector<std::string>>
|
||||
replaceKeyInString( std::string val, int randomPort,
|
||||
const std::unordered_map<std::string, std::string>& solvedInputs );
|
||||
|
||||
@@ -285,7 +285,7 @@ class DebuggerPlugin : public PluginBase {
|
||||
void onDocumentLineMove( TextDocument* doc, const Int64& fromLine, const Int64& toLine,
|
||||
const Int64& numLines );
|
||||
|
||||
void replaceInVal( std::string& val, const std::optional<ProjectBuildStep>& runConfig,
|
||||
bool replaceInVal( std::string& val, const std::optional<ProjectBuildStep>& runConfig,
|
||||
ProjectBuild* buildConfig, int randomPort );
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user