echo-area.c revision 1.2
1/* echo-area.c -- How to read a line in the echo area.
2   $Id: echo-area.c,v 1.2 1999/01/11 16:38:07 espie Exp $
3
4   Copyright (C) 1993, 97, 98 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              inform_in_echo_area (_("Not complete"));
872              continue;
873            }
874        }
875      break;
876    }
877  echo_area_is_active--;
878
879  /* Restore the original active window and show point in it. */
880  active_window = calling_window;
881  restore_calling_window ();
882  display_cursor_at_point (active_window);
883  fflush (stdout);
884
885  echo_area_completion_items = (REFERENCE **)NULL;
886  completions_must_be_rebuilt ();
887
888  /* If there is a previous loop waiting for us, restore it now. */
889  if (echo_area_is_active)
890    pop_echo_area ();
891
892  return (line);
893}
894
895/* Read a line in the echo area with completion over COMPLETIONS. */
896char *
897info_read_completing_in_echo_area (window, prompt, completions)
898     WINDOW *window;
899     char *prompt;
900     REFERENCE **completions;
901{
902  return (info_read_completing_internal (window, prompt, completions, 1));
903}
904
905/* Read a line in the echo area allowing completion over COMPLETIONS, but
906   not requiring it. */
907char *
908info_read_maybe_completing (window, prompt, completions)
909     WINDOW *window;
910     char *prompt;
911     REFERENCE **completions;
912{
913  return (info_read_completing_internal (window, prompt, completions, 0));
914}
915
916DECLARE_INFO_COMMAND (ea_possible_completions, _("List possible completions"))
917{
918  if (!echo_area_completion_items)
919    {
920      ea_insert (window, count, key);
921      return;
922    }
923
924  build_completions ();
925
926  if (!completions_found_index)
927    {
928      terminal_ring_bell ();
929      inform_in_echo_area (_("No completions"));
930    }
931  else if ((completions_found_index == 1) && (key != '?'))
932    {
933      inform_in_echo_area (_("Sole completion"));
934    }
935  else
936    {
937      register int i, l;
938      int limit, count, max_label = 0;
939
940      initialize_message_buffer ();
941      printf_to_message_buffer (completions_found_index == 1
942                                ? _("One completion:\n")
943                                : _("%d completions:\n"));
944
945      /* Find the maximum length of a label. */
946      for (i = 0; i < completions_found_index; i++)
947        {
948          int len = strlen (completions_found[i]->label);
949          if (len > max_label)
950            max_label = len;
951        }
952
953      max_label += 4;
954
955      /* Find out how many columns we should print in. */
956      limit = calling_window->width / max_label;
957      if (limit != 1 && (limit * max_label == calling_window->width))
958        limit--;
959
960      /* Avoid a possible floating exception.  If max_label > width then
961         the limit will be 0 and a divide-by-zero fault will result. */
962      if (limit == 0)
963        limit = 1;
964
965      /* How many iterations of the printing loop? */
966      count = (completions_found_index + (limit - 1)) / limit;
967
968      /* Watch out for special case.  If the number of completions is less
969         than LIMIT, then just do the inner printing loop. */
970      if (completions_found_index < limit)
971        count = 1;
972
973      /* Print the sorted items, up-and-down alphabetically. */
974      for (i = 0; i < count; i++)
975        {
976          register int j;
977
978          for (j = 0, l = i; j < limit; j++)
979            {
980              if (l >= completions_found_index)
981                break;
982              else
983                {
984                  char *label;
985                  int printed_length, k;
986
987                  label = completions_found[l]->label;
988                  printed_length = strlen (label);
989                  printf_to_message_buffer ("%s", label);
990
991                  if (j + 1 < limit)
992                    {
993                      for (k = 0; k < max_label - printed_length; k++)
994                        printf_to_message_buffer (" ");
995                    }
996                }
997              l += count;
998            }
999          printf_to_message_buffer ("\n");
1000        }
1001
1002      /* Make a new node to hold onto possible completions.  Don't destroy
1003         dangling pointers. */
1004      {
1005        NODE *temp;
1006
1007        temp = message_buffer_to_node ();
1008        add_gcable_pointer (temp->contents);
1009        name_internal_node (temp, compwin_name);
1010        possible_completions_output_node = temp;
1011      }
1012
1013      /* Find a suitable window for displaying the completions output.
1014         First choice is an existing window showing completions output.
1015         If there is only one window, and it is large, make another
1016         (smaller) window, and use that one.  Otherwise, use the caller's
1017         window. */
1018      {
1019        WINDOW *compwin;
1020
1021        compwin = get_internal_info_window (compwin_name);
1022
1023        if (!compwin)
1024          {
1025            /* If we can split the window to display most of the completion
1026               items, then do so. */
1027            if (calling_window->height > (count * 2)
1028		&& calling_window->height / 2 >= WINDOW_MIN_SIZE)
1029              {
1030                int start, pagetop;
1031#ifdef SPLIT_BEFORE_ACTIVE
1032                int end;
1033#endif
1034
1035                active_window = calling_window;
1036
1037                /* Perhaps we can scroll this window on redisplay. */
1038                start = calling_window->first_row;
1039                pagetop = calling_window->pagetop;
1040
1041                compwin =
1042                  window_make_window (possible_completions_output_node);
1043                active_window = the_echo_area;
1044                window_change_window_height
1045                  (compwin, -(compwin->height - (count + 2)));
1046
1047                window_adjust_pagetop (calling_window);
1048                remember_calling_window (calling_window);
1049
1050#if defined (SPLIT_BEFORE_ACTIVE)
1051                /* If the pagetop hasn't changed, scrolling the calling
1052                   window is a reasonable thing to do. */
1053                if (pagetop == calling_window->pagetop)
1054                  {
1055                    end = start + calling_window->height;
1056                    display_scroll_display
1057                      (start, end, calling_window->prev->height + 1);
1058                  }
1059#else /* !SPLIT_BEFORE_ACTIVE */
1060                /* If the pagetop has changed, set the new pagetop here. */
1061                if (pagetop != calling_window->pagetop)
1062                  {
1063                    int newtop = calling_window->pagetop;
1064                    calling_window->pagetop = pagetop;
1065                    set_window_pagetop (calling_window, newtop);
1066                  }
1067#endif /* !SPLIT_BEFORE_ACTIVE */
1068
1069                echo_area_completions_window = compwin;
1070                remember_window_and_node (compwin, compwin->node);
1071              }
1072            else
1073              compwin = calling_window;
1074          }
1075
1076        if (compwin->node != possible_completions_output_node)
1077          {
1078            window_set_node_of_window
1079              (compwin, possible_completions_output_node);
1080            remember_window_and_node (compwin, compwin->node);
1081          }
1082
1083        display_update_display (windows);
1084      }
1085    }
1086}
1087
1088DECLARE_INFO_COMMAND (ea_complete, _("Insert completion"))
1089{
1090  if (!echo_area_completion_items)
1091    {
1092      ea_insert (window, count, key);
1093      return;
1094    }
1095
1096  /* If KEY is SPC, and we are not forcing completion to take place, simply
1097     insert the key. */
1098  if (!echo_area_must_complete_p && key == SPC)
1099    {
1100      ea_insert (window, count, key);
1101      return;
1102    }
1103
1104  if (ea_last_executed_command == ea_complete)
1105    {
1106      /* If the keypress is a SPC character, and we have already tried
1107         completing once, and there are several completions, then check
1108         the batch of completions to see if any continue with a space.
1109         If there are some, insert the space character and continue. */
1110      if (key == SPC && completions_found_index > 1)
1111        {
1112          register int i, offset;
1113
1114          offset = input_line_end - input_line_beg;
1115
1116          for (i = 0; i < completions_found_index; i++)
1117            if (completions_found[i]->label[offset] == ' ')
1118              break;
1119
1120          if (completions_found[i])
1121            ea_insert (window, 1, ' ');
1122          else
1123            {
1124              ea_possible_completions (window, count, key);
1125              return;
1126            }
1127        }
1128      else
1129        {
1130          ea_possible_completions (window, count, key);
1131          return;
1132        }
1133    }
1134
1135  input_line_point = input_line_end;
1136  build_completions ();
1137
1138  if (!completions_found_index)
1139    terminal_ring_bell ();
1140  else if (LCD_completion->label[0] == '\0')
1141    ea_possible_completions (window, count, key);
1142  else
1143    {
1144      register int i;
1145      input_line_point = input_line_end = input_line_beg;
1146      for (i = 0; LCD_completion->label[i]; i++)
1147        ea_insert (window, 1, LCD_completion->label[i]);
1148    }
1149}
1150
1151/* Utility REFERENCE used to store possible LCD. */
1152static REFERENCE LCD_reference = { (char *)NULL, (char *)NULL, (char *)NULL };
1153
1154static void remove_completion_duplicates ();
1155
1156/* Variables which remember the state of the most recent call
1157   to build_completions (). */
1158static char *last_completion_request = (char *)NULL;
1159static REFERENCE **last_completion_items = (REFERENCE **)NULL;
1160
1161/* How to tell the completion builder to reset internal state. */
1162static void
1163completions_must_be_rebuilt ()
1164{
1165  maybe_free (last_completion_request);
1166  last_completion_request = (char *)NULL;
1167  last_completion_items = (REFERENCE **)NULL;
1168}
1169
1170/* Build a list of possible completions from echo_area_completion_items,
1171   and the contents of input_line. */
1172static void
1173build_completions ()
1174{
1175  register int i, len;
1176  register REFERENCE *entry;
1177  char *request;
1178  int informed_of_lengthy_job = 0;
1179
1180  /* If there are no items to complete over, exit immediately. */
1181  if (!echo_area_completion_items)
1182    {
1183      completions_found_index = 0;
1184      LCD_completion = (REFERENCE *)NULL;
1185      return;
1186    }
1187
1188  /* Check to see if this call to build completions is the same as the last
1189     call to build completions. */
1190  len = input_line_end - input_line_beg;
1191  request = (char *)xmalloc (1 + len);
1192  strncpy (request, &input_line[input_line_beg], len);
1193  request[len] = '\0';
1194
1195  if (last_completion_request && last_completion_items &&
1196      last_completion_items == echo_area_completion_items &&
1197      (strcmp (last_completion_request, request) == 0))
1198    {
1199      free (request);
1200      return;
1201    }
1202
1203  maybe_free (last_completion_request);
1204  last_completion_request = request;
1205  last_completion_items = echo_area_completion_items;
1206
1207  /* Always start at the beginning of the list. */
1208  completions_found_index = 0;
1209  LCD_completion = (REFERENCE *)NULL;
1210
1211  for (i = 0; (entry = echo_area_completion_items[i]); i++)
1212    {
1213      if (strncasecmp (request, entry->label, len) == 0)
1214        add_pointer_to_array (entry, completions_found_index,
1215                              completions_found, completions_found_slots,
1216                              20, REFERENCE *);
1217
1218      if (!informed_of_lengthy_job && completions_found_index > 100)
1219        {
1220          informed_of_lengthy_job = 1;
1221          window_message_in_echo_area (_("Building completions..."));
1222        }
1223    }
1224
1225  if (!completions_found_index)
1226    return;
1227
1228  /* Sort and prune duplicate entries from the completions array. */
1229  remove_completion_duplicates ();
1230
1231  /* If there is only one completion, just return that. */
1232  if (completions_found_index == 1)
1233    {
1234      LCD_completion = completions_found[0];
1235      return;
1236    }
1237
1238  /* Find the least common denominator. */
1239  {
1240    long shortest = 100000;
1241
1242    for (i = 1; i < completions_found_index; i++)
1243      {
1244        register int j;
1245        int c1, c2;
1246
1247        for (j = 0;
1248             (c1 = info_tolower (completions_found[i - 1]->label[j])) &&
1249             (c2 = info_tolower (completions_found[i]->label[j]));
1250             j++)
1251          if (c1 != c2)
1252            break;
1253
1254        if (shortest > j)
1255          shortest = j;
1256      }
1257
1258    maybe_free (LCD_reference.label);
1259    LCD_reference.label = (char *)xmalloc (1 + shortest);
1260    strncpy (LCD_reference.label, completions_found[0]->label, shortest);
1261    LCD_reference.label[shortest] = '\0';
1262    LCD_completion = &LCD_reference;
1263  }
1264
1265  if (informed_of_lengthy_job)
1266    echo_area_initialize_node ();
1267}
1268
1269/* Function called by qsort. */
1270static int
1271compare_references (entry1, entry2)
1272     REFERENCE **entry1, **entry2;
1273{
1274  return (strcasecmp ((*entry1)->label, (*entry2)->label));
1275}
1276
1277/* Prune duplicate entries from COMPLETIONS_FOUND. */
1278static void
1279remove_completion_duplicates ()
1280{
1281  register int i, j;
1282  REFERENCE **temp;
1283  int newlen;
1284
1285  if (!completions_found_index)
1286    return;
1287
1288  /* Sort the items. */
1289  qsort (completions_found, completions_found_index, sizeof (REFERENCE *),
1290         compare_references);
1291
1292  for (i = 0, newlen = 1; i < completions_found_index - 1; i++)
1293    {
1294      if (strcmp (completions_found[i]->label,
1295                  completions_found[i + 1]->label) == 0)
1296        completions_found[i] = (REFERENCE *)NULL;
1297      else
1298        newlen++;
1299    }
1300
1301  /* We have marked all the dead slots.  It is faster to copy the live slots
1302     twice than to prune the dead slots one by one. */
1303  temp = (REFERENCE **)xmalloc ((1 + newlen) * sizeof (REFERENCE *));
1304  for (i = 0, j = 0; i < completions_found_index; i++)
1305    if (completions_found[i])
1306      temp[j++] = completions_found[i];
1307
1308  for (i = 0; i < newlen; i++)
1309    completions_found[i] = temp[i];
1310
1311  completions_found[i] = (REFERENCE *)NULL;
1312  completions_found_index = newlen;
1313  free (temp);
1314}
1315
1316/* Scroll the "other" window.  If there is a window showing completions, scroll
1317   that one, otherwise scroll the window which was active on entering the read
1318   function. */
1319DECLARE_INFO_COMMAND (ea_scroll_completions_window, _("Scroll the completions window"))
1320{
1321  WINDOW *compwin;
1322  int old_pagetop;
1323
1324  compwin = get_internal_info_window (compwin_name);
1325
1326  if (!compwin)
1327    compwin = calling_window;
1328
1329  old_pagetop = compwin->pagetop;
1330
1331  /* Let info_scroll_forward () do the work, and print any messages that
1332     need to be displayed. */
1333  info_scroll_forward (compwin, count, key);
1334}
1335
1336/* Function which gets called when an Info window is deleted while the
1337   echo area is active.  WINDOW is the window which has just been deleted. */
1338void
1339echo_area_inform_of_deleted_window (window)
1340     WINDOW *window;
1341{
1342  /* If this is the calling_window, forget what we remembered about it. */
1343  if (window == calling_window)
1344    {
1345      if (active_window != the_echo_area)
1346        remember_calling_window (active_window);
1347      else
1348        remember_calling_window (windows);
1349    }
1350
1351  /* If this window was the echo_area_completions_window, then notice that
1352     the window has been deleted. */
1353  if (window == echo_area_completions_window)
1354    echo_area_completions_window = (WINDOW *)NULL;
1355}
1356
1357/* **************************************************************** */
1358/*                                                                  */
1359/*                 Pushing and Popping the Echo Area                */
1360/*                                                                  */
1361/* **************************************************************** */
1362
1363/* Push and Pop the echo area. */
1364typedef struct {
1365  char *line;
1366  char *prompt;
1367  REFERENCE **comp_items;
1368  int point, beg, end;
1369  int must_complete;
1370  NODE node;
1371  WINDOW *compwin;
1372} PUSHED_EA;
1373
1374static PUSHED_EA **pushed_echo_areas = (PUSHED_EA **)NULL;
1375static int pushed_echo_areas_index = 0;
1376static int pushed_echo_areas_slots = 0;
1377
1378/* Pushing the echo_area has a side effect of zeroing the completion_items. */
1379static void
1380push_echo_area ()
1381{
1382  PUSHED_EA *pushed;
1383
1384  pushed = (PUSHED_EA *)xmalloc (sizeof (PUSHED_EA));
1385  pushed->line = xstrdup (input_line);
1386  pushed->prompt = input_line_prompt;
1387  pushed->point = input_line_point;
1388  pushed->beg = input_line_beg;
1389  pushed->end = input_line_end;
1390  pushed->node = input_line_node;
1391  pushed->comp_items = echo_area_completion_items;
1392  pushed->must_complete = echo_area_must_complete_p;
1393  pushed->compwin = echo_area_completions_window;
1394
1395  add_pointer_to_array (pushed, pushed_echo_areas_index, pushed_echo_areas,
1396                        pushed_echo_areas_slots, 4, PUSHED_EA *);
1397
1398  echo_area_completion_items = (REFERENCE **)NULL;
1399}
1400
1401static void
1402pop_echo_area ()
1403{
1404  PUSHED_EA *popped;
1405
1406  popped = pushed_echo_areas[--pushed_echo_areas_index];
1407
1408  strcpy (input_line, popped->line);
1409  free (popped->line);
1410  input_line_prompt = popped->prompt;
1411  input_line_point = popped->point;
1412  input_line_beg = popped->beg;
1413  input_line_end = popped->end;
1414  input_line_node = popped->node;
1415  echo_area_completion_items = popped->comp_items;
1416  echo_area_must_complete_p = popped->must_complete;
1417  echo_area_completions_window = popped->compwin;
1418  completions_must_be_rebuilt ();
1419
1420  /* If the completion window no longer exists, forget about it. */
1421  if (echo_area_completions_window)
1422    {
1423      register WINDOW *win;
1424
1425      for (win = windows; win; win = win->next)
1426        if (echo_area_completions_window == win)
1427          break;
1428
1429      /* If the window wasn't found, then it has already been deleted. */
1430      if (!win)
1431        echo_area_completions_window = (WINDOW *)NULL;
1432    }
1433
1434  free (popped);
1435}
1436
1437/* Returns non-zero if any of the prior stacked calls to read in the echo
1438   area produced a completions window. */
1439static int
1440echo_area_stack_contains_completions_p ()
1441{
1442  register int i;
1443
1444  for (i = 0; i < pushed_echo_areas_index; i++)
1445    if (pushed_echo_areas[i]->compwin)
1446      return (1);
1447
1448  return (0);
1449}
1450
1451/* **************************************************************** */
1452/*                                                                  */
1453/*             Error Messages While Reading in Echo Area            */
1454/*                                                                  */
1455/* **************************************************************** */
1456
1457#if defined (HAVE_SYS_TIME_H)
1458#  include <sys/time.h>
1459#  define HAVE_STRUCT_TIMEVAL
1460#endif /* HAVE_SYS_TIME_H */
1461
1462static void
1463pause_or_input ()
1464{
1465#if defined (FD_SET)
1466  struct timeval timer;
1467  fd_set readfds;
1468  int ready;
1469
1470  FD_ZERO (&readfds);
1471  FD_SET (fileno (stdin), &readfds);
1472  timer.tv_sec = 2;
1473  timer.tv_usec = 750;
1474  ready = select (fileno (stdin) + 1, &readfds, (fd_set *) NULL,
1475                  (fd_set *) NULL, &timer);
1476#endif /* FD_SET */
1477}
1478
1479/* Print MESSAGE right after the end of the current line, and wait
1480   for input or 2.75 seconds, whichever comes first.  Then flush the
1481   informational message that was printed. */
1482void
1483inform_in_echo_area (message)
1484     char *message;
1485{
1486  register int i;
1487  char *text;
1488
1489  text = xstrdup (message);
1490  for (i = 0; text[i] && text[i] != '\n'; i++);
1491  text[i] = '\0';
1492
1493  echo_area_initialize_node ();
1494  sprintf (&input_line[input_line_end], "%s[%s]\n",
1495           echo_area_is_active ? " ": "", text);
1496  free (text);
1497  the_echo_area->point = input_line_point;
1498  display_update_one_window (the_echo_area);
1499  display_cursor_at_point (active_window);
1500  fflush (stdout);
1501  pause_or_input ();
1502  echo_area_initialize_node ();
1503}
1504