OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [readline/] [kill.c] - Blame information for rev 1780

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* 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, a library for
6
   reading lines of text with interactive input and history editing.
7
 
8
   The GNU Readline Library is free software; you can redistribute it
9
   and/or modify it under the terms of the GNU General Public License
10
   as published by the Free Software Foundation; either version 2, or
11
   (at your option) any later version.
12
 
13
   The GNU Readline Library is distributed in the hope that it will be
14
   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15
   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   The GNU General Public License is often shipped with GNU software, and
19
   is generally kept in a file called COPYING or LICENSE.  If you do not
20
   have a copy of the license, write to the Free Software Foundation,
21
   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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
/* How to say that you only want to save a certain amount
74
   of kill material. */
75
int
76
rl_set_retained_kills (num)
77
     int num;
78
{
79
  return 0;
80
}
81
 
82
/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
83
   This uses TEXT directly, so the caller must not free it.  If APPEND is
84
   non-zero, and the last command was a kill, the text is appended to the
85
   current kill ring slot, otherwise prepended. */
86
static int
87
_rl_copy_to_kill_ring (text, append)
88
     char *text;
89
     int append;
90
{
91
  char *old, *new;
92
  int slot;
93
 
94
  /* First, find the slot to work with. */
95
  if (_rl_last_command_was_kill == 0)
96
    {
97
      /* Get a new slot.  */
98
      if (rl_kill_ring == 0)
99
        {
100
          /* If we don't have any defined, then make one. */
101
          rl_kill_ring = (char **)
102
            xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
103
          rl_kill_ring[slot = 0] = (char *)NULL;
104
        }
105
      else
106
        {
107
          /* We have to add a new slot on the end, unless we have
108
             exceeded the max limit for remembering kills. */
109
          slot = rl_kill_ring_length;
110
          if (slot == rl_max_kills)
111
            {
112
              register int i;
113
              free (rl_kill_ring[0]);
114
              for (i = 0; i < slot; i++)
115
                rl_kill_ring[i] = rl_kill_ring[i + 1];
116
            }
117
          else
118
            {
119
              slot = rl_kill_ring_length += 1;
120
              rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
121
            }
122
          rl_kill_ring[--slot] = (char *)NULL;
123
        }
124
    }
125
  else
126
    slot = rl_kill_ring_length - 1;
127
 
128
  /* If the last command was a kill, prepend or append. */
129
  if (_rl_last_command_was_kill && rl_editing_mode != vi_mode)
130
    {
131
      old = rl_kill_ring[slot];
132
      new = xmalloc (1 + strlen (old) + strlen (text));
133
 
134
      if (append)
135
        {
136
          strcpy (new, old);
137
          strcat (new, text);
138
        }
139
      else
140
        {
141
          strcpy (new, text);
142
          strcat (new, old);
143
        }
144
      free (old);
145
      free (text);
146
      rl_kill_ring[slot] = new;
147
    }
148
  else
149
    rl_kill_ring[slot] = text;
150
 
151
  rl_kill_index = slot;
152
  return 0;
153
}
154
 
155
/* The way to kill something.  This appends or prepends to the last
156
   kill, if the last command was a kill command.  if FROM is less
157
   than TO, then the text is appended, otherwise prepended.  If the
158
   last command was not a kill command, then a new slot is made for
159
   this kill. */
160
int
161
rl_kill_text (from, to)
162
     int from, to;
163
{
164
  char *text;
165
 
166
  /* Is there anything to kill? */
167
  if (from == to)
168
    {
169
      _rl_last_command_was_kill++;
170
      return 0;
171
    }
172
 
173
  text = rl_copy_text (from, to);
174
 
175
  /* Delete the copied text from the line. */
176
  rl_delete_text (from, to);
177
 
178
  _rl_copy_to_kill_ring (text, from < to);
179
 
180
  _rl_last_command_was_kill++;
181
  return 0;
182
}
183
 
184
/* Now REMEMBER!  In order to do prepending or appending correctly, kill
185
   commands always make rl_point's original position be the FROM argument,
186
   and rl_point's extent be the TO argument. */
187
 
