diff --git a/TextEditor.cpp b/TextEditor.cpp
index 53e5553..8b30246 100644
--- a/TextEditor.cpp
+++ b/TextEditor.cpp
@@ -1,3159 +1,3158 @@
-#include <algorithm>
-#include <chrono>
-#include <string>
-#include <regex>
-#include <cmath>
-
-#include "TextEditor.h"
-
-#define IMGUI_DEFINE_MATH_OPERATORS
-#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)
-{
-	for (; first1 != last1 && first2 != last2; ++first1, ++first2)
-	{
-		if (!p(*first1, *first2))
-			return false;
-	}
-	return first1 == last1 && first2 == last2;
-}
-
-TextEditor::TextEditor()
-	: mLineSpacing(1.0f)
-	, mUndoIndex(0)
-	, mTabSize(4)
-	, mOverwrite(false)
-	, mReadOnly(false)
-	, mWithinRender(false)
-	, mScrollToCursor(false)
-	, mScrollToTop(false)
-	, mTextChanged(false)
-	, mColorizerEnabled(true)
-	, mTextStart(20.0f)
-	, mLeftMargin(10)
-	, mCursorPositionChanged(false)
-	, mColorRangeMin(0)
-	, mColorRangeMax(0)
-	, mSelectionMode(SelectionMode::Normal)
-	, mCheckComments(true)
-	, mLastClick(-1.0f)
-	, mHandleKeyboardInputs(true)
-	, mHandleMouseInputs(true)
-	, mIgnoreImGuiChild(false)
-	, mShowWhitespaces(true)
-	, mStartTime(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count())
-{
-	SetPalette(GetDarkPalette());
-	SetLanguageDefinition(LanguageDefinition::HLSL());
-	mLines.push_back(Line());
-}
-
-TextEditor::~TextEditor()
-{
-}
-
-void TextEditor::SetLanguageDefinition(const LanguageDefinition & aLanguageDef)
-{
-	mLanguageDefinition = aLanguageDef;
-	mRegexList.clear();
-
-	for (auto& r : mLanguageDefinition.mTokenRegexStrings)
-		mRegexList.push_back(std::make_pair(std::regex(r.first, std::regex_constants::optimize), r.second));
-
-	Colorize();
-}
-
-void TextEditor::SetPalette(const Palette & aValue)
-{
-	mPaletteBase = aValue;
-}
-
-std::string TextEditor::GetText(const Coordinates & aStart, const Coordinates & aEnd) const
-{
-	std::string result;
-
-	auto lstart = aStart.mLine;
-	auto lend = aEnd.mLine;
-	auto istart = GetCharacterIndex(aStart);
-	auto iend = GetCharacterIndex(aEnd);
-	size_t s = 0;
-
-	for (size_t i = lstart; i < lend; i++)
-		s += mLines[i].size();
-
-	result.reserve(s + s / 8);
-
-	while (istart < iend || lstart < lend)
-	{
-		if (lstart >= (int)mLines.size())
-			break;
-
-		auto& line = mLines[lstart];
-		if (istart < (int)line.size())
-		{
-			result += line[istart].mChar;
-			istart++;
-		}
-		else
-		{
-			istart = 0;
-			++lstart;
-			result += '\n';
-		}
-	}
-
-	return result;
-}
-
-TextEditor::Coordinates TextEditor::GetActualCursorCoordinates() const
-{
-	return SanitizeCoordinates(mState.mCursorPosition);
-}
-
-TextEditor::Coordinates TextEditor::SanitizeCoordinates(const Coordinates & aValue) const
-{
-	auto line = aValue.mLine;
-	auto column = aValue.mColumn;
-	if (line >= (int)mLines.size())
-	{
-		if (mLines.empty())
-		{
-			line = 0;
-			column = 0;
-		}
-		else
-		{
-			line = (int)mLines.size() - 1;
-			column = GetLineMaxColumn(line);
-		}
-		return Coordinates(line, column);
-	}
-	else
-	{
-		column = mLines.empty() ? 0 : std::min(column, GetLineMaxColumn(line));
-		return Coordinates(line, column);
-	}
-}
-
-// https://en.wikipedia.org/wiki/UTF-8
-// We assume that the char is a standalone character (<128) or a leading byte of an UTF-8 code sequence (non-10xxxxxx code)
-static int UTF8CharLength(TextEditor::Char c)
-{
-	if ((c & 0xFE) == 0xFC)
-		return 6;
-	if ((c & 0xFC) == 0xF8)
-		return 5;
-	if ((c & 0xF8) == 0xF0)
-		return 4;
-	else if ((c & 0xF0) == 0xE0)
-		return 3;
-	else if ((c & 0xE0) == 0xC0)
-		return 2;
-	return 1;
-}
-
-// "Borrowed" from ImGui source
-static inline int ImTextCharToUtf8(char* buf, int buf_size, unsigned int c)
-{
-	if (c < 0x80)
-	{
-		buf[0] = (char)c;
-		return 1;
-	}
-	if (c < 0x800)
-	{
-		if (buf_size < 2) return 0;
-		buf[0] = (char)(0xc0 + (c >> 6));
-		buf[1] = (char)(0x80 + (c & 0x3f));
-		return 2;
-	}
-	if (c >= 0xdc00 && c < 0xe000)
-	{
-		return 0;
-	}
-	if (c >= 0xd800 && c < 0xdc00)
-	{
-		if (buf_size < 4) return 0;
-		buf[0] = (char)(0xf0 + (c >> 18));
-		buf[1] = (char)(0x80 + ((c >> 12) & 0x3f));
-		buf[2] = (char)(0x80 + ((c >> 6) & 0x3f));
-		buf[3] = (char)(0x80 + ((c) & 0x3f));
-		return 4;
-	}
-	//else if (c < 0x10000)
-	{
-		if (buf_size < 3) return 0;
-		buf[0] = (char)(0xe0 + (c >> 12));
-		buf[1] = (char)(0x80 + ((c >> 6) & 0x3f));
-		buf[2] = (char)(0x80 + ((c) & 0x3f));
-		return 3;
-	}
-}
-
-void TextEditor::Advance(Coordinates & aCoordinates) const
-{
-	if (aCoordinates.mLine < (int)mLines.size())
-	{
-		auto& line = mLines[aCoordinates.mLine];
-		auto cindex = GetCharacterIndex(aCoordinates);
-
-		if (cindex + 1 < (int)line.size())
-		{
-			auto delta = UTF8CharLength(line[cindex].mChar);
-			cindex = std::min(cindex + delta, (int)line.size() - 1);
-		}
-		else
-		{
-			++aCoordinates.mLine;
-			cindex = 0;
-		}
-		aCoordinates.mColumn = GetCharacterColumn(aCoordinates.mLine, cindex);
-	}
-}
-
-void TextEditor::DeleteRange(const Coordinates & aStart, const Coordinates & aEnd)
-{
-	assert(aEnd >= aStart);
-	assert(!mReadOnly);
-
-	//printf("D(%d.%d)-(%d.%d)\n", aStart.mLine, aStart.mColumn, aEnd.mLine, aEnd.mColumn);
-
-	if (aEnd == aStart)
-		return;
-
-	auto start = GetCharacterIndex(aStart);
-	auto end = GetCharacterIndex(aEnd);
-
-	if (aStart.mLine == aEnd.mLine)
-	{
-		auto& line = mLines[aStart.mLine];
-		auto n = GetLineMaxColumn(aStart.mLine);
-		if (aEnd.mColumn >= n)
-			line.erase(line.begin() + start, line.end());
-		else
-			line.erase(line.begin() + start, line.begin() + end);
-	}
-	else
-	{
-		auto& firstLine = mLines[aStart.mLine];
-		auto& lastLine = mLines[aEnd.mLine];
-
-		firstLine.erase(firstLine.begin() + start, firstLine.end());
-		lastLine.erase(lastLine.begin(), lastLine.begin() + end);
-
-		if (aStart.mLine < aEnd.mLine)
-			firstLine.insert(firstLine.end(), lastLine.begin(), lastLine.end());
-
-		if (aStart.mLine < aEnd.mLine)
-			RemoveLine(aStart.mLine + 1, aEnd.mLine + 1);
-	}
-
-	mTextChanged = true;
-}
-
-int TextEditor::InsertTextAt(Coordinates& /* inout */ aWhere, const char * aValue)
-{
-	assert(!mReadOnly);
-
-	int cindex = GetCharacterIndex(aWhere);
-	int totalLines = 0;
-	while (*aValue != '\0')
-	{
-		assert(!mLines.empty());
-
-		if (*aValue == '\r')
-		{
-			// skip
-			++aValue;
-		}
-		else if (*aValue == '\n')
-		{
-			if (cindex < (int)mLines[aWhere.mLine].size())
-			{
-				auto& newLine = InsertLine(aWhere.mLine + 1);
-				auto& line = mLines[aWhere.mLine];
-				newLine.insert(newLine.begin(), line.begin() + cindex, line.end());
-				line.erase(line.begin() + cindex, line.end());
-			}
-			else
-			{
-				InsertLine(aWhere.mLine + 1);
-			}
-			++aWhere.mLine;
-			aWhere.mColumn = 0;
-			cindex = 0;
-			++totalLines;
-			++aValue;
-		}
-		else
-		{
-			auto& line = mLines[aWhere.mLine];
-			auto d = UTF8CharLength(*aValue);
-			while (d-- > 0 && *aValue != '\0')
-				line.insert(line.begin() + cindex++, Glyph(*aValue++, PaletteIndex::Default));
-			++aWhere.mColumn;
-		}
-
-		mTextChanged = true;
-	}
-
-	return totalLines;
-}
-
-void TextEditor::AddUndo(UndoRecord& aValue)
-{
-	assert(!mReadOnly);
-	//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
-	//	);
-
-	mUndoBuffer.resize((size_t)(mUndoIndex + 1));
-	mUndoBuffer.back() = aValue;
-	++mUndoIndex;
-}
-
-TextEditor::Coordinates TextEditor::ScreenPosToCoordinates(const ImVec2& aPosition) const
-{
-	ImVec2 origin = ImGui::GetCursorScreenPos();
-	ImVec2 local(aPosition.x - origin.x, aPosition.y - origin.y);
-
-	int lineNo = std::max(0, (int)floor(local.y / mCharAdvance.y));
-
-	int columnCoord = 0;
-
-	if (lineNo >= 0 && lineNo < (int)mLines.size())
-	{
-		auto& line = mLines.at(lineNo);
-
-		int columnIndex = 0;
-		std::string cumulatedString = "";
-		float columnWidth = 0.0f;
-		float columnX = 0.0f;
-
-		// First we find the hovered column coord.
-		while (mTextStart + columnX < local.x && (size_t)columnIndex < line.size())
-		{
-			if (line[columnIndex].mChar == '\t')
-			{
-				float spaceSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, " ").x;
-				float oldX = columnX;
-				columnX = (1.0f + std::floor((1.0f + columnX) / (float(mTabSize) * spaceSize))) * (float(mTabSize) * spaceSize);
-				columnWidth = columnX - oldX;
-				columnCoord++;
-			}
-			else
-			{
-				char buf[7];
-				auto d = UTF8CharLength(line[columnIndex].mChar);
-				int i = 0;
-				while (i < 6 && d-- > 0)
-					buf[i++] = line[columnIndex++].mChar;
-				buf[i] = '\0';
-				columnWidth = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, buf).x;
-				columnX += columnWidth;
-				columnCoord++;
-			}
-		}
-
-		// Then we reduce by 1 column coord if cursor is on the left side of the hovered column.
-		if (mTextStart + columnX - columnWidth / 2.0f > local.x)
-			columnIndex = std::max(0, columnIndex - 1);
-	}
-
-	return SanitizeCoordinates(Coordinates(lineNo, columnCoord));
-}
-
-TextEditor::Coordinates TextEditor::FindWordStart(const Coordinates & aFrom) const
-{
-	Coordinates at = aFrom;
-	if (at.mLine >= (int)mLines.size())
-		return at;
-
-	auto& line = mLines[at.mLine];
-	auto cindex = GetCharacterIndex(at);
-
-	if (cindex >= (int)line.size())
-		return at;
-
-	while (cindex > 0 && isspace(line[cindex].mChar))
-		--cindex;
-
-	auto cstart = (PaletteIndex)line[cindex].mColorIndex;
-	while (cindex > 0)
-	{
-		auto c = line[cindex].mChar;
-		if ((c & 0xC0) != 0x80)	// not UTF code sequence 10xxxxxx
-		{
-			if (c <= 32 && isspace(c))
-			{
-				cindex++;
-				break;
-			}
-			if (cstart != (PaletteIndex)line[size_t(cindex - 1)].mColorIndex)
-				break;
-		}
-		--cindex;
-	}
-	return Coordinates(at.mLine, GetCharacterColumn(at.mLine, cindex));
-}
-
-TextEditor::Coordinates TextEditor::FindWordEnd(const Coordinates & aFrom) const
-{
-	Coordinates at = aFrom;
-	if (at.mLine >= (int)mLines.size())
-		return at;
-
-	auto& line = mLines[at.mLine];
-	auto cindex = GetCharacterIndex(at);
-
-	if (cindex >= (int)line.size())
-		return at;
-
-	bool prevspace = (bool)isspace(line[cindex].mChar);
-	auto cstart = (PaletteIndex)line[cindex].mColorIndex;
-	while (cindex < (int)line.size())
-	{
-		auto c = line[cindex].mChar;
-		auto d = UTF8CharLength(c);
-		if (cstart != (PaletteIndex)line[cindex].mColorIndex)
-			break;
-
-		if (prevspace != !!isspace(c))
-		{
-			if (isspace(c))
-				while (cindex < (int)line.size() && isspace(line[cindex].mChar))
-					++cindex;
-			break;
-		}
-		cindex += d;
-	}
-	return Coordinates(aFrom.mLine, GetCharacterColumn(aFrom.mLine, cindex));
-}
-
-TextEditor::Coordinates TextEditor::FindNextWord(const Coordinates & aFrom) const
-{
-	Coordinates at = aFrom;
-	if (at.mLine >= (int)mLines.size())
-		return at;
-
-	// skip to the next non-word character
-	auto cindex = GetCharacterIndex(aFrom);
-	bool isword = false;
-	bool skip = false;
-	if (cindex < (int)mLines[at.mLine].size())
-	{
-		auto& line = mLines[at.mLine];
-		isword = isalnum(line[cindex].mChar);
-		skip = isword;
-	}
-
-	while (!isword || skip)
-	{
-		if (at.mLine >= mLines.size())
-		{
-			auto l = std::max(0, (int) mLines.size() - 1);
-			return Coordinates(l, GetLineMaxColumn(l));
-		}
-
-		auto& line = mLines[at.mLine];
-		if (cindex < (int)line.size())
-		{
-			isword = isalnum(line[cindex].mChar);
-
-			if (isword && !skip)
-				return Coordinates(at.mLine, GetCharacterColumn(at.mLine, cindex));
-
-			if (!isword)
-				skip = false;
-
-			cindex++;
-		}
-		else
-		{
-			cindex = 0;
-			++at.mLine;
-			skip = false;
-			isword = false;
-		}
-	}
-
-	return at;
-}
-
-int TextEditor::GetCharacterIndex(const Coordinates& aCoordinates) const
-{
-	if (aCoordinates.mLine >= mLines.size())
-		return -1;
-	auto& line = mLines[aCoordinates.mLine];
-	int c = 0;
-	int i = 0;
-	for (; i < line.size() && c < aCoordinates.mColumn;)
-	{
-		if (line[i].mChar == '\t')
-			c = (c / mTabSize) * mTabSize + mTabSize;
-		else
-			++c;
-		i += UTF8CharLength(line[i].mChar);
-	}
-	return i;
-}
-
-int TextEditor::GetCharacterColumn(int aLine, int aIndex) const
-{
-	if (aLine >= mLines.size())
-		return 0;
-	auto& line = mLines[aLine];
-	int col = 0;
-	int i = 0;
-	while (i < aIndex && i < (int)line.size())
-	{
-		auto c = line[i].mChar;
-		i += UTF8CharLength(c);
-		if (c == '\t')
-			col = (col / mTabSize) * mTabSize + mTabSize;
-		else
-			col++;
-	}
-	return col;
-}
-
-int TextEditor::GetLineCharacterCount(int aLine) const
-{
-	if (aLine >= mLines.size())
-		return 0;
-	auto& line = mLines[aLine];
-	int c = 0;
-	for (unsigned i = 0; i < line.size(); c++)
-		i += UTF8CharLength(line[i].mChar);
-	return c;
-}
-
-int TextEditor::GetLineMaxColumn(int aLine) const
-{
-	if (aLine >= mLines.size())
-		return 0;
-	auto& line = mLines[aLine];
-	int col = 0;
-	for (unsigned i = 0; i < line.size(); )
-	{
-		auto c = line[i].mChar;
-		if (c == '\t')
-			col = (col / mTabSize) * mTabSize + mTabSize;
-		else
-			col++;
-		i += UTF8CharLength(c);
-	}
-	return col;
-}
-
-bool TextEditor::IsOnWordBoundary(const Coordinates & aAt) const
-{
-	if (aAt.mLine >= (int)mLines.size() || aAt.mColumn == 0)
-		return true;
-
-	auto& line = mLines[aAt.mLine];
-	auto cindex = GetCharacterIndex(aAt);
-	if (cindex >= (int)line.size())
-		return true;
-
-	if (mColorizerEnabled)
-		return line[cindex].mColorIndex != line[size_t(cindex - 1)].mColorIndex;
-
-	return isspace(line[cindex].mChar) != isspace(line[cindex - 1].mChar);
-}
-
-void TextEditor::RemoveLine(int aStart, int aEnd)
-{
-	assert(!mReadOnly);
-	assert(aEnd >= aStart);
-	assert(mLines.size() > (size_t)(aEnd - aStart));
-
-	ErrorMarkers etmp;
-	for (auto& i : mErrorMarkers)
-	{
-		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);
-	}
-	mErrorMarkers = std::move(etmp);
-
-	Breakpoints btmp;
-	for (auto i : mBreakpoints)
-	{
-		if (i >= aStart && i <= aEnd)
-			continue;
-		btmp.insert(i >= aStart ? i - 1 : i);
-	}
-	mBreakpoints = std::move(btmp);
-
-	mLines.erase(mLines.begin() + aStart, mLines.begin() + aEnd);
-	assert(!mLines.empty());
-
-	mTextChanged = true;
-}
-
-void TextEditor::RemoveLine(int aIndex)
-{
-	assert(!mReadOnly);
-	assert(mLines.size() > 1);
-
-	ErrorMarkers etmp;
-	for (auto& i : mErrorMarkers)
-	{
-		ErrorMarkers::value_type e(i.first > aIndex ? i.first - 1 : i.first, i.second);
-		if (e.first - 1 == aIndex)
-			continue;
-		etmp.insert(e);
-	}
-	mErrorMarkers = std::move(etmp);
-
-	Breakpoints btmp;
-	for (auto i : mBreakpoints)
-	{
-		if (i == aIndex)
-			continue;
-		btmp.insert(i >= aIndex ? i - 1 : i);
-	}
-	mBreakpoints = std::move(btmp);
-
-	mLines.erase(mLines.begin() + aIndex);
-	assert(!mLines.empty());
-
-	mTextChanged = true;
-}
-
-TextEditor::Line& TextEditor::InsertLine(int aIndex)
-{
-	assert(!mReadOnly);
-
-	auto& result = *mLines.insert(mLines.begin() + aIndex, Line());
-
-	ErrorMarkers etmp;
-	for (auto& i : mErrorMarkers)
-		etmp.insert(ErrorMarkers::value_type(i.first >= aIndex ? i.first + 1 : i.first, i.second));
-	mErrorMarkers = std::move(etmp);
-
-	Breakpoints btmp;
-	for (auto i : mBreakpoints)
-		btmp.insert(i >= aIndex ? i + 1 : i);
-	mBreakpoints = std::move(btmp);
-
-	return result;
-}
-
-std::string TextEditor::GetWordUnderCursor() const
-{
-	auto c = GetCursorPosition();
-	return GetWordAt(c);
-}
-
-std::string TextEditor::GetWordAt(const Coordinates & aCoords) const
-{
-	auto start = FindWordStart(aCoords);
-	auto end = FindWordEnd(aCoords);
-
-	std::string r;
-
-	auto istart = GetCharacterIndex(start);
-	auto iend = GetCharacterIndex(end);
-
-	for (auto it = istart; it < iend; ++it)
-		r.push_back(mLines[aCoords.mLine][it].mChar);
-
-	return r;
-}
-
-ImU32 TextEditor::GetGlyphColor(const Glyph & aGlyph) const
-{
-	if (!mColorizerEnabled)
-		return mPalette[(int)PaletteIndex::Default];
-	if (aGlyph.mComment)
-		return mPalette[(int)PaletteIndex::Comment];
-	if (aGlyph.mMultiLineComment)
-		return mPalette[(int)PaletteIndex::MultiLineComment];
-	auto const color = mPalette[(int)aGlyph.mColorIndex];
-	if (aGlyph.mPreprocessor)
-	{
-		const auto ppcolor = mPalette[(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;
-}
-
-void TextEditor::HandleKeyboardInputs()
-{
-	ImGuiIO& io = ImGui::GetIO();
-	auto shift = io.KeyShift;
-	auto ctrl = io.ConfigMacOSXBehaviors ? io.KeySuper : io.KeyCtrl;
-	auto alt = io.ConfigMacOSXBehaviors ? io.KeyCtrl : io.KeyAlt;
-
-	if (ImGui::IsWindowFocused())
-	{
-		if (ImGui::IsWindowHovered())
-			ImGui::SetMouseCursor(ImGuiMouseCursor_TextInput);
-		//ImGui::CaptureKeyboardFromApp(true);
-
-		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)))
-			MoveUp(1, shift);
-		else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)))
-			MoveDown(1, shift);
-		else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_LeftArrow)))
-			MoveLeft(1, shift, ctrl);
-		else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_RightArrow)))
-			MoveRight(1, shift, ctrl);
-		else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_PageUp)))
-			MoveUp(GetPageSize() - 4, shift);
-		else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_PageDown)))
-			MoveDown(GetPageSize() - 4, shift);
-		else if (!alt && ctrl && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Home)))
-			MoveTop(shift);
-		else if (ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_End)))
-			MoveBottom(shift);
-		else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Home)))
-			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)))
-			mOverwrite ^= 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)))
-			EnterCharacter('\n', false);
-		else if (!IsReadOnly() && !ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Tab)))
-			EnterCharacter('\t', shift);
-
-		if (!IsReadOnly() && !io.InputQueueCharacters.empty())
-		{
-			for (int i = 0; i < io.InputQueueCharacters.Size; i++)
-			{
-				auto c = io.InputQueueCharacters[i];
-				if (c != 0 && (c == '\n' || c >= 32))
-					EnterCharacter(c, shift);
-			}
-			io.InputQueueCharacters.resize(0);
-		}
-	}
-}
-
-void TextEditor::HandleMouseInputs()
-{
-	ImGuiIO& io = ImGui::GetIO();
-	auto shift = io.KeyShift;
-	auto ctrl = io.ConfigMacOSXBehaviors ? io.KeySuper : io.KeyCtrl;
-	auto alt = io.ConfigMacOSXBehaviors ? io.KeyCtrl : io.KeyAlt;
-
-	if (ImGui::IsWindowHovered())
-	{
-		if (!shift && !alt)
-		{
-			auto click = ImGui::IsMouseClicked(0);
-			auto doubleClick = ImGui::IsMouseDoubleClicked(0);
-			auto t = ImGui::GetTime();
-			auto tripleClick = click && !doubleClick && (mLastClick != -1.0f && (t - mLastClick) < io.MouseDoubleClickTime);
-
-			/*
-			Left mouse button triple click
-			*/
-
-			if (tripleClick)
-			{
-				if (!ctrl)
-				{
-					mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = SanitizeCoordinates(ScreenPosToCoordinates(ImGui::GetMousePos()));
-					mSelectionMode = SelectionMode::Line;
-					SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode);
-				}
-
-				mLastClick = -1.0f;
-			}
-
-			/*
-			Left mouse button double click
-			*/
-
-			else if (doubleClick)
-			{
-				if (!ctrl)
-				{
-					mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = SanitizeCoordinates(ScreenPosToCoordinates(ImGui::GetMousePos()));
-					if (mSelectionMode == SelectionMode::Line)
-						mSelectionMode = SelectionMode::Normal;
-					else
-						mSelectionMode = SelectionMode::Word;
-					SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode);
-				}
-
-				mLastClick = (float)ImGui::GetTime();
-			}
-
-			/*
-			Left mouse button click
-			*/
-			else if (click)
-			{
-				mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = SanitizeCoordinates(ScreenPosToCoordinates(ImGui::GetMousePos()));
-				if (ctrl)
-					mSelectionMode = SelectionMode::Word;
-				else
-					mSelectionMode = SelectionMode::Normal;
-				SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode);
-
-				mLastClick = (float)ImGui::GetTime();
-			}
-			// Mouse left button dragging (=> update selection)
-			else if (ImGui::IsMouseDragging(0) && ImGui::IsMouseDown(0))
-			{
-				io.WantCaptureMouse = true;
-				mState.mCursorPosition = mInteractiveEnd = SanitizeCoordinates(ScreenPosToCoordinates(ImGui::GetMousePos()));
-				SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode);
-			}
-		}
-	}
-}
-
-void TextEditor::Render()
-{
-	/* 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;
-	mCharAdvance = ImVec2(fontSize, ImGui::GetTextLineHeightWithSpacing() * mLineSpacing);
-
-	/* Update palette with the current alpha from style */
-	for (int i = 0; i < (int)PaletteIndex::Max; ++i)
-	{
-		auto color = ImGui::ColorConvertU32ToFloat4(mPaletteBase[i]);
-		color.w *= ImGui::GetStyle().Alpha;
-		mPalette[i] = ImGui::ColorConvertFloat4ToU32(color);
-	}
-
-	assert(mLineBuffer.empty());
-
-	auto contentSize = ImGui::GetWindowContentRegionMax();
-	auto drawList = ImGui::GetWindowDrawList();
-	float longest(mTextStart);
-
-	if (mScrollToTop)
-	{
-		mScrollToTop = false;
-		ImGui::SetScrollY(0.f);
-	}
-
-	ImVec2 cursorScreenPos = ImGui::GetCursorScreenPos();
-	auto scrollX = ImGui::GetScrollX();
-	auto scrollY = ImGui::GetScrollY();
-
-	auto lineNo = (int)floor(scrollY / mCharAdvance.y);
-	auto globalLineMax = (int)mLines.size();
-	auto lineMax = std::max(0, std::min((int)mLines.size() - 1, lineNo + (int)floor((scrollY + contentSize.y) / mCharAdvance.y)));
-
-	// Deduce mTextStart by evaluating mLines size (global lineMax) plus two spaces as text width
-	char buf[16];
-	snprintf(buf, 16, " %d ", globalLineMax);
-	mTextStart = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, buf, nullptr, nullptr).x + mLeftMargin;
-
-	if (!mLines.empty())
-	{
-		float spaceSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, " ", nullptr, nullptr).x;
-
-		while (lineNo <= lineMax)
-		{
-			ImVec2 lineStartScreenPos = ImVec2(cursorScreenPos.x, cursorScreenPos.y + lineNo * mCharAdvance.y);
-			ImVec2 textScreenPos = ImVec2(lineStartScreenPos.x + mTextStart, lineStartScreenPos.y);
-
-			auto& line = mLines[lineNo];
-			longest = std::max(mTextStart + TextDistanceToLineStart(Coordinates(lineNo, GetLineMaxColumn(lineNo))), longest);
-			auto columnNo = 0;
-			Coordinates lineStartCoord(lineNo, 0);
-			Coordinates lineEndCoord(lineNo, GetLineMaxColumn(lineNo));
-
-			// Draw selection for the current line
-			float sstart = -1.0f;
-			float ssend = -1.0f;
-
-			assert(mState.mSelectionStart <= mState.mSelectionEnd);
-			if (mState.mSelectionStart <= lineEndCoord)
-				sstart = mState.mSelectionStart > lineStartCoord ? TextDistanceToLineStart(mState.mSelectionStart) : 0.0f;
-			if (mState.mSelectionEnd > lineStartCoord)
-				ssend = TextDistanceToLineStart(mState.mSelectionEnd < lineEndCoord ? mState.mSelectionEnd : lineEndCoord);
-
-			if (mState.mSelectionEnd.mLine > lineNo)
-				ssend += mCharAdvance.x;
-
-			if (sstart != -1 && ssend != -1 && sstart < ssend)
-			{
-				ImVec2 vstart(lineStartScreenPos.x + mTextStart + sstart, lineStartScreenPos.y);
-				ImVec2 vend(lineStartScreenPos.x + mTextStart + ssend, lineStartScreenPos.y + mCharAdvance.y);
-				drawList->AddRectFilled(vstart, vend, mPalette[(int)PaletteIndex::Selection]);
-			}
-
-			// Draw breakpoints
-			auto start = ImVec2(lineStartScreenPos.x + scrollX, lineStartScreenPos.y);
-
-			if (mBreakpoints.count(lineNo + 1) != 0)
-			{
-				auto end = ImVec2(lineStartScreenPos.x + contentSize.x + 2.0f * scrollX, lineStartScreenPos.y + mCharAdvance.y);
-				drawList->AddRectFilled(start, end, mPalette[(int)PaletteIndex::Breakpoint]);
-			}
-
-			// Draw error markers
-			auto errorIt = mErrorMarkers.find(lineNo + 1);
-			if (errorIt != mErrorMarkers.end())
-			{
-				auto end = ImVec2(lineStartScreenPos.x + contentSize.x + 2.0f * scrollX, lineStartScreenPos.y + mCharAdvance.y);
-				drawList->AddRectFilled(start, end, mPalette[(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 + mTextStart - lineNoWidth, lineStartScreenPos.y), mPalette[(int)PaletteIndex::LineNumber], buf);
-
-			if (mState.mCursorPosition.mLine == lineNo)
-			{
-				auto focused = ImGui::IsWindowFocused();
-
-				// Highlight the current line (where the cursor is)
-				if (!HasSelection())
-				{
-					auto end = ImVec2(start.x + contentSize.x + scrollX, start.y + mCharAdvance.y);
-					drawList->AddRectFilled(start, end, mPalette[(int)(focused ? PaletteIndex::CurrentLineFill : PaletteIndex::CurrentLineFillInactive)]);
-					drawList->AddRect(start, end, mPalette[(int)PaletteIndex::CurrentLineEdge], 1.0f);
-				}
-
-				// Render the cursor
-				if (focused)
-				{
-					auto timeEnd = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
-					auto elapsed = timeEnd - mStartTime;
-					if (elapsed > 400)
-					{
-						float width = 1.0f;
-						auto cindex = GetCharacterIndex(mState.mCursorPosition);
-						float cx = TextDistanceToLineStart(mState.mCursorPosition);
-
-						if (mOverwrite && cindex < (int)line.size())
-						{
-							auto c = line[cindex].mChar;
-							if (c == '\t')
-							{
-								auto x = (1.0f + std::floor((1.0f + cx) / (float(mTabSize) * spaceSize))) * (float(mTabSize) * spaceSize);
-								width = x - cx;
-							}
-							else
-							{
-								char buf[2];
-								buf[0] = line[cindex].mChar;
-								buf[1] = '\0';
-								width = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, buf).x;
-							}
-						}
-						ImVec2 cstart(textScreenPos.x + cx, lineStartScreenPos.y);
-						ImVec2 cend(textScreenPos.x + cx + width, lineStartScreenPos.y + mCharAdvance.y);
-						drawList->AddRectFilled(cstart, cend, mPalette[(int)PaletteIndex::Cursor]);
-						if (elapsed > 800)
-							mStartTime = timeEnd;
-					}
-				}
-			}
-
-			// Render colorized text
-			auto prevColor = line.empty() ? mPalette[(int)PaletteIndex::Default] : GetGlyphColor(line[0]);
-			ImVec2 bufferOffset;
-
-			for (int i = 0; i < line.size();)
-			{
-				auto& glyph = line[i];
-				auto color = GetGlyphColor(glyph);
-
-				if ((color != prevColor || glyph.mChar == '\t' || glyph.mChar == ' ') && !mLineBuffer.empty())
-				{
-					const ImVec2 newOffset(textScreenPos.x + bufferOffset.x, textScreenPos.y + bufferOffset.y);
-					drawList->AddText(newOffset, prevColor, mLineBuffer.c_str());
-					auto textSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, mLineBuffer.c_str(), nullptr, nullptr);
-					bufferOffset.x += textSize.x;
-					mLineBuffer.clear();
-				}
-				prevColor = color;
-
-				if (glyph.mChar == '\t')
-				{
-					auto oldX = bufferOffset.x;
-					bufferOffset.x = (1.0f + std::floor((1.0f + bufferOffset.x) / (float(mTabSize) * spaceSize))) * (float(mTabSize) * spaceSize);
-					++i;
-
-					if (mShowWhitespaces)
-					{
-						const auto s = ImGui::GetFontSize();
-						const auto x1 = textScreenPos.x + oldX + 1.0f;
-						const auto x2 = textScreenPos.x + bufferOffset.x - 1.0f;
-						const auto y = textScreenPos.y + bufferOffset.y + s * 0.5f;
-						const ImVec2 p1(x1, y);
-						const ImVec2 p2(x2, y);
-						const ImVec2 p3(x2 - s * 0.2f, y - s * 0.2f);
-						const ImVec2 p4(x2 - s * 0.2f, y + s * 0.2f);
-						drawList->AddLine(p1, p2, 0x90909090);
-						drawList->AddLine(p2, p3, 0x90909090);
-						drawList->AddLine(p2, p4, 0x90909090);
-					}
-				}
-				else if (glyph.mChar == ' ')
-				{
-					if (mShowWhitespaces)
-					{
-						const auto s = ImGui::GetFontSize();
-						const auto x = textScreenPos.x + bufferOffset.x + spaceSize * 0.5f;
-						const auto y = textScreenPos.y + bufferOffset.y + s * 0.5f;
-						drawList->AddCircleFilled(ImVec2(x, y), 1.5f, 0x80808080, 4);
-					}
-					bufferOffset.x += spaceSize;
-					i++;
-				}
-				else
-				{
-					auto l = UTF8CharLength(glyph.mChar);
-					while (l-- > 0)
-						mLineBuffer.push_back(line[i++].mChar);
-				}
-				++columnNo;
-			}
-
-			if (!mLineBuffer.empty())
-			{
-				const ImVec2 newOffset(textScreenPos.x + bufferOffset.x, textScreenPos.y + bufferOffset.y);
-				drawList->AddText(newOffset, prevColor, mLineBuffer.c_str());
-				mLineBuffer.clear();
-			}
-
-			++lineNo;
-		}
-
-		// Draw a tooltip on known identifiers/preprocessor symbols
-		if (ImGui::IsMousePosValid())
-		{
-			auto id = GetWordAt(ScreenPosToCoordinates(ImGui::GetMousePos()));
-			if (!id.empty())
-			{
-				auto it = mLanguageDefinition.mIdentifiers.find(id);
-				if (it != mLanguageDefinition.mIdentifiers.end())
-				{
-					ImGui::BeginTooltip();
-					ImGui::TextUnformatted(it->second.mDeclaration.c_str());
-					ImGui::EndTooltip();
-				}
-				else
-				{
-					auto pi = mLanguageDefinition.mPreprocIdentifiers.find(id);
-					if (pi != mLanguageDefinition.mPreprocIdentifiers.end())
-					{
-						ImGui::BeginTooltip();
-						ImGui::TextUnformatted(pi->second.mDeclaration.c_str());
-						ImGui::EndTooltip();
-					}
-				}
-			}
-		}
-	}
-
-
-	ImGui::Dummy(ImVec2((longest + 2), mLines.size() * mCharAdvance.y));
-
-	if (mScrollToCursor)
-	{
-		EnsureCursorVisible();
-		ImGui::SetWindowFocus();
-		mScrollToCursor = false;
-	}
-}
-
-void TextEditor::Render(const char* aTitle, const ImVec2& aSize, bool aBorder)
-{
-	mWithinRender = true;
-	mTextChanged = false;
-	mCursorPositionChanged = false;
-
-	ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, ImGui::ColorConvertU32ToFloat4(mPalette[(int)PaletteIndex::Background]));
-	ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
-	if (!mIgnoreImGuiChild)
-		ImGui::BeginChild(aTitle, aSize, aBorder, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NoMove);
-
-	if (mHandleKeyboardInputs)
-	{
-		HandleKeyboardInputs();
-		ImGui::PushAllowKeyboardFocus(true);
-	}
-
-	if (mHandleMouseInputs)
-		HandleMouseInputs();
-
-	ColorizeInternal();
-	Render();
-
-	if (mHandleKeyboardInputs)
-		ImGui::PopAllowKeyboardFocus();
-
-	if (!mIgnoreImGuiChild)
-		ImGui::EndChild();
-
-	ImGui::PopStyleVar();
-	ImGui::PopStyleColor();
-
-	mWithinRender = false;
-}
-
-void TextEditor::SetText(const std::string & aText)
-{
-	mLines.clear();
-	mLines.emplace_back(Line());
-	for (auto chr : aText)
-	{
-		if (chr == '\r')
-		{
-			// ignore the carriage return character
-		}
-		else if (chr == '\n')
-			mLines.emplace_back(Line());
-		else
-		{
-			mLines.back().emplace_back(Glyph(chr, PaletteIndex::Default));
-		}
-	}
-
-	mTextChanged = true;
-	mScrollToTop = true;
-
-	mUndoBuffer.clear();
-	mUndoIndex = 0;
-
-	Colorize();
-}
-
-void TextEditor::SetTextLines(const std::vector<std::string> & aLines)
-{
-	mLines.clear();
-
-	if (aLines.empty())
-	{
-		mLines.emplace_back(Line());
-	}
-	else
-	{
-		mLines.resize(aLines.size());
-
-		for (size_t i = 0; i < aLines.size(); ++i)
-		{
-			const std::string & aLine = aLines[i];
-
-			mLines[i].reserve(aLine.size());
-			for (size_t j = 0; j < aLine.size(); ++j)
-				mLines[i].emplace_back(Glyph(aLine[j], PaletteIndex::Default));
-		}
-	}
-
-	mTextChanged = true;
-	mScrollToTop = true;
-
-	mUndoBuffer.clear();
-	mUndoIndex = 0;
-
-	Colorize();
-}
-
-void TextEditor::EnterCharacter(ImWchar aChar, bool aShift)
-{
-	assert(!mReadOnly);
-
-	UndoRecord u;
-
-	u.mBefore = mState;
-
-	if (HasSelection())
-	{
-		if (aChar == '\t' && mState.mSelectionStart.mLine != mState.mSelectionEnd.mLine)
-		{
-
-			auto start = mState.mSelectionStart;
-			auto end = mState.mSelectionEnd;
-			auto originalEnd = end;
-
-			if (start > end)
-				std::swap(start, end);
-			start.mColumn = 0;
-			//			end.mColumn = end.mLine < mLines.size() ? mLines[end.mLine].size() : 0;
-			if (end.mColumn == 0 && end.mLine > 0)
-				--end.mLine;
-			if (end.mLine >= (int)mLines.size())
-				end.mLine = mLines.empty() ? 0 : (int)mLines.size() - 1;
-			end.mColumn = GetLineMaxColumn(end.mLine);
-
-			//if (end.mColumn >= GetLineMaxColumn(end.mLine))
-			//	end.mColumn = GetLineMaxColumn(end.mLine) - 1;
-
-			u.mRemovedStart = start;
-			u.mRemovedEnd = end;
-			u.mRemoved = GetText(start, end);
-
-			bool modified = false;
-
-			for (int i = start.mLine; i <= end.mLine; i++)
-			{
-				auto& line = mLines[i];
-				if (aShift)
-				{
-					if (!line.empty())
-					{
-						if (line.front().mChar == '\t')
-						{
-							line.erase(line.begin());
-							modified = true;
-						}
-						else
-						{
-							for (int j = 0; j < mTabSize && !line.empty() && line.front().mChar == ' '; j++)
-							{
-								line.erase(line.begin());
-								modified = true;
-							}
-						}
-					}
-				}
-				else
-				{
-					line.insert(line.begin(), Glyph('\t', TextEditor::PaletteIndex::Background));
-					modified = true;
-				}
-			}
-
-			if (modified)
-			{
-				start = Coordinates(start.mLine, GetCharacterColumn(start.mLine, 0));
-				Coordinates rangeEnd;
-				if (originalEnd.mColumn != 0)
-				{
-					end = Coordinates(end.mLine, GetLineMaxColumn(end.mLine));
-					rangeEnd = end;
-					u.mAdded = GetText(start, end);
-				}
-				else
-				{
-					end = Coordinates(originalEnd.mLine, 0);
-					rangeEnd = Coordinates(end.mLine - 1, GetLineMaxColumn(end.mLine - 1));
-					u.mAdded = GetText(start, rangeEnd);
-				}
-
-				u.mAddedStart = start;
-				u.mAddedEnd = rangeEnd;
-				u.mAfter = mState;
-
-				mState.mSelectionStart = start;
-				mState.mSelectionEnd = end;
-				AddUndo(u);
-
-				mTextChanged = true;
-
-				EnsureCursorVisible();
-			}
-
-			return;
-		} // c == '\t'
-		else
-		{
-			u.mRemoved = GetSelectedText();
-			u.mRemovedStart = mState.mSelectionStart;
-			u.mRemovedEnd = mState.mSelectionEnd;
-			DeleteSelection();
-		}
-	} // HasSelection
-
-	auto coord = GetActualCursorCoordinates();
-	u.mAddedStart = coord;
-
-	assert(!mLines.empty());
-
-	if (aChar == '\n')
-	{
-		InsertLine(coord.mLine + 1);
-		auto& line = mLines[coord.mLine];
-		auto& newLine = mLines[coord.mLine + 1];
-
-		if (mLanguageDefinition.mAutoIndentation)
-			for (size_t it = 0; it < line.size() && isascii(line[it].mChar) && isblank(line[it].mChar); ++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.mLine + 1, GetCharacterColumn(coord.mLine + 1, (int)whitespaceSize)));
-		u.mAdded = (char)aChar;
-	}
-	else
-	{
-		char buf[7];
-		int e = ImTextCharToUtf8(buf, 7, aChar);
-		if (e > 0)
-		{
-			buf[e] = '\0';
-			auto& line = mLines[coord.mLine];
-			auto cindex = GetCharacterIndex(coord);
-
-			if (mOverwrite && cindex < (int)line.size())
-			{
-				auto d = UTF8CharLength(line[cindex].mChar);
-
-				u.mRemovedStart = mState.mCursorPosition;
-				u.mRemovedEnd = Coordinates(coord.mLine, GetCharacterColumn(coord.mLine, cindex + d));
-
-				while (d-- > 0 && cindex < (int)line.size())
-				{
-					u.mRemoved += line[cindex].mChar;
-					line.erase(line.begin() + cindex);
-				}
-			}
-
-			for (auto p = buf; *p != '\0'; p++, ++cindex)
-				line.insert(line.begin() + cindex, Glyph(*p, PaletteIndex::Default));
-			u.mAdded = buf;
-
-			SetCursorPosition(Coordinates(coord.mLine, GetCharacterColumn(coord.mLine, cindex)));
-		}
-		else
-			return;
-	}
-
-	mTextChanged = true;
-
-	u.mAddedEnd = GetActualCursorCoordinates();
-	u.mAfter = mState;
-
-	AddUndo(u);
-
-	Colorize(coord.mLine - 1, 3);
-	EnsureCursorVisible();
-}
-
-void TextEditor::SetReadOnly(bool aValue)
-{
-	mReadOnly = aValue;
-}
-
-void TextEditor::SetColorizerEnable(bool aValue)
-{
-	mColorizerEnabled = aValue;
-}
-
-void TextEditor::SetCursorPosition(const Coordinates & aPosition)
-{
-	if (mState.mCursorPosition != aPosition)
-	{
-		mState.mCursorPosition = aPosition;
-		mCursorPositionChanged = true;
-		EnsureCursorVisible();
-	}
-}
-
-void TextEditor::SetSelectionStart(const Coordinates & aPosition)
-{
-	mState.mSelectionStart = SanitizeCoordinates(aPosition);
-	if (mState.mSelectionStart > mState.mSelectionEnd)
-		std::swap(mState.mSelectionStart, mState.mSelectionEnd);
-}
-
-void TextEditor::SetSelectionEnd(const Coordinates & aPosition)
-{
-	mState.mSelectionEnd = SanitizeCoordinates(aPosition);
-	if (mState.mSelectionStart > mState.mSelectionEnd)
-		std::swap(mState.mSelectionStart, mState.mSelectionEnd);
-}
-
-void TextEditor::SetSelection(const Coordinates & aStart, const Coordinates & aEnd, SelectionMode aMode)
-{
-	auto oldSelStart = mState.mSelectionStart;
-	auto oldSelEnd = mState.mSelectionEnd;
-
-	mState.mSelectionStart = SanitizeCoordinates(aStart);
-	mState.mSelectionEnd = SanitizeCoordinates(aEnd);
-	if (mState.mSelectionStart > mState.mSelectionEnd)
-		std::swap(mState.mSelectionStart, mState.mSelectionEnd);
-
-	switch (aMode)
-	{
-	case TextEditor::SelectionMode::Normal:
-		break;
-	case TextEditor::SelectionMode::Word:
-	{
-		mState.mSelectionStart = FindWordStart(mState.mSelectionStart);
-		if (!IsOnWordBoundary(mState.mSelectionEnd))
-			mState.mSelectionEnd = FindWordEnd(FindWordStart(mState.mSelectionEnd));
-		break;
-	}
-	case TextEditor::SelectionMode::Line:
-	{
-		const auto lineNo = mState.mSelectionEnd.mLine;
-		const auto lineSize = (size_t)lineNo < mLines.size() ? mLines[lineNo].size() : 0;
-		mState.mSelectionStart = Coordinates(mState.mSelectionStart.mLine, 0);
-		mState.mSelectionEnd = Coordinates(lineNo, GetLineMaxColumn(lineNo));
-		break;
-	}
-	default:
-		break;
-	}
-
-	if (mState.mSelectionStart != oldSelStart ||
-		mState.mSelectionEnd != oldSelEnd)
-		mCursorPositionChanged = true;
-}
-
-void TextEditor::SetTabSize(int aValue)
-{
-	mTabSize = std::max(0, std::min(32, aValue));
-}
-
-void TextEditor::InsertText(const std::string & aValue)
-{
-	InsertText(aValue.c_str());
-}
-
-void TextEditor::InsertText(const char * aValue)
-{
-	if (aValue == nullptr)
-		return;
-
-	auto pos = GetActualCursorCoordinates();
-	auto start = std::min(pos, mState.mSelectionStart);
-	int totalLines = pos.mLine - start.mLine;
-
-	totalLines += InsertTextAt(pos, aValue);
-
-	SetSelection(pos, pos);
-	SetCursorPosition(pos);
-	Colorize(start.mLine - 1, totalLines + 2);
-}
-
-void TextEditor::DeleteSelection()
-{
-	assert(mState.mSelectionEnd >= mState.mSelectionStart);
-
-	if (mState.mSelectionEnd == mState.mSelectionStart)
-		return;
-
-	DeleteRange(mState.mSelectionStart, mState.mSelectionEnd);
-
-	SetSelection(mState.mSelectionStart, mState.mSelectionStart);
-	SetCursorPosition(mState.mSelectionStart);
-	Colorize(mState.mSelectionStart.mLine, 1);
-}
-
-void TextEditor::MoveUp(int aAmount, bool aSelect)
-{
-	auto oldPos = mState.mCursorPosition;
-	mState.mCursorPosition.mLine = std::max(0, mState.mCursorPosition.mLine - aAmount);
-	if (oldPos != mState.mCursorPosition)
-	{
-		if (aSelect)
-		{
-			if (oldPos == mInteractiveStart)
-				mInteractiveStart = mState.mCursorPosition;
-			else if (oldPos == mInteractiveEnd)
-				mInteractiveEnd = mState.mCursorPosition;
-			else
-			{
-				mInteractiveStart = mState.mCursorPosition;
-				mInteractiveEnd = oldPos;
-			}
-		}
-		else
-			mInteractiveStart = mInteractiveEnd = mState.mCursorPosition;
-		SetSelection(mInteractiveStart, mInteractiveEnd);
-
-		EnsureCursorVisible();
-	}
-}
-
-void TextEditor::MoveDown(int aAmount, bool aSelect)
-{
-	assert(mState.mCursorPosition.mColumn >= 0);
-	auto oldPos = mState.mCursorPosition;
-	mState.mCursorPosition.mLine = std::max(0, std::min((int)mLines.size() - 1, mState.mCursorPosition.mLine + aAmount));
-
-	if (mState.mCursorPosition != oldPos)
-	{
-		if (aSelect)
-		{
-			if (oldPos == mInteractiveEnd)
-				mInteractiveEnd = mState.mCursorPosition;
-			else if (oldPos == mInteractiveStart)
-				mInteractiveStart = mState.mCursorPosition;
-			else
-			{
-				mInteractiveStart = oldPos;
-				mInteractiveEnd = mState.mCursorPosition;
-			}
-		}
-		else
-			mInteractiveStart = mInteractiveEnd = mState.mCursorPosition;
-		SetSelection(mInteractiveStart, mInteractiveEnd);
-
-		EnsureCursorVisible();
-	}
-}
-
-static bool IsUTFSequence(char c)
-{
-	return (c & 0xC0) == 0x80;
-}
-
-void TextEditor::MoveLeft(int aAmount, bool aSelect, bool aWordMode)
-{
-	if (mLines.empty())
-		return;
-
-	auto oldPos = mState.mCursorPosition;
-	mState.mCursorPosition = GetActualCursorCoordinates();
-	auto line = mState.mCursorPosition.mLine;
-	auto cindex = GetCharacterIndex(mState.mCursorPosition);
-
-	while (aAmount-- > 0)
-	{
-		if (cindex == 0)
-		{
-			if (line > 0)
-			{
-				--line;
-				if ((int)mLines.size() > line)
-					cindex = (int)mLines[line].size();
-				else
-					cindex = 0;
-			}
-		}
-		else
-		{
-			--cindex;
-			if (cindex > 0)
-			{
-				if ((int)mLines.size() > line)
-				{
-					while (cindex > 0 && IsUTFSequence(mLines[line][cindex].mChar))
-						--cindex;
-				}
-			}
-		}
-
-		mState.mCursorPosition = Coordinates(line, GetCharacterColumn(line, cindex));
-		if (aWordMode)
-		{
-			mState.mCursorPosition = FindWordStart(mState.mCursorPosition);
-			cindex = GetCharacterIndex(mState.mCursorPosition);
-		}
-	}
-
-	mState.mCursorPosition = Coordinates(line, GetCharacterColumn(line, cindex));
-
-	assert(mState.mCursorPosition.mColumn >= 0);
-	if (aSelect)
-	{
-		if (oldPos == mInteractiveStart)
-			mInteractiveStart = mState.mCursorPosition;
-		else if (oldPos == mInteractiveEnd)
-			mInteractiveEnd = mState.mCursorPosition;
-		else
-		{
-			mInteractiveStart = mState.mCursorPosition;
-			mInteractiveEnd = oldPos;
-		}
-	}
-	else
-		mInteractiveStart = mInteractiveEnd = mState.mCursorPosition;
-	SetSelection(mInteractiveStart, mInteractiveEnd, aSelect && aWordMode ? SelectionMode::Word : SelectionMode::Normal);
-
-	EnsureCursorVisible();
-}
-
-void TextEditor::MoveRight(int aAmount, bool aSelect, bool aWordMode)
-{
-	auto oldPos = mState.mCursorPosition;
-
-	if (mLines.empty() || oldPos.mLine >= mLines.size())
-		return;
-
-	auto cindex = GetCharacterIndex(mState.mCursorPosition);
-	while (aAmount-- > 0)
-	{
-		auto lindex = mState.mCursorPosition.mLine;
-		auto& line = mLines[lindex];
-
-		if (cindex >= line.size())
-		{
-			if (mState.mCursorPosition.mLine < mLines.size() - 1)
-			{
-				mState.mCursorPosition.mLine = std::max(0, std::min((int)mLines.size() - 1, mState.mCursorPosition.mLine + 1));
-				mState.mCursorPosition.mColumn = 0;
-			}
-			else
-				return;
-		}
-		else
-		{
-			cindex += UTF8CharLength(line[cindex].mChar);
-			mState.mCursorPosition = Coordinates(lindex, GetCharacterColumn(lindex, cindex));
-			if (aWordMode)
-				mState.mCursorPosition = FindNextWord(mState.mCursorPosition);
-		}
-	}
-
-	if (aSelect)
-	{
-		if (oldPos == mInteractiveEnd)
-			mInteractiveEnd = SanitizeCoordinates(mState.mCursorPosition);
-		else if (oldPos == mInteractiveStart)
-			mInteractiveStart = mState.mCursorPosition;
-		else
-		{
-			mInteractiveStart = oldPos;
-			mInteractiveEnd = mState.mCursorPosition;
-		}
-	}
-	else
-		mInteractiveStart = mInteractiveEnd = mState.mCursorPosition;
-	SetSelection(mInteractiveStart, mInteractiveEnd, aSelect && aWordMode ? SelectionMode::Word : SelectionMode::Normal);
-
-	EnsureCursorVisible();
-}
-
-void TextEditor::MoveTop(bool aSelect)
-{
-	auto oldPos = mState.mCursorPosition;
-	SetCursorPosition(Coordinates(0, 0));
-
-	if (mState.mCursorPosition != oldPos)
-	{
-		if (aSelect)
-		{
-			mInteractiveEnd = oldPos;
-			mInteractiveStart = mState.mCursorPosition;
-		}
-		else
-			mInteractiveStart = mInteractiveEnd = mState.mCursorPosition;
-		SetSelection(mInteractiveStart, mInteractiveEnd);
-	}
-}
-
-void TextEditor::TextEditor::MoveBottom(bool aSelect)
-{
-	auto oldPos = GetCursorPosition();
-	auto newPos = Coordinates((int)mLines.size() - 1, 0);
-	SetCursorPosition(newPos);
-	if (aSelect)
-	{
-		mInteractiveStart = oldPos;
-		mInteractiveEnd = newPos;
-	}
-	else
-		mInteractiveStart = mInteractiveEnd = newPos;
-	SetSelection(mInteractiveStart, mInteractiveEnd);
-}
-
-void TextEditor::MoveHome(bool aSelect)
-{
-	auto oldPos = mState.mCursorPosition;
-	SetCursorPosition(Coordinates(mState.mCursorPosition.mLine, 0));
-
-	if (mState.mCursorPosition != oldPos)
-	{
-		if (aSelect)
-		{
-			if (oldPos == mInteractiveStart)
-				mInteractiveStart = mState.mCursorPosition;
-			else if (oldPos == mInteractiveEnd)
-				mInteractiveEnd = mState.mCursorPosition;
-			else
-			{
-				mInteractiveStart = mState.mCursorPosition;
-				mInteractiveEnd = oldPos;
-			}
-		}
-		else
-			mInteractiveStart = mInteractiveEnd = mState.mCursorPosition;
-		SetSelection(mInteractiveStart, mInteractiveEnd);
-	}
-}
-
-void TextEditor::MoveEnd(bool aSelect)
-{
-	auto oldPos = mState.mCursorPosition;
-	SetCursorPosition(Coordinates(mState.mCursorPosition.mLine, GetLineMaxColumn(oldPos.mLine)));
-
-	if (mState.mCursorPosition != oldPos)
-	{
-		if (aSelect)
-		{
-			if (oldPos == mInteractiveEnd)
-				mInteractiveEnd = mState.mCursorPosition;
-			else if (oldPos == mInteractiveStart)
-				mInteractiveStart = mState.mCursorPosition;
-			else
-			{
-				mInteractiveStart = oldPos;
-				mInteractiveEnd = mState.mCursorPosition;
-			}
-		}
-		else
-			mInteractiveStart = mInteractiveEnd = mState.mCursorPosition;
-		SetSelection(mInteractiveStart, mInteractiveEnd);
-	}
-}
-
-void TextEditor::Delete()
-{
-	assert(!mReadOnly);
-
-	if (mLines.empty())
-		return;
-
-	UndoRecord u;
-	u.mBefore = mState;
-
-	if (HasSelection())
-	{
-		u.mRemoved = GetSelectedText();
-		u.mRemovedStart = mState.mSelectionStart;
-		u.mRemovedEnd = mState.mSelectionEnd;
-
-		DeleteSelection();
-	}
-	else
-	{
-		auto pos = GetActualCursorCoordinates();
-		SetCursorPosition(pos);
-		auto& line = mLines[pos.mLine];
-
-		if (pos.mColumn == GetLineMaxColumn(pos.mLine))
-		{
-			if (pos.mLine == (int)mLines.size() - 1)
-				return;
-
-			u.mRemoved = '\n';
-			u.mRemovedStart = u.mRemovedEnd = GetActualCursorCoordinates();
-			Advance(u.mRemovedEnd);
-
-			auto& nextLine = mLines[pos.mLine + 1];
-			line.insert(line.end(), nextLine.begin(), nextLine.end());
-			RemoveLine(pos.mLine + 1);
-		}
-		else
-		{
-			auto cindex = GetCharacterIndex(pos);
-			u.mRemovedStart = u.mRemovedEnd = GetActualCursorCoordinates();
-			u.mRemovedEnd.mColumn++;
-			u.mRemoved = GetText(u.mRemovedStart, u.mRemovedEnd);
-
-			auto d = UTF8CharLength(line[cindex].mChar);
-			while (d-- > 0 && cindex < (int)line.size())
-				line.erase(line.begin() + cindex);
-		}
-
-		mTextChanged = true;
-
-		Colorize(pos.mLine, 1);
-	}
-
-	u.mAfter = mState;
-	AddUndo(u);
-}
-
-void TextEditor::Backspace()
-{
-	assert(!mReadOnly);
-
-	if (mLines.empty())
-		return;
-
-	UndoRecord u;
-	u.mBefore = mState;
-
-	if (HasSelection())
-	{
-		u.mRemoved = GetSelectedText();
-		u.mRemovedStart = mState.mSelectionStart;
-		u.mRemovedEnd = mState.mSelectionEnd;
-
-		DeleteSelection();
-	}
-	else
-	{
-		auto pos = GetActualCursorCoordinates();
-		SetCursorPosition(pos);
-
-		if (mState.mCursorPosition.mColumn == 0)
-		{
-			if (mState.mCursorPosition.mLine == 0)
-				return;
-
-			u.mRemoved = '\n';
-			u.mRemovedStart = u.mRemovedEnd = Coordinates(pos.mLine - 1, GetLineMaxColumn(pos.mLine - 1));
-			Advance(u.mRemovedEnd);
-
-			auto& line = mLines[mState.mCursorPosition.mLine];
-			auto& prevLine = mLines[mState.mCursorPosition.mLine - 1];
-			auto prevSize = GetLineMaxColumn(mState.mCursorPosition.mLine - 1);
-			prevLine.insert(prevLine.end(), line.begin(), line.end());
-
-			ErrorMarkers etmp;
-			for (auto& i : mErrorMarkers)
-				etmp.insert(ErrorMarkers::value_type(i.first - 1 == mState.mCursorPosition.mLine ? i.first - 1 : i.first, i.second));
-			mErrorMarkers = std::move(etmp);
-
-			RemoveLine(mState.mCursorPosition.mLine);
-			--mState.mCursorPosition.mLine;
-			mState.mCursorPosition.mColumn = prevSize;
-		}
-		else
-		{
-			auto& line = mLines[mState.mCursorPosition.mLine];
-			auto cindex = GetCharacterIndex(pos) - 1;
-			auto cend = cindex + 1;
-			while (cindex > 0 && IsUTFSequence(line[cindex].mChar))
-				--cindex;
-
-			//if (cindex > 0 && UTF8CharLength(line[cindex].mChar) > 1)
-			//	--cindex;
-
-			u.mRemovedStart = u.mRemovedEnd = GetActualCursorCoordinates();
-			--u.mRemovedStart.mColumn;
-			--mState.mCursorPosition.mColumn;
-
-			while (cindex < line.size() && cend-- > cindex)
-			{
-				u.mRemoved += line[cindex].mChar;
-				line.erase(line.begin() + cindex);
-			}
-		}
-
-		mTextChanged = true;
-
-		EnsureCursorVisible();
-		Colorize(mState.mCursorPosition.mLine, 1);
-	}
-
-	u.mAfter = mState;
-	AddUndo(u);
-}
-
-void TextEditor::SelectWordUnderCursor()
-{
-	auto c = GetCursorPosition();
-	SetSelection(FindWordStart(c), FindWordEnd(c));
-}
-
-void TextEditor::SelectAll()
-{
-	SetSelection(Coordinates(0, 0), Coordinates((int)mLines.size(), 0));
-}
-
-bool TextEditor::HasSelection() const
-{
-	return mState.mSelectionEnd > mState.mSelectionStart;
-}
-
-void TextEditor::Copy()
-{
-	if (HasSelection())
-	{
-		ImGui::SetClipboardText(GetSelectedText().c_str());
-	}
-	else
-	{
-		if (!mLines.empty())
-		{
-			std::string str;
-			auto& line = mLines[GetActualCursorCoordinates().mLine];
-			for (auto& g : line)
-				str.push_back(g.mChar);
-			ImGui::SetClipboardText(str.c_str());
-		}
-	}
-}
-
-void TextEditor::Cut()
-{
-	if (IsReadOnly())
-	{
-		Copy();
-	}
-	else
-	{
-		if (HasSelection())
-		{
-			UndoRecord u;
-			u.mBefore = mState;
-			u.mRemoved = GetSelectedText();
-			u.mRemovedStart = mState.mSelectionStart;
-			u.mRemovedEnd = mState.mSelectionEnd;
-
-			Copy();
-			DeleteSelection();
-
-			u.mAfter = mState;
-			AddUndo(u);
-		}
-	}
-}
-
-void TextEditor::Paste()
-{
-	if (IsReadOnly())
-		return;
-
-	auto clipText = ImGui::GetClipboardText();
-	if (clipText != nullptr && strlen(clipText) > 0)
-	{
-		UndoRecord u;
-		u.mBefore = mState;
-
-		if (HasSelection())
-		{
-			u.mRemoved = GetSelectedText();
-			u.mRemovedStart = mState.mSelectionStart;
-			u.mRemovedEnd = mState.mSelectionEnd;
-			DeleteSelection();
-		}
-
-		u.mAdded = clipText;
-		u.mAddedStart = GetActualCursorCoordinates();
-
-		InsertText(clipText);
-
-		u.mAddedEnd = GetActualCursorCoordinates();
-		u.mAfter = mState;
-		AddUndo(u);
-	}
-}
-
-bool TextEditor::CanUndo() const
-{
-	return !mReadOnly && mUndoIndex > 0;
-}
-
-bool TextEditor::CanRedo() const
-{
-	return !mReadOnly && mUndoIndex < (int)mUndoBuffer.size();
-}
-
-void TextEditor::Undo(int aSteps)
-{
-	while (CanUndo() && aSteps-- > 0)
-		mUndoBuffer[--mUndoIndex].Undo(this);
-}
-
-void TextEditor::Redo(int aSteps)
-{
-	while (CanRedo() && aSteps-- > 0)
-		mUndoBuffer[mUndoIndex++].Redo(this);
-}
-
-const TextEditor::Palette & TextEditor::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 TextEditor::Palette & TextEditor::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 TextEditor::Palette & TextEditor::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 TextEditor::GetText() const
-{
-	return GetText(Coordinates(), Coordinates((int)mLines.size(), 0));
-}
-
-std::vector<std::string> TextEditor::GetTextLines() const
-{
-	std::vector<std::string> result;
-
-	result.reserve(mLines.size());
-
-	for (auto & line : mLines)
-	{
-		std::string text;
-
-		text.resize(line.size());
-
-		for (size_t i = 0; i < line.size(); ++i)
-			text[i] = line[i].mChar;
-
-		result.emplace_back(std::move(text));
-	}
-
-	return result;
-}
-
-std::string TextEditor::GetSelectedText() const
-{
-	return GetText(mState.mSelectionStart, mState.mSelectionEnd);
-}
-
-std::string TextEditor::GetCurrentLineText()const
-{
-	auto lineLength = GetLineMaxColumn(mState.mCursorPosition.mLine);
-	return GetText(
-		Coordinates(mState.mCursorPosition.mLine, 0),
-		Coordinates(mState.mCursorPosition.mLine, lineLength));
-}
-
-void TextEditor::ProcessInputs()
-{
-}
-
-void TextEditor::Colorize(int aFromLine, int aLines)
-{
-	int toLine = aLines == -1 ? (int)mLines.size() : std::min((int)mLines.size(), aFromLine + aLines);
-	mColorRangeMin = std::min(mColorRangeMin, aFromLine);
-	mColorRangeMax = std::max(mColorRangeMax, toLine);
-	mColorRangeMin = std::max(0, mColorRangeMin);
-	mColorRangeMax = std::max(mColorRangeMin, mColorRangeMax);
-	mCheckComments = true;
-}
-
-void TextEditor::ColorizeRange(int aFromLine, int aToLine)
-{
-	if (mLines.empty() || aFromLine >= aToLine)
-		return;
-
-	std::string buffer;
-	std::cmatch results;
-	std::string id;
-
-	int endLine = std::max(0, std::min((int)mLines.size(), aToLine));
-	for (int i = aFromLine; i < endLine; ++i)
-	{
-		auto& line = mLines[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.mChar;
-			col.mColorIndex = 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 (mLanguageDefinition.mTokenize != nullptr)
-			{
-				if (mLanguageDefinition.mTokenize(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 : mRegexList)
-				{
-					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 (!mLanguageDefinition.mCaseSensitive)
-						std::transform(id.begin(), id.end(), id.begin(), ::toupper);
-
-					if (!line[first - bufferBegin].mPreprocessor)
-					{
-						if (mLanguageDefinition.mKeywords.count(id) != 0)
-							token_color = PaletteIndex::Keyword;
-						else if (mLanguageDefinition.mIdentifiers.count(id) != 0)
-							token_color = PaletteIndex::KnownIdentifier;
-						else if (mLanguageDefinition.mPreprocIdentifiers.count(id) != 0)
-							token_color = PaletteIndex::PreprocIdentifier;
-					}
-					else
-					{
-						if (mLanguageDefinition.mPreprocIdentifiers.count(id) != 0)
-							token_color = PaletteIndex::PreprocIdentifier;
-					}
-				}
-
-				for (size_t j = 0; j < token_length; ++j)
-					line[(token_begin - bufferBegin) + j].mColorIndex = token_color;
-
-				first = token_end;
-			}
-		}
-	}
-}
-
-void TextEditor::ColorizeInternal()
-{
-	if (mLines.empty() || !mColorizerEnabled)
-		return;
-
-	if (mCheckComments)
-	{
-		auto endLine = mLines.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 = mLines[currentLine];
-
-			if (currentIndex == 0 && !concatenate)
-			{
-				withinSingleLineComment = false;
-				withinPreproc = false;
-				firstChar = true;
-			}
-
-			concatenate = false;
-
-			if (!line.empty())
-			{
-				auto& g = line[currentIndex];
-				auto c = g.mChar;
-
-				if (c != mLanguageDefinition.mPreprocChar && !isspace(c))
-					firstChar = false;
-
-				if (currentIndex == (int)line.size() - 1 && line[line.size() - 1].mChar == '\\')
-					concatenate = true;
-
-				bool inComment = (commentStartLine < currentLine || (commentStartLine == currentLine && commentStartIndex <= currentIndex));
-
-				if (withinString)
-				{
-					line[currentIndex].mMultiLineComment = inComment;
-
-					if (c == '\"')
-					{
-						if (currentIndex + 1 < (int)line.size() && line[currentIndex + 1].mChar == '\"')
-						{
-							currentIndex += 1;
-							if (currentIndex < (int)line.size())
-								line[currentIndex].mMultiLineComment = inComment;
-						}
-						else
-							withinString = false;
-					}
-					else if (c == '\\')
-					{
-						currentIndex += 1;
-						if (currentIndex < (int)line.size())
-							line[currentIndex].mMultiLineComment = inComment;
-					}
-				}
-				else
-				{
-					if (firstChar && c == mLanguageDefinition.mPreprocChar)
-						withinPreproc = true;
-
-					if (c == '\"')
-					{
-						withinString = true;
-						line[currentIndex].mMultiLineComment = inComment;
-					}
-					else
-					{
-						auto pred = [](const char& a, const Glyph& b) { return a == b.mChar; };
-						auto from = line.begin() + currentIndex;
-						auto& startStr = mLanguageDefinition.mCommentStart;
-						auto& singleStartStr = mLanguageDefinition.mSingleLineComment;
-
-						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].mMultiLineComment = inComment;
-						line[currentIndex].mComment = withinSingleLineComment;
-
-						auto& endStr = mLanguageDefinition.mCommentEnd;
-						if (currentIndex + 1 >= (int)endStr.size() &&
-							equals(endStr.begin(), endStr.end(), from + 1 - endStr.size(), from + 1, pred))
-						{
-							commentStartIndex = endIndex;
-							commentStartLine = endLine;
-						}
-					}
-				}
-				line[currentIndex].mPreprocessor = withinPreproc;
-				currentIndex += UTF8CharLength(c);
-				if (currentIndex >= (int)line.size())
-				{
-					currentIndex = 0;
-					++currentLine;
-				}
-			}
-			else
-			{
-				currentIndex = 0;
-				++currentLine;
-			}
-		}
-		mCheckComments = false;
-	}
-
-	if (mColorRangeMin < mColorRangeMax)
-	{
-		const int increment = (mLanguageDefinition.mTokenize == nullptr) ? 10 : 10000;
-		const int to = std::min(mColorRangeMin + increment, mColorRangeMax);
-		ColorizeRange(mColorRangeMin, to);
-		mColorRangeMin = to;
-
-		if (mColorRangeMax == mColorRangeMin)
-		{
-			mColorRangeMin = std::numeric_limits<int>::max();
-			mColorRangeMax = 0;
-		}
-		return;
-	}
-}
-
-float TextEditor::TextDistanceToLineStart(const Coordinates& aFrom) const
-{
-	auto& line = mLines[aFrom.mLine];
-	float distance = 0.0f;
-	float spaceSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, " ", nullptr, nullptr).x;
-	int colIndex = GetCharacterIndex(aFrom);
-	for (size_t it = 0u; it < line.size() && it < colIndex; )
-	{
-		if (line[it].mChar == '\t')
-		{
-			distance = (1.0f + std::floor((1.0f + distance) / (float(mTabSize) * spaceSize))) * (float(mTabSize) * spaceSize);
-			++it;
-		}
-		else
-		{
-			auto d = UTF8CharLength(line[it].mChar);
-			char tempCString[7];
-			int i = 0;
-			for (; i < 6 && d-- > 0 && it < (int)line.size(); i++, it++)
-				tempCString[i] = line[it].mChar;
-
-			tempCString[i] = '\0';
-			distance += ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, tempCString, nullptr, nullptr).x;
-		}
-	}
-
-	return distance;
-}
-
-void TextEditor::EnsureCursorVisible()
-{
-	if (!mWithinRender)
-	{
-		mScrollToCursor = true;
-		return;
-	}
-
-	float scrollX = ImGui::GetScrollX();
-	float scrollY = ImGui::GetScrollY();
-
-	auto height = ImGui::GetWindowHeight();
-	auto width = ImGui::GetWindowWidth();
-
-	auto top = 1 + (int)ceil(scrollY / mCharAdvance.y);
-	auto bottom = (int)ceil((scrollY + height) / mCharAdvance.y);
-
-	auto left = (int)ceil(scrollX / mCharAdvance.x);
-	auto right = (int)ceil((scrollX + width) / mCharAdvance.x);
-
-	auto pos = GetActualCursorCoordinates();
-	auto len = TextDistanceToLineStart(pos);
-
-	if (pos.mLine < top)
-		ImGui::SetScrollY(std::max(0.0f, (pos.mLine - 1) * mCharAdvance.y));
-	if (pos.mLine > bottom - 4)
-		ImGui::SetScrollY(std::max(0.0f, (pos.mLine + 4) * mCharAdvance.y - height));
-	if (len + mTextStart < left + 4)
-		ImGui::SetScrollX(std::max(0.0f, len + mTextStart - 4));
-	if (len + mTextStart > right - 4)
-		ImGui::SetScrollX(std::max(0.0f, len + mTextStart + 4 - width));
-}
-
-int TextEditor::GetPageSize() const
-{
-	auto height = ImGui::GetWindowHeight() - 20.0f;
-	return (int)floor(height / mCharAdvance.y);
-}
-
-TextEditor::UndoRecord::UndoRecord(
-	const std::string& aAdded,
-	const TextEditor::Coordinates aAddedStart,
-	const TextEditor::Coordinates aAddedEnd,
-	const std::string& aRemoved,
-	const TextEditor::Coordinates aRemovedStart,
-	const TextEditor::Coordinates aRemovedEnd,
-	TextEditor::EditorState& aBefore,
-	TextEditor::EditorState& aAfter)
-	: mAdded(aAdded)
-	, mAddedStart(aAddedStart)
-	, mAddedEnd(aAddedEnd)
-	, mRemoved(aRemoved)
-	, mRemovedStart(aRemovedStart)
-	, mRemovedEnd(aRemovedEnd)
-	, mBefore(aBefore)
-	, mAfter(aAfter)
-{
-	assert(mAddedStart <= mAddedEnd);
-	assert(mRemovedStart <= mRemovedEnd);
-}
-
-void TextEditor::UndoRecord::Undo(TextEditor * aEditor)
-{
-	if (!mAdded.empty())
-	{
-		aEditor->DeleteRange(mAddedStart, mAddedEnd);
-		aEditor->Colorize(mAddedStart.mLine - 1, mAddedEnd.mLine - mAddedStart.mLine + 2);
-	}
-
-	if (!mRemoved.empty())
-	{
-		auto start = mRemovedStart;
-		aEditor->InsertTextAt(start, mRemoved.c_str());
-		aEditor->Colorize(mRemovedStart.mLine - 1, mRemovedEnd.mLine - mRemovedStart.mLine + 2);
-	}
-
-	aEditor->mState = mBefore;
-	aEditor->EnsureCursorVisible();
-
-}
-
-void TextEditor::UndoRecord::Redo(TextEditor * aEditor)
-{
-	if (!mRemoved.empty())
-	{
-		aEditor->DeleteRange(mRemovedStart, mRemovedEnd);
-		aEditor->Colorize(mRemovedStart.mLine - 1, mRemovedEnd.mLine - mRemovedStart.mLine + 1);
-	}
-
-	if (!mAdded.empty())
-	{
-		auto start = mAddedStart;
-		aEditor->InsertTextAt(start, mAdded.c_str());
-		aEditor->Colorize(mAddedStart.mLine - 1, mAddedEnd.mLine - mAddedStart.mLine + 1);
-	}
-
-	aEditor->mState = mAfter;
-	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 TextEditor::LanguageDefinition& TextEditor::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.mKeywords.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.mDeclaration = "Built-in function";
-			langDef.mIdentifiers.insert(std::make_pair(std::string(k), id));
-		}
-
-		langDef.mTokenize = [](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.mCommentStart = "/*";
-		langDef.mCommentEnd = "*/";
-		langDef.mSingleLineComment = "//";
-
-		langDef.mCaseSensitive = true;
-		langDef.mAutoIndentation = true;
-
-		langDef.mName = "C++";
-
-		inited = true;
-	}
-	return langDef;
-}
-
-const TextEditor::LanguageDefinition& TextEditor::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.mKeywords.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.mDeclaration = "Built-in function";
-			langDef.mIdentifiers.insert(std::make_pair(std::string(k), id));
-		}
-
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[ \\t]*#[ \\t]*[a-zA-Z_]+", PaletteIndex::Preprocessor));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\'\\\\?[^\\']\\'", PaletteIndex::CharLiteral));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[0-7]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
-
-		langDef.mCommentStart = "/*";
-		langDef.mCommentEnd = "*/";
-		langDef.mSingleLineComment = "//";
-
-		langDef.mCaseSensitive = true;
-		langDef.mAutoIndentation = true;
-
-		langDef.mName = "HLSL";
-
-		inited = true;
-	}
-	return langDef;
-}
-
-const TextEditor::LanguageDefinition& TextEditor::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.mKeywords.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.mDeclaration = "Built-in function";
-			langDef.mIdentifiers.insert(std::make_pair(std::string(k), id));
-		}
-
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[ \\t]*#[ \\t]*[a-zA-Z_]+", PaletteIndex::Preprocessor));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\'\\\\?[^\\']\\'", PaletteIndex::CharLiteral));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[0-7]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
-
-		langDef.mCommentStart = "/*";
-		langDef.mCommentEnd = "*/";
-		langDef.mSingleLineComment = "//";
-
-		langDef.mCaseSensitive = true;
-		langDef.mAutoIndentation = true;
-
-		langDef.mName = "GLSL";
-
-		inited = true;
-	}
-	return langDef;
-}
-
-const TextEditor::LanguageDefinition& TextEditor::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.mKeywords.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.mDeclaration = "Built-in function";
-			langDef.mIdentifiers.insert(std::make_pair(std::string(k), id));
-		}
-
-		langDef.mTokenize = [](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.mCommentStart = "/*";
-		langDef.mCommentEnd = "*/";
-		langDef.mSingleLineComment = "//";
-
-		langDef.mCaseSensitive = true;
-		langDef.mAutoIndentation = true;
-
-		langDef.mName = "C";
-
-		inited = true;
-	}
-	return langDef;
-}
-
-const TextEditor::LanguageDefinition& TextEditor::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.mKeywords.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.mDeclaration = "Built-in function";
-			langDef.mIdentifiers.insert(std::make_pair(std::string(k), id));
-		}
-
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\\'[^\\\']*\\\'", PaletteIndex::String));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[0-7]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
-
-		langDef.mCommentStart = "/*";
-		langDef.mCommentEnd = "*/";
-		langDef.mSingleLineComment = "//";
-
-		langDef.mCaseSensitive = false;
-		langDef.mAutoIndentation = false;
-
-		langDef.mName = "SQL";
-
-		inited = true;
-	}
-	return langDef;
-}
-
-const TextEditor::LanguageDefinition& TextEditor::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.mKeywords.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.mDeclaration = "Built-in function";
-			langDef.mIdentifiers.insert(std::make_pair(std::string(k), id));
-		}
-
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\'\\\\?[^\\']\\'", PaletteIndex::String));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[0-7]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
-
-		langDef.mCommentStart = "/*";
-		langDef.mCommentEnd = "*/";
-		langDef.mSingleLineComment = "//";
-
-		langDef.mCaseSensitive = true;
-		langDef.mAutoIndentation = true;
-
-		langDef.mName = "AngelScript";
-
-		inited = true;
-	}
-	return langDef;
-}
-
-const TextEditor::LanguageDefinition& TextEditor::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.mKeywords.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.mDeclaration = "Built-in function";
-			langDef.mIdentifiers.insert(std::make_pair(std::string(k), id));
-		}
-
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\\'[^\\\']*\\\'", PaletteIndex::String));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
-		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
-
-		langDef.mCommentStart = "--[[";
-		langDef.mCommentEnd = "]]";
-		langDef.mSingleLineComment = "--";
-
-		langDef.mCaseSensitive = true;
-		langDef.mAutoIndentation = false;
-
-		langDef.mName = "Lua";
-
-		inited = true;
-	}
-	return langDef;
-}
+#include <algorithm>
+#include <chrono>
+#include <string>
+#include <regex>
+#include <cmath>
+
+#include "TextEditor.h"
+
+#define IMGUI_DEFINE_MATH_OPERATORS
+#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)
+{
+	for (; first1 != last1 && first2 != last2; ++first1, ++first2)
+	{
+		if (!p(*first1, *first2))
+			return false;
+	}
+	return first1 == last1 && first2 == last2;
+}
+
+TextEditor::TextEditor()
+	: mLineSpacing(1.0f)
+	, mUndoIndex(0)
+	, mTabSize(4)
+	, mOverwrite(false)
+	, mReadOnly(false)
+	, mWithinRender(false)
+	, mScrollToCursor(false)
+	, mScrollToTop(false)
+	, mTextChanged(false)
+	, mColorizerEnabled(true)
+	, mTextStart(20.0f)
+	, mLeftMargin(10)
+	, mCursorPositionChanged(false)
+	, mColorRangeMin(0)
+	, mColorRangeMax(0)
+	, mSelectionMode(SelectionMode::Normal)
+	, mCheckComments(true)
+	, mLastClick(-1.0f)
+	, mHandleKeyboardInputs(true)
+	, mHandleMouseInputs(true)
+	, mIgnoreImGuiChild(false)
+	, mShowWhitespaces(true)
+	, mStartTime(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count())
+{
+	SetPalette(GetDarkPalette());
+	SetLanguageDefinition(LanguageDefinition::HLSL());
+	mLines.push_back(Line());
+}
+
+TextEditor::~TextEditor()
+{
+}
+
+void TextEditor::SetLanguageDefinition(const LanguageDefinition & aLanguageDef)
+{
+	mLanguageDefinition = aLanguageDef;
+	mRegexList.clear();
+
+	for (auto& r : mLanguageDefinition.mTokenRegexStrings)
+		mRegexList.push_back(std::make_pair(std::regex(r.first, std::regex_constants::optimize), r.second));
+
+	Colorize();
+}
+
+void TextEditor::SetPalette(const Palette & aValue)
+{
+	mPaletteBase = aValue;
+}
+
+std::string TextEditor::GetText(const Coordinates & aStart, const Coordinates & aEnd) const
+{
+	std::string result;
+
+	auto lstart = aStart.mLine;
+	auto lend = aEnd.mLine;
+	auto istart = GetCharacterIndex(aStart);
+	auto iend = GetCharacterIndex(aEnd);
+	size_t s = 0;
+
+	for (size_t i = lstart; i < lend; i++)
+		s += mLines[i].size();
+
+	result.reserve(s + s / 8);
+
+	while (istart < iend || lstart < lend)
+	{
+		if (lstart >= (int)mLines.size())
+			break;
+
+		auto& line = mLines[lstart];
+		if (istart < (int)line.size())
+		{
+			result += line[istart].mChar;
+			istart++;
+		}
+		else
+		{
+			istart = 0;
+			++lstart;
+			result += '\n';
+		}
+	}
+
+	return result;
+}
+
+TextEditor::Coordinates TextEditor::GetActualCursorCoordinates() const
+{
+	return SanitizeCoordinates(mState.mCursorPosition);
+}
+
+TextEditor::Coordinates TextEditor::SanitizeCoordinates(const Coordinates & aValue) const
+{
+	auto line = aValue.mLine;
+	auto column = aValue.mColumn;
+	if (line >= (int)mLines.size())
+	{
+		if (mLines.empty())
+		{
+			line = 0;
+			column = 0;
+		}
+		else
+		{
+			line = (int)mLines.size() - 1;
+			column = GetLineMaxColumn(line);
+		}
+		return Coordinates(line, column);
+	}
+	else
+	{
+		column = mLines.empty() ? 0 : std::min(column, GetLineMaxColumn(line));
+		return Coordinates(line, column);
+	}
+}
+
+// https://en.wikipedia.org/wiki/UTF-8
+// We assume that the char is a standalone character (<128) or a leading byte of an UTF-8 code sequence (non-10xxxxxx code)
+static int UTF8CharLength(TextEditor::Char c)
+{
+	if ((c & 0xFE) == 0xFC)
+		return 6;
+	if ((c & 0xFC) == 0xF8)
+		return 5;
+	if ((c & 0xF8) == 0xF0)
+		return 4;
+	else if ((c & 0xF0) == 0xE0)
+		return 3;
+	else if ((c & 0xE0) == 0xC0)
+		return 2;
+	return 1;
+}
+
+// "Borrowed" from ImGui source
+static inline int ImTextCharToUtf8(char* buf, int buf_size, unsigned int c)
+{
+	if (c < 0x80)
+	{
+		buf[0] = (char)c;
+		return 1;
+	}
+	if (c < 0x800)
+	{
+		if (buf_size < 2) return 0;
+		buf[0] = (char)(0xc0 + (c >> 6));
+		buf[1] = (char)(0x80 + (c & 0x3f));
+		return 2;
+	}
+	if (c >= 0xdc00 && c < 0xe000)
+	{
+		return 0;
+	}
+	if (c >= 0xd800 && c < 0xdc00)
+	{
+		if (buf_size < 4) return 0;
+		buf[0] = (char)(0xf0 + (c >> 18));
+		buf[1] = (char)(0x80 + ((c >> 12) & 0x3f));
+		buf[2] = (char)(0x80 + ((c >> 6) & 0x3f));
+		buf[3] = (char)(0x80 + ((c) & 0x3f));
+		return 4;
+	}
+	//else if (c < 0x10000)
+	{
+		if (buf_size < 3) return 0;
+		buf[0] = (char)(0xe0 + (c >> 12));
+		buf[1] = (char)(0x80 + ((c >> 6) & 0x3f));
+		buf[2] = (char)(0x80 + ((c) & 0x3f));
+		return 3;
+	}
+}
+
+void TextEditor::Advance(Coordinates & aCoordinates) const
+{
+	if (aCoordinates.mLine < (int)mLines.size())
+	{
+		auto& line = mLines[aCoordinates.mLine];
+		auto cindex = GetCharacterIndex(aCoordinates);
+
+		if (cindex + 1 < (int)line.size())
+		{
+			auto delta = UTF8CharLength(line[cindex].mChar);
+			cindex = std::min(cindex + delta, (int)line.size() - 1);
+		}
+		else
+		{
+			++aCoordinates.mLine;
+			cindex = 0;
+		}
+		aCoordinates.mColumn = GetCharacterColumn(aCoordinates.mLine, cindex);
+	}
+}
+
+void TextEditor::DeleteRange(const Coordinates & aStart, const Coordinates & aEnd)
+{
+	assert(aEnd >= aStart);
+	assert(!mReadOnly);
+
+	//printf("D(%d.%d)-(%d.%d)\n", aStart.mLine, aStart.mColumn, aEnd.mLine, aEnd.mColumn);
+
+	if (aEnd == aStart)
+		return;
+
+	auto start = GetCharacterIndex(aStart);
+	auto end = GetCharacterIndex(aEnd);
+
+	if (aStart.mLine == aEnd.mLine)
+	{
+		auto& line = mLines[aStart.mLine];
+		auto n = GetLineMaxColumn(aStart.mLine);
+		if (aEnd.mColumn >= n)
+			line.erase(line.begin() + start, line.end());
+		else
+			line.erase(line.begin() + start, line.begin() + end);
+	}
+	else
+	{
+		auto& firstLine = mLines[aStart.mLine];
+		auto& lastLine = mLines[aEnd.mLine];
+
+		firstLine.erase(firstLine.begin() + start, firstLine.end());
+		lastLine.erase(lastLine.begin(), lastLine.begin() + end);
+
+		if (aStart.mLine < aEnd.mLine)
+			firstLine.insert(firstLine.end(), lastLine.begin(), lastLine.end());
+
+		if (aStart.mLine < aEnd.mLine)
+			RemoveLine(aStart.mLine + 1, aEnd.mLine + 1);
+	}
+
+	mTextChanged = true;
+}
+
+int TextEditor::InsertTextAt(Coordinates& /* inout */ aWhere, const char * aValue)
+{
+	assert(!mReadOnly);
+
+	int cindex = GetCharacterIndex(aWhere);
+	int totalLines = 0;
+	while (*aValue != '\0')
+	{
+		assert(!mLines.empty());
+
+		if (*aValue == '\r')
+		{
+			// skip
+			++aValue;
+		}
+		else if (*aValue == '\n')
+		{
+			if (cindex < (int)mLines[aWhere.mLine].size())
+			{
+				auto& newLine = InsertLine(aWhere.mLine + 1);
+				auto& line = mLines[aWhere.mLine];
+				newLine.insert(newLine.begin(), line.begin() + cindex, line.end());
+				line.erase(line.begin() + cindex, line.end());
+			}
+			else
+			{
+				InsertLine(aWhere.mLine + 1);
+			}
+			++aWhere.mLine;
+			aWhere.mColumn = 0;
+			cindex = 0;
+			++totalLines;
+			++aValue;
+		}
+		else
+		{
+			auto& line = mLines[aWhere.mLine];
+			auto d = UTF8CharLength(*aValue);
+			while (d-- > 0 && *aValue != '\0')
+				line.insert(line.begin() + cindex++, Glyph(*aValue++, PaletteIndex::Default));
+			++aWhere.mColumn;
+		}
+
+		mTextChanged = true;
+	}
+
+	return totalLines;
+}
+
+void TextEditor::AddUndo(UndoRecord& aValue)
+{
+	assert(!mReadOnly);
+	//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
+	//	);
+
+	mUndoBuffer.resize((size_t)(mUndoIndex + 1));
+	mUndoBuffer.back() = aValue;
+	++mUndoIndex;
+}
+
+TextEditor::Coordinates TextEditor::ScreenPosToCoordinates(const ImVec2& aPosition) const
+{
+	ImVec2 origin = ImGui::GetCursorScreenPos();
+	ImVec2 local(aPosition.x - origin.x, aPosition.y - origin.y);
+
+	int lineNo = std::max(0, (int)floor(local.y / mCharAdvance.y));
+
+	int columnCoord = 0;
+
+	if (lineNo >= 0 && lineNo < (int)mLines.size())
+	{
+		auto& line = mLines.at(lineNo);
+
+		int columnIndex = 0;
+		std::string cumulatedString = "";
+		float columnWidth = 0.0f;
+		float columnX = 0.0f;
+
+		// First we find the hovered column coord.
+		while (mTextStart + columnX < local.x && (size_t)columnIndex < line.size())
+		{
+			if (line[columnIndex].mChar == '\t')
+			{
+				float spaceSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, " ").x;
+				float oldX = columnX;
+				columnX = (1.0f + std::floor((1.0f + columnX) / (float(mTabSize) * spaceSize))) * (float(mTabSize) * spaceSize);
+				columnWidth = columnX - oldX;
+				columnCoord++;
+			}
+			else
+			{
+				char buf[7];
+				auto d = UTF8CharLength(line[columnIndex].mChar);
+				int i = 0;
+				while (i < 6 && d-- > 0)
+					buf[i++] = line[columnIndex++].mChar;
+				buf[i] = '\0';
+				columnWidth = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, buf).x;
+				columnX += columnWidth;
+				columnCoord++;
+			}
+		}
+
+		// Then we reduce by 1 column coord if cursor is on the left side of the hovered column.
+		if (mTextStart + columnX - columnWidth / 2.0f > local.x)
+			columnIndex = std::max(0, columnIndex - 1);
+	}
+
+	return SanitizeCoordinates(Coordinates(lineNo, columnCoord));
+}
+
+TextEditor::Coordinates TextEditor::FindWordStart(const Coordinates & aFrom) const
+{
+	Coordinates at = aFrom;
+	if (at.mLine >= (int)mLines.size())
+		return at;
+
+	auto& line = mLines[at.mLine];
+	auto cindex = GetCharacterIndex(at);
+
+	if (cindex >= (int)line.size())
+		return at;
+
+	while (cindex > 0 && isspace(line[cindex].mChar))
+		--cindex;
+
+	auto cstart = (PaletteIndex)line[cindex].mColorIndex;
+	while (cindex > 0)
+	{
+		auto c = line[cindex].mChar;
+		if ((c & 0xC0) != 0x80)	// not UTF code sequence 10xxxxxx
+		{
+			if (c <= 32 && isspace(c))
+			{
+				cindex++;
+				break;
+			}
+			if (cstart != (PaletteIndex)line[size_t(cindex - 1)].mColorIndex)
+				break;
+		}
+		--cindex;
+	}
+	return Coordinates(at.mLine, GetCharacterColumn(at.mLine, cindex));
+}
+
+TextEditor::Coordinates TextEditor::FindWordEnd(const Coordinates & aFrom) const
+{
+	Coordinates at = aFrom;
+	if (at.mLine >= (int)mLines.size())
+		return at;
+
+	auto& line = mLines[at.mLine];
+	auto cindex = GetCharacterIndex(at);
+
+	if (cindex >= (int)line.size())
+		return at;
+
+	bool prevspace = (bool)isspace(line[cindex].mChar);
+	auto cstart = (PaletteIndex)line[cindex].mColorIndex;
+	while (cindex < (int)line.size())
+	{
+		auto c = line[cindex].mChar;
+		auto d = UTF8CharLength(c);
+		if (cstart != (PaletteIndex)line[cindex].mColorIndex)
+			break;
+
+		if (prevspace != !!isspace(c))
+		{
+			if (isspace(c))
+				while (cindex < (int)line.size() && isspace(line[cindex].mChar))
+					++cindex;
+			break;
+		}
+		cindex += d;
+	}
+	return Coordinates(aFrom.mLine, GetCharacterColumn(aFrom.mLine, cindex));
+}
+
+TextEditor::Coordinates TextEditor::FindNextWord(const Coordinates & aFrom) const
+{
+	Coordinates at = aFrom;
+	if (at.mLine >= (int)mLines.size())
+		return at;
+
+	// skip to the next non-word character
+	auto cindex = GetCharacterIndex(aFrom);
+	bool isword = false;
+	bool skip = false;
+	if (cindex < (int)mLines[at.mLine].size())
+	{
+		auto& line = mLines[at.mLine];
+		isword = isalnum(line[cindex].mChar);
+		skip = isword;
+	}
+
+	while (!isword || skip)
+	{
+		if (at.mLine >= mLines.size())
+		{
+			auto l = std::max(0, (int) mLines.size() - 1);
+			return Coordinates(l, GetLineMaxColumn(l));
+		}
+
+		auto& line = mLines[at.mLine];
+		if (cindex < (int)line.size())
+		{
+			isword = isalnum(line[cindex].mChar);
+
+			if (isword && !skip)
+				return Coordinates(at.mLine, GetCharacterColumn(at.mLine, cindex));
+
+			if (!isword)
+				skip = false;
+
+			cindex++;
+		}
+		else
+		{
+			cindex = 0;
+			++at.mLine;
+			skip = false;
+			isword = false;
+		}
+	}
+
+	return at;
+}
+
+int TextEditor::GetCharacterIndex(const Coordinates& aCoordinates) const
+{
+	if (aCoordinates.mLine >= mLines.size())
+		return -1;
+	auto& line = mLines[aCoordinates.mLine];
+	int c = 0;
+	int i = 0;
+	for (; i < line.size() && c < aCoordinates.mColumn;)
+	{
+		if (line[i].mChar == '\t')
+			c = (c / mTabSize) * mTabSize + mTabSize;
+		else
+			++c;
+		i += UTF8CharLength(line[i].mChar);
+	}
+	return i;
+}
+
+int TextEditor::GetCharacterColumn(int aLine, int aIndex) const
+{
+	if (aLine >= mLines.size())
+		return 0;
+	auto& line = mLines[aLine];
+	int col = 0;
+	int i = 0;
+	while (i < aIndex && i < (int)line.size())
+	{
+		auto c = line[i].mChar;
+		i += UTF8CharLength(c);
+		if (c == '\t')
+			col = (col / mTabSize) * mTabSize + mTabSize;
+		else
+			col++;
+	}
+	return col;
+}
+
+int TextEditor::GetLineCharacterCount(int aLine) const
+{
+	if (aLine >= mLines.size())
+		return 0;
+	auto& line = mLines[aLine];
+	int c = 0;
+	for (unsigned i = 0; i < line.size(); c++)
+		i += UTF8CharLength(line[i].mChar);
+	return c;
+}
+
+int TextEditor::GetLineMaxColumn(int aLine) const
+{
+	if (aLine >= mLines.size())
+		return 0;
+	auto& line = mLines[aLine];
+	int col = 0;
+	for (unsigned i = 0; i < line.size(); )
+	{
+		auto c = line[i].mChar;
+		if (c == '\t')
+			col = (col / mTabSize) * mTabSize + mTabSize;
+		else
+			col++;
+		i += UTF8CharLength(c);
+	}
+	return col;
+}
+
+bool TextEditor::IsOnWordBoundary(const Coordinates & aAt) const
+{
+	if (aAt.mLine >= (int)mLines.size() || aAt.mColumn == 0)
+		return true;
+
+	auto& line = mLines[aAt.mLine];
+	auto cindex = GetCharacterIndex(aAt);
+	if (cindex >= (int)line.size())
+		return true;
+
+	if (mColorizerEnabled)
+		return line[cindex].mColorIndex != line[size_t(cindex - 1)].mColorIndex;
+
+	return isspace(line[cindex].mChar) != isspace(line[cindex - 1].mChar);
+}
+
+void TextEditor::RemoveLine(int aStart, int aEnd)
+{
+	assert(!mReadOnly);
+	assert(aEnd >= aStart);
+	assert(mLines.size() > (size_t)(aEnd - aStart));
+
+	ErrorMarkers etmp;
+	for (auto& i : mErrorMarkers)
+	{
+		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);
+	}
+	mErrorMarkers = std::move(etmp);
+
+	Breakpoints btmp;
+	for (auto i : mBreakpoints)
+	{
+		if (i >= aStart && i <= aEnd)
+			continue;
+		btmp.insert(i >= aStart ? i - 1 : i);
+	}
+	mBreakpoints = std::move(btmp);
+
+	mLines.erase(mLines.begin() + aStart, mLines.begin() + aEnd);
+	assert(!mLines.empty());
+
+	mTextChanged = true;
+}
+
+void TextEditor::RemoveLine(int aIndex)
+{
+	assert(!mReadOnly);
+	assert(mLines.size() > 1);
+
+	ErrorMarkers etmp;
+	for (auto& i : mErrorMarkers)
+	{
+		ErrorMarkers::value_type e(i.first > aIndex ? i.first - 1 : i.first, i.second);
+		if (e.first - 1 == aIndex)
+			continue;
+		etmp.insert(e);
+	}
+	mErrorMarkers = std::move(etmp);
+
+	Breakpoints btmp;
+	for (auto i : mBreakpoints)
+	{
+		if (i == aIndex)
+			continue;
+		btmp.insert(i >= aIndex ? i - 1 : i);
+	}
+	mBreakpoints = std::move(btmp);
+
+	mLines.erase(mLines.begin() + aIndex);
+	assert(!mLines.empty());
+
+	mTextChanged = true;
+}
+
+TextEditor::Line& TextEditor::InsertLine(int aIndex)
+{
+	assert(!mReadOnly);
+
+	auto& result = *mLines.insert(mLines.begin() + aIndex, Line());
+
+	ErrorMarkers etmp;
+	for (auto& i : mErrorMarkers)
+		etmp.insert(ErrorMarkers::value_type(i.first >= aIndex ? i.first + 1 : i.first, i.second));
+	mErrorMarkers = std::move(etmp);
+
+	Breakpoints btmp;
+	for (auto i : mBreakpoints)
+		btmp.insert(i >= aIndex ? i + 1 : i);
+	mBreakpoints = std::move(btmp);
+
+	return result;
+}
+
+std::string TextEditor::GetWordUnderCursor() const
+{
+	auto c = GetCursorPosition();
+	return GetWordAt(c);
+}
+
+std::string TextEditor::GetWordAt(const Coordinates & aCoords) const
+{
+	auto start = FindWordStart(aCoords);
+	auto end = FindWordEnd(aCoords);
+
+	std::string r;
+
+	auto istart = GetCharacterIndex(start);
+	auto iend = GetCharacterIndex(end);
+
+	for (auto it = istart; it < iend; ++it)
+		r.push_back(mLines[aCoords.mLine][it].mChar);
+
+	return r;
+}
+
+ImU32 TextEditor::GetGlyphColor(const Glyph & aGlyph) const
+{
+	if (!mColorizerEnabled)
+		return mPalette[(int)PaletteIndex::Default];
+	if (aGlyph.mComment)
+		return mPalette[(int)PaletteIndex::Comment];
+	if (aGlyph.mMultiLineComment)
+		return mPalette[(int)PaletteIndex::MultiLineComment];
+	auto const color = mPalette[(int)aGlyph.mColorIndex];
+	if (aGlyph.mPreprocessor)
+	{
+		const auto ppcolor = mPalette[(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;
+}
+
+void TextEditor::HandleKeyboardInputs()
+{
+	ImGuiIO& io = ImGui::GetIO();
+	auto shift = io.KeyShift;
+	auto ctrl = io.ConfigMacOSXBehaviors ? io.KeySuper : io.KeyCtrl;
+	auto alt = io.ConfigMacOSXBehaviors ? io.KeyCtrl : io.KeyAlt;
+
+	if (ImGui::IsWindowFocused())
+	{
+		if (ImGui::IsWindowHovered())
+			ImGui::SetMouseCursor(ImGuiMouseCursor_TextInput);
+		//ImGui::CaptureKeyboardFromApp(true);
+
+		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)))
+			MoveUp(1, shift);
+		else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)))
+			MoveDown(1, shift);
+		else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_LeftArrow)))
+			MoveLeft(1, shift, ctrl);
+		else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_RightArrow)))
+			MoveRight(1, shift, ctrl);
+		else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_PageUp)))
+			MoveUp(GetPageSize() - 4, shift);
+		else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_PageDown)))
+			MoveDown(GetPageSize() - 4, shift);
+		else if (!alt && ctrl && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Home)))
+			MoveTop(shift);
+		else if (ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_End)))
+			MoveBottom(shift);
+		else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Home)))
+			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)))
+			mOverwrite ^= 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)))
+			EnterCharacter('\n', false);
+		else if (!IsReadOnly() && !ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Tab)))
+			EnterCharacter('\t', shift);
+		if (!IsReadOnly() && !io.InputQueueCharacters.empty() && !ctrl)
+		{
+			for (int i = 0; i < io.InputQueueCharacters.Size; i++)
+			{
+				auto c = io.InputQueueCharacters[i];
+				if (c != 0 && (c == '\n' || c >= 32))
+					EnterCharacter(c, shift);
+			}
+			io.InputQueueCharacters.resize(0);
+		}
+	}
+}
+
+void TextEditor::HandleMouseInputs()
+{
+	ImGuiIO& io = ImGui::GetIO();
+	auto shift = io.KeyShift;
+	auto ctrl = io.ConfigMacOSXBehaviors ? io.KeySuper : io.KeyCtrl;
+	auto alt = io.ConfigMacOSXBehaviors ? io.KeyCtrl : io.KeyAlt;
+
+	if (ImGui::IsWindowHovered())
+	{
+		if (!shift && !alt)
+		{
+			auto click = ImGui::IsMouseClicked(0);
+			auto doubleClick = ImGui::IsMouseDoubleClicked(0);
+			auto t = ImGui::GetTime();
+			auto tripleClick = click && !doubleClick && (mLastClick != -1.0f && (t - mLastClick) < io.MouseDoubleClickTime);
+
+			/*
+			Left mouse button triple click
+			*/
+
+			if (tripleClick)
+			{
+				if (!ctrl)
+				{
+					mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = SanitizeCoordinates(ScreenPosToCoordinates(ImGui::GetMousePos()));
+					mSelectionMode = SelectionMode::Line;
+					SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode);
+				}
+
+				mLastClick = -1.0f;
+			}
+
+			/*
+			Left mouse button double click
+			*/
+
+			else if (doubleClick)
+			{
+				if (!ctrl)
+				{
+					mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = SanitizeCoordinates(ScreenPosToCoordinates(ImGui::GetMousePos()));
+					if (mSelectionMode == SelectionMode::Line)
+						mSelectionMode = SelectionMode::Normal;
+					else
+						mSelectionMode = SelectionMode::Word;
+					SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode);
+				}
+
+				mLastClick = (float)ImGui::GetTime();
+			}
+
+			/*
+			Left mouse button click
+			*/
+			else if (click)
+			{
+				mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = SanitizeCoordinates(ScreenPosToCoordinates(ImGui::GetMousePos()));
+				if (ctrl)
+					mSelectionMode = SelectionMode::Word;
+				else
+					mSelectionMode = SelectionMode::Normal;
+				SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode);
+
+				mLastClick = (float)ImGui::GetTime();
+			}
+			// Mouse left button dragging (=> update selection)
+			else if (ImGui::IsMouseDragging(0) && ImGui::IsMouseDown(0))
+			{
+				io.WantCaptureMouse = true;
+				mState.mCursorPosition = mInteractiveEnd = SanitizeCoordinates(ScreenPosToCoordinates(ImGui::GetMousePos()));
+				SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode);
+			}
+		}
+	}
+}
+
+void TextEditor::Render()
+{
+	/* 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;
+	mCharAdvance = ImVec2(fontSize, ImGui::GetTextLineHeightWithSpacing() * mLineSpacing);
+
+	/* Update palette with the current alpha from style */
+	for (int i = 0; i < (int)PaletteIndex::Max; ++i)
+	{
+		auto color = ImGui::ColorConvertU32ToFloat4(mPaletteBase[i]);
+		color.w *= ImGui::GetStyle().Alpha;
+		mPalette[i] = ImGui::ColorConvertFloat4ToU32(color);
+	}
+
+	assert(mLineBuffer.empty());
+
+	auto contentSize = ImGui::GetWindowContentRegionMax();
+	auto drawList = ImGui::GetWindowDrawList();
+	float longest(mTextStart);
+
+	if (mScrollToTop)
+	{
+		mScrollToTop = false;
+		ImGui::SetScrollY(0.f);
+	}
+
+	ImVec2 cursorScreenPos = ImGui::GetCursorScreenPos();
+	auto scrollX = ImGui::GetScrollX();
+	auto scrollY = ImGui::GetScrollY();
+
+	auto lineNo = (int)floor(scrollY / mCharAdvance.y);
+	auto globalLineMax = (int)mLines.size();
+	auto lineMax = std::max(0, std::min((int)mLines.size() - 1, lineNo + (int)floor((scrollY + contentSize.y) / mCharAdvance.y)));
+
+	// Deduce mTextStart by evaluating mLines size (global lineMax) plus two spaces as text width
+	char buf[16];
+	snprintf(buf, 16, " %d ", globalLineMax);
+	mTextStart = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, buf, nullptr, nullptr).x + mLeftMargin;
+
+	if (!mLines.empty())
+	{
+		float spaceSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, " ", nullptr, nullptr).x;
+
+		while (lineNo <= lineMax)
+		{
+			ImVec2 lineStartScreenPos = ImVec2(cursorScreenPos.x, cursorScreenPos.y + lineNo * mCharAdvance.y);
+			ImVec2 textScreenPos = ImVec2(lineStartScreenPos.x + mTextStart, lineStartScreenPos.y);
+
+			auto& line = mLines[lineNo];
+			longest = std::max(mTextStart + TextDistanceToLineStart(Coordinates(lineNo, GetLineMaxColumn(lineNo))), longest);
+			auto columnNo = 0;
+			Coordinates lineStartCoord(lineNo, 0);
+			Coordinates lineEndCoord(lineNo, GetLineMaxColumn(lineNo));
+
+			// Draw selection for the current line
+			float sstart = -1.0f;
+			float ssend = -1.0f;
+
+			assert(mState.mSelectionStart <= mState.mSelectionEnd);
+			if (mState.mSelectionStart <= lineEndCoord)
+				sstart = mState.mSelectionStart > lineStartCoord ? TextDistanceToLineStart(mState.mSelectionStart) : 0.0f;
+			if (mState.mSelectionEnd > lineStartCoord)
+				ssend = TextDistanceToLineStart(mState.mSelectionEnd < lineEndCoord ? mState.mSelectionEnd : lineEndCoord);
+
+			if (mState.mSelectionEnd.mLine > lineNo)
+				ssend += mCharAdvance.x;
+
+			if (sstart != -1 && ssend != -1 && sstart < ssend)
+			{
+				ImVec2 vstart(lineStartScreenPos.x + mTextStart + sstart, lineStartScreenPos.y);
+				ImVec2 vend(lineStartScreenPos.x + mTextStart + ssend, lineStartScreenPos.y + mCharAdvance.y);
+				drawList->AddRectFilled(vstart, vend, mPalette[(int)PaletteIndex::Selection]);
+			}
+
+			// Draw breakpoints
+			auto start = ImVec2(lineStartScreenPos.x + scrollX, lineStartScreenPos.y);
+
+			if (mBreakpoints.count(lineNo + 1) != 0)
+			{
+				auto end = ImVec2(lineStartScreenPos.x + contentSize.x + 2.0f * scrollX, lineStartScreenPos.y + mCharAdvance.y);
+				drawList->AddRectFilled(start, end, mPalette[(int)PaletteIndex::Breakpoint]);
+			}
+
+			// Draw error markers
+			auto errorIt = mErrorMarkers.find(lineNo + 1);
+			if (errorIt != mErrorMarkers.end())
+			{
+				auto end = ImVec2(lineStartScreenPos.x + contentSize.x + 2.0f * scrollX, lineStartScreenPos.y + mCharAdvance.y);
+				drawList->AddRectFilled(start, end, mPalette[(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 + mTextStart - lineNoWidth, lineStartScreenPos.y), mPalette[(int)PaletteIndex::LineNumber], buf);
+
+			if (mState.mCursorPosition.mLine == lineNo)
+			{
+				auto focused = ImGui::IsWindowFocused();
+
+				// Highlight the current line (where the cursor is)
+				if (!HasSelection())
+				{
+					auto end = ImVec2(start.x + contentSize.x + scrollX, start.y + mCharAdvance.y);
+					drawList->AddRectFilled(start, end, mPalette[(int)(focused ? PaletteIndex::CurrentLineFill : PaletteIndex::CurrentLineFillInactive)]);
+					drawList->AddRect(start, end, mPalette[(int)PaletteIndex::CurrentLineEdge], 1.0f);
+				}
+
+				// Render the cursor
+				if (focused)
+				{
+					auto timeEnd = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
+					auto elapsed = timeEnd - mStartTime;
+					if (elapsed > 400)
+					{
+						float width = 1.0f;
+						auto cindex = GetCharacterIndex(mState.mCursorPosition);
+						float cx = TextDistanceToLineStart(mState.mCursorPosition);
+
+						if (mOverwrite && cindex < (int)line.size())
+						{
+							auto c = line[cindex].mChar;
+							if (c == '\t')
+							{
+								auto x = (1.0f + std::floor((1.0f + cx) / (float(mTabSize) * spaceSize))) * (float(mTabSize) * spaceSize);
+								width = x - cx;
+							}
+							else
+							{
+								char buf[2];
+								buf[0] = line[cindex].mChar;
+								buf[1] = '\0';
+								width = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, buf).x;
+							}
+						}
+						ImVec2 cstart(textScreenPos.x + cx, lineStartScreenPos.y);
+						ImVec2 cend(textScreenPos.x + cx + width, lineStartScreenPos.y + mCharAdvance.y);
+						drawList->AddRectFilled(cstart, cend, mPalette[(int)PaletteIndex::Cursor]);
+						if (elapsed > 800)
+							mStartTime = timeEnd;
+					}
+				}
+			}
+
+			// Render colorized text
+			auto prevColor = line.empty() ? mPalette[(int)PaletteIndex::Default] : GetGlyphColor(line[0]);
+			ImVec2 bufferOffset;
+
+			for (int i = 0; i < line.size();)
+			{
+				auto& glyph = line[i];
+				auto color = GetGlyphColor(glyph);
+
+				if ((color != prevColor || glyph.mChar == '\t' || glyph.mChar == ' ') && !mLineBuffer.empty())
+				{
+					const ImVec2 newOffset(textScreenPos.x + bufferOffset.x, textScreenPos.y + bufferOffset.y);
+					drawList->AddText(newOffset, prevColor, mLineBuffer.c_str());
+					auto textSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, mLineBuffer.c_str(), nullptr, nullptr);
+					bufferOffset.x += textSize.x;
+					mLineBuffer.clear();
+				}
+				prevColor = color;
+
+				if (glyph.mChar == '\t')
+				{
+					auto oldX = bufferOffset.x;
+					bufferOffset.x = (1.0f + std::floor((1.0f + bufferOffset.x) / (float(mTabSize) * spaceSize))) * (float(mTabSize) * spaceSize);
+					++i;
+
+					if (mShowWhitespaces)
+					{
+						const auto s = ImGui::GetFontSize();
+						const auto x1 = textScreenPos.x + oldX + 1.0f;
+						const auto x2 = textScreenPos.x + bufferOffset.x - 1.0f;
+						const auto y = textScreenPos.y + bufferOffset.y + s * 0.5f;
+						const ImVec2 p1(x1, y);
+						const ImVec2 p2(x2, y);
+						const ImVec2 p3(x2 - s * 0.2f, y - s * 0.2f);
+						const ImVec2 p4(x2 - s * 0.2f, y + s * 0.2f);
+						drawList->AddLine(p1, p2, 0x90909090);
+						drawList->AddLine(p2, p3, 0x90909090);
+						drawList->AddLine(p2, p4, 0x90909090);
+					}
+				}
+				else if (glyph.mChar == ' ')
+				{
+					if (mShowWhitespaces)
+					{
+						const auto s = ImGui::GetFontSize();
+						const auto x = textScreenPos.x + bufferOffset.x + spaceSize * 0.5f;
+						const auto y = textScreenPos.y + bufferOffset.y + s * 0.5f;
+						drawList->AddCircleFilled(ImVec2(x, y), 1.5f, 0x80808080, 4);
+					}
+					bufferOffset.x += spaceSize;
+					i++;
+				}
+				else
+				{
+					auto l = UTF8CharLength(glyph.mChar);
+					while (l-- > 0)
+						mLineBuffer.push_back(line[i++].mChar);
+				}
+				++columnNo;
+			}
+
+			if (!mLineBuffer.empty())
+			{
+				const ImVec2 newOffset(textScreenPos.x + bufferOffset.x, textScreenPos.y + bufferOffset.y);
+				drawList->AddText(newOffset, prevColor, mLineBuffer.c_str());
+				mLineBuffer.clear();
+			}
+
+			++lineNo;
+		}
+
+		// Draw a tooltip on known identifiers/preprocessor symbols
+		if (ImGui::IsMousePosValid())
+		{
+			auto id = GetWordAt(ScreenPosToCoordinates(ImGui::GetMousePos()));
+			if (!id.empty())
+			{
+				auto it = mLanguageDefinition.mIdentifiers.find(id);
+				if (it != mLanguageDefinition.mIdentifiers.end())
+				{
+					ImGui::BeginTooltip();
+					ImGui::TextUnformatted(it->second.mDeclaration.c_str());
+					ImGui::EndTooltip();
+				}
+				else
+				{
+					auto pi = mLanguageDefinition.mPreprocIdentifiers.find(id);
+					if (pi != mLanguageDefinition.mPreprocIdentifiers.end())
+					{
+						ImGui::BeginTooltip();
+						ImGui::TextUnformatted(pi->second.mDeclaration.c_str());
+						ImGui::EndTooltip();
+					}
+				}
+			}
+		}
+	}
+
+
+	ImGui::Dummy(ImVec2((longest + 2), mLines.size() * mCharAdvance.y));
+
+	if (mScrollToCursor)
+	{
+		EnsureCursorVisible();
+		ImGui::SetWindowFocus();
+		mScrollToCursor = false;
+	}
+}
+
+void TextEditor::Render(const char* aTitle, const ImVec2& aSize, bool aBorder)
+{
+	mWithinRender = true;
+	mTextChanged = false;
+	mCursorPositionChanged = false;
+
+	ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::ColorConvertU32ToFloat4(mPalette[(int)PaletteIndex::Background]));
+	ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
+	if (!mIgnoreImGuiChild)
+		ImGui::BeginChild(aTitle, aSize, aBorder, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NoMove);
+
+	if (mHandleKeyboardInputs)
+	{
+		HandleKeyboardInputs();
+		ImGui::PushAllowKeyboardFocus(true);
+	}
+
+	if (mHandleMouseInputs)
+		HandleMouseInputs();
+
+	ColorizeInternal();
+	Render();
+
+	if (mHandleKeyboardInputs)
+		ImGui::PopAllowKeyboardFocus();
+
+	if (!mIgnoreImGuiChild)
+		ImGui::EndChild();
+
+	ImGui::PopStyleVar();
+	ImGui::PopStyleColor();
+
+	mWithinRender = false;
+}
+
+void TextEditor::SetText(const std::string & aText)
+{
+	mLines.clear();
+	mLines.emplace_back(Line());
+	for (auto chr : aText)
+	{
+		if (chr == '\r')
+		{
+			// ignore the carriage return character
+		}
+		else if (chr == '\n')
+			mLines.emplace_back(Line());
+		else
+		{
+			mLines.back().emplace_back(Glyph(chr, PaletteIndex::Default));
+		}
+	}
+
+	mTextChanged = true;
+	mScrollToTop = true;
+
+	mUndoBuffer.clear();
+	mUndoIndex = 0;
+
+	Colorize();
+}
+
+void TextEditor::SetTextLines(const std::vector<std::string> & aLines)
+{
+	mLines.clear();
+
+	if (aLines.empty())
+	{
+		mLines.emplace_back(Line());
+	}
+	else
+	{
+		mLines.resize(aLines.size());
+
+		for (size_t i = 0; i < aLines.size(); ++i)
+		{
+			const std::string & aLine = aLines[i];
+
+			mLines[i].reserve(aLine.size());
+			for (size_t j = 0; j < aLine.size(); ++j)
+				mLines[i].emplace_back(Glyph(aLine[j], PaletteIndex::Default));
+		}
+	}
+
+	mTextChanged = true;
+	mScrollToTop = true;
+
+	mUndoBuffer.clear();
+	mUndoIndex = 0;
+
+	Colorize();
+}
+
+void TextEditor::EnterCharacter(ImWchar aChar, bool aShift)
+{
+	assert(!mReadOnly);
+
+	UndoRecord u;
+
+	u.mBefore = mState;
+
+	if (HasSelection())
+	{
+		if (aChar == '\t' && mState.mSelectionStart.mLine != mState.mSelectionEnd.mLine)
+		{
+
+			auto start = mState.mSelectionStart;
+			auto end = mState.mSelectionEnd;
+			auto originalEnd = end;
+
+			if (start > end)
+				std::swap(start, end);
+			start.mColumn = 0;
+			//			end.mColumn = end.mLine < mLines.size() ? mLines[end.mLine].size() : 0;
+			if (end.mColumn == 0 && end.mLine > 0)
+				--end.mLine;
+			if (end.mLine >= (int)mLines.size())
+				end.mLine = mLines.empty() ? 0 : (int)mLines.size() - 1;
+			end.mColumn = GetLineMaxColumn(end.mLine);
+
+			//if (end.mColumn >= GetLineMaxColumn(end.mLine))
+			//	end.mColumn = GetLineMaxColumn(end.mLine) - 1;
+
+			u.mRemovedStart = start;
+			u.mRemovedEnd = end;
+			u.mRemoved = GetText(start, end);
+
+			bool modified = false;
+
+			for (int i = start.mLine; i <= end.mLine; i++)
+			{
+				auto& line = mLines[i];
+				if (aShift)
+				{
+					if (!line.empty())
+					{
+						if (line.front().mChar == '\t')
+						{
+							line.erase(line.begin());
+							modified = true;
+						}
+						else
+						{
+							for (int j = 0; j < mTabSize && !line.empty() && line.front().mChar == ' '; j++)
+							{
+								line.erase(line.begin());
+								modified = true;
+							}
+						}
+					}
+				}
+				else
+				{
+					line.insert(line.begin(), Glyph('\t', TextEditor::PaletteIndex::Background));
+					modified = true;
+				}
+			}
+
+			if (modified)
+			{
+				start = Coordinates(start.mLine, GetCharacterColumn(start.mLine, 0));
+				Coordinates rangeEnd;
+				if (originalEnd.mColumn != 0)
+				{
+					end = Coordinates(end.mLine, GetLineMaxColumn(end.mLine));
+					rangeEnd = end;
+					u.mAdded = GetText(start, end);
+				}
+				else
+				{
+					end = Coordinates(originalEnd.mLine, 0);
+					rangeEnd = Coordinates(end.mLine - 1, GetLineMaxColumn(end.mLine - 1));
+					u.mAdded = GetText(start, rangeEnd);
+				}
+
+				u.mAddedStart = start;
+				u.mAddedEnd = rangeEnd;
+				u.mAfter = mState;
+
+				mState.mSelectionStart = start;
+				mState.mSelectionEnd = end;
+				AddUndo(u);
+
+				mTextChanged = true;
+
+				EnsureCursorVisible();
+			}
+
+			return;
+		} // c == '\t'
+		else
+		{
+			u.mRemoved = GetSelectedText();
+			u.mRemovedStart = mState.mSelectionStart;
+			u.mRemovedEnd = mState.mSelectionEnd;
+			DeleteSelection();
+		}
+	} // HasSelection
+
+	auto coord = GetActualCursorCoordinates();
+	u.mAddedStart = coord;
+
+	assert(!mLines.empty());
+
+	if (aChar == '\n')
+	{
+		InsertLine(coord.mLine + 1);
+		auto& line = mLines[coord.mLine];
+		auto& newLine = mLines[coord.mLine + 1];
+
+		if (mLanguageDefinition.mAutoIndentation)
+			for (size_t it = 0; it < line.size() && isascii(line[it].mChar) && isblank(line[it].mChar); ++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.mLine + 1, GetCharacterColumn(coord.mLine + 1, (int)whitespaceSize)));
+		u.mAdded = (char)aChar;
+	}
+	else
+	{
+		char buf[7];
+		int e = ImTextCharToUtf8(buf, 7, aChar);
+		if (e > 0)
+		{
+			buf[e] = '\0';
+			auto& line = mLines[coord.mLine];
+			auto cindex = GetCharacterIndex(coord);
+
+			if (mOverwrite && cindex < (int)line.size())
+			{
+				auto d = UTF8CharLength(line[cindex].mChar);
+
+				u.mRemovedStart = mState.mCursorPosition;
+				u.mRemovedEnd = Coordinates(coord.mLine, GetCharacterColumn(coord.mLine, cindex + d));
+
+				while (d-- > 0 && cindex < (int)line.size())
+				{
+					u.mRemoved += line[cindex].mChar;
+					line.erase(line.begin() + cindex);
+				}
+			}
+
+			for (auto p = buf; *p != '\0'; p++, ++cindex)
+				line.insert(line.begin() + cindex, Glyph(*p, PaletteIndex::Default));
+			u.mAdded = buf;
+
+			SetCursorPosition(Coordinates(coord.mLine, GetCharacterColumn(coord.mLine, cindex)));
+		}
+		else
+			return;
+	}
+
+	mTextChanged = true;
+
+	u.mAddedEnd = GetActualCursorCoordinates();
+	u.mAfter = mState;
+
+	AddUndo(u);
+
+	Colorize(coord.mLine - 1, 3);
+	EnsureCursorVisible();
+}
+
+void TextEditor::SetReadOnly(bool aValue)
+{
+	mReadOnly = aValue;
+}
+
+void TextEditor::SetColorizerEnable(bool aValue)
+{
+	mColorizerEnabled = aValue;
+}
+
+void TextEditor::SetCursorPosition(const Coordinates & aPosition)
+{
+	if (mState.mCursorPosition != aPosition)
+	{
+		mState.mCursorPosition = aPosition;
+		mCursorPositionChanged = true;
+		EnsureCursorVisible();
+	}
+}
+
+void TextEditor::SetSelectionStart(const Coordinates & aPosition)
+{
+	mState.mSelectionStart = SanitizeCoordinates(aPosition);
+	if (mState.mSelectionStart > mState.mSelectionEnd)
+		std::swap(mState.mSelectionStart, mState.mSelectionEnd);
+}
+
+void TextEditor::SetSelectionEnd(const Coordinates & aPosition)
+{
+	mState.mSelectionEnd = SanitizeCoordinates(aPosition);
+	if (mState.mSelectionStart > mState.mSelectionEnd)
+		std::swap(mState.mSelectionStart, mState.mSelectionEnd);
+}
+
+void TextEditor::SetSelection(const Coordinates & aStart, const Coordinates & aEnd, SelectionMode aMode)
+{
+	auto oldSelStart = mState.mSelectionStart;
+	auto oldSelEnd = mState.mSelectionEnd;
+
+	mState.mSelectionStart = SanitizeCoordinates(aStart);
+	mState.mSelectionEnd = SanitizeCoordinates(aEnd);
+	if (mState.mSelectionStart > mState.mSelectionEnd)
+		std::swap(mState.mSelectionStart, mState.mSelectionEnd);
+
+	switch (aMode)
+	{
+	case TextEditor::SelectionMode::Normal:
+		break;
+	case TextEditor::SelectionMode::Word:
+	{
+		mState.mSelectionStart = FindWordStart(mState.mSelectionStart);
+		if (!IsOnWordBoundary(mState.mSelectionEnd))
+			mState.mSelectionEnd = FindWordEnd(FindWordStart(mState.mSelectionEnd));
+		break;
+	}
+	case TextEditor::SelectionMode::Line:
+	{
+		const auto lineNo = mState.mSelectionEnd.mLine;
+		const auto lineSize = (size_t)lineNo < mLines.size() ? mLines[lineNo].size() : 0;
+		mState.mSelectionStart = Coordinates(mState.mSelectionStart.mLine, 0);
+		mState.mSelectionEnd = Coordinates(lineNo, GetLineMaxColumn(lineNo));
+		break;
+	}
+	default:
+		break;
+	}
+
+	if (mState.mSelectionStart != oldSelStart ||
+		mState.mSelectionEnd != oldSelEnd)
+		mCursorPositionChanged = true;
+}
+
+void TextEditor::SetTabSize(int aValue)
+{
+	mTabSize = std::max(0, std::min(32, aValue));
+}
+
+void TextEditor::InsertText(const std::string & aValue)
+{
+	InsertText(aValue.c_str());
+}
+
+void TextEditor::InsertText(const char * aValue)
+{
+	if (aValue == nullptr)
+		return;
+
+	auto pos = GetActualCursorCoordinates();
+	auto start = std::min(pos, mState.mSelectionStart);
+	int totalLines = pos.mLine - start.mLine;
+
+	totalLines += InsertTextAt(pos, aValue);
+
+	SetSelection(pos, pos);
+	SetCursorPosition(pos);
+	Colorize(start.mLine - 1, totalLines + 2);
+}
+
+void TextEditor::DeleteSelection()
+{
+	assert(mState.mSelectionEnd >= mState.mSelectionStart);
+
+	if (mState.mSelectionEnd == mState.mSelectionStart)
+		return;
+
+	DeleteRange(mState.mSelectionStart, mState.mSelectionEnd);
+
+	SetSelection(mState.mSelectionStart, mState.mSelectionStart);
+	SetCursorPosition(mState.mSelectionStart);
+	Colorize(mState.mSelectionStart.mLine, 1);
+}
+
+void TextEditor::MoveUp(int aAmount, bool aSelect)
+{
+	auto oldPos = mState.mCursorPosition;
+	mState.mCursorPosition.mLine = std::max(0, mState.mCursorPosition.mLine - aAmount);
+	if (oldPos != mState.mCursorPosition)
+	{
+		if (aSelect)
+		{
+			if (oldPos == mInteractiveStart)
+				mInteractiveStart = mState.mCursorPosition;
+			else if (oldPos == mInteractiveEnd)
+				mInteractiveEnd = mState.mCursorPosition;
+			else
+			{
+				mInteractiveStart = mState.mCursorPosition;
+				mInteractiveEnd = oldPos;
+			}
+		}
+		else
+			mInteractiveStart = mInteractiveEnd = mState.mCursorPosition;
+		SetSelection(mInteractiveStart, mInteractiveEnd);
+
+		EnsureCursorVisible();
+	}
+}
+
+void TextEditor::MoveDown(int aAmount, bool aSelect)
+{
+	assert(mState.mCursorPosition.mColumn >= 0);
+	auto oldPos = mState.mCursorPosition;
+	mState.mCursorPosition.mLine = std::max(0, std::min((int)mLines.size() - 1, mState.mCursorPosition.mLine + aAmount));
+
+	if (mState.mCursorPosition != oldPos)
+	{
+		if (aSelect)
+		{
+			if (oldPos == mInteractiveEnd)
+				mInteractiveEnd = mState.mCursorPosition;
+			else if (oldPos == mInteractiveStart)
+				mInteractiveStart = mState.mCursorPosition;
+			else
+			{
+				mInteractiveStart = oldPos;
+				mInteractiveEnd = mState.mCursorPosition;
+			}
+		}
+		else
+			mInteractiveStart = mInteractiveEnd = mState.mCursorPosition;
+		SetSelection(mInteractiveStart, mInteractiveEnd);
+
+		EnsureCursorVisible();
+	}
+}
+
+static bool IsUTFSequence(char c)
+{
+	return (c & 0xC0) == 0x80;
+}
+
+void TextEditor::MoveLeft(int aAmount, bool aSelect, bool aWordMode)
+{
+	if (mLines.empty())
+		return;
+
+	auto oldPos = mState.mCursorPosition;
+	mState.mCursorPosition = GetActualCursorCoordinates();
+	auto line = mState.mCursorPosition.mLine;
+	auto cindex = GetCharacterIndex(mState.mCursorPosition);
+
+	while (aAmount-- > 0)
+	{
+		if (cindex == 0)
+		{
+			if (line > 0)
+			{
+				--line;
+				if ((int)mLines.size() > line)
+					cindex = (int)mLines[line].size();
+				else
+					cindex = 0;
+			}
+		}
+		else
+		{
+			--cindex;
+			if (cindex > 0)
+			{
+				if ((int)mLines.size() > line)
+				{
+					while (cindex > 0 && IsUTFSequence(mLines[line][cindex].mChar))
+						--cindex;
+				}
+			}
+		}
+
+		mState.mCursorPosition = Coordinates(line, GetCharacterColumn(line, cindex));
+		if (aWordMode)
+		{
+			mState.mCursorPosition = FindWordStart(mState.mCursorPosition);
+			cindex = GetCharacterIndex(mState.mCursorPosition);
+		}
+	}
+
+	mState.mCursorPosition = Coordinates(line, GetCharacterColumn(line, cindex));
+
+	assert(mState.mCursorPosition.mColumn >= 0);
+	if (aSelect)
+	{
+		if (oldPos == mInteractiveStart)
+			mInteractiveStart = mState.mCursorPosition;
+		else if (oldPos == mInteractiveEnd)
+			mInteractiveEnd = mState.mCursorPosition;
+		else
+		{
+			mInteractiveStart = mState.mCursorPosition;
+			mInteractiveEnd = oldPos;
+		}
+	}
+	else
+		mInteractiveStart = mInteractiveEnd = mState.mCursorPosition;
+	SetSelection(mInteractiveStart, mInteractiveEnd, aSelect && aWordMode ? SelectionMode::Word : SelectionMode::Normal);
+
+	EnsureCursorVisible();
+}
+
+void TextEditor::MoveRight(int aAmount, bool aSelect, bool aWordMode)
+{
+	auto oldPos = mState.mCursorPosition;
+
+	if (mLines.empty() || oldPos.mLine >= mLines.size())
+		return;
+
+	auto cindex = GetCharacterIndex(mState.mCursorPosition);
+	while (aAmount-- > 0)
+	{
+		auto lindex = mState.mCursorPosition.mLine;
+		auto& line = mLines[lindex];
+
+		if (cindex >= line.size())
+		{
+			if (mState.mCursorPosition.mLine < mLines.size() - 1)
+			{
+				mState.mCursorPosition.mLine = std::max(0, std::min((int)mLines.size() - 1, mState.mCursorPosition.mLine + 1));
+				mState.mCursorPosition.mColumn = 0;
+			}
+			else
+				return;
+		}
+		else
+		{
+			cindex += UTF8CharLength(line[cindex].mChar);
+			mState.mCursorPosition = Coordinates(lindex, GetCharacterColumn(lindex, cindex));
+			if (aWordMode)
+				mState.mCursorPosition = FindNextWord(mState.mCursorPosition);
+		}
+	}
+
+	if (aSelect)
+	{
+		if (oldPos == mInteractiveEnd)
+			mInteractiveEnd = SanitizeCoordinates(mState.mCursorPosition);
+		else if (oldPos == mInteractiveStart)
+			mInteractiveStart = mState.mCursorPosition;
+		else
+		{
+			mInteractiveStart = oldPos;
+			mInteractiveEnd = mState.mCursorPosition;
+		}
+	}
+	else
+		mInteractiveStart = mInteractiveEnd = mState.mCursorPosition;
+	SetSelection(mInteractiveStart, mInteractiveEnd, aSelect && aWordMode ? SelectionMode::Word : SelectionMode::Normal);
+
+	EnsureCursorVisible();
+}
+
+void TextEditor::MoveTop(bool aSelect)
+{
+	auto oldPos = mState.mCursorPosition;
+	SetCursorPosition(Coordinates(0, 0));
+
+	if (mState.mCursorPosition != oldPos)
+	{
+		if (aSelect)
+		{
+			mInteractiveEnd = oldPos;
+			mInteractiveStart = mState.mCursorPosition;
+		}
+		else
+			mInteractiveStart = mInteractiveEnd = mState.mCursorPosition;
+		SetSelection(mInteractiveStart, mInteractiveEnd);
+	}
+}
+
+void TextEditor::TextEditor::MoveBottom(bool aSelect)
+{
+	auto oldPos = GetCursorPosition();
+	auto newPos = Coordinates((int)mLines.size() - 1, 0);
+	SetCursorPosition(newPos);
+	if (aSelect)
+	{
+		mInteractiveStart = oldPos;
+		mInteractiveEnd = newPos;
+	}
+	else
+		mInteractiveStart = mInteractiveEnd = newPos;
+	SetSelection(mInteractiveStart, mInteractiveEnd);
+}
+
+void TextEditor::MoveHome(bool aSelect)
+{
+	auto oldPos = mState.mCursorPosition;
+	SetCursorPosition(Coordinates(mState.mCursorPosition.mLine, 0));
+
+	if (mState.mCursorPosition != oldPos)
+	{
+		if (aSelect)
+		{
+			if (oldPos == mInteractiveStart)
+				mInteractiveStart = mState.mCursorPosition;
+			else if (oldPos == mInteractiveEnd)
+				mInteractiveEnd = mState.mCursorPosition;
+			else
+			{
+				mInteractiveStart = mState.mCursorPosition;
+				mInteractiveEnd = oldPos;
+			}
+		}
+		else
+			mInteractiveStart = mInteractiveEnd = mState.mCursorPosition;
+		SetSelection(mInteractiveStart, mInteractiveEnd);
+	}
+}
+
+void TextEditor::MoveEnd(bool aSelect)
+{
+	auto oldPos = mState.mCursorPosition;
+	SetCursorPosition(Coordinates(mState.mCursorPosition.mLine, GetLineMaxColumn(oldPos.mLine)));
+
+	if (mState.mCursorPosition != oldPos)
+	{
+		if (aSelect)
+		{
+			if (oldPos == mInteractiveEnd)
+				mInteractiveEnd = mState.mCursorPosition;
+			else if (oldPos == mInteractiveStart)
+				mInteractiveStart = mState.mCursorPosition;
+			else
+			{
+				mInteractiveStart = oldPos;
+				mInteractiveEnd = mState.mCursorPosition;
+			}
+		}
+		else
+			mInteractiveStart = mInteractiveEnd = mState.mCursorPosition;
+		SetSelection(mInteractiveStart, mInteractiveEnd);
+	}
+}
+
+void TextEditor::Delete()
+{
+	assert(!mReadOnly);
+
+	if (mLines.empty())
+		return;
+
+	UndoRecord u;
+	u.mBefore = mState;
+
+	if (HasSelection())
+	{
+		u.mRemoved = GetSelectedText();
+		u.mRemovedStart = mState.mSelectionStart;
+		u.mRemovedEnd = mState.mSelectionEnd;
+
+		DeleteSelection();
+	}
+	else
+	{
+		auto pos = GetActualCursorCoordinates();
+		SetCursorPosition(pos);
+		auto& line = mLines[pos.mLine];
+
+		if (pos.mColumn == GetLineMaxColumn(pos.mLine))
+		{
+			if (pos.mLine == (int)mLines.size() - 1)
+				return;
+
+			u.mRemoved = '\n';
+			u.mRemovedStart = u.mRemovedEnd = GetActualCursorCoordinates();
+			Advance(u.mRemovedEnd);
+
+			auto& nextLine = mLines[pos.mLine + 1];
+			line.insert(line.end(), nextLine.begin(), nextLine.end());
+			RemoveLine(pos.mLine + 1);
+		}
+		else
+		{
+			auto cindex = GetCharacterIndex(pos);
+			u.mRemovedStart = u.mRemovedEnd = GetActualCursorCoordinates();
+			u.mRemovedEnd.mColumn++;
+			u.mRemoved = GetText(u.mRemovedStart, u.mRemovedEnd);
+
+			auto d = UTF8CharLength(line[cindex].mChar);
+			while (d-- > 0 && cindex < (int)line.size())
+				line.erase(line.begin() + cindex);
+		}
+
+		mTextChanged = true;
+
+		Colorize(pos.mLine, 1);
+	}
+
+	u.mAfter = mState;
+	AddUndo(u);
+}
+
+void TextEditor::Backspace()
+{
+	assert(!mReadOnly);
+
+	if (mLines.empty())
+		return;
+
+	UndoRecord u;
+	u.mBefore = mState;
+
+	if (HasSelection())
+	{
+		u.mRemoved = GetSelectedText();
+		u.mRemovedStart = mState.mSelectionStart;
+		u.mRemovedEnd = mState.mSelectionEnd;
+
+		DeleteSelection();
+	}
+	else
+	{
+		auto pos = GetActualCursorCoordinates();
+		SetCursorPosition(pos);
+
+		if (mState.mCursorPosition.mColumn == 0)
+		{
+			if (mState.mCursorPosition.mLine == 0)
+				return;
+
+			u.mRemoved = '\n';
+			u.mRemovedStart = u.mRemovedEnd = Coordinates(pos.mLine - 1, GetLineMaxColumn(pos.mLine - 1));
+			Advance(u.mRemovedEnd);
+
+			auto& line = mLines[mState.mCursorPosition.mLine];
+			auto& prevLine = mLines[mState.mCursorPosition.mLine - 1];
+			auto prevSize = GetLineMaxColumn(mState.mCursorPosition.mLine - 1);
+			prevLine.insert(prevLine.end(), line.begin(), line.end());
+
+			ErrorMarkers etmp;
+			for (auto& i : mErrorMarkers)
+				etmp.insert(ErrorMarkers::value_type(i.first - 1 == mState.mCursorPosition.mLine ? i.first - 1 : i.first, i.second));
+			mErrorMarkers = std::move(etmp);
+
+			RemoveLine(mState.mCursorPosition.mLine);
+			--mState.mCursorPosition.mLine;
+			mState.mCursorPosition.mColumn = prevSize;
+		}
+		else
+		{
+			auto& line = mLines[mState.mCursorPosition.mLine];
+			auto cindex = GetCharacterIndex(pos) - 1;
+			auto cend = cindex + 1;
+			while (cindex > 0 && IsUTFSequence(line[cindex].mChar))
+				--cindex;
+
+			//if (cindex > 0 && UTF8CharLength(line[cindex].mChar) > 1)
+			//	--cindex;
+
+			u.mRemovedStart = u.mRemovedEnd = GetActualCursorCoordinates();
+			--u.mRemovedStart.mColumn;
+			--mState.mCursorPosition.mColumn;
+
+			while (cindex < line.size() && cend-- > cindex)
+			{
+				u.mRemoved += line[cindex].mChar;
+				line.erase(line.begin() + cindex);
+			}
+		}
+
+		mTextChanged = true;
+
+		EnsureCursorVisible();
+		Colorize(mState.mCursorPosition.mLine, 1);
+	}
+
+	u.mAfter = mState;
+	AddUndo(u);
+}
+
+void TextEditor::SelectWordUnderCursor()
+{
+	auto c = GetCursorPosition();
+	SetSelection(FindWordStart(c), FindWordEnd(c));
+}
+
+void TextEditor::SelectAll()
+{
+	SetSelection(Coordinates(0, 0), Coordinates((int)mLines.size(), 0));
+}
+
+bool TextEditor::HasSelection() const
+{
+	return mState.mSelectionEnd > mState.mSelectionStart;
+}
+
+void TextEditor::Copy()
+{
+	if (HasSelection())
+	{
+		ImGui::SetClipboardText(GetSelectedText().c_str());
+	}
+	else
+	{
+		if (!mLines.empty())
+		{
+			std::string str;
+			auto& line = mLines[GetActualCursorCoordinates().mLine];
+			for (auto& g : line)
+				str.push_back(g.mChar);
+			ImGui::SetClipboardText(str.c_str());
+		}
+	}
+}
+
+void TextEditor::Cut()
+{
+	if (IsReadOnly())
+	{
+		Copy();
+	}
+	else
+	{
+		if (HasSelection())
+		{
+			UndoRecord u;
+			u.mBefore = mState;
+			u.mRemoved = GetSelectedText();
+			u.mRemovedStart = mState.mSelectionStart;
+			u.mRemovedEnd = mState.mSelectionEnd;
+
+			Copy();
+			DeleteSelection();
+
+			u.mAfter = mState;
+			AddUndo(u);
+		}
+	}
+}
+
+void TextEditor::Paste()
+{
+	if (IsReadOnly())
+		return;
+
+	auto clipText = ImGui::GetClipboardText();
+	if (clipText != nullptr && strlen(clipText) > 0)
+	{
+		UndoRecord u;
+		u.mBefore = mState;
+
+		if (HasSelection())
+		{
+			u.mRemoved = GetSelectedText();
+			u.mRemovedStart = mState.mSelectionStart;
+			u.mRemovedEnd = mState.mSelectionEnd;
+			DeleteSelection();
+		}
+
+		u.mAdded = clipText;
+		u.mAddedStart = GetActualCursorCoordinates();
+
+		InsertText(clipText);
+
+		u.mAddedEnd = GetActualCursorCoordinates();
+		u.mAfter = mState;
+		AddUndo(u);
+	}
+}
+
+bool TextEditor::CanUndo() const
+{
+	return !mReadOnly && mUndoIndex > 0;
+}
+
+bool TextEditor::CanRedo() const
+{
+	return !mReadOnly && mUndoIndex < (int)mUndoBuffer.size();
+}
+
+void TextEditor::Undo(int aSteps)
+{
+	while (CanUndo() && aSteps-- > 0)
+		mUndoBuffer[--mUndoIndex].Undo(this);
+}
+
+void TextEditor::Redo(int aSteps)
+{
+	while (CanRedo() && aSteps-- > 0)
+		mUndoBuffer[mUndoIndex++].Redo(this);
+}
+
+const TextEditor::Palette & TextEditor::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 TextEditor::Palette & TextEditor::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 TextEditor::Palette & TextEditor::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 TextEditor::GetText() const
+{
+	return GetText(Coordinates(), Coordinates((int)mLines.size(), 0));
+}
+
+std::vector<std::string> TextEditor::GetTextLines() const
+{
+	std::vector<std::string> result;
+
+	result.reserve(mLines.size());
+
+	for (auto & line : mLines)
+	{
+		std::string text;
+
+		text.resize(line.size());
+
+		for (size_t i = 0; i < line.size(); ++i)
+			text[i] = line[i].mChar;
+
+		result.emplace_back(std::move(text));
+	}
+
+	return result;
+}
+
+std::string TextEditor::GetSelectedText() const
+{
+	return GetText(mState.mSelectionStart, mState.mSelectionEnd);
+}
+
+std::string TextEditor::GetCurrentLineText()const
+{
+	auto lineLength = GetLineMaxColumn(mState.mCursorPosition.mLine);
+	return GetText(
+		Coordinates(mState.mCursorPosition.mLine, 0),
+		Coordinates(mState.mCursorPosition.mLine, lineLength));
+}
+
+void TextEditor::ProcessInputs()
+{
+}
+
+void TextEditor::Colorize(int aFromLine, int aLines)
+{
+	int toLine = aLines == -1 ? (int)mLines.size() : std::min((int)mLines.size(), aFromLine + aLines);
+	mColorRangeMin = std::min(mColorRangeMin, aFromLine);
+	mColorRangeMax = std::max(mColorRangeMax, toLine);
+	mColorRangeMin = std::max(0, mColorRangeMin);
+	mColorRangeMax = std::max(mColorRangeMin, mColorRangeMax);
+	mCheckComments = true;
+}
+
+void TextEditor::ColorizeRange(int aFromLine, int aToLine)
+{
+	if (mLines.empty() || aFromLine >= aToLine)
+		return;
+
+	std::string buffer;
+	std::cmatch results;
+	std::string id;
+
+	int endLine = std::max(0, std::min((int)mLines.size(), aToLine));
+	for (int i = aFromLine; i < endLine; ++i)
+	{
+		auto& line = mLines[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.mChar;
+			col.mColorIndex = 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 (mLanguageDefinition.mTokenize != nullptr)
+			{
+				if (mLanguageDefinition.mTokenize(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 : mRegexList)
+				{
+					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 (!mLanguageDefinition.mCaseSensitive)
+						std::transform(id.begin(), id.end(), id.begin(), ::toupper);
+
+					if (!line[first - bufferBegin].mPreprocessor)
+					{
+						if (mLanguageDefinition.mKeywords.count(id) != 0)
+							token_color = PaletteIndex::Keyword;
+						else if (mLanguageDefinition.mIdentifiers.count(id) != 0)
+							token_color = PaletteIndex::KnownIdentifier;
+						else if (mLanguageDefinition.mPreprocIdentifiers.count(id) != 0)
+							token_color = PaletteIndex::PreprocIdentifier;
+					}
+					else
+					{
+						if (mLanguageDefinition.mPreprocIdentifiers.count(id) != 0)
+							token_color = PaletteIndex::PreprocIdentifier;
+					}
+				}
+
+				for (size_t j = 0; j < token_length; ++j)
+					line[(token_begin - bufferBegin) + j].mColorIndex = token_color;
+
+				first = token_end;
+			}
+		}
+	}
+}
+
+void TextEditor::ColorizeInternal()
+{
+	if (mLines.empty() || !mColorizerEnabled)
+		return;
+
+	if (mCheckComments)
+	{
+		auto endLine = mLines.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 = mLines[currentLine];
+
+			if (currentIndex == 0 && !concatenate)
+			{
+				withinSingleLineComment = false;
+				withinPreproc = false;
+				firstChar = true;
+			}
+
+			concatenate = false;
+
+			if (!line.empty())
+			{
+				auto& g = line[currentIndex];
+				auto c = g.mChar;
+
+				if (c != mLanguageDefinition.mPreprocChar && !isspace(c))
+					firstChar = false;
+
+				if (currentIndex == (int)line.size() - 1 && line[line.size() - 1].mChar == '\\')
+					concatenate = true;
+
+				bool inComment = (commentStartLine < currentLine || (commentStartLine == currentLine && commentStartIndex <= currentIndex));
+
+				if (withinString)
+				{
+					line[currentIndex].mMultiLineComment = inComment;
+
+					if (c == '\"')
+					{
+						if (currentIndex + 1 < (int)line.size() && line[currentIndex + 1].mChar == '\"')
+						{
+							currentIndex += 1;
+							if (currentIndex < (int)line.size())
+								line[currentIndex].mMultiLineComment = inComment;
+						}
+						else
+							withinString = false;
+					}
+					else if (c == '\\')
+					{
+						currentIndex += 1;
+						if (currentIndex < (int)line.size())
+							line[currentIndex].mMultiLineComment = inComment;
+					}
+				}
+				else
+				{
+					if (firstChar && c == mLanguageDefinition.mPreprocChar)
+						withinPreproc = true;
+
+					if (c == '\"')
+					{
+						withinString = true;
+						line[currentIndex].mMultiLineComment = inComment;
+					}
+					else
+					{
+						auto pred = [](const char& a, const Glyph& b) { return a == b.mChar; };
+						auto from = line.begin() + currentIndex;
+						auto& startStr = mLanguageDefinition.mCommentStart;
+						auto& singleStartStr = mLanguageDefinition.mSingleLineComment;
+
+						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].mMultiLineComment = inComment;
+						line[currentIndex].mComment = withinSingleLineComment;
+
+						auto& endStr = mLanguageDefinition.mCommentEnd;
+						if (currentIndex + 1 >= (int)endStr.size() &&
+							equals(endStr.begin(), endStr.end(), from + 1 - endStr.size(), from + 1, pred))
+						{
+							commentStartIndex = endIndex;
+							commentStartLine = endLine;
+						}
+					}
+				}
+				line[currentIndex].mPreprocessor = withinPreproc;
+				currentIndex += UTF8CharLength(c);
+				if (currentIndex >= (int)line.size())
+				{
+					currentIndex = 0;
+					++currentLine;
+				}
+			}
+			else
+			{
+				currentIndex = 0;
+				++currentLine;
+			}
+		}
+		mCheckComments = false;
+	}
+
+	if (mColorRangeMin < mColorRangeMax)
+	{
+		const int increment = (mLanguageDefinition.mTokenize == nullptr) ? 10 : 10000;
+		const int to = std::min(mColorRangeMin + increment, mColorRangeMax);
+		ColorizeRange(mColorRangeMin, to);
+		mColorRangeMin = to;
+
+		if (mColorRangeMax == mColorRangeMin)
+		{
+			mColorRangeMin = std::numeric_limits<int>::max();
+			mColorRangeMax = 0;
+		}
+		return;
+	}
+}
+
+float TextEditor::TextDistanceToLineStart(const Coordinates& aFrom) const
+{
+	auto& line = mLines[aFrom.mLine];
+	float distance = 0.0f;
+	float spaceSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, " ", nullptr, nullptr).x;
+	int colIndex = GetCharacterIndex(aFrom);
+	for (size_t it = 0u; it < line.size() && it < colIndex; )
+	{
+		if (line[it].mChar == '\t')
+		{
+			distance = (1.0f + std::floor((1.0f + distance) / (float(mTabSize) * spaceSize))) * (float(mTabSize) * spaceSize);
+			++it;
+		}
+		else
+		{
+			auto d = UTF8CharLength(line[it].mChar);
+			char tempCString[7];
+			int i = 0;
+			for (; i < 6 && d-- > 0 && it < (int)line.size(); i++, it++)
+				tempCString[i] = line[it].mChar;
+
+			tempCString[i] = '\0';
+			distance += ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, tempCString, nullptr, nullptr).x;
+		}
+	}
+
+	return distance;
+}
+
+void TextEditor::EnsureCursorVisible()
+{
+	if (!mWithinRender)
+	{
+		mScrollToCursor = true;
+		return;
+	}
+
+	float scrollX = ImGui::GetScrollX();
+	float scrollY = ImGui::GetScrollY();
+
+	auto height = ImGui::GetWindowHeight();
+	auto width = ImGui::GetWindowWidth();
+
+	auto top = 1 + (int)ceil(scrollY / mCharAdvance.y);
+	auto bottom = (int)ceil((scrollY + height) / mCharAdvance.y);
+
+	auto left = (int)ceil(scrollX / mCharAdvance.x);
+	auto right = (int)ceil((scrollX + width) / mCharAdvance.x);
+
+	auto pos = GetActualCursorCoordinates();
+	auto len = TextDistanceToLineStart(pos);
+
+	if (pos.mLine < top)
+		ImGui::SetScrollY(std::max(0.0f, (pos.mLine - 1) * mCharAdvance.y));
+	if (pos.mLine > bottom - 4)
+		ImGui::SetScrollY(std::max(0.0f, (pos.mLine + 4) * mCharAdvance.y - height));
+	if (len + mTextStart < left + 4)
+		ImGui::SetScrollX(std::max(0.0f, len + mTextStart - 4));
+	if (len + mTextStart > right - 4)
+		ImGui::SetScrollX(std::max(0.0f, len + mTextStart + 4 - width));
+}
+
+int TextEditor::GetPageSize() const
+{
+	auto height = ImGui::GetWindowHeight() - 20.0f;
+	return (int)floor(height / mCharAdvance.y);
+}
+
+TextEditor::UndoRecord::UndoRecord(
+	const std::string& aAdded,
+	const TextEditor::Coordinates aAddedStart,
+	const TextEditor::Coordinates aAddedEnd,
+	const std::string& aRemoved,
+	const TextEditor::Coordinates aRemovedStart,
+	const TextEditor::Coordinates aRemovedEnd,
+	TextEditor::EditorState& aBefore,
+	TextEditor::EditorState& aAfter)
+	: mAdded(aAdded)
+	, mAddedStart(aAddedStart)
+	, mAddedEnd(aAddedEnd)
+	, mRemoved(aRemoved)
+	, mRemovedStart(aRemovedStart)
+	, mRemovedEnd(aRemovedEnd)
+	, mBefore(aBefore)
+	, mAfter(aAfter)
+{
+	assert(mAddedStart <= mAddedEnd);
+	assert(mRemovedStart <= mRemovedEnd);
+}
+
+void TextEditor::UndoRecord::Undo(TextEditor * aEditor)
+{
+	if (!mAdded.empty())
+	{
+		aEditor->DeleteRange(mAddedStart, mAddedEnd);
+		aEditor->Colorize(mAddedStart.mLine - 1, mAddedEnd.mLine - mAddedStart.mLine + 2);
+	}
+
+	if (!mRemoved.empty())
+	{
+		auto start = mRemovedStart;
+		aEditor->InsertTextAt(start, mRemoved.c_str());
+		aEditor->Colorize(mRemovedStart.mLine - 1, mRemovedEnd.mLine - mRemovedStart.mLine + 2);
+	}
+
+	aEditor->mState = mBefore;
+	aEditor->EnsureCursorVisible();
+
+}
+
+void TextEditor::UndoRecord::Redo(TextEditor * aEditor)
+{
+	if (!mRemoved.empty())
+	{
+		aEditor->DeleteRange(mRemovedStart, mRemovedEnd);
+		aEditor->Colorize(mRemovedStart.mLine - 1, mRemovedEnd.mLine - mRemovedStart.mLine + 1);
+	}
+
+	if (!mAdded.empty())
+	{
+		auto start = mAddedStart;
+		aEditor->InsertTextAt(start, mAdded.c_str());
+		aEditor->Colorize(mAddedStart.mLine - 1, mAddedEnd.mLine - mAddedStart.mLine + 1);
+	}
+
+	aEditor->mState = mAfter;
+	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 TextEditor::LanguageDefinition& TextEditor::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.mKeywords.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.mDeclaration = "Built-in function";
+			langDef.mIdentifiers.insert(std::make_pair(std::string(k), id));
+		}
+
+		langDef.mTokenize = [](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.mCommentStart = "/*";
+		langDef.mCommentEnd = "*/";
+		langDef.mSingleLineComment = "//";
+
+		langDef.mCaseSensitive = true;
+		langDef.mAutoIndentation = true;
+
+		langDef.mName = "C++";
+
+		inited = true;
+	}
+	return langDef;
+}
+
+const TextEditor::LanguageDefinition& TextEditor::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.mKeywords.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.mDeclaration = "Built-in function";
+			langDef.mIdentifiers.insert(std::make_pair(std::string(k), id));
+		}
+
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[ \\t]*#[ \\t]*[a-zA-Z_]+", PaletteIndex::Preprocessor));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\'\\\\?[^\\']\\'", PaletteIndex::CharLiteral));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[0-7]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
+
+		langDef.mCommentStart = "/*";
+		langDef.mCommentEnd = "*/";
+		langDef.mSingleLineComment = "//";
+
+		langDef.mCaseSensitive = true;
+		langDef.mAutoIndentation = true;
+
+		langDef.mName = "HLSL";
+
+		inited = true;
+	}
+	return langDef;
+}
+
+const TextEditor::LanguageDefinition& TextEditor::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.mKeywords.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.mDeclaration = "Built-in function";
+			langDef.mIdentifiers.insert(std::make_pair(std::string(k), id));
+		}
+
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[ \\t]*#[ \\t]*[a-zA-Z_]+", PaletteIndex::Preprocessor));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\'\\\\?[^\\']\\'", PaletteIndex::CharLiteral));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[0-7]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
+
+		langDef.mCommentStart = "/*";
+		langDef.mCommentEnd = "*/";
+		langDef.mSingleLineComment = "//";
+
+		langDef.mCaseSensitive = true;
+		langDef.mAutoIndentation = true;
+
+		langDef.mName = "GLSL";
+
+		inited = true;
+	}
+	return langDef;
+}
+
+const TextEditor::LanguageDefinition& TextEditor::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.mKeywords.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.mDeclaration = "Built-in function";
+			langDef.mIdentifiers.insert(std::make_pair(std::string(k), id));
+		}
+
+		langDef.mTokenize = [](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.mCommentStart = "/*";
+		langDef.mCommentEnd = "*/";
+		langDef.mSingleLineComment = "//";
+
+		langDef.mCaseSensitive = true;
+		langDef.mAutoIndentation = true;
+
+		langDef.mName = "C";
+
+		inited = true;
+	}
+	return langDef;
+}
+
+const TextEditor::LanguageDefinition& TextEditor::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.mKeywords.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.mDeclaration = "Built-in function";
+			langDef.mIdentifiers.insert(std::make_pair(std::string(k), id));
+		}
+
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\\'[^\\\']*\\\'", PaletteIndex::String));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[0-7]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
+
+		langDef.mCommentStart = "/*";
+		langDef.mCommentEnd = "*/";
+		langDef.mSingleLineComment = "//";
+
+		langDef.mCaseSensitive = false;
+		langDef.mAutoIndentation = false;
+
+		langDef.mName = "SQL";
+
+		inited = true;
+	}
+	return langDef;
+}
+
+const TextEditor::LanguageDefinition& TextEditor::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.mKeywords.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.mDeclaration = "Built-in function";
+			langDef.mIdentifiers.insert(std::make_pair(std::string(k), id));
+		}
+
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\'\\\\?[^\\']\\'", PaletteIndex::String));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[0-7]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
+
+		langDef.mCommentStart = "/*";
+		langDef.mCommentEnd = "*/";
+		langDef.mSingleLineComment = "//";
+
+		langDef.mCaseSensitive = true;
+		langDef.mAutoIndentation = true;
+
+		langDef.mName = "AngelScript";
+
+		inited = true;
+	}
+	return langDef;
+}
+
+const TextEditor::LanguageDefinition& TextEditor::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.mKeywords.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.mDeclaration = "Built-in function";
+			langDef.mIdentifiers.insert(std::make_pair(std::string(k), id));
+		}
+
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("\\\'[^\\\']*\\\'", PaletteIndex::String));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[+-]?[0-9]+[Uu]?[lL]?[lL]?", PaletteIndex::Number));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[a-zA-Z_][a-zA-Z0-9_]*", PaletteIndex::Identifier));
+		langDef.mTokenRegexStrings.push_back(std::make_pair<std::string, PaletteIndex>("[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/\\;\\,\\.]", PaletteIndex::Punctuation));
+
+		langDef.mCommentStart = "--[[";
+		langDef.mCommentEnd = "]]";
+		langDef.mSingleLineComment = "--";
+
+		langDef.mCaseSensitive = true;
+		langDef.mAutoIndentation = false;
+
+		langDef.mName = "Lua";
+
+		inited = true;
+	}
+	return langDef;
+}
