support highlighting current line by whole block in Vim non-Insert mode

This commit is contained in:
Le Tan 2017-06-11 19:57:31 +08:00
parent a44259e66c
commit c15908a724
8 changed files with 113 additions and 141 deletions

View File

@ -19,6 +19,7 @@
#include <QElapsedTimer>
#include "vfile.h"
#include "vnote.h"
extern VConfigManager vconfig;
@ -479,3 +480,75 @@ DocType VUtils::docTypeFromName(const QString &p_name)
return DocType::Html;
}
QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType, bool p_exportPdf)
{
QString jsFile, extraFile;
switch (p_conType) {
case MarkdownConverterType::Marked:
jsFile = "qrc" + VNote::c_markedJsFile;
extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>\n";
break;
case MarkdownConverterType::Hoedown:
jsFile = "qrc" + VNote::c_hoedownJsFile;
// Use Marked to highlight code blocks.
extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>\n";
break;
case MarkdownConverterType::MarkdownIt:
jsFile = "qrc" + VNote::c_markdownitJsFile;
extraFile = "<script src=\"qrc" + VNote::c_markdownitExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_markdownitAnchorExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_markdownitTaskListExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_markdownitSubExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_markdownitSupExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_markdownitFootnoteExtraFile + "\"></script>\n";
break;
case MarkdownConverterType::Showdown:
jsFile = "qrc" + VNote::c_showdownJsFile;
extraFile = "<script src=\"qrc" + VNote::c_showdownExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_showdownAnchorExtraFile + "\"></script>\n";
break;
default:
Q_ASSERT(false);
}
if (vconfig.getEnableMermaid()) {
extraFile += "<link rel=\"stylesheet\" type=\"text/css\" href=\"qrc" + VNote::c_mermaidCssFile +
"\"/>\n" + "<script src=\"qrc" + VNote::c_mermaidApiJsFile + "\"></script>\n" +
"<script>var VEnableMermaid = true;</script>\n";
}
if (vconfig.getEnableMathjax()) {
extraFile += "<script type=\"text/x-mathjax-config\">"
"MathJax.Hub.Config({\n"
" tex2jax: {inlineMath: [['$','$'], ['\\\\(','\\\\)']]},\n"
" showProcessingMessages: false,\n"
" messageStyle: \"none\"});\n"
"</script>\n"
"<script type=\"text/javascript\" async src=\"" + VNote::c_mathjaxJsFile + "\"></script>\n" +
"<script>var VEnableMathjax = true;</script>\n";
}
if (vconfig.getEnableImageCaption()) {
extraFile += "<script>var VEnableImageCaption = true;</script>\n";
}
QString htmlTemplate;
if (p_exportPdf) {
htmlTemplate = VNote::s_markdownTemplatePDF;
} else {
htmlTemplate = VNote::s_markdownTemplate;
}
htmlTemplate.replace(c_htmlJSHolder, jsFile);
if (!extraFile.isEmpty()) {
htmlTemplate.replace(c_htmlExtraHolder, extraFile);
}
return htmlTemplate;
}

View File

@ -96,6 +96,9 @@ public:
// Return the DocType according to suffix.
static DocType docTypeFromName(const QString &p_name);
// Generate HTML template.
static QString generateHtmlTemplate(MarkdownConverterType p_conType, bool p_exportPdf);
// Regular expression for image link.
// ![image title]( http://github.com/tamlok/vnote.jpg "alt \" text" )
// Captured texts (need to be trimmed):

View File

