Annotation of OpenXM_contrib2/fep/fep_edit.c, Revision 1.1
1.1 ! noro 1: /* Copyright (c) 1987, 1988 by Software Research Associates, Inc. */
! 2:
! 3: #ifndef lint
! 4: static char rcsid[]=
! 5: "$Id: fep_edit.c,v 4.10 1995/01/20 08:15:55 utashiro Exp $ (SRA)";
! 6: #endif /* lint */
! 7:
! 8: #include <stdio.h>
! 9: #include <sys/types.h>
! 10: #include <sys/stat.h>
! 11: #include <sys/ioctl.h>
! 12: #ifdef TERMIOS
! 13: #include <termios.h>
! 14: #if defined(__linux__) || defined(__CYGWIN__)
! 15: #ifndef _POSIX_VDISABLE
! 16: #define _POSIX_VDISABLE '\0'
! 17: #endif
! 18: #endif
! 19: #else
! 20: #include <sgtty.h>
! 21: #endif
! 22: #include <sys/time.h>
! 23: #include <ctype.h>
! 24: #if defined(__CYGWIN__)
! 25: #include <sys/dirent.h>
! 26: #define direct dirent
! 27: #else
! 28: #include <sys/dir.h>
! 29: #endif
! 30: #include <sys/file.h>
! 31: #include <setjmp.h>
! 32: #include "fep_defs.h"
! 33: #include "fep_glob.h"
! 34: #include "fep_funcs.h"
! 35:
! 36: CHAR *CommandLine; /* pointer to command line buffer */
! 37: CHAR *KillBuffer; /* pointer to kill buffer */
! 38: int CurrentPosition; /* current cursor position */
! 39: int MarkPosition = -1; /* Marked position */
! 40: EDITMODE editmode = NOTYET; /* edtimode EMACS, VI */
! 41: EDITSTATUS editstatus = NOTEDITING;/* EDITING, NOTEDITING */
! 42:
! 43: int maxline = MAXCMDLEN; /* maximum length of command line */
! 44: int NeedNewLine; /* add new line flag */
! 45: int NeedSave; /* need to save to history */
! 46: int Transparency = OFF; /* transparent flag */
! 47: int Through = OFF; /* through flag */
! 48: int eof_occured = 0; /* eof has been occured */
! 49: jmp_buf jbuf; /* jump buffer */
! 50:
! 51: FUNC *curFuncTab; /* current function table */
! 52: FUNC *altFuncTab; /* alternative function table */
! 53:
! 54: /*
! 55: * Default binding table
! 56: */
! 57: BINDENT emacsBindings[] = {
! 58: /* NULL */ {"\0", mark},
! 59: /* ^A */ {"\\^A", beginning_of_line},
! 60: /* ^B */ {"\\^B", backward_character},
! 61: /* ^D */ {"\\^D", delete_next_character},
! 62: /* ^E */ {"\\^E", end_of_line},
! 63: /* ^F */ {"\\^F", forward_character},
! 64: /* ^I */ {"\\^I", insert_tab},
! 65: /* ^J */ {"\\^J", new_line},
! 66: /* ^K */ {"\\^K", kill_to_end_of_line},
! 67: /* ^L */ {"\\^L", clear_screen},
! 68: /* ^M */ {"\\^M", new_line},
! 69: /* ^N */ {"\\^N", next_history},
! 70: /* ^P */ {"\\^P", previous_history},
! 71: /* ^T */ {"\\^T", previous_history},
! 72: /* ^Y */ {"\\^Y", yank_from_kill_buffer},
! 73: /* ^^ */ {"\\^^", toggle_through},
! 74: /* esc-b */ {"\\^[b", backward_word},
! 75: /* esc-B */ {"\\^[B", backward_Word},
! 76: /* esc-d */ {"\\^[d", delete_next_word},
! 77: /* esc-D */ {"\\^[D", delete_next_Word},
! 78: /* esc-f */ {"\\^[f", forward_word},
! 79: /* esc-F */ {"\\^[F", forward_Word},
! 80: /* esc-h */ {"\\^[h", delete_previous_word},
! 81: /* esc-H */ {"\\^[H", delete_previous_Word},
! 82: /* esc-l */ {"\\^[l", list_file_name},
! 83: /* esc-L */ {"\\^[L", list_file_name},
! 84: /* esc-n */ {"\\^[n", insert_next_history},
! 85: /* esc-N */ {"\\^[N", insert_next_history},
! 86: /* esc-p */ {"\\^[p", insert_previous_history},
! 87: /* esc-P */ {"\\^[P", insert_previous_history},
! 88: /* esc-. */ {"\\^[.", insert_current_history},
! 89: /* esc-esc */ {"\\^[\\^[", expand_file_name},
! 90: /* esc-"-" */ {"\\^[-", toggle_through},
! 91: /* esc-_ */ {"\\^[_", invoke_shell},
! 92: /* esc-< */ {"\\^[<", search_reverse},
! 93: /* esc-> */ {"\\^[>", search_forward},
! 94: /* esc-? */ {"\\^[?", show_help},
! 95: /* ^X-^B */ {"\\^X\\^B", show_bindings},
! 96: /* ^X-B */ {"\\^XB", show_bindings},
! 97: /* ^X-b */ {"\\^Xb", show_bindings},
! 98: /* ^X-^H */ {"\\^X\\^H", show_history},
! 99: /* ^X-H */ {"\\^XH", show_history},
! 100: /* ^X-h */ {"\\^Xh", show_history},
! 101: /* ^X-^V */ {"\\^X\\^V", view_buffer},
! 102: /* ^X-^K */ {"\\^X\\^K", kill_to_top_of_line},
! 103: /* ^X-^L */ {"\\^X\\^L", fep_repaint},
! 104: /* ^X-^C */ {"\\^X\\^C", (FUNC)terminate},
! 105: /* ^X-^D */ {"\\^X\\^D", send_eof},
! 106: /* ^X-( */ {"\\^X(", fep_start_script},
! 107: /* ^X-) */ {"\\^X)", fep_end_script},
! 108: /* */ {NULL, NULL}
! 109: };
! 110:
! 111: /*
! 112: * Initialize function table buffer
! 113: */
! 114: init_bind_table ()
! 115: {
! 116:
! 117: curFuncTab = (FUNC *) calloc (sizeof (FUNC), 256);
! 118: altFuncTab = (FUNC *) calloc (sizeof (FUNC), 256);
! 119: if (curFuncTab == 0 || altFuncTab == 0) {
! 120: printf ("Can't allocate space for function table\n");
! 121: exit (1);
! 122: }
! 123: }
! 124:
! 125: /*
! 126: * Initialize function table
! 127: */
! 128: char strspace [256], *strspace_addr = strspace;
! 129:
! 130: init_edit_params ()
! 131: {
! 132: struct indirect *idp;
! 133: char *cp, *getenv();
! 134: char sbuf[2048], *term, *tgetstr();
! 135:
! 136: if (term = look_var ("term")) {
! 137: if (tgetent (sbuf, term) == 1) {
! 138: if (lines == 0)
! 139: lines = tgetnum ("li");
! 140: if (columns == 0)
! 141: columns = tgetnum ("co");
! 142: term_clear = tgetstr ("cl", &strspace_addr);
! 143: }
! 144: }
! 145:
! 146: if (lines == 0)
! 147: lines = 24;
! 148: if (columns == 0)
! 149: columns = 80;
! 150:
! 151: sprintf (sbuf, "%d", lines);
! 152: set_var ("crt", sbuf);
! 153:
! 154: if (editmode == NOTYET) {
! 155: if (look_var ("editmode"))
! 156: set_var ("editmode", look_var ("editmode"));
! 157: else
! 158: set_var ("editmode", "emacs");
! 159: }
! 160:
! 161: set_var ("showhist", itoa (lines - 1));
! 162:
! 163: /*
! 164: * Read startup file
! 165: */
! 166: sourceRcFile ();
! 167:
! 168: /*
! 169: * Read history if 'history-file' is set
! 170: */
! 171: {
! 172: char *cp, *mk_home_relative ();
! 173:
! 174: if (look_var ("savehist") && (cp = look_var ("history-file"))) {
! 175: cp = mk_home_relative (cp);
! 176:
! 177: if (access (cp, R_OK) == 0)
! 178: read_history (cp);
! 179: }
! 180: }
! 181:
! 182: /*
! 183: * Initialize command line buffer
! 184: */
! 185: CommandLine = (CHAR *) calloc (maxline, 1);
! 186: KillBuffer = (CHAR *) calloc (maxline, 1);
! 187: if (CommandLine == 0 || KillBuffer == 0) {
! 188: perror ("Edit line buffer");
! 189: exit (1);
! 190: }
! 191: (void) strcpy (CommandLine, "");
! 192: (void) strcpy (KillBuffer, "");
! 193: CurrentPosition = 0;
! 194: }
! 195:
! 196: /*
! 197: * Initialize emacs bindings
! 198: */
! 199: initEmacsBindings (cft, aft)
! 200: FUNC cft[], aft[];
! 201: {
! 202: register int i;
! 203: BINDENT *ftp;
! 204:
! 205: for (i = 0; i < 256; i++)
! 206: cft[i] = self_insert;
! 207:
! 208: #define import(table,key,fn) if((int)key>0)table[(int)key]=fn
! 209:
! 210: #ifdef TERMIOS
! 211: /* Now, using cbreak mode
! 212: import (cft, initial_ttymode.c_cc[VSTART], ignore);
! 213: import (cft, initial_ttymode.c_cc[VSTOP], ignore);
! 214: */
! 215: #if 0
! 216: import (cft, initial_ttymode.c_cc[VINTR], insert_and_flush);
! 217: #else
! 218: /* added by noro */
! 219: import (cft, initial_ttymode.c_cc[VINTR], send_int_sig);
! 220: /* XXX : this may not be necessary */
! 221: import (aft, initial_ttymode.c_cc[VINTR], send_int_sig);
! 222: #endif
! 223: import (cft, initial_ttymode.c_cc[VQUIT], insert_and_flush);
! 224: /* Now, EOF will be sent on empty line.
! 225: import (cft, initial_ttymode.c_cc[VEOF], send_eof);
! 226: */
! 227: #ifdef VSWTC
! 228: import (cft, initial_ttymode.c_cc[VSWTC], insert_and_flush);
! 229: #endif
! 230: import (cft, initial_ttymode.c_cc[VSUSP], insert_and_flush);
! 231: /* ^Y is used for yank-from-kill-buffer
! 232: import (cft, initial_ttymode.c_cc[VDSUSP], self_insert);
! 233: */
! 234: import (cft, initial_ttymode.c_cc[VREPRINT], reprint);
! 235: import (cft, initial_ttymode.c_cc[VDISCARD], self_insert);
! 236: import (cft, initial_ttymode.c_cc[VWERASE], delete_previous_word);
! 237: import (cft, initial_ttymode.c_cc[VLNEXT], literal_next);
! 238: import (cft, initial_ttymode.c_cc[VERASE], delete_previous_character);
! 239: import (cft, initial_ttymode.c_cc[VKILL], delete_line);
! 240: #else
! 241: /* Now, using cbreak mode
! 242: import (cft, tchars_buf.t_startc, ignore);
! 243: import (cft, tchars_buf.t_stopc, ignore);
! 244: */
! 245: #if 0
! 246: import (cft, tchars_buf.t_intrc, insert_and_flush);
! 247: #else
! 248: import (cft, tchars_buf.t_intrc, send_int_sig);
! 249: import (aft, tchars_buf.t_intrc, send_int_sig);
! 250: #endif
! 251: import (cft, tchars_buf.t_quitc, insert_and_flush);
! 252: /* Now, EOF will be sent on empty line.
! 253: import (cft, tchars_buf.t_eofc, send_eof);
! 254: */
! 255: import (cft, tchars_buf.t_brkc, insert_and_flush);
! 256: import (cft, ltchars_buf.t_suspc, insert_and_flush);
! 257: /* ^Y is used for yank-from-kill-buffer
! 258: import (cft, ltchars_buf.t_dsuspc, self_insert);
! 259: */
! 260: import (cft, ltchars_buf.t_rprntc, reprint);
! 261: import (cft, ltchars_buf.t_flushc, self_insert);
! 262: import (cft, ltchars_buf.t_werasc, delete_previous_word);
! 263: import (cft, ltchars_buf.t_lnextc, literal_next);
! 264: import (cft, initial_ttymode.sg_erase, delete_previous_character);
! 265: import (cft, initial_ttymode.sg_kill, delete_line);
! 266: #endif
! 267:
! 268: #undef import
! 269:
! 270: /*
! 271: * Set default bindings
! 272: */
! 273: for (ftp = emacsBindings; ftp->bt_s; ftp++) {
! 274: bind_key (cft, ftp->bt_func, ftp->bt_s, fep_abort);
! 275: }
! 276: }
! 277:
! 278: /*
! 279: * Main function of front end program
! 280: */
! 281: CHAR *
! 282: getline()
! 283: {
! 284: int c;
! 285: CHAR *execute_command, *check_alias();
! 286: char *remained;
! 287: int processed;
! 288:
! 289: (void) strcpy (CommandLine, "");
! 290: CurrentPosition = 0;
! 291: resetCurrentHistory ();
! 292:
! 293: RETRY:
! 294: (void) fflush (stdout);
! 295: NeedNewLine = 0;
! 296: NeedSave = 0;
! 297: editstatus = EDITING;
! 298: processed = 0;
! 299: (void) setjmp (jbuf);
! 300:
! 301: /*
! 302: * If there is file pointer for I/O redirection,
! 303: * read input from the pointer and return
! 304: */
! 305: if (redirect_fp) {
! 306:
! 307: /*
! 308: * Check output from sub-process
! 309: */
! 310: swallow_output();
! 311:
! 312: if (fgets (CommandLine, MAXCMDLEN, redirect_fp)) {
! 313: ++redirect_line;
! 314: execute_command = CommandLine;
! 315: goto RETURN;
! 316: }
! 317: else {
! 318: if (look_var ("verbose"))
! 319: printf ("%d lines redirected\n", redirect_line);
! 320: errorBell ();
! 321: if (redirect_pid) {
! 322: pclose (redirect_fp);
! 323: redirect_pid = 0;
! 324: }
! 325: else
! 326: fclose (redirect_fp);
! 327: redirect_fp = NULL;
! 328: }
! 329: }
! 330:
! 331: while ((c = getcharacter ()) >= (CHAR) 0) {
! 332: int status;
! 333:
! 334: /*
! 335: * In transparet mode
! 336: */
! 337: if (Through == ON || Transparency == ON) {
! 338: if (*curFuncTab[(int) c] == toggle_through ||
! 339: *curFuncTab[(int) c] == fix_transparency) {
! 340: (*curFuncTab[(int) c])();
! 341: goto RETRY;
! 342: }
! 343: else {
! 344: CommandLine[CurrentPosition] = c;
! 345: CommandLine[CurrentPosition + 1] = '\0';
! 346: return (CommandLine);
! 347: }
! 348: }
! 349:
! 350: /*
! 351: * If find EOF character on top of empty line
! 352: * and the variable "send-eof-on-empty-line" is set
! 353: * call send_eof
! 354: */
! 355: if (
! 356: #ifdef TERMIOS
! 357: c == initial_ttymode.c_cc[VEOF]
! 358: #else
! 359: c == tchars_buf.t_eofc
! 360: #endif
! 361: && curFuncTab[c] != send_eof
! 362: && ! look_var ("ignore-eof")
! 363: && CommandLine [0] == '\0'
! 364: ) {
! 365: if (!eof_occured && look_var ("alarm-on-eof")) {
! 366: eof_occured = 1;
! 367: status = alarm_on_eof (c);
! 368: }
! 369: else
! 370: status = send_eof (c);
! 371: }
! 372: else {
! 373: eof_occured = 0;
! 374: status = callfunc (curFuncTab, c);
! 375: }
! 376:
! 377: (void) fflush (stdout);
! 378: if (status == 1) /* end of line editing */
! 379: break;
! 380: else /* continue line editing */
! 381: continue;
! 382: }
! 383: editstatus = NOTEDITING;
! 384:
! 385: REPROCESS:
! 386:
! 387: /*
! 388: * Check command line refer history or not
! 389: */
! 390: if (refer_history () == PROCESSED)
! 391: goto RETRY;
! 392:
! 393: /*
! 394: * Check alias list
! 395: */
! 396: if (!processed && !look_var ("noalias")
! 397: && (execute_command = check_alias (CommandLine))
! 398: ) {
! 399: if (look_var ("verbose"))
! 400: printf ("%s\n", execute_command);
! 401: }
! 402: else
! 403: execute_command = CommandLine;
! 404:
! 405:
! 406: /*
! 407: * Check builtin function, and execute it.
! 408: */
! 409: if (executeBuiltInFunction (execute_command, &remained) == PROCESSED) {
! 410: if (!processed)
! 411: addHistory (CommandLine);
! 412: CommandLine[0] = '\0';
! 413: CurrentPosition = 0;
! 414: if (remained && *remained) {
! 415: strcpy (CommandLine, remained);
! 416: processed = 1;
! 417: goto REPROCESS;
! 418: }
! 419: if (!redirect_fp)
! 420: fputs (prompt, stdout);
! 421: goto RETRY;
! 422: }
! 423:
! 424: if (NeedSave) {
! 425: if (!is_empty_line (CommandLine) || !look_var ("ignore-empty-line"))
! 426: if (!processed)
! 427: addHistory (CommandLine);
! 428: /*
! 429: * put string to buffer
! 430: */
! 431: buf_put (output_buffer, CommandLine);
! 432: if (NeedNewLine == 1)
! 433: buf_put (output_buffer, "\n");
! 434: }
! 435:
! 436: if (NeedNewLine == 1)
! 437: (void) strcat (execute_command, "\n");
! 438:
! 439: RETURN:
! 440: return (execute_command);
! 441: }
! 442:
! 443: /*
! 444: * Invoke appropliate function according to fucntion table
! 445: * Return value 1 means exit from line editing
! 446: */
! 447: callfunc (ft, c)
! 448: FUNC ft[];
! 449: int c;
! 450: {
! 451:
! 452: if (isIndirect(ft[(int) c])) {
! 453: FUNC *nft = maskIndirect (ft[(int)c]);
! 454: char nc;
! 455:
! 456: nc = (CHAR) getcharacter();
! 457: return (callfunc (nft, nc));
! 458: }
! 459: else
! 460: return ((*ft[(int) c]) (c));
! 461: }
! 462:
! 463: /*
! 464: * Beep and do nothing
! 465: */
! 466: fep_abort()
! 467: {
! 468: (void) errorBell ();
! 469: return (0);
! 470: }
! 471:
! 472: /*
! 473: * Insert the character self
! 474: */
! 475: self_insert(c)
! 476: CHAR c;
! 477: {
! 478: register int i, nbyte = 1, currentNull;
! 479: #ifdef KANJI
! 480: CHAR byte2;
! 481: #endif /* KANJI */
! 482:
! 483: currentNull = strlen (CommandLine);
! 484:
! 485: if (currentNull >= maxline) {
! 486: errorBell();
! 487: return (0);
! 488: }
! 489:
! 490: if (isctlchar(CommandLine[CurrentPosition]))
! 491: (void) putchar (BS);
! 492: #ifdef KANJI
! 493: if (iskanji (c)) {
! 494: byte2 = (CHAR) getcharacter ();
! 495: putchar (c);
! 496: putchar (byte2);
! 497: nbyte = 2;
! 498: }
! 499: else
! 500: #endif /* KANJI */
! 501: putChar (c);
! 502: reverse_strcpy (
! 503: &CommandLine[CurrentPosition] + nbyte,
! 504: &CommandLine[CurrentPosition]
! 505: );
! 506: CurrentPosition += nbyte;
! 507: CommandLine[CurrentPosition - nbyte] = c;
! 508: #ifdef KANJI
! 509: if (nbyte > 1) {
! 510: CommandLine[CurrentPosition - 1] = byte2;
! 511: }
! 512: #endif /* KANJI */
! 513: printS (&CommandLine [CurrentPosition]);
! 514:
! 515: if (CommandLine[CurrentPosition] != '\0') {
! 516: repeat (BS, howlong (&CommandLine[CurrentPosition + 1], 0));
! 517: (void) putchar (BS);
! 518: }
! 519: return (0);
! 520: }
! 521:
! 522: /*
! 523: * Insert string in current position
! 524: */
! 525: insert_string (s)
! 526: CHAR *s;
! 527: {
! 528: register int i, nbyte = strlen (s), currentNull;
! 529:
! 530: currentNull = strlen (CommandLine);
! 531:
! 532: if (currentNull + nbyte >= maxline - 1) {
! 533: errorBell();
! 534: return (0);
! 535: }
! 536:
! 537: if (isctlchar(CommandLine[CurrentPosition]))
! 538: (void) putchar (BS);
! 539: printS (s);
! 540: reverse_strcpy (
! 541: &CommandLine[CurrentPosition] + nbyte, /* to */
! 542: &CommandLine[CurrentPosition] /* from */
! 543: );
! 544: bcopy (s, &CommandLine[CurrentPosition], nbyte);
! 545: CurrentPosition += nbyte;
! 546:
! 547: if (CommandLine[CurrentPosition] != '\0') {
! 548: printS (&CommandLine[CurrentPosition]);
! 549: repeat (BS, howlong (&CommandLine[CurrentPosition], 0));
! 550: }
! 551: return (0);
! 552: }
! 553:
! 554: /*
! 555: * Yank string from kill buffer.
! 556: */
! 557: yank_from_kill_buffer ()
! 558: {
! 559: insert_string (KillBuffer);
! 560: }
! 561:
! 562: /*
! 563: * Set mark to current position
! 564: */
! 565: mark ()
! 566: {
! 567: set_mark (CurrentPosition);
! 568: return (0);
! 569: }
! 570:
! 571: /*
! 572: * Set mark to specified position
! 573: */
! 574: set_mark (pos)
! 575: int pos;
! 576: {
! 577: MarkPosition = pos;
! 578: return (0);
! 579: }
! 580:
! 581: /*
! 582: * Delete area from mark to current position to kill buffer
! 583: */
! 584: delete_to_kill_buffer ()
! 585: {
! 586: int n = abs (CurrentPosition - MarkPosition);
! 587:
! 588: if (MarkPosition < 0) {
! 589: errorBell();
! 590: return (0);
! 591: }
! 592:
! 593: if (CurrentPosition == MarkPosition)
! 594: return;
! 595:
! 596: if (CurrentPosition > MarkPosition) {
! 597: (void) moveto (MarkPosition);
! 598: }
! 599:
! 600: return (delete_next_n_character (n));
! 601: }
! 602:
! 603: /*
! 604: * Move to specified position.
! 605: */
! 606: moveto (position)
! 607: {
! 608: if (position < CurrentPosition)
! 609: while (position < CurrentPosition)
! 610: (void) backward_n_character (1);
! 611: else
! 612: while (position > CurrentPosition
! 613: #ifdef KANJI
! 614: && !(CurrentPosition + 1 == position
! 615: && iskanji (CommandLine[CurrentPosition]))
! 616: #endif /* KANJI */
! 617: )
! 618: (void) forward_n_character (1);
! 619: }
! 620:
! 621: /*
! 622: * Move cursor to top of line
! 623: */
! 624: beginning_of_line()
! 625: {
! 626: register int i;
! 627:
! 628: for (i = CurrentPosition; i > 0; i--) {
! 629: if (isctlchar (CommandLine[i]))
! 630: (void) putchar (BS);
! 631: (void) putchar (BS);
! 632: }
! 633: CurrentPosition = 0;
! 634: return (0);
! 635: }
! 636:
! 637: #ifdef KANJI
! 638: #define INC(i) if(iskanji(CommandLine[i])) i+=2; else i++;
! 639: #define DEC(i) if(i>=2 && iskanji_in_string(CommandLine, i-2)) i-=2; else i--;
! 640: #else /* KANJI */
! 641: #define INC(i) i++
! 642: #define DEC(i) i--
! 643: #endif /* KANJI */
! 644:
! 645: /*
! 646: * Move cursor to end of line
! 647: */
! 648: end_of_line()
! 649: {
! 650: register int i;
! 651:
! 652: for (i = CurrentPosition; CommandLine[i]; i++) {
! 653: if (isctlchar (CommandLine[i]))
! 654: (void) putchar (unctl(CommandLine[i]));
! 655: else
! 656: (void) putchar (CommandLine[i]);
! 657: if (isctlchar(CommandLine[i+1]))
! 658: (void) putchar ('^');
! 659: }
! 660: CurrentPosition = i;
! 661: return (0);
! 662: }
! 663:
! 664: /*
! 665: * Move cursor left one space
! 666: */
! 667: backward_character()
! 668: {
! 669:
! 670: return (backward_n_character (1));
! 671: }
! 672:
! 673: /*
! 674: * Move cursor left "n" space
! 675: */
! 676: backward_n_character(n)
! 677: int n;
! 678: {
! 679: int space;
! 680: int i = CurrentPosition;
! 681:
! 682: if (n == 0)
! 683: return (0);
! 684: else if (n < 0)
! 685: return (forward_n_character (-n));
! 686: else if (n > CurrentPosition) {
! 687: errorBell ();
! 688: return (0);
! 689: }
! 690:
! 691: while (n-- && i >= 0) {
! 692: if (isctlchar (CommandLine[i]))
! 693: putchar (BS);
! 694: #ifdef KANJI
! 695: if (i > 0 && iskanji_in_string (CommandLine, i-2)) {
! 696: (void) putchar (BS);
! 697: (void) putchar (BS);
! 698: i--;
! 699: }
! 700: else
! 701: #endif /* KANJI */
! 702: putchar (BS);
! 703: i--;
! 704: }
! 705: CurrentPosition = i;
! 706: return (0);
! 707: }
! 708:
! 709: /*
! 710: * Move cursor backward one word
! 711: */
! 712: backward_word ()
! 713: {
! 714:
! 715: return (backward_n_word (1));
! 716: }
! 717:
! 718: /*
! 719: * Move cursor backward n word
! 720: */
! 721: backward_n_word (n)
! 722: int n;
! 723: {
! 724: register int i = CurrentPosition, nchars = 0;
! 725:
! 726: if (i == 0) {
! 727: errorBell ();
! 728: return (0);
! 729: }
! 730:
! 731: #ifdef KANJI
! 732: while (n--) {
! 733: DEC(i);
! 734: nchars++;
! 735:
! 736: while (1) {
! 737: if (i >= 2 && iskanji_in_string (CommandLine, i-2))
! 738: break;
! 739: else if (i > 0 && !iswordchar (CommandLine[i]))
! 740: i -= 1;
! 741: else
! 742: break;
! 743:
! 744: nchars++;
! 745: }
! 746: while (1) {
! 747: if (i >= 2 && iskanji_in_string (CommandLine, i - 2))
! 748: i -= 2;
! 749: else if (i > 0 && iswordchar (CommandLine [i -1]))
! 750: i -= 1;
! 751: else
! 752: break;
! 753: nchars++;
! 754: }
! 755: }
! 756: #else /* KANJI */
! 757: while (n--) {
! 758: i--, nchars++;
! 759: while (i > 0 && !iswordchar (CommandLine [i])) {
! 760: i--, nchars++;
! 761: }
! 762: while (i > 0 && iswordchar (CommandLine [i - 1])) {
! 763: i--, nchars++;
! 764: }
! 765: }
! 766: #endif /* KANJI */
! 767: return (backward_n_character (nchars));
! 768: }
! 769:
! 770: /*
! 771: * Move cursor backward one Word
! 772: */
! 773: backward_Word ()
! 774: {
! 775:
! 776: return (backward_n_Word (1));
! 777: }
! 778:
! 779: /*
! 780: * Move cursor backward n Word
! 781: */
! 782: backward_n_Word (n)
! 783: int n;
! 784: {
! 785: register int i = CurrentPosition, nchars = 0;
! 786:
! 787: if (i == 0) {
! 788: errorBell ();
! 789: return (0);
! 790: }
! 791:
! 792: #ifdef KANJI
! 793: while (n--) {
! 794: DEC(i);
! 795: nchars++;
! 796:
! 797: while (1) {
! 798: if (i > 1 && iskanji_in_string (CommandLine, i - 2))
! 799: break;
! 800: else if (i > 0 && !iswordchar (CommandLine[i]))
! 801: i -= 1;
! 802: else
! 803: break;
! 804:
! 805: nchars++;
! 806: }
! 807: while (1) {
! 808: if (i > 2 && iskanji_in_string (CommandLine, i - 2))
! 809: i -= 2;
! 810: else if (i > 0 && iswordchar (CommandLine [i - 1]))
! 811: i -= 1;
! 812: else
! 813: break;
! 814: nchars++;
! 815: }
! 816: }
! 817: #else /* KANJI */
! 818: while (n--) {
! 819: i--, nchars++;
! 820: while (i > 0 && !isWordchar (CommandLine [i]))
! 821: i--, nchars++;
! 822: while (i > 0 && isWordchar (CommandLine [i - 1]))
! 823: i--, nchars++;
! 824: }
! 825: #endif /* KANJI */
! 826: return (backward_n_character (nchars));
! 827: }
! 828:
! 829: /*
! 830: * Move cursor forward one character
! 831: */
! 832: forward_character()
! 833: {
! 834:
! 835: return (forward_n_character (1));
! 836: }
! 837:
! 838: /*
! 839: * Move cursor forward n character
! 840: */
! 841: forward_n_character(n)
! 842: int n;
! 843: {
! 844: int space;
! 845: register int i = CurrentPosition;
! 846:
! 847: if (n == 0)
! 848: return (0);
! 849: else if (n < 0)
! 850: return (backward_n_character (-n));
! 851:
! 852: if (CommandLine [CurrentPosition] == '\0') {
! 853: errorBell ();
! 854: return (0);
! 855: }
! 856:
! 857: #ifdef KANJI
! 858: if (iskanji (CommandLine[i])) {
! 859: (void) putchar (CommandLine[i++]);
! 860: (void) putchar (CommandLine[i++]);
! 861: }
! 862: else
! 863: #endif /* KANJI */
! 864: if (isctlchar(CommandLine[i])) {
! 865: (void) putchar (unctl (CommandLine [i]));
! 866: i++;
! 867: }
! 868: else
! 869: (void) putchar (CommandLine[i++]);
! 870:
! 871: while (--n && CommandLine [i]) {
! 872: #ifdef KANJI
! 873: if (iskanji (CommandLine[i])) {
! 874: (void) putchar (CommandLine[i++]);
! 875: (void) putchar (CommandLine[i++]);
! 876: }
! 877: else
! 878: #endif /* KANJI */
! 879: putChar (CommandLine [i++]);
! 880: }
! 881:
! 882: if (isctlchar (CommandLine [i]))
! 883: putchar ('^');
! 884:
! 885: CurrentPosition = i;
! 886:
! 887: return (0);
! 888: }
! 889:
! 890: /*
! 891: * Move cursor forward one word
! 892: */
! 893: forward_word ()
! 894: {
! 895: return (forward_n_word (1));
! 896: }
! 897:
! 898: /*
! 899: * Move cursor forward n word
! 900: */
! 901: forward_n_word (n)
! 902: int n;
! 903: {
! 904: register int i = CurrentPosition, nchars = 0;
! 905:
! 906: if (CommandLine [i] == '\0') {
! 907: errorBell ();
! 908: return (0);
! 909: }
! 910:
! 911: while (n--) {
! 912: while (CommandLine [i] && iswordchar (CommandLine [i])) {
! 913: INC(i);
! 914: nchars++;
! 915: }
! 916: while (CommandLine [i] && !iswordchar (CommandLine [i])) {
! 917: INC(i);
! 918: nchars++;
! 919: }
! 920: }
! 921: return (forward_n_character (nchars));
! 922: }
! 923:
! 924: /*
! 925: * Move cursor forward one word
! 926: */
! 927: forward_Word ()
! 928: {
! 929: return (forward_n_Word (1));
! 930: }
! 931:
! 932: /*
! 933: * Move cursor forward n word
! 934: */
! 935: forward_n_Word (n)
! 936: int n;
! 937: {
! 938: register int i = CurrentPosition, nchars = 0;
! 939:
! 940: if (CommandLine [i] == '\0') {
! 941: errorBell ();
! 942: return (0);
! 943: }
! 944:
! 945: while (n--) {
! 946: while (CommandLine [i] && isWordchar (CommandLine [i])) {
! 947: INC(i);
! 948: nchars++;
! 949: }
! 950: while (CommandLine [i] && !isWordchar (CommandLine [i])) {
! 951: INC(i);
! 952: nchars++;
! 953: }
! 954: }
! 955: return (forward_n_character (nchars));
! 956: }
! 957:
! 958: /*
! 959: * Forward to end of word
! 960: */
! 961: forward_to_end_of_word ()
! 962: {
! 963:
! 964: return (forward_to_end_of_n_word (1));
! 965: }
! 966:
! 967: /*
! 968: * Forward to end of n word
! 969: */
! 970: forward_to_end_of_n_word (n)
! 971: {
! 972: register int i = CurrentPosition, nchars = 0;
! 973:
! 974: if (CommandLine [i] == '\0') {
! 975: errorBell ();
! 976: return (0);
! 977: }
! 978:
! 979: INC(i);
! 980: while (n--) {
! 981: while (CommandLine [i] && !iswordchar (CommandLine [i])) {
! 982: INC(i);
! 983: nchars++;
! 984: }
! 985: while (CommandLine [i] && iswordchar (CommandLine [i])) {
! 986: INC(i);
! 987: nchars++;
! 988: }
! 989: }
! 990: DEC(i);
! 991: return (forward_n_character (nchars));
! 992: }
! 993:
! 994: /*
! 995: * Forward to end of word
! 996: */
! 997: forward_to_end_of_Word ()
! 998: {
! 999:
! 1000: return (forward_to_end_of_n_Word (1));
! 1001: }
! 1002:
! 1003: /*
! 1004: * Forward to end of n word
! 1005: */
! 1006: forward_to_end_of_n_Word (n)
! 1007: {
! 1008: register int i = CurrentPosition, nchars = 0;
! 1009:
! 1010: if (CommandLine [i] == '\0') {
! 1011: errorBell ();
! 1012: return (0);
! 1013: }
! 1014:
! 1015: INC(i);
! 1016: while (n--) {
! 1017: while (CommandLine [i] && !isWordchar (CommandLine [i])) {
! 1018: INC(i);
! 1019: nchars++;
! 1020: }
! 1021: while (CommandLine [i] && isWordchar (CommandLine [i])) {
! 1022: INC(i);
! 1023: nchars++;
! 1024: }
! 1025: }
! 1026: DEC(i);
! 1027: return (forward_n_character (nchars));
! 1028: }
! 1029:
! 1030: /*
! 1031: * Delete previous one character
! 1032: */
! 1033: delete_previous_character()
! 1034: {
! 1035:
! 1036: return (delete_previous_n_character (1));
! 1037: }
! 1038:
! 1039: /*
! 1040: * Delete previous n characters
! 1041: */
! 1042: delete_previous_n_character(n)
! 1043: int n;
! 1044: {
! 1045: register int i, nbyte;
! 1046: int deleteArea, restArea;
! 1047:
! 1048: if (CurrentPosition < n) {
! 1049: errorBell ();
! 1050: return (0);
! 1051: }
! 1052:
! 1053: #ifdef KANJI
! 1054: for (nbyte = 0, i = CurrentPosition; n-- > 0 && i;)
! 1055: if (i > 1 && iskanji_in_string (CommandLine, i - 2))
! 1056: i -= 2, nbyte += 2;
! 1057: else
! 1058: i -= 1, nbyte += 1;
! 1059: #else /* KANJI */
! 1060: nbyte = n;
! 1061: #endif /* KANJI */
! 1062:
! 1063: deleteArea = howlong (&CommandLine[CurrentPosition - nbyte], nbyte);
! 1064: restArea = howlong (&CommandLine[CurrentPosition], 0);
! 1065: if (isctlchar(CommandLine[CurrentPosition]))
! 1066: (void) putchar (BS);
! 1067: repeat(BS, deleteArea);
! 1068: CurrentPosition -= nbyte;
! 1069: strcpy (KillBuffer, &CommandLine [CurrentPosition]);
! 1070: KillBuffer [nbyte] = '\0';
! 1071: for (i = CurrentPosition; CommandLine[i + nbyte]; i++) {
! 1072: CommandLine[i] = CommandLine[i + nbyte];
! 1073: putChar (CommandLine[i]);
! 1074: }
! 1075: CommandLine[i] = '\0';
! 1076: repeat(SP, deleteArea);
! 1077: repeat(BS, deleteArea);
! 1078: if (isctlchar (CommandLine[CurrentPosition]))
! 1079: repeat(BS, restArea - 1);
! 1080: else
! 1081: repeat(BS, restArea);
! 1082:
! 1083: return (0);
! 1084: }
! 1085:
! 1086: /*
! 1087: * Delete previous one word
! 1088: */
! 1089: delete_previous_word()
! 1090: {
! 1091:
! 1092: return (delete_previous_n_word (1));
! 1093: }
! 1094:
! 1095: /*
! 1096: * Delete previous n word
! 1097: */
! 1098: delete_previous_n_word(n)
! 1099: int n;
! 1100: {
! 1101: register int i = CurrentPosition, nchars = 0;
! 1102:
! 1103: if (i == 0) {
! 1104: errorBell();
! 1105: return (0);
! 1106: }
! 1107:
! 1108: #ifdef KANJI
! 1109: while (n--) {
! 1110: if (i>1 && iskanji_in_string (CommandLine, i-2))
! 1111: i--;
! 1112: i--, nchars++;
! 1113:
! 1114: while (1) {
! 1115: if (i > 1 && iskanji_in_string (CommandLine, i-2))
! 1116: break;
! 1117: else if (i > 0 && !iswordchar (CommandLine[i]))
! 1118: i -= 1;
! 1119: else
! 1120: break;
! 1121:
! 1122: nchars++;
! 1123: }
! 1124: while (1) {
! 1125: if (i > 2 && iskanji_in_string (CommandLine, i - 2))
! 1126: i -= 2;
! 1127: else if (i > 0 && iswordchar (CommandLine [i -1]))
! 1128: i -= 1;
! 1129: else
! 1130: break;
! 1131: nchars++;
! 1132: }
! 1133: }
! 1134: #else /* KANJI */
! 1135: while (n--) {
! 1136: i--, nchars++;
! 1137: while (i > 0 && !iswordchar (CommandLine [i]))
! 1138: i--, nchars++;
! 1139: while (i > 0 && iswordchar (CommandLine [i - 1]))
! 1140: i--, nchars++;
! 1141: }
! 1142: #endif /* KANJI */
! 1143:
! 1144: return (delete_previous_n_character (nchars));
! 1145: }
! 1146:
! 1147: /*
! 1148: * Delete previous one word
! 1149: */
! 1150: delete_previous_Word()
! 1151: {
! 1152:
! 1153: return (delete_previous_n_Word (1));
! 1154: }
! 1155:
! 1156: /*
! 1157: * Delete previous n word
! 1158: */
! 1159: delete_previous_n_Word(n)
! 1160: int n;
! 1161: {
! 1162: register int i = CurrentPosition, nchars = 0;
! 1163:
! 1164: if (i == 0) {
! 1165: errorBell();
! 1166: return (0);
! 1167: }
! 1168:
! 1169: #ifdef KANJI
! 1170: while (n--) {
! 1171: if (i>1 && iskanji_in_string (CommandLine, i-2))
! 1172: i--;
! 1173: i--, nchars++;
! 1174:
! 1175: while (1) {
! 1176: if (i > 1 && iskanji_in_string (CommandLine, i-2))
! 1177: break;
! 1178: else if (i > 0 && !isWordchar (CommandLine[i]))
! 1179: i -= 1;
! 1180: else
! 1181: break;
! 1182:
! 1183: nchars++;
! 1184: }
! 1185: while (1) {
! 1186: if (i > 2 && iskanji_in_string (CommandLine, i - 2))
! 1187: i -= 2;
! 1188: else if (i > 0 && isWordchar (CommandLine [i -1]))
! 1189: i -= 1;
! 1190: else
! 1191: break;
! 1192: nchars++;
! 1193: }
! 1194: }
! 1195: #else /* KANJI */
! 1196: while (n--) {
! 1197: i--, nchars++;
! 1198: while (i > 0 && !isWordchar (CommandLine [i]))
! 1199: i--, nchars++;
! 1200: while (i > 0 && isWordchar (CommandLine [i - 1]))
! 1201: i--, nchars++;
! 1202: }
! 1203: #endif /* KANJI */
! 1204:
! 1205: return (delete_previous_n_character (nchars));
! 1206: }
! 1207:
! 1208: /*
! 1209: * Delete next one character
! 1210: */
! 1211: delete_next_character ()
! 1212: {
! 1213:
! 1214: return (delete_next_n_character (1));
! 1215: }
! 1216:
! 1217: /*
! 1218: * Delete next n character
! 1219: */
! 1220: delete_next_n_character (n)
! 1221: int n;
! 1222: {
! 1223: register int i, nbyte;
! 1224: int deleteArea, restArea;
! 1225:
! 1226: if (strlen (&CommandLine [CurrentPosition]) < n) {
! 1227: errorBell ();
! 1228: return (0);
! 1229: }
! 1230:
! 1231: #ifdef KANJI
! 1232: {
! 1233: register CHAR *cp = &CommandLine[CurrentPosition];
! 1234:
! 1235: nbyte = 0;
! 1236: while (n-- > 0 && *cp)
! 1237: if (iskanji (*cp))
! 1238: cp += 2, nbyte += 2;
! 1239: else
! 1240: cp++, nbyte++;
! 1241: }
! 1242: #else /* KANJI */
! 1243: nbyte = n;
! 1244: #endif /* KANJI */
! 1245:
! 1246: deleteArea = howlong (&CommandLine[CurrentPosition], nbyte);
! 1247: restArea = howlong (&CommandLine[CurrentPosition + nbyte], 0);
! 1248: if (isctlchar(CommandLine[CurrentPosition]))
! 1249: (void) putchar (BS);
! 1250: strcpy (KillBuffer, CommandLine + CurrentPosition);
! 1251: KillBuffer [nbyte] = '\0';
! 1252: for (i = CurrentPosition; CommandLine[i + nbyte]; i++) {
! 1253: CommandLine[i] = CommandLine[i + nbyte];
! 1254: putChar (CommandLine[i]);
! 1255: }
! 1256: CommandLine[i] = '\0';
! 1257: repeat(SP, deleteArea);
! 1258: repeat(BS, deleteArea);
! 1259: if (isctlchar (CommandLine[CurrentPosition]))
! 1260: repeat(BS, restArea - 1);
! 1261: else
! 1262: repeat(BS, restArea);
! 1263:
! 1264: return (0);
! 1265: }
! 1266:
! 1267: /*
! 1268: * Delete next one word
! 1269: */
! 1270: delete_next_word ()
! 1271: {
! 1272: return (delete_next_n_word (1));
! 1273: }
! 1274:
! 1275: /*
! 1276: * Delete next n word
! 1277: */
! 1278: delete_next_n_word (n)
! 1279: int n;
! 1280: {
! 1281: register int i = CurrentPosition, nchars = 0;
! 1282:
! 1283: if (CommandLine [i] == '\0') {
! 1284: errorBell ();
! 1285: return (0);
! 1286: }
! 1287:
! 1288: while (n--) {
! 1289: while (CommandLine [i] && iswordchar (CommandLine [i])) {
! 1290: INC(i);
! 1291: nchars++;
! 1292: }
! 1293: while (CommandLine [i] && !iswordchar (CommandLine [i])) {
! 1294: INC(i);
! 1295: nchars++;
! 1296: }
! 1297: }
! 1298: return (delete_next_n_character (nchars));
! 1299: }
! 1300:
! 1301: /*
! 1302: * Delete next one word
! 1303: */
! 1304: delete_next_Word ()
! 1305: {
! 1306: return (delete_next_n_Word (1));
! 1307: }
! 1308:
! 1309: /*
! 1310: * Delete next n word
! 1311: */
! 1312: delete_next_n_Word (n)
! 1313: int n;
! 1314: {
! 1315: register int i = CurrentPosition, nchars = 0;
! 1316:
! 1317: if (CommandLine [i] == '\0') {
! 1318: errorBell ();
! 1319: return (0);
! 1320: }
! 1321:
! 1322: while (n--) {
! 1323: while (CommandLine [i] && isWordchar (CommandLine [i])) {
! 1324: INC(i);
! 1325: nchars++;
! 1326: }
! 1327: while (CommandLine [i] && !isWordchar (CommandLine [i])) {
! 1328: INC(i);
! 1329: nchars++;
! 1330: }
! 1331: }
! 1332: return (delete_next_n_character (nchars));
! 1333: }
! 1334:
! 1335: /*
! 1336: * Erase whole line
! 1337: */
! 1338: delete_line()
! 1339: {
! 1340: register int i = CurrentPosition;
! 1341: register int len;
! 1342:
! 1343: len = howlong (CommandLine, 0);
! 1344:
! 1345: /*
! 1346: * If cursor is there right part of line, move it to end of line
! 1347: * and erase character by character from end
! 1348: */
! 1349: if (howlong (CommandLine, CurrentPosition + 1) > len / 2) {
! 1350: (void) end_of_line ();
! 1351: repeat_string ("\b \b", len);
! 1352: }
! 1353: /*
! 1354: * If cursor is there on left part of line, move it to top of line
! 1355: * and erase line at once
! 1356: */
! 1357: else {
! 1358: (void) beginning_of_line ();
! 1359: if (isctlchar (CommandLine[0]))
! 1360: putchar (BS);
! 1361: repeat (SP, len);
! 1362: repeat (BS, len);
! 1363: }
! 1364: strcpy (KillBuffer, CommandLine);
! 1365: CurrentPosition = 0;
! 1366: CommandLine [0] = '\0';
! 1367: return (0);
! 1368: }
! 1369:
! 1370: /*
! 1371: * Delete characters from current position to top of line
! 1372: */
! 1373: kill_to_top_of_line()
! 1374: {
! 1375: int i = CurrentPosition;
! 1376:
! 1377: (void) beginning_of_line();
! 1378: return (delete_next_n_character (i));
! 1379: }
! 1380:
! 1381: /*
! 1382: * Delete characters from current position to end of line
! 1383: */
! 1384: kill_to_end_of_line()
! 1385: {
! 1386: register int i, backCnt = 0;
! 1387:
! 1388: if (isctlchar(CommandLine[CurrentPosition])) {
! 1389: (void) putchar(BS);
! 1390: }
! 1391: for (i = CurrentPosition; CommandLine[i]; i++) {
! 1392: if (isctlchar(CommandLine[i])) {
! 1393: fputs(" ", stdout);
! 1394: backCnt++;
! 1395: }
! 1396: else
! 1397: (void) putchar (SP);
! 1398: backCnt++;
! 1399: }
! 1400: for (; backCnt; backCnt--)
! 1401: (void) putchar (BS);
! 1402: strcpy (KillBuffer, CommandLine + CurrentPosition);
! 1403: CommandLine[CurrentPosition] = '\0';
! 1404: return (0);
! 1405: }
! 1406:
! 1407: /*
! 1408: * Insert tab to current cursor position
! 1409: */
! 1410: insert_tab()
! 1411: {
! 1412:
! 1413: /* sorry, not implemented */
! 1414: return (self_insert ('\t'));
! 1415: }
! 1416:
! 1417: /*
! 1418: * Process new line
! 1419: */
! 1420: new_line()
! 1421: {
! 1422:
! 1423: (void) end_of_line;
! 1424: fputs ("\r\n", stdout);
! 1425: NeedNewLine = 1;
! 1426: NeedSave = 1;
! 1427:
! 1428: return (1);
! 1429: }
! 1430:
! 1431: /*
! 1432: * Check current position is top-of-line
! 1433: */
! 1434: is_tol()
! 1435: {
! 1436: return (CurrentPosition == 0);
! 1437: }
! 1438:
! 1439: /*
! 1440: * Check current position is end-of-line
! 1441: */
! 1442: is_eol()
! 1443: {
! 1444: return (CommandLine [CurrentPosition] == '\0');
! 1445: }
! 1446:
! 1447: /*
! 1448: * Check command line if it refer history or not
! 1449: */
! 1450: refer_history()
! 1451: {
! 1452: char *historyExtract ();
! 1453: char *his;
! 1454:
! 1455: if (CommandLine[0] != '!')
! 1456: return (NOT_PROCESSED);
! 1457:
! 1458: if (his = historyExtract (CommandLine)) {
! 1459: (void) strcpy (CommandLine, his);
! 1460: CurrentPosition = strlen (CommandLine);
! 1461: }
! 1462: else {
! 1463: fputs (CommandLine, stdout);
! 1464: fputs (" : Event not found.\r\n", stdout);
! 1465: (void) strcpy (CommandLine, "");
! 1466: CurrentPosition = 0;
! 1467: }
! 1468: fputs (prompt, stdout);
! 1469: print_com_line ();
! 1470: return (PROCESSED);
! 1471: }
! 1472:
! 1473: #define FORWARD 1
! 1474: #define REVERSE 2
! 1475:
! 1476: search_reverse ()
! 1477: {
! 1478: return (search_history (REVERSE));
! 1479: }
! 1480:
! 1481: search_forward ()
! 1482: {
! 1483: return (search_history (FORWARD));
! 1484: }
! 1485:
! 1486: search_history (direct)
! 1487: int direct;
! 1488: {
! 1489: char *his, *search_reverse_history(), *search_forward_history();
! 1490: char *(*func)();
! 1491:
! 1492: if (direct == FORWARD)
! 1493: func = search_forward_history;
! 1494: else
! 1495: func = search_reverse_history;
! 1496:
! 1497: AGAIN:
! 1498: if (his = (*func) (0)) {
! 1499: if (eq (his, CommandLine))
! 1500: goto AGAIN;
! 1501:
! 1502: (void) delete_line ();
! 1503: (void) insert_string (his);
! 1504: CurrentPosition = strlen (CommandLine);
! 1505: }
! 1506: else {
! 1507: (void) errorBell ();
! 1508:
! 1509: if (look_var ("verbose")) {
! 1510: char *cp;
! 1511:
! 1512: if ((cp = look_var ("search-string")) == NULL)
! 1513: cp = "";
! 1514: (void) clear_edit_line ();
! 1515: fprintf (stdout, "\"%s\": No match.\r\n", cp);
! 1516: (void) recover_edit_line (1);
! 1517: }
! 1518: }
! 1519:
! 1520: return 0;
! 1521: }
! 1522:
! 1523:
! 1524: /*
! 1525: * Insert the character and flush buffer
! 1526: */
! 1527: insert_and_flush(c)
! 1528: char c;
! 1529: {
! 1530: (void) self_insert (c);
! 1531: return (1);
! 1532: }
! 1533:
! 1534: /*
! 1535: * Insert the character, but it means EOL. Therefore move cursor backward and
! 1536: * flush buffer
! 1537: */
! 1538: send_eof()
! 1539: {
! 1540: #ifdef TERMIOS
! 1541: char c = initial_ttymode.c_cc[VEOF];
! 1542: #else
! 1543: char c = tchars_buf.t_eofc;
! 1544: #endif
! 1545:
! 1546: (void) self_insert (c);
! 1547: if (isctlchar (c))
! 1548: fputs ("\b\b", stdout);
! 1549: else
! 1550: fputs ("\b", stdout);
! 1551: return (1);
! 1552: }
! 1553:
! 1554: /*
! 1555: * Alarm for EOF on only the first time finding eof character
! 1556: */
! 1557: alarm_on_eof ()
! 1558: {
! 1559:
! 1560: errorBell ();
! 1561: (void) clear_edit_line ();
! 1562: printf ("EOF -- one more eof character to send eof to the process.\n");
! 1563: (void) recover_edit_line (1);
! 1564: }
! 1565:
! 1566: /*
! 1567: * Clear screen
! 1568: */
! 1569: clear_screen()
! 1570: {
! 1571:
! 1572: if (term_clear) {
! 1573: (void) clear_edit_line ();
! 1574: fputs (term_clear, stdout);
! 1575: (void) recover_edit_line (1);
! 1576: }
! 1577: else
! 1578: errorBell ();
! 1579:
! 1580: return (0);
! 1581: }
! 1582:
! 1583: typedef enum {HOP_INSERT, HOP_REPLACE} HISTOP;
! 1584: typedef enum {HDIR_PREV, HDIR_CURRENT, HDIR_NEXT} HISTDIR;
! 1585:
! 1586: /*
! 1587: * Get next history entry
! 1588: */
! 1589: next_history()
! 1590: {
! 1591: return (serv_history (HOP_REPLACE, HDIR_NEXT));
! 1592: }
! 1593:
! 1594: /*
! 1595: * Get next history entry
! 1596: */
! 1597: previous_history()
! 1598: {
! 1599: return (serv_history (HOP_REPLACE, HDIR_PREV));
! 1600: }
! 1601:
! 1602: /*
! 1603: * Insert next history entry
! 1604: */
! 1605: insert_current_history()
! 1606: {
! 1607: return (serv_history (HOP_INSERT, HDIR_CURRENT));
! 1608: }
! 1609:
! 1610: /*
! 1611: * Insert next history entry
! 1612: */
! 1613: insert_next_history()
! 1614: {
! 1615: return (serv_history (HOP_INSERT, HDIR_NEXT));
! 1616: }
! 1617:
! 1618: /*
! 1619: * Insert next history entry
! 1620: */
! 1621: insert_previous_history()
! 1622: {
! 1623: return (serv_history (HOP_INSERT, HDIR_PREV));
! 1624: }
! 1625:
! 1626: /*
! 1627: * Get previous history
! 1628: */
! 1629: serv_history(op, dir)
! 1630: HISTOP op;
! 1631: HISTDIR dir;
! 1632: {
! 1633: register char *cp;
! 1634: char *getPreviousHistory (), *getNextHistory (), *getCurrentHistory ();
! 1635: int diff;
! 1636:
! 1637: switch (dir) {
! 1638: case HDIR_PREV: cp = getPreviousHistory (); break;
! 1639: case HDIR_NEXT: cp = getNextHistory (); break;
! 1640: case HDIR_CURRENT: cp = getCurrentHistory (); break;
! 1641: default: cp = (char*)0;
! 1642: }
! 1643:
! 1644: if (cp == (char *)0) {
! 1645: errorBell ();
! 1646: return (0);
! 1647: }
! 1648:
! 1649: if (op == HOP_REPLACE)
! 1650: (void) delete_line ();
! 1651: (void) insert_string (cp);
! 1652: return (0);
! 1653: }
! 1654:
! 1655: /*
! 1656: * Show history
! 1657: */
! 1658: show_history()
! 1659: {
! 1660:
! 1661: (void) clear_edit_line ();
! 1662: hist_showHistory (lookd_var ("showhist"));
! 1663: (void) recover_edit_line (1);
! 1664: }
! 1665:
! 1666: /*
! 1667: * Do nothing
! 1668: */
! 1669: ignore()
! 1670: {
! 1671: return(0);
! 1672: }
! 1673:
! 1674: /*
! 1675: * Next character is literal
! 1676: */
! 1677: literal_next()
! 1678: {
! 1679:
! 1680: return (self_insert (getcharacter ()));
! 1681: }
! 1682:
! 1683: /*
! 1684: * Reprint command line
! 1685: */
! 1686: reprint()
! 1687: {
! 1688:
! 1689: (void) clear_edit_line ();
! 1690: (void) recover_edit_line (1);
! 1691: return (0);
! 1692: }
! 1693:
! 1694: /*
! 1695: * Print whole command line and move cursor to the current position
! 1696: */
! 1697: print_com_line()
! 1698: {
! 1699:
! 1700: printS (CommandLine);
! 1701: if (CommandLine[CurrentPosition] != '\0') {
! 1702: repeat (BS, howlong(&CommandLine[CurrentPosition + 1], 0));
! 1703: (void) putchar (BS);
! 1704: }
! 1705: }
! 1706:
! 1707: /*
! 1708: * Calcurate space of string using "^" for control character
! 1709: */
! 1710: howlong(s, n)
! 1711: char *s;
! 1712: int n;
! 1713: {
! 1714: register char *sp;
! 1715: register int area = 0;
! 1716:
! 1717: if (n == 0)
! 1718: n = -1;
! 1719: for (sp = s; *sp && n; sp++, n--) {
! 1720: if (isctlchar(*sp))
! 1721: area += 2;
! 1722: else
! 1723: area += 1;
! 1724: }
! 1725: return (area);
! 1726: }
! 1727:
! 1728: /*
! 1729: * Repeat puting character n times
! 1730: */
! 1731: repeat(c, n)
! 1732: char c;
! 1733: register int n;
! 1734: {
! 1735: for (n = n; n; n--)
! 1736: (void) putchar(c);
! 1737: }
! 1738:
! 1739: /*
! 1740: * Repeat putting string n times
! 1741: */
! 1742: repeat_string(s, n)
! 1743: char *s;
! 1744: register int n;
! 1745: {
! 1746: for (n = n; n; n--)
! 1747: fputs(s, stdout);
! 1748: }
! 1749:
! 1750: /*
! 1751: * Expand file name
! 1752: */
! 1753: expand_file_name ()
! 1754: {
! 1755: CHAR *cp, *start_expand;
! 1756: char *x_dirname();
! 1757: char dir[256];
! 1758: char *fileList[256];
! 1759: CHAR line[256];
! 1760: DIR *dirp, *x_opendir();
! 1761: struct direct *dp;
! 1762: int found = 0;
! 1763: int i;
! 1764: int tilde_expanded = 0;
! 1765: CHAR *index(), *rindex();
! 1766:
! 1767: if (delimiters == NULL)
! 1768: delimiters = DEFAULT_DELIMITERS;
! 1769: strcpy (line, CommandLine);
! 1770: for (cp = &line[CurrentPosition] - 1; cp > line ; --cp) {
! 1771: if (index (delimiters, *(cp - 1)))
! 1772: break;
! 1773: }
! 1774: start_expand = cp;
! 1775: if (any ('/', cp)) {
! 1776: (void) strcpy (dir, cp);
! 1777: *(rindex (dir, '/') + 1) = '\0';
! 1778: cp = (CHAR *) (rindex (cp, '/') + 1);
! 1779: }
! 1780: else
! 1781: strcpy (dir, ".");
! 1782:
! 1783: if ((dirp = x_opendir (dir)) == NULL) {
! 1784: errorBell ();
! 1785: return (0);
! 1786: }
! 1787:
! 1788: for (dp = readdir(dirp), i = 0; dp != NULL; dp = readdir(dirp)) {
! 1789:
! 1790: if (*cp == '\0')
! 1791: break;
! 1792:
! 1793: if (*cp != '.' && *(dp->d_name) == '.')
! 1794: continue;
! 1795:
! 1796: if (prefix (cp, dp->d_name)) {
! 1797: char *fcp;
! 1798:
! 1799: # ifdef ALLOCA
! 1800: fcp = (char *) alloca (strlen (dp->d_name) + 1);
! 1801: # else /* ALLOCA */
! 1802: fcp = (char *) malloc (strlen (dp->d_name) + 1);
! 1803: # endif /* ALLOCA */
! 1804: if (fcp == 0) {
! 1805: fputs ("\r\n", stdout);
! 1806: perror ("alloca:");
! 1807: reprint ();
! 1808: longjmp (jbuf, 1);
! 1809: }
! 1810: strcpy (fcp, dp->d_name);
! 1811: fileList [i++] = fcp;
! 1812: }
! 1813: }
! 1814: fileList [i] = (char *) 0;
! 1815:
! 1816: if (*start_expand == '~' && look_var ("expand-tilde")) {
! 1817: char buf [256], *p;
! 1818:
! 1819: strcpy (buf, start_expand);
! 1820: p = x_dirname (buf);
! 1821: if (!eq (p, buf)) {
! 1822: (void) moveto (start_expand - line);
! 1823: (void) kill_to_end_of_line ();
! 1824: (void) insert_string (x_dirname (buf));
! 1825: tilde_expanded = 1;
! 1826: }
! 1827: }
! 1828:
! 1829: switch (i) {
! 1830:
! 1831: case 0:
! 1832: if (tilde_expanded == 0)
! 1833: errorBell ();
! 1834: break;
! 1835:
! 1836: case 1:
! 1837: (void) end_of_line ();
! 1838: (void) insert_string (fileList[0] + strlen (cp));
! 1839: break;
! 1840:
! 1841: default:
! 1842: {
! 1843: char *one, *other;
! 1844: char *c1, *c2;
! 1845: int i;
! 1846:
! 1847: one = fileList [0];
! 1848: for (i = 1; other = fileList [i]; i++) {
! 1849: for (c1 = one, c2 = other; *c1 && *c2; c1++, c2++)
! 1850: if (*c1 != *c2)
! 1851: break;
! 1852: *c1 = '\0';
! 1853: }
! 1854: errorBell ();
! 1855: (void) end_of_line ();
! 1856: (void) insert_string (fileList[0] + strlen (cp));
! 1857: }
! 1858: break;
! 1859: }
! 1860:
! 1861: # ifndef ALLOCA
! 1862: for (i = 0; fileList [i]; i++)
! 1863: free (fileList [i]);
! 1864: # endif /* ALLOCA */
! 1865:
! 1866: closedir(dirp);
! 1867: return (0);
! 1868: }
! 1869:
! 1870: /*
! 1871: * List file name
! 1872: */
! 1873: list_file_name ()
! 1874: {
! 1875: CHAR *cp;
! 1876: char dir[256];
! 1877: DIR *dirp, *x_opendir();
! 1878: CHAR *index(), *rindex();
! 1879:
! 1880: if (delimiters == NULL)
! 1881: delimiters = DEFAULT_DELIMITERS;
! 1882: for (cp = (CHAR *) index (CommandLine, '\0'); cp > CommandLine ; --cp) {
! 1883: if (index (delimiters, *(cp - 1))) {
! 1884: break;
! 1885: }
! 1886: }
! 1887: #ifdef RINFO
! 1888: /*
! 1889: * This is an experimental code for rinfod, which serves remote
! 1890: * information about file, process, etc.
! 1891: */
! 1892: if (any (':', cp)) {
! 1893: char *host, *pattern;
! 1894:
! 1895: (void) strcpy (dir, cp);
! 1896: host = dir;
! 1897: *(index (host, ':')) = '\0';
! 1898: pattern = (index (cp, ':') + 1);;
! 1899:
! 1900: (void) clear_edit_line();
! 1901: list_remote_file (host, pattern);
! 1902: (void) recover_edit_line (1);
! 1903: return;
! 1904: }
! 1905: #endif
! 1906: if (any ('/', cp)) {
! 1907: (void) strcpy (dir, cp);
! 1908: *(rindex (dir, '/') + 1) = '\0';
! 1909: cp = (CHAR *) (rindex (cp, '/') + 1);
! 1910: }
! 1911: else
! 1912: strcpy (dir, ".");
! 1913:
! 1914:
! 1915: if ((dirp = x_opendir (dir)) == NULL) {
! 1916: errorBell ();
! 1917: return (0);
! 1918: }
! 1919:
! 1920: (void) clear_edit_line();
! 1921: ls (dirp, cp);
! 1922: closedir(dirp);
! 1923: (void) recover_edit_line (1);
! 1924:
! 1925: return (0);
! 1926: }
! 1927:
! 1928: int rememberPosition;
! 1929:
! 1930: clear_edit_line ()
! 1931: {
! 1932:
! 1933: if (editstatus == NOTEDITING)
! 1934: return;
! 1935:
! 1936: rememberPosition = CurrentPosition;
! 1937: (void) end_of_line ();
! 1938: (void) fputs ("\r\n", stdout);
! 1939: }
! 1940:
! 1941: recover_edit_line (put_prompt)
! 1942: int put_prompt;
! 1943: {
! 1944:
! 1945: if (editstatus == NOTEDITING)
! 1946: return;
! 1947:
! 1948: if (rememberPosition < 0)
! 1949: return;
! 1950: CurrentPosition = rememberPosition;
! 1951: rememberPosition = -1;
! 1952: if (put_prompt && prompt)
! 1953: fputs (prompt, stdout);
! 1954: (void) print_com_line();
! 1955: }
! 1956:
! 1957: #define MAXFILES 256
! 1958:
! 1959: /*
! 1960: * Do ls
! 1961: */
! 1962: ls (dirp, prefixstring)
! 1963: DIR *dirp;
! 1964: char *prefixstring;
! 1965: {
! 1966: struct direct *dp;
! 1967: char *fileList[MAXFILES + 1];
! 1968: int i, j;
! 1969: int maxlen = 0;
! 1970: int files; /* number of file */
! 1971: int fpl; /* file par line */
! 1972: int cpf; /* column par file */
! 1973: int fpc; /* file par column */
! 1974: int COL = 80;
! 1975: char format[10];
! 1976: int scmp();
! 1977:
! 1978: for (dp = readdir(dirp), i = 0; dp != NULL; dp = readdir(dirp)) {
! 1979: char *fcp;
! 1980:
! 1981: if (i >= MAXFILES) {
! 1982: printf ("Too many files\n");
! 1983: break;
! 1984: }
! 1985:
! 1986: if (dp->d_ino == (unsigned long) 0
! 1987: || (prefixstring[0] != '.' && dp->d_name[0] == '.'))
! 1988: continue;
! 1989: if (prefix (prefixstring, dp->d_name)) {
! 1990: # ifdef ALLOCA
! 1991: fcp = (char *) alloca (strlen (dp->d_name) + 1);
! 1992: # else /* ALLOCA */
! 1993: fcp = (char *) malloc (strlen (dp->d_name) + 1);
! 1994: # endif /* ALLOCA */
! 1995: if (fcp == 0) {
! 1996: fputs ("\r\n", stdout);
! 1997: perror ("alloca:");
! 1998: reprint ();
! 1999: longjmp (jbuf, 1);
! 2000: }
! 2001: strcpy (fcp, dp->d_name);
! 2002: fileList [i++] = fcp;
! 2003: maxlen = max (maxlen, strlen (dp->d_name));
! 2004: }
! 2005: }
! 2006: fileList [i] = (char *) 0;
! 2007:
! 2008: if (i == 0)
! 2009: goto BACK;
! 2010:
! 2011: files = i;
! 2012:
! 2013: qsort (fileList, i, sizeof (char *), scmp);
! 2014:
! 2015: if (debug)
! 2016: printf ("%d files\n", files);
! 2017:
! 2018: cpf = maxlen + 1;
! 2019: fpl = COL / cpf;
! 2020: if (fpl == 0) fpl = 1;
! 2021: fpc = (files + fpl - 1) / fpl;
! 2022:
! 2023: sprintf (format, "%%-%ds", cpf);
! 2024: for (i = 0; i < fpc; i++) {
! 2025: for (j = 0; j < fpl - 1; j++)
! 2026: if (i + j * fpc < files)
! 2027: printf (format, fileList[i + (j * fpc)]);
! 2028: if (i + (fpc * (fpl - 1)) < files)
! 2029: printf ("%s", fileList[i + (fpc * (fpl - 1))]);
! 2030: fputs ("\n", stdout);
! 2031: }
! 2032:
! 2033: BACK:
! 2034:
! 2035: # ifndef ALLOCA
! 2036: for (i = 0; fileList [i]; i++)
! 2037: free (fileList [i]);
! 2038: # endif /* ALLOCA */
! 2039: return;
! 2040: }
! 2041:
! 2042: #ifdef RINFO
! 2043:
! 2044: #include "../rinfo/rinfo.h"
! 2045:
! 2046: list_remote_file (host, pattern)
! 2047: char *host, *pattern;
! 2048: {
! 2049: struct slist *slp, *getfilelist();
! 2050: int i, j;
! 2051: char format [64];
! 2052: int COL = 80;
! 2053: int maxlen, cpf, fpl, fpc;
! 2054: int files;
! 2055:
! 2056: slp = getfilelist (host, pattern);
! 2057: files = slp->s_cnt;
! 2058:
! 2059: COL = 80;
! 2060: maxlen = 0;
! 2061: for (i = 0; i < files; i++) {
! 2062: int len;
! 2063:
! 2064: if ((len = strlen (*(slp->s_list + i))) > maxlen)
! 2065: maxlen = len;
! 2066: }
! 2067:
! 2068: cpf = maxlen + 1;
! 2069: fpl = COL / cpf;
! 2070: if (fpl == 0)
! 2071: fpl = 1;
! 2072: fpc = (files + fpl - 1) / fpl;
! 2073:
! 2074: sprintf (format, "%%-%ds", cpf);
! 2075: for (i = 0; i < fpc; i++) {
! 2076: for (j = 0; j < fpl - 1; j++) {
! 2077: if (i + j * fpc < slp->s_cnt)
! 2078: printf (format, *(slp->s_list + (i + (j * fpc))));
! 2079: }
! 2080: if (i + (fpc * (fpl - 1)) < files)
! 2081: printf ("%s", slp->s_list[i + (fpc * (fpl - 1))]);
! 2082: fputs ("\n", stdout);
! 2083: }
! 2084: }
! 2085: #endif /* RINFO */
! 2086:
! 2087: bind_key (ft, func, s, dfunc)
! 2088: FUNC ft[]; /* Function table */
! 2089: FUNC func; /* Function to be binded */
! 2090: char *s; /* String to bind */
! 2091: FUNC dfunc; /* Default function for table allocating */
! 2092: {
! 2093: char tmps[16];
! 2094:
! 2095: if (s[0] == '\\' && s[1] == '^' && s[2] != '\0') {
! 2096: tmps[0] = toctrl (s[2]);
! 2097: strcpy (&tmps[1], &s[3]);
! 2098: s = tmps;
! 2099: }
! 2100:
! 2101: /*
! 2102: * If the string contain only one character, put the function to
! 2103: * appropriate position in the table.
! 2104: */
! 2105: if (*(s+1) == '\0') {
! 2106: if (isIndirect (ft[(int) *s]))
! 2107: free (maskIndirect (ft[(int) *s]));
! 2108:
! 2109: ft[(int) *s] = func;
! 2110: return (1);
! 2111: }
! 2112: else {
! 2113: FUNC *nft = (FUNC *) 0;
! 2114: int status;
! 2115:
! 2116: /*
! 2117: * If the entry doesn't have indirect function table, allocate it.
! 2118: */
! 2119: if (! (isIndirect (ft[(int) *s]))) {
! 2120: register int i;
! 2121:
! 2122: nft = (FUNC *) calloc (sizeof (FUNC), 256);
! 2123: /*
! 2124: * If failed in allocating, return 0.
! 2125: */
! 2126: if (nft == 0)
! 2127: return (0);
! 2128:
! 2129: /*
! 2130: * Initialize the table with default function
! 2131: */
! 2132: for (i = 0; i < 256; i++)
! 2133: nft [i] = dfunc;
! 2134: ft[(int) *s] = setIndirect (nft);
! 2135: }
! 2136:
! 2137: status = bind_key (maskIndirect (ft[(int) *s]), func, s+1, dfunc);
! 2138: /*
! 2139: * If the binding failed and the table was allocated in this function
! 2140: * free the table and return with same status.
! 2141: */
! 2142: if (status == 0 && nft)
! 2143: free (nft);
! 2144: return (status);
! 2145: }
! 2146: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>