Merge branch 'master' of git+ssh://repo.or.cz/srv/git/org-mode
[org-mode.git] / lisp / org-complete.el
bloba9fed9940b7c2d3a1cd3ab30dab9b13cb989651b
1 ;;; org-complete.el --- In-buffer completion code
3 ;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;;
6 ;; Author: Carsten Dominik <carsten at orgmode dot org>
7 ;; John Wiegley <johnw at gnu dot org>
8 ;; Keywords: outlines, hypermedia, calendar, wp
9 ;; Homepage: http://orgmode.org
10 ;; Version: 7.03trans
12 ;; This file is part of GNU Emacs.
14 ;; GNU Emacs is free software: you can redistribute it and/or modify
15 ;; it under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation, either version 3 of the License, or
17 ;; (at your option) any later version.
19 ;; GNU Emacs is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ;; GNU General Public License for more details.
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
26 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28 ;;; Code:
30 ;;;; Require other packages
32 (eval-when-compile
33 (require 'cl))
35 (require 'org-macs)
36 (require 'pcomplete)
38 ;;;; Customization variables
40 (defgroup org-complete nil
41 "Outline-based notes management and organizer."
42 :tag "Org"
43 :group 'org)
45 (defun org-thing-at-point ()
46 "Examine the thing at point and let the caller know what it is.
47 The return value is a string naming the thing at point."
48 (let ((beg1 (save-excursion
49 (skip-chars-backward (org-re "[:alnum:]_@"))
50 (point)))
51 (beg (save-excursion
52 (skip-chars-backward "a-zA-Z0-9_:$")
53 (point)))
54 (line-to-here (buffer-substring (point-at-bol) (point))))
55 (cond
56 ((string-match "\\`[ \t]*#\\+begin: clocktable[ \t]+" line-to-here)
57 (cons "block-option" "clocktable"))
58 ((string-match "\\`[ \t]*#\\+begin_src[ \t]+" line-to-here)
59 (cons "block-option" "src"))
60 ((save-excursion
61 (re-search-backward "^[ \t]*#\\+\\([A-Z_]+\\):.*"
62 (line-beginning-position) t))
63 (cons "file-option" (match-string-no-properties 1)))
64 ((string-match "\\`[ \t]*#\\+[a-zA-Z]*\\'" line-to-here)
65 (cons "file-option" nil))
66 ((equal (char-before beg) ?\[)
67 (cons "link" nil))
68 ((equal (char-before beg) ?\\)
69 (cons "tex" nil))
70 ((string-match "\\`\\*+[ \t]+\\'"
71 (buffer-substring (point-at-bol) beg))
72 (cons "todo" nil))
73 ((equal (char-before beg) ?*)
74 (cons "searchhead" nil))
75 ((and (equal (char-before beg1) ?:)
76 (equal (char-after (point-at-bol)) ?*))
77 (cons "tag" nil))
78 ((and (equal (char-before beg1) ?:)
79 (not (equal (char-after (point-at-bol)) ?*)))
80 (cons "prop" nil))
81 (t nil))))
83 (defun org-command-at-point ()
84 "Return the qualified name of the Org completion entity at point.
85 When completing for #+STARTUP, for example, this function returns
86 \"file-option/startup\"."
87 (let ((thing (org-thing-at-point)))
88 (cond
89 ((string= "file-option" (car thing))
90 (concat (car thing) "/" (downcase (cdr thing))))
91 ((string= "block-option" (car thing))
92 (concat (car thing) "/" (downcase (cdr thing))))
94 (car thing)))))
96 (defun org-parse-arguments ()
97 "Parse whitespace separated arguments in the current region."
98 (let ((begin (line-beginning-position))
99 (end (line-end-position))
100 begins args)
101 (save-restriction
102 (narrow-to-region begin end)
103 (save-excursion
104 (goto-char (point-min))
105 (while (not (eobp))
106 (skip-chars-forward " \t\n[")
107 (setq begins (cons (point) begins))
108 (skip-chars-forward "^ \t\n[")
109 (setq args (cons (buffer-substring-no-properties
110 (car begins) (point))
111 args)))
112 (cons (reverse args) (reverse begins))))))
115 (defun org-complete-initial ()
116 "Calls the right completion function for first argument completions."
117 (ignore
118 (funcall (or (pcomplete-find-completion-function
119 (car (org-thing-at-point)))
120 pcomplete-default-completion-function))))
122 (defun pcomplete/org-mode/file-option ()
123 "Complete against all valid file options."
124 (require 'org-exp)
125 (pcomplete-here
126 (org-complete-case-double
127 (mapcar (lambda (x)
128 (if (= ?: (aref x (1- (length x))))
129 (concat x " ")
131 (delq nil
132 (pcomplete-uniqify-list
133 (append
134 (mapcar (lambda (x)
135 (if (string-match "^#\\+\\([A-Z_]+:?\\)" x)
136 (match-string 1 x)))
137 (org-split-string (org-get-current-options) "\n"))
138 org-additional-option-like-keywords)))))
139 (substring pcomplete-stub 2)))
141 (defun pcomplete/org-mode/file-option/startup ()
142 "Complete arguments for the #+STARTUP file option."
143 (while (pcomplete-here
144 (let ((opts (pcomplete-uniqify-list
145 (mapcar 'car org-startup-options))))
146 ;; Some options are mutually exclusive, and shouldn't be completed
147 ;; against if certain other options have already been seen.
148 (dolist (arg pcomplete-args)
149 (cond
150 ((string= arg "hidestars")
151 (setq opts (delete "showstars" opts)))))
152 opts))))
154 (defun pcomplete/org-mode/file-option/bind ()
155 "Complete arguments for the #+BIND file option, which are variable names"
156 (let (vars)
157 (mapatoms
158 (lambda (a) (if (boundp a) (setq vars (cons (symbol-name a) vars)))))
159 (pcomplete-here vars)))
161 (defun pcomplete/org-mode/link ()
162 "Complete against defined #+LINK patterns."
163 (pcomplete-here
164 (pcomplete-uniqify-list (append (mapcar 'car org-link-abbrev-alist-local)
165 (mapcar 'car org-link-abbrev-alist)))))
167 (defun pcomplete/org-mode/tex ()
168 "Complete against TeX-style HTML entity names."
169 (require 'org-entities)
170 (while (pcomplete-here
171 (pcomplete-uniqify-list (remove nil (mapcar 'car-safe org-entities)))
172 (substring pcomplete-stub 1))))
174 (defun pcomplete/org-mode/todo ()
175 "Complete against known TODO keywords."
176 (pcomplete-here (pcomplete-uniqify-list org-todo-keywords-1)))
178 (defun pcomplete/org-mode/searchhead ()
179 "Complete against all headings.
180 This needs more work, to handle headings with lots of spaces in them."
181 (while
182 (pcomplete-here
183 (save-excursion
184 (goto-char (point-min))
185 (let (tbl)
186 (while (re-search-forward org-todo-line-regexp nil t)
187 (push (org-make-org-heading-search-string
188 (match-string-no-properties 3) t)
189 tbl))
190 (pcomplete-uniqify-list tbl)))
191 (substring pcomplete-stub 1))))
193 (defun pcomplete/org-mode/tag ()
194 "Complete a tag name. Omit tags already set."
195 (while (pcomplete-here
196 (mapcar (lambda (x)
197 (concat x ":"))
198 (let ((lst (pcomplete-uniqify-list
199 (or (remove
201 (mapcar (lambda (x)
202 (and (stringp (car x)) (car x)))
203 org-tag-alist))
204 (mapcar 'car (org-get-buffer-tags))))))
205 (dolist (tag (org-get-tags))
206 (setq lst (delete tag lst)))
207 lst))
208 (and (string-match ".*:" pcomplete-stub)
209 (substring pcomplete-stub (match-end 0))))))
211 (defun pcomplete/org-mode/prop ()
212 "Complete a property name. Omit properties already set."
213 (pcomplete-here
214 (mapcar (lambda (x)
215 (concat x ": "))
216 (let ((lst (pcomplete-uniqify-list
217 (org-buffer-property-keys nil t t))))
218 (dolist (prop (org-entry-properties))
219 (setq lst (delete (car prop) lst)))
220 lst))
221 (substring pcomplete-stub 1)))
223 (defun pcomplete/org-mode/block-option/src ()
224 "Complete the arguments of a begin_src block.
225 Complete a language in the first field, the header arguments and switches."
226 (pcomplete-here
227 (mapcar
228 (lambda(x) (symbol-name (nth 3 x)))
229 (cdr (car (cdr (memq :key-type (plist-get
230 (symbol-plist
231 'org-babel-load-languages)
232 'custom-type)))))))
233 (while (pcomplete-here
234 '("-n" "-r" "-l"
235 ":cache" ":colnames" ":comments" ":dir" ":eval" ":exports"
236 ":file" ":hlines" ":no-expand" ":noweb" ":results" ":rownames"
237 ":session" ":shebang" ":tangle" ":var"))))
239 (defun pcomplete/org-mode/block-option/clocktable ()
240 "Complete keywords in a clocktable line"
241 (while (pcomplete-here '(":maxlevel" ":scope"
242 ":tstart" ":tend" ":block" ":step"
243 ":stepskip0" ":fileskip0"
244 ":emphasize" ":link" ":narrow" ":indent"
245 ":tcolumns" ":level" ":compact" ":timestamp"
246 ":formula" ":formatter"))))
248 (defun org-complete-case-double (list)
249 "Return list with both upcase and downcase version of all strings in LIST."
250 (let (e res)
251 (while (setq e (pop list))
252 (setq res (cons (downcase e) (cons (upcase e) res))))
253 (nreverse res)))
255 ;;;; Finish up
257 (provide 'org-complete)
259 ;; arch-tag:
261 ;;; org-complete.el ends here