mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
support highlighting current line by whole block in Vim non-Insert mode
This commit is contained in:
parent
a44259e66c
commit
c15908a724
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
// 
|
||||
// Captured texts (need to be trimmed):
|
||||
|
@ -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();
|
||||
selects.append(select);
|
||||
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()) {
|
||||
|
10
src/vedit.h
10
src/vedit.h
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user