Merge pull request #343 from BigBahss/script-editing

Add completion suggestions for global event scripts
This commit is contained in:
garak 2021-05-03 15:03:03 -04:00 committed by GitHub
commit d1be0d5a58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 95 additions and 8 deletions

View file

@ -60,6 +60,9 @@ public:
static int getScriptLineNumber(const QString &filePath, const QString &scriptLabel);
static int getRawScriptLineNumber(QString text, const QString &scriptLabel);
static int getPoryScriptLineNumber(QString text, const QString &scriptLabel);
static QStringList getGlobalScriptLabels(const QString &filePath);
static QStringList getGlobalRawScriptLabels(QString text);
static QStringList getGlobalPoryScriptLabels(QString text);
static QString removeStringLiterals(QString text);
static QString removeLineComments(QString text, const QString &commentSymbol);
static QString removeLineComments(QString text, const QStringList &commentSymbols);
@ -74,6 +77,12 @@ private:
QList<Token> generatePostfix(const QList<Token> &tokens);
int evaluatePostfix(const QList<Token> &postfix);
void error(const QString &message, const QString &expression);
static const QRegularExpression re_incScriptLabel;
static const QRegularExpression re_globalIncScriptLabel;
static const QRegularExpression re_poryScriptLabel;
static const QRegularExpression re_globalPoryScriptLabel;
static const QRegularExpression re_poryRawSection;
};
#endif // PARSEUTIL_H

View file

@ -62,6 +62,7 @@ public:
QStringList secretBaseIds;
QStringList bgEventFacingDirections;
QStringList trainerTypes;
QStringList globalScriptLabels;
QMap<QString, int> metatileBehaviorMap;
QMap<int, QString> metatileBehaviorMapInverse;
QMap<QString, QString> facingDirections;
@ -168,6 +169,7 @@ public:
bool readMetatileBehaviors();
bool readHealLocations();
bool readMiscellaneousConstants();
bool readEventScriptLabels();
void loadEventPixmaps(QList<Event*> objects);
QMap<QString, int> getEventObjGfxConstants();
@ -178,6 +180,7 @@ public:
QString getScriptDefaultString(bool usePoryScript, QString mapName) const;
QString getMapScriptsFilePath(const QString &mapName) const;
QStringList getEventScriptsFilePaths() const;
QCompleter *getEventScriptLabelCompleter(QStringList additionalScriptLabels);
bool loadMapBorder(Map *map);
@ -220,6 +223,9 @@ private:
static int default_map_size;
static int max_object_events;
QStringListModel eventScriptLabelModel;
QCompleter eventScriptLabelCompleter;
signals:
void reloadProject();
void uncheckMonitorFilesAction();

View file

@ -427,8 +427,8 @@ QStringList Map::eventScriptLabels(const QString &event_group_type) const {
scriptLabels << event->get("script_label");
}
scriptLabels.removeAll("");
scriptLabels.removeDuplicates();
scriptLabels.removeAll(QString());
if (scriptLabels.contains("0x0"))
scriptLabels.move(scriptLabels.indexOf("0x0"), scriptLabels.count() - 1);
if (scriptLabels.contains("NULL"))

View file

