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();
|
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_blockNum,
|
||||||
int p_dest);
|
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:
|
private:
|
||||||
VEditUtils() {}
|
VEditUtils() {}
|
||||||
};
|
};
|
||||||
|
@ -351,9 +351,9 @@ static bool isControlModifier(int p_modifiers)
|
|||||||
#endif
|
#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) {
|
if (ret) {
|
||||||
p_event->accept();
|
p_event->accept();
|
||||||
}
|
}
|
||||||
@ -361,23 +361,47 @@ bool VVim::handleKeyPressEvent(QKeyEvent *p_event, bool *p_autoIndented)
|
|||||||
return ret;
|
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 ret = false;
|
||||||
bool resetPositionInBlock = true;
|
bool resetPositionInBlock = true;
|
||||||
Key keyInfo(key, modifiers);
|
Key keyInfo(key, modifiers);
|
||||||
bool unindent = false;
|
bool unindent = false;
|
||||||
|
int autoIndentPos = -1;
|
||||||
if (p_autoIndented) {
|
|
||||||
*p_autoIndented = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle Insert mode key press.
|
// Handle Insert mode key press.
|
||||||
if (VimMode::Insert == m_mode) {
|
if (VimMode::Insert == m_mode) {
|
||||||
if (key == Qt::Key_Escape
|
if (key == Qt::Key_Escape
|
||||||
|| (key == Qt::Key_BracketLeft && isControlModifier(modifiers))) {
|
|| (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.
|
// Clear selection and enter Normal mode.
|
||||||
clearSelection();
|
if (!cancelAutoIndent) {
|
||||||
|
clearSelection();
|
||||||
|
}
|
||||||
|
|
||||||
setMode(VimMode::Normal);
|
setMode(VimMode::Normal);
|
||||||
goto clear_accept;
|
goto clear_accept;
|
||||||
@ -766,8 +790,8 @@ bool VVim::handleKeyPressEvent(int key, int modifiers, bool *p_autoIndented)
|
|||||||
cursor.endEditBlock();
|
cursor.endEditBlock();
|
||||||
m_editor->setTextCursor(cursor);
|
m_editor->setTextCursor(cursor);
|
||||||
|
|
||||||
if (p_autoIndented && textInserted) {
|
if (textInserted) {
|
||||||
*p_autoIndented = true;
|
autoIndentPos = cursor.position();
|
||||||
}
|
}
|
||||||
|
|
||||||
setMode(VimMode::Insert);
|
setMode(VimMode::Insert);
|
||||||
@ -1679,6 +1703,11 @@ clear_accept:
|
|||||||
accept:
|
accept:
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
|
// Only alter the autoIndentPos when the key is handled by Vim.
|
||||||
|
if (p_autoIndentPos) {
|
||||||
|
*p_autoIndentPos = autoIndentPos;
|
||||||
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
m_resetPositionInBlock = resetPositionInBlock;
|
m_resetPositionInBlock = resetPositionInBlock;
|
||||||
emit vimStatusUpdated(this);
|
emit vimStatusUpdated(this);
|
||||||
|
@ -147,8 +147,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Handle key press event.
|
// 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.
|
// 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.
|
// Return current mode.
|
||||||
VimMode getMode() const;
|
VimMode getMode() const;
|
||||||
@ -449,7 +450,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Returns true if the event is consumed and need no more handling.
|
// 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.
|
// Reset all key state info.
|
||||||
void resetState();
|
void resetState();
|
||||||
|
@ -193,15 +193,8 @@ bool VMdEditOperations::insertImage()
|
|||||||
|
|
||||||
bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event)
|
bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event)
|
||||||
{
|
{
|
||||||
bool autoIndentedVim = false;
|
|
||||||
if (m_editConfig->m_enableVimMode
|
if (m_editConfig->m_enableVimMode
|
||||||
&& m_vim->handleKeyPressEvent(p_event, &autoIndentedVim)) {
|
&& m_vim->handleKeyPressEvent(p_event, &m_autoIndentPos)) {
|
||||||
if (autoIndentedVim) {
|
|
||||||
m_autoIndentPos = m_editor->textCursor().position();
|
|
||||||
} else {
|
|
||||||
m_autoIndentPos = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
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.
|
// If it is a Tab key following auto list, increase the indent level.
|
||||||
QTextBlock block = cursor.block();
|
QTextBlock block = cursor.block();
|
||||||
int seq = -1;
|
int seq = -1;
|
||||||
if (m_autoIndentPos == cursor.position() && isListBlock(block, &seq)) {
|
if (m_autoIndentPos == cursor.position()
|
||||||
|
&& VEditUtils::isListBlock(block, &seq)) {
|
||||||
QTextCursor blockCursor(block);
|
QTextCursor blockCursor(block);
|
||||||
blockCursor.beginEditBlock();
|
blockCursor.beginEditBlock();
|
||||||
blockCursor.insertText(text);
|
blockCursor.insertText(text);
|
||||||
@ -418,7 +412,8 @@ bool VMdEditOperations::handleKeyBackTab(QKeyEvent *p_event)
|
|||||||
QTextBlock block = doc->findBlock(cursor.selectionStart());
|
QTextBlock block = doc->findBlock(cursor.selectionStart());
|
||||||
bool continueAutoIndent = false;
|
bool continueAutoIndent = false;
|
||||||
int seq = -1;
|
int seq = -1;
|
||||||
if (cursor.position() == m_autoIndentPos && isListBlock(block, &seq) &&
|
if (cursor.position() == m_autoIndentPos
|
||||||
|
&& VEditUtils::isListBlock(block, &seq) &&
|
||||||
!cursor.hasSelection()) {
|
!cursor.hasSelection()) {
|
||||||
continueAutoIndent = true;
|
continueAutoIndent = true;
|
||||||
}
|
}
|
||||||
@ -668,17 +663,19 @@ bool VMdEditOperations::handleKeyReturn(QKeyEvent *p_event)
|
|||||||
QTextCursor cursor = m_editor->textCursor();
|
QTextCursor cursor = m_editor->textCursor();
|
||||||
QTextBlock block = cursor.block();
|
QTextBlock block = cursor.block();
|
||||||
if (cursor.position() == m_autoIndentPos && !cursor.hasSelection()) {
|
if (cursor.position() == m_autoIndentPos && !cursor.hasSelection()) {
|
||||||
if (isListBlock(block)) {
|
if (VEditUtils::isListBlock(block)) {
|
||||||
if (cursor.atBlockEnd()) {
|
if (cursor.atBlockEnd()) {
|
||||||
cancelAutoIndent = true;
|
cancelAutoIndent = true;
|
||||||
}
|
}
|
||||||
} else if (isSpaceToBlockStart(block, cursor.positionInBlock())) {
|
} else if (VEditUtils::isSpaceToBlockStart(block,
|
||||||
|
cursor.positionInBlock())) {
|
||||||
cancelAutoIndent = true;
|
cancelAutoIndent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cancelAutoIndent) {
|
if (cancelAutoIndent) {
|
||||||
m_autoIndentPos = -1;
|
m_autoIndentPos = -1;
|
||||||
deleteIndentAndListMark();
|
VEditUtils::deleteIndentAndListMark(cursor);
|
||||||
|
m_editor->setTextCursor(cursor);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -711,35 +708,6 @@ bool VMdEditOperations::handleKeyReturn(QKeyEvent *p_event)
|
|||||||
return handled;
|
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)
|
void VMdEditOperations::changeListBlockSeqNumber(QTextBlock &p_block, int p_seq)
|
||||||
{
|
{
|
||||||
QString text = p_block.text();
|
QString text = p_block.text();
|
||||||
@ -774,25 +742,6 @@ void VMdEditOperations::changeListBlockSeqNumber(QTextBlock &p_block, int p_seq)
|
|||||||
cursor.insertText(QString::number(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)
|
bool VMdEditOperations::insertTitle(int p_level)
|
||||||
{
|
{
|
||||||
Q_ASSERT(p_level > 0 && p_level < 7);
|
Q_ASSERT(p_level > 0 && p_level < 7);
|
||||||
|
@ -42,15 +42,6 @@ private:
|
|||||||
bool handleKeyReturn(QKeyEvent *p_event);
|
bool handleKeyReturn(QKeyEvent *p_event);
|
||||||
bool handleKeyBracketLeft(QKeyEvent *p_event);
|
bool handleKeyBracketLeft(QKeyEvent *p_event);
|
||||||
bool insertTitle(int p_level);
|
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.
|
// Change the sequence number of a list block.
|
||||||
void changeListBlockSeqNumber(QTextBlock &p_block, int p_seq);
|
void changeListBlockSeqNumber(QTextBlock &p_block, int p_seq);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user