vim-mode: support Visual mode with block cursor

This commit is contained in:
Le Tan 2017-12-01 23:25:08 +08:00
parent 00f3665c1c
commit f429ffe3e5
10 changed files with 245 additions and 71 deletions

View File

@ -106,7 +106,8 @@ VVim::VVim(VEditor *p_editor)
m_leaderKey(Key(Qt::Key_Space)), m_leaderKey(Key(Qt::Key_Space)),
m_replayLeaderSequence(false), m_replayLeaderSequence(false),
m_registerPending(false), m_registerPending(false),
m_insertModeAfterCommand(false) m_insertModeAfterCommand(false),
m_positionBeforeVisualMode(0)
{ {
Q_ASSERT(m_editConfig->m_enableVimMode); Q_ASSERT(m_editConfig->m_enableVimMode);
@ -114,8 +115,10 @@ VVim::VVim(VEditor *p_editor)
initRegisters(); initRegisters();
connect(m_editor->object(), &VEditorObject::selectionChangedByMouse, connect(m_editor->object(), &VEditorObject::mousePressed,
this, &VVim::selectionToVisualMode); this, &VVim::handleMousePressed);
connect(m_editor->object(), &VEditorObject::mouseMoved,
this, &VVim::handleMouseMoved);
} }
// Set @p_cursor's position specified by @p_positionInBlock. // Set @p_cursor's position specified by @p_positionInBlock.
@ -1332,26 +1335,33 @@ bool VVim::handleKeyPressEvent(int key, int modifiers, int *p_autoIndentPos)
case Qt::Key_Escape: case Qt::Key_Escape:
{ {
// Clear selection and enter normal mode. // Clear selection and enter normal mode.
int position = -1;
if (checkMode(VimMode::Visual)) {
QTextCursor cursor = m_editor->textCursorW();
if (cursor.position() > cursor.anchor()) {
position = cursor.position() - 1;
}
}
bool ret = clearSelection(); bool ret = clearSelection();
if (!ret && checkMode(VimMode::Normal)) { if (!ret && checkMode(VimMode::Normal)) {
emit m_editor->object()->requestCloseFindReplaceDialog(); emit m_editor->object()->requestCloseFindReplaceDialog();
} }
setMode(VimMode::Normal); setMode(VimMode::Normal, true, position);
break; break;
} }
case Qt::Key_V: case Qt::Key_V:
{ {
if (modifiers == Qt::NoModifier) { if (modifiers == Qt::NoModifier) {
if (checkMode(VimMode::Visual)) {
setMode(VimMode::Normal, true);
} else {
// Toggle Visual Mode. // Toggle Visual Mode.
clearSelection(); setMode(VimMode::Visual);
VimMode mode = VimMode::Visual; maintainSelectionInVisualMode();
if (m_mode == VimMode::Visual) {
mode = VimMode::Normal;
} }
setMode(mode);
} else if (modifiers == Qt::ShiftModifier) { } else if (modifiers == Qt::ShiftModifier) {
// Visual Line Mode. // Visual Line Mode.
clearSelection(); clearSelection();
@ -2224,9 +2234,18 @@ VimMode VVim::getMode() const
return m_mode; return m_mode;
} }
void VVim::setMode(VimMode p_mode, bool p_clearSelection) void VVim::setMode(VimMode p_mode, bool p_clearSelection, int p_position)
{ {
if (m_mode != p_mode) { if (m_mode != p_mode) {
QTextCursor cursor = m_editor->textCursorW();
int position = p_position;
if (position == -1
&& m_mode == VimMode::Visual
&& p_mode == VimMode::Normal
&& cursor.position() > cursor.anchor()) {
position = cursor.position() - 1;
}
if (p_clearSelection) { if (p_clearSelection) {
clearSelection(); clearSelection();
} }
@ -2240,7 +2259,26 @@ void VVim::setMode(VimMode p_mode, bool p_clearSelection)
m_mode = p_mode; m_mode = p_mode;
resetState(); resetState();
m_editor->setCursorBlockEnabled(checkMode(VimMode::Normal)); switch (m_mode) {
case VimMode::Insert:
m_editor->setCursorBlockModeW(CursorBlock::None);
break;
case VimMode::Visual:
m_positionBeforeVisualMode = cursor.anchor();
V_FALLTHROUGH;
default:
m_editor->setCursorBlockModeW(CursorBlock::RightSide);
break;
}
if (position != -1) {
cursor.setPosition(position);
m_editor->setTextCursorW(cursor);
}
amendCursorPosition();
emit modeChanged(m_mode); emit modeChanged(m_mode);
emit vimStatusUpdated(this); emit vimStatusUpdated(this);
@ -2436,8 +2474,10 @@ void VVim::processMoveAction(QList<Token> &p_tokens)
break; break;
} }
if (m_mode == VimMode::VisualLine) { if (checkMode(VimMode::VisualLine)) {
expandSelectionToWholeLines(cursor); expandSelectionToWholeLines(cursor);
} else if (checkMode(VimMode::Visual)) {
maintainSelectionInVisualMode(&cursor);
} }
m_editor->setTextCursorW(cursor); m_editor->setTextCursorW(cursor);
@ -4848,15 +4888,58 @@ int VVim::blockCountOfPageStep() const
return pageLineCount; return pageLineCount;
} }
void VVim::selectionToVisualMode(bool p_hasText) void VVim::maintainSelectionInVisualMode(QTextCursor *p_cursor)
{ {
if (p_hasText) { // We need to always select the character on current position.
if (m_mode == VimMode::Normal) { QTextCursor *cursor = p_cursor;
// Enter visual mode without clearing the selection. QTextCursor tmpCursor = m_editor->textCursorW();
setMode(VimMode::Visual, false); if (!cursor) {
cursor = &tmpCursor;
} }
} else if (m_mode == VimMode::Visual || m_mode == VimMode::VisualLine) {
setMode(VimMode::Normal); bool hasChanged = false;
int pos = cursor->position();
int anchor = cursor->anchor();
if (pos > anchor) {
Q_ASSERT(pos > m_positionBeforeVisualMode);
if (anchor > m_positionBeforeVisualMode) {
// Re-select.
cursor->setPosition(m_positionBeforeVisualMode);
cursor->setPosition(pos, QTextCursor::KeepAnchor);
hasChanged = true;
}
m_editor->setCursorBlockModeW(CursorBlock::LeftSide);
} else if (pos == anchor) {
Q_ASSERT(anchor >= m_positionBeforeVisualMode);
// Re-select.
if (anchor == m_positionBeforeVisualMode) {
cursor->setPosition(m_positionBeforeVisualMode + 1);
cursor->setPosition(pos, QTextCursor::KeepAnchor);
hasChanged = true;
m_editor->setCursorBlockModeW(CursorBlock::RightSide);
} else {
cursor->setPosition(m_positionBeforeVisualMode);
cursor->setPosition(pos, QTextCursor::KeepAnchor);
hasChanged = true;
m_editor->setCursorBlockModeW(CursorBlock::LeftSide);
}
} else {
// Re-select.
if (anchor <= m_positionBeforeVisualMode) {
cursor->setPosition(m_positionBeforeVisualMode + 1);
cursor->setPosition(pos, QTextCursor::KeepAnchor);
hasChanged = true;
}
m_editor->setCursorBlockModeW(CursorBlock::RightSide);
}
if (hasChanged && !p_cursor) {
m_editor->setTextCursorW(*cursor);
} }
} }
@ -5828,3 +5911,62 @@ QString VVim::readRegister(int p_key, int p_modifiers)
return ""; return "";
} }
void VVim::amendCursorPosition()
{
if (checkMode(VimMode::Normal)) {
QTextCursor cursor = m_editor->textCursorW();
if (cursor.atBlockEnd() && !cursor.atBlockStart()) {
// Normal mode and cursor at the end of a non-empty block.
cursor.movePosition(QTextCursor::PreviousCharacter);
m_editor->setTextCursorW(cursor);
qDebug() << "vvim alter the cursor position one character left";
}
}
}
void VVim::handleMousePressed(QMouseEvent *p_event)
{
Q_UNUSED(p_event);
QTextCursor cursor = m_editor->textCursorW();
if (checkMode(VimMode::Visual) || checkMode(VimMode::VisualLine)) {
setMode(VimMode::Normal);
} else if (checkMode(VimMode::Normal)) {
if (cursor.hasSelection()) {
setMode(VimMode::Visual, false);
maintainSelectionInVisualMode();
}
}
}
void VVim::handleMouseMoved(QMouseEvent *p_event)
{
if (p_event->buttons() != Qt::LeftButton) {
return;
}
QTextCursor cursor = m_editor->textCursorW();
if (cursor.hasSelection()) {
if (checkMode(VimMode::Normal)) {
int pos = cursor.position();
int anchor = cursor.anchor();
QTextBlock block = cursor.document()->findBlock(anchor);
if (anchor > 0 && anchor == block.position() + block.length() - 1) {
// Move anchor left.
cursor.setPosition(anchor - 1);
cursor.setPosition(pos, QTextCursor::KeepAnchor);
m_editor->setTextCursorW(cursor);
}
setMode(VimMode::Visual, false);
maintainSelectionInVisualMode();
} else if (checkMode(VimMode::Visual)) {
// We need to assure we always select the character on m_positionBeforeVisualMode.
maintainSelectionInVisualMode();
}
} else if (checkMode(VimMode::Visual)) {
// User move cursor in Visual mode. Now the cursor and anchor
// are at the same position.
maintainSelectionInVisualMode();
}
}

