📄 session.c
字号:
binding.end = window->line_starts[point_line + 1] - binding.buffer; else binding.end = window->node->nodelen; binding.flags = 0; if (builder == info_menu_of_node) { if (point_line) { binding.start--; refs = info_menu_items (&binding); } } else {#if defined (HANDLE_MAN_PAGES) if (window->node->flags & N_IsManPage) refs = manpage_xrefs_in_binding (window->node, &binding); else#endif /* HANDLE_MAN_PAGES */ refs = info_xrefs (&binding); } if (refs) { if ((strcmp (refs[0]->label, "Menu") != 0) || (builder == info_xrefs_of_node)) { int which = 0; /* Find the closest reference to point. */ if (builder == info_xrefs_of_node) { int closest = -1; for (; refs[which]; which++) { if ((window->point >= refs[which]->start) && (window->point <= refs[which]->end)) { closest = which; break; } else if (window->point < refs[which]->start) { break; } } if (closest == -1) which--; else which = closest; } defentry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); defentry->label = xstrdup (refs[which]->label); defentry->filename = refs[which]->filename; defentry->nodename = refs[which]->nodename; if (defentry->filename) defentry->filename = xstrdup (defentry->filename); if (defentry->nodename) defentry->nodename = xstrdup (defentry->nodename); } info_free_references (refs); } } } /* If we are going to ask the user a question, do it now. */ if (ask_p) { char *prompt; /* Build the prompt string. */ if (defentry) prompt = (char *)xmalloc (20 + strlen (defentry->label)); else prompt = (char *)xmalloc (20); if (builder == info_menu_of_node) { if (defentry) sprintf (prompt, _("Menu item (%s): "), defentry->label); else sprintf (prompt, _("Menu item: ")); } else { if (defentry) sprintf (prompt, _("Follow xref (%s): "), defentry->label); else sprintf (prompt, _("Follow xref: ")); } line = info_read_completing_in_echo_area (window, prompt, menu); free (prompt); window = active_window; /* User aborts, just quit. */ if (!line) { maybe_free (defentry); info_free_references (menu); info_abort_key (window, 0, 0); return; } /* If we had a default and the user accepted it, use that. */ if (!*line) { free (line); if (defentry) line = xstrdup (defentry->label); else line = (char *)NULL; } } else { /* Not going to ask any questions. If we have a default entry, use that, otherwise return. */ if (!defentry) return; else line = xstrdup (defentry->label); } if (line) { /* Find the selected label in the references. */ entry = info_get_labeled_reference (line, menu); if (!entry && defentry) info_error (_("The reference disappeared! (%s)."), line); else { NODE *orig; orig = window->node; info_select_reference (window, entry); if ((builder == info_xrefs_of_node) && (window->node != orig)) { long offset; long start; if (window->line_count > 0) start = window->line_starts[1] - window->node->contents; else start = 0; offset = info_target_search_node (window->node, entry->label, start); if (offset != -1) { window->point = offset; window_adjust_pagetop (window); } } } free (line); if (defentry) { free (defentry->label); maybe_free (defentry->filename); maybe_free (defentry->nodename); free (defentry); } } info_free_references (menu); if (!info_error_was_printed) window_clear_echo_area ();}/* Read a line (with completion) which is the name of a menu item, and select that item. */DECLARE_INFO_COMMAND (info_menu_item, _("Read a menu item and select its node")){ info_menu_or_ref_item (window, count, key, info_menu_of_node, 1);}/* Read a line (with completion) which is the name of a reference to follow, and select the node. */DECLARE_INFO_COMMAND (info_xref_item, _("Read a footnote or cross reference and select its node")){ info_menu_or_ref_item (window, count, key, info_xrefs_of_node, 1);}/* Position the cursor at the start of this node's menu. */DECLARE_INFO_COMMAND (info_find_menu, _("Move to the start of this node's menu")){ SEARCH_BINDING binding; long position; binding.buffer = window->node->contents; binding.start = 0; binding.end = window->node->nodelen; binding.flags = S_FoldCase | S_SkipDest; position = search (INFO_MENU_LABEL, &binding); if (position == -1) info_error (NO_MENU_NODE); else { window->point = position; window_adjust_pagetop (window); window->flags |= W_UpdateWindow; }}/* Visit as many menu items as is possible, each in a separate window. */DECLARE_INFO_COMMAND (info_visit_menu, _("Visit as many menu items at once as possible")){ register int i; REFERENCE *entry, **menu; menu = info_menu_of_node (window->node); if (!menu) info_error (NO_MENU_NODE); for (i = 0; (!info_error_was_printed) && (entry = menu[i]); i++) { WINDOW *new; new = window_make_window (window->node); window_tile_windows (TILE_INTERNALS); if (!new) info_error (WIN_TOO_SMALL); else { active_window = new; info_select_reference (new, entry); } }}/* Read a line of input which is a node name, and go to that node. */DECLARE_INFO_COMMAND (info_goto_node, _("Read a node name and select it")){ char *line;#define GOTO_COMPLETES#if defined (GOTO_COMPLETES) /* Build a completion list of all of the known nodes. */ { register int fbi, i; FILE_BUFFER *current; REFERENCE **items = (REFERENCE **)NULL; int items_index = 0; int items_slots = 0; current = file_buffer_of_window (window); for (fbi = 0; info_loaded_files && info_loaded_files[fbi]; fbi++) { FILE_BUFFER *fb; REFERENCE *entry; int this_is_the_current_fb; fb = info_loaded_files[fbi]; this_is_the_current_fb = (current == fb); entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); entry->filename = entry->nodename = (char *)NULL; entry->label = (char *)xmalloc (4 + strlen (fb->filename)); sprintf (entry->label, "(%s)*", fb->filename); add_pointer_to_array (entry, items_index, items, items_slots, 10, REFERENCE *); if (fb->tags) { for (i = 0; fb->tags[i]; i++) { entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); entry->filename = entry->nodename = (char *)NULL; entry->label = (char *) xmalloc (4 + strlen (fb->filename) + strlen (fb->tags[i]->nodename)); sprintf (entry->label, "(%s)%s", fb->filename, fb->tags[i]->nodename); add_pointer_to_array (entry, items_index, items, items_slots, 100, REFERENCE *); } if (this_is_the_current_fb) { for (i = 0; fb->tags[i]; i++) { entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); entry->filename = entry->nodename = (char *)NULL; entry->label = xstrdup (fb->tags[i]->nodename); add_pointer_to_array (entry, items_index, items, items_slots, 100, REFERENCE *); } } } } line = info_read_maybe_completing (window, _("Goto Node: "), items); info_free_references (items); }#else /* !GOTO_COMPLETES */ line = info_read_in_echo_area (window, _("Goto Node: "));#endif /* !GOTO_COMPLETES */ /* If the user aborted, quit now. */ if (!line) { info_abort_key (window, 0, 0); return; } canonicalize_whitespace (line); if (*line) info_parse_and_select (line, window); free (line); if (!info_error_was_printed) window_clear_echo_area ();}#if defined (HANDLE_MAN_PAGES)DECLARE_INFO_COMMAND (info_man, _("Read a manpage reference and select it")){ char *line; line = info_read_in_echo_area (window, _("Get Manpage: ")); if (!line) { info_abort_key (window, 0, 0); return; } canonicalize_whitespace (line); if (*line) { char *goto_command; goto_command = (char *)xmalloc (4 + strlen (MANPAGE_FILE_BUFFER_NAME) + strlen (line)); sprintf (goto_command, "(%s)%s", MANPAGE_FILE_BUFFER_NAME, line); info_parse_and_select (goto_command, window); free (goto_command); } free (line); if (!info_error_was_printed) window_clear_echo_area ();}#endif /* HANDLE_MAN_PAGES *//* Move to the "Top" node in this file. */DECLARE_INFO_COMMAND (info_top_node, _("Select the node `Top' in this file")){ info_parse_and_select (_("Top"), window);}/* Move to the node "(dir)Top". */DECLARE_INFO_COMMAND (info_dir_node, _("Select the node `(dir)'")){ info_parse_and_select ("(dir)Top", window);}/* Read the name of a node to kill. The list of available nodes comes from the nodes appearing in the current window configuration. */static char *read_nodename_to_kill (window) WINDOW *window;{ int iw; char *nodename; INFO_WINDOW *info_win; REFERENCE **menu = NULL; int menu_index = 0, menu_slots = 0; char *default_nodename = xstrdup (active_window->node->nodename); char *prompt = xmalloc (40 + strlen (default_nodename)); sprintf (prompt, _("Kill node (%s): "), default_nodename); for (iw = 0; (info_win = info_windows[iw]); iw++) { REFERENCE *entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); entry->label = xstrdup (info_win->window->node->nodename); entry->filename = entry->nodename = (char *)NULL; add_pointer_to_array (entry, menu_index, menu, menu_slots, 10, REFERENCE *); } nodename = info_read_completing_in_echo_area (window, prompt, menu); free (prompt); info_free_references (menu); if (nodename && !*nodename) { free (nodename); nodename = default_nodename; } else free (default_nodename); return nodename;}/* Delete NODENAME from this window, showing the most recently selected node in this window. */static voidkill_node (window, nodename) WINDOW *window; char *nodename;{ int iw, i; INFO_WINDOW *info_win; NODE *temp; /* If there is no nodename to kill, quit now. */ if (!nodename) { info_abort_key (window, 0, 0); return; } /* If there is a nodename, find it in our window list. */ for (iw = 0; (info_win = info_windows[iw]); iw++) if (strcmp (nodename, info_win->nodes[info_win->current]->nodename) == 0) break; if (!info_win) { if (*nodename) info_error (_("Cannot kill node `%s'"), nodename); else window_clear_echo_area (); return; } /* If there are no more nodes left anywhere to view, complain and exit. */ if (info_windows_index == 1 && info_windows[0]->nodes_index == 1) { info_error (_("Cannot kill the last node")); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -