Remove texinfo from base
[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.14 2008/06/11 09:55:41 gray Exp $
3
4    Copyright (C) 1993, 1997, 1998, 1999, 2001, 2004, 2007, 2008
5    Free Software 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 3 of the License, or
10    (at your option) 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, see <http://www.gnu.org/licenses/>.
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 = 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 const 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   NULL, NULL, NULL, input_line,
53   EA_MAX_INPUT, 0, N_IsInternal
54 };
55
56 static void echo_area_initialize_node (void);
57 static void push_echo_area (void), pop_echo_area (void);
58 static int echo_area_stack_contains_completions_p (void);
59
60 static void ea_kill_text (int from, int to);
61
62 /* Non-zero means we force the user to complete. */
63 static int echo_area_must_complete_p = 0;
64 static int completions_window_p (WINDOW *window);
65
66 /* If non-null, this is a window which was specifically created to display
67    possible completions output.  We remember it so we can delete it when
68    appropriate. */
69 static WINDOW *echo_area_completions_window = NULL;
70
71 /* Variables which keep track of the window which was active prior to
72    entering the echo area. */
73 static WINDOW *calling_window = NULL;
74 static NODE *calling_window_node = NULL;
75 static long calling_window_point = 0;
76 static long calling_window_pagetop = 0;
77
78 /* Remember the node and pertinent variables of the calling window. */
79 static void
80 remember_calling_window (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 (void)
98 {
99   register WINDOW *win, *compwin = 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 = 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 = 0;
128           int start = 0;
129           int end = 0;
130           int amount = 0;
131
132           next = compwin->next;
133           if (next)
134             {
135               start = next->first_row;
136               end = start + next->height;
137               amount = - (compwin->height + 1);
138               pagetop = next->pagetop;
139             }
140
141           info_delete_window_internal (compwin);
142
143           /* This is not necessary because info_delete_window_internal ()
144              calls echo_area_inform_of_deleted_window (), which does the
145              right thing. */
146 #if defined (UNNECESSARY)
147           echo_area_completions_window = NULL;
148 #endif /* UNNECESSARY */
149
150           if (next)
151             {
152               display_scroll_display (start, end, amount);
153               next->pagetop = pagetop;
154               display_update_display (windows);
155             }
156         }
157     }
158 }
159
160 /* Set up a new input line with PROMPT. */
161 static void
162 initialize_input_line (const char *prompt)
163 {
164   input_line_prompt = prompt;
165   if (prompt)
166     strcpy (input_line, prompt);
167   else
168     input_line[0] = '\0';
169
170   input_line_beg = input_line_end = input_line_point = strlen (prompt);
171 }
172
173 static char *
174 echo_area_after_read (void)
175 {
176   char *return_value;
177
178   if (info_aborted_echo_area)
179     {
180       info_aborted_echo_area = 0;
181       return_value = NULL;
182     }
183   else
184     {
185       if (input_line_beg == input_line_end)
186         return_value = xstrdup ("");
187       else
188         {
189           int line_len = input_line_end - input_line_beg;
190           return_value = xmalloc (1 + line_len);
191           strncpy (return_value, &input_line[input_line_beg], line_len);
192           return_value[line_len] = '\0';
193         }
194     }
195   return return_value;
196 }
197
198 /* Read a line of text in the echo area.  Return a malloc ()'ed string,
199    or NULL if the user aborted out of this read.  WINDOW is the currently
200    active window, so that we can restore it when we need to.  PROMPT, if
201    non-null, is a prompt to print before reading the line. */
202 char *
203 info_read_in_echo_area (WINDOW *window, const 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 (void)
250 {
251   register int i;
252
253   for (i = input_line_end; (unsigned int) 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 (void)
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   window_line_map_init (window);
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 = 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 (_("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   window_line_map_init (window);
650 }
651
652 /* Delete from point to the start of the current word. */
653 DECLARE_INFO_COMMAND (ea_backward_kill_word,
654                       _("Kill the word preceding the cursor"))
655 {
656   int orig_point = input_line_point;
657
658   if (count < 0)
659     ea_kill_word (window, -count, key);
660   else
661     {
662       ea_backward_word (window, count, key);
663
664       if (input_line_point != orig_point)
665         ea_kill_text (orig_point, input_line_point);
666     }
667   window_line_map_init (window);
668 }
669
670 /* The way to kill something.  This appends or prepends to the last
671    kill, if the last command was a kill command.  If FROM is less
672    than TO, then the killed text is appended to the most recent kill,
673    otherwise it is prepended.  If the last command was not a kill command,
674    then a new slot is made for this kill. */
675 static void
676 ea_kill_text (int from, int to)
677 {
678   register int i, counter, distance;
679   int killing_backwards, slot;
680   char *killed_text;
681
682   killing_backwards = (from > to);
683
684   /* If killing backwards, reverse the values of FROM and TO. */
685   if (killing_backwards)
686     {
687       int temp = from;
688       from = to;
689       to = temp;
690     }
691
692   /* Remember the text that we are about to delete. */
693   distance = to - from;
694   killed_text = xmalloc (1 + distance);
695   strncpy (killed_text, &input_line[from], distance);
696   killed_text[distance] = '\0';
697
698   /* Actually delete the text from the line. */
699   counter = input_line_end - to;
700
701   for (i = from; counter; i++, counter--)
702     input_line[i] = input_line[i + distance];
703
704   input_line_end -= distance;
705
706   /* If the last command was a kill, append or prepend the killed text to
707      the last command's killed text. */
708   if (echo_area_last_command_was_kill)
709     {
710       char *old, *new;
711
712       slot = kill_ring_loc;
713       old = kill_ring[slot];
714       new = xmalloc (1 + strlen (old) + strlen (killed_text));
715
716       if (killing_backwards)
717         {
718           /* Prepend TEXT to current kill. */
719           strcpy (new, killed_text);
720           strcat (new, old);
721         }
722       else
723         {
724           /* Append TEXT to current kill. */
725           strcpy (new, old);
726           strcat (new, killed_text);
727         }
728
729       free (old);
730       free (killed_text);
731       kill_ring[slot] = new;
732     }
733   else
734     {
735       /* Try to store the kill in a new slot, unless that would cause there
736          to be too many remembered kills. */
737       slot = kill_ring_index;
738
739       if (slot == max_retained_kills)
740         slot = 0;
741
742       if (slot + 1 > kill_ring_slots)
743         kill_ring = xrealloc (kill_ring,
744                               (kill_ring_slots += max_retained_kills)
745                               * sizeof (char *));
746
747       if (slot != kill_ring_index)
748         free (kill_ring[slot]);
749       else
750         kill_ring_index++;
751
752       kill_ring[slot] = killed_text;
753
754       kill_ring_loc = slot;
755     }
756
757   /* Notice that the last command was a kill. */
758   echo_area_last_command_was_kill++;
759 }
760 \f
761 /* **************************************************************** */
762 /*                                                                  */
763 /*                      Echo Area Completion                        */
764 /*                                                                  */
765 /* **************************************************************** */
766
767 /* Pointer to an array of REFERENCE to complete over. */
768 static REFERENCE **echo_area_completion_items = NULL;
769
770 /* Sorted array of REFERENCE * which is the possible completions found in
771    the variable echo_area_completion_items.  If there is only one element,
772    it is the only possible completion. */
773 static REFERENCE **completions_found = NULL;
774 static int completions_found_index = 0;
775 static int completions_found_slots = 0;
776
777 /* The lowest common denominator found while completing. */
778 static REFERENCE *LCD_completion;
779
780 /* Internal functions used by the user calls. */
781 static void build_completions (void), completions_must_be_rebuilt (void);
782
783 /* Variable which holds the output of completions. */
784 static NODE *possible_completions_output_node = NULL;
785
786 static char *compwin_name = "*Completions*";
787
788 /* Return non-zero if WINDOW is a window used for completions output. */
789 static int
790 completions_window_p (WINDOW *window)
791 {
792   int result = 0;
793
794   if (internal_info_node_p (window->node) &&
795       (strcmp (window->node->nodename, compwin_name) == 0))
796     result = 1;
797
798   return result;
799 }
800
801 /* Workhorse for completion readers.  If FORCE is non-zero, the user cannot
802    exit unless the line read completes, or is empty. */
803 char *
804 info_read_completing_internal (WINDOW *window, const char *prompt,
805     REFERENCE **completions, int force)
806 {
807   char *line;
808
809   /* If the echo area is already active, remember the current state. */
810   if (echo_area_is_active)
811     push_echo_area ();
812
813   echo_area_must_complete_p = force;
814
815   /* Initialize our local variables. */
816   initialize_input_line (prompt);
817
818   /* Initialize the echo area for the first (but maybe not the last) time. */
819   echo_area_initialize_node ();
820
821   /* Save away the original node of this window, and the window itself,
822      so echo area commands can temporarily use this window. */
823   remember_calling_window (window);
824
825   /* Save away the list of items to complete over. */
826   echo_area_completion_items = completions;
827   completions_must_be_rebuilt ();
828
829   active_window = the_echo_area;
830   echo_area_is_active++;
831
832   /* Read characters in the echo area. */
833   while (1)
834     {
835       info_read_and_dispatch ();
836
837       line = echo_area_after_read ();
838
839       /* Force the completion to take place if the user hasn't accepted
840          a default or aborted, and if FORCE is active. */
841       if (force && line && *line && completions)
842         {
843           register int i;
844
845           build_completions ();
846
847           /* If there is only one completion, then make the line be that
848              completion. */
849           if (completions_found_index == 1)
850             {
851               free (line);
852               line = xstrdup (completions_found[0]->label);
853               break;
854             }
855
856           /* If one of the completions matches exactly, then that is okay, so
857              return the current line. */
858           for (i = 0; i < completions_found_index; i++)
859             if (mbscasecmp (completions_found[i]->label, line) == 0)
860               {
861                 free (line);
862                 line = xstrdup (completions_found[i]->label);
863                 break;
864               }
865
866           /* If no match, go back and try again. */
867           if (i == completions_found_index)
868             {
869               if (!completions_found_index)
870                 inform_in_echo_area (_("No completions"));
871               else
872                 inform_in_echo_area (_("Not complete"));
873               continue;
874             }
875         }
876       break;
877     }
878   echo_area_is_active--;
879
880   /* Restore the original active window and show point in it. */
881   active_window = calling_window;
882   restore_calling_window ();
883   display_cursor_at_point (active_window);
884   fflush (stdout);
885
886   echo_area_completion_items = NULL;
887   completions_must_be_rebuilt ();
888
889   /* If there is a previous loop waiting for us, restore it now. */
890   if (echo_area_is_active)
891     pop_echo_area ();
892
893   return line;
894 }
895   
896 /* Read a line in the echo area with completion over COMPLETIONS. */
897 char *
898 info_read_completing_in_echo_area (WINDOW *window,
899     const char *prompt, REFERENCE **completions)
900 {
901   return info_read_completing_internal (window, prompt, completions, 1);
902 }
903
904 /* Read a line in the echo area allowing completion over COMPLETIONS, but
905    not requiring it. */
906 char *
907 info_read_maybe_completing (WINDOW *window,
908     const char *prompt, REFERENCE **completions)
909 {
910   return info_read_completing_internal (window, prompt, completions, 0);
911 }
912
913 DECLARE_INFO_COMMAND (ea_possible_completions, _("List possible completions"))
914 {
915   if (!echo_area_completion_items)
916     {
917       ea_insert (window, count, key);
918       return;
919     }
920
921   build_completions ();
922
923   if (!completions_found_index)
924     {
925       terminal_ring_bell ();
926       inform_in_echo_area (_("No completions"));
927     }
928   else if ((completions_found_index == 1) && (key != '?'))
929     {
930       inform_in_echo_area (_("Sole completion"));
931     }
932   else
933     {
934       register int i, l;
935       int limit, iterations, max_label = 0;
936
937       initialize_message_buffer ();
938       printf_to_message_buffer (completions_found_index == 1
939                                 ? _("One completion:\n")
940                                 : _("%d completions:\n"),
941                                 (void *) (long) completions_found_index,
942                                 NULL, NULL);
943
944       /* Find the maximum length of a label. */
945       for (i = 0; i < completions_found_index; i++)
946         {
947           int len = strlen (completions_found[i]->label);
948           if (len > max_label)
949             max_label = len;
950         }
951
952       max_label += 4;
953
954       /* Find out how many columns we should print in. */
955       limit = calling_window->width / max_label;
956       if (limit != 1 && (limit * max_label == calling_window->width))
957         limit--;
958
959       /* Avoid a possible floating exception.  If max_label > width then
960          the limit will be 0 and a divide-by-zero fault will result. */
961       if (limit == 0)
962         limit = 1;
963
964       /* How many iterations of the printing loop? */
965       iterations = (completions_found_index + (limit - 1)) / limit;
966
967       /* Watch out for special case.  If the number of completions is less
968          than LIMIT, then just do the inner printing loop. */
969       if (completions_found_index < limit)
970         iterations = 1;
971
972       /* Print the sorted items, up-and-down alphabetically. */
973       for (i = 0; i < iterations; i++)
974         {
975           register int j;
976
977           for (j = 0, l = i; j < limit; j++)
978             {
979               if (l >= completions_found_index)
980                 break;
981               else
982                 {
983                   char *label;
984                   int printed_length, k;
985
986                   label = completions_found[l]->label;
987                   printed_length = strlen (label);
988                   printf_to_message_buffer ("%s", label, NULL, NULL);
989
990                   if (j + 1 < limit)
991                     {
992                       for (k = 0; k < max_label - printed_length; k++)
993                         printf_to_message_buffer (" ", NULL, NULL, NULL);
994                     }
995                 }
996               l += iterations;
997             }
998           printf_to_message_buffer ("\n", NULL, NULL, NULL);
999         }
1000
1001       /* Make a new node to hold onto possible completions.  Don't destroy
1002          dangling pointers. */
1003       {
1004         NODE *temp;
1005
1006         temp = message_buffer_to_node ();
1007         add_gcable_pointer (temp->contents);
1008         name_internal_node (temp, compwin_name);
1009         possible_completions_output_node = temp;
1010       }
1011
1012       /* Find a suitable window for displaying the completions output.
1013          First choice is an existing window showing completions output.
1014          If there is only one window, and it is large, make another
1015          (smaller) window, and use that one.  Otherwise, use the caller's
1016          window. */
1017       {
1018         WINDOW *compwin;
1019
1020         compwin = get_internal_info_window (compwin_name);
1021
1022         if (!compwin)
1023           {
1024             /* If we can split the window to display most of the completion
1025                items, then do so. */
1026             if (calling_window->height > (iterations * 2)
1027                 && calling_window->height / 2 >= WINDOW_MIN_SIZE)
1028               {
1029                 int start, pagetop;
1030 #ifdef SPLIT_BEFORE_ACTIVE
1031                 int end;
1032 #endif
1033
1034                 active_window = calling_window;
1035
1036                 /* Perhaps we can scroll this window on redisplay. */
1037                 start = calling_window->first_row;
1038                 pagetop = calling_window->pagetop;
1039
1040                 compwin =
1041                   window_make_window (possible_completions_output_node);
1042                 active_window = the_echo_area;
1043                 window_change_window_height
1044                   (compwin, -(compwin->height - (iterations + 2)));
1045
1046                 window_adjust_pagetop (calling_window);
1047                 remember_calling_window (calling_window);
1048
1049 #if defined (SPLIT_BEFORE_ACTIVE)
1050                 /* If the pagetop hasn't changed, scrolling the calling
1051                    window is a reasonable thing to do. */
1052                 if (pagetop == calling_window->pagetop)
1053                   {
1054                     end = start + calling_window->height;
1055                     display_scroll_display
1056                       (start, end, calling_window->prev->height + 1);
1057                   }
1058 #else /* !SPLIT_BEFORE_ACTIVE */
1059                 /* If the pagetop has changed, set the new pagetop here. */
1060                 if (pagetop != calling_window->pagetop)
1061                   {
1062                     int newtop = calling_window->pagetop;
1063                     calling_window->pagetop = pagetop;
1064                     set_window_pagetop (calling_window, newtop);
1065                   }
1066 #endif /* !SPLIT_BEFORE_ACTIVE */
1067
1068                 echo_area_completions_window = compwin;
1069                 remember_window_and_node (compwin, compwin->node);
1070               }
1071             else
1072               compwin = calling_window;
1073           }
1074
1075         if (compwin->node != possible_completions_output_node)
1076           {
1077             window_set_node_of_window
1078               (compwin, possible_completions_output_node);
1079             remember_window_and_node (compwin, compwin->node);
1080           }
1081
1082         display_update_display (windows);
1083       }
1084     }
1085 }
1086
1087 DECLARE_INFO_COMMAND (ea_complete, _("Insert completion"))
1088 {
1089   if (!echo_area_completion_items)
1090     {
1091       ea_insert (window, count, key);
1092       return;
1093     }
1094
1095   /* If KEY is SPC, and we are not forcing completion to take place, simply
1096      insert the key. */
1097   if (!echo_area_must_complete_p && key == SPC)
1098     {
1099       ea_insert (window, count, key);
1100       return;
1101     }
1102
1103   if (ea_last_executed_command == (VFunction *) ea_complete)
1104     {
1105       /* If the keypress is a SPC character, and we have already tried
1106          completing once, and there are several completions, then check
1107          the batch of completions to see if any continue with a space.
1108          If there are some, insert the space character and continue. */
1109       if (key == SPC && completions_found_index > 1)
1110         {
1111           register int i, offset;
1112
1113           offset = input_line_end - input_line_beg;
1114
1115           for (i = 0; i < completions_found_index; i++)
1116             if (completions_found[i]->label[offset] == ' ')
1117               break;
1118
1119           if (completions_found[i])
1120             ea_insert (window, 1, ' ');
1121           else
1122             {
1123               ea_possible_completions (window, count, key);
1124               return;
1125             }
1126         }
1127       else
1128         {
1129           ea_possible_completions (window, count, key);
1130           return;
1131         }
1132     }
1133
1134   input_line_point = input_line_end;
1135   build_completions ();
1136
1137   if (!completions_found_index)
1138     terminal_ring_bell ();
1139   else if (LCD_completion->label[0] == '\0')
1140     ea_possible_completions (window, count, key);
1141   else
1142     {
1143       register int i;
1144       input_line_point = input_line_end = input_line_beg;
1145       for (i = 0; LCD_completion->label[i]; i++)
1146         ea_insert (window, 1, LCD_completion->label[i]);
1147     }
1148 }
1149
1150 /* Utility REFERENCE used to store possible LCD. */
1151 static REFERENCE LCD_reference = {
1152     NULL, NULL, NULL, 0, 0, 0
1153 };
1154
1155 static void remove_completion_duplicates (void);
1156
1157 /* Variables which remember the state of the most recent call
1158    to build_completions (). */
1159 static char *last_completion_request = NULL;
1160 static REFERENCE **last_completion_items = NULL;
1161
1162 /* How to tell the completion builder to reset internal state. */
1163 static void
1164 completions_must_be_rebuilt (void)
1165 {
1166   maybe_free (last_completion_request);
1167   last_completion_request = NULL;
1168   last_completion_items = NULL;
1169 }
1170
1171 /* Build a list of possible completions from echo_area_completion_items,
1172    and the contents of input_line. */
1173 static void
1174 build_completions (void)
1175 {
1176   register int i, len;
1177   register REFERENCE *entry;
1178   char *request;
1179   int informed_of_lengthy_job = 0;
1180
1181   /* If there are no items to complete over, exit immediately. */
1182   if (!echo_area_completion_items)
1183     {
1184       completions_found_index = 0;
1185       LCD_completion = NULL;
1186       return;
1187     }
1188
1189   /* Check to see if this call to build completions is the same as the last
1190      call to build completions. */
1191   len = input_line_end - input_line_beg;
1192   request = xmalloc (1 + len);
1193   strncpy (request, &input_line[input_line_beg], len);
1194   request[len] = '\0';
1195
1196   if (last_completion_request && last_completion_items &&
1197       last_completion_items == echo_area_completion_items &&
1198       (strcmp (last_completion_request, request) == 0))
1199     {
1200       free (request);
1201       return;
1202     }
1203
1204   maybe_free (last_completion_request);
1205   last_completion_request = request;
1206   last_completion_items = echo_area_completion_items;
1207
1208   /* Always start at the beginning of the list. */
1209   completions_found_index = 0;
1210   LCD_completion = NULL;
1211
1212   for (i = 0; (entry = echo_area_completion_items[i]); i++)
1213     {
1214       if (mbsncasecmp (request, entry->label, len) == 0)
1215         add_pointer_to_array (entry, completions_found_index,
1216                               completions_found, completions_found_slots,
1217                               20, REFERENCE *);
1218
1219       if (!informed_of_lengthy_job && completions_found_index > 100)
1220         {
1221           informed_of_lengthy_job = 1;
1222           window_message_in_echo_area (_("Building completions..."),
1223               NULL, NULL);
1224         }
1225     }
1226
1227   if (!completions_found_index)
1228     return;
1229
1230   /* Sort and prune duplicate entries from the completions array. */
1231   remove_completion_duplicates ();
1232
1233   /* If there is only one completion, just return that. */
1234   if (completions_found_index == 1)
1235     {
1236       LCD_completion = completions_found[0];
1237       return;
1238     }
1239
1240   /* Find the least common denominator. */
1241   {
1242     long shortest = 100000;
1243
1244     for (i = 1; i < completions_found_index; i++)
1245       {
1246         register int j;
1247         int c1, c2;
1248
1249         for (j = 0;
1250              (c1 = info_tolower (completions_found[i - 1]->label[j])) &&
1251              (c2 = info_tolower (completions_found[i]->label[j]));
1252              j++)
1253           if (c1 != c2)
1254             break;
1255
1256         if (shortest > j)
1257           shortest = j;
1258       }
1259
1260     maybe_free (LCD_reference.label);
1261     LCD_reference.label = xmalloc (1 + shortest);
1262     /* Since both the sorting done inside remove_completion_duplicates
1263        and all the comparisons above are case-insensitive, it's
1264        possible that the completion we are going to return is
1265        identical to what the user typed but for the letter-case.  This
1266        is confusing, since the user could type FOOBAR<TAB> and get her
1267        string change letter-case for no good reason.  So try to find a
1268        possible completion whose letter-case is identical, and if so,
1269        use that.  */
1270     if (completions_found_index > 1)
1271       {
1272         int req_len = strlen (request);
1273
1274         for (i = 0; i < completions_found_index; i++)
1275           if (strncmp (request, completions_found[i]->label, req_len) == 0)
1276             break;
1277         /* If none of the candidates match exactly, use the first one.  */
1278         if (i >= completions_found_index)
1279           i = 0;
1280       }
1281     strncpy (LCD_reference.label, completions_found[i]->label, shortest);
1282     LCD_reference.label[shortest] = '\0';
1283     LCD_completion = &LCD_reference;
1284   }
1285
1286   if (informed_of_lengthy_job)
1287     echo_area_initialize_node ();
1288 }
1289
1290 /* Function called by qsort. */
1291 static int
1292 compare_references (const void *entry1, const void *entry2)
1293 {
1294   REFERENCE **e1 = (REFERENCE **) entry1;
1295   REFERENCE **e2 = (REFERENCE **) entry2;
1296
1297   return mbscasecmp ((*e1)->label, (*e2)->label);
1298 }
1299
1300 /* Prune duplicate entries from COMPLETIONS_FOUND. */
1301 static void
1302 remove_completion_duplicates (void)
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] = 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 = 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] = 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 *window)
1363 {
1364   /* If this is the calling_window, forget what we remembered about it. */
1365   if (window == calling_window)
1366     {
1367       if (active_window != the_echo_area)
1368         remember_calling_window (active_window);
1369       else
1370         remember_calling_window (windows);
1371     }
1372
1373   /* If this window was the echo_area_completions_window, then notice that
1374      the window has been deleted. */
1375   if (window == echo_area_completions_window)
1376     echo_area_completions_window = NULL;
1377 }
1378 \f
1379 /* **************************************************************** */
1380 /*                                                                  */
1381 /*                 Pushing and Popping the Echo Area                */
1382 /*                                                                  */
1383 /* **************************************************************** */
1384
1385 /* Push and Pop the echo area. */
1386 typedef struct {
1387   char *line;
1388   const char *prompt;
1389   REFERENCE **comp_items;
1390   int point, beg, end;
1391   int must_complete;
1392   NODE node;
1393   WINDOW *compwin;
1394 } PUSHED_EA;
1395
1396 static PUSHED_EA **pushed_echo_areas = NULL;
1397 static int pushed_echo_areas_index = 0;
1398 static int pushed_echo_areas_slots = 0;
1399
1400 /* Pushing the echo_area has a side effect of zeroing the completion_items. */
1401 static void
1402 push_echo_area (void)
1403 {
1404   PUSHED_EA *pushed;
1405
1406   pushed = xmalloc (sizeof (PUSHED_EA));
1407   pushed->line = xstrdup (input_line);
1408   pushed->prompt = input_line_prompt;
1409   pushed->point = input_line_point;
1410   pushed->beg = input_line_beg;
1411   pushed->end = input_line_end;
1412   pushed->node = input_line_node;
1413   pushed->comp_items = echo_area_completion_items;
1414   pushed->must_complete = echo_area_must_complete_p;
1415   pushed->compwin = echo_area_completions_window;
1416
1417   add_pointer_to_array (pushed, pushed_echo_areas_index, pushed_echo_areas,
1418                         pushed_echo_areas_slots, 4, PUSHED_EA *);
1419
1420   echo_area_completion_items = NULL;
1421 }
1422
1423 static void
1424 pop_echo_area (void)
1425 {
1426   PUSHED_EA *popped;
1427
1428   popped = pushed_echo_areas[--pushed_echo_areas_index];
1429
1430   strcpy (input_line, popped->line);
1431   free (popped->line);
1432   input_line_prompt = popped->prompt;
1433   input_line_point = popped->point;
1434   input_line_beg = popped->beg;
1435   input_line_end = popped->end;
1436   input_line_node = popped->node;
1437   echo_area_completion_items = popped->comp_items;
1438   echo_area_must_complete_p = popped->must_complete;
1439   echo_area_completions_window = popped->compwin;
1440   completions_must_be_rebuilt ();
1441
1442   /* If the completion window no longer exists, forget about it. */
1443   if (echo_area_completions_window)
1444     {
1445       register WINDOW *win;
1446
1447       for (win = windows; win; win = win->next)
1448         if (echo_area_completions_window == win)
1449           break;
1450
1451       /* If the window wasn't found, then it has already been deleted. */
1452       if (!win)
1453         echo_area_completions_window = NULL;
1454     }
1455
1456   free (popped);
1457 }
1458
1459 /* Returns non-zero if any of the prior stacked calls to read in the echo
1460    area produced a completions window. */
1461 static int
1462 echo_area_stack_contains_completions_p (void)
1463 {
1464   register int i;
1465
1466   for (i = 0; i < pushed_echo_areas_index; i++)
1467     if (pushed_echo_areas[i]->compwin)
1468       return 1;
1469
1470   return 0;
1471 }
1472 \f
1473 /* **************************************************************** */
1474 /*                                                                  */
1475 /*             Error Messages While Reading in Echo Area            */
1476 /*                                                                  */
1477 /* **************************************************************** */
1478
1479 #if defined (HAVE_SYS_TIME_H)
1480 #  include <sys/time.h>
1481 #  define HAVE_STRUCT_TIMEVAL
1482 #endif /* HAVE_SYS_TIME_H */
1483
1484 static void
1485 pause_or_input (void)
1486 {
1487 #ifdef FD_SET
1488   struct timeval timer;
1489   fd_set readfds;
1490   int ready;
1491
1492   FD_ZERO (&readfds);
1493   FD_SET (fileno (stdin), &readfds);
1494   timer.tv_sec = 2;
1495   timer.tv_usec = 0;
1496   ready = select (fileno (stdin) + 1, &readfds, NULL, NULL, &timer);
1497 #endif /* FD_SET */
1498 }
1499
1500 /* Print MESSAGE right after the end of the current line, and wait
1501    for input or a couple of seconds, whichever comes first.  Then flush the
1502    informational message that was printed. */
1503 void
1504 inform_in_echo_area (const char *message)
1505 {
1506   int i;
1507   char *text;
1508   int avail = EA_MAX_INPUT + 1 - input_line_end;
1509
1510   text = xstrdup (message);
1511   for (i = 0; text[i] && text[i] != '\n' && i < avail; i++)
1512     ;
1513   text[i] = 0;
1514
1515   echo_area_initialize_node ();
1516   sprintf (&input_line[input_line_end], "%s[%s]\n",
1517            echo_area_is_active ? " ": "", text);
1518   free (text);
1519   the_echo_area->point = input_line_point;
1520   display_update_one_window (the_echo_area);
1521   display_cursor_at_point (active_window);
1522   fflush (stdout);
1523   pause_or_input ();
1524   echo_area_initialize_node ();
1525 }