Annotation of embedaddon/readline/misc.c, revision 1.1.1.3

1.1       misho       1: /* misc.c -- miscellaneous bindable readline functions. */
                      2: 
1.1.1.3 ! misho       3: /* Copyright (C) 1987-2019 Free Software Foundation, Inc.
1.1       misho       4: 
                      5:    This file is part of the GNU Readline Library (Readline), a library
                      6:    for reading lines of text with interactive input and history editing.      
                      7: 
                      8:    Readline is free software: you can redistribute it and/or modify
                      9:    it under the terms of the GNU General Public License as published by
                     10:    the Free Software Foundation, either version 3 of the License, or
                     11:    (at your option) any later version.
                     12: 
                     13:    Readline is distributed in the hope that it will be useful,
                     14:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16:    GNU General Public License for more details.
                     17: 
                     18:    You should have received a copy of the GNU General Public License
                     19:    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
                     20: */
                     21: 
                     22: #define READLINE_LIBRARY
                     23: 
                     24: #if defined (HAVE_CONFIG_H)
                     25: #  include <config.h>
                     26: #endif
                     27: 
                     28: #if defined (HAVE_UNISTD_H)
                     29: #  include <unistd.h>
                     30: #endif /* HAVE_UNISTD_H */
                     31: 
                     32: #if defined (HAVE_STDLIB_H)
                     33: #  include <stdlib.h>
                     34: #else
                     35: #  include "ansi_stdlib.h"
                     36: #endif /* HAVE_STDLIB_H */
                     37: 
                     38: #if defined (HAVE_LOCALE_H)
                     39: #  include <locale.h>
                     40: #endif
                     41: 
                     42: #include <stdio.h>
                     43: 
                     44: /* System-specific feature definitions and include files. */
                     45: #include "rldefs.h"
                     46: #include "rlmbutil.h"
                     47: 
                     48: /* Some standard library routines. */
                     49: #include "readline.h"
                     50: #include "history.h"
                     51: 
                     52: #include "rlprivate.h"
                     53: #include "rlshell.h"
                     54: #include "xmalloc.h"
                     55: 
                     56: static int rl_digit_loop PARAMS((void));
                     57: static void _rl_history_set_point PARAMS((void));
                     58: 
                     59: /* Forward declarations used in this file */
                     60: void _rl_free_history_entry PARAMS((HIST_ENTRY *));
                     61: 
                     62: /* If non-zero, rl_get_previous_history and rl_get_next_history attempt
                     63:    to preserve the value of rl_point from line to line. */
                     64: int _rl_history_preserve_point = 0;
                     65: 
                     66: _rl_arg_cxt _rl_argcxt;
                     67: 
                     68: /* Saved target point for when _rl_history_preserve_point is set.  Special
                     69:    value of -1 means that point is at the end of the line. */
                     70: int _rl_history_saved_point = -1;
                     71: 
                     72: /* **************************************************************** */
                     73: /*                                                                 */
                     74: /*                     Numeric Arguments                           */
                     75: /*                                                                 */
                     76: /* **************************************************************** */
                     77: 
                     78: int
1.1.1.3 ! misho      79: _rl_arg_overflow (void)
1.1       misho      80: {
                     81:   if (rl_numeric_arg > 1000000)
                     82:     {
                     83:       _rl_argcxt = 0;
                     84:       rl_explicit_arg = rl_numeric_arg = 0;
                     85:       rl_ding ();
                     86:       rl_restore_prompt ();
                     87:       rl_clear_message ();
                     88:       RL_UNSETSTATE(RL_STATE_NUMERICARG);
                     89:       return 1;
                     90:     }
                     91:   return 0;
                     92: }
                     93: 
                     94: void
1.1.1.3 ! misho      95: _rl_arg_init (void)
1.1       misho      96: {
                     97:   rl_save_prompt ();
                     98:   _rl_argcxt = 0;
                     99:   RL_SETSTATE(RL_STATE_NUMERICARG);
                    100: }
                    101: 
                    102: int
