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
#include <wctype.h>
#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)
{
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
if (!is_blank_mbchar(blank_mb))
break;
- current_x += blank_mb_len;
+ current_x = move_right(current->data, current_x);
}
free(blank_mb);
}
#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++;
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--;
placewewant = xplustabs();
/* Update the screen. */
- edit_redraw(old_current, old_pww);
+ edit_redraw(current_save, pww_save);
}
void do_mark(void)
/* 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
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
if (!is_blank_mbchar(blank_mb))
break;
- statusbar_x += blank_mb_len;
+ statusbar_x = move_right(answer, statusbar_x);
}
free(blank_mb);