Created
January 29, 2020 19:09
-
-
Save thevaber/7edf0b3890cf390d1ec2861b655d8600 to your computer and use it in GitHub Desktop.
4coder "toggle_token" command
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
function b32 | |
tv_toggle_token(Application_Links* app, Buffer_ID buffer, View_ID view, Token* tok) | |
{ | |
if (!tok) { | |
return false; | |
} | |
Scratch_Block scratch(app); | |
String_Const_u8 replacement = {}; | |
if (tok->sub_kind == TokenCppKind_LiteralTrue) replacement = string_u8_litexpr("false"); | |
else if (tok->sub_kind == TokenCppKind_LiteralFalse) replacement = string_u8_litexpr("true"); | |
else if (tok->sub_kind == TokenCppKind_PlusPlus) replacement = string_u8_litexpr("--"); | |
else if (tok->sub_kind == TokenCppKind_MinusMinus) replacement = string_u8_litexpr("++"); | |
else if (tok->sub_kind == TokenCppKind_EqEq) replacement = string_u8_litexpr("!="); | |
else if (tok->sub_kind == TokenCppKind_NotEq) replacement = string_u8_litexpr("=="); | |
else if (tok->sub_kind == TokenCppKind_Grtr) replacement = string_u8_litexpr("<"); | |
else if (tok->sub_kind == TokenCppKind_Less) replacement = string_u8_litexpr(">"); | |
else if (tok->sub_kind == TokenCppKind_GrtrEq) replacement = string_u8_litexpr("<="); | |
else if (tok->sub_kind == TokenCppKind_LessEq) replacement = string_u8_litexpr(">="); | |
else if (tok->sub_kind == TokenCppKind_Arrow) replacement = string_u8_litexpr("."); | |
else if (tok->sub_kind == TokenCppKind_Dot) replacement = string_u8_litexpr("->"); | |
else if (tok->sub_kind == TokenCppKind_ArrowStar) replacement = string_u8_litexpr(".*"); | |
else if (tok->sub_kind == TokenCppKind_DotStar) replacement = string_u8_litexpr("->*"); | |
else if (tok->sub_kind == TokenCppKind_LeftLeft) replacement = string_u8_litexpr(">>"); | |
else if (tok->sub_kind == TokenCppKind_LeftLeftEq) replacement = string_u8_litexpr(">>="); | |
else if (tok->sub_kind == TokenCppKind_RightRight) replacement = string_u8_litexpr("<<"); | |
else if (tok->sub_kind == TokenCppKind_RightRightEq) replacement = string_u8_litexpr("<<="); | |
else if (tok->sub_kind == TokenCppKind_OrOr) replacement = string_u8_litexpr("&&"); | |
else if (tok->sub_kind == TokenCppKind_AndAnd) replacement = string_u8_litexpr("||"); | |
else if (tok->sub_kind == TokenCppKind_Or) replacement = string_u8_litexpr("&"); | |
else if (tok->sub_kind == TokenCppKind_And) replacement = string_u8_litexpr("|"); | |
else if (tok->sub_kind == TokenCppKind_Minus) replacement = string_u8_litexpr("+"); | |
else if (tok->sub_kind == TokenCppKind_MinusEq) replacement = string_u8_litexpr("+="); | |
else if (tok->sub_kind == TokenCppKind_Plus) replacement = string_u8_litexpr("-"); | |
else if (tok->sub_kind == TokenCppKind_PlusEq) replacement = string_u8_litexpr("-="); | |
else if (tok->sub_kind == TokenCppKind_Public) replacement = string_u8_litexpr("protected"); | |
else if (tok->sub_kind == TokenCppKind_Protected) replacement = string_u8_litexpr("private"); | |
else if (tok->sub_kind == TokenCppKind_Private) replacement = string_u8_litexpr("public"); | |
else if (tok->sub_kind == TokenCppKind_Class) replacement = string_u8_litexpr("struct"); | |
else if (tok->sub_kind == TokenCppKind_Struct) replacement = string_u8_litexpr("class"); | |
else if (tok->sub_kind == TokenCppKind_Break) replacement = string_u8_litexpr("continue"); | |
else if (tok->sub_kind == TokenCppKind_Continue) replacement = string_u8_litexpr("break"); | |
else if (tok->sub_kind == TokenCppKind_Float) replacement = string_u8_litexpr("double"); | |
else if (tok->sub_kind == TokenCppKind_Double) replacement = string_u8_litexpr("float"); | |
else if (tok->kind == TokenBaseKind_Identifier) { | |
struct local { | |
static b32 try_replacement_word(char* buf, String_Const_u8 identifier, String_Const_u8 from, String_Const_u8 to, String_Const_u8* out) | |
{ | |
if (try_replacement_word_asymmetrical(buf, identifier, from, to, out)) return true; | |
else if (try_replacement_word_asymmetrical(buf, identifier, to, from, out)) return true; | |
return false; | |
} | |
static b32 try_replacement_word_asymmetrical(char* buf, String_Const_u8 identifier, String_Const_u8 from, String_Const_u8 to, String_Const_u8* out) | |
{ | |
String_Const_u8 identifier2 = identifier; | |
b32 first_underscore = false; | |
if (identifier.size > 0 && identifier.str[0] == '_') { | |
identifier2.size--; | |
identifier2.str++; | |
first_underscore = true; | |
} | |
if (string_match_insensitive(identifier2, from)) { | |
char* buf2 = buf; | |
if (first_underscore) { | |
buf[0] = '_'; | |
buf2++; | |
} | |
i32 n_uppercase = 0; | |
i32 n_lowercase = 0; | |
i32 n_letters = 0; | |
for (u64 i = 0; i < identifier2.size; i++) { | |
char c = identifier2.str[i]; | |
if (character_is_upper(c)) n_uppercase++; | |
else if (character_is_lower(c)) n_lowercase++; | |
if (character_is_alpha(c)) n_letters++; | |
} | |
if (n_letters == n_uppercase) { | |
for (u64 i = 0; i < to.size; i++) { | |
buf2[i] = character_to_upper(to.str[i]); | |
} | |
} else if (n_letters == n_lowercase) { | |
for (u64 i = 0; i < to.size; i++) { | |
buf2[i] = character_to_lower(to.str[i]); | |
} | |
} else if (n_uppercase == 1 && n_lowercase >= 1) { | |
b32 did_first = false; | |
for (u64 i = 0; i < to.size; i++) { | |
if (character_is_alpha(to.str[i]) && !did_first) { | |
buf2[i] = character_to_upper(to.str[i]); | |
did_first = true; | |
} else { | |
buf2[i] = character_to_lower(to.str[i]); | |
} | |
} | |
} else { | |
for (u64 i = 0; i < to.size; i++) { | |
buf2[i] = to.str[i]; | |
} | |
} | |
*out = SCu8(buf, to.size + (first_underscore?1:0)); | |
return true; | |
} else { | |
return false; | |
} | |
} | |
}; | |
char buf[256]; | |
String_Const_u8 identifier = push_buffer_range(app, scratch, buffer, Ii64_size(tok->pos, tok->size)); | |
if (local::try_replacement_word(buf, identifier, string_u8_litexpr("f32"), string_u8_litexpr("f64"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("b8"), string_u8_litexpr("b32"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("bool32"), string_u8_litexpr("bool8"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("true"), string_u8_litexpr("false"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("s8"), string_u8_litexpr("u8"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("s16"), string_u8_litexpr("u16"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("s32"), string_u8_litexpr("u32"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("s64"), string_u8_litexpr("u64"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("min"), string_u8_litexpr("max"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("minimum"), string_u8_litexpr("maximum"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("start"), string_u8_litexpr("end"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("first"), string_u8_litexpr("last"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("head"), string_u8_litexpr("tail"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("from"), string_u8_litexpr("to"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("src"), string_u8_litexpr("dst"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("in"), string_u8_litexpr("out"), &replacement)) {} | |
else if (local::try_replacement_word(buf, identifier, string_u8_litexpr("next"), string_u8_litexpr("prev"), &replacement)) {} | |
else return false; | |
} | |
else return false; | |
i64 old_cursor_pos = view_get_cursor_pos(app, view); | |
i64 max_new_cursor_pos = (tok->pos + (i64)replacement.size - 1); | |
i64 new_cursor_pos = (old_cursor_pos <= max_new_cursor_pos) ? old_cursor_pos : max_new_cursor_pos; | |
buffer_replace_range(app, buffer, Ii64_size(tok->pos, tok->size), replacement); | |
view_set_cursor_and_preferred_x(app, view, seek_pos(new_cursor_pos)); | |
return true; | |
} | |
CUSTOM_COMMAND_SIG(toggle_token) | |
CUSTOM_DOC("'Toggle' C/C++ token under cursor") | |
{ | |
View_ID view = get_active_view(app, Access_ReadVisible); | |
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible); | |
i64 pos = view_get_cursor_pos(app, view); | |
Token_Array token_array = get_token_array_from_buffer(app, buffer); | |
if (token_array.tokens == 0) { | |
return; | |
} | |
Token* tok = get_token_from_pos(app, &token_array, pos); | |
if (!tok) { | |
return; | |
} | |
tv_toggle_token(app, buffer, view, tok); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment