From 1b81f2d1eb9bca868cbd1710106345dc76c6145c Mon Sep 17 00:00:00 2001
From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com>
Date: Mon, 20 Jun 2022 10:17:11 +0200
Subject: [PATCH] Modify CTextLogger

Redact and modify CTextLogger (copy of CTextEditor) to fit logger usage.
Removed most unnecessary methods/code and members.
---
 r5dev/thirdparty/imgui/include/imgui_logger.h |  215 +-
 r5dev/thirdparty/imgui/src/imgui_logger.cpp   | 1765 +----------------
 2 files changed, 123 insertions(+), 1857 deletions(-)

diff --git a/r5dev/thirdparty/imgui/include/imgui_logger.h b/r5dev/thirdparty/imgui/include/imgui_logger.h
index 7d8a0329..9df94508 100644
--- a/r5dev/thirdparty/imgui/include/imgui_logger.h
+++ b/r5dev/thirdparty/imgui/include/imgui_logger.h
@@ -10,34 +10,20 @@
 #include <regex>
 #include "imgui.h"
 
+struct CConLog
+{
+	CConLog(const std::string& svConLog, const ImVec4& imColor)
+	{
+		m_svConLog = svConLog;
+		m_imColor = imColor;
+	}
+	std::string m_svConLog;
+	ImVec4 m_imColor;
+};
+
 class CTextLogger
 {
 public:
-	enum class PaletteIndex
-	{
-		Default,
-		Keyword,
-		Number,
-		String,
-		CharLiteral,
-		Punctuation,
-		Preprocessor,
-		Identifier,
-		KnownIdentifier,
-		PreprocIdentifier,
-		Comment,
-		MultiLineComment,
-		Background,
-		Cursor,
-		Selection,
-		ErrorMarker,
-		Breakpoint,
-		LineNumber,
-		CurrentLineFill,
-		CurrentLineFillInactive,
-		CurrentLineEdge,
-		Max
-	};
 
 	enum class SelectionMode
 	{
@@ -46,18 +32,6 @@ public:
 		Line
 	};
 
-	struct Breakpoint
-	{
-		int mLine;
-		bool mEnabled;
-		std::string mCondition;
-
-		Breakpoint()
-			: mLine(-1)
-			, mEnabled(false)
-		{}
-	};
-
 	// Represents a character coordinate from the user's point of view,
 	// i. e. consider an uniform grid (assuming fixed-width font) on the
 	// screen as it is rendered, and each cell has its own coordinate, starting from 0.
@@ -119,86 +93,29 @@ public:
 		}
 	};
 
-	struct Identifier
-	{
-		Coordinates m_Location;
-		std::string m_svDeclaration;
-	};
-
 	typedef std::string String;
-	typedef std::unordered_map<std::string, Identifier> Identifiers;
-	typedef std::unordered_set<std::string> Keywords;
-	typedef std::map<int, std::string> ErrorMarkers;
-	typedef std::unordered_set<int> Breakpoints;
-	typedef std::array<ImU32, (unsigned)PaletteIndex::Max> Palette;
 	typedef uint8_t Char;
 
 	struct Glyph
 	{
 		Char m_Char;
-		PaletteIndex m_ColorIndex = PaletteIndex::Default;
-		bool m_bComment : 1;
-		bool m_bMultiLineComment : 1;
-		bool m_bPreprocessor : 1;
+		ImVec4 m_Color = ImVec4(0.23f, 0.47f, 0.85f, 1.00f);
 
-		Glyph(Char aChar, PaletteIndex aColorIndex) : m_Char(aChar), m_ColorIndex(aColorIndex),
-			m_bComment(false), m_bMultiLineComment(false), m_bPreprocessor(false) {}
+		Glyph(Char aChar, ImVec4 aColor = ImVec4(0.80f, 0.80f, 0.80f, 1.00f)) : m_Char(aChar), m_Color(aColor) {}
 	};
 
 	typedef std::vector<Glyph> Line;
 	typedef std::vector<Line> Lines;
 
-	struct LanguageDefinition
-	{
-		typedef std::pair<std::string, PaletteIndex> TokenRegexString;
-		typedef std::vector<TokenRegexString> TokenRegexStrings;
-		typedef bool(*TokenizeCallback)(const char* in_begin, const char* in_end, const char*& out_begin, const char*& out_end, PaletteIndex& paletteIndex);
-
-		std::string m_svName;
-		Keywords m_Keywords;
-		Identifiers m_Identifiers;
-		Identifiers m_PreprocIdentifiers;
-		std::string m_svCommentStart, m_svCommentEnd, m_svSingleLineComment;
-		char m_PreprocChar;
-		bool m_bAutoIndentation;
-
-		TokenizeCallback m_Tokenize;
-
-		TokenRegexStrings m_TokenRegexStrings;
-
-		bool mCaseSensitive;
-
-		LanguageDefinition()
-			: m_PreprocChar('#'), m_bAutoIndentation(true), m_Tokenize(nullptr), mCaseSensitive(true)
-		{
-		}
-
-		static const LanguageDefinition& CPlusPlus();
-		static const LanguageDefinition& HLSL();
-		static const LanguageDefinition& GLSL();
-		static const LanguageDefinition& C();
-		static const LanguageDefinition& SQL();
-		static const LanguageDefinition& AngelScript();
-		static const LanguageDefinition& Lua();
-	};
-
 	CTextLogger();
 	~CTextLogger();
 
-	void SetLanguageDefinition(const LanguageDefinition& aLanguageDef);
-	const LanguageDefinition& GetLanguageDefinition() const { return m_LanguageDefinition; }
+	void Render();
 
-	const Palette& GetPalette() const { return m_PaletteBase; }
-	void SetPalette(const Palette& aValue);
-
-	void SetErrorMarkers(const ErrorMarkers& aMarkers) { m_ErrorMarkers = aMarkers; }
-	void SetBreakpoints(const Breakpoints& aMarkers) { m_Breakpoints = aMarkers; }
-
-	void Render(const char* aTitle, const ImVec2& aSize = ImVec2(), bool aBorder = false);
-	void SetText(const std::string& aText);
+	void SetText(const CConLog& aText);
 	std::string GetText() const;
 
-	void SetTextLines(const std::vector<std::string>& aLines);
+	void SetTextLines(const std::vector<CConLog>& aLines);
 	std::vector<std::string> GetTextLines() const;
 
 	std::string GetSelectedText() const;
@@ -209,32 +126,24 @@ public:
 
 	void SetReadOnly(bool aValue);
 	bool IsReadOnly() const { return m_bReadOnly; }
-	bool IsTextChanged() const { return m_bTextChanged; }
 	bool IsCursorPositionChanged() const { return m_bCursorPositionChanged; }
 
-	bool IsColorizerEnabled() const { return m_bColorizerEnabled; }
-	void SetColorizerEnable(bool aValue);
-
 	Coordinates GetCursorPosition() const { return GetActualCursorCoordinates(); }
 	void SetCursorPosition(const Coordinates& aPosition);
 
-	inline void SetHandleMouseInputs(bool aValue) { m_bHandleMouseInputs = aValue; }
+	inline void SetHandleMouseInputs    (bool aValue){ m_bHandleMouseInputs    = aValue;}
 	inline bool IsHandleMouseInputsEnabled() const { return m_bHandleKeyboardInputs; }
 
-	inline void SetHandleKeyboardInputs(bool aValue) { m_bHandleKeyboardInputs = aValue; }
+	inline void SetHandleKeyboardInputs (bool aValue){ m_bHandleKeyboardInputs = aValue;}
 	inline bool IsHandleKeyboardInputsEnabled() const { return m_bHandleKeyboardInputs; }
 
-	inline void SetImGuiChildIgnored(bool aValue) { m_bIgnoreImGuiChild = aValue; }
-	inline bool IsImGuiChildIgnored() const { return m_bIgnoreImGuiChild; }
-
-	inline void SetShowWhitespaces(bool aValue) { m_bShowWhitespaces = aValue; }
-	inline bool IsShowingWhitespaces() const { return m_bShowWhitespaces; }
+	inline void SetShowWhitespaces(bool aValue) { m_bShowWhiteSpaces = aValue; }
+	inline bool IsShowingWhitespaces() const { return m_bShowWhiteSpaces; }
 
 	void SetTabSize(int aValue);
 	inline int GetTabSize() const { return m_nTabSize; }
 
-	void InsertText(const std::string& aValue);
-	void InsertText(const char* aValue);
+	void InsertText(const CConLog& aValue);
 
 	void MoveUp(int aAmount = 1, bool aSelect = false);
 	void MoveDown(int aAmount = 1, bool aSelect = false);
@@ -252,22 +161,12 @@ public:
 	void SelectAll();
 	bool HasSelection() const;
 
+	void RemoveLine(int aStart, int aEnd);
+	void RemoveLine(int aIndex);
+
 	void Copy();
-	void Cut();
-	void Paste();
-	void Delete();
-
-	bool CanUndo() const;
-	bool CanRedo() const;
-	void Undo(int aSteps = 1);
-	void Redo(int aSteps = 1);
-
-	static const Palette& GetDarkPalette();
-	static const Palette& GetLightPalette();
-	static const Palette& GetRetroBluePalette();
 
 private:
-	typedef std::vector<std::pair<std::regex, PaletteIndex>> RegexList;
 
 	struct EditorState
 	{
@@ -276,55 +175,16 @@ private:
 		Coordinates m_CursorPosition;
 	};
 
-	class UndoRecord
-	{
-	public:
-		UndoRecord() {}
-		~UndoRecord() {}
-
-		UndoRecord(
-			const std::string& aAdded,
-			const CTextLogger::Coordinates aAddedStart,
-			const CTextLogger::Coordinates aAddedEnd,
-
-			const std::string& aRemoved,
-			const CTextLogger::Coordinates aRemovedStart,
-			const CTextLogger::Coordinates aRemovedEnd,
-
-			CTextLogger::EditorState& aBefore,
-			CTextLogger::EditorState& aAfter);
-
-		void Undo(CTextLogger* aEditor);
-		void Redo(CTextLogger* aEditor);
-
-		std::string m_svAdded;
-		Coordinates m_AddedStart;
-		Coordinates m_AddedEnd;
-
-		std::string m_svRemoved;
-		Coordinates m_RemovedStart;
-		Coordinates m_RemovedEnd;
-
-		EditorState m_Before;
-		EditorState m_After;
-	};
-
-	typedef std::vector<UndoRecord> UndoBuffer;
-
-	void ProcessInputs();
-	void Colorize(int aFromLine = 0, int aCount = -1);
-	void ColorizeRange(int aFromLine = 0, int aToLine = 0);
-	void ColorizeInternal();
 	float TextDistanceToLineStart(const Coordinates& aFrom) const;
 	void EnsureCursorVisible();
 	int GetPageSize() const;
 	std::string GetText(const Coordinates& aStart, const Coordinates& aEnd) const;
+	Coordinates GetActualLastLineCoordinates() const;
 	Coordinates GetActualCursorCoordinates() const;
 	Coordinates SanitizeCoordinates(const Coordinates& aValue) const;
 	void Advance(Coordinates& aCoordinates) const;
 	void DeleteRange(const Coordinates& aStart, const Coordinates& aEnd);
-	int InsertTextAt(Coordinates& aWhere, const char* aValue);
-	void AddUndo(UndoRecord& aValue);
+	int InsertTextAt(Coordinates& aWhere, const char* aValue, ImVec4 aColor);
 	Coordinates ScreenPosToCoordinates(const ImVec2& aPosition) const;
 	Coordinates FindWordStart(const Coordinates& aFrom) const;
 	Coordinates FindWordEnd(const Coordinates& aFrom) const;
@@ -334,34 +194,24 @@ private:
 	int GetLineCharacterCount(int aLine) const;
 	int GetLineMaxColumn(int aLine) const;
 	bool IsOnWordBoundary(const Coordinates& aAt) const;
-	void RemoveLine(int aStart, int aEnd);
-	void RemoveLine(int aIndex);
 	Line& InsertLine(int aIndex);
 	void EnterCharacter(ImWchar aChar, bool aShift);
-	void Backspace();
-	void DeleteSelection();
 	std::string GetWordUnderCursor() const;
 	std::string GetWordAt(const Coordinates& aCoords) const;
 	ImU32 GetGlyphColor(const Glyph& aGlyph) const;
 
 	void HandleKeyboardInputs();
 	void HandleMouseInputs();
-	void Render();
 
 	float m_flLineSpacing;
 	Lines m_Lines;
 	EditorState m_State;
-	UndoBuffer m_UndoBuffer;
-	int m_nUndoIndex;
 
 	int m_nTabSize;
 	bool m_Overwrite;
 	bool m_bReadOnly;
 	bool m_bWithinRender;
 	bool m_bScrollToCursor;
-	bool m_bScrollToTop;
-	bool m_bTextChanged;
-	bool m_bColorizerEnabled;
 	float m_flTextStart;                   // position (in pixels) where a code line starts relative to the left of the TextEditor.
 	int  m_nLeftMargin;
 	bool m_bCursorPositionChanged;
@@ -370,21 +220,12 @@ private:
 	SelectionMode m_SelectionMode;
 	bool m_bHandleKeyboardInputs;
 	bool m_bHandleMouseInputs;
-	bool m_bIgnoreImGuiChild;
-	bool m_bShowWhitespaces;
+	bool m_bShowWhiteSpaces;
 
-	Palette m_PaletteBase;
-	Palette m_Palette;
-	LanguageDefinition m_LanguageDefinition;
-	RegexList m_RegexList;
-
-	bool m_bCheckComments;
-	Breakpoints m_Breakpoints;
-	ErrorMarkers m_ErrorMarkers;
 	ImVec2 m_CharAdvance;
 	Coordinates m_InteractiveStart;
 	Coordinates m_InteractiveEnd;
-	std::string m__svLineBuffer;
+	std::string m_svLineBuffer;
 	uint64_t m_nStartTime;
 
 	float m_flLastClick;
diff --git a/r5dev/thirdparty/imgui/src/imgui_logger.cpp b/r5dev/thirdparty/imgui/src/imgui_logger.cpp
index 99d6b63a..a6c01881 100644
--- a/r5dev/thirdparty/imgui/src/imgui_logger.cpp
+++ b/r5dev/thirdparty/imgui/src/imgui_logger.cpp
@@ -4,14 +4,11 @@
 #include <regex>
 #include <cmath>
 
-#include "thirdparty/imgui/include/imgui_editor.h"
+#include "thirdparty/imgui/include/imgui_logger.h"
 
 #define IMGUI_DEFINE_MATH_OPERATORS
 #include "thirdparty/imgui/include/imgui.h" // for imGui::GetCurrentWindow()
 
-// TODO
-// - multiline comments vs single-line: latter is blocking start of a ML
-
 template<class InputIt1, class InputIt2, class BinaryPredicate>
 bool equals(InputIt1 first1, InputIt1 last1,
 	InputIt2 first2, InputIt2 last2, BinaryPredicate p)
@@ -26,31 +23,23 @@ bool equals(InputIt1 first1, InputIt1 last1,
 
 CTextLogger::CTextLogger()
 	: m_flLineSpacing(1.0f)
-	, m_nUndoIndex(0)
 	, m_nTabSize(4)
 	, m_Overwrite(false)
 	, m_bReadOnly(false)
 	, m_bWithinRender(false)
 	, m_bScrollToCursor(false)
-	, m_bScrollToTop(false)
-	, m_bTextChanged(false)
-	, m_bColorizerEnabled(true)
-	, m_flTextStart(20.0f)
-	, m_nLeftMargin(10)
+	, m_flTextStart(0.f)
+	, m_nLeftMargin(0)
 	, m_bCursorPositionChanged(false)
 	, m_nColorRangeMin(0)
 	, m_nColorRangeMax(0)
 	, m_SelectionMode(SelectionMode::Normal)
-	, m_bCheckComments(true)
 	, m_flLastClick(-1.0f)
 	, m_bHandleKeyboardInputs(true)
 	, m_bHandleMouseInputs(true)
-	, m_bIgnoreImGuiChild(false)
-	, m_bShowWhitespaces(true)
+	, m_bShowWhiteSpaces(false)
 	, m_nStartTime(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count())
 {
-	SetPalette(GetDarkPalette());
-	SetLanguageDefinition(LanguageDefinition::HLSL());
 	m_Lines.push_back(Line());
 }
 
@@ -58,23 +47,7 @@ CTextLogger::~CTextLogger()
 {
 }
 
-void CTextLogger::SetLanguageDefinition(const LanguageDefinition& aLanguageDef)
-{
-	m_LanguageDefinition = aLanguageDef;
-	m_RegexList.clear();
-
-	for (auto& r : m_LanguageDefinition.m_TokenRegexStrings)
-		m_RegexList.push_back(std::make_pair(std::regex(r.first, std::regex_constants::optimize), r.second));
-
-	Colorize();
-}
-
-void CTextLogger::SetPalette(const Palette& aValue)
-{
-	m_PaletteBase = aValue;
-}
-
-std::string CTextLogger::GetText(const Coordinates& aStart, const Coordinates& aEnd) const
+std::string CTextLogger::GetText(const Coordinates & aStart, const Coordinates & aEnd) const
 {
 	std::string result;
 
@@ -111,12 +84,17 @@ std::string CTextLogger::GetText(const Coordinates& aStart, const Coordinates& a
 	return result;
 }
 
+CTextLogger::Coordinates CTextLogger::GetActualLastLineCoordinates() const
+{
+	return SanitizeCoordinates(Coordinates(GetTotalLines(), 0));
+}
+
 CTextLogger::Coordinates CTextLogger::GetActualCursorCoordinates() const
 {
 	return SanitizeCoordinates(m_State.m_CursorPosition);
 }
 
-CTextLogger::Coordinates CTextLogger::SanitizeCoordinates(const Coordinates& aValue) const
+CTextLogger::Coordinates CTextLogger::SanitizeCoordinates(const Coordinates & aValue) const
 {
 	auto line = aValue.m_nLine;
 	auto column = aValue.m_nColumn;
@@ -196,7 +174,7 @@ static inline int ImTextCharToUtf8(char* buf, int buf_size, unsigned int c)
 	}
 }
 
-void CTextLogger::Advance(Coordinates& aCoordinates) const
+void CTextLogger::Advance(Coordinates & aCoordinates) const
 {
 	if (aCoordinates.m_nLine < (int)m_Lines.size())
 	{
@@ -217,7 +195,7 @@ void CTextLogger::Advance(Coordinates& aCoordinates) const
 	}
 }
 
-void CTextLogger::DeleteRange(const Coordinates& aStart, const Coordinates& aEnd)
+void CTextLogger::DeleteRange(const Coordinates & aStart, const Coordinates & aEnd)
 {
 	assert(aEnd >= aStart);
 	assert(!m_bReadOnly);
@@ -253,16 +231,15 @@ void CTextLogger::DeleteRange(const Coordinates& aStart, const Coordinates& aEnd
 		if (aStart.m_nLine < aEnd.m_nLine)
 			RemoveLine(aStart.m_nLine + 1, aEnd.m_nLine + 1);
 	}
-
-	m_bTextChanged = true;
 }
 
-int CTextLogger::InsertTextAt(Coordinates& /* inout */ aWhere, const char* aValue)
+int CTextLogger::InsertTextAt(Coordinates& /* inout */ aWhere, const char * aValue, ImVec4 aColor)
 {
 	assert(!m_bReadOnly);
 
 	int cindex = GetCharacterIndex(aWhere);
 	int totalLines = 0;
+
 	while (*aValue != '\0')
 	{
 		assert(!m_Lines.empty());
@@ -283,7 +260,9 @@ int CTextLogger::InsertTextAt(Coordinates& /* inout */ aWhere, const char* aValu
 			}
 			else
 			{
-				InsertLine(aWhere.m_nLine + 1);
+				auto& newLine = InsertLine(aWhere.m_nLine + 1);
+				auto& line = m_Lines[aWhere.m_nLine];
+				line.insert(line.begin() + cindex, Glyph(*aValue, aColor));
 			}
 			++aWhere.m_nLine;
 			aWhere.m_nColumn = 0;
@@ -295,32 +274,15 @@ int CTextLogger::InsertTextAt(Coordinates& /* inout */ aWhere, const char* aValu
 		{
 			auto& line = m_Lines[aWhere.m_nLine];
 			auto d = UTF8CharLength(*aValue);
-			while (d-- > 0 && *aValue != '\0')
-				line.insert(line.begin() + cindex++, Glyph(*aValue++, PaletteIndex::Default));
+			while (d-- > 0 && *aValue != '\0' && *aValue != '\n' && *aValue != '\t')
+				line.insert(line.begin() + cindex++, Glyph(*aValue++, aColor));
 			++aWhere.m_nColumn;
 		}
-
-		m_bTextChanged = true;
 	}
 
 	return totalLines;
 }
 
-void CTextLogger::AddUndo(UndoRecord& aValue)
-{
-	assert(!m_bReadOnly);
-	//printf("AddUndo: (@%d.%d) +\'%s' [%d.%d .. %d.%d], -\'%s', [%d.%d .. %d.%d] (@%d.%d)\n",
-	//	aValue.mBefore.mCursorPosition.mLine, aValue.mBefore.mCursorPosition.mColumn,
-	//	aValue.mAdded.c_str(), aValue.mAddedStart.mLine, aValue.mAddedStart.mColumn, aValue.mAddedEnd.mLine, aValue.mAddedEnd.mColumn,
-	//	aValue.mRemoved.c_str(), aValue.mRemovedStart.mLine, aValue.mRemovedStart.mColumn, aValue.mRemovedEnd.mLine, aValue.mRemovedEnd.mColumn,
-	//	aValue.mAfter.mCursorPosition.mLine, aValue.mAfter.mCursorPosition.mColumn
-	//	);
-
-	m_UndoBuffer.resize((size_t)(m_nUndoIndex + 1));
-	m_UndoBuffer.back() = aValue;
-	++m_nUndoIndex;
-}
-
 CTextLogger::Coordinates CTextLogger::ScreenPosToCoordinates(const ImVec2& aPosition) const
 {
 	ImVec2 origin = ImGui::GetCursorScreenPos();
@@ -373,7 +335,7 @@ CTextLogger::Coordinates CTextLogger::ScreenPosToCoordinates(const ImVec2& aPosi
 	return SanitizeCoordinates(Coordinates(lineNo, columnCoord));
 }
 
-CTextLogger::Coordinates CTextLogger::FindWordStart(const Coordinates& aFrom) const
+CTextLogger::Coordinates CTextLogger::FindWordStart(const Coordinates & aFrom) const
 {
 	Coordinates at = aFrom;
 	if (at.m_nLine >= (int)m_Lines.size())
@@ -388,7 +350,6 @@ CTextLogger::Coordinates CTextLogger::FindWordStart(const Coordinates& aFrom) co
 	while (cindex > 0 && isspace(line[cindex].m_Char))
 		--cindex;
 
-	auto cstart = (PaletteIndex)line[cindex].m_ColorIndex;
 	while (cindex > 0)
 	{
 		auto c = line[cindex].m_Char;
@@ -399,15 +360,14 @@ CTextLogger::Coordinates CTextLogger::FindWordStart(const Coordinates& aFrom) co
 				cindex++;
 				break;
 			}
-			if (cstart != (PaletteIndex)line[size_t(cindex - 1)].m_ColorIndex)
-				break;
 		}
 		--cindex;
 	}
+
 	return Coordinates(at.m_nLine, GetCharacterColumn(at.m_nLine, cindex));
 }
 
-CTextLogger::Coordinates CTextLogger::FindWordEnd(const Coordinates& aFrom) const
+CTextLogger::Coordinates CTextLogger::FindWordEnd(const Coordinates & aFrom) const
 {
 	Coordinates at = aFrom;
 	if (at.m_nLine >= (int)m_Lines.size())
@@ -420,13 +380,10 @@ CTextLogger::Coordinates CTextLogger::FindWordEnd(const Coordinates& aFrom) cons
 		return at;
 
 	bool prevspace = (bool)isspace(line[cindex].m_Char);
-	auto cstart = (PaletteIndex)line[cindex].m_ColorIndex;
 	while (cindex < (int)line.size())
 	{
 		auto c = line[cindex].m_Char;
 		auto d = UTF8CharLength(c);
-		if (cstart != (PaletteIndex)line[cindex].m_ColorIndex)
-			break;
 
 		if (prevspace != !!isspace(c))
 		{
@@ -437,10 +394,12 @@ CTextLogger::Coordinates CTextLogger::FindWordEnd(const Coordinates& aFrom) cons
 		}
 		cindex += d;
 	}
+	cindex--;
+
 	return Coordinates(aFrom.m_nLine, GetCharacterColumn(aFrom.m_nLine, cindex));
 }
 
-CTextLogger::Coordinates CTextLogger::FindNextWord(const Coordinates& aFrom) const
+CTextLogger::Coordinates CTextLogger::FindNextWord(const Coordinates & aFrom) const
 {
 	Coordinates at = aFrom;
 	if (at.m_nLine >= (int)m_Lines.size())
@@ -461,7 +420,7 @@ CTextLogger::Coordinates CTextLogger::FindNextWord(const Coordinates& aFrom) con
 	{
 		if (at.m_nLine >= m_Lines.size())
 		{
-			auto l = std::max(0, (int)m_Lines.size() - 1);
+			auto l = std::max(0, (int) m_Lines.size() - 1);
 			return Coordinates(l, GetLineMaxColumn(l));
 		}
 
@@ -556,7 +515,7 @@ int CTextLogger::GetLineMaxColumn(int aLine) const
 	return col;
 }
 
-bool CTextLogger::IsOnWordBoundary(const Coordinates& aAt) const
+bool CTextLogger::IsOnWordBoundary(const Coordinates & aAt) const
 {
 	if (aAt.m_nLine >= (int)m_Lines.size() || aAt.m_nColumn == 0)
 		return true;
@@ -566,9 +525,6 @@ bool CTextLogger::IsOnWordBoundary(const Coordinates& aAt) const
 	if (cindex >= (int)line.size())
 		return true;
 
-	if (m_bColorizerEnabled)
-		return line[cindex].m_ColorIndex != line[size_t(cindex - 1)].m_ColorIndex;
-
 	return isspace(line[cindex].m_Char) != isspace(line[cindex - 1].m_Char);
 }
 
@@ -578,29 +534,8 @@ void CTextLogger::RemoveLine(int aStart, int aEnd)
 	assert(aEnd >= aStart);
 	assert(m_Lines.size() > (size_t)(aEnd - aStart));
 
-	ErrorMarkers etmp;
-	for (auto& i : m_ErrorMarkers)
-	{
-		ErrorMarkers::value_type e(i.first >= aStart ? i.first - 1 : i.first, i.second);
-		if (e.first >= aStart && e.first <= aEnd)
-			continue;
-		etmp.insert(e);
-	}
-	m_ErrorMarkers = std::move(etmp);
-
-	Breakpoints btmp;
-	for (auto i : m_Breakpoints)
-	{
-		if (i >= aStart && i <= aEnd)
-			continue;
-		btmp.insert(i >= aStart ? i - 1 : i);
-	}
-	m_Breakpoints = std::move(btmp);
-
 	m_Lines.erase(m_Lines.begin() + aStart, m_Lines.begin() + aEnd);
 	assert(!m_Lines.empty());
-
-	m_bTextChanged = true;
 }
 
 void CTextLogger::RemoveLine(int aIndex)
@@ -608,29 +543,8 @@ void CTextLogger::RemoveLine(int aIndex)
 	assert(!m_bReadOnly);
 	assert(m_Lines.size() > 1);
 
-	ErrorMarkers etmp;
-	for (auto& i : m_ErrorMarkers)
-	{
-		ErrorMarkers::value_type e(i.first > aIndex ? i.first - 1 : i.first, i.second);
-		if (e.first - 1 == aIndex)
-			continue;
-		etmp.insert(e);
-	}
-	m_ErrorMarkers = std::move(etmp);
-
-	Breakpoints btmp;
-	for (auto i : m_Breakpoints)
-	{
-		if (i == aIndex)
-			continue;
-		btmp.insert(i >= aIndex ? i - 1 : i);
-	}
-	m_Breakpoints = std::move(btmp);
-
 	m_Lines.erase(m_Lines.begin() + aIndex);
 	assert(!m_Lines.empty());
-
-	m_bTextChanged = true;
 }
 
 CTextLogger::Line& CTextLogger::InsertLine(int aIndex)