188
/* **************************************************************** */
189
/*                                                                  */
190
/*                      Killing Commands                            */
191
/*                                                                  */
192
/* **************************************************************** */
193
 
194
/* Delete the word at point, saving the text in the kill ring. */
195
int
196
rl_kill_word (count, key)
197
     int count, key;
198
{
199
  int orig_point = rl_point;
200
 
201
  if (count < 0)
202
    return (rl_backward_kill_word (-count, key));
203
  else
204
    {
205
      rl_forward_word (count, key);
206
 
207
      if (rl_point != orig_point)
208
        rl_kill_text (orig_point, rl_point);
209
 
210
      rl_point = orig_point;
211
    }
212
  return 0;
213
}
214
 
215
/* Rubout the word before point, placing it on the kill ring. */
216
int
217
rl_backward_kill_word (count, ignore)
218
     int count, ignore;
219
{
220
  int orig_point = rl_point;
221
 
222
  if (count < 0)
223
    return (rl_kill_word (-count, ignore));
224
  else
225
    {
226
      rl_backward_word (count, ignore);
227
 
228
      if (rl_point != orig_point)
229
        rl_kill_text (orig_point, rl_point);
230
    }
231
  return 0;
232
}
233
 
234
/* Kill from here to the end of the line.  If DIRECTION is negative, kill
235
   back to the line start instead. */
236
int
237
rl_kill_line (direction, ignore)
238
     int direction, ignore;
239
{
240
  int orig_point = rl_point;
241
 
242
  if (direction < 0)
243
    return (rl_backward_kill_line (1, ignore));
244
  else
245
    {
246
      rl_end_of_line (1, ignore);
247
      if (orig_point != rl_point)
248
        rl_kill_text (orig_point, rl_point);
249
      rl_point = orig_point;
250
    }
251
  return 0;
252
}
253
 
254
/* Kill backwards to the start of the line.  If DIRECTION is negative, kill
255
   forwards to the line end instead. */
256
int
257
rl_backward_kill_line (direction, ignore)
258
     int direction, ignore;
259
{
260
  int orig_point = rl_point;
261
 
262
  if (direction < 0)
263
    return (rl_kill_line (1, ignore));
264
  else
265
    {
266
      if (!rl_point)
267
        ding ();
268
      else
269
        {
270
          rl_beg_of_line (1, ignore);
271
          rl_kill_text (orig_point, rl_point);
272
        }
273
    }
274
  return 0;
275
}
276
 
277
/* Kill the whole line, no matter where point is. */
278
int
279
rl_kill_full_line (count, ignore)
280
     int count, ignore;
281
{
282
  rl_begin_undo_group ();
283
  rl_point = 0;
284
  rl_kill_text (rl_point, rl_end);
285
  rl_end_undo_group ();
286
  return 0;
287
}
288
 
289
/* The next two functions mimic unix line editing behaviour, except they
290
   save the deleted text on the kill ring.  This is safer than not saving
291
   it, and since we have a ring, nobody should get screwed. */
292
 
293
/* This does what C-w does in Unix.  We can't prevent people from
294
   using behaviour that they expect. */
295
int
296
rl_unix_word_rubout (count, key)
297
     int count, key;
298
{
299
  int orig_point;
300
 
301
  if (rl_point == 0)
302
    ding ();
303
  else
304
    {
305
      orig_point = rl_point;
306
      if (count <= 0)
307
        count = 1;
308
 
309
      while (count--)
310
        {
311
          while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
312
            rl_point--;
313
 
314
          while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
315
            rl_point--;
316
        }
317
 
318
      rl_kill_text (orig_point, rl_point);
319
    }
320
  return 0;
321
}
322
 
323
/* Here is C-u doing what Unix does.  You don't *have* to use these
324
   key-bindings.  We have a choice of killing the entire line, or
325
   killing from where we are to the start of the line.  We choose the
326
   latter, because if you are a Unix weenie, then you haven't backspaced
327
   into the line at all, and if you aren't, then you know what you are
328
   doing. */
329
int
330
rl_unix_line_discard (count, key)
331
     int count, key;
