Skip to content

Commit 55eba78

Browse files
Sightemadriweb
authored andcommitted
Add equate autocomplete to disassembly view's goto dialog
1 parent 257b6a4 commit 55eba78

5 files changed

Lines changed: 78 additions & 7 deletions

File tree

gui/qt/debugger.cpp

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include <QtWidgets/QToolTip>
2828
#include <QtCore/QFileInfo>
29+
#include <QtCore/QStringList>
2930
#include <QtCore/QRegularExpression>
3031
#include <QtWidgets/QMessageBox>
3132
#include <QtWidgets/QInputDialog>
@@ -41,6 +42,7 @@
4142
#include <QtGui/QScreen>
4243
#include <algorithm>
4344
#include <array>
45+
#include <ranges>
4446

4547
#ifdef _MSC_VER
4648
#include <direct.h>
@@ -222,6 +224,7 @@ void MainWindow::debugImportFile(const QString &file) {
222224

223225
disasm.map.clear();
224226
disasm.reverse.clear();
227+
markDisasmGotoCompletionsDirty();
225228
for (QString &equFile : m_equateFiles) {
226229
equatesAddFile(equFile);
227230
}
@@ -1887,6 +1890,7 @@ void MainWindow::updateLabels() {
18871890
void MainWindow::equatesRefresh() {
18881891
disasm.map.clear();
18891892
disasm.reverse.clear();
1893+
markDisasmGotoCompletionsDirty();
18901894
for (QString &file : m_equateFiles) {
18911895
equatesAddFile(file);
18921896
}
@@ -1984,11 +1988,14 @@ void MainWindow::equatesAddEquate(const QString &name, uint32_t address) {
19841988
if (!equatesAddEquateInternal(name, address)) {
19851989
return;
19861990
}
1991+
markDisasmGotoCompletionsDirty();
19871992
uint8_t *ptr = static_cast<uint8_t *>(phys_mem_ptr(address - 4, 9));
19881993
if (ptr && ptr[4] == 0xC3 && (ptr[0] == 0xC3 || ptr[8] == 0xC3)) { // jump table?
19891994
uint32_t address2 = ptr[5] | ptr[6] << 8 | ptr[7] << 16;
19901995
if (phys_mem_ptr(address2, 1)) {
1991-
equatesAddEquateInternal(QStringLiteral("_") + name, address2);
1996+
if (equatesAddEquateInternal(QStringLiteral("_") + name, address2)) {
1997+
markDisasmGotoCompletionsDirty();
1998+
}
19921999
}
19932000
}
19942001
}
@@ -2148,14 +2155,15 @@ void MainWindow::gotoPressed() {
21482155
m_gotoAddr = m_disasm->getSelectedAddr();
21492156
}
21502157

2151-
GotoDialog dlg(m_gotoAddr, m_disasmGotoHistory, this);
2158+
GotoDialog dlg(m_gotoAddr, m_disasmGotoHistory, disasmGotoCompletions(), this);
21522159
if (dlg.exec() == QDialog::Accepted) {
21532160
QString typed = dlg.text().trimmed();
21542161
bool ok = false;
21552162
QString resolved = resolveAddressOrEquate(typed, &ok);
21562163
if (ok) {
21572164
m_gotoAddr = typed;
2158-
disasmUpdateAddr(hex2int(resolved), false);
2165+
// changes are routed through here to make sure history is updated for fwd and back
2166+
gotoDisasmAddr(static_cast<uint32_t>(hex2int(resolved)));
21592167

21602168
auto &hist = m_disasmGotoHistory;
21612169
std::erase_if(hist, [&](const QString &s){ return s.compare(typed, Qt::CaseInsensitive) == 0; });
@@ -2226,6 +2234,43 @@ QAction *MainWindow::gotoMemAction(QMenu *menu, bool vat) const {
22262234
return gotoMem;
22272235
}
22282236

2237+
const QStringList &MainWindow::disasmGotoCompletions() {
2238+
if (!m_disasmGotoCompletionsDirty) {
2239+
return m_disasmGotoCompletions;
2240+
}
2241+
2242+
m_disasmGotoCompletionsDirty = false;
2243+
2244+
QStringList completions;
2245+
static constexpr std::array kRegisterAliases = {
2246+
"AF"_L1, "HL"_L1, "DE"_L1, "BC"_L1, "IX"_L1, "IY"_L1,
2247+
"AF'"_L1, "HL'"_L1, "DE'"_L1, "BC'"_L1, "SPL"_L1, "SPS"_L1, "PC"_L1
2248+
};
2249+
2250+
completions.reserve(static_cast<int>(disasm.reverse.size() + kRegisterAliases.size()));
2251+
2252+
for (const auto &name : disasm.reverse | std::views::keys) {
2253+
completions.append(QString::fromStdString(name));
2254+
}
2255+
2256+
for (const auto alias : kRegisterAliases) {
2257+
if (!completions.contains(alias)) {
2258+
completions.append(QString(alias));
2259+
}
2260+
}
2261+
2262+
std::ranges::sort(completions, [](const QString &lhs, const QString &rhs) {
2263+
return lhs.localeAwareCompare(rhs) < 0;
2264+
});
2265+
2266+
m_disasmGotoCompletions = std::move(completions);
2267+
return m_disasmGotoCompletions;
2268+
}
2269+
2270+
void MainWindow::markDisasmGotoCompletionsDirty() {
2271+
m_disasmGotoCompletionsDirty = true;
2272+
}
2273+
22292274
void MainWindow::handleCtrlClickText(QPlainTextEdit *edit) {
22302275
if (QApplication::keyboardModifiers().testFlag(Qt::ControlModifier)) {
22312276
bool ok = true;
@@ -2352,7 +2397,7 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *e) {
23522397
return true;
23532398
}
23542399
}
2355-
2400+
23562401
// Mouse back/forward in Disassembly view
23572402
if (obj == m_disasm && e->type() == QEvent::MouseButtonPress) {
23582403
auto *me = static_cast<QMouseEvent*>(e);

gui/qt/gotodialog.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
#include "gotodialog.h"
22

33
#include <QtWidgets/QComboBox>
4+
#include <QtWidgets/QCompleter>
45
#include <QtWidgets/QDialogButtonBox>
56
#include <QtWidgets/QLabel>
67
#include <QtWidgets/QVBoxLayout>
78
#include <QtWidgets/QSizePolicy>
9+
#include <QtWidgets/QLineEdit>
10+
#include <QtCore/Qt>
811

912
GotoDialog::GotoDialog(const QString &seed,
1013
const std::vector<QString> &history,
14+
const QStringList &completions,
1115
QWidget *parent)
1216
: QDialog(parent) {
1317
setWindowTitle(tr("Goto"));
@@ -18,6 +22,19 @@ GotoDialog::GotoDialog(const QString &seed,
1822

1923
m_combo = new QComboBox(this); // NOLINT: Qt parent-ownership handles deletion
2024
m_combo->setEditable(true);
25+
m_combo->setInsertPolicy(QComboBox::NoInsert);
26+
27+
if (!completions.isEmpty()) {
28+
auto *completer = new QCompleter(completions, m_combo); // NOLINT: Qt parent-ownership handles deletion
29+
completer->setCaseSensitivity(Qt::CaseInsensitive);
30+
completer->setFilterMode(Qt::MatchContains);
31+
completer->setCompletionMode(QCompleter::PopupCompletion);
32+
if (auto *lineEdit = m_combo->lineEdit()) {
33+
lineEdit->setCompleter(completer);
34+
} else {
35+
m_combo->setCompleter(completer);
36+
}
37+
}
2138

2239
for (const QString &h : history) {
2340
m_combo->addItem(h);

gui/qt/gotodialog.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <QtWidgets/QDialog>
55
#include <QtCore/QString>
6+
#include <QtCore/QStringList>
67
#include <vector>
78

89
QT_BEGIN_NAMESPACE
@@ -14,6 +15,7 @@ class GotoDialog : public QDialog {
1415
public:
1516
explicit GotoDialog(const QString &seed,
1617
const std::vector<QString> &history,
18+
const QStringList &completions = {},
1719
QWidget *parent = nullptr);
1820

1921
[[nodiscard]] QString text() const;

gui/qt/mainwindow.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <QtWidgets/QTableWidgetItem>
2424
#include <QtWidgets/QPlainTextEdit>
2525
#include <QtWidgets/QFileDialog>
26+
#include <QtCore/QStringList>
2627
#include <QtCore/QSettings>
2728
#include <QtCore/QThread>
2829
#include <QtCore/QTimer>
@@ -366,6 +367,8 @@ private slots:
366367
void gotoMemAddr(uint32_t addr);
367368
HexWidget *gotoMemAddrNoRaise(uint32_t addr);
368369
QAction *gotoMemAction(QMenu *menu, bool vat = false) const;
370+
const QStringList &disasmGotoCompletions();
371+
void markDisasmGotoCompletionsDirty();
369372

370373
void handleCtrlClickText(QPlainTextEdit *edit);
371374
void handleCtrlClickLine(QLineEdit *edit);
@@ -736,6 +739,9 @@ private slots:
736739

737740
std::vector<QString> m_memGotoHistory;
738741

742+
QStringList m_disasmGotoCompletions;
743+
bool m_disasmGotoCompletionsDirty = true;
744+
739745
QString m_pathConfig;
740746
QMenu *m_menuDocks;
741747
QMenu *m_menuDebug;

gui/qt/memorywidget.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <QtGui/QClipboard>
1212
#include <QtCore/QFileInfo>
1313
#include <QtCore/QRegularExpression>
14+
#include <QtCore/QStringList>
1415
#include <QtWidgets/QMessageBox>
1516
#include <QtWidgets/QInputDialog>
1617
#include <algorithm>
@@ -107,7 +108,7 @@ void MainWindow::memUpdateEdit(HexWidget *edit, bool force) {
107108
}
108109

109110
void MainWindow::flashGotoPressed() {
110-
if (GotoDialog dlg(m_flashGotoAddr, m_memGotoHistory, this); dlg.exec() == QDialog::Accepted) {
111+
if (GotoDialog dlg(m_flashGotoAddr, m_memGotoHistory, QStringList(), this); dlg.exec() == QDialog::Accepted) {
111112
const QString typed = dlg.text().trimmed();
112113
bool ok = false;
113114
const QString resolved = resolveAddressOrEquate(typed, &ok);
@@ -127,7 +128,7 @@ void MainWindow::flashGotoPressed() {
127128
}
128129

129130
void MainWindow::ramGotoPressed() {
130-
GotoDialog dlg(m_RamGotoAddr, m_memGotoHistory, this);
131+
GotoDialog dlg(m_RamGotoAddr, m_memGotoHistory, QStringList(), this);
131132
if (dlg.exec() == QDialog::Accepted) {
132133
const QString typed = dlg.text().trimmed();
133134
bool ok = false;
@@ -216,7 +217,7 @@ void MainWindow::memGotoEdit(HexWidget *edit) {
216217
return;
217218
}
218219

219-
GotoDialog dlg(m_memGotoAddr, m_memGotoHistory, this);
220+
GotoDialog dlg(m_memGotoAddr, m_memGotoHistory, QStringList(), this);
220221
if (dlg.exec() == QDialog::Accepted) {
221222
QString typed = dlg.text().trimmed();
222223
bool ok = false;

0 commit comments

Comments
 (0)