implement automatic completion popup and reformat on return
This commit is contained in:
@ -3,6 +3,9 @@ LAMMPS-GUI TODO list:
|
|||||||
# Short term goals
|
# Short term goals
|
||||||
|
|
||||||
- add "syntax check" with enabled "-skiprun" flag
|
- 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
|
# Long term ideas
|
||||||
- rewrite entire application to build the App and its layout manually
|
- 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)
|
void CodeEditor::keyPressEvent(QKeyEvent *event)
|
||||||
{
|
{
|
||||||
|
const auto key = event->key();
|
||||||
if (command_completer && command_completer->popup()->isVisible()) {
|
if (command_completer && command_completer->popup()->isVisible()) {
|
||||||
// The following keys are forwarded by the completer to the widget
|
// The following keys are forwarded by the completer to the widget
|
||||||
switch (event->key()) {
|
switch (key) {
|
||||||
case Qt::Key_Enter:
|
case Qt::Key_Enter:
|
||||||
case Qt::Key_Return:
|
case Qt::Key_Return:
|
||||||
case Qt::Key_Escape:
|
case Qt::Key_Escape:
|
||||||
@ -304,15 +305,47 @@ void CodeEditor::keyPressEvent(QKeyEvent *event)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (event->key() == Qt::Key_Tab) {
|
|
||||||
|
// reformat current line and consume key event
|
||||||
|
if (key == Qt::Key_Tab) {
|
||||||
reformatCurrentLine();
|
reformatCurrentLine();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event->key() == Qt::Key_Backtab) {
|
|
||||||
|
// run command completion and consume key event
|
||||||
|
if (key == Qt::Key_Backtab) {
|
||||||
runCompletion();
|
runCompletion();
|
||||||
return;
|
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);
|
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 */)
|
void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
|
||||||
@ -475,7 +508,12 @@ void CodeEditor::runCompletion()
|
|||||||
|
|
||||||
command_completer->setCompletionPrefix(words[0].c_str());
|
command_completer->setCompletionPrefix(words[0].c_str());
|
||||||
auto popup = command_completer->popup();
|
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) +
|
cr.setWidth(popup->sizeHintForColumn(0) +
|
||||||
popup->verticalScrollBar()->sizeHint().width());
|
popup->verticalScrollBar()->sizeHint().width());
|
||||||
popup->setAlternatingRowColors(true);
|
popup->setAlternatingRowColors(true);
|
||||||
|
|||||||
@ -33,6 +33,8 @@ public:
|
|||||||
void setFont(const QFont &newfont);
|
void setFont(const QFont &newfont);
|
||||||
void setCursor(int block);
|
void setCursor(int block);
|
||||||
void setHighlight(int block, bool error);
|
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);
|
QString reformatLine(const QString &line);
|
||||||
void setCommandList(const QStringList &words);
|
void setCommandList(const QStringList &words);
|
||||||
|
|
||||||
@ -61,6 +63,8 @@ private:
|
|||||||
QShortcut *help_action;
|
QShortcut *help_action;
|
||||||
QCompleter *command_completer;
|
QCompleter *command_completer;
|
||||||
int highlight;
|
int highlight;
|
||||||
|
bool reformat_on_return;
|
||||||
|
bool automatic_completion;
|
||||||
|
|
||||||
QMap<QString, QString> cmd_map;
|
QMap<QString, QString> cmd_map;
|
||||||
QMap<QString, QString> fix_map;
|
QMap<QString, QString> fix_map;
|
||||||
|
|||||||
@ -317,6 +317,10 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) :
|
|||||||
}
|
}
|
||||||
command_list.sort();
|
command_list.sort();
|
||||||
ui->textEdit->setCommandList(command_list);
|
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()
|
LammpsGui::~LammpsGui()
|
||||||
@ -1256,6 +1260,10 @@ void LammpsGui::preferences()
|
|||||||
lammpsstatus->hide();
|
lammpsstatus->hide();
|
||||||
}
|
}
|
||||||
if (imagewindow) imagewindow->createImage();
|
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);
|
execl(path, arg0, (char *)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reformattting settings
|
// reformatting settings
|
||||||
|
|
||||||
settings->beginGroup("reformat");
|
settings->beginGroup("reformat");
|
||||||
auto spin = tabWidget->findChild<QSpinBox *>("cmdval");
|
auto spin = tabWidget->findChild<QSpinBox *>("cmdval");
|
||||||
@ -189,6 +189,10 @@ void Preferences::accept()
|
|||||||
if (spin) settings->setValue("id", spin->value());
|
if (spin) settings->setValue("id", spin->value());
|
||||||
spin = tabWidget->findChild<QSpinBox *>("nameval");
|
spin = tabWidget->findChild<QSpinBox *>("nameval");
|
||||||
if (spin) settings->setValue("name", spin->value());
|
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();
|
settings->endGroup();
|
||||||
|
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
@ -508,10 +512,14 @@ EditorTab::EditorTab(QSettings *_settings, QWidget *parent) : QWidget(parent), s
|
|||||||
auto *typelbl = new QLabel("Type width:");
|
auto *typelbl = new QLabel("Type width:");
|
||||||
auto *idlbl = new QLabel("ID width:");
|
auto *idlbl = new QLabel("ID width:");
|
||||||
auto *namelbl = new QLabel("Name 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 *cmdval = new QSpinBox;
|
||||||
auto *typeval = new QSpinBox;
|
auto *typeval = new QSpinBox;
|
||||||
auto *idval = new QSpinBox;
|
auto *idval = new QSpinBox;
|
||||||
auto *nameval = new QSpinBox;
|
auto *nameval = new QSpinBox;
|
||||||
|
auto *retval = new QCheckBox;
|
||||||
|
auto *autoval = new QCheckBox;
|
||||||
cmdval->setRange(1, 32);
|
cmdval->setRange(1, 32);
|
||||||
cmdval->setValue(settings->value("command", "16").toInt());
|
cmdval->setValue(settings->value("command", "16").toInt());
|
||||||
cmdval->setObjectName("cmdval");
|
cmdval->setObjectName("cmdval");
|
||||||
@ -524,6 +532,11 @@ EditorTab::EditorTab(QSettings *_settings, QWidget *parent) : QWidget(parent), s
|
|||||||
nameval->setRange(1, 32);
|
nameval->setRange(1, 32);
|
||||||
nameval->setValue(settings->value("name", "8").toInt());
|
nameval->setValue(settings->value("name", "8").toInt());
|
||||||
nameval->setObjectName("nameval");
|
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();
|
settings->endGroup();
|
||||||
|
|
||||||
int i = 0;
|
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(idval, i++, 1, Qt::AlignTop);
|
||||||
grid->addWidget(namelbl, i, 0, Qt::AlignTop);
|
grid->addWidget(namelbl, i, 0, Qt::AlignTop);
|
||||||
grid->addWidget(nameval, i++, 1, 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, 0);
|
||||||
grid->addItem(new QSpacerItem(100, 100, QSizePolicy::Minimum, QSizePolicy::Expanding), i, 1);
|
grid->addItem(new QSpacerItem(100, 100, QSizePolicy::Minimum, QSizePolicy::Expanding), i, 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user