1
0
mirror of https://github.com/rfivet/uemacs.git synced 2024-12-19 15:56:24 -05:00

Improve handling of UTF-8 interactive input of strings.

This commit is contained in:
Renaud 2021-08-01 15:07:06 +08:00
parent 27f30e48d2
commit 7730a4e730
3 changed files with 37 additions and 33 deletions

64
input.c
View File

@ -324,9 +324,13 @@ int tgetc(void)
return c; return c;
} }
static int get1unicode( int *k) { /* GET1KEY: Get one keystroke. The only prefixes legal here are the SPEC
and CTRL prefixes. */
static int get1unicode( int *up) {
/* Accept UTF-8 sequence */ /* Accept UTF-8 sequence */
int c = *k ; int bytes ;
int c = tgetc() ;
if( c > 0xC1 && c <= 0xF4) { if( c > 0xC1 && c <= 0xF4) {
char utf[ 4] ; char utf[ 4] ;
char cc ; char cc ;
@ -339,22 +343,23 @@ static int get1unicode( int *k) {
utf[ 3] = tgetc() ; utf[ 3] = tgetc() ;
} }
return utf8_to_unicode( utf, 0, sizeof utf, (unicode_t *) k) ; bytes = utf8_to_unicode( utf, 0, sizeof utf, (unicode_t *) up) ;
} else } else {
return 1 ; if( (c >= 0x00 && c <= 0x1F) || c == 0x7F) /* C0 control -> C- */
c ^= CTRL | 0x40 ;
*up = c ;
bytes = 1 ;
}
return bytes ;
} }
/* GET1KEY: Get one keystroke. The only prefixes legal here are the SPEC
and CTRL prefixes. */
int get1key( void) { int get1key( void) {
/* get a keystroke */ int c ;
int c = tgetc() ;
get1unicode( &c) ; get1unicode( &c) ;
return c ;
if( (c >= 0x00 && c <= 0x1F) || c == 0x7F) /* C0 control -> C- */
c ^= CTRL | 0x40 ;
return c ;
} }
/* GETCMD: Get a command from the keyboard. Process all applicable /* GETCMD: Get a command from the keyboard. Process all applicable
@ -463,12 +468,8 @@ handle_CSI:
return CTLX | c; return CTLX | c;
} }
#ifdef CYGWIN /* otherwise, just return it */
// get1unicode( &c) ; return c ;
#endif
/* otherwise, just return it */
return c;
} }
/* A more generalized prompt/reply function allowing the caller /* A more generalized prompt/reply function allowing the caller
@ -490,16 +491,17 @@ static void echov( int c) {
} }
} }
static void rubc( char c) { static void rubc( int c) {
rubout() ; rubout() ;
if( (c >= 0 && c < ' ') || c == 0x7F) { if( (c >= 0 && c < ' ') || c == 0x7F) {
/* ^x range */ /* ^x range */
rubout() ; rubout() ;
if( c == '\n') { if( c == '\n') { /* <NL> */
rubout() ; rubout() ;
rubout() ; rubout() ;
} }
} } else if( utf8_width( c) == 2)
rubout() ;
} }
int getstring( const char *prompt, char *buf, int nbuf, int eolchar) int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
@ -537,14 +539,14 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
didtry = 0; didtry = 0;
#endif #endif
/* get a character from the user */ /* get a character from the user */
c = get1key(); int bytes = get1unicode( &c) ;
/* Quoting? Store as it is */ /* Quoting? Store as it is */
if( quote_f == TRUE) { if( quote_f == TRUE) {
quote_f = FALSE ; quote_f = FALSE ;
if( cpos < nbuf - 1) { if( cpos < nbuf - bytes) {
c = ectoc( c) ; c = ectoc( c) ;
buf[ cpos++] = c ; cpos += unicode_to_utf8( c, &buf[ cpos]) ;
echov( c) ; echov( c) ;
TTflush() ; TTflush() ;
} }
@ -579,8 +581,12 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
if( c == 0x7F || c == 0x08) { if( c == 0x7F || c == 0x08) {
/* rubout/erase */ /* rubout/erase */
if (cpos != 0) { if (cpos != 0) {
rubc( buf[ --cpos]) ; int c ;
cpos -= 1 ;
cpos -= utf8_revdelta( (unsigned char *) &buf[ cpos], cpos) ; cpos -= utf8_revdelta( (unsigned char *) &buf[ cpos], cpos) ;
utf8_to_unicode( &buf[ cpos], 0, 4, (unicode_t *) &c) ;
rubc( c) ;
TTflush(); TTflush();
} }
} else if( c == 0x15) { } else if( c == 0x15) {
@ -695,9 +701,7 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
quote_f = TRUE ; quote_f = TRUE ;
else { else {
/* store as it is */ /* store as it is */
// n = get1unicode( &c) ; /* fetch multiple bytes */ if( cpos + bytes < nbuf) {
int n = 4 ; /* long utf-8 encoding */
if( cpos + n < nbuf) {
cpos += unicode_to_utf8( c, &buf[ cpos]) ; cpos += unicode_to_utf8( c, &buf[ cpos]) ;
echov( c) ; echov( c) ;
TTflush() ; TTflush() ;

View File

@ -177,7 +177,7 @@ const name_bind names[] = {
{" next-word", forwword, META | 'F'} , {" next-word", forwword, META | 'F'} ,
{" nop", nullproc, SPEC | META | 'C'}, /* hook */ {" nop", nullproc, SPEC | META | 'C'}, /* hook */
{"!open-line", openline, CTRL | 'O'} , {"!open-line", openline, CTRL | 'O'} ,
{" overwrite-string", ovstring, 0} , {"!overwrite-string", ovstring, 0} ,
{" pipe-command", pipecmd, CTLX | '@'} , {" pipe-command", pipecmd, CTLX | '@'} ,
{" previous-line", (fnp_t) backline, CTRL | 'P'} , {" previous-line", (fnp_t) backline, CTRL | 'P'} ,
{" previous-page", (fnp_t) backpage, CTRL | 'Z'} , /* MV */ {" previous-page", (fnp_t) backpage, CTRL | 'Z'} , /* MV */

View File

@ -954,7 +954,7 @@ static int iovstring( int f, int n, const char *prompt, int (*fun)( char *)) {
* int f, n; ignored arguments * int f, n; ignored arguments
*/ */
int istring( int f, int n) { int istring( int f, int n) {
return iovstring( f, n, "String to insert<META>: ", linstr) ; return iovstring( f, n, "insert-string<META>: ", linstr) ;
} }
/* /*
@ -964,7 +964,7 @@ int istring( int f, int n) {
* int f, n; ignored arguments * int f, n; ignored arguments
*/ */
int ovstring( int f, int n) { int ovstring( int f, int n) {
return iovstring( f, n, "String to overwrite<META>: ", lover) ; return iovstring( f, n, "overwrite-string<META>: ", lover) ;
} }
/* end of random.c */ /* end of random.c */