diff --git a/.gitignore b/.gitignore
index 0da26e3..9e9e867 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,6 @@
 *.out
 *.app
 TextEditor.cpp.bak
+*.bak
+Save/TextEditor.h
+Save/TextEditor.cpp
diff --git a/ImGuiTextEdit.png b/ImGuiTextEdit.png
index ec3455b..e9e1906 100644
--- a/ImGuiTextEdit.png
+++ b/ImGuiTextEdit.png
Binary files differ
diff --git a/README.md b/README.md
index 03cfc93..20506b6 100644
--- a/README.md
+++ b/README.md
@@ -1,35 +1,32 @@
 # ImGuiColorTextEdit
 Syntax highlighting text editor for ImGui
 
-![Screenshot](https://github.com/BalazsJako/ImGuiColorTextEdit/blob/master/ImGuiTextEdit.png "Screenshot")
+![Screenshot](https://github.com/BalazsJako/ImGuiColorTextEdit/blob/dev/ImGuiTextEdit.png "Screenshot")
 
 Demo project: https://github.com/BalazsJako/ColorTextEditorDemo
 
-This started as my attempt to write a relatively simple widget which provides source code editing functionality with basic syntax highlighting. Now there are other contributors who provide valuable additions.
+This started as my attempt to write a relatively simple widget which provides text editing functionality with syntax highlighting. Now there are other contributors who provide valuable additions.
 
-While it relies on Omar Cornut's https://github.com/ocornut/imgui, it does not follow the "pure" one widget - one function approach. Since the editor has to maintain a relatively complex and large internal state, it did not seem to be practical to try and enforce fully immediate mode.
+While it relies on Omar Cornut's https://github.com/ocornut/imgui, it does not follow the "pure" one widget - one function approach. Since the editor has to maintain a relatively complex and large internal state, it did not seem to be practical to try and enforce fully immediate mode. It stores its internal state in an object instance which is reused across frames.
 
 The code is (still) work in progress, please report if you find any issues.
 
 # Main features
  - approximates typical code editor look and feel (essential mouse/keyboard commands work - I mean, the commands _I_ normally use :))
- - undo/redo support
- - extensible, multiple language syntax support
- - identifier declarations: a small piece of text associated with an identifier. The editor displays it in a tooltip when the mouse cursor is hovered over the identifier
+ - undo/redo
+ - UTF-8 support
+ - works with both fixed and variable-width fonts
+ - extensible syntax highlighting for multiple languages
+ - identifier declarations: a small piece of description can be associated with an identifier. The editor displays it in a tooltip when the mouse cursor is hovered over the identifier
  - error markers: the user can specify a list of error messages together the line of occurence, the editor will highligh the lines with red backround and display error message in a tooltip when the mouse cursor is hovered over the line
- - supports large files: there is no explicit limit set on file size or number of lines, performance is not affected when large files are loaded (except syntax coloring, see below)
+ - large files: there is no explicit limit set on file size or number of lines (below 2GB, performance is not affected when large files are loaded (except syntax coloring, see below)
  - color palette support: you can switch between different color palettes, or even define your own
- - supports both fixed and variable-width fonts
  
 # Known issues
  - syntax highligthing of most languages - except C/C++ - is based on std::regex, which is diasppointingly slow. Because of that, the highlighting process is amortized between multiple frames. C/C++ has a hand-written tokenizer which is much faster. 
- - 8 bit character only, no Unicode or Utf support
- - no find/replace support
-
-Don't forget to post your screenshots if you use this little piece of software in order to keep me us motivated. :)
+ 
+Please post your screenshots if you find this little piece of software useful. :)
 
 # Contribute
 
 If you want to contribute, please refer to CONTRIBUTE file.
-
-Thank you. :)
diff --git a/TextEditor.cpp b/TextEditor.cpp
index 381b50e..8b30246 100644
--- a/TextEditor.cpp
+++ b/TextEditor.cpp
@@ -1,2747 +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
-// - handle unicode/utf
-// - testing
-
-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)
-	, mTextStart(20.0f)
-	, mLeftMargin(10)
-	, mColorRangeMin(0)
-	, mColorRangeMax(0)
-	, mSelectionMode(SelectionMode::Normal)
-	, mCheckComments(true)
-	, mLastClick(-1.0f)
-	, mHandleKeyboardInputs(true)
-	, mHandleMouseInputs(true)
-	, mIgnoreImGuiChild(false)
-{
-	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));
-}
-
-void TextEditor::SetPalette(const Palette & aValue)
-{
-	mPaletteBase = aValue;
-}
-
-int TextEditor::AppendBuffer(std::string& aBuffer, char chr, int aIndex)
-{
-	if (chr != '\t')
-	{
-		aBuffer.push_back(chr);
-		return aIndex + 1;
-	}
-	else
-	{
-		//auto num = mTabSize - aIndex % mTabSize;
-		//for (int j = num; j > 0; --j)
-		//	aBuffer.push_back(' ');
-		//return aIndex + num;
-		return aIndex;
-	}
-}
-
-std::string TextEditor::GetText(const Coordinates & aStart, const Coordinates & aEnd) const
-{
-	std::string result;
-
-	int prevLineNo = aStart.mLine;
-	for (auto it = aStart; it <= aEnd; Advance(it))
-	{
-		if (prevLineNo != it.mLine && it.mLine < (int)mLines.size())
-			result.push_back('\n');
-
-		if (it == aEnd)
-			break;
-
-		prevLineNo = it.mLine;
-		const auto& line = mLines[it.mLine];
-		if (!line.empty() && it.mColumn < (int)line.size())
-			result.push_back(line[it.mColumn].mChar);
-	}
-
-	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 = (int)mLines[line].size();
-		}
-	}
-	else
-	{
-		column = mLines.empty() ? 0 : std::min((int)mLines[line].size(), aValue.mColumn);
-	}
-
-	return Coordinates(line, column);
-}
-
-void TextEditor::Advance(Coordinates & aCoordinates) const
-{
-	if (aCoordinates.mLine < (int)mLines.size())
-	{
-		auto& line = mLines[aCoordinates.mLine];
-
-		if (aCoordinates.mColumn + 1 < (int)line.size())
-			++aCoordinates.mColumn;
-		else
-		{
-			++aCoordinates.mLine;
-			aCoordinates.mColumn = 0;
-		}
-	}
-}
-
-void TextEditor::DeleteRange(const Coordinates & aStart, const Coordinates & aEnd)
-{
-	assert(aEnd >= aStart);
-	assert(!mReadOnly);
-
-	if (aEnd == aStart)
-		return;
-
-	if (aStart.mLine == aEnd.mLine)
-	{
-		auto& line = mLines[aStart.mLine];
-		if (aEnd.mColumn >= (int)line.size())
-			line.erase(line.begin() + aStart.mColumn, line.end());
-		else
-			line.erase(line.begin() + aStart.mColumn, line.begin() + aEnd.mColumn);
-	}
-	else
-	{
-		auto& firstLine = mLines[aStart.mLine];
-		auto& lastLine = mLines[aEnd.mLine];
-
-		firstLine.erase(firstLine.begin() + aStart.mColumn, firstLine.end());
-		lastLine.erase(lastLine.begin(), lastLine.begin() + aEnd.mColumn);
-
-		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 totalLines = 0;
-	auto chr = *aValue;
-	while (chr != '\0')
-	{
-		assert(!mLines.empty());
-
-		if (chr == '\r')
-		{
-			// skip
-		}
-		else if (chr == '\n')
-		{
-			if (aWhere.mColumn < (int)mLines[aWhere.mLine].size())
-			{
-				auto& newLine = InsertLine(aWhere.mLine + 1);
-				auto& line = mLines[aWhere.mLine];
-				newLine.insert(newLine.begin(), line.begin() + aWhere.mColumn, line.end());
-				line.erase(line.begin() + aWhere.mColumn, line.end());
-			}
-			else
-			{
-				InsertLine(aWhere.mLine + 1);
-			}
-			++aWhere.mLine;
-			aWhere.mColumn = 0;
-			++totalLines;
-		}
-		else
-		{
-			auto& line = mLines[aWhere.mLine];
-			line.insert(line.begin() + aWhere.mColumn, Glyph(chr, PaletteIndex::Default));
-			++aWhere.mColumn;
-		}
-		chr = *(++aValue);
-
-		mTextChanged = true;
-	}
-
-	return totalLines;
-}
-
-void TextEditor::AddUndo(UndoRecord& aValue)
-{
-	assert(!mReadOnly);
-
-	mUndoBuffer.resize(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));
-
-	/*
-		Compute columnCoord according to text size
-	*/
-	int columnCoord = 0;
-	float columnWidth = 0.0f;
-	std::string cumulatedString = "";
-	float cumulatedStringWidth[2] = { 0.0f, 0.0f }; //( [0] is the lastest, [1] is the previous. I use that trick to check where cursor is exactly (important for tabs)
-
-	if (lineNo >= 0 && lineNo < (int)mLines.size())
-	{
-		auto& line = mLines.at(lineNo);
-
-		// First we find the hovered column coord.
-		while (mTextStart + cumulatedStringWidth[0] < local.x &&
-			(size_t)columnCoord < line.size())
-		{
-			cumulatedStringWidth[1] = cumulatedStringWidth[0];
-			cumulatedString += line[columnCoord].mChar;
-			cumulatedStringWidth[0] = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, cumulatedString.c_str(), nullptr, nullptr).x;
-			columnWidth = (cumulatedStringWidth[0] - cumulatedStringWidth[1]);
-			columnCoord++;
-		}
-
-		// Then we reduce by 1 column coord if cursor is on the left side of the hovered column.
-		if (mTextStart + cumulatedStringWidth[0] - columnWidth / 2.0f > local.x)
-			columnCoord = std::max(0, columnCoord - 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];
-
-	if (at.mColumn >= (int)line.size())
-		return at;
-
-	auto cstart = (PaletteIndex)line[at.mColumn].mColorIndex;
-	while (at.mColumn > 0)
-	{
-		if (cstart != (PaletteIndex)line[at.mColumn - 1].mColorIndex)
-			break;
-		--at.mColumn;
-	}
-	return at;
-}
-
-TextEditor::Coordinates TextEditor::FindWordEnd(const Coordinates & aFrom) const
-{
-	Coordinates at = aFrom;
-	if (at.mLine >= (int)mLines.size())
-		return at;
-
-	auto& line = mLines[at.mLine];
-
-	if (at.mColumn >= (int)line.size())
-		return at;
-
-	auto cstart = (PaletteIndex)line[at.mColumn].mColorIndex;
-	while (at.mColumn < (int)line.size())
-	{
-		if (cstart != (PaletteIndex)line[at.mColumn].mColorIndex)
-			break;
-		++at.mColumn;
-	}
-	return at;
-}
-
-bool TextEditor::IsOnWordBoundary(const Coordinates & aAt) const
-{
-	if (aAt.mLine >= (int)mLines.size() || aAt.mColumn == 0)
-		return true;
-
-	auto& line = mLines[aAt.mLine];
-	if (aAt.mColumn >= (int)line.size())
-		return true;
-
-	return line[aAt.mColumn].mColorIndex != line[aAt.mColumn - 1].mColorIndex;
-}
-
-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;
-
-	for (auto it = start; it < end; Advance(it))
-		r.push_back(mLines[it.mLine][it.mColumn].mChar);
-
-	return r;
-}
-
-ImU32 TextEditor::GetGlyphColor(const Glyph & aGlyph) const
-{
-	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::IsAnyItemHovered() && !ImGui::IsAnyItemFocused())
-			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);
-		else if (!IsReadOnly() && !ctrl)
-		{
-			for (int i = 0; i < io.InputQueueCharacters.Size; i++)
-			{
-				auto c = (unsigned char)io.InputQueueCharacters[i];
-				if (c != 0)
-				{
-					if (isprint(c) || isspace(c))
-					{
-						EnterCharacter((char)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);
-	}
-	
-	static std::string buffer;
-	assert(buffer.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())
-	{
-		auto fontScale = ImGui::GetFontSize() / ImGui::GetFont()->FontSize;
-		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, (int)line.size())), longest);
-			auto columnNo = 0;
-			Coordinates lineStartCoord(lineNo, 0);
-			Coordinates lineEndCoord(lineNo, (int)line.size());
-
-			// 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);
-
-			// Highlight the current line (where the cursor is)
-			if (mState.mCursorPosition.mLine == lineNo)
-			{
-				auto focused = ImGui::IsWindowFocused();
-
-				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);
-				}
-
-				float cx = TextDistanceToLineStart(mState.mCursorPosition);
-
-				if (focused)
-				{
-					static auto timeStart = std::chrono::system_clock::now();
-					auto timeEnd = std::chrono::system_clock::now();
-					auto diff = timeEnd - timeStart;
-					auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(diff).count();
-					if (elapsed > 400)
-					{
-						ImVec2 cstart(textScreenPos.x + cx, lineStartScreenPos.y);
-						ImVec2 cend(textScreenPos.x + cx + (mOverwrite ? mCharAdvance.x : 1.0f), lineStartScreenPos.y + mCharAdvance.y);
-						drawList->AddRectFilled(cstart, cend, mPalette[(int)PaletteIndex::Cursor]);
-						if (elapsed > 800)
-							timeStart = timeEnd;
-					}
-				}
-			}
-
-			// Render colorized text
-			auto prevColor = line.empty() ? mPalette[(int)PaletteIndex::Default] : GetGlyphColor(line[0]);
-			ImVec2 bufferOffset;
-
-			for (auto& glyph : line)
-			{
-				auto color = GetGlyphColor(glyph);
-
-				if ((color != prevColor || glyph.mChar == '\t') && !buffer.empty())
-				{
-					const ImVec2 newOffset(textScreenPos.x + bufferOffset.x, textScreenPos.y + bufferOffset.y);
-					drawList->AddText(newOffset, prevColor, buffer.c_str());
-					auto textSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, buffer.c_str(), nullptr, nullptr);
-					bufferOffset.x += textSize.x;
-					buffer.clear();
-				}
-				prevColor = color;
-
-				if (glyph.mChar == '\t')
-					bufferOffset.x = (1.0f * fontScale + std::floor((1.0f + bufferOffset.x)) / (float(mTabSize) * spaceSize)) * (float(mTabSize) * spaceSize);
-				else
-					AppendBuffer(buffer, glyph.mChar, 0);
-				++columnNo;
-			}
-
-			if (!buffer.empty())
-			{
-				const ImVec2 newOffset(textScreenPos.x + bufferOffset.x, textScreenPos.y + bufferOffset.y);
-				drawList->AddText(newOffset, prevColor, buffer.c_str());
-				buffer.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(Char aChar, bool aShift)
-{
-	assert(!mReadOnly);
-
-	UndoRecord u;
-
-	u.mBefore = mState;
-
-	if (HasSelection())
-	{
-		if (aChar == '\t')
-		{
-			auto start = mState.mSelectionStart;
-			auto end = mState.mSelectionEnd;
-
-			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;
-				end.mColumn = (int)mLines[end.mLine].size();
-			}
-
-			if (end.mColumn >= (int)mLines[end.mLine].size())
-				end.mColumn = (int)mLines[end.mLine].size() - 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() == false)
-					{
-						if (line.front().mChar == '\t')
-						{
-							line.erase(line.begin());
-							if (i == end.mLine && end.mColumn > 0)
-								end.mColumn--;
-							modified = true;
-						}
-					}
-					else
-					{
-						for (int j = 0; j < mTabSize && line.empty() == false && line.front().mChar == ' '; j++)
-						{
-							line.erase(line.begin());
-							if (i == end.mLine && end.mColumn > 0)
-								end.mColumn--;
-							modified = true;
-						}
-					}
-				}
-				else
-				{
-					line.insert(line.begin(), Glyph('\t', TextEditor::PaletteIndex::Background));
-					if (i == end.mLine)
-						++end.mColumn;
-					modified = true;
-				}
-			}
-
-			if (modified)
-			{
-				assert(mLines.size() > start.mLine && mLines[start.mLine].size() > start.mColumn);
-				assert(mLines.size() > end.mLine && mLines[end.mLine].size() > end.mColumn);
-				u.mAddedStart = start;
-				u.mAddedEnd = end;
-				u.mAdded = GetText(start, end);
-
-				mTextChanged = true;
-
-				AddUndo(u);
-				EnsureCursorVisible();
-			}
-
-			return;
-		}
-		else
-		{
-			u.mRemoved = GetSelectedText();
-			u.mRemovedStart = mState.mSelectionStart;
-			u.mRemovedEnd = mState.mSelectionEnd;
-			DeleteSelection();
-		}
-	}
-
-	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() && isblank(line[it].mChar); ++it)
-				newLine.push_back(line[it]);
-		}
-
-		const size_t whitespaceSize = newLine.size();
-		newLine.insert(newLine.end(), line.begin() + coord.mColumn, line.end());
-		line.erase(line.begin() + coord.mColumn, line.begin() + line.size());
-		SetCursorPosition(Coordinates(coord.mLine + 1, (int)whitespaceSize));
-	}
-	else
-	{
-		auto& line = mLines[coord.mLine];
-		if (mOverwrite && (int)line.size() > coord.mColumn)
-			line[coord.mColumn] = Glyph(aChar, PaletteIndex::Default);
-		else
-			line.insert(line.begin() + coord.mColumn, Glyph(aChar, PaletteIndex::Default));
-		SetCursorPosition(Coordinates(coord.mLine, coord.mColumn + 1));
-	}
-
-	mTextChanged = true;
-
-	u.mAdded = aChar;
-	u.mAddedEnd = GetActualCursorCoordinates();
-	u.mAfter = mState;
-
-	AddUndo(u);
-
-	Colorize(coord.mLine - 1, 3);
-	EnsureCursorVisible();
-}
-
-void TextEditor::SetReadOnly(bool aValue)
-{
-	mReadOnly = 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 (aStart > aEnd)
-		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, (int)lineSize);
-		break;
-	}
-	default:
-		break;
-	}
-
-	if (mState.mSelectionStart != oldSelStart ||
-		mState.mSelectionEnd != oldSelEnd)
-		mCursorPositionChanged = true;
-}
-
-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();
-	}
-}
-
-void TextEditor::MoveLeft(int aAmount, bool aSelect, bool aWordMode)
-{
-	if (mLines.empty())
-		return;
-
-	auto oldPos = mState.mCursorPosition;
-	mState.mCursorPosition = GetActualCursorCoordinates();
-
-	while (aAmount-- > 0)
-	{
-		if (mState.mCursorPosition.mColumn == 0)
-		{
-			if (mState.mCursorPosition.mLine > 0)
-			{
-				--mState.mCursorPosition.mLine;
-				mState.mCursorPosition.mColumn = (int)mLines[mState.mCursorPosition.mLine].size();
-			}
-		}
-		else
-		{
-			mState.mCursorPosition.mColumn = std::max(0, mState.mCursorPosition.mColumn - 1);
-			if (aWordMode)
-				mState.mCursorPosition = FindWordStart(mState.mCursorPosition);
-		}
-	}
-
-	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())
-		return;
-
-	while (aAmount-- > 0)
-	{
-		auto& line = mLines[mState.mCursorPosition.mLine];
-		if (mState.mCursorPosition.mColumn >= (int)line.size())
-		{
-			if (mState.mCursorPosition.mLine < (int)mLines.size() - 1)
-			{
-				mState.mCursorPosition.mLine = std::max(0, std::min((int)mLines.size() - 1, mState.mCursorPosition.mLine + 1));
-				mState.mCursorPosition.mColumn = 0;
-			}
-		}
-		else
-		{
-			mState.mCursorPosition.mColumn = std::max(0, std::min((int)line.size(), mState.mCursorPosition.mColumn + 1));
-			if (aWordMode)
-				mState.mCursorPosition = FindWordEnd(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, (int)mLines[oldPos.mLine].size()));
-
-	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 == (int)line.size())
-		{
-			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
-		{
-			u.mRemoved = line[pos.mColumn].mChar;
-			u.mRemovedStart = u.mRemovedEnd = GetActualCursorCoordinates();
-			u.mRemovedEnd.mColumn++;
-
-			line.erase(line.begin() + pos.mColumn);
-		}
-
-		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, (int)mLines[pos.mLine - 1].size());
-			Advance(u.mRemovedEnd);
-
-			auto& line = mLines[mState.mCursorPosition.mLine];
-			auto& prevLine = mLines[mState.mCursorPosition.mLine - 1];
-			auto prevSize = (int)prevLine.size();
-			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];
-
-			u.mRemoved = line[pos.mColumn - 1].mChar;
-			u.mRemovedStart = u.mRemovedEnd = GetActualCursorCoordinates();
-			--u.mRemovedStart.mColumn;
-
-			--mState.mCursorPosition.mColumn;
-			if (mState.mCursorPosition.mColumn < (int)line.size())
-				line.erase(line.begin() + mState.mCursorPosition.mColumn);
-		}
-
-		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()
-{
-	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 mUndoIndex > 0;
-}
-
-bool TextEditor::CanRedo() const
-{
-	return 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 = (int)mLines[mState.mCursorPosition.mLine].size();
-	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())
-		return;
-
-	if (mCheckComments)
-	{
-		auto end = Coordinates((int)mLines.size(), 0);
-		auto commentStart = end;
-		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
-
-		for (auto currentCoord = Coordinates(0, 0); currentCoord < end; Advance(currentCoord))
-		{
-			auto& line = mLines[currentCoord.mLine];
-
-			if (currentCoord.mColumn == 0 && !concatenate)
-			{
-				withinSingleLineComment = false;
-				withinPreproc = false;
-				firstChar = true;
-			}
-
-			concatenate = false;
-
-			if (!line.empty())
-			{
-				auto& g = line[currentCoord.mColumn];
-				auto c = g.mChar;
-
-				if (c != mLanguageDefinition.mPreprocChar && !isspace(c))
-					firstChar = false;
-
-				if (currentCoord.mColumn == line.size() - 1 && line[line.size() - 1].mChar == '\\')
-					concatenate = true;
-
-				bool inComment = commentStart <= currentCoord;
-
-				if (withinString)
-				{
-					line[currentCoord.mColumn].mMultiLineComment = inComment;
-
-					if (c == '\"')
-					{
-						if (currentCoord.mColumn + 1 < (int)line.size() && line[currentCoord.mColumn + 1].mChar == '\"')
-						{
-							Advance(currentCoord);
-							if (currentCoord.mColumn < (int)line.size())
-								line[currentCoord.mColumn].mMultiLineComment = inComment;
-						}
-						else
-							withinString = false;
-					}
-					else if (c == '\\')
-					{
-						Advance(currentCoord);
-						if (currentCoord.mColumn < (int)line.size())
-							line[currentCoord.mColumn].mMultiLineComment = inComment;
-					}
-				}
-				else
-				{
-					if (firstChar && c == mLanguageDefinition.mPreprocChar)
-						withinPreproc = true;
-
-					if (c == '\"')
-					{
-						withinString = true;
-						line[currentCoord.mColumn].mMultiLineComment = inComment;
-					}
-					else
-					{
-						auto pred = [](const char& a, const Glyph& b) { return a == b.mChar; };
-						auto from = line.begin() + currentCoord.mColumn;
-						auto& startStr = mLanguageDefinition.mCommentStart;
-						auto& singleStartStr = mLanguageDefinition.mSingleLineComment;
-						if (singleStartStr.size() > 0 &&
-							currentCoord.mColumn + singleStartStr.size() <= line.size() &&
-							equals(singleStartStr.begin(), singleStartStr.end(), from, from + singleStartStr.size(), pred))
-							withinSingleLineComment = true;
-						else if (!withinSingleLineComment && currentCoord.mColumn + startStr.size() <= line.size() &&
-							equals(startStr.begin(), startStr.end(), from, from + startStr.size(), pred))
-							commentStart = currentCoord;
-
-						inComment = commentStart <= currentCoord;
-
-						line[currentCoord.mColumn].mMultiLineComment = inComment;
-						line[currentCoord.mColumn].mComment = withinSingleLineComment;
-
-						auto& endStr = mLanguageDefinition.mCommentEnd;
-						if (currentCoord.mColumn + 1 >= (int)endStr.size() &&
-							equals(endStr.begin(), endStr.end(), from + 1 - endStr.size(), from + 1, pred))
-							commentStart = end;
-					}
-				}
-				line[currentCoord.mColumn].mPreprocessor = withinPreproc;
-			}
-		}
-		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;
-	auto fontScale = ImGui::GetFontSize() / ImGui::GetFont()->FontSize;
-	float spaceSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, " ", nullptr, nullptr).x;
-	for (size_t it = 0u; it < line.size() && it < (unsigned)aFrom.mColumn; ++it)
-	{
-		if (line[it].mChar == '\t')
-		{
-			distance = (1.0f * fontScale + std::floor((1.0f + distance)) / (float(mTabSize) * spaceSize)) * (float(mTabSize) * spaceSize);
-		}
-		else
-		{
-			char tempCString[2];
-			tempCString[0] = line[it].mChar;
-			tempCString[1] = '\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 && 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 && 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;
+}
diff --git a/TextEditor.h b/TextEditor.h
index cfc68d5..bd52e13 100644
--- a/TextEditor.h
+++ b/TextEditor.h
@@ -57,7 +57,14 @@
 			, mEnabled(false)
 		{}
 	};
