MdEditOperations: support auto block quote

This commit is contained in:
Le Tan 2018-08-09 20:00:42 +08:00
parent da36e1a91f
commit 4fbe2d87b7
11 changed files with 93 additions and 15 deletions

View File

@ -277,7 +277,7 @@ void PegMarkdownHighlighter::handleContentsChange(int p_position, int p_charsRem
// We still need a timer to start a complete parse. // We still need a timer to start a complete parse.
if (m_timeStamp == 2) { if (m_timeStamp == 2) {
startParse(); m_timer->start(0);
} else { } else {
m_timer->start(); m_timer->start();
} }

View File

@ -25,8 +25,7 @@ highlight_cursor_line=true
highlight_selected_word=true highlight_selected_word=true
highlight_searched_word=true highlight_searched_word=true
auto_indent=true
auto_list=true
current_background_color=System current_background_color=System
current_render_background_color=System current_render_background_color=System
language=System language=System
@ -249,6 +248,16 @@ max_tag_label_length=10
; Max number of tag labels to display ; Max number of tag labels to display
max_num_of_tag_labels=3 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] [export]
; Path of the wkhtmltopdf tool ; Path of the wkhtmltopdf tool
wkhtmltopdf=wkhtmltopdf wkhtmltopdf=wkhtmltopdf

View File

