mirror of
https://github.com/rfivet/uemacs.git
synced 2024-12-17 23:06:25 -05:00
Rewrite keycode command input from command line according to terminal sequence handling.
This commit is contained in:
parent
7f3f498f3f
commit
5002897705
151
bind.c
151
bind.c
@ -1,9 +1,7 @@
|
||||
/* bind.c -- implements bind.h */
|
||||
#include "bind.h"
|
||||
|
||||
/* bind.c
|
||||
*
|
||||
* This file is for functions having to do with key bindings,
|
||||
/* This file is for functions having to do with key bindings,
|
||||
* descriptions, help commands and startup file.
|
||||
*
|
||||
* Written 11-feb-86 by Daniel Lawrence
|
||||
@ -33,9 +31,14 @@ static int buildlist( char *mstring) ;
|
||||
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) ;
|
||||
static const char *getfname( unsigned keycode, const char *failmsg) ;
|
||||
|
||||
|
||||
static boolean cmdfail( const char *msg) {
|
||||
mlwrite( "%s", msg) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
BINDABLE( help) {
|
||||
/* give me some help!!!!
|
||||
bring up a fake buffer and read the help file into it with view mode */
|
||||
@ -46,12 +49,10 @@ BINDABLE( help) {
|
||||
if( bp == curbp)
|
||||
return TRUE ;
|
||||
|
||||
if (bp == NULL) {
|
||||
fname = flook( hlpfname, FALSE);
|
||||
if (fname == NULL) {
|
||||
mlwrite("(Help file is not online)");
|
||||
return FALSE;
|
||||
}
|
||||
if( bp == NULL) {
|
||||
fname = flook( hlpfname, FALSE) ;
|
||||
if( fname == NULL)
|
||||
return cmdfail( "(Help file is not online)") ;
|
||||
}
|
||||
|
||||
/* split the current window to make room for the help stuff */
|
||||
@ -73,6 +74,10 @@ BINDABLE( help) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean invalidkey( void) {
|
||||
return cmdfail( "(Invalid key sequence)") ;
|
||||
}
|
||||
|
||||
/* describe the command for a certain key */
|
||||
BINDABLE( deskey) {
|
||||
const char cmdname[] = "describe-key" ;
|
||||
@ -84,6 +89,8 @@ BINDABLE( deskey) {
|
||||
/* get the command sequence to describe
|
||||
* change it to something we can print as well */
|
||||
unsigned keycode = getckey( FALSE) ;
|
||||
if( keycode == (unsigned) ~0)
|
||||
return invalidkey() ;
|
||||
|
||||
/* output the command sequence */
|
||||
mlwrite( "%s %s: 0x%x, %s", cmdname, cmdstr( keycode, outseq), keycode,
|
||||
@ -110,10 +117,8 @@ BINDABLE( bindtokey) {
|
||||
return FALSE ;
|
||||
|
||||
fnp_t kfunc = nbp->n_func ;
|
||||
if( kfunc == NULL) {
|
||||
mlwrite( "(No such function)") ;
|
||||
return FALSE ;
|
||||
}
|
||||
if( kfunc == NULL)
|
||||
return cmdfail( "(No such function)") ;
|
||||
|
||||
mlwrite( "bind-to-key %s: ", bind_name( nbp)) ;
|
||||
|
||||
@ -121,6 +126,8 @@ BINDABLE( bindtokey) {
|
||||
boolean prefix_f = (kfunc == metafn) || (kfunc == cex) ||
|
||||
(kfunc == unarg) || (kfunc == ctrlg) ;
|
||||
int c = getckey( prefix_f) ;
|
||||
if( c == ~0)
|
||||
return invalidkey() ;
|
||||
|
||||
/* change it to something we can print as well */
|
||||
/* and dump it out */
|
||||
@ -134,8 +141,7 @@ BINDABLE( bindtokey) {
|
||||
|| (c == abortc && kfunc == ctrlg))
|
||||
return TRUE ;
|
||||
|
||||
mlwrite( "(Can't bind to active prefix)") ;
|
||||
return FALSE ;
|
||||
return cmdfail( "(Can't bind to active prefix)") ;
|
||||
}
|
||||
|
||||
/* if the function is a prefix key */
|
||||
@ -159,10 +165,8 @@ BINDABLE( bindtokey) {
|
||||
}
|
||||
|
||||
ktp = setkeybinding( c, nbp) ;
|
||||
if( ktp->k_code == 0) {
|
||||
mlwrite( "Binding table FULL!") ;
|
||||
return FALSE ;
|
||||
}
|
||||
if( ktp->k_code == 0)
|
||||
return cmdfail( "Binding table FULL!") ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
@ -181,16 +185,16 @@ BINDABLE( unbindkey) {
|
||||
|
||||
/* get the command sequence to unbind */
|
||||
int c = getckey( FALSE) ; /* get a command sequence */
|
||||
if( c == ~0)
|
||||
return invalidkey() ;
|
||||
|
||||
/* change it to something we can print as well */
|
||||
/* and dump it out */
|
||||
ostring( cmdstr( c, outseq)) ;
|
||||
|
||||
/* prefix key sequence can't be undound, just redefined */
|
||||
if( c == reptc || c == abortc) {
|
||||
mlwrite( "(Can't unbind prefix)") ;
|
||||
return FALSE ;
|
||||
}
|
||||
if( c == reptc || c == abortc)
|
||||
return cmdfail( "(Can't unbind prefix)") ;
|
||||
|
||||
/* if it isn't bound, bitch */
|
||||
if( delkeybinding( c) == FALSE) {
|
||||
@ -269,10 +273,8 @@ static int buildlist( char *mstring) {
|
||||
|
||||
/* and get a buffer for it */
|
||||
bp = bfind("*Binding list*", TRUE, 0);
|
||||
if (bp == NULL || bclear(bp) == FALSE) {
|
||||
mlwrite("Can not display binding list");
|
||||
return FALSE;
|
||||
}
|
||||
if( bp == NULL || bclear( bp) == FALSE)
|
||||
return cmdfail( "Can't display binding list") ;
|
||||
|
||||
/* let us know this is in progress */
|
||||
mlwrite("(Building binding list)");
|
||||
@ -352,17 +354,16 @@ static int buildlist( char *mstring) {
|
||||
* get a command key sequence from the keyboard
|
||||
*
|
||||
* int mflag; going for a meta sequence?
|
||||
* returns ~0 on failure
|
||||
*/
|
||||
static unsigned int getckey( int mflag) {
|
||||
unsigned int c ; /* character fetched */
|
||||
|
||||
/* check to see if we are executing a command line */
|
||||
if( clexec) {
|
||||
char *tok ; /* command incoming */
|
||||
|
||||
tok = getnewtokval() ; /* get the next token */
|
||||
char *tok = getnewtokval() ; /* get the next token */
|
||||
if( tok == NULL)
|
||||
c = 0 ; /* return dummy key on failure */
|
||||
c = ~0 ; /* return invalid key on failure */
|
||||
else {
|
||||
c = stock( tok) ;
|
||||
free( tok) ;
|
||||
@ -416,23 +417,23 @@ static char *cmdstr( unsigned c, char *seq) {
|
||||
*ptr++ = ctlxc & ~PRFXMASK ;
|
||||
}
|
||||
|
||||
/* apply control sequence if needed */
|
||||
if( c & CTRL)
|
||||
*ptr++ = '^' ;
|
||||
|
||||
/* apply SPEC sequence if needed */
|
||||
if( c & SPEC) {
|
||||
*ptr++ = 'F' ;
|
||||
*ptr++ = 'N' ;
|
||||
}
|
||||
|
||||
/* apply control sequence if needed */
|
||||
if( c & CTRL)
|
||||
*ptr++ = '^' ;
|
||||
|
||||
/* 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) {
|
||||
static const char *getfname( unsigned keycode, const char *failmsg) {
|
||||
/* takes a key code and gets the name of the function bound to it */
|
||||
kbind_p kbp = getkeybinding( keycode) ;
|
||||
if( kbp->k_code == 0)
|
||||
@ -443,54 +444,58 @@ static const char *getfname( unsigned keycode, char *failmsg) {
|
||||
return found ;
|
||||
}
|
||||
|
||||
/*
|
||||
* stock:
|
||||
/* stock:
|
||||
* String key name TO Command Key
|
||||
*
|
||||
* char *keyname; name of key to translate to Command key form
|
||||
* fmt: [M-][^X][^][FN]X
|
||||
* returns ~0 on invalid sequence
|
||||
*/
|
||||
static unsigned int stock( char *keyname) {
|
||||
unsigned int c; /* key sequence to return */
|
||||
/* parse it up */
|
||||
unsigned c = 0 ;
|
||||
|
||||
/* parse it up */
|
||||
c = 0;
|
||||
|
||||
/* first, the META prefix */
|
||||
if (*keyname == 'M' && *(keyname + 1) == '-') {
|
||||
c = META;
|
||||
keyname += 2;
|
||||
/* first, the META prefix */
|
||||
if( *keyname == 'M' && keyname[ 1] == '-') {
|
||||
c = META ;
|
||||
keyname += 2 ;
|
||||
}
|
||||
|
||||
/* next the function prefix */
|
||||
if (*keyname == 'F' && *(keyname + 1) == 'N') {
|
||||
c |= SPEC;
|
||||
keyname += 2;
|
||||
/* control-x prefix */
|
||||
if( *keyname == '^' && keyname[ 1] == 'X') {
|
||||
c |= CTLX ;
|
||||
keyname += 2 ;
|
||||
}
|
||||
|
||||
/* control-x as well... (but not with FN) */
|
||||
if (*keyname == '^' && *(keyname + 1) == 'X' && !(c & SPEC)) {
|
||||
c |= CTLX;
|
||||
keyname += 2;
|
||||
/* a control char? */
|
||||
if( *keyname == '^' && keyname[ 1] != 0) {
|
||||
c |= CTRL ;
|
||||
++keyname ;
|
||||
}
|
||||
|
||||
/* a control char? */
|
||||
if (*keyname == '^' && *(keyname + 1) != 0) {
|
||||
c |= CTRL;
|
||||
++keyname;
|
||||
}
|
||||
if (*keyname < 32) {
|
||||
c |= CTRL;
|
||||
*keyname += 'A';
|
||||
/* next the function prefix */
|
||||
if( *keyname == 'F' && keyname[ 1] == 'N') {
|
||||
c |= SPEC ;
|
||||
keyname += 2 ;
|
||||
}
|
||||
|
||||
/* only one character left to parse */
|
||||
if( !*keyname || keyname[1])
|
||||
return ~0 ;
|
||||
|
||||
/* make sure we are not lower case (not with function keys) */
|
||||
if (*keyname >= 'a' && *keyname <= 'z' && !(c & SPEC))
|
||||
*keyname -= 32;
|
||||
/* only way to redefine ^X is by quoting binary value */
|
||||
if( *keyname < 32 || *keyname == 0x7F) {
|
||||
c |= CTRL ;
|
||||
*keyname ^= 0x40 ;
|
||||
}
|
||||
|
||||
/* the final sequence... */
|
||||
/* make sure we are not lower case (not with function keys) */
|
||||
if( *keyname >= 'a' && *keyname <= 'z' && !(c & SPEC))
|
||||
*keyname -= 32 ;
|
||||
|
||||
/* the final sequence... */
|
||||
c |= *keyname & 0xFFU ;
|
||||
return c;
|
||||
return c ;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -499,5 +504,13 @@ static unsigned int stock( char *keyname) {
|
||||
* char *skey; name of key to get binding for
|
||||
*/
|
||||
const char *transbind( char *skey) {
|
||||
return getfname( stock( skey), "ERROR") ;
|
||||
static const char failmsg[] = "ERROR" ;
|
||||
|
||||
unsigned c = stock( skey) ;
|
||||
if( c == (unsigned) ~0)
|
||||
return failmsg ;
|
||||
else
|
||||
return getfname( c, failmsg) ;
|
||||
}
|
||||
|
||||
/* end of bind.c */
|
||||
|
89
input.c
89
input.c
@ -1,10 +1,7 @@
|
||||
/* input.c -- implements input.h */
|
||||
|
||||
#include "input.h"
|
||||
|
||||
/* input.c
|
||||
*
|
||||
* Various input routines
|
||||
/* Various input routines
|
||||
*
|
||||
* written by Daniel Lawrence 5/9/86
|
||||
* modified by Petri Kutvonen
|
||||
@ -355,15 +352,17 @@ static int get1unicode( int *up) {
|
||||
return bytes ;
|
||||
}
|
||||
|
||||
static int keystack[ 8] ;
|
||||
static int *stackptr = &keystack[ 8] ;
|
||||
/* Terminal sequences need up to 6 read ahead characters */
|
||||
#define STACKSIZE 6
|
||||
static int keystack[ STACKSIZE] ;
|
||||
static int *stackptr = &keystack[ STACKSIZE] ;
|
||||
#define KPUSH( c) *(--stackptr) = (c)
|
||||
|
||||
int get1key( void) {
|
||||
int c ;
|
||||
|
||||
/* fetch from queue if any were pushed back */
|
||||
if( stackptr != &keystack[ 8])
|
||||
if( stackptr != &keystack[ STACKSIZE])
|
||||
return *(stackptr++) ;
|
||||
|
||||
/* fetch from keyboard */
|
||||
@ -372,52 +371,62 @@ int get1key( void) {
|
||||
}
|
||||
|
||||
/* GETCMD: Get a command from the keyboard. Process all applicable prefix
|
||||
keys.
|
||||
keys. Handle alted and controlled FNx, not shifted. Allow double
|
||||
prefix M-^X.
|
||||
*/
|
||||
int getcmd( void) {
|
||||
int cmask = 0 ;
|
||||
int c, d, e, f ; /* read up to ^[[24~ */
|
||||
int cmask = 0 ; /* prefixes M- & ^X */
|
||||
int keyread[ STACKSIZE] ; /* room to process sequences like ^[[24;2~ */
|
||||
int *kptr = keyread ;
|
||||
int c ;
|
||||
|
||||
for( ;;) {
|
||||
c = get1key() ;
|
||||
if( c == (CTRL | '[')) {
|
||||
/* fetch terminal sequence */
|
||||
c = get1key() ;
|
||||
c = *(kptr++) = get1key() ;
|
||||
if( c == 'O') { /* F1 .. F4 */
|
||||
d = get1key() ;
|
||||
if( d >= 'P' && d <= 'S') {
|
||||
c = d | SPEC ;
|
||||
break ;
|
||||
}
|
||||
|
||||
KPUSH( d) ;
|
||||
c = *(kptr++) = get1key() ;
|
||||
if( c >= 'P' && c <= 'S')
|
||||
return c | SPEC | cmask ;
|
||||
} else if( c == '[') {
|
||||
d = get1key() ;
|
||||
if( d >= 'A' && d <= 'Z') { /* Arrows, Home, End, ReverseTab */
|
||||
c = d | SPEC ;
|
||||
break ;
|
||||
} else if( d >= '0' && d <= '9') {
|
||||
e = get1key() ;
|
||||
if( e == '~') { /* Insert, Delete, PageUp, PageDown */
|
||||
c = d | SPEC ;
|
||||
break ;
|
||||
} else if( e >= '0' && e <= '9') {
|
||||
f = get1key() ;
|
||||
if( f == '~') { /* F5 .. F12 */
|
||||
c = (16 + (d - '0') * 16 + e) | SPEC ;
|
||||
break ;
|
||||
int v = 0 ; /* ^[[v1;v~ or ^[[v~ */
|
||||
int v1 = 0 ;
|
||||
while( kptr < &keyread[ STACKSIZE]) {
|
||||
c = *(kptr++) = get1key() ;
|
||||
if( (c == '~') || (c >= 'A' && c <= 'Z')) {
|
||||
/* Found end of sequence */
|
||||
if( v1) { /* Handle ALT/CTL, not SHFT */
|
||||
if( (v - 1) & 4)
|
||||
cmask |= CTRL ;
|
||||
|
||||
if( (v - 1) & 2)
|
||||
cmask |= META ;
|
||||
|
||||
v = v1 ;
|
||||
}
|
||||
|
||||
KPUSH( f) ;
|
||||
}
|
||||
|
||||
KPUSH( e) ;
|
||||
}
|
||||
if( c == '~') {
|
||||
if( v)
|
||||
c = v + ((v <= 9) ? '0' : 'a' - 10) ;
|
||||
else
|
||||
break ;
|
||||
}
|
||||
|
||||
KPUSH( d) ;
|
||||
return c | SPEC | cmask ;
|
||||
} else if( c == ';') { /* Start of SHFT/ALT/CTL state */
|
||||
v1 = v ;
|
||||
v = 0 ;
|
||||
} else if( c >= '0' && c <= '9')
|
||||
v = v * 10 + c - '0' ;
|
||||
else
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
KPUSH( c) ;
|
||||
/* not a match, unget the keys read so far */
|
||||
while( kptr > keyread)
|
||||
KPUSH( *(--kptr)) ;
|
||||
|
||||
c = CTRL | '[' ;
|
||||
}
|
||||
@ -681,3 +690,5 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
|
||||
|
||||
return retval ;
|
||||
}
|
||||
|
||||
/* end of input.c */
|
||||
|
Loading…
Reference in New Issue
Block a user