View File

@ -12,6 +12,7 @@ class VEditor;
class QKeyEvent; class QKeyEvent;
class VEditConfig; class VEditConfig;
class QKeyEvent; class QKeyEvent;
class QMouseEvent;
enum class VimMode { enum class VimMode {
Normal = 0, Normal = 0,
@ -163,7 +164,7 @@ public:
VimMode getMode() const; VimMode getMode() const;
// Set current mode. // Set current mode.
void setMode(VimMode p_mode, bool p_clearSelection = true); void setMode(VimMode p_mode, bool p_clearSelection = true, int p_position = -1);
// Set current register. // Set current register.
void setCurrentRegisterName(QChar p_reg); void setCurrentRegisterName(QChar p_reg);
@ -218,9 +219,13 @@ signals:
void commandLineTriggered(VVim::CommandLineType p_type); void commandLineTriggered(VVim::CommandLineType p_type);
private slots: private slots:
// When user use mouse to select texts in Normal mode, we should change to void handleMousePressed(QMouseEvent *p_event);
// Visual mode.
void selectionToVisualMode(bool p_hasText); void handleMouseMoved(QMouseEvent *p_event);
// When we display cursor as block, it makes no sense to put cursor at the
// end of line.
void amendCursorPosition();
private: private:
// Struct for a key press. // Struct for a key press.
@ -805,6 +810,12 @@ private:
Register &getRegister(QChar p_regName) const; Register &getRegister(QChar p_regName) const;
void setRegister(QChar p_regName, const QString &p_val); void setRegister(QChar p_regName, const QString &p_val);
// May need to do these things:
// 1. Change the CursorBlock mode;
// 2. Alter the selection to assure the character in m_positionBeforeVisualMode
// is always selected.
void maintainSelectionInVisualMode(QTextCursor *p_cursor = NULL);
VEditor *m_editor; VEditor *m_editor;
const VEditConfig *m_editConfig; const VEditConfig *m_editConfig;
VimMode m_mode; VimMode m_mode;
@ -849,6 +860,11 @@ private:
// Whether enter insert mode after a command. // Whether enter insert mode after a command.
bool m_insertModeAfterCommand; bool m_insertModeAfterCommand;
// Cursor position when entering Visual mode.
// After displaying cursor as block, we need to always select current character
// when entering Visual mode.
int m_positionBeforeVisualMode;
static const QChar c_unnamedRegister; static const QChar c_unnamedRegister;
static const QChar c_blackHoleRegister; static const QChar c_blackHoleRegister;
static const QChar c_selectionRegister; static const QChar c_selectionRegister;

View File

@ -118,4 +118,14 @@ enum class StartupPageType
Invalid Invalid
}; };
// Cursor block mode.
enum class CursorBlock
{
None = 0,
// Display a cursor block on the character on the right side of the cursor.
RightSide,
// Display a cursor block on the character on the left side of the cursor.
LeftSide
};
#endif #endif

