home *** CD-ROM | disk | FTP | other *** search
-
- #include "file+rk.h"
- #include "functions.h"
- #include <stdio.h>
- #include <sys/ioctl.h>
- #include <ctype.h>
-
- #define MAXKEYLEN 19
- #define MAXTOKEN 30
- #define UPCASE(c) (islower(c)?toupper(c):c)
-
- #define UPCASE(c) (islower(c)?toupper(c):c)
- #define KEYWORDS (sizeof(functions)/sizeof(struct func))
- #define isodigit(c) ((isdigit(c))&&(c<'8'))
-
- FILE *filedesc;
- char *key_file;
-
- extern int (*keymap[128][MAXEXTENSIONS])();
- extern char meta_prefixes[MAXEXTENSIONS][MAXEXTENSIONS];
- extern int meta_map[MAXEXTENSIONS][MAXEXTENSIONS];
- extern char next_free_map;
- extern char tc_ent[1024], tc_seq_buf[1024];
- extern struct sgttyb new_stdin, old_stdin;
-
- char *tgetstr();
- struct func {
- char *name;
- int (*address)();
- char *description;
- } functions[]=
- {
- {"BOGUS",
- BOGUS,
- "Null routine, beeps terminal bell"},
-
- {"accept_forward_char",
- accept_forward_char,
- "Accept the next predicted character"},
-
- {"accept_forward_word",
- accept_forward_word,
- "Accept the next predicted word"},
-
- {"accept_to_end_of_line",
- accept_to_end_of_line,
- "Accept the whole predicted line"},
-
- {"backspace_char",
- backspace_char,
- "Backspace a single character"},
-
- {"backspace_word",
- backspace_word,
- "Backspace a single word"},
-
- {"backward_char",
- backward_char,
- "Go backwards a single character"},
-
- {"backward_paren",
- backward_paren,
- "Go backwards to matching parenthesis \"(\""},
-
- {"backward_word",
- backward_word,
- "Go backwards a single word"},
-
- {"beginning_of_line",
- beginning_of_line,
- "Move to the beginning of the line"},
-
- {"bogus",
- BOGUS,
- "Null routine, beeps terminal bell"},
-
- {"capitalize_word",
- capitalize_word,
- "Capitalize this word"},
-
- {"clear_display",
- clear_display,
- "Clear the screen and redraw the line"},
-
- {"close_paren",
- close_paren,
- "Close and show matching parenthesis"},
-
- {"command_completion",
- command_completion,
- "Expand a command using $PATH"},
-
- {"dash_to_ul_word",
- dash_to_ul_word,
- "Convert -'s to _'s in this word"},
-
- {"delete_char",
- delete_char,
- "Delete a single character"},
-
- {"delete_region_to_killbuffer",
- delete_region_to_killbuffer,
- "Delete marked region to killbuffer"},
-
- {"delete_word",
- delete_word,
- "Delete a single word"},
-
- {"describe_arguments",
- describe_arguments,
- "Show the current command line arguments"},
-
- {"describe_bindings",
- describe_bindings,
- "Show the current key bindings"},
-
- {"discard_current_edit_line",
- discard_current_edit_line,
- "Delete this line and forget it"},
-
- {"discard_rest_of_line",
- discard_rest_of_line,
- "Delete rest of line to killbuffer"},
-
- {"end_of_line",
- end_of_line,
- "Move to the end of the line"},
-
- {"file_completion",
- file_completion,
- "Expand pathname from the current prefix"},
-
- {"finish_editing_line",
- finish_editing_line,
- "Enter this line"},
-
- {"forward_char",
- forward_char,
- "Go forward a single character"},
-
- {"forward_paren",
- forward_paren,
- "Move to matching close parenthesis \")\""},
-
- {"forward_word",
- forward_word,
- "Go forward a single word"},
-
- {"increment_universal_argument",
- increment_universal_argument,
- "Do the next command 4^(presses) times"},
-
- {"insert_interrupt_char",
- insert_interrupt_char,
- "Send an interrupt character"},
-
- {"insert_quit_char",
- insert_quit_char,
- "Send a quit character"},
-
- {"insert_start_char",
- insert_start_char,
- "Send a start character"},
-
- {"insert_stop_char",
- insert_stop_char,
- "Send a stop character"},
-
- {"insert_suspend_char",
- insert_suspend_char,
- "Send a suspend character"},
-
- {"lowercase_word",
- lowercase_word,
- "Lowercase this word"},
-
- {"next_line",
- next_line,
- "Show the next line buffer"},
-
- {"next_pred",
- next_pred,
- "Show next alternative prediction"},
-
- {"null",
- BOGUS,
- "Null routine, beeps terminal bell"},
-
- {"open_paren",
- open_paren,
- "Open and show matching parenthesis"},
-
- {"previous_line",
- previous_line,
- "Show the previous line buffer"},
-
- {"previous_pred",
- previous_pred,
- "Show the previous alternative prediction"},
-
- {"prime_from_file",
- prime_from_file,
- "Prime the predictions from a file"},
-
- {"quote_char",
- quote_char,
- "Literally insert the next character"},
-
- {"run_mesg",
- run_mesg,
- "Run the mesg command"},
-
- {"run_ruptime",
- run_ruptime,
- "Run the ruptime command"},
-
- {"run_talk",
- run_talk,
- "Run the talk command"},
-
- {"run_tty_program",
- run_tty_program,
- "Run a program with rk turned off"},
-
- {"run_write",
- run_write,
- "Run the write command"},
-
- {"self_insert",
- self_insert,
- "Literally insert the current character"},
-
- {"set_mark",
- set_mark,
- "Set mark at the current cursor position"},
-
- {"show_free_nodes",
- show_free_nodes,
- "Show memory usage info for debugging"},
-
- {"show_mark",
- show_mark,
- "Show the position of the current mark"},
-
- {"show_version",
- show_version,
- "Show the current version number and date"},
-
- {"toggle_add_space_mode",
- toggle_add_space_mode,
- "Toggle add_space_mode (see manual)"},
-
- {"toggle_eol_longer_mode",
- toggle_eol_longer_mode,
- "Toggle eol_longer_mode (see manual)"},
-
- {"toggle_eol_only_mode",
- toggle_eol_only_mode,
- "Toggle eol_only_mode (see manual)"},
-
- {"toggle_lisp_mode",
- toggle_lisp_mode,
- "Toggle lisp_mode (see manual)"},
-
- {"toggle_nl_truncate_mode",
- toggle_nl_truncate_mode,
- "Toggle nl_truncate_mode (see manual)"},
-
- {"toggle_pred_mode",
- toggle_pred_mode,
- "Turn prediction display off or on"},
-
- {"toggle_show_eol_mode",
- toggle_show_eol_mode,
- "Toggle display of ^J at end of line"},
-
- {"twiddle_chars",
- twiddle_chars,
- "Exchange previous two characters"},
-
- {"ul_to_dash_word",
- ul_to_dash_word,
- "Convert _'s to -'s in this word"},
-
- {"uppercase_word",
- uppercase_word,
- "Uppercase this word"},
-
- {"yank_from_kill_buffer",
- yank_from_kill_buffer,
- "Insert text stored in killbuffer"}
- };
-
-
- struct list {
- char *key;
- struct list *next;
- } *bindings[sizeof(functions)/sizeof(struct func)];
-
-
-
- /***********************************\
- * *
- * binary search from K&R "C" book *
- * *
- \***********************************/
-
- bsearch(s)
- char *s;
- {
- int low, high, mid, cond;
- low=0;
- high= KEYWORDS-1;
- while( low<= high) {
- mid = (low+high)/2;
- if( (cond = strcmp(s,functions[mid].name)) < 0)
- high=mid-1;
- else if (cond>0)
- low=mid+1;
- else
- return(mid);
- }
- return(-1);
- }
-
- parse_command()
- {
- int x=1;
- int number;
- char c;
- char token[MAXTOKEN];
-
-
- while(isspace(c=fgetc(filedesc)));
-
- token[0]=c;
-
- while((isalpha(c=fgetc(filedesc)) || (c=='_'))&& (x<=MAXTOKEN))
- token[x++]=c;
-
- token[x]=0;
- if (c==EOF) return(-1);
-
- if ((!isspace(c)) && (c!=EOF)){
- printf("Unexpected character '%c', Expecting whitespace or EOF.\n",c);
- return(-1);
- }
- if(x>MAXTOKEN){
- printf("Function name too long: '%s'\n",token);
- return(-1);
- }
- number=bsearch(token);
- if(number==-1)
- printf("Function not found: %s\n",token);
- return(number);
- }
-
-
- char get_cntl()
- {
- int c=fgetc(filedesc);
-
- if(c==' ') return(200); /* Can't use 0 */
- else if(c==EOF){
- printf("Unexpected EOF\n");
- return(200);
- }else return(UPCASE(c)-'@');
- }
-
- char parse_cntl(key)
- char key;
- {
- if(key==0) abortit("Invalid ^ in key binding.\n",-1);
- if(key==' ') return(0);
- else return(UPCASE(key)-'@');
- }
-
-
- char get_slash()
- {
-
- int c=fgetc(filedesc);
- int code=0;
-
- if(isodigit(c)){
- while(isodigit(c)){
- if((256-(c-='0'))<code){
- printf("Character Overflow\n");
- return(code);
- }
- code=(code<<3)+c;
- c=fgetc(filedesc);
- }
- ungetc(c,filedesc);
- return((char)code);
- }
- else if(c=='E')
- return(27);
- else if(c=='n')
- return('\n');
- else if(c=='r')
- return('\r');
- else if(c=='t')
- return('\t');
- else if(c=='b')
- return('\b');
- else if(c=='f')
- return('\f');
- else return(c);
- }
-
- char parse_slash(key)
- char **key;
- {
-
- int c=(*key)[0];
- int code=0;
-
- (*key)++;
- if(c==0) abortit("Invalid \\ in key binding.\n",-1);
-
- if(isodigit(c)){
- while(isodigit(c)){
- if((256-(c-='0'))<code){
- printf("Character Overflow\n");
- return(code);
- }
- code=(code<<3)+c;
- c=(*key)[0];
- (*key)++;
- }
- (*key)--;
- return((char)code);
- }
- else if(c=='E')
- return(27);
- else if(c=='n')
- return('\n');
- else if(c=='r')
- return('\r');
- else if(c=='t')
- return('\t');
- else if(c=='b')
- return('\b');
- else if(c=='f')
- return('\f');
- else return(c);
- }
-
-
- char *parse_key(key)
- char *key;
- {
- static char ret_key[20];
- int x=0;
- int retval;
- char c;
-
- while(((c=key[0])!='\0') && (x<=MAXKEYLEN)){
- if(c=='\\'){
- key++;
- ret_key[x++]=parse_slash(&key);
- }
- else if(c=='^'){
- ret_key[x++]=parse_cntl(key[1]);
- key+=2;
- }
- else{
- ret_key[x++]=c;
- key++;
- }
- }
- ret_key[x]=0;
-
- if(x>MAXKEYLEN){
- printf("Key too long.\n");
- return((char *)-1);
- }
- return(ret_key);
- }
-
- char *parse_termcap_key(key)
- char *key;
- {
- char *term_key;
- char term_cap[3];
- char *key_ptr;
-
-
- term_key = tc_seq_buf;
- key_ptr=tgetstr(key,&term_key);
- if(!key_ptr){
- printf("Unavailable Terminal Capability: %s\n",term_cap);
- return((char *) -1);
- }else
- return(key_ptr);
- }
-
- char *get_key(buffer)
- char *buffer;
- {
- static char key[20];
- char *term_key;
- char *key_ptr;
- char term_cap[3];
- int x=0;
- int c;
- int retval;
-
- while(isspace(c=fgetc(filedesc)));
- if (c!='"'){
- term_cap[0]=c;
- term_cap[1]=fgetc(filedesc);
- term_cap[2]=0;
- term_key = tc_seq_buf;
- key_ptr=tgetstr(term_cap,&term_key);
- if(!key_ptr){
- printf("Unavailable Terminal Capability: %s\n",term_cap);
- return((char *) -1);
- }
- else{
- strcpy(buffer,term_cap);
- return(key_ptr);
- }
- }
-
- while(((c=fgetc(filedesc))!='\"') && (c!=EOF)
- && (x<=MAXKEYLEN)){
- if(c=='\\') key[x++]=get_slash();
- else if(c=='^') key[x++]=get_cntl();
- else key[x++]=c;
- }
- key[x]=0;
-
- if(x>MAXKEYLEN){
- printf("Key too long.\n");
- return((char *)-1);
- }
- strcpy(buffer,key);
- return(key);
- }
-
- /***************************************************************************\
- * *
- * Find the length of a string but count control chars as two so the length *
- * of something like ^C is right *
- * *
- \***************************************************************************/
- Strlen(str)
- char *str;
- {
- register int len=0;
- while(*str){
- if((*str<32) || (*str==127))
- len++;
- len++;
- str++;
- }
- return(len);
- }
- /*****************************************************************\
- * *
- * Copy from b to a but replace control chars with ^-char like ^C *
- * *
- \*****************************************************************/
- Strcpy(a,b)
- char *a,*b;
- {
- while(*b){
- if((*b<32) || (*b==127)){
- *a++='^';
- *a++=(*b==127)?b++,'?':(*b++)+'@';
- }
- *a++ = *b++;
- }
- *a=0;
- }
-
-
- add_to_bindings(key,function)
- char *key;
- int (*function)();
- {
- int x,found_it=0;
- struct list *current,*previous;
- char good_key[30];
- Strcpy(good_key,key);
-
- for(x=0;x<sizeof(functions)/sizeof(struct func);x++){
- current=bindings[x];
- while(bindings[x]&&!strcmp(bindings[x]->key,good_key)){
- current=bindings[x]->next;
- free(bindings[x]);
- bindings[x]=current;
- }
- while(current!=0){
- if(!strcmp(current->key,good_key)){
- previous->next=current->next;
- free(current);
- }
- previous=current;
- current=current->next;
- }
-
- }
- for(x=0;x<sizeof(functions)/sizeof(struct func);x++){
- if(function==functions[x].address){
- found_it=1;
- break;
- }
- }
- if(found_it){
- if(bindings[x]==0){
- bindings[x]=(struct list *)malloc(sizeof(struct list));
- bindings[x]->key=malloc(Strlen(key)+1);
- Strcpy(bindings[x]->key,key);
- bindings[x]->next=0;
- } else {
- current=bindings[x];
- while(current->next != 0)
- current=current->next;
- current->next=(struct list *)malloc(sizeof(struct list));
- current->next->key=malloc(Strlen(key)+1);
- Strcpy(current->next->key,key);
- current->next->next=0;
- }
- }
- }
-
-
-
- bind_to_key(key,function)
- char *key;
- int (*function)();
- {
- char *binary_key;
-
- binary_key=parse_key(key);
- if(binary_key!=(char *)-1){
- add_to_bindings(key,function);
- do_bind_to_key(binary_key,0,function);
- }
- }
-
- bind_termcap_key(key,function)
- char *key;
- int (*function)();
- {
- char *binary_key;
-
- binary_key=parse_termcap_key(key);
- if(binary_key!=(char *)-1){
- add_to_bindings(key,function);
- do_bind_to_key(binary_key,0,function);
- }
- }
-
- do_bind_to_key(key,current_key_map,function)
- char *key;
- char current_key_map;
- int (*function)();
- {
- int x;
-
-
- if((strlen(key)==1) || (strlen(key)==0)){
- keymap[key[0]][current_key_map]=function;
- } else {
- for(x=0;(x<MAXEXTENSIONS)&&(meta_prefixes[x][current_key_map])&&
- (key[0]!=meta_prefixes[x][current_key_map]);x++);
- if(x==MAXEXTENSIONS){
- abortit("Too many keymaps, aborting.\r\n",-1);
- }else if(meta_prefixes[x][current_key_map]){
- do_bind_to_key(key+1,meta_map[x][current_key_map],function);
- }else {
- meta_prefixes[x][current_key_map]=key[0];
- meta_map[x][current_key_map]=next_free_map;
- keymap[key[0]][current_key_map]=meta_prefix;
- next_free_map++;
- do_bind_to_key(key+1,next_free_map-1,function);
- if(next_free_map==MAXEXTENSIONS)
- abortit("Too many keymaps, aborting.\r\n",-1);
- }
- }
- }
-
-
- get_key_bindings()
- {
-
- char *termname, *tbuf, *getenv();
- int function_num;
- char *key;
- char key_string[30];
- int x;
-
- if ((filedesc=fopen(key_file,"r"))==0){
- return;
- }
-
- do{
- function_num=parse_command();
- if(function_num==-1)
- break;
- key=get_key(key_string);
- if(key==(char *)-1)
- break;
- add_to_bindings(key_string,functions[function_num].address);
- do_bind_to_key(key,0,functions[function_num].address);
- } while(1);
- fclose(filedesc);
- }
-
- int
- describe_bindings(e)
- ED_STRUCT *e;
- {
- void (*sig)();
- char reply;
- char fname[100];
-
- printf("\r\nSend to a file? (y/n)");
- if((reply=getchar())=='Y' || reply == 'y'){
- ioctl(0, TIOCGETP, &new_stdin);
- ioctl(0, TIOCSETP, &old_stdin);
- sig=signal(SIGCHLD,SIG_DFL);
- printf("\nFilename: ");
- gets(fname);
- show_bindings(fname);
- }else{
- ioctl(0, TIOCGETP, &new_stdin);
- ioctl(0, TIOCSETP, &old_stdin);
- sig=signal(SIGCHLD,SIG_DFL);
- fname[0]=0;
- show_bindings(0);
- }
- signal(SIGCHLD,sig);
- ioctl(0, TIOCSETP, &new_stdin);
- write(1, "Continue: ", 10);
- draw_current_edit_line(e);
- }
-
-
- show_bindings(fname)
- char *fname;
- {
- int x;
- struct list *current;
- char *more;
- FILE *pipe;
-
- if(!fname)
- if((more=getenv("PAGER"))==0){
- if((pipe=popen("more","w"))==0){
- perror("more");
- return;
- }
- } else {
- if((pipe=popen(more,"w"))==0){
- perror(more);
- return;
- }
- }
- else
- if((pipe=fopen(fname,"w"))==0){
- perror(fname);
- return;
- }
-
-
-
- fprintf(pipe,"\n FUNCTION NAME BOUND TO \tDESCRIPTION\n");
- fprintf(pipe," -------- ---- ----- -- \t-----------\n");
-
- for(x=0;x<(sizeof(functions)/sizeof(struct func));x++){
- if((functions[x].address==BOGUS)
- || (functions[x].address==self_insert))
- continue;
- fprintf(pipe,"%28s",functions[x].name);
- current=bindings[x];
- if(current!=0){
- fprintf(pipe,"%6s\t",current->key);
- current=current->next;
- } else {
- fprintf(pipe," \t");
- }
- fprintf(pipe,"%s",functions[x].description);
- while(current!=0){
- fprintf(pipe,"\n%34s",current->key);
- current=current->next;
- }
- fprintf(pipe,"\n");
- }
- pclose(pipe);
- }
-
-
-