diff --git a/plugins/builtin/include/content/views/view_pattern_editor.hpp b/plugins/builtin/include/content/views/view_pattern_editor.hpp index 9627d593d..05e2a0d44 100644 --- a/plugins/builtin/include/content/views/view_pattern_editor.hpp +++ b/plugins/builtin/include/content/views/view_pattern_editor.hpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -126,8 +127,8 @@ namespace hex::plugin::builtin { std::atomic m_dangerousFunctionCalled = false; std::atomic m_dangerousFunctionsAllowed = DangerousFunctionPerms::Ask; - bool m_suggestSupportedPatterns = true; - bool m_autoApplyPatterns = false; + ContentRegistry::Settings::SettingsVariable m_suggestSupportedPatterns = true; + ContentRegistry::Settings::SettingsVariable m_autoApplyPatterns = false; PerProvider m_visualizerDrawer; bool m_tooltipJustOpened = false; @@ -166,8 +167,7 @@ namespace hex::plugin::builtin { std::array m_accessHistory = {}; u32 m_accessHistoryIndex = 0; - bool m_parentHighlightingEnabled = true; - bool m_replaceMode = false; + ContentRegistry::Settings::SettingsVariable m_parentHighlightingEnabled = false; bool m_replaceMode = false; bool m_openFindReplacePopUp = false; bool m_openGotoLinePopUp = false; bool m_patternEvaluating = false; diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index d3b3aa6c2..436886a90 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -37,7 +37,10 @@ #include #include +#include + #include +#include #include #include #include @@ -320,7 +323,10 @@ namespace hex::plugin::builtin { registerHandlers(); // Initialize the text editor with some basic help text - m_textEditor.setOnCreateCallback([](auto, ui::TextEditor &editor) { + m_textEditor.setOnCreateCallback([this](auto *provider, ui::TextEditor &editor) { + if (m_sourceCode.isSynced() && !m_sourceCode.get(provider).empty()) + return; + std::string text = "hex.builtin.view.pattern_editor.default_help_text"_lang; text = "// " + wolv::util::replaceStrings(text, "\n", "\n// "); @@ -1861,14 +1867,6 @@ namespace hex::plugin::builtin { m_sourceCode.enableSync(value.get(false)); }); - ContentRegistry::Settings::onChange("hex.builtin.setting.general", "hex.builtin.setting.general.suggest_patterns", [this](const ContentRegistry::Settings::SettingsValue &value) { - m_suggestSupportedPatterns = value.get(true); - }); - - ContentRegistry::Settings::onChange("hex.builtin.setting.general", "hex.builtin.setting.general.auto_apply_patterns", [this](const ContentRegistry::Settings::SettingsValue &value) { - m_autoApplyPatterns = value.get(true); - }); - EventProviderOpened::subscribe(this, [this](prv::Provider *provider) { m_textEditor.get(provider).setLanguageDefinition(PatternLanguage()); m_textEditor.get(provider).setShowWhitespaces(false); @@ -2264,10 +2262,6 @@ namespace hex::plugin::builtin { } }); - ContentRegistry::Settings::onChange("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.pattern_parent_highlighting", [this](const ContentRegistry::Settings::SettingsValue &value) { - m_parentHighlightingEnabled = bool(value.get(false)); - }); - ImHexApi::HexEditor::addBackgroundHighlightingProvider([this](u64 address, const u8 *data, size_t size, bool) -> std::optional { std::ignore = data; std::ignore = size; @@ -2582,6 +2576,81 @@ namespace hex::plugin::builtin { return result; }); + + ContentRegistry::MCP::registerTool(romfs::get("mcp/tools/execute_pattern_code.json").string(), [this](const nlohmann::json &data) -> nlohmann::json { + auto provider = ImHexApi::Provider::get(); + + auto sourceCode = data.at("source_code").get(); + + this->evaluatePattern(sourceCode, provider); + + // Wait until evaluation has finished + while (m_runningEvaluators > 0) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock()); + + auto evaluationResult = m_lastEvaluationResult.load(); + + nlohmann::json result = { + { "handle", provider->getID() }, + { "result_code", evaluationResult } + }; + return mcp::StructuredContent { + .text = result.dump(), + .data = result + }; + }); + + ContentRegistry::MCP::registerTool(romfs::get("mcp/tools/get_pattern_console_content.json").string(), [this](const nlohmann::json &data) -> nlohmann::json { + std::ignore = data; + + auto provider = ImHexApi::Provider::get(); + + // Wait until evaluation has finished + while (m_runningEvaluators > 0) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock()); + + auto consoleOutput = m_console.get(provider); + + nlohmann::json result = { + { "handle", provider->getID() }, + { "content", wolv::util::combineStrings(consoleOutput, "\n") } + }; + return mcp::StructuredContent { + .text = result.dump(), + .data = result + }; + }); + + ContentRegistry::MCP::registerTool(romfs::get("mcp/tools/get_patterns.json").string(), [this](const nlohmann::json &data) -> nlohmann::json { + std::ignore = data; + + auto provider = ImHexApi::Provider::get(); + + // Wait until evaluation has finished + while (m_runningEvaluators > 0) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock()); + + pl::gen::fmt::FormatterJson formatter; + auto formattedPatterns = formatter.format(ContentRegistry::PatternLanguage::getRuntime()); + + nlohmann::json result = { + { "handle", provider->getID() }, + { "patterns", nlohmann::json::parse(std::string(formattedPatterns.begin(), formattedPatterns.end())) } + }; + return mcp::StructuredContent { + .text = result.dump(), + .data = result + }; + }); } void ViewPatternEditor::handleFileChange(prv::Provider *provider) {