summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Aaberge <trygveaa@gmail.com>2020-05-12 23:06:39 +0200
committerSébastien Helleu <flashcode@flashtux.org>2023-03-26 15:52:19 +0200
commit9ac30381faf07f298e88ee777cbc6748b68a5cab (patch)
tree342c6b2b1f11b4c56a35ecd34c48d55fab83d0b6
parent20cea84917804baa379902e757cd1d71cc05d1a1 (diff)
downloadweechat-9ac30381faf07f298e88ee777cbc6748b68a5cab.zip
core: Implement commands for operating on a single input line
This changes the commands delete_beginning_of_line, delete_end_of_line, delete_line, move_beginning_of_line and move_end_of_line to operate on the current line instead of the whole input. The commands delete_beginning_of_input, delete_end_of_input, delete_input, move_beginning_of_input and move_end_of_input are added with the previous implementations that the line commands had. Additionally, the commands move_previous_line and move_next_line are added which moves the cursor to the previous/next line and keeps the horizontal position in the line. The meta-r key is changed from delete_line to delete_input to keep the behavior, and because you probably want to delete the whole input more often than the line. The meta-R key is added for delete_line. The home, end, ctrl-u and ctrl-k keys are kept to the same commands, which means that they change behaviour. This is because having them operate on the line is consistent with other applications (vim, zsh), and I also think it's more practical. These new bindings are added: shift-home: /input move_beginning_of_input shift-end: /input move_end_of_input shift-up: /input move_previous_line shift-down: /input move_next_line meta-R: /input delete_line meta-ctrl-u: /input delete_beginning_of_input meta-ctrl-k: /input delete_end_of_input Relates to #1498
-rw-r--r--src/core/wee-command.c32
-rw-r--r--src/core/wee-utf8.c42
-rw-r--r--src/core/wee-utf8.h3
-rw-r--r--src/gui/curses/gui-curses-key.c9
-rw-r--r--src/gui/gui-input.c290
-rw-r--r--src/gui/gui-input.h7
-rw-r--r--tests/unit/core/test-core-utf8.cpp36
7 files changed, 405 insertions, 14 deletions
diff --git a/src/core/wee-command.c b/src/core/wee-command.c
index 6f426c965..ab43e2c2f 100644
--- a/src/core/wee-command.c
+++ b/src/core/wee-command.c
@@ -3481,16 +3481,26 @@ COMMAND_CALLBACK(input)
gui_input_delete_next_word (buffer);
else if (string_strcmp (argv[1], "delete_beginning_of_line") == 0)
gui_input_delete_beginning_of_line (buffer);
+ else if (string_strcmp (argv[1], "delete_beginning_of_input") == 0)
+ gui_input_delete_beginning_of_input (buffer);
else if (string_strcmp (argv[1], "delete_end_of_line") == 0)
gui_input_delete_end_of_line (buffer);
+ else if (string_strcmp (argv[1], "delete_end_of_input") == 0)
+ gui_input_delete_end_of_input (buffer);
else if (string_strcmp (argv[1], "delete_line") == 0)
gui_input_delete_line (buffer);
+ else if (string_strcmp (argv[1], "delete_input") == 0)
+ gui_input_delete_input (buffer);
else if (string_strcmp (argv[1], "transpose_chars") == 0)
gui_input_transpose_chars (buffer);
else if (string_strcmp (argv[1], "move_beginning_of_line") == 0)
gui_input_move_beginning_of_line (buffer);
+ else if (string_strcmp (argv[1], "move_beginning_of_input") == 0)
+ gui_input_move_beginning_of_input (buffer);
else if (string_strcmp (argv[1], "move_end_of_line") == 0)
gui_input_move_end_of_line (buffer);
+ else if (string_strcmp (argv[1], "move_end_of_input") == 0)
+ gui_input_move_end_of_input (buffer);
else if (string_strcmp (argv[1], "move_previous_char") == 0)
gui_input_move_previous_char (buffer);
else if (string_strcmp (argv[1], "move_next_char") == 0)
@@ -3499,6 +3509,10 @@ COMMAND_CALLBACK(input)
gui_input_move_previous_word (buffer);
else if (string_strcmp (argv[1], "move_next_word") == 0)
gui_input_move_next_word (buffer);
+ else if (string_strcmp (argv[1], "move_previous_line") == 0)
+ gui_input_move_previous_line (buffer);
+ else if (string_strcmp (argv[1], "move_next_line") == 0)
+ gui_input_move_next_line (buffer);
else if (string_strcmp (argv[1], "history_previous") == 0)
gui_input_history_local_previous (buffer);
else if (string_strcmp (argv[1], "history_next") == 0)
@@ -8352,18 +8366,26 @@ command_init ()
" delete_next_word: delete next word\n"
" delete_beginning_of_line: delete from beginning of line until "
"cursor\n"
+ " delete_beginning_of_input: delete from beginning of input until "
" delete_end_of_line: delete from cursor until end of line\n"
+ "cursor\n"
+ " delete_end_of_input: delete from cursor until end of input\n"
" delete_line: delete entire line\n"
+ " delete_input: delete entire input\n"
" clipboard_paste: paste from the internal clipboard\n"
" transpose_chars: transpose two chars\n"
" undo: undo last command line action\n"
" redo: redo last command line action\n"
" move_beginning_of_line: move cursor to beginning of line\n"
+ " move_beginning_of_input: move cursor to beginning of input\n"
" move_end_of_line: move cursor to end of line\n"
+ " move_end_of_input: move cursor to end of input\n"
" move_previous_char: move cursor to previous char\n"
" move_next_char: move cursor to next char\n"
" move_previous_word: move cursor to previous word\n"
" move_next_word: move cursor to next word\n"
+ " move_previous_line: move cursor to previous line\n"
+ " move_next_line: move cursor to next line\n"
" history_previous: recall previous command in current buffer "
"history\n"
" history_next: recall next command in current buffer history\n"
@@ -8387,12 +8409,16 @@ command_init ()
"search_stop_here || search_stop || "
"delete_previous_char || delete_next_char || delete_previous_word || "
"delete_previous_word_whitespace || delete_next_word || "
- "delete_beginning_of_line || delete_end_of_line || delete_line || "
+ "delete_beginning_of_line || delete_beginning_of_input || "
+ "delete_end_of_line || delete_end_of_input || "
+ "delete_line || delete_input || "
"clipboard_paste || "
"transpose_chars || "
"undo || redo || "
- "move_beginning_of_line || move_end_of_line || move_previous_char || "
- "move_next_char || move_previous_word || move_next_word || "
+ "move_beginning_of_line || move_beginning_of_input || "
+ "move_end_of_line || move_end_of_input || "
+ "move_previous_char || move_next_char || move_previous_word || "
+ "move_next_word || move_previous_line || move_next_line || "
"history_previous || history_next || history_global_previous || "
"history_global_next || "
"grab_key || grab_raw_key || grab_raw_key_command || grab_key_command || "
diff --git a/src/core/wee-utf8.c b/src/core/wee-utf8.c
index b29870f3f..e8c30792c 100644
--- a/src/core/wee-utf8.c
+++ b/src/core/wee-utf8.c
@@ -271,6 +271,48 @@ utf8_next_char (const char *string)
}
/*
+ * Gets pointer to the beginning of the UTF-8 line in a string.
+ *
+ * Returns pointer to the beginning of the UTF-8 line, NULL if string was NULL.
+ */
+
+const char *
+utf8_beginning_of_line (const char *string_start, const char *string)
+{
+ if (string && string[0] == '\n')
+ string = (char *)utf8_prev_char (string_start, string);
+
+ while (string && string[0] != '\n')
+ {
+ string = (char *)utf8_prev_char (string_start, string);
+ }
+
+ if (string)
+ return (char *)utf8_next_char (string);
+
+ return string_start;
+}
+
+/*
+ * Gets pointer to the end of the UTF-8 line in a string.
+ *
+ * Returns pointer to the end of the UTF-8 line, NULL if string was NULL.
+ */
+
+const char *
+utf8_end_of_line (const char *string)
+{
+ if (!string)
+ return NULL;
+
+ while (string[0] && string[0] != '\n')
+ {
+ string = (char *)utf8_next_char (string);
+ }
+ return string;
+}
+
+/*
* Gets UTF-8 char as an integer.
*
* Returns the UTF-8 char as integer number.
diff --git a/src/core/wee-utf8.h b/src/core/wee-utf8.h
index b2dab3334..88e8badb8 100644
--- a/src/core/wee-utf8.h
+++ b/src/core/wee-utf8.h
@@ -35,6 +35,9 @@ extern void utf8_normalize (char *string, char replacement);
extern const char *utf8_prev_char (const char *string_start,
const char *string);
extern const char *utf8_next_char (const char *string);
+extern const char *utf8_beginning_of_line (const char *string_start,
+ const char *string);
+extern const char *utf8_end_of_line (const char *string);
extern int utf8_char_int (const char *string);
extern int utf8_int_string (unsigned int unicode_value, char *string);
extern int utf8_char_size (const char *string);
diff --git a/src/gui/curses/gui-curses-key.c b/src/gui/curses/gui-curses-key.c
index 4fb0f6fc3..cf0c9c57f 100644
--- a/src/gui/curses/gui-curses-key.c
+++ b/src/gui/curses/gui-curses-key.c
@@ -95,14 +95,19 @@ gui_key_default_bindings (int context, int create_option)
BIND("meta-x", "/buffer zoom");
BIND("meta-d", "/input delete_next_word");
BIND("ctrl-k", "/input delete_end_of_line");
- BIND("meta-r", "/input delete_line");
+ BIND("meta-ctrl-k", "/input delete_end_of_input");
+ BIND("meta-r", "/input delete_input");
+ BIND("meta-R", "/input delete_line");
BIND("ctrl-t", "/input transpose_chars");
BIND("ctrl-u", "/input delete_beginning_of_line");
+ BIND("meta-ctrl-u", "/input delete_beginning_of_input");
BIND("ctrl-y", "/input clipboard_paste");
BIND("home", "/input move_beginning_of_line");
BIND("ctrl-a", "/input move_beginning_of_line");
+ BIND("shift-home", "/input move_beginning_of_input");
BIND("end", "/input move_end_of_line");
BIND("ctrl-e", "/input move_end_of_line");
+ BIND("shift-end", "/input move_end_of_input");
BIND("left", "/input move_previous_char");
BIND("ctrl-b", "/input move_previous_char");
BIND("right", "/input move_next_char");
@@ -115,6 +120,8 @@ gui_key_default_bindings (int context, int create_option)
BIND("down", "/input history_next");
BIND("ctrl-up", "/input history_global_previous");
BIND("ctrl-down", "/input history_global_next");
+ BIND("shift-up", "/input move_previous_line");
+ BIND("shift-down", "/input move_next_line");
BIND("meta-a", "/buffer jump smart");
BIND("meta-j,meta-f", "/buffer -");
BIND("meta-j,meta-l", "/buffer +");
diff --git a/src/gui/gui-input.c b/src/gui/gui-input.c
index 7f364cecb..c614867b6 100644
--- a/src/gui/gui-input.c
+++ b/src/gui/gui-input.c
@@ -915,12 +915,106 @@ gui_input_delete_next_word (struct t_gui_buffer *buffer)
/*
* Deletes all from cursor pos to beginning of line (default key: ctrl-u).
+ *
+ * If cursor is at beginning of line, deletes to beginning of previous line.
*/
void
gui_input_delete_beginning_of_line (struct t_gui_buffer *buffer)
{
int length_deleted, size_deleted;
+ char *start, *beginning_of_line;
+
+ if (!buffer->input || (buffer->input_buffer_pos <= 0))
+ return;
+
+ gui_buffer_undo_snap (buffer);
+ start = (char *)utf8_add_offset (buffer->input_buffer,
+ buffer->input_buffer_pos);
+
+ beginning_of_line = (char *)utf8_beginning_of_line (buffer->input_buffer, start);
+ if (beginning_of_line == start)
+ {
+ beginning_of_line = (char *)utf8_prev_char (buffer->input_buffer,
+ beginning_of_line);
+ beginning_of_line = (char *)utf8_beginning_of_line (buffer->input_buffer,
+ beginning_of_line);
+ }
+
+ size_deleted = start - beginning_of_line;
+ length_deleted = utf8_strnlen (beginning_of_line, size_deleted);
+ gui_input_clipboard_copy (beginning_of_line, size_deleted);
+
+ memmove (beginning_of_line, start, strlen (start));
+
+ if (gui_input_optimize_size (
+ buffer,
+ buffer->input_buffer_size - size_deleted,
+ buffer->input_buffer_length - length_deleted))
+ {
+ buffer->input_buffer[buffer->input_buffer_size] = '\0';
+ buffer->input_buffer_pos = utf8_pos (buffer->input_buffer,
+ beginning_of_line - buffer->input_buffer);
+ }
+ gui_input_text_changed_modifier_and_signal (buffer,
+ 1, /* save undo */
+ 1); /* stop completion */
+}
+
+/*
+ * Deletes all from cursor pos to end of line (default key: ctrl-k).
+ *
+ * If cursor is at end of line, deletes to end of next line.
+ */
+
+void
+gui_input_delete_end_of_line (struct t_gui_buffer *buffer)
+{
+ int length_deleted, size_deleted;
+ char *start, *end_of_line;
+
+ if (!buffer->input)
+ return;
+
+ gui_buffer_undo_snap (buffer);
+ start = (char *)utf8_add_offset (buffer->input_buffer,
+ buffer->input_buffer_pos);
+
+ if (start[0] && start[0] == '\n')
+ end_of_line = (char *)utf8_next_char (start);
+ else
+ end_of_line = start;
+ end_of_line = (char *)utf8_end_of_line (end_of_line);
+
+ size_deleted = end_of_line - start;
+ length_deleted = utf8_strnlen (start, size_deleted);
+ gui_input_clipboard_copy (start, size_deleted);
+
+ memmove (start, end_of_line, strlen (end_of_line));
+
+ if (gui_input_optimize_size (
+ buffer,
+ buffer->input_buffer_size - size_deleted,
+ buffer->input_buffer_length - length_deleted))
+ {
+ buffer->input_buffer[buffer->input_buffer_size] = '\0';
+ buffer->input_buffer_pos = utf8_pos (buffer->input_buffer,
+ start - buffer->input_buffer);
+ }
+
+ gui_input_text_changed_modifier_and_signal (buffer,
+ 1, /* save undo */
+ 1); /* stop completion */
+}
+
+/*
+ * Deletes all from cursor pos to beginning of input (default key: alt-ctrl-u).
+ */
+
+void
+gui_input_delete_beginning_of_input (struct t_gui_buffer *buffer)
+{
+ int length_deleted, size_deleted;
char *start;
if (!buffer->input || (buffer->input_buffer_pos <= 0))
@@ -950,11 +1044,11 @@ gui_input_delete_beginning_of_line (struct t_gui_buffer *buffer)
}
/*
- * Deletes all from cursor pos to end of line (default key: ctrl-k).
+ * Deletes all from cursor pos to end of input (default key: alt-ctrl-k).
*/
void
-gui_input_delete_end_of_line (struct t_gui_buffer *buffer)
+gui_input_delete_end_of_input (struct t_gui_buffer *buffer)
{
char *start;
int size_deleted;
@@ -977,12 +1071,52 @@ gui_input_delete_end_of_line (struct t_gui_buffer *buffer)
}
/*
- * Deletes entire line (default key: alt-r).
+ * Deletes entire line (default key: alt-R).
*/
void
gui_input_delete_line (struct t_gui_buffer *buffer)
{
+ int length_deleted, size_deleted;
+ char *start, *beginning_of_line, *end_of_line;
+
+ if (!buffer->input)
+ return;
+
+ gui_buffer_undo_snap (buffer);
+ start = (char *)utf8_add_offset (buffer->input_buffer,
+ buffer->input_buffer_pos);
+
+ beginning_of_line = (char *)utf8_beginning_of_line (buffer->input_buffer, start);
+ end_of_line = (char *)utf8_end_of_line (start);
+
+ size_deleted = end_of_line - beginning_of_line;
+ length_deleted = utf8_strnlen (start, size_deleted);
+
+ memmove (beginning_of_line, end_of_line, strlen (end_of_line));
+
+ if (gui_input_optimize_size (
+ buffer,
+ buffer->input_buffer_size - size_deleted,
+ buffer->input_buffer_length - length_deleted))
+ {
+ buffer->input_buffer[buffer->input_buffer_size] = '\0';
+ buffer->input_buffer_pos = utf8_pos (buffer->input_buffer,
+ beginning_of_line - buffer->input_buffer);
+ }
+
+ gui_input_text_changed_modifier_and_signal (buffer,
+ 1, /* save undo */
+ 1); /* stop completion */
+}
+
+/*
+ * Deletes entire input (default key: alt-r).
+ */
+
+void
+gui_input_delete_input (struct t_gui_buffer *buffer)
+{
if (!buffer->input)
return;
@@ -1037,33 +1171,100 @@ gui_input_transpose_chars (struct t_gui_buffer *buffer)
}
/*
+ * Moves cursor to beginning of input (default key: shift-home).
+ */
+
+void
+gui_input_move_beginning_of_input (struct t_gui_buffer *buffer)
+{
+ if (!buffer->input || (buffer->input_buffer_pos <= 0))
+ return;
+
+ buffer->input_buffer_pos = 0;
+ gui_input_text_cursor_moved_signal (buffer);
+}
+
+/*
+ * Moves cursor to end of input (default key: shift-end).
+ */
+
+void
+gui_input_move_end_of_input (struct t_gui_buffer *buffer)
+{
+ if (!buffer->input
+ || (buffer->input_buffer_pos >= buffer->input_buffer_length))
+ {
+ return;
+ }
+
+ buffer->input_buffer_pos = buffer->input_buffer_length;
+ gui_input_text_cursor_moved_signal (buffer);
+}
+
+/*
* Moves cursor to beginning of line (default key: home).
+ *
+ * If cursor is at beginning of line, moves to beginning of previous line.
*/
void
gui_input_move_beginning_of_line (struct t_gui_buffer *buffer)
{
+ char *pos, *original_pos;
+
if (!buffer->input || (buffer->input_buffer_pos <= 0))
return;
- buffer->input_buffer_pos = 0;
+ pos = (char *)utf8_add_offset (buffer->input_buffer,
+ buffer->input_buffer_pos);
+ original_pos = pos;
+ pos = (char *)utf8_beginning_of_line (buffer->input_buffer, pos);
+
+ if (pos == original_pos)
+ {
+ pos = (char *)utf8_prev_char (buffer->input_buffer, pos);
+ pos = (char *)utf8_beginning_of_line (buffer->input_buffer, pos);
+ }
+
+ buffer->input_buffer_pos = utf8_pos (buffer->input_buffer,
+ pos - buffer->input_buffer);
+
gui_input_text_cursor_moved_signal (buffer);
}
/*
* Moves cursor to end of line (default key: end).
+ *
+ * If cursor is at end of line, moves to end of next line.
*/
void
gui_input_move_end_of_line (struct t_gui_buffer *buffer)
{
+ char *pos;
+
if (!buffer->input
|| (buffer->input_buffer_pos >= buffer->input_buffer_length))
{
return;
}
- buffer->input_buffer_pos = buffer->input_buffer_length;
+ pos = (char *)utf8_add_offset (buffer->input_buffer,
+ buffer->input_buffer_pos);
+ if (pos[0] && pos[0] == '\n')
+ {
+ pos = (char *)utf8_next_char (pos);
+ }
+ pos = (char *)utf8_end_of_line (pos);
+ if (pos[0])
+ {
+ buffer->input_buffer_pos =
+ utf8_pos (buffer->input_buffer,
+ pos - buffer->input_buffer);
+ }
+ else
+ buffer->input_buffer_pos = buffer->input_buffer_length;
+
gui_input_text_cursor_moved_signal (buffer);
}
@@ -1180,6 +1381,85 @@ gui_input_move_next_word (struct t_gui_buffer *buffer)
}
/*
+ * Moves cursor to previous line (default key: shift-up).
+ */
+
+void
+gui_input_move_previous_line (struct t_gui_buffer *buffer)
+{
+ int beginning_of_line_pos, length_from_beginning, i;
+ char *pos;
+
+ if (!buffer->input || (buffer->input_buffer_pos <= 0))
+ return;
+
+ pos = (char *)utf8_add_offset (buffer->input_buffer,
+ buffer->input_buffer_pos);
+ pos = (char *)utf8_beginning_of_line (buffer->input_buffer, pos);
+
+ if (pos != buffer->input_buffer)
+ {
+ beginning_of_line_pos = utf8_pos (buffer->input_buffer,
+ pos - buffer->input_buffer);
+ length_from_beginning = buffer->input_buffer_pos - beginning_of_line_pos;
+
+ pos = (char *)utf8_prev_char (buffer->input_buffer, pos);
+ pos = (char *)utf8_beginning_of_line (buffer->input_buffer, pos);
+
+ for (i = 0; pos[0] && pos[0] != '\n' && i < length_from_beginning; i++)
+ {
+ pos = (char *)utf8_next_char (pos);
+ }
+
+ buffer->input_buffer_pos = utf8_pos (buffer->input_buffer,
+ pos - buffer->input_buffer);
+
+ gui_input_text_cursor_moved_signal (buffer);
+ }
+}
+
+/*
+ * Moves cursor to next line (default key: shift-down).
+ */
+
+void
+gui_input_move_next_line (struct t_gui_buffer *buffer)
+{
+ int beginning_of_line_pos, length_from_beginning, i;
+ char *pos;
+
+ if (!buffer->input
+ || (buffer->input_buffer_pos >= buffer->input_buffer_length))
+ {
+ return;
+ }
+
+ pos = (char *)utf8_add_offset (buffer->input_buffer,
+ buffer->input_buffer_pos);
+ pos = (char *)utf8_beginning_of_line (buffer->input_buffer, pos);
+
+ beginning_of_line_pos = utf8_pos (buffer->input_buffer,
+ pos - buffer->input_buffer);
+ length_from_beginning = buffer->input_buffer_pos - beginning_of_line_pos;
+
+ pos = (char *)utf8_end_of_line (pos);
+ if (pos[0])
+ {
+ pos = (char *)utf8_next_char (pos);
+
+ for (i = 0; pos[0] && pos[0] != '\n' && i < length_from_beginning; i++)
+ {
+ pos = (char *)utf8_next_char (pos);
+ }
+
+ buffer->input_buffer_pos = utf8_pos (buffer->input_buffer,
+ pos - buffer->input_buffer);
+
+ gui_input_text_cursor_moved_signal (buffer);
+ }
+}
+
+/*
* Recalls previous command from local or global history.
*/
diff --git a/src/gui/gui-input.h b/src/gui/gui-input.h
index be93805d5..4608f9581 100644
--- a/src/gui/gui-input.h
+++ b/src/gui/gui-input.h
@@ -58,14 +58,21 @@ extern void gui_input_delete_previous_word_whitespace (struct t_gui_buffer *buff
extern void gui_input_delete_next_word (struct t_gui_buffer *buffer);
extern void gui_input_delete_beginning_of_line (struct t_gui_buffer *buffer);
extern void gui_input_delete_end_of_line (struct t_gui_buffer *buffer);
+extern void gui_input_delete_beginning_of_input (struct t_gui_buffer *buffer);
+extern void gui_input_delete_end_of_input (struct t_gui_buffer *buffer);
extern void gui_input_delete_line (struct t_gui_buffer *buffer);
+extern void gui_input_delete_input (struct t_gui_buffer *buffer);
extern void gui_input_transpose_chars (struct t_gui_buffer *buffer);
+extern void gui_input_move_beginning_of_input (struct t_gui_buffer *buffer);
+extern void gui_input_move_end_of_input (struct t_gui_buffer *buffer);
extern void gui_input_move_beginning_of_line (struct t_gui_buffer *buffer);
extern void gui_input_move_end_of_line (struct t_gui_buffer *buffer);
extern void gui_input_move_previous_char (struct t_gui_buffer *buffer);
extern void gui_input_move_next_char (struct t_gui_buffer *buffer);
extern void gui_input_move_previous_word (struct t_gui_buffer *buffer);
extern void gui_input_move_next_word (struct t_gui_buffer *buffer);
+extern void gui_input_move_previous_line (struct t_gui_buffer *buffer);
+extern void gui_input_move_next_line (struct t_gui_buffer *buffer);
extern void gui_input_history_local_previous (struct t_gui_buffer *buffer);
extern void gui_input_history_local_next (struct t_gui_buffer *buffer);
extern void gui_input_history_global_previous (struct t_gui_buffer *buffer);
diff --git a/tests/unit/core/test-core-utf8.cpp b/tests/unit/core/test-core-utf8.cpp
index 389344a55..89615a9c0 100644
--- a/tests/unit/core/test-core-utf8.cpp
+++ b/tests/unit/core/test-core-utf8.cpp
@@ -114,11 +114,12 @@ extern "C"
#define UTF8_4BYTES_TRUNCATED_3 "\xf0\xa4\xad"
/* "noël" */
-#define UTF8_NOEL_VALID "no\xc3\xabl"
-#define UTF8_NOEL_INVALID "no\xc3l"
-#define UTF8_NOEL_INVALID2 "no\xff\xffl"
-#define UTF8_NOEL_INVALID_NORM "no?l"
-#define UTF8_NOEL_INVALID2_NORM "no??l"
+#define UTF8_NOEL_VALID "no\xc3\xabl"
+#define UTF8_NOEL_VALID_MULTILINE "no\xc3\xabl\nno\xc3\xabl"
+#define UTF8_NOEL_INVALID "no\xc3l"
+#define UTF8_NOEL_INVALID2 "no\xff\xffl"
+#define UTF8_NOEL_INVALID_NORM "no?l"
+#define UTF8_NOEL_INVALID2_NORM "no??l"
TEST_GROUP(CoreUtf8)
{
@@ -323,6 +324,8 @@ TEST(CoreUtf8, Normalize)
* Tests functions:
* utf8_prev_char
* utf8_next_char
+ * utf8_beginning_of_line
+ * utf8_end_of_line
* utf8_add_offset
* utf8_real_pos
* utf8_pos
@@ -333,6 +336,7 @@ TEST(CoreUtf8, Move)
const char *ptr;
const char *empty_string = "";
const char *noel_valid = UTF8_NOEL_VALID;
+ const char *noel_valid_multiline = UTF8_NOEL_VALID_MULTILINE;
const char *utf8_2bytes_truncated_1 = UTF8_2BYTES_TRUNCATED_1;
const char *utf8_3bytes_truncated_1 = UTF8_3BYTES_TRUNCATED_1;
const char *utf8_3bytes_truncated_2 = UTF8_3BYTES_TRUNCATED_2;
@@ -377,6 +381,28 @@ TEST(CoreUtf8, Move)
POINTERS_EQUAL(utf8_4bytes_truncated_3 + 3,
utf8_next_char (utf8_4bytes_truncated_3));
+ /* beginning/end of line */
+ POINTERS_EQUAL(NULL, utf8_beginning_of_line (NULL, NULL));
+ POINTERS_EQUAL(NULL, utf8_end_of_line (NULL));
+ ptr = utf8_end_of_line (noel_valid_multiline);
+ STRCMP_EQUAL("\nnoël", ptr);
+ ptr = utf8_end_of_line (ptr);
+ STRCMP_EQUAL("\nnoël", ptr);
+ ptr = utf8_next_char (ptr);
+ ptr = utf8_end_of_line (ptr);
+ STRCMP_EQUAL("", ptr);
+ ptr = utf8_end_of_line (ptr);
+ STRCMP_EQUAL("", ptr);
+ ptr = utf8_beginning_of_line (noel_valid_multiline, ptr);
+ STRCMP_EQUAL(noel_valid, ptr);
+ ptr = utf8_beginning_of_line (noel_valid_multiline, ptr);
+ STRCMP_EQUAL(noel_valid, ptr);
+ ptr = utf8_prev_char (noel_valid_multiline, ptr);
+ ptr = utf8_beginning_of_line (noel_valid_multiline, ptr);
+ STRCMP_EQUAL(noel_valid_multiline, ptr);
+ ptr = utf8_beginning_of_line (noel_valid_multiline, ptr);
+ STRCMP_EQUAL(noel_valid_multiline, ptr);
+
/* add offset */
POINTERS_EQUAL(NULL, utf8_add_offset (NULL, 0));
ptr = utf8_add_offset (noel_valid, 0);