PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/site/speedbar/sb-info.el

https://github.com/NiftyIon/emacs.d
Emacs Lisp | 251 lines | 164 code | 18 blank | 69 comment | 1 complexity | 748fd69427535193cdd26a2a2e481051 MD5 | raw file
Possible License(s): GPL-2.0
  1. ;;; sb-info --- Speedbar support for Info
  2. ;; Copyright (C) 1997, 1998, 2000, 2001, 2002 Free Software Foundation
  3. ;;
  4. ;; Author: Eric M. Ludlam <zappo@gnu.ai.mit.edu>
  5. ;; Version: 0.3
  6. ;; Keywords: file, tags, tools
  7. ;; X-RCS: $Id: sb-info.el,v 1.18 2002/03/16 20:07:19 zappo Exp $
  8. ;;
  9. ;; This file is patch of GNU Emacs.
  10. ;;
  11. ;; This program is free software; you can redistribute it and/or modify
  12. ;; it under the terms of the GNU General Public License as published by
  13. ;; the Free Software Foundation; either version 2, or (at your option)
  14. ;; any later version.
  15. ;;
  16. ;; This program is distributed in the hope that it will be useful,
  17. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. ;; GNU General Public License for more details.
  20. ;;
  21. ;; You should have received a copy of the GNU General Public License
  22. ;; along with this program; if not, you can either send email to this
  23. ;; program's author (see below) or write to:
  24. ;;
  25. ;; The Free Software Foundation, Inc.
  26. ;; 675 Mass Ave.
  27. ;; Cambridge, MA 02139, USA.
  28. ;;
  29. ;; Please send bug reports, etc. to zappo@gnu.org
  30. ;;
  31. ;;; Commentary:
  32. ;;
  33. ;; Speedbar provides a frame in which files, and locations in
  34. ;; files are displayed. These functions provide Info specific support,
  35. ;; showing links and addresses in the side-bar.
  36. ;;
  37. ;; To enable in Emacs 20.2 or earlier, add this to your .emacs file.
  38. ;; (autoload 'Info-speedbar-buttons "sb-info"
  39. ;; "Info specific speedbar button generator.")
  40. ;;
  41. ;; This file requires speedbar and Info.
  42. ;;; Change log:
  43. ;; 0.1 - first revision copied from speedbspec.el V 0.1.1
  44. ;; 0.1.1 - No longer require speedbspec
  45. ;; 0.2 - Added a speedbar major mode for displaying Info nodes, and modeled
  46. ;; the minor mode after it. Completely replaced the old info display
  47. ;; with the major mode, and mixed them to move nicely from major to
  48. ;; minor mode effortlessly.
  49. ;; 0.2.1 Added section adding major display mode at load time.
  50. (require 'speedbar)
  51. (require 'info)
  52. ;;; Code:
  53. (defvar Info-speedbar-key-map nil
  54. "Keymap used when in the info display mode.")
  55. (defun Info-install-speedbar-variables ()
  56. "Install those variables used by speedbar to enhance Info."
  57. (if Info-speedbar-key-map
  58. nil
  59. (setq Info-speedbar-key-map (speedbar-make-specialized-keymap))
  60. ;; Basic tree features
  61. (define-key Info-speedbar-key-map "e" 'speedbar-edit-line)
  62. (define-key Info-speedbar-key-map "\C-m" 'speedbar-edit-line)
  63. (define-key Info-speedbar-key-map "+" 'speedbar-expand-line)
  64. (define-key Info-speedbar-key-map "=" 'speedbar-expand-line)
  65. (define-key Info-speedbar-key-map "-" 'speedbar-contract-line)
  66. (define-key Info-speedbar-key-map " " 'speedbar-toggle-line-expansion)
  67. )
  68. (speedbar-add-expansion-list '("Info" Info-speedbar-menu-items
  69. Info-speedbar-key-map
  70. Info-speedbar-hierarchy-buttons)))
  71. (defvar Info-speedbar-menu-items
  72. '(["Browse Node" speedbar-edit-line t]
  73. ["Expand Node" speedbar-expand-line
  74. (save-excursion (beginning-of-line)
  75. (looking-at "[0-9]+: *.\\+. "))]
  76. ["Contract Node" speedbar-contract-line
  77. (save-excursion (beginning-of-line)
  78. (looking-at "[0-9]+: *.-. "))]
  79. )
  80. "Additional menu-items to add to speedbar frame.")
  81. ;; Make sure our special speedbar major mode is loaded
  82. (if (featurep 'speedbar)
  83. (Info-install-speedbar-variables)
  84. (add-hook 'speedbar-load-hook 'Info-install-speedbar-variables))
  85. ;;; Info hierarchy display method
  86. ;;;###autoload
  87. (defun Info-speedbar-browser ()
  88. "Initialize speedbar to display an info node browser.
  89. This will add a speedbar major display mode."
  90. (interactive)
  91. (require 'speedbar)
  92. ;; Make sure that speedbar is active
  93. (speedbar-frame-mode 1)
  94. ;; Now, throw us into Info mode on speedbar.
  95. (speedbar-change-initial-expansion-list "Info")
  96. )
  97. (defvar Info-speedbar-image-button-alist
  98. '(("<+>" . speedbar-document-plus)
  99. ("<->" . speedbar-document-minus)
  100. ("[+]" . speedbar-page-plus)
  101. ("[-]" . speedbar-page-minus)
  102. ("[?]" . speedbar-page)
  103. ("[ ]" . speedbar-page)
  104. )
  105. "Image buttons used for Info mode.")
  106. (defun Info-speedbar-hierarchy-buttons (directory depth &optional node)
  107. "Display an Info directory hierarchy in speedbar.
  108. DIRECTORY is the current directory in the attached frame.
  109. DEPTH is the current indentation depth.
  110. NODE is an optional argument that is used to represent the
  111. specific node to expand."
  112. (if (and (not node)
  113. (save-excursion (goto-char (point-min))
  114. (looking-at "Info Nodes:")))
  115. ;; Update our "current node" maybe?
  116. nil
  117. ;; We cannot use the generic list code, that depends on all leaves
  118. ;; being known at creation time.
  119. (if (not node)
  120. (speedbar-with-writable (insert "Info Nodes:\n")))
  121. (let ((completions nil)
  122. (speedbar-expand-image-button-alist
  123. Info-speedbar-image-button-alist))
  124. (dframe-select-attached-frame speedbar-frame)
  125. (save-window-excursion
  126. (setq completions
  127. (Info-speedbar-fetch-file-nodes (or node '"(dir)top"))))
  128. (select-frame speedbar-frame)
  129. (if completions
  130. (speedbar-with-writable
  131. (while completions
  132. (speedbar-make-tag-line (if (= depth 0)
  133. 'angle
  134. 'bracket)
  135. ?+ 'Info-speedbar-expand-node
  136. (cdr (car completions))
  137. (car (car completions))
  138. 'Info-speedbar-goto-node
  139. (cdr (car completions))
  140. 'info-xref depth)
  141. (setq completions (cdr completions)))
  142. t)
  143. nil))))
  144. (defun Info-speedbar-goto-node (text node indent)
  145. "When user clicks on TEXT, goto an info NODE.
  146. The INDENT level is ignored."
  147. (dframe-select-attached-frame speedbar-frame)
  148. (let* ((buff (or (get-buffer "*info*")
  149. (progn (info) (get-buffer "*info*"))))
  150. (bwin (get-buffer-window buff 0)))
  151. (if bwin
  152. (progn
  153. (select-window bwin)
  154. (raise-frame (window-frame bwin)))
  155. (if dframe-power-click
  156. (let ((pop-up-frames t)) (select-window (display-buffer buff)))
  157. (dframe-select-attached-frame speedbar-frame)
  158. (switch-to-buffer buff)))
  159. (if (string-match "^(\\([^)]+\\))\\([^,:]+\\)$" node)
  160. (let ((file (match-string 1 node))
  161. (node (match-string 2 node)))
  162. (Info-find-node file node)
  163. ;; If we do a find-node, and we were in info mode, restore
  164. ;; the old default method. Once we are in info mode, it makes
  165. ;; sense to return to whatever method the user was using before.
  166. (if (string= speedbar-initial-expansion-list-name "Info")
  167. (speedbar-change-initial-expansion-list
  168. speedbar-previously-used-expansion-list-name))))))
  169. (defun Info-speedbar-expand-node (text token indent)
  170. "Expand the node the user clicked on.
  171. TEXT is the text of the button we clicked on, a + or - item.
  172. TOKEN is data related to this node (NAME . FILE).
  173. INDENT is the current indentation depth."
  174. (let ((speedbar-expand-image-button-alist Info-speedbar-image-button-alist))
  175. (cond ((string-match "+" text) ;we have to expand this file
  176. (speedbar-change-expand-button-char ?-)
  177. (if (speedbar-with-writable
  178. (save-excursion
  179. (end-of-line) (forward-char 1)
  180. (Info-speedbar-hierarchy-buttons nil (1+ indent) token)))
  181. (speedbar-change-expand-button-char ?-)
  182. (speedbar-change-expand-button-char ??)))
  183. ((string-match "-" text) ;we have to contract this node
  184. (speedbar-change-expand-button-char ?+)
  185. (speedbar-delete-subblock indent))
  186. (t (error "Ooops... not sure what to do")))
  187. (speedbar-center-buffer-smartly)))
  188. (defun Info-speedbar-fetch-file-nodes (nodespec)
  189. "Fetch the subnodes from the info NODESPEC.
  190. NODESPEC is a string of the form: (file)node.
  191. Optional THISFILE represends the filename of"
  192. (save-excursion
  193. ;; Set up a buffer we can use to fake-out Info.
  194. (set-buffer (get-buffer-create "*info-browse-tmp*"))
  195. (if (not (equal major-mode 'Info-mode))
  196. (Info-mode))
  197. ;; Get the node into this buffer
  198. (if (string-match "^(\\([^)]+\\))\\([^,:]+\\)$" nodespec)
  199. (let ((file (match-string 1 nodespec))
  200. (node (match-string 2 nodespec)))
  201. (Info-find-node file node))
  202. (error "Node %s not found!" nodespec))
  203. ;; Scan the created buffer
  204. (goto-char (point-min))
  205. (let ((completions nil)
  206. (thisfile (progn (string-match "^(\\([^)]+\\))" nodespec)
  207. (match-string 1 nodespec))))
  208. ;; Always skip the first one...
  209. (re-search-forward "\n\\* \\([^:\t\n]*\\):" nil t)
  210. (while (re-search-forward "\n\\* \\([^:\t\n]*\\):" nil t)
  211. (let ((name (match-string 1)))
  212. (if (looking-at " *\\(([^)]+)[^.\n]+\\)\\.")
  213. (setq name (cons name (match-string 1)))
  214. (if (looking-at "[ \t]*\\(([^)]+)\\)\\.")
  215. (setq name (cons name (concat (match-string 1) "Top")))
  216. (if (looking-at " \\([^.]+\\).")
  217. (setq name
  218. (cons name (concat "(" thisfile ")" (match-string 1))))
  219. (setq name (cons name (concat "(" thisfile ")" name))))))
  220. (setq completions (cons name completions))))
  221. (nreverse completions))))
  222. ;;; Info mode node listing
  223. ;;;###autoload
  224. (defun Info-speedbar-buttons (buffer)
  225. "Create a speedbar display to help navigation in an Info file.
  226. BUFFER is the buffer speedbar is requesting buttons for."
  227. (if (save-excursion (goto-char (point-min))
  228. (not (looking-at "Info Nodes:")))
  229. (erase-buffer))
  230. (Info-speedbar-hierarchy-buttons nil 0)
  231. )
  232. (provide 'sb-info)
  233. ;;; sb-info.el ends here