aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Moore <ken@ixsystems.com>2017-06-09 14:04:11 -0400
committerKen Moore <ken@ixsystems.com>2017-06-09 14:04:11 -0400
commitbbf81abc29e626b654366b7083babe9f355709ea (patch)
treef62602228809158e4e48d465f58f323b453a673c
parentGet the SyntaxFile loading mechanisms all setup. (diff)
downloadlumina-bbf81abc29e626b654366b7083babe9f355709ea.tar.gz
lumina-bbf81abc29e626b654366b7083babe9f355709ea.tar.bz2
lumina-bbf81abc29e626b654366b7083babe9f355709ea.zip
Get the new syntax highlighting support framework functional with the C++ rules files as the example (still need to convert the other existing rulesets over to the new format).
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/MainUI.cpp6
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp12
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp274
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h74
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax109
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/tests/test.cpp7
6 files changed, 170 insertions, 312 deletions
diff --git a/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp b/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp
index ec2d7d0d..40ff2c71 100644
--- a/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp
+++ b/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp
@@ -65,7 +65,7 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
connect(closeFindS, SIGNAL(activated()), this, SLOT(closeFindReplace()) );
ui->groupReplace->setVisible(false);
//Update the menu of available syntax highlighting modes
- QStringList smodes = Custom_Syntax::availableRules();
+ QStringList smodes = Custom_Syntax::availableRules(settings);
for(int i=0; i<smodes.length(); i++){
ui->menuSyntax_Highlighting->addAction(smodes[i]);
}
@@ -242,13 +242,13 @@ void MainUI::fontChanged(const QFont &font){
//Save this font for later
settings->setValue("lastfont", font.toString());
//Now apply this font to all the open editors
- QApplication::setFont(font, "PlainTextEditor");
+ //QApplication::setFont(font, "PlainTextEditor");
}
void MainUI::changeFontSize(int newFontSize){
QFont currentFont = fontbox->currentFont();
currentFont.setPointSize(newFontSize);
- QApplication::setFont(currentFont, "PlainTextEditor");
+ //QApplication::setFont(currentFont, "PlainTextEditor");
}
void MainUI::changeTabsLocation(QAction *act){
diff --git a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp
index a0aff9cc..e62ff0d4 100644
--- a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp
+++ b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp
@@ -68,7 +68,15 @@ void PlainTextEditor::LoadFile(QString filepath){
bool diffFile = (filepath != this->whatsThis());
this->setWhatsThis(filepath);
this->clear();
- SYNTAX->loadRules( Custom_Syntax::ruleForFile(filepath.section("/",-1)) );
+ QList<SyntaxFile> files = SyntaxFile::availableFiles(settings);
+ for(int i=0; i<files.length(); i++){
+ if(files[i].supportsFile(filepath) ){
+ files[i].SetupDocument(this);
+ SYNTAX->loadRules(files[i]);
+ break;
+ }
+ }
+ //SYNTAX->loadRules( Custom_Syntax::ruleForFile(filepath.section("/",-1), settings) );
lastSaveContents = LUtils::readFile(filepath).join("\n");
if(diffFile){
this->setPlainText( lastSaveContents );
@@ -94,7 +102,7 @@ void PlainTextEditor::SaveFile(bool newname){
QString file = QFileDialog::getSaveFileName(this, tr("Save File"), this->whatsThis(), tr("Text File (*)"));
if(file.isEmpty()){ return; }
this->setWhatsThis(file);
- SYNTAX->loadRules( Custom_Syntax::ruleForFile(this->whatsThis().section("/",-1)) );
+ SYNTAX->loadRules( Custom_Syntax::ruleForFile(this->whatsThis().section("/",-1), settings) );
SYNTAX->rehighlight();
}
if( !watcher->files().isEmpty() ){ watcher->removePaths(watcher->files()); }
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp
index a590d3a4..9c264fca 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp
+++ b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp
@@ -27,7 +27,7 @@ QColor SyntaxFile::colorFromOption(QString opt, QSettings *settings){
}else if(opt.startsWith("colors/")){
return QColor(settings->value(opt,"").toString());
}
- return QColor();
+ return QColor("transparent");
}
QString SyntaxFile::name(){
@@ -46,6 +46,13 @@ bool SyntaxFile::highlight_excess_whitespace(){
return formatObj.value("highlight_whitespace_eol").toBool();
}
+int SyntaxFile::tab_length(){
+ int num = -1;
+ if(formatObj.contains("tab_width")){ num = formatObj.value("tab_width").toInt(); }
+ if(num<=0){ num = 8; } //UNIX Standard of 8 characters per tab
+ return num;
+}
+
void SyntaxFile::SetupDocument(QPlainTextEdit* editor){
if(formatObj.contains("line_wrap")){
editor->setLineWrapMode( formatObj.value("line_wrap").toBool() ? QPlainTextEdit::WidgetWidth : QPlainTextEdit::NoWrap);
@@ -54,7 +61,8 @@ void SyntaxFile::SetupDocument(QPlainTextEdit* editor){
QString type = formatObj.value("font_type").toString();
QFont font = editor->document()->defaultFont(); // current font
if(type=="monospace"){
- font = QFontDatabase::systemFont(QFontDatabase::FixedFont); //get the default fixed-size font for the system
+ font = QFont("monospace");
+ //font = QFontDatabase::systemFont(QFontDatabase::FixedFont); //get the default fixed-size font for the system
}
font.setStyle(QFont::StyleNormal);
font.setStyleStrategy(QFont::PreferAntialias);
@@ -81,8 +89,12 @@ bool SyntaxFile::LoadFile(QString file, QSettings *settings){
if(contents[0].startsWith("{")){ break; } //stop here
else{ contents.removeAt(0); }
}
- QJsonObject obj = QJsonDocument::fromJson(contents.join("\n").simplified().toLocal8Bit()).object();
- if(!obj.contains("meta") || !obj.contains("format") || !obj.contains("rules")){ return false; } //could not get any info
+ //qDebug() << "Contents:" << contents.join("\n").simplified();
+ QJsonParseError err;
+ QJsonDocument doc = QJsonDocument::fromJson(contents.join("\n").simplified().toLocal8Bit(), &err );
+ if(doc.isNull()){ qDebug() << "JSON Syntax Error:" << err.errorString(); }
+ QJsonObject obj = doc.object();
+ if(!obj.contains("meta") || !obj.contains("format") || !obj.contains("rules")){ qDebug() << "Could not read syntax file:" << file; return false; } //could not get any info
//Save the raw meta/format objects for later
fileLoaded = file;
metaObj = obj.value("meta").toObject();
@@ -95,11 +107,14 @@ bool SyntaxFile::LoadFile(QString file, QSettings *settings){
QJsonObject rule = rulesArray[i].toObject();
SyntaxRule tmp;
//First load the rule
+ //qDebug() << "Load Rule:" << rule.keys();
if(rule.contains("words")){} //valid option - handled at the end though
else if(rule.contains("regex")){
tmp.pattern = QRegExp(rule.value("regex").toString());
- }else if(rule.contains("regex_start") && rule.contains("regex_stop")){
-
+ }else if(rule.contains("regex_start") && rule.contains("regex_end")){
+ tmp.startPattern = QRegExp(rule.value("regex_start").toString());
+ tmp.endPattern = QRegExp(rule.value("regex_end").toString());
+ //qDebug() << " -- Multi-line Rule:" << tmp.startPattern << tmp.endPattern;
}else{ continue; } //bad rule - missing the actual detection logic
//Now load the appearance logic
if(rule.contains("foreground")){ tmp.format.setForeground( colorFromOption(rule.value("foreground").toString(), settings) ); }
@@ -139,10 +154,12 @@ QList<SyntaxFile> SyntaxFile::availableFiles(QSettings *settings){
for(int i=0; i<paths.length(); i++){
QDir dir(paths[i]+"/lumina-desktop/syntax_rules");
if(!dir.exists()){ continue; }
+ //qDebug() << "Found directory:" << dir.absolutePath();
QFileInfoList files = dir.entryInfoList(QStringList() << "*.syntax", QDir::Files, QDir::Name);
for(int f=0; f<files.length(); f++){
if(paths.contains(files[f].absoluteFilePath()) ){ continue; } //already handled
//New Syntax File found
+ //qDebug() << "Found File:" << files[f].fileName();
SyntaxFile nfile;
if( nfile.LoadFile(files[f].absoluteFilePath(), settings) ){ list << nfile; }
}
@@ -150,12 +167,14 @@ QList<SyntaxFile> SyntaxFile::availableFiles(QSettings *settings){
return list;
}
-QStringList Custom_Syntax::availableRules(){
+QStringList Custom_Syntax::availableRules(QSettings *settings){
QStringList avail;
- avail << "C++";
+ QList<SyntaxFile> files = SyntaxFile::availableFiles(settings);
+ for(int i=0; i<files.length(); i++){ avail << files[i].name(); }
+ /*avail << "C++";
//avail << "Python";
avail << "Shell";
- avail << "reST";
+ avail << "reST";*/
return avail;
}
@@ -181,232 +200,29 @@ void Custom_Syntax::SetupDefaultColors(QSettings *settings){
if(!settings->contains("colors/preprocessor")){settings->setValue("colors/preprocessor", QColor(Qt::darkYellow).name() ); }
}
-QString Custom_Syntax::ruleForFile(QString filename){
- QString suffix = filename.section(".",-1);
+QString Custom_Syntax::ruleForFile(QString filename, QSettings *settings){
+ QList<SyntaxFile> files = SyntaxFile::availableFiles(settings);
+ for(int i=0; i<files.length(); i++){
+ if(files[i].supportsFile(filename)){ return files[i].name(); }
+ }
+
+ /*QString suffix = filename.section(".",-1);
if(suffix=="cpp" || suffix=="hpp" || suffix=="c" || suffix=="h"){ return "C++"; }
//else if(suffix=="py" || suffix=="pyc"){ return "Python"; }
else if(suffix=="sh"){ return "Shell"; }
- else if(suffix=="rst"){ return "reST"; }
+ else if(suffix=="rst"){ return "reST"; }*/
return "";
}
-void Custom_Syntax::loadRules(QString type){
- //NOTE: the "multiLineComment
- lasttype = type;
- rules.clear();
- splitrules.clear();
- if(type=="C++"){
- //Keywords (standard C/C++/Qt definitions)
- QStringList keywords;
- keywords << "char" << "class" << "const" << "double" << "enum" << "explicit" << "extern" << "float" << "friend" << "inline" \
- << "int" << "long" << "namespace" << "operator" << "private" << "protected" << "public" \
- << "short" << "signals" << "signed" << "slots" << "static" << "struct" << "template" \
- << "typedef" << "typename" << "union" << "unsigned" << "virtual" << "void" << "volatile" \
- << "true" << "false" << "bool";
- SyntaxRule rule;
- rule.format.setForeground( QColor(settings->value("colors/keyword").toString()) );
- rule.format.setFontWeight(QFont::Bold);
- for(int i=0; i<keywords.length(); i++){
- rule.pattern = QRegExp("\\b"+keywords[i]+"\\b"); //turn each keyword into a QRegExp and insert the rule
- rules << rule;
- }
- //Alternate Keywords (built-in functions)
- keywords.clear();
- keywords << "for" << "while" << "switch" << "case" << "if" << "else" << "return" << "exit";
- rule.format.setForeground( QColor(settings->value("colors/altkeyword").toString()) );
- for(int i=0; i<keywords.length(); i++){
- rule.pattern = QRegExp("\\b"+keywords[i]+"\\b"); //turn each keyword into a QRegExp and insert the rule
- rules << rule;
- }
- //Class Names
- rule.format.setForeground( QColor(settings->value("colors/class").toString()) );
- rule.pattern = QRegExp("\\b[A-Za-z0-9_-\\.]+(?=::)\\b");
- rules << rule;
- //Quotes
- rule.format.setForeground( QColor(settings->value("colors/text").toString()) );
- rule.format.setFontWeight(QFont::Normal);
- rule.pattern = QRegExp( "\"[^\"\\\\]*(\\\\(.|\\n)[^\"\\\\]*)*\"|'[^'\\\\]*(\\\\(.|\\n)[^'\\\\]*)*'");
- rules << rule;
- //Functions
- rule.format.setForeground( QColor(settings->value("colors/function").toString()) );
- rule.pattern = QRegExp("\\b[A-Za-z0-9_]+(?=\\()");
- rules << rule;
- //Proprocessor commands
- rule.format.setForeground( QColor(settings->value("colors/preprocessor").toString()) );
- rule.pattern = QRegExp("^[\\s]*#[^\n]*");
- rules << rule;
- //Comment (single line)
- rule.format.setForeground( QColor(settings->value("colors/comment").toString()) );
- rule.pattern = QRegExp("//[^\n]*");
- rules << rule;
- //Comment (multi-line)
- SyntaxRuleSplit srule;
- srule.format = rule.format; //re-use the single-line comment format
- srule.startPattern = QRegExp("/\\*");
- srule.endPattern = QRegExp("\\*/");
- splitrules << srule;
-
- }else if(type=="Shell"){
- //Keywords (standard Shell definitions)
- QStringList keywords;
- keywords << "alias" << "alloc" << "bg" << "bind" << " bindkey" << "break" \
- << "breaksw"<<"builtins"<<"case"<<"cd"<<"chdir"<<"command"<<"complete"<<"continue"<<"default" \
- <<"dirs"<<"do"<<"done"<<"echo"<<"echotc"<<"elif"<<"else"<<"end"<<"endif"<<"endsw"<<"esac"<<"eval" \
- <<"exec"<<"exit"<<"export"<<"false"<<"fc"<<"fg"<<"filetest"<<"fi"<<"for"<<"foreach"<<"getopts" \
- <<"glob"<<"goto"<<"hash"<<"hashstat"<<"history"<<"hup"<<"if"<<"jobid"<<"jobs"<<"kill"<<"limit" \
- <<"local"<<"log"<<"login"<<"logout"<<"ls-F"<<"nice"<<"nohup"<<"notify"<<"onintr"<<"popd" \
- <<"printenv"<<"printf"<<"pushd"<<"pwd"<<"read"<<"readonly"<<"rehash"<<"repeat"<<"return" \
- <<"sched"<<"set"<<"setenv"<<"settc"<<"setty"<<"setvar"<<"shift"<<"source"<<"stop"<<"suspend" \
- <<"switch"<<"telltc"<<"test"<<"then"<<"time"<<"times"<<"trap"<<"true"<<"type"<<"ulimit"<<"umask" \
- <<"unalias"<<"uncomplete"<<"unhash"<<"unlimit"<<"unset"<<"unsetenv"<<"until"<<"wait" \
- <<"where"<<"which"<<"while";
-
- SyntaxRule rule;
- rule.format.setForeground( QColor(settings->value("colors/keyword").toString()) );
- rule.format.setFontWeight(QFont::Bold);
- for(int i=0; i<keywords.length(); i++){
- rule.pattern = QRegExp("\\b"+keywords[i]+"\\b"); //turn each keyword into a QRegExp and insert the rule
- rules << rule;
- }
- //Alternate Keywords (built-in functions)
- /*keywords.clear();
- keywords << "for" << "while" << "switch" << "case" << "if" << "else" << "return" << "exit";
- rule.format.setForeground( QColor(settings->value("colors/altkeyword").toString()) );
- for(int i=0; i<keywords.length(); i++){
- rule.pattern = QRegExp("\\b"+keywords[i]+"\\b"); //turn each keyword into a QRegExp and insert the rule
- rules << rule;
- }*/
- //Variable Names
- rule.format.setForeground( QColor(settings->value("colors/class").toString()) );
- rule.pattern = QRegExp("\\$\\{[^\\n\\}]+\\}");
- rules << rule;
- rule.pattern = QRegExp("\\$[^\\s$]+(?=\\s|$)");
- rules << rule;
- //Quotes
- rule.format.setForeground( QColor(settings->value("colors/text").toString()) );
- rule.format.setFontWeight(QFont::Normal);
- rule.pattern = QRegExp( "\"[^\"\\\\]*(\\\\(.|\\n)[^\"\\\\]*)*\"|'[^'\\\\]*(\\\\(.|\\n)[^'\\\\]*)*'");
- rules << rule;
- //Functions
- rule.format.setForeground( QColor(settings->value("colors/function").toString()) );
- rule.pattern = QRegExp("\\b[A-Za-z0-9_]+(?=\\()");
- rules << rule;
- //Proprocessor commands
- rule.format.setForeground( QColor(settings->value("colors/preprocessor").toString()) );
- rule.pattern = QRegExp("^#![^\n]*");
- rules << rule;
- //Comment (single line)
- rule.format.setForeground( QColor(settings->value("colors/comment").toString()) );
- rule.pattern = QRegExp("#[^\n]*");
- rules << rule;
- //Comment (multi-line)
- //SyntaxRuleSplit srule;
- //srule.format = rule.format; //re-use the single-line comment format
- //srule.startPattern = QRegExp("/\\*");
- //srule.endPattern = QRegExp("\\*/");
- //splitrules << srule;
-
- }else if(type=="Python"){
- //Keywords
- QStringList keywords;
- keywords << "and" << "as" << "assert" << "break" << "class" << "continue" << "def" << "del" \
- << "elif" << "else" << "except" << "exec" << "finally" << "for" << "from" \
- << "global" << "if" << "import" << "in" << "is" << "lambda" << "not" \
- << "or" << "pass" << "print" << "raise" << "return" << "try" << "while" << "with" << "yield";
-
- SyntaxRule rule;
- rule.format.setForeground( QColor(settings->value("colors/keyword").toString()) );
- rule.format.setFontWeight(QFont::Bold);
- for(int i=0; i<keywords.length(); i++){
- rule.pattern = QRegExp("\\b"+keywords[i]+"\\b"); //turn each keyword into a QRegExp and insert the rule
- rules << rule;
- }
- //Class Names
- //rule.format.setForeground(Qt::darkMagenta);
- //rule.pattern = QRegExp("\\bQ[A-Za-z]+\\b");
- //rules << rule;
- //Quotes
- rule.format.setForeground( QColor(settings->value("colors/text").toString()) );
- rule.format.setFontWeight(QFont::Normal);
- rule.pattern = QRegExp( "\"[^\"\\\\]*(\\\\(.|\\n)[^\"\\\\]*)*\"|'[^'\\\\]*(\\\\(.|\\n)[^'\\\\]*)*'");
- rules << rule;
- //Functions
- rule.format.setForeground( QColor(settings->value("colors/function").toString()) );
- rule.pattern = QRegExp("\\b[A-Za-z0-9_]+(?=\\()");
- rules << rule;
- //Comment (single line)
- rule.format.setForeground( QColor(settings->value("colors/comment").toString()) );
- rule.pattern = QRegExp("#[^\n]*");
- rules << rule;
- //Comment (multi-line)
- //SyntaxRuleSplit srule;
- //srule.format = rule.format; //re-use the single-line comment format
- //srule.startPattern = QRegExp("/\\*");
- //srule.endPattern = QRegExp("\\*/");
- //splitrules << srule;
-
- }else if(type=="reST"){
- SyntaxRule rule;
- // directives
- rule.format.setForeground( QColor(settings->value("colors/class").toString()) );
- rule.format.setFontItalic(false);
- rule.pattern = QRegExp("(\\s|^):[a-zA-Z0-9 ]*:`[^`]*`");
- rules << rule;
- // hyperlinks
- rule.format.setFontItalic(true);
- rule.format.setFontWeight(QFont::Normal);
- rule.pattern = QRegExp("`[^\\<]*\\<[^\\>]*\\>`_");
- rules << rule;
- // Code Sample
- rule.format.setFontItalic(false);
- rule.format.setFontWeight(QFont::Light);
- rule.format.setFontFixedPitch(true);
- rule.pattern = QRegExp("\\b`{2}.*`{2}\\b");
- rules << rule;
- //Quotes
- /*rule.format.setForeground( QColor(settings->value("colors/text").toString()) );
- rule.format.setFontWeight(QFont::Normal);
- rule.pattern = QRegExp( "\"[^\"\\\\]*(\\\\(.|\\n)[^\"\\\\]*)*\"|'[^'\\\\]*(\\\\(.|\\n)[^'\\\\]*)*'");
- rules << rule;*/
- //TODO
- rule = SyntaxRule(); //reset rule
- rule.format.setFontWeight( QFont::Bold );
- rule.pattern = QRegExp("^\\.\\.\\sTODO\\b");
- rules << rule;
- rule = SyntaxRule(); //reset rule
- rule.format.setFontWeight( QFont::Bold );
- rule.pattern = QRegExp("^(\\s*)\\.\\.(\\s*)([a-zA-Z0-9]+)::");
- rules << rule;
- //Functions
- rule = SyntaxRule(); //reset rule
- rule.format.setForeground( QColor(settings->value("colors/preprocessor").toString()) );
- rule.pattern = QRegExp("^(\\s*)\\.\\.(\\s*)\\b_[a-zA-Z0-9 ]*:(\\s|$)");
- rules << rule;
- //figures and other properties for them
- rule = SyntaxRule(); //reset rule
- rule.format.setForeground( QColor(settings->value("colors/keyword").toString()) );
- rule.pattern = QRegExp("^(\\s*)\\.\\.\\sfigure::\\s");
- rules << rule;
- rule = SyntaxRule(); //reset rule
- rule.format.setForeground( QColor(settings->value("colors/altkeyword").toString()) );
- rule.pattern = QRegExp("^( ){3}:(.)*: ");
- rules << rule;
-
- //Code Blocks
- SyntaxRuleSplit srule;
- srule.format.setBackground( QColor("lightblue") );
- srule.startPattern = QRegExp("\\:\\:$");
- srule.endPattern = QRegExp("^(?=[^\\s])");
- splitrules << srule;
- srule.startPattern = QRegExp("^(\\s*)\\.\\.\\scode-block::\\s"); //alternate start string for the same rule
- srule.endPattern = QRegExp("^(?=[^\\s])");
- splitrules << srule;
- //Comment (multi-line)
- srule = SyntaxRuleSplit();
- srule.format.setForeground( QColor(settings->value("colors/comment").toString()) );
- srule.startPattern = QRegExp("^(\\s*)\\.\\.\\s[^_](?![\\w-_\\.]+::(\\s|$))");
- srule.endPattern = QRegExp("^(?=([^\\s]|$))");
- splitrules << srule;
+void Custom_Syntax::loadRules(QString type){
+ QList<SyntaxFile> files = SyntaxFile::availableFiles(settings);
+ for(int i=0; i<files.length(); i++){
+ if(files[i].name() == type){ syntax = files[i]; break; }
}
+ return;
+}
+
+void Custom_Syntax::loadRules(SyntaxFile sfile){
+ syntax = sfile;
}
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h
index 746df750..fde68f84 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h
+++ b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h
@@ -47,6 +47,7 @@ public:
QString name();
int char_limit();
bool highlight_excess_whitespace();
+ int tab_length();
void SetupDocument(QPlainTextEdit *editor);
bool supportsFile(QString file); //does this syntax set support the file?
@@ -62,9 +63,10 @@ class Custom_Syntax : public QSyntaxHighlighter{
Q_OBJECT
private:
QSettings *settings;
- QString lasttype;
- QVector<SyntaxRule> rules;
- QVector<SyntaxRuleSplit> splitrules;
+ //QString lasttype;
+ SyntaxFile syntax;
+ //QVector<SyntaxRule> rules;
+ //QVector<SyntaxRuleSplit> splitrules;
public:
Custom_Syntax(QSettings *set, QTextDocument *parent = 0) : QSyntaxHighlighter(parent){
@@ -72,47 +74,53 @@ public:
}
~Custom_Syntax(){}
- static QStringList availableRules();
+ static QStringList availableRules(QSettings *settings);
static QStringList knownColors();
static void SetupDefaultColors(QSettings *settings);
- static QString ruleForFile(QString filename);
+ static QString ruleForFile(QString filename, QSettings *settings);
void loadRules(QString type);
+ void loadRules(SyntaxFile sfile);
void reloadRules(){
- loadRules(lasttype);
+ loadRules( syntax.name() );
}
+
protected:
void highlightBlock(const QString &text){
//qDebug() << "Highlight Block:" << text;
//Now look for any multi-line patterns (starting/continuing/ending)
int start = 0;
int splitactive = previousBlockState();
- if(splitactive>splitrules.length()-1){ splitactive = -1; } //just in case
+ if(splitactive>syntax.rules.length()-1){ splitactive = -1; } //just in case
+
while(start>=0 && start<=text.length()-1){
//qDebug() << "split check:" << start << splitactive;
if(splitactive>=0){
//Find the end of the current rule
- int end = splitrules[splitactive].endPattern.indexIn(text, start);
+ int end = syntax.rules[splitactive].endPattern.indexIn(text, start);
if(end==-1){
//qDebug() << "Highlight to end of line:" << text << start;
//rule did not finish - apply to all
- if(start>0){ setFormat(start-1, text.length()-start+1, splitrules[splitactive].format); }
- else{ setFormat(start, text.length()-start, splitrules[splitactive].format); }
+ if(start>0){ setFormat(start-1, text.length()-start+1, syntax.rules[splitactive].format); }
+ else{ setFormat(start, text.length()-start, syntax.rules[splitactive].format); }
break; //stop looking for more multi-line patterns
}else{
//Found end point within the same line
//qDebug() << "Highlight to particular point:" << text << start << end;
- int len = end-start+splitrules[splitactive].endPattern.matchedLength();
+ int len = end-start+syntax.rules[splitactive].endPattern.matchedLength();
if(start>0){ start--; len++; } //need to include the first character as well
- setFormat(start, len , splitrules[splitactive].format);
+ setFormat(start, len , syntax.rules[splitactive].format);
start+=len; //move pointer to the end of handled range
splitactive = -1; //done with this rule
}
} //end check for end match
- //Look for the start of any new split rule
- for(int i=0; i<splitrules.length() && splitactive<0; i++){
- //qDebug() << "Look for start of split rule:" << splitrules[i].startPattern << splitactive;
- int newstart = splitrules[i].startPattern.indexIn(text,start);
+ //Look for the start of any new split rules
+ //qDebug() << "Loop over multi-line rules";
+ for(int i=0; i<syntax.rules.length() && splitactive<0; i++){
+ //qDebug() << "Check Rule:" << i << syntax.rules[i].startPattern << syntax.rules[i].endPattern;
+ if(syntax.rules[i].startPattern.isEmpty()){ continue; }
+ //qDebug() << "Look for start of split rule:" << syntax.rules[i].startPattern << splitactive;
+ int newstart = syntax.rules[i].startPattern.indexIn(text,start);
if(newstart>=start){
//qDebug() << "Got Start of split rule:" << start << newstart << text;
splitactive = i;
@@ -120,24 +128,48 @@ protected:
if(start>=text.length()-1){
//qDebug() << "Special case: start now greater than line length";
//Need to apply highlighting to this section too - start matches the end of the line
- setFormat(start-1, text.length()-start+1, splitrules[splitactive].format);
+ setFormat(start-1, text.length()-start+1, syntax.rules[splitactive].format);
}
}
}
if(splitactive<0){ break; } //no other rules found - go ahead and exit the loop
- }
+ } //end scan over line length and multi-line formats
+
setCurrentBlockState(splitactive);
//Do all the single-line patterns
- for(int i=0; i<rules.length(); i++){
- QRegExp patt(rules[i].pattern); //need a copy of the rule's pattern (will be changing it below)
+ for(int i=0; i<syntax.rules.length(); i++){
+ if(syntax.rules[i].pattern.isEmpty()){ continue; } //not a single-line rule
+ QRegExp patt(syntax.rules[i].pattern); //need a copy of the rule's pattern (will be changing it below)
int index = patt.indexIn(text);
if(splitactive>=0 || index<start){ continue; } //skip this one - falls within a multi-line pattern above
while(index>=0){
int len = patt.matchedLength();
- if(format(index)==currentBlock().charFormat()){ setFormat(index, len, rules[i].format); } //only apply highlighting if not within a section already
+ if(format(index)==currentBlock().charFormat()){ setFormat(index, len, syntax.rules[i].format); } //only apply highlighting if not within a section already
index = patt.indexIn(text, index+len); //go to the next match
}
}//end loop over normal (single-line) patterns
+
+ //Now go through and apply any document-wide formatting rules
+ QTextCharFormat fmt;
+ fmt.setBackground( QColor( settings->value("colors/bracket-missing").toString() ) );
+ int max = syntax.char_limit();
+ if(max >= 0 && ( (text.length()+(text.count("\t")*(syntax.tab_length()-1)) )> max) ){
+ //Line longer than it should be - highlight the offending characters
+ //Need to be careful about where tabs show up in the line
+ int len = 0;
+ for(int i=0; i<text.length(); i++){
+ if(text[i]=='\t'){ len += syntax.tab_length(); }
+ else{ len++; }
+ if(len>max){ setFormat(i, text.length()-i, fmt); break; }
+ }
+ }
+ if(syntax.highlight_excess_whitespace()){
+ int last = text.length()-1;
+ while(last>=0 && (text[last]==' ' || text[last]=='\t' ) ){ last--; }
+ if(last < text.length()-1){
+ setFormat(last+1, text.length()-1-last, fmt);
+ }
+ }
}
};
#endif
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax
index c09fbec2..9a235ae3 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax
@@ -6,60 +6,57 @@
# ===================================
{
- "meta" : {
- "name" : "C++",
- "file_suffix" : ["cpp","hpp","c", "h" ]
- },
- "format" : {
- "font_type" : "monospace",
- "line_wrap" : false
- },
- "rules" : [
- {
- "name" : "multi-line comment",
- "regex_start" : "/\\*",
- "regex_end" : "\\*/",
- "foreground" : "colors/comment"
- },
- {
- "name" : "single-line comment",
- "regex" : "//[^\n]*",
- "foreground" : "colors/comment",
- },
- {
- "name" : "keywords",
- "words" : ["char", "class", "const", "double", "enum", "explicit", "extern", "float", "friend", "inline", "int", "long", "namespace", "operator", "private", "protected", "public" , "short", "signals", "signed", "slots", "static", "struct", "template", "typedef", "typename", "union", "unsigned", "virtual", "void", "volatile", "true", "false", "bool"],
- "foreground" : "colors/keyword",
- "background" : "none",
- "font_weight" : "bold"
- },
- {
- "name" : "alternate keywords",
- "words" : ["for", "while", "switch", "case", "continue", "break", "if", "else", "return", "exit"],
- "foreground" : "colors/altkeyword",
- "background" : "none",
- "font_weight" : "bold"
- },
- {
- "name" : "class names",
- "regex" : "\\b[A-Za-z0-9_-\\.]+(?=::)\\b",
- "foreground" : "colors/class",
- "font_weight" : "bold"
- },
- {
- "name" : "function names",
- "regex" : "\\b[A-Za-z0-9_]+(?=\\()",
- "foreground" : "colors/function"
- },
- {
- "name" : "text",
- "regex" : "\"[^\"\\\\]*(\\\\(.|\\n)[^\"\\\\]*)*\"|'[^'\\\\]*(\\\\(.|\\n)[^'\\\\]*)*'",
- "foreground" : "colors/text"
- },
- {
- "name" : "preprocessor",
- "regex" : "^[\\s]*#[^\n]*",
- "foreground" : "colors/preprocessor"
- }
- ]
+ "meta": {
+ "name": "C++",
+ "file_suffix": ["cpp", "hpp", "c", "h"]
+ },
+ "format": {
+ "line_wrap": false,
+ "highlight_whitespace_eol": true
+ },
+ "rules": [{
+ "name": "multi-line comment",
+ "regex_start": "/\\*",
+ "regex_end": "\\*/",
+ "foreground": "colors/comment"
+ },
+ {
+ "name": "single-line comment",
+ "regex": "//[^\n]*",
+ "foreground": "colors/comment"
+ },
+ {
+ "name": "keywords",
+ "words": ["char", "class", "const", "double", "enum", "explicit", "extern", "float", "friend", "inline", "int", "long", "namespace", "operator", "private", "protected", "public", "short", "signals", "signed", "slots", "static", "struct", "template", "typedef", "typename", "union", "unsigned", "virtual", "void", "volatile", "true", "false", "bool"],
+ "foreground": "colors/keyword",
+ "font_weight": "bold"
+ },
+ {
+ "name": "alternate keywords",
+ "words": ["for", "while", "switch", "case", "continue", "break", "if", "else", "return", "exit"],
+ "foreground": "colors/altkeyword",
+ "font_weight": "bold"
+ },
+ {
+ "name": "class names",
+ "regex": "\\b[A-Za-z0-9_-\\.]+(?=::)\\b",
+ "foreground": "colors/class",
+ "font_weight": "bold"
+ },
+ {
+ "name": "function names",
+ "regex": "\\b[A-Za-z0-9_]+(?=\\()",
+ "foreground": "colors/function"
+ },
+ {
+ "name": "text",
+ "regex": "\"[^\"\\\\]*(\\\\(.|\\n)[^\"\\\\]*)*\"|'[^'\\\\]*(\\\\(.|\\n)[^'\\\\]*)*'",
+ "foreground": "colors/text"
+ },
+ {
+ "name": "preprocessor",
+ "regex": "^[\\s]*#[^\n]*",
+ "foreground": "colors/preprocessor"
+ }
+ ]
}
diff --git a/src-qt5/desktop-utils/lumina-textedit/tests/test.cpp b/src-qt5/desktop-utils/lumina-textedit/tests/test.cpp
index e135227d..31e15eea 100644
--- a/src-qt5/desktop-utils/lumina-textedit/tests/test.cpp
+++ b/src-qt5/desktop-utils/lumina-textedit/tests/test.cpp
@@ -12,7 +12,12 @@ line
comment */
stuff
-some /*single line comment with multi-line tags */
+some /*single line comment with multi-line tags */ and other stuff
"some text"
"some text with url: http://sample.com"
+
+switch(something){
+ case 1:
+
+}
bgstack15