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

1.1       misho       1: /* kill.c -- kill ring management. */
                      2: 
1.1.1.2 ! misho       3: /* Copyright (C) 1994-2020 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: #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
1.1.1.2 ! misho      81: rl_set_retained_kills (int num)
1.1       misho      82: {
                     83:   return 0;
                     84: }
                     85: 
                     86: /* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
                     87:    This uses TEXT directly, so the caller must not free it.  If APPEND is
                     88:    non-zero, and the last command was a kill, the text is appended to the
                     89:    current kill ring slot, otherwise prepended. */
                     90: static int
1.1.1.2 ! misho      91: _rl_copy_to_kill_ring (char *text, int append)
1.1       misho      92: {
                     93:   char *old, *new;
                     94:   int slot;
                     95: 
                     96:   /* First, find the slot to work with. */
1.1.1.2 ! misho      97:   if (_rl_last_command_was_kill == 0 || rl_kill_ring == 0)
1.1       misho      98:     {
                     99:       /* Get a new slot.  */
                    100:       if (rl_kill_ring == 0)
                    101:        {
                    102:          /* If we don't have any defined, then make one. */
                    103:          rl_kill_ring = (char **)
                    104:            xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
                    105:          rl_kill_ring[slot = 0] = (char *)NULL;
                    106:        }
                    107:       else
                    108:        {
                    109:          /* We have to add a new slot on the end, unless we have
                    110:             exceeded the max limit for remembering kills. */
                    111:          slot = rl_kill_ring_length;
                    112:          if (slot == rl_max_kills)
                    113:            {
                    114:              register int i;
                    115:              xfree (rl_kill_ring[0]);
                    116:              for (i = 0; i < slot; i++)
                    117:                rl_kill_ring[i] = rl_kill_ring[i + 1];
                    118:            }
                    119:          else
                    120:            {
                    121:              slot = rl_kill_ring_length += 1;
1.1.1.2 ! misho     122:              rl_kill_ring = (char **)xrealloc (rl_kill_ring, (slot + 1) * sizeof (char *));
1.1       misho     123:            }
                    124:          rl_kill_ring[--slot] = (char *)NULL;
                    125:        }
                    126:     }
                    127:   else
                    128:     slot = rl_kill_ring_length - 1;
                    129: 
                    130:   /* If the last command was a kill, prepend or append. */
1.1.1.2 ! misho     131:   if (_rl_last_command_was_kill && rl_kill_ring[slot] && rl_editing_mode != vi_mode)
1.1       misho     132:     {
                    133:       old = rl_kill_ring[slot];
                    134:       new = (char *)xmalloc (1 + strlen (old) + strlen (text));
                    135: 
                    136:       if (append)
                    137:        {
                    138:          strcpy (new, old);
                    139:          strcat (new, text);
                    140:        }
                    141:       else
                    142:        {
                    143:          strcpy (new, text);
                    144:          strcat (new, old);
                    145:        }
                    146:       xfree (old);
                    147:       xfree (text);
                    148:       rl_kill_ring[slot] = new;
                    149:     }
                    150:   else
                    151:     rl_kill_ring[slot] = text;
                    152: 
                    153:   rl_kill_index = slot;
                    154:   return 0;
                    155: }
                    156: 
                    157: /* The way to kill something.  This appends or prepends to the last
                    158:    kill, if the last command was a kill command.  if FROM is less
                    159:    than TO, then the text is appended, otherwise prepended.  If the
                    160:    last command was not a kill command, then a new slot is made for
                    161:    this kill. */
                    162: int
1.1.1.2 ! misho     163: rl_kill_text (int from, int to)
1.1       misho     164: {
                    165:   char *text;
                    166: 
                    167:   /* Is there anything to kill? */
                    168:   if (from == to)
                    169:     {
                    170:       _rl_last_command_was_kill++;
                    171:       return 0;
                    172:     }
                    173: 
                    174:   text = rl_copy_text (from, to);
                    175: 
                    176:   /* Delete the copied text from the line. */
                    177:   rl_delete_text (from, to);
                    178: 
                    179:   _rl_copy_to_kill_ring (text, from < to);
                    180: 
                    181:   _rl_last_command_was_kill++;
                    182:   return 0;
                    183: }
                    184: 
                    185: /* Now REMEMBER!  In order to do prepending or appending correctly, kill
                    186:    commands always make rl_point's original position be the FROM argument,
                    187:    and rl_point's extent be the TO argument. */
                    188: 
                    189: /* **************************************************************** */
                    190: /*                                                                 */
                    191: /*                     Killing Commands                            */
                    192: /*                                                                 */
                    193: /* **************************************************************** */
                    194: 
                    195: /* Delete the word at point, saving the text in the kill ring. */
                    196: int
