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