Improve support for Unicode in describe-key.

This commit is contained in:
Renaud 2021-07-31 12:35:39 +08:00
parent c4fab606d1
commit d48120a557
3 changed files with 52 additions and 73 deletions

60
bind.c
View File

@ -30,7 +30,7 @@
static int buildlist( char *mstring) ;
static void cmdstr( int c, char *seq) ;
static char *cmdstr( unsigned c, char *seq) ;
static unsigned int getckey( int mflag) ;
static unsigned int stock( char *keyname) ;
static const char *getfname( unsigned keycode, char *failmsg) ;
@ -75,19 +75,19 @@ BINDABLE( help) {
/* describe the command for a certain key */
BINDABLE( deskey) {
const char cmdname[] = "describe-key" ;
char outseq[ NSTRING] ; /* output buffer for command sequence */
/* prompt the user to type a key to describe */
mlwrite( "describe-key: ");
mlwrite( "%s: ", cmdname) ;
/* get the command sequence to describe
* change it to something we can print as well */
int c = getckey( FALSE) ;
cmdstr( c, outseq) ;
unsigned keycode = getckey( FALSE) ;
/* output the command sequence */
mlwrite( "describe-key %s: 0x%x, %s",
outseq, c, getfname( c, "Not Bound")) ;
mlwrite( "%s %s: 0x%x, %s", cmdname, cmdstr( keycode, outseq), keycode,
getfname( keycode, "Not Bound")) ;
return TRUE ;
}
@ -123,10 +123,8 @@ BINDABLE( bindtokey) {
int c = getckey( prefix_f) ;
/* change it to something we can print as well */
cmdstr( c, outseq) ;
/* and dump it out */
ostring( outseq) ;
ostring( cmdstr( c, outseq)) ;
/* key sequence can't be an active prefix key */
if( c == metac || c == ctlxc || c == reptc || c == abortc) {
@ -185,10 +183,8 @@ BINDABLE( unbindkey) {
int c = getckey( FALSE) ; /* get a command sequence */
/* change it to something we can print as well */
cmdstr( c, outseq) ;
/* and dump it out */
ostring( outseq) ;
ostring( cmdstr( c, outseq)) ;
/* prefix key sequence can't be undound, just redefined */
if( c == reptc || c == abortc) {
@ -403,41 +399,37 @@ int startup( const char *fname) {
* int c; sequence to translate
* char *seq; destination string for sequence
*/
static void cmdstr( int c, char *seq) {
char *ptr; /* pointer into current position in sequence */
static char *cmdstr( unsigned c, char *seq) {
char *ptr = seq ; /* pointer into current position in sequence */
ptr = seq;
/* apply meta sequence if needed */
if (c & META) {
/* apply meta sequence if needed */
if( c & META) {
*ptr++ = 'M';
*ptr++ = '-';
}
/* apply ^X sequence if needed */
if (c & CTLX) {
/* apply ^X sequence if needed */
if( c & CTLX) {
if( ctlxc & CTRL)
*ptr++ = '^' ;
*ptr++ = ctlxc & 0x1FFFFF ;
*ptr++ = ctlxc & ~PRFXMASK ;
}
/* apply SPEC sequence if needed */
if (c & SPEC) {
*ptr++ = 'F';
*ptr++ = 'N';
/* apply SPEC sequence if needed */
if( c & SPEC) {
*ptr++ = 'F' ;
*ptr++ = 'N' ;
}
/* apply control sequence if needed */
if (c & CTRL) {
*ptr++ = '^';
}
/* apply control sequence if needed */
if( c & CTRL)
*ptr++ = '^' ;
/* and output the final sequence */
*ptr++ = c & 0x1FFFFF ; /* strip the prefixes */
*ptr = 0; /* terminate the string */
/* and output the final sequence */
ptr += unicode_to_utf8( c & ~PRFXMASK, ptr) ;
*ptr = 0 ; /* terminate the string */
return seq ;
}
static const char *getfname( unsigned keycode, char *failmsg) {

View File

@ -89,7 +89,7 @@ static void modeline(struct window *wp);
static void mlputi(int i, int r);
static void mlputli(long l, int r);
static void mlputf(int s);
static void mlputs( unsigned char *s) ;
static void mlputs( const char *s) ;
#if SIGWINCH
static int newscreensize(int h, int w);
#endif
@ -1274,7 +1274,7 @@ void mlerase( void) {
static void mlputc( unicode_t c) {
if( ttcol < term.t_ncol) {
TTputc( c) ;
++ttcol ;
ttcol += utf8_width( c) ;
}
}
@ -1284,11 +1284,8 @@ static void mlputc( unicode_t c) {
* char *s; string to output
*/
void ostring( const char *s) {
unsigned char c ;
if( discmd)
while( (c = *s++) != 0)
mlputc( c) ;
mlputs( s) ;
}
@ -1302,8 +1299,6 @@ void ostring( const char *s) {
* char *arg; pointer to first argument to print
*/
void vmlwrite( const char *fmt, va_list ap) {
int c; /* current char in format string */
/* if we are not currently echoing on the command line, abort this */
if (discmd == FALSE) {
movecursor(term.t_nrow, 0);
@ -1322,13 +1317,17 @@ void vmlwrite( const char *fmt, va_list ap) {
movecursor( term.t_nrow, 0) ;
mpresf = *fmt ? TRUE : FALSE ; /* flag if line has content or not */
while( ( c = *fmt++) != 0)
while( *fmt) {
unicode_t c ;
fmt += utf8_to_unicode( fmt, 0, 4, &c) ;
if( c != '%')
mlputc( c) ;
else if( ( c = *fmt++) == 0) {
else if( *fmt == 0) {
mlputc( '%') ;
break ;
} else
} else {
fmt += utf8_to_unicode( fmt, 0, 4, &c) ;
switch( c) {
case 'd':
mlputi(va_arg(ap, int), 10);
@ -1347,7 +1346,7 @@ void vmlwrite( const char *fmt, va_list ap) {
break;
case 's':
mlputs( (unsigned char *) va_arg( ap, char *)) ;
mlputs( (char *) va_arg( ap, char *)) ;
break;
case 'f':
@ -1364,6 +1363,8 @@ void vmlwrite( const char *fmt, va_list ap) {
case '%':
mlputc( c) ;
}
}
}
/* if we can, erase to the end of screen */
if( eolexist == TRUE && ttcol < term.t_ncol)
@ -1385,31 +1386,16 @@ void mlwrite( const char *fmt, ...) {
* the characters in the string all have width "1"; if this is not the case
* things will get screwed up a little.
*/
static void mlputs( unsigned char *s) {
unicode_t c ;
static void mlputs( const char *s) {
while( *s && (ttcol < term.t_ncol)) {
unicode_t uc ;
while( ((c = *s++) != 0) && (ttcol < term.t_ncol)) {
if( c == '\t') /* Don't render tabulation */
c = ' ' ;
else if( c > 0xC1 && c <= 0xF4) { /* Accept UTF-8 sequence */
char utf[ 4] ;
char cc ;
int bytes ;
s += utf8_to_unicode( (char *) s, 0, 4, &uc) ;
if( uc == '\t') /* Don't render tabulation */
uc = ' ' ;
utf[ 0] = c ;
utf[ 1] = cc = *s ;
if( (c & 0x20) && ((cc & 0xC0) == 0x80)) { /* at least 3 bytes and a valid encoded char */
utf[ 2] = cc = s[ 1] ;
if( (c & 0x10) && ((cc & 0xC0) == 0x80)) /* at least 4 bytes and a valid encoded char */
utf[ 3] = s[ 2] ;
}
bytes = utf8_to_unicode( utf, 0, sizeof utf, (unicode_t *) &c) ;
s += bytes - 1 ;
}
TTputc( c) ;
++ttcol ;
TTputc( uc) ;
ttcol += utf8_width( uc) ;
}
}

View File

@ -6,10 +6,11 @@
#include "retcode.h"
#define CTRL 0x01000000 /* Control flag, or'ed in */
#define META 0x02000000 /* Meta flag, or'ed in */
#define CTLX 0x04000000 /* ^X flag, or'ed in */
#define SPEC 0x08000000 /* special key (function keys) */
#define CTRL 0x01000000 /* Control flag, or'ed in */
#define META 0x02000000 /* Meta flag, or'ed in */
#define CTLX 0x04000000 /* ^X flag, or'ed in */
#define SPEC 0x08000000 /* special key (function keys) */
#define PRFXMASK 0x0F000000 /* prefix mask */
/* Bindable uEMACS function pointer type and definition template */