Show resolved code language on the left of each block header

This commit is contained in:
evgeny committed 2026-11-03 00:12:23 +01:00
1 parent 54b1a4fbe5
commit c1daeb4982
3 files changed
+16 -3

No files matched your search

+10 -3
View File
@@ -166,18 +166,25 @@ QSharedPointer<const MessageText> formattedMessageText(const QModelIndex& index)
static const QHash<QString, QString> aliases = {{"cpp", "C++"}, {"c++", "C++"}, {"c", "C"},
{"py", "Python"}, {"js", "JavaScript"}, {"ts", "TypeScript"}, {"sh", "Bash"}, {"shell", "Bash"},
{"cs", "C#"}, {"csharp", "C#"}, {"kt", "Kotlin"}, {"rs", "Rust"}, {"php", "PHP/PHP"}, {"yml", "YAML"}};
for (const auto& block : message->code) {
if (block.language == "text" || block.language == "plain") continue;
for (auto& block : message->code) {
block.languageName = block.language;
if (block.language == "text" || block.language == "plain") { block.languageName = "text"; continue; }
const QString language = block.language.isEmpty()
? detectCodeLanguage(QStringView(message->text).mid(block.start, block.length)) : block.language;
if (language.isEmpty()) continue;
block.languageName = language;
auto definition = repository.definitionForName(aliases.value(language, language));
if (!definition.isValid()) {
for (const auto& candidate : repository.definitions()) {
if (candidate.name().compare(language, Qt::CaseInsensitive) == 0) { definition = candidate; break; }
}
}
if (definition.isValid()) highlighter.highlight(block, definition);
if (definition.isValid()) {
block.languageName = definition.name() == "PHP/PHP" ? QStringLiteral("PHP") : definition.name();
highlighter.highlight(block, definition);
GUI_DEBUG("message code: language=%s explicit=%d chars=%d", qPrintable(block.languageName),
!block.language.isEmpty(), block.length);
}
else GUI_DEBUG("message code: unknown language=%s; using plain code", qPrintable(language));
}
}
+1
View File
@@ -12,6 +12,7 @@ struct MessageCodeBlock {
int start; // Начало кода в видимом тексте, UTF-16.
int length; // Длина без строк-ограждений; ноль означает пустой блок.
QString language; // Имя из ограждения: пустое включает автоопределение, неизвестное/text/plain отключает раскраску.
QString languageName; // Имя для шапки после подготовки подсветки; пусто означает обычный text.
};
struct MessageText {
+5
View File
@@ -1624,6 +1624,11 @@ void MessageDelegate::paintBody(QPainter* painter, const QStyleOptionViewItem& o
painter->drawRoundedRect(button.adjusted(0.5, 0.5, -0.5, -0.5), 4, 4);
painter->setPen(option.palette.buttonText().color());
painter->drawText(button, Qt::AlignCenter, QCoreApplication::translate("ChatGui", "Copy"));
const QRectF label(L.textRect.x() + 8, button.top(), qMax(0.0, button.left() - L.textRect.x() - 16), button.height());
painter->setPen(option.palette.text().color());
const QString language = block.languageName.isEmpty() ? QStringLiteral("text") : block.languageName;
painter->drawText(label, Qt::AlignLeft | Qt::AlignVCenter,
painter->fontMetrics().elidedText(language, Qt::ElideRight, int(label.width())));
}
painter->restore();
}