From 4fbe2d87b73af81426705c47a1e044c19d601e86 Mon Sep 17 00:00:00 2001 From: Le Tan Date: Thu, 9 Aug 2018 20:00:42 +0800 Subject: [PATCH] MdEditOperations: support auto block quote --- src/pegmarkdownhighlighter.cpp | 2 +- src/resources/vnote.ini | 13 +++++++++++-- src/utils/veditutils.cpp | 31 ++++++++++++++++++++++++++++++- src/utils/veditutils.h | 7 +++++++ src/utils/vutils.cpp | 2 ++ src/utils/vutils.h | 2 ++ src/utils/vvim.cpp | 8 +++++++- src/vconfigmanager.cpp | 8 ++++++-- src/vconfigmanager.h | 16 ++++++++++++---- src/veditor.cpp | 4 ++++ src/vmdeditoperations.cpp | 15 +++++++++++---- 11 files changed, 93 insertions(+), 15 deletions(-) diff --git a/src/pegmarkdownhighlighter.cpp b/src/pegmarkdownhighlighter.cpp index a4f543d4..8376fc34 100644 --- a/src/pegmarkdownhighlighter.cpp +++ b/src/pegmarkdownhighlighter.cpp @@ -277,7 +277,7 @@ void PegMarkdownHighlighter::handleContentsChange(int p_position, int p_charsRem // We still need a timer to start a complete parse. if (m_timeStamp == 2) { - startParse(); + m_timer->start(0); } else { m_timer->start(); } diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini index 779cc764..895d41e8 100644 --- a/src/resources/vnote.ini +++ b/src/resources/vnote.ini @@ -25,8 +25,7 @@ highlight_cursor_line=true highlight_selected_word=true highlight_searched_word=true -auto_indent=true -auto_list=true + current_background_color=System current_render_background_color=System language=System @@ -249,6 +248,16 @@ max_tag_label_length=10 ; Max number of tag labels to display max_num_of_tag_labels=3 +[editor] +; Auto indent as previous line +auto_indent=true + +; Auto add list marker +auto_list=true + +; Auto add block quote marker +auto_quote=true + [export] ; Path of the wkhtmltopdf tool wkhtmltopdf=wkhtmltopdf diff --git a/src/utils/veditutils.cpp b/src/utils/veditutils.cpp index ce506f03..14cb0f33 100644 --- a/src/utils/veditutils.cpp +++ b/src/utils/veditutils.cpp @@ -83,7 +83,28 @@ bool VEditUtils::insertListMarkAsPreviousBlock(QTextCursor &p_cursor) } return ret; +} +bool VEditUtils::insertQuoteMarkAsPreviousBlock(QTextCursor &p_cursor) +{ + bool ret = false; + QTextBlock block = p_cursor.block(); + QTextBlock preBlock = block.previous(); + if (!preBlock.isValid()) { + return false; + } + + QString text = preBlock.text(); + QRegExp regExp(VUtils::c_blockQuoteRegExp); + int regIdx = regExp.indexIn(text); + if (regIdx != -1) { + ret = true; + Q_ASSERT(regExp.captureCount() == 1); + QString markText = regExp.capturedTexts()[1]; + p_cursor.insertText(markText); + } + + return ret; } bool VEditUtils::indentBlockAsBlock(QTextCursor &p_cursor, bool p_next) @@ -554,6 +575,14 @@ void VEditUtils::scrollBlockInPage(QPlainTextEdit *p_edit, p_edit->ensureCursorVisible(); } +bool VEditUtils::isBlockQuoteBlock(const QTextBlock &p_block) +{ + QString text = p_block.text(); + QRegExp regExp(VUtils::c_blockQuoteRegExp); + int regIdx = regExp.indexIn(text); + return regIdx >= 0; +} + bool VEditUtils::isListBlock(const QTextBlock &p_block, int *p_seq) { QString text = p_block.text(); @@ -820,7 +849,7 @@ bool VEditUtils::needToCancelAutoIndent(int p_autoIndentPos, const QTextCursor & if (p_cursor.position() == p_autoIndentPos && !p_cursor.hasSelection() && p_cursor.atBlockEnd()) { - if (isListBlock(block)) { + if (isListBlock(block) || isBlockQuoteBlock(block)) { return true; } else if (isSpaceToBlockStart(block, p_cursor.positionInBlock())) { diff --git a/src/utils/veditutils.h b/src/utils/veditutils.h index e5f293f3..3eee56df 100644 --- a/src/utils/veditutils.h +++ b/src/utils/veditutils.h @@ -49,6 +49,11 @@ public: // Need to call setTextCursor() to make it take effect. static bool insertListMarkAsPreviousBlock(QTextCursor &p_cursor); + // Fetch the block quote mark of previous block, and insert it at current position. + // Returns true if quote mark has been inserted. + // Need to call setTextCursor() to make it take effect. + static bool insertQuoteMarkAsPreviousBlock(QTextCursor &p_cursor); + // Remove ObjectReplaceCharacter in p_text. // If the ObjectReplaceCharacter is in a block with only other spaces, remove the // whole block. @@ -141,6 +146,8 @@ public: static bool isListBullet(const QString &p_str); + static bool isBlockQuoteBlock(const QTextBlock &p_block); + // If the start of @p_block to postition @p_posInBlock are spaces. static bool isSpaceToBlockStart(const QTextBlock &p_block, int p_posInBlock); diff --git a/src/utils/vutils.cpp b/src/utils/vutils.cpp index 5cd1e93f..bca5d3f3 100644 --- a/src/utils/vutils.cpp +++ b/src/utils/vutils.cpp @@ -61,6 +61,8 @@ const QString VUtils::c_headerPrefixRegExp = QString("^(#{1,6}\\s+((\\d+\\.)+(?= const QString VUtils::c_listRegExp = QString("^\\s*(-|\\*|\\d+\\.)\\s"); +const QString VUtils::c_blockQuoteRegExp = QString("^\\s*(\\>\\s?)"); + void VUtils::initAvailableLanguage() { if (!s_availableLanguages.isEmpty()) { diff --git a/src/utils/vutils.h b/src/utils/vutils.h index 4c983b3b..f816d979 100644 --- a/src/utils/vutils.h +++ b/src/utils/vutils.h @@ -401,6 +401,8 @@ public: static const QString c_listRegExp; + static const QString c_blockQuoteRegExp; + private: VUtils() {} diff --git a/src/utils/vvim.cpp b/src/utils/vvim.cpp index 7f571be3..32ed8001 100644 --- a/src/utils/vvim.cpp +++ b/src/utils/vvim.cpp @@ -921,8 +921,14 @@ bool VVim::handleKeyPressEvent(int key, int modifiers, int *p_autoIndentPos) bool textInserted = false; if (g_config->getAutoIndent()) { textInserted = VEditUtils::indentBlockAsBlock(cursor, false); + bool listInserted = false; if (g_config->getAutoList()) { - textInserted = VEditUtils::insertListMarkAsPreviousBlock(cursor) + listInserted = VEditUtils::insertListMarkAsPreviousBlock(cursor); + textInserted = listInserted || textInserted; + } + + if (!listInserted && g_config->getAutoQuote()) { + textInserted = VEditUtils::insertQuoteMarkAsPreviousBlock(cursor) || textInserted; } } diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp index fb8aa3a7..e67ac949 100644 --- a/src/vconfigmanager.cpp +++ b/src/vconfigmanager.cpp @@ -92,8 +92,12 @@ void VConfigManager::initialize() m_highlightCursorLine = getConfigFromSettings("global", "highlight_cursor_line").toBool(); m_highlightSelectedWord = getConfigFromSettings("global", "highlight_selected_word").toBool(); m_highlightSearchedWord = getConfigFromSettings("global", "highlight_searched_word").toBool(); - m_autoIndent = getConfigFromSettings("global", "auto_indent").toBool(); - m_autoList = getConfigFromSettings("global", "auto_list").toBool(); + + m_autoIndent = getConfigFromSettings("editor", "auto_indent").toBool(); + + m_autoList = getConfigFromSettings("editor", "auto_list").toBool(); + + m_autoQuote = getConfigFromSettings("editor", "auto_quote").toBool(); readCustomColors(); diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h index 148086b6..47598b14 100644 --- a/src/vconfigmanager.h +++ b/src/vconfigmanager.h @@ -166,6 +166,8 @@ public: bool getAutoList() const; void setAutoList(bool p_autoList); + bool getAutoQuote() const; + const QVector &getCustomColors() const; const QString &getCurBackgroundColor() const; @@ -659,6 +661,9 @@ private: // Auto List. bool m_autoList; + // Auto quote. + bool m_autoQuote; + // App defined color QVector m_customColors; @@ -1193,8 +1198,7 @@ inline void VConfigManager::setAutoIndent(bool p_autoIndent) return; } m_autoIndent = p_autoIndent; - setConfigToSettings("global", "auto_indent", - m_autoIndent); + setConfigToSettings("editor", "auto_indent", m_autoIndent); } inline bool VConfigManager::getAutoList() const @@ -1208,8 +1212,12 @@ inline void VConfigManager::setAutoList(bool p_autoList) return; } m_autoList = p_autoList; - setConfigToSettings("global", "auto_list", - m_autoList); + setConfigToSettings("editor", "auto_list", m_autoList); +} + +inline bool VConfigManager::getAutoQuote() const +{ + return m_autoQuote; } inline const QVector& VConfigManager::getCustomColors() const diff --git a/src/veditor.cpp b/src/veditor.cpp index e4d71cc8..7a6fe127 100644 --- a/src/veditor.cpp +++ b/src/veditor.cpp @@ -1202,7 +1202,11 @@ QString VEditor::fetchCompletionPrefix() const void VEditor::insertCompletion(const QString &p_prefix, const QString &p_completion) { QTextCursor cursor = textCursorW(); + + cursor.joinPreviousEditBlock(); cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, p_prefix.size()); cursor.insertText(p_completion); + cursor.endEditBlock(); + setTextCursorW(cursor); } diff --git a/src/vmdeditoperations.cpp b/src/vmdeditoperations.cpp index 84c0bc9d..d510f2b7 100644 --- a/src/vmdeditoperations.cpp +++ b/src/vmdeditoperations.cpp @@ -645,6 +645,7 @@ bool VMdEditOperations::handleKeyEsc(QKeyEvent *p_event) bool VMdEditOperations::handleKeyReturn(QKeyEvent *p_event) { bool autolist = true; + bool autoQuote = true; if (p_event->modifiers() & Qt::ControlModifier) { m_autoIndentPos = -1; return false; @@ -660,6 +661,7 @@ bool VMdEditOperations::handleKeyReturn(QKeyEvent *p_event) // Let remaining logics handle inserting the new block except that we // do not need to insert auto list. + // But we still need auto quote. autolist = false; } @@ -682,16 +684,21 @@ bool VMdEditOperations::handleKeyReturn(QKeyEvent *p_event) handled = true; QTextCursor cursor = m_editor->textCursorW(); - bool textInserted = false; cursor.beginEditBlock(); cursor.removeSelectedText(); // Indent the new line as previous line. - textInserted = VEditUtils::insertBlockWithIndent(cursor); + bool textInserted = VEditUtils::insertBlockWithIndent(cursor); // Continue the list from previous line. - if (g_config->getAutoList() && autolist) { - textInserted = VEditUtils::insertListMarkAsPreviousBlock(cursor) || textInserted; + bool listInserted = false; + if (autolist && g_config->getAutoList()) { + listInserted = VEditUtils::insertListMarkAsPreviousBlock(cursor); + textInserted = listInserted || textInserted; + } + + if (autoQuote && !listInserted && g_config->getAutoQuote()) { + textInserted = VEditUtils::insertQuoteMarkAsPreviousBlock(cursor) || textInserted; } cursor.endEditBlock();