Browse Source

support highlighting current line by whole block in Vim non-Insert mode

Le Tan 8 years ago
parent
commit
c15908a724
8 changed files with 113 additions and 141 deletions
  1. 73 0
      src/utils/vutils.cpp
  2. 3 0
      src/utils/vutils.h
  3. 24 4
      src/vedit.cpp
  4. 8 2
      src/vedit.h
  5. 2 1
      src/veditoperations.cpp
  6. 1 61
      src/vexporter.cpp
  7. 2 70
      src/vmdtab.cpp
  8. 0 3
      src/vmdtab.h

+ 73 - 0
src/utils/vutils.cpp

@@ -19,6 +19,7 @@
 #include <QElapsedTimer>
 
 #include "vfile.h"
+#include "vnote.h"
 
 extern VConfigManager vconfig;
 
@@ -479,3 +480,75 @@ DocType VUtils::docTypeFromName(const QString &p_name)
 
     return DocType::Html;
 }
+
+QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType, bool p_exportPdf)
+{
+    QString jsFile, extraFile;
+    switch (p_conType) {
+    case MarkdownConverterType::Marked:
+        jsFile = "qrc" + VNote::c_markedJsFile;
+        extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>\n";
+        break;
+
+    case MarkdownConverterType::Hoedown:
+        jsFile = "qrc" + VNote::c_hoedownJsFile;
+        // Use Marked to highlight code blocks.
+        extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>\n";
+        break;
+
+    case MarkdownConverterType::MarkdownIt:
+        jsFile = "qrc" + VNote::c_markdownitJsFile;
+        extraFile = "<script src=\"qrc" + VNote::c_markdownitExtraFile + "\"></script>\n" +
+                    "<script src=\"qrc" + VNote::c_markdownitAnchorExtraFile + "\"></script>\n" +
+                    "<script src=\"qrc" + VNote::c_markdownitTaskListExtraFile + "\"></script>\n" +
+                    "<script src=\"qrc" + VNote::c_markdownitSubExtraFile + "\"></script>\n" +
+                    "<script src=\"qrc" + VNote::c_markdownitSupExtraFile + "\"></script>\n" +
+                    "<script src=\"qrc" + VNote::c_markdownitFootnoteExtraFile + "\"></script>\n";
+        break;
+
+    case MarkdownConverterType::Showdown:
+        jsFile = "qrc" + VNote::c_showdownJsFile;
+        extraFile = "<script src=\"qrc" + VNote::c_showdownExtraFile + "\"></script>\n" +
+                    "<script src=\"qrc" + VNote::c_showdownAnchorExtraFile + "\"></script>\n";
+
+        break;
+
+    default:
+        Q_ASSERT(false);
+    }
+
+    if (vconfig.getEnableMermaid()) {
+        extraFile += "<link rel=\"stylesheet\" type=\"text/css\" href=\"qrc" + VNote::c_mermaidCssFile +
+                     "\"/>\n" + "<script src=\"qrc" + VNote::c_mermaidApiJsFile + "\"></script>\n" +
+                     "<script>var VEnableMermaid = true;</script>\n";
+    }
+
+    if (vconfig.getEnableMathjax()) {
+        extraFile += "<script type=\"text/x-mathjax-config\">"
+                     "MathJax.Hub.Config({\n"
+                     "                    tex2jax: {inlineMath: [['$','$'], ['\\\\(','\\\\)']]},\n"
+                     "                    showProcessingMessages: false,\n"
+                     "                    messageStyle: \"none\"});\n"
+                     "</script>\n"
+                     "<script type=\"text/javascript\" async src=\"" + VNote::c_mathjaxJsFile + "\"></script>\n" +
+                     "<script>var VEnableMathjax = true;</script>\n";
+    }
+
+    if (vconfig.getEnableImageCaption()) {
+        extraFile += "<script>var VEnableImageCaption = true;</script>\n";
+    }
+
+    QString htmlTemplate;
+    if (p_exportPdf) {
+        htmlTemplate = VNote::s_markdownTemplatePDF;
+    } else {
+        htmlTemplate = VNote::s_markdownTemplate;
+    }
+
+    htmlTemplate.replace(c_htmlJSHolder, jsFile);
+    if (!extraFile.isEmpty()) {
+        htmlTemplate.replace(c_htmlExtraHolder, extraFile);
+    }
+
+    return htmlTemplate;
+}

