Skip to content

Instantly share code, notes, and snippets.

@thevaber
Created January 29, 2020 19:09
Show Gist options
  • Save thevaber/7edf0b3890cf390d1ec2861b655d8600 to your computer and use it in GitHub Desktop.
Save thevaber/7edf0b3890cf390d1ec2861b655d8600 to your computer and use it in GitHub Desktop.
4coder "toggle_token" command
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