1.1.1.2 ! misho     197: rl_kill_word (int count, int key)
1.1       misho     198: {
                    199:   int orig_point;
                    200: 
                    201:   if (count < 0)
                    202:     return (rl_backward_kill_word (-count, key));
                    203:   else
                    204:     {
                    205:       orig_point = rl_point;
                    206:       rl_forward_word (count, key);
                    207: 
                    208:       if (rl_point != orig_point)
                    209:        rl_kill_text (orig_point, rl_point);
                    210: 
                    211:       rl_point = orig_point;
                    212:       if (rl_editing_mode == emacs_mode)
                    213:        rl_mark = rl_point;
                    214:     }
                    215:   return 0;
                    216: }
                    217: 
                    218: /* Rubout the word before point, placing it on the kill ring. */
                    219: int
1.1.1.2 ! misho     220: rl_backward_kill_word (int count, int key)
1.1       misho     221: {
                    222:   int orig_point;
                    223: 
                    224:   if (count < 0)
1.1.1.2 ! misho     225:     return (rl_kill_word (-count, key));
1.1       misho     226:   else
                    227:     {
                    228:       orig_point = rl_point;
1.1.1.2 ! misho     229:       rl_backward_word (count, key);
1.1       misho     230: 
                    231:       if (rl_point != orig_point)
                    232:        rl_kill_text (orig_point, rl_point);
                    233: 
                    234:       if (rl_editing_mode == emacs_mode)
                    235:        rl_mark = rl_point;
                    236:     }
                    237:   return 0;
                    238: }
                    239: 
                    240: /* Kill from here to the end of the line.  If DIRECTION is negative, kill
                    241:    back to the line start instead. */
                    242: int
1.1.1.2 ! misho     243: rl_kill_line (int direction, int key)
1.1       misho     244: {
                    245:   int orig_point;
                    246: 
                    247:   if (direction < 0)
1.1.1.2 ! misho     248:     return (rl_backward_kill_line (1, key));
1.1       misho     249:   else
                    250:     {
                    251:       orig_point = rl_point;
1.1.1.2 ! misho     252:       rl_end_of_line (1, key);
1.1       misho     253:       if (orig_point != rl_point)
                    254:        rl_kill_text (orig_point, rl_point);
                    255:       rl_point = orig_point;
                    256:       if (rl_editing_mode == emacs_mode)
                    257:        rl_mark = rl_point;
                    258:     }
                    259:   return 0;
                    260: }
                    261: 
                    262: /* Kill backwards to the start of the line.  If DIRECTION is negative, kill
                    263:    forwards to the line end instead. */
                    264: int
1.1.1.2 ! misho     265: rl_backward_kill_line (int direction, int key)
1.1       misho     266: {
                    267:   int orig_point;
                    268: 
                    269:   if (direction < 0)
1.1.1.2 ! misho     270:     return (rl_kill_line (1, key));
1.1       misho     271:   else
                    272:     {
1.1.1.2 ! misho     273:       if (rl_point == 0)
1.1       misho     274:        rl_ding ();
                    275:       else
                    276:        {
                    277:          orig_point = rl_point;
1.1.1.2 ! misho     278:          rl_beg_of_line (1, key);
1.1       misho     279:          if (rl_point != orig_point)
                    280:            rl_kill_text (orig_point, rl_point);
                    281:          if (rl_editing_mode == emacs_mode)
                    282:            rl_mark = rl_point;
                    283:        }
                    284:     }
                    285:   return 0;
                    286: }
                    287: 
                    288: /* Kill the whole line, no matter where point is. */
                    289: int
1.1.1.2 ! misho     290: rl_kill_full_line (int count, int key)
1.1       misho     291: {
                    292:   rl_begin_undo_group ();
                    293:   rl_point = 0;
                    294:   rl_kill_text (rl_point, rl_end);
                    295:   rl_mark = 0;
                    296:   rl_end_undo_group ();
                    297:   return 0;
                    298: }
                    299: 
                    300: /* The next two functions mimic unix line editing behaviour, except they
                    301:    save the deleted text on the kill ring.  This is safer than not saving
                    302:    it, and since we have a ring, nobody should get screwed. */
                    303: 
                    304: /* This does what C-w does in Unix.  We can't prevent people from
                    305:    using behaviour that they expect. */
                    306: int
