No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / texinfo / info / echo-area.c
blob6b151682a080b5a9dc1c5827c15b60cb9d967b4d
1 /* $NetBSD: echo-area.c,v 1.3 2008/09/02 08:00:24 christos Exp $ */
3 /* echo-area.c -- how to read a line in the echo area.
4 Id: echo-area.c,v 1.7 2004/12/14 00:15:36 karl Exp
6 Copyright (C) 1993, 1997, 1998, 1999, 2001, 2004 Free Software
7 Foundation, Inc.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 Written by Brian Fox (bfox@ai.mit.edu). */
25 #include "info.h"
27 #if defined (FD_SET)
28 # if defined (hpux)
29 # define fd_set_cast(x) (int *)(x)
30 # else
31 # define fd_set_cast(x) (fd_set *)(x)
32 # endif /* !hpux */
33 #endif /* FD_SET */
35 /* Non-zero means that C-g was used to quit reading input. */
36 int info_aborted_echo_area = 0;
38 /* Non-zero means that the echo area is being used to read input. */
39 int echo_area_is_active = 0;
41 /* The address of the last command executed in the echo area. */
42 VFunction *ea_last_executed_command = (VFunction *)NULL;
44 /* Non-zero means that the last command executed while reading input
45 killed some text. */
46 int echo_area_last_command_was_kill = 0;
48 /* Variables which hold on to the current state of the input line. */
49 static char input_line[1 + EA_MAX_INPUT];
50 static char *input_line_prompt;
51 static int input_line_point;
52 static int input_line_beg;
53 static int input_line_end;
54 static NODE input_line_node = {
55 (char *)NULL, (char *)NULL, (char *)NULL, input_line,
56 EA_MAX_INPUT, 0, N_IsInternal
59 static void echo_area_initialize_node (void);
60 static void push_echo_area (void), pop_echo_area (void);
61 static int echo_area_stack_contains_completions_p (void);
63 static void ea_kill_text (int from, int to);
65 /* Non-zero means we force the user to complete. */
66 static int echo_area_must_complete_p = 0;
67 static int completions_window_p (WINDOW *window);
69 /* If non-null, this is a window which was specifically created to display
70 possible completions output. We remember it so we can delete it when
71 appropriate. */
72 static WINDOW *echo_area_completions_window = (WINDOW *)NULL;
74 /* Variables which keep track of the window which was active prior to
75 entering the echo area. */
76 static WINDOW *calling_window = (WINDOW *)NULL;
77 static NODE *calling_window_node = (NODE *)NULL;
78 static long calling_window_point = 0;
79 static long calling_window_pagetop = 0;
81 /* Remember the node and pertinent variables of the calling window. */
82 static void
83 remember_calling_window (WINDOW *window)
85 /* Only do this if the calling window is not the completions window, or,
86 if it is the completions window and there is no other window. */
87 if (!completions_window_p (window) ||
88 ((window == windows) && !(window->next)))
90 calling_window = window;
91 calling_window_node = window->node;
92 calling_window_point = window->point;
93 calling_window_pagetop = window->pagetop;
97 /* Restore the caller's window so that it shows the node that it was showing
98 on entry to info_read_xxx_echo_area (). */
99 static void
100 restore_calling_window (void)
102 register WINDOW *win, *compwin = (WINDOW *)NULL;
104 /* If the calling window is still visible, and it is the window that
105 we used for completions output, then restore the calling window. */
106 for (win = windows; win; win = win->next)
108 if (completions_window_p (win))
109 compwin = win;
111 if (win == calling_window && win == compwin)
113 window_set_node_of_window (calling_window, calling_window_node);
114 calling_window->point = calling_window_point;
115 calling_window->pagetop = calling_window_pagetop;
116 compwin = (WINDOW *)NULL;
117 break;
121 /* Delete the completions window if it is still present, it isn't the
122 last window on the screen, and there aren't any prior echo area reads
123 pending which created a completions window. */
124 if (compwin)
126 if ((compwin != windows || windows->next) &&
127 !echo_area_stack_contains_completions_p ())
129 WINDOW *next;
130 int pagetop = 0;
131 int start = 0;
132 int end = 0;
133 int amount = 0;
135 next = compwin->next;
136 if (next)
138 start = next->first_row;
139 end = start + next->height;
140 amount = - (compwin->height + 1);
141 pagetop = next->pagetop;
144 info_delete_window_internal (compwin);
146 /* This is not necessary because info_delete_window_internal ()
147 calls echo_area_inform_of_deleted_window (), which does the
148 right thing. */
149 #if defined (UNNECESSARY)
150 echo_area_completions_window = (WINDOW *)NULL;
151 #endif /* UNNECESSARY */
153 if (next)
155 display_scroll_display (start, end, amount);
156 next->pagetop = pagetop;
157 display_update_display (windows);
163 /* Set up a new input line with PROMPT. */
164 static void
165 initialize_input_line (char *prompt)
167 input_line_prompt = prompt;
168 if (prompt)
169 strcpy (input_line, prompt);
170 else
171 input_line[0] = '\0';
173 input_line_beg = input_line_end = input_line_point = strlen (prompt);
176 static char *
177 echo_area_after_read (void)
179 char *return_value;
181 if (info_aborted_echo_area)
183 info_aborted_echo_area = 0;
184 return_value = (char *)NULL;
186 else
188 if (input_line_beg == input_line_end)
189 return_value = xstrdup ("");
190 else
192 int line_len = input_line_end - input_line_beg;
193 return_value = (char *) xmalloc (1 + line_len);
194 strncpy (return_value, &input_line[input_line_beg], line_len);
195 return_value[line_len] = '\0';
198 return (return_value);
201 /* Read a line of text in the echo area. Return a malloc ()'ed string,
202 or NULL if the user aborted out of this read. WINDOW is the currently
203 active window, so that we can restore it when we need to. PROMPT, if
204 non-null, is a prompt to print before reading the line. */
205 char *
206 info_read_in_echo_area (WINDOW *window, char *prompt)
208 char *line;
210 /* If the echo area is already active, remember the current state. */
211 if (echo_area_is_active)
212 push_echo_area ();
214 /* Initialize our local variables. */
215 initialize_input_line (prompt);
217 /* Initialize the echo area for the first (but maybe not the last) time. */
218 echo_area_initialize_node ();
220 /* Save away the original node of this window, and the window itself,
221 so echo area commands can temporarily use this window. */
222 remember_calling_window (window);
224 /* Let the rest of Info know that the echo area is active. */
225 echo_area_is_active++;
226 active_window = the_echo_area;
228 /* Read characters in the echo area. */
229 info_read_and_dispatch ();
231 echo_area_is_active--;
233 /* Restore the original active window and show point in it. */
234 active_window = calling_window;
235 restore_calling_window ();
236 display_cursor_at_point (active_window);
237 fflush (stdout);
239 /* Get the value of the line. */
240 line = echo_area_after_read ();
242 /* If there is a previous loop waiting for us, restore it now. */
243 if (echo_area_is_active)
244 pop_echo_area ();
246 /* Return the results to the caller. */
247 return (line);
250 /* (re) Initialize the echo area node. */
251 static void
252 echo_area_initialize_node (void)
254 register int i;
256 for (i = input_line_end; (unsigned int) i < sizeof (input_line); i++)
257 input_line[i] = ' ';
259 input_line[i - 1] = '\n';
260 window_set_node_of_window (the_echo_area, &input_line_node);
261 input_line[input_line_end] = '\n';
264 /* Prepare to read characters in the echo area. This can initialize the
265 echo area node, but its primary purpose is to side effect the input
266 line buffer contents. */
267 void
268 echo_area_prep_read (void)
270 if (the_echo_area->node != &input_line_node)
271 echo_area_initialize_node ();
273 the_echo_area->point = input_line_point;
274 input_line[input_line_end] = '\n';
275 display_update_one_window (the_echo_area);
276 display_cursor_at_point (active_window);
280 /* **************************************************************** */
281 /* */
282 /* Echo Area Movement Commands */
283 /* */
284 /* **************************************************************** */
286 DECLARE_INFO_COMMAND (ea_forward, _("Move forward a character"))
288 if (count < 0)
289 ea_backward (window, -count, key);
290 else
292 input_line_point += count;
293 if (input_line_point > input_line_end)
294 input_line_point = input_line_end;
298 DECLARE_INFO_COMMAND (ea_backward, _("Move backward a character"))
300 if (count < 0)
301 ea_forward (window, -count, key);
302 else
304 input_line_point -= count;
305 if (input_line_point < input_line_beg)
306 input_line_point = input_line_beg;
310 DECLARE_INFO_COMMAND (ea_beg_of_line, _("Move to the start of this line"))
312 input_line_point = input_line_beg;
315 DECLARE_INFO_COMMAND (ea_end_of_line, _("Move to the end of this line"))
317 input_line_point = input_line_end;
320 #define alphabetic(c) (islower (c) || isupper (c) || isdigit (c))
322 /* Move forward a word in the input line. */
323 DECLARE_INFO_COMMAND (ea_forward_word, _("Move forward a word"))
325 int c;
327 if (count < 0)
328 ea_backward_word (window, -count, key);
329 else
331 while (count--)
333 if (input_line_point == input_line_end)
334 return;
336 /* If we are not in a word, move forward until we are in one.
337 Then, move forward until we hit a non-alphabetic character. */
338 c = input_line[input_line_point];
340 if (!alphabetic (c))
342 while (++input_line_point < input_line_end)
344 c = input_line[input_line_point];
345 if (alphabetic (c))
346 break;
350 if (input_line_point == input_line_end)
351 return;
353 while (++input_line_point < input_line_end)
355 c = input_line[input_line_point];
356 if (!alphabetic (c))
357 break;
363 DECLARE_INFO_COMMAND (ea_backward_word, _("Move backward a word"))
365 int c;
367 if (count < 0)
368 ea_forward_word (window, -count, key);
369 else
371 while (count--)
373 if (input_line_point == input_line_beg)
374 return;
376 /* Like ea_forward_word (), except that we look at the
377 characters just before point. */
379 c = input_line[input_line_point - 1];
381 if (!alphabetic (c))
383 while ((--input_line_point) != input_line_beg)
385 c = input_line[input_line_point - 1];
386 if (alphabetic (c))
387 break;
391 while (input_line_point != input_line_beg)
393 c = input_line[input_line_point - 1];
394 if (!alphabetic (c))
395 break;
396 else
397 --input_line_point;
403 DECLARE_INFO_COMMAND (ea_delete, _("Delete the character under the cursor"))
405 register int i;
407 if (count < 0)
408 ea_rubout (window, -count, key);
409 else
411 if (input_line_point == input_line_end)
412 return;
414 if (info_explicit_arg || count > 1)
416 int orig_point;
418 orig_point = input_line_point;
419 ea_forward (window, count, key);
420 ea_kill_text (orig_point, input_line_point);
421 input_line_point = orig_point;
423 else
425 for (i = input_line_point; i < input_line_end; i++)
426 input_line[i] = input_line[i + 1];
428 input_line_end--;
433 DECLARE_INFO_COMMAND (ea_rubout, _("Delete the character behind the cursor"))
435 if (count < 0)
436 ea_delete (window, -count, key);
437 else
439 int start;
441 if (input_line_point == input_line_beg)
442 return;
444 start = input_line_point;
445 ea_backward (window, count, key);
447 if (info_explicit_arg || count > 1)
448 ea_kill_text (start, input_line_point);
449 else
450 ea_delete (window, count, key);
454 DECLARE_INFO_COMMAND (ea_abort, _("Cancel or quit operation"))
456 /* If any text, just discard it, and restore the calling window's node.
457 If no text, quit. */
458 if (input_line_end != input_line_beg)
460 terminal_ring_bell ();
461 input_line_end = input_line_point = input_line_beg;
462 if (calling_window->node != calling_window_node)
463 restore_calling_window ();
465 else
466 info_aborted_echo_area = 1;
469 DECLARE_INFO_COMMAND (ea_newline, _("Accept (or force completion of) this line"))
471 /* Stub does nothing. Simply here to see if it has been executed. */
474 DECLARE_INFO_COMMAND (ea_quoted_insert, _("Insert next character verbatim"))
476 unsigned char character;
478 character = info_get_another_input_char ();
479 ea_insert (window, count, character);
482 DECLARE_INFO_COMMAND (ea_insert, _("Insert this character"))
484 register int i;
486 if ((input_line_end + 1) == EA_MAX_INPUT)
488 terminal_ring_bell ();
489 return;
492 for (i = input_line_end + 1; i != input_line_point; i--)
493 input_line[i] = input_line[i - 1];
495 input_line[input_line_point] = key;
496 input_line_point++;
497 input_line_end++;
500 DECLARE_INFO_COMMAND (ea_tab_insert, _("Insert a TAB character"))
502 ea_insert (window, count, '\t');
505 /* Transpose the characters at point. If point is at the end of the line,
506 then transpose the characters before point. */
507 DECLARE_INFO_COMMAND (ea_transpose_chars, _("Transpose characters at point"))
509 /* Handle conditions that would make it impossible to transpose
510 characters. */
511 if (!count || !input_line_point || (input_line_end - input_line_beg) < 2)
512 return;
514 while (count)
516 int t;
517 if (input_line_point == input_line_end)
519 t = input_line[input_line_point - 1];
521 input_line[input_line_point - 1] = input_line[input_line_point - 2];
522 input_line[input_line_point - 2] = t;
524 else
526 t = input_line[input_line_point];
528 input_line[input_line_point] = input_line[input_line_point - 1];
529 input_line[input_line_point - 1] = t;
531 if (count < 0 && input_line_point != input_line_beg)
532 input_line_point--;
533 else
534 input_line_point++;
537 if (count < 0)
538 count++;
539 else
540 count--;
544 /* **************************************************************** */
545 /* */
546 /* Echo Area Killing and Yanking */
547 /* */
548 /* **************************************************************** */
550 static char **kill_ring = (char **)NULL;
551 static int kill_ring_index = 0; /* Number of kills appearing in KILL_RING. */
552 static int kill_ring_slots = 0; /* Number of slots allocated to KILL_RING. */
553 static int kill_ring_loc = 0; /* Location of current yank pointer. */
555 /* The largest number of kills that we remember at one time. */
556 static int max_retained_kills = 15;
558 DECLARE_INFO_COMMAND (ea_yank, _("Yank back the contents of the last kill"))
560 register int i;
561 register char *text;
563 if (!kill_ring_index)
565 inform_in_echo_area ((char *) _("Kill ring is empty"));
566 return;
569 text = kill_ring[kill_ring_loc];
571 for (i = 0; text[i]; i++)
572 ea_insert (window, 1, text[i]);
575 /* If the last command was yank, or yank_pop, and the text just before
576 point is identical to the current kill item, then delete that text
577 from the line, rotate the index down, and yank back some other text. */
578 DECLARE_INFO_COMMAND (ea_yank_pop, _("Yank back a previous kill"))
580 register int len;
582 if (((ea_last_executed_command != (VFunction *) ea_yank) &&
583 (ea_last_executed_command != (VFunction *) ea_yank_pop)) ||
584 (kill_ring_index == 0))
585 return;
587 len = strlen (kill_ring[kill_ring_loc]);
589 /* Delete the last yanked item from the line. */
591 register int i, counter;
593 counter = input_line_end - input_line_point;
595 for (i = input_line_point - len; counter; i++, counter--)
596 input_line[i] = input_line[i + len];
598 input_line_end -= len;
599 input_line_point -= len;
602 /* Get a previous kill, and yank that. */
603 kill_ring_loc--;
604 if (kill_ring_loc < 0)
605 kill_ring_loc = kill_ring_index - 1;
607 ea_yank (window, count, key);
610 /* Delete the text from point to end of line. */
611 DECLARE_INFO_COMMAND (ea_kill_line, _("Kill to the end of the line"))
613 if (count < 0)
615 ea_kill_text (input_line_point, input_line_beg);
616 input_line_point = input_line_beg;
618 else
619 ea_kill_text (input_line_point, input_line_end);
622 /* Delete the text from point to beg of line. */
623 DECLARE_INFO_COMMAND (ea_backward_kill_line,
624 _("Kill to the beginning of the line"))
626 if (count < 0)
627 ea_kill_text (input_line_point, input_line_end);
628 else
630 ea_kill_text (input_line_point, input_line_beg);
631 input_line_point = input_line_beg;
635 /* Delete from point to the end of the current word. */
636 DECLARE_INFO_COMMAND (ea_kill_word, _("Kill the word following the cursor"))
638 int orig_point = input_line_point;
640 if (count < 0)
641 ea_backward_kill_word (window, -count, key);
642 else
644 ea_forward_word (window, count, key);
646 if (input_line_point != orig_point)
647 ea_kill_text (orig_point, input_line_point);
649 input_line_point = orig_point;
653 /* Delete from point to the start of the current word. */
654 DECLARE_INFO_COMMAND (ea_backward_kill_word,
655 _("Kill the word preceding the cursor"))
657 int orig_point = input_line_point;
659 if (count < 0)
660 ea_kill_word (window, -count, key);
661 else
663 ea_backward_word (window, count, key);
665 if (input_line_point != orig_point)
666 ea_kill_text (orig_point, input_line_point);
670 /* The way to kill something. This appends or prepends to the last
671 kill, if the last command was a kill command. If FROM is less
672 than TO, then the killed text is appended to the most recent kill,
673 otherwise it is prepended. If the last command was not a kill command,
674 then a new slot is made for this kill. */
675 static void
676 ea_kill_text (int from, int to)
678 register int i, counter, distance;
679 int killing_backwards, slot;
680 char *killed_text;
682 killing_backwards = (from > to);
684 /* If killing backwards, reverse the values of FROM and TO. */
685 if (killing_backwards)
687 int temp = from;
688 from = to;
689 to = temp;
692 /* Remember the text that we are about to delete. */
693 distance = to - from;
694 killed_text = (char *)xmalloc (1 + distance);
695 strncpy (killed_text, &input_line[from], distance);
696 killed_text[distance] = '\0';
698 /* Actually delete the text from the line. */
699 counter = input_line_end - to;
701 for (i = from; counter; i++, counter--)
702 input_line[i] = input_line[i + distance];
704 input_line_end -= distance;
706 /* If the last command was a kill, append or prepend the killed text to
707 the last command's killed text. */
708 if (echo_area_last_command_was_kill)
710 char *old, *new;
712 slot = kill_ring_loc;
713 old = kill_ring[slot];
714 new = (char *)xmalloc (1 + strlen (old) + strlen (killed_text));
716 if (killing_backwards)
718 /* Prepend TEXT to current kill. */
719 strcpy (new, killed_text);
720 strcat (new, old);
722 else
724 /* Append TEXT to current kill. */
725 strcpy (new, old);
726 strcat (new, killed_text);
729 free (old);
730 free (killed_text);
731 kill_ring[slot] = new;
733 else
735 /* Try to store the kill in a new slot, unless that would cause there
736 to be too many remembered kills. */
737 slot = kill_ring_index;
739 if (slot == max_retained_kills)
740 slot = 0;
742 if (slot + 1 > kill_ring_slots)
743 kill_ring = (char **) xrealloc
744 (kill_ring,
745 (kill_ring_slots += max_retained_kills) * sizeof (char *));
747 if (slot != kill_ring_index)
748 free (kill_ring[slot]);
749 else
750 kill_ring_index++;
752 kill_ring[slot] = killed_text;
754 kill_ring_loc = slot;
757 /* Notice that the last command was a kill. */
758 echo_area_last_command_was_kill++;
761 /* **************************************************************** */
762 /* */
763 /* Echo Area Completion */
764 /* */
765 /* **************************************************************** */
767 /* Pointer to an array of REFERENCE to complete over. */
768 static REFERENCE **echo_area_completion_items = (REFERENCE **)NULL;
770 /* Sorted array of REFERENCE * which is the possible completions found in
771 the variable echo_area_completion_items. If there is only one element,
772 it is the only possible completion. */
773 static REFERENCE **completions_found = (REFERENCE **)NULL;
774 static int completions_found_index = 0;
775 static int completions_found_slots = 0;
777 /* The lowest common denominator found while completing. */
778 static REFERENCE *LCD_completion;
780 /* Internal functions used by the user calls. */
781 static void build_completions (void), completions_must_be_rebuilt (void);
783 /* Variable which holds the output of completions. */
784 static NODE *possible_completions_output_node = (NODE *)NULL;
786 static char *compwin_name = "*Completions*";
788 /* Return non-zero if WINDOW is a window used for completions output. */
789 static int
790 completions_window_p (WINDOW *window)
792 int result = 0;
794 if (internal_info_node_p (window->node) &&
795 (strcmp (window->node->nodename, compwin_name) == 0))
796 result = 1;
798 return (result);
801 /* Workhorse for completion readers. If FORCE is non-zero, the user cannot
802 exit unless the line read completes, or is empty. */
803 char *
804 info_read_completing_internal (WINDOW *window, char *prompt,
805 REFERENCE **completions, int force)
807 char *line;
809 /* If the echo area is already active, remember the current state. */
810 if (echo_area_is_active)
811 push_echo_area ();
813 echo_area_must_complete_p = force;
815 /* Initialize our local variables. */
816 initialize_input_line (prompt);
818 /* Initialize the echo area for the first (but maybe not the last) time. */
819 echo_area_initialize_node ();
821 /* Save away the original node of this window, and the window itself,
822 so echo area commands can temporarily use this window. */
823 remember_calling_window (window);
825 /* Save away the list of items to complete over. */
826 echo_area_completion_items = completions;
827 completions_must_be_rebuilt ();
829 active_window = the_echo_area;
830 echo_area_is_active++;
832 /* Read characters in the echo area. */
833 while (1)
835 info_read_and_dispatch ();
837 line = echo_area_after_read ();
839 /* Force the completion to take place if the user hasn't accepted
840 a default or aborted, and if FORCE is active. */
841 if (force && line && *line && completions)
843 register int i;
845 build_completions ();
847 /* If there is only one completion, then make the line be that
848 completion. */
849 if (completions_found_index == 1)
851 free (line);
852 line = xstrdup (completions_found[0]->label);
853 break;
856 /* If one of the completions matches exactly, then that is okay, so
857 return the current line. */
858 for (i = 0; i < completions_found_index; i++)
859 if (strcasecmp (completions_found[i]->label, line) == 0)
861 free (line);
862 line = xstrdup (completions_found[i]->label);
863 break;
866 /* If no match, go back and try again. */
867 if (i == completions_found_index)
869 if (!completions_found_index)
870 inform_in_echo_area ((char *) _("No completions"));
871 else
872 inform_in_echo_area ((char *) _("Not complete"));
873 continue;
876 break;
878 echo_area_is_active--;
880 /* Restore the original active window and show point in it. */
881 active_window = calling_window;
882 restore_calling_window ();
883 display_cursor_at_point (active_window);
884 fflush (stdout);
886 echo_area_completion_items = (REFERENCE **)NULL;
887 completions_must_be_rebuilt ();
889 /* If there is a previous loop waiting for us, restore it now. */
890 if (echo_area_is_active)
891 pop_echo_area ();
893 return (line);
896 /* Read a line in the echo area with completion over COMPLETIONS. */
897 char *
898 info_read_completing_in_echo_area (WINDOW *window,
899 char *prompt, REFERENCE **completions)
901 return (info_read_completing_internal (window, prompt, completions, 1));
904 /* Read a line in the echo area allowing completion over COMPLETIONS, but
905 not requiring it. */
906 char *
907 info_read_maybe_completing (WINDOW *window,
908 char *prompt, REFERENCE **completions)
910 return (info_read_completing_internal (window, prompt, completions, 0));
913 DECLARE_INFO_COMMAND (ea_possible_completions, _("List possible completions"))
915 if (!echo_area_completion_items)
917 ea_insert (window, count, key);
918 return;
921 build_completions ();
923 if (!completions_found_index)
925 terminal_ring_bell ();
926 inform_in_echo_area ((char *) _("No completions"));
928 else if ((completions_found_index == 1) && (key != '?'))
930 inform_in_echo_area ((char *) _("Sole completion"));
932 else
934 register int i, l;
935 int limit, iterations, max_label = 0;
937 initialize_message_buffer ();
938 printf_to_message_buffer (completions_found_index == 1
939 ? (char *) _("One completion:\n")
940 : (char *) _("%d completions:\n"),
941 (void*)((intptr_t)completions_found_index),
942 NULL, NULL);
944 /* Find the maximum length of a label. */
945 for (i = 0; i < completions_found_index; i++)
947 int len = strlen (completions_found[i]->label);
948 if (len > max_label)
949 max_label = len;
952 max_label += 4;
954 /* Find out how many columns we should print in. */
955 limit = calling_window->width / max_label;
956 if (limit != 1 && (limit * max_label == calling_window->width))
957 limit--;
959 /* Avoid a possible floating exception. If max_label > width then
960 the limit will be 0 and a divide-by-zero fault will result. */
961 if (limit == 0)
962 limit = 1;
964 /* How many iterations of the printing loop? */
965 iterations = (completions_found_index + (limit - 1)) / limit;
967 /* Watch out for special case. If the number of completions is less
968 than LIMIT, then just do the inner printing loop. */
969 if (completions_found_index < limit)
970 iterations = 1;
972 /* Print the sorted items, up-and-down alphabetically. */
973 for (i = 0; i < iterations; i++)
975 register int j;
977 for (j = 0, l = i; j < limit; j++)
979 if (l >= completions_found_index)
980 break;
981 else
983 char *label;
984 int printed_length, k;
986 label = completions_found[l]->label;
987 printed_length = strlen (label);
988 printf_to_message_buffer ("%s", label, NULL, NULL);
990 if (j + 1 < limit)
992 for (k = 0; k < max_label - printed_length; k++)
993 printf_to_message_buffer (" ", NULL, NULL, NULL);
996 l += iterations;
998 printf_to_message_buffer ("\n", NULL, NULL, NULL);
1001 /* Make a new node to hold onto possible completions. Don't destroy
1002 dangling pointers. */
1004 NODE *temp;
1006 temp = message_buffer_to_node ();
1007 add_gcable_pointer (temp->contents);
1008 name_internal_node (temp, compwin_name);
1009 possible_completions_output_node = temp;
1012 /* Find a suitable window for displaying the completions output.
1013 First choice is an existing window showing completions output.
1014 If there is only one window, and it is large, make another
1015 (smaller) window, and use that one. Otherwise, use the caller's
1016 window. */
1018 WINDOW *compwin;
1020 compwin = get_internal_info_window (compwin_name);
1022 if (!compwin)
1024 /* If we can split the window to display most of the completion
1025 items, then do so. */
1026 if (calling_window->height > (iterations * 2)
1027 && calling_window->height / 2 >= WINDOW_MIN_SIZE)
1029 int start, pagetop;
1030 #ifdef SPLIT_BEFORE_ACTIVE
1031 int end;
1032 #endif
1034 active_window = calling_window;
1036 /* Perhaps we can scroll this window on redisplay. */
1037 start = calling_window->first_row;
1038 pagetop = calling_window->pagetop;
1040 compwin =
1041 window_make_window (possible_completions_output_node);
1042 active_window = the_echo_area;
1043 window_change_window_height
1044 (compwin, -(compwin->height - (iterations + 2)));
1046 window_adjust_pagetop (calling_window);
1047 remember_calling_window (calling_window);
1049 #if defined (SPLIT_BEFORE_ACTIVE)
1050 /* If the pagetop hasn't changed, scrolling the calling
1051 window is a reasonable thing to do. */
1052 if (pagetop == calling_window->pagetop)
1054 end = start + calling_window->height;
1055 display_scroll_display
1056 (start, end, calling_window->prev->height + 1);
1058 #else /* !SPLIT_BEFORE_ACTIVE */
1059 /* If the pagetop has changed, set the new pagetop here. */
1060 if (pagetop != calling_window->pagetop)
1062 int newtop = calling_window->pagetop;
1063 calling_window->pagetop = pagetop;
1064 set_window_pagetop (calling_window, newtop);
1066 #endif /* !SPLIT_BEFORE_ACTIVE */
1068 echo_area_completions_window = compwin;
1069 remember_window_and_node (compwin, compwin->node);
1071 else
1072 compwin = calling_window;
1075 if (compwin->node != possible_completions_output_node)
1077 window_set_node_of_window
1078 (compwin, possible_completions_output_node);
1079 remember_window_and_node (compwin, compwin->node);
1082 display_update_display (windows);
1087 DECLARE_INFO_COMMAND (ea_complete, _("Insert completion"))
1089 if (!echo_area_completion_items)
1091 ea_insert (window, count, key);
1092 return;
1095 /* If KEY is SPC, and we are not forcing completion to take place, simply
1096 insert the key. */
1097 if (!echo_area_must_complete_p && key == SPC)
1099 ea_insert (window, count, key);
1100 return;
1103 if (ea_last_executed_command == (VFunction *) ea_complete)
1105 /* If the keypress is a SPC character, and we have already tried
1106 completing once, and there are several completions, then check
1107 the batch of completions to see if any continue with a space.
1108 If there are some, insert the space character and continue. */
1109 if (key == SPC && completions_found_index > 1)
1111 register int i, offset;
1113 offset = input_line_end - input_line_beg;
1115 for (i = 0; i < completions_found_index; i++)
1116 if (completions_found[i]->label[offset] == ' ')
1117 break;
1119 if (completions_found[i])
1120 ea_insert (window, 1, ' ');
1121 else
1123 ea_possible_completions (window, count, key);
1124 return;
1127 else
1129 ea_possible_completions (window, count, key);
1130 return;
1134 input_line_point = input_line_end;
1135 build_completions ();
1137 if (!completions_found_index)
1138 terminal_ring_bell ();
1139 else if (LCD_completion->label[0] == '\0')
1140 ea_possible_completions (window, count, key);
1141 else
1143 register int i;
1144 input_line_point = input_line_end = input_line_beg;
1145 for (i = 0; LCD_completion->label[i]; i++)
1146 ea_insert (window, 1, LCD_completion->label[i]);
1150 /* Utility REFERENCE used to store possible LCD. */
1151 static REFERENCE LCD_reference = {
1152 (char *)NULL, (char *)NULL, (char *)NULL, 0, 0, 0
1155 static void remove_completion_duplicates (void);
1157 /* Variables which remember the state of the most recent call
1158 to build_completions (). */
1159 static char *last_completion_request = (char *)NULL;
1160 static REFERENCE **last_completion_items = (REFERENCE **)NULL;
1162 /* How to tell the completion builder to reset internal state. */
1163 static void
1164 completions_must_be_rebuilt (void)
1166 maybe_free (last_completion_request);
1167 last_completion_request = (char *)NULL;
1168 last_completion_items = (REFERENCE **)NULL;
1171 /* Build a list of possible completions from echo_area_completion_items,
1172 and the contents of input_line. */
1173 static void
1174 build_completions (void)
1176 register int i, len;
1177 register REFERENCE *entry;
1178 char *request;
1179 int informed_of_lengthy_job = 0;
1181 /* If there are no items to complete over, exit immediately. */
1182 if (!echo_area_completion_items)
1184 completions_found_index = 0;
1185 LCD_completion = (REFERENCE *)NULL;
1186 return;
1189 /* Check to see if this call to build completions is the same as the last
1190 call to build completions. */
1191 len = input_line_end - input_line_beg;
1192 request = (char *)xmalloc (1 + len);
1193 strncpy (request, &input_line[input_line_beg], len);
1194 request[len] = '\0';
1196 if (last_completion_request && last_completion_items &&
1197 last_completion_items == echo_area_completion_items &&
1198 (strcmp (last_completion_request, request) == 0))
1200 free (request);
1201 return;
1204 maybe_free (last_completion_request);
1205 last_completion_request = request;
1206 last_completion_items = echo_area_completion_items;
1208 /* Always start at the beginning of the list. */
1209 completions_found_index = 0;
1210 LCD_completion = (REFERENCE *)NULL;
1212 for (i = 0; (entry = echo_area_completion_items[i]); i++)
1214 if (strncasecmp (request, entry->label, len) == 0)
1215 add_pointer_to_array (entry, completions_found_index,
1216 completions_found, completions_found_slots,
1217 20, REFERENCE *);
1219 if (!informed_of_lengthy_job && completions_found_index > 100)
1221 informed_of_lengthy_job = 1;
1222 window_message_in_echo_area ((char *) _("Building completions..."),
1223 NULL, NULL);
1227 if (!completions_found_index)
1228 return;
1230 /* Sort and prune duplicate entries from the completions array. */
1231 remove_completion_duplicates ();
1233 /* If there is only one completion, just return that. */
1234 if (completions_found_index == 1)
1236 LCD_completion = completions_found[0];
1237 return;
1240 /* Find the least common denominator. */
1242 long shortest = 100000;
1244 for (i = 1; i < completions_found_index; i++)
1246 register int j;
1247 int c1, c2;
1249 for (j = 0;
1250 (c1 = info_tolower (completions_found[i - 1]->label[j])) &&
1251 (c2 = info_tolower (completions_found[i]->label[j]));
1252 j++)
1253 if (c1 != c2)
1254 break;
1256 if (shortest > j)
1257 shortest = j;
1260 maybe_free (LCD_reference.label);
1261 LCD_reference.label = (char *)xmalloc (1 + shortest);
1262 /* Since both the sorting done inside remove_completion_duplicates
1263 and all the comparisons above are case-insensitive, it's
1264 possible that the completion we are going to return is
1265 identical to what the user typed but for the letter-case. This
1266 is confusing, since the user could type FOOBAR<TAB> and get her
1267 string change letter-case for no good reason. So try to find a
1268 possible completion whose letter-case is identical, and if so,
1269 use that. */
1270 if (completions_found_index > 1)
1272 int req_len = strlen (request);
1274 for (i = 0; i < completions_found_index; i++)
1275 if (strncmp (request, completions_found[i]->label, req_len) == 0)
1276 break;
1277 /* If none of the candidates match exactly, use the first one. */
1278 if (i >= completions_found_index)
1279 i = 0;
1281 strncpy (LCD_reference.label, completions_found[i]->label, shortest);
1282 LCD_reference.label[shortest] = '\0';
1283 LCD_completion = &LCD_reference;
1286 if (informed_of_lengthy_job)
1287 echo_area_initialize_node ();
1290 /* Function called by qsort. */
1291 static int
1292 compare_references (const void *entry1, const void *entry2)
1294 REFERENCE **e1 = (REFERENCE **) entry1;
1295 REFERENCE **e2 = (REFERENCE **) entry2;
1297 return (strcasecmp ((*e1)->label, (*e2)->label));
1300 /* Prune duplicate entries from COMPLETIONS_FOUND. */
1301 static void
1302 remove_completion_duplicates (void)
1304 register int i, j;
1305 REFERENCE **temp;
1306 int newlen;
1308 if (!completions_found_index)
1309 return;
1311 /* Sort the items. */
1312 qsort (completions_found, completions_found_index, sizeof (REFERENCE *),
1313 compare_references);
1315 for (i = 0, newlen = 1; i < completions_found_index - 1; i++)
1317 if (strcmp (completions_found[i]->label,
1318 completions_found[i + 1]->label) == 0)
1319 completions_found[i] = (REFERENCE *)NULL;
1320 else
1321 newlen++;
1324 /* We have marked all the dead slots. It is faster to copy the live slots
1325 twice than to prune the dead slots one by one. */
1326 temp = (REFERENCE **)xmalloc ((1 + newlen) * sizeof (REFERENCE *));
1327 for (i = 0, j = 0; i < completions_found_index; i++)
1328 if (completions_found[i])
1329 temp[j++] = completions_found[i];
1331 for (i = 0; i < newlen; i++)
1332 completions_found[i] = temp[i];
1334 completions_found[i] = (REFERENCE *)NULL;
1335 completions_found_index = newlen;
1336 free (temp);
1339 /* Scroll the "other" window. If there is a window showing completions, scroll
1340 that one, otherwise scroll the window which was active on entering the read
1341 function. */
1342 DECLARE_INFO_COMMAND (ea_scroll_completions_window, _("Scroll the completions window"))
1344 WINDOW *compwin;
1345 int old_pagetop;
1347 compwin = get_internal_info_window (compwin_name);
1349 if (!compwin)
1350 compwin = calling_window;
1352 old_pagetop = compwin->pagetop;
1354 /* Let info_scroll_forward () do the work, and print any messages that
1355 need to be displayed. */
1356 info_scroll_forward (compwin, count, key);
1359 /* Function which gets called when an Info window is deleted while the
1360 echo area is active. WINDOW is the window which has just been deleted. */
1361 void
1362 echo_area_inform_of_deleted_window (WINDOW *window)
1364 /* If this is the calling_window, forget what we remembered about it. */
1365 if (window == calling_window)
1367 if (active_window != the_echo_area)
1368 remember_calling_window (active_window);
1369 else
1370 remember_calling_window (windows);
1373 /* If this window was the echo_area_completions_window, then notice that
1374 the window has been deleted. */
1375 if (window == echo_area_completions_window)
1376 echo_area_completions_window = (WINDOW *)NULL;
1379 /* **************************************************************** */
1380 /* */
1381 /* Pushing and Popping the Echo Area */
1382 /* */
1383 /* **************************************************************** */
1385 /* Push and Pop the echo area. */
1386 typedef struct {
1387 char *line;
1388 char *prompt;
1389 REFERENCE **comp_items;
1390 int point, beg, end;
1391 int must_complete;
1392 NODE node;
1393 WINDOW *compwin;
1394 } PUSHED_EA;
1396 static PUSHED_EA **pushed_echo_areas = (PUSHED_EA **)NULL;
1397 static int pushed_echo_areas_index = 0;
1398 static int pushed_echo_areas_slots = 0;
1400 /* Pushing the echo_area has a side effect of zeroing the completion_items. */
1401 static void
1402 push_echo_area (void)
1404 PUSHED_EA *pushed;
1406 pushed = (PUSHED_EA *)xmalloc (sizeof (PUSHED_EA));
1407 pushed->line = xstrdup (input_line);
1408 pushed->prompt = input_line_prompt;
1409 pushed->point = input_line_point;
1410 pushed->beg = input_line_beg;
1411 pushed->end = input_line_end;
1412 pushed->node = input_line_node;
1413 pushed->comp_items = echo_area_completion_items;
1414 pushed->must_complete = echo_area_must_complete_p;
1415 pushed->compwin = echo_area_completions_window;
1417 add_pointer_to_array (pushed, pushed_echo_areas_index, pushed_echo_areas,
1418 pushed_echo_areas_slots, 4, PUSHED_EA *);
1420 echo_area_completion_items = (REFERENCE **)NULL;
1423 static void
1424 pop_echo_area (void)
1426 PUSHED_EA *popped;
1428 popped = pushed_echo_areas[--pushed_echo_areas_index];
1430 strcpy (input_line, popped->line);
1431 free (popped->line);
1432 input_line_prompt = popped->prompt;
1433 input_line_point = popped->point;
1434 input_line_beg = popped->beg;
1435 input_line_end = popped->end;
1436 input_line_node = popped->node;
1437 echo_area_completion_items = popped->comp_items;
1438 echo_area_must_complete_p = popped->must_complete;
1439 echo_area_completions_window = popped->compwin;
1440 completions_must_be_rebuilt ();
1442 /* If the completion window no longer exists, forget about it. */
1443 if (echo_area_completions_window)
1445 register WINDOW *win;
1447 for (win = windows; win; win = win->next)
1448 if (echo_area_completions_window == win)
1449 break;
1451 /* If the window wasn't found, then it has already been deleted. */
1452 if (!win)
1453 echo_area_completions_window = (WINDOW *)NULL;
1456 free (popped);
1459 /* Returns non-zero if any of the prior stacked calls to read in the echo
1460 area produced a completions window. */
1461 static int
1462 echo_area_stack_contains_completions_p (void)
1464 register int i;
1466 for (i = 0; i < pushed_echo_areas_index; i++)
1467 if (pushed_echo_areas[i]->compwin)
1468 return (1);
1470 return (0);
1473 /* **************************************************************** */
1474 /* */
1475 /* Error Messages While Reading in Echo Area */
1476 /* */
1477 /* **************************************************************** */
1479 #if defined (HAVE_SYS_TIME_H)
1480 # include <sys/time.h>
1481 # define HAVE_STRUCT_TIMEVAL
1482 #endif /* HAVE_SYS_TIME_H */
1484 static void
1485 pause_or_input (void)
1487 #ifdef FD_SET
1488 struct timeval timer;
1489 fd_set readfds;
1490 int ready;
1492 FD_ZERO (&readfds);
1493 FD_SET (fileno (stdin), &readfds);
1494 timer.tv_sec = 2;
1495 timer.tv_usec = 0;
1496 ready = select (fileno (stdin) + 1, &readfds, (fd_set *) NULL,
1497 (fd_set *) NULL, &timer);
1498 #endif /* FD_SET */
1501 /* Print MESSAGE right after the end of the current line, and wait
1502 for input or a couple of seconds, whichever comes first. Then flush the
1503 informational message that was printed. */
1504 void
1505 inform_in_echo_area (const char *message)
1507 int i;
1508 char *text;
1509 int avail = EA_MAX_INPUT + 1 - input_line_end;
1511 text = xstrdup (message);
1512 for (i = 0; text[i] && text[i] != '\n' && i < avail; i++)
1514 text[i] = 0;
1516 echo_area_initialize_node ();
1517 sprintf (&input_line[input_line_end], "%s[%s]\n",
1518 echo_area_is_active ? " ": "", text);
1519 free (text);
1520 the_echo_area->point = input_line_point;
1521 display_update_one_window (the_echo_area);
1522 display_cursor_at_point (active_window);
1523 fflush (stdout);
1524 pause_or_input ();
1525 echo_area_initialize_node ();