aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/desktop-utils/lumina-textedit
diff options
context:
space:
mode:
Diffstat (limited to 'src-qt5/desktop-utils/lumina-textedit')
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp117
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h33
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/README.md18
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax24
4 files changed, 170 insertions, 22 deletions
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp
index 0edb2160..4c3b3805 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp
+++ b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp
@@ -6,6 +6,123 @@
//===========================================
#include "syntaxSupport.h"
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QFontDatabase>
+#include <QFont>
+
+#include <LUtils.h>
+
+// ================
+// SYNTAX FILE CLASS
+// ================
+QColor SyntaxFile::colorFromOption(QString opt, QSettings *settings){
+ opt = opt.simplified();
+ if(opt.startsWith("rgb(")){
+ QStringList opts = opt.section("(",1,-1).section(")",0,0).split(",");
+ if(opts.length()!=3){ return QColor(); }
+ return QColor( opts[0].simplified().toInt(), opts[1].simplified().toInt(), opts[2].simplified().toInt() );
+ }else if(opt.startsWith("#")){
+ return QColor(opt);
+ }else if(opt.startsWith("colors/")){
+ return QColor(settings->value(opt,"").toString());
+ }
+ return QColor();
+}
+
+QString SyntaxFile::name(){
+ if(!metaObj.contains("name")){ return ""; }
+ return metaObj.value("name").toString();
+}
+
+int SyntaxFile::char_limit(){
+ if(!formatObj.contains("columns_per_line")){ return -1; }
+ int num = formatObj.value("columns_per_line").toInt();
+ return num;
+}
+
+bool SyntaxFile::highlight_excess_whitespace(){
+ if(!formatObj.contains("highlight_whitespace_eol")){ return false; }
+ return formatObj.value("highlight_whitespace_eol").toBool();
+}
+
+void SyntaxFile::SetupDocument(QPlainTextEdit* editor){
+ if(formatObj.contains("line_wrap")){
+ editor->setLineWrapMode( formatObj.value("line_wrap").toBool() ? QPlainTextEdit::WidgetWidth : QPlainTextEdit::NoWrap);
+ }
+ if(formatObj.contains("font_type")){
+ 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.setStyle(QFont::StyleNormal);
+ font.setStyleStrategy(QFont::PreferAntialias);
+ editor->document()->setDefaultFont(font);
+ }
+ if(formatObj.contains("tab_width")){
+ int num = formatObj.value("tab_width").toInt();
+ if(num<=0){ num = 8; } //UNIX Standard of 8 characters per tab
+ editor->setTabStopWidth( num * QFontMetrics(editor->document()->defaultFont()).width(" ") );
+ }
+}
+
+bool SyntaxFile::supportsFile(QString file){
+ if(metaObj.contains("file_suffix")){
+ return metaObj.value("file_suffix").toArray().contains( file.section("/",-1).section(".",-1) );
+ }
+ return false;
+}
+
+bool SyntaxFile::LoadFile(QString file, QSettings *settings){
+ QStringList contents = LUtils::readFile(file);
+ //Now trim the extra non-JSON off the beginning of the file
+ while(!contents.isEmpty()){
+ 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
+ //Save the raw meta/format objects for later
+ fileLoaded = file;
+ metaObj = obj.value("meta").toObject();
+ formatObj = obj.value("format").toObject();
+ //Now read/save the rules structure
+ QJsonArray rulesArray = obj.value("rules").toArray();
+ rules.clear();
+ //Create the blank/generic text format
+ for(int i=0; i<rulesArray.count(); i++){
+ QJsonObject rule = rulesArray[i].toObject();
+ SyntaxRule tmp;
+ //First load the rule
+ 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{ 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) ); }
+ if(rule.contains("background")){ tmp.format.setBackground( colorFromOption(rule.value("background").toString(), settings) ); }
+ if(rule.contains("font-weight")){
+ QString wgt = rule.value("font-weight").toString();
+ if(wgt =="bold"){ tmp.format.setFontWeight(QFont::Bold); }
+ if(wgt =="light"){ tmp.format.setFontWeight(QFont::Light); }
+ else{ tmp.format.setFontWeight(QFont::Normal); }
+ }
+ //Now save the rule(s) to the list
+ if(rule.contains("words")){
+ //special logic - this generates a bunch of rules all at once (one per word)
+ QJsonArray tmpArr = rule.value("words").toArray();
+ for(int a=0; a<tmpArr.count(); a++){
+ tmp.pattern = QRegExp("\\b"+tmpArr[a].toString()+"\\b"); //turn each keyword into a QRegExp and insert the rule
+ rules << tmp;
+ }
+ }else{ rules << tmp; } //just a single rule
+ }
+ return true;
+}
+
QStringList Custom_Syntax::availableRules(){
QStringList avail;
avail << "C++";
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h
index f834e275..ba4c211a 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h
+++ b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h
@@ -13,10 +13,15 @@
#include <QString>
#include <QSettings>
#include <QDebug>
+#include <QDateTime>
+#include <QJsonObject>
+#include <QPlainTextEdit>
+
//Simple syntax rules
struct SyntaxRule{
- QRegExp pattern;
+ QRegExp pattern; //single-line rule
+ QRegExp startPattern, endPattern; //multi-line rules
QTextCharFormat format;
};
//Complicated/multi-line rules
@@ -25,6 +30,32 @@ struct SyntaxRuleSplit{
QTextCharFormat format;
};
+class SyntaxFile{
+private:
+ QJsonObject metaObj;
+ QJsonObject formatObj;
+
+ QColor colorFromOption(QString opt, QSettings *settings);
+
+public:
+ QVector<SyntaxRule> rules;
+ QDateTime lastLoaded;
+ QString fileLoaded;
+
+ SyntaxFile(){}
+
+ QString name();
+ int char_limit();
+ bool highlight_excess_whitespace();
+
+ void SetupDocument(QPlainTextEdit *editor);
+ bool supportsFile(QString file); //does this syntax set support the file?
+
+ //Main Loading routine (run this before other functions)
+ bool LoadFile(QString file, QSettings *settings);
+
+};
+
class Custom_Syntax : public QSyntaxHighlighter{
Q_OBJECT
private:
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/README.md b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/README.md
index aaf134aa..0bd0616b 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/README.md
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/README.md
@@ -12,15 +12,17 @@ A small comment section may be placed at the top of the file where every line st
2. "file_suffix" : An array of suffixes for identifying which files this rule set supports.
2. A "format" object containing the following variables (file-wide formatting):
1. "columns_per_line" : (integer, optional) For file formats with line-length restrictions, this will automatically highlight/flag any "overage" of the designated limit.
- 2. "font_type" : One of the following ["fixed-width", "all", "monospace"]. This is for assisting with file formats that need characters to line up within the file (all columns are in the same place per line, etc).
- 3. "line_wrap" : (boolian, optional) Automatically enable/disable line wrapping for this type of file
-3. A "rules" object containing each of the individual rules, with the name of the rules objects being a number which corresponds to when the rule should be applied (lower numbers are applied before higher numbers). The required fields are:
- 1. "name" : Not directly used by LTE (yet) - but is useful for noting what each rule is for
- 2. Exactly **one** of the following fields must also be included:
+ 2. "highlight_whitespace_eol" : (boolian, optional) Highlight any excess whitespace at the end of a line.
+ 3. "font_type" : (optional) One of the following ["all", "monospace"]. This is for assisting with file formats that need characters to line up within the file (all columns are in the same place per line, etc).
+ 4. "line_wrap" : (boolian) Automatically enable/disable line wrapping for this type of file
+ 5. "tab_width" : (integer - 8 by default) Have tabs automatically take up this many characters.
+3. A "rules" array containing each of the individual rules (earlier rules are applied before later ones). The required fields for a rule are:
+ 1. "name" : Not directly used by LTE (yet) - but is useful for noting the purpose of each rule
+ 2. Exactly **one** of the following options must also be included:
1. "words" : Array of exact words/text which should be matched (automatically converted to a regular expression with a break on either side of the word)
2. "regex" : single-line regular expression to be used for finding matching text
3. "regex_start" **and** "regex_end" : multi-line regular expression. Everything between the start/end matches will be highlighted.
- 3. At least **one** of the following fields should also be supplied (format of any text matches)
+ 3. At least **one** of the following fields should also be supplied:
1. "foreground" : Font color of the matching text (see the Colors section for additional information)
2. "background" : Highlighting color of the matching text (see the Colors section for additional information)
3. "font-weight" : One of the following ["bold","normal", "light"]. Changes the thickness of the font for the matching text
@@ -30,9 +32,9 @@ There are a number of built-in colors which may be defined by the user, and thes
`"colors/[name of color]"`
The currently-valid colors are: ["keyword", "altkeyword", "class", "text", "function", "comment", "bracket-found", "bracket-missing"].
-Alternatively, an RGB (0-255)or Hex color code may be used instead (please limit this though - it can conflict with the user's preferred color scheme quite badly)
+Alternatively, an RGB (0-255) or Hex color code may be used instead (please limit this though - it can conflict with the user's preferred color scheme quite badly)
Examples:
- `"foreground" : "rgb(10,10,15)"`
+ `"foreground" : "rgb(10,10,255)"`
`"background" : "colors/text"`
`"foreground" : "#0F0F0F"`
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 d5a5e4d9..c09fbec2 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax
@@ -11,57 +11,55 @@
"file_suffix" : ["cpp","hpp","c", "h" ]
},
"format" : {
- "columns_per_line" : -1,
- "font_type" : "fixed-width",
+ "font_type" : "monospace",
"line_wrap" : false
},
- "rules" : {
- "1" : {
+ "rules" : [
+ {
"name" : "multi-line comment",
"regex_start" : "/\\*",
"regex_end" : "\\*/",
"foreground" : "colors/comment"
},
- "2" : {
+ {
"name" : "single-line comment",
"regex" : "//[^\n]*",
"foreground" : "colors/comment",
},
- "3" : {
+ {
"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"
},
- "4" : {
+ {
"name" : "alternate keywords",
"words" : ["for", "while", "switch", "case", "continue", "break", "if", "else", "return", "exit"],
"foreground" : "colors/altkeyword",
"background" : "none",
"font_weight" : "bold"
},
- "5" : {
+ {
"name" : "class names",
"regex" : "\\b[A-Za-z0-9_-\\.]+(?=::)\\b",
"foreground" : "colors/class",
"font_weight" : "bold"
},
- "6" : {
+ {
"name" : "function names",
"regex" : "\\b[A-Za-z0-9_]+(?=\\()",
"foreground" : "colors/function"
},
- "7" : {
+ {
"name" : "text",
"regex" : "\"[^\"\\\\]*(\\\\(.|\\n)[^\"\\\\]*)*\"|'[^'\\\\]*(\\\\(.|\\n)[^'\\\\]*)*'",
"foreground" : "colors/text"
},
- "8" : {
+ {
"name" : "preprocessor",
"regex" : "^[\\s]*#[^\n]*",
"foreground" : "colors/preprocessor"
}
-
- }
+ ]
}
bgstack15