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