1.1.1.3 ! misho     103: _rl_arg_getchar (void)
1.1       misho     104: {
                    105:   int c;
                    106: 
                    107:   rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
                    108:   RL_SETSTATE(RL_STATE_MOREINPUT);
                    109:   c = rl_read_key ();
                    110:   RL_UNSETSTATE(RL_STATE_MOREINPUT);
                    111: 
                    112:   return c;
                    113: }
                    114: 
                    115: /* Process C as part of the current numeric argument.  Return -1 if the
                    116:    argument should be aborted, 0 if we should not read any more chars, and
                    117:    1 if we should continue to read chars. */
                    118: int
1.1.1.3 ! misho     119: _rl_arg_dispatch (_rl_arg_cxt cxt, int c)
1.1       misho     120: {
                    121:   int key, r;
                    122: 
                    123:   key = c;
                    124: 
                    125:   /* If we see a key bound to `universal-argument' after seeing digits,
                    126:       it ends the argument but is otherwise ignored. */
1.1.1.3 ! misho     127:   if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
1.1       misho     128:     {
                    129:       if ((cxt & NUM_SAWDIGITS) == 0)
                    130:        {
                    131:          rl_numeric_arg *= 4;
                    132:          return 1;
                    133:        }
                    134:       else if (RL_ISSTATE (RL_STATE_CALLBACK))
                    135:         {
                    136:           _rl_argcxt |= NUM_READONE;
                    137:           return 0;    /* XXX */
                    138:         }
                    139:       else
                    140:        {
1.1.1.3 ! misho     141:          key = _rl_bracketed_read_key ();
1.1       misho     142:          rl_restore_prompt ();
                    143:          rl_clear_message ();
                    144:          RL_UNSETSTATE(RL_STATE_NUMERICARG);
                    145:          if (key < 0)
                    146:            return -1;
                    147:          return (_rl_dispatch (key, _rl_keymap));
                    148:        }
                    149:     }
                    150: 
                    151:   c = UNMETA (c);
                    152: 
                    153:   if (_rl_digit_p (c))
                    154:     {
                    155:       r = _rl_digit_value (c);         
                    156:       rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) +  r : r;
                    157:       rl_explicit_arg = 1;
                    158:       _rl_argcxt |= NUM_SAWDIGITS;
                    159:     }
                    160:   else if (c == '-' && rl_explicit_arg == 0)
                    161:     {
                    162:       rl_numeric_arg = 1;
                    163:       _rl_argcxt |= NUM_SAWMINUS;
                    164:       rl_arg_sign = -1;
                    165:     }
                    166:   else
                    167:     {
                    168:       /* Make M-- command equivalent to M--1 command. */
                    169:       if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
                    170:        rl_explicit_arg = 1;
                    171:       rl_restore_prompt ();
                    172:       rl_clear_message ();
                    173:       RL_UNSETSTATE(RL_STATE_NUMERICARG);
                    174: 
                    175:       r = _rl_dispatch (key, _rl_keymap);
                    176:       if (RL_ISSTATE (RL_STATE_CALLBACK))
                    177:        {
                    178:          /* At worst, this will cause an extra redisplay.  Otherwise,
                    179:             we have to wait until the next character comes in. */
                    180:          if (rl_done == 0)
                    181:            (*rl_redisplay_function) ();
                    182:          r = 0;
                    183:        }
                    184:       return r;
                    185:     }
                    186: 
                    187:   return 1;
                    188: }
                    189: 
                    190: /* Handle C-u style numeric args, as well as M--, and M-digits. */
                    191: static int
1.1.1.3 ! misho     192: rl_digit_loop (void)
1.1       misho     193: {
                    194:   int c, r;
                    195: 
                    196:   while (1)
                    197:     {
                    198:       if (_rl_arg_overflow ())
                    199:        return 1;
                    200: 
                    201:       c = _rl_arg_getchar ();
                    202: 
                    203:       if (c < 0)
                    204:        {
                    205:          _rl_abort_internal ();
                    206:          return -1;
                    207:        }
                    208: 
                    209:       r = _rl_arg_dispatch (_rl_argcxt, c);
                    210:       if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
                    211:         break;
                    212:     }
                    213: 
                    214:   return r;
                    215: }
                    216: 
                    217: /* Create a default argument. */
                    218: void
