Merge branch 'vendor/OPENSSL'
[dragonfly.git] / contrib / texinfo / info / m-x.c
1 /* m-x.c -- Meta-x minibuffer reader.
2    $Id: m-x.c,v 1.8 2008/06/11 09:55:42 gray Exp $
3
4    Copyright (C) 1993, 1997, 1998, 2001, 2002, 2004, 2007, 2008
5    Free Software Foundation, Inc.
6
7    This program is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20    Originally written by Brian Fox (bfox@ai.mit.edu). */
21
22 #include "info.h"
23 #include "funs.h"
24
25 /* **************************************************************** */
26 /*                                                                  */
27 /*                     Reading Named Commands                       */
28 /*                                                                  */
29 /* **************************************************************** */
30
31 /* Read the name of an Info function in the echo area and return the
32    name.  A return value of NULL indicates that no function name could
33    be read. */
34 char *
35 read_function_name (const char *prompt, WINDOW *window)
36 {
37   register int i;
38   char *line;
39   REFERENCE **array = NULL;
40   int array_index = 0, array_slots = 0;
41
42   /* Make an array of REFERENCE which actually contains the names of
43      the functions available in Info. */
44   for (i = 0; function_doc_array[i].func; i++)
45     {
46       REFERENCE *entry;
47
48       entry = xmalloc (sizeof (REFERENCE));
49       entry->label = xstrdup (function_doc_array[i].func_name);
50       entry->nodename = NULL;
51       entry->filename = NULL;
52
53       add_pointer_to_array
54         (entry, array_index, array, array_slots, 200, REFERENCE *);
55     }
56
57   line = info_read_completing_in_echo_area (window, prompt, array);
58
59   info_free_references (array);
60
61   if (!echo_area_is_active)
62     window_clear_echo_area ();
63
64   return line;
65 }
66
67 DECLARE_INFO_COMMAND (describe_command,
68    _("Read the name of an Info command and describe it"))
69 {
70   char *line;
71
72   line = read_function_name (_("Describe command: "), window);
73
74   if (!line)
75     {
76       info_abort_key (active_window, count, key);
77       return;
78     }
79
80   /* Describe the function named in "LINE". */
81   if (*line)
82     {
83       InfoCommand *cmd = named_function (line);
84
85       if (!cmd)
86         return;
87
88       window_message_in_echo_area ("%s: %s.",
89                                    line, function_documentation (cmd));
90     }
91   free (line);
92 }
93
94 DECLARE_INFO_COMMAND (info_execute_command,
95    _("Read a command name in the echo area and execute it"))
96 {
97   char *line;
98   char *keys;
99   char *prompt;
100
101   prompt = xmalloc (20);
102
103   keys = where_is (info_keymap, InfoCmd(info_execute_command));
104   /* If the where_is () function thinks that this command doesn't exist,
105      there's something very wrong!  */
106   if (!keys)
107     abort();
108
109   if (info_explicit_arg || count != 1)
110     sprintf (prompt, "%d %s ", count, keys);
111   else
112     sprintf (prompt, "%s ", keys);
113
114   /* Ask the completer to read a reference for us. */
115   line = read_function_name (prompt, window);
116
117   /* User aborted? */
118   if (!line)
119     {
120       info_abort_key (active_window, count, key);
121       return;
122     }
123
124   /* User accepted "default"?  (There is none.) */
125   if (!*line)
126     {
127       free (line);
128       return;
129     }
130
131   /* User wants to execute a named command.  Do it. */
132   {
133     InfoCommand *command;
134
135     if ((active_window != the_echo_area) &&
136         (strncmp (line, "echo-area-", 10) == 0))
137       {
138         free (line);
139         info_error (_("Cannot execute an `echo-area' command here."),
140             NULL, NULL);
141         return;
142       }
143
144     command = named_function (line);
145     free (line);
146
147     if (!command)
148       return;
149
150     if (InfoFunction(command))
151       (*InfoFunction(command)) (active_window, count, 0);
152     else
153       info_error (_("Undefined command: %s"), line, NULL);
154   }
155 }
156
157 /* Okay, now that we have M-x, let the user set the screen height. */
158 DECLARE_INFO_COMMAND (set_screen_height,
159   _("Set the height of the displayed window"))
160 {
161   int new_height, old_height = screenheight;
162
163   if (info_explicit_arg || count != 1)
164     new_height = count;
165   else
166     {
167       char prompt[80];
168       char *line;
169
170       new_height = screenheight;
171
172       sprintf (prompt, _("Set screen height to (%d): "), new_height);
173
174       line = info_read_in_echo_area (window, prompt);
175
176       /* If the user aborted, do that now. */
177       if (!line)
178         {
179           info_abort_key (active_window, count, 0);
180           return;
181         }
182
183       /* Find out what the new height is supposed to be. */
184       if (*line)
185         new_height = atoi (line);
186
187       /* Clear the echo area if it isn't active. */
188       if (!echo_area_is_active)
189         window_clear_echo_area ();
190
191       free (line);
192     }
193
194   terminal_clear_screen ();
195   display_clear_display (the_display);
196   screenheight = new_height;
197 #ifdef SET_SCREEN_SIZE_HELPER
198   SET_SCREEN_SIZE_HELPER;
199 #endif
200   if (screenheight == old_height)
201     {
202       /* Display dimensions didn't actually change, so
203          window_new_screen_size won't do anything, but we've
204          already cleared the display above.  Undo the damage.  */
205       window_mark_chain (windows, W_UpdateWindow);
206       display_update_display (windows);
207     }
208   else
209     {
210       display_initialize_display (screenwidth, screenheight);
211       window_new_screen_size (screenwidth, screenheight);
212     }
213 }