View File

@ -8,6 +8,7 @@
#include <QColor> #include <QColor>
#include "veditconfig.h" #include "veditconfig.h"
#include "vconstants.h"
#include "vfile.h" #include "vfile.h"
class QWidget; class QWidget;
@ -17,6 +18,7 @@ class QTimer;
class QLabel; class QLabel;
class VVim; class VVim;
enum class VimMode; enum class VimMode;
class QMouseEvent;
enum class SelectionId { enum class SelectionId {
@ -144,9 +146,6 @@ public:
// @p_modified: if true, delete the whole content and insert the new content. // @p_modified: if true, delete the whole content and insert the new content.
virtual void setContent(const QString &p_content, bool p_modified = false) = 0; virtual void setContent(const QString &p_content, bool p_modified = false) = 0;
// Whether display cursor as block.
virtual void setCursorBlockEnabled(bool p_enabled) = 0;
// Set the cursor block's background and foreground. // Set the cursor block's background and foreground.
virtual void setCursorBlockColor(const QColor &p_bg, const QColor &p_fg) = 0; virtual void setCursorBlockColor(const QColor &p_bg, const QColor &p_fg) = 0;
@ -186,6 +185,9 @@ public:
virtual void redoW() = 0; virtual void redoW() = 0;
// Whether display cursor as block.
virtual void setCursorBlockModeW(CursorBlock p_mode) = 0;
protected: protected:
void init(); void init();
@ -332,9 +334,6 @@ signals:
// Request VEditTab to save this file. // Request VEditTab to save this file.
void saveNote(); void saveNote();
// Selection changed by mouse.
void selectionChangedByMouse(bool p_hasSelection);
// Emit when Vim status updated. // Emit when Vim status updated.
void vimStatusUpdated(const VVim *p_vim); void vimStatusUpdated(const VVim *p_vim);
@ -344,6 +343,10 @@ signals:
// Request the edit tab to close find and replace dialog. // Request the edit tab to close find and replace dialog.
void requestCloseFindReplaceDialog(); void requestCloseFindReplaceDialog();
void mouseMoved(QMouseEvent *p_event);
void mousePressed(QMouseEvent *p_event);
private slots: private slots:
// Timer for find-wrap label. // Timer for find-wrap label.
void labelTimerTimeout() void labelTimerTimeout()

View File

@ -302,7 +302,7 @@ void VMdEditor::mousePressEvent(QMouseEvent *p_event)
VTextEdit::mousePressEvent(p_event); VTextEdit::mousePressEvent(p_event);
emit m_object->selectionChangedByMouse(textCursor().hasSelection()); emit m_object->mousePressed(p_event);
} }
void VMdEditor::mouseReleaseEvent(QMouseEvent *p_event) void VMdEditor::mouseReleaseEvent(QMouseEvent *p_event)
@ -322,7 +322,7 @@ void VMdEditor::mouseMoveEvent(QMouseEvent *p_event)
VTextEdit::mouseMoveEvent(p_event); VTextEdit::mouseMoveEvent(p_event);
emit m_object->selectionChangedByMouse(textCursor().hasSelection()); emit m_object->mouseMoved(p_event);
} }
QVariant VMdEditor::inputMethodQuery(Qt::InputMethodQuery p_query) const QVariant VMdEditor::inputMethodQuery(Qt::InputMethodQuery p_query) const

