variables.c revision 21495
1/* variables.c -- How to manipulate user visible variables in Info. */
2
3/* This file is part of GNU Info, a program for reading online documentation
4   stored in Info format.
5
6   Copyright (C) 1993 Free Software Foundation, Inc.
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22   Written by Brian Fox (bfox@ai.mit.edu). */
23
24#include "info.h"
25#include "variables.h"
26
27/* **************************************************************** */
28/*								    */
29/*		    User Visible Variables in Info		    */
30/*								    */
31/* **************************************************************** */
32
33/* Choices used by the completer when reading a zero/non-zero value for
34   a variable. */
35static char *on_off_choices[] = { "Off", "On", (char *)NULL };
36
37VARIABLE_ALIST info_variables[] = {
38  { "automatic-footnotes",
39      "When \"On\", footnotes appear and disappear automatically",
40      &auto_footnotes_p, (char **)on_off_choices },
41
42  { "automatic-tiling",
43      "When \"On\", creating or deleting a window resizes other windows",
44      &auto_tiling_p, (char **)on_off_choices },
45
46  { "visible-bell",
47      "When \"On\", flash the screen instead of ringing the bell",
48      &terminal_use_visible_bell_p, (char **)on_off_choices },
49
50  { "errors-ring-bell",
51      "When \"On\", errors cause the bell to ring",
52      &info_error_rings_bell_p, (char **)on_off_choices },
53
54  { "gc-compressed-files",
55      "When \"On\", Info garbage collects files which had to be uncompressed",
56      &gc_compressed_files, (char **)on_off_choices },
57  { "show-index-match",
58      "When \"On\", the portion of the matched search string is highlighted",
59      &show_index_match, (char **)on_off_choices },
60
61  { "scroll-behaviour",
62      "Controls what happens when scrolling is requested at the end of a node",
63      &info_scroll_behaviour, (char **)info_scroll_choices },
64
65  { "scroll-step",
66      "The number lines to scroll when the cursor moves out of the window",
67      &window_scroll_step, (char **)NULL },
68
69  { "ISO-Latin",
70      "When \"On\", Info accepts and displays ISO Latin characters",
71      &ISO_Latin_p, (char **)on_off_choices },
72
73  { (char *)NULL, (char *)NULL, (int *)NULL, (char **)NULL }
74};
75
76DECLARE_INFO_COMMAND (describe_variable, "Explain the use of a variable")
77{
78  VARIABLE_ALIST *var;
79  char *description;
80
81  /* Get the variable's name. */
82  var = read_variable_name ("Describe variable: ", window);
83
84  if (!var)
85    return;
86
87  description = (char *)xmalloc (20 + strlen (var->name) + strlen (var->doc));
88
89  if (var->choices)
90    sprintf (description, "%s (%s): %s.",
91	     var->name, var->choices[*(var->value)], var->doc);
92  else
93    sprintf (description, "%s (%d): %s.", var->name, *(var->value), var->doc);
94
95  window_message_in_echo_area ("%s", description);
96  free (description);
97}
98
99DECLARE_INFO_COMMAND (set_variable, "Set the value of an Info variable")
100{
101  VARIABLE_ALIST *var;
102  char *line;
103
104  /* Get the variable's name and value. */
105  var = read_variable_name ("Set variable: ", window);
106
107  if (!var)
108    return;
109
110  /* Read a new value for this variable. */
111  {
112    char prompt[100];
113
114    if (!var->choices)
115      {
116	int potential_value;
117
118	if (info_explicit_arg || count != 1)
119	  potential_value = count;
120	else
121	  potential_value = *(var->value);
122
123	sprintf (prompt, "Set %s to value (%d): ",
124		 var->name, potential_value);
125	line = info_read_in_echo_area (active_window, prompt);
126
127	/* If no error was printed, clear the echo area. */
128	if (!info_error_was_printed)
129	  window_clear_echo_area ();
130
131	/* User aborted? */
132	if (!line)
133	  return;
134
135	/* If the user specified a value, get that, otherwise, we are done. */
136	canonicalize_whitespace (line);
137	if (*line)
138	  *(var->value) = atoi (line);
139	else
140	  *(var->value) = potential_value;
141
142	free (line);
143      }
144    else
145      {
146	register int i;
147	REFERENCE **array = (REFERENCE **)NULL;
148	int array_index = 0;
149	int array_slots = 0;
150
151	for (i = 0; var->choices[i]; i++)
152	  {
153	    REFERENCE *entry;
154
155	    entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
156	    entry->label = strdup (var->choices[i]);
157	    entry->nodename = (char *)NULL;
158	    entry->filename = (char *)NULL;
159
160	    add_pointer_to_array
161	      (entry, array_index, array, array_slots, 10, REFERENCE *);
162	  }
163
164	sprintf (prompt, "Set %s to value (%s): ",
165		 var->name, var->choices[*(var->value)]);
166
167	/* Ask the completer to read a variable value for us. */
168	line = info_read_completing_in_echo_area (window, prompt, array);
169
170	info_free_references (array);
171
172	if (!echo_area_is_active)
173	  window_clear_echo_area ();
174
175	/* User aborted? */
176	if (!line)
177	  {
178	    info_abort_key (active_window, 0, 0);
179	    return;
180	  }
181
182	/* User accepted default choice?  If so, no change. */
183	if (!*line)
184	  {
185	    free (line);
186	    return;
187	  }
188
189	/* Find the choice in our list of choices. */
190	for (i = 0; var->choices[i]; i++)
191	  if (strcmp (var->choices[i], line) == 0)
192	    break;
193
194	if (var->choices[i])
195	  *(var->value) = i;
196      }
197  }
198}
199
200/* Read the name of an Info variable in the echo area and return the
201   address of a VARIABLE_ALIST member.  A return value of NULL indicates
202   that no variable could be read. */
203VARIABLE_ALIST *
204read_variable_name (prompt, window)
205     char *prompt;
206     WINDOW *window;
207{
208  register int i;
209  char *line;
210  REFERENCE **variables;
211
212  /* Get the completion array of variable names. */
213  variables = make_variable_completions_array ();
214
215  /* Ask the completer to read a variable for us. */
216  line =
217    info_read_completing_in_echo_area (window, prompt, variables);
218
219  info_free_references (variables);
220
221  if (!echo_area_is_active)
222    window_clear_echo_area ();
223
224  /* User aborted? */
225  if (!line)
226    {
227      info_abort_key (active_window, 0, 0);
228      return ((VARIABLE_ALIST *)NULL);
229    }
230
231  /* User accepted "default"?  (There is none.) */
232  if (!*line)
233    {
234      free (line);
235      return ((VARIABLE_ALIST *)NULL);
236    }
237
238  /* Find the variable in our list of variables. */
239  for (i = 0; info_variables[i].name; i++)
240    if (strcmp (info_variables[i].name, line) == 0)
241      break;
242
243  if (!info_variables[i].name)
244    return ((VARIABLE_ALIST *)NULL);
245  else
246    return (&(info_variables[i]));
247}
248
249/* Make an array of REFERENCE which actually contains the names of the
250   variables available in Info. */
251REFERENCE **
252make_variable_completions_array ()
253{
254  register int i;
255  REFERENCE **array = (REFERENCE **)NULL;
256  int array_index = 0, array_slots = 0;
257
258  for (i = 0; info_variables[i].name; i++)
259    {
260      REFERENCE *entry;
261
262      entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
263      entry->label = strdup (info_variables[i].name);
264      entry->nodename = (char *)NULL;
265      entry->filename = (char *)NULL;
266
267      add_pointer_to_array
268	(entry, array_index, array, array_slots, 200, REFERENCE *);
269    }
270
271  return (array);
272}
273