diff --git a/edit/edit-widget.h b/edit/edit-widget.h index 39ea7aa7e..b144a70fe 100644 --- a/edit/edit-widget.h +++ b/edit/edit-widget.h @@ -45,6 +45,9 @@ struct WEdit { unsigned char *buffers1[MAXBUFF + 1]; /* all data up to curs1 */ unsigned char *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */ + /* UTF8 */ + unsigned char charbuf[MB_LEN_MAX]; + int charpoint; /* search variables */ long search_start; /* First character to start searching from */ int found_len; /* Length of found string or 0 if none was found */ diff --git a/edit/edit.c b/edit/edit.c index 500f696ea..2cae64805 100644 --- a/edit/edit.c +++ b/edit/edit.c @@ -120,9 +120,38 @@ int edit_get_byte (WEdit * edit, long byte_index) } } -int edit_get_utf (WEdit * edit, long byte_index, int *char_width) +char *edit_get_byte_ptr (WEdit * edit, long byte_index) { unsigned long p; + + if (byte_index >= (edit->curs1 + edit->curs2) || byte_index < 0) + return NULL; + + if (byte_index >= edit->curs1) { + p = edit->curs1 + edit->curs2 - byte_index - 1; + return (char *) (edit->buffers2[p >> S_EDIT_BUF_SIZE]+(EDIT_BUF_SIZE - (p & M_EDIT_BUF_SIZE) - 1)); + } else { + return (char *) (edit->buffers1[byte_index >> S_EDIT_BUF_SIZE]+(byte_index & M_EDIT_BUF_SIZE)); + } +} + +char *edit_get_buf_ptr (WEdit * edit, long byte_index) +{ + unsigned long p; + + if (byte_index >= (edit->curs1 + edit->curs2) || byte_index < 0) + return NULL; + + if (byte_index >= edit->curs1) { + p = edit->curs1 + edit->curs2 - byte_index - 1; + return (char *) (edit->buffers2[p >> S_EDIT_BUF_SIZE]); + } else { + return (char *) (edit->buffers1[byte_index >> S_EDIT_BUF_SIZE]); + } +} + +int edit_get_utf (WEdit * edit, long byte_index, int *char_width) +{ gchar *str = NULL; int res = -1; gunichar ch; @@ -134,12 +163,50 @@ int edit_get_utf (WEdit * edit, long byte_index, int *char_width) return '\n'; } - if (byte_index >= edit->curs1) { - p = edit->curs1 + edit->curs2 - byte_index - 1; - str = (edit->buffers2[p >> S_EDIT_BUF_SIZE]+(EDIT_BUF_SIZE - (p & M_EDIT_BUF_SIZE) - 1)); + str = edit_get_byte_ptr (edit, byte_index); + + res = g_utf8_get_char_validated (str, -1); + + if ( res < 0 ) { + ch = *str; + width = 1; } else { - str = (edit->buffers1[byte_index >> S_EDIT_BUF_SIZE]+(byte_index & M_EDIT_BUF_SIZE)); + ch = res; + /* Calculate UTF-8 char width */ + next_ch = g_utf8_next_char(str); + if ( next_ch ) { + if ( next_ch != str ) { + width = next_ch - str; + } else { + width = 0; + } + } else { + ch = 0; + width = 0; + } } + *char_width = width; + return ch; +} + +int edit_get_prev_utf (WEdit * edit, long byte_index, int *char_width) +{ + gchar *str, *buf = NULL; + int res = -1; + gunichar ch; + gchar *next_ch = NULL; + int width = 0; + + if (byte_index >= (edit->curs1 + edit->curs2) || byte_index < 0) { + *char_width = 1; + return '\n'; + } + + str = edit_get_byte_ptr (edit, byte_index); + buf = edit_get_buf_ptr (edit, byte_index); + + /* get prev utf8 char */ + str = g_utf8_find_prev_char (buf, str); res = g_utf8_get_char_validated (str, -1); diff --git a/edit/editkeys.c b/edit/editkeys.c index 91306ca21..503e7cda4 100644 --- a/edit/editkeys.c +++ b/edit/editkeys.c @@ -192,7 +192,6 @@ edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch) int i = 0; int extmod = 0; const edit_key_map_type *key_map = NULL; - switch (edit_key_emulation) { case EDIT_KEY_EMULATION_NORMAL: key_map = cooledit_key_map; @@ -244,12 +243,41 @@ edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch) /* an ordinary insertable character */ if (x_key < 256 && !extmod) { - int c = convert_from_input_c (x_key); + if (!edit->utf8) { + int c = convert_from_input_c (x_key); + if (is_printable (c)) { + char_for_insertion = c; + goto fin; + } + } else { + if (edit->charpoint >= MB_LEN_MAX) { + goto fin; + edit->charpoint = 0; + } - if (is_printable (c)) { - char_for_insertion = c; - goto fin; - } + edit->charbuf[edit->charpoint] = x_key; + edit->charpoint++; + + int res = str_is_valid_char (edit->charbuf, edit->charpoint); + mc_log("res:%i, edit->charpoint : %i\n",res, edit->charpoint); + if (res < 0) { + if (res != -2) { + edit->charpoint = 0; /* broken multibyte char, skip */ + goto fin; + } + char_for_insertion = x_key; + goto fin; + } else { + edit->charbuf[edit->charpoint]='\0'; + edit->charpoint = 0; + if ( g_unichar_isprint (g_utf8_get_char(edit->charbuf))) { + char_for_insertion = x_key; + goto fin; + } + } + //char_for_insertion = x_key; + //goto fin; + } } /* Commands specific to the key emulation */