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