📄 info.el
字号:
;; there is a problem here in that if several menu items have the same ;; name you can only go to the node of the first with this command. (Info-goto-node (Info-extract-menu-item menu-item))) (defun Info-extract-menu-item (menu-item) (setq menu-item (regexp-quote menu-item)) (save-excursion (goto-char (point-min)) (or (search-forward "\n* menu:" nil t) (error "No menu in this node")) (or (re-search-forward (concat "\n\\* " menu-item ":") nil t) (re-search-forward (concat "\n\\* " menu-item) nil t) (error "No such item in menu")) (beginning-of-line) (forward-char 2) (Info-extract-menu-node-name)));; If COUNT is nil, use the last item in the menu.(defun Info-extract-menu-counting (count) (save-excursion (goto-char (point-min)) (or (search-forward "\n* menu:" nil t) (error "No menu in this node")) (if count (or (search-forward "\n* " nil t count) (error "Too few items in menu")) (while (search-forward "\n* " nil t) nil)) (Info-extract-menu-node-name)))(defun Info-nth-menu-item () "Go to the node of the Nth menu item.N is the digit argument used to invoke this command." (interactive) (Info-goto-node (Info-extract-menu-counting (- (aref (this-command-keys) (1- (length (this-command-keys)))) ?0))))(defun Info-top-node () "Go to the Top node of this file." (interactive) (Info-goto-node "Top"))(defun Info-final-node () "Go to the final node in this file." (interactive) (Info-goto-node "Top") (let (Info-history) ;; Go to the last node in the menu of Top. (Info-goto-node (Info-extract-menu-counting nil)) ;; If the last node in the menu is not last in pointer structure, ;; move forward until we can't go any farther. (while (Info-forward-node t t) nil) ;; Then keep moving down to last subnode, unless we reach an index. (while (and (not (string-match "\\<index\\>" Info-current-node)) (save-excursion (search-forward "\n* Menu:" nil t))) (Info-goto-node (Info-extract-menu-counting nil)))))(defun Info-forward-node (&optional not-down no-error) "Go forward one node, considering all nodes as forming one sequence." (interactive) (goto-char (point-min)) (forward-line 1) ;; three possibilities, in order of priority: ;; 1. next node is in a menu in this node (but not in an index) ;; 2. next node is next at same level ;; 3. next node is up and next (cond ((and (not not-down) (save-excursion (search-forward "\n* menu:" nil t)) (not (string-match "\\<index\\>" Info-current-node))) (Info-goto-node (Info-extract-menu-counting 1)) t) ((save-excursion (search-backward "next:" nil t)) (Info-next) t) ((and (save-excursion (search-backward "up:" nil t)) ;; Use string-equal, not equal, to ignore text props. (not (string-equal (downcase (Info-extract-pointer "up")) "top"))) (let ((old-node Info-current-node)) (Info-up) (let (Info-history success) (unwind-protect (setq success (Info-forward-node t no-error)) (or success (Info-goto-node old-node)))))) (no-error nil) (t (error "No pointer forward from this node"))))(defun Info-backward-node () "Go backward one node, considering all nodes as forming one sequence." (interactive) (let ((prevnode (Info-extract-pointer "prev[ious]*" t)) (upnode (Info-extract-pointer "up" t))) (cond ((and upnode (string-match "(" upnode)) (error "First node in file")) ((and upnode (or (null prevnode) ;; Use string-equal, not equal, ;; to ignore text properties. (string-equal (downcase prevnode) (downcase upnode)))) (Info-up)) (prevnode ;; If we move back at the same level, ;; go down to find the last subnode*. (Info-prev) (let (Info-history) (while (and (not (string-match "\\<index\\>" Info-current-node)) (save-excursion (search-forward "\n* Menu:" nil t))) (Info-goto-node (Info-extract-menu-counting nil))))) (t (error "No pointer backward from this node")))))(defun Info-exit () "Exit Info by selecting some other buffer." (interactive) (if Info-standalone (save-buffers-kill-emacs) (bury-buffer)))(defun Info-next-menu-item () (interactive) (save-excursion (forward-line -1) (search-forward "\n* menu:" nil t) (or (search-forward "\n* " nil t) (error "No more items in menu")) (Info-goto-node (Info-extract-menu-node-name))))(defun Info-last-menu-item () (interactive) (save-excursion (forward-line 1) (let ((beg (save-excursion (and (search-backward "\n* menu:" nil t) (point))))) (or (and beg (search-backward "\n* " beg t)) (error "No previous items in menu"))) (Info-goto-node (save-excursion (goto-char (match-end 0)) (Info-extract-menu-node-name)))))(defmacro Info-no-error (&rest body) (list 'condition-case nil (cons 'progn (append body '(t))) '(error nil)))(defun Info-next-preorder () "Go to the next subnode or the next node, or go up a level." (interactive) (cond ((Info-no-error (Info-next-menu-item))) ((Info-no-error (Info-next))) ((Info-no-error (Info-up)) ;; Since we have already gone thru all the items in this menu, ;; go up to the end of this node. (goto-char (point-max)) ;; Since logically we are done with the node with that menu, ;; move on from it. (Info-next-preorder)) (t (error "No more nodes"))))(defun Info-last-preorder () "Go to the last node, popping up a level if there is none." (interactive) (cond ((Info-no-error (Info-last-menu-item) ;; If we go down a menu item, go to the end of the node ;; so we can scroll back through it. (goto-char (point-max))) ;; Keep going down, as long as there are nested menu nodes. (while (Info-no-error (Info-last-menu-item) ;; If we go down a menu item, go to the end of the node ;; so we can scroll back through it. (goto-char (point-max)))) (recenter -1)) ((Info-no-error (Info-prev)) (goto-char (point-max)) (while (Info-no-error (Info-last-menu-item) ;; If we go down a menu item, go to the end of the node ;; so we can scroll back through it. (goto-char (point-max)))) (recenter -1)) ((Info-no-error (Info-up)) (goto-char (point-min)) (or (search-forward "\n* Menu:" nil t) (goto-char (point-max)))) (t (error "No previous nodes"))))(defun Info-scroll-up () "Scroll one screenful forward in Info, considering all nodes as one sequence.Once you scroll far enough in a node that its menu appears on the screenbut after point, the next scroll moves into its first subnode.When you scroll past the end of a node, that goes to the next node; ifthis node has no successor, it moves to the parent node's successor,and so on. If point is inside the menu of a node, it moves tosubnode indicated by the following menu item. (That case won'tnormally result from this command, but can happen in other ways.)" (interactive) (if (or (< (window-start) (point-min)) (> (window-start) (point-max))) (set-window-start (selected-window) (point))) (let ((virtual-end (save-excursion (goto-char (point-min)) (if (search-forward "\n* Menu:" nil t) (point) (point-max))))) (if (or (< virtual-end (window-start)) (pos-visible-in-window-p virtual-end)) (Info-next-preorder) (scroll-up))))(defun Info-scroll-down () "Scroll one screenful back in Info, considering all nodes as one sequence.Within the menu of a node, this goes to its last subnode.When you scroll past the beginning of a node, that goes to theprevious node or back up to the parent node." (interactive) (if (or (< (window-start) (point-min)) (> (window-start) (point-max))) (set-window-start (selected-window) (point))) (let* ((current-point (point)) (virtual-end (save-excursion (beginning-of-line) (setq current-point (point)) (goto-char (point-min)) (search-forward "\n* Menu:" current-point t)))) (if (or virtual-end (pos-visible-in-window-p (point-min))) (Info-last-preorder) (scroll-down))))(defun Info-next-reference (&optional recur) "Move cursor to the next cross-reference or menu item in the node." (interactive) (let ((pat "\\*note[ \n\t]*\\([^:]*\\):\\|^\\* .*:") (old-pt (point))) (or (eobp) (forward-char 1)) (or (re-search-forward pat nil t) (progn (goto-char (point-min)) (or (re-search-forward pat nil t) (progn (goto-char old-pt) (error "No cross references in this node"))))) (goto-char (match-beginning 0)) (if (looking-at "\\* Menu:") (if recur (error "No cross references in this node") (Info-next-reference t)))))(defun Info-prev-reference (&optional recur) "Move cursor to the previous cross-reference or menu item in the node." (interactive) (let ((pat "\\*note[ \n\t]*\\([^:]*\\):\\|^\\* .*:") (old-pt (point))) (or (re-search-backward pat nil t) (progn (goto-char (point-max)) (or (re-search-backward pat nil t) (progn (goto-char old-pt) (error "No cross references in this node"))))) (goto-char (match-beginning 0)) (if (looking-at "\\* Menu:") (if recur (error "No cross references in this node") (Info-prev-reference t)))))(defun Info-index (topic) "Look up a string in the index for this file.The index is defined as the first node in the top-level menu whosename contains the word \"Index\", plus any immediately followingnodes whose names also contain the word \"Index\".If there are no exact matches to the specified topic, this choosesthe first match which is a case-insensitive substring of a topic.Use the `,' command to see the other matches.Give a blank topic name to go to the Index node itself." (interactive "sIndex topic: ") (let ((orignode Info-current-node) (rnode nil) (pattern (format "\n\\* \\([^\n:]*%s[^\n:]*\\):[ \t]*\\([^.\n]*\\)\\.[ \t]*\\([0-9]*\\)" (regexp-quote topic))) node) (Info-goto-node "Top") (or (search-forward "\n* menu:" nil t) (error "No index")) (or (re-search-forward "\n\\* \\(.*\\<Index\\>\\)" nil t) (error "No index")) (goto-char (match-beginning 1)) ;; Here, and subsequently in this function, ;; we bind Info-history to nil for internal node-switches ;; so that we don't put junk in the history. ;; In the first Info-goto-node call, above, we do update the history ;; because that is what the user's previous node choice into it. (let ((Info-history nil)) (Info-goto-node (Info-extract-menu-node-name))) (or (equal topic "") (let ((matches nil) (exact nil) (Info-history nil) found) (while (progn (goto-char (point-min)) (while (re-search-forward pattern nil t) (setq matches (cons (list (buffer-substring (match-beginning 1) (match-end 1)) (buffer-substring (match-beginning 2) (match-end 2)) Info-current-node (string-to-int (concat "0" (buffer-substring (match-beginning 3) (match-end 3))))) matches))) (and (setq node (Info-extract-pointer "next" t)) (string-match "\\<Index\\>" node))) (Info-goto-node node)) (or matches (progn (Info-goto-node orignode) (error "No `%s' in index" topic))) ;; Here it is a feature that assoc is case-sensitive. (while (setq found (assoc topic matches)) (setq exact (cons found exact) matches (delq found matches))) (setq Info-index-alternatives (nconc exact (nreverse matches))) (Info-index-next 0)))))(defun Info-index-next (num) "Go to the next matching index item from the last `i' command." (interactive "p") (or Info-index-alternatives (error "No previous `i' command")) (while (< num 0) (setq num (+ num (length Info-index-alternatives)))) (while (> num 0) (setq Info-index-alternatives (nconc (cdr Info-index-alternatives) (list (car Info-index-alternatives))) num (1- num))) (Info-goto-node (nth 1 (car Info-index-alternatives))) (if (> (nth 3 (car Info-index-alternatives)) 0) (forward-line (nth 3 (car Info-index-alternatives))) (forward-line 3) ; don't search in headers (let ((name (car (car Info-index-alternatives)))) (Info-find-index-name name))) (message "Found `%s' in %s. %s" (car (car Info-index-alternatives)) (nth 2 (car Info-index-alternatives)) (if (cdr Info-index-alternatives) "(Press `,' for more)" "(Only match)")))(defun Info-find-index-name (name) "Move point to the place within the current node where NAME is defined." (if (or (re-search-forward (format "[a-zA-Z]+: %s\\( \\|$\\)" (regexp-quote name)) nil t) (search-forward (format "`%s'" name) nil t) (and (string-match "\\`.*\\( (.*)\\)\\'" name) (search-forward
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -