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 <QElapsedTimer>
|
||||||
|
|
||||||
#include "vfile.h"
|
#include "vfile.h"
|
||||||
|
#include "vnote.h"
|
||||||
|
|
||||||
extern VConfigManager vconfig;
|
extern VConfigManager vconfig;
|
||||||
|
|
||||||
@ -479,3 +480,75 @@ DocType VUtils::docTypeFromName(const QString &p_name)
|
|||||||
|
|
||||||
return DocType::Html;
|
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.
|
// Return the DocType according to suffix.
|
||||||
static DocType docTypeFromName(const QString &p_name);
|
static DocType docTypeFromName(const QString &p_name);
|
||||||
|
|
||||||
|
// Generate HTML template.
|
||||||
|
static QString generateHtmlTemplate(MarkdownConverterType p_conType, bool p_exportPdf);
|
||||||
|
|
||||||
// Regular expression for image link.
|
// Regular expression for image link.
|
||||||
// 
|
// 
|
||||||
// Captured texts (need to be trimmed):
|
// Captured texts (need to be trimmed):
|
||||||
|
@ -32,6 +32,8 @@ void VEditConfig::init(const QFontMetrics &p_metric)
|
|||||||
m_enableVimMode = vconfig.getEnableVimMode();
|
m_enableVimMode = vconfig.getEnableVimMode();
|
||||||
|
|
||||||
m_cursorLineBg = QColor(vconfig.getEditorCurrentLineBg());
|
m_cursorLineBg = QColor(vconfig.getEditorCurrentLineBg());
|
||||||
|
|
||||||
|
m_highlightWholeBlock = m_enableVimMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
VEdit::VEdit(VFile *p_file, QWidget *p_parent)
|
VEdit::VEdit(VFile *p_file, QWidget *p_parent)
|
||||||
@ -439,14 +441,32 @@ void VEdit::highlightCurrentLine()
|
|||||||
QList<QTextEdit::ExtraSelection> &selects = m_extraSelections[(int)SelectionId::CurrentLine];
|
QList<QTextEdit::ExtraSelection> &selects = m_extraSelections[(int)SelectionId::CurrentLine];
|
||||||
if (vconfig.getHighlightCursorLine() && !isReadOnly()) {
|
if (vconfig.getHighlightCursorLine() && !isReadOnly()) {
|
||||||
// Need to highlight current line.
|
// Need to highlight current line.
|
||||||
|
selects.clear();
|
||||||
|
|
||||||
|
// A long block maybe splited into multiple visual lines.
|
||||||
QTextEdit::ExtraSelection select;
|
QTextEdit::ExtraSelection select;
|
||||||
select.format.setBackground(m_config.m_cursorLineBg);
|
select.format.setBackground(m_config.m_cursorLineBg);
|
||||||
select.format.setProperty(QTextFormat::FullWidthSelection, true);
|
select.format.setProperty(QTextFormat::FullWidthSelection, true);
|
||||||
select.cursor = textCursor();
|
|
||||||
select.cursor.clearSelection();
|
|
||||||
|
|
||||||
selects.clear();
|
QTextCursor cursor = textCursor();
|
||||||
selects.append(select);
|
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 {
|
} else {
|
||||||
// Need to clear current line highlight.
|
// Need to clear current line highlight.
|
||||||
if (selects.isEmpty()) {
|
if (selects.isEmpty()) {
|
||||||
|
10
src/vedit.h
10
src/vedit.h
@ -26,8 +26,11 @@ enum class SelectionId {
|
|||||||
|
|
||||||
class VEditConfig {
|
class VEditConfig {
|
||||||
public:
|
public:
|
||||||
VEditConfig() : m_tabStopWidth(0), m_tabSpaces("\t"),
|
VEditConfig() : m_tabStopWidth(0),
|
||||||
m_enableVimMode(false) {}
|
m_tabSpaces("\t"),
|
||||||
|
m_enableVimMode(false),
|
||||||
|
m_highlightWholeBlock(false)
|
||||||
|
{}
|
||||||
|
|
||||||
void init(const QFontMetrics &p_metric);
|
void init(const QFontMetrics &p_metric);
|
||||||
|
|
||||||
@ -43,6 +46,9 @@ public:
|
|||||||
|
|
||||||
// The background color of cursor line.
|
// The background color of cursor line.
|
||||||
QColor m_cursorLineBg;
|
QColor m_cursorLineBg;
|
||||||
|
|
||||||
|
// Whether highlight a visual line or a whole block.
|
||||||
|
bool m_highlightWholeBlock;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VEdit : public QTextEdit
|
class VEdit : public QTextEdit
|
||||||
|
@ -70,7 +70,8 @@ void VEditOperations::handleEditConfigUpdated()
|
|||||||
|
|
||||||
void VEditOperations::handleVimModeChanged(VimMode p_mode)
|
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();
|
updateCursorLineBg();
|
||||||
}
|
}
|
||||||
|
@ -40,63 +40,7 @@ VExporter::VExporter(MarkdownConverterType p_mdType, QWidget *p_parent)
|
|||||||
|
|
||||||
void VExporter::initMarkdownTemplate()
|
void VExporter::initMarkdownTemplate()
|
||||||
{
|
{
|
||||||
QString jsFile, extraFile;
|
m_htmlTemplate = VUtils::generateHtmlTemplate(m_mdType, true);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VExporter::setupUI()
|
void VExporter::setupUI()
|
||||||
@ -268,8 +212,6 @@ void VExporter::initWebViewer(VFile *p_file)
|
|||||||
channel->registerObject(QStringLiteral("content"), document);
|
channel->registerObject(QStringLiteral("content"), document);
|
||||||
page->setWebChannel(channel);
|
page->setWebChannel(channel);
|
||||||
|
|
||||||
qDebug() << "VPreviewPage" << page->parent() << "QWebChannel" << channel->parent();
|
|
||||||
|
|
||||||
// Need to generate HTML using Hoedown.
|
// Need to generate HTML using Hoedown.
|
||||||
if (m_mdType == MarkdownConverterType::Hoedown) {
|
if (m_mdType == MarkdownConverterType::Hoedown) {
|
||||||
VMarkdownConverter mdConverter;
|
VMarkdownConverter mdConverter;
|
||||||
@ -299,8 +241,6 @@ void VExporter::handleLogicsFinished()
|
|||||||
|
|
||||||
void VExporter::handleLoadFinished(bool p_ok)
|
void VExporter::handleLoadFinished(bool p_ok)
|
||||||
{
|
{
|
||||||
qDebug() << "Web load finished" << p_ok;
|
|
||||||
|
|
||||||
Q_ASSERT(!(m_noteState & NoteState::WebLoadFinished));
|
Q_ASSERT(!(m_noteState & NoteState::WebLoadFinished));
|
||||||
m_noteState = NoteState(m_noteState | NoteState::WebLoadFinished);
|
m_noteState = NoteState(m_noteState | NoteState::WebLoadFinished);
|
||||||
|
|
||||||
|
@ -278,75 +278,6 @@ void VMdTab::discardAndRead()
|
|||||||
readFile();
|
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()
|
void VMdTab::setupMarkdownViewer()
|
||||||
{
|
{
|
||||||
m_webViewer = new VWebView(m_file, this);
|
m_webViewer = new VWebView(m_file, this);
|
||||||
@ -369,7 +300,8 @@ void VMdTab::setupMarkdownViewer()
|
|||||||
this, &VMdTab::handleWebKeyPressed);
|
this, &VMdTab::handleWebKeyPressed);
|
||||||
page->setWebChannel(channel);
|
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);
|
m_stacks->addWidget(m_webViewer);
|
||||||
}
|
}
|
||||||
|
@ -97,9 +97,6 @@ private:
|
|||||||
// Show the file content in edit mode.
|
// Show the file content in edit mode.
|
||||||
void showFileEditMode();
|
void showFileEditMode();
|
||||||
|
|
||||||
// Generate HTML template for Web view.
|
|
||||||
QString fillHtmlTemplate() const;
|
|
||||||
|
|
||||||
// Setup Markdown viewer.
|
// Setup Markdown viewer.
|
||||||
void setupMarkdownViewer();
|
void setupMarkdownViewer();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user