VSnippet: support auto indent

This commit is contained in:
Le Tan 2017-11-24 19:57:23 +08:00
parent d79ad54822
commit 94260b3df8
8 changed files with 84 additions and 15 deletions

View File

@ -72,6 +72,11 @@ void VEditSnippetDialog::setupUI(const QString &p_title, const QString &p_info)
m_selectionMarkEdit = new QLineEdit(m_snippet.getSelectionMark()); m_selectionMarkEdit = new QLineEdit(m_snippet.getSelectionMark());
m_selectionMarkEdit->setToolTip(tr("String in the content to be replaced with selected text")); m_selectionMarkEdit->setToolTip(tr("String in the content to be replaced with selected text"));
// Auto Indent.
m_autoIndentCB = new QCheckBox(tr("Auto indent"), this);
m_autoIndentCB->setToolTip(tr("Auto indent the content according to the first line"));
m_autoIndentCB->setChecked(m_snippet.getAutoIndent());
// Content. // Content.
m_contentEdit = new QTextEdit(); m_contentEdit = new QTextEdit();
setContentEditByType(); setContentEditByType();
@ -82,6 +87,7 @@ void VEditSnippetDialog::setupUI(const QString &p_title, const QString &p_info)
topLayout->addRow(tr("Shortc&ut:"), m_shortcutCB); topLayout->addRow(tr("Shortc&ut:"), m_shortcutCB);
topLayout->addRow(tr("Cursor &mark:"), m_cursorMarkEdit); topLayout->addRow(tr("Cursor &mark:"), m_cursorMarkEdit);
topLayout->addRow(tr("&Selection mark:"), m_selectionMarkEdit); topLayout->addRow(tr("&Selection mark:"), m_selectionMarkEdit);
topLayout->addWidget(m_autoIndentCB);
topLayout->addRow(tr("&Content:"), m_contentEdit); topLayout->addRow(tr("&Content:"), m_contentEdit);
m_warnLabel = new QLabel(); m_warnLabel = new QLabel();
@ -275,6 +281,11 @@ QChar VEditSnippetDialog::getShortcutInput() const
return m_shortcutCB->currentData().toChar(); return m_shortcutCB->currentData().toChar();
} }
bool VEditSnippetDialog::getAutoIndentInput() const
{
return m_autoIndentCB->isChecked();
}
QVector<QChar> VEditSnippetDialog::getAvailableShortcuts() const QVector<QChar> VEditSnippetDialog::getAvailableShortcuts() const
{ {
QVector<QChar> ret = VSnippet::getAllShortcuts(); QVector<QChar> ret = VSnippet::getAllShortcuts();

View File

@ -12,6 +12,7 @@ class QLabel;
class QDialogButtonBox; class QDialogButtonBox;
class QComboBox; class QComboBox;
class QTextEdit; class QTextEdit;
class QCheckBox;
class VEditSnippetDialog : public QDialog class VEditSnippetDialog : public QDialog
@ -36,6 +37,8 @@ public:
QChar getShortcutInput() const; QChar getShortcutInput() const;
bool getAutoIndentInput() const;
private slots: private slots:
void handleInputChanged(); void handleInputChanged();
@ -53,6 +56,7 @@ private:
QComboBox *m_shortcutCB; QComboBox *m_shortcutCB;
QLineEdit *m_cursorMarkEdit; QLineEdit *m_cursorMarkEdit;
QLineEdit *m_selectionMarkEdit; QLineEdit *m_selectionMarkEdit;
QCheckBox *m_autoIndentCB;
QTextEdit *m_contentEdit; QTextEdit *m_contentEdit;
QLabel *m_warnLabel; QLabel *m_warnLabel;

View File

@ -200,10 +200,11 @@ void VEditUtils::indentSelectedBlocks(const QTextDocument *p_doc,
} }
void VEditUtils::indentBlock(QTextCursor &p_cursor, void VEditUtils::indentBlock(QTextCursor &p_cursor,
const QString &p_indentationText) const QString &p_indentationText,
bool p_skipEmpty)
{ {
QTextBlock block = p_cursor.block(); QTextBlock block = p_cursor.block();
if (block.length() > 1) { if (block.length() > 1 || !p_skipEmpty) {
p_cursor.movePosition(QTextCursor::StartOfBlock); p_cursor.movePosition(QTextCursor::StartOfBlock);
p_cursor.insertText(p_indentationText); p_cursor.insertText(p_indentationText);
} }

View File

@ -63,9 +63,10 @@ public:
bool p_isIndent); bool p_isIndent);
// Indent current block. // Indent current block.
// Skip empty block. // @p_skipEmpty: skip empty block.
static void indentBlock(QTextCursor &p_cursor, static void indentBlock(QTextCursor &p_cursor,
const QString &p_indentationText); const QString &p_indentationText,
bool p_skipEmpty = true);
static void unindentBlock(QTextCursor &p_cursor, static void unindentBlock(QTextCursor &p_cursor,
const QString &p_indentationText); const QString &p_indentationText);

View File

@ -60,6 +60,7 @@ namespace SnippetConfig
static const QString c_cursorMark = "cursor_mark"; static const QString c_cursorMark = "cursor_mark";
static const QString c_selectionMark = "selection_mark"; static const QString c_selectionMark = "selection_mark";
static const QString c_shortcut = "shortcut"; static const QString c_shortcut = "shortcut";
static const QString c_autoIndent = "auto_indent";
} }
static const QString c_emptyHeaderName = "[EMPTY]"; static const QString c_emptyHeaderName = "[EMPTY]";

