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
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)
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). */
29 # define fd_set_cast(x) (int *)(x)
31 # define fd_set_cast(x) (fd_set *)(x)
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
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
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. */
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 (). */
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
))
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
;
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. */
126 if ((compwin
!= windows
|| windows
->next
) &&
127 !echo_area_stack_contains_completions_p ())
135 next
= compwin
->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
149 #if defined (UNNECESSARY)
150 echo_area_completions_window
= (WINDOW
*)NULL
;
151 #endif /* UNNECESSARY */
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. */
165 initialize_input_line (char *prompt
)
167 input_line_prompt
= prompt
;
169 strcpy (input_line
, prompt
);
171 input_line
[0] = '\0';
173 input_line_beg
= input_line_end
= input_line_point
= strlen (prompt
);
177 echo_area_after_read (void)
181 if (info_aborted_echo_area
)
183 info_aborted_echo_area
= 0;
184 return_value
= (char *)NULL
;
188 if (input_line_beg
== input_line_end
)
189 return_value
= xstrdup ("");
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. */
206 info_read_in_echo_area (WINDOW
*window
, char *prompt
)
210 /* If the echo area is already active, remember the current state. */
211 if (echo_area_is_active
)
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
);
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
)
246 /* Return the results to the caller. */
250 /* (re) Initialize the echo area node. */
252 echo_area_initialize_node (void)
256 for (i
= input_line_end
; (unsigned int) i
< sizeof (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. */
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 /* **************************************************************** */
282 /* Echo Area Movement Commands */
284 /* **************************************************************** */
286 DECLARE_INFO_COMMAND (ea_forward
, _("Move forward a character"))
289 ea_backward (window
, -count
, key
);
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"))
301 ea_forward (window
, -count
, key
);
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"))
328 ea_backward_word (window
, -count
, key
);
333 if (input_line_point
== input_line_end
)
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
];
342 while (++input_line_point
< input_line_end
)
344 c
= input_line
[input_line_point
];
350 if (input_line_point
== input_line_end
)
353 while (++input_line_point
< input_line_end
)
355 c
= input_line
[input_line_point
];
363 DECLARE_INFO_COMMAND (ea_backward_word
, _("Move backward a word"))
368 ea_forward_word (window
, -count
, key
);
373 if (input_line_point
== input_line_beg
)
376 /* Like ea_forward_word (), except that we look at the
377 characters just before point. */
379 c
= input_line
[input_line_point
- 1];
383 while ((--input_line_point
) != input_line_beg
)
385 c
= input_line
[input_line_point
- 1];
391 while (input_line_point
!= input_line_beg
)
393 c
= input_line
[input_line_point
- 1];
403 DECLARE_INFO_COMMAND (ea_delete
, _("Delete the character under the cursor"))
408 ea_rubout (window
, -count
, key
);
411 if (input_line_point
== input_line_end
)
414 if (info_explicit_arg
|| count
> 1)
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
;
425 for (i
= input_line_point
; i
< input_line_end
; i
++)
426 input_line
[i
] = input_line
[i
+ 1];
433 DECLARE_INFO_COMMAND (ea_rubout
, _("Delete the character behind the cursor"))
436 ea_delete (window
, -count
, key
);
441 if (input_line_point
== input_line_beg
)
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
);
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.
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 ();
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"))
486 if ((input_line_end
+ 1) == EA_MAX_INPUT
)
488 terminal_ring_bell ();
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
;
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
511 if (!count
|| !input_line_point
|| (input_line_end
- input_line_beg
) < 2)
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
;
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
)
544 /* **************************************************************** */
546 /* Echo Area Killing and Yanking */
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"))
563 if (!kill_ring_index
)
565 inform_in_echo_area ((char *) _("Kill ring is empty"));
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"))
582 if (((ea_last_executed_command
!= (VFunction
*) ea_yank
) &&
583 (ea_last_executed_command
!= (VFunction
*) ea_yank_pop
)) ||
584 (kill_ring_index
== 0))
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. */
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"))
615 ea_kill_text (input_line_point
, input_line_beg
);
616 input_line_point
= input_line_beg
;
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"))
627 ea_kill_text (input_line_point
, input_line_end
);
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
;
641 ea_backward_kill_word (window
, -count
, key
);
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
;
660 ea_kill_word (window
, -count
, key
);
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. */
676 ea_kill_text (int from
, int to
)
678 register int i
, counter
, distance
;
679 int killing_backwards
, slot
;
682 killing_backwards
= (from
> to
);
684 /* If killing backwards, reverse the values of FROM and TO. */
685 if (killing_backwards
)
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
)
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
);
724 /* Append TEXT to current kill. */
726 strcat (new, killed_text
);
731 kill_ring
[slot
] = new;
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
)
742 if (slot
+ 1 > kill_ring_slots
)
743 kill_ring
= (char **) xrealloc
745 (kill_ring_slots
+= max_retained_kills
) * sizeof (char *));
747 if (slot
!= kill_ring_index
)
748 free (kill_ring
[slot
]);
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 /* **************************************************************** */
763 /* Echo Area Completion */
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. */
790 completions_window_p (WINDOW
*window
)
794 if (internal_info_node_p (window
->node
) &&
795 (strcmp (window
->node
->nodename
, compwin_name
) == 0))
801 /* Workhorse for completion readers. If FORCE is non-zero, the user cannot
802 exit unless the line read completes, or is empty. */
804 info_read_completing_internal (WINDOW
*window
, char *prompt
,
805 REFERENCE
**completions
, int force
)
809 /* If the echo area is already active, remember the current state. */
810 if (echo_area_is_active
)
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. */
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
)
845 build_completions ();
847 /* If there is only one completion, then make the line be that
849 if (completions_found_index
== 1)
852 line
= xstrdup (completions_found
[0]->label
);
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)
862 line
= xstrdup (completions_found
[i
]->label
);
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"));
872 inform_in_echo_area ((char *) _("Not complete"));
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
);
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
)
896 /* Read a line in the echo area with completion over COMPLETIONS. */
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
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
);
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"));
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
),
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
);
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
))
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. */
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
)
972 /* Print the sorted items, up-and-down alphabetically. */
973 for (i
= 0; i
< iterations
; i
++)
977 for (j
= 0, l
= i
; j
< limit
; j
++)
979 if (l
>= completions_found_index
)
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
);
992 for (k
= 0; k
< max_label
- printed_length
; k
++)
993 printf_to_message_buffer (" ", NULL
, NULL
, NULL
);
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. */
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
1020 compwin
= get_internal_info_window (compwin_name
);
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
)
1030 #ifdef SPLIT_BEFORE_ACTIVE
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
;
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
);
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
);
1095 /* If KEY is SPC, and we are not forcing completion to take place, simply
1097 if (!echo_area_must_complete_p
&& key
== SPC
)
1099 ea_insert (window
, count
, key
);
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
] == ' ')
1119 if (completions_found
[i
])
1120 ea_insert (window
, 1, ' ');
1123 ea_possible_completions (window
, count
, key
);
1129 ea_possible_completions (window
, count
, key
);
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
);
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. */
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. */
1174 build_completions (void)
1176 register int i
, len
;
1177 register REFERENCE
*entry
;
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
;
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))
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
,
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..."),
1227 if (!completions_found_index
)
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];
1240 /* Find the least common denominator. */
1242 long shortest
= 100000;
1244 for (i
= 1; i
< completions_found_index
; i
++)
1250 (c1
= info_tolower (completions_found
[i
- 1]->label
[j
])) &&
1251 (c2
= info_tolower (completions_found
[i
]->label
[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,
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)
1277 /* If none of the candidates match exactly, use the first one. */
1278 if (i
>= completions_found_index
)
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. */
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. */
1302 remove_completion_duplicates (void)
1308 if (!completions_found_index
)
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
;
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
;
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
1342 DECLARE_INFO_COMMAND (ea_scroll_completions_window
, _("Scroll the completions window"))
1347 compwin
= get_internal_info_window (compwin_name
);
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. */
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
);
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 /* **************************************************************** */
1381 /* Pushing and Popping the Echo Area */
1383 /* **************************************************************** */
1385 /* Push and Pop the echo area. */
1389 REFERENCE
**comp_items
;
1390 int point
, beg
, end
;
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. */
1402 push_echo_area (void)
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
;
1424 pop_echo_area (void)
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
)
1451 /* If the window wasn't found, then it has already been deleted. */
1453 echo_area_completions_window
= (WINDOW
*)NULL
;
1459 /* Returns non-zero if any of the prior stacked calls to read in the echo
1460 area produced a completions window. */
1462 echo_area_stack_contains_completions_p (void)
1466 for (i
= 0; i
< pushed_echo_areas_index
; i
++)
1467 if (pushed_echo_areas
[i
]->compwin
)
1473 /* **************************************************************** */
1475 /* Error Messages While Reading in Echo Area */
1477 /* **************************************************************** */
1479 #if defined (HAVE_SYS_TIME_H)
1480 # include <sys/time.h>
1481 # define HAVE_STRUCT_TIMEVAL
1482 #endif /* HAVE_SYS_TIME_H */
1485 pause_or_input (void)
1488 struct timeval timer
;
1493 FD_SET (fileno (stdin
), &readfds
);
1496 ready
= select (fileno (stdin
) + 1, &readfds
, (fd_set
*) NULL
,
1497 (fd_set
*) NULL
, &timer
);
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. */
1505 inform_in_echo_area (const char *message
)
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
++)
1516 echo_area_initialize_node ();
1517 sprintf (&input_line
[input_line_end
], "%s[%s]\n",
1518 echo_area_is_active
? " ": "", text
);
1520 the_echo_area
->point
= input_line_point
;
1521 display_update_one_window (the_echo_area
);
1522 display_cursor_at_point (active_window
);
1525 echo_area_initialize_node ();