@@ -638,17 +552,6 @@ CTextLogger::Line& CTextLogger::InsertLine(int aIndex)
 	assert(!m_bReadOnly);
 
 	auto& result = *m_Lines.insert(m_Lines.begin() + aIndex, Line());
-
-	ErrorMarkers etmp;
-	for (auto& i : m_ErrorMarkers)
-		etmp.insert(ErrorMarkers::value_type(i.first >= aIndex ? i.first + 1 : i.first, i.second));
-	m_ErrorMarkers = std::move(etmp);
-
-	Breakpoints btmp;
-	for (auto i : m_Breakpoints)
-		btmp.insert(i >= aIndex ? i + 1 : i);
-	m_Breakpoints = std::move(btmp);
-
 	return result;
 }
 
@@ -658,7 +561,7 @@ std::string CTextLogger::GetWordUnderCursor() const
 	return GetWordAt(c);
 }
 
-std::string CTextLogger::GetWordAt(const Coordinates& aCoords) const
+std::string CTextLogger::GetWordAt(const Coordinates & aCoords) const
 {
 	auto start = FindWordStart(aCoords);
 	auto end = FindWordEnd(aCoords);
@@ -674,25 +577,10 @@ std::string CTextLogger::GetWordAt(const Coordinates& aCoords) const
 	return r;
 }
 
-ImU32 CTextLogger::GetGlyphColor(const Glyph& aGlyph) const
+ImU32 CTextLogger::GetGlyphColor(const Glyph & aGlyph) const
 {
-	if (!m_bColorizerEnabled)
-		return m_Palette[(int)PaletteIndex::Default];
-	if (aGlyph.m_bComment)
-		return m_Palette[(int)PaletteIndex::Comment];
-	if (aGlyph.m_bMultiLineComment)
-		return m_Palette[(int)PaletteIndex::MultiLineComment];
-	auto const color = m_Palette[(int)aGlyph.m_ColorIndex];
-	if (aGlyph.m_bPreprocessor)
-	{
-		const auto ppcolor = m_Palette[(int)PaletteIndex::Preprocessor];
-		const int c0 = ((ppcolor & 0xff) + (color & 0xff)) / 2;
-		const int c1 = (((ppcolor >> 8) & 0xff) + ((color >> 8) & 0xff)) / 2;
-		const int c2 = (((ppcolor >> 16) & 0xff) + ((color >> 16) & 0xff)) / 2;
-		const int c3 = (((ppcolor >> 24) & 0xff) + ((color >> 24) & 0xff)) / 2;
-		return ImU32(c0 | (c1 << 8) | (c2 << 16) | (c3 << 24));
-	}
-	return color;
+	ImVec4 color = aGlyph.m_Color;
+	return ImGui::ColorConvertFloat4ToU32(color);
 }
 
 void CTextLogger::HandleKeyboardInputs()
@@ -711,13 +599,7 @@ void CTextLogger::HandleKeyboardInputs()
 		io.WantCaptureKeyboard = true;
 		io.WantTextInput = true;
 
-		if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Z)))
-			Undo();
-		else if (!IsReadOnly() && !ctrl && !shift && alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Backspace)))
-			Undo();
-		else if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Y)))
-			Redo();
-		else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)))
+		if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)))
 			MoveUp(1, shift);
 		else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)))
 			MoveDown(1, shift);
@@ -737,24 +619,12 @@ void CTextLogger::HandleKeyboardInputs()
 			MoveHome(shift);
 		else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_End)))
 			MoveEnd(shift);
-		else if (!IsReadOnly() && !ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Delete)))
-			Delete();
-		else if (!IsReadOnly() && !ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Backspace)))
-			Backspace();
 		else if (!ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Insert)))
 			m_Overwrite ^= true;
 		else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Insert)))
 			Copy();
 		else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_C)))
 			Copy();
-		else if (!IsReadOnly() && !ctrl && shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Insert)))
-			Paste();
-		else if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_V)))
-			Paste();
-		else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_X)))
-			Cut();
-		else if (!ctrl && shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Delete)))
-			Cut();
 		else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_A)))
 			SelectAll();
 		else if (!IsReadOnly() && !ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Enter)))
@@ -816,6 +686,7 @@ void CTextLogger::HandleMouseInputs()
 				if (!ctrl)
 				{
 					m_State.m_CursorPosition = m_InteractiveStart = m_InteractiveEnd = ScreenPosToCoordinates(ImGui::GetMousePos());
+
 					if (m_SelectionMode == SelectionMode::Line)
 						m_SelectionMode = SelectionMode::Normal;
 					else
@@ -853,42 +724,37 @@ void CTextLogger::HandleMouseInputs()
 
 void CTextLogger::Render()
 {
+	m_bWithinRender = true;
+	m_bCursorPositionChanged = false;
+
+	ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
+	if (m_bHandleKeyboardInputs)
+	{
+		HandleKeyboardInputs();
+		ImGui::PushAllowKeyboardFocus(true);
+	}
+
+	if (m_bHandleMouseInputs)
+		HandleMouseInputs();
+
 	/* Compute mCharAdvance regarding to scaled font size (Ctrl + mouse wheel)*/
 	const float fontSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, "#", nullptr, nullptr).x;
 	m_CharAdvance = ImVec2(fontSize, ImGui::GetTextLineHeightWithSpacing() * m_flLineSpacing);
 
-	/* Update palette with the current alpha from style */
-	for (int i = 0; i < (int)PaletteIndex::Max; ++i)
-	{
-		auto color = ImGui::ColorConvertU32ToFloat4(m_PaletteBase[i]);
-		color.w *= ImGui::GetStyle().Alpha;
-		m_Palette[i] = ImGui::ColorConvertFloat4ToU32(color);
-	}
-
-	assert(m__svLineBuffer.empty());
+	assert(m_svLineBuffer.empty());
 
 	auto contentSize = ImGui::GetWindowContentRegionMax();
 	auto drawList = ImGui::GetWindowDrawList();
 	float longest(m_flTextStart);
 
-	if (m_bScrollToTop)
-	{
-		m_bScrollToTop = false;
-		ImGui::SetScrollY(0.f);
-	}
-
 	ImVec2 cursorScreenPos = ImGui::GetCursorScreenPos();
 	auto scrollX = ImGui::GetScrollX();
 	auto scrollY = ImGui::GetScrollY();
 
 	auto lineNo = (int)floor(scrollY / m_CharAdvance.y);
-	auto globalLineMax = (int)m_Lines.size();
 	auto lineMax = std::max(0, std::min((int)m_Lines.size() - 1, lineNo + (int)floor((scrollY + contentSize.y) / m_CharAdvance.y)));
 
-	// Deduce mTextStart by evaluating mLines size (global lineMax) plus two spaces as text width
-	char buf[16];
-	snprintf(buf, 16, " %d ", globalLineMax);
-	m_flTextStart = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, buf, nullptr, nullptr).x + m_nLeftMargin;
+	//m_flTextStart = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, buf, nullptr, nullptr).x + m_nLeftMargin;
 
 	if (!m_Lines.empty())
 	{
@@ -922,55 +788,20 @@ void CTextLogger::Render()
 			{
 				ImVec2 vstart(lineStartScreenPos.x + m_flTextStart + sstart, lineStartScreenPos.y);
 				ImVec2 vend(lineStartScreenPos.x + m_flTextStart + ssend, lineStartScreenPos.y + m_CharAdvance.y);
-				drawList->AddRectFilled(vstart, vend, m_Palette[(int)PaletteIndex::Selection]);
+				drawList->AddRectFilled(vstart, vend, 0x80a06020); // COLOR
 			}
 
-			// Draw breakpoints
-			auto start = ImVec2(lineStartScreenPos.x + scrollX, lineStartScreenPos.y);
-
-			if (m_Breakpoints.count(lineNo + 1) != 0)
-			{
-				auto end = ImVec2(lineStartScreenPos.x + contentSize.x + 2.0f * scrollX, lineStartScreenPos.y + m_CharAdvance.y);
-				drawList->AddRectFilled(start, end, m_Palette[(int)PaletteIndex::Breakpoint]);
-			}
-
-			// Draw error markers
-			auto errorIt = m_ErrorMarkers.find(lineNo + 1);
-			if (errorIt != m_ErrorMarkers.end())
-			{
-				auto end = ImVec2(lineStartScreenPos.x + contentSize.x + 2.0f * scrollX, lineStartScreenPos.y + m_CharAdvance.y);
-				drawList->AddRectFilled(start, end, m_Palette[(int)PaletteIndex::ErrorMarker]);
-
-				if (ImGui::IsMouseHoveringRect(lineStartScreenPos, end))
-				{
-					ImGui::BeginTooltip();
-					ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.2f, 0.2f, 1.0f));
-					ImGui::Text("Error at line %d:", errorIt->first);
-					ImGui::PopStyleColor();
-					ImGui::Separator();
-					ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 0.2f, 1.0f));
-					ImGui::Text("%s", errorIt->second.c_str());
-					ImGui::PopStyleColor();
-					ImGui::EndTooltip();
-				}
-			}
-
-			// Draw line number (right aligned)
-			snprintf(buf, 16, "%d  ", lineNo + 1);
-
-			auto lineNoWidth = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, buf, nullptr, nullptr).x;
-			drawList->AddText(ImVec2(lineStartScreenPos.x + m_flTextStart - lineNoWidth, lineStartScreenPos.y), m_Palette[(int)PaletteIndex::LineNumber], buf);
-
 			if (m_State.m_CursorPosition.m_nLine == lineNo)
 			{
-				auto focused = ImGui::IsWindowFocused();
+				bool focused = ImGui::IsWindowFocused();
+				ImVec2 start = ImVec2(lineStartScreenPos.x + scrollX, lineStartScreenPos.y);
 
 				// Highlight the current line (where the cursor is)
 				if (!HasSelection())
 				{
 					auto end = ImVec2(start.x + contentSize.x + scrollX, start.y + m_CharAdvance.y);
-					drawList->AddRectFilled(start, end, m_Palette[(int)(focused ? PaletteIndex::CurrentLineFill : PaletteIndex::CurrentLineFillInactive)]);
-					drawList->AddRect(start, end, m_Palette[(int)PaletteIndex::CurrentLineEdge], 1.0f);
+					drawList->AddRectFilled(start, end, 0x40000000);
+					drawList->AddRect(start, end, 0x40000000, 1.0f);
 				}
 
 				// Render the cursor
@@ -1002,7 +833,7 @@ void CTextLogger::Render()
 						}
 						ImVec2 cstart(textScreenPos.x + cx, lineStartScreenPos.y);
 						ImVec2 cend(textScreenPos.x + cx + width, lineStartScreenPos.y + m_CharAdvance.y);
-						drawList->AddRectFilled(cstart, cend, m_Palette[(int)PaletteIndex::Cursor]);
+						drawList->AddRectFilled(cstart, cend, 0xffe0e0e0);
 						if (elapsed > 800)
 							m_nStartTime = timeEnd;
 					}
@@ -1010,31 +841,30 @@ void CTextLogger::Render()
 			}
 
 			// Render colorized text
-			auto prevColor = line.empty() ? m_Palette[(int)PaletteIndex::Default] : GetGlyphColor(line[0]);
+			//auto prevColor = GetGlyphColor(line[0]);
 			ImVec2 bufferOffset;
 
-			for (int i = 0; i < line.size();)
+			for (size_t i = 0; i < line.size();)
 			{
 				auto& glyph = line[i];
 				auto color = GetGlyphColor(glyph);
 
-				if ((color != prevColor || glyph.m_Char == '\t' || glyph.m_Char == ' ') && !m__svLineBuffer.empty())
+				if ((glyph.m_Char == '\t' || glyph.m_Char == '\n' || glyph.m_Char == ' ') && !m_svLineBuffer.empty())
 				{
 					const ImVec2 newOffset(textScreenPos.x + bufferOffset.x, textScreenPos.y + bufferOffset.y);
-					drawList->AddText(newOffset, prevColor, m__svLineBuffer.c_str());
-					auto textSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, m__svLineBuffer.c_str(), nullptr, nullptr);
+					drawList->AddText(newOffset, color, m_svLineBuffer.c_str());
+					auto textSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, m_svLineBuffer.c_str(), nullptr, nullptr);
 					bufferOffset.x += textSize.x;
-					m__svLineBuffer.clear();
+					m_svLineBuffer.clear();
 				}
-				prevColor = color;
 
