чување 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:
измењених датотека: 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);
}