1.1.1.2 ! misho     307: rl_unix_word_rubout (int count, int key)
1.1       misho     308: {
                    309:   int orig_point;
                    310: 
                    311:   if (rl_point == 0)
                    312:     rl_ding ();
                    313:   else
                    314:     {
                    315:       orig_point = rl_point;
                    316:       if (count <= 0)
                    317:        count = 1;
                    318: 
                    319:       while (count--)
                    320:        {
                    321:          while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
                    322:            rl_point--;
                    323: 
                    324:          while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
1.1.1.2 ! misho     325:            rl_point--;         /* XXX - multibyte? */
1.1       misho     326:        }
                    327: 
                    328:       rl_kill_text (orig_point, rl_point);
                    329:       if (rl_editing_mode == emacs_mode)
                    330:        rl_mark = rl_point;
                    331:     }
                    332: 
                    333:   return 0;
                    334: }
                    335: 
                    336: /* This deletes one filename component in a Unix pathname.  That is, it
                    337:    deletes backward to directory separator (`/') or whitespace.  */
                    338: int
1.1.1.2 ! misho     339: rl_unix_filename_rubout (int count, int key)
1.1       misho     340: {
                    341:   int orig_point, c;
                    342: 
                    343:   if (rl_point == 0)
                    344:     rl_ding ();
                    345:   else
                    346:     {
                    347:       orig_point = rl_point;
                    348:       if (count <= 0)
                    349:        count = 1;
                    350: 
                    351:       while (count--)
                    352:        {
                    353:          c = rl_line_buffer[rl_point - 1];
                    354:          while (rl_point && (whitespace (c) || c == '/'))
                    355:            {
                    356:              rl_point--;
                    357:              c = rl_line_buffer[rl_point - 1];
                    358:            }
                    359: 
                    360:          while (rl_point && (whitespace (c) == 0) && c != '/')
                    361:            {
1.1.1.2 ! misho     362:              rl_point--;       /* XXX - multibyte? */
1.1       misho     363:              c = rl_line_buffer[rl_point - 1];
                    364:            }
                    365:        }
                    366: 
                    367:       rl_kill_text (orig_point, rl_point);
                    368:       if (rl_editing_mode == emacs_mode)
                    369:        rl_mark = rl_point;
                    370:     }
                    371: 
                    372:   return 0;
                    373: }
                    374: 
                    375: /* Here is C-u doing what Unix does.  You don't *have* to use these
                    376:    key-bindings.  We have a choice of killing the entire line, or
                    377:    killing from where we are to the start of the line.  We choose the
                    378:    latter, because if you are a Unix weenie, then you haven't backspaced
                    379:    into the line at all, and if you aren't, then you know what you are
                    380:    doing. */
                    381: int
1.1.1.2 ! misho     382: rl_unix_line_discard (int count, int key)
1.1       misho     383: {
                    384:   if (rl_point == 0)
                    385:     rl_ding ();
                    386:   else
                    387:     {
                    388:       rl_kill_text (rl_point, 0);
                    389:       rl_point = 0;
                    390:       if (rl_editing_mode == emacs_mode)
                    391:        rl_mark = rl_point;
                    392:     }
                    393:   return 0;
                    394: }
                    395: 
                    396: /* Copy the text in the `region' to the kill ring.  If DELETE is non-zero,
                    397:    delete the text from the line as well. */
                    398: static int
1.1.1.2 ! misho     399: region_kill_internal (int delete)
1.1       misho     400: {
                    401:   char *text;
                    402: 
                    403:   if (rl_mark != rl_point)
                    404:     {
                    405:       text = rl_copy_text (rl_point, rl_mark);
                    406:       if (delete)
                    407:        rl_delete_text (rl_point, rl_mark);
                    408:       _rl_copy_to_kill_ring (text, rl_point < rl_mark);
                    409:     }
                    410: 
1.1.1.2 ! misho     411:   _rl_fix_point (1);
1.1       misho     412:   _rl_last_command_was_kill++;
                    413:   return 0;
                    414: }
                    415: 
                    416: /* Copy the text in the region to the kill ring. */
                    417: int
