diff --git a/4coder_helper.h b/4coder_helper.h index f7e5de5f..51e97164 100644 --- a/4coder_helper.h +++ b/4coder_helper.h @@ -255,7 +255,7 @@ struct Buffer_Rect{ inline Buffer_Rect get_rect(View_Summary *view){ - Buffer_Rect rect; + Buffer_Rect rect = {0}; rect.char0 = view->mark.character; rect.line0 = view->mark.line; diff --git a/4coder_jump_parsing.cpp b/4coder_jump_parsing.cpp index 09c9ad03..78eb29a8 100644 --- a/4coder_jump_parsing.cpp +++ b/4coder_jump_parsing.cpp @@ -307,8 +307,8 @@ seek_error_skip_repeats(Application_Links *app, Partition *part, } static int -seek_error(Application_Links *app, Partition *part, - int skip_sub_error, int dir){ +seek_error_no_skip(Application_Links *app, Partition *part, + int skip_sub_error, int dir){ int result = true; Jump_Location location = {0}; Prev_Jump jump = {0}; @@ -327,6 +327,17 @@ seek_error(Application_Links *app, Partition *part, return(result); } +static int +seek_error(Application_Links *app, Partition *part, + int skip_sub_error, int skip_same_line, int dir){ + if (skip_same_line){ + seek_error_skip_repeats(app, part, skip_sub_error, dir); + } + else{ + seek_error_no_skip(app, part, skip_sub_error, dir); + } +} + CUSTOM_COMMAND_SIG(goto_next_error){ seek_error_skip_repeats(app, &global_part, true, 1); } @@ -336,11 +347,11 @@ CUSTOM_COMMAND_SIG(goto_prev_error){ } CUSTOM_COMMAND_SIG(goto_next_error_no_skips){ - seek_error(app, &global_part, true, 1); + seek_error_no_skip(app, &global_part, true, 1); } CUSTOM_COMMAND_SIG(goto_prev_error_no_skips){ - seek_error(app, &global_part, true, -1); + seek_error_no_skip(app, &global_part, true, -1); } CUSTOM_COMMAND_SIG(goto_first_error){ diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp index f3dd7f55..dd927a89 100644 --- a/buffer/4coder_buffer_abstract.cpp +++ b/buffer/4coder_buffer_abstract.cpp @@ -1110,13 +1110,12 @@ buffer_partial_from_line_character(Buffer_Type *buffer, int line, int character) if (line_index < 0) line_index = 0; int this_start = buffer->line_starts[line_index]; - int next_start = buffer->size; + int max_character = (buffer->size-this_start) + 1; if (line_index+1 < buffer->line_count){ - next_start = buffer->line_starts[line_index+1]; + int next_start = buffer->line_starts[line_index+1]; + max_character = (next_start-this_start); } - int max_character = (next_start-this_start); - if (character <= 0) character = 1; if (character > max_character) character = max_character; diff --git a/power/4coder_experiments.cpp b/power/4coder_experiments.cpp index 86949d36..86e6dac9 100644 --- a/power/4coder_experiments.cpp +++ b/power/4coder_experiments.cpp @@ -10,9 +10,8 @@ #include CUSTOM_COMMAND_SIG(kill_rect){ - unsigned int access = AccessOpen; - View_Summary view = app->get_active_view(app, access); - Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access); + View_Summary view = app->get_active_view(app, AccessOpen); + Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, AccessOpen); Buffer_Rect rect = get_rect(&view); @@ -37,6 +36,112 @@ CUSTOM_COMMAND_SIG(kill_rect){ } } +static void +pad_buffer_line(Application_Links *app, Partition *part, + Buffer_Summary *buffer, int line, + char padchar, int target){ + Partial_Cursor start = {0}; + Partial_Cursor end = {0}; + + if (app->buffer_compute_cursor(app, buffer, seek_line_char(line, 1), &start)){ + if (app->buffer_compute_cursor(app, buffer, seek_line_char(line, 65536), &end)){ + if (start.line == line){ + if (end.character-1 < target){ + Temp_Memory temp = begin_temp_memory(part); + int size = target - (end.character-1); + char *str = push_array(part, char, size); + memset(str, ' ', size); + app->buffer_replace_range(app, buffer, end.pos, end.pos, str, size); + end_temp_memory(temp); + } + } + } + } +} + +CUSTOM_COMMAND_SIG(multi_line_edit){ + Partition *part = &global_part; + + View_Summary view = app->get_active_view(app, AccessOpen); + Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, AccessOpen); + + Buffer_Rect rect = get_rect(&view); + + int start_line = view.cursor.line; + int pos = view.cursor.character-1; + + for (int i = rect.line0; i <= rect.line1; ++i){ + pad_buffer_line(app, &global_part, &buffer, i, ' ', pos); + } + + int line_count = rect.line1 - rect.line0 + 1; + + for (;;){ + User_Input in = app->get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton); + if (in.abort) break; + + if (in.key.character && key_is_unmodified(&in.key)){ + char str = (char)in.key.character; + + Temp_Memory temp = begin_temp_memory(part); + Buffer_Edit *edit = push_array(part, Buffer_Edit, line_count); + Buffer_Edit *edits = edit; + + for (int i = rect.line0; i <= rect.line1; ++i){ + Partial_Cursor cursor = {0}; + + if (app->buffer_compute_cursor(app, &buffer, seek_line_char(i, pos+1), &cursor)){ + edit->str_start = 0; + edit->len = 1; + edit->start = cursor.pos; + edit->end = cursor.pos; + ++edit; + } + } + + int edit_count = (int)(edit - edits); + app->buffer_batch_edit(app, &buffer, &str, 1, edits, edit_count, BatchEdit_Normal); + + end_temp_memory(temp); + + ++pos; + + app->view_set_cursor(app, &view, seek_line_char(start_line, pos+1), true); + } + else if (in.key.keycode == key_back){ + if (pos > 0){ + + Temp_Memory temp = begin_temp_memory(part); + Buffer_Edit *edit = push_array(part, Buffer_Edit, line_count); + Buffer_Edit *edits = edit; + + for (int i = rect.line0; i <= rect.line1; ++i){ + Partial_Cursor cursor = {0}; + + if (app->buffer_compute_cursor(app, &buffer, seek_line_char(i, pos+1), &cursor)){ + edit->str_start = 0; + edit->len = 0; + edit->start = cursor.pos-1; + edit->end = cursor.pos; + ++edit; + } + } + + int edit_count = (int)(edit - edits); + app->buffer_batch_edit(app, &buffer, 0, 0, edits, edit_count, BatchEdit_Normal); + + end_temp_memory(temp); + + --pos; + } + + } + else{ + break; + } + } +} + // TODO(allen): Both of these brace related commands would work better // if the API exposed access to the tokens in a code file. CUSTOM_COMMAND_SIG(mark_matching_brace){ @@ -256,6 +361,7 @@ get_bindings(void *data, int size){ begin_map(context, mapid_file); bind(context, 'k', MDFR_ALT, kill_rect); + bind(context, ' ', MDFR_ALT, multi_line_edit); end_map(context); begin_map(context, my_code_map);