@ -32,6 +32,8 @@ void VEditConfig::init(const QFontMetrics &p_metric)
m_enableVimMode = vconfig.getEnableVimMode();
m_cursorLineBg = QColor(vconfig.getEditorCurrentLineBg());
m_highlightWholeBlock = m_enableVimMode;
}
VEdit::VEdit(VFile *p_file, QWidget *p_parent)
@ -439,14 +441,32 @@ void VEdit::highlightCurrentLine()
QList<QTextEdit::ExtraSelection> &selects = m_extraSelections[(int)SelectionId::CurrentLine];
if (vconfig.getHighlightCursorLine() && !isReadOnly()) {
// Need to highlight current line.
selects.clear();
// A long block maybe splited into multiple visual lines.
QTextEdit::ExtraSelection select;
select.format.setBackground(m_config.m_cursorLineBg);
select.format.setProperty(QTextFormat::FullWidthSelection, true);
select.cursor = textCursor();
select.cursor.clearSelection();
selects.clear();
QTextCursor cursor = textCursor();
if (m_config.m_highlightWholeBlock) {
cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor, 1);
QTextBlock block = cursor.block();
int blockEnd = block.position() + block.length();
int pos = -1;
while (cursor.position() < blockEnd && pos != cursor.position()) {
QTextEdit::ExtraSelection newSelect = select;
newSelect.cursor = cursor;
selects.append(newSelect);
pos = cursor.position();
cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, 1);
}
} else {
cursor.clearSelection();
select.cursor = cursor;
selects.append(select);
}
} else {
// Need to clear current line highlight.
if (selects.isEmpty()) {

View File

@ -26,8 +26,11 @@ enum class SelectionId {
class VEditConfig {
public:
VEditConfig() : m_tabStopWidth(0), m_tabSpaces("\t"),
m_enableVimMode(false) {}
VEditConfig() : m_tabStopWidth(0),
m_tabSpaces("\t"),
m_enableVimMode(false),
m_highlightWholeBlock(false)
{}
void init(const QFontMetrics &p_metric);
@ -43,6 +46,9 @@ public:
// The background color of cursor line.
QColor m_cursorLineBg;
// Whether highlight a visual line or a whole block.
bool m_highlightWholeBlock;
};
class VEdit : public QTextEdit

View File

@ -70,7 +70,8 @@ void VEditOperations::handleEditConfigUpdated()
void VEditOperations::handleVimModeChanged(VimMode p_mode)
{
Q_UNUSED(p_mode);
// Only highlight current visual line in Insert mode.
m_editConfig->m_highlightWholeBlock = (p_mode != VimMode::Insert);
updateCursorLineBg();
}

View File

@ -40,63 +40,7 @@ VExporter::VExporter(MarkdownConverterType p_mdType, QWidget *p_parent)
void VExporter::initMarkdownTemplate()
{
QString jsFile, extraFile;
switch (m_mdType) {
case MarkdownConverterType::Marked:
jsFile = "qrc" + VNote::c_markedJsFile;
extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>\n";
break;
case MarkdownConverterType::Hoedown:
jsFile = "qrc" + VNote::c_hoedownJsFile;
// Use Marked to highlight code blocks.
extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>\n";
break;
case MarkdownConverterType::MarkdownIt:
jsFile = "qrc" + VNote::c_markdownitJsFile;
extraFile = "<script src=\"qrc" + VNote::c_markdownitExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_markdownitAnchorExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_markdownitTaskListExtraFile + "\"></script>\n";
break;
case MarkdownConverterType::Showdown:
jsFile = "qrc" + VNote::c_showdownJsFile;
extraFile = "<script src=\"qrc" + VNote::c_showdownExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_showdownAnchorExtraFile + "\"></script>\n";
break;
default:
Q_ASSERT(false);
}
if (vconfig.getEnableMermaid()) {
extraFile += "<link rel=\"stylesheet\" type=\"text/css\" href=\"qrc" + VNote::c_mermaidCssFile +
"\"/>\n" + "<script src=\"qrc" + VNote::c_mermaidApiJsFile + "\"></script>\n" +
"<script>var VEnableMermaid = true;</script>\n";
}
if (vconfig.getEnableMathjax()) {
extraFile += "<script type=\"text/x-mathjax-config\">"
"MathJax.Hub.Config({\n"
" tex2jax: {inlineMath: [['$','$'], ['\\\\(','\\\\)']]},\n"
" showProcessingMessages: false,\n"
" messageStyle: \"none\"});\n"
"</script>\n"
"<script type=\"text/javascript\" async src=\"" + VNote::c_mathjaxJsFile + "\"></script>\n" +
"<script>var VEnableMathjax = true;</script>\n";
}
if (vconfig.getEnableImageCaption()) {
extraFile += "<script>var VEnableImageCaption = true;</script>\n";
}
m_htmlTemplate = VNote::s_markdownTemplatePDF;
m_htmlTemplate.replace(c_htmlJSHolder, jsFile);
if (!extraFile.isEmpty()) {
m_htmlTemplate.replace(c_htmlExtraHolder, extraFile);
}
m_htmlTemplate = VUtils::generateHtmlTemplate(m_mdType, true);
}
void VExporter::setupUI()
@ -268,8 +212,6 @@ void VExporter::initWebViewer(VFile *p_file)
channel->registerObject(QStringLiteral("content"), document);
page->setWebChannel(channel);
qDebug() << "VPreviewPage" << page->parent() << "QWebChannel" << channel->parent();
// Need to generate HTML using Hoedown.
if (m_mdType == MarkdownConverterType::Hoedown) {
VMarkdownConverter mdConverter;
@ -299,8 +241,6 @@ void VExporter::handleLogicsFinished()
void VExporter::handleLoadFinished(bool p_ok)
{
qDebug() << "Web load finished" << p_ok;
Q_ASSERT(!(m_noteState & NoteState::WebLoadFinished));
m_noteState = NoteState(m_noteState | NoteState::WebLoadFinished);

View File

@ -278,75 +278,6 @@ void VMdTab::discardAndRead()
readFile();
}
QString VMdTab::fillHtmlTemplate() const
{
const QString &jsHolder = c_htmlJSHolder;
const QString &extraHolder = c_htmlExtraHolder;
QString jsFile, extraFile;
switch (m_mdConType) {
case MarkdownConverterType::Marked:
jsFile = "qrc" + VNote::c_markedJsFile;
extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>\n";
break;
case MarkdownConverterType::Hoedown:
jsFile = "qrc" + VNote::c_hoedownJsFile;
// Use Marked to highlight code blocks.
extraFile = "<script src=\"qrc" + VNote::c_markedExtraFile + "\"></script>\n";
break;
case MarkdownConverterType::MarkdownIt:
jsFile = "qrc" + VNote::c_markdownitJsFile;
extraFile = "<script src=\"qrc" + VNote::c_markdownitExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_markdownitAnchorExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_markdownitTaskListExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_markdownitSubExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_markdownitSupExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_markdownitFootnoteExtraFile + "\"></script>\n";
break;
case MarkdownConverterType::Showdown:
jsFile = "qrc" + VNote::c_showdownJsFile;
extraFile = "<script src=\"qrc" + VNote::c_showdownExtraFile + "\"></script>\n" +
"<script src=\"qrc" + VNote::c_showdownAnchorExtraFile + "\"></script>\n";
break;
default:
Q_ASSERT(false);
}
if (vconfig.getEnableMermaid()) {
extraFile += "<link rel=\"stylesheet\" type=\"text/css\" href=\"qrc" + VNote::c_mermaidCssFile +
"\"/>\n" + "<script src=\"qrc" + VNote::c_mermaidApiJsFile + "\"></script>\n" +
"<script>var VEnableMermaid = true;</script>\n";
}
if (vconfig.getEnableMathjax()) {
extraFile += "<script type=\"text/x-mathjax-config\">"
"MathJax.Hub.Config({\n"
" tex2jax: {inlineMath: [['$','$'], ['\\\\(','\\\\)']]},\n"
" showProcessingMessages: false,\n"
" messageStyle: \"none\"});\n"
"</script>\n"
"<script type=\"text/javascript\" async src=\"" + VNote::c_mathjaxJsFile + "\"></script>\n" +
"<script>var VEnableMathjax = true;</script>\n";
}
if (vconfig.getEnableImageCaption()) {
extraFile += "<script>var VEnableImageCaption = true;</script>\n";
}
QString htmlTemplate = VNote::s_markdownTemplate;
htmlTemplate.replace(jsHolder, jsFile);
if (!extraFile.isEmpty()) {
htmlTemplate.replace(extraHolder, extraFile);
}
return htmlTemplate;
}
void VMdTab::setupMarkdownViewer()
{
m_webViewer = new VWebView(m_file, this);
@ -369,7 +300,8 @@ void VMdTab::setupMarkdownViewer()
this, &VMdTab::handleWebKeyPressed);
page->setWebChannel(channel);
m_webViewer->setHtml(fillHtmlTemplate(), m_file->getBaseUrl());
m_webViewer->setHtml(VUtils::generateHtmlTemplate(m_mdConType, false),
m_file->getBaseUrl());
m_stacks->addWidget(m_webViewer);
}

View File

@ -97,9 +97,6 @@ private:
// Show the file content in edit mode.
void showFileEditMode();
// Generate HTML template for Web view.
QString fillHtmlTemplate() const;
// Setup Markdown viewer.
void setupMarkdownViewer();