Last active
July 10, 2021 09:05
-
-
Save luis-reyes-a/f25517a5e6a32b8b13d3434cc24998e1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
NOTE this doesn't really check if a specifier is entirely valid in order to highlight | |
for example if you have %lls we highlight it | |
we simply check each subspecifier in order to see if it seems valid and move on and don't have logic to see if | |
the subspecifiers are comptaible or not | |
we don't highlight if any of the subspecifier checks fail so if you do %.qd we don't highlight it | |
Also I commented out some checks that I wasn't sure if they were invalid in c++ but valid in C or ones that I just never use | |
Instructions | |
In 4coder_draw.cpp there a function draw_cpp_token_colors() that decides what color to draw tokens and draws them. | |
In the function there should be this: | |
ARGB_Color argb = fcolor_resolve(color); | |
paint_text_color(app, text_layout_id, Ii64_size(token->pos, token->size), argb); | |
You want to #if 0 the top of that and add an #else #endif right below and stick the following code in between the #else and #endif | |
so you can toggle this on and off in case you discover some bugs. And you might! I haven't had any problems with it though | |
Now when you compile you should get an error like "buffer_id" unrecognized identifier. | |
We have to pass the buffer_id of the buffer whose tokens we are rendering into draw_cpp_token_colors() | |
so we can parse the contents of the string | |
4coder_default_hooks.cpp has a default_render_buffer() which seems to be the only place that that function gets called and the | |
only place you need to pass in the buffer_id. Anyways cheers and let me know if you find bugs! | |
*/ | |
if(token->kind == TokenBaseKind_LiteralString && token->sub_kind != TokenCppKind_LiteralCharacter) | |
{ | |
Scratch_Block scratch(app); | |
String_Const_u8 string = push_token_lexeme(app, scratch, buffer_id, token); | |
ARGB_Color alt_argb = fcolor_resolve(fcolor_id(defcolor_comment)); | |
ARGB_Color str_argb = fcolor_resolve(fcolor_id(defcolor_str_constant)); | |
u64 normal_at = 0; //represents the substring before the specifier that we color normally | |
u64 normal_length = 0; //we iterate until we reach a specifier, color normal substring, specifier, and continue | |
for(u64 i = 0; i < string.size; /*we increment i ourselves*/ ) | |
{ | |
if(string.str[i] == '\\' || string.str[i] == '%') | |
{ | |
if(normal_length) //draw normal substring | |
paint_text_color(app, text_layout_id, Ii64_size(token->pos + normal_at, normal_length), str_argb); | |
//decides whether to actually color in the case where user hasn't finished typing the specifier | |
b32 actually_found_specifier = false; | |
i32 specifier_length = 0; | |
if(string.str[i] == '\\') | |
{ | |
//NOTE 4coder seems to not lex a token as a string token if nothing comes after the first '\' | |
//meaning it seems safe to just assume the specifier is complete and of length 2 | |
//NOTE I don't actually check if the escape character is valid because I don't care :P | |
specifier_length = 2; | |
actually_found_specifier = true; | |
goto JUST_DRAW_THE_FREAKING_STRING; //we use this extensively below to 'break' out if we pass the end of str | |
} | |
//else{} we have a printf specifier like so %[flags][width][.precision][length]specifier | |
//increments length but if we reach the ending " we just 'break' out and draw | |
#define INCREMENT_SPECIFIER_LENGTH do {specifier_length += 1; \ | |
if((i + specifier_length) >= (string.size - 1)) goto JUST_DRAW_THE_FREAKING_STRING; } while(0) | |
//next character to see if it's part of the specifier | |
#define NEXT string.str[i + specifier_length] | |
INCREMENT_SPECIFIER_LENGTH; //for first % | |
//[flags] | |
if(NEXT == '+' || NEXT == '-' || NEXT == '#' || NEXT == '0' /*|| NEXT == ' '*/) | |
INCREMENT_SPECIFIER_LENGTH; | |
//[width] is either '*' or a sequence of numbers denoting the width | |
if(NEXT == '*') INCREMENT_SPECIFIER_LENGTH; | |
else if(character_is_base10(NEXT)) | |
{ | |
while(character_is_base10(NEXT)) INCREMENT_SPECIFIER_LENGTH; | |
} | |
//[precision] begins with '.' and followed by either '*' or a sequence of numbers | |
if(NEXT == '.') | |
{ | |
INCREMENT_SPECIFIER_LENGTH; | |
if(NEXT == '*') INCREMENT_SPECIFIER_LENGTH; | |
else if(character_is_base10(NEXT)) | |
{ | |
while(character_is_base10(NEXT)) INCREMENT_SPECIFIER_LENGTH; | |
} | |
} | |
//[length] length can either be h, l, j, z, t, hh, ll | |
if(NEXT == 'j' || NEXT == 'z' || NEXT == 't') INCREMENT_SPECIFIER_LENGTH; | |
else if(NEXT == 'h') //hh | |
{ | |
INCREMENT_SPECIFIER_LENGTH; | |
if(NEXT == 'h') INCREMENT_SPECIFIER_LENGTH; //second h | |
} | |
else if(NEXT == 'l') //ll | |
{ | |
INCREMENT_SPECIFIER_LENGTH; | |
if(NEXT == 'l') INCREMENT_SPECIFIER_LENGTH; //second l | |
} | |
//the actual specifier where we decide if to actually highlight | |
if(NEXT == 'd' || NEXT == 'i' || NEXT == 'u' || NEXT == 'o' || NEXT == 'x' || NEXT == 'X' || | |
NEXT == 'f' || NEXT == 'e' || NEXT == 'g' || NEXT == '%' || NEXT == 'c' || NEXT == 's' || | |
NEXT == 'p' || NEXT == 'n') | |
/*NEXT == 'F' || NEXT == 'E' || NEXT == 'G' || NEXT == 'a' || NEXT == 'A' ||*/ | |
{ | |
actually_found_specifier = true; | |
INCREMENT_SPECIFIER_LENGTH; | |
} | |
JUST_DRAW_THE_FREAKING_STRING: | |
paint_text_color(app, text_layout_id, Ii64_size(token->pos + i, specifier_length), | |
actually_found_specifier ? alt_argb : str_argb); | |
i += specifier_length; | |
normal_at = i; | |
normal_length = 0; //to begin search for a new normal substring | |
#undef NEXT | |
#undef INCREMENT_SPECIFIER_LENGTH | |
} | |
else | |
{ | |
normal_length += 1; | |
i += 1; | |
} | |
} | |
//we do this one more time bc we only draw the normnal substring *before* specifiers | |
//so the normal substring after the last specifier won't come up in the loop | |
if(normal_length) paint_text_color(app, text_layout_id, Ii64_size(token->pos + normal_at, normal_length), str_argb); | |
} | |
else //normal token coloring | |
{ | |
ARGB_Color argb = fcolor_resolve(color); | |
paint_text_color(app, text_layout_id, Ii64_size(token->pos, token->size), argb); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment