mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
vim-mode: going back to Normal mode from insert mode will clear auto indent and auto list
This commit is contained in:
parent
eeaeb0b567
commit
4b1e256308
@ -352,3 +352,51 @@ void VEditUtils::scrollBlockInPage(QTextEdit *p_edit,
|
||||
|
||||
p_edit->ensureCursorVisible();
|
||||
}
|
||||
|
||||
bool VEditUtils::isListBlock(const QTextBlock &p_block, int *p_seq)
|
||||
{
|
||||
QString text = p_block.text();
|
||||
QRegExp regExp("^\\s*(-|\\d+\\.)\\s");
|
||||
|
||||
if (p_seq) {
|
||||
*p_seq = -1;
|
||||
}
|
||||
|
||||
int regIdx = regExp.indexIn(text);
|
||||
if (regIdx == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
V_ASSERT(regExp.captureCount() == 1);
|
||||
QString markText = regExp.capturedTexts()[1];
|
||||
if (markText != "-") {
|
||||
V_ASSERT(markText.endsWith('.'));
|
||||
bool ok = false;
|
||||
int num = markText.left(markText.size() - 1).toInt(&ok, 10);
|
||||
V_ASSERT(ok);
|
||||
if (p_seq) {
|
||||
*p_seq = num;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VEditUtils::isSpaceToBlockStart(const QTextBlock &p_block, int p_posInBlock)
|
||||
{
|
||||
if (p_posInBlock <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QString text = p_block.text();
|
||||
V_ASSERT(text.size() >= p_posInBlock);
|
||||
return text.left(p_posInBlock).trimmed().isEmpty();
|
||||
}
|
||||
|
||||
void VEditUtils::deleteIndentAndListMark(QTextCursor &p_cursor)
|
||||
{
|
||||
V_ASSERT(!p_cursor.hasSelection());
|
||||
p_cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor);
|
||||
p_cursor.removeSelectedText();
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,18 @@ public:
|
||||
int p_blockNum,
|
||||
int p_dest);
|
||||
|
||||
// Check if @p_block is a auto list block.
|
||||
// @p_seq will be the seq number of the ordered list, or -1.
|
||||
// Returns true if it is an auto list block.
|
||||
static bool isListBlock(const QTextBlock &p_block, int *p_seq = NULL);
|
||||
|
||||
// If the start of @p_block to postition @p_posInBlock are spaces.
|
||||
static bool isSpaceToBlockStart(const QTextBlock &p_block, int p_posInBlock);
|
||||
|
||||
// @p_cursor is positioned right after auto indetn and auto list.
|
||||
// Need to call setTextCursor() to make it take effect.
|
||||
static void deleteIndentAndListMark(QTextCursor &p_cursor);
|
||||
|
||||
private:
|
||||
VEditUtils() {}
|
||||
};
|
||||
|
@ -351,9 +351,9 @@ static bool isControlModifier(int p_modifiers)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool VVim::handleKeyPressEvent(QKeyEvent *p_event, bool *p_autoIndented)
|
||||
bool VVim::handleKeyPressEvent(QKeyEvent *p_event, int *p_autoIndentPos)
|
||||
{
|
||||
bool ret = handleKeyPressEvent(p_event->key(), p_event->modifiers(), p_autoIndented);
|
||||
bool ret = handleKeyPressEvent(p_event->key(), p_event->modifiers(), p_autoIndentPos);
|
||||
if (ret) {
|
||||
p_event->accept();
|
||||
}
|
||||
@ -361,23 +361,47 @@ bool VVim::handleKeyPressEvent(QKeyEvent *p_event, bool *p_autoIndented)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool VVim::handleKeyPressEvent(int key, int modifiers, bool *p_autoIndented)
|
||||
bool VVim::handleKeyPressEvent(int key, int modifiers, int *p_autoIndentPos)
|
||||
{
|
||||
bool ret = false;
|
||||
bool resetPositionInBlock = true;
|
||||
Key keyInfo(key, modifiers);
|
||||
bool unindent = false;
|
||||
|
||||
if (p_autoIndented) {
|
||||
*p_autoIndented = false;
|
||||
}
|
||||
int autoIndentPos = -1;
|
||||
|
||||
// Handle Insert mode key press.
|
||||
if (VimMode::Insert == m_mode) {
|
||||
if (key == Qt::Key_Escape
|
||||
|| (key == Qt::Key_BracketLeft && isControlModifier(modifiers))) {
|
||||
// See if we need to cancel auto indent.
|
||||
bool cancelAutoIndent = false;
|
||||
if (p_autoIndentPos && *p_autoIndentPos > -1) {
|
||||
// Cancel the auto indent/list if the pos is the same and cursor is at
|
||||
// the end of a block.
|
||||
QTextCursor cursor = m_editor->textCursor();
|
||||
QTextBlock block = cursor.block();
|
||||
if (cursor.position() == *p_autoIndentPos && !cursor.hasSelection()) {
|
||||
if (VEditUtils::isListBlock(block)) {
|
||||
if (cursor.atBlockEnd()) {
|
||||
cancelAutoIndent = true;
|
||||
}
|
||||
} else if (VEditUtils::isSpaceToBlockStart(block,
|
||||
cursor.positionInBlock())) {
|
||||
cancelAutoIndent = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (cancelAutoIndent) {
|
||||
autoIndentPos = -1;
|
||||
VEditUtils::deleteIndentAndListMark(cursor);
|
||||
m_editor->setTextCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear selection and enter Normal mode.
|
||||
if (!cancelAutoIndent) {
|
||||
clearSelection();
|
||||
}
|
||||
|
||||
setMode(VimMode::Normal);
|
||||
goto clear_accept;
|
||||
@ -766,8 +790,8 @@ bool VVim::handleKeyPressEvent(int key, int modifiers, bool *p_autoIndented)
|
||||
cursor.endEditBlock();
|
||||
m_editor->setTextCursor(cursor);
|
||||
|
||||
if (p_autoIndented && textInserted) {
|
||||
*p_autoIndented = true;
|
||||
if (textInserted) {
|
||||
autoIndentPos = cursor.position();
|
||||
}
|
||||
|
||||
setMode(VimMode::Insert);
|
||||
@ -1679,6 +1703,11 @@ clear_accept:
|
||||
accept:
|
||||
ret = true;
|
||||
|
||||
// Only alter the autoIndentPos when the key is handled by Vim.
|
||||
if (p_autoIndentPos) {
|
||||
*p_autoIndentPos = autoIndentPos;
|
||||
}
|
||||
|
||||
exit:
|
||||
m_resetPositionInBlock = resetPositionInBlock;
|
||||
emit vimStatusUpdated(this);
|
||||
|
@ -147,8 +147,9 @@ public:
|
||||
};
|
||||
|
||||
// Handle key press event.
|
||||
// @p_autoIndentPos: the cursor position of last auto indent.
|
||||
// Returns true if the event is consumed and need no more handling.
|
||||
bool handleKeyPressEvent(QKeyEvent *p_event, bool *p_autoIndented = NULL);
|
||||
bool handleKeyPressEvent(QKeyEvent *p_event, int *p_autoIndentPos = NULL);
|
||||
|
||||
// Return current mode.
|
||||
VimMode getMode() const;
|
||||
@ -449,7 +450,7 @@ private:
|
||||
};
|
||||
|
||||
// Returns true if the event is consumed and need no more handling.
|
||||
bool handleKeyPressEvent(int key, int modifiers, bool *p_autoIndented = NULL);
|
||||
bool handleKeyPressEvent(int key, int modifiers, int *p_autoIndentPos = NULL);
|
||||
|
||||
// Reset all key state info.
|
||||
void resetState();
|
||||
|
@ -193,15 +193,8 @@ bool VMdEditOperations::insertImage()
|
||||
|
||||
bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event)
|
||||
{
|
||||
bool autoIndentedVim = false;
|
||||
if (m_editConfig->m_enableVimMode
|
||||
&& m_vim->handleKeyPressEvent(p_event, &autoIndentedVim)) {
|
||||
if (autoIndentedVim) {
|
||||
m_autoIndentPos = m_editor->textCursor().position();
|
||||
} else {
|
||||
m_autoIndentPos = -1;
|
||||
}
|
||||
|
||||
&& m_vim->handleKeyPressEvent(p_event, &m_autoIndentPos)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -383,7 +376,8 @@ bool VMdEditOperations::handleKeyTab(QKeyEvent *p_event)
|
||||
// If it is a Tab key following auto list, increase the indent level.
|
||||
QTextBlock block = cursor.block();
|
||||
int seq = -1;
|
||||
if (m_autoIndentPos == cursor.position() && isListBlock(block, &seq)) {
|
||||
if (m_autoIndentPos == cursor.position()
|
||||
&& VEditUtils::isListBlock(block, &seq)) {
|
||||
QTextCursor blockCursor(block);
|
||||
blockCursor.beginEditBlock();
|
||||
blockCursor.insertText(text);
|
||||
@ -418,7 +412,8 @@ bool VMdEditOperations::handleKeyBackTab(QKeyEvent *p_event)
|
||||
QTextBlock block = doc->findBlock(cursor.selectionStart());
|
||||
bool continueAutoIndent = false;
|
||||
int seq = -1;
|
||||
if (cursor.position() == m_autoIndentPos && isListBlock(block, &seq) &&
|
||||
if (cursor.position() == m_autoIndentPos
|
||||
&& VEditUtils::isListBlock(block, &seq) &&
|
||||
!cursor.hasSelection()) {
|
||||
continueAutoIndent = true;
|
||||
}
|
||||
@ -668,17 +663,19 @@ bool VMdEditOperations::handleKeyReturn(QKeyEvent *p_event)
|
||||
QTextCursor cursor = m_editor->textCursor();
|
||||
QTextBlock block = cursor.block();
|
||||
if (cursor.position() == m_autoIndentPos && !cursor.hasSelection()) {
|
||||
if (isListBlock(block)) {
|
||||
if (VEditUtils::isListBlock(block)) {
|
||||
if (cursor.atBlockEnd()) {
|
||||
cancelAutoIndent = true;
|
||||
}
|
||||
} else if (isSpaceToBlockStart(block, cursor.positionInBlock())) {
|
||||
} else if (VEditUtils::isSpaceToBlockStart(block,
|
||||
cursor.positionInBlock())) {
|
||||
cancelAutoIndent = true;
|
||||
}
|
||||
}
|
||||
if (cancelAutoIndent) {
|
||||
m_autoIndentPos = -1;
|
||||
deleteIndentAndListMark();
|
||||
VEditUtils::deleteIndentAndListMark(cursor);
|
||||
m_editor->setTextCursor(cursor);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -711,35 +708,6 @@ bool VMdEditOperations::handleKeyReturn(QKeyEvent *p_event)
|
||||
return handled;
|
||||
}
|
||||
|
||||
bool VMdEditOperations::isListBlock(const QTextBlock &p_block, int *p_seq)
|
||||
{
|
||||
QString text = p_block.text();
|
||||
QRegExp regExp("^\\s*(-|\\d+\\.)\\s");
|
||||
|
||||
if (p_seq) {
|
||||
*p_seq = -1;
|
||||
}
|
||||
|
||||
int regIdx = regExp.indexIn(text);
|
||||
if (regIdx == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
V_ASSERT(regExp.captureCount() == 1);
|
||||
QString markText = regExp.capturedTexts()[1];
|
||||
if (markText != "-") {
|
||||
V_ASSERT(markText.endsWith('.'));
|
||||
bool ok = false;
|
||||
int num = markText.left(markText.size() - 1).toInt(&ok, 10);
|
||||
V_ASSERT(ok);
|
||||
if (p_seq) {
|
||||
*p_seq = num;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VMdEditOperations::changeListBlockSeqNumber(QTextBlock &p_block, int p_seq)
|
||||
{
|
||||
QString text = p_block.text();
|
||||
@ -774,25 +742,6 @@ void VMdEditOperations::changeListBlockSeqNumber(QTextBlock &p_block, int p_seq)
|
||||
cursor.insertText(QString::number(p_seq));
|
||||
}
|
||||
|
||||
bool VMdEditOperations::isSpaceToBlockStart(const QTextBlock &p_block, int p_posInBlock)
|
||||
{
|
||||
if (p_posInBlock <= 0) {
|
||||
return true;
|
||||
}
|
||||
QString text = p_block.text();
|
||||
V_ASSERT(text.size() >= p_posInBlock);
|
||||
return text.left(p_posInBlock).trimmed().isEmpty();
|
||||
}
|
||||
|
||||
void VMdEditOperations::deleteIndentAndListMark()
|
||||
{
|
||||
QTextCursor cursor = m_editor->textCursor();
|
||||
V_ASSERT(!cursor.hasSelection());
|
||||
cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor);
|
||||
cursor.removeSelectedText();
|
||||
m_editor->setTextCursor(cursor);
|
||||
}
|
||||
|
||||
bool VMdEditOperations::insertTitle(int p_level)
|
||||
{
|
||||
Q_ASSERT(p_level > 0 && p_level < 7);
|
||||
|
@ -42,15 +42,6 @@ private:
|
||||
bool handleKeyReturn(QKeyEvent *p_event);
|
||||
bool handleKeyBracketLeft(QKeyEvent *p_event);
|
||||
bool insertTitle(int p_level);
|
||||
void deleteIndentAndListMark();
|
||||
|
||||
// Check if @p_block is a auto list block.
|
||||
// @p_seq will be the seq number of the ordered list, or -1.
|
||||
// Returns true if it is an auto list block.
|
||||
bool isListBlock(const QTextBlock &p_block, int *p_seq = NULL);
|
||||
|
||||
// If the start of @p_block to postition @p_posInBlock are spaces.
|
||||
bool isSpaceToBlockStart(const QTextBlock &p_block, int p_posInBlock);
|
||||
|
||||
// Change the sequence number of a list block.
|
||||
void changeListBlockSeqNumber(QTextBlock &p_block, int p_seq);
|
||||
|
Loading…
x
Reference in New Issue
Block a user