* class.c (create_vtable_ptr): Put the vtable at the beginning of
[official-gcc.git] / texinfo / info / echo-area.c
blob2c80d23d77cd479be87b51b255fc001bf65f3555
1 /* echo-area.c -- How to read a line in the echo area.
2 $Id: echo-area.c,v 1.1.1.2 1998/03/24 18:20:08 law Exp $
4 Copyright (C) 1993, 97, 98 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 Written by Brian Fox (bfox@ai.mit.edu). */
22 #include "info.h"
24 #if defined (FD_SET)
25 # if defined (hpux)
26 # define fd_set_cast(x) (int *)(x)
27 # else
28 # define fd_set_cast(x) (fd_set *)(x)
29 # endif /* !hpux */
30 #endif /* FD_SET */
32 /* Non-zero means that C-g was used to quit reading input. */
33 int info_aborted_echo_area = 0;
35 /* Non-zero means that the echo area is being used to read input. */
36 int echo_area_is_active = 0;
38 /* The address of the last command executed in the echo area. */
39 VFunction *ea_last_executed_command = (VFunction *)NULL;
41 /* Non-zero means that the last command executed while reading input
42 killed some text. */
43 int echo_area_last_command_was_kill = 0;
45 /* Variables which hold on to the current state of the input line. */
46 static char input_line[1 + EA_MAX_INPUT];
47 static char *input_line_prompt;
48 static int input_line_point;
49 static int input_line_beg;
50 static int input_line_end;
51 static NODE input_line_node = {
52 (char *)NULL, (char *)NULL, (char *)NULL, input_line, EA_MAX_INPUT, 0
55 static void echo_area_initialize_node ();
56 static void push_echo_area (), pop_echo_area ();
57 static int echo_area_stack_contains_completions_p ();
59 static void ea_kill_text ();
61 /* Non-zero means we force the user to complete. */
62 static int echo_area_must_complete_p = 0;
63 static int completions_window_p ();
65 /* If non-null, this is a window which was specifically created to display
66 possible completions output. We remember it so we can delete it when
67 appropriate. */
68 static WINDOW *echo_area_completions_window = (WINDOW *)NULL;
70 /* Variables which keep track of the window which was active prior to
71 entering the echo area. */
72 static WINDOW *calling_window = (WINDOW *)NULL;
73 static NODE *calling_window_node = (NODE *)NULL;
74 static long calling_window_point = 0;
75 static long calling_window_pagetop = 0;
77 /* Remember the node and pertinent variables of the calling window. */
78 static void
79 remember_calling_window (window)
80 WINDOW *window;
82 /* Only do this if the calling window is not the completions window, or,
83 if it is the completions window and there is no other window. */
84 if (!completions_window_p (window) ||
85 ((window == windows) && !(window->next)))
87 calling_window = window;
88 calling_window_node = window->node;
89 calling_window_point = window->point;
90 calling_window_pagetop = window->pagetop;
94 /* Restore the caller's window so that it shows the node that it was showing
95 on entry to info_read_xxx_echo_area (). */
96 static void
97 restore_calling_window ()
99 register WINDOW *win, *compwin = (WINDOW *)NULL;
101 /* If the calling window is still visible, and it is the window that
102 we used for completions output, then restore the calling window. */
103 for (win = windows; win; win = win->next)
105 if (completions_window_p (win))
106 compwin = win;
108 if (win == calling_window && win == compwin)
110 window_set_node_of_window (calling_window, calling_window_node);
111 calling_window->point = calling_window_point;
112 calling_window->pagetop = calling_window_pagetop;
113 compwin = (WINDOW *)NULL;
114 break;
118 /* Delete the completions window if it is still present, it isn't the
119 last window on the screen, and there aren't any prior echo area reads
120 pending which created a completions window. */
121 if (compwin)
123 if ((compwin != windows || windows->next) &&
124 !echo_area_stack_contains_completions_p ())
126 WINDOW *next;
127 int pagetop, start, end, amount;
129 next = compwin->next;
130 if (next)
132 start = next->first_row;
133 end = start + next->height;
134 amount = - (compwin->height + 1);
135 pagetop = next->pagetop;
138 info_delete_window_internal (compwin);
140 /* This is not necessary because info_delete_window_internal ()
141 calls echo_area_inform_of_deleted_window (), which does the
142 right thing. */
143 #if defined (UNNECESSARY)
144 echo_area_completions_window = (WINDOW *)NULL;
145 #endif /* UNNECESSARY */
147 if (next)
149 display_scroll_display (start, end, amount);
150 next->pagetop = pagetop;
151 display_update_display (windows);
157 /* Set up a new input line with PROMPT. */
158 static void
159 initialize_input_line (prompt)
160 char *prompt;
162 input_line_prompt = prompt;
163 if (prompt)
164 strcpy (input_line, prompt);
165 else
166 input_line[0] = '\0';
168 input_line_beg = input_line_end = input_line_point = strlen (prompt);
171 static char *
172 echo_area_after_read ()
174 char *return_value;
176 if (info_aborted_echo_area)
178 info_aborted_echo_area = 0;
179 return_value = (char *)NULL;
181 else
183 if (input_line_beg == input_line_end)
184 return_value = xstrdup ("");
185 else
187 int line_len = input_line_end - input_line_beg;
188 return_value = (char *) xmalloc (1 + line_len);
189 strncpy (return_value, &input_line[input_line_beg], line_len);
190 return_value[line_len] = '\0';
193 return (return_value);
196 /* Read a line of text in the echo area. Return a malloc ()'ed string,
197 or NULL if the user aborted out of this read. WINDOW is the currently
198 active window, so that we can restore it when we need to. PROMPT, if
199 non-null, is a prompt to print before reading the line. */
200 char *
201 info_read_in_echo_area (window, prompt)
202 WINDOW *window;
203 char *prompt;
205 char *line;
207 /* If the echo area is already active, remember the current state. */
208 if (echo_area_is_active)
209 push_echo_area ();
211 /* Initialize our local variables. */
212 initialize_input_line (prompt);
214 /* Initialize the echo area for the first (but maybe not the last) time. */
215 echo_area_initialize_node ();
217 /* Save away the original node of this window, and the window itself,
218 so echo area commands can temporarily use this window. */
219 remember_calling_window (window);
221 /* Let the rest of Info know that the echo area is active. */
222 echo_area_is_active++;
223 active_window = the_echo_area;
225 /* Read characters in the echo area. */
226 info_read_and_dispatch ();
228 echo_area_is_active--;
230 /* Restore the original active window and show point in it. */
231 active_window = calling_window;
232 restore_calling_window ();
233 display_cursor_at_point (active_window);
234 fflush (stdout);
236 /* Get the value of the line. */
237 line = echo_area_after_read ();
239 /* If there is a previous loop waiting for us, restore it now. */
240 if (echo_area_is_active)
241 pop_echo_area ();
243 /* Return the results to the caller. */
244 return (line);
247 /* (re) Initialize the echo area node. */
248 static void
249 echo_area_initialize_node ()
251 register int i;
253 for (i = input_line_end; i < sizeof (input_line); i++)
254 input_line[i] = ' ';
256 input_line[i - 1] = '\n';
257 window_set_node_of_window (the_echo_area, &input_line_node);
258 input_line[input_line_end] = '\n';
261 /* Prepare to read characters in the echo area. This can initialize the
262 echo area node, but its primary purpose is to side effect the input
263 line buffer contents. */
264 void
265 echo_area_prep_read ()
267 if (the_echo_area->node != &input_line_node)
268 echo_area_initialize_node ();
270 the_echo_area->point = input_line_point;
271 input_line[input_line_end] = '\n';
272 display_update_one_window (the_echo_area);
273 display_cursor_at_point (active_window);
277 /* **************************************************************** */
278 /* */
279 /* Echo Area Movement Commands */
280 /* */
281 /* **************************************************************** */
283 DECLARE_INFO_COMMAND (ea_forward, _("Move forward a character"))
285 if (count < 0)
286 ea_backward (window, -count, key);
287 else
289 input_line_point += count;
290 if (input_line_point > input_line_end)
291 input_line_point = input_line_end;
295 DECLARE_INFO_COMMAND (ea_backward, _("Move backward a character"))
297 if (count < 0)
298 ea_forward (window, -count, key);
299 else
301 input_line_point -= count;
302 if (input_line_point < input_line_beg)
303 input_line_point = input_line_beg;
307 DECLARE_INFO_COMMAND (ea_beg_of_line, _("Move to the start of this line"))
309 input_line_point = input_line_beg;
312 DECLARE_INFO_COMMAND (ea_end_of_line, _("Move to the end of this line"))
314 input_line_point = input_line_end;
317 #define alphabetic(c) (islower (c) || isupper (c) || isdigit (c))
319 /* Move forward a word in the input line. */
320 DECLARE_INFO_COMMAND (ea_forward_word, _("Move forward a word"))
322 int c;
324 if (count < 0)
325 ea_backward_word (window, -count, key);
326 else
328 while (count--)
330 if (input_line_point == input_line_end)
331 return;
333 /* If we are not in a word, move forward until we are in one.
334 Then, move forward until we hit a non-alphabetic character. */
335 c = input_line[input_line_point];
337 if (!alphabetic (c))
339 while (++input_line_point < input_line_end)
341 c = input_line[input_line_point];
342 if (alphabetic (c))
343 break;
347 if (input_line_point == input_line_end)
348 return;
350 while (++input_line_point < input_line_end)
352 c = input_line[input_line_point];
353 if (!alphabetic (c))
354 break;
360 DECLARE_INFO_COMMAND (ea_backward_word, _("Move backward a word"))
362 int c;
364 if (count < 0)
365 ea_forward_word (window, -count, key);
366 else
368 while (count--)
370 if (input_line_point == input_line_beg)
371 return;
373 /* Like ea_forward_word (), except that we look at the
374 characters just before point. */
376 c = input_line[input_line_point - 1];
378 if (!alphabetic (c))
380 while ((--input_line_point) != input_line_beg)
382 c = input_line[input_line_point - 1];
383 if (alphabetic (c))
384 break;
388 while (input_line_point != input_line_beg)
390 c = input_line[input_line_point - 1];
391 if (!alphabetic (c))
392 break;
393 else
394 --input_line_point;
400 DECLARE_INFO_COMMAND (ea_delete, _("Delete the character under the cursor"))
402 register int i;
404 if (count < 0)
405 ea_rubout (window, -count, key);
406 else
408 if (input_line_point == input_line_end)
409 return;
411 if (info_explicit_arg || count > 1)
413 int orig_point;
415 orig_point = input_line_point;
416 ea_forward (window, count, key);
417 ea_kill_text (orig_point, input_line_point);
418 input_line_point = orig_point;
420 else
422 for (i = input_line_point; i < input_line_end; i++)
423 input_line[i] = input_line[i + 1];
425 input_line_end--;
430 DECLARE_INFO_COMMAND (ea_rubout, _("Delete the character behind the cursor"))
432 if (count < 0)
433 ea_delete (window, -count, key);
434 else
436 int start;
438 if (input_line_point == input_line_beg)
439 return;
441 start = input_line_point;
442 ea_backward (window, count, key);
444 if (info_explicit_arg || count > 1)
445 ea_kill_text (start, input_line_point);
446 else
447 ea_delete (window, count, key);
451 DECLARE_INFO_COMMAND (ea_abort, _("Cancel or quit operation"))
453 /* If any text, just discard it, and restore the calling window's node.
454 If no text, quit. */
455 if (input_line_end != input_line_beg)
457 terminal_ring_bell ();
458 input_line_end = input_line_point = input_line_beg;
459 if (calling_window->node != calling_window_node)
460 restore_calling_window ();
462 else
463 info_aborted_echo_area = 1;
466 DECLARE_INFO_COMMAND (ea_newline, _("Accept (or force completion of) this line"))
468 /* Stub does nothing. Simply here to see if it has been executed. */
471 DECLARE_INFO_COMMAND (ea_quoted_insert, _("Insert next character verbatim"))
473 unsigned char character;
475 character = info_get_another_input_char ();
476 ea_insert (window, count, character);
479 DECLARE_INFO_COMMAND (ea_insert, _("Insert this character"))
481 register int i;
483 if ((input_line_end + 1) == EA_MAX_INPUT)
485 terminal_ring_bell ();
486 return;
489 for (i = input_line_end + 1; i != input_line_point; i--)
490 input_line[i] = input_line[i - 1];
492 input_line[input_line_point] = key;
493 input_line_point++;
494 input_line_end++;
497 DECLARE_INFO_COMMAND (ea_tab_insert, _("Insert a TAB character"))
499 ea_insert (window, count, '\t');
502 /* Transpose the characters at point. If point is at the end of the line,
503 then transpose the characters before point. */
504 DECLARE_INFO_COMMAND (ea_transpose_chars, _("Transpose characters at point"))
506 /* Handle conditions that would make it impossible to transpose
507 characters. */
508 if (!count || !input_line_point || (input_line_end - input_line_beg) < 2)
509 return;
511 while (count)
513 int t;
514 if (input_line_point == input_line_end)
516 t = input_line[input_line_point - 1];
518 input_line[input_line_point - 1] = input_line[input_line_point - 2];
519 input_line[input_line_point - 2] = t;
521 else
523 t = input_line[input_line_point];
525 input_line[input_line_point] = input_line[input_line_point - 1];
526 input_line[input_line_point - 1] = t;
528 if (count < 0 && input_line_point != input_line_beg)
529 input_line_point--;
530 else
531 input_line_point++;
534 if (count < 0)
535 count++;
536 else
537 count--;
541 /* **************************************************************** */
542 /* */
543 /* Echo Area Killing and Yanking */
544 /* */
545 /* **************************************************************** */
547 static char **kill_ring = (char **)NULL;
548 static int kill_ring_index = 0; /* Number of kills appearing in KILL_RING. */
549 static int kill_ring_slots = 0; /* Number of slots allocated to KILL_RING. */
550 static int kill_ring_loc = 0; /* Location of current yank pointer. */
552 /* The largest number of kills that we remember at one time. */
553 static int max_retained_kills = 15;
555 DECLARE_INFO_COMMAND (ea_yank, _("Yank back the contents of the last kill"))
557 register int i;
558 register char *text;
560 if (!kill_ring_index)
562 inform_in_echo_area (_("Kill ring is empty"));
563 return;
566 text = kill_ring[kill_ring_loc];
568 for (i = 0; text[i]; i++)
569 ea_insert (window, 1, text[i]);
572 /* If the last command was yank, or yank_pop, and the text just before
573 point is identical to the current kill item, then delete that text
574 from the line, rotate the index down, and yank back some other text. */
575 DECLARE_INFO_COMMAND (ea_yank_pop, _("Yank back a previous kill"))
577 register int len;
579 if (((ea_last_executed_command != ea_yank) &&
580 (ea_last_executed_command != ea_yank_pop)) ||
581 (kill_ring_index == 0))
582 return;
584 len = strlen (kill_ring[kill_ring_loc]);
586 /* Delete the last yanked item from the line. */
588 register int i, counter;
590 counter = input_line_end - input_line_point;
592 for (i = input_line_point - len; counter; i++, counter--)
593 input_line[i] = input_line[i + len];
595 input_line_end -= len;
596 input_line_point -= len;
599 /* Get a previous kill, and yank that. */
600 kill_ring_loc--;
601 if (kill_ring_loc < 0)
602 kill_ring_loc = kill_ring_index - 1;
604 ea_yank (window, count, key);
607 /* Delete the text from point to end of line. */
608 DECLARE_INFO_COMMAND (ea_kill_line, _("Kill to the end of the line"))
610 if (count < 0)
612 ea_kill_text (input_line_point, input_line_beg);
613 input_line_point = input_line_beg;
615 else
616 ea_kill_text (input_line_point, input_line_end);
619 /* Delete the text from point to beg of line. */
620 DECLARE_INFO_COMMAND (ea_backward_kill_line,
621 _("Kill to the beginning of the line"))
623 if (count < 0)
624 ea_kill_text (input_line_point, input_line_end);
625 else
627 ea_kill_text (input_line_point, input_line_beg);
628 input_line_point = input_line_beg;
632 /* Delete from point to the end of the current word. */
633 DECLARE_INFO_COMMAND (ea_kill_word, _("Kill the word following the cursor"))
635 int orig_point = input_line_point;
637 if (count < 0)
638 ea_backward_kill_word (window, -count, key);
639 else
641 ea_forward_word (window, count, key);
643 if (input_line_point != orig_point)
644 ea_kill_text (orig_point, input_line_point);
646 input_line_point = orig_point;
650 /* Delete from point to the start of the current word. */
651 DECLARE_INFO_COMMAND (ea_backward_kill_word,
652 _("Kill the word preceding the cursor"))
654 int orig_point = input_line_point;
656 if (count < 0)
657 ea_kill_word (window, -count, key);
658 else
660 ea_backward_word (window, count, key);
662 if (input_line_point != orig_point)
663 ea_kill_text (orig_point, input_line_point);
667 /* The way to kill something. This appends or prepends to the last
668 kill, if the last command was a kill command. If FROM is less
669 than TO, then the killed text is appended to the most recent kill,
670 otherwise it is prepended. If the last command was not a kill command,
671 then a new slot is made for this kill. */
672 static void
673 ea_kill_text (from, to)
674 int from, to;
676 register int i, counter, distance;
677 int killing_backwards, slot;
678 char *killed_text;
680 killing_backwards = (from > to);
682 /* If killing backwards, reverse the values of FROM and TO. */
683 if (killing_backwards)
685 int temp = from;
686 from = to;
687 to = temp;
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';
696 /* Actually delete the text from the line. */
697 counter = input_line_end - to;
699 for (i = from; counter; i++, counter--)
700 input_line[i] = input_line[i + distance];
702 input_line_end -= distance;
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)
708 char *old, *new;
710 slot = kill_ring_loc;
711 old = kill_ring[slot];
712 new = (char *)xmalloc (1 + strlen (old) + strlen (killed_text));
714 if (killing_backwards)
716 /* Prepend TEXT to current kill. */
717 strcpy (new, killed_text);
718 strcat (new, old);
720 else
722 /* Append TEXT to current kill. */
723 strcpy (new, old);
724 strcat (new, killed_text);
727 free (old);
728 free (killed_text);
729 kill_ring[slot] = new;
731 else
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;
737 if (slot == max_retained_kills)
738 slot = 0;
740 if (slot + 1 > kill_ring_slots)
741 kill_ring = (char **) xrealloc
742 (kill_ring,
743 (kill_ring_slots += max_retained_kills) * sizeof (char *));
745 if (slot != kill_ring_index)
746 free (kill_ring[slot]);
747 else
748 kill_ring_index++;
750 kill_ring[slot] = killed_text;
752 kill_ring_loc = slot;
755 /* Notice that the last command was a kill. */
756 echo_area_last_command_was_kill++;
759 /* **************************************************************** */
760 /* */
761 /* Echo Area Completion */
762 /* */
763 /* **************************************************************** */
765 /* Pointer to an array of REFERENCE to complete over. */
766 static REFERENCE **echo_area_completion_items = (REFERENCE **)NULL;
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. */
771 static REFERENCE **completions_found = (REFERENCE **)NULL;
772 static int completions_found_index = 0;
773 static int completions_found_slots = 0;
775 /* The lowest common denominator found while completing. */
776 static REFERENCE *LCD_completion;
778 /* Internal functions used by the user calls. */
779 static void build_completions (), completions_must_be_rebuilt ();
781 /* Variable which holds the output of completions. */
782 static NODE *possible_completions_output_node = (NODE *)NULL;
784 static char *compwin_name = "*Completions*";
786 /* Return non-zero if WINDOW is a window used for completions output. */
787 static int
788 completions_window_p (window)
789 WINDOW *window;
791 int result = 0;
793 if (internal_info_node_p (window->node) &&
794 (strcmp (window->node->nodename, compwin_name) == 0))
795 result = 1;
797 return (result);
800 /* Workhorse for completion readers. If FORCE is non-zero, the user cannot
801 exit unless the line read completes, or is empty. */
802 char *
803 info_read_completing_internal (window, prompt, completions, force)
804 WINDOW *window;
805 char *prompt;
806 REFERENCE **completions;
807 int force;
809 char *line;
811 /* If the echo area is already active, remember the current state. */
812 if (echo_area_is_active)
813 push_echo_area ();
815 echo_area_must_complete_p = force;
817 /* Initialize our local variables. */
818 initialize_input_line (prompt);
820 /* Initialize the echo area for the first (but maybe not the last) time. */
821 echo_area_initialize_node ();
823 /* Save away the original node of this window, and the window itself,
824 so echo area commands can temporarily use this window. */
825 remember_calling_window (window);
827 /* Save away the list of items to complete over. */
828 echo_area_completion_items = completions;
829 completions_must_be_rebuilt ();
831 active_window = the_echo_area;
832 echo_area_is_active++;
834 /* Read characters in the echo area. */
835 while (1)
837 info_read_and_dispatch ();
839 line = echo_area_after_read ();
841 /* Force the completion to take place if the user hasn't accepted
842 a default or aborted, and if FORCE is active. */
843 if (force && line && *line && completions)
845 register int i;
847 build_completions ();
849 /* If there is only one completion, then make the line be that
850 completion. */
851 if (completions_found_index == 1)
853 free (line);
854 line = xstrdup (completions_found[0]->label);
855 break;
858 /* If one of the completions matches exactly, then that is okay, so
859 return the current line. */
860 for (i = 0; i < completions_found_index; i++)
861 if (strcasecmp (completions_found[i]->label, line) == 0)
863 free (line);
864 line = xstrdup (completions_found[i]->label);
865 break;
868 /* If no match, go back and try again. */
869 if (i == completions_found_index)
871 inform_in_echo_area (_("Not complete"));
872 continue;
875 break;
877 echo_area_is_active--;
879 /* Restore the original active window and show point in it. */
880 active_window = calling_window;
881 restore_calling_window ();
882 display_cursor_at_point (active_window);
883 fflush (stdout);
885 echo_area_completion_items = (REFERENCE **)NULL;
886 completions_must_be_rebuilt ();
888 /* If there is a previous loop waiting for us, restore it now. */
889 if (echo_area_is_active)
890 pop_echo_area ();
892 return (line);
895 /* Read a line in the echo area with completion over COMPLETIONS. */
896 char *
897 info_read_completing_in_echo_area (window, prompt, completions)
898 WINDOW *window;
899 char *prompt;
900 REFERENCE **completions;
902 return (info_read_completing_internal (window, prompt, completions, 1));
905 /* Read a line in the echo area allowing completion over COMPLETIONS, but
906 not requiring it. */
907 char *
908 info_read_maybe_completing (window, prompt, completions)
909 WINDOW *window;
910 char *prompt;
911 REFERENCE **completions;
913 return (info_read_completing_internal (window, prompt, completions, 0));
916 DECLARE_INFO_COMMAND (ea_possible_completions, _("List possible completions"))
918 if (!echo_area_completion_items)
920 ea_insert (window, count, key);
921 return;
924 build_completions ();
926 if (!completions_found_index)
928 terminal_ring_bell ();
929 inform_in_echo_area (_("No completions"));
931 else if ((completions_found_index == 1) && (key != '?'))
933 inform_in_echo_area (_("Sole completion"));
935 else
937 register int i, l;
938 int limit, count, max_label = 0;
940 initialize_message_buffer ();
941 printf_to_message_buffer (completions_found_index == 1
942 ? _("One completion:\n")
943 : _("%d completions:\n"));
945 /* Find the maximum length of a label. */
946 for (i = 0; i < completions_found_index; i++)
948 int len = strlen (completions_found[i]->label);
949 if (len > max_label)
950 max_label = len;
953 max_label += 4;
955 /* Find out how many columns we should print in. */
956 limit = calling_window->width / max_label;
957 if (limit != 1 && (limit * max_label == calling_window->width))
958 limit--;
960 /* Avoid a possible floating exception. If max_label > width then
961 the limit will be 0 and a divide-by-zero fault will result. */
962 if (limit == 0)
963 limit = 1;
965 /* How many iterations of the printing loop? */
966 count = (completions_found_index + (limit - 1)) / limit;
968 /* Watch out for special case. If the number of completions is less
969 than LIMIT, then just do the inner printing loop. */
970 if (completions_found_index < limit)
971 count = 1;
973 /* Print the sorted items, up-and-down alphabetically. */
974 for (i = 0; i < count; i++)
976 register int j;
978 for (j = 0, l = i; j < limit; j++)
980 if (l >= completions_found_index)
981 break;
982 else
984 char *label;
985 int printed_length, k;
987 label = completions_found[l]->label;
988 printed_length = strlen (label);
989 printf_to_message_buffer ("%s", label);
991 if (j + 1 < limit)
993 for (k = 0; k < max_label - printed_length; k++)
994 printf_to_message_buffer (" ");
997 l += count;
999 printf_to_message_buffer ("\n");
1002 /* Make a new node to hold onto possible completions. Don't destroy
1003 dangling pointers. */
1005 NODE *temp;
1007 temp = message_buffer_to_node ();
1008 add_gcable_pointer (temp->contents);
1009 name_internal_node (temp, compwin_name);
1010 possible_completions_output_node = temp;
1013 /* Find a suitable window for displaying the completions output.
1014 First choice is an existing window showing completions output.
1015 If there is only one window, and it is large, make another
1016 (smaller) window, and use that one. Otherwise, use the caller's
1017 window. */
1019 WINDOW *compwin;
1021 compwin = get_internal_info_window (compwin_name);
1023 if (!compwin)
1025 /* If we can split the window to display most of the completion
1026 items, then do so. */
1027 if (calling_window->height > (count * 2)
1028 && calling_window->height / 2 >= WINDOW_MIN_SIZE)
1030 int start, pagetop;
1031 #ifdef SPLIT_BEFORE_ACTIVE
1032 int end;
1033 #endif
1035 active_window = calling_window;
1037 /* Perhaps we can scroll this window on redisplay. */
1038 start = calling_window->first_row;
1039 pagetop = calling_window->pagetop;
1041 compwin =
1042 window_make_window (possible_completions_output_node);
1043 active_window = the_echo_area;
1044 window_change_window_height
1045 (compwin, -(compwin->height - (count + 2)));
1047 window_adjust_pagetop (calling_window);
1048 remember_calling_window (calling_window);
1050 #if defined (SPLIT_BEFORE_ACTIVE)
1051 /* If the pagetop hasn't changed, scrolling the calling
1052 window is a reasonable thing to do. */
1053 if (pagetop == calling_window->pagetop)
1055 end = start + calling_window->height;
1056 display_scroll_display
1057 (start, end, calling_window->prev->height + 1);
1059 #else /* !SPLIT_BEFORE_ACTIVE */
1060 /* If the pagetop has changed, set the new pagetop here. */
1061 if (pagetop != calling_window->pagetop)
1063 int newtop = calling_window->pagetop;
1064 calling_window->pagetop = pagetop;
1065 set_window_pagetop (calling_window, newtop);
1067 #endif /* !SPLIT_BEFORE_ACTIVE */
1069 echo_area_completions_window = compwin;
1070 remember_window_and_node (compwin, compwin->node);
1072 else
1073 compwin = calling_window;
1076 if (compwin->node != possible_completions_output_node)
1078 window_set_node_of_window
1079 (compwin, possible_completions_output_node);
1080 remember_window_and_node (compwin, compwin->node);
1083 display_update_display (windows);
1088 DECLARE_INFO_COMMAND (ea_complete, _("Insert completion"))
1090 if (!echo_area_completion_items)
1092 ea_insert (window, count, key);
1093 return;
1096 /* If KEY is SPC, and we are not forcing completion to take place, simply
1097 insert the key. */
1098 if (!echo_area_must_complete_p && key == SPC)
1100 ea_insert (window, count, key);
1101 return;
1104 if (ea_last_executed_command == ea_complete)
1106 /* If the keypress is a SPC character, and we have already tried
1107 completing once, and there are several completions, then check
1108 the batch of completions to see if any continue with a space.
1109 If there are some, insert the space character and continue. */
1110 if (key == SPC && completions_found_index > 1)
1112 register int i, offset;
1114 offset = input_line_end - input_line_beg;
1116 for (i = 0; i < completions_found_index; i++)
1117 if (completions_found[i]->label[offset] == ' ')
1118 break;
1120 if (completions_found[i])
1121 ea_insert (window, 1, ' ');
1122 else
1124 ea_possible_completions (window, count, key);
1125 return;
1128 else
1130 ea_possible_completions (window, count, key);
1131 return;
1135 input_line_point = input_line_end;
1136 build_completions ();
1138 if (!completions_found_index)
1139 terminal_ring_bell ();
1140 else if (LCD_completion->label[0] == '\0')
1141 ea_possible_completions (window, count, key);
1142 else
1144 register int i;
1145 input_line_point = input_line_end = input_line_beg;
1146 for (i = 0; LCD_completion->label[i]; i++)
1147 ea_insert (window, 1, LCD_completion->label[i]);
1151 /* Utility REFERENCE used to store possible LCD. */
1152 static REFERENCE LCD_reference = { (char *)NULL, (char *)NULL, (char *)NULL };
1154 static void remove_completion_duplicates ();
1156 /* Variables which remember the state of the most recent call
1157 to build_completions (). */
1158 static char *last_completion_request = (char *)NULL;
1159 static REFERENCE **last_completion_items = (REFERENCE **)NULL;
1161 /* How to tell the completion builder to reset internal state. */
1162 static void
1163 completions_must_be_rebuilt ()
1165 maybe_free (last_completion_request);
1166 last_completion_request = (char *)NULL;
1167 last_completion_items = (REFERENCE **)NULL;
1170 /* Build a list of possible completions from echo_area_completion_items,
1171 and the contents of input_line. */
1172 static void
1173 build_completions ()
1175 register int i, len;
1176 register REFERENCE *entry;
1177 char *request;
1178 int informed_of_lengthy_job = 0;
1180 /* If there are no items to complete over, exit immediately. */
1181 if (!echo_area_completion_items)
1183 completions_found_index = 0;
1184 LCD_completion = (REFERENCE *)NULL;
1185 return;
1188 /* Check to see if this call to build completions is the same as the last
1189 call to build completions. */
1190 len = input_line_end - input_line_beg;
1191 request = (char *)xmalloc (1 + len);
1192 strncpy (request, &input_line[input_line_beg], len);
1193 request[len] = '\0';
1195 if (last_completion_request && last_completion_items &&
1196 last_completion_items == echo_area_completion_items &&
1197 (strcmp (last_completion_request, request) == 0))
1199 free (request);
1200 return;
1203 maybe_free (last_completion_request);
1204 last_completion_request = request;
1205 last_completion_items = echo_area_completion_items;
1207 /* Always start at the beginning of the list. */
1208 completions_found_index = 0;
1209 LCD_completion = (REFERENCE *)NULL;
1211 for (i = 0; (entry = echo_area_completion_items[i]); i++)
1213 if (strncasecmp (request, entry->label, len) == 0)
1214 add_pointer_to_array (entry, completions_found_index,
1215 completions_found, completions_found_slots,
1216 20, REFERENCE *);
1218 if (!informed_of_lengthy_job && completions_found_index > 100)
1220 informed_of_lengthy_job = 1;
1221 window_message_in_echo_area (_("Building completions..."));
1225 if (!completions_found_index)
1226 return;
1228 /* Sort and prune duplicate entries from the completions array. */
1229 remove_completion_duplicates ();
1231 /* If there is only one completion, just return that. */
1232 if (completions_found_index == 1)
1234 LCD_completion = completions_found[0];
1235 return;
1238 /* Find the least common denominator. */
1240 long shortest = 100000;
1242 for (i = 1; i < completions_found_index; i++)
1244 register int j;
1245 int c1, c2;
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;
1254 if (shortest > j)
1255 shortest = j;
1258 maybe_free (LCD_reference.label);
1259 LCD_reference.label = (char *)xmalloc (1 + shortest);
1260 strncpy (LCD_reference.label, completions_found[0]->label, shortest);
1261 LCD_reference.label[shortest] = '\0';
1262 LCD_completion = &LCD_reference;
1265 if (informed_of_lengthy_job)
1266 echo_area_initialize_node ();
1269 /* Function called by qsort. */
1270 static int
1271 compare_references (entry1, entry2)
1272 REFERENCE **entry1, **entry2;
1274 return (strcasecmp ((*entry1)->label, (*entry2)->label));
1277 /* Prune duplicate entries from COMPLETIONS_FOUND. */
1278 static void
1279 remove_completion_duplicates ()
1281 register int i, j;
1282 REFERENCE **temp;
1283 int newlen;
1285 if (!completions_found_index)
1286 return;
1288 /* Sort the items. */
1289 qsort (completions_found, completions_found_index, sizeof (REFERENCE *),
1290 compare_references);
1292 for (i = 0, newlen = 1; i < completions_found_index - 1; i++)
1294 if (strcmp (completions_found[i]->label,
1295 completions_found[i + 1]->label) == 0)
1296 completions_found[i] = (REFERENCE *)NULL;
1297 else
1298 newlen++;
1301 /* We have marked all the dead slots. It is faster to copy the live slots
1302 twice than to prune the dead slots one by one. */
1303 temp = (REFERENCE **)xmalloc ((1 + newlen) * sizeof (REFERENCE *));
1304 for (i = 0, j = 0; i < completions_found_index; i++)
1305 if (completions_found[i])
1306 temp[j++] = completions_found[i];
1308 for (i = 0; i < newlen; i++)
1309 completions_found[i] = temp[i];
1311 completions_found[i] = (REFERENCE *)NULL;
1312 completions_found_index = newlen;
1313 free (temp);
1316 /* Scroll the "other" window. If there is a window showing completions, scroll
1317 that one, otherwise scroll the window which was active on entering the read
1318 function. */
1319 DECLARE_INFO_COMMAND (ea_scroll_completions_window, _("Scroll the completions window"))
1321 WINDOW *compwin;
1322 int old_pagetop;
1324 compwin = get_internal_info_window (compwin_name);
1326 if (!compwin)
1327 compwin = calling_window;
1329 old_pagetop = compwin->pagetop;
1331 /* Let info_scroll_forward () do the work, and print any messages that
1332 need to be displayed. */
1333 info_scroll_forward (compwin, count, key);
1336 /* Function which gets called when an Info window is deleted while the
1337 echo area is active. WINDOW is the window which has just been deleted. */
1338 void
1339 echo_area_inform_of_deleted_window (window)
1340 WINDOW *window;
1342 /* If this is the calling_window, forget what we remembered about it. */
1343 if (window == calling_window)
1345 if (active_window != the_echo_area)
1346 remember_calling_window (active_window);
1347 else
1348 remember_calling_window (windows);
1351 /* If this window was the echo_area_completions_window, then notice that
1352 the window has been deleted. */
1353 if (window == echo_area_completions_window)
1354 echo_area_completions_window = (WINDOW *)NULL;
1357 /* **************************************************************** */
1358 /* */
1359 /* Pushing and Popping the Echo Area */
1360 /* */
1361 /* **************************************************************** */
1363 /* Push and Pop the echo area. */
1364 typedef struct {
1365 char *line;
1366 char *prompt;
1367 REFERENCE **comp_items;
1368 int point, beg, end;
1369 int must_complete;
1370 NODE node;
1371 WINDOW *compwin;
1372 } PUSHED_EA;
1374 static PUSHED_EA **pushed_echo_areas = (PUSHED_EA **)NULL;
1375 static int pushed_echo_areas_index = 0;
1376 static int pushed_echo_areas_slots = 0;
1378 /* Pushing the echo_area has a side effect of zeroing the completion_items. */
1379 static void
1380 push_echo_area ()
1382 PUSHED_EA *pushed;
1384 pushed = (PUSHED_EA *)xmalloc (sizeof (PUSHED_EA));
1385 pushed->line = xstrdup (input_line);
1386 pushed->prompt = input_line_prompt;
1387 pushed->point = input_line_point;
1388 pushed->beg = input_line_beg;
1389 pushed->end = input_line_end;
1390 pushed->node = input_line_node;
1391 pushed->comp_items = echo_area_completion_items;
1392 pushed->must_complete = echo_area_must_complete_p;
1393 pushed->compwin = echo_area_completions_window;
1395 add_pointer_to_array (pushed, pushed_echo_areas_index, pushed_echo_areas,
1396 pushed_echo_areas_slots, 4, PUSHED_EA *);
1398 echo_area_completion_items = (REFERENCE **)NULL;
1401 static void
1402 pop_echo_area ()
1404 PUSHED_EA *popped;
1406 popped = pushed_echo_areas[--pushed_echo_areas_index];
1408 strcpy (input_line, popped->line);
1409 free (popped->line);
1410 input_line_prompt = popped->prompt;
1411 input_line_point = popped->point;
1412 input_line_beg = popped->beg;
1413 input_line_end = popped->end;
1414 input_line_node = popped->node;
1415 echo_area_completion_items = popped->comp_items;
1416 echo_area_must_complete_p = popped->must_complete;
1417 echo_area_completions_window = popped->compwin;
1418 completions_must_be_rebuilt ();
1420 /* If the completion window no longer exists, forget about it. */
1421 if (echo_area_completions_window)
1423 register WINDOW *win;
1425 for (win = windows; win; win = win->next)
1426 if (echo_area_completions_window == win)
1427 break;
1429 /* If the window wasn't found, then it has already been deleted. */
1430 if (!win)
1431 echo_area_completions_window = (WINDOW *)NULL;
1434 free (popped);
1437 /* Returns non-zero if any of the prior stacked calls to read in the echo
1438 area produced a completions window. */
1439 static int
1440 echo_area_stack_contains_completions_p ()
1442 register int i;
1444 for (i = 0; i < pushed_echo_areas_index; i++)
1445 if (pushed_echo_areas[i]->compwin)
1446 return (1);
1448 return (0);
1451 /* **************************************************************** */
1452 /* */
1453 /* Error Messages While Reading in Echo Area */
1454 /* */
1455 /* **************************************************************** */
1457 #if defined (HAVE_SYS_TIME_H)
1458 # include <sys/time.h>
1459 # define HAVE_STRUCT_TIMEVAL
1460 #endif /* HAVE_SYS_TIME_H */
1462 static void
1463 pause_or_input ()
1465 #if defined (FD_SET)
1466 struct timeval timer;
1467 fd_set readfds;
1468 int ready;
1470 FD_ZERO (&readfds);
1471 FD_SET (fileno (stdin), &readfds);
1472 timer.tv_sec = 2;
1473 timer.tv_usec = 750;
1474 ready = select (fileno (stdin) + 1, &readfds, (fd_set *) NULL,
1475 (fd_set *) NULL, &timer);
1476 #endif /* FD_SET */
1479 /* Print MESSAGE right after the end of the current line, and wait
1480 for input or 2.75 seconds, whichever comes first. Then flush the
1481 informational message that was printed. */
1482 void
1483 inform_in_echo_area (message)
1484 char *message;
1486 register int i;
1487 char *text;
1489 text = xstrdup (message);
1490 for (i = 0; text[i] && text[i] != '\n'; i++);
1491 text[i] = '\0';
1493 echo_area_initialize_node ();
1494 sprintf (&input_line[input_line_end], "%s[%s]\n",
1495 echo_area_is_active ? " ": "", text);
1496 free (text);
1497 the_echo_area->point = input_line_point;
1498 display_update_one_window (the_echo_area);
1499 display_cursor_at_point (active_window);
1500 fflush (stdout);
1501 pause_or_input ();
1502 echo_area_initialize_node ();