1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-01 03:21:41 +00:00
OpenMW/apps/opencs/view/world/scripthighlighter.cpp
florent.teppe 65cdd489fb create a specific esm reader function for RefID to avoid allocation for string and then again for RefId
Fixed some types

removed useless header

applied clang format

fixed compile tests

fixed clang tidy, and closer to logic before this MR

Removed hardcoded refids

unless there is a returned value we don't use static RefIds
can use == between RefId and hardcoded string

Fix clang format

Fixed a few instances where std::string was used, when only const std::string& was needed

removed unused variable
2022-12-27 19:15:57 +01:00

162 lines
4.8 KiB
C++

#include "scripthighlighter.hpp"
#include <sstream>
#include <utility>
#include <apps/opencs/model/prefs/category.hpp>
#include <apps/opencs/model/prefs/setting.hpp>
#include <apps/opencs/model/world/scriptcontext.hpp>
#include <components/compiler/extensions0.hpp>
#include <components/compiler/scanner.hpp>
#include <components/compiler/tokenloc.hpp>
#include <components/esm/refid.hpp>
class QTextDocument;
namespace CSMWorld
{
class Data;
}
bool CSVWorld::ScriptHighlighter::parseInt(int value, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner)
{
highlight(loc, Type_Int);
return true;
}
bool CSVWorld::ScriptHighlighter::parseFloat(float value, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner)
{
highlight(loc, Type_Float);
return true;
}
bool CSVWorld::ScriptHighlighter::parseName(
const std::string& name, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner)
{
highlight(loc, mContext.isId(ESM::RefId::stringRefId(name)) ? Type_Id : Type_Name);
return true;
}
bool CSVWorld::ScriptHighlighter::parseKeyword(int keyword, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner)
{
if (((mMode == Mode_Console || mMode == Mode_Dialogue)
&& (keyword == Compiler::Scanner::K_begin || keyword == Compiler::Scanner::K_end
|| keyword == Compiler::Scanner::K_short || keyword == Compiler::Scanner::K_long
|| keyword == Compiler::Scanner::K_float))
|| (mMode == Mode_Console
&& (keyword == Compiler::Scanner::K_if || keyword == Compiler::Scanner::K_endif
|| keyword == Compiler::Scanner::K_else || keyword == Compiler::Scanner::K_elseif
|| keyword == Compiler::Scanner::K_while || keyword == Compiler::Scanner::K_endwhile)))
return parseName(loc.mLiteral, loc, scanner);
highlight(loc, Type_Keyword);
return true;
}
bool CSVWorld::ScriptHighlighter::parseSpecial(int code, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner)
{
highlight(loc, Type_Special);
return true;
}
bool CSVWorld::ScriptHighlighter::parseComment(
const std::string& comment, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner)
{
highlight(loc, Type_Comment);
return true;
}
void CSVWorld::ScriptHighlighter::parseEOF(Compiler::Scanner& scanner) {}
void CSVWorld::ScriptHighlighter::highlight(const Compiler::TokenLoc& loc, Type type)
{
// We should take in account multibyte characters
int length = 0;
const char* token = loc.mLiteral.c_str();
while (*token)
length += (*token++ & 0xc0) != 0x80;
int index = loc.mColumn;
// compensate for bug in Compiler::Scanner (position of token is the character after the token)
index -= length;
QTextCharFormat scheme = mScheme[type];
if (mMarkOccurrences && type == Type_Name && loc.mLiteral == mMarkedWord)
scheme.merge(mScheme[Type_Highlight]);
setFormat(index, length, scheme);
}
CSVWorld::ScriptHighlighter::ScriptHighlighter(const CSMWorld::Data& data, Mode mode, QTextDocument* parent)
: QSyntaxHighlighter(parent)
, Compiler::Parser(mErrorHandler, mContext)
, mContext(data)
, mMode(mode)
, mMarkOccurrences(false)
{
QColor color("black");
QTextCharFormat format;
format.setForeground(color);
for (int i = 0; i <= Type_Id; ++i)
mScheme.insert(std::make_pair(static_cast<Type>(i), format));
// configure compiler
Compiler::registerExtensions(mExtensions);
mContext.setExtensions(&mExtensions);
}
void CSVWorld::ScriptHighlighter::highlightBlock(const QString& text)
{
std::istringstream stream(text.toUtf8().constData());
Compiler::Scanner scanner(mErrorHandler, stream, mContext.getExtensions());
try
{
scanner.scan(*this);
}
catch (...)
{
} // ignore syntax errors
}
void CSVWorld::ScriptHighlighter::setMarkOccurrences(bool flag)
{
mMarkOccurrences = flag;
}
void CSVWorld::ScriptHighlighter::setMarkedWord(const std::string& name)
{
mMarkedWord = name;
}
void CSVWorld::ScriptHighlighter::invalidateIds()
{
mContext.invalidateIds();
}
bool CSVWorld::ScriptHighlighter::settingChanged(const CSMPrefs::Setting* setting)
{
if (setting->getParent()->getKey() == "Scripts")
{
static const char* const colours[Type_Id + 2] = { "colour-int", "colour-float", "colour-name", "colour-keyword",
"colour-special", "colour-comment", "colour-highlight", "colour-id", 0 };
for (int i = 0; colours[i]; ++i)
if (setting->getKey() == colours[i])
{
QTextCharFormat format;
if (i == Type_Highlight)
format.setBackground(setting->toColor());
else
format.setForeground(setting->toColor());
mScheme[static_cast<Type>(i)] = format;
return true;
}
}
return false;
}