-				if (glyph.m_Char == '\t')
+				if (glyph.m_Char == '\t' || glyph.m_Char == '\n')
 				{
 					auto oldX = bufferOffset.x;
 					bufferOffset.x = (1.0f + std::floor((1.0f + bufferOffset.x) / (float(m_nTabSize) * spaceSize))) * (float(m_nTabSize) * spaceSize);
 					++i;
 
-					if (m_bShowWhitespaces)
+					if (m_bShowWhiteSpaces)
 					{
 						const auto s = ImGui::GetFontSize();
 						const auto x1 = textScreenPos.x + oldX + 1.0f;
@@ -1051,7 +881,7 @@ void CTextLogger::Render()
 				}
 				else if (glyph.m_Char == ' ')
 				{
-					if (m_bShowWhitespaces)
+					if (m_bShowWhiteSpaces)
 					{
 						const auto s = ImGui::GetFontSize();
 						const auto x = textScreenPos.x + bufferOffset.x + spaceSize * 0.5f;
@@ -1063,48 +893,25 @@ void CTextLogger::Render()
 				}
 				else
 				{
-					auto l = UTF8CharLength(glyph.m_Char);
-					while (l-- > 0)
-						m__svLineBuffer.push_back(line[i++].m_Char);
+					m_svLineBuffer.push_back(line[i++].m_Char);
+					//auto l = UTF8CharLength(glyph.m_Char); // !TODO: (this currently causes crashes)
+					//while (l-- > 0)
+					//{
+					//	m_svLineBuffer.push_back(line[i++].m_Char);
+					//}
 				}
 				++columnNo;
 			}
 
-			if (!m__svLineBuffer.empty())
+			if (!m_svLineBuffer.empty())
 			{
 				const ImVec2 newOffset(textScreenPos.x + bufferOffset.x, textScreenPos.y + bufferOffset.y);
-				drawList->AddText(newOffset, prevColor, m__svLineBuffer.c_str());
-				m__svLineBuffer.clear();
+				drawList->AddText(newOffset, 0xffffffff, m_svLineBuffer.c_str()); // COLOR (obtain from glyph?)
+				m_svLineBuffer.clear();
 			}
 
 			++lineNo;
 		}
-
-		// Draw a tooltip on known identifiers/preprocessor symbols
-		if (ImGui::IsMousePosValid())
-		{
-			auto id = GetWordAt(ScreenPosToCoordinates(ImGui::GetMousePos()));
-			if (!id.empty())
-			{
-				auto it = m_LanguageDefinition.m_Identifiers.find(id);
-				if (it != m_LanguageDefinition.m_Identifiers.end())
-				{
-					ImGui::BeginTooltip();
-					ImGui::TextUnformatted(it->second.m_svDeclaration.c_str());
-					ImGui::EndTooltip();
-				}
-				else
-				{
-					auto pi = m_LanguageDefinition.m_PreprocIdentifiers.find(id);
-					if (pi != m_LanguageDefinition.m_PreprocIdentifiers.end())
-					{
-						ImGui::BeginTooltip();
-						ImGui::TextUnformatted(pi->second.m_svDeclaration.c_str());
-						ImGui::EndTooltip();
-					}
-				}
-			}
-		}
 	}
 
 
@@ -1116,71 +923,30 @@ void CTextLogger::Render()
 		ImGui::SetWindowFocus();
 		m_bScrollToCursor = false;
 	}
-}
-
-void CTextLogger::Render(const char* aTitle, const ImVec2& aSize, bool aBorder)
-{
-	m_bWithinRender = true;
-	m_bTextChanged = false;
-	m_bCursorPositionChanged = false;
-
-	ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::ColorConvertU32ToFloat4(m_Palette[(int)PaletteIndex::Background]));
-	ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
-	if (!m_bIgnoreImGuiChild)
-		ImGui::BeginChild(aTitle, aSize, aBorder, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NoMove);
-
-	if (m_bHandleKeyboardInputs)
-	{
-		HandleKeyboardInputs();
-		ImGui::PushAllowKeyboardFocus(true);
-	}
-
-	if (m_bHandleMouseInputs)
-		HandleMouseInputs();
-
-	ColorizeInternal();
-	Render();
 
 	if (m_bHandleKeyboardInputs)
 		ImGui::PopAllowKeyboardFocus();
 
-	if (!m_bIgnoreImGuiChild)
-		ImGui::EndChild();
-
 	ImGui::PopStyleVar();
-	ImGui::PopStyleColor();
-
 	m_bWithinRender = false;
 }
 
-void CTextLogger::SetText(const std::string& aText)
+void CTextLogger::SetText(const CConLog& aText)
 {
 	m_Lines.clear();
 	m_Lines.emplace_back(Line());
-	for (auto chr : aText)
+	for (auto chr : aText.m_svConLog)
 	{
-		if (chr == '\r')
-		{
-			// ignore the carriage return character
-		}
+		if (chr == '\r') // ignore the carriage return character
+			continue;
 		else if (chr == '\n')
 			m_Lines.emplace_back(Line());
 		else
-		{
-			m_Lines.back().emplace_back(Glyph(chr, PaletteIndex::Default));
-		}
+			m_Lines.back().emplace_back(Glyph(chr, aText.m_imColor));
 	}
-
-	m_bTextChanged = true;
-	m_bScrollToTop = true;
-
-	m_UndoBuffer.clear();
-	m_nUndoIndex = 0;
-
-	Colorize();
 }
 
-void CTextLogger::SetTextLines(const std::vector<std::string>& aLines)
+void CTextLogger::SetTextLines(const std::vector<CConLog>& aLines)
 {
 	m_Lines.clear();
 
@@ -1194,31 +960,20 @@ void CTextLogger::SetTextLines(const std::vector<std::string>& aLines)
 
 		for (size_t i = 0; i < aLines.size(); ++i)
 		{
-			const std::string& aLine = aLines[i];
+			const std::string & aLine = aLines[i].m_svConLog;
 
 			m_Lines[i].reserve(aLine.size());
 			for (size_t j = 0; j < aLine.size(); ++j)
-				m_Lines[i].emplace_back(Glyph(aLine[j], PaletteIndex::Default));
+			{
+				m_Lines[i].emplace_back(Glyph(aLine[j], aLines[i].m_imColor));
+			}
 		}
 	}
-
-	m_bTextChanged = true;
-	m_bScrollToTop = true;
-
-	m_UndoBuffer.clear();
-	m_nUndoIndex = 0;
-
-	Colorize();
 }
 
 void CTextLogger::EnterCharacter(ImWchar aChar, bool aShift)
 {
 	assert(!m_bReadOnly);
-
-	UndoRecord u;
-
-	u.m_Before = m_State;
-
 	if (HasSelection())
 	{
 		if (aChar == '\t' && m_State.m_SelectionStart.m_nLine != m_State.m_SelectionEnd.m_nLine)
@@ -1241,10 +996,6 @@ void CTextLogger::EnterCharacter(ImWchar aChar, bool aShift)
 			//if (end.mColumn >= GetLineMaxColumn(end.mLine))
 			//	end.mColumn = GetLineMaxColumn(end.mLine) - 1;
 
-			u.m_RemovedStart = start;
-			u.m_RemovedEnd = end;
-			u.m_svRemoved = GetText(start, end);
-
 			bool modified = false;
 
 			for (int i = start.m_nLine; i <= end.m_nLine; i++)
@@ -1271,7 +1022,7 @@ void CTextLogger::EnterCharacter(ImWchar aChar, bool aShift)
 				}
 				else
 				{
-					line.insert(line.begin(), Glyph('\t', CTextLogger::PaletteIndex::Background));
+					line.insert(line.begin(), Glyph('\t'));
 					modified = true;
 				}
 			}
@@ -1284,42 +1035,24 @@ void CTextLogger::EnterCharacter(ImWchar aChar, bool aShift)
 				{
 					end = Coordinates(end.m_nLine, GetLineMaxColumn(end.m_nLine));
 					rangeEnd = end;
-					u.m_svAdded = GetText(start, end);
 				}
 				else
 				{
 					end = Coordinates(originalEnd.m_nLine, 0);
 					rangeEnd = Coordinates(end.m_nLine - 1, GetLineMaxColumn(end.m_nLine - 1));
-					u.m_svAdded = GetText(start, rangeEnd);
 				}
 
-				u.m_AddedStart = start;
-				u.m_AddedEnd = rangeEnd;
-				u.m_After = m_State;
-
 				m_State.m_SelectionStart = start;
 				m_State.m_SelectionEnd = end;
-				AddUndo(u);
-
-				m_bTextChanged = true;
 
 				EnsureCursorVisible();
 			}
 
 			return;
 		} // c == '\t'
-		else
-		{
-			u.m_svRemoved = GetSelectedText();
-			u.m_RemovedStart = m_State.m_SelectionStart;
-			u.m_RemovedEnd = m_State.m_SelectionEnd;
-			DeleteSelection();
-		}
 	} // HasSelection
 
 	auto coord = GetActualCursorCoordinates();
-	u.m_AddedStart = coord;
-
 	assert(!m_Lines.empty());
 
 	if (aChar == '\n')
@@ -1328,16 +1061,11 @@ void CTextLogger::EnterCharacter(ImWchar aChar, bool aShift)
 		auto& line = m_Lines[coord.m_nLine];
 		auto& newLine = m_Lines[coord.m_nLine + 1];
 
-		if (m_LanguageDefinition.m_bAutoIndentation)
-			for (size_t it = 0; it < line.size() && isascii(line[it].m_Char) && isblank(line[it].m_Char); ++it)
-				newLine.push_back(line[it]);
-
 		const size_t whitespaceSize = newLine.size();
 		auto cindex = GetCharacterIndex(coord);
 		newLine.insert(newLine.end(), line.begin() + cindex, line.end());
 		line.erase(line.begin() + cindex, line.begin() + line.size());
 		SetCursorPosition(Coordinates(coord.m_nLine + 1, GetCharacterColumn(coord.m_nLine + 1, (int)whitespaceSize)));
-		u.m_svAdded = (char)aChar;
 	}
 	else
 	{
@@ -1352,20 +1080,14 @@ void CTextLogger::EnterCharacter(ImWchar aChar, bool aShift)
 			if (m_Overwrite && cindex < (int)line.size())
 			{
 				auto d = UTF8CharLength(line[cindex].m_Char);
-
-				u.m_RemovedStart = m_State.m_CursorPosition;
-				u.m_RemovedEnd = Coordinates(coord.m_nLine, GetCharacterColumn(coord.m_nLine, cindex + d));
-
 				while (d-- > 0 && cindex < (int)line.size())
 				{
-					u.m_svRemoved += line[cindex].m_Char;
 					line.erase(line.begin() + cindex);
 				}
 			}
 
 			for (auto p = buf; *p != '\0'; p++, ++cindex)
-				line.insert(line.begin() + cindex, Glyph(*p, PaletteIndex::Default));
-			u.m_svAdded = buf;
+				line.insert(line.begin() + cindex, Glyph(*p));
 
 			SetCursorPosition(Coordinates(coord.m_nLine, GetCharacterColumn(coord.m_nLine, cindex)));
 		}
@@ -1373,14 +1095,6 @@ void CTextLogger::EnterCharacter(ImWchar aChar, bool aShift)
 			return;
 	}
 
-	m_bTextChanged = true;
-
-	u.m_AddedEnd = GetActualCursorCoordinates();
-	u.m_After = m_State;
-
-	AddUndo(u);
-
-	Colorize(coord.m_nLine - 1, 3);
 	EnsureCursorVisible();
 }
 
@@ -1389,12 +1103,7 @@ void CTextLogger::SetReadOnly(bool aValue)
 	m_bReadOnly = aValue;
 }
 
-void CTextLogger::SetColorizerEnable(bool aValue)
-{
-	m_bColorizerEnabled = aValue;
-}
-
-void CTextLogger::SetCursorPosition(const Coordinates& aPosition)
+void CTextLogger::SetCursorPosition(const Coordinates & aPosition)
 {
 	if (m_State.m_CursorPosition != aPosition)
 	{
@@ -1404,21 +1113,21 @@ void CTextLogger::SetCursorPosition(const Coordinates& aPosition)
 	}
 }
 
-void CTextLogger::SetSelectionStart(const Coordinates& aPosition)
+void CTextLogger::SetSelectionStart(const Coordinates & aPosition)
 {
 	m_State.m_SelectionStart = SanitizeCoordinates(aPosition);
 	if (m_State.m_SelectionStart > m_State.m_SelectionEnd)
 		std::swap(m_State.m_SelectionStart, m_State.m_SelectionEnd);
 }
 
-void CTextLogger::SetSelectionEnd(const Coordinates& aPosition)
+void CTextLogger::SetSelectionEnd(const Coordinates & aPosition)
 {
 	m_State.m_SelectionEnd = SanitizeCoordinates(aPosition);
 	if (m_State.m_SelectionStart > m_State.m_SelectionEnd)
 		std::swap(m_State.m_SelectionStart, m_State.m_SelectionEnd);
 }
 
-void CTextLogger::SetSelection(const Coordinates& aStart, const Coordinates& aEnd, SelectionMode aMode)
+void CTextLogger::SetSelection(const Coordinates & aStart, const Coordinates & aEnd, SelectionMode aMode)
 {
 	auto oldSelStart = m_State.m_SelectionStart;
 	auto oldSelEnd = m_State.m_SelectionEnd;
@@ -1461,39 +1170,17 @@ void CTextLogger::SetTabSize(int aValue)
 	m_nTabSize = std::max(0, std::min(32, aValue));
 }
 
-void CTextLogger::InsertText(const std::string& aValue)
+void CTextLogger::InsertText(const CConLog & aValue)
 {
-	InsertText(aValue.c_str());
-}
-
-void CTextLogger::InsertText(const char* aValue)
-{
-	if (aValue == nullptr)
+	if (aValue.m_svConLog.empty())
 		return;
 
-	auto pos = GetActualCursorCoordinates();
+	auto pos = GetActualLastLineCoordinates();
+
 	auto start = std::min(pos, m_State.m_SelectionStart);
 	int totalLines = pos.m_nLine - start.m_nLine;
 
-	totalLines += InsertTextAt(pos, aValue);
-
-	SetSelection(pos, pos);
-	SetCursorPosition(pos);
-	Colorize(start.m_nLine - 1, totalLines + 2);
-}
-
-void CTextLogger::DeleteSelection()
-{
-	assert(m_State.m_SelectionEnd >= m_State.m_SelectionStart);
-
-	if (m_State.m_SelectionEnd == m_State.m_SelectionStart)
-		return;
-
-	DeleteRange(m_State.m_SelectionStart, m_State.m_SelectionEnd);
-
-	SetSelection(m_State.m_SelectionStart, m_State.m_SelectionStart);
-	SetCursorPosition(m_State.m_SelectionStart);
-	Colorize(m_State.m_SelectionStart.m_nLine, 1);
+	totalLines += InsertTextAt(pos, aValue.m_svConLog.c_str(), aValue.m_imColor);
 }
 
 void CTextLogger::MoveUp(int aAmount, bool aSelect)