332
{
333
  if (rl_point == 0)
334
    ding ();
335
  else
336
    {
337
      rl_kill_text (rl_point, 0);
338
      rl_point = 0;
339
    }
340
  return 0;
341
}
342
 
343
/* Copy the text in the `region' to the kill ring.  If DELETE is non-zero,
344
   delete the text from the line as well. */
345
static int
346
region_kill_internal (delete)
347
     int delete;
348
{
349
  char *text;
350
 
351
  if (rl_mark == rl_point)
352
    {
353
      _rl_last_command_was_kill++;
354
      return 0;
355
    }
356
 
357
  text = rl_copy_text (rl_point, rl_mark);
358
  if (delete)
359
    rl_delete_text (rl_point, rl_mark);
360
  _rl_copy_to_kill_ring (text, rl_point < rl_mark);
361
 
362
  _rl_last_command_was_kill++;
363
  return 0;
364
}
365
 
366
/* Copy the text in the region to the kill ring. */
367
int
368
rl_copy_region_to_kill (count, ignore)
369
     int count, ignore;
370
{
371
  return (region_kill_internal (0));
372
}
373
 
374
/* Kill the text between the point and mark. */
375
int
376
rl_kill_region (count, ignore)
377
     int count, ignore;
378
{
379
  int r, npoint;
380
 
381
  npoint = (rl_point < rl_mark) ? rl_point : rl_mark;
382
  r = region_kill_internal (1);
383
  _rl_fix_point (1);
384
  rl_point = npoint;
385
  return r;
386
}
387
 
388
/* Copy COUNT words to the kill ring.  DIR says which direction we look
389
   to find the words. */
390
static int
391
_rl_copy_word_as_kill (count, dir)
392
     int count, dir;
393
{
394
  int om, op, r;
395
 
396
  om = rl_mark;
397
  op = rl_point;
398
 
399
  if (dir > 0)
400
    rl_forward_word (count, 0);
401
  else
402
    rl_backward_word (count, 0);
403
 
404
  rl_mark = rl_point;
405
 
406
  if (dir > 0)
407
    rl_backward_word (count, 0);
408
  else
409
    rl_forward_word (count, 0);
410
 
411
  r = region_kill_internal (0);
412
 
413
  rl_mark = om;
414
  rl_point = op;
415
 
416
  return r;
417
}
418
 
419
int
420
rl_copy_forward_word (count, key)
421
     int count, key;
422
{
423
  if (count < 0)
424
    return (rl_copy_backward_word (-count, key));
425
 
426
  return (_rl_copy_word_as_kill (count, 1));
427
}
428
 
429
int
430
rl_copy_backward_word (count, key)
431
     int count, key;
432
{
433
  if (count < 0)
434
    return (rl_copy_forward_word (-count, key));
435
 
436
  return (_rl_copy_word_as_kill (count, -1));
437
}
438
 
439
/* Yank back the last killed text.  This ignores arguments. */
440
int
441
rl_yank (count, ignore)
442
     int count, ignore;
443
{
444
  if (rl_kill_ring == 0)
445
    {
446
      _rl_abort_internal ();
447
      return -1;
448
    }
449
 
450
  _rl_set_mark_at_pos (rl_point);
451
  rl_insert_text (rl_kill_ring[rl_kill_index]);
452
  return 0;
453
}
454
 
455
/* If the last command was yank, or yank_pop, and the text just
456
   before point is identical to the current kill item, then
457
   delete that text from the line, rotate the index down, and
458
   yank back some other text. */
459
int
460
rl_yank_pop (count, key)
461
     int count, key;
462
{
463
  int l, n;
464
 
465
  if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
466
      !rl_kill_ring)
467
    {
468
      _rl_abort_internal ();
469
      return -1;
470
    }
471
 
472
  l = strlen (rl_kill_ring[rl_kill_index]);
473
  n = rl_point - l;
474
  if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
475
    {
476
      rl_delete_text (n, rl_point);
477
      rl_point = n;
478
      rl_kill_index--;
479
      if (rl_kill_index < 0)
480
        rl_kill_index = rl_kill_ring_length - 1;
481
      rl_yank (1, 0);
482
      return 0;
483
    }