@ -83,7 +83,28 @@ bool VEditUtils::insertListMarkAsPreviousBlock(QTextCursor &p_cursor)
} }
return ret; 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) bool VEditUtils::indentBlockAsBlock(QTextCursor &p_cursor, bool p_next)
@ -554,6 +575,14 @@ void VEditUtils::scrollBlockInPage(QPlainTextEdit *p_edit,
p_edit->ensureCursorVisible(); 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) bool VEditUtils::isListBlock(const QTextBlock &p_block, int *p_seq)
{ {
QString text = p_block.text(); QString text = p_block.text();
@ -820,7 +849,7 @@ bool VEditUtils::needToCancelAutoIndent(int p_autoIndentPos, const QTextCursor &
if (p_cursor.position() == p_autoIndentPos if (p_cursor.position() == p_autoIndentPos
&& !p_cursor.hasSelection() && !p_cursor.hasSelection()
&& p_cursor.atBlockEnd()) { && p_cursor.atBlockEnd()) {
if (isListBlock(block)) { if (isListBlock(block) || isBlockQuoteBlock(block)) {
return true; return true;
} else if (isSpaceToBlockStart(block, } else if (isSpaceToBlockStart(block,
p_cursor.positionInBlock())) { p_cursor.positionInBlock())) {

View File

@ -49,6 +49,11 @@ public:
// Need to call setTextCursor() to make it take effect. // Need to call setTextCursor() to make it take effect.
static bool insertListMarkAsPreviousBlock(QTextCursor &p_cursor); 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. // Remove ObjectReplaceCharacter in p_text.
// If the ObjectReplaceCharacter is in a block with only other spaces, remove the // If the ObjectReplaceCharacter is in a block with only other spaces, remove the
// whole block. // whole block.
@ -141,6 +146,8 @@ public:
static bool isListBullet(const QString &p_str); 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. // If the start of @p_block to postition @p_posInBlock are spaces.
static bool isSpaceToBlockStart(const QTextBlock &p_block, int p_posInBlock); static bool isSpaceToBlockStart(const QTextBlock &p_block, int p_posInBlock);

View File

@ -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_listRegExp = QString("^\\s*(-|\\*|\\d+\\.)\\s");
const QString VUtils::c_blockQuoteRegExp = QString("^\\s*(\\>\\s?)");
void VUtils::initAvailableLanguage() void VUtils::initAvailableLanguage()
{ {
if (!s_availableLanguages.isEmpty()) { if (!s_availableLanguages.isEmpty()) {

View File

@ -401,6 +401,8 @@ public:
static const QString c_listRegExp; static const QString c_listRegExp;
static const QString c_blockQuoteRegExp;
private: private:
VUtils() {} VUtils() {}

View File

@ -921,8 +921,14 @@ bool VVim::handleKeyPressEvent(int key, int modifiers, int *p_autoIndentPos)
bool textInserted = false; bool textInserted = false;
if (g_config->getAutoIndent()) { if (g_config->getAutoIndent()) {
textInserted = VEditUtils::indentBlockAsBlock(cursor, false); textInserted = VEditUtils::indentBlockAsBlock(cursor, false);
bool listInserted = false;
if (g_config->getAutoList()) { 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; || textInserted;
} }
} }

View File

@ -92,8 +92,12 @@ void VConfigManager::initialize()
m_highlightCursorLine = getConfigFromSettings("global", "highlight_cursor_line").toBool(); m_highlightCursorLine = getConfigFromSettings("global", "highlight_cursor_line").toBool();
m_highlightSelectedWord = getConfigFromSettings("global", "highlight_selected_word").toBool(); m_highlightSelectedWord = getConfigFromSettings("global", "highlight_selected_word").toBool();
m_highlightSearchedWord = getConfigFromSettings("global", "highlight_searched_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(); readCustomColors();

View File

@ -166,6 +166,8 @@ public:
bool getAutoList() const; bool getAutoList() const;
void setAutoList(bool p_autoList); void setAutoList(bool p_autoList);
bool getAutoQuote() const;
const QVector<VColor> &getCustomColors() const; const QVector<VColor> &getCustomColors() const;
const QString &getCurBackgroundColor() const; const QString &getCurBackgroundColor() const;
@ -659,6 +661,9 @@ private:
// Auto List. // Auto List.
bool m_autoList; bool m_autoList;
// Auto quote.
bool m_autoQuote;
// App defined color // App defined color
QVector<VColor> m_customColors; QVector<VColor> m_customColors;
@ -1193,8 +1198,7 @@ inline void VConfigManager::setAutoIndent(bool p_autoIndent)
return; return;
} }
m_autoIndent = p_autoIndent; m_autoIndent = p_autoIndent;
setConfigToSettings("global", "auto_indent", setConfigToSettings("editor", "auto_indent", m_autoIndent);
m_autoIndent);
} }
inline bool VConfigManager::getAutoList() const inline bool VConfigManager::getAutoList() const
@ -1208,8 +1212,12 @@ inline void VConfigManager::setAutoList(bool p_autoList)
return; return;
} }
m_autoList = p_autoList; m_autoList = p_autoList;
setConfigToSettings("global", "auto_list", setConfigToSettings("editor", "auto_list", m_autoList);
m_autoList); }
inline bool VConfigManager::getAutoQuote() const
{
return m_autoQuote;
} }
inline const QVector<VColor>& VConfigManager::getCustomColors() const inline const QVector<VColor>& VConfigManager::getCustomColors() const

View File

@ -1202,7 +1202,11 @@ QString VEditor::fetchCompletionPrefix() const
void VEditor::insertCompletion(const QString &p_prefix, const QString &p_completion) void VEditor::insertCompletion(const QString &p_prefix, const QString &p_completion)
{ {
QTextCursor cursor = textCursorW(); QTextCursor cursor = textCursorW();
cursor.joinPreviousEditBlock();
cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, p_prefix.size()); cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, p_prefix.size());
cursor.insertText(p_completion); cursor.insertText(p_completion);
cursor.endEditBlock();
setTextCursorW(cursor); setTextCursorW(cursor);
} }

View File

@ -645,6 +645,7 @@ bool VMdEditOperations::handleKeyEsc(QKeyEvent *p_event)
bool VMdEditOperations::handleKeyReturn(QKeyEvent *p_event) bool VMdEditOperations::handleKeyReturn(QKeyEvent *p_event)
{ {
bool autolist = true; bool autolist = true;
bool autoQuote = true;
if (p_event->modifiers() & Qt::ControlModifier) { if (p_event->modifiers() & Qt::ControlModifier) {
m_autoIndentPos = -1; m_autoIndentPos = -1;
return false; return false;
@ -660,6 +661,7 @@ bool VMdEditOperations::handleKeyReturn(QKeyEvent *p_event)
// Let remaining logics handle inserting the new block except that we // Let remaining logics handle inserting the new block except that we
// do not need to insert auto list. // do not need to insert auto list.
// But we still need auto quote.
autolist = false; autolist = false;
} }
@ -682,16 +684,21 @@ bool VMdEditOperations::handleKeyReturn(QKeyEvent *p_event)
handled = true; handled = true;
QTextCursor cursor = m_editor->textCursorW(); QTextCursor cursor = m_editor->textCursorW();
bool textInserted = false;
cursor.beginEditBlock(); cursor.beginEditBlock();
cursor.removeSelectedText(); cursor.removeSelectedText();
// Indent the new line as previous line. // Indent the new line as previous line.
textInserted = VEditUtils::insertBlockWithIndent(cursor); bool textInserted = VEditUtils::insertBlockWithIndent(cursor);
// Continue the list from previous line. // Continue the list from previous line.
if (g_config->getAutoList() && autolist) { bool listInserted = false;
textInserted = VEditUtils::insertListMarkAsPreviousBlock(cursor) || textInserted; 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(); cursor.endEditBlock();