mirror of
https://github.com/RGBCube/serenity
synced 2025-05-28 19:55:10 +00:00
HackStudio: Assorted improvements to C++ highlighting
Add a list of hard-coded standard types (including AK types) and show them in a different style. Rehighligt the file whenever it changes. (This is very inefficient but makes it much easier to experiment.) Also keep tweaking the colors. :^)
This commit is contained in:
parent
2b19badd74
commit
ed242d538a
3 changed files with 111 additions and 36 deletions
|
@ -48,28 +48,22 @@ static bool is_keyword(const StringView& string)
|
|||
keywords.set("and");
|
||||
keywords.set("and_eq");
|
||||
keywords.set("asm");
|
||||
keywords.set("auto");
|
||||
keywords.set("bitand");
|
||||
keywords.set("bitor");
|
||||
keywords.set("bool");
|
||||
keywords.set("break");
|
||||
keywords.set("case");
|
||||
keywords.set("catch");
|
||||
keywords.set("char");
|
||||
keywords.set("char8_t");
|
||||
keywords.set("char16_t");
|
||||
keywords.set("char32_t");
|
||||
keywords.set("class");
|
||||
keywords.set("compl");
|
||||
keywords.set("const");
|
||||
keywords.set("constexpr");
|
||||
keywords.set("const_cast");
|
||||
keywords.set("constexpr");
|
||||
keywords.set("continue");
|
||||
keywords.set("decltype");
|
||||
keywords.set("default");
|
||||
keywords.set("delete");
|
||||
keywords.set("do");
|
||||
keywords.set("double");
|
||||
keywords.set("dynamic_cast");
|
||||
keywords.set("else");
|
||||
keywords.set("enum");
|
||||
|
@ -77,14 +71,12 @@ static bool is_keyword(const StringView& string)
|
|||
keywords.set("export");
|
||||
keywords.set("extern");
|
||||
keywords.set("false");
|
||||
keywords.set("float");
|
||||
keywords.set("final");
|
||||
keywords.set("for");
|
||||
keywords.set("friend");
|
||||
keywords.set("goto");
|
||||
keywords.set("if");
|
||||
keywords.set("inline");
|
||||
keywords.set("int");
|
||||
keywords.set("long");
|
||||
keywords.set("mutable");
|
||||
keywords.set("namespace");
|
||||
keywords.set("new");
|
||||
|
@ -95,13 +87,13 @@ static bool is_keyword(const StringView& string)
|
|||
keywords.set("operator");
|
||||
keywords.set("or");
|
||||
keywords.set("or_eq");
|
||||
keywords.set("override");
|
||||
keywords.set("private");
|
||||
keywords.set("protected");
|
||||
keywords.set("public");
|
||||
keywords.set("register");
|
||||
keywords.set("reinterpret_cast");
|
||||
keywords.set("return");
|
||||
keywords.set("short");
|
||||
keywords.set("signed");
|
||||
keywords.set("sizeof");
|
||||
keywords.set("static");
|
||||
|
@ -119,12 +111,9 @@ static bool is_keyword(const StringView& string)
|
|||
keywords.set("typeid");
|
||||
keywords.set("typename");
|
||||
keywords.set("union");
|
||||
keywords.set("unsigned");
|
||||
keywords.set("using");
|
||||
keywords.set("virtual");
|
||||
keywords.set("void");
|
||||
keywords.set("volatile");
|
||||
keywords.set("wchar_t");
|
||||
keywords.set("while");
|
||||
keywords.set("xor");
|
||||
keywords.set("xor_eq");
|
||||
|
@ -132,6 +121,72 @@ static bool is_keyword(const StringView& string)
|
|||
return keywords.contains(string);
|
||||
}
|
||||
|
||||
static bool is_known_type(const StringView& string)
|
||||
{
|
||||
static HashTable<String> types;
|
||||
if (types.is_empty()) {
|
||||
types.set("ByteBuffer");
|
||||
types.set("CircularDeque");
|
||||
types.set("CircularQueue");
|
||||
types.set("Deque");
|
||||
types.set("DoublyLinkedList");
|
||||
types.set("FileSystemPath");
|
||||
types.set("FixedArray");
|
||||
types.set("Function");
|
||||
types.set("HashMap");
|
||||
types.set("HashTable");
|
||||
types.set("IPv4Address");
|
||||
types.set("InlineLinkedList");
|
||||
types.set("IntrusiveList");
|
||||
types.set("JsonArray");
|
||||
types.set("JsonObject");
|
||||
types.set("JsonValue");
|
||||
types.set("MappedFile");
|
||||
types.set("NetworkOrdered");
|
||||
types.set("NonnullOwnPtr");
|
||||
types.set("NonnullOwnPtrVector");
|
||||
types.set("NonnullRefPtr");
|
||||
types.set("NonnullRefPtrVector");
|
||||
types.set("Optional");
|
||||
types.set("OwnPtr");
|
||||
types.set("RefPtr");
|
||||
types.set("Result");
|
||||
types.set("ScopeGuard");
|
||||
types.set("SinglyLinkedList");
|
||||
types.set("String");
|
||||
types.set("StringBuilder");
|
||||
types.set("StringImpl");
|
||||
types.set("StringView");
|
||||
types.set("Utf8View");
|
||||
types.set("Vector");
|
||||
types.set("WeakPtr");
|
||||
types.set("auto");
|
||||
types.set("char");
|
||||
types.set("char16_t");
|
||||
types.set("char32_t");
|
||||
types.set("char8_t");
|
||||
types.set("double");
|
||||
types.set("float");
|
||||
types.set("i16");
|
||||
types.set("i32");
|
||||
types.set("i64");
|
||||
types.set("i8");
|
||||
types.set("int");
|
||||
types.set("int");
|
||||
types.set("long");
|
||||
types.set("short");
|
||||
types.set("signed");
|
||||
types.set("u16");
|
||||
types.set("u32");
|
||||
types.set("u64");
|
||||
types.set("u8");
|
||||
types.set("unsigned");
|
||||
types.set("void");
|
||||
types.set("wchar_t");
|
||||
}
|
||||
return types.contains(string);
|
||||
}
|
||||
|
||||
Vector<CppToken> CppLexer::lex()
|
||||
{
|
||||
Vector<CppToken> tokens;
|
||||
|
@ -268,6 +323,8 @@ Vector<CppToken> CppLexer::lex()
|
|||
auto token_view = StringView(m_input.characters_without_null_termination() + token_start_index, m_index - token_start_index);
|
||||
if (is_keyword(token_view))
|
||||
commit_token(CppToken::Type::Keyword);
|
||||
else if (is_known_type(token_view))
|
||||
commit_token(CppToken::Type::KnownType);
|
||||
else
|
||||
commit_token(CppToken::Type::Identifier);
|
||||
continue;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
__TOKEN(Comment) \
|
||||
__TOKEN(Number) \
|
||||
__TOKEN(Keyword) \
|
||||
__TOKEN(KnownType) \
|
||||
__TOKEN(Identifier)
|
||||
|
||||
struct CppPosition {
|
||||
|
|
|
@ -178,6 +178,8 @@ int main(int argc, char** argv)
|
|||
g_window->set_icon(small_icon);
|
||||
|
||||
g_window->show();
|
||||
|
||||
open_file("main.cpp");
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
|
@ -201,21 +203,46 @@ static TextStyle style_for_token_type(CppToken::Type type)
|
|||
switch (type) {
|
||||
case CppToken::Type::Keyword:
|
||||
return { Color::Black, &Font::default_bold_fixed_width_font() };
|
||||
case CppToken::Type::KnownType:
|
||||
return { Color::from_rgb(0x929200), &Font::default_bold_fixed_width_font() };
|
||||
case CppToken::Type::Identifier:
|
||||
return { Color::Blue };
|
||||
return { Color::from_rgb(0x000092), &Font::default_bold_fixed_width_font() };
|
||||
case CppToken::Type::DoubleQuotedString:
|
||||
case CppToken::Type::SingleQuotedString:
|
||||
case CppToken::Type::Number:
|
||||
return { Color::Red };
|
||||
return { Color::from_rgb(0x920000) };
|
||||
case CppToken::Type::PreprocessorStatement:
|
||||
return { Color::Magenta };
|
||||
return { Color::from_rgb(0x009292) };
|
||||
case CppToken::Type::Comment:
|
||||
return { Color::from_rgb(0x008200) };
|
||||
return { Color::from_rgb(0x009200) };
|
||||
default:
|
||||
return { Color::Black };
|
||||
}
|
||||
}
|
||||
|
||||
static void rehighlight()
|
||||
{
|
||||
auto text = g_text_editor->text();
|
||||
CppLexer lexer(text);
|
||||
auto tokens = lexer.lex();
|
||||
|
||||
Vector<GTextEditor::Span> spans;
|
||||
for (auto& token : tokens) {
|
||||
#ifdef DEBUG_SYNTAX_HIGHLIGHTING
|
||||
dbg() << token.to_string() << " @ " << token.m_start.line << ":" << token.m_start.column << " - " << token.m_end.line << ":" << token.m_end.column;
|
||||
#endif
|
||||
GTextEditor::Span span;
|
||||
span.start = { token.m_start.line, token.m_start.column };
|
||||
span.end = { token.m_end.line, token.m_end.column };
|
||||
auto style = style_for_token_type(token.m_type);
|
||||
span.color = style.color;
|
||||
span.font = style.font;
|
||||
spans.append(span);
|
||||
}
|
||||
g_text_editor->set_spans(spans);
|
||||
g_text_editor->update();
|
||||
}
|
||||
|
||||
void open_file(const String& filename)
|
||||
{
|
||||
auto file = CFile::construct(filename);
|
||||
|
@ -225,25 +252,15 @@ void open_file(const String& filename)
|
|||
}
|
||||
auto contents = file->read_all();
|
||||
g_text_editor->set_text(contents);
|
||||
|
||||
if (filename.ends_with(".cpp")) {
|
||||
g_text_editor->on_change = [] { rehighlight(); };
|
||||
rehighlight();
|
||||
} else {
|
||||
g_text_editor->on_change = nullptr;
|
||||
}
|
||||
|
||||
g_currently_open_file = filename;
|
||||
g_window->set_title(String::format("%s - HackStudio", g_currently_open_file.characters()));
|
||||
g_project_list_view->update();
|
||||
|
||||
if (filename.ends_with(".cpp")) {
|
||||
CppLexer lexer(contents);
|
||||
auto tokens = lexer.lex();
|
||||
|
||||
Vector<GTextEditor::Span> spans;
|
||||
for (auto& token : tokens) {
|
||||
dbg() << token.to_string() << " @ " << token.m_start.line << ":" << token.m_start.column << " - " << token.m_end.line << ":" << token.m_end.column;
|
||||
GTextEditor::Span span;
|
||||
span.start = { token.m_start.line, token.m_start.column };
|
||||
span.end = { token.m_end.line, token.m_end.column };
|
||||
auto style = style_for_token_type(token.m_type);
|
||||
span.color = style.color;
|
||||
span.font = style.font;
|
||||
spans.append(span);
|
||||
}
|
||||
g_text_editor->set_spans(spans);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue