fix: find next and find previous not working on console. (#2358)

With only one menu entry and having set it to use the text editor then
the console losses that functionality. Since both the console and the
text editor are on the same view, it follows that they must share the
menu entries. In some cases it is necessary to determine which of the
two editors needs to be processed inside the menu entry itself.

Also an error that caused the creation of invalid coordinates when
console is still empty was fixed by setting coordinates to 0,0 for empty
files. Another problem was that left clicking on the console didn't
select the word under the cursor but it does when left clicking on the
text editor. Now it works in both.

The menu entries on the console were removed completely and swapped with
a call to obtain the default 'edit' menu for the context popup. Also,
the console in write-only, so some of the entries like `Paste` or
`Replace` must be greyed out.

This PR is only to fix the bugs that exist currently. More work is still
needed for:
1) Removing the remaining shortcuts and creating new menu entries for
them and
2) Adding support for `Open` and `Save` in the pattern editor with path
tracking.

I tested all combinations of menus and shorcuts with console and pattern
editor and there were no problems I could detect.
This commit is contained in:
paxcut 2025-07-26 21:41:43 -07:00 committed by GitHub
parent 3d3674d405
commit 7ff1e72093
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 54 additions and 61 deletions

View File

@ -150,12 +150,8 @@ std::string TextEditor::GetText(const Coordinates &aStart, const Coordinates &aE
} }
TextEditor::Coordinates TextEditor::SetCoordinates(int aLine, int aColumn) const { TextEditor::Coordinates TextEditor::SetCoordinates(int aLine, int aColumn) const {
if (isEmpty()) { if (isEmpty())
if ((aLine == 0 || aLine == -1) && (aColumn == 0 || aColumn == -1)) return Coordinates(0, 0);
return Coordinates(0, 0);
else
return Invalid;
}
Coordinates result = Coordinates(0, 0); Coordinates result = Coordinates(0, 0);
auto lineCount = (int)mLines.size(); auto lineCount = (int)mLines.size();

View File

@ -989,41 +989,13 @@ namespace hex::plugin::builtin {
void ViewPatternEditor::drawConsole(ImVec2 size) { void ViewPatternEditor::drawConsole(ImVec2 size) {
auto provider = ImHexApi::Provider::get(); auto provider = ImHexApi::Provider::get();
auto findReplaceHandler = m_consoleEditor.get(provider).GetFindReplaceHandler();
if (m_consoleEditor.get(provider).RaiseContextMenu()) { if (m_consoleEditor.get(provider).RaiseContextMenu()) {
ImGui::OpenPopup("##console_context_menu"); RequestOpenPopup::post("hex.builtin.menu.edit");
m_consoleEditor.get(provider).ClearRaiseContextMenu(); m_consoleEditor.get(provider).ClearRaiseContextMenu();
} }
if (!m_consoleEditor.get(provider).HasSelection())
const bool hasSelection = m_consoleEditor.get(provider).HasSelection(); m_consoleEditor.get(provider).SelectWordUnderCursor();
if (ImGui::BeginPopup("##console_context_menu")) {
if (ImGui::MenuItemEx("hex.builtin.view.hex_editor.menu.edit.copy"_lang, ICON_VS_COPY, Shortcut(CTRLCMD + Keys::C).toString().c_str(), false, hasSelection)) {
m_consoleEditor.get(provider).Copy();
}
if (ImGui::MenuItemEx("hex.builtin.view.hex_editor.menu.edit.select_all"_lang, ICON_VS_LIST_FLAT, Shortcut(CTRLCMD + Keys::A).toString().c_str())) {
m_consoleEditor.get(provider).SelectAll();
}
ImGui::Separator();
// Search and replace entries
if (ImGui::MenuItemEx("hex.builtin.view.pattern_editor.menu.find"_lang, ICON_VS_SEARCH, Shortcut(CTRLCMD + Keys::F).toString().c_str())) {
m_openFindReplacePopUp = true;
m_replaceMode = false;
}
if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.find_next"_lang, Shortcut(Keys::F3).toString().c_str(),false,!findReplaceHandler->GetFindWord().empty()))
findReplaceHandler->FindMatch(&m_consoleEditor.get(provider),true);
if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.find_previous"_lang, Shortcut(SHIFT + Keys::F3).toString().c_str(),false,!findReplaceHandler->GetFindWord().empty()))
findReplaceHandler->FindMatch(&m_consoleEditor.get(provider),false);
ImGui::Separator();
if (ImGui::MenuItemEx("hex.builtin.view.pattern_editor.menu.goto_line"_lang, ICON_VS_DEBUG_STEP_INTO, Shortcut(ALT + Keys::G).toString().c_str()))
m_openGotoLinePopUp = true;
ImGui::EndPopup();
}
if (m_consoleCursorNeedsUpdate.get(provider)) { if (m_consoleCursorNeedsUpdate.get(provider)) {
m_consoleEditor.get(provider).SetFocusAtCoords(m_consoleCursorPosition.get(provider)); m_consoleEditor.get(provider).SetFocusAtCoords(m_consoleCursorPosition.get(provider));
@ -2012,23 +1984,17 @@ namespace hex::plugin::builtin {
} }
void ViewPatternEditor::registerMenuItems() { void ViewPatternEditor::registerMenuItems() {
/*if (ImGui::MenuItemEx("hex.builtin.menu.file.import.pattern_file"_lang, ICON_VS_SIGN_IN, nullptr, false))
m_importPatternFile();
if (ImGui::MenuItemEx("hex.builtin.menu.file.export.pattern_file"_lang, ICON_VS_SIGN_OUT, nullptr, false))
m_exportPatternFile();
ImGui::Separator();*/
/* Undo */ /* Undo */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.pattern_editor.menu.edit.undo" }, ICON_VS_DISCARD, 1000, AllowWhileTyping + CTRLCMD + Keys::Z, [this] { ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.pattern_editor.menu.edit.undo" }, ICON_VS_DISCARD, 1000, AllowWhileTyping + CTRLCMD + Keys::Z, [this] {
m_textEditor->Undo(); m_textEditor->Undo();
}, [this] { return ImHexApi::Provider::isValid() && m_textEditor->CanUndo(); }, }, [this] { return ImHexApi::Provider::isValid() && m_textEditor->CanUndo() && m_focusedSubWindowName.contains(textEditorView); },
this); this);
/* Redo */ /* Redo */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.pattern_editor.menu.edit.redo" }, ICON_VS_REDO, 1100, AllowWhileTyping + CTRLCMD + Keys::Y, [this] { ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.pattern_editor.menu.edit.redo" }, ICON_VS_REDO, 1100, AllowWhileTyping + CTRLCMD + Keys::Y, [this] {
m_textEditor->Redo(); m_textEditor->Redo();
}, [this] { return ImHexApi::Provider::isValid() &&m_textEditor->CanRedo(); }, }, [this] { return ImHexApi::Provider::isValid() &&m_textEditor->CanRedo() && m_focusedSubWindowName.contains(textEditorView); },
this); this);
ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.edit" }, 1200, this); ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.edit" }, 1200, this);
@ -2037,19 +2003,28 @@ namespace hex::plugin::builtin {
/* Cut */ /* Cut */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.hex_editor.menu.edit.cut" }, ICON_VS_COMBINE, 1300, AllowWhileTyping + CTRLCMD + Keys::X, [this] { ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.hex_editor.menu.edit.cut" }, ICON_VS_COMBINE, 1300, AllowWhileTyping + CTRLCMD + Keys::X, [this] {
m_textEditor->Cut(); m_textEditor->Cut();
}, [this] { return ImHexApi::Provider::isValid() &&m_textEditor->HasSelection(); }, }, [this] { return ImHexApi::Provider::isValid() &&m_textEditor->HasSelection() && m_focusedSubWindowName.contains(textEditorView); },
this); this);
/* Copy */ /* Copy */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.hex_editor.menu.edit.copy" }, ICON_VS_COPY, 1400, AllowWhileTyping + CTRLCMD + Keys::C, [this] { ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.hex_editor.menu.edit.copy" }, ICON_VS_COPY, 1400, AllowWhileTyping + CTRLCMD + Keys::C, [this] {
m_textEditor->Copy(); if (auto editor = getEditorFromFocusedWindow(); editor != nullptr) {
}, [this] { return ImHexApi::Provider::isValid() &&m_textEditor->HasSelection(); }, editor->Copy();
} else {
m_textEditor->Copy();
}
}, [this] {
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
return ImHexApi::Provider::isValid() && editor->HasSelection();
else
return false;
},
this); this);
/* Paste */ /* Paste */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.hex_editor.menu.edit.paste" }, ICON_VS_OUTPUT, 1500, AllowWhileTyping + CTRLCMD + Keys::V, [this] { ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.hex_editor.menu.edit.paste" }, ICON_VS_OUTPUT, 1500, AllowWhileTyping + CTRLCMD + Keys::V, [this] {
m_textEditor->Paste(); m_textEditor->Paste();
}, [] { return true; }, }, [this] { return m_focusedSubWindowName.contains(textEditorView); },
this); this);
/* Find */ /* Find */
@ -2061,15 +2036,37 @@ namespace hex::plugin::builtin {
/* Find Next */ /* Find Next */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.view.pattern_editor.menu.find_next" }, 1800, AllowWhileTyping + Keys::F3, [this] { ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.view.pattern_editor.menu.find_next" }, 1800, AllowWhileTyping + Keys::F3, [this] {
m_consoleEditor->GetFindReplaceHandler()->FindMatch(&*m_textEditor, true); if (auto editor = getEditorFromFocusedWindow(); editor != nullptr) {
}, [this] { return ImHexApi::Provider::isValid() && !m_textEditor->GetFindReplaceHandler()->GetFindWord().empty(); }, TextEditor::FindReplaceHandler *findReplaceHandler = editor->GetFindReplaceHandler();
findReplaceHandler->FindMatch(editor, true);
} else {
m_textEditor->GetFindReplaceHandler()->FindMatch(&*m_textEditor, true);
}
}, [this] {
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr) {
return ImHexApi::Provider::isValid() && !editor->GetFindReplaceHandler()->GetFindWord().empty();
} else {
return false;
}
},
[]{ return false; }, []{ return false; },
this); this);
/* Find Previous */ /* Find Previous */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.view.pattern_editor.menu.find_previous" }, 1900, AllowWhileTyping + SHIFT + Keys::F3, [this] { ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.view.pattern_editor.menu.find_previous" }, 1900, AllowWhileTyping + SHIFT + Keys::F3, [this] {
m_consoleEditor->GetFindReplaceHandler()->FindMatch(&*m_textEditor, true); if (auto editor = getEditorFromFocusedWindow(); editor != nullptr) {
}, [this] { return ImHexApi::Provider::isValid() && !m_textEditor->GetFindReplaceHandler()->GetFindWord().empty(); }, TextEditor::FindReplaceHandler *findReplaceHandler = editor->GetFindReplaceHandler();
findReplaceHandler->FindMatch(editor, false);
} else {
m_textEditor->GetFindReplaceHandler()->FindMatch(&*m_textEditor, false);
}
}, [this] {
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr) {
return ImHexApi::Provider::isValid() && !m_textEditor->GetFindReplaceHandler()->GetFindWord().empty();
} else {
return false;
}
},
[]{ return false; }, []{ return false; },
this); this);
@ -2077,27 +2074,27 @@ namespace hex::plugin::builtin {
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.view.pattern_editor.menu.replace" }, ICON_VS_REPLACE, 2000, AllowWhileTyping + CTRLCMD + Keys::H, [this] { ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.view.pattern_editor.menu.replace" }, ICON_VS_REPLACE, 2000, AllowWhileTyping + CTRLCMD + Keys::H, [this] {
m_replaceMode = true; m_replaceMode = true;
m_openFindReplacePopUp = true; m_openFindReplacePopUp = true;
}, [] { return true; }, }, [this] { return m_focusedSubWindowName.contains(textEditorView); },
this); this);
/* Replace Next */ /* Replace Next */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.view.pattern_editor.menu.replace_next" }, 2100, Shortcut::None, [this] { ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.view.pattern_editor.menu.replace_next" }, 2100, Shortcut::None, [this] {
m_consoleEditor->GetFindReplaceHandler()->Replace(&*m_textEditor, true); m_textEditor->GetFindReplaceHandler()->Replace(&*m_textEditor, true);
}, [this] { return ImHexApi::Provider::isValid() && !m_textEditor->GetFindReplaceHandler()->GetReplaceWord().empty(); }, }, [this] { return ImHexApi::Provider::isValid() && !m_textEditor->GetFindReplaceHandler()->GetReplaceWord().empty() && m_focusedSubWindowName.contains(textEditorView); },
[]{ return false; }, []{ return false; },
this); this);
/* Replace Previous */ /* Replace Previous */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.view.pattern_editor.menu.replace_previous" }, 2200, Shortcut::None, [this] { ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.view.pattern_editor.menu.replace_previous" }, 2200, Shortcut::None, [this] {
m_consoleEditor->GetFindReplaceHandler()->Replace(&*m_textEditor, false); m_textEditor->GetFindReplaceHandler()->Replace(&*m_textEditor, false);
}, [this] { return ImHexApi::Provider::isValid() && !m_textEditor->GetFindReplaceHandler()->GetReplaceWord().empty(); }, }, [this] { return ImHexApi::Provider::isValid() && !m_textEditor->GetFindReplaceHandler()->GetReplaceWord().empty() && m_focusedSubWindowName.contains(textEditorView); },
[]{ return false; }, []{ return false; },
this); this);
/* Replace All */ /* Replace All */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.view.pattern_editor.menu.replace_all" }, ICON_VS_REPLACE_ALL, 2300, Shortcut::None, [this] { ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.view.pattern_editor.menu.replace_all" }, ICON_VS_REPLACE_ALL, 2300, Shortcut::None, [this] {
m_consoleEditor->GetFindReplaceHandler()->ReplaceAll(&*m_textEditor); m_textEditor->GetFindReplaceHandler()->ReplaceAll(&*m_textEditor);
}, [this] { return ImHexApi::Provider::isValid() && !m_textEditor->GetFindReplaceHandler()->GetReplaceWord().empty(); }, }, [this] { return ImHexApi::Provider::isValid() && !m_textEditor->GetFindReplaceHandler()->GetReplaceWord().empty() && m_focusedSubWindowName.contains(textEditorView); },
this); this);
ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.file" }, 2400, this); ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.file" }, 2400, this);