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/MainUI.cpp21
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp46
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h5
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax7
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/go.syntax49
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/html.syntax74
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/javascript.syntax54
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/json.syntax2
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/md.syntax103
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/php.syntax49
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/python.syntax7
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/tests/test.go185
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/tests/test.html20
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/tests/test.js44
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/tests/test.md53
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/tests/test.php224
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/tests/test.py17
17 files changed, 934 insertions, 26 deletions
diff --git a/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp b/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp
index 145c7c7e..65979c46 100644
--- a/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp
+++ b/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp
@@ -18,6 +18,7 @@
#include <QTimer>
#include <QMessageBox>
#include <QActionGroup>
+#include "PlainTextEditor.h"
MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
ui->setupUi(this);
@@ -118,7 +119,7 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
}
MainUI::~MainUI(){
-
+
}
void MainUI::LoadArguments(QStringList args){ //CLI arguments
@@ -156,7 +157,7 @@ void MainUI::updateIcons(){
ui->tool_replace_all->setIcon(LXDG::findIcon("arrow-down-double"));
ui->tool_hideReplaceGroup->setIcon(LXDG::findIcon("dialog-close",""));
//ui->tool_find_next->setIcon(LXDG::findIcon(""));
-
+
QTimer::singleShot(0,colorDLG, SLOT(updateIcons()) );
}
@@ -255,6 +256,7 @@ void MainUI::changeFontSize(int newFontSize){
QFont currentFont = currentEditor()->document()->defaultFont();
currentFont.setPointSize(newFontSize);
currentEditor()->document()->setDefaultFont(currentFont);
+ currentEditor()->updateLNW();
}
void MainUI::changeTabsLocation(QAction *act){
@@ -301,10 +303,12 @@ void MainUI::showLineNumbers(bool show){
void MainUI::wrapLines(bool wrap){
settings->setValue("wrapLines",wrap);
- for(int i=0; i<tabWidget->count(); i++){
+ if(currentEditor() == 0){ return; }
+ currentEditor()->setLineWrapMode( wrap ? QPlainTextEdit::WidgetWidth : QPlainTextEdit::NoWrap);
+ /*for(int i=0; i<tabWidget->count(); i++){
PlainTextEditor *edit = static_cast<PlainTextEditor*>(tabWidget->widget(i));
edit->setLineWrapMode( wrap ? QPlainTextEdit::WidgetWidth : QPlainTextEdit::NoWrap);
- }
+ }*/
}
void MainUI::ModifyColors(){
@@ -351,6 +355,7 @@ void MainUI::tabChanged(){
//Update the font/size widgets to reflect what is set on this tab
fontbox->setCurrentFont(font);
fontSizes->setValue( font.pointSize() );
+ ui->actionWrap_Lines->setChecked( cur->lineWrapMode()==QPlainTextEdit::WidgetWidth );
}
void MainUI::tabClosed(int tab){
@@ -389,7 +394,7 @@ void MainUI::tabDraggedOut(int tab, Qt::DropAction act){
void MainUI::closeFindReplace(){
ui->groupReplace->setVisible(false);
PlainTextEditor *cur = currentEditor();
- if(cur!=0){ cur->setFocus(); }
+ if(cur!=0){ cur->setFocus(); }
}
void MainUI::openFind(){
@@ -397,8 +402,8 @@ void MainUI::openFind(){
if(cur==0){ return; }
ui->groupReplace->setVisible(true);
ui->line_find->setText( cur->textCursor().selectedText() );
- ui->line_replace->setText("");
- ui->line_find->setFocus();
+ ui->line_replace->setText("");
+ ui->line_find->setFocus();
}
void MainUI::openReplace(){
@@ -406,7 +411,7 @@ void MainUI::openReplace(){
if(cur==0){ return; }
ui->groupReplace->setVisible(true);
ui->line_find->setText( cur->textCursor().selectedText() );
- ui->line_replace->setText("");
+ ui->line_replace->setText("");
ui->line_replace->setFocus();
}
diff --git a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp
index a1b77732..653bd0e8 100644
--- a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp
+++ b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp
@@ -43,7 +43,7 @@ PlainTextEditor::PlainTextEditor(QSettings *set, QWidget *parent) : QPlainTextEd
}
PlainTextEditor::~PlainTextEditor(){
-
+
}
void PlainTextEditor::showLineNumbers(bool show){
@@ -60,13 +60,14 @@ void PlainTextEditor::LoadSyntaxRule(QString type){
SYNTAX->loadRules(files[i]);
break;
}
+ if(i==files.length()-1){ SyntaxFile dummy; SYNTAX->loadRules(dummy); }
}
SYNTAX->rehighlight();
}
void PlainTextEditor::updateSyntaxColors(){
SYNTAX->reloadRules();
- SYNTAX->rehighlight();
+ SYNTAX->rehighlight();
}
//File loading/setting options
@@ -77,7 +78,7 @@ void PlainTextEditor::LoadFile(QString filepath){
this->clear();
QList<SyntaxFile> files = SyntaxFile::availableFiles(settings);
for(int i=0; i<files.length(); i++){
- if(files[i].supportsFile(filepath) ){
+ if(files[i].supportsFile(filepath) ){
files[i].SetupDocument(this);
SYNTAX->loadRules(files[i]);
break;
@@ -125,7 +126,7 @@ QString PlainTextEditor::currentFile(){
}
bool PlainTextEditor::hasChange(){
- return hasChanges;
+ return hasChanges;
}
//Functions for managing the line number widget
@@ -134,11 +135,16 @@ int PlainTextEditor::LNWWidth(){
int lines = this->blockCount();
if(lines<1){ lines = 1; }
int chars = 1;
+ //qDebug() << "point 1" << this->document()->defaultFont();
while(lines>=10){ chars++; lines/=10; }
- return (this->fontMetrics().width("9")*chars); //make sure to add a tiny bit of padding
+ QFontMetrics metrics(this->document()->defaultFont());
+ return (metrics.width("9")*chars); //make sure to add a tiny bit of padding
}
void PlainTextEditor::paintLNW(QPaintEvent *ev){
+ //qDebug() << "Paint LNW Event:" << ev->rect() << LNW->geometry();
+ //if(ev->rect().height() < (QFontMetrics(this->document()->defaultFont()).height() *1.5) ){ return; }
+ //qDebug() << " -- paint line numbers";
QPainter P(LNW);
//First set the background color
P.fillRect(ev->rect(), QColor("lightgrey"));
@@ -146,19 +152,27 @@ void PlainTextEditor::paintLNW(QPaintEvent *ev){
QTextBlock block = this->firstVisibleBlock();
int bTop = blockBoundingGeometry(block).translated(contentOffset()).top();
int bBottom;
+// QFont font = P.font();
+// font.setPointSize(this->document()->defaultFont().pointSize());
+ P.setFont(this->document()->defaultFont());
//Now loop over the blocks (lines) and write in the numbers
+ QFontMetrics metrics(this->document()->defaultFont());
+ //qDebug() << "point 2" << this->document()->defaultFont();
P.setPen(Qt::black); //setup the font color
while(block.isValid() && bTop<=ev->rect().bottom()){ //ensure block below top of viewport
bBottom = bTop+blockBoundingRect(block).height();
if(block.isVisible() && bBottom >= ev->rect().top()){ //ensure block above bottom of viewport
- P.drawText(0,bTop, LNW->width(), this->fontMetrics().height(), Qt::AlignRight, QString::number(block.blockNumber()+1) );
+ P.drawText(0,bTop, LNW->width(), metrics.height(), Qt::AlignRight, QString::number(block.blockNumber()+1) );
+ //qDebug() << "bTop" << bTop;
+ //qDebug() << "LNW->width()" << LNW->width();
+ //qDebug() << "metrics.height()" << metrics.height();
}
//Go to the next block
block = block.next();
bTop = bBottom;
}
}
-
+
//==============
// PRIVATE
//==============
@@ -177,7 +191,7 @@ void PlainTextEditor::clearMatchData(){
void PlainTextEditor::highlightMatch(QChar ch, bool forward, int fromPos, QChar startch){
if(forward){ matchleft = fromPos; }
else{ matchright = fromPos; }
-
+
int nested = 1; //always start within the first nest (the primary nest)
int tmpFromPos = fromPos;
//if(!forward){ tmpFromPos++; } //need to include the initial location
@@ -192,7 +206,7 @@ void PlainTextEditor::highlightMatch(QChar ch, bool forward, int fromPos, QChar
}else{ break; }
}else{
QTextCursor cur = this->document()->find(ch, tmpFromPos, QTextDocument::FindBackward);
- if(!cur.isNull()){
+ if(!cur.isNull()){
QString mid = doc.mid(cur.position()-1, tmpFromPos-cur.position()+1);
//qDebug() << "Found backwards match:" << nested << startch << ch << mid;
//qDebug() << doc.mid(cur.position(),1) << doc.mid(tmpFromPos,1);
@@ -202,10 +216,10 @@ void PlainTextEditor::highlightMatch(QChar ch, bool forward, int fromPos, QChar
}else{ break; }
}
}
-
+
//Now highlight the two characters
- QList<QTextEdit::ExtraSelection> sels = this->extraSelections();
- if(matchleft>=0){
+ QList<QTextEdit::ExtraSelection> sels = this->extraSelections();
+ if(matchleft>=0){
QTextEdit::ExtraSelection sel;
if(matchright>=0){ sel.format.setBackground( QColor(settings->value("colors/bracket-found").toString()) ); }
else{ sel.format.setBackground( QColor(settings->value("colors/bracket-missing").toString()) ); }
@@ -225,7 +239,7 @@ void PlainTextEditor::highlightMatch(QChar ch, bool forward, int fromPos, QChar
if(!forward){ cur.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); }
else{ cur.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); }
sel.cursor = cur;
- sels << sel;
+ sels << sel;
}
this->setExtraSelections(sels);
}
@@ -314,7 +328,7 @@ void PlainTextEditor::fileChanged(){
text.append("\n");
text.append( tr("(Note: You will lose all currently-unsaved changes)") );
text.append("\n\n%1");
-
+
if(!update){
update = (QMessageBox::Yes == QMessageBox::question(this, tr("File Modified"),text.arg(currentFile()) , QMessageBox::Yes | QMessageBox::No, QMessageBox::No) );
}
@@ -333,3 +347,7 @@ void PlainTextEditor::resizeEvent(QResizeEvent *ev){
QRect cGeom = this->contentsRect();
LNW->setGeometry( QRect(cGeom.left(), cGeom.top(), LNWWidth(), cGeom.height()) );
}
+
+void PlainTextEditor::updateLNW(){
+ LNW_updateWidth();
+}
diff --git a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h
index 64ff256b..0c83b7ce 100644
--- a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h
+++ b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h
@@ -37,6 +37,9 @@ public:
//Functions for managing the line number widget (internal - do not need to run directly)
int LNWWidth(); //replacing the LNW size hint detection
void paintLNW(QPaintEvent *ev); //forwarded from the LNW paint event
+ void updateLNW();
+
+ QFontMetrics *metrics;
private:
QWidget *LNW; //Line Number Widget
@@ -65,7 +68,7 @@ private slots:
void textChanged();
void cursorMoved();
//Function for prompting the user if the file changed externally
- void fileChanged();
+ void fileChanged();
protected:
void resizeEvent(QResizeEvent *ev);
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 9a235ae3..f504263e 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/cpp.syntax
@@ -27,7 +27,7 @@
},
{
"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"],
+ "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", "using","unsigned", "virtual", "void", "volatile", "true", "false", "bool"],
"foreground": "colors/keyword",
"font_weight": "bold"
},
@@ -44,6 +44,11 @@
"font_weight": "bold"
},
{
+ "name": "numbers",
+ "regex" : "\\b[0-9\\.]+\\b",
+ "foreground": "colors/text"
+ },
+ {
"name": "function names",
"regex": "\\b[A-Za-z0-9_]+(?=\\()",
"foreground": "colors/function"
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/go.syntax b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/go.syntax
new file mode 100644
index 00000000..3eff96c1
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/go.syntax
@@ -0,0 +1,49 @@
+# Syntax support file for the Lumina Text Editor
+# ===================================
+# Go language support rules
+# Written by Zackary Welch <zwelch@ixsystems.com>
+# Released under the 2-clause BSD license
+# ===================================
+
+{
+ "meta": {
+ "name": "Go",
+ "file_suffix": ["go"]
+ },
+ "format": {
+ "line_wrap": false,
+ "highlight_whitespace_eol" : false
+ },
+ "rules": [{
+ "name": "keywords",
+ "words": ["break", "default", "func", "interface", "select", "case", "defer", "go", "map", "struct", "chan", "else", "goto", "package", "switch", "const", "fallthrough", "if", "range", "type", "continue", "for", "import", "return", "var", "uint32", "uint64", "float32", "float64"],
+ "foreground": "colors/keyword"
+ },
+ {
+ "name": "single-line comment",
+ "regex": "//[^\n]*",
+ "foreground": "colors/comment"
+ },
+ {
+ "name": "multi-line comment",
+ "regex_start": "/\\*",
+ "regex_end": "\\*/",
+ "foreground": "colors/comment"
+ },
+ {
+ "name": "numbers",
+ "regex": "\\b[0-9]+\\.?[0-9]*\\b|[0-9]+e[\\+\\-]?[0-9]+",
+ "foreground": "colors/altkeyword"
+ },
+ {
+ "name": "function names",
+ "regex": "\\b[A-Za-z0-9_]+(?=\\()",
+ "foreground": "colors/class"
+ },
+ {
+ "name" : "text",
+ "regex": "\"[^\"\\\\]*(\\\\(.|\\n)[^\"\\\\]*)*\"|'[^'\\\\]*(\\\\(.|\\n)[^'\\\\]*)*'",
+ "foreground" : "colors/text"
+ }
+ ]
+}
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/html.syntax b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/html.syntax
new file mode 100644
index 00000000..22567a9b
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/html.syntax
@@ -0,0 +1,74 @@
+# Syntax support file for the Lumina Text Editor
+# ===================================
+# HTML language support rules
+# Written by Ken Moore <ken@ixsystems.com>
+# Released under the 2-clause BSD license
+# ===================================
+
+{
+ "meta": {
+ "name": "HTML",
+ "file_suffix": ["html", "htm"]
+ },
+ "format": {
+ "line_wrap": false,
+ "highlight_whitespace_eol" : true,
+ "font_type" : "monospace",
+ "tab_width": 8
+ },
+ "rules": [{
+ "name": "8 spaces rather than a tab",
+ "regex": "([ ]{8})+",
+ "background": "colors/bracket-missing"
+ },
+ {
+ "name": "tabs after spaces",
+ "regex": "( )+\\t",
+ "background": "colors/bracket-missing"
+ },
+ {
+ "name" : "odd number of spaces within indentation",
+ "regex": "(^|\\t)([ ]{2})*[ ](?=\\<)",
+ "background": "colors/bracket-missing"
+ },
+ {
+ "name" : "ID of a tag",
+ "regex": "<[^> ]+[>]?",
+ "font_weight" : "bold",
+ "foreground" : "colors/function"
+ },
+ {
+ "name" : "tag modifiers",
+ "regex" : "\\s[^\\= ]+(?=\\=)",
+ "foreground" : "colors/class"
+ },
+ {
+ "name" : "strings inside a tag",
+ "regex": "\\\"[^\\\"]*\\\"",
+ "foreground" : "colors/text"
+ },
+ {
+ "name" : "comment",
+ "regex_start" : "<!DOCTYPE",
+ "regex_end" : "[/]?>",
+ "foreground" : "colors/comment"
+ },
+ {
+ "name" : "comment",
+ "regex_start" : "<!--",
+ "regex_end" : "-->",
+ "foreground" : "colors/comment"
+ },
+ {
+ "name" : "escapes",
+ "regex" : "&[^;]*;",
+ "foreground" : "colors/preprocessor"
+ },
+ {
+ "name" : "HTML preprocessor",
+ "regex_start" : "\\<\\?html ",
+ "regex_end" : "\\?>",
+ "foreground" : "colors/preprocessor"
+ }
+ ]
+}
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/javascript.syntax b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/javascript.syntax
new file mode 100644
index 00000000..02e1092a
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/javascript.syntax
@@ -0,0 +1,54 @@
+# Syntax support file for the Lumina Text Editor
+# ===================================
+# Javascript language support rules
+# Written by Ken Moore <ken@ixsystems.com>
+# Released under the 2-clause BSD license
+# ===================================
+
+{
+ "meta": {
+ "name": "Javascript",
+ "file_suffix": ["js"]
+ },
+ "format": {
+ "line_wrap": false,
+ "highlight_whitespace_eol" : false
+ },
+ "rules": [{
+ "name": "keywords",
+ "words": ["export","function", "import", "from", "let", "if", "return", "for", "while"],
+ "foreground": "colors/keyword"
+ },
+ {
+ "name": "single-line comment",
+ "regex": "//[^\n]*",
+ "foreground": "colors/comment"
+ },
+ {
+ "name": "multi-line comment",
+ "regex_start": "/\\*",
+ "regex_end": "\\*/",
+ "foreground": "colors/comment"
+ },
+ {
+ "name": "numbers",
+ "regex": "\\b[0-9]+\\.?[0-9]*\\b",
+ "foreground": "colors/altkeyword"
+ },
+ {
+ "name": "attributes",
+ "regex": "(\\.)[A-Za-z_][A-Za-z0-9_]*(?![\\(a-zA-Z0-9])",
+ "foreground": "colors/function"
+ },
+ {
+ "name": "function names",
+ "regex": "\\b[A-Za-z0-9_]+(?=\\()",
+ "foreground": "colors/class"
+ },
+ {
+ "name" : "text",
+ "regex": "\"[^\"\\\\]*(\\\\(.|\\n)[^\"\\\\]*)*\"|'[^'\\\\]*(\\\\(.|\\n)[^'\\\\]*)*'",
+ "foreground" : "colors/text"
+ }
+ ]
+}
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/json.syntax b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/json.syntax
index fdca7211..ab67d384 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/json.syntax
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/json.syntax
@@ -8,7 +8,7 @@
{
"meta": {
"name": "JSON",
- "file_suffix": ["json"]
+ "file_suffix": ["json", "syntax"]
},
"format": {
"line_wrap": false,
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/md.syntax b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/md.syntax
new file mode 100644
index 00000000..2ba4bca7
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/md.syntax
@@ -0,0 +1,103 @@
+# Syntax support file for the Lumina Text Editor
+# ===================================
+# Markdown language support rules
+# Written by Zackary Welch <zwelch@ixsystems.com>
+# Released under the 2-clause BSD license
+# ===================================
+
+{
+ "meta": {
+ "name": "Markdown",
+ "file_suffix": ["md", "markdown"]
+ },
+ "format": {
+ "line_wrap": true,
+ "highlight_whitespace_eol" : false,
+ "tab_width" : 4
+ },
+ "rules": [{
+ "name": "links",
+ "regex": "\\[[^\\[\\]]+\\]\\(#?[^\\s\\]\\)\\[\\(]*\\)",
+ "foreground": "colors/keyword"
+ },
+ {
+ "name": "bold and italic",
+ "regex" : "[\\*]{3}(?!\\s)[^\\*\\_]+(?!\\s)[\\*]{3}",
+ "foreground": "colors/altkeyword",
+ "font_weight" : "bold",
+ "font_style" : "italic"
+ },
+ {
+ "name": "bold",
+ "regex" : "[\\*]{2}(?!\\s)[^\\*\\_]+(?!\\s)[\\*]{2}",
+ "foreground": "colors/altkeyword",
+ "font_weight" : "bold"
+ },
+ {
+ "name": "italic",
+ "regex" : "[\\*](?!\\s){1}[^\\*\\_]+(?!\\s)[\\*]{1}",
+ "foreground": "colors/altkeyword",
+ "font_style" : "italic"
+ },
+ {
+ "name": "bold and italic",
+ "regex" : "[_]{3}(?!\\s)[^\\*\\_]+(?!\\s)[_]{3}",
+ "foreground": "colors/altkeyword",
+ "font_weight" : "bold",
+ "font_style" : "italic"
+ },
+ {
+ "name": "bold",
+ "regex" : "[_]{2}(?!\\s)[^\\*\\_]+(?!\\s)[_]{2}",
+ "foreground": "colors/altkeyword",
+ "font_weight" : "bold"
+ },
+ {
+ "name": "italic",
+ "regex" : "[_]{1}(?!\\s)[^\\*\\_]+(?!\\s)[_]{1}",
+ "foreground": "colors/altkeyword",
+ "font_style" : "italic"
+ },
+ {
+ "name" : "markup",
+ "regex": "<[a-z].*><\\/[a-z]>",
+ "foreground" : "colors/class"
+ },
+ {
+ "name" : "heading",
+ "regex": "^#+ (.)*$",
+ "foreground" : "colors/function"
+ },
+ {
+ "name" : "horizontal rule",
+ "regex": "^((\\-\\s*\\-\\s*\\-\\s*)|(\\*\\s*\\*\\s*\\*)|(\\_\\s*\\_\\s*\\_\\s*))$",
+ "foreground" : "colors/function"
+ },
+ {
+ "name" : "multi-line code block",
+ "regex_start" : "^```$",
+ "regex_end" : "^```$",
+ "foreground" : "colors/comment"
+ },
+ {
+ "name" : "in-line code block",
+ "regex" : "`([^`])+`",
+ "foreground" : "colors/comment"
+ },
+ {
+ "name" : "block quote",
+ "regex" : "^(\\> )+",
+ "foreground" : "colors/keyword"
+ },
+ {
+ "name" : "lists",
+ "regex" : "^\\s*([0-9].|[\\*\\+\\-]{1})\\s+",
+ "foreground" : "colors/function"
+ },
+ {
+ "name" : "text",
+ "regex": "\"[^\"\\\\]*(\\\\(.|\\n)[^\"\\\\]*)*\"|'[^'\\\\]*(\\\\(.|\\n)[^'\\\\]*)*'",
+ "foreground" : "colors/text"
+ }
+ ]
+}
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/php.syntax b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/php.syntax
new file mode 100644
index 00000000..15f6e2a5
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/php.syntax
@@ -0,0 +1,49 @@
+# Syntax support file for the Lumina Text Editor
+# ===================================
+# PHP language support rules
+# Written by Zackary Welch <zwelch@ixsystems.com>
+# Released under the 2-clause BSD license
+# ===================================
+
+{
+ "meta": {
+ "name": "PHP",
+ "file_suffix": ["php"]
+ },
+ "format": {
+ "line_wrap": false,
+ "highlight_whitespace_eol" : false
+ },
+ "rules": [{
+ "name": "keywords",
+ "words": ["private", "public", "class", "function", "const", "return", "if", "else", "bool", "abstract", "and", "as", "break", "case", "catch", "const", "do", "echo", "int", "elseif", "default", "endif", "endfor", "final", "for", "foreach", "extends", "global", "include", "interface", "new", "or", "protected", "require", "static", "switch", "throw", "try", "use", "var", "while", "xor"],
+ "foreground": "colors/keyword"
+ },
+ {
+ "name": "single-line comment",
+ "regex": "[//#][^\n]*",
+ "foreground": "colors/comment"
+ },
+ {
+ "name": "multi-line comment",
+ "regex_start": "/\\*",
+ "regex_end": "\\*/",
+ "foreground": "colors/comment"
+ },
+ {
+ "name": "numbers",
+ "regex": "\\b[0-9]+\\.?[0-9]*\\b",
+ "foreground": "colors/altkeyword"
+ },
+ {
+ "name": "function names",
+ "regex": "\\b[A-Za-z0-9_]+(?=\\()",
+ "foreground": "colors/class"
+ },
+ {
+ "name" : "text",
+ "regex": "\"[^\"\\\\]*(\\\\(.|\\n)[^\"\\\\]*)*\"|'[^'\\\\]*(\\\\(.|\\n)[^'\\\\]*)*'",
+ "foreground" : "colors/text"
+ }
+ ]
+}
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/python.syntax b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/python.syntax
index f6d2223d..6690d98c 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/python.syntax
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/python.syntax
@@ -7,7 +7,7 @@
{
"meta": {
- "name": "Python (Experimental)",
+ "name": "Python",
"file_suffix": ["py", "pyc"]
},
"format": {
@@ -37,6 +37,11 @@
"foreground": "colors/function"
},
{
+ "name": "numbers",
+ "regex" : "\\b[0-9]+\\.?[0-9]*\\b",
+ "foreground": "colors/altkeyword"
+ },
+ {
"name": "text",
"regex": "\"[^\"\\\\]*(\\\\(.|\\n)[^\"\\\\]*)*\"|'[^'\\\\]*(\\\\(.|\\n)[^'\\\\]*)*'",
"foreground": "colors/text"
diff --git a/src-qt5/desktop-utils/lumina-textedit/tests/test.go b/src-qt5/desktop-utils/lumina-textedit/tests/test.go
new file mode 100644
index 00000000..0ae9b2dc
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-textedit/tests/test.go
@@ -0,0 +1,185 @@
+// Source: https://github.com/golang/geo
+/*
+Copyright 2014 Google Inc. All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package r3
+
+import (
+ "fmt"
+ "math"
+
+ "github.com/golang/geo/s1"
+)
+
+// Vector represents a point in ℝ³.
+type Vector struct {
+ X, Y, Z float64
+}
+
+// ApproxEqual reports whether v and ov are equal within a small epsilon.
+func (v Vector) ApproxEqual(ov Vector) bool {
+ const epsilon = 1e-16
+ return math.Abs(v.X-ov.X) < epsilon && math.Abs(v.Y-ov.Y) < epsilon && math.Abs(v.Z-ov.Z) < epsilon
+}
+
+func (v Vector) String() string { return fmt.Sprintf("(%0.24f, %0.24f, %0.24f)", v.X, v.Y, v.Z) }
+
+// Norm returns the vector's norm.
+func (v Vector) Norm() float64 { return math.Sqrt(v.Dot(v)) }
+
+// Norm2 returns the square of the norm.
+func (v Vector) Norm2() float64 { return v.Dot(v) }
+
+// Normalize returns a unit vector in the same direction as v.
+func (v Vector) Normalize() Vector {
+ if v == (Vector{0, 0, 0}) {
+ return v
+ }
+ return v.Mul(1 / v.Norm())
+}
+
+// IsUnit returns whether this vector is of approximately unit length.
+func (v Vector) IsUnit() bool {
+ const epsilon = 5e-14
+ return math.Abs(v.Norm2()-1) <= epsilon
+}
+
+// Abs returns the vector with nonnegative components.
+func (v Vector) Abs() Vector { return Vector{math.Abs(v.X), math.Abs(v.Y), math.Abs(v.Z)} }
+
+// Add returns the standard vector sum of v and ov.
+func (v Vector) Add(ov Vector) Vector { return Vector{v.X + ov.X, v.Y + ov.Y, v.Z + ov.Z} }
+
+// Sub returns the standard vector difference of v and ov.
+func (v Vector) Sub(ov Vector) Vector { return Vector{v.X - ov.X, v.Y - ov.Y, v.Z - ov.Z} }
+
+// Mul returns the standard scalar product of v and m.
+func (v Vector) Mul(m float64) Vector { return Vector{m * v.X, m * v.Y, m * v.Z} }
+
+// Dot returns the standard dot product of v and ov.
+func (v Vector) Dot(ov Vector) float64 { return v.X*ov.X + v.Y*ov.Y + v.Z*ov.Z }
+
+// Cross returns the standard cross product of v and ov.
+func (v Vector) Cross(ov Vector) Vector {
+ return Vector{
+ v.Y*ov.Z - v.Z*ov.Y,
+ v.Z*ov.X - v.X*ov.Z,
+ v.X*ov.Y - v.Y*ov.X,
+ }
+}
+
+// Distance returns the Euclidean distance between v and ov.
+func (v Vector) Distance(ov Vector) float64 { return v.Sub(ov).Norm() }
+
+// Angle returns the angle between v and ov.
+func (v Vector) Angle(ov Vector) s1.Angle {
+ return s1.Angle(math.Atan2(v.Cross(ov).Norm(), v.Dot(ov))) * s1.Radian
+}
+
+// Axis enumerates the 3 axes of ℝ³.
+type Axis int
+
+// The three axes of ℝ³.
+const (
+ XAxis Axis = iota
+ YAxis
+ ZAxis
+)
+
+// Ortho returns a unit vector that is orthogonal to v.
+// Ortho(-v) = -Ortho(v) for all v.
+func (v Vector) Ortho() Vector {
+ ov := Vector{0.012, 0.0053, 0.00457}
+ switch v.LargestComponent() {
+ case XAxis:
+ ov.Z = 1
+ case YAxis:
+ ov.X = 1
+ default:
+ ov.Y = 1
+ }
+ return v.Cross(ov).Normalize()
+}
+
+// LargestComponent returns the axis that represents the largest component in this vector.
+func (v Vector) LargestComponent() Axis {
+ t := v.Abs()
+
+ if t.X > t.Y {
+ if t.X > t.Z {
+ return XAxis
+ }
+ return ZAxis
+ }
+ if t.Y > t.Z {
+ return YAxis
+ }
+ return ZAxis
+}
+
+// SmallestComponent returns the axis that represents the smallest component in this vector.
+func (v Vector) SmallestComponent() Axis {
+ t := v.Abs()
+
+ if t.X < t.Y {
+ if t.X < t.Z {
+ return XAxis
+ }
+ return ZAxis
+ }
+ if t.Y < t.Z {
+ return YAxis
+ }
+ return ZAxis
+}
+
+// Cmp compares v and ov lexicographically and returns:
+//
+// -1 if v < ov
+// 0 if v == ov
+// +1 if v > ov
+//
+// This method is based on C++'s std::lexicographical_compare. Two entities
+// are compared element by element with the given operator. The first mismatch
+// defines which is less (or greater) than the other. If both have equivalent
+// values they are lexicographically equal.
+func (v Vector) Cmp(ov Vector) int {
+ if v.X < ov.X {
+ return -1
+ }
+ if v.X > ov.X {
+ return 1
+ }
+
+ // First elements were the same, try the next.
+ if v.Y < ov.Y {
+ return -1
+ }
+ if v.Y > ov.Y {
+ return 1
+ }
+
+ // Second elements were the same return the final compare.
+ if v.Z < ov.Z {
+ return -1
+ }
+ if v.Z > ov.Z {
+ return 1
+ }
+
+ // Both are equal
+ return 0
+}
diff --git a/src-qt5/desktop-utils/lumina-textedit/tests/test.html b/src-qt5/desktop-utils/lumina-textedit/tests/test.html
new file mode 100644
index 00000000..a83618bc
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-textedit/tests/test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <title>Spoon-Knife</title>
+ <LINK href="styles.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+
+<img src="forkit.gif" id="octocat" alt="" />
+
+<!-- Feel free to change this text here -->
+<p>
+ Fork me? Fork you, @octocat!
+</p>
+
+</body>
+</html>
diff --git a/src-qt5/desktop-utils/lumina-textedit/tests/test.js b/src-qt5/desktop-utils/lumina-textedit/tests/test.js
new file mode 100644
index 00000000..696cd74d
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-textedit/tests/test.js
@@ -0,0 +1,44 @@
+import { distance } from "./math.js";
+import { polygonCentroid } from "d3-polygon";
+
+export default function(start, end) {
+ let distances = start.map(p1 => end.map(p2 => squaredDistance(p1, p2))),
+ order = bestOrder(start, end, distances);
+
+ // Don't permute huge array
+ if (start.length > 8) {
+ return start.map((d, i) => i);
+ }
+ return bestOrder(start, end, distances);
+}
+
+export function bestOrder(start, end, distances) {
+ let min = Infinity,
+ best = start.map((d, i) => i);
+
+ function permute(arr, order = [], sum = 0) {
+ for (let i = 0; i < arr.length; i++) {
+ let cur = arr.splice(i, 1),
+ dist = distances[cur[0]][order.length];
+ if (sum + dist < min) {
+ if (arr.length) {
+ permute(arr.slice(), order.concat(cur), sum + dist);
+ } else {
+ min = sum + dist;
+ best = order.concat(cur);
+ }
+ }
+ if (arr.length) {
+ arr.splice(i, 0, cur[0]);
+ }
+ }
+ }
+
+ permute(best);
+ return best;
+}
+
+function squaredDistance(p1, p2) {
+ let d = distance(polygonCentroid(p1), polygonCentroid(p2));
+ return d * d;
+}
diff --git a/src-qt5/desktop-utils/lumina-textedit/tests/test.md b/src-qt5/desktop-utils/lumina-textedit/tests/test.md
new file mode 100644
index 00000000..fc6bc78b
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-textedit/tests/test.md
@@ -0,0 +1,53 @@
+
+# Header
+
+## Header 2
+
+## Header 3
+
+*Italic*
+
+**Bold**
+***Bold and Italic***
+***a***
+
+_Italic_
+__Bold__
+___Bold and Italic___
+___a___
+[link](link)
+
+Some [link](link) within a text block.
+
+Some [text](link) within a text block with another [Link](Link) in it.
+
+Horizontal Rules
+---
+***
+___
+* * *
+_ _ _
+* * *
+
+some `in-line code block` test in `a line`.
+
+some
+```
+multi-line
+code block
+```
+outside block
+
+quote
+
+> > I like cheese > whine.
+> Is what he said
+
+* Bullet List
+ * Indented bullet list
+ * indented 2 bullet list
+
+- or this bullet
+
+1. or this numbered list
+2. second item
diff --git a/src-qt5/desktop-utils/lumina-textedit/tests/test.php b/src-qt5/desktop-utils/lumina-textedit/tests/test.php
new file mode 100644
index 00000000..d297c16b
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-textedit/tests/test.php
@@ -0,0 +1,224 @@
+<?php
+
+class Mail
+{
+ private $from = ['name' => '', 'email' => ''];
+ private $to = [];
+ private $subject = '';
+ private $message = '';
+ private $files = [];
+ private $multipart = false;
+ private $boundary = '';
+ private $uniqId = '';
+ private $replyTo = [];
+ private $timestamp = null;
+
+ const CRLF = "\r\n";
+
+
+ public function __construct()
+ {
+ $this->uniqId = '<php-mail-' . md5(microtime()) . mt_rand() . '@git.php.net>';
+ }
+
+ /**
+ * Return unique id of mail
+ * @return string unique Id of message in format: '<php-mail-...@git.php.net';
+ */
+ public function getId()
+ {
+ return $this->uniqId;
+ }
+
+ /**
+ * Add parent mail for this mail
+ * @param string $uniqId unique Id of message in format: '<php-mail-...@git.php.net';
+ */
+ public function addReplyTo($uniqId)
+ {
+ $this->replyTo[] = $uniqId;
+ }
+
+ /**
+ * Add attached text file to mail
+ * @param string $name unique file name
+ * @param string $data file content
+ */
+ public function addTextFile($name , $data)
+ {
+ $this->files[trim($name)] = chunk_split(base64_encode($data), 76, self::CRLF);
+ }
+
+ /**
+ * Return length of attached file
+ * @param string $name unique file name
+ * @return int file length
+ */
+ public function getFileLength($name)
+ {
+ $name = trim($name);
+ return isset($this->files[$name]) ? strlen($this->files[$name]) : 0;
+ }
+
+ /**
+ * Delete attached file
+ * @param string $name unique file name
+ */
+ public function dropFile($name)
+ {
+ $name = trim($name);
+ unset($this->files[$name]);
+ }
+
+ /**
+ * Set "From" address
+ * @param string $email email author address
+ * @param string $name author name
+ */
+ public function setFrom($email, $name = '')
+ {
+ $this->from = ['email' => trim($email), 'name' => trim($name)];
+ }
+
+ /**
+ * Add recipient address
+ * @param string $email recipient address
+ * @param string $name recipient name
+ */
+ public function addTo($email, $name = '')
+ {
+ $this->to[] = ['email' => trim($email), 'name' => trim($name)];
+ }
+
+ /**
+ * Set mail subject
+ * @param string $subject subject
+ */
+ public function setSubject($subject)
+ {
+ $this->subject = trim($subject);
+ }
+
+ /**
+ * Set timestamp
+ * @param string $timestamp timestamp
+ */
+ public function setTimestamp($timestamp)
+ {
+ $this->timestamp = trim($timestamp);
+ }
+
+ /**
+ * Set mail body text
+ * @param string $message body text
+ */
+ public function setMessage($message)
+ {
+ $this->message = $message;
+ }
+
+
+ /**
+ * Format header string
+ * @param string $name header name
+ * @param string $value header value
+ * @return string header string
+ */
+ private function makeHeader($name, $value)
+ {
+ return $name . ': ' . $value;
+ }
+
+ /**
+ * Format address string
+ * @param array $address array with email adress and name
+ * @return string address string
+ */
+ private function makeAddress(array $address)
+ {
+ return $address['name'] ? $this->utf8SafeEncode($address['name'], 100) . ' <'. $address['email'] . '>' : $address['email'];
+ }
+
+ /**
+ * Cut end encode string by mb_encode_mimeheader
+ * @param string $value utf8 string
+ * @param int $maxLenght max length
+ * @return string encoded string
+ */
+ private function utf8SafeEncode($value, $maxLenght = null)
+ {
+ if ($maxLenght) $value = mb_substr($value, 0, $maxLenght);
+ return mb_encode_mimeheader($value, 'UTF-8', 'Q');
+ }
+
+ /**
+ * Prepare heade part of mail
+ * @return string header part of mail
+ */
+ private function makeHeaders()
+ {
+ $headers = [];
+ $headers[] = $this->makeHeader('From', $this->makeAddress($this->from));
+ $headers[] = $this->makeHeader('Message-ID', $this->uniqId);
+ if (count($this->replyTo)) {
+ $replyTo = implode(' ', $this->replyTo);
+ $headers[] = $this->makeHeader('References', $replyTo);
+ $headers[] = $this->makeHeader('In-Reply-To', $replyTo);
+ }
+ $headers[] = $this->makeHeader('MIME-Version', '1.0');
+ $headers[] = $this->makeHeader('Date', date(DATE_RFC2822, $this->timestamp ?: time()));
+ if ($this->multipart) {
+ $this->boundary = sha1($this->uniqId);
+ $headers[] = $this->makeHeader('Content-Type', 'multipart/mixed; boundary="' . $this->boundary . '"');
+ } else {
+ $headers[] = $this->makeHeader('Content-Type', 'text/plain; charset="utf-8"');
+ // we use base64 for avoiding some problems sush string length limit, safety encoding etc.
+ $headers[] = $this->makeHeader('Content-Transfer-Encoding', 'quoted-printable');
+ }
+ return implode(self::CRLF , $headers);
+ }
+
+ /**
+ * Prepare body part of mail
+ * @return string mail body
+ */
+ private function makeBody()
+ {
+ $body = '';
+ if ($this->multipart) {
+ $body .= '--' . $this->boundary . self::CRLF;
+ $body .= $this->makeHeader('Content-Type', 'text/plain; charset="utf-8"') . self::CRLF;
+ $body .= $this->makeHeader('Content-Transfer-Encoding', 'quoted-printable') . self::CRLF;
+ $body .= self::CRLF;
+ $body .= quoted_printable_encode($this->message);
+ foreach ($this->files as $name => $data) {
+ $body .= self::CRLF . '--' . $this->boundary . self::CRLF;
+ $body .= $this->makeHeader('Content-Type', 'text/plain; charset="utf-8"') . self::CRLF;
+ $body .= $this->makeHeader('Content-Transfer-Encoding', 'base64') . self::CRLF;
+ $body .= $this->makeHeader('Content-Disposition', 'attachment; filename="' . $name . '"') . self::CRLF;
+ $body .= self::CRLF;
+ $body .= $data;
+ }
+ $body .= self::CRLF . '--' . $this->boundary . '--';
+ } else {
+ $body = quoted_printable_encode($this->message);
+ }
+ return $body;
+ }
+
+ /**
+ * Send current mail
+ * @return bool
+ */
+ public function send()
+ {
+ $this->multipart = (bool) count($this->files);
+
+ $receivers = implode(', ', array_map([$this, 'makeAddress'], $this->to));
+ $subject = $this->utf8SafeEncode($this->subject, 450);
+ $headers = $this->makeHeaders();
+ $body = $this->makeBody();
+
+ return mail($receivers, $subject, $body, $headers, "-f noreply@php.net");
+ }
+}
diff --git a/src-qt5/desktop-utils/lumina-textedit/tests/test.py b/src-qt5/desktop-utils/lumina-textedit/tests/test.py
new file mode 100644
index 00000000..cfac4984
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-textedit/tests/test.py
@@ -0,0 +1,17 @@
+import math
+
+primes = [2]
+print(2, end=' ')
+count = 1;
+for i in range(3, 200000):
+ for j in primes:
+ if i % j == 0:
+ break
+ elif j > math.sqrt(i):
+ count += 1
+ print(i, end=' ')
+ if count % 5 == 0:
+ print()
+ primes.append(i)
+ break
+print()
bgstack15