1.1.1.2 ! misho     418: rl_copy_region_to_kill (int count, int key)
1.1       misho     419: {
                    420:   return (region_kill_internal (0));
                    421: }
                    422: 
                    423: /* Kill the text between the point and mark. */
                    424: int
1.1.1.2 ! misho     425: rl_kill_region (int count, int key)
1.1       misho     426: {
                    427:   int r, npoint;
                    428: 
                    429:   npoint = (rl_point < rl_mark) ? rl_point : rl_mark;
                    430:   r = region_kill_internal (1);
                    431:   rl_point = npoint;
1.1.1.2 ! misho     432:   _rl_fix_point (1);
1.1       misho     433:   return r;
                    434: }
                    435: 
                    436: /* Copy COUNT words to the kill ring.  DIR says which direction we look
                    437:    to find the words. */
                    438: static int
1.1.1.2 ! misho     439: _rl_copy_word_as_kill (int count, int dir)
1.1       misho     440: {
                    441:   int om, op, r;
                    442: 
                    443:   om = rl_mark;
                    444:   op = rl_point;
                    445: 
                    446:   if (dir > 0)
                    447:     rl_forward_word (count, 0);
                    448:   else
                    449:     rl_backward_word (count, 0);
                    450: 
                    451:   rl_mark = rl_point;
                    452: 
                    453:   if (dir > 0)
                    454:     rl_backward_word (count, 0);
                    455:   else
                    456:     rl_forward_word (count, 0);
                    457: 
                    458:   r = region_kill_internal (0);
                    459: 
                    460:   rl_mark = om;
                    461:   rl_point = op;
                    462: 
                    463:   return r;
                    464: }
                    465: 
                    466: int
1.1.1.2 ! misho     467: rl_copy_forward_word (int count, int key)
1.1       misho     468: {
                    469:   if (count < 0)
                    470:     return (rl_copy_backward_word (-count, key));
                    471: 
                    472:   return (_rl_copy_word_as_kill (count, 1));
                    473: }
                    474: 
                    475: int
1.1.1.2 ! misho     476: rl_copy_backward_word (int count, int key)
1.1       misho     477: {
                    478:   if (count < 0)
                    479:     return (rl_copy_forward_word (-count, key));
                    480: 
                    481:   return (_rl_copy_word_as_kill (count, -1));
                    482: }
                    483:   
                    484: /* Yank back the last killed text.  This ignores arguments. */
                    485: int
1.1.1.2 ! misho     486: rl_yank (int count, int key)
1.1       misho     487: {
                    488:   if (rl_kill_ring == 0)
                    489:     {
                    490:       _rl_abort_internal ();
1.1.1.2 ! misho     491:       return 1;
1.1       misho     492:     }
                    493: 
                    494:   _rl_set_mark_at_pos (rl_point);
                    495:   rl_insert_text (rl_kill_ring[rl_kill_index]);
                    496:   return 0;
                    497: }
                    498: 
                    499: /* If the last command was yank, or yank_pop, and the text just
                    500:    before point is identical to the current kill item, then
                    501:    delete that text from the line, rotate the index down, and
                    502:    yank back some other text. */
                    503: int
1.1.1.2 ! misho     504: rl_yank_pop (int count, int key)
1.1       misho     505: {
                    506:   int l, n;
                    507: 
                    508:   if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
                    509:       !rl_kill_ring)
                    510:     {
                    511:       _rl_abort_internal ();
1.1.1.2 ! misho     512:       return 1;
1.1       misho     513:     }
                    514: 
                    515:   l = strlen (rl_kill_ring[rl_kill_index]);
                    516:   n = rl_point - l;
                    517:   if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
                    518:     {
                    519:       rl_delete_text (n, rl_point);
                    520:       rl_point = n;
                    521:       rl_kill_index--;
                    522:       if (rl_kill_index < 0)
                    523:        rl_kill_index = rl_kill_ring_length - 1;
                    524:       rl_yank (1, 0);
                    525:       return 0;
                    526:     }
                    527:   else
                    528:     {
                    529:       _rl_abort_internal ();
1.1.1.2 ! misho     530:       return 1;
        !           531:     }
        !           532: }
        !           533: 
        !           534: #if defined (VI_MODE)
        !           535: int
        !           536: rl_vi_yank_pop (int count, int key)
        !           537: {
        !           538:   int l, n;
        !           539: 
        !           540:   if (((rl_last_func != rl_vi_yank_pop) && (rl_last_func != rl_vi_put)) ||
        !           541:       !rl_kill_ring)
        !           542:     {
        !           543:       _rl_abort_internal ();
        !           544:       return 1;
        !           545:     }
        !           546: 
        !           547:   l = strlen (rl_kill_ring[rl_kill_index]);
        !           548:   n = rl_point - l;
        !           549:   if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
        !           550:     {
        !           551:       rl_delete_text (n, rl_point);
        !           552:       rl_point = n;
        !           553:       rl_kill_index--;
        !           554:       if (rl_kill_index < 0)
        !           555:        rl_kill_index = rl_kill_ring_length - 1;
        !           556:       rl_vi_put (1, 'p');
        !           557:       return 0;
        !           558:     }
        !           559:   else
        !           560:     {
        !           561:       _rl_abort_internal ();
        !           562:       return 1;
1.1       misho     563:     }
                    564: }
