Skip to content

Commit

Permalink
feat: support for ANSI color sequences(#338)
Browse files Browse the repository at this point in the history
  • Loading branch information
nowhszh committed Jul 31, 2023
1 parent ab20712 commit 8ad7bea
Show file tree
Hide file tree
Showing 15 changed files with 1,062 additions and 19 deletions.
8 changes: 4 additions & 4 deletions src/logdata/include/onelinelog.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ class OneLineLog {
OneLineLog& operator=( OneLineLog&& ) = default;
OneLineLog( OneLineLog&& ) = default;

QString string();
QString string() const;

QString expandedString();
QString expandedString() const;

QString process( std::function<void( QString& )> fn );
QString process( std::function<void( QString& )> fn ) const;

inline bool empty()
inline bool empty() const
{
return buffer_.isEmpty() || !decoder_ || !reg_;
}
Expand Down
6 changes: 3 additions & 3 deletions src/logdata/src/onelinelog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ OneLineLog::OneLineLog( const char* data, OneLineLog::Length len, std::shared_pt
{
}

QString OneLineLog::string()
QString OneLineLog::string() const
{
if ( empty() ) {
LOG_WARNING << buffer_.isEmpty() << ",count:" << decoder_.use_count() << ","
Expand All @@ -35,7 +35,7 @@ QString OneLineLog::string()
return log;
}

QString OneLineLog::expandedString()
QString OneLineLog::expandedString() const
{
if ( empty() ) {
LOG_INFO << buffer_.isEmpty() << ",count:" << decoder_.use_count() << ","
Expand All @@ -51,7 +51,7 @@ QString OneLineLog::expandedString()
return untabify( std::move( log ) );
}

QString OneLineLog::process( std::function<void( QString& )> fn )
QString OneLineLog::process( std::function<void( QString& )> fn ) const
{
if ( empty() ) {
LOG_INFO << buffer_.isEmpty() << ",count:" << decoder_.use_count() << ","
Expand Down
13 changes: 12 additions & 1 deletion src/settings/include/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,15 @@ class Configuration final : public Persistable<Configuration> {
hideAnsiColorSequences_ = hide;
}

bool displayAnsiColorSequences() const
{
return displayAnsiColorSequences_;
}
void setDisplayAnsiColorSequences( bool display )
{
displayAnsiColorSequences_ = display;
}

int defaultEncodingMib() const
{
return defaultEncodingMib_;
Expand All @@ -500,7 +509,8 @@ class Configuration final : public Persistable<Configuration> {
defaultEncodingMib_ = mib;
}

std::map<QString, QString> darkPalette() const {
std::map<QString, QString> darkPalette() const
{
return darkPalette_;
}

Expand Down Expand Up @@ -581,6 +591,7 @@ class Configuration final : public Persistable<Configuration> {
bool optimizeForNotLatinEncodings_ = false;

bool hideAnsiColorSequences_ = false;
bool displayAnsiColorSequences_ = false;

int defaultEncodingMib_ = -1;

Expand Down
9 changes: 7 additions & 2 deletions src/settings/src/configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,10 @@ void Configuration::retrieveFromStorage( QSettings& settings )
= settings
.value( "view.hideAnsiColorSequences", DefaultConfiguration.hideAnsiColorSequences_ )
.toBool();
displayAnsiColorSequences_ = settings
.value( "view.displayAnsiColorSequences",
DefaultConfiguration.displayAnsiColorSequences_ )
.toBool();

useTextWrap_ = settings.value( "view.textWrap", DefaultConfiguration.useTextWrap() ).toBool();

Expand Down Expand Up @@ -300,7 +304,7 @@ void Configuration::retrieveFromStorage( QSettings& settings )
const auto mapping = settings.value( "shortcuts.mapping" ).toMap();
for ( auto keys = mapping.begin(); keys != mapping.end(); ++keys ) {
auto action = keys.key().toStdString();
if (action == ShortcutAction::LogViewJumpToButtom) {
if ( action == ShortcutAction::LogViewJumpToButtom ) {
action = ShortcutAction::LogViewJumpToBottom;
}
shortcuts_.emplace( action, keys.value().toStringList() );
Expand All @@ -314,7 +318,7 @@ void Configuration::retrieveFromStorage( QSettings& settings )
settings.setArrayIndex( static_cast<int>( shortcutIndex ) );
auto action = settings.value( "action", "" ).toString();
if ( !action.isEmpty() ) {
if (action == ShortcutAction::LogViewJumpToButtom) {
if ( action == ShortcutAction::LogViewJumpToButtom ) {
action = ShortcutAction::LogViewJumpToBottom;
}
const auto keys = settings.value( "keys", QStringList() ).toStringList();
Expand Down Expand Up @@ -395,6 +399,7 @@ void Configuration::saveToStorage( QSettings& settings ) const
settings.setValue( "view.scaleFactorRounding", scaleFactorRounding_ );

settings.setValue( "view.hideAnsiColorSequences", hideAnsiColorSequences_ );
settings.setValue( "view.displayAnsiColorSequences", displayAnsiColorSequences_ );

settings.setValue( "defaultView.searchAutoRefresh", searchAutoRefresh_ );
settings.setValue( "defaultView.searchIgnoreCase", searchIgnoreCase_ );
Expand Down
5 changes: 5 additions & 0 deletions src/ui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ add_library(
${CMAKE_CURRENT_SOURCE_DIR}/include/decompressor.h
${CMAKE_CURRENT_SOURCE_DIR}/include/fontutils.h
${CMAKE_CURRENT_SOURCE_DIR}/include/colorlabelsmanager.h
${CMAKE_CURRENT_SOURCE_DIR}/include/ansi.h
${CMAKE_CURRENT_SOURCE_DIR}/include/sgrparser.h
${CMAKE_CURRENT_SOURCE_DIR}/include/colorfultextparser.h
${CMAKE_CURRENT_SOURCE_DIR}/include/highlighteredit.ui
${CMAKE_CURRENT_SOURCE_DIR}/include/highlightersetedit.ui
${CMAKE_CURRENT_SOURCE_DIR}/include/highlightersdialog.ui
Expand Down Expand Up @@ -91,6 +94,8 @@ add_library(
${CMAKE_CURRENT_SOURCE_DIR}/src/downloader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/decompressor.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/colorlabelsmanager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/sgrparser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/colorfultextparser.cpp
)

set_target_properties(klogg_ui PROPERTIES AUTOUIC ON)
Expand Down
1 change: 1 addition & 0 deletions src/ui/include/abstractlogview.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#include "quickfindmux.h"
#include "regularexpressionpattern.h"
#include "selection.h"
#include "sgrparser.h"
#include "viewtools.h"

class QMenu;
Expand Down
94 changes: 94 additions & 0 deletions src/ui/include/ansi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//
// Created by marvin on 23-7-18.
//
#pragma once

#include <cstdint>

namespace ANSI {

enum SequenceStartCnt {
HEAD_CNT = 2,
};

// reference: https://www.ecma-international.org/publications-and-standards/standards/ecma-48/
enum SequenceFirst {
EXC = 0x1B, // Escape(转义)
};

// reference: https://www.ecma-international.org/publications-and-standards/standards/ecma-48/
enum SequenceSecond {
PAD = 0x40, // 0x80 Padding Character(填充字符)
HOP = 0x41, // 0x81 High Octet Preset(高字节前置)
BPH = 0x42, // 0x82 Break Permitted Here(此处允许中断)
NBH = 0x43, // 0x83 No Break Here(此处禁止中断)
IND = 0x44, // 0x84 Index(索引)
NEL = 0x45, // 0x85 Next Line(下一行)
SSA = 0x46, // 0x86 Start of Selected Area(选择区域开始)
ESA = 0x47, // 0x87 End of Selected Area(选择区域结束)
HTS = 0x48, // 0x88 Horizontal Tab Set(水平制表设置)
HTJ = 0x49, // 0x89 Horizontal Tab Justified(水平制表调整)
VTS = 0x4A, // 0x8A Vertical Tab Set(垂直制表设置)
PLD = 0x4B, // 0x8B Partial Line Forward(部分行前移)
PLU = 0x4C, // 0x8C Partial Line Backward(部分行后移)
RI = 0x4D, // 0x8D Reverse Line Feed(逆向馈行)
SS2 = 0x4E, // 0x8E Single-Shift 2(单个移动2)
SS3 = 0x4F, // 0x8F Single-Shift 3(单个移动3)
DCS = 0x50, // 0x90 Device Control String(设备控制串)
PU1 = 0x51, // 0x91 Private Use 1(私用1)
PU2 = 0x52, // 0x92 Private Use 2(私用2)
STS = 0x53, // 0x93 Set Transmit State(发送规则设置)
CCH = 0x54, // 0x94 Cancel Character(取消字符)
MW = 0x55, // 0x95 Message Waiting(消息等待)
SPA = 0x56, // 0x96 Start of Protected Area(保护区域开始)
EPA = 0x57, // 0x97 End of Protected Area(保护区域结束)
SOS = 0x58, // 0x98 Start of String(串开始)
SGC = 0x59, // 0x99 Single Graphic Char Intro(单个图形字符描述)
SCI = 0x5A, // 0x9A Single Char Intro(单个字符描述)
CSI = 0x5B, // 0x9B Control Sequence Intro(控制顺序描述)
ST = 0x5C, // 0x9C String Terminator(串终止)
OSC = 0x5D, // 0x9D OS Command(操作系统指令)
PM = 0x5E, // 0x9E Private Message(私讯)
APC = 0x5F, // 0x9F App Program Command(应用程序命令)

SECOND_BYTE_BEGIN = PAD,
SECOND_BYTE_END = APC,
};

// reference: https://www.ecma-international.org/publications-and-standards/standards/ecma-48/
enum CSIParameterBytes {
// ASCII: 0–9:;<=>?
NUM_BEGIN = 0x30,
NUM_END = 0x39,
SUB_PARA_SEPARATOR = 0x3A,
PARA_SEPARATOR = 0x3B,
STANDARDIZATION_KEEP_BEGIN = 0x3C,
STANDARDIZATION_KEEP_END = 0x3F,

CSI_PARAMETER_BEGIN = 0x30,
CSI_PARAMETER_END = 0x3F,
};

enum CSIIntermediateBytes {
// ASCII: Space、!"#$%&'()*+,-./
CSIIntermediateBegin = 0x20,
CSIIntermediateEnd = 0x2F,
};

enum CSIFinalBytes {
// ASCII: @A–Z[\]^_`a–z{|}~
SGR = 0x6D, // m

CSIFinalBegin = 0x40,
CSIFinalEnd = 0x7E,

CSIFinalExperimentalBegin = 0x70,
CSIFinalExperimentalEnd = CSIFinalEnd,
};

enum class Return {
PARSE_ERROR = -1,
PARSE_SUCC = 0,
};

} // namespace ANSI
68 changes: 68 additions & 0 deletions src/ui/include/colorfultextparser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//
// Created by marvin on 23-7-24.
//

#pragma once

#include <vector>

#include <QString>

#include "containers.h"
#include "highlightedmatch.h"
#include "sgrparser.h"

namespace ansi {
using position_t = QString::size_type;
}

struct TextColorAttr {
ANSI::Color color;
ansi::position_t start;
ansi::position_t len;
operator HighlightedMatch();
};

struct ColorfulText {
QString text;
klogg::vector<TextColorAttr> color;
};

// ANSI: start, data
using SGRSequence = std::pair<ansi::position_t, QString>;

class CSIFilter {
public:
CSIFilter() = default;
~CSIFilter() = default;

static klogg::vector<SGRSequence> filter( QString& text );
};

class ColorfulTextParser {
public:
enum class Mode {
MARKED_TEXT,
ALL_TEXT,
};

public:
explicit ColorfulTextParser( const ANSI::TextAttribute& defaultAttr,
const ANSI::TextAttribute& currentAttr );

// QString
ColorfulText parse( QString strings, Mode mode = Mode::ALL_TEXT );

klogg::vector<ColorfulText> parse( const klogg::vector<QString>& strings,
Mode mode = Mode::ALL_TEXT );

private:
void markedStringToText( klogg::vector<ColorfulText>& textList,
const klogg::vector<SGRSequence>& sgrSeqs, QString&& string );
void allStringToText( klogg::vector<ColorfulText>& textList,
const klogg::vector<SGRSequence>& sgrSeqs, QString&& string );

private:
ANSI::TextAttribute currentTextAttr_;
ANSI::SGRParser sgrParser_;
};
9 changes: 8 additions & 1 deletion src/ui/include/optionsdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<bool>true</bool>
</property>
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="general_tab">
<attribute name="title">
Expand Down Expand Up @@ -398,6 +398,13 @@
<string>Miscellaneous</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QCheckBox" name="displayAnsiColorsCheckBox">
<property name="text">
<string>Display ANSI Colors (search performance will be reduced)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="hideAnsiColorsCheckBox">
<property name="enabled">
Expand Down
Loading

0 comments on commit 8ad7bea

Please sign in to comment.