1.1.1.3 ! misho     219: _rl_reset_argument (void)
1.1       misho     220: {
                    221:   rl_numeric_arg = rl_arg_sign = 1;
                    222:   rl_explicit_arg = 0;
                    223:   _rl_argcxt = 0;
                    224: }
                    225: 
                    226: /* Start a numeric argument with initial value KEY */
                    227: int
1.1.1.3 ! misho     228: rl_digit_argument (int ignore, int key)
1.1       misho     229: {
                    230:   _rl_arg_init ();
                    231:   if (RL_ISSTATE (RL_STATE_CALLBACK))
                    232:     {
                    233:       _rl_arg_dispatch (_rl_argcxt, key);
                    234:       rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
                    235:       return 0;
                    236:     }
                    237:   else
                    238:     {
                    239:       rl_execute_next (key);
                    240:       return (rl_digit_loop ());
                    241:     }
                    242: }
                    243: 
                    244: /* C-u, universal argument.  Multiply the current argument by 4.
                    245:    Read a key.  If the key has nothing to do with arguments, then
                    246:    dispatch on it.  If the key is the abort character then abort. */
                    247: int
1.1.1.3 ! misho     248: rl_universal_argument (int count, int key)
1.1       misho     249: {
                    250:   _rl_arg_init ();
                    251:   rl_numeric_arg *= 4;
                    252: 
                    253:   return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
                    254: }
                    255: 
                    256: int
1.1.1.3 ! misho     257: _rl_arg_callback (_rl_arg_cxt cxt)
1.1       misho     258: {
                    259:   int c, r;
                    260: 
                    261:   c = _rl_arg_getchar ();
1.1.1.3 ! misho     262:   if (c < 0)
        !           263:     return (1);                /* EOF */
1.1       misho     264: 
                    265:   if (_rl_argcxt & NUM_READONE)
                    266:     {
                    267:       _rl_argcxt &= ~NUM_READONE;
                    268:       rl_restore_prompt ();
                    269:       rl_clear_message ();
                    270:       RL_UNSETSTATE(RL_STATE_NUMERICARG);
                    271:       rl_execute_next (c);
                    272:       return 0;
                    273:     }
                    274: 
                    275:   r = _rl_arg_dispatch (cxt, c);
1.1.1.3 ! misho     276:   if (r > 0)
        !           277:     rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
1.1       misho     278:   return (r != 1);
                    279: }
                    280: 
                    281: /* What to do when you abort reading an argument. */
                    282: int
1.1.1.3 ! misho     283: rl_discard_argument (void)
1.1       misho     284: {
                    285:   rl_ding ();
                    286:   rl_clear_message ();
                    287:   _rl_reset_argument ();
                    288: 
                    289:   return 0;
                    290: }
                    291: 
                    292: /* **************************************************************** */
                    293: /*                                                                 */
                    294: /*                     History Utilities                           */
                    295: /*                                                                 */
                    296: /* **************************************************************** */
                    297: 
                    298: /* We already have a history library, and that is what we use to control
                    299:    the history features of readline.  This is our local interface to
                    300:    the history mechanism. */
                    301: 
                    302: /* While we are editing the history, this is the saved
                    303:    version of the original line. */
                    304: HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
                    305: 
                    306: /* Set the history pointer back to the last entry in the history. */
                    307: void
1.1.1.3 ! misho     308: _rl_start_using_history (void)
1.1       misho     309: {
                    310:   using_history ();
                    311:   if (_rl_saved_line_for_history)
                    312:     _rl_free_history_entry (_rl_saved_line_for_history);
                    313: 
                    314:   _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
                    315: }
                    316: 
                    317: /* Free the contents (and containing structure) of a HIST_ENTRY. */
                    318: void