-	
+
+	// Represents a character coordinate from the user's point of view,
+	// i. e. consider an uniform grid (assuming fixed-width font) on the
+	// screen as it is rendered, and each cell has its own coordinate, starting from 0.
+	// Tabs are counted as [1..mTabSize] count empty spaces, depending on
+	// how many space is necessary to reach the next tab stop.
+	// For example, coordinate (1, 5) represents the character 'B' in a line "\tABC", when mTabSize = 4,
+	// because it is rendered as "    ABC" on the screen.
 	struct Coordinates
 	{
 		int mLine, mColumn;
@@ -124,8 +131,8 @@
 	typedef std::map<int, std::string> ErrorMarkers;
 	typedef std::unordered_set<int> Breakpoints;
 	typedef std::array<ImU32, (unsigned)PaletteIndex::Max> Palette;
-	typedef char Char;
-	
+	typedef uint8_t Char;
+
 	struct Glyph
 	{
 		Char mChar;
@@ -134,7 +141,7 @@
 		bool mMultiLineComment : 1;
 		bool mPreprocessor : 1;
 
-		Glyph(Char aChar, PaletteIndex aColorIndex) : mChar(aChar), mColorIndex(aColorIndex), 
+		Glyph(Char aChar, PaletteIndex aColorIndex) : mChar(aChar), mColorIndex(aColorIndex),
 			mComment(false), mMultiLineComment(false), mPreprocessor(false) {}
 	};
 
@@ -145,7 +152,7 @@
 	{
 		typedef std::pair<std::string, PaletteIndex> TokenRegexString;
 		typedef std::vector<TokenRegexString> TokenRegexStrings;
-		typedef bool (*TokenizeCallback)(const char * in_begin, const char * in_end, const char *& out_begin, const char *& out_end, PaletteIndex & paletteIndex);
+		typedef bool(*TokenizeCallback)(const char * in_begin, const char * in_end, const char *& out_begin, const char *& out_end, PaletteIndex & paletteIndex);
 
 		std::string mName;
 		Keywords mKeywords;
@@ -160,12 +167,12 @@
 		TokenRegexStrings mTokenRegexStrings;
 
 		bool mCaseSensitive;
-		
+
 		LanguageDefinition()
 			: mPreprocChar('#'), mAutoIndentation(true), mTokenize(nullptr), mCaseSensitive(true)
 		{
 		}
-		
+
 		static const LanguageDefinition& CPlusPlus();
 		static const LanguageDefinition& HLSL();
 		static const LanguageDefinition& GLSL();
@@ -189,12 +196,14 @@
 
 	void Render(const char* aTitle, const ImVec2& aSize = ImVec2(), bool aBorder = false);
 	void SetText(const std::string& aText);
-	void SetTextLines(const std::vector<std::string>& aLines);
 	std::string GetText() const;
+
+	void SetTextLines(const std::vector<std::string>& aLines);
 	std::vector<std::string> GetTextLines() const;
+
 	std::string GetSelectedText() const;
 	std::string GetCurrentLineText()const;
-	
+
 	int GetTotalLines() const { return (int)mLines.size(); }
 	bool IsOverwrite() const { return mOverwrite; }
 
@@ -203,12 +212,26 @@
 	bool IsTextChanged() const { return mTextChanged; }
 	bool IsCursorPositionChanged() const { return mCursorPositionChanged; }
 
+	bool IsColorizerEnabled() const { return mColorizerEnabled; }
+	void SetColorizerEnable(bool aValue);
+
 	Coordinates GetCursorPosition() const { return GetActualCursorCoordinates(); }
 	void SetCursorPosition(const Coordinates& aPosition);
 
-	void SetHandleMouseInputs    (bool aValue){ mHandleMouseInputs    = aValue;}
-	void SetHandleKeyboardInputs (bool aValue){ mHandleKeyboardInputs = aValue;}
-	void SetImGuiChildIgnored    (bool aValue){ mIgnoreImGuiChild     = aValue;}
+	inline void SetHandleMouseInputs    (bool aValue){ mHandleMouseInputs    = aValue;}
+	inline bool IsHandleMouseInputsEnabled() const { return mHandleKeyboardInputs; }
+
+	inline void SetHandleKeyboardInputs (bool aValue){ mHandleKeyboardInputs = aValue;}
+	inline bool IsHandleKeyboardInputsEnabled() const { return mHandleKeyboardInputs; }
+
+	inline void SetImGuiChildIgnored    (bool aValue){ mIgnoreImGuiChild     = aValue;}
+	inline bool IsImGuiChildIgnored() const { return mIgnoreImGuiChild; }
+
+	inline void SetShowWhitespaces(bool aValue) { mShowWhitespaces = aValue; }
+	inline bool IsShowingWhitespaces() const { return mShowWhitespaces; }
+
+	void SetTabSize(int aValue);
+	inline int GetTabSize() const { return mTabSize; }
 
 	void InsertText(const std::string& aValue);
 	void InsertText(const char* aValue);
@@ -261,14 +284,14 @@
 
 		UndoRecord(
 			const std::string& aAdded,
-			const TextEditor::Coordinates aAddedStart, 
-			const TextEditor::Coordinates aAddedEnd, 
-			
-			const std::string& aRemoved, 
+			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& aBefore,
 			TextEditor::EditorState& aAfter);
 
 		void Undo(TextEditor* aEditor);
@@ -295,7 +318,6 @@
 	float TextDistanceToLineStart(const Coordinates& aFrom) const;
 	void EnsureCursorVisible();
 	int GetPageSize() const;
-	int AppendBuffer(std::string& aBuffer, char chr, int aIndex);
 	std::string GetText(const Coordinates& aStart, const Coordinates& aEnd) const;
 	Coordinates GetActualCursorCoordinates() const;
 	Coordinates SanitizeCoordinates(const Coordinates& aValue) const;
@@ -306,12 +328,17 @@
 	Coordinates ScreenPosToCoordinates(const ImVec2& aPosition) const;
 	Coordinates FindWordStart(const Coordinates& aFrom) const;
 	Coordinates FindWordEnd(const Coordinates& aFrom) const;
+	Coordinates FindNextWord(const Coordinates& aFrom) const;
+	int GetCharacterIndex(const Coordinates& aCoordinates) const;
+	int GetCharacterColumn(int aLine, int aIndex) const;
+	int GetLineCharacterCount(int aLine) const;
+	int GetLineMaxColumn(int aLine) const;
 	bool IsOnWordBoundary(const Coordinates& aAt) const;
 	void RemoveLine(int aStart, int aEnd);
 	void RemoveLine(int aIndex);
 	Line& InsertLine(int aIndex);
-	void EnterCharacter(Char aChar, bool aShift);
-	void BackSpace();
+	void EnterCharacter(ImWchar aChar, bool aShift);
+	void Backspace();
 	void DeleteSelection();
 	std::string GetWordUnderCursor() const;
 	std::string GetWordAt(const Coordinates& aCoords) const;
@@ -326,23 +353,25 @@
 	EditorState mState;
 	UndoBuffer mUndoBuffer;
 	int mUndoIndex;
-	
+
 	int mTabSize;
 	bool mOverwrite;
 	bool mReadOnly;
 	bool mWithinRender;
-	bool mScrollToCursor;
+	bool mScrollToCursor;
 	bool mScrollToTop;
 	bool mTextChanged;
-	float  mTextStart;                   // position (in pixels) where a code line starts relative to the left of the TextEditor.
+	bool mColorizerEnabled;
+	float mTextStart;                   // position (in pixels) where a code line starts relative to the left of the TextEditor.
 	int  mLeftMargin;
 	bool mCursorPositionChanged;
 	int mColorRangeMin, mColorRangeMax;
 	SelectionMode mSelectionMode;
-	bool mHandleKeyboardInputs;
-	bool mHandleMouseInputs;
-	bool mIgnoreImGuiChild;
-
+	bool mHandleKeyboardInputs;
+	bool mHandleMouseInputs;
+	bool mIgnoreImGuiChild;
+	bool mShowWhitespaces;
+
 	Palette mPaletteBase;
 	Palette mPalette;
 	LanguageDefinition mLanguageDefinition;
@@ -353,6 +382,8 @@
 	ErrorMarkers mErrorMarkers;
 	ImVec2 mCharAdvance;
 	Coordinates mInteractiveStart, mInteractiveEnd;
-	
+	std::string mLineBuffer;
+	uint64_t mStartTime;
+
 	float mLastClick;
 };