1.1.1.2 ! misho     565: #endif /* VI_MODE */
1.1       misho     566: 
                    567: /* Yank the COUNTh argument from the previous history line, skipping
                    568:    HISTORY_SKIP lines before looking for the `previous line'. */
                    569: static int
1.1.1.2 ! misho     570: rl_yank_nth_arg_internal (int count, int key, int history_skip)
1.1       misho     571: {
                    572:   register HIST_ENTRY *entry;
                    573:   char *arg;
                    574:   int i, pos;
                    575: 
                    576:   pos = where_history ();
                    577: 
                    578:   if (history_skip)
                    579:     {
                    580:       for (i = 0; i < history_skip; i++)
                    581:        entry = previous_history ();
                    582:     }
                    583: 
                    584:   entry = previous_history ();
                    585: 
                    586:   history_set_pos (pos);
                    587: 
                    588:   if (entry == 0)
                    589:     {
                    590:       rl_ding ();
1.1.1.2 ! misho     591:       return 1;
1.1       misho     592:     }
                    593: 
                    594:   arg = history_arg_extract (count, count, entry->line);
                    595:   if (!arg || !*arg)
                    596:     {
                    597:       rl_ding ();
                    598:       FREE (arg);
1.1.1.2 ! misho     599:       return 1;
1.1       misho     600:     }
                    601: 
                    602:   rl_begin_undo_group ();
                    603: 
                    604:   _rl_set_mark_at_pos (rl_point);
                    605: 
                    606: #if defined (VI_MODE)
                    607:   /* Vi mode always inserts a space before yanking the argument, and it
                    608:      inserts it right *after* rl_point. */
1.1.1.2 ! misho     609:   if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
1.1       misho     610:     {
1.1.1.2 ! misho     611:       rl_vi_append_mode (1, key);
1.1       misho     612:       rl_insert_text (" ");
                    613:     }
                    614: #endif /* VI_MODE */
                    615: 
                    616:   rl_insert_text (arg);
                    617:   xfree (arg);
                    618: 
                    619:   rl_end_undo_group ();
                    620:   return 0;
                    621: }
                    622: 
                    623: /* Yank the COUNTth argument from the previous history line. */
                    624: int
1.1.1.2 ! misho     625: rl_yank_nth_arg (int count, int key)
1.1       misho     626: {
1.1.1.2 ! misho     627:   return (rl_yank_nth_arg_internal (count, key, 0));
1.1       misho     628: }
                    629: 
                    630: /* Yank the last argument from the previous history line.  This `knows'
                    631:    how rl_yank_nth_arg treats a count of `$'.  With an argument, this
                    632:    behaves the same as rl_yank_nth_arg. */
                    633: int
