From 1fe2eebf743c678ebf39fef834a3bea29dbadd96 Mon Sep 17 00:00:00 2001 From: David Lawrence Ramsey Date: Fri, 14 Jan 2005 21:33:47 +0000 Subject: [PATCH] add multibyte and wide equivalents of isalnum(), make do_next_word() work with multibyte strings, and tweak the "smart home" routines to use move_right() for consistency git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2269 35c25a1d-7b9e-4130-9fde-d3aeb78583b8 --- ChangeLog | 18 ++++++++++-------- src/chars.c | 35 +++++++++++++++++++++++++++++++++++ src/move.c | 6 ++---- src/nano.c | 51 ++++++++++++++++++++++++++++++++++++++------------- src/proto.h | 5 +++++ src/winio.c | 5 ++--- 6 files changed, 92 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index 17000b88..75acea22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -93,20 +93,22 @@ CVS code - them to work with multibyte strings as much as possible, add support to a few more functions as well, and move multibyte character-specific functions to their own source file. New - file chars.c; new functions is_blank_mbchar(), + file chars.c; new functions is_alnum_char(), + is_alnum_mbchar(), is_alnum_wchar(), is_blank_mbchar(), is_blank_wchar(), is_cntrl_mbchar(), is_cntrl_wchar(), mbstrnlen(), control_mbrep(), control_wrep(), mbwidth(), mb_cur_max(), and make_mbchar(); changes to is_blank_char() (moved to chars.c), is_cntrl_char() (moved to chars.c), nstrnlen() (moved to chars.c), parse_char() (renamed parse_mbchar() and moved to chars.c), do_home(), - do_verbatim_input(), do_delete(), do_tab(), 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 display_string(); removal of - buffer_to_keys() and keys_to_buffer(). (DLR) + do_verbatim_input(), do_delete(), do_tab(), do_next_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 + display_string(); removal of buffer_to_keys() and + keys_to_buffer(). (DLR) - cut.c: do_cut_text() - If keep_cutbuffer is FALSE, only blow away the text in the diff --git a/src/chars.c b/src/chars.c index 5834e59b..02a1ca95 100644 --- a/src/chars.c +++ b/src/chars.c @@ -38,6 +38,41 @@ #include #endif +/* This function is equivalent to isalnum(). */ +bool is_alnum_char(unsigned int c) +{ + return isalnum(c); +} + +/* This function is equivalent to isalnum() for multibyte characters. */ +bool is_alnum_mbchar(const char *c) +{ + assert(c != NULL); + +#ifdef NANO_WIDE + if (!ISSET(NO_UTF8)) { + wchar_t wc; + int c_mb_len = mbtowc(&wc, c, MB_CUR_MAX); + + if (c_mb_len <= 0) { + mbtowc(NULL, NULL, 0); + wc = (unsigned char)*c; + } + + return is_alnum_wchar(wc); + } else +#endif + return is_alnum_char((unsigned char)*c); +} + +#ifdef NANO_WIDE +/* This function is equivalent to isalnum() for wide characters. */ +bool is_alnum_wchar(wchar_t wc) +{ + return iswalnum(wc); +} +#endif + /* This function is equivalent to isblank(). */ bool is_blank_char(unsigned int c) { diff --git a/src/move.c b/src/move.c index 3a811592..cdd88e14 100644 --- a/src/move.c +++ b/src/move.c @@ -58,13 +58,11 @@ void do_home(void) if (ISSET(SMART_HOME)) { size_t current_x_save = current_x; char *blank_mb = charalloc(mb_cur_max()); - int blank_mb_len; current_x = 0; while (current->data[current_x] != '\0') { - blank_mb_len = parse_mbchar(current->data + current_x, - blank_mb + parse_mbchar(current->data + current_x, blank_mb #ifdef NANO_WIDE , NULL #endif @@ -73,7 +71,7 @@ void do_home(void) if (!is_blank_mbchar(blank_mb)) break; - current_x += blank_mb_len; + current_x = move_right(current->data, current_x); } free(blank_mb); diff --git a/src/nano.c b/src/nano.c index 00c0fd5f..7518e0de 100644 --- a/src/nano.c +++ b/src/nano.c @@ -1315,41 +1315,65 @@ void do_enter(void) } #ifndef NANO_SMALL +/* Move to the next word. */ void do_next_word(void) { - size_t old_pww = placewewant; - const filestruct *old_current = current; + size_t pww_save = placewewant; + const filestruct *current_save = current; + char *char_mb = charalloc(mb_cur_max()); + assert(current != NULL && current->data != NULL); /* Skip letters in this word first. */ - while (current->data[current_x] != '\0' && - isalnum(current->data[current_x])) - current_x++; + while (current->data[current_x] != '\0') { + parse_mbchar(current->data + current_x, char_mb +#ifdef NANO_WIDE + , NULL +#endif + , NULL); + if (!is_alnum_mbchar(char_mb)) + break; + + current_x = move_right(current->data, current_x); + } + + /* Go until we find the first letter of the next word. */ for (; current != NULL; current = current->next) { - while (current->data[current_x] != '\0' && - !isalnum(current->data[current_x])) - current_x++; + while (current->data[current_x] != '\0') { + parse_mbchar(current->data + current_x, char_mb +#ifdef NANO_WIDE + , NULL +#endif + , NULL); + + if (is_alnum_mbchar(char_mb)) + break; + + current_x = move_right(current->data, current_x); + } if (current->data[current_x] != '\0') break; current_x = 0; } + if (current == NULL) current = filebot; placewewant = xplustabs(); /* Update the screen. */ - edit_redraw(old_current, old_pww); + edit_redraw(current_save, pww_save); } -/* The same thing for backwards. */ +/* Move to the previous word. */ void do_prev_word(void) { - size_t old_pww = placewewant; - const filestruct *old_current = current; + size_t pww_save = placewewant; + const filestruct *current_save = current; + assert(current != NULL && current->data != NULL); current_x++; @@ -1358,6 +1382,7 @@ void do_prev_word(void) while (current_x > 0 && isalnum(current->data[current_x - 1])) current_x--; + /* Go until we find the first letter of the previous word. */ for (; current != NULL; current = current->prev) { while (current_x > 0 && !isalnum(current->data[current_x - 1])) current_x--; @@ -1382,7 +1407,7 @@ void do_prev_word(void) placewewant = xplustabs(); /* Update the screen. */ - edit_redraw(old_current, old_pww); + edit_redraw(current_save, pww_save); } void do_mark(void) diff --git a/src/proto.h b/src/proto.h index 0dfbfc34..10b452a3 100644 --- a/src/proto.h +++ b/src/proto.h @@ -151,6 +151,11 @@ extern char *homedir; /* Functions we want available. */ /* Public functions in chars.c. */ +bool is_alnum_char(unsigned int c); +bool is_alnum_mbchar(const char *c); +#ifdef NANO_WIDE +bool is_alnum_wchar(wchar_t wc); +#endif bool is_blank_char(unsigned int c); bool is_blank_mbchar(const char *c); #ifdef NANO_WIDE diff --git a/src/winio.c b/src/winio.c index faa15adf..5ae85bb6 100644 --- a/src/winio.c +++ b/src/winio.c @@ -1804,12 +1804,11 @@ void do_statusbar_home(void) if (ISSET(SMART_HOME)) { size_t statusbar_x_save = statusbar_x; char *blank_mb = charalloc(mb_cur_max()); - int blank_mb_len; statusbar_x = 0; while (statusbar_x < statusbar_xend) { - blank_mb_len = parse_mbchar(answer + statusbar_x, + parse_mbchar(answer + statusbar_x, blank_mb #ifdef NANO_WIDE , NULL @@ -1819,7 +1818,7 @@ void do_statusbar_home(void) if (!is_blank_mbchar(blank_mb)) break; - statusbar_x += blank_mb_len; + statusbar_x = move_right(answer, statusbar_x); } free(blank_mb); -- 2.39.5