diff --git a/4coder_style.h b/4coder_style.h index 7c88d18d..576ada94 100644 --- a/4coder_style.h +++ b/4coder_style.h @@ -24,6 +24,7 @@ Stag_Bool_Constant, Stag_Preproc, Stag_Include, Stag_Special_Character, +Stag_Ghost_Character, Stag_Highlight_Junk, Stag_Highlight_White, Stag_Paste, diff --git a/4ed.cpp b/4ed.cpp index 3e4c0de0..ba5091a4 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -861,6 +861,7 @@ app_hardcode_styles(Models *models){ style->main.include_color = style->main.str_constant_color; style->main.preproc_color = style->main.default_color; style->main.special_character_color = 0xFFFF0000; + style->main.ghost_character_color = color_blend(style->main.default_color, 0.5f, style->main.back_color); style->main.paste_color = 0xFFDDEE00; style->main.undo_color = 0xFF00DDEE; @@ -899,6 +900,7 @@ app_hardcode_styles(Models *models){ style->main.include_color = 0xFF6B8E23; style->main.preproc_color = 0xFFDAB98F; style->main.special_character_color = 0xFFFF0000; + style->main.ghost_character_color = color_blend(style->main.default_color, 0.5f, style->main.back_color); style->main.paste_color = 0xFFFFBB00; style->main.undo_color = 0xFF80005D; @@ -937,6 +939,7 @@ app_hardcode_styles(Models *models){ style->main.include_color = style->main.str_constant_color; style->main.preproc_color = style->main.default_color; style->main.special_character_color = 0xFFFF0000; + style->main.ghost_character_color = color_blend(0xFFFFFFFF, 0.75f, style->main.back_color); style->main.paste_color = 0xFFDDEE00; style->main.undo_color = 0xFF00DDEE; @@ -975,6 +978,7 @@ app_hardcode_styles(Models *models){ style->main.include_color = style->main.str_constant_color; style->main.preproc_color = style->main.default_color; style->main.special_character_color = 0xFFFF0000; + style->main.ghost_character_color = color_blend(style->main.default_color, 0.5f, style->main.back_color); style->main.paste_color = 0xFF900090; style->main.undo_color = 0xFF606090; @@ -1013,6 +1017,7 @@ app_hardcode_styles(Models *models){ style->main.include_color = style->main.str_constant_color; style->main.preproc_color = style->main.default_color; style->main.special_character_color = 0xFF9A0000; + style->main.ghost_character_color = color_blend(style->main.default_color, 0.5f, style->main.back_color); style->main.paste_color = 0xFF00B8B8; style->main.undo_color = 0xFFB800B8; @@ -1051,6 +1056,7 @@ app_hardcode_styles(Models *models){ style->main.bool_constant_color = 0xFF007C00; style->main.preproc_color = 0xFF0000FF; style->main.special_character_color = 0xFF9A0000; + style->main.ghost_character_color = color_blend(style->main.default_color, 0.5f, style->main.back_color); style->main.paste_color = 0xFFB87600; style->main.undo_color = 0xFFB87600; @@ -1089,6 +1095,7 @@ app_hardcode_styles(Models *models){ style->main.include_color = 0xFF9a99e7; style->main.preproc_color = 0xFF606590; style->main.special_character_color = 0xFFFF0000; + style->main.ghost_character_color = color_blend(style->main.default_color, 0.5f, style->main.back_color); style->main.paste_color = 0xFFFFBB00; style->main.undo_color = 0xFF80005D; diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 1632e61f..a64290ee 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -1016,7 +1016,7 @@ struct Potential_Wrap_Indent_Pair{ i32 wrap_position; f32 line_shift; - f32 start_x; + f32 wrap_x; i32 wrappable_score; }; @@ -1192,7 +1192,7 @@ wrap_state_consume_token(Code_Wrap_State *state, i32 fixed_end_point){ } internal i32 -stickieness_guess(Cpp_Token_Type type, Cpp_Token_Type other_type, b32 on_left, b32 in_parens){ +stickieness_guess(Cpp_Token_Type type, Cpp_Token_Type other_type, u16 flags, u16 other_flags, b32 on_left){ i32 guess = 0; b32 is_words = 0, other_is_words = 0; @@ -1203,6 +1203,14 @@ stickieness_guess(Cpp_Token_Type type, Cpp_Token_Type other_type, b32 on_left, b other_is_words = 1; } + b32 is_operator = 0, other_is_operator = 0; + if (flags & CPP_TFLAG_IS_OPERATOR){ + is_operator = 1; + } + if (other_flags & CPP_TFLAG_IS_OPERATOR){ + other_is_operator = 1; + } + i32 operator_side_bias = 70*(!on_left); if (is_words && other_is_words){ @@ -1213,7 +1221,7 @@ stickieness_guess(Cpp_Token_Type type, Cpp_Token_Type other_type, b32 on_left, b guess = 0; } else{ - if (other_type == CPP_TOKEN_IDENTIFIER){ + if (other_is_words){ guess = 100; } } @@ -1223,7 +1231,7 @@ stickieness_guess(Cpp_Token_Type type, Cpp_Token_Type other_type, b32 on_left, b guess = 0; } else{ - guess = 200; + guess = 1000; } } else if (type == CPP_TOKEN_COLON || @@ -1257,14 +1265,21 @@ stickieness_guess(Cpp_Token_Type type, Cpp_Token_Type other_type, b32 on_left, b guess = 60; } } + else if (type == CPP_TOKEN_DOT || + type == CPP_TOKEN_ARROW){ + guess = 200; + } else if (type == CPP_TOKEN_INCREMENT || type == CPP_TOKEN_DECREMENT || type == CPP_TOKEN_STAR || type == CPP_TOKEN_AMPERSAND || type == CPP_TOKEN_TILDE || (type >= CPP_TOKEN_POSTINC && - type <= CPP_TOKEN_PTRARROW)){ + type <= CPP_TOKEN_DELETE_ARRAY)){ guess = 80; + if (!on_left && other_is_operator){ + guess = 20; + } } else if (type >= CPP_TOKEN_MUL && type <= CPP_TOKEN_MOD){ guess = 70; @@ -1306,6 +1321,7 @@ internal f32 get_current_shift(Code_Wrap_State *wrap_state, i32 next_line_start){ f32 current_shift = wrap_state->paren_nesting[wrap_state->paren_safe_top]; + f32 statement_continuation_indent = 0.f; if (current_shift != 0.f && wrap_state->paren_safe_top == 0){ if (wrap_state->token_ptr > wrap_state->token_array.tokens){ Cpp_Token prev_token = *(wrap_state->token_ptr-1); @@ -1313,12 +1329,18 @@ get_current_shift(Code_Wrap_State *wrap_state, i32 next_line_start){ if (!(prev_token.flags & CPP_TFLAG_PP_BODY) && !(prev_token.flags & CPP_TFLAG_PP_DIRECTIVE)){ switch (prev_token.type){ case CPP_TOKEN_BRACKET_OPEN: case CPP_TOKEN_BRACE_OPEN: case CPP_TOKEN_BRACE_CLOSE: case CPP_TOKEN_SEMICOLON: case CPP_TOKEN_COLON: case CPP_TOKEN_COMMA: case CPP_TOKEN_COMMENT: break; - default: current_shift += wrap_state->tab_indent_amount; break; + default: statement_continuation_indent += wrap_state->tab_indent_amount; break; } } } } + switch (wrap_state->token_ptr->type){ + case CPP_TOKEN_BRACE_CLOSE: case CPP_TOKEN_BRACE_OPEN:break; + + default: current_shift += statement_continuation_indent; break; + } + if (wrap_state->token_ptr->start < next_line_start){ if (wrap_state->token_ptr->flags & CPP_TFLAG_PP_DIRECTIVE){ current_shift = 0; @@ -1522,8 +1544,8 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv } i32 wrap_position = step.position_end; - if (wrap_state.token_ptr->start > step.position_start && - wrap_position < wrap_state.token_ptr->start && next_token_is_on_line){ + f32 wrap_x = step.final_x; + if (wrap_state.token_ptr->start > step.position_start && wrap_position < wrap_state.token_ptr->start && next_token_is_on_line){ wrap_position = wrap_state.token_ptr->start; } @@ -1536,20 +1558,23 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv Cpp_Token_Type this_type = this_token->type; Cpp_Token_Type next_type = CPP_TOKEN_JUNK; + u16 this_flags = this_token->flags; + u16 next_flags = 0; + if (this_token == next_token || !next_token_is_on_line){ next_token = 0; } if (next_token){ next_type = next_token->type; + next_flags = next_token->flags; } - b32 in_parens = (wrap_state.paren_top == 0); - i32 this_stickieness = stickieness_guess(this_type, next_type, 1, in_parens); + i32 this_stickieness = stickieness_guess(this_type, next_type, this_flags, next_flags, 1); i32 next_stickieness = 0; if (next_token){ - next_stickieness = stickieness_guess(next_type, this_type, 0, in_parens); + next_stickieness = stickieness_guess(next_type, this_type, next_flags, this_flags, 0); } i32 general_stickieness = this_stickieness; @@ -1558,17 +1583,12 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv } wrappable_score = 64*50; - if (in_parens){ - wrappable_score += 101 - general_stickieness; - } - else{ - wrappable_score += 101 - general_stickieness - wrap_state.paren_safe_top*80; - } + wrappable_score += 101 - general_stickieness- wrap_state.paren_safe_top*80; potential_marks[potential_count].wrap_position = wrap_position; potential_marks[potential_count].line_shift = current_shift; potential_marks[potential_count].wrappable_score = wrappable_score; - potential_marks[potential_count].start_x = step.start_x; + potential_marks[potential_count].wrap_x = wrap_x; ++potential_count; } @@ -1587,12 +1607,20 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv for (; i < potential_count; ++i){ i32 this_score = potential_marks[i].wrappable_score; - f32 x_shift = potential_marks[i].start_x - potential_marks[i].line_shift; + f32 x_shift = potential_marks[i].wrap_x - potential_marks[i].line_shift; f32 x_shift_adjusted = x_shift - x_gain_threshold; + f32 x_left_over = step.final_x - x_shift; + if (x_shift_adjusted < 0){ this_score = 0; } + else if (x_left_over <= x_gain_threshold){ + this_score = 1; + } + else{ + this_score += FLOOR32(0.5f*x_shift_adjusted); + } if (this_score > best_score){ best_score = this_score; @@ -5594,15 +5622,11 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target params.font_height = (f32)line_height; params.adv = advance_data; params.virtual_white = file->settings.virtual_white; + params.wrap_slashes = BRWrapSlash_Show_At_Wrap_Edge; Buffer_Render_State state = {0}; Buffer_Layout_Stop stop = {0}; - f32 edge_tolerance = 50.f; - if (edge_tolerance > params.width){ - edge_tolerance = params.width; - } - f32 line_shift = 0.f; b32 do_wrap = 0; i32 wrap_unit_end = 0; @@ -5663,6 +5687,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target i32 token_i = 0; u32 main_color = style->main.default_color; u32 special_color = style->main.special_character_color; + u32 ghost_color = style->main.ghost_character_color; if (tokens_use){ Cpp_Get_Token_Result result = cpp_get_token(token_array, items->index); main_color = *style_get_color(style, token_array.tokens[result.token_index]); @@ -5706,6 +5731,9 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target if (item->flags & BRFlag_Special_Character){ char_color = special_color; } + else if (item->flags & BRFlag_Ghost_Character){ + char_color = ghost_color; + } f32_Rect char_rect = f32R(item->x0, item->y0, item->x1, item->y1); diff --git a/4ed_metagen.cpp b/4ed_metagen.cpp index 39160325..2bad4c2c 100644 --- a/4ed_metagen.cpp +++ b/4ed_metagen.cpp @@ -217,6 +217,7 @@ static char* main_style_fields[] = { "preproc", "include", "special_character", + "ghost_character", "highlight_junk", "highlight_white", "paste", diff --git a/4ed_style.h b/4ed_style.h index f31eb94b..4d2d0401 100644 --- a/4ed_style.h +++ b/4ed_style.h @@ -27,6 +27,7 @@ u32 bool_constant_color; u32 preproc_color; u32 include_color; u32 special_character_color; +u32 ghost_character_color; u32 highlight_junk_color; u32 highlight_white_color; u32 paste_color; @@ -64,6 +65,7 @@ case Stag_Bool_Constant: result = &s->bool_constant_color; break; case Stag_Preproc: result = &s->preproc_color; break; case Stag_Include: result = &s->include_color; break; case Stag_Special_Character: result = &s->special_character_color; break; +case Stag_Ghost_Character: result = &s->ghost_character_color; break; case Stag_Highlight_Junk: result = &s->highlight_junk_color; break; case Stag_Highlight_White: result = &s->highlight_white_color; break; case Stag_Paste: result = &s->paste_color; break; diff --git a/TODO.txt b/TODO.txt index 270a7dfd..67e931e4 100644 --- a/TODO.txt +++ b/TODO.txt @@ -175,11 +175,11 @@ ; [X] handle square brackets ; [X] smarter wrap rule ; [X] handle unclosed statements +; [+] wrapped line indication ; [] special indent rules in preprocessor body ; [] handle comments -; [] fix issues when relexing happens in parallel ; [] additional width for nesting? -; [] wrapped line indication +; [] fix issues when relexing happens in parallel ; [] remeasure version of measure_wraps ; Buffer behavior cleanup diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp index f81ebf8e..f16be574 100644 --- a/buffer/4coder_buffer_abstract.cpp +++ b/buffer/4coder_buffer_abstract.cpp @@ -1125,7 +1125,8 @@ buffer_invert_batch(Buffer_Invert_Batch *state, Buffer_Type *buffer, Buffer_Edit } enum Buffer_Render_Flag{ - BRFlag_Special_Character = (1 << 0) + BRFlag_Special_Character = (1 << 0), + BRFlag_Ghost_Character = (1 << 1) }; typedef struct Buffer_Render_Item{ @@ -1184,6 +1185,13 @@ struct Buffer_Render_Params{ f32 font_height; f32 *adv; b32 virtual_white; + i32 wrap_slashes; +}; + +enum Wrap_Slash_Mode{ + BRWrapSlash_Hide, + BRWrapSlash_Show_After_Line, + BRWrapSlash_Show_At_Wrap_Edge, }; struct Buffer_Render_State{ @@ -1211,8 +1219,7 @@ struct Buffer_Render_State{ #define DrReturn(n) { *S_ptr = S; S_ptr->__pc__ = -1; return(n); } internal_4tech Buffer_Layout_Stop -buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, - f32 line_shift, b32 do_wrap, i32 wrap_unit_end){ +buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 line_shift, b32 do_wrap, i32 wrap_unit_end){ Buffer_Render_State S = *S_ptr; Buffer_Layout_Stop S_stop; @@ -1287,6 +1294,21 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, ++S.wrap_line; if (params.wrapped){ + switch (params.wrap_slashes){ + case BRWrapSlash_Show_After_Line: + { + S.write = write_render_item(S.write, S.i-1, '\\', BRFlag_Ghost_Character); + }break; + + case BRWrapSlash_Show_At_Wrap_Edge: + { + if (S.write.x < shift_x + params.width){ + S.write.x = shift_x + params.width; + } + S.write = write_render_item(S.write, S.i-1, '\\', BRFlag_Ghost_Character); + }break; + } + S.write.x = shift_x + line_shift; S.write.y += params.font_height; }