1.1.1.2 ! misho     634: rl_yank_last_arg (int count, int key)
1.1       misho     635: {
                    636:   static int history_skip = 0;
                    637:   static int explicit_arg_p = 0;
                    638:   static int count_passed = 1;
                    639:   static int direction = 1;
                    640:   static int undo_needed = 0;
                    641:   int retval;
                    642: 
                    643:   if (rl_last_func != rl_yank_last_arg)
                    644:     {
                    645:       history_skip = 0;
                    646:       explicit_arg_p = rl_explicit_arg;
                    647:       count_passed = count;
                    648:       direction = 1;
                    649:     }
                    650:   else
                    651:     {
                    652:       if (undo_needed)
                    653:        rl_do_undo ();
                    654:       if (count < 0)           /* XXX - was < 1 */
                    655:         direction = -direction;
                    656:       history_skip += direction;
                    657:       if (history_skip < 0)
                    658:        history_skip = 0;
                    659:     }
                    660:  
                    661:   if (explicit_arg_p)
                    662:     retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
                    663:   else
                    664:     retval = rl_yank_nth_arg_internal ('$', key, history_skip);
                    665: 
                    666:   undo_needed = retval == 0;
                    667:   return retval;
                    668: }
                    669: 
1.1.1.2 ! misho     670: /* Having read the special escape sequence denoting the beginning of a
        !           671:    `bracketed paste' sequence, read the rest of the pasted input until the
        !           672:    closing sequence and return the pasted text. */
        !           673: char *
        !           674: _rl_bracketed_text (size_t *lenp)
        !           675: {
        !           676:   int c;
        !           677:   size_t len, cap;
        !           678:   char *buf;
        !           679: 
        !           680:   len = 0;
        !           681:   buf = xmalloc (cap = 64);
        !           682:   buf[0] = '\0';
        !           683: 
        !           684:   RL_SETSTATE (RL_STATE_MOREINPUT);
        !           685:   while ((c = rl_read_key ()) >= 0)
        !           686:     {
        !           687:       if (RL_ISSTATE (RL_STATE_MACRODEF))
        !           688:        _rl_add_macro_char (c);
        !           689: 
        !           690:       if (c == '\r')           /* XXX */
        !           691:        c = '\n';
        !           692: 
        !           693:       if (len == cap)
        !           694:        buf = xrealloc (buf, cap *= 2);
        !           695: 
        !           696:       buf[len++] = c;
        !           697:       if (len >= BRACK_PASTE_SLEN && c == BRACK_PASTE_LAST &&
        !           698:          STREQN (buf + len - BRACK_PASTE_SLEN, BRACK_PASTE_SUFF, BRACK_PASTE_SLEN))
        !           699:        {
        !           700:          len -= BRACK_PASTE_SLEN;
        !           701:          break;
        !           702:        }
        !           703:     }
        !           704:   RL_UNSETSTATE (RL_STATE_MOREINPUT);
        !           705: 
        !           706:   if (c >= 0)
        !           707:     {
        !           708:       if (len == cap)
        !           709:        buf = xrealloc (buf, cap + 1);
        !           710:       buf[len] = '\0';
        !           711:     }
        !           712: 
        !           713:   if (lenp)
        !           714:     *lenp = len;
        !           715:   return (buf);
        !           716: }
        !           717: 
        !           718: /* Having read the special escape sequence denoting the beginning of a
        !           719:    `bracketed paste' sequence, read the rest of the pasted input until the
        !           720:    closing sequence and insert the pasted text as a single unit without
        !           721:    interpretation. Temporarily highlight the inserted text. */
        !           722: int
        !           723: rl_bracketed_paste_begin (int count, int key)
        !           724: {
        !           725:   int retval, c;
        !           726:   size_t len, cap;
        !           727:   char *buf;
        !           728: 
        !           729:   buf = _rl_bracketed_text (&len);
        !           730:   rl_mark = rl_point;
        !           731:   retval = rl_insert_text (buf) == len ? 0 : 1;
        !           732:   if (_rl_enable_active_region)
        !           733:     rl_activate_mark ();
        !           734: 
        !           735:   xfree (buf);
        !           736:   return (retval);
        !           737: }
        !           738: 
        !           739: int
        !           740: _rl_read_bracketed_paste_prefix (int c)
        !           741: {
        !           742:   char pbuf[BRACK_PASTE_SLEN+1], *pbpref;
        !           743:   int key, ind, j;
        !           744: 
        !           745:   pbpref = BRACK_PASTE_PREF;           /* XXX - debugging */
        !           746:   if (c != pbpref[0])
        !           747:     return (0);
        !           748:   pbuf[ind = 0] = c;
        !           749:   while (ind < BRACK_PASTE_SLEN-1 &&
        !           750:         (RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) &&
        !           751:          _rl_pushed_input_available () == 0 &&
        !           752:          _rl_input_queued (0))
        !           753:     {
        !           754:       key = rl_read_key ();            /* XXX - for now */
        !           755:       if (key < 0)
        !           756:        break;
        !           757:       pbuf[++ind] = key;
        !           758:       if (pbuf[ind] != pbpref[ind])
        !           759:         break;
        !           760:     }
        !           761: 
        !           762:   if (ind < BRACK_PASTE_SLEN-1)                /* read incomplete sequence */
        !           763:     {
        !           764:       while (ind >= 0)
        !           765:        _rl_unget_char (pbuf[ind--]);
        !           766:       return (key < 0 ? key : 0);
        !           767:     }
        !           768:   return (key < 0 ? key : 1);
        !           769: }
        !           770: 
        !           771: /* Get a character from wherever we read input, handling input in bracketed
        !           772:    paste mode. If we don't have or use bracketed paste mode, this can be
        !           773:    used in place of rl_read_key(). */
        !           774: int
        !           775: _rl_bracketed_read_key ()
        !           776: {
        !           777:   int c, r;
        !           778:   char *pbuf;
        !           779:   size_t pblen;
        !           780: 
        !           781:   RL_SETSTATE(RL_STATE_MOREINPUT);
        !           782:   c = rl_read_key ();
        !           783:   RL_UNSETSTATE(RL_STATE_MOREINPUT);
        !           784: 
        !           785:   if (c < 0)
        !           786:     return -1;
        !           787: 
        !           788:   /* read pasted data with bracketed-paste mode enabled. */
        !           789:   if (_rl_enable_bracketed_paste && c == ESC && (r = _rl_read_bracketed_paste_prefix (c)) == 1)
        !           790:     {
        !           791:       pbuf = _rl_bracketed_text (&pblen);
        !           792:       if (pblen == 0)
        !           793:        {
        !           794:          xfree (pbuf);
        !           795:          return 0;             /* XXX */
        !           796:        }
        !           797:       c = (unsigned char)pbuf[0];
        !           798:       if (pblen > 1)
        !           799:        {
        !           800:          while (--pblen > 0)
        !           801:            _rl_unget_char ((unsigned char)pbuf[pblen]);
        !           802:        }
        !           803:       xfree (pbuf);
        !           804:     }
        !           805: 
        !           806:   return c;
        !           807: }
        !           808: 
        !           809: /* Get a character from wherever we read input, handling input in bracketed
        !           810:    paste mode. If we don't have or use bracketed paste mode, this can be
        !           811:    used in place of rl_read_key(). */
        !           812: int
        !           813: _rl_bracketed_read_mbstring (char *mb, int mlen)
        !           814: {
        !           815:   int c, r;
        !           816: 
        !           817:   c = _rl_bracketed_read_key ();
        !           818:   if (c < 0)
        !           819:     return -1;
        !           820: 
        !           821: #if defined (HANDLE_MULTIBYTE)
        !           822:   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
        !           823:     c = _rl_read_mbstring (c, mb, mlen);
        !           824:   else
        !           825: #endif
        !           826:     mb[0] = c;
        !           827:   mb[mlen] = '\0';             /* just in case */
        !           828: 
        !           829:   return c;
        !           830: }
        !           831: 
        !           832: /* A special paste command for Windows users. */
        !           833: #if defined (_WIN32)
1.1       misho     834: #include <windows.h>
                    835: 
                    836: int
1.1.1.2 ! misho     837: rl_paste_from_clipboard (int count, int key)
1.1       misho     838: {
                    839:   char *data, *ptr;
                    840:   int len;
                    841: 
                    842:   if (OpenClipboard (NULL) == 0)
                    843:     return (0);
                    844: 
                    845:   data = (char *)GetClipboardData (CF_TEXT);
                    846:   if (data)
                    847:     {
                    848:       ptr = strchr (data, '\r');
                    849:       if (ptr)
                    850:        {
                    851:          len = ptr - data;
                    852:          ptr = (char *)xmalloc (len + 1);
                    853:          ptr[len] = '\0';
                    854:          strncpy (ptr, data, len);
                    855:        }
                    856:       else
                    857:         ptr = data;
                    858:       _rl_set_mark_at_pos (rl_point);
                    859:       rl_insert_text (ptr);
                    860:       if (ptr != data)
                    861:        xfree (ptr);
                    862:       CloseClipboard ();
                    863:     }
                    864:   return (0);
                    865: }
1.1.1.2 ! misho     866: #endif /* _WIN32 */

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