From 94c923507b0db790e5c48b79c2bf51e61e2057c4 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 24 Apr 2020 16:37:16 -0400 Subject: Update some syntax highlighting handling. Prevent multi-line rules from starting within a section that was handled by a single-line rule earlier. Also add a 1s delay/timer on file reload if it changes in the background. Also add detection for bash scripts automatically --- .../lumina-textedit/PlainTextEditor.cpp | 6 +- .../lumina-textedit/PlainTextEditor.h | 1 + .../desktop-utils/lumina-textedit/syntaxSupport.h | 107 +++++++++++---------- .../lumina-textedit/syntax_rules/sh.syntax | 2 +- 4 files changed, 64 insertions(+), 52 deletions(-) (limited to 'src-qt5/desktop-utils/lumina-textedit') diff --git a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp index 0aedb1a0..ed3ca2c3 100644 --- a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp +++ b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp @@ -34,13 +34,17 @@ PlainTextEditor::PlainTextEditor(QSettings *set, QWidget *parent) : QPlainTextEd //this->setObjectName("PlainTextEditor"); //this->setStyleSheet("QPlainTextEdit#PlainTextEditor{ }"); SYNTAX = new Custom_Syntax(settings, this->document()); + FTIMER = new QTimer(this); + FTIMER->setInterval(1000); + FTIMER->setSingleShot(true); connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(LNW_updateWidth()) ); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(LNW_highlightLine()) ); connect(this, SIGNAL(updateRequest(const QRect&, int)), this, SLOT(LNW_update(const QRect&, int)) ); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(checkMatchChar()) ); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(cursorMoved()) ); connect(this, SIGNAL(textChanged()), this, SLOT(textChanged()) ); - connect(watcher, SIGNAL(fileChanged(const QString&)), this, SLOT(fileChanged()) ); + connect(watcher, SIGNAL(fileChanged(const QString&)), FTIMER, SLOT(start()) ); + connect(FTIMER, SIGNAL(timeout()), this, SLOT(fileChanged())); LNW_updateWidth(); LNW_highlightLine(); } diff --git a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h index 8f174d4b..8f2d7e98 100644 --- a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h +++ b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h @@ -55,6 +55,7 @@ private: QString lastSaveContents; QFileSystemWatcher *watcher; QList wordList; + QTimer *FTIMER; //Syntax Highlighting class Custom_Syntax *SYNTAX; //Hunspell *hunspell; diff --git a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h index f7321869..4ce2424c 100644 --- a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h +++ b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h @@ -85,62 +85,42 @@ public: void setupDocument(QPlainTextEdit *edit){ syntax.SetupDocument(edit); } //simple redirect for the function in the currently-loaded rules protected: + void highlightBlock(const QString &text){ + QTextCharFormat defaultFormat; //qDebug() << "Highlight Block:" << text; - //Now look for any multi-line patterns (starting/continuing/ending) + //Now finish any multi-line patterns int start = 0; int splitactive = previousBlockState(); 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 = 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, 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+syntax.rules[splitactive].endPattern.matchedLength(); - if(start>0){ start--; len++; } //need to include the first character as well - 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 rules - //qDebug() << "Loop over multi-line rules"; - for(int i=0; i=start){ - //qDebug() << "Got Start of split rule:" << start << newstart << text; - splitactive = i; - start = newstart+1; - 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, syntax.rules[splitactive].format); - } - } + //qDebug() << "split check:" << start << splitactive; + if(splitactive>=0){ + //Find the end of the current rule + 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, syntax.rules[splitactive].format); } + else{ setFormat(start, text.length()-start, syntax.rules[splitactive].format); } + }else{ + //Found end point within the same line + //qDebug() << "Highlight to particular point:" << text << start << end; + 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 , syntax.rules[splitactive].format); + start+=len; //move pointer to the end of handled range + splitactive = -1; //done with this rule } - if(splitactive<0){ break; } //no other rules found - go ahead and exit the loop - } //end scan over line length and multi-line formats + } //end check for end of pre-existing multi-line block match + setCurrentBlockState(splitactive); //tag this block as continuing as well - setCurrentBlockState(splitactive); - //Do all the single-line patterns - for(int i=0; i=0 || index=0){ int len = patt.matchedLength(); if(format(index)==currentBlock().charFormat()){ setFormat(index, len, syntax.rules[i].format); } //only apply highlighting if not within a section already @@ -148,10 +128,37 @@ protected: } }//end loop over normal (single-line) patterns + //Look for the start of any new split rules + //qDebug() << "Loop over multi-line rules"; + for(int i=0; i=start && (format(newstart) == defaultFormat) ){ //only start multi-line formatting if it is not already contained in a single-line formatting + //qDebug() << "Got Start of split rule:" << start << newstart << text << (format(newstart) != defaultFormat); + splitactive = i; + start = newstart+1; + int end = syntax.rules[splitactive].endPattern.indexIn(text, start); + if(end>0){ //end of multi-line comment in the same block + setFormat(start-1, end-start+1, syntax.rules[splitactive].format); + start = end+1; + }else{ + setCurrentBlockState(splitactive); + } + if(start>=text.length()-1 || splitactive>=0){ + //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, syntax.rules[splitactive].format); + break; //this goes to the end of the text block + } + } + } + //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(); + 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 @@ -159,7 +166,7 @@ protected: for(int i=0; imax) - setFormat(i, text.length()-i, fmt); + setFormat(i, text.length()-i, fmt); } } if(syntax.highlight_excess_whitespace()){ diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/sh.syntax b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/sh.syntax index f2256731..6ca832e9 100644 --- a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/sh.syntax +++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/sh.syntax @@ -9,7 +9,7 @@ "meta": { "name": "Shell", "file_suffix": ["sh"], - "first_line_match":["#!/bin/sh", "#!/sbin/openrc-run"] + "first_line_match":["#!/bin/sh", "#!/bin/bash","#!/bin/env bash","#!/sbin/openrc-run"] }, "format": { "line_wrap": false, -- cgit