@@ -1755,142 +1442,6 @@ void CTextLogger::MoveEnd(bool aSelect)
 	}
 }
 
-void CTextLogger::Delete()
-{
-	assert(!m_bReadOnly);
-
-	if (m_Lines.empty())
-		return;
-
-	UndoRecord u;
-	u.m_Before = m_State;
-
-	if (HasSelection())
-	{
-		u.m_svRemoved = GetSelectedText();
-		u.m_RemovedStart = m_State.m_SelectionStart;
-		u.m_RemovedEnd = m_State.m_SelectionEnd;
-
-		DeleteSelection();
-	}
-	else
-	{
-		auto pos = GetActualCursorCoordinates();
-		SetCursorPosition(pos);
-		auto& line = m_Lines[pos.m_nLine];
-
-		if (pos.m_nColumn == GetLineMaxColumn(pos.m_nLine))
-		{
-			if (pos.m_nLine == (int)m_Lines.size() - 1)
-				return;
-
-			u.m_svRemoved = '\n';
-			u.m_RemovedStart = u.m_RemovedEnd = GetActualCursorCoordinates();
-			Advance(u.m_RemovedEnd);
-
-			auto& nextLine = m_Lines[pos.m_nLine + 1];
-			line.insert(line.end(), nextLine.begin(), nextLine.end());
-			RemoveLine(pos.m_nLine + 1);
-		}
-		else
-		{
-			auto cindex = GetCharacterIndex(pos);
-			u.m_RemovedStart = u.m_RemovedEnd = GetActualCursorCoordinates();
-			u.m_RemovedEnd.m_nColumn++;
-			u.m_svRemoved = GetText(u.m_RemovedStart, u.m_RemovedEnd);
-
-			auto d = UTF8CharLength(line[cindex].m_Char);
-			while (d-- > 0 && cindex < (int)line.size())
-				line.erase(line.begin() + cindex);
-		}
-
-		m_bTextChanged = true;
-
-		Colorize(pos.m_nLine, 1);
-	}
-
-	u.m_After = m_State;
-	AddUndo(u);
-}
-
-void CTextLogger::Backspace()
-{
-	assert(!m_bReadOnly);
-
-	if (m_Lines.empty())
-		return;
-
-	UndoRecord u;
-	u.m_Before = m_State;
-
-	if (HasSelection())
-	{
-		u.m_svRemoved = GetSelectedText();
-		u.m_RemovedStart = m_State.m_SelectionStart;
-		u.m_RemovedEnd = m_State.m_SelectionEnd;
-
-		DeleteSelection();
-	}
-	else
-	{
-		auto pos = GetActualCursorCoordinates();
-		SetCursorPosition(pos);
-
-		if (m_State.m_CursorPosition.m_nColumn == 0)
-		{
-			if (m_State.m_CursorPosition.m_nLine == 0)
-				return;
-
-			u.m_svRemoved = '\n';
-			u.m_RemovedStart = u.m_RemovedEnd = Coordinates(pos.m_nLine - 1, GetLineMaxColumn(pos.m_nLine - 1));
-			Advance(u.m_RemovedEnd);
-
-			auto& line = m_Lines[m_State.m_CursorPosition.m_nLine];
-			auto& prevLine = m_Lines[m_State.m_CursorPosition.m_nLine - 1];
-			auto prevSize = GetLineMaxColumn(m_State.m_CursorPosition.m_nLine - 1);
-			prevLine.insert(prevLine.end(), line.begin(), line.end());
-
-			ErrorMarkers etmp;
-			for (auto& i : m_ErrorMarkers)
-				etmp.insert(ErrorMarkers::value_type(i.first - 1 == m_State.m_CursorPosition.m_nLine ? i.first - 1 : i.first, i.second));
-			m_ErrorMarkers = std::move(etmp);
-
-			RemoveLine(m_State.m_CursorPosition.m_nLine);
-			--m_State.m_CursorPosition.m_nLine;
-			m_State.m_CursorPosition.m_nColumn = prevSize;
-		}
-		else
-		{
-			auto& line = m_Lines[m_State.m_CursorPosition.m_nLine];
-			auto cindex = GetCharacterIndex(pos) - 1;
-			auto cend = cindex + 1;
-			while (cindex > 0 && IsUTFSequence(line[cindex].m_Char))
-				--cindex;
-
-			//if (cindex > 0 && UTF8CharLength(line[cindex].mChar) > 1)
-			//	--cindex;
-
-			u.m_RemovedStart = u.m_RemovedEnd = GetActualCursorCoordinates();
-			--u.m_RemovedStart.m_nColumn;
-			--m_State.m_CursorPosition.m_nColumn;
-
-			while (cindex < line.size() && cend-- > cindex)
-			{
-				u.m_svRemoved += line[cindex].m_Char;
-				line.erase(line.begin() + cindex);
-			}
-		}
-
-		m_bTextChanged = true;
-
-		EnsureCursorVisible();
-		Colorize(m_State.m_CursorPosition.m_nLine, 1);
-	}
-
-	u.m_After = m_State;
-	AddUndo(u);
-}
-
 void CTextLogger::SelectWordUnderCursor()
 {
 	auto c = GetCursorPosition();
@@ -1926,168 +1477,6 @@ void CTextLogger::Copy()
 	}
 }
 
-void CTextLogger::Cut()
-{
-	if (IsReadOnly())
-	{
-		Copy();
-	}
-	else
-	{
-		if (HasSelection())
-		{
-			UndoRecord u;
-			u.m_Before = m_State;
-			u.m_svRemoved = GetSelectedText();
-			u.m_RemovedStart = m_State.m_SelectionStart;
-			u.m_RemovedEnd = m_State.m_SelectionEnd;
-
-			Copy();
-			DeleteSelection();
-
-			u.m_After = m_State;
-			AddUndo(u);
-		}
-	}
-}
-
-void CTextLogger::Paste()
-{
-	if (IsReadOnly())
-		return;
-
-	auto clipText = ImGui::GetClipboardText();
-	if (clipText != nullptr && strlen(clipText) > 0)
-	{
-		UndoRecord u;
-		u.m_Before = m_State;
-
-		if (HasSelection())
-		{
-			u.m_svRemoved = GetSelectedText();
-			u.m_RemovedStart = m_State.m_SelectionStart;
-			u.m_RemovedEnd = m_State.m_SelectionEnd;
-			DeleteSelection();
-		}
-
-		u.m_svAdded = clipText;
-		u.m_AddedStart = GetActualCursorCoordinates();
-
-		InsertText(clipText);
-
-		u.m_AddedEnd = GetActualCursorCoordinates();
-		u.m_After = m_State;
-		AddUndo(u);
-	}
-}
-
-bool CTextLogger::CanUndo() const
-{
-	return !m_bReadOnly && m_nUndoIndex > 0;
-}
-
-bool CTextLogger::CanRedo() const
-{
-	return !m_bReadOnly && m_nUndoIndex < (int)m_UndoBuffer.size();
-}
-
-void CTextLogger::Undo(int aSteps)
-{
-	while (CanUndo() && aSteps-- > 0)
-		m_UndoBuffer[--m_nUndoIndex].Undo(this);
-}
-
-void CTextLogger::Redo(int aSteps)
-{
-	while (CanRedo() && aSteps-- > 0)
-		m_UndoBuffer[m_nUndoIndex++].Redo(this);
-}
-
-const CTextLogger::Palette& CTextLogger::GetDarkPalette()
-{
-	const static Palette p = { {
-			0xff7f7f7f,	// Default
-			0xffd69c56,	// Keyword	
-			0xff00ff00,	// Number
-			0xff7070e0,	// String
-			0xff70a0e0, // Char literal
-			0xffffffff, // Punctuation
-			0xff408080,	// Preprocessor
-			0xffaaaaaa, // Identifier
-			0xff9bc64d, // Known identifier
-			0xffc040a0, // Preproc identifier
-			0xff206020, // Comment (single line)
-			0xff406020, // Comment (multi line)
-			0xff101010, // Background
-			0xffe0e0e0, // Cursor
-			0x80a06020, // Selection
-			0x800020ff, // ErrorMarker
-			0x40f08000, // Breakpoint
-			0xff707000, // Line number
-			0x40000000, // Current line fill
-			0x40808080, // Current line fill (inactive)
-			0x40a0a0a0, // Current line edge
-		} };
-	return p;
-}
-
-const CTextLogger::Palette& CTextLogger::GetLightPalette()
-{
-	const static Palette p = { {
-			0xff7f7f7f,	// None
-			0xffff0c06,	// Keyword	
-			0xff008000,	// Number
-			0xff2020a0,	// String
-			0xff304070, // Char literal
-			0xff000000, // Punctuation
-			0xff406060,	// Preprocessor
-			0xff404040, // Identifier
-			0xff606010, // Known identifier
-			0xffc040a0, // Preproc identifier
-			0xff205020, // Comment (single line)
-			0xff405020, // Comment (multi line)
-			0xffffffff, // Background
-			0xff000000, // Cursor
-			0x80600000, // Selection
-			0xa00010ff, // ErrorMarker
-			0x80f08000, // Breakpoint
-			0xff505000, // Line number
-			0x40000000, // Current line fill
-			0x40808080, // Current line fill (inactive)
-			0x40000000, // Current line edge
-		} };
-	return p;
-}
-
-const CTextLogger::Palette& CTextLogger::GetRetroBluePalette()
-{
-	const static Palette p = { {
-			0xff00ffff,	// None
-			0xffffff00,	// Keyword	
-			0xff00ff00,	// Number
-			0xff808000,	// String
-			0xff808000, // Char literal
-			0xffffffff, // Punctuation
-			0xff008000,	// Preprocessor
-			0xff00ffff, // Identifier
-			0xffffffff, // Known identifier
-			0xffff00ff, // Preproc identifier
-			0xff808080, // Comment (single line)
-			0xff404040, // Comment (multi line)
-			0xff800000, // Background
-			0xff0080ff, // Cursor
-			0x80ffff00, // Selection
-			0xa00000ff, // ErrorMarker
-			0x80ff8000, // Breakpoint
-			0xff808000, // Line number
-			0x40000000, // Current line fill
-			0x40808080, // Current line fill (inactive)
-			0x40000000, // Current line edge
-		} };
-	return p;
-}
-
-
 std::string CTextLogger::GetText() const
 {
 	return GetText(Coordinates(), Coordinates((int)m_Lines.size(), 0));
@@ -2099,7 +1488,7 @@ std::vector<std::string> CTextLogger::GetTextLines() const
 
 	result.reserve(m_Lines.size());
 
-	for (auto& line : m_Lines)
+	for (auto & line : m_Lines)
 	{
 		std::string text;
 
@@ -2127,268 +1516,6 @@ std::string CTextLogger::GetCurrentLineText()const
 		Coordinates(m_State.m_CursorPosition.m_nLine, lineLength));
 }
 