1.1.1.3 ! misho     319: _rl_free_history_entry (HIST_ENTRY *entry)
1.1       misho     320: {
                    321:   if (entry == 0)
                    322:     return;
                    323: 
                    324:   FREE (entry->line);
                    325:   FREE (entry->timestamp);
                    326: 
                    327:   xfree (entry);
                    328: }
                    329: 
                    330: /* Perhaps put back the current line if it has changed. */
                    331: int
1.1.1.3 ! misho     332: rl_maybe_replace_line (void)
1.1       misho     333: {
                    334:   HIST_ENTRY *temp;
                    335: 
                    336:   temp = current_history ();
                    337:   /* If the current line has changed, save the changes. */
                    338:   if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
                    339:     {
                    340:       temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
                    341:       xfree (temp->line);
                    342:       FREE (temp->timestamp);
                    343:       xfree (temp);
                    344:     }
                    345:   return 0;
                    346: }
                    347: 
                    348: /* Restore the _rl_saved_line_for_history if there is one. */
                    349: int
1.1.1.3 ! misho     350: rl_maybe_unsave_line (void)
1.1       misho     351: {
                    352:   if (_rl_saved_line_for_history)
                    353:     {
                    354:       /* Can't call with `1' because rl_undo_list might point to an undo
                    355:         list from a history entry, as in rl_replace_from_history() below. */
                    356:       rl_replace_line (_rl_saved_line_for_history->line, 0);
                    357:       rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
                    358:       _rl_free_history_entry (_rl_saved_line_for_history);
                    359:       _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
                    360:       rl_point = rl_end;       /* rl_replace_line sets rl_end */
                    361:     }
                    362:   else
                    363:     rl_ding ();
                    364:   return 0;
                    365: }
                    366: 
                    367: /* Save the current line in _rl_saved_line_for_history. */
                    368: int
1.1.1.3 ! misho     369: rl_maybe_save_line (void)
1.1       misho     370: {
                    371:   if (_rl_saved_line_for_history == 0)
                    372:     {
                    373:       _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
                    374:       _rl_saved_line_for_history->line = savestring (rl_line_buffer);
                    375:       _rl_saved_line_for_history->timestamp = (char *)NULL;
                    376:       _rl_saved_line_for_history->data = (char *)rl_undo_list;
                    377:     }
                    378: 
                    379:   return 0;
                    380: }
                    381: 
                    382: int
1.1.1.3 ! misho     383: _rl_free_saved_history_line (void)
1.1       misho     384: {
                    385:   if (_rl_saved_line_for_history)
                    386:     {
                    387:       _rl_free_history_entry (_rl_saved_line_for_history);
                    388:       _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
                    389:     }
                    390:   return 0;
                    391: }
                    392: 
                    393: static void
1.1.1.3 ! misho     394: _rl_history_set_point (void)
1.1       misho     395: {
                    396:   rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
                    397:                ? _rl_history_saved_point
                    398:                : rl_end;
                    399:   if (rl_point > rl_end)
                    400:     rl_point = rl_end;
                    401: 
                    402: #if defined (VI_MODE)
                    403:   if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
                    404:     rl_point = 0;
                    405: #endif /* VI_MODE */
                    406: 
                    407:   if (rl_editing_mode == emacs_mode)
                    408:     rl_mark = (rl_point == rl_end ? 0 : rl_end);
                    409: }
                    410: 
                    411: void
1.1.1.3 ! misho     412: rl_replace_from_history (HIST_ENTRY *entry, int flags)
1.1       misho     413: {
                    414:   /* Can't call with `1' because rl_undo_list might point to an undo list
                    415:      from a history entry, just like we're setting up here. */
                    416:   rl_replace_line (entry->line, 0);
                    417:   rl_undo_list = (UNDO_LIST *)entry->data;
                    418:   rl_point = rl_end;
                    419:   rl_mark = 0;
                    420: 
                    421: #if defined (VI_MODE)
                    422:   if (rl_editing_mode == vi_mode)
                    423:     {
                    424:       rl_point = 0;
                    425:       rl_mark = rl_end;
                    426:     }
                    427: #endif
                    428: }
                    429: 
                    430: /* Process and free undo lists attached to each history entry prior to the
                    431:    current entry, inclusive, reverting each line to its saved state.  This 
                    432:    is destructive, and state about the current line is lost.  This is not
                    433:    intended to be called while actively editing, and the current line is
                    434:    not assumed to have been added to the history list. */
                    435: void
