sled

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

чување 48a637a1cb8928bb1d9ef144b044a9ac311cbe7d
родитељ 2a8cec6e1b28f77396a1d2b676d934b737b95851
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Sat, 30 Apr 2022 21:17:04 +0200

Fix positioning with previous/next match

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

Diffstat:
MTODO | 2--
Mdraw.h | 26+++++++++++++-------------
Msled.c | 69+++++++++++++++++++++++++++++++++++++++++----------------------------
Mutil.c | 24++++++++++++++++++++++++
Mutil.h | 7+++----
измењених датотека: 5, додавања: 81(+), брисања: 47(-)

diff --git a/TODO b/TODO @@ -1,8 +1,6 @@ TODO ==== - [x] Avoid inserting additional spaces when joining lines - [ ] Replace (patch) [~] Code optimization (struct coord...) diff --git a/draw.h b/draw.h @@ -59,18 +59,18 @@ struct DrawState { uint32_t* input; uint32_t* search; struct BufferLine* buffer; - size_t buffer_size; - struct Coord coord; - struct Coord first_shown; - int input_first_shown_column; - int input_display_column; - int input_column; + size_t buffer_size; /* buffer parameter */ + struct Coord coord; /* buffer coordinates */ + struct Coord first_shown; /* display coordinates */ + int input_first_shown_column; /* display coordinate */ + int input_display_column; /* display coordinate */ + int input_column; /* buffer coordinates */ char* input_title; - size_t rows_count; - int display_column; - int saved_column; - int help_width; - int input_dialog_width; + size_t rows_count; /* buffer parameter */ + int display_column; /* display coordinate */ + int saved_column; /* display coordinate */ + int help_width; /* display parameter */ + int input_dialog_width; /* display parameter */ struct BufferLine* paste; size_t paste_count; size_t paste_size; @@ -83,8 +83,8 @@ struct DrawState { int mode; int maxx; int maxy; - struct Coord sel_start; - struct Coord sel_end; + struct Coord sel_start; /* buffer coordinate */ + struct Coord sel_end; /* buffer coordinate */ }; struct Key { diff --git a/sled.c b/sled.c @@ -599,6 +599,10 @@ load_file(struct DrawState* state, long* lineno, long* col) return LOAD_ERR_NONE; } +/* + * state->saved_column - display coordinate + * row, column - buffer coordinates (not display) + */ void position_to(struct DrawState* state, const int row, const int column) { @@ -646,7 +650,7 @@ position_to(struct DrawState* state, const int row, const int column) } if (state->first_shown.col > state->display_column) state->first_shown.col = state->display_column; - if (state->first_shown.col + (state->maxx - 1) < state->coord.col) + if (state->first_shown.col + (state->maxx - 1) < state->display_column) state->first_shown.col = state->display_column - (state->maxx - 1); @@ -1479,22 +1483,18 @@ next_match(struct DrawState* state) found = current->text; if (row == state->coord.row) found += state->coord.col + 1; - do + found = u32_strstr(found, state->search); + if (found) { - found = u32_strstr(found, state->search); - if (found) + idelta = found - (const uint32_t*)current->text; + state->saved_column + = display_length(state, current->text, idelta); + if (*current->text) { - idelta = found - (const uint32_t*)current->text; - state->saved_column = display_length(state, - current->text, idelta); - if (*current->text) - { - position_to(state, row, - state->saved_column); - return 0; - } + position_to(state, row, idelta); + return 0; } - } while (found); + } } return 0; } @@ -1608,33 +1608,46 @@ prev_match(struct DrawState* state) struct BufferLine* current = NULL; const uint32_t* found = NULL; size_t idelta; + size_t search_len; if (!state->search || !*state->search) return 0; *state->error = 0; + search_len = u32_strlen(state->search); for (size_t row = state->coord.row + 1; row > 0; row--) { current = state->buffer + row - 1; found = current->text; + if (!found) + return 0; if (row == state->coord.row + 1) - found += state->coord.col + 1; - do { - found = u32_strstr(found, state->search); - if (found) + if (state->coord.col > search_len) + found += state->coord.col - search_len + 1; + } + else if (current->length > search_len) + found += current->length - search_len + 1; + + prev_match_loop: + const uint32_t* save_found = found; + found = u32_strrstr(current->text, state->search, found); + if (found) + { + idelta = found - (const uint32_t*)current->text; + state->saved_column + = display_length(state, current->text, idelta); + if (*current->text) { - idelta = found - (const uint32_t*)current->text; - state->saved_column = display_length(state, - current->text, idelta); - if (*current->text) - { - position_to(state, row - 1, - state->saved_column); - return 0; - } + position_to(state, row - 1, idelta); + return 0; } - } while (found); + } + if (save_found == current->text) + goto prev_match_end; + found = save_found - 1; + goto prev_match_loop; + prev_match_end:; } return 0; } diff --git a/util.c b/util.c @@ -81,6 +81,30 @@ u32_strstr(const uint32_t* haystack, const uint32_t* needle) } const uint32_t* +u32_strrstr(const uint32_t* haystack, const uint32_t* needle, + const uint32_t* haystack_tail) +{ + size_t needle_len = u32_strlen(needle); + const uint32_t* ph; + + if (needle_len > haystack_tail - haystack) + return NULL; + + ph = haystack_tail - needle_len; + +strrstr_loop: + if (u32_starts_with(ph, needle)) + return ph; + if (ph != haystack) + ph--; + else + goto strrstr_end; + goto strrstr_loop; +strrstr_end: + return NULL; +} + +const uint32_t* u32_strchr(const uint32_t* haystack, const uint32_t needle) { const uint32_t* ph = haystack; diff --git a/util.h b/util.h @@ -29,10 +29,7 @@ enum { ERR_INVALID_NUM }; -enum { - ACT_WRITING, - ACT_READING -}; +enum { ACT_WRITING, ACT_READING }; #define ALLOC_DELTA 50 #define MAXBUFLINE 4096 @@ -49,6 +46,8 @@ size_t u8_string_to_unicode(uint32_t* us, const char* s, const size_t max); size_t unicode_string_to_u8(char* s, const uint32_t* us, const size_t max); size_t u32_strlen(const uint32_t* s); const uint32_t* u32_strstr(const uint32_t* haystack, const uint32_t* needle); +const uint32_t* u32_strrstr(const uint32_t* haystack, const uint32_t* needle, + const uint32_t* haystack_tail); const uint32_t* u32_strchr(const uint32_t* haystack, const uint32_t needle); size_t u32_strcpy(uint32_t* to, const uint32_t* from); size_t u32_strncpy(uint32_t* to, const uint32_t* from, size_t max);