484
  else
485
    {
486
      _rl_abort_internal ();
487
      return -1;
488
    }
489
}
490
 
491
/* Yank the COUNTh argument from the previous history line, skipping
492
   HISTORY_SKIP lines before looking for the `previous line'. */
493
static int
494
rl_yank_nth_arg_internal (count, ignore, history_skip)
495
     int count, ignore, history_skip;
496
{
497
  register HIST_ENTRY *entry;
498
  char *arg;
499
  int i, pos;
500
 
501
  pos = where_history ();
502
 
503
  if (history_skip)
504
    {
505
      for (i = 0; i < history_skip; i++)
506
        entry = previous_history ();
507
    }
508
 
509
  entry = previous_history ();
510
 
511
  history_set_pos (pos);
512
 
513
  if (entry == 0)
514
    {
515
      ding ();
516
      return -1;
517
    }
518
 
519
  arg = history_arg_extract (count, count, entry->line);
520
  if (!arg || !*arg)
521
    {
522
      ding ();
523
      return -1;
524
    }
525
 
526
  rl_begin_undo_group ();
527
 
528
#if defined (VI_MODE)
529
  /* Vi mode always inserts a space before yanking the argument, and it
530
     inserts it right *after* rl_point. */
531
  if (rl_editing_mode == vi_mode)
532
    {
533
      rl_vi_append_mode (1, ignore);
534
      rl_insert_text (" ");
535
    }
536
#endif /* VI_MODE */
537
 
538
  rl_insert_text (arg);
539
  free (arg);
540
 
541
  rl_end_undo_group ();
542
  return 0;
543
}
544
 
545
/* Yank the COUNTth argument from the previous history line. */
546
int
547
rl_yank_nth_arg (count, ignore)
548
     int count, ignore;
549
{
550
  return (rl_yank_nth_arg_internal (count, ignore, 0));
551
}
552
 
553
/* Yank the last argument from the previous history line.  This `knows'
554
   how rl_yank_nth_arg treats a count of `$'.  With an argument, this
555
   behaves the same as rl_yank_nth_arg. */
556
int
557
rl_yank_last_arg (count, key)
558
     int count, key;
559
{
560
  static int history_skip = 0;
561
  static int explicit_arg_p = 0;
562
  static int count_passed = 1;
563
  static int direction = 1;
564
  static int undo_needed = 0;
565
  int retval;
566
 
567
  if (rl_last_func != rl_yank_last_arg)
568
    {
569
      history_skip = 0;
570
      explicit_arg_p = rl_explicit_arg;
571
      count_passed = count;
572
      direction = 1;
573
    }
574
  else
575
    {
576
      if (undo_needed)
577
        rl_do_undo ();
578
      if (count < 1)
579
        direction = -direction;
580
      history_skip += direction;
581
      if (history_skip < 0)
582
        history_skip = 0;
583
    }
584
 
585
  if (explicit_arg_p)
586
    retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
587
  else
588
    retval = rl_yank_nth_arg_internal ('$', key, history_skip);
589
 
590
  undo_needed = retval == 0;
591
  return retval;
592
}
593
 
594
/* A special paste command for users of Cygnus's cygwin32. */
595
#if defined (__CYGWIN32__)
596
#include <windows.h>
597
 
598
int
599
rl_paste_from_clipboard (count, key)
600
     int count, key;
601
{
602
  char *data, *ptr;
603
  int len;
604
 
605
  if (OpenClipboard (NULL) == 0)
606
    return (0);
607
 
608
  data = (char *)GetClipboardData (CF_TEXT);
609
  if (data)
610
    {
611
      ptr = strchr (data, '\r');
612
      if (ptr)
613
        {
614
          len = ptr - data;
615
          ptr = xmalloc (len + 1);
616
          ptr[len] = '\0';
617
          strncpy (ptr, data, len);
618
        }
619
      else
620
        ptr = data;
621
      rl_insert_text (ptr);
622
      if (ptr != data)
623
        free (ptr);
624
      CloseClipboard ();
625
    }
626
  return (0);
627
}
628
#endif /* __CYGWIN32__ */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.