Render(...) function has been refactored into smaller, functionally separate parts: handle keyboard, mouse, colorize, and the actual render.
Code fancy/cleanup.
diff --git a/TextEditor.cpp b/TextEditor.cpp
index 0029d36..963e754 100644
--- a/TextEditor.cpp
+++ b/TextEditor.cpp
@@ -18,7 +18,7 @@
bool equals(InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2, BinaryPredicate p)
{
- for (; first1 != last1 && first2 != last2; ++first1, ++first2)
+ for (; first1 != last1 && first2 != last2; ++first1, ++first2)
{
if (!p(*first1, *first2))
return false;
@@ -89,7 +89,7 @@
int prevLineNo = aStart.mLine;
for (auto it = aStart; it <= aEnd; Advance(it))
{
- if (prevLineNo != it.mLine && it.mLine < (int) mLines.size())
+ if (prevLineNo != it.mLine && it.mLine < (int)mLines.size())
result.push_back('\n');
if (it == aEnd)
@@ -249,29 +249,28 @@
/*
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)
+ 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);
-
+ 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];
+ while (mTextStart + cumulatedStringWidth[0] < local.x &&
+ (size_t)columnCoord < line.size())
+ {
+ cumulatedStringWidth[1] = cumulatedStringWidth[0];
cumulatedString += line[columnCoord].mChar;
- cumulatedStringWidth[0] = ImGui::CalcTextSize(cumulatedString.c_str()).x ;
+ cumulatedStringWidth[0] = ImGui::CalcTextSize(cumulatedString.c_str()).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)
+ if (mTextStart + cumulatedStringWidth[0] - columnWidth / 2.0f > local.x)
columnCoord = std::max(0, columnCoord - 1);
}
@@ -337,7 +336,7 @@
assert(!mReadOnly);
assert(aEnd >= aStart);
assert(mLines.size() > (size_t)(aEnd - aStart));
-
+
ErrorMarkers etmp;
for (auto& i : mErrorMarkers)
{
@@ -451,25 +450,8 @@
return color;
}
-void TextEditor::Render(const char* aTitle, const ImVec2& aSize, bool aBorder)
+void TextEditor::HandleKeyboardInputs()
{
- mWithinRender = true;
- mTextChanged = false;
- mCursorPositionChanged = false;
-
- ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, ImGui::ColorConvertU32ToFloat4(mPalette[(int)PaletteIndex::Background]));
- ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
- ImGui::BeginChild(aTitle, aSize, aBorder, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NoMove);
-
- /* Compute mCharAdvance regarding to scaled font size (Ctrl + mouse wheel)*/
- const float fontSize = ImGui::CalcTextSize("#").x;
- mCharAdvance = ImVec2(fontSize , ImGui::GetTextLineHeightWithSpacing() * mLineSpacing);
-
- /*
- Keyboard inputs
- */
-
- ImGui::PushAllowKeyboardFocus(true);
ImGuiIO& io = ImGui::GetIO();
auto shift = io.KeyShift;
auto ctrl = io.ConfigMacOSXBehaviors ? io.KeySuper : io.KeyCtrl;
@@ -547,19 +529,23 @@
}
}
}
+}
- /*
- Mouse inputs
- */
+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())
{
static float lastClick = -1.0f;
if (!shift && !alt)
{
- auto click = ImGui::IsMouseClicked(0);
+ auto click = ImGui::IsMouseClicked(0);
auto doubleClick = ImGui::IsMouseDoubleClicked(0);
- auto t = ImGui::GetTime();
+ auto t = ImGui::GetTime();
auto tripleClick = click && !doubleClick && t - lastClick < io.MouseDoubleClickTime;
/*
@@ -600,7 +586,6 @@
/*
Left mouse button click
*/
-
else if (click)
{
mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = SanitizeCoordinates(ScreenPosToCoordinates(ImGui::GetMousePos()));
@@ -621,8 +606,13 @@
}
}
}
+}
- ColorizeInternal();
+void TextEditor::Render()
+{
+ /* Compute mCharAdvance regarding to scaled font size (Ctrl + mouse wheel)*/
+ const float fontSize = ImGui::CalcTextSize("#").x;
+ mCharAdvance = ImVec2(fontSize, ImGui::GetTextLineHeightWithSpacing() * mLineSpacing);
static std::string buffer;
auto contentSize = ImGui::GetWindowContentRegionMax();
@@ -653,15 +643,12 @@
ImVec2 textScreenPos = ImVec2(lineStartScreenPos.x + mTextStart, lineStartScreenPos.y);
auto& line = mLines[lineNo];
- longest = std::max(mTextStart + TextDistanceToLineStart(Coordinates(lineNo, (int) line.size())), longest);
+ 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 Selected area
- */
-
+ // Draw selection for the current line
float sstart = -1.0f;
float ssend = -1.0f;
@@ -681,10 +668,7 @@
drawList->AddRectFilled(vstart, vend, mPalette[(int)PaletteIndex::Selection]);
}
- /*
- Draw break point
- */
-
+ // Draw breakpoints
auto start = ImVec2(lineStartScreenPos.x + scrollX, lineStartScreenPos.y);
if (mBreakpoints.count(lineNo + 1) != 0)
@@ -693,10 +677,7 @@
drawList->AddRectFilled(start, end, mPalette[(int)PaletteIndex::Breakpoint]);
}
- /*
- Draw error marker
- */
-
+ // Draw error markers
auto errorIt = mErrorMarkers.find(lineNo + 1);
if (errorIt != mErrorMarkers.end())
{
@@ -717,18 +698,12 @@
}
}
- /*
- Draw line number (right aligned)
- */
-
+ // Draw line number (right aligned)
snprintf(buf, 16, "%d ", lineNo + 1);
auto lineNoWidth = ImGui::CalcTextSize(buf).x;
drawList->AddText(ImVec2(lineStartScreenPos.x + mTextStart - lineNoWidth, lineStartScreenPos.y), mPalette[(int)PaletteIndex::LineNumber], buf);
- /*
- Highlight the current line (where the cursor is).
- */
-
+ // Highlight the current line (where the cursor is)
if (mState.mCursorPosition.mLine == lineNo)
{
auto focused = ImGui::IsWindowFocused();
@@ -759,10 +734,8 @@
}
}
- /*
- Draw Text
- */
- auto prevColor = line.empty() ? mPalette[(int) PaletteIndex::Default] : GetGlyphColor(line[0]);
+ // Render colorized text
+ auto prevColor = line.empty() ? mPalette[(int)PaletteIndex::Default] : GetGlyphColor(line[0]);
ImVec2 bufferOffset;
for (auto& glyph : line)
@@ -795,7 +768,8 @@
++lineNo;
}
-
+
+ // Draw a tooltip on known identifiers/preprocessor symbols
if (ImGui::IsMousePosValid())
{
auto id = GetWordAt(ScreenPosToCoordinates(ImGui::GetMousePos()));
@@ -831,6 +805,23 @@
ImGui::SetWindowFocus();
mScrollToCursor = false;
}
+}
+
+void TextEditor::Render(const char* aTitle, const ImVec2& aSize, bool aBorder)
+{
+ mWithinRender = true;
+ mTextChanged = false;
+ mCursorPositionChanged = false;
+
+ ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, ImGui::ColorConvertU32ToFloat4(mPalette[(int)PaletteIndex::Background]));
+ ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
+ ImGui::BeginChild(aTitle, aSize, aBorder, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NoMove);
+ ImGui::PushAllowKeyboardFocus(true);
+
+ HandleKeyboardInputs();
+ HandleMouseInputs();
+ ColorizeInternal();
+ Render();
ImGui::PopAllowKeyboardFocus();
ImGui::EndChild();
@@ -868,7 +859,7 @@
void TextEditor::SetTextLines(const std::vector<std::string> & aLines)
{
mLines.clear();
-
+
if (aLines.empty())
{
mLines.emplace_back(Line());
@@ -876,11 +867,11 @@
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));
@@ -912,11 +903,11 @@
if (start > end)
std::swap(start, end);
start.mColumn = 0;
-// end.mColumn = end.mLine < mLines.size() ? mLines[end.mLine].size() : 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();
+ end.mColumn = (int)mLines[end.mLine].size();
}
u.mRemovedStart = start;
@@ -987,13 +978,13 @@
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());
@@ -1053,7 +1044,7 @@
void TextEditor::SetSelection(const Coordinates & aStart, const Coordinates & aEnd, SelectionMode aMode)
{
auto oldSelStart = mState.mSelectionStart;
- auto oldSelEnd = mState.mSelectionEnd;
+ auto oldSelEnd = mState.mSelectionEnd;
mState.mSelectionStart = SanitizeCoordinates(aStart);
mState.mSelectionEnd = SanitizeCoordinates(aEnd);
@@ -1076,7 +1067,7 @@
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);
+ mState.mSelectionEnd = Coordinates(lineNo, (int)lineSize);
break;
}
default:
@@ -1677,21 +1668,21 @@
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;
}
@@ -1702,7 +1693,7 @@
std::string TextEditor::GetCurrentLineText()const
{
- auto lineLength = (int) mLines[mState.mCursorPosition.mLine].size();
+ auto lineLength = (int)mLines[mState.mCursorPosition.mLine].size();
return GetText(Coordinates(mState.mCursorPosition.mLine, 0), Coordinates(mState.mCursorPosition.mLine, lineLength));
}
@@ -1728,15 +1719,15 @@
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)
{
@@ -1744,37 +1735,37 @@
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);
-
+ // 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;
@@ -1783,7 +1774,7 @@
}
}
}
-
+
if (hasTokenizeResult == false)
{
first++;
@@ -1791,11 +1782,11 @@
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);
@@ -1815,10 +1806,10 @@
token_color = PaletteIndex::PreprocIdentifier;
}
}
-
+
for (size_t j = 0; j < token_length; ++j)
line[(token_begin - bufferBegin) + j].mColorIndex = token_color;
-
+
first = token_end;
}
}
@@ -1829,7 +1820,7 @@
{
if (mLines.empty())
return;
-
+
if (mCheckComments)
{
auto end = Coordinates((int)mLines.size(), 0);
@@ -1839,7 +1830,7 @@
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];
@@ -1960,7 +1951,7 @@
else
{
char tempCString[2];
- tempCString[0] = line[it].mChar;
+ tempCString[0] = line[it].mChar;
tempCString[1] = '\0';
distance += ImGui::CalcTextSize(tempCString).x + 1.0f * fontScale;
}
@@ -2072,11 +2063,11 @@
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
@@ -2086,15 +2077,15 @@
out_end = p + 1;
return true;
}
-
+
// handle escape character for "
if (*p == '\\' && p + 1 < in_end && p[1] == '"')
p++;
-
+
p++;
}
}
-
+
return false;
}
@@ -2105,14 +2096,14 @@
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 == '\'')
{
@@ -2128,121 +2119,121 @@
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;
@@ -2254,35 +2245,35 @@
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;
+ 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;
}
@@ -2313,14 +2304,14 @@
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;
@@ -2337,10 +2328,10 @@
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 = "//";
@@ -2504,10 +2495,10 @@
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;
@@ -2524,10 +2515,10 @@
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 = "//";
@@ -2671,9 +2662,9 @@
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",
+ "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",
diff --git a/TextEditor.h b/TextEditor.h
index 3e37e86..ac03ad4 100644
--- a/TextEditor.h
+++ b/TextEditor.h
@@ -313,6 +313,10 @@
std::string GetWordAt(const Coordinates& aCoords) const;
ImU32 GetGlyphColor(const Glyph& aGlyph) const;
+ void HandleKeyboardInputs();
+ void HandleMouseInputs();
+ void Render();
+
float mLineSpacing;
Lines mLines;
EditorState mState;