From: Thomas Roessler Date: Sun, 10 Dec 2000 18:03:43 +0000 (+0000) Subject: More enter.c updates. From E.G.E.. X-Git-Tag: mutt-1-3-13-rel~12 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a430df47aff19a5f945691ca90c5e72c202f9e29;p=mutt More enter.c updates. From E.G.E.. --- diff --git a/configure.in b/configure.in index 23500b67..7e174f37 100644 --- a/configure.in +++ b/configure.in @@ -864,10 +864,14 @@ if test "$wc_funcs" != yes -a "$wc_funcs" != no; then #define _XOPEN_SOURCE 1 #include #include +#ifdef HAVE_WCTYPE_H +#include +#endif #ifdef HAVE_WCHAR_H #include #endif], - [mbrtowc(0, 0, 0, 0); wctomb(0, 0); wcwidth(0);], + [mbrtowc(0, 0, 0, 0); wctomb(0, 0); wcwidth(0); + iswprint(0); iswspace(0); towlower(0); towupper(0); iswalnum(0)], mutt_cv_wc_funcs=yes)) wc_funcs=$mutt_cv_wc_funcs fi diff --git a/enter.c b/enter.c index 5b6aa001..d69971a2 100644 --- a/enter.c +++ b/enter.c @@ -1,7 +1,6 @@ /* * Copyright (C) 1996-2000 Michael R. Elkins * Copyright (C) 2000 Edmund Grimley Evans - * Copyright (C) 2000 Thomas Roessler * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,8 +25,6 @@ #include -#include "mbyte.h" - /* redraw flags for mutt_enter_string() */ enum { @@ -102,30 +99,29 @@ size_t my_mbstowcs (wchar_t **pwbuf, size_t *pwbuflen, size_t i, char *buf) } /* - * Replace part of the wchar_t buffer, from FROM to TO, by BUF. + * Replace part of the wchar_t buffer, from FROM to CURPOS, by BUF. */ -static void replace_part (wchar_t **pwbuf, size_t *pwbuflen, - size_t from, size_t *to, size_t *end, char *buf) +static void replace_part (ENTER_STATE *state, size_t from, char *buf) { /* Save the suffix */ - size_t savelen = *end - *to; + size_t savelen = state->lastchar - state->curpos; wchar_t *savebuf = safe_malloc (savelen * sizeof (wchar_t)); - memcpy (savebuf, *pwbuf + *to, savelen * sizeof (wchar_t)); + memcpy (savebuf, state->wbuf + state->curpos, savelen * sizeof (wchar_t)); /* Convert to wide characters */ - *to = my_mbstowcs (pwbuf, pwbuflen, from, buf); + state->curpos = my_mbstowcs (&state->wbuf, &state->wbuflen, from, buf); /* Make space for suffix */ - if (*to + savelen > *pwbuflen) + if (state->curpos + savelen > state->wbuflen) { - *pwbuflen = *to + savelen; - safe_realloc ((void **) pwbuf, *pwbuflen * sizeof (wchar_t)); + state->wbuflen = state->curpos + savelen; + safe_realloc ((void **) state->wbuf, state->wbuflen * sizeof (wchar_t)); } /* Restore suffix */ - memcpy (*pwbuf + *to, savebuf, savelen * sizeof (wchar_t)); - *end = *to + savelen; + memcpy (state->wbuf + state->curpos, savebuf, savelen * sizeof (wchar_t)); + state->lastchar = state->curpos + savelen; free (savebuf); } @@ -232,15 +228,13 @@ int _mutt_enter_string (char *buf, size_t buflen, int y, int x, { case OP_EDITOR_HISTORY_UP: state->curpos = state->lastchar; - replace_part (&state->wbuf, &state->wbuflen, 0, &state->curpos, &state->lastchar, - mutt_history_prev (hclass)); + replace_part (state, 0, mutt_history_prev (hclass)); redraw = M_REDRAW_INIT; break; case OP_EDITOR_HISTORY_DOWN: state->curpos = state->lastchar; - replace_part (&state->wbuf, &state->wbuflen, 0, &state->curpos, &state->lastchar, - mutt_history_prev (hclass)); + replace_part (state, 0, mutt_history_prev (hclass)); redraw = M_REDRAW_INIT; break; @@ -254,7 +248,7 @@ int _mutt_enter_string (char *buf, size_t buflen, int y, int x, --i; if (i) --i; - memmove(state->wbuf + i, state->wbuf + state->curpos, (state->lastchar - state->curpos) * sizeof (*state->wbuf)); + memmove (state->wbuf + i, state->wbuf + state->curpos, (state->lastchar - state->curpos) * sizeof (wchar_t)); state->lastchar -= state->curpos - i; state->curpos = i; } @@ -305,9 +299,9 @@ int _mutt_enter_string (char *buf, size_t buflen, int y, int x, else { while (state->curpos && iswspace (state->wbuf[state->curpos - 1])) - state->curpos--; + --state->curpos; while (state->curpos && !iswspace (state->wbuf[state->curpos - 1])) - state->curpos--; + --state->curpos; } break; @@ -332,9 +326,9 @@ int _mutt_enter_string (char *buf, size_t buflen, int y, int x, break; } while (state->curpos && !iswspace (state->wbuf[state->curpos])) - state->curpos--; + --state->curpos; while (state->curpos < state->lastchar && iswspace (state->wbuf[state->curpos])) - state->curpos--; + ++state->curpos; while (state->curpos < state->lastchar && !iswspace (state->wbuf[state->curpos])) { if (ch == OP_EDITOR_DOWNCASE_WORD) @@ -361,77 +355,47 @@ int _mutt_enter_string (char *buf, size_t buflen, int y, int x, ++i; while (i < state->lastchar && !wcwidth (state->wbuf[i])) ++i; - memmove(state->wbuf + state->curpos, state->wbuf + i, (state->lastchar - i) * sizeof (*state->wbuf)); + memmove (state->wbuf + state->curpos, state->wbuf + i, (state->lastchar - i) * sizeof (wchar_t)); state->lastchar -= i - state->curpos; } break; - case OP_EDITOR_TRANSPOSE_CHARS: - { - int idx; - wchar_t wc; - - idx = state->curpos; - if (idx == 0) - idx = 1; - if (idx == state->lastchar) - idx = state->curpos - 1; - if (idx == 0) - { - BEEP(); - break; - } - - wc = state->wbuf[idx]; - state->wbuf[idx] = state->wbuf[idx-1]; - state->wbuf[idx-1] = wc; - - break; - } - case OP_EDITOR_KILL_WORD: - { - int j, k; - /* delete to begining of word */ if (state->curpos != 0) { - j = state->curpos; - while (j > 0 && iswspace (state->wbuf[j - 1])) - j--; - if (j > 0) + i = state->curpos; + while (i && iswspace (state->wbuf[i - 1])) + --i; + if (i) { - if (iswalnum (state->wbuf[j - 1])) + if (iswalnum (state->wbuf[i - 1])) { - for (j--; j > 0 && iswalnum (state->wbuf[j - 1]); j--) + for (--i; i && iswalnum (state->wbuf[i - 1]); i--) ; } else - j--; + --i; } - k = state->curpos; - state->curpos = j; - while (k < state->lastchar) - state->wbuf[j++] = state->wbuf[k++]; - state->lastchar = j; + memmove (state->wbuf + i, state->wbuf + state->curpos, + (state->lastchar - state->curpos) * sizeof (wchar_t)); + state->lastchar += i - state->curpos; + state->curpos = i; } break; - } case OP_EDITOR_KILL_EOW: - { - int j, k; /* delete to end of word */ - for (j = state->curpos; j < state->lastchar && iswspace (state->wbuf[j]); j++) + for (i = state->curpos; + i < state->lastchar && iswspace (state->wbuf[i]); i++) ; - for ( ; j < state->lastchar && !iswspace (state->wbuf[j]); j++) + for (; i < state->lastchar && !iswspace (state->wbuf[i]); i++) ; - for (k = state->curpos; j < state->lastchar; j++, k++) - state->wbuf[k] = state->wbuf[j]; - state->lastchar = k; + memmove (state->wbuf + state->curpos, state->wbuf + i, + (state->lastchar - i) * sizeof (wchar_t)); + state->lastchar += state->curpos - i; break; - } - + case OP_EDITOR_BUFFY_CYCLE: if (flags & M_EFILE) { @@ -453,24 +417,24 @@ int _mutt_enter_string (char *buf, size_t buflen, int y, int x, ; my_wcstombs (buf, buflen, state->wbuf + i, state->curpos - i); if (tempbuf && templen == state->lastchar - i && - !memcmp (tempbuf, state->wbuf + i, (state->lastchar - i) * sizeof (*state->wbuf))) + !memcmp (tempbuf, state->wbuf + i, (state->lastchar - i) * sizeof (wchar_t))) { mutt_select_file (buf, buflen, 0); set_option (OPTNEEDREDRAW); if (*buf) - replace_part (&state->wbuf, &state->wbuflen, i, &state->curpos, &state->lastchar, buf); + replace_part (state, i, buf); rv = 1; goto bye; } if (!mutt_complete (buf, buflen)) { templen = state->lastchar - i; - safe_realloc ((void **) &tempbuf, templen * sizeof (*state->wbuf)); + safe_realloc ((void **) &tempbuf, templen * sizeof (wchar_t)); } else BEEP (); - replace_part (&state->wbuf, &state->wbuflen, i, &state->curpos, &state->lastchar, buf); + replace_part (state, i, buf); } else if (flags & M_ALIAS) { @@ -481,7 +445,7 @@ int _mutt_enter_string (char *buf, size_t buflen, int y, int x, ; my_wcstombs (buf, buflen, state->wbuf + i, state->curpos - i); r = mutt_alias_complete (buf, buflen); - replace_part (&state->wbuf, &state->wbuflen, i, &state->curpos, &state->lastchar, buf); + replace_part (state, i, buf); if (!r) { rv = 1; @@ -498,7 +462,7 @@ int _mutt_enter_string (char *buf, size_t buflen, int y, int x, tabs = 0; else if (!mutt_command_complete (buf, buflen, i, tabs)) BEEP (); - replace_part (&state->wbuf, &state->wbuflen, 0, &state->curpos, &state->lastchar, buf); + replace_part (state, 0, buf); } else if (flags & (M_FILE | M_EFILE)) { @@ -506,7 +470,7 @@ int _mutt_enter_string (char *buf, size_t buflen, int y, int x, /* see if the path has changed from the last time */ if (tempbuf && templen == state->lastchar && - !memcmp (tempbuf, state->wbuf, state->lastchar * sizeof (*state->wbuf))) + !memcmp (tempbuf, state->wbuf, state->lastchar * sizeof (wchar_t))) { _mutt_select_file (buf, buflen, 0, multiple, files, numfiles); set_option (OPTNEEDREDRAW); @@ -527,12 +491,12 @@ int _mutt_enter_string (char *buf, size_t buflen, int y, int x, if (!mutt_complete (buf, buflen)) { templen = state->lastchar; - safe_realloc ((void **) &tempbuf, templen * sizeof (*state->wbuf)); - memcpy (tempbuf, state->wbuf, templen * sizeof (*state->wbuf)); + safe_realloc ((void **) &tempbuf, templen * sizeof (wchar_t)); + memcpy (tempbuf, state->wbuf, templen * sizeof (wchar_t)); } else BEEP (); /* let the user know that nothing matched */ - replace_part (&state->wbuf, &state->wbuflen, 0, &state->curpos, &state->lastchar, buf); + replace_part (state, 0, buf); } else goto self_insert; @@ -550,13 +514,13 @@ int _mutt_enter_string (char *buf, size_t buflen, int y, int x, ; my_wcstombs (buf, buflen, state->wbuf + i, state->curpos - i); mutt_query_complete (buf, buflen); - replace_part (&state->wbuf, &state->wbuflen, i, &state->curpos, &state->lastchar, buf); + replace_part (state, i, buf); } else { my_wcstombs (buf, buflen, state->wbuf, state->curpos); mutt_query_menu (buf, buflen); - replace_part (&state->wbuf, &state->wbuflen, 0, &state->curpos, &state->lastchar, buf); + replace_part (state, 0, buf); } rv = 1; goto bye; @@ -576,6 +540,24 @@ int _mutt_enter_string (char *buf, size_t buflen, int y, int x, } } + case OP_EDITOR_TRANSPOSE_CHARS: + if (state->lastchar < 2) + BEEP (); + else + { + wchar_t t; + + if (state->curpos == 0) + state->curpos = 2; + else if (state->curpos < state->lastchar) + ++state->curpos; + + t = state->wbuf[state->curpos - 2]; + state->wbuf[state->curpos - 2] = state->wbuf[state->curpos - 1]; + state->wbuf[state->curpos - 1] = t; + } + break; + default: BEEP (); } @@ -620,9 +602,9 @@ self_insert: if (state->lastchar >= state->wbuflen) { state->wbuflen = state->lastchar + 20; - safe_realloc ((void **) &state->wbuf, state->wbuflen * sizeof (*state->wbuf)); + safe_realloc ((void **) &state->wbuf, state->wbuflen * sizeof (wchar_t)); } - memmove (state->wbuf + state->curpos + 1, state->wbuf + state->curpos, (state->lastchar - state->curpos) * sizeof (*state->wbuf)); + memmove (state->wbuf + state->curpos + 1, state->wbuf + state->curpos, (state->lastchar - state->curpos) * sizeof (wchar_t)); state->wbuf[state->curpos++] = ch; state->lastchar++; } @@ -653,5 +635,4 @@ void mutt_free_enter_state (ENTER_STATE **esp) * very narrow screen might crash it * sort out the input side * unprintable chars - * config tests for iswspace, towupper, towlower */ diff --git a/mbyte.c b/mbyte.c index 0eb8f350..f895a179 100644 --- a/mbyte.c +++ b/mbyte.c @@ -246,6 +246,81 @@ int iswprint (wint_t wc) return (0 <= wc && wc < 256) ? IsPrint (wc) : 0; } +int iswspace (wint_t wc) +{ + if (Charset_is_utf8 || charset_is_ja) + return (9 <= wc && wc <= 13) || wc == 32; + else + return (0 <= wc && wc < 256) ? isspace (wc) : 0; +} + +static wint_t towupper_ucs (wint_t x) +{ + /* Only works for x < 0x130 */ + if ((0x60 < x && x < 0x7b) || (0xe0 <= x && x < 0xff && x != 0xf7)) + return x - 32; + else if (0x100 <= x && x < 0x130) + return x & ~1; + else if (x == 0xb5) + return 0x39c; + else if (x == 0xff) + return 0x178; + else + return x; +} + +static wint_t towlower_ucs (wint_t x) +{ + /* Only works for x < 0x130 */ + if ((0x40 < x && x < 0x5b) || (0xc0 <= x && x < 0xdf && x != 0xd7)) + return x + 32; + else if (0x100 <= x && x < 0x130) + return x | 1; + else + return x; +} + +static int iswalnum_ucs (wint_t wc) +{ + /* Only works for x < 0x220 */ + if (wc >= 0x100) + return 1; + else if (wc < 0x30) + return 0; + else if (wc < 0x3a) + return 1; + else if (wc < 0xa0) + return (0x40 < (wc & ~0x20) && (wc & ~0x20) < 0x5b); + else if (wc < 0xc0) + return (wc == 0xaa || wc == 0xb5 || wc == 0xba); + else + return !(wc == 0xd7 || wc == 0xf7); +} + +wint_t towupper (wint_t wc) +{ + if (Charset_is_utf8 || charset_is_ja) + return towupper_ucs (wc); + else + return (0 <= wc && wc < 256) ? toupper (wc) : wc; +} + +wint_t towlower (wint_t wc) +{ + if (Charset_is_utf8 || charset_is_ja) + return towlower_ucs (wc); + else + return (0 <= wc && wc < 256) ? tolower (wc) : wc; +} + +int iswalnum (wint_t wc) +{ + if (Charset_is_utf8 || charset_is_ja) + return iswalnum_ucs (wc); + else + return (0 <= wc && wc < 256) ? isalnum (wc) : 0; +} + /* * l10n for Japanese: * Symbols, Greek and Cyrillic in JIS X 0208, Japanese Kanji diff --git a/mbyte.h b/mbyte.h index 4fba8a77..797a2da7 100644 --- a/mbyte.h +++ b/mbyte.h @@ -16,6 +16,10 @@ size_t wcrtomb (char *s, wchar_t wc, mbstate_t *ps); size_t mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps); int iswprint (wint_t wc); +int iswspace (wint_t wc); +int iswalnum (wint_t wc); +wint_t towupper (wint_t wc); +wint_t towlower (wint_t wc); int wcwidth (wchar_t wc); # endif /* !HAVE_WC_FUNCS */ diff --git a/mutt.h b/mutt.h index 33551989..e98a4c38 100644 --- a/mutt.h +++ b/mutt.h @@ -33,7 +33,10 @@ #include #include #ifdef HAVE_WCHAR_H -#include +# include +#endif +#if defined(HAVE_WCTYPE_H) && defined(HAVE_WC_FUNCS) +# include #endif #ifndef _POSIX_PATH_MAX