Annotation of embedaddon/readline/kill.c, revision 1.1.1.1

1.1       misho       1: /* kill.c -- kill ring management. */
                      2: 
                      3: /* Copyright (C) 1994 Free Software Foundation, Inc.
                      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: #include <sys/types.h>
                     29: 
                     30: #if defined (HAVE_UNISTD_H)
                     31: #  include <unistd.h>           /* for _POSIX_VERSION */
                     32: #endif /* HAVE_UNISTD_H */
                     33: 
                     34: #if defined (HAVE_STDLIB_H)
                     35: #  include <stdlib.h>
                     36: #else
                     37: #  include "ansi_stdlib.h"
                     38: #endif /* HAVE_STDLIB_H */
                     39: 
                     40: #include <stdio.h>
                     41: 
                     42: /* System-specific feature definitions and include files. */
                     43: #include "rldefs.h"
                     44: 
                     45: /* Some standard library routines. */
                     46: #include "readline.h"
                     47: #include "history.h"
                     48: 
                     49: #include "rlprivate.h"
                     50: #include "xmalloc.h"
                     51: 
                     52: /* **************************************************************** */
                     53: /*                                                                 */
                     54: /*                     Killing Mechanism                           */
                     55: /*                                                                 */
                     56: /* **************************************************************** */
                     57: 
                     58: /* What we assume for a max number of kills. */
                     59: #define DEFAULT_MAX_KILLS 10
                     60: 
                     61: /* The real variable to look at to find out when to flush kills. */
                     62: static int rl_max_kills =  DEFAULT_MAX_KILLS;
                     63: 
                     64: /* Where to store killed text. */
                     65: static char **rl_kill_ring = (char **)NULL;
                     66: 
                     67: /* Where we are in the kill ring. */
                     68: static int rl_kill_index;
                     69: 
                     70: /* How many slots we have in the kill ring. */
                     71: static int rl_kill_ring_length;
                     72: 
                     73: static int _rl_copy_to_kill_ring PARAMS((char *, int));
                     74: static int region_kill_internal PARAMS((int));
                     75: static int _rl_copy_word_as_kill PARAMS((int, int));
                     76: static int rl_yank_nth_arg_internal PARAMS((int, int, int));
                     77: 
                     78: /* How to say that you only want to save a certain amount
                     79:    of kill material. */
                     80: int
                     81: rl_set_retained_kills (num)
                     82:      int num;
                     83: {
                     84:   return 0;
                     85: }
                     86: 
                     87: /* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
                     88:    This uses TEXT directly, so the caller must not free it.  If APPEND is
                     89:    non-zero, and the last command was a kill, the text is appended to the
                     90:    current kill ring slot, otherwise prepended. */
                     91: static int
                     92: _rl_copy_to_kill_ring (text, append)
                     93:      char *text;
                     94:      int append;
                     95: {
                     96:   char *old, *new;
                     97:   int slot;
                     98: 
                     99:   /* First, find the slot to work with. */
                    100:   if (_rl_last_command_was_kill == 0)
                    101:     {
                    102:       /* Get a new slot.  */
                    103:       if (rl_kill_ring == 0)
                    104:        {
                    105:          /* If we don't have any defined, then make one. */
                    106:          rl_kill_ring = (char **)
                    107:            xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
                    108:          rl_kill_ring[slot = 0] = (char *)NULL;
                    109:        }
                    110:       else
                    111:        {
                    112:          /* We have to add a new slot on the end, unless we have
                    113:             exceeded the max limit for remembering kills. */
                    114:          slot = rl_kill_ring_length;
                    115:          if (slot == rl_max_kills)
                    116:            {
                    117:              register int i;
                    118:              xfree (rl_kill_ring[0]);
                    119:              for (i = 0; i < slot; i++)
                    120:                rl_kill_ring[i] = rl_kill_ring[i + 1];
                    121:            }
                    122:          else
                    123:            {
                    124:              slot = rl_kill_ring_length += 1;
                    125:              rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
                    126:            }
                    127:          rl_kill_ring[--slot] = (char *)NULL;
                    128:        }
                    129:     }
                    130:   else
                    131:     slot = rl_kill_ring_length - 1;
                    132: 
                    133:   /* If the last command was a kill, prepend or append. */
                    134:   if (_rl_last_command_was_kill && rl_editing_mode != vi_mode)
                    135:     {
                    136:       old = rl_kill_ring[slot];
                    137:       new = (char *)xmalloc (1 + strlen (old) + strlen (text));
                    138: 
                    139:       if (append)
                    140:        {
                    141:          strcpy (new, old);
                    142:          strcat (new, text);
                    143:        }
                    144:       else
                    145:        {
                    146:          strcpy (new, text);
                    147:          strcat (new, old);
                    148:        }
                    149:       xfree (old);
                    150:       xfree (text);
                    151:       rl_kill_ring[slot] = new;
                    152:     }
                    153:   else
                    154:     rl_kill_ring[slot] = text;
                    155: 
                    156:   rl_kill_index = slot;
                    157:   return 0;
                    158: }
                    159: 
                    160: /* The way to kill something.  This appends or prepends to the last
                    161:    kill, if the last command was a kill command.  if FROM is less
                    162:    than TO, then the text is appended, otherwise prepended.  If the
                    163:    last command was not a kill command, then a new slot is made for
                    164:    this kill. */
                    165: int
                    166: rl_kill_text (from, to)
                    167:      int from, to;
                    168: {
                    169:   char *text;
                    170: 
                    171:   /* Is there anything to kill? */
                    172:   if (from == to)
                    173:     {
                    174:       _rl_last_command_was_kill++;
                    175:       return 0;
                    176:     }
                    177: 
                    178:   text = rl_copy_text (from, to);
                    179: 
                    180:   /* Delete the copied text from the line. */
                    181:   rl_delete_text (from, to);
                    182: 
                    183:   _rl_copy_to_kill_ring (text, from < to);
                    184: 
                    185:   _rl_last_command_was_kill++;
                    186:   return 0;
                    187: }
                    188: 
                    189: /* Now REMEMBER!  In order to do prepending or appending correctly, kill
                    190:    commands always make rl_point's original position be the FROM argument,
                    191:    and rl_point's extent be the TO argument. */
                    192: 
                    193: /* **************************************************************** */
                    194: /*                                                                 */
                    195: /*                     Killing Commands                            */
                    196: /*                                                                 */
                    197: /* **************************************************************** */
                    198: 
                    199: /* Delete the word at point, saving the text in the kill ring. */
                    200: int
                    201: rl_kill_word (count, key)
                    202:      int count, key;
                    203: {
                    204:   int orig_point;
                    205: 
                    206:   if (count < 0)
                    207:     return (rl_backward_kill_word (-count, key));
                    208:   else
                    209:     {
                    210:       orig_point = rl_point;
                    211:       rl_forward_word (count, key);
                    212: 
                    213:       if (rl_point != orig_point)
                    214:        rl_kill_text (orig_point, rl_point);
                    215: 
                    216:       rl_point = orig_point;
                    217:       if (rl_editing_mode == emacs_mode)
                    218:        rl_mark = rl_point;
                    219:     }
                    220:   return 0;
                    221: }
                    222: 
                    223: /* Rubout the word before point, placing it on the kill ring. */
                    224: int
                    225: rl_backward_kill_word (count, ignore)
                    226:      int count, ignore;
                    227: {
                    228:   int orig_point;
                    229: 
                    230:   if (count < 0)
                    231:     return (rl_kill_word (-count, ignore));
                    232:   else
                    233:     {
                    234:       orig_point = rl_point;
                    235:       rl_backward_word (count, ignore);
                    236: 
                    237:       if (rl_point != orig_point)
                    238:        rl_kill_text (orig_point, rl_point);
                    239: 
                    240:       if (rl_editing_mode == emacs_mode)
                    241:        rl_mark = rl_point;
                    242:     }
                    243:   return 0;
                    244: }
                    245: 
                    246: /* Kill from here to the end of the line.  If DIRECTION is negative, kill
                    247:    back to the line start instead. */
                    248: int
                    249: rl_kill_line (direction, ignore)
                    250:      int direction, ignore;
                    251: {
                    252:   int orig_point;
                    253: 
                    254:   if (direction < 0)
                    255:     return (rl_backward_kill_line (1, ignore));
                    256:   else
                    257:     {
                    258:       orig_point = rl_point;
                    259:       rl_end_of_line (1, ignore);
                    260:       if (orig_point != rl_point)
                    261:        rl_kill_text (orig_point, rl_point);
                    262:       rl_point = orig_point;
                    263:       if (rl_editing_mode == emacs_mode)
                    264:        rl_mark = rl_point;
                    265:     }
                    266:   return 0;
                    267: }
                    268: 
                    269: /* Kill backwards to the start of the line.  If DIRECTION is negative, kill
                    270:    forwards to the line end instead. */
                    271: int
                    272: rl_backward_kill_line (direction, ignore)
                    273:      int direction, ignore;
                    274: {
                    275:   int orig_point;
                    276: 
                    277:   if (direction < 0)
                    278:     return (rl_kill_line (1, ignore));
                    279:   else
                    280:     {
                    281:       if (!rl_point)
                    282:        rl_ding ();
                    283:       else
                    284:        {
                    285:          orig_point = rl_point;
                    286:          rl_beg_of_line (1, ignore);
                    287:          if (rl_point != orig_point)
                    288:            rl_kill_text (orig_point, rl_point);
                    289:          if (rl_editing_mode == emacs_mode)
                    290:            rl_mark = rl_point;
                    291:        }
                    292:     }
                    293:   return 0;
                    294: }
                    295: 
                    296: /* Kill the whole line, no matter where point is. */
                    297: int
                    298: rl_kill_full_line (count, ignore)
                    299:      int count, ignore;
                    300: {
                    301:   rl_begin_undo_group ();
                    302:   rl_point = 0;
                    303:   rl_kill_text (rl_point, rl_end);
                    304:   rl_mark = 0;
                    305:   rl_end_undo_group ();
                    306:   return 0;
                    307: }
                    308: 
                    309: /* The next two functions mimic unix line editing behaviour, except they
                    310:    save the deleted text on the kill ring.  This is safer than not saving
                    311:    it, and since we have a ring, nobody should get screwed. */
                    312: 
                    313: /* This does what C-w does in Unix.  We can't prevent people from
                    314:    using behaviour that they expect. */
                    315: int
                    316: rl_unix_word_rubout (count, key)
                    317:      int count, key;
                    318: {
                    319:   int orig_point;
                    320: 
                    321:   if (rl_point == 0)
                    322:     rl_ding ();
                    323:   else
                    324:     {
                    325:       orig_point = rl_point;
                    326:       if (count <= 0)
                    327:        count = 1;
                    328: 
                    329:       while (count--)
                    330:        {
                    331:          while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
                    332:            rl_point--;
                    333: 
                    334:          while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
                    335:            rl_point--;
                    336:        }
                    337: 
                    338:       rl_kill_text (orig_point, rl_point);
                    339:       if (rl_editing_mode == emacs_mode)
                    340:        rl_mark = rl_point;
                    341:     }
                    342: 
                    343:   return 0;
                    344: }
                    345: 
                    346: /* This deletes one filename component in a Unix pathname.  That is, it
                    347:    deletes backward to directory separator (`/') or whitespace.  */
                    348: int
                    349: rl_unix_filename_rubout (count, key)
                    350:      int count, key;
                    351: {
                    352:   int orig_point, c;
                    353: 
                    354:   if (rl_point == 0)
                    355:     rl_ding ();
                    356:   else
                    357:     {
                    358:       orig_point = rl_point;
                    359:       if (count <= 0)
                    360:        count = 1;
                    361: 
                    362:       while (count--)
                    363:        {
                    364:          c = rl_line_buffer[rl_point - 1];
                    365:          while (rl_point && (whitespace (c) || c == '/'))
                    366:            {
                    367:              rl_point--;
                    368:              c = rl_line_buffer[rl_point - 1];
                    369:            }
                    370: 
                    371:          while (rl_point && (whitespace (c) == 0) && c != '/')
                    372:            {
                    373:              rl_point--;
                    374:              c = rl_line_buffer[rl_point - 1];
                    375:            }
                    376:        }
                    377: 
                    378:       rl_kill_text (orig_point, rl_point);
                    379:       if (rl_editing_mode == emacs_mode)
                    380:        rl_mark = rl_point;
                    381:     }
                    382: 
                    383:   return 0;
                    384: }
                    385: 
                    386: /* Here is C-u doing what Unix does.  You don't *have* to use these
                    387:    key-bindings.  We have a choice of killing the entire line, or
                    388:    killing from where we are to the start of the line.  We choose the
                    389:    latter, because if you are a Unix weenie, then you haven't backspaced
                    390:    into the line at all, and if you aren't, then you know what you are
                    391:    doing. */
                    392: int
                    393: rl_unix_line_discard (count, key)
                    394:      int count, key;
                    395: {
                    396:   if (rl_point == 0)
                    397:     rl_ding ();
                    398:   else
                    399:     {
                    400:       rl_kill_text (rl_point, 0);
                    401:       rl_point = 0;
                    402:       if (rl_editing_mode == emacs_mode)
                    403:        rl_mark = rl_point;
                    404:     }
                    405:   return 0;
                    406: }
                    407: 
                    408: /* Copy the text in the `region' to the kill ring.  If DELETE is non-zero,
                    409:    delete the text from the line as well. */
                    410: static int
                    411: region_kill_internal (delete)
                    412:      int delete;
                    413: {
                    414:   char *text;
                    415: 
                    416:   if (rl_mark != rl_point)
                    417:     {
                    418:       text = rl_copy_text (rl_point, rl_mark);
                    419:       if (delete)
                    420:        rl_delete_text (rl_point, rl_mark);
                    421:       _rl_copy_to_kill_ring (text, rl_point < rl_mark);
                    422:     }
                    423: 
                    424:   _rl_last_command_was_kill++;
                    425:   return 0;
                    426: }
                    427: 
                    428: /* Copy the text in the region to the kill ring. */
                    429: int
                    430: rl_copy_region_to_kill (count, ignore)
                    431:      int count, ignore;
                    432: {
                    433:   return (region_kill_internal (0));
                    434: }
                    435: 
                    436: /* Kill the text between the point and mark. */
                    437: int
                    438: rl_kill_region (count, ignore)
                    439:      int count, ignore;
                    440: {
                    441:   int r, npoint;
                    442: 
                    443:   npoint = (rl_point < rl_mark) ? rl_point : rl_mark;
                    444:   r = region_kill_internal (1);
                    445:   _rl_fix_point (1);
                    446:   rl_point = npoint;
                    447:   return r;
                    448: }
                    449: 
                    450: /* Copy COUNT words to the kill ring.  DIR says which direction we look
                    451:    to find the words. */
                    452: static int
                    453: _rl_copy_word_as_kill (count, dir)
                    454:      int count, dir;
                    455: {
                    456:   int om, op, r;
                    457: 
                    458:   om = rl_mark;
                    459:   op = rl_point;
                    460: 
                    461:   if (dir > 0)
                    462:     rl_forward_word (count, 0);
                    463:   else
                    464:     rl_backward_word (count, 0);
                    465: 
                    466:   rl_mark = rl_point;
                    467: 
                    468:   if (dir > 0)
                    469:     rl_backward_word (count, 0);
                    470:   else
                    471:     rl_forward_word (count, 0);
                    472: 
                    473:   r = region_kill_internal (0);
                    474: 
                    475:   rl_mark = om;
                    476:   rl_point = op;
                    477: 
                    478:   return r;
                    479: }
                    480: 
                    481: int
                    482: rl_copy_forward_word (count, key)
                    483:      int count, key;
                    484: {
                    485:   if (count < 0)
                    486:     return (rl_copy_backward_word (-count, key));
                    487: 
                    488:   return (_rl_copy_word_as_kill (count, 1));
                    489: }
                    490: 
                    491: int
                    492: rl_copy_backward_word (count, key)
                    493:      int count, key;
                    494: {
                    495:   if (count < 0)
                    496:     return (rl_copy_forward_word (-count, key));
                    497: 
                    498:   return (_rl_copy_word_as_kill (count, -1));
                    499: }
                    500:   
                    501: /* Yank back the last killed text.  This ignores arguments. */
                    502: int
                    503: rl_yank (count, ignore)
                    504:      int count, ignore;
                    505: {
                    506:   if (rl_kill_ring == 0)
                    507:     {
                    508:       _rl_abort_internal ();
                    509:       return -1;
                    510:     }
                    511: 
                    512:   _rl_set_mark_at_pos (rl_point);
                    513:   rl_insert_text (rl_kill_ring[rl_kill_index]);
                    514:   return 0;
                    515: }
                    516: 
                    517: /* If the last command was yank, or yank_pop, and the text just
                    518:    before point is identical to the current kill item, then
                    519:    delete that text from the line, rotate the index down, and
                    520:    yank back some other text. */
                    521: int
                    522: rl_yank_pop (count, key)
                    523:      int count, key;
                    524: {
                    525:   int l, n;
                    526: 
                    527:   if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
                    528:       !rl_kill_ring)
                    529:     {
                    530:       _rl_abort_internal ();
                    531:       return -1;
                    532:     }
                    533: 
                    534:   l = strlen (rl_kill_ring[rl_kill_index]);
                    535:   n = rl_point - l;
                    536:   if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
                    537:     {
                    538:       rl_delete_text (n, rl_point);
                    539:       rl_point = n;
                    540:       rl_kill_index--;
                    541:       if (rl_kill_index < 0)
                    542:        rl_kill_index = rl_kill_ring_length - 1;
                    543:       rl_yank (1, 0);
                    544:       return 0;
                    545:     }
                    546:   else
                    547:     {
                    548:       _rl_abort_internal ();
                    549:       return -1;
                    550:     }
                    551: }
                    552: 
                    553: /* Yank the COUNTh argument from the previous history line, skipping
                    554:    HISTORY_SKIP lines before looking for the `previous line'. */
                    555: static int
                    556: rl_yank_nth_arg_internal (count, ignore, history_skip)
                    557:      int count, ignore, history_skip;
                    558: {
                    559:   register HIST_ENTRY *entry;
                    560:   char *arg;
                    561:   int i, pos;
                    562: 
                    563:   pos = where_history ();
                    564: 
                    565:   if (history_skip)
                    566:     {
                    567:       for (i = 0; i < history_skip; i++)
                    568:        entry = previous_history ();
                    569:     }
                    570: 
                    571:   entry = previous_history ();
                    572: 
                    573:   history_set_pos (pos);
                    574: 
                    575:   if (entry == 0)
                    576:     {
                    577:       rl_ding ();
                    578:       return -1;
                    579:     }
                    580: 
                    581:   arg = history_arg_extract (count, count, entry->line);
                    582:   if (!arg || !*arg)
                    583:     {
                    584:       rl_ding ();
                    585:       FREE (arg);
                    586:       return -1;
                    587:     }
                    588: 
                    589:   rl_begin_undo_group ();
                    590: 
                    591:   _rl_set_mark_at_pos (rl_point);
                    592: 
                    593: #if defined (VI_MODE)
                    594:   /* Vi mode always inserts a space before yanking the argument, and it
                    595:      inserts it right *after* rl_point. */
                    596:   if (rl_editing_mode == vi_mode)
                    597:     {
                    598:       rl_vi_append_mode (1, ignore);
                    599:       rl_insert_text (" ");
                    600:     }
                    601: #endif /* VI_MODE */
                    602: 
                    603:   rl_insert_text (arg);
                    604:   xfree (arg);
                    605: 
                    606:   rl_end_undo_group ();
                    607:   return 0;
                    608: }
                    609: 
                    610: /* Yank the COUNTth argument from the previous history line. */
                    611: int
                    612: rl_yank_nth_arg (count, ignore)
                    613:      int count, ignore;
                    614: {
                    615:   return (rl_yank_nth_arg_internal (count, ignore, 0));
                    616: }
                    617: 
                    618: /* Yank the last argument from the previous history line.  This `knows'
                    619:    how rl_yank_nth_arg treats a count of `$'.  With an argument, this
                    620:    behaves the same as rl_yank_nth_arg. */
                    621: int
                    622: rl_yank_last_arg (count, key)
                    623:      int count, key;
                    624: {
                    625:   static int history_skip = 0;
                    626:   static int explicit_arg_p = 0;
                    627:   static int count_passed = 1;
                    628:   static int direction = 1;
                    629:   static int undo_needed = 0;
                    630:   int retval;
                    631: 
                    632:   if (rl_last_func != rl_yank_last_arg)
                    633:     {
                    634:       history_skip = 0;
                    635:       explicit_arg_p = rl_explicit_arg;
                    636:       count_passed = count;
                    637:       direction = 1;
                    638:     }
                    639:   else
                    640:     {
                    641:       if (undo_needed)
                    642:        rl_do_undo ();
                    643:       if (count < 0)           /* XXX - was < 1 */
                    644:         direction = -direction;
                    645:       history_skip += direction;
                    646:       if (history_skip < 0)
                    647:        history_skip = 0;
                    648:     }
                    649:  
                    650:   if (explicit_arg_p)
                    651:     retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
                    652:   else
                    653:     retval = rl_yank_nth_arg_internal ('$', key, history_skip);
                    654: 
                    655:   undo_needed = retval == 0;
                    656:   return retval;
                    657: }
                    658: 
                    659: /* A special paste command for users of Cygnus's cygwin32. */
                    660: #if defined (__CYGWIN__)
                    661: #include <windows.h>
                    662: 
                    663: int
                    664: rl_paste_from_clipboard (count, key)
                    665:      int count, key;
                    666: {
                    667:   char *data, *ptr;
                    668:   int len;
                    669: 
                    670:   if (OpenClipboard (NULL) == 0)
                    671:     return (0);
                    672: 
                    673:   data = (char *)GetClipboardData (CF_TEXT);
                    674:   if (data)
                    675:     {
                    676:       ptr = strchr (data, '\r');
                    677:       if (ptr)
                    678:        {
                    679:          len = ptr - data;
                    680:          ptr = (char *)xmalloc (len + 1);
                    681:          ptr[len] = '\0';
                    682:          strncpy (ptr, data, len);
                    683:        }
                    684:       else
                    685:         ptr = data;
                    686:       _rl_set_mark_at_pos (rl_point);
                    687:       rl_insert_text (ptr);
                    688:       if (ptr != data)
                    689:        xfree (ptr);
                    690:       CloseClipboard ();
                    691:     }
                    692:   return (0);
                    693: }
                    694: #endif /* __CYGWIN__ */

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