Browse Source

PegMarkdownHighlighter: fix the timer issue

Le Tan 7 years ago
parent
commit
b94a9489d2
4 changed files with 60 additions and 23 deletions
  1. 31 21
      src/pegmarkdownhighlighter.cpp
  2. 9 0
      src/pegmarkdownhighlighter.h
  3. 16 2
      src/vlivepreviewhelper.cpp
  4. 4 0
      src/vlivepreviewhelper.h

+ 31 - 21
src/pegmarkdownhighlighter.cpp

@@ -22,6 +22,7 @@ PegMarkdownHighlighter::PegMarkdownHighlighter(QTextDocument *p_doc, VMdEditor *
       m_codeBlockTimeStamp(0),
       m_parser(NULL),
       m_parserExts(pmh_EXT_NOTES | pmh_EXT_STRIKE | pmh_EXT_FRONTMATTER | pmh_EXT_MARK),
+      m_parseInterval(50),
       m_notifyHighlightComplete(false)
 {
 }
@@ -38,6 +39,8 @@ void PegMarkdownHighlighter::init(const QVector<HighlightingStyle> &p_styles,
         m_parserExts |= pmh_EXT_MATH;
     }
 
+    m_parseInterval = p_timerInterval;
+
     m_codeBlockFormat.setForeground(QBrush(Qt::darkYellow));
     for (int index = 0; index < m_styles.size(); ++index) {
         switch (m_styles[index].type) {
@@ -65,24 +68,18 @@ void PegMarkdownHighlighter::init(const QVector<HighlightingStyle> &p_styles,
 
     m_timer = new QTimer(this);
     m_timer->setSingleShot(true);
-    m_timer->setInterval(p_timerInterval);
+    m_timer->setInterval(m_parseInterval);
     connect(m_timer, &QTimer::timeout,
             this, &PegMarkdownHighlighter::startParse);
 
     m_fastParseTimer = new QTimer(this);
     m_fastParseTimer->setSingleShot(true);
-    m_fastParseTimer->setInterval(5);
+    m_fastParseTimer->setInterval(50);
     connect(m_fastParseTimer, &QTimer::timeout,
             this, [this]() {
-                QSharedPointer<PegHighlighterFastResult> result(m_fastResult);
-                if (!result->matched(m_timeStamp) || m_result->matched(m_timeStamp)) {
-                    return;
-                }
-
-                for (int i = m_fastParseBlocks.first; i <= m_fastParseBlocks.second; ++i) {
-                    QTextBlock block = m_doc->findBlockByNumber(i);
-                    rehighlightBlock(block);
-                }
+                startFastParse(m_fastParseInfo.m_position,
+                               m_fastParseInfo.m_charsRemoved,
+                               m_fastParseInfo.m_charsAdded);
             });
 
     m_scrollRehighlightTimer = new QTimer(this);
@@ -271,16 +268,17 @@ void PegMarkdownHighlighter::handleContentsChange(int p_position, int p_charsRem
 
     ++m_timeStamp;
 
+    m_timer->stop();
+
     if (m_timeStamp > 2) {
-        startFastParse(p_position, p_charsRemoved, p_charsAdded);
+        m_fastParseInfo.m_position = p_position;
+        m_fastParseInfo.m_charsRemoved = p_charsRemoved;
+        m_fastParseInfo.m_charsAdded = p_charsAdded;
+        m_fastParseTimer->start();
     }
 
     // We still need a timer to start a complete parse.
-    if (m_timeStamp == 2) {
-        m_timer->start(0);
-    } else {
-        m_timer->start();
-    }
+    m_timer->start(m_timeStamp == 2 ? 0 : m_parseInterval);
 }
 
 void PegMarkdownHighlighter::startParse()
@@ -338,11 +336,19 @@ void PegMarkdownHighlighter::startFastParse(int p_position, int p_charsRemoved,
 
 void PegMarkdownHighlighter::processFastParseResult(const QSharedPointer<PegParseResult> &p_result)
 {
-    m_fastParseTimer->stop();
     m_fastResult.reset(new PegHighlighterFastResult(this, p_result));
+
     // Add additional single format blocks.
     updateSingleFormatBlocks(m_fastResult->m_blocksHighlights);
-    m_fastParseTimer->start();
+
+    if (!m_fastResult->matched(m_timeStamp) || m_result->matched(m_timeStamp)) {
+        return;
+    }
+
+    for (int i = m_fastParseBlocks.first; i <= m_fastParseBlocks.second; ++i) {
+        QTextBlock block = m_doc->findBlockByNumber(i);
+        rehighlightBlock(block);
+    }
 }
 
 static bool compHLUnitStyle(const HLUnitStyle &a, const HLUnitStyle &b)
@@ -759,10 +765,14 @@ void PegMarkdownHighlighter::getFastParseBlockRange(int p_position,
             goto goup;
         }
 
-        if (VEditUtils::fetchIndentation(firstBlock) == 0) {
+        if (VEditUtils::fetchIndentation(firstBlock) < 4) {
             // If previous block is empty, then we could stop now.
             if (VEditUtils::isEmptyBlock(preBlock)) {
-                break;
+                int preState = preBlock.userState();
+                if (preState != HighlightBlockState::CodeBlockStart
+                    && preState != HighlightBlockState::CodeBlock) {
+                    break;
+                }
             }
         }
 

+ 9 - 0
src/pegmarkdownhighlighter.h

@@ -74,6 +74,13 @@ private slots:
     void handleParseResult(const QSharedPointer<PegParseResult> &p_result);
 
 private:
+    struct FastParseInfo
+    {
+        int m_position;
+        int m_charsRemoved;
+        int m_charsAdded;
+    } m_fastParseInfo;
+
     void startParse();
 
     void startFastParse(int p_position, int p_charsRemoved, int p_charsAdded);
@@ -189,6 +196,8 @@ private:
     // Timer to trigger parse.
     QTimer *m_timer;
 
+    int m_parseInterval;
+
     QTimer *m_fastParseTimer;
 
     QTimer *m_scrollRehighlightTimer;

+ 16 - 2
src/vlivepreviewhelper.cpp

@@ -1,6 +1,7 @@
 #include "vlivepreviewhelper.h"
 
 #include <QByteArray>
+#include <QTimer>
 
 #include "veditor.h"
 #include "vdocument.h"
@@ -83,11 +84,18 @@ VLivePreviewHelper::VLivePreviewHelper(VEditor *p_editor,
       m_plantUMLHelper(NULL),
       m_lastInplacePreviewSize(0),
       m_timeStamp(0),
-      m_scaleFactor(VUtils::calculateScaleFactor())
+      m_scaleFactor(VUtils::calculateScaleFactor()),
+      m_lastCursorBlock(-1)
 {
-    connect(m_editor->object(), &VEditorObject::cursorPositionChanged,
+    m_livePreviewTimer = new QTimer(this);
+    m_livePreviewTimer->setSingleShot(true);
+    m_livePreviewTimer->setInterval(100);
+    connect(m_livePreviewTimer, &QTimer::timeout,
             this, &VLivePreviewHelper::handleCursorPositionChanged);
 
+    connect(m_editor->object(), SIGNAL(cursorPositionChanged()),
+            m_livePreviewTimer, SLOT(start()));
+
     m_flowchartEnabled = g_config->getEnableFlowchart();
     m_mermaidEnabled = g_config->getEnableMermaid();
     m_plantUMLMode = g_config->getPlantUMLMode();
@@ -206,10 +214,16 @@ void VLivePreviewHelper::updateCodeBlocks(TimeStamp p_timeStamp, const QVector<V
 void VLivePreviewHelper::handleCursorPositionChanged()
 {
     if (!m_livePreviewEnabled || m_codeBlocks.isEmpty()) {
+        m_lastCursorBlock = -1;
         return;
     }
 
     int cursorBlock = m_editor->textCursorW().block().blockNumber();
+    if (m_lastCursorBlock == cursorBlock) {
+        return;
+    }
+
+    m_lastCursorBlock = cursorBlock;
 
     int left = 0, right = m_codeBlocks.size() - 1;
     int mid = left;

+ 4 - 0
src/vlivepreviewhelper.h

@@ -250,6 +250,10 @@ private:
 
     // Indexed by content.
     QHash<QString, QSharedPointer<CodeBlockImageCacheEntry>> m_cache;
+
+    int m_lastCursorBlock;
+
+    QTimer *m_livePreviewTimer;
 };
 
 inline bool VLivePreviewHelper::isPreviewEnabled() const