View File

@ -59,9 +59,6 @@ public:
void setContent(const QString &p_content, bool p_modified = false) Q_DECL_OVERRIDE; void setContent(const QString &p_content, bool p_modified = false) Q_DECL_OVERRIDE;
// Whether display cursor as block.
void setCursorBlockEnabled(bool p_enabled) Q_DECL_OVERRIDE;
// Set the cursor block's background and foreground. // Set the cursor block's background and foreground.
void setCursorBlockColor(const QColor &p_bg, const QColor &p_fg) Q_DECL_OVERRIDE; void setCursorBlockColor(const QColor &p_bg, const QColor &p_fg) Q_DECL_OVERRIDE;
@ -148,6 +145,12 @@ public:
redo(); redo();
} }
// Whether display cursor as block.
void setCursorBlockModeW(CursorBlock p_mode) Q_DECL_OVERRIDE
{
setCursorBlockMode(p_mode);
}
signals: signals:
// Signal when headers change. // Signal when headers change.
void headersChanged(const QVector<VTableOfContentItem> &p_headers); void headersChanged(const QVector<VTableOfContentItem> &p_headers);
@ -218,11 +221,6 @@ private:
bool m_freshEdit; bool m_freshEdit;
}; };
inline void VMdEditor::setCursorBlockEnabled(bool p_enabled)
{
setCursorBlockMode(p_enabled);
}
inline void VMdEditor::setCursorBlockColor(const QColor &p_bg, const QColor &p_fg) inline void VMdEditor::setCursorBlockColor(const QColor &p_bg, const QColor &p_fg)
{ {
setCursorBlockBg(p_bg); setCursorBlockBg(p_bg);

View File

@ -32,7 +32,7 @@ VTextDocumentLayout::VTextDocumentLayout(QTextDocument *p_doc,
m_blockImageEnabled(false), m_blockImageEnabled(false),
m_imageWidthConstrainted(false), m_imageWidthConstrainted(false),
m_imageLineColor("#9575CD"), m_imageLineColor("#9575CD"),
m_cursorBlockMode(false), m_cursorBlockMode(CursorBlock::None),
m_virtualCursorBlockWidth(8), m_virtualCursorBlockWidth(8),
m_cursorBlockFg("#EEEEEE"), m_cursorBlockFg("#EEEEEE"),
m_cursorBlockBg("#222222"), m_cursorBlockBg("#222222"),
@ -232,14 +232,17 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
bool drawCursor = p_context.cursorPosition >= blpos bool drawCursor = p_context.cursorPosition >= blpos
&& p_context.cursorPosition < blpos + bllen; && p_context.cursorPosition < blpos + bllen;
int cursorWidth = m_cursorWidth; int cursorWidth = m_cursorWidth;
if (drawCursor && m_cursorBlockMode) { int cursorPosition = p_context.cursorPosition - blpos;
if (p_context.cursorPosition == blpos + bllen - 1) { if (drawCursor && m_cursorBlockMode != CursorBlock::None) {
if (cursorPosition > 0 && m_cursorBlockMode == CursorBlock::LeftSide) {
--cursorPosition;
}
if (cursorPosition == bllen - 1) {
cursorWidth = m_virtualCursorBlockWidth; cursorWidth = m_virtualCursorBlockWidth;
} else { } else {
// Get the width of the selection to update cursor width. // Get the width of the selection to update cursor width.
cursorWidth = getTextWidthWithinTextLine(layout, cursorWidth = getTextWidthWithinTextLine(layout, cursorPosition, 1);
p_context.cursorPosition - blpos,
1);
if (cursorWidth < m_cursorWidth) { if (cursorWidth < m_cursorWidth) {
cursorWidth = m_cursorWidth; cursorWidth = m_cursorWidth;
} }
@ -263,16 +266,14 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
if (drawCursor if (drawCursor
|| (p_context.cursorPosition < -1 || (p_context.cursorPosition < -1
&& !layout->preeditAreaText().isEmpty())) { && !layout->preeditAreaText().isEmpty())) {
int cpos = p_context.cursorPosition; if (p_context.cursorPosition < -1) {
if (cpos < -1) { cursorPosition = layout->preeditAreaPosition()
cpos = layout->preeditAreaPosition() - (cpos + 2); - (p_context.cursorPosition + 2);
} else {
cpos -= blpos;
} }
layout->drawCursor(p_painter, layout->drawCursor(p_painter,
offset, offset,
cpos, cursorPosition,
cursorWidth); cursorWidth);
} }
@ -353,12 +354,6 @@ int VTextDocumentLayout::hitTest(const QPointF &p_point, Qt::HitTestAccuracy p_a
} }
} }
if (m_cursorBlockMode
&& off == block.length() - 1
&& off != 0) {
--off;
}
return block.position() + off; return block.position() + off;
} }

View File

@ -5,6 +5,7 @@
#include <QVector> #include <QVector>
#include <QSize> #include <QSize>
#include <QSet> #include <QSet>
#include "vconstants.h"
class VImageResourceManager2; class VImageResourceManager2;
struct VPreviewedImageInfo; struct VPreviewedImageInfo;
@ -54,7 +55,7 @@ public:
void setImageLineColor(const QColor &p_color); void setImageLineColor(const QColor &p_color);
void setCursorBlockMode(bool p_enabled); void setCursorBlockMode(CursorBlock p_mode);
void setCursorBlockFg(const QColor &p_color); void setCursorBlockFg(const QColor &p_color);
@ -62,6 +63,8 @@ public:
void setVirtualCursorBlockWidth(int p_width); void setVirtualCursorBlockWidth(int p_width);
void clearLastCursorBlockWidth();
signals: signals:
// Emit to update current cursor block width if m_cursorBlockMode is enabled. // Emit to update current cursor block width if m_cursorBlockMode is enabled.
void cursorBlockWidthUpdated(int p_width); void cursorBlockWidthUpdated(int p_width);
@ -282,7 +285,7 @@ private:
QColor m_imageLineColor; QColor m_imageLineColor;
// Draw cursor as block. // Draw cursor as block.
bool m_cursorBlockMode; CursorBlock m_cursorBlockMode;
// Virtual cursor block: cursor block on no character. // Virtual cursor block: cursor block on no character.
int m_virtualCursorBlockWidth; int m_virtualCursorBlockWidth;
@ -313,9 +316,9 @@ inline void VTextDocumentLayout::scaleSize(QSize &p_size, int p_width, int p_hei
} }
} }
inline void VTextDocumentLayout::setCursorBlockMode(bool p_enabled) inline void VTextDocumentLayout::setCursorBlockMode(CursorBlock p_mode)
{ {
m_cursorBlockMode = p_enabled; m_cursorBlockMode = p_mode;
} }
inline void VTextDocumentLayout::setCursorBlockFg(const QColor &p_color) inline void VTextDocumentLayout::setCursorBlockFg(const QColor &p_color)
@ -332,4 +335,9 @@ inline void VTextDocumentLayout::setVirtualCursorBlockWidth(int p_width)
{ {
m_virtualCursorBlockWidth = p_width; m_virtualCursorBlockWidth = p_width;
} }
inline void VTextDocumentLayout::clearLastCursorBlockWidth()
{
m_lastCursorBlockWidth = -1;
}
#endif // VTEXTDOCUMENTLAYOUT_H #endif // VTEXTDOCUMENTLAYOUT_H

