/* Create or delete the footnotes window depending on whether footnotes exist in WINDOW's node or not. Returns FN_FOUND if footnotes were found and displayed. Returns FN_UNFOUND if there were no footnotes found in WINDOW's node. Returns FN_UNABLE if there were footnotes, but the window to show them couldn't be made. */ int info_get_or_remove_footnotes (WINDOW *window) { WINDOW *fn_win; NODE *new_footnotes; fn_win = find_footnotes_window (); /* If we are in the footnotes window, change nothing. */ if (fn_win == window) return (FN_FOUND); /* Try to find footnotes for this window's node. */ new_footnotes = make_footnotes_node (window->node); /* If there was a window showing footnotes, and there are no footnotes for the current window, delete the old footnote window. */ if (fn_win && !new_footnotes) { if (windows->next) info_delete_window_internal (fn_win); } /* If there are footnotes for this window's node, but no window around showing footnotes, try to make a new window. */ if (new_footnotes && !fn_win) { WINDOW *old_active; WINDOW *last, *win; /* Always make this window be the last one appearing in the list. Find the last window in the chain. */ for (win = windows, last = windows; win; last = win, win = win->next); /* Try to split this window, and make the split window the one to contain the footnotes. */ old_active = active_window; active_window = last; fn_win = window_make_window (new_footnotes); active_window = old_active; if (!fn_win) { free (new_footnotes->contents); free (new_footnotes); /* If we are hacking automatic footnotes, and there are footnotes but we couldn't display them, print a message to that effect. */ if (auto_footnotes_p) inform_in_echo_area ((char *) _("Footnotes could not be displayed")); return (FN_UNABLE); } } /* If there are footnotes, and there is a window to display them, make that window be the number of lines appearing in the footnotes. */ if (new_footnotes && fn_win) { window_set_node_of_window (fn_win, new_footnotes); window_change_window_height (fn_win, fn_win->line_count - fn_win->height); remember_window_and_node (fn_win, new_footnotes); add_gcable_pointer (new_footnotes->contents); } if (!new_footnotes) return (FN_UNFOUND); else return (FN_FOUND); }
static void create_internal_info_help_node (int help_is_only_window_p) { register int i; NODE *node; char *contents = NULL; char *exec_keys; #ifndef HELP_NODE_GETS_REGENERATED if (internal_info_help_node_contents) contents = internal_info_help_node_contents; #endif /* !HELP_NODE_GETS_REGENERATED */ if (!contents) { int printed_one_mx = 0; initialize_message_buffer (); for (i = 0; info_internal_help_text[i]; i++) { #ifdef INFOKEY printf_to_message_buffer (replace_in_documentation (_(info_internal_help_text[i]), help_is_only_window_p), NULL, NULL, NULL); #else /* Don't translate blank lines, gettext outputs the po file header in that case. We want a blank line. */ char *msg = *(info_internal_help_text[i]) ? _(info_internal_help_text[i]) : info_internal_help_text[i]; char *key = info_help_keys_text[i][vi_keys_p]; /* If we have only one window (because the window size was too small to split it), CTRL-x 0 doesn't work to `quit' help. */ if (STREQ (key, "CTRL-x 0") && help_is_only_window_p) key = "l"; printf_to_message_buffer (msg, key, NULL, NULL); #endif /* !INFOKEY */ } printf_to_message_buffer ("---------------------\n", NULL, NULL, NULL); printf_to_message_buffer (_("The current search path is:\n"), NULL, NULL, NULL); printf_to_message_buffer ("%s\n", infopath, NULL, NULL); printf_to_message_buffer ("---------------------\n\n", NULL, NULL, NULL); printf_to_message_buffer (_("Commands available in Info windows:\n\n"), NULL, NULL, NULL); dump_map_to_message_buffer ("", info_keymap); printf_to_message_buffer ("---------------------\n\n", NULL, NULL, NULL); printf_to_message_buffer (_("Commands available in the echo area:\n\n"), NULL, NULL, NULL); dump_map_to_message_buffer ("", echo_area_keymap); #if defined (NAMED_FUNCTIONS) /* Get a list of commands which have no keystroke equivs. */ exec_keys = where_is (info_keymap, InfoCmd(info_execute_command)); if (exec_keys) exec_keys = xstrdup (exec_keys); for (i = 0; function_doc_array[i].func; i++) { InfoCommand *cmd = DocInfoCmd(&function_doc_array[i]); if (InfoFunction(cmd) != (VFunction *) info_do_lowercase_version && !where_is_internal (info_keymap, cmd) && !where_is_internal (echo_area_keymap, cmd)) { if (!printed_one_mx) { printf_to_message_buffer ("---------------------\n\n", NULL, NULL, NULL); if (exec_keys && exec_keys[0]) printf_to_message_buffer (_("The following commands can only be invoked via %s:\n\n"), exec_keys, NULL, NULL); else printf_to_message_buffer (_("The following commands cannot be invoked at all:\n\n"), NULL, NULL, NULL); printed_one_mx = 1; } printf_to_message_buffer ("%s %s\n %s\n", exec_keys, function_doc_array[i].func_name, replace_in_documentation (strlen (function_doc_array[i].doc) ? _(function_doc_array[i].doc) : "", 0) ); } } if (printed_one_mx) printf_to_message_buffer ("\n", NULL, NULL, NULL); maybe_free (exec_keys); #endif /* NAMED_FUNCTIONS */ node = message_buffer_to_node (); internal_info_help_node_contents = node->contents; } else { /* We already had the right contents, so simply use them. */ node = build_message_node ("", 0, 0); free (node->contents); node->contents = contents; node->nodelen = 1 + strlen (contents); } internal_info_help_node = node; /* Do not GC this node's contents. It never changes, and we never need to delete it once it is made. If you change some things (such as placing information about dynamic variables in the help text) then you will need to allow the contents to be gc'd, and you will have to arrange to always regenerate the help node. */ #if defined (HELP_NODE_GETS_REGENERATED) add_gcable_pointer (internal_info_help_node->contents); #endif name_internal_node (internal_info_help_node, info_help_nodename); /* Even though this is an internal node, we don't want the window system to treat it specially. So we turn off the internalness of it here. */ internal_info_help_node->flags &= ~N_IsInternal; }