+ 3 - 0
src/utils/vutils.h

@@ -96,6 +96,9 @@ public:
     // Return the DocType according to suffix.
     static DocType docTypeFromName(const QString &p_name);
 
+    // Generate HTML template.
+    static QString generateHtmlTemplate(MarkdownConverterType p_conType, bool p_exportPdf);
+
     // Regular expression for image link.
     // ![image title]( http://github.com/tamlok/vnote.jpg "alt \" text" )
     // Captured texts (need to be trimmed):

+ 24 - 4
src/vedit.cpp

@@ -32,6 +32,8 @@ void VEditConfig::init(const QFontMetrics &p_metric)
     m_enableVimMode = vconfig.getEnableVimMode();
 
     m_cursorLineBg = QColor(vconfig.getEditorCurrentLineBg());
+
+    m_highlightWholeBlock = m_enableVimMode;
 }
 
 VEdit::VEdit(VFile *p_file, QWidget *p_parent)
@@ -439,14 +441,32 @@ void VEdit::highlightCurrentLine()
     QList<QTextEdit::ExtraSelection> &selects = m_extraSelections[(int)SelectionId::CurrentLine];
     if (vconfig.getHighlightCursorLine() && !isReadOnly()) {
         // Need to highlight current line.
+        selects.clear();
+
+        // A long block maybe splited into multiple visual lines.
         QTextEdit::ExtraSelection select;
         select.format.setBackground(m_config.m_cursorLineBg);
         select.format.setProperty(QTextFormat::FullWidthSelection, true);
-        select.cursor = textCursor();
-        select.cursor.clearSelection();
 
-        selects.clear();
-        selects.append(select);
+        QTextCursor cursor = textCursor();
+        if (m_config.m_highlightWholeBlock) {
+            cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor, 1);
+            QTextBlock block = cursor.block();
+            int blockEnd = block.position() + block.length();
+            int pos = -1;
+            while (cursor.position() < blockEnd && pos != cursor.position()) {
+                QTextEdit::ExtraSelection newSelect = select;
+                newSelect.cursor = cursor;
+                selects.append(newSelect);
+
+                pos = cursor.position();
+                cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, 1);
+            }
+        } else {
+            cursor.clearSelection();
+            select.cursor = cursor;
+            selects.append(select);
+        }
     } else {
         // Need to clear current line highlight.
         if (selects.isEmpty()) {

+ 8 - 2
src/vedit.h

@@ -26,8 +26,11 @@ enum class SelectionId {
 
 class VEditConfig {
 public:
-    VEditConfig() : m_tabStopWidth(0), m_tabSpaces("\t"),
-                    m_enableVimMode(false) {}
+    VEditConfig() : m_tabStopWidth(0),
+                    m_tabSpaces("\t"),
+                    m_enableVimMode(false),
+                    m_highlightWholeBlock(false)
+    {}
 
     void init(const QFontMetrics &p_metric);
 
@@ -43,6 +46,9 @@ public:
 
     // The background color of cursor line.
     QColor m_cursorLineBg;
+
+    // Whether highlight a visual line or a whole block.
+    bool m_highlightWholeBlock;
 };
 
 class VEdit : public QTextEdit

+ 2 - 1
src/veditoperations.cpp

@@ -70,7 +70,8 @@ void VEditOperations::handleEditConfigUpdated()
 
 void VEditOperations::handleVimModeChanged(VimMode p_mode)
 {
-    Q_UNUSED(p_mode);
+    // Only highlight current visual line in Insert mode.
+    m_editConfig->m_highlightWholeBlock = (p_mode != VimMode::Insert);
 
     updateCursorLineBg();
 }

+ 1 - 61
src/vexporter.cpp

@@ -40,63 +40,7 @@ VExporter::VExporter(MarkdownConverterType p_mdType, QWidget *p_parent)
 
 void VExporter::initMarkdownTemplate()
 {
-    QString jsFile, extraFile;
-    switch (m_mdType) {
-    case MarkdownConverterType::Marked:
-        jsFile = "qrc" + VNote::c_markedJsFile;
-        extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>\n";
-        break;
-
-    case MarkdownConverterType::Hoedown:
-        jsFile = "qrc" + VNote::c_hoedownJsFile;
-        // Use Marked to highlight code blocks.
-        extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>\n";
-        break;
-
-    case MarkdownConverterType::MarkdownIt:
-        jsFile = "qrc" + VNote::c_markdownitJsFile;
-        extraFile = "<script src=\"qrc" + VNote::c_markdownitExtraFile + "\"></script>\n" +
-                    "<script src=\"qrc" + VNote::c_markdownitAnchorExtraFile + "\"></script>\n" +
-                    "<script src=\"qrc" + VNote::c_markdownitTaskListExtraFile + "\"></script>\n";
-        break;
-
-    case MarkdownConverterType::Showdown:
-        jsFile = "qrc" + VNote::c_showdownJsFile;
-        extraFile = "<script src=\"qrc" + VNote::c_showdownExtraFile + "\"></script>\n" +
-                    "<script src=\"qrc" + VNote::c_showdownAnchorExtraFile + "\"></script>\n";
-
-        break;
-
-    default:
-        Q_ASSERT(false);
-    }
-
-    if (vconfig.getEnableMermaid()) {
-        extraFile += "<link rel=\"stylesheet\" type=\"text/css\" href=\"qrc" + VNote::c_mermaidCssFile +
-                     "\"/>\n" + "<script src=\"qrc" + VNote::c_mermaidApiJsFile + "\"></script>\n" +
-                     "<script>var VEnableMermaid = true;</script>\n";
-    }
-
-    if (vconfig.getEnableMathjax()) {
-        extraFile += "<script type=\"text/x-mathjax-config\">"
-                     "MathJax.Hub.Config({\n"
-                     "                    tex2jax: {inlineMath: [['$','$'], ['\\\\(','\\\\)']]},\n"
-                     "                    showProcessingMessages: false,\n"
-                     "                    messageStyle: \"none\"});\n"
-                     "</script>\n"
-                     "<script type=\"text/javascript\" async src=\"" + VNote::c_mathjaxJsFile + "\"></script>\n" +
-                     "<script>var VEnableMathjax = true;</script>\n";
-    }
-
-    if (vconfig.getEnableImageCaption()) {
-        extraFile += "<script>var VEnableImageCaption = true;</script>\n";
-    }
-
-    m_htmlTemplate = VNote::s_markdownTemplatePDF;
-    m_htmlTemplate.replace(c_htmlJSHolder, jsFile);
-    if (!extraFile.isEmpty()) {
-        m_htmlTemplate.replace(c_htmlExtraHolder, extraFile);
-    }
+    m_htmlTemplate = VUtils::generateHtmlTemplate(m_mdType, true);
 }
 
 void VExporter::setupUI()
@@ -268,8 +212,6 @@ void VExporter::initWebViewer(VFile *p_file)
     channel->registerObject(QStringLiteral("content"), document);
     page->setWebChannel(channel);
 
-    qDebug() << "VPreviewPage" << page->parent() << "QWebChannel" << channel->parent();
-
     // Need to generate HTML using Hoedown.
     if (m_mdType == MarkdownConverterType::Hoedown) {
         VMarkdownConverter mdConverter;
@@ -299,8 +241,6 @@ void VExporter::handleLogicsFinished()
 
 void VExporter::handleLoadFinished(bool p_ok)
 {
-    qDebug() << "Web load finished" << p_ok;
-
     Q_ASSERT(!(m_noteState & NoteState::WebLoadFinished));
     m_noteState = NoteState(m_noteState | NoteState::WebLoadFinished);
 

+ 2 - 70
src/vmdtab.cpp

@@ -278,75 +278,6 @@ void VMdTab::discardAndRead()
     readFile();
 }
 
-QString VMdTab::fillHtmlTemplate() const
-{
-    const QString &jsHolder = c_htmlJSHolder;
-    const QString &extraHolder = c_htmlExtraHolder;
-
-    QString jsFile, extraFile;
-    switch (m_mdConType) {
-    case MarkdownConverterType::Marked:
-        jsFile = "qrc" + VNote::c_markedJsFile;
-        extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>\n";
-        break;
-
-    case MarkdownConverterType::Hoedown:
-        jsFile = "qrc" + VNote::c_hoedownJsFile;
-        // Use Marked to highlight code blocks.
-        extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>\n";
-        break;
-
-    case MarkdownConverterType::MarkdownIt:
-        jsFile = "qrc" + VNote::c_markdownitJsFile;
-        extraFile = "<script src=\"qrc" + VNote::c_markdownitExtraFile + "\"></script>\n" +
-                    "<script src=\"qrc" + VNote::c_markdownitAnchorExtraFile + "\"></script>\n" +
-                    "<script src=\"qrc" + VNote::c_markdownitTaskListExtraFile + "\"></script>\n" +
-                    "<script src=\"qrc" + VNote::c_markdownitSubExtraFile + "\"></script>\n" +
-                    "<script src=\"qrc" + VNote::c_markdownitSupExtraFile + "\"></script>\n" +
-                    "<script src=\"qrc" + VNote::c_markdownitFootnoteExtraFile + "\"></script>\n";
-        break;
-
-    case MarkdownConverterType::Showdown:
-        jsFile = "qrc" + VNote::c_showdownJsFile;
-        extraFile = "<script src=\"qrc" + VNote::c_showdownExtraFile + "\"></script>\n" +
-                    "<script src=\"qrc" + VNote::c_showdownAnchorExtraFile + "\"></script>\n";
-
-        break;
-
-    default:
-        Q_ASSERT(false);
-    }
-
-    if (vconfig.getEnableMermaid()) {
-        extraFile += "<link rel=\"stylesheet\" type=\"text/css\" href=\"qrc" + VNote::c_mermaidCssFile +
-                     "\"/>\n" + "<script src=\"qrc" + VNote::c_mermaidApiJsFile + "\"></script>\n" +
-                     "<script>var VEnableMermaid = true;</script>\n";
-    }
-
-    if (vconfig.getEnableMathjax()) {
-        extraFile += "<script type=\"text/x-mathjax-config\">"
-                     "MathJax.Hub.Config({\n"
-                     "                    tex2jax: {inlineMath: [['$','$'], ['\\\\(','\\\\)']]},\n"
-                     "                    showProcessingMessages: false,\n"
-                     "                    messageStyle: \"none\"});\n"
-                     "</script>\n"
-                     "<script type=\"text/javascript\" async src=\"" + VNote::c_mathjaxJsFile + "\"></script>\n" +
-                     "<script>var VEnableMathjax = true;</script>\n";
-    }
-
-    if (vconfig.getEnableImageCaption()) {
-        extraFile += "<script>var VEnableImageCaption = true;</script>\n";
-    }
-
-    QString htmlTemplate = VNote::s_markdownTemplate;
-    htmlTemplate.replace(jsHolder, jsFile);
-    if (!extraFile.isEmpty()) {
-        htmlTemplate.replace(extraHolder, extraFile);
-    }
-
-    return htmlTemplate;
-}
-
 void VMdTab::setupMarkdownViewer()
 {
     m_webViewer = new VWebView(m_file, this);
@@ -369,7 +300,8 @@ void VMdTab::setupMarkdownViewer()
             this, &VMdTab::handleWebKeyPressed);
     page->setWebChannel(channel);
 
-    m_webViewer->setHtml(fillHtmlTemplate(), m_file->getBaseUrl());
+    m_webViewer->setHtml(VUtils::generateHtmlTemplate(m_mdConType, false),
+                         m_file->getBaseUrl());
 
     m_stacks->addWidget(m_webViewer);
 }

+ 0 - 3
src/vmdtab.h

@@ -97,9 +97,6 @@ private:
     // Show the file content in edit mode.
     void showFileEditMode();
 
-    // Generate HTML template for Web view.
-    QString fillHtmlTemplate() const;
-
     // Setup Markdown viewer.
     void setupMarkdownViewer();