echo-area.c revision 1.4
1/* echo-area.c -- how to read a line in the echo area.
2   $Id: echo-area.c,v 1.4 2002/06/10 13:51:03 espie 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. */
33int info_aborted_echo_area = 0;
34
35/* Non-zero means that the echo area is being used to read input. */
36int echo_area_is_active = 0;
37
38/* The address of the last command executed in the echo area. */
39VFunction *ea_last_executed_command = (VFunction *)NULL;
40
41/* Non-zero means that the last command executed while reading input
42   killed some text. */
43int echo_area_last_command_was_kill = 0;
44
45/* Variables which hold on to the current state of the input line. */
46static char input_line[1 + EA_MAX_INPUT];
47static char *input_line_prompt;
48static int input_line_point;
49static int input_line_beg;
50static int input_line_end;
51static NODE input_line_node = {
52  (char *)NULL, (char *)NULL, (char *)NULL, input_line, EA_MAX_INPUT, 0
53};
54
55static void echo_area_initialize_node ();
56static void push_echo_area (), pop_echo_area ();
57static int echo_area_stack_contains_completions_p ();
58
59static void ea_kill_text ();
60
61/* Non-zero means we force the user to complete. */
62static int echo_area_must_complete_p = 0;
63static 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. */
68static 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. */
72static WINDOW *calling_window = (WINDOW *)NULL;
73static NODE *calling_window_node = (NODE *)NULL;
74static long calling_window_point = 0;
75static long calling_window_pagetop = 0;
76
77/* Remember the node and pertinent variables of the calling window. */
78static void
79remember_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 (). */
96static void
97restore_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. */
158static void
159initialize_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
171static char *
172echo_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. */
200char *
201info_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. */
248static void
249echo_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. */
264void
265echo_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
277/* **************************************************************** */
278/*                                                                  */
279/*                   Echo Area Movement Commands                    */
280/*                                                                  */
281/* **************************************************************** */
282
283DECLARE_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
295DECLARE_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
307DECLARE_INFO_COMMAND (ea_beg_of_line, _("Move to the start of this line"))
308{
309  input_line_point = input_line_beg;
310}
311
312DECLARE_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. */
320DECLARE_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
360DECLARE_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
400DECLARE_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
430DECLARE_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
451DECLARE_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
466DECLARE_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
471DECLARE_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
479DECLARE_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
497DECLARE_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. */
504DECLARE_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
541/* **************************************************************** */
542/*                                                                  */
543/*                   Echo Area Killing and Yanking                  */
544/*                                                                  */
545/* **************************************************************** */
546
547static char **kill_ring = (char **)NULL;
548static int kill_ring_index = 0; /* Number of kills appearing in KILL_RING. */
549static int kill_ring_slots = 0; /* Number of slots allocated to KILL_RING. */
550static int kill_ring_loc = 0;   /* Location of current yank pointer. */
551
552/* The largest number of kills that we remember at one time. */
553static int max_retained_kills = 15;
554
555DECLARE_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. */
575DECLARE_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. */
608DECLARE_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. */
620DECLARE_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. */
633DECLARE_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. */
651DECLARE_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. */
672static void
673ea_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
759/* **************************************************************** */
760/*                                                                  */
761/*                      Echo Area Completion                        */
762/*                                                                  */
763/* **************************************************************** */
764
765/* Pointer to an array of REFERENCE to complete over. */
766static 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. */
771static REFERENCE **completions_found = (REFERENCE **)NULL;
772static int completions_found_index = 0;
773static int completions_found_slots = 0;
774
775/* The lowest common denominator found while completing. */
776static REFERENCE *LCD_completion;
777
778/* Internal functions used by the user calls. */
779static void build_completions (), completions_must_be_rebuilt ();
780
781/* Variable which holds the output of completions. */
782static NODE *possible_completions_output_node = (NODE *)NULL;
783
784static char *compwin_name = "*Completions*";
785
786/* Return non-zero if WINDOW is a window used for completions output. */
787static int
788completions_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. */
802char *
803info_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. */
899char *
900info_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. */
910char *
911info_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
919DECLARE_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
1092DECLARE_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. */
1156static REFERENCE LCD_reference = { (char *)NULL, (char *)NULL, (char *)NULL };
1157
1158static void remove_completion_duplicates ();
1159
1160/* Variables which remember the state of the most recent call
1161   to build_completions (). */
1162static char *last_completion_request = (char *)NULL;
1163static REFERENCE **last_completion_items = (REFERENCE **)NULL;
1164
1165/* How to tell the completion builder to reset internal state. */
1166static void
1167completions_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. */
1176static void
1177build_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. */
1293static int
1294compare_references (entry1, entry2)
1295     REFERENCE **entry1, **entry2;
1296{
1297  return (strcasecmp ((*entry1)->label, (*entry2)->label));
1298}
1299
1300/* Prune duplicate entries from COMPLETIONS_FOUND. */
1301static void
1302remove_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. */
1342DECLARE_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. */
1361void
1362echo_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
1380/* **************************************************************** */
1381/*                                                                  */
1382/*                 Pushing and Popping the Echo Area                */
1383/*                                                                  */
1384/* **************************************************************** */
1385
1386/* Push and Pop the echo area. */
1387typedef 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
1397static PUSHED_EA **pushed_echo_areas = (PUSHED_EA **)NULL;
1398static int pushed_echo_areas_index = 0;
1399static int pushed_echo_areas_slots = 0;
1400
1401/* Pushing the echo_area has a side effect of zeroing the completion_items. */
1402static void
1403push_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
1424static void
1425pop_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. */
1462static int
1463echo_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
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
1485static void
1486pause_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. */
1505void
1506inform_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}
1528