📄 session.c
字号:
/* Free the node structures which held onto internal node contents here. This doesn't free the contents; we have a garbage collector which does that. */ for (i = 0; info_win->nodes[i]; i++) if (internal_info_node_p (info_win->nodes[i])) free (info_win->nodes[i]); free (info_win->nodes); maybe_free (info_win->pagetops); maybe_free (info_win->points); } free (info_win); }#if defined (DEBUG_FORGET_WINDOW_AND_NODES) consistency_check_info_windows ();#endif /* DEBUG_FORGET_WINDOW_AND_NODES */}/* Set WINDOW to show NODE. Remember the new window in our list of Info windows. If we are doing automatic footnote display, also try to display the footnotes for this window. */voidinfo_set_node_of_window (window, node) WINDOW *window; NODE *node;{ /* Put this node into the window. */ window_set_node_of_window (window, node); /* Remember this node and window in our list of info windows. */ remember_window_and_node (window, node); /* If doing auto-footnote display/undisplay, show the footnotes belonging to this window's node. */ if (auto_footnotes_p) info_get_or_remove_footnotes (window);}/* **************************************************************** *//* *//* Info Movement Commands *//* *//* **************************************************************** *//* Change the pagetop of WINDOW to DESIRED_TOP, perhaps scrolling the screen to do so. */voidset_window_pagetop (window, desired_top) WINDOW *window; int desired_top;{ int point_line, old_pagetop; if (desired_top < 0) desired_top = 0; else if (desired_top > window->line_count) desired_top = window->line_count - 1; if (window->pagetop == desired_top) return; old_pagetop = window->pagetop; window->pagetop = desired_top; /* Make sure that point appears in this window. */ point_line = window_line_of_point (window); if ((point_line < window->pagetop) || ((point_line - window->pagetop) > window->height - 1)) window->point = window->line_starts[window->pagetop] - window->node->contents; window->flags |= W_UpdateWindow; /* Find out which direction to scroll, and scroll the window in that direction. Do this only if there would be a savings in redisplay time. This is true if the amount to scroll is less than the height of the window, and if the number of lines scrolled would be greater than 10 % of the window's height. */ if (old_pagetop < desired_top) { int start, end, amount; amount = desired_top - old_pagetop; if ((amount >= window->height) || (((window->height - amount) * 10) < window->height)) return; start = amount + window->first_row; end = window->height + window->first_row; display_scroll_display (start, end, -amount); } else { int start, end, amount; amount = old_pagetop - desired_top; if ((amount >= window->height) || (((window->height - amount) * 10) < window->height)) return; start = window->first_row; end = (window->first_row + window->height) - amount; display_scroll_display (start, end, amount); }}/* Immediately make WINDOW->point visible on the screen, and move the terminal cursor there. */static voidinfo_show_point (window) WINDOW *window;{ int old_pagetop; old_pagetop = window->pagetop; window_adjust_pagetop (window); if (old_pagetop != window->pagetop) { int new_pagetop; new_pagetop = window->pagetop; window->pagetop = old_pagetop; set_window_pagetop (window, new_pagetop); } if (window->flags & W_UpdateWindow) display_update_one_window (window); display_cursor_at_point (window);}/* Move WINDOW->point from OLD line index to NEW line index. */static voidmove_to_new_line (old, new, window) int old, new; WINDOW *window;{ if (old == -1) { info_error (CANT_FIND_POINT); } else { int goal; if (new >= window->line_count || new < 0) return; goal = window_get_goal_column (window); window->goal_column = goal; window->point = window->line_starts[new] - window->node->contents; window->point += window_chars_to_goal (window->line_starts[new], goal); info_show_point (window); }}/* Move WINDOW's point down to the next line if possible. */DECLARE_INFO_COMMAND (info_next_line, _("Move down to the next line")){ int old_line, new_line; if (count < 0) info_prev_line (window, -count, key); else { old_line = window_line_of_point (window); new_line = old_line + count; move_to_new_line (old_line, new_line, window); }}/* Move WINDOW's point up to the previous line if possible. */DECLARE_INFO_COMMAND (info_prev_line, _("Move up to the previous line")){ int old_line, new_line; if (count < 0) info_next_line (window, -count, key); else { old_line = window_line_of_point (window); new_line = old_line - count; move_to_new_line (old_line, new_line, window); }}/* Move WINDOW's point to the end of the true line. */DECLARE_INFO_COMMAND (info_end_of_line, _("Move to the end of the line")){ register int point, len; register char *buffer; buffer = window->node->contents; len = window->node->nodelen; for (point = window->point; (point < len) && (buffer[point] != '\n'); point++); if (point != window->point) { window->point = point; info_show_point (window); }}/* Move WINDOW's point to the beginning of the true line. */DECLARE_INFO_COMMAND (info_beginning_of_line, _("Move to the start of the line")){ register int point; register char *buffer; buffer = window->node->contents; point = window->point; for (; (point) && (buffer[point - 1] != '\n'); point--); /* If at a line start alreay, do nothing. */ if (point != window->point) { window->point = point; info_show_point (window); }}/* Move point forward in the node. */DECLARE_INFO_COMMAND (info_forward_char, _("Move forward a character")){ if (count < 0) info_backward_char (window, -count, key); else { window->point += count; if (window->point >= window->node->nodelen) window->point = window->node->nodelen - 1; info_show_point (window); }}/* Move point backward in the node. */DECLARE_INFO_COMMAND (info_backward_char, _("Move backward a character")){ if (count < 0) info_forward_char (window, -count, key); else { window->point -= count; if (window->point < 0) window->point = 0; info_show_point (window); }}#define alphabetic(c) (islower (c) || isupper (c) || isdigit (c))/* Move forward a word in this node. */DECLARE_INFO_COMMAND (info_forward_word, _("Move forward a word")){ long point; char *buffer; int end, c; if (count < 0) { info_backward_word (window, -count, key); return; } point = window->point; buffer = window->node->contents; end = window->node->nodelen; while (count) { if (point + 1 >= end) return; /* If we are not in a word, move forward until we are in one. Then, move forward until we hit a non-alphabetic character. */ c = buffer[point]; if (!alphabetic (c)) { while (++point < end) { c = buffer[point]; if (alphabetic (c)) break; } } if (point >= end) return; while (++point < end) { c = buffer[point]; if (!alphabetic (c)) break; } --count; } window->point = point; info_show_point (window);}DECLARE_INFO_COMMAND (info_backward_word, _("Move backward a word")){ long point; char *buffer; int c; if (count < 0) { info_forward_word (window, -count, key); return; } buffer = window->node->contents; point = window->point; while (count) { if (point == 0) break; /* Like info_forward_word (), except that we look at the characters just before point. */ c = buffer[point - 1]; if (!alphabetic (c)) { while (--point) { c = buffer[point - 1]; if (alphabetic (c)) break; } } while (point) { c = buffer[point - 1]; if (!alphabetic (c)) break; else --point; } --count; } window->point = point; info_show_point (window);}/* Here is a list of time counter names which correspond to ordinal numbers. It is used to print "once" instead of "1". */static char *counter_names[] = { "not at all", "once", "twice", "three", "four", "five", "six", (char *)NULL};/* Buffer used to return values from times_description (). */static char td_buffer[50];/* Function returns a static string fully describing the number of times present in COUNT. */static char *times_description (count) int count;{ register int i; td_buffer[0] = '\0'; for (i = 0; counter_names[i]; i++) if (count == i) break; if (counter_names[i]) sprintf (td_buffer, "%s%s", counter_names[i], count > 2 ? _(" times") : ""); else sprintf (td_buffer, _("%d times"), count); return (td_buffer);}/* Variable controlling the behaviour of default scrolling when you are already at the bottom of a node. Possible values are defined in session.h. The meanings are: IS_Continuous Try to get first menu item, or failing that, the "Next:" pointer, or failing that, the "Up:" and "Next:" of the up. IS_NextOnly Try to get "Next:" menu item. IS_PageOnly Simply give up at the bottom of a node. */int info_scroll_behaviour = IS_Continuous;/* Choices used by the completer when reading a value for the user-visible variable "scroll-behaviour". */char *info_scroll_choices[] = { "Continuous", "Next Only", "Page Only", (char *)NULL};/* Move to 1st menu item, Next, Up/Next, or error in this window. */static voidforward_move_node_structure (window, behaviour) WINDOW *window; int behaviour;{ switch (behaviour) { case IS_PageOnly: info_error (AT_NODE_BOTTOM); break; case IS_NextOnly: info_next_label_of_node (window->node); if (!info_parsed_nodename && !info_parsed_filename) info_error (_("No \"Next\" pointer for this node.")); else { window_message_in_echo_area (_("Following \"Next\" node...")); info_handle_pointer (_("Next"), window); } break; case IS_Continuous: { /* First things first. If this node contains a menu, move down into the menu. */ { REFERENCE **menu; menu = info_menu_of_node (window->node); if (menu) { info_free_references (menu); window_message_in_echo_area (_("Selecting first menu item...")); info_menu_digit (window, 1, '1'); return; } } /* Okay, this node does not contain a menu. If it contains a "Next:" pointer, use that. */ info_next_label_of_node (window->node); if (info_label_was_found) { window_message_in_echo_area (_("Selecting \"Next\" node...")); info_handle_pointer (_("Next"), window); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -