Annotation of OpenXM_contrib/pari-2.2/src/gp/gp_rl.c, Revision 1.1
1.1 ! noro 1: /* $Id: gp_rl.c,v 1.11 2001/09/27 09:47:51 karim Exp $
! 2:
! 3: Copyright (C) 2000 The PARI group.
! 4:
! 5: This file is part of the PARI/GP package.
! 6:
! 7: PARI/GP is free software; you can redistribute it and/or modify it under the
! 8: terms of the GNU General Public License as published by the Free Software
! 9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
! 10: ANY WARRANTY WHATSOEVER.
! 11:
! 12: Check the License for details. You should have received a copy of it, along
! 13: with the package; see the file 'COPYING'. If not, write to the Free Software
! 14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
! 15:
! 16: /*******************************************************************/
! 17: /* */
! 18: /* INTERFACE TO READLINE COMPLETION */
! 19: /* */
! 20: /*******************************************************************/
! 21: #include "pari.h"
! 22: #include "../language/anal.h"
! 23: #include "gp.h"
! 24:
! 25: #ifdef READLINE
! 26: typedef char** (*CF)(char*, char* (*)()); /* completion function */
! 27: typedef char* (*GF)(char*, int); /* generator function */
! 28: typedef int (*RLCI)(int, int); /* rl_complete and rl_insert functions */
! 29:
! 30: BEGINEXTERN
! 31: #ifdef HAS_RL_MESSAGE
! 32: # define USE_VARARGS
! 33: # define PREFER_STDARG
! 34: #endif
! 35: #ifdef READLINE_LIBRARY
! 36: # include <readline.h>
! 37: #else
! 38: # include <readline/readline.h>
! 39: #endif
! 40: #ifndef HAS_RL_MESSAGE
! 41: extern int rl_message (const char *, ...);
! 42: extern int rl_clear_message();
! 43: extern int rl_begin_undo_group(), rl_end_undo_group();
! 44: extern int rl_read_key();
! 45: extern int rl_stuff_char();
! 46: extern char *filename_completion_function(char *text,int state);
! 47: extern char *username_completion_function(char *text,int state);
! 48: #endif
! 49: char **pari_completion(char *text, int start, int end);
! 50: extern int rl_completion_query_items;
! 51: extern int rl_bind_key_in_map();
! 52: ENDEXTERN
! 53:
! 54: void print_fun_list(char **matches, int nbli);
! 55: void aide(char *s, int flag);
! 56:
! 57: extern default_type gp_default_list[];
! 58: extern char *keyword_list[];
! 59: static int add_help_keywords;
! 60: static entree *current_ep = NULL;
! 61:
! 62: static int pari_rl_back;
! 63: extern RLCI rl_last_func;
! 64: static int do_args_complete = 1;
! 65: static int do_matched_insert = 0;
! 66: static int did_init_matched = 0;
! 67:
! 68: #ifdef HAS_RL_SAVE_PROMPT
! 69: # define SAVE_PROMPT() rl_save_prompt()
! 70: # define RESTORE_PROMPT() rl_restore_prompt()
! 71: #else
! 72: # ifdef HAS_UNDERSCORE_RL_SAVE_PROMPT
! 73: # define SAVE_PROMPT() _rl_save_prompt()
! 74: # define RESTORE_PROMPT() _rl_restore_prompt()
! 75: # else
! 76: # define SAVE_PROMPT()
! 77: # define RESTORE_PROMPT()
! 78: # endif
! 79: #endif
! 80:
! 81: #ifdef HAS_RL_COMPLETION_MATCHES
! 82: # define COMPLETION_MATCHES ((CF)rl_completion_matches)
! 83: # define FILE_COMPLETION ((GF)rl_filename_completion_function)
! 84: # define USER_COMPLETION ((GF)rl_username_completion_function)
! 85: #else
! 86: # define COMPLETION_MATCHES ((CF)completion_matches)
! 87: # define FILE_COMPLETION ((GF)filename_completion_function)
! 88: # define USER_COMPLETION ((GF)username_completion_function)
! 89: #endif
! 90:
! 91: #define ELECTRIC_PAREN 1
! 92: #define ARGS_COMPLETE 2
! 93: static int
! 94: change_state(char *msg, int *opt, int count)
! 95: {
! 96: int c;
! 97:
! 98: switch(count)
! 99: {
! 100: default: c = 0; break; /* off */
! 101: case -1: c = 1; break; /* on */
! 102: case -2: c = 1 - *opt; /* toggle */
! 103: }
! 104: *opt = c;
! 105: SAVE_PROMPT();
! 106: rl_message("%s: %s.", (long)msg, (long)(c? "on": "off"));
! 107: c = rl_read_key();
! 108: RESTORE_PROMPT();
! 109: rl_clear_message();
! 110: rl_stuff_char(c); return 1;
! 111: }
! 112:
! 113: /* Wrapper around rl_complete to allow toggling insertion of arguments */
! 114: static int
! 115: pari_rl_complete(int count, int key)
! 116: {
! 117: int ret;
! 118:
! 119: pari_rl_back = 0;
! 120: if (count <= 0)
! 121: return change_state("complete args", &do_args_complete, count);
! 122:
! 123: rl_begin_undo_group();
! 124: if (rl_last_func == pari_rl_complete)
! 125: rl_last_func = (RLCI) rl_complete; /* Make repeated TABs different */
! 126: ret = ((RLCI)rl_complete)(count,key);
! 127: if (pari_rl_back && (pari_rl_back <= rl_point))
! 128: rl_point -= pari_rl_back;
! 129: rl_end_undo_group(); return ret;
! 130: }
! 131:
! 132: static const char paropen[] = "([{";
! 133: static const char parclose[] = ")]}";
! 134:
! 135: /* To allow insertion of () with a point in between. */
! 136: static int
! 137: pari_rl_matched_insert(int count, int key)
! 138: {
! 139: int i = 0, ret;
! 140:
! 141: if (count <= 0)
! 142: return change_state("electric parens", &do_matched_insert, count);
! 143: while (paropen[i] && paropen[i] != key) i++;
! 144: if (!paropen[i] || !do_matched_insert || under_emacs)
! 145: return ((RLCI)rl_insert)(count,key);
! 146: rl_begin_undo_group();
! 147: ((RLCI)rl_insert)(count,key);
! 148: ret = ((RLCI)rl_insert)(count,parclose[i]);
! 149: rl_point -= count;
! 150: rl_end_undo_group(); return ret;
! 151: }
! 152:
! 153: static int
! 154: pari_rl_default_matched_insert(int count, int key)
! 155: {
! 156: if (!did_init_matched) {
! 157: did_init_matched = 1;
! 158: do_matched_insert = 1;
! 159: }
! 160: return pari_rl_matched_insert(count, key);
! 161: }
! 162:
! 163: static int
! 164: pari_rl_forward_sexp(int count, int key)
! 165: {
! 166: int deep = 0, dir = 1, move_point = 0, lfail;
! 167:
! 168: (void)key;
! 169: if (count < 0)
! 170: {
! 171: count = -count; dir = -1;
! 172: if (!rl_point) goto fail;
! 173: rl_point--;
! 174: }
! 175: while (count || deep)
! 176: {
! 177: move_point = 1; /* Need to move point if moving left. */
! 178: lfail = 0; /* Do not need to fail left movement yet. */
! 179: while ( !is_keyword_char(rl_line_buffer[rl_point])
! 180: && !strchr("\"([{}])",rl_line_buffer[rl_point])
! 181: && !( (dir == 1)
! 182: ? (rl_point >= rl_end)
! 183: : (rl_point <= 0 && (lfail = 1))))
! 184: rl_point += dir;
! 185: if (lfail || !rl_line_buffer[rl_point]) goto fail;
! 186:
! 187: if (is_keyword_char(rl_line_buffer[rl_point]))
! 188: {
! 189: while ( is_keyword_char(rl_line_buffer[rl_point])
! 190: && (!((dir == 1) ? (rl_point >= rl_end) : (rl_point <= 0))
! 191: || (move_point = 0)))
! 192: rl_point += dir;
! 193: if (!deep) count--;
! 194: }
! 195: else if (strchr(paropen,rl_line_buffer[rl_point]))
! 196: {
! 197: if (deep == 0 && dir == -1) goto fail; /* We are already out of pars. */
! 198: rl_point += dir;
! 199: deep++; if (!deep) count--;
! 200: }
! 201: else if (strchr(parclose,rl_line_buffer[rl_point]))
! 202: {
! 203: if (deep == 0 && dir == 1)
! 204: {
! 205: rl_point++; goto fail; /* Get out of pars. */
! 206: }
! 207: rl_point += dir;
! 208: deep--; if (!deep) count--;
! 209: }
! 210: else if (rl_line_buffer[rl_point] == '\"')
! 211: {
! 212: int bad = 1;
! 213:
! 214: rl_point += dir;
! 215: while ( ((rl_line_buffer[rl_point] != '\"') || (bad = 0))
! 216: && (!((dir == 1) ? (rl_point >= rl_end) : (rl_point <= 0))
! 217: || (move_point = 0)) )
! 218: rl_point += dir;
! 219: if (bad) goto fail;
! 220: rl_point += dir; /* Skip the other delimiter */
! 221: if (!deep) count--;
! 222: }
! 223: else
! 224: {
! 225: fail: ding(); return 1;
! 226: }
! 227: }
! 228: if (dir != 1 && move_point) rl_point++;
! 229: return 1;
! 230: }
! 231:
! 232: static int
! 233: pari_rl_backward_sexp(int count, int key)
! 234: {
! 235: return pari_rl_forward_sexp(-count, key);
! 236: }
! 237:
! 238: /* do we add () at the end of completed word? (is it a function?) */
! 239: static int
! 240: add_paren(int end)
! 241: {
! 242: entree *ep;
! 243: char *s;
! 244:
! 245: if (end < 0 || rl_line_buffer[end] == '(')
! 246: return 0; /* not from command_generator or already there */
! 247: ep = do_alias(current_ep); /* current_ep set in command_generator */
! 248: if (EpVALENCE(ep) < EpUSER)
! 249: { /* is it a constant masked as a function (e.g Pi)? */
! 250: s = ep->help; if (!s) return 1;
! 251: while (is_keyword_char(*s)) s++;
! 252: return (*s != '=');
! 253: }
! 254: switch(EpVALENCE(ep))
! 255: {
! 256: case EpUSER:
! 257: case EpINSTALL: return 1;
! 258: }
! 259: return 0;
! 260: }
! 261:
! 262: static void
! 263: match_concat(char **matches, char *s)
! 264: {
! 265: int i = strlen(matches[0]) + 1;
! 266: matches[0] = (char*) gprealloc(matches[0], i+strlen(s), i);
! 267: strcat(matches[0],s);
! 268: }
! 269:
! 270: static char **
! 271: matches_for_emacs(char *text, char **matches)
! 272: {
! 273: if (!matches) printf("@");
! 274: else
! 275: {
! 276: int i;
! 277: printf("%s@", matches[0] + strlen(text));
! 278: if (matches[1]) print_fun_list(matches+1,0);
! 279:
! 280: /* we don't want readline to do anything, but insert some junk
! 281: * which will be erased by emacs.
! 282: */
! 283: for (i=0; matches[i]; i++) free(matches[i]);
! 284: free(matches);
! 285: }
! 286: matches = (char **) gpmalloc(2*sizeof(char *));
! 287: matches[0] = gpmalloc(2); sprintf(matches[0],"_");
! 288: matches[1] = NULL; printf("@E_N_D"); pariflush();
! 289: return matches;
! 290: }
! 291:
! 292: #define add_comma(x) (x==-2) /* from default_generator */
! 293:
! 294: /* Attempt to complete on the contents of TEXT. END points to the end of the
! 295: * word to complete. Return the array of matches, or NULL if there aren't any.
! 296: */
! 297: static char **
! 298: get_matches(int end, char *text, char* f(char*,int))
! 299: {
! 300: char **matches;
! 301:
! 302: #ifdef HAS_COMPLETION_APPEND_CHAR
! 303: rl_completion_append_character = ' ';
! 304: #endif
! 305: current_ep = NULL;
! 306: matches = COMPLETION_MATCHES(text, (char *(*)())f);
! 307: if (matches && !matches[1]) /* a single match */
! 308: {
! 309: if (add_paren(end))
! 310: {
! 311: match_concat(matches,"()");
! 312: pari_rl_back = 1;
! 313: if (rl_point == rl_end)
! 314: #ifdef HAS_COMPLETION_APPEND_CHAR
! 315: rl_completion_append_character = '\0'; /* Do not append space. */
! 316: #else
! 317: pari_rl_back = 2;
! 318: #endif
! 319: }
! 320: else if (add_comma(end))
! 321: match_concat(matches,",");
! 322: }
! 323: if (under_emacs) matches = matches_for_emacs(text,matches);
! 324: return matches;
! 325: }
! 326: #undef add_comma
! 327:
! 328: static char *
! 329: add_junk(char *name, char *text, long junk)
! 330: {
! 331: char *s = strncpy((char*) gpmalloc(strlen(name)+1+junk),text,junk);
! 332: strcpy(s+junk,name); return s;
! 333: }
! 334:
! 335: /* Generator function for command completion. STATE lets us know whether
! 336: * to start from scratch; without any state (i.e. STATE == 0), then we
! 337: * start at the top of the list.
! 338: */
! 339: static char *
! 340: hashtable_generator (char *text, int state, entree **hash)
! 341: {
! 342: static int hashpos, len, junk, n;
! 343: static entree* ep;
! 344: static char *TEXT;
! 345:
! 346: /* If this is a new word to complete, initialize now:
! 347: * + indexes hashpos (GP hash list) and n (keywords specific to long help).
! 348: * + file completion and keyword completion use different word boundaries,
! 349: * have TEXT point to the keyword start.
! 350: * + save the length of TEXT for efficiency.
! 351: */
! 352: if (!state)
! 353: {
! 354: n = hashpos = 0; ep=hash[hashpos];
! 355: len=strlen(text); junk=len-1;
! 356: while (junk >= 0 && is_keyword_char(text[junk])) junk--;
! 357: junk++; len -= junk; TEXT = text + junk;
! 358: }
! 359:
! 360: /* First check the keywords list */
! 361: if (add_help_keywords)
! 362: {
! 363: for ( ; keyword_list[n]; n++)
! 364: if (!strncmp(keyword_list[n],TEXT,len))
! 365: {
! 366: text = add_junk(keyword_list[n],text,junk);
! 367: n++; return text;
! 368: }
! 369: }
! 370:
! 371: /* Return the next name which partially matches from the command list. */
! 372: for(;;)
! 373: if (!ep)
! 374: {
! 375: if (++hashpos >= functions_tblsz) return NULL; /* no names matched */
! 376: ep = hash[hashpos];
! 377: }
! 378: else if (strncmp(ep->name,TEXT,len))
! 379: ep = ep->next;
! 380: else
! 381: break;
! 382: current_ep = ep;
! 383: text = add_junk(ep->name,text,junk);
! 384: ep=ep->next; return text;
! 385: }
! 386:
! 387: static char *
! 388: command_generator (char *text, int state)
! 389: {
! 390: return hashtable_generator(text,state, functions_hash);
! 391: }
! 392: static char *
! 393: member_generator (char *text, int state)
! 394: {
! 395: return hashtable_generator(text,state, members_hash);
! 396: }
! 397:
! 398: #define DFLT 0
! 399: #define ENTREE 1
! 400:
! 401: static char *
! 402: generator(void *list, char *text, int *nn, int len, int typ)
! 403: {
! 404: char *def = NULL, *name;
! 405: int n = *nn;
! 406:
! 407: /* Return the next name which partially matches from list.*/
! 408: switch(typ)
! 409: {
! 410: case DFLT :
! 411: do
! 412: def = (((default_type *) list)[n++]).name;
! 413: while (def && strncmp(def,text,len));
! 414: break;
! 415:
! 416: case ENTREE :
! 417: do
! 418: def = (((entree *) list)[n++]).name;
! 419: while (def && strncmp(def,text,len));
! 420: }
! 421:
! 422: *nn = n;
! 423: if (def)
! 424: {
! 425: name = strcpy((char*) gpmalloc(strlen(def)+1), def);
! 426: return name;
! 427: }
! 428: return NULL; /* no names matched */
! 429: }
! 430:
! 431: static char *
! 432: old_generator(char *text,int state)
! 433: {
! 434: static int n,len;
! 435: static char *res;
! 436:
! 437: if (!state) { res = "a"; n=0; len=strlen(text); }
! 438: if (res)
! 439: {
! 440: res = generator((void *)oldfonctions,text,&n,len,ENTREE);
! 441: if (res) return res;
! 442: n=0;
! 443: }
! 444: return generator((void *)functions_oldgp,text,&n,len,ENTREE);
! 445: }
! 446:
! 447: static char *
! 448: default_generator(char *text,int state)
! 449: {
! 450: static int n,len;
! 451:
! 452: if (!state) { n=0; len=strlen(text); }
! 453: return generator(gp_default_list,text,&n,len,DFLT);
! 454: }
! 455:
! 456: static void
! 457: rl_print_aide(char *s, int flag)
! 458: {
! 459: int p = rl_point, e = rl_end;
! 460: FILE *save = pari_outfile;
! 461:
! 462: rl_point = 0; rl_end = 0; pari_outfile = rl_outstream;
! 463: SAVE_PROMPT();
! 464: rl_message("",0,0);
! 465: aide(s, flag);
! 466: RESTORE_PROMPT();
! 467: rl_point = p; rl_end = e; pari_outfile = save;
! 468: rl_clear_message();
! 469: #ifdef RL_REFRESH_LINE_OLDPROTO
! 470: rl_refresh_line();
! 471: #else
! 472: rl_refresh_line(0,0);
! 473: #endif
! 474: }
! 475:
! 476: char **
! 477: pari_completion(char *text, int START, int END)
! 478: {
! 479: int i, first=0, start=START;
! 480:
! 481: /* If the line does not begin by a backslash, then it is:
! 482: * . an old command ( if preceded by "whatnow(" ).
! 483: * . a default ( if preceded by "default(" ).
! 484: * . a member function ( if preceded by "." within 4 letters )
! 485: * . a file name (in current directory) ( if preceded by "read(" )
! 486: * . a command
! 487: */
! 488: if (start >=1 && rl_line_buffer[start] != '~') start--;
! 489: while (start && is_keyword_char(rl_line_buffer[start])) start--;
! 490: if (rl_line_buffer[start] == '~')
! 491: {
! 492: for(i=start+1;i<=END;i++)
! 493: if (rl_line_buffer[i] == '/')
! 494: return get_matches(-1,text,FILE_COMPLETION);
! 495: return get_matches(-1,text,USER_COMPLETION);
! 496: }
! 497:
! 498: while (rl_line_buffer[first] && isspace((int)rl_line_buffer[first])) first++;
! 499: switch (rl_line_buffer[first])
! 500: {
! 501: case '\\':
! 502: if (first == start) text = rl_line_buffer+start+2;
! 503: return get_matches(-1,text,FILE_COMPLETION);
! 504: case '?':
! 505: if (rl_line_buffer[first+1] == '?') add_help_keywords = 1;
! 506: return get_matches(-1,text,command_generator);
! 507: }
! 508:
! 509: while (start && rl_line_buffer[start] != '('
! 510: && rl_line_buffer[start] != ',') start--;
! 511: if (rl_line_buffer[start] == '(' && start)
! 512: {
! 513: #define MAX_KEYWORD 200
! 514: int iend, j,k;
! 515: entree *ep;
! 516: char buf[MAX_KEYWORD];
! 517:
! 518: i = start;
! 519:
! 520: while (i && isspace((int)rl_line_buffer[i-1])) i--;
! 521: iend = i;
! 522: while (i && is_keyword_char(rl_line_buffer[i-1])) i--;
! 523:
! 524: if (iend - i == 7)
! 525: {
! 526: if (strncmp(rl_line_buffer + i,"default",7) == 0)
! 527: return get_matches(-2,text,default_generator);
! 528: if (strncmp(rl_line_buffer + i,"whatnow",7) == 0)
! 529: return get_matches(-1,text,old_generator);
! 530: }
! 531: if (iend - i >= 4)
! 532: {
! 533: if (strncmp(rl_line_buffer + i,"read",4) == 0)
! 534: return get_matches(-1,text,FILE_COMPLETION);
! 535: }
! 536:
! 537: j = start + 1;
! 538: while (j <= END && isspace((int)rl_line_buffer[j])) j++;
! 539: k = END;
! 540: while (k > j && isspace((int)rl_line_buffer[k])) k--;
! 541: /* If we are in empty parens, insert arguments for the function: */
! 542: if (do_args_complete && k == j
! 543: && (rl_line_buffer[j] == ')' || !rl_line_buffer[j])
! 544: && (iend - i < MAX_KEYWORD)
! 545: && ( strncpy(buf, rl_line_buffer + i, iend - i),
! 546: buf[iend - i] = 0, 1)
! 547: && (ep = is_entry(buf)) && ep->help)
! 548: {
! 549: #if 0
! 550: char *s = ep->help;
! 551:
! 552: while (is_keyword_char(*s)) s++;
! 553: if (*s++ == '(')
! 554: { /* Function, print arguments! */
! 555: char *endh = s;
! 556: while (*endh && *endh != ')' && *endh != '(') endh++;
! 557: if (*endh == ')')
! 558: { /* Well-formed help. */
! 559: char *str = strncpy((char*) gpmalloc(endh-s + 1), s, endh-s);
! 560: char **ret = (char**)gpmalloc(sizeof(char*)*2);
! 561: str[endh-s] = 0;
! 562: ret[0] = str; ret[1] = NULL;
! 563: if (under_emacs) ret = matches_for_emacs("",ret);
! 564: return ret;
! 565: }
! 566: }
! 567: #endif
! 568: rl_print_aide(buf,h_RL);
! 569: rl_attempted_completion_over = 1;
! 570: return NULL;
! 571: }
! 572: }
! 573: for(i=END-1;i>=start;i--)
! 574: if (!is_keyword_char(rl_line_buffer[i]))
! 575: {
! 576: if (rl_line_buffer[i] == '.')
! 577: return get_matches(-1,text,member_generator);
! 578: break;
! 579: }
! 580: add_help_keywords = 0;
! 581: return get_matches(END,text,command_generator);
! 582: }
! 583:
! 584: /* long help if count < 0 */
! 585: static int
! 586: rl_short_help(int count, int key)
! 587: {
! 588: int flag = (count < 0 || rl_last_func == rl_short_help)? h_RL|h_LONG: h_RL;
! 589: int off = rl_point;
! 590:
! 591: /* func() with cursor on ')' following completion */
! 592: if (off && rl_line_buffer[off-1] == '('
! 593: && !is_keyword_char(rl_line_buffer[off])) off--;
! 594:
! 595: while (off && is_keyword_char(rl_line_buffer[off-1])) off--;
! 596:
! 597: /* Check for \c type situation. Could check for leading whitespace too... */
! 598: if (off == 1 && rl_line_buffer[off-1] == '\\') off--;
! 599: if (off >= 8) { /* Check for default(whatever) */
! 600: int t = off - 1;
! 601:
! 602: while (t >= 7 && isspace((int)rl_line_buffer[t])) t--;
! 603: if (rl_line_buffer[t--] == '(') {
! 604: while (t >= 6 && isspace((int)rl_line_buffer[t])) t--;
! 605: t -= 6;
! 606: if (t >= 0
! 607: && strncmp(rl_line_buffer + t, "default", 7) == 0
! 608: && (t == 0 || !is_keyword_char(rl_line_buffer[t-1])))
! 609: off = t;
! 610: }
! 611: }
! 612: rl_print_aide(rl_line_buffer + off, flag);
! 613: return 0;
! 614: }
! 615:
! 616: static int
! 617: rl_long_help(int count, int key)
! 618: {
! 619: (void)count;
! 620: return rl_short_help(-1,key);
! 621: }
! 622:
! 623: void
! 624: init_readline()
! 625: {
! 626: /* Allow conditional parsing of the ~/.inputrc file. */
! 627: rl_readline_name = "Pari-GP";
! 628:
! 629: /* added ~, ? and , */
! 630: rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{(?,~";
! 631: rl_special_prefixes = "~";
! 632:
! 633: /* custom completer */
! 634: #ifndef HAS_RL_COMPLETION_FUNC_T
! 635: # ifndef CPPFunction_defined
! 636: # define CPPFunction Function
! 637: # endif
! 638: # define rl_completion_func_t CPPFunction
! 639: #endif
! 640: rl_attempted_completion_function = (rl_completion_func_t*) pari_completion;
! 641:
! 642: /* we always want the whole list of completions under emacs */
! 643: if (under_emacs) rl_completion_query_items = 0x8fff;
! 644:
! 645: #define Bind(a,b,c) (((void(*)(int,Function*,Keymap)) rl_bind_key_in_map)\
! 646: ((a), (Function*)(b), (c)))
! 647: #define Defun(a,b,c) (((void(*)(const char*,Function*,int)) rl_add_defun)\
! 648: ((a), (Function*)(b), (c)))
! 649:
! 650: Defun("short-help", rl_short_help, -1);
! 651: Defun("long-help", rl_long_help, -1);
! 652: Defun("pari-complete", pari_rl_complete, '\t');
! 653: Defun("pari-matched-insert", pari_rl_default_matched_insert, -1);
! 654: Defun("pari-forward-sexp", pari_rl_forward_sexp, -1);
! 655: Defun("pari-backward-sexp", pari_rl_backward_sexp, -1);
! 656:
! 657: Bind('h', rl_short_help, emacs_meta_keymap);
! 658: Bind('H', rl_long_help, emacs_meta_keymap);
! 659: Bind('h', rl_short_help, vi_movement_keymap);
! 660: Bind('H', rl_long_help, vi_movement_keymap);
! 661: # ifdef HAS_RL_GENERIC_BIND
! 662: #define KSbind(s,f,k) rl_generic_bind(ISFUNC, (s), (char*)(f), (k))
! 663:
! 664: KSbind("OP", rl_short_help, emacs_meta_keymap); /* f1, vt100 */
! 665: KSbind("[11~", rl_short_help, emacs_meta_keymap); /* f1, xterm */
! 666: KSbind("OP", rl_short_help, vi_movement_keymap); /* f1, vt100 */
! 667: KSbind("[11~", rl_short_help, vi_movement_keymap); /* f1, xterm */
! 668: # endif
! 669: Bind('(', pari_rl_matched_insert, emacs_standard_keymap);
! 670: Bind('[', pari_rl_matched_insert, emacs_standard_keymap);
! 671: Bind(6, pari_rl_forward_sexp, emacs_meta_keymap); /* M-C-f */
! 672: Bind(2, pari_rl_backward_sexp, emacs_meta_keymap); /* M-C-b */
! 673:
! 674: #ifdef EMACS_DOS_KEYMAP
! 675: Bind(';', rl_short_help, emacs_dos_keymap); /* F1 */
! 676: Bind('T', rl_long_help, emacs_dos_keymap); /* Shift-F1 */
! 677: Bind(155, pari_rl_backward_sexp, emacs_dos_keymap); /* Alt-Left */
! 678: Bind(157, pari_rl_forward_sexp, emacs_dos_keymap); /* Alt-Right*/
! 679: #endif
! 680: }
! 681: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>