@ -6,6 +6,11 @@
#include <QJsonObject>
#include <QStack>
const QRegularExpression ParseUtil::re_incScriptLabel("\\b(?<label>[\\w_][\\w\\d_]*):{1,2}");
const QRegularExpression ParseUtil::re_globalIncScriptLabel("\\b(?<label>[\\w_][\\w\\d_]*)::");
const QRegularExpression ParseUtil::re_poryScriptLabel("\\b(script)(\\((global|local)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)");
const QRegularExpression ParseUtil::re_globalPoryScriptLabel("\\b(script)(\\((global)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)");
const QRegularExpression ParseUtil::re_poryRawSection("\\b(raw)\\s*`(?<raw_script>[^`]*)");
void ParseUtil::set_root(const QString &dir) {
this->root = dir;
@ -425,7 +430,6 @@ int ParseUtil::getRawScriptLineNumber(QString text, const QString &scriptLabel)
text = removeStringLiterals(text);
text = removeLineComments(text, "@");
static const QRegularExpression re_incScriptLabel("\\b(?<label>[\\w_][\\w\\d_]*):{1,2}");
QRegularExpressionMatchIterator it = re_incScriptLabel.globalMatch(text);
while (it.hasNext()) {
const QRegularExpressionMatch match = it.next();
@ -440,7 +444,6 @@ int ParseUtil::getPoryScriptLineNumber(QString text, const QString &scriptLabel)
text = removeStringLiterals(text);
text = removeLineComments(text, {"//", "#"});
static const QRegularExpression re_poryScriptLabel("\\b(script)(\\((global|local)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)");
QRegularExpressionMatchIterator it = re_poryScriptLabel.globalMatch(text);
while (it.hasNext()) {
const QRegularExpressionMatch match = it.next();
@ -448,7 +451,6 @@ int ParseUtil::getPoryScriptLineNumber(QString text, const QString &scriptLabel)
return text.left(match.capturedStart("label")).count('\n') + 1;
}
static const QRegularExpression re_poryRawSection("\\b(raw)\\s*`(?<raw_script>[^`]*)");
QRegularExpressionMatchIterator raw_it = re_poryRawSection.globalMatch(text);
while (raw_it.hasNext()) {
const QRegularExpressionMatch match = raw_it.next();
@ -460,6 +462,47 @@ int ParseUtil::getPoryScriptLineNumber(QString text, const QString &scriptLabel)
return 0;
}
QStringList ParseUtil::getGlobalScriptLabels(const QString &filePath) {
if (filePath.endsWith(".inc") || filePath.endsWith(".s"))
return getGlobalRawScriptLabels(readTextFile(filePath));
else if (filePath.endsWith(".pory"))
return getGlobalPoryScriptLabels(readTextFile(filePath));
else
return { };
}
QStringList ParseUtil::getGlobalRawScriptLabels(QString text) {
removeStringLiterals(text);
removeLineComments(text, "@");
QStringList rawScriptLabels;
QRegularExpressionMatchIterator it = re_globalIncScriptLabel.globalMatch(text);
while (it.hasNext()) {
const QRegularExpressionMatch match = it.next();
rawScriptLabels << match.captured("label");
}
return rawScriptLabels;
}
QStringList ParseUtil::getGlobalPoryScriptLabels(QString text) {
removeStringLiterals(text);
removeLineComments(text, {"//", "#"});
QStringList poryScriptLabels;
QRegularExpressionMatchIterator it = re_globalPoryScriptLabel.globalMatch(text);
while (it.hasNext())
poryScriptLabels << it.next().captured("label");
QRegularExpressionMatchIterator raw_it = re_poryRawSection.globalMatch(text);
while (raw_it.hasNext())
poryScriptLabels << getGlobalRawScriptLabels(raw_it.next().captured("raw_script"));
return poryScriptLabels;
}
QString ParseUtil::removeStringLiterals(QString text) {
static const QRegularExpression re_string("\".*\"");
return text.remove(re_string);
@ -477,12 +520,15 @@ QString ParseUtil::removeLineComments(QString text, const QStringList &commentSy
}
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
#include <QProcess>
QStringList ParseUtil::splitShellCommand(QStringView command) {
return QProcess::splitCommand(command);
}
#else
// The source for QProcess::splitCommand() as of Qt 5.15.2
QStringList ParseUtil::splitShellCommand(QStringView command) {
QStringList args;
@ -522,4 +568,5 @@ QStringList ParseUtil::splitShellCommand(QStringView command) {
return args;
}
#endif

View file

@ -877,8 +877,9 @@ bool MainWindow::loadDataStructures() {
&& project->readHealLocations()
&& project->readMiscellaneousConstants()
&& project->readSpeciesIconPaths()
&& project->readWildMonData();
&& project->readWildMonData()
&& project->readEventScriptLabels();
return success && loadProjectCombos();
}
@ -1913,7 +1914,9 @@ void MainWindow::updateSelectedObjects() {
"normal movement behavior actions.");
combo->setMinimumContentsLength(4);
} else if (key == "script_label") {
combo->addItems(editor->map->eventScriptLabels());
const auto localScriptLabels = editor->map->eventScriptLabels();
combo->addItems(localScriptLabels);
combo->setCompleter(editor->project->getEventScriptLabelCompleter(localScriptLabels));
combo->setToolTip("The script which is executed with this event.");
} else if (key == "trainer_type") {
combo->addItems(editor->project->trainerTypes);

View file

@ -36,7 +36,10 @@ int Project::max_map_data_size = 10240; // 0x2800
int Project::default_map_size = 20;
int Project::max_object_events = 64;
Project::Project(QWidget *parent) : QObject(parent)
Project::Project(QWidget *parent) :
QObject(parent),
eventScriptLabelModel(this),
eventScriptLabelCompleter(this)
{
initSignals();
}
@ -2311,6 +2314,18 @@ bool Project::readMiscellaneousConstants() {
return true;
}
bool Project::readEventScriptLabels() {
for (const auto &filePath : getEventScriptsFilePaths())
globalScriptLabels << ParseUtil::getGlobalScriptLabels(filePath);
eventScriptLabelModel.setStringList(globalScriptLabels);
eventScriptLabelCompleter.setModel(&eventScriptLabelModel);
eventScriptLabelCompleter.setCaseSensitivity(Qt::CaseInsensitive);
eventScriptLabelCompleter.setFilterMode(Qt::MatchContains);
return true;
}
QString Project::fixPalettePath(QString path) {
path = path.replace(QRegExp("\\.gbapal$"), ".pal");
return path;
@ -2374,6 +2389,13 @@ QStringList Project::getEventScriptsFilePaths() const {
return filePaths;
}
QCompleter *Project::getEventScriptLabelCompleter(QStringList additionalScriptLabels) {
additionalScriptLabels << globalScriptLabels;
additionalScriptLabels.removeDuplicates();
eventScriptLabelModel.setStringList(additionalScriptLabels);
return &eventScriptLabelCompleter;
}
void Project::loadEventPixmaps(QList<Event*> objects) {
bool needs_update = false;
for (Event *object : objects) {