From c13ca28c50a17aa91d8e9a4d178ef07aaf295a7c Mon Sep 17 00:00:00 2001 From: Kacper Paciorek Date: Wed, 14 Jan 2026 15:09:03 +0100 Subject: [PATCH 1/4] Test implementation of syntax highlighting for C++ --- include/text-editor/editor.hpp | 1 + source/text-editor/editor.cpp | 95 +++++++++++++++++++++++++++++++--- 2 files changed, 88 insertions(+), 8 deletions(-) diff --git a/include/text-editor/editor.hpp b/include/text-editor/editor.hpp index a281455..533545d 100644 --- a/include/text-editor/editor.hpp +++ b/include/text-editor/editor.hpp @@ -38,6 +38,7 @@ struct Editor : turbo::TScintillaParent{ private: void updateAll(); + void configureStyling(Scintilla::ILexer5* lexer); private: std::string path; diff --git a/source/text-editor/editor.cpp b/source/text-editor/editor.cpp index ffc3117..20cc52b 100644 --- a/source/text-editor/editor.cpp +++ b/source/text-editor/editor.cpp @@ -1,6 +1,9 @@ #include #include #include +#include + +extern Scintilla::LexerModule lmCPP; Editor::Editor(){ scintilla.setParent(this); @@ -13,14 +16,6 @@ Editor::Editor(){ turbo::call(scintilla, SCI_SETTABWIDTH, 4, 0U); turbo::call(scintilla, SCI_SETTABINDENTS, true, 0U); turbo::call(scintilla, SCI_SETBACKSPACEUNINDENTS, true, 0U); - - //Style configuration - TColorAttr textColor = {0xFFFFFF, 0x000000}; - turbo::setStyleColor(scintilla, STYLE_DEFAULT, textColor); - turbo::call(scintilla, SCI_STYLECLEARALL, 0, 0); - - TColorAttr selectionColor = {0xFFFFFF, 0x444466}; - turbo::setSelectionColor(scintilla, selectionColor); } void Editor::setSize(const TPoint& size){ @@ -86,6 +81,8 @@ long buffSize = 128*1024; void Editor::openFile(const std::string& path){ this->path = path; + Scintilla::ILexer5* lexer = lmCPP.Create(); + configureStyling(lexer); } void Editor::readFile(){ @@ -131,4 +128,86 @@ bool Editor::isModified(){ void Editor::updateAll(){ for(auto observer : observers)observer->editorUpdate(); +} + +//temporary stuff for C++ styling +constexpr std::array stylesC[] = +{ + {SCE_C_DEFAULT, 0, 0xffffff, 0x000000}, + {SCE_C_COMMENT, 10, 0xff0000, 0x000000}, + {SCE_C_COMMENTLINE, 10, 0xff0000, 0x222222}, + {SCE_C_COMMENTDOC, 10, 0xff0000, 0x0000FF}, + {SCE_C_NUMBER, 13, 0x00ff00, 0x000000}, + {SCE_C_WORD, 5, 0x00ffff, 0x000000}, + {SCE_C_STRING, 11, 0xffff00, 0x000000}, + {SCE_C_CHARACTER, 12, 0x0000ff, 0x000000}, + {SCE_C_PREPROCESSOR, 8, 0xff00ff, 0x000000}, + {SCE_C_OPERATOR, 9, 0xaa00bb, 0x000000}, + {SCE_C_COMMENTLINEDOC, 10, 0xff0000, 0x00FFFF}, + {SCE_C_WORD2, 6, 0x000fff, 0x000000}, + {SCE_C_GLOBALCLASS, 7, 0xf0ab0f, 0x000000}, + {SCE_C_PREPROCESSORCOMMENT, 10, 0xf888ff, 0x000000}, + {SCE_C_PREPROCESSORCOMMENTDOC, 10, 0xf2ff80, 0x000000}, + {SCE_C_ESCAPESEQUENCE, 14, 0x8888ff, 0x000000}, +}; + +std::pair keywordsC[] = +{ + {0, +"alignas alignof and and_eq asm auto bitand bitor break case catch class compl " +"concept consteval constexpr constinit const_cast continue co_await co_return " +"co_yield decltype default delete do dynamic_cast else enum explicit export " +"false final for friend goto if import inline module namespace new noexcept not " +"not_eq nullptr operator or or_eq override private protected public " +"reinterpret_cast return sizeof static_assert static_cast struct switch " +"template this throw true try typedef typeid typename union using virtual while " +"xor xor_eq " + }, + {1, +"bool char char8_t char16_t char32_t const double extern float int long mutable " +"register static short signed unsigned thread_local void volatile wchar_t int8_t " +"uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_t size_t ptrdiff_t " +"intptr_t uintptr_t far near uchar ushort uint ulong " + }, + {3, +"std" + }, +}; + +std::pair propertiesC[] = +{ + {"styling.within.preprocessor", "1"}, + {"lexer.cpp.track.preprocessor", "0"}, + {"lexer.cpp.escape.sequence", "1"}, +}; + +void Editor::configureStyling(Scintilla::ILexer5* lexer){ + //Style configuration + TColorAttr textColor = {0xFFFFFF, 0x000000}; + turbo::setStyleColor(scintilla, STYLE_DEFAULT, textColor); + turbo::call(scintilla, SCI_STYLECLEARALL, 0, 0); + + TColorAttr selectionColor = {0xFFFFFF, 0x444466}; + turbo::setSelectionColor(scintilla, selectionColor); + + //lexer configuration + int id = turbo::call(scintilla, SCI_GETLEXER, 0, 0); + std::cerr << "Id before setilexer " << id << "\n"; + turbo::call(scintilla, SCI_SETILEXER, 0, (sptr_t) lexer); + id = turbo::call(scintilla, SCI_GETLEXER, 0, 0); + std::cerr << "Id after setilexer " << id << "\n"; + turbo::call(scintilla, SCI_COLOURISE, 0, -1); + + //color of comments + for(int i = 0; i < 16; i++){ + TColorAttr color = {stylesC[i][2], stylesC[i][3]}; + turbo::setStyleColor(scintilla, stylesC[i][0], color); + } + + for (int i = 0; i < 3; i++){ + turbo::call(scintilla, SCI_SETKEYWORDS, keywordsC[i].first, (sptr_t)keywordsC[i].second.c_str()); + } + for(int i = 0; i < 3; i++){ + turbo::call(scintilla, SCI_SETPROPERTY, (sptr_t) propertiesC[i].first.c_str(), (sptr_t)propertiesC[i].second.c_str()); + } } \ No newline at end of file From 104dad8910c202d14a2d4396b2f6877e3543f397 Mon Sep 17 00:00:00 2001 From: mateuszgabzdyl2 Date: Mon, 19 Jan 2026 13:11:06 +0100 Subject: [PATCH 2/4] C++ coloring only when file extension matches --- include/text-editor/editor.hpp | 3 ++- source/text-editor/editor.cpp | 40 ++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/include/text-editor/editor.hpp b/include/text-editor/editor.hpp index 533545d..77ad953 100644 --- a/include/text-editor/editor.hpp +++ b/include/text-editor/editor.hpp @@ -38,7 +38,8 @@ struct Editor : turbo::TScintillaParent{ private: void updateAll(); - void configureStyling(Scintilla::ILexer5* lexer); + void configureStyling(Scintilla::ILexer5* lexer); + Scintilla::ILexer5* getLexerForExtension(const std::string& path); private: std::string path; diff --git a/source/text-editor/editor.cpp b/source/text-editor/editor.cpp index fab5d6f..f205d67 100644 --- a/source/text-editor/editor.cpp +++ b/source/text-editor/editor.cpp @@ -84,10 +84,46 @@ void Editor::setHorizontalScrollPos(int delta, int limit) noexcept{ static char buffer alignas(4*1024) [128*1024 + 1024]; long buffSize = 128*1024; +Scintilla::ILexer5* Editor::getLexerForExtension(const std::string& path) { + + // std::string ext = std::filesystem::path(path).extension().string(); + + size_t pos = path.rfind('.'); + std::string ext; + if(pos != std::string::npos) { + ext = path.substr(pos); + } + + + if(ext == ".cpp" || ext == ".cxx" || ext == ".cc" || ext == ".hpp" || ext == ".h") { + return lmCPP.Create(); // lexer C++ + } + + // other languages + + return nullptr; +} + void Editor::openFile(const std::string& path){ this->path = path; - Scintilla::ILexer5* lexer = lmCPP.Create(); - configureStyling(lexer); + // Scintilla::ILexer5* lexer = lmCPP.Create(); + // configureStyling(lexer); + + Scintilla::ILexer5* lexer = getLexerForExtension(path); + + // default coloring + TColorAttr textColor = {0xFFFFFF, 0x000000}; + turbo::setStyleColor(scintilla, STYLE_DEFAULT, textColor); + + TColorAttr selectionColor = {0xFFFFFF, 0x444466}; + turbo::setSelectionColor(scintilla, selectionColor); + + if(lexer) { + configureStyling(lexer); + } else { + turbo::call(scintilla, SCI_SETLEXER, SCLEX_NULL, 0); + turbo::call(scintilla, SCI_STYLECLEARALL, 0, 0); + } } void Editor::readFile(){ From acb08fda993d39d2068f1751a43b3109000fbbbf Mon Sep 17 00:00:00 2001 From: mateuszgabzdyl2 Date: Mon, 19 Jan 2026 15:20:40 +0100 Subject: [PATCH 3/4] C++, Python coloring test --- include/text-editor/editor.hpp | 11 ++- source/text-editor/editor.cpp | 122 +++++++++++++++++++++++---------- 2 files changed, 96 insertions(+), 37 deletions(-) diff --git a/include/text-editor/editor.hpp b/include/text-editor/editor.hpp index 77ad953..aaf72b4 100644 --- a/include/text-editor/editor.hpp +++ b/include/text-editor/editor.hpp @@ -14,6 +14,13 @@ struct EditorObserver{ struct Editor : turbo::TScintillaParent{ public: + enum class Language { + None, + Cpp, + Python, + // + }; + Editor(); void setSize(const TPoint& size); void paint(TDrawSurface& surface, TRect area); @@ -38,8 +45,8 @@ struct Editor : turbo::TScintillaParent{ private: void updateAll(); - void configureStyling(Scintilla::ILexer5* lexer); - Scintilla::ILexer5* getLexerForExtension(const std::string& path); + void configureStyling(Scintilla::ILexer5* lexer, Language lang); + std::pair getLexerForExtension(const std::string& path); private: std::string path; diff --git a/source/text-editor/editor.cpp b/source/text-editor/editor.cpp index f205d67..8267818 100644 --- a/source/text-editor/editor.cpp +++ b/source/text-editor/editor.cpp @@ -4,6 +4,7 @@ #include extern Scintilla::LexerModule lmCPP; +extern Scintilla::LexerModule lmPython; Editor::Editor(){ scintilla.setParent(this); @@ -84,24 +85,21 @@ void Editor::setHorizontalScrollPos(int delta, int limit) noexcept{ static char buffer alignas(4*1024) [128*1024 + 1024]; long buffSize = 128*1024; -Scintilla::ILexer5* Editor::getLexerForExtension(const std::string& path) { +std::pair Editor::getLexerForExtension(const std::string& path) { // std::string ext = std::filesystem::path(path).extension().string(); size_t pos = path.rfind('.'); std::string ext; - if(pos != std::string::npos) { + if(pos != std::string::npos) ext = path.substr(pos); - } - - if(ext == ".cpp" || ext == ".cxx" || ext == ".cc" || ext == ".hpp" || ext == ".h") { - return lmCPP.Create(); // lexer C++ - } + if(ext == ".cpp" || ext == ".cxx" || ext == ".cc" || ext == ".hpp" || ext == ".h") + return { lmCPP.Create(), Language::Cpp }; + if(ext == ".py") + return { lmPython.Create(), Language::Python }; - // other languages - - return nullptr; + return { nullptr, Language::None }; } void Editor::openFile(const std::string& path){ @@ -109,21 +107,12 @@ void Editor::openFile(const std::string& path){ // Scintilla::ILexer5* lexer = lmCPP.Create(); // configureStyling(lexer); - Scintilla::ILexer5* lexer = getLexerForExtension(path); - - // default coloring - TColorAttr textColor = {0xFFFFFF, 0x000000}; - turbo::setStyleColor(scintilla, STYLE_DEFAULT, textColor); - - TColorAttr selectionColor = {0xFFFFFF, 0x444466}; - turbo::setSelectionColor(scintilla, selectionColor); + // Scintilla::ILexer5* lexer = getLexerForExtension(path); + + // configureStyling(lexer); - if(lexer) { - configureStyling(lexer); - } else { - turbo::call(scintilla, SCI_SETLEXER, SCLEX_NULL, 0); - turbo::call(scintilla, SCI_STYLECLEARALL, 0, 0); - } + auto [lexer, lang] = getLexerForExtension(path); + configureStyling(lexer, lang); } void Editor::readFile(){ @@ -222,7 +211,50 @@ std::pair propertiesC[] = {"lexer.cpp.escape.sequence", "1"}, }; -void Editor::configureStyling(Scintilla::ILexer5* lexer){ + +constexpr std::array stylesPython[] = +{ + {SCE_P_DEFAULT, 0xFFFFFF, 0x000000}, + {SCE_P_COMMENTLINE, 0x008000, 0x000000}, + {SCE_P_NUMBER, 0x00FF00, 0x000000}, + {SCE_P_STRING, 0xFFFF00, 0x000000}, + {SCE_P_CHARACTER, 0x0000FF, 0x000000}, + {SCE_P_WORD, 0x0000FF, 0x000000}, + {SCE_P_TRIPLE, 0xFFFF00, 0x000000}, + {SCE_P_TRIPLEDOUBLE, 0xFFFF00, 0x000000}, + {SCE_P_CLASSNAME, 0x00FFFF, 0x000000}, + {SCE_P_DEFNAME, 0x00FFFF, 0x000000}, + {SCE_P_OPERATOR, 0xAA00BB, 0x000000}, + {SCE_P_IDENTIFIER, 0xFFFFFF, 0x000000}, + {SCE_P_COMMENTBLOCK, 0x008000, 0x000000}, + {SCE_P_STRINGEOL, 0xFFFF00, 0x000000}, + {SCE_P_WORD2, 0x00AAAA, 0x000000}, + {SCE_P_DECORATOR, 0xFF8800, 0x000000}, + {SCE_P_FSTRING, 0xFFFF00, 0x000000}, + {SCE_P_FCHARACTER, 0x0000FF, 0x000000}, + {SCE_P_FTRIPLE, 0xFFFF00, 0x000000}, + {SCE_P_FTRIPLEDOUBLE, 0xFFFF00, 0x000000} +}; + +std::pair keywordsPython[] = +{ + {0, +"and as assert break class continue def del elif else except exec finally for " +"from global if import in is lambda not or pass print raise return try while " +"with yield" + }, + {1, +"int float complex list tuple range str bytes bytearray memoryview set frozenset " +"dict " + }, +}; + +std::pair propertiesPython[] = +{ + {"lexer.python.keywords2.no.sub.identifiers", "1"}, +}; + +void Editor::configureStyling(Scintilla::ILexer5* lexer, Language lang){ //Style configuration TColorAttr textColor = {0xFFFFFF, 0x000000}; turbo::setStyleColor(scintilla, STYLE_DEFAULT, textColor); @@ -231,6 +263,11 @@ void Editor::configureStyling(Scintilla::ILexer5* lexer){ TColorAttr selectionColor = {0xFFFFFF, 0x444466}; turbo::setSelectionColor(scintilla, selectionColor); + if(!lexer) { + turbo::call(scintilla, SCI_SETLEXER, SCLEX_NULL, 0); + return; + } + //lexer configuration int id = turbo::call(scintilla, SCI_GETLEXER, 0, 0); std::cerr << "Id before setilexer " << id << "\n"; @@ -239,16 +276,31 @@ void Editor::configureStyling(Scintilla::ILexer5* lexer){ std::cerr << "Id after setilexer " << id << "\n"; turbo::call(scintilla, SCI_COLOURISE, 0, -1); - //color of comments - for(int i = 0; i < 16; i++){ - TColorAttr color = {stylesC[i][2], stylesC[i][3]}; - turbo::setStyleColor(scintilla, stylesC[i][0], color); - } - for (int i = 0; i < 3; i++){ - turbo::call(scintilla, SCI_SETKEYWORDS, keywordsC[i].first, (sptr_t)keywordsC[i].second.c_str()); - } - for(int i = 0; i < 3; i++){ - turbo::call(scintilla, SCI_SETPROPERTY, (sptr_t) propertiesC[i].first.c_str(), (sptr_t)propertiesC[i].second.c_str()); + switch (lang) { + case Language::Cpp: + for (int i = 0; i < 16; i++) { + TColorAttr color = {stylesC[i][2], stylesC[i][3]}; + turbo::setStyleColor(scintilla, stylesC[i][0], color); + } + for (int i = 0; i < 3; i++) + turbo::call(scintilla, SCI_SETKEYWORDS, keywordsC[i].first, (sptr_t)keywordsC[i].second.c_str()); + for (int i = 0; i < 3; i++) + turbo::call(scintilla, SCI_SETPROPERTY, (sptr_t)propertiesC[i].first.c_str(), (sptr_t)propertiesC[i].second.c_str()); + break; + + case Language::Python: + for (int i = 0; i < 20; i++) { + TColorAttr color = {stylesPython[i][1], stylesPython[i][2]}; + turbo::setStyleColor(scintilla, stylesPython[i][0], color); + } + for (int i = 0; i < 2; i++) + turbo::call(scintilla, SCI_SETKEYWORDS, keywordsPython[i].first, (sptr_t)keywordsPython[i].second.c_str()); + for (int i = 0; i < 1; i++) + turbo::call(scintilla, SCI_SETPROPERTY, (sptr_t)propertiesPython[i].first.c_str(), (sptr_t)propertiesPython[i].second.c_str()); + break; + + default: + break; } } \ No newline at end of file From 80f45179dea07a3bd4d370271817d8e8de47b877 Mon Sep 17 00:00:00 2001 From: mateuszgabzdyl2 Date: Tue, 20 Jan 2026 17:38:00 +0100 Subject: [PATCH 4/4] More languages + small change of structure --- include/text-editor/editor.hpp | 19 +-- source/text-editor/editor.cpp | 243 ++++++++++++++++++++++++++++----- 2 files changed, 216 insertions(+), 46 deletions(-) diff --git a/include/text-editor/editor.hpp b/include/text-editor/editor.hpp index aaf72b4..dcebd8e 100644 --- a/include/text-editor/editor.hpp +++ b/include/text-editor/editor.hpp @@ -6,6 +6,15 @@ #include #include +enum class Language : uint8_t { + None, + CPP, + Python, + JSON, + Bash, + Pascal +}; + struct EditorObserver{ public: virtual void editorUpdate() = 0; @@ -14,13 +23,6 @@ struct EditorObserver{ struct Editor : turbo::TScintillaParent{ public: - enum class Language { - None, - Cpp, - Python, - // - }; - Editor(); void setSize(const TPoint& size); void paint(TDrawSurface& surface, TRect area); @@ -45,8 +47,7 @@ struct Editor : turbo::TScintillaParent{ private: void updateAll(); - void configureStyling(Scintilla::ILexer5* lexer, Language lang); - std::pair getLexerForExtension(const std::string& path); + void configureStyling(Language language); private: std::string path; diff --git a/source/text-editor/editor.cpp b/source/text-editor/editor.cpp index 8267818..56a9f7f 100644 --- a/source/text-editor/editor.cpp +++ b/source/text-editor/editor.cpp @@ -5,6 +5,9 @@ extern Scintilla::LexerModule lmCPP; extern Scintilla::LexerModule lmPython; +extern Scintilla::LexerModule lmJSON; +extern Scintilla::LexerModule lmBash; +extern Scintilla::LexerModule lmPascal; Editor::Editor(){ scintilla.setParent(this); @@ -85,34 +88,61 @@ void Editor::setHorizontalScrollPos(int delta, int limit) noexcept{ static char buffer alignas(4*1024) [128*1024 + 1024]; long buffSize = 128*1024; -std::pair Editor::getLexerForExtension(const std::string& path) { - // std::string ext = std::filesystem::path(path).extension().string(); +static const std::unordered_map ext2lang = { + {".c", Language::CPP}, + {".cc", Language::CPP}, + {".cpp", Language::CPP}, + {".h", Language::CPP}, - size_t pos = path.rfind('.'); - std::string ext; - if(pos != std::string::npos) - ext = path.substr(pos); + {".py", Language::Python}, - if(ext == ".cpp" || ext == ".cxx" || ext == ".cc" || ext == ".hpp" || ext == ".h") - return { lmCPP.Create(), Language::Cpp }; - if(ext == ".py") - return { lmPython.Create(), Language::Python }; + {".json",Language::JSON}, - return { nullptr, Language::None }; + {".sh", Language::Bash}, + + {".pas", Language::Pascal} +}; + +Language detectFileLanguage(const std::string &path) +{ + size_t pos = path.find_last_of('.'); + if (pos != std::string::npos) + { + std::string ext = path.substr(pos); + auto it = ext2lang.find(ext); + if (it != ext2lang.end()) + return it->second; + } + + size_t slash = path.find_last_of("/\\"); + std::string name = (slash == std::string::npos) ? path : path.substr(slash+1); + + auto it2 = ext2lang.find(name); + if (it2 != ext2lang.end()) + return it2->second; + + return Language::None; +} + +Scintilla::ILexer5 *getLexerForLanguage(Language lang) +{ + switch(lang) + { + case Language::CPP: return lmCPP.Create(); + case Language::Python: return lmPython.Create(); + case Language::JSON: return lmJSON.Create(); + case Language::Bash: return lmBash.Create(); + case Language::Pascal: return lmPascal.Create(); + default: return nullptr; + } } void Editor::openFile(const std::string& path){ this->path = path; - // Scintilla::ILexer5* lexer = lmCPP.Create(); - // configureStyling(lexer); - - // Scintilla::ILexer5* lexer = getLexerForExtension(path); - - // configureStyling(lexer); - auto [lexer, lang] = getLexerForExtension(path); - configureStyling(lexer, lang); + Language language = detectFileLanguage(path); + configureStyling(language); } void Editor::readFile(){ @@ -160,7 +190,6 @@ void Editor::updateAll(){ for(auto observer : observers)observer->editorUpdate(); } -//temporary stuff for C++ styling constexpr std::array stylesC[] = { {SCE_C_DEFAULT, 0, 0xffffff, 0x000000}, @@ -254,7 +283,116 @@ std::pair propertiesPython[] = {"lexer.python.keywords2.no.sub.identifiers", "1"}, }; -void Editor::configureStyling(Scintilla::ILexer5* lexer, Language lang){ +constexpr std::array stylesJSON[] = +{ + {SCE_JSON_DEFAULT, 0, 0xFFFFFF, 0x000000}, + {SCE_JSON_NUMBER, 13, 0x00FF00, 0x000000}, + {SCE_JSON_STRING, 11, 0xFFFF00, 0x000000}, + {SCE_JSON_STRINGEOL, 11, 0xFFFF00, 0x000000}, + {SCE_JSON_PROPERTYNAME, 8, 0xFF8800, 0x000000}, + {SCE_JSON_ESCAPESEQUENCE, 14, 0x8888FF, 0x000000}, + {SCE_JSON_LINECOMMENT, 10, 0x008000, 0x000000}, + {SCE_JSON_BLOCKCOMMENT, 10, 0x008000, 0x000000}, + {SCE_JSON_OPERATOR, 9, 0xAA00BB, 0x000000}, + {SCE_JSON_URI, 11, 0x0000FF, 0x000000}, + {SCE_JSON_COMPACTIRI, 6, 0x00AAAA, 0x000000}, + {SCE_JSON_KEYWORD, 5, 0x0000FF, 0x000000}, + {SCE_JSON_LDKEYWORD, 6, 0x00AAAA, 0x000000}, + {SCE_JSON_ERROR, 15, 0xFF0000, 0x000000}, +}; + +std::pair keywordsJSON[] = +{ + {0, "false true null"}, + {1, +"@id @context @type @value @language @container @list @set @reverse @index " +"@base @vocab @graph " + }, +}; + +std::pair propertiesJSON[] = +{ + {"lexer.json.escape.sequence", "1"}, + {"lexer.json.allow.comments", "1"}, +}; + +constexpr std::array stylesBash[] = +{ + {SCE_SH_DEFAULT, 0, 0xFFFFFF, 0x000000}, + {SCE_SH_ERROR, 15, 0xFF0000, 0x000000}, + {SCE_SH_COMMENTLINE, 10, 0x008000, 0x000000}, + {SCE_SH_NUMBER, 13, 0x00FF00, 0x000000}, + {SCE_SH_WORD, 6, 0x0000FF, 0x000000}, + {SCE_SH_STRING, 11, 0xFFFF00, 0x000000}, + {SCE_SH_CHARACTER, 12, 0x0000FF, 0x000000}, + {SCE_SH_OPERATOR, 9, 0xAA00BB, 0x000000}, + {SCE_SH_IDENTIFIER, 0, 0xFFFFFF, 0x000000}, + {SCE_SH_SCALAR, 5, 0xFF8800, 0x000000}, + {SCE_SH_PARAM, 5, 0xFF8800, 0x000000}, + {SCE_SH_BACKTICKS, 5, 0xFF8800, 0x000000}, + {SCE_SH_HERE_DELIM, 7, 0xAAAAAA, 0x000000}, + {SCE_SH_HERE_Q, 7, 0xAAAAAA, 0x000000}, +}; + +std::pair keywordsBash[] = +{ + {0, +// Keywords +"case do done elif else esac fi for function if in select then time until while " +// Builtins +"alias bg bind break builtin caller cd command compgen complete compopt continue " +"declare dirs disown echo enable eval exec exit export fc fg getopts hash help " +"history jobs kill let local logout mapfile popd printf pushd pwd read readarray " +"readonly return set shift shopt source suspend test times trap type typeset ulimit " +"umask unalias unset wait " + }, +}; + +constexpr std::array stylesPascal[] = +{ + {SCE_PAS_DEFAULT, 0, 0xFFFFFF, 0x000000}, + {SCE_PAS_IDENTIFIER, 0, 0xFFFFFF, 0x000000}, + {SCE_PAS_COMMENT, 10, 0x008000, 0x000000}, + {SCE_PAS_COMMENT2, 10, 0x008000, 0x000000}, + {SCE_PAS_COMMENTLINE, 10, 0x008000, 0x000000}, + {SCE_PAS_PREPROCESSOR, 8, 0xFF00FF, 0x000000}, + {SCE_PAS_PREPROCESSOR2, 8, 0xFF00FF, 0x000000}, + {SCE_PAS_NUMBER, 13, 0x00FF00, 0x000000}, + {SCE_PAS_HEXNUMBER, 13, 0x00FF00, 0x000000}, + {SCE_PAS_WORD, 5, 0x0000FF, 0x000000}, + {SCE_PAS_STRING, 11, 0xFFFF00, 0x000000}, + {SCE_PAS_STRINGEOL, 11, 0xFFFF00, 0x000000}, + {SCE_PAS_CHARACTER, 12, 0x0000FF, 0x000000}, + {SCE_PAS_OPERATOR, 9, 0xAA00BB, 0x000000}, + {SCE_PAS_ASM, 7, 0xAAAAAA, 0x000000} +}; + +std::pair keywordsPascal[] = +{ + {0, +// Pascal +"and array asm begin break case const constructor continue destructor div do " +"downto else end false file for function goto if implementation in inline interface " +"label mod nil not object of on operator or packed procedure program record " +"repeat set shl shr string then to true type unit until uses var while with xor " + +"as class constref dispose except exit exports finalization finally inherited " +"initialization is library new on out property raise self threadvar try far near " + +"absolute abstract alias assembler cdecl Cppdecl default export external forward " +"generic index local name nostackframe oldfpccall override pascal private protected " +"public published read register reintroduce safecall softfloat specialize stdcall " +"virtual write " + +// Delphi +"resourcestring dispinterface strict nodefault stored automated final readonly " +"unsafe reference varargs contains helper overload implements winapi delayed package " +"requires deprecated resident writeonly dispid platform dynamic sealed experimental " +"message static " + } +}; + +void Editor::configureStyling(Language language){ //Style configuration TColorAttr textColor = {0xFFFFFF, 0x000000}; turbo::setStyleColor(scintilla, STYLE_DEFAULT, textColor); @@ -263,6 +401,8 @@ void Editor::configureStyling(Scintilla::ILexer5* lexer, Language lang){ TColorAttr selectionColor = {0xFFFFFF, 0x444466}; turbo::setSelectionColor(scintilla, selectionColor); + Scintilla::ILexer5 *lexer = getLexerForLanguage(language); + if(!lexer) { turbo::call(scintilla, SCI_SETLEXER, SCLEX_NULL, 0); return; @@ -277,27 +417,56 @@ void Editor::configureStyling(Scintilla::ILexer5* lexer, Language lang){ turbo::call(scintilla, SCI_COLOURISE, 0, -1); - switch (lang) { - case Language::Cpp: - for (int i = 0; i < 16; i++) { - TColorAttr color = {stylesC[i][2], stylesC[i][3]}; - turbo::setStyleColor(scintilla, stylesC[i][0], color); + switch (language) { + case Language::CPP: + for(const auto &s : stylesC) { + TColorAttr color = { s[2], s[3] }; + turbo::setStyleColor(scintilla, s[0], color); } - for (int i = 0; i < 3; i++) - turbo::call(scintilla, SCI_SETKEYWORDS, keywordsC[i].first, (sptr_t)keywordsC[i].second.c_str()); - for (int i = 0; i < 3; i++) - turbo::call(scintilla, SCI_SETPROPERTY, (sptr_t)propertiesC[i].first.c_str(), (sptr_t)propertiesC[i].second.c_str()); + for(const auto &k : keywordsC) + turbo::call(scintilla, SCI_SETKEYWORDS, k.first, (sptr_t)k.second.c_str()); + for(const auto &p : propertiesC) + turbo::call(scintilla, SCI_SETPROPERTY, (sptr_t)p.first.c_str(), (sptr_t)p.second.c_str()); break; case Language::Python: - for (int i = 0; i < 20; i++) { - TColorAttr color = {stylesPython[i][1], stylesPython[i][2]}; - turbo::setStyleColor(scintilla, stylesPython[i][0], color); + for(const auto &s : stylesPython) { + TColorAttr color = { s[1], s[2] }; + turbo::setStyleColor(scintilla, s[0], color); + } + for(const auto &k : keywordsPython) + turbo::call(scintilla, SCI_SETKEYWORDS, k.first, (sptr_t)k.second.c_str()); + for(const auto &p : propertiesPython) + turbo::call(scintilla, SCI_SETPROPERTY, (sptr_t)p.first.c_str(), (sptr_t)p.second.c_str()); + break; + + case Language::JSON: + for(const auto &s : stylesJSON) { + TColorAttr color = { s[1], s[2] }; + turbo::setStyleColor(scintilla, s[0], color); + } + for(const auto &k : keywordsJSON) + turbo::call(scintilla, SCI_SETKEYWORDS, k.first, (sptr_t)k.second.c_str()); + for(const auto &p : propertiesJSON) + turbo::call(scintilla, SCI_SETPROPERTY, (sptr_t)p.first.c_str(), (sptr_t)p.second.c_str()); + break; + + case Language::Bash: + for(const auto &s : stylesBash) { + TColorAttr color = { s[1], s[2] }; + turbo::setStyleColor(scintilla, s[0], color); + } + for(const auto &k : keywordsBash) + turbo::call(scintilla, SCI_SETKEYWORDS, k.first, (sptr_t)k.second.c_str()); + break; + + case Language::Pascal: + for(const auto &s : stylesPascal) { + TColorAttr color = { s[1], s[2] }; + turbo::setStyleColor(scintilla, s[0], color); } - for (int i = 0; i < 2; i++) - turbo::call(scintilla, SCI_SETKEYWORDS, keywordsPython[i].first, (sptr_t)keywordsPython[i].second.c_str()); - for (int i = 0; i < 1; i++) - turbo::call(scintilla, SCI_SETPROPERTY, (sptr_t)propertiesPython[i].first.c_str(), (sptr_t)propertiesPython[i].second.c_str()); + for(const auto &k : keywordsPascal) + turbo::call(scintilla, SCI_SETKEYWORDS, k.first, (sptr_t)k.second.c_str()); break; default: