implement automatic completion popup and reformat on return
This commit is contained in:
@ -3,6 +3,9 @@ LAMMPS-GUI TODO list:
|
||||
# Short term goals
|
||||
|
||||
- add "syntax check" with enabled "-skiprun" flag
|
||||
- implement "static" completion for fix/compute/styles/region etc...
|
||||
- implement "dynamic" completion for variable names, group names, molecule names, compute/dump/fix/region/group IDs
|
||||
- implement indenting regions for (nested) loops?
|
||||
|
||||
# Long term ideas
|
||||
- rewrite entire application to build the App and its layout manually
|
||||
|
||||
@ -290,9 +290,10 @@ void CodeEditor::setCommandList(const QStringList &words)
|
||||
|
||||
void CodeEditor::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
const auto key = event->key();
|
||||
if (command_completer && command_completer->popup()->isVisible()) {
|
||||
// The following keys are forwarded by the completer to the widget
|
||||
switch (event->key()) {
|
||||
switch (key) {
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Escape:
|
||||
@ -304,15 +305,47 @@ void CodeEditor::keyPressEvent(QKeyEvent *event)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (event->key() == Qt::Key_Tab) {
|
||||
|
||||
// reformat current line and consume key event
|
||||
if (key == Qt::Key_Tab) {
|
||||
reformatCurrentLine();
|
||||
return;
|
||||
}
|
||||
if (event->key() == Qt::Key_Backtab) {
|
||||
|
||||
// run command completion and consume key event
|
||||
if (key == Qt::Key_Backtab) {
|
||||
runCompletion();
|
||||
return;
|
||||
}
|
||||
|
||||
// automatically reformat when hitting the return or enter key
|
||||
if (reformat_on_return && (key == Qt::Key_Return) || (key == Qt::Key_Enter)) {
|
||||
reformatCurrentLine();
|
||||
}
|
||||
|
||||
// pass key event on to parent class
|
||||
QPlainTextEdit::keyPressEvent(event);
|
||||
|
||||
// pop up completion automatically after 3 characters
|
||||
if (automatic_completion) {
|
||||
auto cursor = textCursor();
|
||||
auto line = cursor.block().text().trimmed();
|
||||
if (!line.isEmpty()) {
|
||||
auto words = split_line(line.toStdString());
|
||||
cursor.select(QTextCursor::WordUnderCursor);
|
||||
auto word = cursor.selectedText().trimmed();
|
||||
if (command_completer) {
|
||||
if (words[0] == word.toStdString()) {
|
||||
if (word.length() > 2)
|
||||
runCompletion();
|
||||
else if (command_completer->popup()->isVisible())
|
||||
command_completer->popup()->hide();
|
||||
} else {
|
||||
if (command_completer->popup()->isVisible()) command_completer->popup()->hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
|
||||
@ -475,7 +508,12 @@ void CodeEditor::runCompletion()
|
||||
|
||||
command_completer->setCompletionPrefix(words[0].c_str());
|
||||
auto popup = command_completer->popup();
|
||||
QRect cr = cursorRect();
|
||||
// if the command is already a complete command, remove existing popup
|
||||
if (words[0] == command_completer->currentCompletion().toStdString()) {
|
||||
if (popup->isVisible()) popup->hide();
|
||||
return;
|
||||
}
|
||||
QRect cr = cursorRect();
|
||||
cr.setWidth(popup->sizeHintForColumn(0) +
|
||||
popup->verticalScrollBar()->sizeHint().width());
|
||||
popup->setAlternatingRowColors(true);
|
||||
|
||||
@ -33,6 +33,8 @@ public:
|
||||
void setFont(const QFont &newfont);
|
||||
void setCursor(int block);
|
||||
void setHighlight(int block, bool error);
|
||||
void setReformatOnReturn(bool flag) { reformat_on_return = flag; }
|
||||
void setAutoComplete(bool flag) { automatic_completion = flag; }
|
||||
QString reformatLine(const QString &line);
|
||||
void setCommandList(const QStringList &words);
|
||||
|
||||
@ -61,6 +63,8 @@ private:
|
||||
QShortcut *help_action;
|
||||
QCompleter *command_completer;
|
||||
int highlight;
|
||||
bool reformat_on_return;
|
||||
bool automatic_completion;
|
||||
|
||||
QMap<QString, QString> cmd_map;
|
||||
QMap<QString, QString> fix_map;
|
||||
|
||||
@ -317,6 +317,10 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) :
|
||||
}
|
||||
command_list.sort();
|
||||
ui->textEdit->setCommandList(command_list);
|
||||
settings.beginGroup("reformat");
|
||||
ui->textEdit->setReformatOnReturn(settings.value("return", true).toBool());
|
||||
ui->textEdit->setAutoComplete(settings.value("automatic", true).toBool());
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
LammpsGui::~LammpsGui()
|
||||
@ -1256,6 +1260,10 @@ void LammpsGui::preferences()
|
||||
lammpsstatus->hide();
|
||||
}
|
||||
if (imagewindow) imagewindow->createImage();
|
||||
settings.beginGroup("reformat");
|
||||
ui->textEdit->setReformatOnReturn(settings.value("return", true).toBool());
|
||||
ui->textEdit->setAutoComplete(settings.value("automatic", true).toBool());
|
||||
settings.endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -178,7 +178,7 @@ void Preferences::accept()
|
||||
execl(path, arg0, (char *)NULL);
|
||||
}
|
||||
|
||||
// reformattting settings
|
||||
// reformatting settings
|
||||
|
||||
settings->beginGroup("reformat");
|
||||
auto spin = tabWidget->findChild<QSpinBox *>("cmdval");
|
||||
@ -189,6 +189,10 @@ void Preferences::accept()
|
||||
if (spin) settings->setValue("id", spin->value());
|
||||
spin = tabWidget->findChild<QSpinBox *>("nameval");
|
||||
if (spin) settings->setValue("name", spin->value());
|
||||
box = tabWidget->findChild<QCheckBox *>("retval");
|
||||
if (box) settings->setValue("return", box->isChecked());
|
||||
box = tabWidget->findChild<QCheckBox *>("autoval");
|
||||
if (box) settings->setValue("automatic", box->isChecked());
|
||||
settings->endGroup();
|
||||
|
||||
QDialog::accept();
|
||||
@ -508,10 +512,14 @@ EditorTab::EditorTab(QSettings *_settings, QWidget *parent) : QWidget(parent), s
|
||||
auto *typelbl = new QLabel("Type width:");
|
||||
auto *idlbl = new QLabel("ID width:");
|
||||
auto *namelbl = new QLabel("Name width:");
|
||||
auto *retlbl = new QLabel("Reformat with 'Return':");
|
||||
auto *autolbl = new QLabel("Automatic completion:");
|
||||
auto *cmdval = new QSpinBox;
|
||||
auto *typeval = new QSpinBox;
|
||||
auto *idval = new QSpinBox;
|
||||
auto *nameval = new QSpinBox;
|
||||
auto *retval = new QCheckBox;
|
||||
auto *autoval = new QCheckBox;
|
||||
cmdval->setRange(1, 32);
|
||||
cmdval->setValue(settings->value("command", "16").toInt());
|
||||
cmdval->setObjectName("cmdval");
|
||||
@ -524,6 +532,11 @@ EditorTab::EditorTab(QSettings *_settings, QWidget *parent) : QWidget(parent), s
|
||||
nameval->setRange(1, 32);
|
||||
nameval->setValue(settings->value("name", "8").toInt());
|
||||
nameval->setObjectName("nameval");
|
||||
retval->setCheckState(settings->value("return", true).toBool() ? Qt::Checked : Qt::Unchecked);
|
||||
retval->setObjectName("retval");
|
||||
autoval->setCheckState(settings->value("automatic", true).toBool() ? Qt::Checked
|
||||
: Qt::Unchecked);
|
||||
autoval->setObjectName("autoval");
|
||||
settings->endGroup();
|
||||
|
||||
int i = 0;
|
||||
@ -536,6 +549,10 @@ EditorTab::EditorTab(QSettings *_settings, QWidget *parent) : QWidget(parent), s
|
||||
grid->addWidget(idval, i++, 1, Qt::AlignTop);
|
||||
grid->addWidget(namelbl, i, 0, Qt::AlignTop);
|
||||
grid->addWidget(nameval, i++, 1, Qt::AlignTop);
|
||||
grid->addWidget(retlbl, i, 0, Qt::AlignTop);
|
||||
grid->addWidget(retval, i++, 1, Qt::AlignVCenter);
|
||||
grid->addWidget(autolbl, i, 0, Qt::AlignTop);
|
||||
grid->addWidget(autoval, i++, 1, Qt::AlignVCenter);
|
||||
|
||||
grid->addItem(new QSpacerItem(100, 100, QSizePolicy::Minimum, QSizePolicy::Expanding), i, 0);
|
||||
grid->addItem(new QSpacerItem(100, 100, QSizePolicy::Minimum, QSizePolicy::Expanding), i, 1);
|
||||
|
||||
Reference in New Issue
Block a user