From ce0451348c775d5afb07e4b6e48d93c1693a9865 Mon Sep 17 00:00:00 2001 From: David Lawrence Ramsey Date: Sat, 15 Jan 2005 00:34:57 +0000 Subject: [PATCH] make do_prev_word() work with multibyte strings, and update various comments in do_next_word() and do_prev_word() git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2273 35c25a1d-7b9e-4130-9fde-d3aeb78583b8 --- ChangeLog | 4 +- src/nano.c | 112 +++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 97 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index f141a531..f3d3fa66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -104,8 +104,8 @@ CVS code - move_mbleft() and moved to chars.c), move_right() (renamed move_mbright() and moved to chars.c), do_home(), do_verbatim_input(), do_delete(), do_tab(), do_next_word(), - do_input(), do_output(), get_buffer(), unget_input(), - unget_kbinput(), get_input(), parse_kbinput(), + do_prev_word(), do_input(), do_output(), get_buffer(), + unget_input(), unget_kbinput(), get_input(), parse_kbinput(), unparse_kbinput(), parse_verbatim_kbinput(), do_statusbar_input(), do_statusbar_home(), do_statusbar_verbatim_kbinput(), do_statusbar_output(), and diff --git a/src/nano.c b/src/nano.c index 6c8ad362..6ca25b22 100644 --- a/src/nano.c +++ b/src/nano.c @@ -1325,7 +1325,8 @@ void do_next_word(void) assert(current != NULL && current->data != NULL); - /* Skip letters in this word first. */ + /* Move forward until we find the character after the last letter of + * the current word. */ while (current->data[current_x] != '\0') { char_mb_len = parse_mbchar(current->data + current_x, char_mb @@ -1334,13 +1335,15 @@ void do_next_word(void) #endif , NULL); + /* If we've found it, stop moving forward through the current + * line. */ if (!is_alnum_mbchar(char_mb)) break; current_x += char_mb_len; } - /* Go until we find the first letter of the next word. */ + /* Move forward until we find the first letter of the next word. */ for (; current != NULL; current = current->next) { while (current->data[current_x] != '\0') { char_mb_len = parse_mbchar(current->data + current_x, @@ -1350,12 +1353,16 @@ void do_next_word(void) #endif , NULL); + /* If we've found it, stop moving forward through the + * current line. */ if (is_alnum_mbchar(char_mb)) break; current_x += char_mb_len; } + /* If we've found it, stop moving forward to the beginnings of + * subsequent lines. */ if (current->data[current_x] != '\0') break; @@ -1364,6 +1371,8 @@ void do_next_word(void) free(char_mb); + /* If we haven't found it, leave the cursor at the end of the + * file. */ if (current == NULL) current = filebot; @@ -1378,37 +1387,106 @@ void do_prev_word(void) { size_t pww_save = placewewant; const filestruct *current_save = current; + char *char_mb = charalloc(mb_cur_max()); + int char_mb_len; + bool begin_line = FALSE; assert(current != NULL && current->data != NULL); - current_x++; + /* Move backward until we find the character before the first letter + * of the current word. */ + while (!begin_line) { + char_mb_len = parse_mbchar(current->data + current_x, + char_mb +#ifdef NANO_WIDE + , NULL +#endif + , NULL); + + /* If we've found it, stop moving backward through the current + * line. */ + if (!is_alnum_mbchar(char_mb)) + break; - /* Skip letters in this word first. */ - while (current_x > 0 && isalnum(current->data[current_x - 1])) - current_x--; + if (current_x == 0) + begin_line = TRUE; + else + current_x = move_mbleft(current->data, current_x); + } - /* Go until we find the first letter of the previous word. */ + /* Move backward until we find the last letter of the previous + * word. */ for (; current != NULL; current = current->prev) { - while (current_x > 0 && !isalnum(current->data[current_x - 1])) - current_x--; + while (!begin_line) { + char_mb_len = parse_mbchar(current->data + current_x, + char_mb +#ifdef NANO_WIDE + , NULL +#endif + , NULL); + + /* If we've found it, stop moving backward through the + * current line. */ + if (is_alnum_mbchar(char_mb)) + break; - if (current_x > 0) + if (current_x == 0) + begin_line = TRUE; + else + current_x = move_mbleft(current->data, current_x); + } + + /* If we've found it, stop moving backward to the ends of + * previous lines. */ + if (!begin_line) break; - if (current->prev != NULL) - current_x = strlen(current->prev->data) + 1; + if (current->prev != NULL) { + begin_line = FALSE; + current_x = strlen(current->prev->data); + } } - current_x--; - + /* If we haven't found it, leave the cursor at the beginning of the + * file. */ if (current == NULL) { current = fileage; current_x = 0; - } else { - while (current_x > 0 && isalnum(current->data[current_x - 1])) - current_x--; + /* If we've found it, move backward until we find the character + * before the first letter of the previous word. */ + } else if (!begin_line) { + if (current_x == 0) + begin_line = TRUE; + else + current_x = move_mbleft(current->data, current_x); + + while (!begin_line) { + char_mb_len = parse_mbchar(current->data + current_x, + char_mb +#ifdef NANO_WIDE + , NULL +#endif + , NULL); + + /* If we've found it, stop moving backward through the + * current line. */ + if (!is_alnum_mbchar(char_mb)) + break; + + if (current_x == 0) + begin_line = TRUE; + else + current_x = move_mbleft(current->data, current_x); + } + + /* If we've found it, move forward to the first letter of the + * previous word. */ + if (!begin_line) + current_x += char_mb_len; } + free(char_mb); + placewewant = xplustabs(); /* Update the screen. */ -- 2.39.5