Skip to content

Commit 602052f

Browse files
committed
[fix] regex search
1 parent 6a9799d commit 602052f

File tree

5 files changed

+199
-15
lines changed

5 files changed

+199
-15
lines changed

include/ekg/io/utf.hpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,46 @@ namespace ekg {
5757
size_t &it
5858
);
5959

60+
/**
61+
* @brief
62+
* find for a aligned utf position by byte position
63+
*
64+
* @param `string` string for find utf position
65+
* @param `byte_pos` byte pos used for find utf position
66+
* @param `utf_pos` utf position relative to byte position
67+
*
68+
* @description
69+
* if no utf position was found then `utf_pos` keeps unchanged.
70+
* if a invalid byte position is passed, e.g a position inside a
71+
* utf sequence, it return atuomatically `false`.
72+
*
73+
* @return `true` if a valid utf position was found else `false` if was not found
74+
**/
75+
bool utf8_find_utf_pos_by_byte_pos(
76+
std::string &string,
77+
size_t byte_pos,
78+
size_t &utf_pos
79+
);
80+
81+
/**
82+
* @brief
83+
* find for a byte pos from an aligned utf position
84+
*
85+
* @param `string` string for find utf position
86+
* @param `utf_pos` utf pos used for find byte pos
87+
* @param `byte_pos` byte pos relative to utf position
88+
*
89+
* @description
90+
* if no byte position was found then `utf_byte` keeps unchanged.
91+
*
92+
* @return `true` if a valid byte position was found else `false` if was not found
93+
**/
94+
bool utf8_find_byte_pos_by_utf_pos(
95+
std::string &string,
96+
size_t utf_pos,
97+
size_t &byte_pos
98+
);
99+
60100
/**
61101
* Returns a UTF string by `char32` converting
62102
* the UTF-32 unique char into a sequence of UTF-8

include/ekg/ui/textbox/textbox.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ namespace ekg {
141141
ekg::at_array_t<ekg::layer, ekg::enum_layer_size> layers {};
142142

143143
std::array<std::regex, ekg::textbox_t::operation_enum_size> regex_operations {
144-
std::regex(" +|:+|&+|\\(\\)|\\(|\\)|;+"),
145-
std::regex(" +|:+|&+|\\(\\)|\\(|\\)|;+")
144+
std::regex("^| +|:+|&+|\\(\\)|\\(|\\)|;+"),
145+
std::regex("$| +|:+|&+|\\(\\)|\\(|\\)|;+")
146146
};
147147
public:
148148
ekg_descriptor(ekg::textbox_t);

src/handler/input/handler.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,19 +154,19 @@ void ekg::handler::input::init() {
154154
this->insert_input_bind("textbox-action-multicursor", "lctrl+mouse-1");
155155
this->insert_input_bind("textbox-action-multicursor", "rctrl+mouse-1");
156156

157-
this->insert_input_bind("textbox-action-down", "abs-down");
158-
this->insert_input_bind("textbox-action-select", "lshift+down");
159-
this->insert_input_bind("textbox-action-select", "rshift+down");
160-
this->insert_input_bind("textbox-action-modifier-down", "lctrl+down");
161-
this->insert_input_bind("textbox-action-modifier-down", "rctrl+down");
157+
this->insert_input_bind("textbox-action-up", "abs-up");
158+
this->insert_input_bind("textbox-action-select", "lshift+up");
159+
this->insert_input_bind("textbox-action-select", "rshift+up");
160+
this->insert_input_bind("textbox-action-modifier-up", "lctrl+up");
161+
this->insert_input_bind("textbox-action-modifier-up", "rctrl+up");
162162

163163
this->insert_input_bind("textbox-action-down", "abs-down");
164164
this->insert_input_bind("textbox-action-select", "lshift+down");
165165
this->insert_input_bind("textbox-action-select", "rshift+down");
166166
this->insert_input_bind("textbox-action-modifier-down", "lctrl+down");
167167
this->insert_input_bind("textbox-action-modifier-down", "rctrl+down");
168168

169-
this->insert_input_bind("textbox-action-right", "abs-left");
169+
this->insert_input_bind("textbox-action-right", "abs-right");
170170
this->insert_input_bind("textbox-action-select", "lctrl+lshift+right");
171171
this->insert_input_bind("textbox-action-select", "lctrl+rshift+right");
172172
this->insert_input_bind("textbox-action-select", "rctrl+lshift+right");

src/io/utf.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,70 @@ void ekg::utf8_sequence(
5050
}
5151
}
5252

53+
bool ekg::utf8_find_utf_pos_by_byte_pos(
54+
std::string &string,
55+
size_t byte_pos,
56+
size_t &utf_pos
57+
) {
58+
size_t utf_sequence_size {};
59+
size_t string_size {string.size()};
60+
size_t utf_pos_count {};
61+
for (size_t it {}; it < string_size; it++) {
62+
if (it == byte_pos) {
63+
utf_pos = utf_pos_count;
64+
return true;
65+
}
66+
67+
char &char8 {string.at(it)};
68+
utf_sequence_size = 0;
69+
utf_sequence_size += ((char8 & 0xE0) == 0xC0);
70+
utf_sequence_size += 2 * ((char8 & 0xF0) == 0xE0);
71+
utf_sequence_size += 3 * ((char8 & 0xF8) == 0xF0);
72+
73+
if (it > byte_pos && it + utf_sequence_size < byte_pos) {
74+
return false;
75+
}
76+
77+
it += utf_sequence_size;
78+
utf_pos_count++;
79+
80+
if (it == byte_pos) {
81+
utf_pos = utf_pos_count;
82+
return true;
83+
}
84+
}
85+
86+
return false;
87+
}
88+
89+
bool ekg::utf8_find_byte_pos_by_utf_pos(
90+
std::string &string,
91+
size_t utf_pos,
92+
size_t &byte_pos
93+
) {
94+
size_t utf_sequence_size {};
95+
size_t string_size {string.size()};
96+
size_t utf_pos_count {};
97+
98+
for (size_t it {}; it < string_size; it++) {
99+
if (utf_pos_count == utf_pos) {
100+
byte_pos = it;
101+
return true;
102+
}
103+
104+
char &char8 {string.at(it)};
105+
utf_sequence_size = 0;
106+
utf_sequence_size += ((char8 & 0xE0) == 0xC0);
107+
utf_sequence_size += 2 * ((char8 & 0xF0) == 0xE0);
108+
utf_sequence_size += 3 * ((char8 & 0xF8) == 0xF0);
109+
110+
it += utf_sequence_size;
111+
utf_pos_count++;
112+
}
113+
114+
return false;
115+
}
116+
53117
uint64_t ekg::utf8_check_sequence(
54118
uint8_t &char8,
55119
char32_t &char32,

src/ui/textbox/widget.cpp

Lines changed: 87 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -464,21 +464,28 @@ void ekg::ui::event(
464464
bool is_up_fired {ekg::fired("textbox-action-up")};
465465
bool is_modifier_up_fired {is_up_fired && ekg::fired("textbox-action-modifier-up")};
466466
bool is_down_fired {ekg::fired("textbox-action-down")};
467-
bool is_modifier_down_fired {ekg::fired("textbox-action-modifier-down")};
467+
bool is_modifier_down_fired {is_down_fired && ekg::fired("textbox-action-modifier-down")};
468468
bool is_action_selected_fired {is_modifier_down_fired && ekg::fired("textbox-action-select")};
469469

470-
if (!is_left_fired && !is_right_fired && !is_up_fired && !is_down_fired) {
470+
if (is_left_fired || is_right_fired || is_up_fired || is_down_fired) {
471471
textbox.widget.set_cursor_static = true;
472472
}
473473

474474
bool is_ab_equals {};
475475
bool is_ab_delta_equals {};
476476
bool is_bounding {};
477477

478+
size_t utf_position_count {};
479+
size_t utf_sequence_size {};
480+
size_t new_cursor_byte_pos {};
481+
size_t cursor_byte_pos {};
478482
size_t text_total_lines {textbox.text.length_of_lines()};
483+
size_t byte_pos {};
479484

480485
ekg::rect_t<float> &rect_abs {ekg::ui::get_abs_rect(property, textbox.rect)};
481486
ekg::vec2_t<float> cursor_pos {};
487+
488+
std::string line {};
482489
std::sregex_iterator end {};
483490

484491
for (ekg::textbox_t::cursor_t &cursor : textbox.widget.cursors) {
@@ -495,15 +502,45 @@ void ekg::ui::event(
495502
}
496503
}
497504

498-
if (is_modifier_left_fired) {
499-
std::string line {textbox.text.at(cursor.a.y)};
500-
std::sregex_iterator it(
505+
if (
506+
is_modifier_left_fired
507+
&&
508+
ekg::utf8_find_byte_pos_by_utf_pos(
509+
(line = textbox.text.at(cursor.a.y)),
510+
cursor.a.x,
511+
cursor_byte_pos
512+
)
513+
) {
514+
std::sregex_iterator iterator(
501515
line.begin(),
502-
line.end(),
516+
line.begin() + cursor_byte_pos,
503517
textbox.regex_operations[ekg::textbox_t::operation::modifier_left]
504518
);
505519

506-
std::smatch j = *it;
520+
new_cursor_byte_pos = UINT64_MAX;
521+
std::sregex_iterator end {};
522+
for (auto it = iterator; it != end; it++) {
523+
std::smatch j = *it;
524+
new_cursor_byte_pos = j.position();
525+
ekg_log_low_level(new_cursor_byte_pos << " " << j.prefix().str())
526+
}
527+
528+
if (new_cursor_byte_pos != UINT64_MAX) {
529+
byte_pos = new_cursor_byte_pos;
530+
utf_position_count = 0;
531+
while (byte_pos < cursor_byte_pos) {
532+
char &char8 {line.at(byte_pos)};
533+
utf_sequence_size = 1;
534+
utf_sequence_size += ((char8 & 0xE0) == 0xC0);
535+
utf_sequence_size += 2 * ((char8 & 0xF0) == 0xE0);
536+
utf_sequence_size += 3 * ((char8 & 0xF8) == 0xF0);
537+
byte_pos += utf_sequence_size;
538+
utf_position_count++;
539+
}
540+
541+
ekg_log_low_level(utf_position_count)
542+
cursor.a.x -= utf_position_count;
543+
}
507544
}
508545

509546
cursor.highest_char_index = cursor.a.x;
@@ -522,6 +559,49 @@ void ekg::ui::event(
522559
}
523560
}
524561

562+
if (
563+
is_modifier_right_fired
564+
&&
565+
ekg::utf8_find_byte_pos_by_utf_pos(
566+
(line = textbox.text.at(cursor.b.y)),
567+
cursor.b.x,
568+
cursor_byte_pos
569+
)
570+
) {
571+
std::sregex_iterator iterator(
572+
line.begin() + cursor_byte_pos,
573+
line.end(),
574+
textbox.regex_operations[ekg::textbox_t::operation::modifier_right]
575+
);
576+
577+
new_cursor_byte_pos = UINT64_MAX;
578+
std::sregex_iterator end {};
579+
for (auto it = iterator; it != end; it++) {
580+
std::smatch j = *it;
581+
new_cursor_byte_pos = cursor_byte_pos + j.position();
582+
ekg_log_low_level(new_cursor_byte_pos << " v " << j.prefix().str())
583+
break;
584+
}
585+
586+
if (new_cursor_byte_pos != UINT64_MAX) {
587+
byte_pos = cursor_byte_pos;
588+
utf_position_count = 0;
589+
ekg_log_low_level(byte_pos << " x " << new_cursor_byte_pos)
590+
while (byte_pos < new_cursor_byte_pos) {
591+
char &char8 {line.at(byte_pos)};
592+
utf_sequence_size = 1;
593+
utf_sequence_size += ((char8 & 0xE0) == 0xC0);
594+
utf_sequence_size += 2 * ((char8 & 0xF0) == 0xE0);
595+
utf_sequence_size += 3 * ((char8 & 0xF8) == 0xF0);
596+
byte_pos += utf_sequence_size;
597+
utf_position_count++;
598+
}
599+
600+
ekg_log_low_level(utf_position_count)
601+
cursor.b.x += utf_position_count;
602+
}
603+
}
604+
525605
cursor.highest_char_index = cursor.b.x;
526606
cursor.a = cursor.b;
527607
cursor.delta = cursor.a;

0 commit comments

Comments
 (0)