sled

Једноставни уређивач текста
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 5aa788004fa5a65179344c9e340e569378b5b170
родитељ d02d94c4259feb838f0c6e110fd0667054c48f85
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Sun, 13 Mar 2022 21:23:36 +0100

Move recalculate_size to DrawState; join_lines now joins lines in selection; new key: J -> join_lines

Signed-off-by: Страхиња Радић <contact@strahinja.org>

Diffstat:
Mconfig.def.h | 2++
Mconfig.h | 2++
Mdraw.c | 20++++++++++++++++----
Mdraw.h | 6++++--
Msled.1.in | 1+
Msled.c | 132+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
измењених датотека: 6, додавања: 117(+), брисања: 46(-)

diff --git a/config.def.h b/config.def.h @@ -66,6 +66,7 @@ int input_move_next_word(struct DrawState* state); int insert_line(struct DrawState* state); int insert_space(struct DrawState* state); int insert_tab(struct DrawState* state); +int join_lines(struct DrawState* state); int move_bottom(struct DrawState* state); int move_down(struct DrawState* state); int move_end(struct DrawState* state); @@ -230,6 +231,7 @@ static const struct Key command_keys[] = { { .ev = { .ch = 'g' }, .callback = move_top }, { .ev = { .ch = 'H' }, .callback = move_screen_top }, { .ev = { .ch = 'h' }, .callback = move_left }, + { .ev = { .ch = 'J' }, .callback = join_lines }, { .ev = { .ch = 'j' }, .callback = move_down }, { .ev = { .ch = 'k' }, .callback = move_up }, { .ev = { .ch = 'L' }, .callback = move_screen_bottom }, diff --git a/config.h b/config.h @@ -66,6 +66,7 @@ int input_move_next_word(struct DrawState* state); int insert_line(struct DrawState* state); int insert_space(struct DrawState* state); int insert_tab(struct DrawState* state); +int join_lines(struct DrawState* state); int move_bottom(struct DrawState* state); int move_down(struct DrawState* state); int move_end(struct DrawState* state); @@ -230,6 +231,7 @@ static const struct Key command_keys[] = { { .ev = { .ch = 'g' }, .callback = move_top }, { .ev = { .ch = 'H' }, .callback = move_screen_top }, { .ev = { .ch = 'h' }, .callback = move_left }, + { .ev = { .ch = 'J' }, .callback = join_lines }, { .ev = { .ch = 'j' }, .callback = move_down }, { .ev = { .ch = 'k' }, .callback = move_up }, { .ev = { .ch = 'L' }, .callback = move_screen_bottom }, diff --git a/draw.c b/draw.c @@ -116,6 +116,7 @@ init_drawstate(struct DrawState* state, char* error, char* action, state->input_update_callback = NULL; state->running = 1; state->dirty = 0; + state->recalculate_size = 1; state->in_prompt = 0; state->in_selection_mode = 0; state->show_help = 0; @@ -770,12 +771,23 @@ draw_status(const struct DrawState* state) return state; } -const struct DrawState* -redraw_status(const struct DrawState* state) +void +recalculate_size(struct DrawState* state) +{ + state->maxx = tb_width(); + state->help_width = calculate_help_width(state); + state->input_dialog_width = calculate_input_dialog_width(state); + state->maxy = tb_height(); + state->recalculate_size = 0; +} + +void +redraw_status(struct DrawState* state) { - const struct DrawState* result = draw_status(state); + if (state->recalculate_size) + recalculate_size(state); + draw_status(state); tb_present(); - return result; } const struct DrawState* diff --git a/draw.h b/draw.h @@ -16,7 +16,7 @@ #define HELP_WIDTH 60 #define HELP_HEIGHT 22 -#define INPUT_DLG_WIDTH 20 +#define INPUT_DLG_WIDTH 40 #define INPUT_DLG_HEIGHT 4 #define TAB_SIZE 8 #define MAXINPUT (512 + 1) @@ -60,6 +60,7 @@ struct DrawState { void (*input_update_callback)(struct DrawState*); int running; int dirty; + int recalculate_size; int in_prompt; int in_command_mode; int in_overwrite_mode; @@ -121,5 +122,6 @@ const struct DrawState* draw_help(const struct DrawState* state); const struct DrawState* draw_input_dialog(const struct DrawState* state); const struct DrawState* draw_screen(const struct DrawState* state); const struct DrawState* draw_status(const struct DrawState* state); -const struct DrawState* redraw_status(const struct DrawState* state); +void recalculate_size(struct DrawState* state); +void redraw_status(struct DrawState* state); const struct DrawState* draw(const struct DrawState* state); diff --git a/sled.1.in b/sled.1.in @@ -152,6 +152,7 @@ _ \fCg\fP@Go to first line in the file \fCH\fP@Go to first line on the screen \fCh\fP@Go to previous character +\fCJ\fP@Join lines in selection/line and next line \fCj\fP@Go to next line \fCk\fP@Go to previous line \fCL\fP@Go to last line on the screen diff --git a/sled.c b/sled.c @@ -62,8 +62,6 @@ void handle_key_event(struct tb_event* ev, struct DrawState* state); int input_insert_char(struct DrawState* state, uint32_t ch); void input_position_to(struct DrawState* state, const int column); int insert_char(struct DrawState* state, uint32_t ch); -struct DrawState* join_lines(struct DrawState* state, size_t first_line, - int forward); int load_file(struct DrawState* dstate, long* lineno, long* col); void position_to(struct DrawState* state, const int row, const int column); int position_to_selection_start(struct DrawState* state); @@ -73,6 +71,7 @@ void reread_file(struct DrawState* state); void quit_callback(struct DrawState* state, struct tb_event* ev); int save_file(struct DrawState* state); void search_dialog_callback(struct DrawState* state); +int simple_join_lines(struct DrawState* state); int clear_selection(struct DrawState* state) @@ -416,36 +415,66 @@ insert_char(struct DrawState* state, uint32_t ch) return 0; } -struct DrawState* -join_lines(struct DrawState* state, size_t first_line, int forward) +int +join_lines(struct DrawState* state) { - if (!state) - return NULL; + /* Selection start row/col */ + int ssr = 0; + int ssc = 0; + /* Selection end row */ + int ser = 0; + int selection = 0; + int saved_row = state->row; + struct BufferLine* current = NULL; - state->column = state->buffer[first_line].length; - state->display_column = display_length(state, - state->buffer[state->row].text, state->column); - u32_strncat(state->buffer[first_line].text, - state->buffer[first_line + 1].text, MAXBUFLINE); - state->buffer[first_line].length - = u32_strlen(state->buffer[first_line].text); - if (!forward) + if (SEL_NOT_EMPTY(state)) { - state->row--; - if (state->row < 0) - state->row = 0; + if (state->sel_start_row <= state->sel_end_row) + { + ssr = state->sel_start_row; + ssc = state->sel_start_col; + ser = state->sel_end_row - 1; + } + else /* Swap */ + { + ssr = state->sel_end_row; + ssc = state->sel_end_col; + ser = state->sel_start_row - 1; + } + selection = 1; + clear_selection(state); } - for (size_t i = first_line + 1; i < state->rows_count - 1; i++) + else { - u32_strncpy(state->buffer[i].text, state->buffer[i + 1].text, - MAXBUFLINE); - state->buffer[i].length = state->buffer[i + 1].length; + ssr = state->row; + ssc = state->column; + ser = state->row + 1; } - *state->buffer[state->rows_count - 1].text = 0; - state->buffer[state->rows_count - 1].length = 0; - state->rows_count--; - state->dirty = 1; - return state; + + for (int row = ssr; row < ser; row++) + { + current = state->buffer + ssr; + if (current->length + 2 < MAXBUFLINE) + { + state->row = ssr; + if (current->length > 0) + { + current->text[current->length] = ' '; + current->text[current->length + 1] = 0; + current->length++; + } + state->column = current->length; + state->display_column = display_length(state, + current->text, state->column); + simple_join_lines(state); + } + } + + state->row = saved_row; + if (selection) + position_to(state, ssr, ssc); + + return 0; } int @@ -875,11 +904,17 @@ erase_forward(struct DrawState* state) } else if (state->row < state->rows_count - 1) { - if (!join_lines(state, state->row, 1)) + struct BufferLine* current = state->buffer + state->row; + if (state->row == state->rows_count - 1 + || current->length + state->buffer[state->row + 1].length + >= MAXBUFLINE) + goto skip_join_lines; + if (simple_join_lines(state)) { strcpy(state->error, errors[ERR_CANT_ALLOC]); state->running = 0; } + skip_join_lines:; } return 0; } @@ -1640,6 +1675,30 @@ show_help(struct DrawState* state) } int +simple_join_lines(struct DrawState* state) +{ + size_t first_line = state->row; + + if (state->rows_count == 1) + return 0; + + u32_strcat(state->buffer[first_line].text, + state->buffer[first_line + 1].text); + state->buffer[first_line].length + = u32_strlen(state->buffer[first_line].text); + for (size_t i = first_line + 1; i < state->rows_count - 1; i++) + { + u32_strcpy(state->buffer[i].text, state->buffer[i + 1].text); + state->buffer[i].length = state->buffer[i + 1].length; + } + *state->buffer[state->rows_count - 1].text = 0; + state->buffer[state->rows_count - 1].length = 0; + state->rows_count--; + state->dirty = 1; + return 0; +} + +int toggle_overwrite(struct DrawState* state) { state->in_overwrite_mode = !state->in_overwrite_mode; @@ -1812,7 +1871,6 @@ main(int argc, char** argv) int result; int dir_access; int dir_access_errno; - int recalculate_size = 1; char dirname[MAXPATH]; char* slash = NULL; @@ -1905,22 +1963,16 @@ file_error: init_termbox: tb_init(); - *error = 0; - state.maxx = 0; + *error = 0; + state.maxx = 0; + state.recalculate_size = 1; while (state.running) { tb_clear(); - if (recalculate_size) - { - state.maxx = tb_width(); - state.help_width = calculate_help_width(&state); - state.input_dialog_width - = calculate_input_dialog_width(&state); - state.maxy = tb_height(); - recalculate_size = 0; - } + if (state.recalculate_size) + recalculate_size(&state); if (!draw(&state)) { state.running = 0; @@ -1929,7 +1981,7 @@ init_termbox: tb_present(); result = tb_poll_event(&ev); if (result == TB_OK && ev.type == TB_EVENT_RESIZE) - recalculate_size = 1; + state.recalculate_size = 1; else if (result == TB_OK && ev.type == TB_EVENT_KEY) handle_key_event(&ev, &state); }