View File

@ -49,7 +49,7 @@ void VTextEdit::init()
m_blockImageEnabled = false; m_blockImageEnabled = false;
m_cursorBlockMode = false; m_cursorBlockMode = CursorBlock::None;
m_imageMgr = new VImageResourceManager2(); m_imageMgr = new VImageResourceManager2();
@ -346,13 +346,14 @@ void VTextEdit::setImageLineColor(const QColor &p_color)
getLayout()->setImageLineColor(p_color); getLayout()->setImageLineColor(p_color);
} }
void VTextEdit::setCursorBlockMode(bool p_enabled) void VTextEdit::setCursorBlockMode(CursorBlock p_mode)
{ {
if (p_enabled != m_cursorBlockMode) { if (p_mode != m_cursorBlockMode) {
m_cursorBlockMode = p_enabled; m_cursorBlockMode = p_mode;
getLayout()->setCursorBlockMode(m_cursorBlockMode); getLayout()->setCursorBlockMode(m_cursorBlockMode);
getLayout()->clearLastCursorBlockWidth();
setCursorWidth(m_cursorBlockMode ? VIRTUAL_CURSOR_BLOCK_WIDTH : 1); setCursorWidth(m_cursorBlockMode != CursorBlock::None ? VIRTUAL_CURSOR_BLOCK_WIDTH
: 1);
} }
} }

View File

@ -5,6 +5,7 @@
#include <QTextBlock> #include <QTextBlock>
#include "vlinenumberarea.h" #include "vlinenumberarea.h"
#include "vconstants.h"
class VTextDocumentLayout; class VTextDocumentLayout;
class QPainter; class QPainter;
@ -56,7 +57,7 @@ public:
void relayout(const QSet<int> &p_blocks); void relayout(const QSet<int> &p_blocks);
void setCursorBlockMode(bool p_enabled); void setCursorBlockMode(CursorBlock p_mode);
void setCursorBlockFg(const QColor &p_color); void setCursorBlockFg(const QColor &p_color);
@ -85,7 +86,7 @@ private:
bool m_blockImageEnabled; bool m_blockImageEnabled;
bool m_cursorBlockMode; CursorBlock m_cursorBlockMode;
}; };
inline void VTextEdit::setLineNumberType(LineNumberType p_type) inline void VTextEdit::setLineNumberType(LineNumberType p_type)