1
0
mirror of https://github.com/rfivet/uemacs.git synced 2024-06-03 11:00:42 +00:00

Remove function pointer from key to bindable table.

Emphasize bindable functions in code.
Use function name based prompts.
This commit is contained in:
Renaud 2021-07-24 08:58:23 +08:00
parent f30ef38bc8
commit 1aadb53956
10 changed files with 109 additions and 138 deletions

101
bind.c
View File

@ -76,27 +76,22 @@ int help(int f, int n)
return TRUE; return TRUE;
} }
int deskey( int f, int n) {
/* describe the command for a certain key */ /* describe the command for a certain key */
int c; /* key to describe */ BINDABLE( deskey) {
char outseq[NSTRING]; /* output buffer for command sequence */ char outseq[ NSTRING] ; /* output buffer for command sequence */
/* prompt the user to type us a key to describe */ /* prompt the user to type a key to describe */
mlwrite(": describe-key "); mlwrite( "describe-key: ");
/* get the command sequence to describe /* get the command sequence to describe
change it to something we can print as well */ * change it to something we can print as well */
c = getckey( FALSE) ; int c = getckey( FALSE) ;
mlwrite( ": describe-key 0x%x, ", c) ; cmdstr( c, outseq) ;
cmdstr( c, &outseq[ 0]) ;
/* and dump it out */ /* output the command sequence */
ostring(outseq); mlwrite( "describe-key %s: 0x%x, %s",
ostring(" "); outseq, c, getfname( c, "Not Bound")) ;
return TRUE ;
/* output the command sequence */
ostring( getfname( c, "Not Bound")) ;
return TRUE;
} }
/* /*
@ -105,12 +100,12 @@ int deskey( int f, int n) {
* *
* int f, n; command arguments [IGNORED] * int f, n; command arguments [IGNORED]
*/ */
int bindtokey( int f, int n) { BINDABLE( bindtokey) {
key_tab *ktp ; /* pointer into the command table */ key_tab *ktp ; /* pointer into the command table */
char outseq[ 80] ; /* output buffer for keystroke sequence */ char outseq[ 80] ; /* output buffer for keystroke sequence */
/* prompt the user to type in a key to bind */ /* prompt the user to type in a key to bind */
mlwrite(": bind-to-key "); mlwrite("bind-to-key: ");
/* get the function name to bind it to */ /* get the function name to bind it to */
const name_bind *nbp = getname() ; const name_bind *nbp = getname() ;
@ -123,7 +118,7 @@ int bindtokey( int f, int n) {
return FALSE ; return FALSE ;
} }
ostring( " ") ; mlwrite( "bind-to-key %s: ", bind_name( nbp)) ;
/* get the command sequence to bind */ /* get the command sequence to bind */
boolean prefix_f = (kfunc == metafn) || (kfunc == cex) || boolean prefix_f = (kfunc == metafn) || (kfunc == cex) ||
@ -138,28 +133,27 @@ int bindtokey( int f, int n) {
/* if the function is a prefix key */ /* if the function is a prefix key */
if( prefix_f) { if( prefix_f) {
/* search for an existing binding for the prefix key */ /* search and remove all existing binding for the prefix */
for( ktp = keytab ; ktp->k_fp != NULL ; ktp++) for( ktp = keytab ; ktp->k_code != 0 ; ktp++)
if( ktp->k_fp == kfunc) if( ktp->k_nbp == nbp)
unbindchar( ktp->k_code) ; unbindchar( ktp->k_code) ;
/* reset the appropriate global prefix variable */ /* set the appropriate global prefix variable */
if (kfunc == metafn) if( kfunc == metafn)
metac = c; metac = c ;
if (kfunc == cex) else if( kfunc == cex)
ctlxc = c; ctlxc = c ;
if (kfunc == unarg) if( kfunc == unarg)
reptc = c; reptc = c ;
if (kfunc == ctrlg) if( kfunc == ctrlg)
abortc = c; abortc = c ;
} }
/* search the table to see if it exists */ /* search the table to see if it exists */
for( ktp = keytab ; ktp->k_fp != NULL ; ktp++) { for( ktp = keytab ; ktp->k_code != 0 ; ktp++) {
if( ktp->k_code == c) { if( ktp->k_code == c) {
/* it exists, just change it then */ /* it exists, just change it then */
ktp->k_fp = kfunc ; ktp->k_nbp = nbp ;
ktp->k_nbp = NULL ;
return TRUE ; return TRUE ;
} }
} }
@ -172,11 +166,9 @@ int bindtokey( int f, int n) {
} }
ktp->k_code = c; /* add keycode */ ktp->k_code = c; /* add keycode */
ktp->k_fp = kfunc; /* and the function pointer */ ktp->k_nbp = nbp ;
ktp->k_nbp = NULL ;
++ktp; /* and make sure the next is null */ ++ktp; /* and make sure the next is null */
ktp->k_code = 0; ktp->k_code = 0;
ktp->k_fp = NULL;
ktp->k_nbp = NULL ; ktp->k_nbp = NULL ;
return TRUE; return TRUE;
@ -194,7 +186,7 @@ int unbindkey(int f, int n)
char outseq[80]; /* output buffer for keystroke sequence */ char outseq[80]; /* output buffer for keystroke sequence */
/* prompt the user to type in a key to unbind */ /* prompt the user to type in a key to unbind */
mlwrite(": unbind-key "); mlwrite("unbind-key: ");
/* get the command sequence to unbind */ /* get the command sequence to unbind */
c = getckey(FALSE); /* get a command sequence */ c = getckey(FALSE); /* get a command sequence */
@ -223,21 +215,19 @@ static boolean unbindchar( unsigned c) {
key_tab *ktp ; /* pointer into the command table */ key_tab *ktp ; /* pointer into the command table */
/* search the table to see if the key exists */ /* search the table to see if the key exists */
for( ktp = keytab ; ktp->k_fp != NULL ; ktp++) { for( ktp = keytab ; ktp->k_code != 0 ; ktp++) {
if (ktp->k_code == c) { if (ktp->k_code == c) {
/* save the pointer and scan to the end of the table */ /* save the pointer and scan to the end of the table */
key_tab *sktp = ktp ; key_tab *sav_ktp = ktp ;
while( (++ktp)->k_fp != NULL) ; while( (++ktp)->k_code != 0) ;
ktp -= 1 ; /* backup to the last legit entry */ ktp -= 1 ; /* backup to the last legit entry */
/* copy the last entry to the current one */ /* copy the last entry to the current one */
sktp->k_code = ktp->k_code ; sav_ktp->k_code = ktp->k_code ;
sktp->k_fp = ktp->k_fp ; sav_ktp->k_nbp = ktp->k_nbp ;
sktp->k_nbp = ktp->k_nbp ;
/* null out the last one */ /* null out the last one */
ktp->k_code = 0 ; ktp->k_code = 0 ;
ktp->k_fp = NULL ;
ktp->k_nbp = NULL ; ktp->k_nbp = NULL ;
return TRUE ; return TRUE ;
} }
@ -289,7 +279,7 @@ int apro( int f, int n) {
char *mstring ; /* string to match cmd names to */ char *mstring ; /* string to match cmd names to */
int status ; /* status return */ int status ; /* status return */
status = newmlarg( &mstring, "Apropos string: ", 0) ; status = newmlarg( &mstring, "apropos: ", 0) ;
if( status == TRUE) { if( status == TRUE) {
status = buildlist( mstring) ; status = buildlist( mstring) ;
free( mstring) ; free( mstring) ;
@ -362,9 +352,8 @@ static int buildlist( char *mstring) {
cpos = strlen(outseq); cpos = strlen(outseq);
/* search down any keys bound to this */ /* search down any keys bound to this */
ktp = &keytab[0]; for( ktp = keytab ; ktp->k_code != 0 ; ktp++) {
while (ktp->k_fp != NULL) { if( ktp->k_nbp == nptr) {
if (ktp->k_fp == nptr->n_func) {
/* padd out some spaces */ /* padd out some spaces */
while (cpos < 28) while (cpos < 28)
outseq[cpos++] = ' '; outseq[cpos++] = ' ';
@ -379,7 +368,6 @@ static int buildlist( char *mstring) {
cpos = 0; /* and clear the line */ cpos = 0; /* and clear the line */
} }
++ktp;
} }
/* if no key was bound, we need to dump it anyway */ /* if no key was bound, we need to dump it anyway */
@ -494,7 +482,7 @@ static void cmdstr( int c, char *seq) {
key_tab *getkeybind( unsigned c) { key_tab *getkeybind( unsigned c) {
key_tab *ktp ; key_tab *ktp ;
for( ktp = keytab ; ktp->k_fp != NULL ; ktp++) for( ktp = keytab ; ktp->k_code != 0 ; ktp++)
if (ktp->k_code == c) if (ktp->k_code == c)
break ; break ;
@ -504,17 +492,12 @@ key_tab *getkeybind( unsigned c) {
static const char *getfname( unsigned keycode, char *failmsg) { static const char *getfname( unsigned keycode, char *failmsg) {
/* takes a key code and gets the name of the function bound to it */ /* takes a key code and gets the name of the function bound to it */
key_tab *kbp = getkeybind( keycode) ; key_tab *kbp = getkeybind( keycode) ;
fnp_t func = kbp->k_fp ; if( kbp->k_code == 0)
if( func == NULL)
return failmsg ; return failmsg ;
if( kbp->k_nbp == NULL)
kbp->k_nbp = getfncnb( func) ;
assert( func == kbp->k_nbp->n_func) ;
const char *found = bind_name( kbp->k_nbp) ; const char *found = bind_name( kbp->k_nbp) ;
assert( *found) ; assert( *found) ;
return *found ? found : failmsg ; return found ;
} }
/* /*

View File

@ -1,4 +1,4 @@
/* bindable.h -- implements bindable.c */ /* bindable.c -- implements bindable.h */
#include "bindable.h" #include "bindable.h"
#include <stdlib.h> #include <stdlib.h>
@ -135,9 +135,9 @@ int ctlxe(int f, int n)
} }
/* /*
* Abort. * abort:
* Beep the beeper. Kill off any keyboard macro, etc., that is in progress. * Beep the beeper. Kill off any keyboard macro, etc., that is in progress.
* Sometimes called as a routine, to do general aborting of stuff. * Sometimes called as a routine, to do general aborting of stuff.
*/ */
int ctrlg( int f, int n) { int ctrlg( int f, int n) {
kbdmode = STOP ; kbdmode = STOP ;
@ -145,26 +145,4 @@ int ctrlg( int f, int n) {
return ABORT ; return ABORT ;
} }
/* user function that does NOTHING */ /* end of bindable.c */
int nullproc(int f, int n)
{
return TRUE;
}
/* dummy function for binding to meta prefix */
int metafn(int f, int n)
{
return TRUE;
}
/* dummy function for binding to control-x prefix */
int cex(int f, int n)
{
return TRUE;
}
/* dummy function for binding to universal-argument */
int unarg(int f, int n)
{
return TRUE;
}

View File

@ -1,11 +1,9 @@
#include "names.h"
/* functions that can be bound to keys or procedure names */ /* functions that can be bound to keys or procedure names */
int quickexit( int f, int n) ; BINDABLE( quickexit) ;
int quit( int f, int n) ; BINDABLE( quit) ;
int ctlxlp( int f, int n) ; BINDABLE( ctlxlp) ;
int ctlxrp( int f, int n) ; BINDABLE( ctlxrp) ;
int ctlxe( int f, int n) ; BINDABLE( ctlxe) ;
int ctrlg( int f, int n) ; BINDABLE( ctrlg) ;
int nullproc( int f, int n) ;
int metafn( int f, int n) ;
int cex( int f, int n) ;
int unarg( int f, int n) ;

2
exec.c
View File

@ -511,7 +511,7 @@ int execproc( int f, int n) {
char *name ; char *name ;
/* find out what buffer the user wants to execute */ /* find out what buffer the user wants to execute */
status = newmlarg( &name, "Execute procedure: ", sizeof bufn - 2) ; status = newmlarg( &name, "execute-procedure: ", sizeof bufn - 2) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;

View File

@ -214,18 +214,16 @@ int execute( int c, int f, int n) {
/* if the keystroke is a bound function...do it */ /* if the keystroke is a bound function...do it */
key_tab *ktp = getkeybind( c) ; key_tab *ktp = getkeybind( c) ;
fnp_t execfunc = ktp->k_fp ; if( ktp->k_code != 0) {
if( execfunc != NULL) {
thisflag = 0 ; thisflag = 0 ;
if( ktp->k_nbp == NULL) assert( ktp->k_nbp != NULL) ;
ktp->k_nbp = getfncnb( execfunc) ;
assert( ktp->k_nbp->n_func == execfunc) ;
char tag = bind_tag( ktp->k_nbp) ; char tag = bind_tag( ktp->k_nbp) ;
if( (tag & 1) && (curbp->b_mode & MDVIEW)) if( (tag & 1) && (curbp->b_mode & MDVIEW))
status = rdonly() ; status = rdonly() ;
else else {
fnp_t execfunc = ktp->k_nbp->n_func ;
status = execfunc( f, n) ; status = execfunc( f, n) ;
}
lastflag = thisflag ; lastflag = thisflag ;
return status ; return status ;
@ -340,11 +338,12 @@ void kbd_loop( void) {
newc = getcmd() ; newc = getcmd() ;
update( FALSE) ; update( FALSE) ;
do { do {
key_tab *ktp ;
fnp_t execfunc ; fnp_t execfunc ;
if( c == newc if( c == newc
&& (execfunc = getkeybind( c)->k_fp) != NULL && (ktp = getkeybind( c))->k_code == c
&& execfunc != insert_newline && (execfunc = ktp->k_nbp->k_func) != insert_newline
&& execfunc != insert_tab) && execfunc != insert_tab)
newc = getcmd() ; newc = getcmd() ;
else else

2
file.c
View File

@ -134,7 +134,7 @@ int filefind( int f, int n) {
if( restflag) /* don't allow this command if restricted */ if( restflag) /* don't allow this command if restricted */
return resterr() ; return resterr() ;
status = newmlarg( &fname, "Find file: ", sizeof( fname_t)) ; status = newmlarg( &fname, "find-file: ", sizeof( fname_t)) ;
if( status == TRUE) { if( status == TRUE) {
status = getfile( fname, TRUE) ; status = getfile( fname, TRUE) ;
free( fname) ; free( fname) ;

11
input.c
View File

@ -157,17 +157,6 @@ int ectoc( int c) {
return c ; return c ;
} }
const name_bind *getfncnb( fnp_t func) {
const name_bind *nptr ; /* pointer into the name binding table */
/* skim through the table, looking for a match */
for( nptr = names ; nptr->n_func != NULL ; nptr++)
if (nptr->n_func == func)
break ;
return nptr ;
}
/* /*
* get a command name from the command line. Command completion means * get a command name from the command line. Command completion means
* that pressing a <SPACE> will attempt to complete an unfinished command * that pressing a <SPACE> will attempt to complete an unfinished command

19
input.h
View File

@ -10,16 +10,16 @@ typedef enum {
extern kbdstate kbdmode ; /* current keyboard macro mode */ extern kbdstate kbdmode ; /* current keyboard macro mode */
extern int lastkey ; /* last keystoke */ extern int lastkey ; /* last keystoke */
extern int kbdrep ; /* number of repetitions */ extern int kbdrep ; /* number of repetitions */
extern int kbdm[] ; /* Holds kayboard macro data */ extern int kbdm[] ; /* Holds kayboard macro data */
extern int *kbdptr ; /* current position in keyboard buf */ extern int *kbdptr ; /* current position in keyboard buf */
extern int *kbdend ; /* ptr to end of the keyboard */ extern int *kbdend ; /* ptr to end of the keyboard */
extern int metac; /* current meta character */ extern int metac ; /* current meta character */
extern int ctlxc; /* current control X prefix char */ extern int ctlxc ; /* current control X prefix char */
extern int reptc; /* current universal repeat char */ extern int reptc ; /* current universal repeat char */
extern int abortc; /* current abort command char */ extern int abortc ; /* current abort command char */
extern const int nlc ; /* end of input char */ extern const int nlc ; /* end of input char */
void ue_system( const char *cmd) ; void ue_system( const char *cmd) ;
@ -28,9 +28,8 @@ int newmlarg( char **outbufref, const char *prompt, int size) ;
int newmlargt( char **outbufref, const char *prompt, int size) ; int newmlargt( char **outbufref, const char *prompt, int size) ;
int ectoc( int c) ; int ectoc( int c) ;
/* Look up in names to function association table */ /* Get a command name from the command line or interactively */
const name_bind *getname( void) ; /* interactively */ const name_bind *getname( void) ;
const name_bind *getfncnb( fnp_t func) ; /* by function */
int tgetc( void) ; int tgetc( void) ;
int get1key( void) ; int get1key( void) ;

28
names.c
View File

@ -204,7 +204,7 @@ const name_bind names[] = {
{" reverse-incremental-search", risearch, CTLX | 'R'} , {" reverse-incremental-search", risearch, CTLX | 'R'} ,
#endif #endif
#if PROC #if PROC
{" run", execproc, 0} , {" run", execproc, 0} , // alias of execute-procedure
#endif #endif
{"!save-file", filesave, CTLX | CTL_ | 'S'} , /* also X^D */ {"!save-file", filesave, CTLX | CTL_ | 'S'} , /* also X^D */
{" save-window", savewnd, 0} , {" save-window", savewnd, 0} ,
@ -278,7 +278,7 @@ const name_bind names[] = {
static int lastidx = 0 ; static int lastidx = 0 ;
key_tab keytab[ NBINDS] = { key_tab keytab[ NBINDS] = {
{0, NULL, NULL} {0, NULL}
} ; } ;
@ -299,7 +299,6 @@ void init_bindings( void) {
/* Add key definition */ /* Add key definition */
if( nbp->n_keycode) { if( nbp->n_keycode) {
ktp->k_code = nbp->n_keycode ; ktp->k_code = nbp->n_keycode ;
ktp->k_fp = nbp->n_func ;
ktp->k_nbp = nbp ; ktp->k_nbp = nbp ;
ktp += 1 ; ktp += 1 ;
} }
@ -320,7 +319,6 @@ void init_bindings( void) {
for( fnbp = names ; fnbp->n_func != NULL ; fnbp++) for( fnbp = names ; fnbp->n_func != NULL ; fnbp++)
if( fnbp->n_func == nbp->n_func) { if( fnbp->n_func == nbp->n_func) {
ktp->k_code = nbp->n_keycode ; ktp->k_code = nbp->n_keycode ;
ktp->k_fp = nbp->n_func ;
ktp->k_nbp = fnbp ; ktp->k_nbp = fnbp ;
ktp += 1 ; ktp += 1 ;
break ; break ;
@ -340,7 +338,6 @@ void init_bindings( void) {
/* Mark position after last valid key entry */ /* Mark position after last valid key entry */
ktp->k_code = 0 ; ktp->k_code = 0 ;
ktp->k_fp = NULL ;
ktp->k_nbp = NULL ; ktp->k_nbp = NULL ;
} }
@ -374,4 +371,25 @@ const name_bind *fncmatch( char *name) {
#endif #endif
} }
/* user function that does NOTHING */
BINDABLE( nullproc) {
return TRUE ;
}
/* dummy function for binding to meta prefix */
BINDABLE( metafn) {
return TRUE ;
}
/* dummy function for binding to control-x prefix */
BINDABLE( cex) {
return TRUE ;
}
/* dummy function for binding to universal-argument */
BINDABLE( unarg) {
return TRUE ;
}
/* end of names.c */ /* end of names.c */

17
names.h
View File

@ -3,8 +3,10 @@
#ifndef _NAMES_H_ #ifndef _NAMES_H_
#define _NAMES_H_ #define _NAMES_H_
/* Generic uEMACS function pointer type */ /* Bindable uEMACS function pointer type and definition template */
typedef int (*fnp_t)( int, int) ; #define BINDABLE( fname) int fname( int f, int n)
typedef BINDABLE( (*fnp_t)) ;
/* Structure for the name binding table. */ /* Structure for the name binding table. */
@ -14,13 +16,12 @@ typedef struct {
unsigned n_keycode ; /* default key assignment, 0 when none */ unsigned n_keycode ; /* default key assignment, 0 when none */
} name_bind ; } name_bind ;
#define bind_name( p) (&(p)->n_name[ 1]) #define bind_name( p) (&( p)->n_name[ 1])
#define bind_tag( p) (p)->n_name[ 0] #define bind_tag( p) ( p)->n_name[ 0]
/* Structure for the key bindings table. */ /* Structure for the key bindings table. */
typedef struct { typedef struct {
unsigned k_code ; /* Key code */ unsigned k_code ; /* Key code */
fnp_t k_fp ; /* Routine to handle it */
const name_bind *k_nbp ; /* entry in name to function map table */ const name_bind *k_nbp ; /* entry in name to function map table */
} key_tab ; } key_tab ;
@ -35,6 +36,12 @@ extern key_tab keytab[ NBINDS] ; /* key bind to functions table */
void init_bindings( void) ; void init_bindings( void) ;
const name_bind *fncmatch( char *name) ; /* look up by name */ const name_bind *fncmatch( char *name) ; /* look up by name */
/* bindable functions mapped to prefix keys and hooks */
BINDABLE( nullproc) ;
BINDABLE( metafn) ;
BINDABLE( cex) ;
BINDABLE( unarg) ;
#endif #endif
/* end of names.h */ /* end of names.h */