1 ;;; org-elisp-symbol.el --- Org links to emacs-lisp symbols
3 ;; Copyright 2007 Bastien Guerry
5 ;; Author: bzg AT altern DOT org
7 ;; Keywords: org, remember, lisp
8 ;; URL: http://www.cognition.ens.fr/~guerry/u/org-elisp-symbol.el
10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with this program; if not, write to the Free Software
22 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 ;; Org-mode already lets you store/insert links to emacs-lisp files,
27 ;; just like any other file. This package lets you precisely link to
28 ;; any emacs-lisp symbol and access uesful information about the symbol.
30 ;; Here is the list of available properties when linking from a elisp-symbol:
32 ;; :name The symbol's name.
33 ;; :stype The symbol's type (commandp, function, etc.)
34 ;; :def The function used to set the symbol's value (defun, etc.)
35 ;; :keys The keys associated with the command.
36 ;; :args The arguments of the function.
37 ;; :docstring The docstring of the symbol.
38 ;; :doc The first line of the dostring.
39 ;; :comment A comment line just above the sexp, if any.
40 ;; :fixme A FIXME comment line just above the sexp, if any.
42 ;; Let's say we have a defun like this one:
44 ;; ;; FIXME update docstring
45 ;; (defun org-export-latex-lists ()
46 ;; "Convert lists to LaTeX."
47 ;; (goto-char (point-min))
48 ;; (while (re-search-forward org-export-latex-list-beginning-re nil t)
49 ;; (beginning-of-line)
50 ;; (insert (org-list-to-latex (org-list-parse-list t)) "\n")))
52 ;; And a remember template like:
54 ;; (setq org-remember-templates
55 ;; '((?s "* DEBUG `%:name' (%:args)\n\n%?\n\nFixme: %:fixme\n \
56 ;; Doc: \"%:doc\"\n\n%a")))
58 ;; Then M-x `org-remember' on this sexp will produce this buffer:
60 ;; =====================================================================
61 ;; * DEBUG `org-export-latex-lists' ()
65 ;; Fixme: update the docstring
66 ;; Doc: "Convert lists to LaTeX."
68 ;; [[file:~/path/file.el::defun%20my-func][Function: my-func]]
69 ;; =====================================================================
71 ;; Put this file into your load-path and the following into your ~/.emacs:
72 ;; (require 'org-elisp-symbol)
76 (provide 'org-elisp-symbol
)
80 (org-add-link-type "elisp-symbol" 'org-elisp-symbol-open
)
81 (add-hook 'org-store-link-functions
'org-elisp-symbol-store-link
)
83 (defun org-elisp-symbol-open (path)
84 "Visit the emacs-lisp elisp-symbol at PATH."
85 (let* ((search (when (string-match "::\\(.+\\)\\'" path
)
86 (match-string 1 path
)))
87 (path (substring path
0 (match-beginning 0))))
88 (org-open-file path t nil search
)))
90 (defun org-elisp-symbol-store-link ()
91 "Store a link to an emacs-lisp elisp-symbol."
92 (when (eq major-mode
'emacs-lisp-mode
)
94 (or (looking-at "^(") (beginning-of-defun))
95 (looking-at "^(\\([a-z]+\\) \\([^)\n ]+\\) ?\n?[ \t]*\\(?:(\\(.*\\))\\)?")
96 (let* ((end (save-excursion
98 (end-of-defun) (point))))
99 (def (match-string 1))
100 (name (match-string 2))
101 (sym-name (intern-soft name
))
102 (stype (cond ((commandp sym-name
) "Command")
103 ((functionp sym-name
) "Function")
104 ((user-variable-p sym-name
) "User variable")
105 ((eq def
"defvar") "Variable")
106 ((eq def
"defmacro") "Macro")
108 (args (if (match-string 3)
109 (mapconcat (lambda (a) (unless (string-match "^&" a
) a
))
110 (split-string (match-string 3)) " ")
112 (docstring (cond ((functionp sym-name
)
113 (or (documentation sym-name
)
114 "[no documentation]"))
115 ((string-match "[Vv]ariable" stype
)
116 (documentation-property sym-name
117 'variable-documentation
))
118 (t "no documentation")))
119 (doc (and (string-match "^\\([^\n]+\\)$" docstring
)
120 (match-string 1 docstring
)))
121 (fixme (save-excursion
122 (beginning-of-defun) (end-of-defun)
123 (if (re-search-forward "^;+ ?FIXME[ :]*\\(.*\\)$" end t
)
124 (match-string 1) "nothing to fix")))
125 (comment (save-excursion
126 (beginning-of-defun) (end-of-defun)
127 (if (re-search-forward "^;;+ ?\\(.*\\)$" end t
)
128 (match-string 1) "no comment")))
129 keys keys-desc link description
)
130 (if (equal stype
"Command")
131 (setq keys
(where-is-internal sym-name
)
133 (if keys
(mapconcat 'key-description keys
" ") "none")))
134 (setq link
(concat "file:" (abbreviate-file-name buffer-file-name
)
136 (setq description
(concat stype
": " name
))
137 (org-store-link-props
140 :description description
149 :comment comment
)))))
151 (provide 'org-elisp-symbol
)
154 ;;;;##########################################################################
155 ;;;; User Options, Variables
156 ;;;;##########################################################################
159 ;;; org-elisp-symbol.el ends here