-void CTextLogger::ProcessInputs()
-{
-}
-
-void CTextLogger::Colorize(int aFromLine, int aLines)
-{
-	int toLine = aLines == -1 ? (int)m_Lines.size() : std::min((int)m_Lines.size(), aFromLine + aLines);
-	m_nColorRangeMin = std::min(m_nColorRangeMin, aFromLine);
-	m_nColorRangeMax = std::max(m_nColorRangeMax, toLine);
-	m_nColorRangeMin = std::max(0, m_nColorRangeMin);
-	m_nColorRangeMax = std::max(m_nColorRangeMin, m_nColorRangeMax);
-	m_bCheckComments = true;
-}
-
-void CTextLogger::ColorizeRange(int aFromLine, int aToLine)
-{
-	if (m_Lines.empty() || aFromLine >= aToLine)
-		return;
-
-	std::string buffer;
-	std::cmatch results;
-	std::string id;
-
-	int endLine = std::max(0, std::min((int)m_Lines.size(), aToLine));
-	for (int i = aFromLine; i < endLine; ++i)
-	{
-		auto& line = m_Lines[i];
-
-		if (line.empty())
-			continue;
-
-		buffer.resize(line.size());
-		for (size_t j = 0; j < line.size(); ++j)
-		{
-			auto& col = line[j];
-			buffer[j] = col.m_Char;
-			col.m_ColorIndex = PaletteIndex::Default;
-		}
-
-		const char* bufferBegin = &buffer.front();
-		const char* bufferEnd = bufferBegin + buffer.size();
-
-		auto last = bufferEnd;
-
-		for (auto first = bufferBegin; first != last; )
-		{
-			const char* token_begin = nullptr;
-			const char* token_end = nullptr;
-			PaletteIndex token_color = PaletteIndex::Default;
-
-			bool hasTokenizeResult = false;
-
-			if (m_LanguageDefinition.m_Tokenize != nullptr)
-			{
-				if (m_LanguageDefinition.m_Tokenize(first, last, token_begin, token_end, token_color))
-					hasTokenizeResult = true;
-			}
-
-			if (hasTokenizeResult == false)
-			{
-				// todo : remove
-				//printf("using regex for %.*s\n", first + 10 < last ? 10 : int(last - first), first);
-
-				for (auto& p : m_RegexList)
-				{
-					if (std::regex_search(first, last, results, p.first, std::regex_constants::match_continuous))
-					{
-						hasTokenizeResult = true;
-
-						auto& v = *results.begin();
-						token_begin = v.first;
-						token_end = v.second;
-						token_color = p.second;
-						break;
-					}
-				}
-			}
-
-			if (hasTokenizeResult == false)
-			{
-				first++;
-			}
-			else
-			{
-				const size_t token_length = token_end - token_begin;
-
-				if (token_color == PaletteIndex::Identifier)
-				{
-					id.assign(token_begin, token_end);
-
-					// todo : allmost all language definitions use lower case to specify keywords, so shouldn't this use ::tolower ?
-					if (!m_LanguageDefinition.mCaseSensitive)
-						std::transform(id.begin(), id.end(), id.begin(), ::toupper);
-
-					if (!line[first - bufferBegin].m_bPreprocessor)
-					{
-						if (m_LanguageDefinition.m_Keywords.count(id) != 0)
-							token_color = PaletteIndex::Keyword;
-						else if (m_LanguageDefinition.m_Identifiers.count(id) != 0)
-							token_color = PaletteIndex::KnownIdentifier;
-						else if (m_LanguageDefinition.m_PreprocIdentifiers.count(id) != 0)
-							token_color = PaletteIndex::PreprocIdentifier;
-					}
-					else
-					{
-						if (m_LanguageDefinition.m_PreprocIdentifiers.count(id) != 0)
-							token_color = PaletteIndex::PreprocIdentifier;
-					}
-				}
-
-				for (size_t j = 0; j < token_length; ++j)
-					line[(token_begin - bufferBegin) + j].m_ColorIndex = token_color;
-
-				first = token_end;
-			}
-		}
-	}
-}
-
-void CTextLogger::ColorizeInternal()
-{
-	if (m_Lines.empty() || !m_bColorizerEnabled)
-		return;
-
-	if (m_bCheckComments)
-	{
-		auto endLine = m_Lines.size();
-		auto endIndex = 0;
-		auto commentStartLine = endLine;
-		auto commentStartIndex = endIndex;
-		auto withinString = false;
-		auto withinSingleLineComment = false;
-		auto withinPreproc = false;
-		auto firstChar = true;			// there is no other non-whitespace characters in the line before
-		auto concatenate = false;		// '\' on the very end of the line
-		auto currentLine = 0;
-		auto currentIndex = 0;
-		while (currentLine < endLine || currentIndex < endIndex)
-		{
-			auto& line = m_Lines[currentLine];
-
-			if (currentIndex == 0 && !concatenate)
-			{
-				withinSingleLineComment = false;
-				withinPreproc = false;
-				firstChar = true;
-			}
-
-			concatenate = false;
-
-			if (!line.empty())
-			{
-				auto& g = line[currentIndex];
-				auto c = g.m_Char;
-
-				if (c != m_LanguageDefinition.m_PreprocChar && !isspace(c))
-					firstChar = false;
-
-				if (currentIndex == (int)line.size() - 1 && line[line.size() - 1].m_Char == '\\')
-					concatenate = true;
-
-				bool inComment = (commentStartLine < currentLine || (commentStartLine == currentLine && commentStartIndex <= currentIndex));
-
-				if (withinString)
-				{
-					line[currentIndex].m_bMultiLineComment = inComment;
-
-					if (c == '\"')
-					{
-						if (currentIndex + 1 < (int)line.size() && line[currentIndex + 1].m_Char == '\"')
-						{
-							currentIndex += 1;
-							if (currentIndex < (int)line.size())
-								line[currentIndex].m_bMultiLineComment = inComment;
-						}
-						else
-							withinString = false;
-					}
-					else if (c == '\\')
-					{
-						currentIndex += 1;
-						if (currentIndex < (int)line.size())
-							line[currentIndex].m_bMultiLineComment = inComment;
-					}
-				}
-				else
-				{
-					if (firstChar && c == m_LanguageDefinition.m_PreprocChar)
-						withinPreproc = true;
-
-					if (c == '\"')
-					{
-						withinString = true;
-						line[currentIndex].m_bMultiLineComment = inComment;
-					}
-					else
-					{
-						auto pred = [](const char& a, const Glyph& b) { return a == b.m_Char; };
-						auto from = line.begin() + currentIndex;
-						auto& startStr = m_LanguageDefinition.m_svCommentStart;
-						auto& singleStartStr = m_LanguageDefinition.m_svSingleLineComment;
-
-						if (singleStartStr.size() > 0 &&
-							currentIndex + singleStartStr.size() <= line.size() &&
-							equals(singleStartStr.begin(), singleStartStr.end(), from, from + singleStartStr.size(), pred))
-						{
-							withinSingleLineComment = true;
-						}
-						else if (!withinSingleLineComment && currentIndex + startStr.size() <= line.size() &&
-							equals(startStr.begin(), startStr.end(), from, from + startStr.size(), pred))
-						{
-							commentStartLine = currentLine;
-							commentStartIndex = currentIndex;
-						}
-
-						inComment = inComment = (commentStartLine < currentLine || (commentStartLine == currentLine && commentStartIndex <= currentIndex));
-
-						line[currentIndex].m_bMultiLineComment = inComment;
-						line[currentIndex].m_bComment = withinSingleLineComment;
-
-						auto& endStr = m_LanguageDefinition.m_svCommentEnd;
-						if (currentIndex + 1 >= (int)endStr.size() &&
-							equals(endStr.begin(), endStr.end(), from + 1 - endStr.size(), from + 1, pred))
-						{
-							commentStartIndex = endIndex;
-							commentStartLine = endLine;
-						}
-					}
-				}
-				line[currentIndex].m_bPreprocessor = withinPreproc;
-				currentIndex += UTF8CharLength(c);
-				if (currentIndex >= (int)line.size())
-				{
-					currentIndex = 0;
-					++currentLine;
-				}
-			}
-			else
-			{
-				currentIndex = 0;
-				++currentLine;
-			}
-		}
-		m_bCheckComments = false;
-	}
-
-	if (m_nColorRangeMin < m_nColorRangeMax)
-	{
-		const int increment = (m_LanguageDefinition.m_Tokenize == nullptr) ? 10 : 10000;
-		const int to = std::min(m_nColorRangeMin + increment, m_nColorRangeMax);
-		ColorizeRange(m_nColorRangeMin, to);
-		m_nColorRangeMin = to;
-
-		if (m_nColorRangeMax == m_nColorRangeMin)
-		{
-			m_nColorRangeMin = std::numeric_limits<int>::max();
-			m_nColorRangeMax = 0;
-		}
-		return;
-	}
-}
-
 float CTextLogger::TextDistanceToLineStart(const Coordinates& aFrom) const
 {
 	auto& line = m_Lines[aFrom.m_nLine];
@@ -2456,705 +1583,3 @@ int CTextLogger::GetPageSize() const
 	auto height = ImGui::GetWindowHeight() - 20.0f;
 	return (int)floor(height / m_CharAdvance.y);
 }
