TextEditor: add json indenter

Use an EditorFactory that sets up a custom indenter for json files.

Change-Id: Id5ade9f9f551835131a62e381a972f0b6032e7c0
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2023-08-23 15:38:01 +02:00
parent 28742774fe
commit ddb4aa0151
5 changed files with 116 additions and 0 deletions

View File

@@ -68,6 +68,7 @@ add_qtc_plugin(TextEditor
icodestylepreferencesfactory.cpp icodestylepreferencesfactory.h
indenter.h
ioutlinewidget.h
jsoneditor.cpp jsoneditor.h
linenumberfilter.cpp linenumberfilter.h
marginsettings.cpp marginsettings.h
markdowneditor.cpp markdowneditor.h

View File

@@ -0,0 +1,95 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "jsoneditor.h"
#include "autocompleter.h"
#include "textdocument.h"
#include "texteditoractionhandler.h"
#include "texteditortr.h"
#include "textindenter.h"
namespace TextEditor::Internal {
const char JSON_EDITOR_ID[] = "Editors.Json";
const char JSON_MIME_TYPE[] = "application/json";
static int startsWith(const QString &line, const QString &closingChars)
{
int count = 0;
for (const QChar &lineChar : line) {
if (closingChars.contains(lineChar))
++count;
else if (!lineChar.isSpace())
break;
}
return count;
}
class JsonAutoCompleter : public AutoCompleter
{
bool contextAllowsElectricCharacters(const QTextCursor &cursor) const override { return true; }
};
class JsonIndenter : public TextIndenter
{
public:
JsonIndenter(QTextDocument *doc) : TextIndenter(doc) {}
bool isElectricCharacter(const QChar &c) const override
{
static QString echars("{}[]");
return echars.contains(c);
}
int indentFor(const QTextBlock &block,
const TabSettings &tabSettings,
int /*cursorPositionInEditor*/) override
{
QTextBlock previous = block.previous();
if (!previous.isValid())
return 0;
QString previousText = previous.text();
while (previousText.trimmed().isEmpty()) {
previous = previous.previous();
if (!previous.isValid())
return 0;
previousText = previous.text();
}
int indent = tabSettings.indentationColumn(previousText);
int adjust = previousText.count('{') + previousText.count('[');
adjust -= previousText.count('}') + previousText.count(']');
adjust += startsWith(previousText, "}]") - startsWith(block.text(), "}]");
adjust *= tabSettings.m_indentSize;
return qMax(0, indent + adjust);
}
void indentBlock(const QTextBlock &block,
const QChar &typedChar,
const TabSettings &tabSettings,
int cursorPositionInEditor) override
{
tabSettings.indentLine(block, indentFor(block, tabSettings, cursorPositionInEditor));
}
};
JsonEditorFactory::JsonEditorFactory()
{
setId(JSON_EDITOR_ID);
setDisplayName(Tr::tr("Json Editor"));
addMimeType(JSON_MIME_TYPE);
setEditorCreator([] { return new BaseTextEditor; });
setEditorWidgetCreator([] { return new TextEditorWidget; });
setDocumentCreator([] { return new TextDocument(JSON_EDITOR_ID); });
setAutoCompleterCreator([] { return new JsonAutoCompleter; });
setIndenterCreator([](QTextDocument *doc) { return new JsonIndenter(doc); });
setEditorActionHandlers(TextEditorActionHandler::Format);
setUseGenericHighlighter(true);
}
} // namespace TextEditor::Internal

View File

@@ -0,0 +1,16 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include "texteditor.h"
namespace TextEditor::Internal {
class JsonEditorFactory final : public TextEditorFactory
{
public:
JsonEditorFactory();
};
} // TextEditor::Internal

View File

@@ -90,6 +90,8 @@ Project {
"icodestylepreferencesfactory.h",
"indenter.h",
"ioutlinewidget.h",
"jsoneditor.cpp",
"jsoneditor.h",
"linenumberfilter.cpp",
"linenumberfilter.h",
"marginsettings.cpp",

View File

@@ -10,6 +10,7 @@
#include "fontsettings.h"
#include "highlighter.h"
#include "icodestylepreferences.h"
#include "jsoneditor.h"
#include "linenumberfilter.h"
#include "markdowneditor.h"
#include "outlinefactory.h"
@@ -76,6 +77,7 @@ public:
PlainTextEditorFactory plainTextEditorFactory;
MarkdownEditorFactory markdownEditorFactory;
JsonEditorFactory jsonEditorFactory;
};
static TextEditorPlugin *m_instance = nullptr;