#include "info.h"
static char *
nodemenu_format_info ()
{
return (_("\n\
* Menu:\n\
(File)Node Lines Size Containing File\n\
---------- ----- ---- ---------------"));
}
static char *
format_node_info (node)
NODE *node;
{
register int i, len;
char *parent, *containing_file;
static char *line_buffer = (char *)NULL;
if (!line_buffer)
line_buffer = (char *)xmalloc (1000);
if (node->parent)
{
parent = filename_non_directory (node->parent);
if (!parent)
parent = node->parent;
}
else
parent = (char *)NULL;
containing_file = node->filename;
if (!parent && !*containing_file)
sprintf (line_buffer, "* %s::", node->nodename);
else
{
char *file = (char *)NULL;
if (parent)
file = parent;
else
file = filename_non_directory (containing_file);
if (!file)
file = containing_file;
if (!*file)
file = "dir";
sprintf (line_buffer, "* (%s)%s::", file, node->nodename);
}
len = pad_to (36, line_buffer);
{
int lines = 1;
for (i = 0; i < node->nodelen; i++)
if (node->contents[i] == '\n')
lines++;
sprintf (line_buffer + len, "%d", lines);
}
len = pad_to (44, line_buffer);
sprintf (line_buffer + len, "%ld", node->nodelen);
if (node->filename && *(node->filename))
{
len = pad_to (51, line_buffer);
sprintf (line_buffer + len, node->filename);
}
return xstrdup (line_buffer);
}
static int
compare_strings (string1, string2)
char **string1, **string2;
{
return (strcasecmp (*string1, *string2));
}
static char *nodemenu_nodename = "*Node Menu*";
NODE *
get_visited_nodes (filter_func)
Function *filter_func;
{
register int i, iw_index;
INFO_WINDOW *info_win;
NODE *node;
char **lines = (char **)NULL;
int lines_index = 0, lines_slots = 0;
if (!info_windows)
return ((NODE *)NULL);
for (iw_index = 0; (info_win = info_windows[iw_index]); iw_index++)
{
for (i = 0; i < info_win->nodes_index; i++)
{
node = info_win->nodes[i];
if (internal_info_node_p (node) &&
(strcmp (node->nodename, nodemenu_nodename) == 0))
continue;
if (node && (!filter_func || (*filter_func) (node)))
{
char *line;
line = format_node_info (node);
add_pointer_to_array
(line, lines_index, lines, lines_slots, 20, char *);
}
}
}
if (lines)
{
register int j, newlen;
char **temp;
qsort (lines, lines_index, sizeof (char *), compare_strings);
for (i = 0, newlen = 1; i < lines_index - 1; i++)
{
if (strcmp (lines[i], lines[i + 1]) == 0)
{
free (lines[i]);
lines[i] = (char *)NULL;
}
else
newlen++;
}
temp = (char **)xmalloc ((1 + newlen) * sizeof (char *));
for (i = 0, j = 0; i < lines_index; i++)
if (lines[i])
temp[j++] = lines[i];
temp[j] = (char *)NULL;
free (lines);
lines = temp;
lines_index = newlen;
}
initialize_message_buffer ();
printf_to_message_buffer
("%s", replace_in_documentation
(_("Here is the menu of nodes you have recently visited.\n\
Select one from this menu, or use `\\[history-node]' in another window.\n")));
printf_to_message_buffer ("%s\n", nodemenu_format_info ());
for (i = 0; (lines != (char **)NULL) && (i < lines_index); i++)
{
printf_to_message_buffer ("%s\n", lines[i]);
free (lines[i]);
}
if (lines)
free (lines);
node = message_buffer_to_node ();
add_gcable_pointer (node->contents);
return (node);
}
DECLARE_INFO_COMMAND (list_visited_nodes,
_("Make a window containing a menu of all of the currently visited nodes"))
{
WINDOW *new;
NODE *node;
set_remembered_pagetop_and_point (window);
for (new = windows; new; new = new->next)
{
node = new->node;
if (internal_info_node_p (node) &&
(strcmp (node->nodename, nodemenu_nodename) == 0))
break;
}
if (!new)
{
if (window->next)
new = window->next;
else if (window != windows)
new = windows;
}
if (!new)
{
WINDOW *old_active;
old_active = active_window;
active_window = window;
new = window_make_window ((NODE *)NULL);
active_window = old_active;
}
if (!new)
new = window;
new->flags |= W_NoWrap;
node = get_visited_nodes ((Function *)NULL);
name_internal_node (node, nodemenu_nodename);
#if 0
node->flags &= ~N_IsInternal;
#endif
{
int remember_me = 1;
#if defined (NOTDEF)
if (internal_info_node_p (new->node) &&
(strcmp (new->node->nodename, nodemenu_nodename) == 0))
remember_me = 0;
#endif
window_set_node_of_window (new, node);
if (remember_me)
remember_window_and_node (new, node);
}
active_window = new;
}
DECLARE_INFO_COMMAND (select_visited_node,
_("Select a node which has been previously visited in a visible window"))
{
char *line;
NODE *node;
REFERENCE **menu;
node = get_visited_nodes ((Function *)NULL);
menu = info_menu_of_node (node);
free (node);
line =
info_read_completing_in_echo_area (window, _("Select visited node: "), menu);
window = active_window;
if (!line)
{
info_abort_key (window, 0, 0);
info_free_references (menu);
return;
}
if (*line)
{
REFERENCE *entry;
entry = info_get_labeled_reference (line, menu);
if (!entry)
info_error (_("The reference disappeared! (%s)."), line);
else
info_select_reference (window, entry);
}
free (line);
info_free_references (menu);
if (!info_error_was_printed)
window_clear_echo_area ();
}