home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2326 < prev    next >
Internet Message Format  |  1990-12-28  |  81KB

  1. From: pfalstad@phoenix.Princeton.EDU (Paul John Falstad)
  2. Newsgroups: alt.sources
  3. Subject: zsh - ksh/tcsh-like shell (part 7 of 8)
  4. Message-ID: <4749@idunno.Princeton.EDU>
  5. Date: 14 Dec 90 23:33:21 GMT
  6.  
  7. ---cut here---cut here---cut here---
  8. -/* What YOU turn on when you have handled all redisplay yourself. */
  9. -int rl_display_fixed = 0;
  10. -
  11. -/* The visible cursor position.  If you print some text, adjust this. */
  12. -int last_c_pos = 0;
  13. -int last_v_pos = 0;
  14. -
  15. -/* The last left edge of text that was displayed.  This is used when
  16. -   doing horizontal scrolling.  It shifts in thirds of a screenwidth. */
  17. -static int last_lmargin = 0;
  18. -
  19. -/* The line display buffers.  One is the line currently displayed on
  20. -   the screen.  The other is the line about to be displayed. */
  21. -static char *visible_line = (char *)NULL;
  22. -static char *invisible_line = (char *)NULL;
  23. -
  24. -/* Number of lines currently on screen minus 1. */
  25. -int vis_botlin = 0;
  26. -
  27. -/* A buffer for `modeline' messages. */
  28. -char msg_buf[128];
  29. -
  30. -/* Non-zero forces the redisplay even if we thought it was unnecessary. */
  31. -int forced_display = 0;
  32. -
  33. -/* The stuff that gets printed out before the actual text of the line.
  34. -   This is usually pointing to rl_prompt. */
  35. -char *rl_display_prompt = (char *)NULL;
  36. -
  37. -/* Default and initial buffer size.  Can grow. */
  38. -static int line_size = 1024;
  39. -
  40. -/* Non-zero means to always use horizontal scrolling in line display. */
  41. -int horizontal_scroll_mode = 0;
  42. -
  43. -/* I really disagree with this, but my boss (among others) insists that we
  44. -   support compilers that don't work.  I don't think we are gaining by doing
  45. -   so; what is the advantage in producing better code if we can't use it? */
  46. -/* The following two declarations belong inside the
  47. -   function block, not here. */
  48. -static void move_cursor_relative ();
  49. -static void output_some_chars ();
  50. -static void output_character_function ();
  51. -static int compare_strings ();
  52. -
  53. -/* Basic redisplay algorithm. */
  54. -rl_redisplay ()
  55. -{
  56. -    register int in, out, c, linenum;
  57. -    register char *line = invisible_line;
  58. -    int c_pos = 0;
  59. -    int inv_botlin = 0;        /* Number of lines in newly drawn buffer. */
  60. -
  61. -    extern int readline_echoing_p;
  62. -
  63. -    if (!readline_echoing_p)
  64. -        return;
  65. -
  66. -    if (!rl_display_prompt)
  67. -        rl_display_prompt = "";
  68. -
  69. -    if (!invisible_line)
  70. -    {
  71. -        visible_line = (char *)xmalloc (line_size);
  72. -        invisible_line = (char *)xmalloc (line_size);
  73. -        line = invisible_line;
  74. -        for (in = 0; in < line_size; in++)
  75. -        {
  76. -            visible_line[in] = 0;
  77. -            invisible_line[in] = 1;
  78. -        }
  79. -        rl_on_new_line ();
  80. -    }
  81. -
  82. -    /* Draw the line into the buffer. */
  83. -    c_pos = -1;
  84. -
  85. -    /* Mark the line as modified or not.  We only do this for history
  86. -     lines.  No we don't.  -pjf */
  87. -    out = 0;
  88. -    /*if (current_history () && rl_undo_list)
  89. -    {
  90. -      line[out++] = '*';
  91. -      line[out] = '\0';
  92. -    }*/
  93. -
  94. -    /* If someone thought that the redisplay was handled, but the currently
  95. -     visible line has a different modification state than the one about
  96. -     to become visible, then correct the callers misconception. */
  97. -    if (visible_line[0] != invisible_line[0])
  98. -        rl_display_fixed = 0;
  99. -
  100. -    strncpy (line + out,  rl_display_prompt, strlen (rl_display_prompt));
  101. -    out += strlen (rl_display_prompt);
  102. -    line[out] = '\0';
  103. -
  104. -    for (in = 0; in < rl_end; in++)
  105. -    {
  106. -        c = the_line[in];
  107. -
  108. -        if (out + 1 >= line_size)
  109. -        {
  110. -            line_size *= 2;
  111. -            visible_line = (char *)xrealloc (visible_line, line_size);
  112. -            invisible_line = (char *)xrealloc (invisible_line, line_size);
  113. -            line = invisible_line;
  114. -        }
  115. -
  116. -        if (in == rl_point)
  117. -            c_pos = out;
  118. -
  119. -        if (c > 127)
  120. -        {
  121. -            line[out++] = 'M';
  122. -            line[out++] = '-';
  123. -            line[out++] = c - 128;
  124. -        }
  125. -#define DISPLAY_TABS
  126. -#ifdef DISPLAY_TABS
  127. -        else if (c == '\t')
  128. -        {
  129. -            register int newout = (out | (int)7) + 1;
  130. -            while (out < newout)
  131. -                line[out++] = ' ';
  132. -        }
  133. -#endif
  134. -        else if (c == '\n')
  135. -        {
  136. -            line[out++] = '\\';
  137. -            line[out++] = 'n';
  138. -        }
  139. -        else if (c < 32)
  140. -        {
  141. -            line[out++] = '^';
  142. -            line[out++] = c + 64;
  143. -        }
  144. -        else
  145. -            line[out++] = c;
  146. -    }
  147. -    line[out] = '\0';
  148. -    if (c_pos < 0)
  149. -        c_pos = out;
  150. -
  151. -    /* PWP: now is when things get a bit hairy.  The visible and invisible
  152. -     line buffers are really multiple lines, which would wrap every
  153. -     (screenwidth - 1) characters.  Go through each in turn, finding
  154. -     the changed region and updating it.  The line order is top to bottom. */
  155. -
  156. -    /* If we can move the cursor up and down, then use multiple lines,
  157. -     otherwise, let long lines display in a single terminal line, and
  158. -     horizontally scroll it. */
  159. -
  160. -    if (!horizontal_scroll_mode && term_up && *term_up)
  161. -    {
  162. -        int total_screen_chars = (screenwidth * screenheight);
  163. -
  164. -        if (!rl_display_fixed || forced_display)
  165. -        {
  166. -            forced_display = 0;
  167. -
  168. -            /* If we have more than a screenful of material to display, then
  169. -         only display a screenful.  We should display the last screen,
  170. -         not the first.  I'll fix this in a minute. */
  171. -            if (out >= total_screen_chars)
  172. -                out = total_screen_chars - 1;
  173. -
  174. -            /* Number of screen lines to display. */
  175. -            inv_botlin = out / screenwidth;
  176. -
  177. -            /* For each line in the buffer, do the updating display. */
  178. -            for (linenum = 0; linenum <= inv_botlin; linenum++)
  179. -                update_line (linenum > vis_botlin ? ""
  180. -                    : &visible_line[linenum * screenwidth],
  181. -                    &invisible_line[linenum * screenwidth],
  182. -                    linenum);
  183. -
  184. -            /* We may have deleted some lines.  If so, clear the left over
  185. -         blank ones at the bottom out. */
  186. -            if (vis_botlin > inv_botlin)
  187. -            {
  188. -                char *tt;
  189. -                for (; linenum <= vis_botlin; linenum++)
  190. -                {
  191. -                    tt = &visible_line[linenum * screenwidth];
  192. -                    move_vert (linenum);
  193. -                    move_cursor_relative (0, tt);
  194. -                    clear_to_eol ((linenum == vis_botlin)?
  195. -                        strlen (tt) : screenwidth);
  196. -                }
  197. -            }
  198. -            vis_botlin = inv_botlin;
  199. -
  200. -            /* Move the cursor where it should be. */
  201. -            move_vert (c_pos / screenwidth);
  202. -            move_cursor_relative (c_pos % screenwidth,
  203. -                &invisible_line[(c_pos / screenwidth) * screenwidth]);
  204. -        }
  205. -    }
  206. -    else    /* Do horizontal scrolling. */
  207. -    {
  208. -        int lmargin;
  209. -
  210. -        /* Always at top line. */
  211. -        last_v_pos = 0;
  212. -
  213. -        /* If the display position of the cursor would be off the edge
  214. -     of the screen, start the display of this line at an offset that
  215. -     leaves the cursor on the screen. */
  216. -        if (c_pos - last_lmargin > screenwidth - 2)
  217. -            lmargin = (c_pos / (screenwidth / 3) - 2) * (screenwidth / 3);
  218. -        else if (c_pos - last_lmargin < 1)
  219. -            lmargin = ((c_pos - 1) / (screenwidth / 3)) * (screenwidth / 3);
  220. -        else
  221. -            lmargin = last_lmargin;
  222. -
  223. -        /* If the first character on the screen isn't the first character
  224. -     in the display line, indicate this with a special character. */
  225. -        if (lmargin > 0)
  226. -            line[lmargin] = '<';
  227. -
  228. -        if (lmargin + screenwidth < out)
  229. -            line[lmargin + screenwidth - 1] = '>';
  230. -
  231. -        if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
  232. -        {
  233. -            forced_display = 0;
  234. -            update_line (&visible_line[last_lmargin],
  235. -                &invisible_line[lmargin], 0);
  236. -
  237. -            move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
  238. -            last_lmargin = lmargin;
  239. -        }
  240. -    }
  241. -    fflush (out_stream);
  242. -
  243. -    /* Swap visible and non-visible lines. */
  244. -    {
  245. -        char *temp = visible_line;
  246. -        visible_line = invisible_line;
  247. -        invisible_line = temp;
  248. -        rl_display_fixed = 0;
  249. -    }
  250. -}
  251. -
  252. -/* PWP: update_line() is based on finding the middle difference of each
  253. -   line on the screen; vis:
  254. -
  255. -                 /old first difference
  256. -    /beginning of line   |              /old last same       /old EOL
  257. -    v             v              v                    v
  258. -old:    eddie> Oh, my little gruntle-buggy is to me, as lurgid as
  259. -new:    eddie> Oh, my little buggy says to me, as lurgid as
  260. -    ^             ^        ^               ^
  261. -    \beginning of line   |        \new last same       \new end of line
  262. -                 \new first difference
  263. -
  264. -   All are character pointers for the sake of speed.  Special cases for
  265. -   no differences, as well as for end of line additions must be handeled.
  266. -
  267. -   Could be made even smarter, but this works well enough */
  268. -static
  269. -update_line (old, new, current_line)
  270. -register char *old, *new;
  271. -int current_line;
  272. -{
  273. -    register char *ofd, *ols, *oe, *nfd, *nls, *ne;
  274. -    int lendiff, wsatend;
  275. -
  276. -    /* Find first difference. */
  277. -    for (ofd = old, nfd = new;
  278. -        (ofd - old < screenwidth) && *ofd && (*ofd == *nfd);
  279. -        ofd++, nfd++)
  280. -        ;
  281. -
  282. -    /* Move to the end of the screen line. */
  283. -    for (oe = ofd; ((oe - old) < screenwidth) && *oe; oe++);
  284. -    for (ne = nfd; ((ne - new) < screenwidth) && *ne; ne++);
  285. -
  286. -    /* If no difference, continue to next line. */
  287. -    if (ofd == oe && nfd == ne)
  288. -        return;
  289. -
  290. -    wsatend = 1;            /* flag for trailing whitespace */
  291. -    ols = oe - 1;            /* find last same */
  292. -    nls = ne - 1;
  293. -    while ((*ols == *nls) && (ols > ofd) && (nls > nfd))
  294. -    {
  295. -        if (*ols != ' ')
  296. -            wsatend = 0;
  297. -        ols--;
  298. -        nls--;
  299. -    }
  300. -
  301. -    if (wsatend)
  302. -    {
  303. -        ols = oe;
  304. -        nls = ne;
  305. -    }
  306. -    else if (*ols != *nls)
  307. -    {
  308. -        if (*ols)            /* don't step past the NUL */
  309. -            ols++;
  310. -        if (*nls)
  311. -            nls++;
  312. -    }
  313. -
  314. -    move_vert (current_line);
  315. -    move_cursor_relative (ofd - old, old);
  316. -
  317. -    /* if (len (new) > len (old)) */
  318. -    lendiff = (nls - nfd) - (ols - ofd);
  319. -
  320. -    /* Insert (diff(len(old),len(new)) ch */
  321. -    if (lendiff > 0)
  322. -    {
  323. -        if (terminal_can_insert)
  324. -        {
  325. -            extern char *term_IC;
  326. -
  327. -            /* Sometimes it is cheaper to print the characters rather than
  328. -         use the terminal's capabilities. */
  329. -            if ((2 * (ne - nfd)) < lendiff && !term_IC)
  330. -            {
  331. -                output_some_chars (nfd, (ne - nfd));
  332. -                last_c_pos += (ne - nfd);
  333. -            }
  334. -            else
  335. -            {
  336. -                if (*ols)
  337. -                {
  338. -                    insert_some_chars (nfd, lendiff);
  339. -                    last_c_pos += lendiff;
  340. -                }
  341. -                else
  342. -                {
  343. -                    /* At the end of a line the characters do not have to
  344. -             be "inserted".  They can just be placed on the screen. */
  345. -                    output_some_chars (nfd, lendiff);
  346. -                    last_c_pos += lendiff;
  347. -                }
  348. -                /* Copy (new) chars to screen from first diff to last match. */
  349. -                if (((nls - nfd) - lendiff) > 0)
  350. -                {
  351. -                    output_some_chars (&nfd[lendiff], ((nls - nfd) - lendiff));
  352. -                    last_c_pos += ((nls - nfd) - lendiff);
  353. -                }
  354. -            }
  355. -        }
  356. -        else
  357. -        {        /* cannot insert chars, write to EOL */
  358. -            output_some_chars (nfd, (ne - nfd));
  359. -            last_c_pos += (ne - nfd);
  360. -        }
  361. -    }
  362. -    else    /* Delete characters from line. */
  363. -    {
  364. -        /* If possible and inexpensive to use terminal deletion, then do so. */
  365. -        if (term_dc && (2 * (ne - nfd)) >= (-lendiff))
  366. -        {
  367. -            if (lendiff)
  368. -                delete_chars (-lendiff); /* delete (diff) characters */
  369. -
  370. -            /* Copy (new) chars to screen from first diff to last match */
  371. -            if ((nls - nfd) > 0)
  372. -            {
  373. -                output_some_chars (nfd, (nls - nfd));
  374. -                last_c_pos += (nls - nfd);
  375. -            }
  376. -        }
  377. -        /* Otherwise, print over the existing material. */
  378. -        else
  379. -        {
  380. -            output_some_chars (nfd, (ne - nfd));
  381. -            last_c_pos += (ne - nfd);
  382. -            clear_to_eol ((oe - old) - (ne - new));
  383. -        }
  384. -    }
  385. -}
  386. -
  387. -/* (PWP) tell the update routines that we have moved onto a
  388. -   new (empty) line. */
  389. -rl_on_new_line ()
  390. -{
  391. -    if (visible_line)
  392. -        visible_line[0] = '\0';
  393. -
  394. -    last_c_pos = last_v_pos = 0;
  395. -    vis_botlin = last_lmargin = 0;
  396. -}
  397. -
  398. -/* Actually update the display, period. */
  399. -rl_forced_update_display ()
  400. -{
  401. -    if (visible_line)
  402. -    {
  403. -        register char *temp = visible_line;
  404. -
  405. -        while (*temp) *temp++ = '\0';
  406. -    }
  407. -    rl_on_new_line ();
  408. -    forced_display++;
  409. -    rl_redisplay ();
  410. -}
  411. -
  412. -/* Move the cursor from last_c_pos to NEW, which are buffer indices.
  413. -   DATA is the contents of the screen line of interest; i.e., where
  414. -   the movement is being done. */
  415. -static void
  416. -move_cursor_relative (new, data)
  417. -int new;
  418. -char *data;
  419. -{
  420. -    register int i;
  421. -
  422. -    /* It may be faster to output a CR, and then move forwards instead
  423. -     of moving backwards. */
  424. -    if (new + 1 < last_c_pos - new)
  425. -    {
  426. -        tputs (term_cr, 1, output_character_function);
  427. -        last_c_pos = 0;
  428. -    }
  429. -
  430. -    if (last_c_pos == new) return;
  431. -
  432. -    if (last_c_pos < new)
  433. -    {
  434. -        /* Move the cursor forward.  We do it by printing the command
  435. -     to move the cursor forward if there is one, else print that
  436. -     portion of the output buffer again.  Which is cheaper? */
  437. -
  438. -        /* The above comment is left here for posterity.  It is faster
  439. -     to print one character (non-control) than to print a control
  440. -     sequence telling the terminal to move forward one character.
  441. -     That kind of control is for people who don't know what the
  442. -     data is underneath the cursor. */
  443. -#ifdef HACK_TERMCAP_MOTION
  444. -        extern char *term_forward_char;
  445. -
  446. -        if (term_forward_char)
  447. -            for (i = last_c_pos; i < new; i++)
  448. -                tputs (term_forward_char, 1, output_character_function);
  449. -        else
  450. -            for (i = last_c_pos; i < new; i++)
  451. -                putc (data[i], out_stream);
  452. -#else
  453. -        for (i = last_c_pos; i < new; i++)
  454. -            putc (data[i], out_stream);
  455. -#endif                /* HACK_TERMCAP_MOTION */
  456. -    }
  457. -    else
  458. -        backspace (last_c_pos - new);
  459. -    last_c_pos = new;
  460. -}
  461. -
  462. -/* PWP: move the cursor up or down. */
  463. -move_vert (to)
  464. -int to;
  465. -{
  466. -    void output_character_function ();
  467. -    register int delta, i;
  468. -
  469. -    if (last_v_pos == to) return;
  470. -
  471. -    if (to > screenheight)
  472. -        return;
  473. -
  474. -    if ((delta = to - last_v_pos) > 0)
  475. -    {
  476. -        for (i = 0; i < delta; i++)
  477. -            putc ('\n', out_stream);
  478. -        tputs (term_cr, 1, output_character_function);
  479. -        last_c_pos = 0;        /* because crlf() will do \r\n */
  480. -    }
  481. -    else
  482. -    {            /* delta < 0 */
  483. -        if (term_up && *term_up)
  484. -            for (i = 0; i < -delta; i++)
  485. -                tputs (term_up, 1, output_character_function);
  486. -    }
  487. -    last_v_pos = to;        /* now to is here */
  488. -}
  489. -
  490. -/* Physically print C on out_stream.  This is for functions which know
  491. -   how to optimize the display. */
  492. -rl_show_char (c)
  493. -int c;
  494. -{
  495. -    if (c > 127)
  496. -    {
  497. -        fprintf (out_stream, "M-");
  498. -        c -= 128;
  499. -    }
  500. -
  501. -#ifdef DISPLAY_TABS
  502. -    if (c < 32 && c != '\t')
  503. -#else
  504. -        if (c < 32)
  505. -#endif
  506. -        {
  507. -
  508. -            c += 64;
  509. -        }
  510. -
  511. -    putc (c, out_stream);
  512. -    fflush (out_stream);
  513. -}
  514. -
  515. -#ifdef DISPLAY_TABS
  516. -int
  517. -rl_character_len (c, pos)
  518. -register int c, pos;
  519. -{
  520. -    if (c < ' ' || c > 126)
  521. -    {
  522. -        if (c == '\t')
  523. -            return (((pos | (int)7) + 1) - pos);
  524. -        else
  525. -            return (3);
  526. -    }
  527. -    else
  528. -        return (1);
  529. -}
  530. -#else
  531. -int
  532. -rl_character_len (c)
  533. -int c;
  534. -{
  535. -    if (c < ' ' || c > 126)
  536. -        return (3);
  537. -    else
  538. -        return (1);
  539. -}
  540. -#endif  /* DISPLAY_TAB */
  541. -
  542. -/* How to print things in the "echo-area".  The prompt is treated as a
  543. -   mini-modeline. */
  544. -rl_message (string, arg1, arg2)
  545. -char *string;
  546. -{
  547. -    sprintf (msg_buf, string, arg1, arg2);
  548. -    rl_display_prompt = msg_buf;
  549. -    rl_redisplay ();
  550. -}
  551. -
  552. -/* How to clear things from the "echo-area". */
  553. -rl_clear_message ()
  554. -{
  555. -    rl_display_prompt = rl_prompt;
  556. -    rl_redisplay ();
  557. -}
  558. -
  559. -/* **************************************************************** */
  560. -/*                                    */
  561. -/*            Terminal and Termcap                */
  562. -/*                                    */
  563. -/* **************************************************************** */
  564. -
  565. -static char *term_buffer = (char *)NULL;
  566. -static char *term_string_buffer = (char *)NULL;
  567. -
  568. -/* Non-zero means this terminal can't really do anything. */
  569. -int dumb_term = 0;
  570. -
  571. -char PC;
  572. -char *BC, *UP;
  573. -
  574. -/* Some strings to control terminal actions.  These are output by tputs (). */
  575. -char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
  576. -
  577. -int screenwidth, screenheight;
  578. -
  579. -/* Non-zero if we determine that the terminal can do character insertion. */
  580. -int terminal_can_insert = 0;
  581. -
  582. -/* How to insert characters. */
  583. -char *term_im, *term_ei, *term_ic, *term_ip, *term_IC;
  584. -
  585. -/* How to delete characters. */
  586. -char *term_dc, *term_DC;
  587. -
  588. -#ifdef HACK_TERMCAP_MOTION
  589. -char *term_forward_char;
  590. -#endif  /* HACK_TERMCAP_MOTION */
  591. -
  592. -/* How to go up a line. */
  593. -char *term_up;
  594. -
  595. -/* Re-initialize the terminal considering that the TERM/TERMCAP variable
  596. -   has changed. */
  597. -rl_reset_terminal (terminal_name)
  598. -char *terminal_name;
  599. -{
  600. -    init_terminal_io (terminal_name);
  601. -}
  602. -
  603. -init_terminal_io (terminal_name)
  604. -char *terminal_name;
  605. -{
  606. -    char *term = (terminal_name? terminal_name : (char *)getenv ("TERM"));
  607. -    char *tgetstr (), *buffer;
  608. -
  609. -
  610. -    if (!term_string_buffer)
  611. -        term_string_buffer = (char *)xmalloc (2048);
  612. -
  613. -    if (!term_buffer)
  614. -        term_buffer = (char *)xmalloc (2048);
  615. -
  616. -    buffer = term_string_buffer;
  617. -
  618. -    term_clrpag = term_cr = term_clreol = (char *)NULL;
  619. -
  620. -    if (!term)
  621. -        term = "dumb";
  622. -
  623. -    if (tgetent (term_buffer, term) < 0)
  624. -    {
  625. -        dumb_term = 1;
  626. -        return;
  627. -    }
  628. -
  629. -    BC = tgetstr ("pc", &buffer);
  630. -    PC = buffer ? *buffer : 0;
  631. -
  632. -    term_backspace = tgetstr ("le", &buffer);
  633. -
  634. -    term_cr = tgetstr ("cr", &buffer);
  635. -    term_clreol = tgetstr ("ce", &buffer);
  636. -    term_clrpag = tgetstr ("cl", &buffer);
  637. -
  638. -    if (!term_cr)
  639. -        term_cr =  "\r";
  640. -
  641. -#ifdef HACK_TERMCAP_MOTION
  642. -    term_forward_char = tgetstr ("nd", &buffer);
  643. -#endif  /* HACK_TERMCAP_MOTION */
  644. -
  645. -    screenwidth = tgetnum ("co");
  646. -    if (screenwidth <= 0)
  647. -        screenwidth = 80;
  648. -    screenwidth--;        /* PWP: avoid autowrap bugs */
  649. -
  650. -    screenheight = tgetnum ("li");
  651. -    if (screenheight <= 0)
  652. -        screenheight = 24;
  653. -
  654. -    term_im = tgetstr ("im", &buffer);
  655. -    term_ei = tgetstr ("ei", &buffer);
  656. -    term_IC = tgetstr ("IC", &buffer);
  657. -    term_ic = tgetstr ("ic", &buffer);
  658. -
  659. -    /* "An application program can assume that the terminal can do
  660. -      character insertion if *any one of* the capabilities `IC',
  661. -      `im', `ic' or `ip' is provided."  But we can't do anything if
  662. -      only `ip' is provided, so... */
  663. -    terminal_can_insert = (term_IC || term_im || term_ic);
  664. -
  665. -    term_up = tgetstr ("up", &buffer);
  666. -    term_dc = tgetstr ("dc", &buffer);
  667. -    term_DC = tgetstr ("DC", &buffer);
  668. -}
  669. -
  670. -/* A function for the use of tputs () */
  671. -static void
  672. -output_character_function (c)
  673. -int c;
  674. -{
  675. -    putc (c, out_stream);
  676. -}
  677. -
  678. -/* Write COUNT characters from STRING to the output stream. */
  679. -static void
  680. -output_some_chars (string, count)
  681. -char *string;
  682. -int count;
  683. -{
  684. -    fwrite (string, 1, count, out_stream);
  685. -}
  686. -
  687. -
  688. -/* Delete COUNT characters from the display line. */
  689. -static
  690. -delete_chars (count)
  691. -int count;
  692. -{
  693. -    if (count > screenwidth)
  694. -        return;
  695. -
  696. -    if (term_DC && *term_DC)
  697. -    {
  698. -        char *tgoto (), *buffer;
  699. -        buffer = tgoto (term_DC, 0, count);
  700. -        tputs (buffer, 1, output_character_function);
  701. -    }
  702. -    else
  703. -    {
  704. -        if (term_dc && *term_dc)
  705. -            while (count--)
  706. -                tputs (term_dc, 1, output_character_function);
  707. -    }
  708. -}
  709. -
  710. -/* Insert COUNT character from STRING to the output stream. */
  711. -static
  712. -insert_some_chars (string, count)
  713. -char *string;
  714. -int count;
  715. -{
  716. -    /* If IC is defined, then we do not have to "enter" insert mode. */
  717. -    if (term_IC)
  718. -    {
  719. -        char *tgoto (), *buffer;
  720. -        buffer = tgoto (term_IC, 0, count);
  721. -        tputs (buffer, 1, output_character_function);
  722. -        output_some_chars (string, count);
  723. -    }
  724. -    else
  725. -    {
  726. -        register int i;
  727. -
  728. -        /* If we have to turn on insert-mode, then do so. */
  729. -        if (term_im && *term_im)
  730. -            tputs (term_im, 1, output_character_function);
  731. -
  732. -        /* If there is a special command for inserting characters, then
  733. -     use that first to open up the space. */
  734. -        if (term_ic && *term_ic)
  735. -        {
  736. -            for (i = count; i--; )
  737. -                tputs (term_ic, 1, output_character_function);
  738. -        }
  739. -
  740. -        /* Print the text. */
  741. -        output_some_chars (string, count);
  742. -
  743. -        /* If there is a string to turn off insert mode, we had best use
  744. -     it now. */
  745. -        if (term_ei && *term_ei)
  746. -            tputs (term_ei, 1, output_character_function);
  747. -    }
  748. -}
  749. -
  750. -/* Move the cursor back. */
  751. -backspace (count)
  752. -int count;
  753. -{
  754. -    register int i;
  755. -
  756. -    if (term_backspace)
  757. -        for (i = 0; i < count; i++)
  758. -            tputs (term_backspace, 1, output_character_function);
  759. -    else
  760. -        for (i = 0; i < count; i++)
  761. -            putc ('\b', out_stream);
  762. -}
  763. -
  764. -/* Move to the start of the next line. */
  765. -crlf ()
  766. -{
  767. -    tputs (term_cr, 1, output_character_function);
  768. -    putc ('\n', out_stream);
  769. -}
  770. -
  771. -/* Clear to the end of the line.  COUNT is the minimum
  772. -   number of character spaces to clear, */
  773. -clear_to_eol (count)
  774. -int count;
  775. -{
  776. -    if (term_clreol)
  777. -    {
  778. -        tputs (term_clreol, 1, output_character_function);
  779. -    }
  780. -    else
  781. -    {
  782. -        register int i;
  783. -
  784. -        /* Do one more character space. */
  785. -        count++;
  786. -
  787. -        for (i = 0; i < count; i++)
  788. -            putc (' ', out_stream);
  789. -
  790. -        backspace (count);
  791. -    }
  792. -}
  793. -
  794. -
  795. -/* **************************************************************** */
  796. -/*                                    */
  797. -/*              Saving and Restoring the TTY                */
  798. -/*                                    */
  799. -/* **************************************************************** */
  800. -
  801. -#ifdef NEW_TTY_DRIVER
  802. -
  803. -/* We use this to get and set the tty_flags. */
  804. -static struct sgttyb the_ttybuff;
  805. -
  806. -/* Put the terminal in CBREAK mode so that we can detect key presses. */
  807. -rl_prep_terminal ()
  808. -{
  809. -int original_tty_flags,local_mode_flags;
  810. -
  811. -    static int firsttime = 1;
  812. -    int tty = fileno (rl_instream);
  813. -
  814. -    /* We always get the latest tty values.  Maybe stty changed them. */
  815. -    ioctl (tty, TIOCGETP, &the_ttybuff);
  816. -    original_tty_flags = ((the_ttybuff.sg_flags)&~(O_CBREAK|O_RAW))|O_ECHO;
  817. -
  818. -    readline_echoing_p = (original_tty_flags & ECHO);
  819. -
  820. -    /* If this terminal doesn't care how the 8th bit is used,
  821. -     then we can use it for the meta-key.
  822. -     We check by seeing if BOTH odd and even parity are allowed. */
  823. -    if ((the_ttybuff.sg_flags & ODDP) && (the_ttybuff.sg_flags & EVENP))
  824. -    {
  825. -#ifdef PASS8
  826. -        the_ttybuff.sg_flags |= PASS8;
  827. -#endif
  828. -    }
  829. -
  830. -    /* Hack on local mode flags if we can. */
  831. -#if defined (TIOCLGET) && defined (LPASS8)
  832. -    {
  833. -        int flags;
  834. -
  835. -        ioctl (tty, TIOCLGET, &local_mode_flags);
  836. -        flags = local_mode_flags | LPASS8;
  837. -        ioctl (tty, TIOCLSET, &flags);
  838. -    }
  839. -#endif
  840. -
  841. -#ifdef TIOCGETC
  842. -    {
  843. -        struct tchars temp;
  844. -
  845. -        ioctl (tty, TIOCGETC, &temp);
  846. -
  847. -        /* Get rid of C-s and C-q.
  848. -       We remember the value of startc (C-q) so that if the terminal is in
  849. -       xoff state, the user can xon it by pressing that character. */
  850. -        xon_char = temp.t_startc;
  851. -        temp.t_stopc = -1;
  852. -        temp.t_startc = -1;
  853. -
  854. -        /* If there is an XON character, bind it to restart the output. */
  855. -        if (xon_char != -1)
  856. -            rl_bind_key (xon_char, rl_restart_output);
  857. -
  858. -        /* If there is an EOF char, bind eof_char to it. */
  859. -        if (temp.t_eofc != -1)
  860. -            eof_char = temp.t_eofc;
  861. -
  862. -#ifdef NEVER
  863. -        /* Get rid of C-\ and C-c. */
  864. -        temp.t_intrc = temp.t_quitc = -1;
  865. -#endif
  866. -
  867. -        ioctl (tty, TIOCSETC, &temp);
  868. -    }
  869. -#endif /* TIOCGETC */
  870. -
  871. -#ifdef TIOCGLTC
  872. -    {
  873. -        struct ltchars temp;
  874. -
  875. -        ioctl (tty, TIOCGLTC, &temp);
  876. -
  877. -        /* Make the interrupt keys go away.  Just enough to make people happy. */
  878. -        temp.t_dsuspc = -1;        /* C-y */
  879. -        temp.t_lnextc = -1;        /* C-v */
  880. -
  881. -        ioctl (tty, TIOCSLTC, &temp);
  882. -    }
  883. -#endif /* TIOCGLTC */
  884. -
  885. -    the_ttybuff.sg_flags &= ~ECHO;
  886. -    the_ttybuff.sg_flags |= CBREAK;
  887. -    ioctl (tty, TIOCSETN, &the_ttybuff);
  888. -}
  889. -
  890. -
  891. -#else  /* !defined (NEW_TTY_DRIVER) */
  892. -
  893. -#if !defined (VMIN)
  894. -#define VMIN VEOF
  895. -#endif
  896. -
  897. -#if !defined (VTIME)
  898. -#define VTIME VEOL
  899. -#endif
  900. -
  901. -static struct termio otio;
  902. -
  903. -rl_prep_terminal ()
  904. -{
  905. -    int tty = fileno (rl_instream);
  906. -    struct termio tio;
  907. -
  908. -    ioctl (tty, TCGETA, &tio);
  909. -    ioctl (tty, TCGETA, &otio);
  910. -
  911. -    readline_echoing_p = (tio.c_lflag & ECHO);
  912. -
  913. -    tio.c_lflag &= ~(ICANON|ECHO);
  914. -    tio.c_iflag &= ~(IXON|IXOFF|IXANY|ISTRIP|INPCK);
  915. -
  916. -#if !defined (HANDLE_SIGNALS)
  917. -    tio.c_lflag &= ~ISIG;
  918. -#endif
  919. -
  920. -    tio.c_cc[VMIN] = 1;
  921. -    tio.c_cc[VTIME] = 0;
  922. -    ioctl (tty, TCSETAW, &tio);
  923. -    ioctl (tty, TCXONC, 1);    /* Simulate a ^Q. */
  924. -}
  925. -
  926. -#endif  /* NEW_TTY_DRIVER */
  927. -
  928. -/* Restore the terminal to its original state. */
  929. -rl_deprep_terminal ()
  930. -{
  931. -    rl_active = 0;
  932. -    restoretty();
  933. -}
  934. -
  935. -
  936. -/* **************************************************************** */
  937. -/*                                    */
  938. -/*            Utility Functions                */
  939. -/*                                    */
  940. -/* **************************************************************** */
  941. -
  942. -/* Return 0 if C is not a member of the class of characters that belong
  943. -   in words, or 1 if it is. */
  944. -
  945. -int allow_pathname_alphabetic_chars = 0;
  946. -char *pathname_alphabetic_chars = "/-_=~.#$";
  947. -
  948. -int
  949. -alphabetic (c)
  950. -int c;
  951. -{
  952. -    char *rindex ();
  953. -    if (pure_alphabetic (c) || (numeric (c)))
  954. -        return (1);
  955. -
  956. -    if (allow_pathname_alphabetic_chars)
  957. -        return ((int)rindex (pathname_alphabetic_chars, c));
  958. -    else
  959. -        return (0);
  960. -}
  961. -
  962. -/* Return non-zero if C is a numeric character. */
  963. -int
  964. -numeric (c)
  965. -int c;
  966. -{
  967. -    return (c >= '0' && c <= '9');
  968. -}
  969. -
  970. -/* Ring the terminal bell. */
  971. -int
  972. -ding ()
  973. -{
  974. -extern int opts[128];
  975. -
  976. -    if (readline_echoing_p && opts['B'] == 0)
  977. -    {
  978. -        fprintf (stderr, "\007");
  979. -        fflush (stderr);
  980. -    }
  981. -    return (-1);
  982. -}
  983. -
  984. -/* How to abort things. */
  985. -rl_abort ()
  986. -{
  987. -    ding ();
  988. -    rl_clear_message ();
  989. -    rl_init_argument ();
  990. -    rl_pending_input = 0;
  991. -
  992. -    defining_kbd_macro = 0;
  993. -    while (executing_macro)
  994. -        pop_executing_macro ();
  995. -
  996. -    longjmp (readline_top_level, 1);
  997. -}
  998. -
  999. -/* Return a copy of the string between FROM and TO.
  1000. -   FROM is inclusive, TO is not. */
  1001. -static char *
  1002. -rl_copy (from, to)
  1003. -int from, to;
  1004. -{
  1005. -    register int length;
  1006. -    char *copy;
  1007. -
  1008. -    /* Fix it if the caller is confused. */
  1009. -    if (from > to) {
  1010. -        int t = from;
  1011. -        from = to;
  1012. -        to = t;
  1013. -    }
  1014. -
  1015. -    length = to - from;
  1016. -    copy = (char *)xmalloc (1 + length);
  1017. -    strncpy (copy, the_line + from, length);
  1018. -    copy[length] = '\0';
  1019. -    return (copy);
  1020. -}
  1021. -
  1022. -
  1023. -/* **************************************************************** */
  1024. -/*                                    */
  1025. -/*            Insert and Delete                */
  1026. -/*                                    */
  1027. -/* **************************************************************** */
  1028. -
  1029. -
  1030. -/* Insert a string of text into the line at point.  This is the only
  1031. -   way that you should do insertion.  rl_insert () calls this
  1032. -   function. */
  1033. -rl_insert_text (string)
  1034. -char *string;
  1035. -{
  1036. -    extern int doing_an_undo;
  1037. -    register int i, l = strlen (string);
  1038. -    while (rl_end + l >= rl_line_buffer_len)
  1039. -    {
  1040. -        rl_line_buffer =
  1041. -            (char *)xrealloc (rl_line_buffer,
  1042. -            rl_line_buffer_len += DEFAULT_BUFFER_SIZE);
  1043. -        the_line = rl_line_buffer;
  1044. -    }
  1045. -
  1046. -    for (i = rl_end; i >= rl_point; i--)
  1047. -        the_line[i + l] = the_line[i];
  1048. -    strncpy (the_line + rl_point, string, l);
  1049. -
  1050. -    /* Remember how to undo this if we aren't undoing something. */
  1051. -    if (!doing_an_undo)
  1052. -    {
  1053. -        /* If possible and desirable, concatenate the undos. */
  1054. -        if ((strlen (string) == 1) &&
  1055. -            rl_undo_list &&
  1056. -            (rl_undo_list->what == UNDO_INSERT) &&
  1057. -            (rl_undo_list->end == rl_point) &&
  1058. -            (rl_undo_list->end - rl_undo_list->start < 20))
  1059. -            rl_undo_list->end++;
  1060. -        else
  1061. -            rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
  1062. -    }
  1063. -    rl_point += l;
  1064. -    rl_end += l;
  1065. -    the_line[rl_end] = '\0';
  1066. -}
  1067. -
  1068. -/* Delete the string between FROM and TO.  FROM is
  1069. -   inclusive, TO is not. */
  1070. -rl_delete_text (from, to)
  1071. -int from, to;
  1072. -{
  1073. -    extern int doing_an_undo;
  1074. -    register char *text;
  1075. -
  1076. -    /* Fix it if the caller is confused. */
  1077. -    if (from > to) {
  1078. -        int t = from;
  1079. -        from = to;
  1080. -        to = t;
  1081. -    }
  1082. -    text = rl_copy (from, to);
  1083. -    strncpy (the_line + from, the_line + to, rl_end - to);
  1084. -
  1085. -    /* Remember how to undo this delete. */
  1086. -    if (!doing_an_undo)
  1087. -        rl_add_undo (UNDO_DELETE, from, to, text);
  1088. -    else
  1089. -        free (text);
  1090. -
  1091. -    rl_end -= (to - from);
  1092. -    the_line[rl_end] = '\0';
  1093. -}
  1094. -
  1095. -
  1096. -/* **************************************************************** */
  1097. -/*                                    */
  1098. -/*            Readline character functions            */
  1099. -/*                                    */
  1100. -/* **************************************************************** */
  1101. -
  1102. -/* This is not a gap editor, just a stupid line input routine.  No hair
  1103. -   is involved in writing any of the functions, and none should be. */
  1104. -
  1105. -/* Note that:
  1106. -
  1107. -   rl_end is the place in the string that we would place '\0';
  1108. -   i.e., it is always safe to place '\0' there.
  1109. -
  1110. -   rl_point is the place in the string where the cursor is.  Sometimes
  1111. -   this is the same as rl_end.
  1112. -
  1113. -   Any command that is called interactively receives two arguments.
  1114. -   The first is a count: the numeric arg pased to this command.
  1115. -   The second is the key which invoked this command.
  1116. -*/
  1117. -
  1118. -
  1119. -/* **************************************************************** */
  1120. -/*                                    */
  1121. -/*            Movement Commands                */
  1122. -/*                                    */
  1123. -/* **************************************************************** */
  1124. -
  1125. -/* Note that if you `optimize' the display for these functions, you cannot
  1126. -   use said functions in other functions which do not do optimizing display.
  1127. -   I.e., you will have to update the data base for rl_redisplay, and you
  1128. -   might as well let rl_redisplay do that job. */
  1129. -
  1130. -/* Move forward COUNT characters. */
  1131. -rl_forward (count)
  1132. -int count;
  1133. -{
  1134. -    if (count < 0)
  1135. -        rl_backward (-count);
  1136. -    else
  1137. -        while (count)
  1138. -        {
  1139. -#ifdef VI_MODE
  1140. -            if (rl_point == (rl_end - (rl_editing_mode == vi_mode)))
  1141. -#else
  1142. -                if (rl_point == rl_end)
  1143. -#endif
  1144. -                {
  1145. -                    ding ();
  1146. -                    return;
  1147. -                }
  1148. -                else
  1149. -                    rl_point++;
  1150. -            --count;
  1151. -        }
  1152. -}
  1153. -
  1154. -/* Move backward COUNT characters. */
  1155. -rl_backward (count)
  1156. -int count;
  1157. -{
  1158. -    if (count < 0)
  1159. -        rl_forward (-count);
  1160. -    else
  1161. -        while (count)
  1162. -        {
  1163. -            if (!rl_point)
  1164. -            {
  1165. -                ding ();
  1166. -                return;
  1167. -            }
  1168. -            else
  1169. -                --rl_point;
  1170. -            --count;
  1171. -        }
  1172. -}
  1173. -
  1174. -/* Move to the beginning of the line. */
  1175. -rl_beg_of_line ()
  1176. -{
  1177. -    rl_point = 0;
  1178. -}
  1179. -
  1180. -/* Move to the end of the line. */
  1181. -rl_end_of_line ()
  1182. -{
  1183. -    rl_point = rl_end;
  1184. -}
  1185. -
  1186. -/* Move forward a word.  We do what Emacs does. */
  1187. -rl_forward_word (count)
  1188. -int count;
  1189. -{
  1190. -    int c;
  1191. -
  1192. -    if (count < 0)
  1193. -    {
  1194. -        rl_backward_word (-count);
  1195. -        return;
  1196. -    }
  1197. -
  1198. -    while (count)
  1199. -    {
  1200. -        if (rl_point == rl_end)
  1201. -            return;
  1202. -
  1203. -        /* If we are not in a word, move forward until we are in one.
  1204. -     Then, move forward until we hit a non-alphabetic character. */
  1205. -        c = the_line[rl_point];
  1206. -        if (!alphabetic (c))
  1207. -        {
  1208. -            while (++rl_point < rl_end)
  1209. -            {
  1210. -                c = the_line[rl_point];
  1211. -                if (alphabetic (c)) break;
  1212. -            }
  1213. -        }
  1214. -        if (rl_point == rl_end) return;
  1215. -        while (++rl_point < rl_end)
  1216. -        {
  1217. -            c = the_line[rl_point];
  1218. -            if (!alphabetic (c)) break;
  1219. -        }
  1220. -        --count;
  1221. -    }
  1222. -}
  1223. -
  1224. -/* Move backward a word.  We do what Emacs does. */
  1225. -rl_backward_word (count)
  1226. -int count;
  1227. -{
  1228. -    int c;
  1229. -
  1230. -    if (count < 0)
  1231. -    {
  1232. -        rl_forward_word (-count);
  1233. -        return;
  1234. -    }
  1235. -
  1236. -    while (count)
  1237. -    {
  1238. -        if (!rl_point)
  1239. -            return;
  1240. -
  1241. -        /* Like rl_forward_word (), except that we look at the characters
  1242. -     just before point. */
  1243. -
  1244. -        c = the_line[rl_point - 1];
  1245. -        if (!alphabetic (c))
  1246. -        {
  1247. -            while (--rl_point)
  1248. -            {
  1249. -                c = the_line[rl_point - 1];
  1250. -                if (alphabetic (c)) break;
  1251. -            }
  1252. -        }
  1253. -
  1254. -        while (rl_point)
  1255. -        {
  1256. -            c = the_line[rl_point - 1];
  1257. -            if (!alphabetic (c))
  1258. -                break;
  1259. -            else --rl_point;
  1260. -        }
  1261. -        --count;
  1262. -    }
  1263. -}
  1264. -
  1265. -/* Clear the current line.  Numeric argument to C-l does this. */
  1266. -rl_refresh_line ()
  1267. -{
  1268. -    int curr_line = last_c_pos / screenwidth;
  1269. -    extern char *term_clreol;
  1270. -
  1271. -    move_vert(curr_line);
  1272. -    move_cursor_relative (0, the_line);   /* XXX is this right */
  1273. -
  1274. -    if (term_clreol)
  1275. -        tputs (term_clreol, 1, output_character_function);
  1276. -
  1277. -    rl_forced_update_display ();
  1278. -    rl_display_fixed = 1;
  1279. -}
  1280. -
  1281. -/* C-l typed to a line without quoting clears the screen, and then reprints
  1282. -   the prompt and the current input line.  Given a numeric arg, redraw only
  1283. -   the current line. */
  1284. -rl_clear_screen ()
  1285. -{
  1286. -    extern char *term_clrpag;
  1287. -
  1288. -    if (rl_explicit_arg)
  1289. -    {
  1290. -        rl_refresh_line ();
  1291. -        return;
  1292. -    }
  1293. -
  1294. -    if (term_clrpag)
  1295. -        tputs (term_clrpag, 1, output_character_function);
  1296. -    else
  1297. -        crlf ();
  1298. -
  1299. -    rl_forced_update_display ();
  1300. -    rl_display_fixed = 1;
  1301. -}
  1302. -
  1303. -
  1304. -/* **************************************************************** */
  1305. -/*                                    */
  1306. -/*            Text commands                    */
  1307. -/*                                    */
  1308. -/* **************************************************************** */
  1309. -
  1310. -/* Insert the character C at the current location, moving point forward. */
  1311. -rl_insert (count, c)
  1312. -int count, c;
  1313. -{
  1314. -    register int i;
  1315. -    char *string;
  1316. -
  1317. -    if (count <= 0)
  1318. -        return;
  1319. -
  1320. -    /* If we can optimize, then do it.  But don't let people crash
  1321. -     readline because of extra large arguments. */
  1322. -    if (count > 1 && count < 1024)
  1323. -    {
  1324. -        string = (char *)alloca (1 + count);
  1325. -
  1326. -        for (i = 0; i < count; i++)
  1327. -            string[i] = c;
  1328. -
  1329. -        string[i] = '\0';
  1330. -        rl_insert_text (string);
  1331. -        return;
  1332. -    }
  1333. -
  1334. -    if (count > 1024)
  1335. -    {
  1336. -        int decreaser;
  1337. -
  1338. -        string = (char *)alloca (1024 + 1);
  1339. -
  1340. -        for (i = 0; i < 1024; i++)
  1341. -            string[i] = c;
  1342. -
  1343. -        while (count)
  1344. -        {
  1345. -            decreaser = (count > 1024 ? 1024 : count);
  1346. -            string[decreaser] = '\0';
  1347. -            rl_insert_text (string);
  1348. -            count -= decreaser;
  1349. -        }
  1350. -        return;
  1351. -    }
  1352. -
  1353. -    /* We are inserting a single character.
  1354. -     If there is pending input, then make a string of all of the
  1355. -     pending characters that are bound to rl_insert, and insert
  1356. -     them all. */
  1357. -    if (any_typein)
  1358. -    {
  1359. -        int key = 0, t;
  1360. -
  1361. -        i = 0;
  1362. -        string = (char *)alloca (ibuffer_len + 1);
  1363. -        string[i++] = c;
  1364. -
  1365. -        while ((t = rl_get_char (&key)) &&
  1366. -            (keymap[key].type == ISFUNC &&
  1367. -            keymap[key].function == rl_insert))
  1368. -            string[i++] = key;
  1369. -
  1370. -        if (t)
  1371. -            rl_unget_char (key);
  1372. -
  1373. -        string[i] = '\0';
  1374. -        rl_insert_text (string);
  1375. -        return;
  1376. -    }
  1377. -    else
  1378. -    {
  1379. -        /* Inserting a single character. */
  1380. -        string = (char *)alloca (2);
  1381. -
  1382. -        string[1] = '\0';
  1383. -        string[0] = c;
  1384. -        rl_insert_text (string);
  1385. -    }
  1386. -}
  1387. -
  1388. -/* Insert the next typed character verbatim. */
  1389. -rl_quoted_insert (count)
  1390. -int count;
  1391. -{
  1392. -    int c = rl_read_key ();
  1393. -    rl_insert (count, c);
  1394. -}
  1395. -
  1396. -/* Insert a tab character. */
  1397. -rl_tab_insert (count)
  1398. -int count;
  1399. -{
  1400. -    rl_insert (count, '\t');
  1401. -}
  1402. -
  1403. -/* What to do when a NEWLINE is pressed.  We accept the whole line.
  1404. -   KEY is the key that invoked this command.  I guess it could have
  1405. -   meaning in the future. */
  1406. -rl_newline (count, key)
  1407. -int count, key;
  1408. -{
  1409. -
  1410. -    rl_done = 1;
  1411. -#ifdef VI_MODE
  1412. -    {
  1413. -        extern int vi_doing_insert;
  1414. -        if (vi_doing_insert)
  1415. -        {
  1416. -            rl_end_undo_group ();
  1417. -            vi_doing_insert = 0;
  1418. -        }
  1419. -    }
  1420. -#endif /* VI_MODE */
  1421. -
  1422. -    if (readline_echoing_p)
  1423. -    {
  1424. -        move_vert (vis_botlin);
  1425. -        vis_botlin = 0;
  1426. -        crlf ();
  1427. -        fflush (out_stream);
  1428. -        rl_display_fixed++;
  1429. -    }
  1430. -    rl_end_of_line(); 
  1431. -    rl_insert(1,'\n');  /* added by pjf */
  1432. -}
  1433. -
  1434. -rl_clean_up_for_exit ()
  1435. -{
  1436. -    if (readline_echoing_p)
  1437. -    {
  1438. -        move_vert (vis_botlin);
  1439. -        vis_botlin = 0;
  1440. -        fflush (out_stream);
  1441. -        rl_restart_output ();
  1442. -    }
  1443. -}
  1444. -
  1445. -/* What to do for some uppercase characters, like meta characters,
  1446. -   and some characters appearing in emacs_ctlx_keymap.  This function
  1447. -   is just a stub, you bind keys to it and the code in rl_dispatch ()
  1448. -   is special cased. */
  1449. -rl_do_lowercase_version (ignore1, ignore2)
  1450. -int ignore1, ignore2;
  1451. -{
  1452. -}
  1453. -
  1454. -/* Rubout the character behind point. */
  1455. -rl_rubout (count)
  1456. -int count;
  1457. -{
  1458. -    if (count < 0)
  1459. -    {
  1460. -        rl_delete (-count);
  1461. -        return;
  1462. -    }
  1463. -
  1464. -    if (!rl_point)
  1465. -    {
  1466. -        ding ();
  1467. -        return;
  1468. -    }
  1469. -
  1470. -    if (count > 1)
  1471. -    {
  1472. -        int orig_point = rl_point;
  1473. -        rl_backward (count);
  1474. -        rl_kill_text (orig_point, rl_point);
  1475. -    }
  1476. -    else
  1477. -    {
  1478. -        int c = the_line[--rl_point];
  1479. -        rl_delete_text (rl_point, rl_point + 1);
  1480. -
  1481. -        if (rl_point == rl_end && alphabetic (c) && last_c_pos)
  1482. -        {
  1483. -            backspace (1);
  1484. -            putc (' ', out_stream);
  1485. -            backspace (1);
  1486. -            last_c_pos--;
  1487. -            rl_display_fixed++;
  1488. -        }
  1489. -    }
  1490. -}
  1491. -
  1492. -/* Delete the character under the cursor.  Given a numeric argument,
  1493. -   kill that many characters instead. */
  1494. -rl_delete (count, invoking_key)
  1495. -int count, invoking_key;
  1496. -{
  1497. -    if (count < 0)
  1498. -    {
  1499. -        rl_rubout (-count);
  1500. -        return;
  1501. -    }
  1502. -
  1503. -    if (rl_point == rl_end)
  1504. -    {
  1505. -        ding ();
  1506. -        return;
  1507. -    }
  1508. -
  1509. -    if (count > 1)
  1510. -    {
  1511. -        int orig_point = rl_point;
  1512. -        rl_forward (count);
  1513. -        rl_kill_text (orig_point, rl_point);
  1514. -        rl_point = orig_point;
  1515. -    }
  1516. -    else
  1517. -        rl_delete_text (rl_point, rl_point + 1);
  1518. -}
  1519. -
  1520. -
  1521. -/* **************************************************************** */
  1522. -/*                                    */
  1523. -/*            Kill commands                    */
  1524. -/*                                    */
  1525. -/* **************************************************************** */
  1526. -
  1527. -/* The next two functions mimic unix line editing behaviour, except they
  1528. -   save the deleted text on the kill ring.  This is safer than not saving
  1529. -   it, and since we have a ring, nobody should get screwed. */
  1530. -
  1531. -/* This does what C-w does in Unix.  We can't prevent people from
  1532. -   using behaviour that they expect. */
  1533. -rl_unix_word_rubout ()
  1534. -{
  1535. -    if (!rl_point) ding ();
  1536. -    else {
  1537. -        int orig_point = rl_point;
  1538. -        while (rl_point && whitespace (the_line[rl_point - 1]))
  1539. -            rl_point--;
  1540. -        while (rl_point && !whitespace (the_line[rl_point - 1]))
  1541. -            rl_point--;
  1542. -        rl_kill_text (rl_point, orig_point);
  1543. -    }
  1544. -}
  1545. -
  1546. -/* Here is C-u doing what Unix does.  You don't *have* to use these
  1547. -   key-bindings.  We have a choice of killing the entire line, or
  1548. -   killing from where we are to the start of the line.  We choose the
  1549. -   latter, because if you are a Unix weenie, then you haven't backspaced
  1550. -   into the line at all, and if you aren't, then you know what you are
  1551. -   doing.  (pjf: I disagree*/
  1552. -rl_unix_line_discard ()
  1553. -{
  1554. -    rl_end_of_line();
  1555. -    if (!rl_point) ding ();
  1556. -    else {
  1557. -        rl_kill_text (rl_point, 0);
  1558. -        rl_point = 0;
  1559. -    }
  1560. -}
  1561. -
  1562. -
  1563. -
  1564. -/* **************************************************************** */
  1565. -/*                                    */
  1566. -/*            Commands For Typos                */
  1567. -/*                                    */
  1568. -/* **************************************************************** */
  1569. -
  1570. -/* Random and interesting things in here.  */
  1571. -
  1572. -
  1573. -/* **************************************************************** */
  1574. -/*                                    */
  1575. -/*            Changing Case                    */
  1576. -/*                                    */
  1577. -/* **************************************************************** */
  1578. -
  1579. -/* The three kinds of things that we know how to do. */
  1580. -#define UpCase 1
  1581. -#define DownCase 2
  1582. -#define CapCase 3
  1583. -
  1584. -/* Uppercase the word at point. */
  1585. -rl_upcase_word (count)
  1586. -int count;
  1587. -{
  1588. -    rl_change_case (count, UpCase);
  1589. -}
  1590. -
  1591. -/* Lowercase the word at point. */
  1592. -rl_downcase_word (count)
  1593. -int count;
  1594. -{
  1595. -    rl_change_case (count, DownCase);
  1596. -}
  1597. -
  1598. -/* Upcase the first letter, downcase the rest. */
  1599. -rl_capitalize_word (count)
  1600. -int count;
  1601. -{
  1602. -    rl_change_case (count, CapCase);
  1603. -}
  1604. -
  1605. -/* The meaty function.
  1606. -   Change the case of COUNT words, performing OP on them.
  1607. -   OP is one of UpCase, DownCase, or CapCase.
  1608. -   If a negative argument is given, leave point where it started,
  1609. -   otherwise, leave it where it moves to. */
  1610. -rl_change_case (count, op)
  1611. -int count, op;
  1612. -{
  1613. -    register int start = rl_point, end;
  1614. -    int state = 0;
  1615. -
  1616. -    rl_forward_word (count);
  1617. -    end = rl_point;
  1618. -
  1619. -    if (count < 0)
  1620. -    {
  1621. -        int temp = start;
  1622. -        start = end;
  1623. -        end = temp;
  1624. -    }
  1625. -
  1626. -    /* We are going to modify some text, so let's prepare to undo it. */
  1627. -    rl_modifying (start, end);
  1628. -
  1629. -    for (; start < end; start++)
  1630. -    {
  1631. -        switch (op)
  1632. -        {
  1633. -        case UpCase:
  1634. -            the_line[start] = to_upper (the_line[start]);
  1635. -            break;
  1636. -
  1637. -        case DownCase:
  1638. -            the_line[start] = to_lower (the_line[start]);
  1639. -            break;
  1640. -
  1641. -        case CapCase:
  1642. -            if (state == 0)
  1643. -            {
  1644. -                the_line[start] = to_upper (the_line[start]);
  1645. -                state = 1;
  1646. -            }
  1647. -            else
  1648. -            {
  1649. -                the_line[start] = to_lower (the_line[start]);
  1650. -            }
  1651. -            if (!pure_alphabetic (the_line[start]))
  1652. -                state = 0;
  1653. -            break;
  1654. -
  1655. -        default:
  1656. -            abort ();
  1657. -        }
  1658. -    }
  1659. -    rl_point = end;
  1660. -}
  1661. -
  1662. -/* **************************************************************** */
  1663. -/*                                    */
  1664. -/*            Transposition                    */
  1665. -/*                                    */
  1666. -/* **************************************************************** */
  1667. -
  1668. -/* Transpose the words at point. */
  1669. -rl_transpose_words (count)
  1670. -int count;
  1671. -{
  1672. -    char *word1, *word2;
  1673. -    int w1_beg, w1_end, w2_beg, w2_end;
  1674. -    int orig_point = rl_point;
  1675. -
  1676. -    if (!count) return;
  1677. -
  1678. -    /* Find the two words. */
  1679. -    rl_forward_word (count);
  1680. -    w2_end = rl_point;
  1681. -    rl_backward_word (1);
  1682. -    w2_beg = rl_point;
  1683. -    rl_backward_word (count);
  1684. -    w1_beg = rl_point;
  1685. -    rl_forward_word (1);
  1686. -    w1_end = rl_point;
  1687. -
  1688. -    /* Do some check to make sure that there really are two words. */
  1689. -    if ((w1_beg == w2_beg) || (w2_beg < w1_end))
  1690. -    {
  1691. -        ding ();
  1692. -        rl_point = orig_point;
  1693. -        return;
  1694. -    }
  1695. -
  1696. -    /* Get the text of the words. */
  1697. -    word1 = rl_copy (w1_beg, w1_end);
  1698. -    word2 = rl_copy (w2_beg, w2_end);
  1699. -
  1700. -    /* We are about to do many insertions and deletions.  Remember them
  1701. -     as one operation. */
  1702. -    rl_begin_undo_group ();
  1703. -
  1704. -    /* Do the stuff at word2 first, so that we don't have to worry
  1705. -     about word1 moving. */
  1706. -    rl_point = w2_beg;
  1707. -    rl_delete_text (w2_beg, w2_end);
  1708. -    rl_insert_text (word1);
  1709. -
  1710. -    rl_point = w1_beg;
  1711. -    rl_delete_text (w1_beg, w1_end);
  1712. -    rl_insert_text (word2);
  1713. -
  1714. -    /* This is exactly correct since the text before this point has not
  1715. -     changed in length. */
  1716. -    rl_point = w2_end;
  1717. -
  1718. -    /* I think that does it. */
  1719. -    rl_end_undo_group ();
  1720. -    free (word1); 
  1721. -    free (word2);
  1722. -}
  1723. -
  1724. -/* Transpose the characters at point.  If point is at the end of the line,
  1725. -   then transpose the characters before point. */
  1726. -rl_transpose_chars (count)
  1727. -int count;
  1728. -{
  1729. -    if (!count)
  1730. -        return;
  1731. -
  1732. -    if (!rl_point || rl_end < 2) {
  1733. -        ding ();
  1734. -        return;
  1735. -    }
  1736. -
  1737. -    while (count) {
  1738. -        if (rl_point == rl_end) {
  1739. -            int t = the_line[rl_point - 1];
  1740. -            the_line[rl_point - 1] = the_line[rl_point - 2];
  1741. -            the_line[rl_point - 2] = t;
  1742. -        } else {
  1743. -            int t = the_line[rl_point];
  1744. -            the_line[rl_point] = the_line[rl_point - 1];
  1745. -            the_line[rl_point - 1] = t;
  1746. -            if (count < 0 && rl_point)
  1747. -                rl_point--;
  1748. -            else
  1749. -                rl_point++;
  1750. -        }
  1751. -        if (count < 0)
  1752. -            count++;
  1753. -        else
  1754. -            count--;
  1755. -    }
  1756. -}
  1757. -
  1758. -
  1759. -/* **************************************************************** */
  1760. -/*                                    */
  1761. -/*            Bogus Flow Control                  */
  1762. -/*                                    */
  1763. -/* **************************************************************** */
  1764. -
  1765. -rl_restart_output (count, key)
  1766. -int count, key;
  1767. -{
  1768. -    int fildes = fileno (stdin);
  1769. -#ifdef TIOCSTART
  1770. -    ioctl (fildes, TIOCSTART, 0);
  1771. -#endif /* TIOCSTART */
  1772. -}
  1773. -
  1774. -/* **************************************************************** */
  1775. -/*                                    */
  1776. -/*    Completion matching, from readline's point of view.        */
  1777. -/*                                    */
  1778. -/* **************************************************************** */
  1779. -
  1780. -/* Pointer to the generator function for completion_matches ().
  1781. -   NULL means to use filename_entry_function (), the default filename
  1782. -   completer. */
  1783. -Function *rl_completion_entry_function = (Function *)NULL;
  1784. -
  1785. -/* Pointer to alternative function to create matches.
  1786. -   Function is called with TEXT, START, and END.
  1787. -   START and END are indices in RL_LINE_BUFFER saying what the boundaries
  1788. -   of TEXT are.
  1789. -   If this function exists and returns NULL then call the value of
  1790. -   rl_completion_entry_function to try to match, otherwise use the
  1791. -   array of strings returned. */
  1792. -Function *rl_attempted_completion_function = (Function *)NULL;
  1793. -
  1794. -/* Complete the word at or before point.  You have supplied the function
  1795. -   that does the initial simple matching selection algorithm (see
  1796. -   completion_matches ()).  The default is to do filename completion. */
  1797. -rl_complete (ignore, invoking_key)
  1798. -int ignore, invoking_key;
  1799. -{
  1800. -    rl_complete_internal (TAB);
  1801. -}
  1802. -
  1803. -/* List the possible completions.  See description of rl_complete (). */
  1804. -rl_possible_completions ()
  1805. -{
  1806. -    rl_complete_internal ('?');
  1807. -}
  1808. -
  1809. -/* The user must press "y" or "n". Non-zero return means "y" pressed. */
  1810. -get_y_or_n ()
  1811. -{
  1812. -    int c;
  1813. -loop:
  1814. -    c = rl_read_key ();
  1815. -    if (c == 'y' || c == 'Y') return (1);
  1816. -    if (c == 'n' || c == 'N') return (0);
  1817. -    if (c == ABORT_CHAR) rl_abort ();
  1818. -    ding (); 
  1819. -    goto loop;
  1820. -}
  1821. -
  1822. -/* Up to this many items will be displayed in response to a
  1823. -   possible-completions call.  After that, we ask the user if
  1824. -   she is sure she wants to see them all. */
  1825. -int rl_completion_query_items = 100;
  1826. -
  1827. -/* The basic list of characters that signal a break between words for the
  1828. -   completer routine.  The contents of this variable is what breaks words
  1829. -   in the shell, i.e. " \t\n\"\\'`@><" */
  1830. -char *rl_basic_word_break_characters = " \t\n@><;(";
  1831. -
  1832. -/* The list of characters that signal a break between words for
  1833. -   rl_complete_internal.  The default list is the contents of
  1834. -   rl_basic_word_break_characters.  */
  1835. -char *rl_completer_word_break_characters = (char *)NULL;
  1836. -
  1837. -/* List of characters that are word break characters, but should be left
  1838. -   in TEXT when it is passed to the completion function.  The shell uses
  1839. -   this to help determine what kind of completing to do. */
  1840. -char *rl_special_prefixes = (char *)NULL;
  1841. -
  1842. -/* If non-zero, then disallow duplicates in the matches. */
  1843. -int rl_ignore_completion_duplicates = 1;
  1844. -
  1845. -/* Non-zero means that the results of the matches are to be treated
  1846. -   as filenames.  This is ALWAYS zero on entry, and can only be changed
  1847. -   within a completion entry finder function. */
  1848. -int rl_filename_completion_desired = 0;
  1849. -
  1850. -/* Complete the word at or before point.
  1851. -   WHAT_TO_DO says what to do with the completion.
  1852. -   `?' means list the possible completions.
  1853. -   TAB means do standard completion.
  1854. -   `*' means insert all of the possible completions. */
  1855. -rl_complete_internal (what_to_do)
  1856. -int what_to_do;
  1857. -{
  1858. -    char *filename_completion_function ();
  1859. -    char **completion_matches (), **matches;
  1860. -    Function *our_func;
  1861. -    int start, end,did = 0;
  1862. -    char *text;
  1863. -
  1864. -    if (rl_completion_entry_function)
  1865. -        our_func = rl_completion_entry_function;
  1866. -    else
  1867. -        our_func = (int (*)())filename_completion_function;
  1868. -
  1869. -    /* Only the completion entry function can change this. */
  1870. -    rl_filename_completion_desired = 0;
  1871. -
  1872. -    /* We now look backwards for the start of a filename/variable word. */
  1873. -    end = rl_point;
  1874. -    if (rl_point)
  1875. -    {
  1876. -        for(;;) {
  1877. -            while (--rl_point >= 0 &&
  1878. -                !rindex (rl_completer_word_break_characters, the_line[rl_point]))
  1879. -                if (the_line[rl_point] == '`')
  1880. -                    while(rl_point-- && the_line[rl_point] != '`');
  1881. -                else if (the_line[rl_point] == '\'')
  1882. -                    while(rl_point-- && the_line[rl_point] != '\'');
  1883. -                else if (the_line[rl_point] == '\"')
  1884. -                    while(rl_point-- && the_line[rl_point] != '\"');
  1885. -
  1886. -            if (rl_point < 0)
  1887. -                {
  1888. -                rl_point = end;
  1889. -                ding();
  1890. -                return 0;
  1891. -                }
  1892. -            if (rl_point == 0 || the_line[rl_point-1] != '\\')
  1893. -                break;
  1894. -            rl_point--;
  1895. -        }
  1896. -        /* If we are at a word break, then advance past it. */
  1897. -        if (rindex (rl_completer_word_break_characters,  (the_line[rl_point])))
  1898. -            rl_point++;
  1899. -    }
  1900. -
  1901. -    start = rl_point;
  1902. -    rl_point = end;
  1903. -    text = rl_copy (start, end);
  1904. -    text = docompsubs(text,&did);
  1905. -    rl_prep_terminal();
  1906. -    if (!text)
  1907. -        return 0;
  1908. -    if (did)
  1909. -    {
  1910. -        rl_delete_text (start, rl_point);
  1911. -        rl_point = start;
  1912. -        if (what_to_do == '?')
  1913. -            puts(text);
  1914. -        else if (did == 2)
  1915. -            rl_insert_text(text);
  1916. -        else
  1917. -            rl_safe_insert_text (text);
  1918. -        free(text);
  1919. -        return 0;
  1920. -    }
  1921. -    /* If the user wants to TRY to complete, but then wants to give
  1922. -     up and use the default completion function, they set the
  1923. -     variable rl_attempted_completion_function. */
  1924. -    if (rl_attempted_completion_function)
  1925. -    {
  1926. -        matches =
  1927. -            (char **)(*rl_attempted_completion_function) (text, start, end);
  1928. -
  1929. -        if (matches)
  1930. -            goto after_usual_completion;
  1931. -    }
  1932. -
  1933. -    matches = completion_matches (text, our_func, start, end);
  1934. -
  1935. -after_usual_completion:
  1936. -    free (text);
  1937. -
  1938. -    if (!matches)
  1939. -        ding ();
  1940. -    else
  1941. -    {
  1942. -        register int i;
  1943. -
  1944. -some_matches:
  1945. -
  1946. -        /* It seems to me that in all the cases we handle we would like
  1947. -     to ignore duplicate possiblilities.  Scan for the text to
  1948. -     insert being identical to the other completions. */
  1949. -        if (rl_ignore_completion_duplicates)
  1950. -        {
  1951. -            char *lowest_common;
  1952. -            int j, newlen = 0;
  1953. -
  1954. -            /* Sort the items. */
  1955. -            /* It is safe to sort this array, because the lowest common
  1956. -         denominator found in matches[0] will remain in place. */
  1957. -            for (i = 0; matches[i]; i++);
  1958. -            qsort (matches, i, sizeof (char *), compare_strings);
  1959. -
  1960. -            /* Remember the lowest common denimator for it may be unique. */
  1961. -            lowest_common = savestring (matches[0]);
  1962. -
  1963. -            for (i = 0; matches[i + 1]; i++)
  1964. -            {
  1965. -                if (strcmp (matches[i], matches[i + 1]) == 0)
  1966. -                {
  1967. -                    free (matches[i]);
  1968. -                    matches[i] = (char *)-1;
  1969. -                }
  1970. -                else
  1971. -                    newlen++;
  1972. -            }
  1973. -
  1974. -            /* We have marked all the dead slots with (char *)-1.
  1975. -         Copy all the non-dead entries into a new array. */
  1976. -            {
  1977. -                char **temp_array =
  1978. -                (char **)malloc ((3 + newlen) * sizeof (char *));
  1979. -
  1980. -                for (i = 1, j = 1; matches[i]; i++)
  1981. -                    if (matches[i] != (char *)-1)
  1982. -                        temp_array[j++] = matches[i];
  1983. -                temp_array[j] = (char *)NULL;
  1984. -
  1985. -                if (matches[0] != (char *)-1)
  1986. -                    free (matches[0]);
  1987. -                free (matches);
  1988. -
  1989. -                matches = temp_array;
  1990. -            }
  1991. -
  1992. -            /* Place the lowest common denominator back in [0]. */
  1993. -            matches[0] = lowest_common;
  1994. -
  1995. -            /* If there is one string left, and it is identical to the
  1996. -         lowest common denominator, then the LCD is the string to
  1997. -         insert. */
  1998. -            if (j == 2 && strcmp (matches[0], matches[1]) == 0)
  1999. -            {
  2000. -                free (matches[1]);
  2001. -                matches[1] = (char *)NULL;
  2002. -            }
  2003. -        }
  2004. -
  2005. -        switch (what_to_do)
  2006. -        {
  2007. -        case TAB:
  2008. -            if (matches[0])
  2009. -            {
  2010. -                rl_delete_text (start, rl_point);
  2011. -                rl_point = start;
  2012. -                rl_safe_insert_text (matches[0]);
  2013. -            }
  2014. -
  2015. -            /* If there are more matches, ring the bell to indicate.
  2016. -         If this was the only match, and we are hacking files,
  2017. -         check the file to see if it was a directory.  If so,
  2018. -         add a '/' to the name.  If not, and we are at the end
  2019. -         of the line, then add a space. */
  2020. -            if (matches[1])
  2021. -            {
  2022. -            extern int opts[128];
  2023. -
  2024. -                ding ();        /* There are other matches remaining. */
  2025. -                if (opts['9'] == 2)
  2026. -                    goto autolist;
  2027. -            }
  2028. -            else
  2029. -            {
  2030. -                char temp_string[2];
  2031. -
  2032. -                temp_string[0] = ' ';
  2033. -                temp_string[1] = '\0';
  2034. -
  2035. -                if (rl_filename_completion_desired)
  2036. -                {
  2037. -                    struct stat finfo;
  2038. -                    char *tilde_expand ();
  2039. -                    char *filename = tilde_expand (matches[0]);
  2040. -
  2041. -                    if ((stat (filename, &finfo) == 0) &&
  2042. -                        ((finfo.st_mode & S_IFMT) == S_IFDIR))
  2043. -                    {
  2044. -                        if (the_line[rl_point] != '/')
  2045. -                            rl_insert_text ("/");
  2046. -                    }
  2047. -                    else
  2048. -                    {
  2049. -                        if (rl_point == rl_end)
  2050. -                            rl_insert_text (temp_string);
  2051. -                    }
  2052. -                    free (filename);
  2053. -                }
  2054. -                else
  2055. -                {
  2056. -                    if (rl_point == rl_end)
  2057. -                        rl_insert_text (temp_string);
  2058. -                }
  2059. -            }
  2060. -            break;
  2061. -
  2062. -        case '*':
  2063. -            {
  2064. -                int i = 1;
  2065. -
  2066. -                rl_delete_text (start, rl_point);
  2067. -                rl_point = start;
  2068. -                rl_begin_undo_group ();
  2069. -                if (matches[1])
  2070. -                {
  2071. -                    while (matches[i])
  2072. -                    {
  2073. -                        rl_safe_insert_text (matches[i++]);
  2074. -                        rl_insert_text (" ");
  2075. -                    }
  2076. -                }
  2077. -                else
  2078. -                {
  2079. -                    rl_safe_insert_text (matches[0]);
  2080. -                    rl_insert_text (" ");
  2081. -                }
  2082. -                rl_end_undo_group ();
  2083. -            }
  2084. -            break;
  2085. -
  2086. -
  2087. -        case '?':
  2088. -            {
  2089. -                int len, count, limit, max = 0;
  2090. -                int j, k, l;
  2091. -
  2092. -autolist:
  2093. -                /* Handle simple case first.  What if there is only one answer? */
  2094. -                if (!matches[1])
  2095. -                {
  2096. -                    char *rindex (), *temp;
  2097. -
  2098. -                    if (rl_filename_completion_desired)
  2099. -                        temp = rindex (matches[0], '/');
  2100. -                    else
  2101. -                        temp = (char *)NULL;
  2102. -
  2103. -                    if (!temp)
  2104. -                        temp = matches[0];
  2105. -                    else
  2106. -                        temp++;
  2107. -
  2108. -                    crlf ();
  2109. -                    fprintf (out_stream, "%s", temp);
  2110. -                    crlf ();
  2111. -                    goto restart;
  2112. -                }
  2113. -
  2114. -                /* There is more than one answer.  Find out how many there are,
  2115. -           and find out what the maximum printed length of a single entry
  2116. -           is. */
  2117. -                for (i = 1; matches[i]; i++)
  2118. -                {
  2119. -                    char *rindex (), *temp = (char *)NULL;
  2120. -
  2121. -                    /* If we are hacking filenames, then only count the characters
  2122. -           after the last slash in the pathname. */
  2123. -                    if (rl_filename_completion_desired)
  2124. -                        temp = rindex (matches[i], '/');
  2125. -                    else
  2126. -                        temp = (char *)NULL;
  2127. -
  2128. -                    if (!temp)
  2129. -                        temp = matches[i];
  2130. -                    else
  2131. -                        temp++;
  2132. -
  2133. -                    if (strlen (temp) > max)
  2134. -                        max = strlen (temp);
  2135. -                }
  2136. -
  2137. -                len = i;
  2138. -
  2139. -                /* If there are many items, then ask the user if she
  2140. -           really wants to see them all. */
  2141. -                if (len >= rl_completion_query_items)
  2142. -                {
  2143. -                    crlf ();
  2144. -                    fprintf (out_stream,
  2145. -                        "There are %d possibilities.  Do you really", len);
  2146. -                    crlf ();
  2147. -                    fprintf (out_stream, "wish to see them all? (y or n)");
  2148. -                    fflush (out_stream);
  2149. -                    if (!get_y_or_n ())
  2150. -                    {
  2151. -                        crlf ();
  2152. -                        goto restart;
  2153. -                    }
  2154. -                }
  2155. -                /* How many items of MAX length can we fit in the screen window? */
  2156. -                max += 2;
  2157. -                limit = screenwidth / max;
  2158. -                if (limit != 1 && (limit * max == screenwidth))
  2159. -                    limit--;
  2160. -
  2161. -                /* How many iterations of the printing loop? */
  2162. -                count = (len + (limit - 1)) / limit;
  2163. -
  2164. -                /* Watch out for special case.  If LEN is less than LIMIT, then
  2165. -           just do the inner printing loop. */
  2166. -                if (len < limit) count = 1;
  2167. -
  2168. -                /* Sort the items if they are not already sorted. */
  2169. -                if (!rl_ignore_completion_duplicates)
  2170. -                    qsort (matches, len, sizeof (char *), compare_strings);
  2171. -
  2172. -                /* Print the sorted items, up-and-down alphabetically, like
  2173. -           ls might. */
  2174. -                crlf ();
  2175. -
  2176. -                for (i = 1; i < count + 1; i++)
  2177. -                {
  2178. -                    for (j = 0, l = i; j < limit; j++)
  2179. -                    {
  2180. -                        if (l > len || !matches[l])
  2181. -                        {
  2182. -                            break;
  2183. -                        }
  2184. -                        else
  2185. -                        {
  2186. -                            char *rindex (), *temp = (char *)NULL;
  2187. -
  2188. -                            if (rl_filename_completion_desired)
  2189. -                                temp = rindex (matches[l], '/');
  2190. -                            else
  2191. -                                temp = (char *)NULL;
  2192. -
  2193. -                            if (!temp)
  2194. -                                temp = matches[l];
  2195. -                            else
  2196. -                                temp++;
  2197. -
  2198. -                            fprintf (out_stream, "%s", temp);
  2199. -                            for (k = 0; k < max - strlen (temp); k++)
  2200. -                                putc (' ', out_stream);
  2201. -                        }
  2202. -                        l += count;
  2203. -                    }
  2204. -                    crlf ();
  2205. -                }
  2206. -restart:
  2207. -
  2208. -                rl_on_new_line ();
  2209. -            }
  2210. -            break;
  2211. -
  2212. -        default:
  2213. -            abort ();
  2214. -        }
  2215. -
  2216. -        for (i = 0; matches[i]; i++)
  2217. -            free (matches[i]);
  2218. -        free (matches);
  2219. -    }
  2220. -}
  2221. -
  2222. -/* Stupid comparison routine for qsort () ing strings. */
  2223. -static int
  2224. -compare_strings (s1, s2)
  2225. -char **s1, **s2;
  2226. -{
  2227. -    return (strcmp (*s1, *s2));
  2228. -}
  2229. -
  2230. -/* If non-null, this contains the address of a function to call if the
  2231. -   standard meaning for expanding a tilde fails.  The function is called
  2232. -   with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
  2233. -   which is the expansion, or a NULL pointer if there is no expansion. */
  2234. -Function *rl_tilde_expander = (Function *)NULL;
  2235. -
  2236. -/* Expand FILENAME if it begins with a tilde.  This always returns
  2237. -   a new string. */
  2238. -char *
  2239. -tilde_expand (filename)
  2240. -char *filename;
  2241. -{
  2242. -    char *dirname = filename ? savestring (filename) : (char *)NULL;
  2243. -
  2244. -    if (dirname && *dirname == '~')
  2245. -    {
  2246. -        char *temp_name;
  2247. -        if (!dirname[1] || dirname[1] == '/')
  2248. -        {
  2249. -            /* Prepend $HOME to the rest of the string. */
  2250. -            char *temp_home = (char *)getenv ("HOME");
  2251. -
  2252. -            temp_name = (char *)alloca (1 + strlen (&dirname[1])
  2253. -                + (temp_home? strlen (temp_home) : 0));
  2254. -            temp_name[0] = '\0';
  2255. -            if (temp_home)
  2256. -                strcpy (temp_name, temp_home);
  2257. -            strcat (temp_name, &dirname[1]);
  2258. -            free (dirname);
  2259. -            dirname = savestring (temp_name);
  2260. -        }
  2261. -        else
  2262. -        {
  2263. -            struct passwd *getpwnam (), *user_entry;
  2264. -            char *username = (char *)alloca (257);
  2265. -            int i, c;
  2266. -
  2267. -            for (i = 1; c = dirname[i]; i++)
  2268. -            {
  2269. -                if (c == '/') break;
  2270. -                else username[i - 1] = c;
  2271. -            }
  2272. -            username[i - 1] = '\0';
  2273. -
  2274. -            if (!(user_entry = getpwnam (username)))
  2275. -            {
  2276. -                /* If the calling program has a special syntax for
  2277. -         expanding tildes, and we couldn't find a standard
  2278. -         expansion, then let them try. */
  2279. -                if (rl_tilde_expander)
  2280. -                {
  2281. -                    char *expansion;
  2282. -
  2283. -                    expansion = (char *)(*rl_tilde_expander) (username);
  2284. -
  2285. -                    if (expansion)
  2286. -                    {
  2287. -                        temp_name = (char *)alloca (1 + strlen (expansion)
  2288. -                            + strlen (&dirname[i]));
  2289. -                        strcpy (temp_name, expansion);
  2290. -                        strcat (temp_name, &dirname[i]);
  2291. -                        free (expansion);
  2292. -                        goto return_name;
  2293. -                    }
  2294. -                }
  2295. -                /*
  2296. -           * We shouldn't report errors.
  2297. -           */
  2298. -            }
  2299. -            else
  2300. -            {
  2301. -                temp_name = (char *)alloca (1 + strlen (user_entry->pw_dir)
  2302. -                    + strlen (&dirname[i]));
  2303. -                strcpy (temp_name, user_entry->pw_dir);
  2304. -                strcat (temp_name, &dirname[i]);
  2305. -return_name:
  2306. -                free (dirname);
  2307. -                dirname = savestring (temp_name);
  2308. -            }
  2309. -        }
  2310. -    }
  2311. -    return (dirname);
  2312. -}
  2313. -
  2314. -
  2315. -/* **************************************************************** */
  2316. -/*                                    */
  2317. -/*            Undo, and Undoing                */
  2318. -/*                                    */
  2319. -/* **************************************************************** */
  2320. -
  2321. -/* Non-zero tells rl_delete_text and rl_insert_text to not add to
  2322. -   the undo list. */
  2323. -int doing_an_undo = 0;
  2324. -
  2325. -/* The current undo list for THE_LINE. */
  2326. -UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
  2327. -
  2328. -/* Remember how to undo something.  Concatenate some undos if that
  2329. -   seems right. */
  2330. -rl_add_undo (what, start, end, text)
  2331. -enum undo_code what;
  2332. -int start, end;
  2333. -char *text;
  2334. -{
  2335. -    UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
  2336. -    temp->what = what;
  2337. -    temp->start = start;
  2338. -    temp->end = end;
  2339. -    temp->text = text;
  2340. -    temp->next = rl_undo_list;
  2341. -    rl_undo_list = temp;
  2342. -}
  2343. -
  2344. -/* Free the existing undo list. */
  2345. -free_undo_list ()
  2346. -{
  2347. -    while (rl_undo_list) {
  2348. -        UNDO_LIST *release = rl_undo_list;
  2349. -        rl_undo_list = rl_undo_list->next;
  2350. -
  2351. -        if (release->what == UNDO_DELETE)
  2352. -            free (release->text);
  2353. -
  2354. -        free (release);
  2355. -    }
  2356. -}
  2357. -
  2358. -/* Undo the next thing in the list.  Return 0 if there
  2359. -   is nothing to undo, or non-zero if there was. */
  2360. -int
  2361. -rl_do_undo ()
  2362. -{
  2363. -    UNDO_LIST *release;
  2364. -    int waiting_for_begin = 0;
  2365. -
  2366. -undo_thing:
  2367. -    if (!rl_undo_list)
  2368. -        return (0);
  2369. -
  2370. -    doing_an_undo = 1;
  2371. -
  2372. -    switch (rl_undo_list->what) {
  2373. -
  2374. -        /* Undoing deletes means inserting some text. */
  2375. -    case UNDO_DELETE:
  2376. -        rl_point = rl_undo_list->start;
  2377. -        rl_insert_text (rl_undo_list->text);
  2378. -        free (rl_undo_list->text);
  2379. -        break;
  2380. -
  2381. -        /* Undoing inserts means deleting some text. */
  2382. -    case UNDO_INSERT:
  2383. -        rl_delete_text (rl_undo_list->start, rl_undo_list->end);
  2384. -        rl_point = rl_undo_list->start;
  2385. -        break;
  2386. -
  2387. -        /* Undoing an END means undoing everything 'til we get to
  2388. -       a BEGIN. */
  2389. -    case UNDO_END:
  2390. -        waiting_for_begin++;
  2391. -        break;
  2392. -
  2393. -        /* Undoing a BEGIN means that we are done with this group. */
  2394. -    case UNDO_BEGIN:
  2395. -        if (waiting_for_begin)
  2396. -            waiting_for_begin--;
  2397. -        else
  2398. -            abort ();
  2399. -        break;
  2400. -    }
  2401. -
  2402. -    doing_an_undo = 0;
  2403. -
  2404. -    release = rl_undo_list;
  2405. -    rl_undo_list = rl_undo_list->next;
  2406. -    free (release);
  2407. -
  2408. -    if (waiting_for_begin)
  2409. -        goto undo_thing;
  2410. -
  2411. -    return (1);
  2412. -}
  2413. -
  2414. -/* Begin a group.  Subsequent undos are undone as an atomic operation. */
  2415. -rl_begin_undo_group ()
  2416. -{
  2417. -    rl_add_undo (UNDO_BEGIN, 0, 0, 0);
  2418. -}
  2419. -
  2420. -/* End an undo group started with rl_begin_undo_group (). */
  2421. -rl_end_undo_group ()
  2422. -{
  2423. -    rl_add_undo (UNDO_END, 0, 0, 0);
  2424. -}
  2425. -
  2426. -/* Save an undo entry for the text from START to END. */
  2427. -rl_modifying (start, end)
  2428. -int start, end;
  2429. -{
  2430. -    if (start > end)
  2431. -    {
  2432. -        int t = start;
  2433. -        start = end;
  2434. -        end = t;
  2435. -    }
  2436. -
  2437. -    if (start != end)
  2438. -    {
  2439. -        char *temp = rl_copy (start, end);
  2440. -        rl_begin_undo_group ();
  2441. -        rl_add_undo (UNDO_DELETE, start, end, temp);
  2442. -        rl_add_undo (UNDO_INSERT, start, end, (char *)NULL);
  2443. -        rl_end_undo_group ();
  2444. -    }
  2445. -}
  2446. -
  2447. -/* Revert the current line to its previous state. */
  2448. -rl_revert_line ()
  2449. -{
  2450. -    if (!rl_undo_list) ding ();
  2451. -    else {
  2452. -        while (rl_undo_list)
  2453. -            rl_do_undo ();
  2454. -    }
  2455. -}
  2456. -
  2457. -/* Do some undoing of things that were done. */
  2458. -rl_undo_command (count)
  2459. -{
  2460. -    if (count < 0) return;    /* Nothing to do. */
  2461. -
  2462. -    while (count)
  2463. -    {
  2464. -        if (rl_do_undo ())
  2465. -        {
  2466. -            count--;
  2467. -        }
  2468. -        else
  2469. -        {
  2470. -            ding ();
  2471. -            break;
  2472. -        }
  2473. -    }
  2474. -}
  2475. -
  2476. -/* **************************************************************** */
  2477. -/*                                    */
  2478. -/*            History Utilities                */
  2479. -/*                                    */
  2480. -/* **************************************************************** */
  2481. -
  2482. -/* We already have a history library, and that is what we use to control
  2483. -   the history features of readline.  However, this is our local interface
  2484. -   to the history mechanism. */
  2485. -
  2486. -/* While we are editing the history, this is the saved
  2487. -   version of the original line. */
  2488. -HIST_ENTRY *saved_line_for_history = (HIST_ENTRY *)NULL;
  2489. -
  2490. -/* Set the history pointer back to the last entry in the history. */
  2491. -start_using_history ()
  2492. -{
  2493. -    using_history ();
  2494. -    if (saved_line_for_history)
  2495. -        free_history_entry (saved_line_for_history);
  2496. -
  2497. -    saved_line_for_history = (HIST_ENTRY *)NULL;
  2498. -}
  2499. -
  2500. -/* Free the contents (and containing structure) of a HIST_ENTRY. */
  2501. -free_history_entry (entry)
  2502. -HIST_ENTRY *entry;
  2503. -{
  2504. -    if (!entry) return;
  2505. -    if (entry->line)
  2506. -        free (entry->line);
  2507. -    free (entry);
  2508. -}
  2509. -
  2510. -/* Perhaps put back the current line if it has changed. */
  2511. -maybe_replace_line ()
  2512. -{
  2513. -    HIST_ENTRY *temp = current_history ();
  2514. -
  2515. -    /* If the current line has changed, save the changes. */
  2516. -    if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list)) {
  2517. -        free (temp->line);
  2518. -        free (temp);
  2519. -    }
  2520. -}
  2521. -
  2522. -/* Put back the saved_line_for_history if there is one. */
  2523. -maybe_unsave_line ()
  2524. -{
  2525. -    if (saved_line_for_history) {
  2526. -        strcpy (the_line, saved_line_for_history->line);
  2527. -        rl_undo_list = (UNDO_LIST *)saved_line_for_history->data;
  2528. -        free_history_entry (saved_line_for_history);
  2529. -        saved_line_for_history = (HIST_ENTRY *)NULL;
  2530. -        rl_end = rl_point = strlen (the_line);
  2531. -    } else {
  2532. -        ding ();
  2533. -    }
  2534. -}
  2535. -
  2536. -/* Save the current line in saved_line_for_history. */
  2537. -maybe_save_line ()
  2538. -{
  2539. -    if (!saved_line_for_history) {
  2540. -        saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
  2541. -        saved_line_for_history->line = savestring (the_line);
  2542. -        saved_line_for_history->data = (char *)rl_undo_list;
  2543. -    }
  2544. -}
  2545. -
  2546. -
  2547. -
  2548. -/* **************************************************************** */
  2549. -/*                                    */
  2550. -/*            History Commands                */
  2551. -/*                                    */
  2552. -/* **************************************************************** */
  2553. -
  2554. -/* Meta-< goes to the start of the history. */
  2555. -rl_beginning_of_history ()
  2556. -{
  2557. -    rl_get_previous_history (1 + where_history ());
  2558. -}
  2559. -
  2560. -/* Meta-> goes to the end of the history.  (The current line). */
  2561. -rl_end_of_history ()
  2562. -{
  2563. -    maybe_replace_line ();
  2564. -    using_history ();
  2565. -    maybe_unsave_line ();
  2566. -}
  2567. -
  2568. -/* Move down to the next history line. */
  2569. -rl_get_next_history (count)
  2570. -int count;
  2571. -{
  2572. -    HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
  2573. -
  2574. -    if (count < 0)
  2575. -    {
  2576. -        rl_get_previous_history (-count);
  2577. -        return;
  2578. -    }
  2579. -
  2580. -    if (!count)
  2581. -        return;
  2582. -
  2583. -    maybe_replace_line ();
  2584. -
  2585. -    while (count)
  2586. -    {
  2587. -        temp = next_history ();
  2588. -        if (!temp)
  2589. -            break;
  2590. -        if (--count)
  2591. -            free(temp);
  2592. -    }
  2593. -
  2594. -    if (!temp)
  2595. -        maybe_unsave_line ();
  2596. -    else
  2597. -    {
  2598. -        free(temp);
  2599. -        strcpy (the_line, temp->line);
  2600. -        rl_undo_list = (UNDO_LIST *)temp->data;
  2601. -        rl_end = rl_point = strlen (the_line);
  2602. -    }
  2603. -}
  2604. -
  2605. -/* Get the previous item out of our interactive history, making it the current
  2606. -   line.  If there is no previous history, just ding. */
  2607. -rl_get_previous_history (count)
  2608. -int count;
  2609. -{
  2610. -    HIST_ENTRY *old_temp = (HIST_ENTRY *)NULL;
  2611. -    HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
  2612. -
  2613. -    if (count < 0)
  2614. -    {
  2615. -        rl_get_next_history (-count);
  2616. -        return;
  2617. -    }
  2618. -
  2619. -    if (!count)
  2620. -        return;
  2621. -
  2622. -    /* If we don't have a line saved, then save this one. */
  2623. -    maybe_save_line ();
  2624. -
  2625. -    /* If the current line has changed, save the changes. */
  2626. -    maybe_replace_line ();
  2627. -
  2628. -    while (count)
  2629. -    {
  2630. -        temp = previous_history ();
  2631. -        if (!temp)
  2632. -            break;
  2633. -        else
  2634. -            old_temp = temp;
  2635. -        if (--count)
  2636. -            free(temp);
  2637. -    }
  2638. -
  2639. -    /* If there was a large argument, and we moved back to the start of the
  2640. -     history, that is not an error.  So use the last value found. */
  2641. -    if (!temp && old_temp)
  2642. -        temp = old_temp;
  2643. -
  2644. -    if (!temp)
  2645. -        ding ();
  2646. -    else
  2647. -    {
  2648. -        strcpy (the_line, temp->line);
  2649. -        rl_undo_list = (UNDO_LIST *)temp->data;
  2650. -        rl_end = rl_point = strlen (the_line);
  2651. -#ifdef VI_MODE
  2652. -        if (rl_editing_mode == vi_mode)
  2653. -            rl_point = 0;
  2654. -#endif /* VI_MODE */
  2655. -    }
  2656. -}
  2657. -
  2658. -/* There is a command in ksh which yanks into this line, the last word
  2659. -   of the previous line.  Here it is.  We left it on M-. */
  2660. -rl_yank_previous_last_arg (ignore)
  2661. -int ignore;
  2662. -{
  2663. -}
  2664. -
  2665. -/* Make C be the next command to be executed. */
  2666. -rl_execute_next (c)
  2667. -int c;
  2668. -{
  2669. -    rl_pending_input = c;
  2670. -}
  2671. -
  2672. -/* **************************************************************** */
  2673. -/*                                    */
  2674. -/*            Killing Mechanism                */
  2675. -/*                                    */
  2676. -/* **************************************************************** */
  2677. -
  2678. -/* What we assume for a max number of kills. */
  2679. -#define DEFAULT_MAX_KILLS 10
  2680. -
  2681. -/* The real variable to look at to find out when to flush kills. */
  2682. -int rl_max_kills = DEFAULT_MAX_KILLS;
  2683. -
  2684. -/* Where to store killed text. */
  2685. -char **rl_kill_ring = (char **)NULL;
  2686. -
  2687. -/* Where we are in the kill ring. */
  2688. -int rl_kill_index = 0;
  2689. -
  2690. -/* How many slots we have in the kill ring. */
  2691. -int rl_kill_ring_length = 0;
  2692. -
  2693. -/* How to say that you only want to save a certain amount
  2694. -   of kill material. */
  2695. -rl_set_retained_kills (num)
  2696. -int num;
  2697. -{
  2698. -}
  2699. -
  2700. -/* The way to kill something.  This appends or prepends to the last
  2701. -   kill, if the last command was a kill command.  if FROM is less
  2702. -   than TO, then the text is appended, otherwise prepended.  If the
  2703. -   last command was not a kill command, then a new slot is made for
  2704. -   this kill. */
  2705. -rl_kill_text (from, to)
  2706. -int from, to;
  2707. -{
  2708. -    int slot;
  2709. -    char *text = rl_copy (from, to);
  2710. -
  2711. -    /* Is there anything to kill? */
  2712. -    if (from == to) {
  2713. -        free (text);
  2714. -        last_command_was_kill++;
  2715. -        return;
  2716. -    }
  2717. -
  2718. -    /* Delete the copied text from the line. */
  2719. -    rl_delete_text (from, to);
  2720. -
  2721. -    /* First, find the slot to work with. */
  2722. -    if (!last_command_was_kill) {
  2723. -
  2724. -        /* Get a new slot.  */
  2725. -        if (!rl_kill_ring) {
  2726. -
  2727. -            /* If we don't have any defined, then make one. */
  2728. -            rl_kill_ring =
  2729. -                (char **)xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
  2730. -            slot = 1;
  2731. -
  2732. -        } else {
  2733. -
  2734. -            /* We have to add a new slot on the end, unless we have exceeded
  2735. -     the max limit for remembering kills. */
  2736. -            slot = rl_kill_ring_length;
  2737. -            if (slot == rl_max_kills) {
  2738. -                register int i;
  2739. -                free (rl_kill_ring[0]);
  2740. -                for (i = 0; i < slot; i++)
  2741. -                    rl_kill_ring[i] = rl_kill_ring[i + 1];
  2742. -            } else {
  2743. -                rl_kill_ring =
  2744. -                    (char **)xrealloc (rl_kill_ring,
  2745. -                    ((slot = (rl_kill_ring_length += 1)) + 1)
  2746. -                    * sizeof (char *));
  2747. -            }
  2748. -        }
  2749. -        slot--;
  2750. -    } else {
  2751. -        slot = rl_kill_ring_length - 1;
  2752. -    }
  2753. -
  2754. -    /* If the last command was a kill, prepend or append. */
  2755. -    if (last_command_was_kill) {
  2756. -        char *old = rl_kill_ring[slot];
  2757. -        char *new = (char *)xmalloc (1 + strlen (old) + strlen (text));
  2758. -
  2759. -        if (from < to) {
  2760. -            strcpy (new, old);
  2761. -            strcat (new, text);
  2762. -        } else {
  2763. -            strcpy (new, text);
  2764. -            strcat (new, old);
  2765. -        }
  2766. -        free (old);
  2767. -        free (text);
  2768. -        rl_kill_ring[slot] = new;
  2769. -    } else {
  2770. -        rl_kill_ring[slot] = text;
  2771. -    }
  2772. -    rl_kill_index = slot;
  2773. -    last_command_was_kill++;
  2774. -}
  2775. -
  2776. -/* Now REMEMBER!  In order to do prepending or appending correctly, kill
  2777. -   commands always make rl_point's original position be the FROM argument,
  2778. -   and rl_point's extent be the TO argument. */
  2779. -
  2780. -
  2781. -/* **************************************************************** */
  2782. -/*                                    */
  2783. -/*            Killing Commands                */
  2784. -/*                                    */
  2785. -/* **************************************************************** */
  2786. -
  2787. -/* Delete the word at point, saving the text in the kill ring. */
  2788. -rl_kill_word (count)
  2789. -int count;
  2790. -{
  2791. -    int orig_point = rl_point;
  2792. -
  2793. -    if (count < 0)
  2794. -        rl_backward_kill_word (-count);
  2795. -    else
  2796. -    {
  2797. -        rl_forward_word (count);
  2798. -
  2799. -        if (rl_point != orig_point)
  2800. -            rl_kill_text (orig_point, rl_point);
  2801. -
  2802. -        rl_point = orig_point;
  2803. -    }
  2804. -}
  2805. -
  2806. -/* Rubout the word before point, placing it on the kill ring. */
  2807. -rl_backward_kill_word (count)
  2808. -int count;
  2809. -{
  2810. -    int orig_point = rl_point;
  2811. -
  2812. -    if (count < 0)
  2813. -        rl_kill_word (-count);
  2814. -    else
  2815. -    {
  2816. -        rl_backward_word (count);
  2817. -
  2818. -        if (rl_point != orig_point)
  2819. -            rl_kill_text (orig_point, rl_point);
  2820. -    }
  2821. -}
  2822. -
  2823. -/* Kill from here to the end of the line.  If DIRECTION is negative, kill
  2824. -   back to the line start instead. */
  2825. -rl_kill_line (direction)
  2826. -int direction;
  2827. -{
  2828. -    int orig_point = rl_point;
  2829. -
  2830. -    if (direction < 0)
  2831. -        rl_backward_kill_line (1);
  2832. -    else
  2833. -    {
  2834. -        rl_end_of_line ();
  2835. -        if (orig_point != rl_point)
  2836. -            rl_kill_text (orig_point, rl_point);
  2837. -        rl_point = orig_point;
  2838. -    }
  2839. -}
  2840. -
  2841. -/* Kill backwards to the start of the line.  If DIRECTION is negative, kill
  2842. -   forwards to the line end instead. */
  2843. -rl_backward_kill_line (direction)
  2844. -int direction;
  2845. -{
  2846. -    int orig_point = rl_point;
  2847. -
  2848. -    if (direction < 0)
  2849. -        rl_kill_line (1);
  2850. -    else
  2851. -    {
  2852. -        if (!rl_point)
  2853. -            ding ();
  2854. -        else
  2855. -        {
  2856. -            rl_beg_of_line ();
  2857. -            rl_kill_text (orig_point, rl_point);
  2858. -        }
  2859. -    }
  2860. -}
  2861. -
  2862. -/* Yank back the last killed text.  This ignores arguments. */
  2863. -rl_yank ()
  2864. -{
  2865. -    if (!rl_kill_ring) rl_abort ();
  2866. -    rl_insert_text (rl_kill_ring[rl_kill_index]);
  2867. -}
  2868. -
  2869. -/* If the last command was yank, or yank_pop, and the text just
  2870. -   before point is identical to the current kill item, then
  2871. -   delete that text from the line, rotate the index down, and
  2872. -   yank back some other text. */
  2873. -rl_yank_pop ()
  2874. -{
  2875. -    int l;
  2876. -
  2877. -    if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
  2878. -        !rl_kill_ring)
  2879. -    {
  2880. -        rl_abort ();
  2881. -    }
  2882. -
  2883. -    l = strlen (rl_kill_ring[rl_kill_index]);
  2884. -    if (((rl_point - l) >= 0) &&
  2885. -        (strncmp (the_line + (rl_point - l),
  2886. -        rl_kill_ring[rl_kill_index], l) == 0))
  2887. -    {
  2888. -        rl_delete_text ((rl_point - l), rl_point);
  2889. -        rl_point -= l;
  2890. -        rl_kill_index--;
  2891. -        if (rl_kill_index < 0)
  2892. -            rl_kill_index = rl_kill_ring_length - 1;
  2893. -        rl_yank ();
  2894. -    }
  2895. -    else
  2896. -        rl_abort ();
  2897. -
  2898. -}
  2899. -
  2900. -extern char *extracthistarg();
  2901. -
  2902. -/* Yank the COUNTth argument from the previous history line. */
  2903. -rl_yank_nth_arg (count, ignore)
  2904. -int count;
  2905. -{
  2906. -char *arg;
  2907. -
  2908. -    arg = extracthistarg(count);
  2909. -    if (!arg || !*arg)
  2910. -    {
  2911. -        ding ();
  2912. -        return;
  2913. -    }
  2914. -
  2915. -    rl_begin_undo_group ();
  2916. -    if (rl_point && the_line[rl_point - 1] != ' ')
  2917. -        rl_insert_text (" ");
  2918. -    rl_insert_text (arg);
  2919. -    free (arg);
  2920. -    rl_end_undo_group ();
  2921. -}
  2922. -
  2923. -/* Vi Mode. */
  2924. -#ifdef VI_MODE
  2925. -#include "vi_mode.c"
  2926. -#endif /* VI_MODE */
  2927. -
  2928. -/* How to toggle back and forth between editing modes. */
  2929. -rl_vi_editing_mode ()
  2930. -{
  2931. -#ifdef VI_MODE
  2932. -    rl_editing_mode = vi_mode;
  2933. -    rl_vi_insertion_mode ();
  2934. -#endif /* VI_MODE */
  2935. -}
  2936. -
  2937. -rl_emacs_editing_mode ()
  2938. -{
  2939. -    rl_editing_mode = emacs_mode;
  2940. -    keymap = emacs_standard_keymap;
  2941. -}
  2942. -
  2943. -
  2944. -/* **************************************************************** */
  2945. -/*                                    */
  2946. -/*                 Completion                    */
  2947. -/*                                    */
  2948. -/* **************************************************************** */
  2949. -
  2950. -/* Non-zero means that case is not significant in completion. */
  2951. -int completion_case_fold = 0;
  2952. -
  2953. -/* Return an array of (char *) which is a list of completions for TEXT.
  2954. -   If there are no completions, return a NULL pointer.
  2955. -   The first entry in the returned array is the substitution for TEXT.
  2956. -    The remaining entries are the possible completions.
  2957. -   The array is terminated with a NULL pointer.
  2958. -
  2959. -   ENTRY_FUNCTION is a function of two args, and returns a (char *).
  2960. -     The first argument is TEXT.
  2961. -     The second is a state argument; it should be zero on the first call, and
  2962. -     non-zero on subsequent calls.  It returns a NULL pointer to the caller
  2963. -     when there are no more matches.
  2964. - */
  2965. -char **
  2966. -completion_matches (text, entry_function)
  2967. -char *text;
  2968. -char *(*entry_function) ();
  2969. -{
  2970. -    /* Number of slots in match_list. */
  2971. -    int match_list_size;
  2972. -
  2973. -    /* The list of matches. */
  2974. -    char **match_list =
  2975. -    (char **)xmalloc (((match_list_size = 10) + 1) * sizeof (char *));
  2976. -
  2977. -    /* Number of matches actually found. */
  2978. -    int matches = 0;
  2979. -
  2980. -    /* Temporary string binder. */
  2981. -    char *string;
  2982. -
  2983. -    match_list[1] = (char *)NULL;
  2984. -
  2985. -    while (string = (*entry_function) (text, matches))
  2986. -    {
  2987. -        if (matches + 1 == match_list_size)
  2988. -            match_list =
  2989. -                (char **)xrealloc (match_list,
  2990. -                ((match_list_size += 10) + 1) * sizeof (char *));
  2991. -
  2992. -        match_list[++matches] = string;
  2993. -        match_list[matches + 1] = (char *)NULL;
  2994. -    }
  2995. -
  2996. -    /* If there were any matches, then look through them finding out the
  2997. -     lowest common denominator.  That then becomes match_list[0]. */
  2998. -    if (matches)
  2999. -    {
  3000. -        register int i = 1;
  3001. -        int low = 100000;        /* Count of max-matched characters. */
  3002. -
  3003. -        /* If only one match, just use that. */
  3004. -        if (matches == 1)
  3005. -        {
  3006. -            match_list[0] = match_list[1];
  3007. -            match_list[1] = (char *)NULL;
  3008. -        }
  3009. -        else
  3010. -        {
  3011. -            /* Otherwise, compare each member of the list with
  3012. -         the next, finding out where they stop matching. */
  3013. -
  3014. -            while (i < matches)
  3015. -            {
  3016. -                register int c1, c2, si;
  3017. -
  3018. -                if (completion_case_fold)
  3019. -                {
  3020. -                    for (si = 0;
  3021. -                        (c1 = to_lower(match_list[i][si])) &&
  3022. -                        (c2 = to_lower(match_list[i + 1][si]));
  3023. -                        si++)
  3024. -                        if (c1 != c2) break;
  3025. -                }
  3026. -                else
  3027. -                {
  3028. -                    for (si = 0;
  3029. -                        (c1 = match_list[i][si]) &&
  3030. -                        (c2 = match_list[i + 1][si]);
  3031. -                        si++)
  3032. -                        if (c1 != c2) break;
  3033. -                }
  3034. -
  3035. -                if (low > si) low = si;
  3036. -                i++;
  3037. -            }
  3038. -            match_list[0] = (char *)xmalloc (low + 1);
  3039. -            strncpy (match_list[0], match_list[1], low);
  3040. -            match_list[0][low] = '\0';
  3041. -        }
  3042. -    }
  3043. -    else    /* There were no matches. */
  3044. -    {
  3045. -        free (match_list);
  3046. -        match_list = (char **)NULL;
  3047. -    }
  3048. -    return (match_list);
  3049. -}
  3050. -
  3051. -/* Okay, now we write the entry_function for filename completion.  In the
  3052. -   general case.  Note that completion in the shell is a little different
  3053. -   because of all the pathnames that must be followed when looking up the
  3054. -   completion for a command. */
  3055. -char *
  3056. -filename_completion_function (text, state)
  3057. -int state;
  3058. -char *text;
  3059. -{
  3060. -    static DIR *directory;
  3061. -    static char *filename = (char *)NULL;
  3062. -    static char *dirname = (char *)NULL;
  3063. -    static char *users_dirname = (char *)NULL;
  3064. -    static int filename_len;
  3065. -
  3066. -    struct direct *entry = (struct direct *)NULL;
  3067. -
  3068. -    /* If we don't have any state, then do some initialization. */
  3069. -    if (!state)
  3070. -    {
  3071. -        char *rindex (), *temp;
  3072. -
  3073. -        if (dirname) free (dirname);
  3074. -        if (filename) free (filename);
  3075. -        if (users_dirname) free (users_dirname);
  3076. -
  3077. -        filename = savestring (text);
  3078. -        if (!*text) text = ".";
  3079. -        dirname = savestring (text);
  3080. -
  3081. -        temp = rindex (dirname, '/');
  3082. -
  3083. -        if (temp)
  3084. -        {
  3085. -            strcpy (filename, ++temp);
  3086. -            *temp = '\0';
  3087. -        }
  3088. -        else
  3089. -            strcpy (dirname, ".");
  3090. -
  3091. -        /* We aren't done yet.  We also support the "~user" syntax. */
  3092. -
  3093. -        /* Save the version of the directory that the user typed. */
  3094. -        users_dirname = savestring (dirname);
  3095. -        directory = opendir (dirname);
  3096. -        filename_len = strlen (filename);
  3097. -
  3098. -        rl_filename_completion_desired = 1;
  3099. -    }
  3100. -
  3101. -    /* At this point we should entertain the possibility of hacking wildcarded
  3102. -     filenames, like /usr/man*\/te<TAB>.  If the directory name contains
  3103. -     globbing characters, then build an array of directories to glob on, and
  3104. -     glob on the first one. */
  3105. -
  3106. -    /* Now that we have some state, we can read the directory. */
  3107. -
  3108. -    while (directory && (entry = readdir (directory)))
  3109. -    {
  3110. -        /* Special case for no filename.
  3111. -     All entries except "." and ".." match. */
  3112. -        if (!filename_len)
  3113. -        {
  3114. -            if ((strcmp (entry->d_name, ".") != 0) &&
  3115. -                (strcmp (entry->d_name, "..") != 0))
  3116. -                break;
  3117. -        }
  3118. -        else
  3119. -        {
  3120. -            /* Otherwise, if these match upto the length of filename, then
  3121. -         it is a match. */
  3122. -#ifdef TMB_SYSV
  3123. -            if ((strlen (entry->d_name) >= filename_len) &&
  3124. -                (strncmp (filename, entry->d_name, filename_len) == 0))
  3125. -#else
  3126. -                if ((entry->d_namlen >= filename_len) &&
  3127. -                    (strncmp (filename, entry->d_name, filename_len) == 0))
  3128. -#endif /* TMB_SYSV */
  3129. -                {
  3130. -                    break;
  3131. -                }
  3132. -        }
  3133. -    }
  3134. -
  3135. -    if (!entry)
  3136. -    {
  3137. -        if (directory)
  3138. -        {
  3139. -            closedir (directory);
  3140. -            directory = (DIR *)NULL;
  3141. -        }
  3142. -        return (char *)NULL;
  3143. -    }
  3144. -    else
  3145. -    {
  3146. -        char *temp;
  3147. -
  3148. -        if (dirname && (strcmp (dirname, ".") != 0))
  3149. -        {
  3150. -#ifdef TMB_SYSV
  3151. -            temp = (char *)xmalloc (1 + strlen (users_dirname)
  3152. -                + strlen (entry->d_name));
  3153. -#else
  3154. -            temp = (char *)xmalloc (1 + strlen (users_dirname)
  3155. -                + entry->d_namlen);
  3156. -#endif /* TMB_SYSV */
  3157. -            strcpy (temp, users_dirname);
  3158. -            strcat (temp, entry->d_name);
  3159. -        }
  3160. -        else
  3161. -        {
  3162. -            temp = (savestring (entry->d_name));
  3163. -        }
  3164. -        return (temp);
  3165. -    }
  3166. -}
  3167. -
  3168. -
  3169. -/* **************************************************************** */
  3170. -/*                                    */
  3171. -/*            Binding keys                    */
  3172. -/*                                    */
  3173. -/* **************************************************************** */
  3174. -
  3175. -/* rl_add_defun (char *name, Function *function, int key)
  3176. -   Add NAME to the list of named functions.  Make FUNCTION
  3177. -   be the function that gets called.
  3178. -   If KEY is not -1, then bind it. */
  3179. -rl_add_defun (name, function, key)
  3180. -char *name;
  3181. -Function *function;
  3182. -int key;
  3183. -{
  3184. -    if (key != -1)
  3185. -        rl_bind_key (key, function);
  3186. -    rl_add_funmap_entry (name, function);
  3187. -}
  3188. -
  3189. -/* Bind KEY to FUNCTION.  Returns non-zero if KEY is out of range. */
  3190. -int
  3191. -rl_bind_key (key, function)
  3192. -int key;
  3193. -Function *function;
  3194. -{
  3195. -    if (key < 0)
  3196. -        return (key);
  3197. -
  3198. -    if (key > 127 && key < 256)
  3199. -    {
  3200. -        if (keymap[ESC].type == ISKMAP)
  3201. -        {
  3202. -            Keymap escmap = (Keymap)keymap[ESC].function;
  3203. -
  3204. -            key -= 128;
  3205. -            escmap[key].type = ISFUNC;
  3206. -            escmap[key].function = function;
  3207. -            return (0);
  3208. -        }
  3209. -        return (key);
  3210. -    }
  3211. -
  3212. -    keymap[key].type = ISFUNC;
  3213. -    keymap[key].function = function;
  3214. -    return (0);
  3215. -}
  3216. -
  3217. -/* Bind KEY to FUNCTION in MAP.  Returns non-zero in case of invalid
  3218. -   KEY. */
  3219. -int
  3220. -rl_bind_key_in_map (key, function, map)
  3221. -int key;
  3222. -Function *function;
  3223. -Keymap map;
  3224. -{
  3225. -    int result;
  3226. -    Keymap oldmap = keymap;
  3227. -
  3228. -    keymap = map;
  3229. -    result = rl_bind_key (key, function);
  3230. -    keymap = oldmap;
  3231. -    return (result);
  3232. -}
  3233. -
  3234. -/* Make KEY do nothing in the currently selected keymap.
  3235. -   Returns non-zero in case of error. */
  3236. -int
  3237. -rl_unbind_key (key)
  3238. -int key;
  3239. -{
  3240. -    return (rl_bind_key (key, (Function *)NULL));
  3241. -}
  3242. -
  3243. -/* Make KEY do nothing in MAP.
  3244. -   Returns non-zero in case of error. */
  3245. -int
  3246. -rl_unbind_key_in_map (key, map)
  3247. -int key;
  3248. -Keymap map;
  3249. -{
  3250. -    return (rl_bind_key_in_map (key, (Function *)NULL, map));
  3251. -}
  3252. -
  3253. -/* Bind the key sequence represented by the string KEYSEQ to
  3254. -   FUNCTION.  This makes new keymaps as necessary.  The initial
  3255. -   place to do bindings is in MAP. */
  3256. -rl_set_key (keyseq, function, map)
  3257. -char *keyseq;
  3258. -Function *function;
  3259. -Keymap map;
  3260. -{
  3261. -    rl_generic_bind (ISFUNC, keyseq, function, map);
  3262. -}
  3263. -
  3264. -/* Bind the key sequence represented by the string KEYSEQ to
  3265. -   the string of characters MACRO.  This makes new keymaps as
  3266. -   necessary.  The initial place to do bindings is in MAP. */
  3267. -rl_macro_bind (keyseq, macro, map)
  3268. -char *keyseq, *macro;
  3269. -Keymap map;
  3270. -{
  3271. -    char *macro_keys = (char *)xmalloc (2 * (strlen (macro)));
  3272. -    int macro_keys_len;
  3273. -
  3274. -    if (rl_translate_keyseq (macro, macro_keys, ¯o_keys_len))
  3275. -    {
  3276. -        free (macro_keys);
  3277. -        return;
  3278. -    }
  3279. -    rl_generic_bind (ISMACR, keyseq, macro_keys, map);
  3280. -}
  3281. -
  3282. -/* Bind the key sequence represented by the string KEYSEQ to
  3283. -   the arbitrary pointer DATA.  TYPE says what kind of data is
  3284. -   pointed to by DATA, right now this can be a function (ISFUNC),
  3285. -   a macro (ISMACR), or a keymap (ISKMAP).  This makes new keymaps
  3286. -   as necessary.  The initial place to do bindings is in MAP. */
  3287. -rl_generic_bind (type, keyseq, data, map)
  3288. -int type;
  3289. -char *keyseq, *data;
  3290. -Keymap map;
  3291. -{
  3292. -    char *keys;
  3293. -    int keys_len;
  3294. -    register int i;
  3295. -
  3296. -    /* If no keys to bind to, exit right away. */
  3297. -    if (!keyseq || !*keyseq)
  3298. -    {
  3299. -        if (type == ISMACR)
  3300. -            free (data);
  3301. -        return;
  3302. -    }
  3303. -
  3304. -    keys = (char *)alloca (1 + (2 * strlen (keyseq)));
  3305. -
  3306. -    /* Translate the ASCII representation of KEYSEQ into an array
  3307. -     of characters.  Stuff the characters into ARRAY, and the
  3308. -     length of ARRAY into LENGTH. */
  3309. -    if (rl_translate_keyseq (keyseq, keys, &keys_len))
  3310. -        return;
  3311. -
  3312. -    /* Bind keys, making new keymaps as necessary. */
  3313. -    for (i = 0; i < keys_len; i++)
  3314. -    {
  3315. -        if (i + 1 < keys_len)
  3316. -        {
  3317. -            if (map[keys[i]].type != ISKMAP)
  3318. -            {
  3319. -                if (map[i].type == ISMACR)
  3320. -                    free ((char *)map[i].function);
  3321. -
  3322. -                map[keys[i]].type = ISKMAP;
  3323. -                map[keys[i]].function = (Function *)rl_make_bare_keymap ();
  3324. -            }
  3325. -            map = (Keymap)map[keys[i]].function;
  3326. -        }
  3327. -        else
  3328. -        {
  3329. -            if (map[keys[i]].type == ISMACR)
  3330. -                free ((char *)map[keys[i]].function);
  3331. -
  3332. -            map[keys[i]].function = (Function *)data;
  3333. -            map[keys[i]].type = type;
  3334. -        }
  3335. -    }
  3336. -}
  3337. -
  3338. -/* Translate the ASCII representation of SEQ, stuffing the
  3339. -   values into ARRAY, an array of characters.  LEN gets the
  3340. -   final length of ARRAY.  Return non-zero if there was an
  3341. -   error parsing SEQ. */
  3342. -rl_translate_keyseq (seq, array, len)
  3343. -char *seq, *array;
  3344. -int *len;
  3345. -{
  3346. -    register int i, c, l = 0;
  3347. -
  3348. -    for (i = 0; c = seq[i]; i++)
  3349. -    {
  3350. -        if (c == '\\')
  3351. -        {
  3352. -            c = seq[++i];
  3353. -
  3354. -            if (!c)
  3355. -                break;
  3356. -
  3357. -            if (((c == 'C' || c == 'M') &&  seq[i + 1] == '-') ||
  3358. -                (c == 'e'))
  3359. -            {
  3360. -                /* Handle special case of backwards define. */
  3361. -                if (strncmp (&seq[i], "C-\\M-", 5) == 0)
  3362. -                {
  3363. -                    array[l++] = ESC;
  3364. -                    i += 5;
  3365. -                    array[l++] = CTRL (to_upper (seq[i]));
  3366. -                    if (!seq[i])
  3367. -                        i--;
  3368. -                    continue;
  3369. -                }
  3370. -
  3371. -                switch (c)
  3372. -                {
  3373. -                case 'M':
  3374. -                    i++;
  3375. -                    array[l++] = ESC;
  3376. -                    break;
  3377. -
  3378. -                case 'C':
  3379. -                    i += 2;
  3380. -                    array[l++] = CTRL (to_upper (seq[i]));
  3381. -                    break;
  3382. -
  3383. -                case 'e':
  3384. -                    array[l++] = ESC;
  3385. -                }
  3386. -
  3387. -                continue;
  3388. -            }
  3389. -        }
  3390. -        array[l++] = c;
  3391. -    }
  3392. -
  3393. -    *len = l;
  3394. -    array[l] = '\0';
  3395. -    return (0);
  3396. -}
  3397. -
  3398. -/* Return a pointer to the function that STRING represents.
  3399. -   If STRING doesn't have a matching function, then a NULL pointer
  3400. -   is returned. */
  3401. -Function *
  3402. -rl_named_function (string)
  3403. -char *string;
  3404. -{
  3405. -    register int i;
  3406. -
  3407. -    for (i = 0; funmap[i]; i++)
  3408. -        if (stricmp (funmap[i]->name, string) == 0)
  3409. -            return (funmap[i]->function);
  3410. -    return ((Function *)NULL);
  3411. -}
  3412. -
  3413. ---cut here---cut here---cut here---
  3414.