diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/wee-command.c | 32 | ||||
-rw-r--r-- | src/core/wee-utf8.c | 42 | ||||
-rw-r--r-- | src/core/wee-utf8.h | 3 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-key.c | 9 | ||||
-rw-r--r-- | src/gui/gui-input.c | 290 | ||||
-rw-r--r-- | src/gui/gui-input.h | 7 |
6 files changed, 374 insertions, 9 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); |