View File

@ -18,7 +18,8 @@ QVector<QChar> VSnippet::s_allShortcuts;
VSnippet::VSnippet() VSnippet::VSnippet()
: m_type(Type::PlainText), : m_type(Type::PlainText),
m_cursorMark(c_defaultCursorMark) m_cursorMark(c_defaultCursorMark),
m_autoIndent(false)
{ {
} }
@ -27,13 +28,15 @@ VSnippet::VSnippet(const QString &p_name,
const QString &p_content, const QString &p_content,
const QString &p_cursorMark, const QString &p_cursorMark,
const QString &p_selectionMark, const QString &p_selectionMark,
QChar p_shortcut) QChar p_shortcut,
bool p_autoIndent)
: m_name(p_name), : m_name(p_name),
m_type(p_type), m_type(p_type),
m_content(p_content), m_content(p_content),
m_cursorMark(p_cursorMark), m_cursorMark(p_cursorMark),
m_selectionMark(p_selectionMark), m_selectionMark(p_selectionMark),
m_shortcut(p_shortcut) m_shortcut(p_shortcut),
m_autoIndent(p_autoIndent)
{ {
Q_ASSERT(m_selectionMark != m_cursorMark); Q_ASSERT(m_selectionMark != m_cursorMark);
} }
@ -43,7 +46,8 @@ bool VSnippet::update(const QString &p_name,
const QString &p_content, const QString &p_content,
const QString &p_cursorMark, const QString &p_cursorMark,
const QString &p_selectionMark, const QString &p_selectionMark,
QChar p_shortcut) QChar p_shortcut,
bool p_autoIndent)
{ {
bool updated = false; bool updated = false;
if (m_name != p_name) { if (m_name != p_name) {
@ -76,6 +80,11 @@ bool VSnippet::update(const QString &p_name,
updated = true; updated = true;
} }
if (m_autoIndent != p_autoIndent) {
m_autoIndent = p_autoIndent;
updated = true;
}
qDebug() << "snippet" << m_name << "updated" << updated; qDebug() << "snippet" << m_name << "updated" << updated;
return updated; return updated;
@ -103,6 +112,7 @@ QJsonObject VSnippet::toJson() const
snip[SnippetConfig::c_cursorMark] = m_cursorMark; snip[SnippetConfig::c_cursorMark] = m_cursorMark;
snip[SnippetConfig::c_selectionMark] = m_selectionMark; snip[SnippetConfig::c_selectionMark] = m_selectionMark;
snip[SnippetConfig::c_shortcut] = m_shortcut.isNull() ? "" : QString(m_shortcut); snip[SnippetConfig::c_shortcut] = m_shortcut.isNull() ? "" : QString(m_shortcut);
snip[SnippetConfig::c_autoIndent] = m_autoIndent;
return snip; return snip;
} }
@ -120,7 +130,8 @@ VSnippet VSnippet::fromJson(const QJsonObject &p_json)
"", "",
p_json[SnippetConfig::c_cursorMark].toString(), p_json[SnippetConfig::c_cursorMark].toString(),
p_json[SnippetConfig::c_selectionMark].toString(), p_json[SnippetConfig::c_selectionMark].toString(),
shortcut); shortcut,
p_json[SnippetConfig::c_autoIndent].toBool());
return snip; return snip;
} }
@ -193,11 +204,15 @@ bool VSnippet::apply(QTextCursor &p_cursor) const
content += secondPart; content += secondPart;
// Auto indent.
QTextBlock startBlock = p_cursor.block();
QTextBlock endBlock;
QString indentation = VEditUtils::fetchIndentSpaces(startBlock);
// Insert it. // Insert it.
switch (m_type) { switch (m_type) {
case Type::Html: case Type::Html:
p_cursor.insertHtml(content); p_cursor.insertHtml(content);
// TODO: set the position of the cursor.
break; break;
case Type::PlainText: case Type::PlainText:
@ -205,10 +220,34 @@ bool VSnippet::apply(QTextCursor &p_cursor) const
default: default:
p_cursor.insertText(content); p_cursor.insertText(content);
p_cursor.setPosition(pos);
break; break;
} }
endBlock = p_cursor.block();
if (m_autoIndent
&& startBlock != endBlock
&& !indentation.isEmpty()) {
// Indent (startBlock, endBlock].
startBlock = startBlock.next();
while (startBlock.isValid()) {
int tmpPos = startBlock.position();
p_cursor.setPosition(tmpPos);
VEditUtils::indentBlock(p_cursor, indentation, false);
if (tmpPos <= pos) {
pos += indentation.size();
}
if (startBlock == endBlock) {
break;
}
startBlock = startBlock.next();
}
}
p_cursor.setPosition(pos);
p_cursor.endEditBlock(); p_cursor.endEditBlock();
return true; return true;
} }

