Fix incomplete stack traces by gdb.
[dragonfly.git] / contrib / texinfo-4 / info / echo-area.c
blob31385c88a37672363b6e238decc51f5cc705e76d
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 $
4 Copyright (C) 1993, 1997, 1998, 1999, 2001, 2004 Free Software
5 Foundation, Inc.
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.
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.
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.
21 Written by Brian Fox (bfox@ai.mit.edu). */
23 #include "info.h"
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 */
33 /* Non-zero means that C-g was used to quit reading input. */
34 int info_aborted_echo_area = 0;
36 /* Non-zero means that the echo area is being used to read input. */
37 int echo_area_is_active = 0;
39 /* The address of the last command executed in the echo area. */
40 VFunction *ea_last_executed_command = (VFunction *)NULL;
42 /* Non-zero means that the last command executed while reading input
43 killed some text. */
44 int echo_area_last_command_was_kill = 0;
46 /* Variables which hold on to the current state of the input line. */
47 static char input_line[1 + EA_MAX_INPUT];
48 static char *input_line_prompt;
49 static int input_line_point;
50 static int input_line_beg;
51 static int input_line_end;
52 static NODE input_line_node = {
53 (char *)NULL, (char *)NULL, (char *)NULL, input_line,
54 EA_MAX_INPUT, 0, N_IsInternal
57 static void echo_area_initialize_node (void);
58 static void push_echo_area (void), pop_echo_area (void);
59 static int echo_area_stack_contains_completions_p (void);
61 static void ea_kill_text (int from, int to);
63 /* Non-zero means we force the user to complete. */
64 static int echo_area_must_complete_p = 0;
65 static int completions_window_p (WINDOW *window);
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. */
70 static WINDOW *echo_area_completions_window = (WINDOW *)NULL;
72 /* Variables which keep track of the window which was active prior to
73 entering the echo area. */
74 static WINDOW *calling_window = (WINDOW *)NULL;
75 static NODE *calling_window_node = (NODE *)NULL;
76 static long calling_window_point = 0;
77 static long calling_window_pagetop = 0;
79 /* Remember the node and pertinent variables of the calling window. */
80 static void
81 remember_calling_window (WINDOW *window)
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)))
88 calling_window = window;
89 calling_window_node = window->node;
90 calling_window_point = window->point;
91 calling_window_pagetop = window->pagetop;
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 (). */
97 static void
98 restore_calling_window (void)
100 register WINDOW *win, *compwin = (WINDOW *)NULL;
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)
106 if (completions_window_p (win))
107 compwin = win;
109 if (win == calling_window && win == compwin)
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;
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)
124 if ((compwin != windows || windows->next) &&
125 !echo_area_stack_contains_completions_p ())
127 WINDOW *next;
128 int pagetop = 0;
129 int start = 0;
130 int end = 0;
131 int amount = 0;
133 next = compwin->next;
134 if (next)
136 start = next->first_row;
137 end = start + next->height;
138 amount = - (compwin->height + 1);
139 pagetop = next->pagetop;
142 info_delete_window_internal (compwin);
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 */
151 if (next)
153 display_scroll_display (start, end, amount);
154 next->pagetop = pagetop;
155 display_update_display (windows);
161 /* Set up a new input line with PROMPT. */
162 static void
163 initialize_input_line (char *prompt)
165 input_line_prompt = prompt;
166 if (prompt)
167 strcpy (input_line, prompt);
168 else
169 input_line[0] = '\0';
171 input_line_beg = input_line_end = input_line_point = strlen (prompt);
174 static char *
175 echo_area_after_read (void)
177 char *return_value;
179 if (info_aborted_echo_area)
181 info_aborted_echo_area = 0;
182 return_value = (char *)NULL;
184 else
186 if (input_line_beg == input_line_end)
187 return_value = xstrdup ("");
188 else
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';
196 return (return_value);
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. */
203 char *
204 info_read_in_echo_area (WINDOW *window, char *prompt)
206 char *line;
208 /* If the echo area is already active, remember the current state. */
209 if (echo_area_is_active)
210 push_echo_area ();
212 /* Initialize our local variables. */
213 initialize_input_line (prompt);
215 /* Initialize the echo area for the first (but maybe not the last) time. */
216 echo_area_initialize_node ();
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);
222 /* Let the rest of Info know that the echo area is active. */
223 echo_area_is_active++;
224 active_window = the_echo_area;
226 /* Read characters in the echo area. */
227 info_read_and_dispatch ();
229 echo_area_is_active--;
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);
237 /* Get the value of the line. */
238 line = echo_area_after_read ();
240 /* If there is a previous loop waiting for us, restore it now. */
241 if (echo_area_is_active)
242 pop_echo_area ();
244 /* Return the results to the caller. */
245 return (line);
248 /* (re) Initialize the echo area node. */
249 static void
250 echo_area_initialize_node (void)
252 register int i;
254 for (i = input_line_end; (unsigned int) i < sizeof (input_line); i++)
255 input_line[i] = ' ';
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';
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. */
265 void
266 echo_area_prep_read (void)
268 if (the_echo_area->node != &input_line_node)
269 echo_area_initialize_node ();
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);
278 /* **************************************************************** */
279 /* */
280 /* Echo Area Movement Commands */
281 /* */
282 /* **************************************************************** */
284 DECLARE_INFO_COMMAND (ea_forward, _("Move forward a character"))
286 if (count < 0)
287 ea_backward (window, -count, key);
288 else
290 input_line_point += count;
291 if (input_line_point > input_line_end)
292 input_line_point = input_line_end;
296 DECLARE_INFO_COMMAND (ea_backward, _("Move backward a character"))
298 if (count < 0)
299 ea_forward (window, -count, key);
300 else
302 input_line_point -= count;
303 if (input_line_point < input_line_beg)
304 input_line_point = input_line_beg;
308 DECLARE_INFO_COMMAND (ea_beg_of_line, _("Move to the start of this line"))
310 input_line_point = input_line_beg;
313 DECLARE_INFO_COMMAND (ea_end_of_line, _("Move to the end of this line"))
315 input_line_point = input_line_end;
318 #define alphabetic(c) (islower (c) || isupper (c) || isdigit (c))
320 /* Move forward a word in the input line. */
321 DECLARE_INFO_COMMAND (ea_forward_word, _("Move forward a word"))
323 int c;
325 if (count < 0)
326 ea_backward_word (window, -count, key);
327 else
329 while (count--)
331 if (input_line_point == input_line_end)
332 return;
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];
338 if (!alphabetic (c))
340 while (++input_line_point < input_line_end)
342 c = input_line[input_line_point];
343 if (alphabetic (c))
344 break;
348 if (input_line_point == input_line_end)
349 return;
351 while (++input_line_point < input_line_end)
353 c = input_line[input_line_point];
354 if (!alphabetic (c))
355 break;
361 DECLARE_INFO_COMMAND (ea_backward_word, _("Move backward a word"))
363 int c;
365 if (count < 0)
366 ea_forward_word (window, -count, key);
367 else
369 while (count--)
371 if (input_line_point == input_line_beg)
372 return;
374 /* Like ea_forward_word (), except that we look at the
375 characters just before point. */
377 c = input_line[input_line_point - 1];
379 if (!alphabetic (c))
381 while ((--input_line_point) != input_line_beg)
383 c = input_line[input_line_point - 1];
384 if (alphabetic (c))
385 break;
389 while (input_line_point != input_line_beg)
391 c = input_line[input_line_point - 1];
392 if (!alphabetic (c))
393 break;
394 else
395 --input_line_point;
401 DECLARE_INFO_COMMAND (ea_delete, _("Delete the character under the cursor"))
403 register int i;
405 if (count < 0)
406 ea_rubout (window, -count, key);
407 else
409 if (input_line_point == input_line_end)
410 return;
412 if (info_explicit_arg || count > 1)
414 int orig_point;
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;
421 else
423 for (i = input_line_point; i < input_line_end; i++)
424 input_line[i] = input_line[i + 1];
426 input_line_end--;
431 DECLARE_INFO_COMMAND (ea_rubout, _("Delete the character behind the cursor"))
433 if (count < 0)
434 ea_delete (window, -count, key);
435 else
437 int start;
439 if (input_line_point == input_line_beg)
440 return;
442 start = input_line_point;
443 ea_backward (window, count, key);
445 if (info_explicit_arg || count > 1)
446 ea_kill_text (start, input_line_point);
447 else
448 ea_delete (window, count, key);
452 DECLARE_INFO_COMMAND (ea_abort, _("Cancel or quit operation"))
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)
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 ();
463 else
464 info_aborted_echo_area = 1;
467 DECLARE_INFO_COMMAND (ea_newline, _("Accept (or force completion of) this line"))
469 /* Stub does nothing. Simply here to see if it has been executed. */
472 DECLARE_INFO_COMMAND (ea_quoted_insert, _("Insert next character verbatim"))
474 unsigned char character;
476 character = info_get_another_input_char ();
477 ea_insert (window, count, character);
480 DECLARE_INFO_COMMAND (ea_insert, _("Insert this character"))
482 register int i;
484 if ((input_line_end + 1) == EA_MAX_INPUT)
486 terminal_ring_bell ();
487 return;
490 for (i = input_line_end + 1; i != input_line_point; i--)
491 input_line[i] = input_line[i - 1];
493 input_line[input_line_point] = key;
494 input_line_point++;
495 input_line_end++;
498 DECLARE_INFO_COMMAND (ea_tab_insert, _("Insert a TAB character"))
500 ea_insert (window, count, '\t');
503 /* Transpose the characters at point. If point is at the end of the line,
504 then transpose the characters before point. */
505 DECLARE_INFO_COMMAND (ea_transpose_chars, _("Transpose characters at point"))
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;
512 while (count)
514 int t;
515 if (input_line_point == input_line_end)
517 t = input_line[input_line_point - 1];
519 input_line[input_line_point - 1] = input_line[input_line_point - 2];
520 input_line[input_line_point - 2] = t;
522 else
524 t = input_line[input_line_point];
526 input_line[input_line_point] = input_line[input_line_point - 1];
527 input_line[input_line_point - 1] = t;
529 if (count < 0 && input_line_point != input_line_beg)
530 input_line_point--;
531 else
532 input_line_point++;
535 if (count < 0)
536 count++;
537 else
538 count--;
542 /* **************************************************************** */
543 /* */
544 /* Echo Area Killing and Yanking */
545 /* */
546 /* **************************************************************** */
548 static char **kill_ring = (char **)NULL;
549 static int kill_ring_index = 0; /* Number of kills appearing in KILL_RING. */
550 static int kill_ring_slots = 0; /* Number of slots allocated to KILL_RING. */
551 static int kill_ring_loc = 0; /* Location of current yank pointer. */
553 /* The largest number of kills that we remember at one time. */
554 static int max_retained_kills = 15;
556 DECLARE_INFO_COMMAND (ea_yank, _("Yank back the contents of the last kill"))
558 register int i;
559 register char *text;
561 if (!kill_ring_index)
563 inform_in_echo_area ((char *) _("Kill ring is empty"));
564 return;
567 text = kill_ring[kill_ring_loc];
569 for (i = 0; text[i]; i++)
570 ea_insert (window, 1, text[i]);
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. */
576 DECLARE_INFO_COMMAND (ea_yank_pop, _("Yank back a previous kill"))
578 register int len;
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;
585 len = strlen (kill_ring[kill_ring_loc]);
587 /* Delete the last yanked item from the line. */
589 register int i, counter;
591 counter = input_line_end - input_line_point;
593 for (i = input_line_point - len; counter; i++, counter--)
594 input_line[i] = input_line[i + len];
596 input_line_end -= len;
597 input_line_point -= len;
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;
605 ea_yank (window, count, key);
608 /* Delete the text from point to end of line. */
609 DECLARE_INFO_COMMAND (ea_kill_line, _("Kill to the end of the line"))
611 if (count < 0)
613 ea_kill_text (input_line_point, input_line_beg);
614 input_line_point = input_line_beg;
616 else
617 ea_kill_text (input_line_point, input_line_end);
620 /* Delete the text from point to beg of line. */
621 DECLARE_INFO_COMMAND (ea_backward_kill_line,
622 _("Kill to the beginning of the line"))
624 if (count < 0)
625 ea_kill_text (input_line_point, input_line_end);
626 else
628 ea_kill_text (input_line_point, input_line_beg);
629 input_line_point = input_line_beg;
633 /* Delete from point to the end of the current word. */
634 DECLARE_INFO_COMMAND (ea_kill_word, _("Kill the word following the cursor"))
636 int orig_point = input_line_point;
638 if (count < 0)
639 ea_backward_kill_word (window, -count, key);
640 else
642 ea_forward_word (window, count, key);
644 if (input_line_point != orig_point)
645 ea_kill_text (orig_point, input_line_point);
647 input_line_point = orig_point;
651 /* Delete from point to the start of the current word. */
652 DECLARE_INFO_COMMAND (ea_backward_kill_word,
653 _("Kill the word preceding the cursor"))
655 int orig_point = input_line_point;
657 if (count < 0)
658 ea_kill_word (window, -count, key);
659 else
661 ea_backward_word (window, count, key);
663 if (input_line_point != orig_point)
664 ea_kill_text (orig_point, input_line_point);
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. */
673 static void
674 ea_kill_text (int from, int 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 (void), completions_must_be_rebuilt (void);
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 *window)
790 int result = 0;
792 if (internal_info_node_p (window->node) &&
793 (strcmp (window->node->nodename, compwin_name) == 0))
794 result = 1;
796 return (result);
799 /* Workhorse for completion readers. If FORCE is non-zero, the user cannot
800 exit unless the line read completes, or is empty. */
801 char *
802 info_read_completing_internal (WINDOW *window, char *prompt,
803 REFERENCE **completions, int force)
805 char *line;
807 /* If the echo area is already active, remember the current state. */
808 if (echo_area_is_active)
809 push_echo_area ();
811 echo_area_must_complete_p = force;
813 /* Initialize our local variables. */
814 initialize_input_line (prompt);
816 /* Initialize the echo area for the first (but maybe not the last) time. */
817 echo_area_initialize_node ();
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);
823 /* Save away the list of items to complete over. */
824 echo_area_completion_items = completions;
825 completions_must_be_rebuilt ();
827 active_window = the_echo_area;
828 echo_area_is_active++;
830 /* Read characters in the echo area. */
831 while (1)
833 info_read_and_dispatch ();
835 line = echo_area_after_read ();
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)
841 register int i;
843 build_completions ();
845 /* If there is only one completion, then make the line be that
846 completion. */
847 if (completions_found_index == 1)
849 free (line);
850 line = xstrdup (completions_found[0]->label);
851 break;
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)
859 free (line);
860 line = xstrdup (completions_found[i]->label);
861 break;
864 /* If no match, go back and try again. */
865 if (i == completions_found_index)
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;
874 break;
876 echo_area_is_active--;
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);
884 echo_area_completion_items = (REFERENCE **)NULL;
885 completions_must_be_rebuilt ();
887 /* If there is a previous loop waiting for us, restore it now. */
888 if (echo_area_is_active)
889 pop_echo_area ();
891 return (line);
894 /* Read a line in the echo area with completion over COMPLETIONS. */
895 char *
896 info_read_completing_in_echo_area (WINDOW *window,
897 char *prompt, REFERENCE **completions)
899 return (info_read_completing_internal (window, prompt, completions, 1));
902 /* Read a line in the echo area allowing completion over COMPLETIONS, but
903 not requiring it. */
904 char *
905 info_read_maybe_completing (WINDOW *window,
906 char *prompt, REFERENCE **completions)
908 return (info_read_completing_internal (window, prompt, completions, 0));
911 DECLARE_INFO_COMMAND (ea_possible_completions, _("List possible completions"))
913 if (!echo_area_completion_items)
915 ea_insert (window, count, key);
916 return;
919 build_completions ();
921 if (!completions_found_index)
923 terminal_ring_bell ();
924 inform_in_echo_area ((char *) _("No completions"));
926 else if ((completions_found_index == 1) && (key != '?'))
928 inform_in_echo_area ((char *) _("Sole completion"));
930 else
932 register int i, l;
933 int limit, iterations, max_label = 0;
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);
942 /* Find the maximum length of a label. */
943 for (i = 0; i < completions_found_index; i++)
945 int len = strlen (completions_found[i]->label);
946 if (len > max_label)
947 max_label = len;
950 max_label += 4;
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--;
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;
962 /* How many iterations of the printing loop? */
963 iterations = (completions_found_index + (limit - 1)) / limit;
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;
970 /* Print the sorted items, up-and-down alphabetically. */
971 for (i = 0; i < iterations; i++)
973 register int j;
975 for (j = 0, l = i; j < limit; j++)
977 if (l >= completions_found_index)
978 break;
979 else
981 char *label;
982 int printed_length, k;
984 label = completions_found[l]->label;
985 printed_length = strlen (label);
986 printf_to_message_buffer ("%s", label, NULL, NULL);
988 if (j + 1 < limit)
990 for (k = 0; k < max_label - printed_length; k++)
991 printf_to_message_buffer (" ", NULL, NULL, NULL);
994 l += iterations;
996 printf_to_message_buffer ("\n", NULL, NULL, NULL);
999 /* Make a new node to hold onto possible completions. Don't destroy
1000 dangling pointers. */
1002 NODE *temp;
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;
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. */
1016 WINDOW *compwin;
1018 compwin = get_internal_info_window (compwin_name);
1020 if (!compwin)
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)
1027 int start, pagetop;
1028 #ifdef SPLIT_BEFORE_ACTIVE
1029 int end;
1030 #endif
1032 active_window = calling_window;
1034 /* Perhaps we can scroll this window on redisplay. */
1035 start = calling_window->first_row;
1036 pagetop = calling_window->pagetop;
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)));
1044 window_adjust_pagetop (calling_window);
1045 remember_calling_window (calling_window);
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)
1052 end = start + calling_window->height;
1053 display_scroll_display
1054 (start, end, calling_window->prev->height + 1);
1056 #else /* !SPLIT_BEFORE_ACTIVE */
1057 /* If the pagetop has changed, set the new pagetop here. */
1058 if (pagetop != calling_window->pagetop)
1060 int newtop = calling_window->pagetop;
1061 calling_window->pagetop = pagetop;
1062 set_window_pagetop (calling_window, newtop);
1064 #endif /* !SPLIT_BEFORE_ACTIVE */
1066 echo_area_completions_window = compwin;
1067 remember_window_and_node (compwin, compwin->node);
1069 else
1070 compwin = calling_window;
1073 if (compwin->node != possible_completions_output_node)
1075 window_set_node_of_window
1076 (compwin, possible_completions_output_node);
1077 remember_window_and_node (compwin, compwin->node);
1080 display_update_display (windows);
1085 DECLARE_INFO_COMMAND (ea_complete, _("Insert completion"))
1087 if (!echo_area_completion_items)
1089 ea_insert (window, count, key);
1090 return;
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)
1097 ea_insert (window, count, key);
1098 return;
1101 if (ea_last_executed_command == (VFunction *) ea_complete)
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)
1109 register int i, offset;
1111 offset = input_line_end - input_line_beg;
1113 for (i = 0; i < completions_found_index; i++)
1114 if (completions_found[i]->label[offset] == ' ')
1115 break;
1117 if (completions_found[i])
1118 ea_insert (window, 1, ' ');
1119 else
1121 ea_possible_completions (window, count, key);
1122 return;
1125 else
1127 ea_possible_completions (window, count, key);
1128 return;
1132 input_line_point = input_line_end;
1133 build_completions ();
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
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]);
1148 /* Utility REFERENCE used to store possible LCD. */
1149 static REFERENCE LCD_reference = {
1150 (char *)NULL, (char *)NULL, (char *)NULL, 0, 0, 0
1153 static void remove_completion_duplicates (void);
1155 /* Variables which remember the state of the most recent call
1156 to build_completions (). */
1157 static char *last_completion_request = (char *)NULL;
1158 static REFERENCE **last_completion_items = (REFERENCE **)NULL;
1160 /* How to tell the completion builder to reset internal state. */
1161 static void
1162 completions_must_be_rebuilt (void)
1164 maybe_free (last_completion_request);
1165 last_completion_request = (char *)NULL;
1166 last_completion_items = (REFERENCE **)NULL;
1169 /* Build a list of possible completions from echo_area_completion_items,
1170 and the contents of input_line. */
1171 static void
1172 build_completions (void)
1174 register int i, len;
1175 register REFERENCE *entry;
1176 char *request;
1177 int informed_of_lengthy_job = 0;
1179 /* If there are no items to complete over, exit immediately. */
1180 if (!echo_area_completion_items)
1182 completions_found_index = 0;
1183 LCD_completion = (REFERENCE *)NULL;
1184 return;
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';
1194 if (last_completion_request && last_completion_items &&
1195 last_completion_items == echo_area_completion_items &&
1196 (strcmp (last_completion_request, request) == 0))
1198 free (request);
1199 return;
1202 maybe_free (last_completion_request);
1203 last_completion_request = request;
1204 last_completion_items = echo_area_completion_items;
1206 /* Always start at the beginning of the list. */
1207 completions_found_index = 0;
1208 LCD_completion = (REFERENCE *)NULL;
1210 for (i = 0; (entry = echo_area_completion_items[i]); i++)
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 *);
1217 if (!informed_of_lengthy_job && completions_found_index > 100)
1219 informed_of_lengthy_job = 1;
1220 window_message_in_echo_area ((char *) _("Building completions..."),
1221 NULL, NULL);
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 /* 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)
1270 int req_len = strlen (request);
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;
1279 strncpy (LCD_reference.label, completions_found[i]->label, shortest);
1280 LCD_reference.label[shortest] = '\0';
1281 LCD_completion = &LCD_reference;
1284 if (informed_of_lengthy_job)
1285 echo_area_initialize_node ();
1288 /* Function called by qsort. */
1289 static int
1290 compare_references (const void *entry1, const void *entry2)
1292 REFERENCE **e1 = (REFERENCE **) entry1;
1293 REFERENCE **e2 = (REFERENCE **) entry2;
1295 return (strcasecmp ((*e1)->label, (*e2)->label));
1298 /* Prune duplicate entries from COMPLETIONS_FOUND. */
1299 static void
1300 remove_completion_duplicates (void)
1302 register int i, j;
1303 REFERENCE **temp;
1304 int newlen;
1306 if (!completions_found_index)
1307 return;
1309 /* Sort the items. */
1310 qsort (completions_found, completions_found_index, sizeof (REFERENCE *),
1311 compare_references);
1313 for (i = 0, newlen = 1; i < completions_found_index - 1; i++)
1315 if (strcmp (completions_found[i]->label,
1316 completions_found[i + 1]->label) == 0)
1317 completions_found[i] = (REFERENCE *)NULL;
1318 else
1319 newlen++;
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];
1329 for (i = 0; i < newlen; i++)
1330 completions_found[i] = temp[i];
1332 completions_found[i] = (REFERENCE *)NULL;
1333 completions_found_index = newlen;
1334 free (temp);
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. */
1340 DECLARE_INFO_COMMAND (ea_scroll_completions_window, _("Scroll the completions window"))
1342 WINDOW *compwin;
1343 int old_pagetop;
1345 compwin = get_internal_info_window (compwin_name);
1347 if (!compwin)
1348 compwin = calling_window;
1350 old_pagetop = compwin->pagetop;
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);
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. */
1359 void
1360 echo_area_inform_of_deleted_window (WINDOW *window)
1362 /* If this is the calling_window, forget what we remembered about it. */
1363 if (window == calling_window)
1365 if (active_window != the_echo_area)
1366 remember_calling_window (active_window);
1367 else
1368 remember_calling_window (windows);
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;
1377 /* **************************************************************** */
1378 /* */
1379 /* Pushing and Popping the Echo Area */
1380 /* */
1381 /* **************************************************************** */
1383 /* Push and Pop the echo area. */
1384 typedef 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;
1394 static PUSHED_EA **pushed_echo_areas = (PUSHED_EA **)NULL;
1395 static int pushed_echo_areas_index = 0;
1396 static int pushed_echo_areas_slots = 0;
1398 /* Pushing the echo_area has a side effect of zeroing the completion_items. */
1399 static void
1400 push_echo_area (void)
1402 PUSHED_EA *pushed;
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;
1415 add_pointer_to_array (pushed, pushed_echo_areas_index, pushed_echo_areas,
1416 pushed_echo_areas_slots, 4, PUSHED_EA *);
1418 echo_area_completion_items = (REFERENCE **)NULL;
1421 static void
1422 pop_echo_area (void)
1424 PUSHED_EA *popped;
1426 popped = pushed_echo_areas[--pushed_echo_areas_index];
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 ();
1440 /* If the completion window no longer exists, forget about it. */
1441 if (echo_area_completions_window)
1443 register WINDOW *win;
1445 for (win = windows; win; win = win->next)
1446 if (echo_area_completions_window == win)
1447 break;
1449 /* If the window wasn't found, then it has already been deleted. */
1450 if (!win)
1451 echo_area_completions_window = (WINDOW *)NULL;
1454 free (popped);
1457 /* Returns non-zero if any of the prior stacked calls to read in the echo
1458 area produced a completions window. */
1459 static int
1460 echo_area_stack_contains_completions_p (void)
1462 register int i;
1464 for (i = 0; i < pushed_echo_areas_index; i++)
1465 if (pushed_echo_areas[i]->compwin)
1466 return (1);
1468 return (0);
1471 /* **************************************************************** */
1472 /* */
1473 /* Error Messages While Reading in Echo Area */
1474 /* */
1475 /* **************************************************************** */
1477 #if defined (HAVE_SYS_TIME_H)
1478 # include <sys/time.h>
1479 # define HAVE_STRUCT_TIMEVAL
1480 #endif /* HAVE_SYS_TIME_H */
1482 static void
1483 pause_or_input (void)
1485 #ifdef FD_SET
1486 struct timeval timer;
1487 fd_set readfds;
1488 int ready;
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 */
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. */
1502 void
1503 inform_in_echo_area (const char *message)
1505 int i;
1506 char *text;
1507 int avail = EA_MAX_INPUT + 1 - input_line_end;
1509 text = xstrdup (message);
1510 for (i = 0; text[i] && text[i] != '\n' && i < avail; i++)
1512 text[i] = 0;
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 ();