1.1.1.3 ! misho     436: _rl_revert_previous_lines (void)
1.1       misho     437: {
                    438:   int hpos;
                    439:   HIST_ENTRY *entry;
                    440:   UNDO_LIST *ul, *saved_undo_list;
                    441:   char *lbuf;
                    442: 
                    443:   lbuf = savestring (rl_line_buffer);
                    444:   saved_undo_list = rl_undo_list;
                    445:   hpos = where_history ();
                    446: 
                    447:   entry = (hpos == history_length) ? previous_history () : current_history ();
                    448:   while (entry)
                    449:     {
                    450:       if (ul = (UNDO_LIST *)entry->data)
                    451:        {
                    452:          if (ul == saved_undo_list)
                    453:            saved_undo_list = 0;
                    454:          /* Set up rl_line_buffer and other variables from history entry */
                    455:          rl_replace_from_history (entry, 0);   /* entry->line is now current */
1.1.1.2   misho     456:          entry->data = 0;                      /* entry->data is now current undo list */
1.1       misho     457:          /* Undo all changes to this history entry */
                    458:          while (rl_undo_list)
                    459:            rl_do_undo ();
                    460:          /* And copy the reverted line back to the history entry, preserving
                    461:             the timestamp. */
                    462:          FREE (entry->line);
                    463:          entry->line = savestring (rl_line_buffer);
                    464:        }
                    465:       entry = previous_history ();
                    466:     }
                    467: 
                    468:   /* Restore history state */
                    469:   rl_undo_list = saved_undo_list;      /* may have been set to null */
                    470:   history_set_pos (hpos);
                    471:   
                    472:   /* reset the line buffer */
                    473:   rl_replace_line (lbuf, 0);
                    474:   _rl_set_the_line ();
                    475: 
                    476:   /* and clean up */
                    477:   xfree (lbuf);
                    478: }  
                    479: 
1.1.1.3 ! misho     480: /* Revert all lines in the history by making sure we are at the end of the
        !           481:    history before calling _rl_revert_previous_lines() */
        !           482: void
        !           483: _rl_revert_all_lines (void)
        !           484: {
        !           485:   int pos;
        !           486: 
        !           487:   pos = where_history ();
        !           488:   using_history ();
        !           489:   _rl_revert_previous_lines ();
        !           490:   history_set_pos (pos);
        !           491: }
        !           492: 
1.1       misho     493: /* Free the history list, including private readline data and take care
                    494:    of pointer aliases to history data.  Resets rl_undo_list if it points
                    495:    to an UNDO_LIST * saved as some history entry's data member.  This
                    496:    should not be called while editing is active. */
                    497: void
1.1.1.3 ! misho     498: rl_clear_history (void)
1.1       misho     499: {
                    500:   HIST_ENTRY **hlist, *hent;
                    501:   register int i;
                    502:   UNDO_LIST *ul, *saved_undo_list;
                    503: 
                    504:   saved_undo_list = rl_undo_list;
                    505:   hlist = history_list ();             /* direct pointer, not copy */
                    506: 
                    507:   for (i = 0; i < history_length; i++)
                    508:     {
                    509:       hent = hlist[i];
                    510:       if (ul = (UNDO_LIST *)hent->data)
                    511:        {
                    512:          if (ul == saved_undo_list)
                    513:            saved_undo_list = 0;
                    514:          _rl_free_undo_list (ul);
                    515:          hent->data = 0;
                    516:        }
                    517:       _rl_free_history_entry (hent);
                    518:     }
                    519: 
                    520:   history_offset = history_length = 0;
                    521:   rl_undo_list = saved_undo_list;      /* should be NULL */
                    522: }
                    523: 
                    524: /* **************************************************************** */
                    525: /*                                                                 */
                    526: /*                     History Commands                            */
                    527: /*                                                                 */
                    528: /* **************************************************************** */
                    529: 
                    530: /* Meta-< goes to the start of the history. */
                    531: int
