From 778263673cc65e22003e1ad1a93090b8bede67d0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 8 Sep 2023 08:53:06 -0400 Subject: [PATCH] add completion for variables and variable references --- tools/lammps-gui/codeeditor.cpp | 65 ++++++++++++++++++++++++++++++--- tools/lammps-gui/codeeditor.h | 4 +- tools/lammps-gui/lammpsgui.cpp | 1 + 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/tools/lammps-gui/codeeditor.cpp b/tools/lammps-gui/codeeditor.cpp index 9491a9af8a..f32cf4f632 100644 --- a/tools/lammps-gui/codeeditor.cpp +++ b/tools/lammps-gui/codeeditor.cpp @@ -129,7 +129,9 @@ CodeEditor::CodeEditor(QWidget *parent) : improper_comp(new QCompleter(this)), kspace_comp(new QCompleter(this)), region_comp(new QCompleter(this)), integrate_comp(new QCompleter(this)), minimize_comp(new QCompleter(this)), variable_comp(new QCompleter(this)), - units_comp(new QCompleter(this)), group_comp(new QCompleter(this)), highlight(NO_HIGHLIGHT) + units_comp(new QCompleter(this)), group_comp(new QCompleter(this)), + varname_comp(new QCompleter(this)), fixid_comp(new QCompleter(this)), + compid_comp(new QCompleter(this)), highlight(NO_HIGHLIGHT) { help_action = new QShortcut(QKeySequence::fromString("Ctrl+?"), parent); connect(help_action, &QShortcut::activated, this, &CodeEditor::get_help); @@ -161,6 +163,9 @@ CodeEditor::CodeEditor(QWidget *parent) : COMPLETER_SETUP(variable_comp); COMPLETER_SETUP(units_comp); COMPLETER_SETUP(group_comp); + COMPLETER_SETUP(varname_comp); + COMPLETER_SETUP(fixid_comp); + COMPLETER_SETUP(compid_comp); #undef COMPLETER_SETUP // initialize help system @@ -225,6 +230,9 @@ CodeEditor::~CodeEditor() delete variable_comp; delete units_comp; delete group_comp; + delete varname_comp; + delete fixid_comp; + delete compid_comp; } int CodeEditor::lineNumberAreaWidth() @@ -286,7 +294,8 @@ QString CodeEditor::reformatLine(const QString &line) int namesize = settings.value("name", "8").toInt(); settings.endGroup(); - bool rebuildGroupComp = false; + bool rebuildGroupComp = false; + bool rebuildVarNameComp = false; if (words.size()) { // commented line. do nothing @@ -299,6 +308,8 @@ QString CodeEditor::reformatLine(const QString &line) newtext += ' '; // new/updated group command -> update completer if (words[0] == "group") rebuildGroupComp = true; + // new/updated variable command -> update completer + if (words[0] == "variable") rebuildVarNameComp = true; } // append remaining words with just a single blank added. @@ -336,6 +347,7 @@ QString CodeEditor::reformatLine(const QString &line) } } if (rebuildGroupComp) setGroupList(); + if (rebuildVarNameComp) setVarNameList(); return newtext; } @@ -473,7 +485,7 @@ void CodeEditor::keyPressEvent(QKeyEvent *event) if (line[begin].isSpace()) break; --begin; } - if ((cursor.positionInBlock() - begin) > 2) runCompletion(); + if (((cursor.positionInBlock() - begin) > 2) || (line[begin+1] == '$')) runCompletion(); } } @@ -649,8 +661,26 @@ void CodeEditor::runCompletion() } const auto selected = line.mid(begin, end - begin); - // if on first word, try to complete command - if ((words.size() > 0) && (words[0] == selected.toStdString())) { + // variable expansion may be anywhere + if (selected.startsWith("$")) { + current_comp = varname_comp; + current_comp->setCompletionPrefix(selected); + auto popup = current_comp->popup(); + // if the command is already a complete command, remove existing popup + if (selected == current_comp->currentCompletion()) { + if (popup->isVisible()) { + popup->hide(); + current_comp = nullptr; + } + return; + } + QRect cr = cursorRect(); + cr.setWidth(popup->sizeHintForColumn(0) + popup->verticalScrollBar()->sizeHint().width()); + popup->setAlternatingRowColors(true); + current_comp->complete(cr); + + // if on first word, try to complete command + } else if ((words.size() > 0) && (words[0] == selected.toStdString())) { // no completion on comment lines if (words[0][0] == '#') return; @@ -699,6 +729,8 @@ void CodeEditor::runCompletion() else if ((words[0] == "change_box") || (words[0] == "displace_atoms") || (words[0] == "velocity") || (words[0] == "write_dump")) current_comp = group_comp; + else if (selected.startsWith("v_")) + current_comp = varname_comp; if (current_comp) { current_comp->setCompletionPrefix(words[1].c_str()); @@ -730,6 +762,8 @@ void CodeEditor::runCompletion() current_comp = group_comp; else if (words[0] == "dump") current_comp = group_comp; + else if (selected.startsWith("v_")) + current_comp = varname_comp; if (current_comp) { current_comp->setCompletionPrefix(words[2].c_str()); @@ -757,6 +791,27 @@ void CodeEditor::runCompletion() current_comp = compute_comp; else if (words[0] == "dump") current_comp = dump_comp; + else if (selected.startsWith("v_")) + current_comp = varname_comp; + + if (current_comp) { + current_comp->setCompletionPrefix(words[3].c_str()); + auto popup = current_comp->popup(); + // if the command is already a complete command, remove existing popup + if (words[3] == current_comp->currentCompletion().toStdString()) { + if (popup->isVisible()) popup->hide(); + return; + } + QRect cr = cursorRect(); + cr.setWidth(popup->sizeHintForColumn(0) + + popup->verticalScrollBar()->sizeHint().width()); + popup->setAlternatingRowColors(true); + current_comp->complete(cr); + } + // reference located anywhere further right in the line + } else if (words.size() > 3) { + current_comp = nullptr; + if (selected.startsWith("v_")) current_comp = varname_comp; if (current_comp) { current_comp->setCompletionPrefix(words[3].c_str()); diff --git a/tools/lammps-gui/codeeditor.h b/tools/lammps-gui/codeeditor.h index 5fe15b0b2c..10a1083ecf 100644 --- a/tools/lammps-gui/codeeditor.h +++ b/tools/lammps-gui/codeeditor.h @@ -57,6 +57,7 @@ public: void setVariableList(const QStringList &words); void setUnitsList(const QStringList &words); void setGroupList(); + void setVarNameList(); static constexpr int NO_HIGHLIGHT = 1 << 30; @@ -83,7 +84,8 @@ private: QShortcut *help_action; QCompleter *current_comp, *command_comp, *fix_comp, *compute_comp, *dump_comp, *atom_comp, *pair_comp, *bond_comp, *angle_comp, *dihedral_comp, *improper_comp, *kspace_comp, - *region_comp, *integrate_comp, *minimize_comp, *variable_comp, *units_comp, *group_comp; + *region_comp, *integrate_comp, *minimize_comp, *variable_comp, *units_comp, *group_comp, + *varname_comp, *fixid_comp, *compid_comp; int highlight; bool reformat_on_return; diff --git a/tools/lammps-gui/lammpsgui.cpp b/tools/lammps-gui/lammpsgui.cpp index 1f8e737be5..8fc28bab84 100644 --- a/tools/lammps-gui/lammpsgui.cpp +++ b/tools/lammps-gui/lammpsgui.cpp @@ -628,6 +628,7 @@ void LammpsGui::open_file(const QString &fileName) ui->textEdit->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor); ui->textEdit->document()->setModified(false); ui->textEdit->setGroupList(); + ui->textEdit->setVarNameList(); file.close(); dirstatus->setText(QString(" Directory: ") + current_dir); status->setText("Ready.");