Add one dir to magit-repo-dirs
[emacs.git] / .emacs.d / elisp / idomenu / idomenu.el
1 ;;; idomenu.el --- imenu tag selection a la ido
2 ;;
3 ;; Copyright (C) 2010 Georg Brandl
4 ;;
5 ;; Author: Georg Brandl <georg@python.org>
6 ;; Version: 20111122.1048
7 ;; X-Original-Version: 0.1
8 ;;
9 ;; This file is NOT part of GNU Emacs.
10 ;;
11 ;; This program is free software; you can redistribute it and/or
12 ;; modify it under the terms of the GNU General Public License
13 ;; as published by the Free Software Foundation; either version 2
14 ;; of the License, or (at your option) 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, see <http://www.gnu.org/licenses/>.
23 ;;
24 ;;; Commentary:
25 ;;
26 ;; This package provides the `idomenu' command for selecting an imenu tag using
27 ;; ido completion. The buffer needs to have support for imenu already enabled.
28 ;;
29 ;; Add something like the following to your .emacs:
30 ;;
31 ;; (autoload 'idomenu "idomenu" nil t)
32 ;;
33 ;;; Code:
34
35 (require 'ido)
36 (require 'imenu)
37
38 (defun idomenu--guess-default (index-alist symbol)
39 "Guess a default choice from the given symbol."
40 (catch 'found
41 (let ((regex (concat "\\_<" (regexp-quote symbol) "\\_>")))
42 (dolist (item index-alist)
43 (if (string-match regex (car item)) (throw 'found (car item)))))))
44
45 (defun idomenu--read (index-alist &optional prompt guess)
46 "Read a choice from an Imenu alist via Ido."
47 (let* ((symatpt (thing-at-point 'symbol))
48 (default (and guess symatpt (idomenu--guess-default index-alist symatpt)))
49 (names (mapcar 'car index-alist))
50 (name (ido-completing-read (or prompt "imenu ") names
51 nil t nil nil default))
52 (choice (assoc name index-alist)))
53 (if (imenu--subalist-p choice)
54 (idomenu--read (cdr choice) prompt nil)
55 choice)))
56
57 (defun idomenu--trim (str)
58 "Trim leading and tailing whitespace from STR."
59 (let ((s (if (symbolp str) (symbol-name str) str)))
60 (replace-regexp-in-string "\\(^[[:space:]\n]*\\|[[:space:]\n]*$\\)" "" s)))
61
62 (defun idomenu--trim-alist (index-alist)
63 "There must be a better way to apply a function to all cars of an alist"
64 (mapcar (lambda (pair) (cons (idomenu--trim (car pair)) (cdr pair)))
65 index-alist))
66
67 ;;;###autoload
68 (defun idomenu ()
69 "Switch to a buffer-local tag from Imenu via Ido."
70 (interactive)
71 ;; ido initialization
72 (ido-init-completion-maps)
73 (add-hook 'minibuffer-setup-hook 'ido-minibuffer-setup)
74 (add-hook 'choose-completion-string-functions 'ido-choose-completion-string)
75 (add-hook 'kill-emacs-hook 'ido-kill-emacs-hook)
76 ;; set up ido completion list
77 (let ((index-alist (cdr (imenu--make-index-alist))))
78 (if (equal index-alist '(nil))
79 (message "No imenu tags in buffer")
80 (imenu (idomenu--read (idomenu--trim-alist index-alist) nil t)))))
81
82 (provide 'idomenu)
83 ;;; idomenu.el ends here