1.1.1.3 ! misho     532: rl_beginning_of_history (int count, int key)
1.1       misho     533: {
                    534:   return (rl_get_previous_history (1 + where_history (), key));
                    535: }
                    536: 
                    537: /* Meta-> goes to the end of the history.  (The current line). */
                    538: int
1.1.1.3 ! misho     539: rl_end_of_history (int count, int key)
1.1       misho     540: {
                    541:   rl_maybe_replace_line ();
                    542:   using_history ();
                    543:   rl_maybe_unsave_line ();
                    544:   return 0;
                    545: }
                    546: 
                    547: /* Move down to the next history line. */
                    548: int
1.1.1.3 ! misho     549: rl_get_next_history (int count, int key)
1.1       misho     550: {
                    551:   HIST_ENTRY *temp;
                    552: 
                    553:   if (count < 0)
                    554:     return (rl_get_previous_history (-count, key));
                    555: 
                    556:   if (count == 0)
                    557:     return 0;
                    558: 
                    559:   rl_maybe_replace_line ();
                    560: 
                    561:   /* either not saved by rl_newline or at end of line, so set appropriately. */
                    562:   if (_rl_history_saved_point == -1 && (rl_point || rl_end))
                    563:     _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
                    564: 
                    565:   temp = (HIST_ENTRY *)NULL;
                    566:   while (count)
                    567:     {
                    568:       temp = next_history ();
                    569:       if (!temp)
                    570:        break;
                    571:       --count;
                    572:     }
                    573: 
                    574:   if (temp == 0)
                    575:     rl_maybe_unsave_line ();
                    576:   else
                    577:     {
                    578:       rl_replace_from_history (temp, 0);
                    579:       _rl_history_set_point ();
                    580:     }
                    581:   return 0;
                    582: }
                    583: 
                    584: /* Get the previous item out of our interactive history, making it the current
                    585:    line.  If there is no previous history, just ding. */
                    586: int
1.1.1.3 ! misho     587: rl_get_previous_history (int count, int key)
1.1       misho     588: {
                    589:   HIST_ENTRY *old_temp, *temp;
1.1.1.3 ! misho     590:   int had_saved_line;
1.1       misho     591: 
                    592:   if (count < 0)
                    593:     return (rl_get_next_history (-count, key));
                    594: 
1.1.1.3 ! misho     595:   if (count == 0 || history_list () == 0)
1.1       misho     596:     return 0;
                    597: 
                    598:   /* either not saved by rl_newline or at end of line, so set appropriately. */
                    599:   if (_rl_history_saved_point == -1 && (rl_point || rl_end))
                    600:     _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
                    601: 
                    602:   /* If we don't have a line saved, then save this one. */
1.1.1.3 ! misho     603:   had_saved_line = _rl_saved_line_for_history != 0;
1.1       misho     604:   rl_maybe_save_line ();
                    605: 
                    606:   /* If the current line has changed, save the changes. */
                    607:   rl_maybe_replace_line ();
                    608: 
                    609:   temp = old_temp = (HIST_ENTRY *)NULL;
                    610:   while (count)
                    611:     {
                    612:       temp = previous_history ();
                    613:       if (temp == 0)
                    614:        break;
                    615: 
                    616:       old_temp = temp;
                    617:       --count;
                    618:     }
                    619: 
                    620:   /* If there was a large argument, and we moved back to the start of the
                    621:      history, that is not an error.  So use the last value found. */
                    622:   if (!temp && old_temp)
                    623:     temp = old_temp;
                    624: 
                    625:   if (temp == 0)
1.1.1.3 ! misho     626:     {
        !           627:       if (had_saved_line == 0)
        !           628:         _rl_free_saved_history_line ();
        !           629:       rl_ding ();
        !           630:     }
1.1       misho     631:   else
                    632:     {
                    633:       rl_replace_from_history (temp, 0);
                    634:       _rl_history_set_point ();
                    635:     }
                    636: 
                    637:   return 0;
                    638: }
                    639: 