-
-CTextLogger::UndoRecord::UndoRecord(
-	const std::string& aAdded,
-	const CTextLogger::Coordinates aAddedStart,
-	const CTextLogger::Coordinates aAddedEnd,
-	const std::string& aRemoved,
-	const CTextLogger::Coordinates aRemovedStart,
-	const CTextLogger::Coordinates aRemovedEnd,
-	CTextLogger::EditorState& aBefore,
-	CTextLogger::EditorState& aAfter)
-	: m_svAdded(aAdded)
-	, m_AddedStart(aAddedStart)
-	, m_AddedEnd(aAddedEnd)
-	, m_svRemoved(aRemoved)
-	, m_RemovedStart(aRemovedStart)
-	, m_RemovedEnd(aRemovedEnd)
-	, m_Before(aBefore)
-	, m_After(aAfter)
-{
-	assert(m_AddedStart <= m_AddedEnd);
-	assert(m_RemovedStart <= m_RemovedEnd);
-}
-
-void CTextLogger::UndoRecord::Undo(CTextLogger* aEditor)
-{
-	if (!m_svAdded.empty())
-	{
-		aEditor->DeleteRange(m_AddedStart, m_AddedEnd);
-		aEditor->Colorize(m_AddedStart.m_nLine - 1, m_AddedEnd.m_nLine - m_AddedStart.m_nLine + 2);
-	}
-
-	if (!m_svRemoved.empty())
-	{
-		auto start = m_RemovedStart;
-		aEditor->InsertTextAt(start, m_svRemoved.c_str());
-		aEditor->Colorize(m_RemovedStart.m_nLine - 1, m_RemovedEnd.m_nLine - m_RemovedStart.m_nLine + 2);
-	}
-
-	aEditor->m_State = m_Before;
-	aEditor->EnsureCursorVisible();
-
-}
-
-void CTextLogger::UndoRecord::Redo(CTextLogger* aEditor)
-{
-	if (!m_svRemoved.empty())
-	{
-		aEditor->DeleteRange(m_RemovedStart, m_RemovedEnd);
-		aEditor->Colorize(m_RemovedStart.m_nLine - 1, m_RemovedEnd.m_nLine - m_RemovedStart.m_nLine + 1);
-	}
-
-	if (!m_svAdded.empty())
-	{
-		auto start = m_AddedStart;
-		aEditor->InsertTextAt(start, m_svAdded.c_str());
-		aEditor->Colorize(m_AddedStart.m_nLine - 1, m_AddedEnd.m_nLine - m_AddedStart.m_nLine + 1);
-	}
-
-	aEditor->m_State = m_After;
-	aEditor->EnsureCursorVisible();
-}
-
-static bool TokenizeCStyleString(const char* in_begin, const char* in_end, const char*& out_begin, const char*& out_end)
-{
-	const char* p = in_begin;
-
-	if (*p == '"')
-	{
-		p++;
-
-		while (p < in_end)
-		{
-			// handle end of string
-			if (*p == '"')
-			{
-				out_begin = in_begin;
-				out_end = p + 1;
-				return true;
-			}
-
-			// handle escape character for "
-			if (*p == '\\' && p + 1 < in_end && p[1] == '"')
-				p++;
-
-			p++;
-		}
-	}
-
-	return false;
-}
-
-static bool TokenizeCStyleCharacterLiteral(const char* in_begin, const char* in_end, const char*& out_begin, const char*& out_end)
-{
-	const char* p = in_begin;
-
-	if (*p == '\'')
-	{
-		p++;
-
-		// handle escape characters
-		if (p < in_end && *p == '\\')
-			p++;
-
-		if (p < in_end)
-			p++;
-
-		// handle end of character literal
-		if (p < in_end && *p == '\'')
-		{
-			out_begin = in_begin;
-			out_end = p + 1;
-			return true;
-		}
-	}
-
-	return false;
-}
-
-static bool TokenizeCStyleIdentifier(const char* in_begin, const char* in_end, const char*& out_begin, const char*& out_end)
-{
-	const char* p = in_begin;
-
-	if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || *p == '_')
-	{
-		p++;
-
-		while ((p < in_end) && ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9') || *p == '_'))
-			p++;
-
-		out_begin = in_begin;
-		out_end = p;
-		return true;
-	}
-
-	return false;
-}
-
-static bool TokenizeCStyleNumber(const char* in_begin, const char* in_end, const char*& out_begin, const char*& out_end)
-{
-	const char* p = in_begin;
-
-	const bool startsWithNumber = *p >= '0' && *p <= '9';
-
-	if (*p != '+' && *p != '-' && !startsWithNumber)
-		return false;
-
-	p++;
-
-	bool hasNumber = startsWithNumber;
-
-	while (p < in_end && (*p >= '0' && *p <= '9'))
-	{
-		hasNumber = true;
-
-		p++;
-	}
-
-	if (hasNumber == false)
-		return false;
-
-	bool isFloat = false;
-	bool isHex = false;
-	bool isBinary = false;
-
-	if (p < in_end)
-	{
-		if (*p == '.')
-		{
-			isFloat = true;
-
-			p++;
-
-			while (p < in_end && (*p >= '0' && *p <= '9'))
-				p++;
-		}
-		else if (*p == 'x' || *p == 'X')
-		{
-			// hex formatted integer of the type 0xef80
-
-			isHex = true;
-
-			p++;
-
-			while (p < in_end && ((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F')))
-				p++;
-		}
-		else if (*p == 'b' || *p == 'B')
-		{
-			// binary formatted integer of the type 0b01011101
-
-			isBinary = true;
-
-			p++;
-
-			while (p < in_end && (*p >= '0' && *p <= '1'))
-				p++;
-		}
-	}
-
-	if (isHex == false && isBinary == false)
-	{
-		// floating point exponent
-		if (p < in_end && (*p == 'e' || *p == 'E'))
-		{
-			isFloat = true;
-
-			p++;
-
-			if (p < in_end && (*p == '+' || *p == '-'))
-				p++;
-
-			bool hasDigits = false;
-
-			while (p < in_end && (*p >= '0' && *p <= '9'))
-			{
-				hasDigits = true;
-
-				p++;
-			}
-
-			if (hasDigits == false)
-				return false;
-		}
-
-		// single precision floating point type
-		if (p < in_end && *p == 'f')
-			p++;
-	}
-
-	if (isFloat == false)
-	{
-		// integer size type
-		while (p < in_end && (*p == 'u' || *p == 'U' || *p == 'l' || *p == 'L'))
-			p++;
-	}
-
-	out_begin = in_begin;
-	out_end = p;
-	return true;
-}
-
-static bool TokenizeCStylePunctuation(const char* in_begin, const char* in_end, const char*& out_begin, const char*& out_end)
-{
-	(void)in_end;
-
-	switch (*in_begin)
-	{
-	case '[':
-	case ']':
-	case '{':
-	case '}':
-	case '!':
-	case '%':
-	case '^':
-	case '&':
-	case '*':
-	case '(':
-	case ')':
-	case '-':
-	case '+':
-	case '=':
-	case '~':
-	case '|':
-	case '<':
-	case '>':
-	case '?':
-	case ':':
-	case '/':
-	case ';':
-	case ',':
-	case '.':
-		out_begin = in_begin;
-		out_end = in_begin + 1;
-		return true;
-	}
-
-	return false;
-}
-
-const CTextLogger::LanguageDefinition& CTextLogger::LanguageDefinition::CPlusPlus()
-{
-	static bool inited = false;
-	static LanguageDefinition langDef;
-	if (!inited)
-	{
-		static const char* const cppKeywords[] = {
-			"alignas", "alignof", "and", "and_eq", "asm", "atomic_cancel", "atomic_commit", "atomic_noexcept", "auto", "bitand", "bitor", "bool", "break", "case", "catch", "char", "char16_t", "char32_t", "class",
-			"compl", "concept", "const", "constexpr", "const_cast", "continue", "decltype", "default", "delete", "do", "double", "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float",
-			"for", "friend", "goto", "if", "import", "inline", "int", "long", "module", "mutable", "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq", "private", "protected", "public",
-			"register", "reinterpret_cast", "requires", "return", "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct", "switch", "synchronized", "template", "this", "thread_local",
-			"throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq"
-		};
-		for (auto& k : cppKeywords)
-			langDef.m_Keywords.insert(k);
-
-		static const char* const identifiers[] = {
-			"abort", "abs", "acos", "asin", "atan", "atexit", "atof", "atoi", "atol", "ceil", "clock", "cosh", "ctime", "div", "exit", "fabs", "floor", "fmod", "getchar", "getenv", "isalnum", "isalpha", "isdigit", "isgraph",
-			"ispunct", "isspace", "isupper", "kbhit", "log10", "log2", "log", "memcmp", "modf", "pow", "printf", "sprintf", "snprintf", "putchar", "putenv", "puts", "rand", "remove", "rename", "sinh", "sqrt", "srand", "strcat", "strcmp", "strerror", "time", "tolower", "toupper",
-			"std", "string", "vector", "map", "unordered_map", "set", "unordered_set", "min", "max"
-		};
-		for (auto& k : identifiers)
-		{
-			Identifier id;
-			id.m_svDeclaration = "Built-in function";
-			langDef.m_Identifiers.insert(std::make_pair(std::string(k), id));
-		}
-
-		langDef.m_Tokenize = [](const char* in_begin, const char* in_end, const char*& out_begin, const char*& out_end, PaletteIndex& paletteIndex) -> bool
-		{
-			paletteIndex = PaletteIndex::Max;
-
-			while (in_begin < in_end && isascii(*in_begin) && isblank(*in_begin))
-				in_begin++;
-
-			if (in_begin == in_end)
-			{
-				out_begin = in_end;
-				out_end = in_end;
-				paletteIndex = PaletteIndex::Default;
-			}
-			else if (TokenizeCStyleString(in_begin, in_end, out_begin, out_end))
-				paletteIndex = PaletteIndex::String;
-			else if (TokenizeCStyleCharacterLiteral(in_begin, in_end, out_begin, out_end))
-				paletteIndex = PaletteIndex::CharLiteral;
-			else if (TokenizeCStyleIdentifier(in_begin, in_end, out_begin, out_end))
-				paletteIndex = PaletteIndex::Identifier;
-			else if (TokenizeCStyleNumber(in_begin, in_end, out_begin, out_end))
-				paletteIndex = PaletteIndex::Number;
-			else if (TokenizeCStylePunctuation(in_begin, in_end, out_begin, out_end))
-				paletteIndex = PaletteIndex::Punctuation;
-
-			return paletteIndex != PaletteIndex::Max;
-		};
-
-		langDef.m_svCommentStart = "/*";
-		langDef.m_svCommentEnd = "*/";
-		langDef.m_svSingleLineComment = "//";
-
-		langDef.mCaseSensitive = true;
-		langDef.m_bAutoIndentation = true;
-
-		langDef.m_svName = "C++";
-
-		inited = true;
-	}
-	return langDef;
-}
-
-const CTextLogger::LanguageDefinition& CTextLogger::LanguageDefinition::HLSL()
-{
-	static bool inited = false;
-	static LanguageDefinition langDef;
-	if (!inited)
-	{
-		static const char* const keywords[] = {
-			"AppendStructuredBuffer", "asm", "asm_fragment", "BlendState", "bool", "break", "Buffer", "ByteAddressBuffer", "case", "cbuffer", "centroid", "class", "column_major", "compile", "compile_fragment",
-			"CompileShader", "const", "continue", "ComputeShader", "ConsumeStructuredBuffer", "default", "DepthStencilState", "DepthStencilView", "discard", "do", "double", "DomainShader", "dword", "else",
-			"export", "extern", "false", "float", "for", "fxgroup", "GeometryShader", "groupshared", "half", "Hullshader", "if", "in", "inline", "inout", "InputPatch", "int", "interface", "line", "lineadj",
-			"linear", "LineStream", "matrix", "min16float", "min10float", "min16int", "min12int", "min16uint", "namespace", "nointerpolation", "noperspective", "NULL", "out", "OutputPatch", "packoffset",
-			"pass", "pixelfragment", "PixelShader", "point", "PointStream", "precise", "RasterizerState", "RenderTargetView", "return", "register", "row_major", "RWBuffer", "RWByteAddressBuffer", "RWStructuredBuffer",
-			"RWTexture1D", "RWTexture1DArray", "RWTexture2D", "RWTexture2DArray", "RWTexture3D", "sample", "sampler", "SamplerState", "SamplerComparisonState", "shared", "snorm", "stateblock", "stateblock_state",
-			"static", "string", "struct", "switch", "StructuredBuffer", "tbuffer", "technique", "technique10", "technique11", "texture", "Texture1D", "Texture1DArray", "Texture2D", "Texture2DArray", "Texture2DMS",
-			"Texture2DMSArray", "Texture3D", "TextureCube", "TextureCubeArray", "true", "typedef", "triangle", "triangleadj", "TriangleStream", "uint", "uniform", "unorm", "unsigned", "vector", "vertexfragment",
-			"VertexShader", "void", "volatile", "while",
-			"bool1","bool2","bool3","bool4","double1","double2","double3","double4", "float1", "float2", "float3", "float4", "int1", "int2", "int3", "int4", "in", "out", "inout",
-			"uint1", "uint2", "uint3", "uint4", "dword1", "dword2", "dword3", "dword4", "half1", "half2", "half3", "half4",
-			"float1x1","float2x1","float3x1","float4x1","float1x2","float2x2","float3x2","float4x2",
-			"float1x3","float2x3","float3x3","float4x3","float1x4","float2x4","float3x4","float4x4",
-			"half1x1","half2x1","half3x1","half4x1","half1x2","half2x2","half3x2","half4x2",
-			"half1x3","half2x3","half3x3","half4x3","half1x4","half2x4","half3x4","half4x4",
-		};
-		for (auto& k : keywords)
-			langDef.m_Keywords.insert(k);
-
-		static const char* const identifiers[] = {
-			"abort", "abs", "acos", "all", "AllMemoryBarrier", "AllMemoryBarrierWithGroupSync", "any", "asdouble", "asfloat", "asin", "asint", "asint", "asuint",
-			"asuint", "atan", "atan2", "ceil", "CheckAccessFullyMapped", "clamp", "clip", "cos", "cosh", "countbits", "cross", "D3DCOLORtoUBYTE4", "ddx",
-			"ddx_coarse", "ddx_fine", "ddy", "ddy_coarse", "ddy_fine", "degrees", "determinant", "DeviceMemoryBarrier", "DeviceMemoryBarrierWithGroupSync",
-			"distance", "dot", "dst", "errorf", "EvaluateAttributeAtCentroid", "EvaluateAttributeAtSample", "EvaluateAttributeSnapped", "exp", "exp2",
-			"f16tof32", "f32tof16", "faceforward", "firstbithigh", "firstbitlow", "floor", "fma", "fmod", "frac", "frexp", "fwidth", "GetRenderTargetSampleCount",
-			"GetRenderTargetSamplePosition", "GroupMemoryBarrier", "GroupMemoryBarrierWithGroupSync", "InterlockedAdd", "InterlockedAnd", "InterlockedCompareExchange",
-			"InterlockedCompareStore", "InterlockedExchange", "InterlockedMax", "InterlockedMin", "InterlockedOr", "InterlockedXor", "isfinite", "isinf", "isnan",
-			"ldexp", "length", "lerp", "lit", "log", "log10", "log2", "mad", "max", "min", "modf", "msad4", "mul", "noise", "normalize", "pow", "printf",
-			"Process2DQuadTessFactorsAvg", "Process2DQuadTessFactorsMax", "Process2DQuadTessFactorsMin", "ProcessIsolineTessFactors", "ProcessQuadTessFactorsAvg",
-			"ProcessQuadTessFactorsMax", "ProcessQuadTessFactorsMin", "ProcessTriTessFactorsAvg", "ProcessTriTessFactorsMax", "ProcessTriTessFactorsMin",
-			"radians", "rcp", "reflect", "refract", "reversebits", "round", "rsqrt", "saturate", "sign", "sin", "sincos", "sinh", "smoothstep", "sqrt", "step",
-			"tan", "tanh", "tex1D", "tex1D", "tex1Dbias", "tex1Dgrad", "tex1Dlod", "tex1Dproj", "tex2D", "tex2D", "tex2Dbias", "tex2Dgrad", "tex2Dlod", "tex2Dproj",
-			"tex3D", "tex3D", "tex3Dbias", "tex3Dgrad", "tex3Dlod", "tex3Dproj", "texCUBE", "texCUBE", "texCUBEbias", "texCUBEgrad", "texCUBElod", "texCUBEproj", "transpose", "trunc"
-		};
-		for (auto& k : identifiers)
-		{
-			Identifier id;
-			id.m_svDeclaration = "Built-in function";
-			langDef.m_Identifiers.insert(std::make_pair(std::string(k), id));
-		}
-
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[ \\t]*#[ \\t]*[a-zA-Z_]+", PaletteIndex::Preprocessor));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\'\\\\?[^\\']\\'", PaletteIndex::CharLiteral));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[0-7]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
-
-		langDef.m_svCommentStart = "/*";
-		langDef.m_svCommentEnd = "*/";
-		langDef.m_svSingleLineComment = "//";
-
-		langDef.mCaseSensitive = true;
-		langDef.m_bAutoIndentation = true;
-
-		langDef.m_svName = "HLSL";
-
-		inited = true;
-	}
-	return langDef;
-}
-
-const CTextLogger::LanguageDefinition& CTextLogger::LanguageDefinition::GLSL()
-{
-	static bool inited = false;
-	static LanguageDefinition langDef;
-	if (!inited)
-	{
-		static const char* const keywords[] = {
-			"auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "inline", "int", "long", "register", "restrict", "return", "short",
-			"signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while", "_Alignas", "_Alignof", "_Atomic", "_Bool", "_Complex", "_Generic", "_Imaginary",
-			"_Noreturn", "_Static_assert", "_Thread_local"
-		};
-		for (auto& k : keywords)
-			langDef.m_Keywords.insert(k);
-
-		static const char* const identifiers[] = {
-			"abort", "abs", "acos", "asin", "atan", "atexit", "atof", "atoi", "atol", "ceil", "clock", "cosh", "ctime", "div", "exit", "fabs", "floor", "fmod", "getchar", "getenv", "isalnum", "isalpha", "isdigit", "isgraph",
-			"ispunct", "isspace", "isupper", "kbhit", "log10", "log2", "log", "memcmp", "modf", "pow", "putchar", "putenv", "puts", "rand", "remove", "rename", "sinh", "sqrt", "srand", "strcat", "strcmp", "strerror", "time", "tolower", "toupper"
-		};
-		for (auto& k : identifiers)
-		{
-			Identifier id;
-			id.m_svDeclaration = "Built-in function";
-			langDef.m_Identifiers.insert(std::make_pair(std::string(k), id));
-		}
-
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[ \\t]*#[ \\t]*[a-zA-Z_]+", PaletteIndex::Preprocessor));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\'\\\\?[^\\']\\'", PaletteIndex::CharLiteral));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[0-7]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
-
-		langDef.m_svCommentStart = "/*";
-		langDef.m_svCommentEnd = "*/";
-		langDef.m_svSingleLineComment = "//";
-
-		langDef.mCaseSensitive = true;
-		langDef.m_bAutoIndentation = true;
-
-		langDef.m_svName = "GLSL";
-
-		inited = true;
-	}
-	return langDef;
-}
-
-const CTextLogger::LanguageDefinition& CTextLogger::LanguageDefinition::C()
-{
-	static bool inited = false;
-	static LanguageDefinition langDef;
-	if (!inited)
-	{
-		static const char* const keywords[] = {
-			"auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "inline", "int", "long", "register", "restrict", "return", "short",
-			"signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while", "_Alignas", "_Alignof", "_Atomic", "_Bool", "_Complex", "_Generic", "_Imaginary",
-			"_Noreturn", "_Static_assert", "_Thread_local"
-		};
-		for (auto& k : keywords)
-			langDef.m_Keywords.insert(k);
-
-		static const char* const identifiers[] = {
-			"abort", "abs", "acos", "asin", "atan", "atexit", "atof", "atoi", "atol", "ceil", "clock", "cosh", "ctime", "div", "exit", "fabs", "floor", "fmod", "getchar", "getenv", "isalnum", "isalpha", "isdigit", "isgraph",
-			"ispunct", "isspace", "isupper", "kbhit", "log10", "log2", "log", "memcmp", "modf", "pow", "putchar", "putenv", "puts", "rand", "remove", "rename", "sinh", "sqrt", "srand", "strcat", "strcmp", "strerror", "time", "tolower", "toupper"
-		};
-		for (auto& k : identifiers)
-		{
-			Identifier id;
-			id.m_svDeclaration = "Built-in function";
-			langDef.m_Identifiers.insert(std::make_pair(std::string(k), id));
-		}
-
-		langDef.m_Tokenize = [](const char* in_begin, const char* in_end, const char*& out_begin, const char*& out_end, PaletteIndex& paletteIndex) -> bool
-		{
-			paletteIndex = PaletteIndex::Max;
-
-			while (in_begin < in_end && isascii(*in_begin) && isblank(*in_begin))
-				in_begin++;
-
-			if (in_begin == in_end)
-			{
-				out_begin = in_end;
-				out_end = in_end;
-				paletteIndex = PaletteIndex::Default;
-			}
-			else if (TokenizeCStyleString(in_begin, in_end, out_begin, out_end))
-				paletteIndex = PaletteIndex::String;
-			else if (TokenizeCStyleCharacterLiteral(in_begin, in_end, out_begin, out_end))
-				paletteIndex = PaletteIndex::CharLiteral;
-			else if (TokenizeCStyleIdentifier(in_begin, in_end, out_begin, out_end))
-				paletteIndex = PaletteIndex::Identifier;
-			else if (TokenizeCStyleNumber(in_begin, in_end, out_begin, out_end))
-				paletteIndex = PaletteIndex::Number;
-			else if (TokenizeCStylePunctuation(in_begin, in_end, out_begin, out_end))
-				paletteIndex = PaletteIndex::Punctuation;
-
-			return paletteIndex != PaletteIndex::Max;
-		};
-
-		langDef.m_svCommentStart = "/*";
-		langDef.m_svCommentEnd = "*/";
-		langDef.m_svSingleLineComment = "//";
-
-		langDef.mCaseSensitive = true;
-		langDef.m_bAutoIndentation = true;
-
-		langDef.m_svName = "C";
-
-		inited = true;
-	}
-	return langDef;
-}
-
-const CTextLogger::LanguageDefinition& CTextLogger::LanguageDefinition::SQL()
-{
-	static bool inited = false;
-	static LanguageDefinition langDef;
-	if (!inited)
-	{
-		static const char* const keywords[] = {
-			"ADD", "EXCEPT", "PERCENT", "ALL", "EXEC", "PLAN", "ALTER", "EXECUTE", "PRECISION", "AND", "EXISTS", "PRIMARY", "ANY", "EXIT", "PRINT", "AS", "FETCH", "PROC", "ASC", "FILE", "PROCEDURE",
-			"AUTHORIZATION", "FILLFACTOR", "PUBLIC", "BACKUP", "FOR", "RAISERROR", "BEGIN", "FOREIGN", "READ", "BETWEEN", "FREETEXT", "READTEXT", "BREAK", "FREETEXTTABLE", "RECONFIGURE",
-			"BROWSE", "FROM", "REFERENCES", "BULK", "FULL", "REPLICATION", "BY", "FUNCTION", "RESTORE", "CASCADE", "GOTO", "RESTRICT", "CASE", "GRANT", "RETURN", "CHECK", "GROUP", "REVOKE",
-			"CHECKPOINT", "HAVING", "RIGHT", "CLOSE", "HOLDLOCK", "ROLLBACK", "CLUSTERED", "IDENTITY", "ROWCOUNT", "COALESCE", "IDENTITY_INSERT", "ROWGUIDCOL", "COLLATE", "IDENTITYCOL", "RULE",
-			"COLUMN", "IF", "SAVE", "COMMIT", "IN", "SCHEMA", "COMPUTE", "INDEX", "SELECT", "CONSTRAINT", "INNER", "SESSION_USER", "CONTAINS", "INSERT", "SET", "CONTAINSTABLE", "INTERSECT", "SETUSER",
-			"CONTINUE", "INTO", "SHUTDOWN", "CONVERT", "IS", "SOME", "CREATE", "JOIN", "STATISTICS", "CROSS", "KEY", "SYSTEM_USER", "CURRENT", "KILL", "TABLE", "CURRENT_DATE", "LEFT", "TEXTSIZE",
-			"CURRENT_TIME", "LIKE", "THEN", "CURRENT_TIMESTAMP", "LINENO", "TO", "CURRENT_USER", "LOAD", "TOP", "CURSOR", "NATIONAL", "TRAN", "DATABASE", "NOCHECK", "TRANSACTION",
-			"DBCC", "NONCLUSTERED", "TRIGGER", "DEALLOCATE", "NOT", "TRUNCATE", "DECLARE", "NULL", "TSEQUAL", "DEFAULT", "NULLIF", "UNION", "DELETE", "OF", "UNIQUE", "DENY", "OFF", "UPDATE",
-			"DESC", "OFFSETS", "UPDATETEXT", "DISK", "ON", "USE", "DISTINCT", "OPEN", "USER", "DISTRIBUTED", "OPENDATASOURCE", "VALUES", "DOUBLE", "OPENQUERY", "VARYING","DROP", "OPENROWSET", "VIEW",
-			"DUMMY", "OPENXML", "WAITFOR", "DUMP", "OPTION", "WHEN", "ELSE", "OR", "WHERE", "END", "ORDER", "WHILE", "ERRLVL", "OUTER", "WITH", "ESCAPE", "OVER", "WRITETEXT"
-		};
-
-		for (auto& k : keywords)
-			langDef.m_Keywords.insert(k);
-
-		static const char* const identifiers[] = {
-			"ABS",  "ACOS",  "ADD_MONTHS",  "ASCII",  "ASCIISTR",  "ASIN",  "ATAN",  "ATAN2",  "AVG",  "BFILENAME",  "BIN_TO_NUM",  "BITAND",  "CARDINALITY",  "CASE",  "CAST",  "CEIL",
-			"CHARTOROWID",  "CHR",  "COALESCE",  "COMPOSE",  "CONCAT",  "CONVERT",  "CORR",  "COS",  "COSH",  "COUNT",  "COVAR_POP",  "COVAR_SAMP",  "CUME_DIST",  "CURRENT_DATE",
-			"CURRENT_TIMESTAMP",  "DBTIMEZONE",  "DECODE",  "DECOMPOSE",  "DENSE_RANK",  "DUMP",  "EMPTY_BLOB",  "EMPTY_CLOB",  "EXP",  "EXTRACT",  "FIRST_VALUE",  "FLOOR",  "FROM_TZ",  "GREATEST",
-			"GROUP_ID",  "HEXTORAW",  "INITCAP",  "INSTR",  "INSTR2",  "INSTR4",  "INSTRB",  "INSTRC",  "LAG",  "LAST_DAY",  "LAST_VALUE",  "LEAD",  "LEAST",  "LENGTH",  "LENGTH2",  "LENGTH4",
-			"LENGTHB",  "LENGTHC",  "LISTAGG",  "LN",  "LNNVL",  "LOCALTIMESTAMP",  "LOG",  "LOWER",  "LPAD",  "LTRIM",  "MAX",  "MEDIAN",  "MIN",  "MOD",  "MONTHS_BETWEEN",  "NANVL",  "NCHR",
-			"NEW_TIME",  "NEXT_DAY",  "NTH_VALUE",  "NULLIF",  "NUMTODSINTERVAL",  "NUMTOYMINTERVAL",  "NVL",  "NVL2",  "POWER",  "RANK",  "RAWTOHEX",  "REGEXP_COUNT",  "REGEXP_INSTR",
-			"REGEXP_REPLACE",  "REGEXP_SUBSTR",  "REMAINDER",  "REPLACE",  "ROUND",  "ROWNUM",  "RPAD",  "RTRIM",  "SESSIONTIMEZONE",  "SIGN",  "SIN",  "SINH",
-			"SOUNDEX",  "SQRT",  "STDDEV",  "SUBSTR",  "SUM",  "SYS_CONTEXT",  "SYSDATE",  "SYSTIMESTAMP",  "TAN",  "TANH",  "TO_CHAR",  "TO_CLOB",  "TO_DATE",  "TO_DSINTERVAL",  "TO_LOB",
-			"TO_MULTI_BYTE",  "TO_NCLOB",  "TO_NUMBER",  "TO_SINGLE_BYTE",  "TO_TIMESTAMP",  "TO_TIMESTAMP_TZ",  "TO_YMINTERVAL",  "TRANSLATE",  "TRIM",  "TRUNC", "TZ_OFFSET",  "UID",  "UPPER",
-			"USER",  "USERENV",  "VAR_POP",  "VAR_SAMP",  "VARIANCE",  "VSIZE "
-		};
-		for (auto& k : identifiers)
-		{
-			Identifier id;
-			id.m_svDeclaration = "Built-in function";
-			langDef.m_Identifiers.insert(std::make_pair(std::string(k), id));
-		}
-
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\\'[^\\\']*\\\'", PaletteIndex::String));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[0-7]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
-
-		langDef.m_svCommentStart = "/*";
-		langDef.m_svCommentEnd = "*/";
-		langDef.m_svSingleLineComment = "//";
-
-		langDef.mCaseSensitive = false;
-		langDef.m_bAutoIndentation = false;
-
-		langDef.m_svName = "SQL";
-
-		inited = true;
-	}
-	return langDef;
-}
-
-const CTextLogger::LanguageDefinition& CTextLogger::LanguageDefinition::AngelScript()
-{
-	static bool inited = false;
-	static LanguageDefinition langDef;
-	if (!inited)
-	{
-		static const char* const keywords[] = {
-			"and", "abstract", "auto", "bool", "break", "case", "cast", "class", "const", "continue", "default", "do", "double", "else", "enum", "false", "final", "float", "for",
-			"from", "funcdef", "function", "get", "if", "import", "in", "inout", "int", "interface", "int8", "int16", "int32", "int64", "is", "mixin", "namespace", "not",
-			"null", "or", "out", "override", "private", "protected", "return", "set", "shared", "super", "switch", "this ", "true", "typedef", "uint", "uint8", "uint16", "uint32",
-			"uint64", "void", "while", "xor"
-		};
-
-		for (auto& k : keywords)
-			langDef.m_Keywords.insert(k);
-
-		static const char* const identifiers[] = {
-			"cos", "sin", "tab", "acos", "asin", "atan", "atan2", "cosh", "sinh", "tanh", "log", "log10", "pow", "sqrt", "abs", "ceil", "floor", "fraction", "closeTo", "fpFromIEEE", "fpToIEEE",
-			"complex", "opEquals", "opAddAssign", "opSubAssign", "opMulAssign", "opDivAssign", "opAdd", "opSub", "opMul", "opDiv"
-		};
-		for (auto& k : identifiers)
-		{
-			Identifier id;
-			id.m_svDeclaration = "Built-in function";
-			langDef.m_Identifiers.insert(std::make_pair(std::string(k), id));
-		}
-
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\'\\\\?[^\\']\\'", PaletteIndex::String));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[0-7]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
-
-		langDef.m_svCommentStart = "/*";
-		langDef.m_svCommentEnd = "*/";
-		langDef.m_svSingleLineComment = "//";
-
-		langDef.mCaseSensitive = true;
-		langDef.m_bAutoIndentation = true;
-
-		langDef.m_svName = "AngelScript";
-
-		inited = true;
-	}
-	return langDef;
-}
-
-const CTextLogger::LanguageDefinition& CTextLogger::LanguageDefinition::Lua()
-{
-	static bool inited = false;
-	static LanguageDefinition langDef;
-	if (!inited)
-	{
-		static const char* const keywords[] = {
-			"and", "break", "do", "", "else", "elseif", "end", "false", "for", "function", "if", "in", "", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while"
-		};
-
-		for (auto& k : keywords)
-			langDef.m_Keywords.insert(k);
-
-		static const char* const identifiers[] = {
-			"assert", "collectgarbage", "dofile", "error", "getmetatable", "ipairs", "loadfile", "load", "loadstring",  "next",  "pairs",  "pcall",  "print",  "rawequal",  "rawlen",  "rawget",  "rawset",
-			"select",  "setmetatable",  "tonumber",  "tostring",  "type",  "xpcall",  "_G",  "_VERSION","arshift", "band", "bnot", "bor", "bxor", "btest", "extract", "lrotate", "lshift", "replace",
-			"rrotate", "rshift", "create", "resume", "running", "status", "wrap", "yield", "isyieldable", "debug","getuservalue", "gethook", "getinfo", "getlocal", "getregistry", "getmetatable",
-			"getupvalue", "upvaluejoin", "upvalueid", "setuservalue", "sethook", "setlocal", "setmetatable", "setupvalue", "traceback", "close", "flush", "input", "lines", "open", "output", "popen",
-			"read", "tmpfile", "type", "write", "close", "flush", "lines", "read", "seek", "setvbuf", "write", "__gc", "__tostring", "abs", "acos", "asin", "atan", "ceil", "cos", "deg", "exp", "tointeger",
-			"floor", "fmod", "ult", "log", "max", "min", "modf", "rad", "random", "randomseed", "sin", "sqrt", "string", "tan", "type", "atan2", "cosh", "sinh", "tanh",
-			"pow", "frexp", "ldexp", "log10", "pi", "huge", "maxinteger", "mininteger", "loadlib", "searchpath", "seeall", "preload", "cpath", "path", "searchers", "loaded", "module", "require", "clock",
-			"date", "difftime", "execute", "exit", "getenv", "remove", "rename", "setlocale", "time", "tmpname", "byte", "char", "dump", "find", "format", "gmatch", "gsub", "len", "lower", "match", "rep",
-			"reverse", "sub", "upper", "pack", "packsize", "unpack", "concat", "maxn", "insert", "pack", "unpack", "remove", "move", "sort", "offset", "codepoint", "char", "len", "codes", "charpattern",
-			"coroutine", "table", "io", "os", "string", "utf8", "bit32", "math", "debug", "package"
-		};
-		for (auto& k : identifiers)
-		{
-			Identifier id;
-			id.m_svDeclaration = "Built-in function";
-			langDef.m_Identifiers.insert(std::make_pair(std::string(k), id));
-		}
-
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\\'[^\\\']*\\\'", PaletteIndex::String));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
-		langDef.m_TokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
-
-		langDef.m_svCommentStart = "--[[";
-		langDef.m_svCommentEnd = "]]";
-		langDef.m_svSingleLineComment = "--";
-
-		langDef.mCaseSensitive = true;
-		langDef.m_bAutoIndentation = false;
-
-		langDef.m_svName = "Lua";
-
-		inited = true;
-	}
-	return langDef;
-}