View File

@ -23,7 +23,8 @@ public:
const QString &p_content = QString(), const QString &p_content = QString(),
const QString &p_cursorMark = c_defaultCursorMark, const QString &p_cursorMark = c_defaultCursorMark,
const QString &p_selectionMark = c_defaultSelectionMark, const QString &p_selectionMark = c_defaultSelectionMark,
QChar p_shortcut = QChar()); QChar p_shortcut = QChar(),
bool p_autoIndent = false);
// Return true if there is any update. // Return true if there is any update.
bool update(const QString &p_name, bool update(const QString &p_name,
@ -31,7 +32,8 @@ public:
const QString &p_content, const QString &p_content,
const QString &p_cursorMark, const QString &p_cursorMark,
const QString &p_selectionMark, const QString &p_selectionMark,
QChar p_shortcut); QChar p_shortcut,
bool p_autoIndent);
const QString &getName() const const QString &getName() const
{ {
@ -63,6 +65,11 @@ public:
return m_shortcut; return m_shortcut;
} }
bool getAutoIndent() const
{
return m_autoIndent;
}
void setContent(const QString &p_content) void setContent(const QString &p_content)
{ {
m_content = p_content; m_content = p_content;
@ -103,6 +110,9 @@ private:
// Shortcut to apply this snippet. // Shortcut to apply this snippet.
QChar m_shortcut; QChar m_shortcut;
// Auto indent with the first line.
bool m_autoIndent;
static const QString c_defaultCursorMark; static const QString c_defaultCursorMark;
static const QString c_defaultSelectionMark; static const QString c_defaultSelectionMark;

View File

@ -145,7 +145,8 @@ void VSnippetList::newSnippet()
dialog.getContentInput(), dialog.getContentInput(),
dialog.getCursorMarkInput(), dialog.getCursorMarkInput(),
dialog.getSelectionMarkInput(), dialog.getSelectionMarkInput(),
dialog.getShortcutInput()); dialog.getShortcutInput(),
dialog.getAutoIndentInput());
QString errMsg; QString errMsg;
if (!addSnippet(snippet, &errMsg)) { if (!addSnippet(snippet, &errMsg)) {
@ -336,7 +337,8 @@ void VSnippetList::snippetInfo()
dialog.getContentInput(), dialog.getContentInput(),
dialog.getCursorMarkInput(), dialog.getCursorMarkInput(),
dialog.getSelectionMarkInput(), dialog.getSelectionMarkInput(),
dialog.getShortcutInput())) { dialog.getShortcutInput(),
dialog.getAutoIndentInput())) {
if (!writeSnippetFile(*snip, &errMsg)) { if (!writeSnippetFile(*snip, &errMsg)) {
ret = false; ret = false;
} }