1.1.1.3 ! misho     640: /* The equivalent of the Korn shell C-o operate-and-get-next-history-line
        !           641:    editing command. */
        !           642: 
        !           643: /* This could stand to be global to the readline library */
        !           644: static rl_hook_func_t *_rl_saved_internal_startup_hook = 0;
        !           645: static int saved_history_logical_offset = -1;
        !           646: 
        !           647: #define HISTORY_FULL() (history_is_stifled () && history_length >= history_max_entries)
        !           648: 
        !           649: static int
        !           650: set_saved_history ()
        !           651: {
        !           652:   int absolute_offset, count;
        !           653: 
        !           654:   if (saved_history_logical_offset >= 0)
        !           655:     {
        !           656:       absolute_offset = saved_history_logical_offset - history_base;
        !           657:       count = where_history () - absolute_offset;
        !           658:       rl_get_previous_history (count, 0);
        !           659:     }
        !           660:   saved_history_logical_offset = -1;
        !           661:   _rl_internal_startup_hook = _rl_saved_internal_startup_hook;
        !           662: 
        !           663:   return (0);
        !           664: }
        !           665: 
        !           666: int
        !           667: rl_operate_and_get_next (count, c)
        !           668:      int count, c;
        !           669: {
        !           670:   /* Accept the current line. */
        !           671:   rl_newline (1, c);
        !           672: 
        !           673:   saved_history_logical_offset = rl_explicit_arg ? count : where_history () + history_base + 1;
        !           674: 
        !           675: 
        !           676:   _rl_saved_internal_startup_hook = _rl_internal_startup_hook;
        !           677:   _rl_internal_startup_hook = set_saved_history;
        !           678: 
        !           679:   return 0;
        !           680: }
        !           681: 
1.1       misho     682: /* **************************************************************** */
                    683: /*                                                                 */
                    684: /*                         Editing Modes                           */
                    685: /*                                                                 */
                    686: /* **************************************************************** */
                    687: /* How to toggle back and forth between editing modes. */
                    688: int
1.1.1.3 ! misho     689: rl_vi_editing_mode (int count, int key)
1.1       misho     690: {
                    691: #if defined (VI_MODE)
                    692:   _rl_set_insert_mode (RL_IM_INSERT, 1);       /* vi mode ignores insert mode */
                    693:   rl_editing_mode = vi_mode;
                    694:   rl_vi_insert_mode (1, key);
                    695: #endif /* VI_MODE */
                    696: 
                    697:   return 0;
                    698: }
                    699: 
                    700: int
1.1.1.3 ! misho     701: rl_emacs_editing_mode (int count, int key)
1.1       misho     702: {
                    703:   rl_editing_mode = emacs_mode;
                    704:   _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
                    705:   _rl_keymap = emacs_standard_keymap;
                    706: 
                    707:   if (_rl_show_mode_in_prompt)
                    708:     _rl_reset_prompt ();
                    709: 
                    710:   return 0;
                    711: }
                    712: 
                    713: /* Function for the rest of the library to use to set insert/overwrite mode. */
                    714: void
1.1.1.3 ! misho     715: _rl_set_insert_mode (int im, int force)
1.1       misho     716: {
                    717: #ifdef CURSOR_MODE
                    718:   _rl_set_cursor (im, force);
                    719: #endif
                    720: 
                    721:   rl_insert_mode = im;
                    722: }
                    723: 
                    724: /* Toggle overwrite mode.  A positive explicit argument selects overwrite
                    725:    mode.  A negative or zero explicit argument selects insert mode. */
                    726: int
1.1.1.3 ! misho     727: rl_overwrite_mode (int count, int key)
1.1       misho     728: {
                    729:   if (rl_explicit_arg == 0)
                    730:     _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
                    731:   else if (count > 0)
                    732:     _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
                    733:   else
                    734:     _rl_set_insert_mode (RL_IM_INSERT, 0);
                    735: 
                    736:   return 0;
                    737: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>