Merge from vendor branch CVS:
[dragonfly.git] / contrib / texinfo-4 / info / echo-area.c
1 /* echo-area.c -- how to read a line in the echo area.
2    $Id: echo-area.c,v 1.7 2004/12/14 00:15:36 karl Exp $
3
4    Copyright (C) 1993, 1997, 1998, 1999, 2001, 2004 Free Software
5    Foundation, Inc.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2, or (at your option)
10    any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21    Written by Brian Fox (bfox@ai.mit.edu). */
22
23 #include "info.h"
24
25 #if defined (FD_SET)
26 #  if defined (hpux)
27 #    define fd_set_cast(x) (int *)(x)
28 #  else
29 #    define fd_set_cast(x) (fd_set *)(x)
30 #  endif /* !hpux */
31 #endif /* FD_SET */
32
33 /* Non-zero means that C-g was used to quit reading input. */
34 int info_aborted_echo_area = 0;
35
36 /* Non-zero means that the echo area is being used to read input. */
37 int echo_area_is_active = 0;
38
39 /* The address of the last command executed in the echo area. */
40 VFunction *ea_last_executed_command = (VFunction *)NULL;
41
42 /* Non-zero means that the last command executed while reading input
43    killed some text. */
44 int echo_area_last_command_was_kill = 0;
45
46 /* Variables which hold on to the current state of the input line. */
47 static char input_line[1 + EA_MAX_INPUT];
48 static char *input_line_prompt;
49 static int input_line_point;
50 static int input_line_beg;
51 static int input_line_end;
52 static NODE input_line_node = {
53   (char *)NULL, (char *)NULL, (char *)NULL, input_line,
54   EA_MAX_INPUT, 0, N_IsInternal
55 };
56
57 static void echo_area_initialize_node (void);
58 static void push_echo_area (void), pop_echo_area (void);
59 static int echo_area_stack_contains_completions_p (void);
60
61 static void ea_kill_text (int from, int to);
62
63 /* Non-zero means we force the user to complete. */
64 static int echo_area_must_complete_p = 0;
65 static int completions_window_p (WINDOW *window);
66
67 /* If non-null, this is a window which was specifically created to display
68    possible completions output.  We remember it so we can delete it when
69    appropriate. */
70 static WINDOW *echo_area_completions_window = (WINDOW *)NULL;
71
72 /* Variables which keep track of the window which was active prior to
73    entering the echo area. */
74 static WINDOW *calling_window = (WINDOW *)NULL;
75 static NODE *calling_window_node = (NODE *)NULL;
76 static long calling_window_point = 0;
77 static long calling_window_pagetop = 0;
78
79 /* Remember the node and pertinent variables of the calling window. */
80 static void
81 remember_calling_window (WINDOW *window)
82 {
83   /* Only do this if the calling window is not the completions window, or,
84      if it is the completions window and there is no other window. */
85   if (!completions_window_p (window) ||
86       ((window == windows) && !(window->next)))
87     {
88       calling_window = window;
89       calling_window_node = window->node;
90       calling_window_point = window->point;
91       calling_window_pagetop = window->pagetop;
92     }
93 }
94
95 /* Restore the caller's window so that it shows the node that it was showing
96    on entry to info_read_xxx_echo_area (). */
97 static void
98 restore_calling_window (void)
99 {
100   register WINDOW *win, *compwin = (WINDOW *)NULL;
101
102   /* If the calling window is still visible, and it is the window that
103      we used for completions output, then restore the calling window. */
104   for (win = windows; win; win = win->next)
105     {
106       if (completions_window_p (win))
107         compwin = win;
108
109       if (win == calling_window && win == compwin)
110         {
111           window_set_node_of_window (calling_window, calling_window_node);
112           calling_window->point = calling_window_point;
113           calling_window->pagetop = calling_window_pagetop;
114           compwin = (WINDOW *)NULL;
115           break;
116         }
117     }
118
119   /* Delete the completions window if it is still present, it isn't the
120      last window on the screen, and there aren't any prior echo area reads
121      pending which created a completions window. */
122   if (compwin)
123     {
124       if ((compwin != windows || windows->next) &&
125           !echo_area_stack_contains_completions_p ())
126         {
127           WINDOW *next;
128           int pagetop = 0;
129           int start = 0;
130           int end = 0;
131           int amount = 0;
132
133           next = compwin->next;
134           if (next)
135             {
136               start = next->first_row;
137               end = start + next->height;
138               amount = - (compwin->height + 1);
139               pagetop = next->pagetop;
140             }
141
142           info_delete_window_internal (compwin);
143
144           /* This is not necessary because info_delete_window_internal ()
145              calls echo_area_inform_of_deleted_window (), which does the
146              right thing. */
147 #if defined (UNNECESSARY)
148           echo_area_completions_window = (WINDOW *)NULL;
149 #endif /* UNNECESSARY */
150
151           if (next)
152             {
153               display_scroll_display (start, end, amount);
154               next->pagetop = pagetop;
155               display_update_display (windows);
156             }
157         }
158     }
159 }
160
161 /* Set up a new input line with PROMPT. */
162 static void
163 initialize_input_line (char *prompt)
164 {
165   input_line_prompt = prompt;
166   if (prompt)
167     strcpy (input_line, prompt);
168   else
169     input_line[0] = '\0';
170
171   input_line_beg = input_line_end = input_line_point = strlen (prompt);
172 }
173
174 static char *
175 echo_area_after_read (void)
176 {
177   char *return_value;
178
179   if (info_aborted_echo_area)
180     {
181       info_aborted_echo_area = 0;
182       return_value = (char *)NULL;
183     }
184   else
185     {
186       if (input_line_beg == input_line_end)
187         return_value = xstrdup ("");
188       else
189         {
190           int line_len = input_line_end - input_line_beg;
191           return_value = (char *) xmalloc (1 + line_len);
192           strncpy (return_value, &input_line[input_line_beg], line_len);
193           return_value[line_len] = '\0';
194         }
195     }
196   return (return_value);
197 }
198
199 /* Read a line of text in the echo area.  Return a malloc ()'ed string,
200    or NULL if the user aborted out of this read.  WINDOW is the currently
201    active window, so that we can restore it when we need to.  PROMPT, if
202    non-null, is a prompt to print before reading the line. */
203 char *
204 info_read_in_echo_area (WINDOW *window, char *prompt)
205 {
206   char *line;
207
208   /* If the echo area is already active, remember the current state. */
209   if (echo_area_is_active)
210     push_echo_area ();
211
212   /* Initialize our local variables. */
213   initialize_input_line (prompt);
214
215   /* Initialize the echo area for the first (but maybe not the last) time. */
216   echo_area_initialize_node ();
217
218   /* Save away the original node of this window, and the window itself,
219      so echo area commands can temporarily use this window. */
220   remember_calling_window (window);
221
222   /* Let the rest of Info know that the echo area is active. */
223   echo_area_is_active++;
224   active_window = the_echo_area;
225
226   /* Read characters in the echo area. */
227   info_read_and_dispatch ();
228
229   echo_area_is_active--;
230
231   /* Restore the original active window and show point in it. */
232   active_window = calling_window;
233   restore_calling_window ();
234   display_cursor_at_point (active_window);
235   fflush (stdout);
236
237   /* Get the value of the line. */
238   line = echo_area_after_read ();
239
240   /* If there is a previous loop waiting for us, restore it now. */
241   if (echo_area_is_active)
242     pop_echo_area ();
243
244   /* Return the results to the caller. */
245   return (line);
246 }
247
248 /* (re) Initialize the echo area node. */
249 static void
250 echo_area_initialize_node (void)
251 {
252   register int i;
253
254   for (i = input_line_end; (unsigned int) i < sizeof (input_line); i++)
255     input_line[i] = ' ';
256
257   input_line[i - 1] = '\n';
258   window_set_node_of_window (the_echo_area, &input_line_node);
259   input_line[input_line_end] = '\n';
260 }
261
262 /* Prepare to read characters in the echo area.  This can initialize the
263    echo area node, but its primary purpose is to side effect the input
264    line buffer contents. */
265 void
266 echo_area_prep_read (void)
267 {
268   if (the_echo_area->node != &input_line_node)
269     echo_area_initialize_node ();
270
271   the_echo_area->point = input_line_point;
272   input_line[input_line_end] = '\n';
273   display_update_one_window (the_echo_area);
274   display_cursor_at_point (active_window);
275 }
276
277 \f
278 /* **************************************************************** */
279 /*                                                                  */
280 /*                   Echo Area Movement Commands                    */
281 /*                                                                  */
282 /* **************************************************************** */
283
284 DECLARE_INFO_COMMAND (ea_forward, _("Move forward a character"))
285 {
286   if (count < 0)
287     ea_backward (window, -count, key);
288   else
289     {
290       input_line_point += count;
291       if (input_line_point > input_line_end)
292         input_line_point = input_line_end;
293     }
294 }
295
296 DECLARE_INFO_COMMAND (ea_backward, _("Move backward a character"))
297 {
298   if (count < 0)
299     ea_forward (window, -count, key);
300   else
301     {
302       input_line_point -= count;
303       if (input_line_point < input_line_beg)
304         input_line_point = input_line_beg;
305     }
306 }
307
308 DECLARE_INFO_COMMAND (ea_beg_of_line, _("Move to the start of this line"))
309 {
310   input_line_point = input_line_beg;
311 }
312
313 DECLARE_INFO_COMMAND (ea_end_of_line, _("Move to the end of this line"))
314 {
315   input_line_point = input_line_end;
316 }
317
318 #define alphabetic(c) (islower (c) || isupper (c) || isdigit (c))
319
320 /* Move forward a word in the input line. */
321 DECLARE_INFO_COMMAND (ea_forward_word, _("Move forward a word"))
322 {
323   int c;
324
325   if (count < 0)
326     ea_backward_word (window, -count, key);
327   else
328     {
329       while (count--)
330         {
331           if (input_line_point == input_line_end)
332             return;
333
334           /* If we are not in a word, move forward until we are in one.
335              Then, move forward until we hit a non-alphabetic character. */
336           c = input_line[input_line_point];
337
338           if (!alphabetic (c))
339             {
340               while (++input_line_point < input_line_end)
341                 {
342                   c = input_line[input_line_point];
343                   if (alphabetic (c))
344                     break;
345                 }
346             }
347
348           if (input_line_point == input_line_end)
349             return;
350
351           while (++input_line_point < input_line_end)
352             {
353               c = input_line[input_line_point];
354               if (!alphabetic (c))
355                 break;
356             }
357         }
358     }
359 }
360
361 DECLARE_INFO_COMMAND (ea_backward_word, _("Move backward a word"))
362 {
363   int c;
364
365   if (count < 0)
366     ea_forward_word (window, -count, key);
367   else
368     {
369       while (count--)
370         {
371           if (input_line_point == input_line_beg)
372             return;
373
374           /* Like ea_forward_word (), except that we look at the
375              characters just before point. */
376
377           c = input_line[input_line_point - 1];
378
379           if (!alphabetic (c))
380             {
381               while ((--input_line_point) != input_line_beg)
382                 {
383                   c = input_line[input_line_point - 1];
384                   if (alphabetic (c))
385                     break;
386                 }
387             }
388
389           while (input_line_point != input_line_beg)
390             {
391               c = input_line[input_line_point - 1];
392               if (!alphabetic (c))
393                 break;
394               else
395                 --input_line_point;
396             }
397         }
398     }
399 }
400
401 DECLARE_INFO_COMMAND (ea_delete, _("Delete the character under the cursor"))
402 {
403   register int i;
404
405   if (count < 0)
406     ea_rubout (window, -count, key);
407   else
408     {
409       if (input_line_point == input_line_end)
410         return;
411
412       if (info_explicit_arg || count > 1)
413         {
414           int orig_point;
415
416           orig_point = input_line_point;
417           ea_forward (window, count, key);
418           ea_kill_text (orig_point, input_line_point);
419           input_line_point = orig_point;
420         }
421       else
422         {
423           for (i = input_line_point; i < input_line_end; i++)
424             input_line[i] = input_line[i + 1];
425
426           input_line_end--;
427         }
428     }
429 }
430
431 DECLARE_INFO_COMMAND (ea_rubout, _("Delete the character behind the cursor"))
432 {
433   if (count < 0)
434     ea_delete (window, -count, key);
435   else
436     {
437       int start;
438
439       if (input_line_point == input_line_beg)
440         return;
441
442       start = input_line_point;
443       ea_backward (window, count, key);
444
445       if (info_explicit_arg || count > 1)
446         ea_kill_text (start, input_line_point);
447       else
448         ea_delete (window, count, key);
449     }
450 }
451
452 DECLARE_INFO_COMMAND (ea_abort, _("Cancel or quit operation"))
453 {
454   /* If any text, just discard it, and restore the calling window's node.
455      If no text, quit. */
456   if (input_line_end != input_line_beg)
457     {
458       terminal_ring_bell ();
459       input_line_end = input_line_point = input_line_beg;
460       if (calling_window->node != calling_window_node)
461         restore_calling_window ();
462     }
463   else
464     info_aborted_echo_area = 1;
465 }
466
467 DECLARE_INFO_COMMAND (ea_newline, _("Accept (or force completion of) this line"))
468 {
469   /* Stub does nothing.  Simply here to see if it has been executed. */
470 }
471
472 DECLARE_INFO_COMMAND (ea_quoted_insert, _("Insert next character verbatim"))
473 {
474   unsigned char character;
475
476   character = info_get_another_input_char ();
477   ea_insert (window, count, character);
478 }
479
480 DECLARE_INFO_COMMAND (ea_insert, _("Insert this character"))
481 {
482   register int i;
483
484   if ((input_line_end + 1) == EA_MAX_INPUT)
485     {
486       terminal_ring_bell ();
487       return;
488     }
489
490   for (i = input_line_end + 1; i != input_line_point; i--)
491     input_line[i] = input_line[i - 1];
492
493   input_line[input_line_point] = key;
494   input_line_point++;
495   input_line_end++;
496 }
497
498 DECLARE_INFO_COMMAND (ea_tab_insert, _("Insert a TAB character"))
499 {
500   ea_insert (window, count, '\t');
501 }
502
503 /* Transpose the characters at point.  If point is at the end of the line,
504    then transpose the characters before point. */
505 DECLARE_INFO_COMMAND (ea_transpose_chars, _("Transpose characters at point"))
506 {
507   /* Handle conditions that would make it impossible to transpose
508      characters. */
509   if (!count || !input_line_point || (input_line_end - input_line_beg) < 2)
510     return;
511
512   while (count)
513     {
514       int t;
515       if (input_line_point == input_line_end)
516         {
517           t = input_line[input_line_point - 1];
518
519           input_line[input_line_point - 1] = input_line[input_line_point - 2];
520           input_line[input_line_point - 2] = t;
521         }
522       else
523         {
524           t = input_line[input_line_point];
525
526           input_line[input_line_point] = input_line[input_line_point - 1];
527           input_line[input_line_point - 1] = t;
528
529           if (count < 0 && input_line_point != input_line_beg)
530             input_line_point--;
531           else
532             input_line_point++;
533         }
534
535       if (count < 0)
536         count++;
537       else
538         count--;
539     }
540 }
541 \f
542 /* **************************************************************** */
543 /*                                                                  */
544 /*                   Echo Area Killing and Yanking                  */
545 /*                                                                  */
546 /* **************************************************************** */
547
548 static char **kill_ring = (char **)NULL;
549 static int kill_ring_index = 0; /* Number of kills appearing in KILL_RING. */
550 static int kill_ring_slots = 0; /* Number of slots allocated to KILL_RING. */
551 static int kill_ring_loc = 0;   /* Location of current yank pointer. */
552
553 /* The largest number of kills that we remember at one time. */
554 static int max_retained_kills = 15;
555
556 DECLARE_INFO_COMMAND (ea_yank, _("Yank back the contents of the last kill"))
557 {
558   register int i;
559   register char *text;
560
561   if (!kill_ring_index)
562     {
563       inform_in_echo_area ((char *) _("Kill ring is empty"));
564       return;
565     }
566
567   text = kill_ring[kill_ring_loc];
568
569   for (i = 0; text[i]; i++)
570     ea_insert (window, 1, text[i]);
571 }
572
573 /* If the last command was yank, or yank_pop, and the text just before
574    point is identical to the current kill item, then delete that text
575    from the line, rotate the index down, and yank back some other text. */
576 DECLARE_INFO_COMMAND (ea_yank_pop, _("Yank back a previous kill"))
577 {
578   register int len;
579
580   if (((ea_last_executed_command != (VFunction *) ea_yank) &&
581        (ea_last_executed_command != (VFunction *) ea_yank_pop)) ||
582       (kill_ring_index == 0))
583     return;
584
585   len = strlen (kill_ring[kill_ring_loc]);
586
587   /* Delete the last yanked item from the line. */
588   {
589     register int i, counter;
590
591     counter = input_line_end - input_line_point;
592     
593     for (i = input_line_point - len; counter; i++, counter--)
594       input_line[i] = input_line[i + len];
595
596     input_line_end -= len;
597     input_line_point -= len;
598   }
599
600   /* Get a previous kill, and yank that. */
601   kill_ring_loc--;
602   if (kill_ring_loc < 0)
603     kill_ring_loc = kill_ring_index - 1;
604
605   ea_yank (window, count, key);
606 }
607
608 /* Delete the text from point to end of line. */
609 DECLARE_INFO_COMMAND (ea_kill_line, _("Kill to the end of the line"))
610 {
611   if (count < 0)
612     {
613       ea_kill_text (input_line_point, input_line_beg);
614       input_line_point = input_line_beg;
615     }
616   else
617     ea_kill_text (input_line_point, input_line_end);
618 }
619
620 /* Delete the text from point to beg of line. */
621 DECLARE_INFO_COMMAND (ea_backward_kill_line,
622                       _("Kill to the beginning of the line"))
623 {
624   if (count < 0)
625     ea_kill_text (input_line_point, input_line_end);
626   else
627     {
628       ea_kill_text (input_line_point, input_line_beg);
629       input_line_point = input_line_beg;
630     }
631 }
632
633 /* Delete from point to the end of the current word. */
634 DECLARE_INFO_COMMAND (ea_kill_word, _("Kill the word following the cursor"))
635 {
636   int orig_point = input_line_point;
637
638   if (count < 0)
639     ea_backward_kill_word (window, -count, key);
640   else
641     {
642       ea_forward_word (window, count, key);
643
644       if (input_line_point != orig_point)
645         ea_kill_text (orig_point, input_line_point);
646
647       input_line_point = orig_point;
648     }
649 }
650
651 /* Delete from point to the start of the current word. */
652 DECLARE_INFO_COMMAND (ea_backward_kill_word,
653                       _("Kill the word preceding the cursor"))
654 {
655   int orig_point = input_line_point;
656
657   if (count < 0)
658     ea_kill_word (window, -count, key);
659   else
660     {
661       ea_backward_word (window, count, key);
662
663       if (input_line_point != orig_point)
664         ea_kill_text (orig_point, input_line_point);
665     }
666 }
667
668 /* The way to kill something.  This appends or prepends to the last
669    kill, if the last command was a kill command.  If FROM is less
670    than TO, then the killed text is appended to the most recent kill,
671    otherwise it is prepended.  If the last command was not a kill command,
672    then a new slot is made for this kill. */
673 static void
674 ea_kill_text (int from, int to)
675 {
676   register int i, counter, distance;
677   int killing_backwards, slot;
678   char *killed_text;
679
680   killing_backwards = (from > to);
681
682   /* If killing backwards, reverse the values of FROM and TO. */
683   if (killing_backwards)
684     {
685       int temp = from;
686       from = to;
687       to = temp;
688     }
689
690   /* Remember the text that we are about to delete. */
691   distance = to - from;
692   killed_text = (char *)xmalloc (1 + distance);
693   strncpy (killed_text, &input_line[from], distance);
694   killed_text[distance] = '\0';
695
696   /* Actually delete the text from the line. */
697   counter = input_line_end - to;
698
699   for (i = from; counter; i++, counter--)
700     input_line[i] = input_line[i + distance];
701
702   input_line_end -= distance;
703
704   /* If the last command was a kill, append or prepend the killed text to
705      the last command's killed text. */
706   if (echo_area_last_command_was_kill)
707     {
708       char *old, *new;
709
710       slot = kill_ring_loc;
711       old = kill_ring[slot];
712       new = (char *)xmalloc (1 + strlen (old) + strlen (killed_text));
713
714       if (killing_backwards)
715         {
716           /* Prepend TEXT to current kill. */
717           strcpy (new, killed_text);
718           strcat (new, old);
719         }
720       else
721         {
722           /* Append TEXT to current kill. */
723           strcpy (new, old);
724           strcat (new, killed_text);
725         }
726
727       free (old);
728       free (killed_text);
729       kill_ring[slot] = new;
730     }
731   else
732     {
733       /* Try to store the kill in a new slot, unless that would cause there
734          to be too many remembered kills. */
735       slot = kill_ring_index;
736
737       if (slot == max_retained_kills)
738         slot = 0;
739
740       if (slot + 1 > kill_ring_slots)
741         kill_ring = (char **) xrealloc
742           (kill_ring,
743            (kill_ring_slots += max_retained_kills) * sizeof (char *));
744
745       if (slot != kill_ring_index)
746         free (kill_ring[slot]);
747       else
748         kill_ring_index++;
749
750       kill_ring[slot] = killed_text;
751
752       kill_ring_loc = slot;
753     }
754
755   /* Notice that the last command was a kill. */
756   echo_area_last_command_was_kill++;
757 }
758 \f
759 /* **************************************************************** */
760 /*                                                                  */
761 /*                      Echo Area Completion                        */
762 /*                                                                  */
763 /* **************************************************************** */
764
765 /* Pointer to an array of REFERENCE to complete over. */
766 static REFERENCE **echo_area_completion_items = (REFERENCE **)NULL;
767
768 /* Sorted array of REFERENCE * which is the possible completions found in
769    the variable echo_area_completion_items.  If there is only one element,
770    it is the only possible completion. */
771 static REFERENCE **completions_found = (REFERENCE **)NULL;
772 static int completions_found_index = 0;
773 static int completions_found_slots = 0;
774
775 /* The lowest common denominator found while completing. */
776 static REFERENCE *LCD_completion;
777
778 /* Internal functions used by the user calls. */
779 static void build_completions (void), completions_must_be_rebuilt (void);
780
781 /* Variable which holds the output of completions. */
782 static NODE *possible_completions_output_node = (NODE *)NULL;
783
784 static char *compwin_name = "*Completions*";
785
786 /* Return non-zero if WINDOW is a window used for completions output. */
787 static int
788 completions_window_p (WINDOW *window)
789 {
790   int result = 0;
791
792   if (internal_info_node_p (window->node) &&
793       (strcmp (window->node->nodename, compwin_name) == 0))
794     result = 1;
795
796   return (result);
797 }
798
799 /* Workhorse for completion readers.  If FORCE is non-zero, the user cannot
800    exit unless the line read completes, or is empty. */
801 char *
802 info_read_completing_internal (WINDOW *window, char *prompt,
803     REFERENCE **completions, int force)
804 {
805   char *line;
806
807   /* If the echo area is already active, remember the current state. */
808   if (echo_area_is_active)
809     push_echo_area ();
810
811   echo_area_must_complete_p = force;
812
813   /* Initialize our local variables. */
814   initialize_input_line (prompt);
815
816   /* Initialize the echo area for the first (but maybe not the last) time. */
817   echo_area_initialize_node ();
818
819   /* Save away the original node of this window, and the window itself,
820      so echo area commands can temporarily use this window. */
821   remember_calling_window (window);
822
823   /* Save away the list of items to complete over. */
824   echo_area_completion_items = completions;
825   completions_must_be_rebuilt ();
826
827   active_window = the_echo_area;
828   echo_area_is_active++;
829
830   /* Read characters in the echo area. */
831   while (1)
832     {
833       info_read_and_dispatch ();
834
835       line = echo_area_after_read ();
836
837       /* Force the completion to take place if the user hasn't accepted
838          a default or aborted, and if FORCE is active. */
839       if (force && line && *line && completions)
840         {
841           register int i;
842
843           build_completions ();
844
845           /* If there is only one completion, then make the line be that
846              completion. */
847           if (completions_found_index == 1)
848             {
849               free (line);
850               line = xstrdup (completions_found[0]->label);
851               break;
852             }
853
854           /* If one of the completions matches exactly, then that is okay, so
855              return the current line. */
856           for (i = 0; i < completions_found_index; i++)
857             if (strcasecmp (completions_found[i]->label, line) == 0)
858               {
859                 free (line);
860                 line = xstrdup (completions_found[i]->label);
861                 break;
862               }
863
864           /* If no match, go back and try again. */
865           if (i == completions_found_index)
866             {
867               if (!completions_found_index)
868                 inform_in_echo_area ((char *) _("No completions"));
869               else
870                 inform_in_echo_area ((char *) _("Not complete"));
871               continue;
872             }
873         }
874       break;
875     }
876   echo_area_is_active--;
877
878   /* Restore the original active window and show point in it. */
879   active_window = calling_window;
880   restore_calling_window ();
881   display_cursor_at_point (active_window);
882   fflush (stdout);
883
884   echo_area_completion_items = (REFERENCE **)NULL;
885   completions_must_be_rebuilt ();
886
887   /* If there is a previous loop waiting for us, restore it now. */
888   if (echo_area_is_active)
889     pop_echo_area ();
890
891   return (line);
892 }
893   
894 /* Read a line in the echo area with completion over COMPLETIONS. */
895 char *
896 info_read_completing_in_echo_area (WINDOW *window,
897     char *prompt, REFERENCE **completions)
898 {
899   return (info_read_completing_internal (window, prompt, completions, 1));
900 }
901
902 /* Read a line in the echo area allowing completion over COMPLETIONS, but
903    not requiring it. */
904 char *
905 info_read_maybe_completing (WINDOW *window,
906     char *prompt, REFERENCE **completions)
907 {
908   return (info_read_completing_internal (window, prompt, completions, 0));
909 }
910
911 DECLARE_INFO_COMMAND (ea_possible_completions, _("List possible completions"))
912 {
913   if (!echo_area_completion_items)
914     {
915       ea_insert (window, count, key);
916       return;
917     }
918
919   build_completions ();
920
921   if (!completions_found_index)
922     {
923       terminal_ring_bell ();
924       inform_in_echo_area ((char *) _("No completions"));
925     }
926   else if ((completions_found_index == 1) && (key != '?'))
927     {
928       inform_in_echo_area ((char *) _("Sole completion"));
929     }
930   else
931     {
932       register int i, l;
933       int limit, iterations, max_label = 0;
934
935       initialize_message_buffer ();
936       printf_to_message_buffer (completions_found_index == 1
937                                 ? (char *) _("One completion:\n")
938                                 : (char *) _("%d completions:\n"),
939                                 (void *) (long) completions_found_index,
940                                 NULL, NULL);
941
942       /* Find the maximum length of a label. */
943       for (i = 0; i < completions_found_index; i++)
944         {
945           int len = strlen (completions_found[i]->label);
946           if (len > max_label)
947             max_label = len;
948         }
949
950       max_label += 4;
951
952       /* Find out how many columns we should print in. */
953       limit = calling_window->width / max_label;
954       if (limit != 1 && (limit * max_label == calling_window->width))
955         limit--;
956
957       /* Avoid a possible floating exception.  If max_label > width then
958          the limit will be 0 and a divide-by-zero fault will result. */
959       if (limit == 0)
960         limit = 1;
961
962       /* How many iterations of the printing loop? */
963       iterations = (completions_found_index + (limit - 1)) / limit;
964
965       /* Watch out for special case.  If the number of completions is less
966          than LIMIT, then just do the inner printing loop. */
967       if (completions_found_index < limit)
968         iterations = 1;
969
970       /* Print the sorted items, up-and-down alphabetically. */
971       for (i = 0; i < iterations; i++)
972         {
973           register int j;
974
975           for (j = 0, l = i; j < limit; j++)
976             {
977               if (l >= completions_found_index)
978                 break;
979               else
980                 {
981                   char *label;
982                   int printed_length, k;
983
984                   label = completions_found[l]->label;
985                   printed_length = strlen (label);
986                   printf_to_message_buffer ("%s", label, NULL, NULL);
987
988                   if (j + 1 < limit)
989                     {
990                       for (k = 0; k < max_label - printed_length; k++)
991                         printf_to_message_buffer (" ", NULL, NULL, NULL);
992                     }
993                 }
994               l += iterations;
995             }
996           printf_to_message_buffer ("\n", NULL, NULL, NULL);
997         }
998
999       /* Make a new node to hold onto possible completions.  Don't destroy
1000          dangling pointers. */
1001       {
1002         NODE *temp;
1003
1004         temp = message_buffer_to_node ();
1005         add_gcable_pointer (temp->contents);
1006         name_internal_node (temp, compwin_name);
1007         possible_completions_output_node = temp;
1008       }
1009
1010       /* Find a suitable window for displaying the completions output.
1011          First choice is an existing window showing completions output.
1012          If there is only one window, and it is large, make another
1013          (smaller) window, and use that one.  Otherwise, use the caller's
1014          window. */
1015       {
1016         WINDOW *compwin;
1017
1018         compwin = get_internal_info_window (compwin_name);
1019
1020         if (!compwin)
1021           {
1022             /* If we can split the window to display most of the completion
1023                items, then do so. */
1024             if (calling_window->height > (iterations * 2)
1025                 && calling_window->height / 2 >= WINDOW_MIN_SIZE)
1026               {
1027                 int start, pagetop;
1028 #ifdef SPLIT_BEFORE_ACTIVE
1029                 int end;
1030 #endif
1031
1032                 active_window = calling_window;
1033
1034                 /* Perhaps we can scroll this window on redisplay. */
1035                 start = calling_window->first_row;
1036                 pagetop = calling_window->pagetop;
1037
1038                 compwin =
1039                   window_make_window (possible_completions_output_node);
1040                 active_window = the_echo_area;
1041                 window_change_window_height
1042                   (compwin, -(compwin->height - (iterations + 2)));
1043
1044                 window_adjust_pagetop (calling_window);
1045                 remember_calling_window (calling_window);
1046
1047 #if defined (SPLIT_BEFORE_ACTIVE)
1048                 /* If the pagetop hasn't changed, scrolling the calling
1049                    window is a reasonable thing to do. */
1050                 if (pagetop == calling_window->pagetop)
1051                   {
1052                     end = start + calling_window->height;
1053                     display_scroll_display
1054                       (start, end, calling_window->prev->height + 1);
1055                   }
1056 #else /* !SPLIT_BEFORE_ACTIVE */
1057                 /* If the pagetop has changed, set the new pagetop here. */
1058                 if (pagetop != calling_window->pagetop)
1059                   {
1060                     int newtop = calling_window->pagetop;
1061                     calling_window->pagetop = pagetop;
1062                     set_window_pagetop (calling_window, newtop);
1063                   }
1064 #endif /* !SPLIT_BEFORE_ACTIVE */
1065
1066                 echo_area_completions_window = compwin;
1067                 remember_window_and_node (compwin, compwin->node);
1068               }
1069             else
1070               compwin = calling_window;
1071           }
1072
1073         if (compwin->node != possible_completions_output_node)
1074           {
1075             window_set_node_of_window
1076               (compwin, possible_completions_output_node);
1077             remember_window_and_node (compwin, compwin->node);
1078           }
1079
1080         display_update_display (windows);
1081       }
1082     }
1083 }
1084
1085 DECLARE_INFO_COMMAND (ea_complete, _("Insert completion"))
1086 {
1087   if (!echo_area_completion_items)
1088     {
1089       ea_insert (window, count, key);
1090       return;
1091     }
1092
1093   /* If KEY is SPC, and we are not forcing completion to take place, simply
1094      insert the key. */
1095   if (!echo_area_must_complete_p && key == SPC)
1096     {
1097       ea_insert (window, count, key);
1098       return;
1099     }
1100
1101   if (ea_last_executed_command == (VFunction *) ea_complete)
1102     {
1103       /* If the keypress is a SPC character, and we have already tried
1104          completing once, and there are several completions, then check
1105          the batch of completions to see if any continue with a space.
1106          If there are some, insert the space character and continue. */
1107       if (key == SPC && completions_found_index > 1)
1108         {
1109           register int i, offset;
1110
1111           offset = input_line_end - input_line_beg;
1112
1113           for (i = 0; i < completions_found_index; i++)
1114             if (completions_found[i]->label[offset] == ' ')
1115               break;
1116
1117           if (completions_found[i])
1118             ea_insert (window, 1, ' ');
1119           else
1120             {
1121               ea_possible_completions (window, count, key);
1122               return;
1123             }
1124         }
1125       else
1126         {
1127           ea_possible_completions (window, count, key);
1128           return;
1129         }
1130     }
1131
1132   input_line_point = input_line_end;
1133   build_completions ();
1134
1135   if (!completions_found_index)
1136     terminal_ring_bell ();
1137   else if (LCD_completion->label[0] == '\0')
1138     ea_possible_completions (window, count, key);
1139   else
1140     {
1141       register int i;
1142       input_line_point = input_line_end = input_line_beg;
1143       for (i = 0; LCD_completion->label[i]; i++)
1144         ea_insert (window, 1, LCD_completion->label[i]);
1145     }
1146 }
1147
1148 /* Utility REFERENCE used to store possible LCD. */
1149 static REFERENCE LCD_reference = {
1150     (char *)NULL, (char *)NULL, (char *)NULL, 0, 0, 0
1151 };
1152
1153 static void remove_completion_duplicates (void);
1154
1155 /* Variables which remember the state of the most recent call
1156    to build_completions (). */
1157 static char *last_completion_request = (char *)NULL;
1158 static REFERENCE **last_completion_items = (REFERENCE **)NULL;
1159
1160 /* How to tell the completion builder to reset internal state. */
1161 static void
1162 completions_must_be_rebuilt (void)
1163 {
1164   maybe_free (last_completion_request);
1165   last_completion_request = (char *)NULL;
1166   last_completion_items = (REFERENCE **)NULL;
1167 }
1168
1169 /* Build a list of possible completions from echo_area_completion_items,
1170    and the contents of input_line. */
1171 static void
1172 build_completions (void)
1173 {
1174   register int i, len;
1175   register REFERENCE *entry;
1176   char *request;
1177   int informed_of_lengthy_job = 0;
1178
1179   /* If there are no items to complete over, exit immediately. */
1180   if (!echo_area_completion_items)
1181     {
1182       completions_found_index = 0;
1183       LCD_completion = (REFERENCE *)NULL;
1184       return;
1185     }
1186
1187   /* Check to see if this call to build completions is the same as the last
1188      call to build completions. */
1189   len = input_line_end - input_line_beg;
1190   request = (char *)xmalloc (1 + len);
1191   strncpy (request, &input_line[input_line_beg], len);
1192   request[len] = '\0';
1193
1194   if (last_completion_request && last_completion_items &&
1195       last_completion_items == echo_area_completion_items &&
1196       (strcmp (last_completion_request, request) == 0))
1197     {
1198       free (request);
1199       return;
1200     }
1201
1202   maybe_free (last_completion_request);
1203   last_completion_request = request;
1204   last_completion_items = echo_area_completion_items;
1205
1206   /* Always start at the beginning of the list. */
1207   completions_found_index = 0;
1208   LCD_completion = (REFERENCE *)NULL;
1209
1210   for (i = 0; (entry = echo_area_completion_items[i]); i++)
1211     {
1212       if (strncasecmp (request, entry->label, len) == 0)
1213         add_pointer_to_array (entry, completions_found_index,
1214                               completions_found, completions_found_slots,
1215                               20, REFERENCE *);
1216
1217       if (!informed_of_lengthy_job && completions_found_index > 100)
1218         {
1219           informed_of_lengthy_job = 1;
1220           window_message_in_echo_area ((char *) _("Building completions..."),
1221               NULL, NULL);
1222         }
1223     }
1224
1225   if (!completions_found_index)
1226     return;
1227
1228   /* Sort and prune duplicate entries from the completions array. */
1229   remove_completion_duplicates ();
1230
1231   /* If there is only one completion, just return that. */
1232   if (completions_found_index == 1)
1233     {
1234       LCD_completion = completions_found[0];
1235       return;
1236     }
1237
1238   /* Find the least common denominator. */
1239   {
1240     long shortest = 100000;
1241
1242     for (i = 1; i < completions_found_index; i++)
1243       {
1244         register int j;
1245         int c1, c2;
1246
1247         for (j = 0;
1248              (c1 = info_tolower (completions_found[i - 1]->label[j])) &&
1249              (c2 = info_tolower (completions_found[i]->label[j]));
1250              j++)
1251           if (c1 != c2)
1252             break;
1253
1254         if (shortest > j)
1255           shortest = j;
1256       }
1257
1258     maybe_free (LCD_reference.label);
1259     LCD_reference.label = (char *)xmalloc (1 + shortest);
1260     /* Since both the sorting done inside remove_completion_duplicates
1261        and all the comparisons above are case-insensitive, it's
1262        possible that the completion we are going to return is
1263        identical to what the user typed but for the letter-case.  This
1264        is confusing, since the user could type FOOBAR<TAB> and get her
1265        string change letter-case for no good reason.  So try to find a
1266        possible completion whose letter-case is identical, and if so,
1267        use that.  */
1268     if (completions_found_index > 1)
1269       {
1270         int req_len = strlen (request);
1271
1272         for (i = 0; i < completions_found_index; i++)
1273           if (strncmp (request, completions_found[i]->label, req_len) == 0)
1274             break;
1275         /* If none of the candidates match exactly, use the first one.  */
1276         if (i >= completions_found_index)
1277           i = 0;
1278       }
1279     strncpy (LCD_reference.label, completions_found[i]->label, shortest);
1280     LCD_reference.label[shortest] = '\0';
1281     LCD_completion = &LCD_reference;
1282   }
1283
1284   if (informed_of_lengthy_job)
1285     echo_area_initialize_node ();
1286 }
1287
1288 /* Function called by qsort. */
1289 static int
1290 compare_references (const void *entry1, const void *entry2)
1291 {
1292   REFERENCE **e1 = (REFERENCE **) entry1;
1293   REFERENCE **e2 = (REFERENCE **) entry2;
1294
1295   return (strcasecmp ((*e1)->label, (*e2)->label));
1296 }
1297
1298 /* Prune duplicate entries from COMPLETIONS_FOUND. */
1299 static void
1300 remove_completion_duplicates (void)
1301 {
1302   register int i, j;
1303   REFERENCE **temp;
1304   int newlen;
1305
1306   if (!completions_found_index)
1307     return;
1308
1309   /* Sort the items. */
1310   qsort (completions_found, completions_found_index, sizeof (REFERENCE *),
1311          compare_references);
1312
1313   for (i = 0, newlen = 1; i < completions_found_index - 1; i++)
1314     {
1315       if (strcmp (completions_found[i]->label,
1316                   completions_found[i + 1]->label) == 0)
1317         completions_found[i] = (REFERENCE *)NULL;
1318       else
1319         newlen++;
1320     }
1321
1322   /* We have marked all the dead slots.  It is faster to copy the live slots
1323      twice than to prune the dead slots one by one. */
1324   temp = (REFERENCE **)xmalloc ((1 + newlen) * sizeof (REFERENCE *));
1325   for (i = 0, j = 0; i < completions_found_index; i++)
1326     if (completions_found[i])
1327       temp[j++] = completions_found[i];
1328
1329   for (i = 0; i < newlen; i++)
1330     completions_found[i] = temp[i];
1331
1332   completions_found[i] = (REFERENCE *)NULL;
1333   completions_found_index = newlen;
1334   free (temp);
1335 }
1336
1337 /* Scroll the "other" window.  If there is a window showing completions, scroll
1338    that one, otherwise scroll the window which was active on entering the read
1339    function. */
1340 DECLARE_INFO_COMMAND (ea_scroll_completions_window, _("Scroll the completions window"))
1341 {
1342   WINDOW *compwin;
1343   int old_pagetop;
1344
1345   compwin = get_internal_info_window (compwin_name);
1346
1347   if (!compwin)
1348     compwin = calling_window;
1349
1350   old_pagetop = compwin->pagetop;
1351
1352   /* Let info_scroll_forward () do the work, and print any messages that
1353      need to be displayed. */
1354   info_scroll_forward (compwin, count, key);
1355 }
1356
1357 /* Function which gets called when an Info window is deleted while the
1358    echo area is active.  WINDOW is the window which has just been deleted. */
1359 void
1360 echo_area_inform_of_deleted_window (WINDOW *window)
1361 {
1362   /* If this is the calling_window, forget what we remembered about it. */
1363   if (window == calling_window)
1364     {
1365       if (active_window != the_echo_area)
1366         remember_calling_window (active_window);
1367       else
1368         remember_calling_window (windows);
1369     }
1370
1371   /* If this window was the echo_area_completions_window, then notice that
1372      the window has been deleted. */
1373   if (window == echo_area_completions_window)
1374     echo_area_completions_window = (WINDOW *)NULL;
1375 }
1376 \f
1377 /* **************************************************************** */
1378 /*                                                                  */
1379 /*                 Pushing and Popping the Echo Area                */
1380 /*                                                                  */
1381 /* **************************************************************** */
1382
1383 /* Push and Pop the echo area. */
1384 typedef struct {
1385   char *line;
1386   char *prompt;
1387   REFERENCE **comp_items;
1388   int point, beg, end;
1389   int must_complete;
1390   NODE node;
1391   WINDOW *compwin;
1392 } PUSHED_EA;
1393
1394 static PUSHED_EA **pushed_echo_areas = (PUSHED_EA **)NULL;
1395 static int pushed_echo_areas_index = 0;
1396 static int pushed_echo_areas_slots = 0;
1397
1398 /* Pushing the echo_area has a side effect of zeroing the completion_items. */
1399 static void
1400 push_echo_area (void)
1401 {
1402   PUSHED_EA *pushed;
1403
1404   pushed = (PUSHED_EA *)xmalloc (sizeof (PUSHED_EA));
1405   pushed->line = xstrdup (input_line);
1406   pushed->prompt = input_line_prompt;
1407   pushed->point = input_line_point;
1408   pushed->beg = input_line_beg;
1409   pushed->end = input_line_end;
1410   pushed->node = input_line_node;
1411   pushed->comp_items = echo_area_completion_items;
1412   pushed->must_complete = echo_area_must_complete_p;
1413   pushed->compwin = echo_area_completions_window;
1414
1415   add_pointer_to_array (pushed, pushed_echo_areas_index, pushed_echo_areas,
1416                         pushed_echo_areas_slots, 4, PUSHED_EA *);
1417
1418   echo_area_completion_items = (REFERENCE **)NULL;
1419 }
1420
1421 static void
1422 pop_echo_area (void)
1423 {
1424   PUSHED_EA *popped;
1425
1426   popped = pushed_echo_areas[--pushed_echo_areas_index];
1427
1428   strcpy (input_line, popped->line);
1429   free (popped->line);
1430   input_line_prompt = popped->prompt;
1431   input_line_point = popped->point;
1432   input_line_beg = popped->beg;
1433   input_line_end = popped->end;
1434   input_line_node = popped->node;
1435   echo_area_completion_items = popped->comp_items;
1436   echo_area_must_complete_p = popped->must_complete;
1437   echo_area_completions_window = popped->compwin;
1438   completions_must_be_rebuilt ();
1439
1440   /* If the completion window no longer exists, forget about it. */
1441   if (echo_area_completions_window)
1442     {
1443       register WINDOW *win;
1444
1445       for (win = windows; win; win = win->next)
1446         if (echo_area_completions_window == win)
1447           break;
1448
1449       /* If the window wasn't found, then it has already been deleted. */
1450       if (!win)
1451         echo_area_completions_window = (WINDOW *)NULL;
1452     }
1453
1454   free (popped);
1455 }
1456
1457 /* Returns non-zero if any of the prior stacked calls to read in the echo
1458    area produced a completions window. */
1459 static int
1460 echo_area_stack_contains_completions_p (void)
1461 {
1462   register int i;
1463
1464   for (i = 0; i < pushed_echo_areas_index; i++)
1465     if (pushed_echo_areas[i]->compwin)
1466       return (1);
1467
1468   return (0);
1469 }
1470 \f
1471 /* **************************************************************** */
1472 /*                                                                  */
1473 /*             Error Messages While Reading in Echo Area            */
1474 /*                                                                  */
1475 /* **************************************************************** */
1476
1477 #if defined (HAVE_SYS_TIME_H)
1478 #  include <sys/time.h>
1479 #  define HAVE_STRUCT_TIMEVAL
1480 #endif /* HAVE_SYS_TIME_H */
1481
1482 static void
1483 pause_or_input (void)
1484 {
1485 #ifdef FD_SET
1486   struct timeval timer;
1487   fd_set readfds;
1488   int ready;
1489
1490   FD_ZERO (&readfds);
1491   FD_SET (fileno (stdin), &readfds);
1492   timer.tv_sec = 2;
1493   timer.tv_usec = 0;
1494   ready = select (fileno (stdin) + 1, &readfds, (fd_set *) NULL,
1495                   (fd_set *) NULL, &timer);
1496 #endif /* FD_SET */
1497 }
1498
1499 /* Print MESSAGE right after the end of the current line, and wait
1500    for input or a couple of seconds, whichever comes first.  Then flush the
1501    informational message that was printed. */
1502 void
1503 inform_in_echo_area (const char *message)
1504 {
1505   int i;
1506   char *text;
1507   int avail = EA_MAX_INPUT + 1 - input_line_end;
1508
1509   text = xstrdup (message);
1510   for (i = 0; text[i] && text[i] != '\n' && i < avail; i++)
1511     ;
1512   text[i] = 0;
1513
1514   echo_area_initialize_node ();
1515   sprintf (&input_line[input_line_end], "%s[%s]\n",
1516            echo_area_is_active ? " ": "", text);
1517   free (text);
1518   the_echo_area->point = input_line_point;
1519   display_update_one_window (the_echo_area);
1520   display_cursor_at_point (active_window);
1521   fflush (stdout);
1522   pause_or_input ();
1523   echo_area_initialize_node ();
1524 }