diff --git a/code/custom/4coder_default_bindings.cpp b/code/custom/4coder_default_bindings.cpp index 46a78e4c..b893c98a 100644 --- a/code/custom/4coder_default_bindings.cpp +++ b/code/custom/4coder_default_bindings.cpp @@ -123,6 +123,85 @@ CUSTOM_COMMAND_SIG(cmd_alt_enter_behavior) } } +function i64 +qol_seek_char(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i64 start_pos, u8 target_char){ + Scratch_Block scratch(app); + i64 line = get_line_number_from_pos(app, buffer, start_pos); + Range_i64 range = get_line_pos_range(app, buffer, line); + range.max += 1; + String_Const_u8 string = push_buffer_range(app, scratch, buffer, range); + i64 pos = start_pos; + while(range_contains(range, pos)){ + pos += direction; + u8 current_char = string.str[pos - range.min]; + if (current_char == target_char){ return pos; } + } + return start_pos; +} + +CUSTOM_COMMAND_SIG(qol_char_forward) +CUSTOM_DOC("[QOL] Seeks forward in current line to the selected char") +{ + View_ID view = get_active_view(app, Access_ReadVisible); + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible); + i64 cursor_pos = view_get_cursor_pos(app, view); + i64 pos = qol_seek_char(app, buffer, Scan_Forward, cursor_pos, qol_target_char); + view_set_cursor_and_preferred_x(app, view, seek_pos(pos)); +} + +CUSTOM_COMMAND_SIG(qol_char_backward) +CUSTOM_DOC("[QOL] Seeks back in current line to the selected char") +{ + View_ID view = get_active_view(app, Access_ReadVisible); + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible); + i64 cursor_pos = view_get_cursor_pos(app, view); + i64 pos = qol_seek_char(app, buffer, Scan_Backward, cursor_pos, qol_target_char); + view_set_cursor_and_preferred_x(app, view, seek_pos(pos)); +} + +CUSTOM_COMMAND_SIG(qol_column_toggle) +CUSTOM_DOC("[QOL] Toggles the column for bumping and selects hovered char") +{ + View_ID view = get_active_view(app, Access_ReadVisible); + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible); + if (qol_col_cursor.pos < 0){ + i64 pos = view_get_cursor_pos(app, view); + qol_target_char = buffer_get_char(app, buffer, pos); + qol_col_cursor = buffer_compute_cursor(app, buffer, seek_pos(pos)); + } + else{ + qol_col_cursor.pos = -1; + } +} + +CUSTOM_COMMAND_SIG(qol_write_space) +CUSTOM_DOC("[QOL] Writes as many spaces needed for bumping to column") +{ + Scratch_Block scratch(app); + if (qol_col_cursor.pos > 0){ + View_ID view = get_active_view(app, Access_ReadVisible); + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible); + + qol_col_cursor = buffer_compute_cursor(app, buffer, seek_line_col(qol_col_cursor.line, qol_col_cursor.col)); + + i64 pos = view_get_cursor_pos(app, view); + i64 line = get_line_number_from_pos(app, buffer, pos); + f32 col_x = view_relative_xy_of_pos(app, view, line, qol_col_cursor.pos).x; + f32 cur_x = view_relative_xy_of_pos(app, view, line, pos).x; + Face_ID face = get_face_id(app, buffer); + f32 space_advance = get_face_metrics(app, face).space_advance; + + i64 N = i64((col_x - cur_x) / space_advance); + if (N < 0){ N = 1; } + String_Const_u8 spaces = string_const_u8_push(scratch, N); + block_fill_u8(spaces.str, N, ' '); + write_text(app, spaces); + } + else{ + write_space(app); + } +} + function void bindings_cmd_misc(Mapping* m, Command_Map* map) @@ -231,6 +310,11 @@ custom_keyboard_bindings() Bind(unindent_range, KeyCode_Tab, KeyCode_Shift); Bind(indent_range, KeyCode_Tab); + Bind(qol_column_toggle, KeyCode_BackwardSlash, key_alt); + Bind(qol_write_space, KeyCode_Space, key_alt, KeyCode_Shift); + Bind(qol_char_forward, KeyCode_L, key_alt); + Bind(qol_char_backward, KeyCode_J, key_alt); + // Macros Bind(keyboard_macro_start_recording, KeyCode_1, key_alt); Bind(keyboard_macro_finish_recording, KeyCode_2, key_alt); diff --git a/code/custom/4coder_default_hooks.cpp b/code/custom/4coder_default_hooks.cpp index 82d9ac90..c727dbf2 100644 --- a/code/custom/4coder_default_hooks.cpp +++ b/code/custom/4coder_default_hooks.cpp @@ -326,50 +326,50 @@ default_render_buffer(Application_Links *app, View_ID view_id, Face_ID face_id, // NOTE(allen): Token colorizing -ARGB_Color color_default = fcolor_resolve(fcolor_id(defcolor_text_default)); - ARGB_Color color_function = fcolor_resolve(fcolor_id(defcolor_function)); - ARGB_Color color_operator = fcolor_resolve(fcolor_id(defcolor_operator)); - ARGB_Color color_type = fcolor_resolve(fcolor_id(defcolor_type)); - ARGB_Color color_macro = fcolor_resolve(fcolor_id(defcolor_macro)); + ARGB_Color color_default = fcolor_resolve(fcolor_id(defcolor_text_default)); + ARGB_Color color_function = fcolor_resolve(fcolor_id(defcolor_function)); + ARGB_Color color_operator = fcolor_resolve(fcolor_id(defcolor_operator)); + ARGB_Color color_type = fcolor_resolve(fcolor_id(defcolor_type)); + ARGB_Color color_macro = fcolor_resolve(fcolor_id(defcolor_macro)); Token_Array token_array = get_token_array_from_buffer(app, buffer); if (token_array.tokens != 0){ - draw_cpp_token_colors(app, text_layout_id, &token_array); + draw_cpp_token_colors(app, text_layout_id, &token_array); - // NOTE(allen): Scan for TODOs and NOTEs - b32 use_comment_keyword = def_get_config_b32(vars_save_string_lit("use_comment_keyword")); - if (use_comment_keyword){ - Comment_Highlight_Pair pairs[] = { - {string_u8_litexpr("NOTE"), finalize_color(defcolor_comment_pop, 0)}, - {string_u8_litexpr("TODO"), finalize_color(defcolor_comment_pop, 1)}, - }; - draw_comment_highlights(app, buffer, text_layout_id, &token_array, pairs, ArrayCount(pairs)); + // NOTE(allen): Scan for TODOs and NOTEs + b32 use_comment_keyword = def_get_config_b32(vars_save_string_lit("use_comment_keyword")); + if (use_comment_keyword){ + Comment_Highlight_Pair pairs[] = { + {string_u8_litexpr("NOTE"), finalize_color(defcolor_comment_pop, 0)}, + {string_u8_litexpr("TODO"), finalize_color(defcolor_comment_pop, 1)}, + }; + draw_comment_highlights(app, buffer, text_layout_id, &token_array, pairs, ArrayCount(pairs)); + } + + // NOTE(allen): Color functions + Scratch_Block scratch(app); + + Token_Iterator_Array it = token_iterator_pos(0, &token_array, visible_range.first); + it.count = Min(it.count, visible_range.one_past_last - visible_range.first); + for (;;){ + if (!token_it_inc_non_whitespace(&it)){ + break; } - // NOTE(allen): Color functions - Scratch_Block scratch(app); - - Token_Iterator_Array it = token_iterator_pos(0, &token_array, visible_range.first); - it.count = Min(it.count, visible_range.one_past_last - visible_range.first); - for (;;){ - if (!token_it_inc_non_whitespace(&it)){ - break; - } - - ARGB_Color token_color = color_default; - Token *token = token_it_read(&it); - if (token->kind == TokenBaseKind_Operator || - token->kind == TokenBaseKind_ScopeOpen || - token->kind == TokenBaseKind_ScopeClose || - token->kind == TokenBaseKind_ParentheticalOpen || - token->kind == TokenBaseKind_ParentheticalClose || - token->kind == TokenBaseKind_StatementClose) - { -token_color = color_operator; - } - else - { -String_Const_u8 lexeme = push_token_lexeme(app, scratch, buffer, token); + ARGB_Color token_color = color_default; + Token *token = token_it_read(&it); + if (token->kind == TokenBaseKind_Operator || + token->kind == TokenBaseKind_ScopeOpen || + token->kind == TokenBaseKind_ScopeClose || + token->kind == TokenBaseKind_ParentheticalOpen || + token->kind == TokenBaseKind_ParentheticalClose || + token->kind == TokenBaseKind_StatementClose) + { + token_color = color_operator; + } + else + { + String_Const_u8 lexeme = push_token_lexeme(app, scratch, buffer, token); Code_Index_Note *note = code_index_note_from_string(lexeme); if (note != 0) { @@ -381,14 +381,14 @@ String_Const_u8 lexeme = push_token_lexeme(app, scratch, buffer, token); default: {} break; } } - } - paint_text_color(app, text_layout_id, Ii64_size(token->pos, token->size), token_color); - } - } - else - { - paint_text_color(app, text_layout_id, visible_range, color_default); - } + } + paint_text_color(app, text_layout_id, Ii64_size(token->pos, token->size), token_color); + } + } + else + { + paint_text_color(app, text_layout_id, visible_range, color_default); + } i64 cursor_pos = view_correct_cursor(app, view_id); view_correct_mark(app, view_id); @@ -400,6 +400,18 @@ String_Const_u8 lexeme = push_token_lexeme(app, scratch, buffer, token); draw_scope_highlight(app, buffer, text_layout_id, cursor_pos, colors.vals, colors.count); } + // NOTE(PS): QOL Column + if (qol_col_cursor.pos >= 0){ + Buffer_Seek seek = seek_line_col(qol_col_cursor.line, qol_col_cursor.col); + Buffer_Cursor cursor = buffer_compute_cursor(app, buffer, seek); + Rect_f32 col_rect = text_layout_character_on_screen(app, text_layout_id, cursor.pos); + if (col_rect.x1 > 0.f){ + col_rect.y0 = rect.y0; + col_rect.y1 = rect.y1; + draw_rectangle_fcolor(app, col_rect, 0.f, fcolor_id(defcolor_highlight_cursor_line)); + } + } + b32 use_error_highlight = def_get_config_b32(vars_save_string_lit("use_error_highlight")); b32 use_jump_highlight = def_get_config_b32(vars_save_string_lit("use_jump_highlight")); if (use_error_highlight || use_jump_highlight){ diff --git a/code/custom/4coder_default_include.cpp b/code/custom/4coder_default_include.cpp index c0f7fe75..198ace40 100644 --- a/code/custom/4coder_default_include.cpp +++ b/code/custom/4coder_default_include.cpp @@ -64,6 +64,7 @@ #include "4coder_tutorial.h" #include "4coder_search_list.h" #include "4coder_modal.h" +#include "4coder_qol.h" //////////////////////////////// @@ -147,6 +148,8 @@ #include "4coder_default_hooks.cpp" +#include "4coder_qol.cpp" + #endif // BOTTOM diff --git a/code/custom/4coder_qol.cpp b/code/custom/4coder_qol.cpp new file mode 100644 index 00000000..e69de29b diff --git a/code/custom/4coder_qol.h b/code/custom/4coder_qol.h new file mode 100644 index 00000000..68e913ab --- /dev/null +++ b/code/custom/4coder_qol.h @@ -0,0 +1,9 @@ +/* date = July 7th 2025 2:22 pm */ + +#ifndef FCODER_QOL_H +#define FCODER_QOL_H + +global u8 qol_target_char; +global Buffer_Cursor qol_col_cursor = {-1}; + +#endif //FCODER_QOL_H