чување 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:
| M | TODO | | | 2 | -- |
| M | draw.h | | | 26 | +++++++++++++------------- |
| M | sled.c | | | 69 | +++++++++++++++++++++++++++++++++++++++++---------------------------- |
| M | util.c | | | 24 | ++++++++++++++++++++++++ |
| M | util.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);