initial version of bigclean-emacs,from svn to git
[bigclean-emacs.git] / emacs / .emacs.d / site-lisp / auto-complete.el
blobcdc4e862c04547a5df107ec181ad4f374f661efe
1 ;;; auto-complete.el --- Inline auto completion
3 ;; Copyright (C) 2008, 2009 MATSUYAMA Tomohiro
5 ;; Author: MATSUYAMA Tomohiro <t.matsuyama.pub@gmail.com>
6 ;; Keywords: convenience
7 ;; Version: 0.2.0
9 ;; This program is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation, either version 3 of the License, or
12 ;; (at your option) any later version.
14 ;; This program is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
22 ;;; Commentary:
24 ;; This extension provides a way to complete with popup menu like:
26 ;; def-!-
27 ;; +-----------------+
28 ;; |defun::::::::::::|
29 ;; |defvar |
30 ;; |defmacro |
31 ;; | ... |
32 ;; +-----------------+
34 ;; You can complete by typing and selecting menu.
35 ;; Enjoy!
37 ;;; Qualification:
39 ;; This extension can work property on GNU Emacs 22 or higher.
41 ;;; Installation:
43 ;; To use this extension, locate all .el files of this package to your load-path directory.
45 ;; $ cp auto-complete-x.x.x/*.el ~/.emacs.d/
47 ;; And write following code into your .emacs.
49 ;; (require 'auto-complete)
50 ;; (global-auto-complete-mode t)
52 ;;; Tips:
54 ;; Use C-n/C-p to select candidates
55 ;; --------------------------------
57 ;; Add following code to your .emacs.
58 ;;
59 ;; (define-key ac-complete-mode-map "\C-n" 'ac-next)
60 ;; (define-key ac-complete-mode-map "\C-p" 'ac-previous)
63 ;; Don't start completion automatically
64 ;; ------------------------------------
66 ;; Add following code to your .emacs.
68 ;; (setq ac-auto-start nil)
69 ;; (global-set-key "\M-/" 'ac-start)
71 ;; or
73 ;; ;; start completion when entered 3 characters
74 ;; (setq ac-auto-start 3)
77 ;; Stop completion
78 ;; ---------------
80 ;; Add following code to your .emacs.
82 ;; (define-key ac-complete-mode-map "\M-/" 'ac-stop)
84 ;; Now you can stop completion by pressing M-/.
87 ;; Completion by TAB
88 ;; -----------------
90 ;; Add following code to your .emacs.
92 ;; (define-key ac-complete-mode-map "\t" 'ac-complete)
93 ;; (define-key ac-complete-mode-map "\r" nil)
96 ;; Do What I Mean mode
97 ;; -------------------
99 ;; If DWIM (Do What I Mean) mode is enabled,
100 ;; the following features is available:
102 ;; a. TAB (ac-expand) behave as completion (ac-complete)
103 ;; when only one candidate is left
104 ;; b. TAB (ac-expand) behave as completion (ac-complete)
105 ;; after you select candidate
106 ;; c. Disapear automatically when you
107 ;; complete a candidate.
109 ;; DWIM mode is enabled by default.
110 ;; You can enable this feature by
111 ;; setting `ac-dwim' to t.
113 ;; (setq ac-dwim t)
116 ;; Change default sources
117 ;; ----------------------
119 ;; (setq-default ac-sources '(ac-source-abbrev ac-source-words-in-buffer))
122 ;; Change sources for particular mode
123 ;; ----------------------------------
125 ;; (add-hook 'emacs-lisp-mode-hook
126 ;; (lambda ()
127 ;; (setq ac-sources '(ac-source-words-in-buffer ac-source-symbols))))
129 ;;; History:
131 ;; 2008-03-18
132 ;; * auto-complete.el 0.2.0 released
134 ;; 2008-03-04
135 ;; * fixed menu position bug
137 ;; 2008-03-02
138 ;; * made a source be able to be just a function which returns candidates
139 ;; * added ac-source-words-in-all-buffer
141 ;; 2008-03-01
142 ;; * added basic cache facility
144 ;; 2008-02-20
145 ;; * fixed menu position bug at long line (thanks rubikitch <rubikitch@ruby-lang.org>)
146 ;; * made dictionary source generator (ac-define-dictionary-source)
147 ;; * devided into some files (auto-complete-ruby.el, auto-complete-yasnippet.el, etc)
149 ;; 2008-02-19
150 ;; * added ac-trigger-commands switch
152 ;; 2008-02-10
153 ;; * added ac-stop function (suggestion from Andy Stewart)
154 ;; * added ac-override-local-map switch (suggestion from Andy Stewart)
156 ;; 2008-02-03
157 ;; * omni completion redesign
158 ;; * ac-sources is now buffer local for every buffer
159 ;; * fixed a menu position bug (thanks Andy Stewart)
160 ;; * fixed byte-compile warnings (thanks Andy Stewart)
162 ;; 2008-01-22
163 ;; * added face/selection-face property for sources
164 ;; * supported menu scroll
166 ;; 2008-01-20
167 ;; * omni completion
169 ;; 2008-12-24
170 ;; * suppress errors on command hook
172 ;; 2008-12-03
173 ;; * changed ac-dwim to nil by default
174 ;; * made menu to be able to adjust width
176 ;; 2008-12-03
177 ;; * renamed ac-find-function to ac-prefix-function
178 ;; * renamed ac-target to ac-prefix
180 ;; 2008-11-26
181 ;; * auto-complete.el 0.1.0 released
183 ;; 2008-11-19
184 ;; * thanks for Taiki SUGAWARA <buzz.taiki@gmail.com>
185 ;; * added source ac-source-abbrev
186 ;; * added source ac-source-symbols
187 ;; * added ac-expand-common to expand common part
189 ;; 2008-11-18
190 ;; * added ac-auto-start switch
191 ;; * added ac-dwim switch
192 ;; * changed menu popup behavior at end of window
193 ;; * thanks rubikitch <rubikitch@ruby-lang.org>, kazu-yamamoto.
194 ;; * fixed canceler bug
195 ;; * changed to use overriding-local-map instead of minor mode map
196 ;; * changed default key bindings
198 ;; 2008-11-16
199 ;; * supported candidates by using sources
200 ;; * added automatically start swtich
201 ;; * fixed some bug
202 ;; * added source ac-source-files-in-current-dir
203 ;; * added source ac-source-words-in-buffer
204 ;; * added source ac-source-yasnippet
205 ;; * renamed ac-enum-candidates-function to ac-candidate-function
206 ;; * renamed ac-find-target-function to ac-find-function
207 ;; * ac-find-function and ac-candidate-function is not buffer local variable now
208 ;; * made candidates visible when you are end of line
210 ;; 2008-11-11
211 ;; * by reporting from rubikitch <rubikitch@ruby-lang.org>
212 ;; * renamed hook name
213 ;; * registered backward-delete-char as special command
214 ;; * fixed code for creating candidates
215 ;; * made auto-complete disabled when isearch-mode enabled
216 ;; * added some major-mode into ac-modes
218 ;; 2008-11-09
219 ;; * auto-complete.el 0.0.1 released
220 ;; * fixed double-width character displaying problem
221 ;; * fixed menu position following tab character
222 ;; * made candidates visible when you are end of window
224 ;;; TODO:
226 ;; - test facility
227 ;; - support composed chars
228 ;; - fuzzy match
229 ;; - minibuffer completion
230 ;; - dictionary
231 ;; - documentation
232 ;; - performance issue (cache issue)
233 ;; - fix narrowing bug (reported by Yuto Hayamizu <y.hayamizu@gmail.com>)
234 ;; - care about undo (buffer-disable-undo)
235 ;; - scroll bar (visual)
236 ;; - show description
237 ;; - semantic
238 ;; - use cl
239 ;; - icon
240 ;; - refactoring (especially menu)
241 ;; - linum.el bug (reported by Andy Stewart)
242 ;; - flymake bug (reported by TiagoCamargo)
244 ;;; Code:
248 (defgroup auto-complete nil
249 "Auto completion with popup menu"
250 :group 'convenience
251 :prefix "auto-complete-")
253 (defcustom ac-candidate-menu-height 10
254 "Max height of candidate menu."
255 :type 'number
256 :group 'auto-complete)
258 (defcustom ac-candidate-max 10
259 "Max of number of candidates."
260 :type 'number
261 :group 'auto-complete)
263 (defcustom ac-modes
264 '(emacs-lisp-mode lisp-interaction-mode
265 c-mode cc-mode c++-mode java-mode
266 perl-mode cperl-mode python-mode ruby-mode
267 ecmascript-mode javascript-mode js2-mode php-mode css-mode
268 makefile-mode sh-mode fortran-mode f90-mode ada-mode
269 xml-mode sgml-mode)
270 "Major modes `auto-complete-mode' can run on."
271 :type '(list symbol)
272 :group 'auto-complete)
274 (defcustom ac-trigger-commands
275 '(self-insert-command)
276 "Trigger commands that specify whether `auto-complete' should start or not."
277 :type '(list symbol)
278 :group 'auto-complete)
280 (defcustom ac-auto-start t
281 "Non-nil means completion will be started automatically.
282 Positive integer means if a length of a word you entered is larger than the value,
283 completion will be started automatically.
284 If you specify `nil', never be started automatically."
285 :group 'auto-complete)
287 (defcustom ac-dwim nil
288 "Non-nil means `auto-complete' works based on Do What I Mean."
289 :type 'boolean
290 :group 'auto-complete)
292 (defcustom ac-override-local-map nil
293 "Non-nil mean use `ac-complete-mode-map' override local map.
294 Please set it to non-nil only if you faced to some problem about
295 minor-mode keymap conflicts."
296 :type 'boolean
297 :group 'auto-complete)
299 (defface ac-candidate-face
300 '((t (:background "lightgray" :foreground "black")))
301 "Face for candidate."
302 :group 'auto-complete)
304 (defface ac-selection-face
305 '((t (:background "blue" :foreground "white")))
306 "Face for the selected candidate."
307 :group 'auto-complete)
309 (defvar auto-complete-mode-hook nil
310 "Hook for `auto-complete-mode'.")
312 (defvar ac-menu nil
313 "Menu instance.")
315 (defvar ac-menu-direction 1
316 "Positive integer means `ac-menu' grows forward.
317 Or, `ac-menu' grows backward.")
319 (defvar ac-menu-offset 0
320 "Offset to contents.")
322 (defvar ac-menu-scroll 0
323 "Scroll top of `ac-menu'.")
325 (defvar ac-completing nil
326 "Non-nil means `auto-complete-mode' is now working on completion.")
328 (defvar ac-saved-window-start nil
329 "Saved window start value for restore.")
331 (defvar ac-saved-window-hscroll nil
332 "Saved window hscroll value for restore.")
334 (defvar ac-buffer nil
335 "A buffer where auto-complete is started.")
337 (defvar ac-point nil
338 "Start point of prefix.")
340 (defvar ac-old-point nil
341 "Previous start point of prefix.")
343 (defvar ac-prefix nil
344 "Prefix.")
345 (defvaralias 'ac-target 'ac-prefix)
347 (defvar ac-limit 0
348 "Limit of number of candidates.")
350 (defvar ac-candidates nil
351 "Current candidates.")
353 (defvar ac-selection nil
354 "Current candidate index.")
356 (defvar ac-dwim-enable nil
357 "Non-nil means DWIM completion will be allowed.")
359 (defvar ac-setup-function 'ac-sources-setup
360 "This function will be called when `auto-complete-mode' is enabled.")
362 (defvar ac-prefix-function 'ac-sources-prefix
363 "When `auto-complete-mode' finds it can start completion
364 or update candidates, it will call this function to find a
365 start point of the prefix.
367 If this function returns a point `auto-complete-mode'
368 will set the substring between the point and current point to `ac-prefix'.
369 And also it will start completion or update candidates by using
370 the `ac-prefix'.
372 If this function returns `nil', `auto-complete-mode'
373 ignore starting completion or stop completing.")
374 (defvaralias 'ac-find-function 'ac-prefix-function)
376 (defvar ac-init-function 'ac-sources-init
377 "This function will be called when candidate menu is setupped.")
379 (defvar ac-cleanup-function 'ac-sources-cleanup
380 "This function will be called when candidate menu is cleanupped")
382 (defvar ac-candidate-function 'ac-sources-candidate
383 "This function can return candidates as list by
384 using the `TARGET' that is given as a first argument.")
386 (defvar ac-complete-mode-map
387 (let ((map (make-sparse-keymap)))
388 (define-key map "\t" 'ac-expand)
389 (define-key map "\r" 'ac-complete)
391 (define-key map [down] 'ac-next)
392 (define-key map [up] 'ac-previous)
394 map)
395 "Keymap for completion.")
397 (defvar ac-saved-local-map nil
398 "Old keymap before `auto-complete' activated.")
402 ;;;; Auto completion
404 (defun ac-setup-menu (point width)
405 "Setup popup menu."
406 (when ac-menu
407 ;; reposition
408 (ac-menu-delete ac-menu)
409 (setq ac-menu nil))
410 (save-excursion
411 (goto-char point)
412 (let ((column (ac-current-physical-column))
413 (line (line-number-at-pos)))
414 (setq ac-saved-window-start (window-start))
415 (setq ac-saved-window-hscroll (window-hscroll))
416 (setq ac-menu-direction
417 (if (and (> line ac-candidate-menu-height)
418 (> ac-candidate-menu-height
420 (max 1 (- (window-height)
421 (if mode-line-format 1 0)
422 (if header-line-format 1 0)))
423 (count-lines (window-start) (point)))))
426 (let ((window-width (window-width))
427 (right (- (+ column width)
428 (window-hscroll))))
429 (if (and (> right window-width)
430 (>= right width)
431 (>= column width))
432 (setq column (- column width))))
433 (if (> ac-menu-direction 0)
434 (progn
435 (forward-line)
436 (if (eq line (line-number-at-pos))
437 (newline)
438 (forward-line -1))
439 (setq ac-menu (ac-menu-create (1+ line) column width ac-candidate-menu-height))
440 (setq ac-point point))
441 (setq ac-menu (ac-menu-create (- line ac-candidate-menu-height) column width ac-candidate-menu-height))
442 (setq ac-point point)))))
444 (defun ac-cleanup ()
445 "Destroy popup menu."
446 (ac-deactivate-mode-map)
447 (when ac-menu
448 (ac-menu-delete ac-menu)
449 (set-window-start (selected-window) ac-saved-window-start)
450 (set-window-hscroll (selected-window) ac-saved-window-hscroll))
451 (setq ac-menu nil)
452 (setq ac-menu-scroll 0)
453 (setq ac-completing nil)
454 (setq ac-point nil)
455 (setq ac-candidates nil)
456 (setq ac-selection 0)
457 (setq ac-selection-scroll-top 0)
458 (funcall ac-cleanup-function))
460 (defun ac-activate-mode-map ()
461 "Activate `ac-complete-mode-map'."
462 (if ac-override-local-map
463 (progn
464 (setq ac-saved-local-map overriding-terminal-local-map)
465 (if (eq ac-saved-local-map ac-complete-mode-map)
466 ;; maybe never reach here
467 (setq ac-saved-local-map nil))
468 (setq overriding-terminal-local-map ac-complete-mode-map))
469 ;; rearrange ac-mode-map pair first
470 (assq-delete-all 'ac-completing minor-mode-map-alist)
471 (push (cons 'ac-completing ac-complete-mode-map) minor-mode-map-alist)))
473 (defun ac-deactivate-mode-map ()
474 "Deactivate `ac-complete-mode-map'."
475 (when (and ac-override-local-map
476 (eq overriding-terminal-local-map ac-complete-mode-map))
477 (setq overriding-terminal-local-map ac-saved-local-map)
478 (setq ac-saved-local-map nil)))
480 (defun ac-next ()
481 "Select next candidate."
482 (interactive)
483 (if (interactive-p)
484 (setq ac-dwim-enable t))
485 (if ac-candidates
486 (ac-select-candidate
487 (let ((selection (1+ ac-selection)))
488 (if (= selection (+ ac-menu-offset (min ac-candidate-menu-height (length ac-candidates))))
489 (if (< (+ (- ac-selection ac-menu-offset) ac-menu-scroll) (1- (length ac-candidates)))
490 (prog1 ac-selection
491 (setq ac-menu-scroll (1+ ac-menu-scroll))
492 (ac-redraw-candidates))
493 (setq ac-menu-scroll 0)
494 (ac-redraw-candidates)
495 ac-menu-offset)
496 selection)))))
498 (defun ac-previous ()
499 "Select previous candidate."
500 (interactive)
501 (if (interactive-p)
502 (setq ac-dwim-enable t))
503 (if ac-candidates
504 (ac-select-candidate
505 (let ((selection (1- ac-selection)))
506 (if (< selection ac-menu-offset)
507 (if (= ac-menu-scroll 0)
508 (prog1 (1- (+ ac-menu-offset (min ac-candidate-menu-height (length ac-candidates))))
509 (setq ac-menu-scroll (- (length ac-candidates) (min ac-candidate-menu-height (length ac-candidates))))
510 (ac-redraw-candidates))
511 (setq ac-menu-scroll (1- ac-menu-scroll))
512 (ac-redraw-candidates)
513 ac-selection)
514 selection)))))
516 (defun ac-expand-1 ()
517 "Try expansion."
518 (let ((string (overlay-get (ac-menu-line-overlay ac-menu ac-selection) 'real-string)))
519 (delete-region ac-point (point))
520 (insert string)
521 (setq ac-prefix string)))
523 (defun ac-expand ()
524 "Try expansion but select next if expanded twice."
525 (interactive)
526 (if (and ac-dwim ac-dwim-enable)
527 (ac-complete)
528 (let ((target ac-prefix)
529 (string (ac-expand-1)))
530 (when (equal target string)
531 (ac-next)
532 (ac-expand-1)))))
534 (defun ac-expand-common ()
535 "Try expansion common part."
536 (interactive)
537 (let ((common (try-completion ac-prefix ac-candidates))
538 (buffer-undo-list t))
539 (when (stringp common)
540 (delete-region ac-point (point))
541 (insert common)
542 (setq ac-prefix common))))
544 (defun ac-complete ()
545 "Try completion."
546 (interactive)
547 (let* ((candidate (ac-get-selected-candidate))
548 (action (ac-get-candidate-action candidate)))
549 (ac-expand-1)
550 (if action
551 (funcall action))
552 (ac-abort)))
554 (defun ac-abort ()
555 "Abort completion."
556 (ac-cleanup))
558 (defun ac-stop ()
559 "Stop completiong."
560 (interactive)
561 (ac-abort))
563 (defun ac-redraw-candidates ()
564 "Redraw the menu contents."
565 (let ((i ac-menu-offset))
566 ;; show line and set string to the line
567 (mapc
568 (lambda (candidate)
569 (when (< i ac-candidate-menu-height)
570 (ac-menu-show-line ac-menu i)
571 (ac-menu-set-line-string ac-menu i candidate
572 (if (= i ac-selection)
573 (or (ac-get-candidate-property 'selection-face candidate) 'ac-selection-face)
574 (or (ac-get-candidate-property 'candidate-face candidate) 'ac-candidate-face)))
575 (setq i (1+ i))))
576 (nthcdr ac-menu-scroll ac-candidates))
577 ;; ensure lines visible
578 (if (and (> ac-menu-direction 0)
579 (> i (-
580 (max 1 (- (window-height)
581 (if mode-line-format 1 0)
582 (if header-line-format 1 0)))
583 (count-lines (window-start) (point)))))
584 (recenter (- (1+ i))))
585 (if (> i ac-menu-offset)
586 (let ((window-width (window-width))
587 (right (- (+ (ac-menu-column ac-menu) (ac-menu-width ac-menu))
588 (window-hscroll))))
589 (if (> right window-width)
590 (scroll-left (- right window-width)))))
591 ;; hide remaining lines
592 (if (> ac-menu-direction 0)
593 (while (< i ac-candidate-menu-height)
594 (ac-menu-hide-line ac-menu i)
595 (setq i (1+ i)))
596 (dotimes (i ac-menu-offset)
597 (ac-menu-hide-line ac-menu i)))))
599 (defun ac-update-candidates (candidates)
600 "Update candidates of popup menu."
601 (setq ac-menu-offset (if (> ac-menu-direction 0)
603 (- ac-candidate-menu-height
604 (min ac-candidate-menu-height
605 (length candidates)))))
606 (setq ac-selection ac-menu-offset)
607 (setq ac-candidates candidates)
608 (setq ac-dwim-enable (= (length candidates) 1))
609 (if candidates
610 (progn
611 (setq ac-completing t)
612 (ac-activate-mode-map))
613 (setq ac-completing nil)
614 (ac-deactivate-mode-map))
615 (ac-redraw-candidates))
617 (defun ac-get-selected-candidate ()
618 (overlay-get (ac-menu-line-overlay ac-menu ac-selection) 'real-string))
620 (defun ac-get-candidate-action (candidate)
621 (ac-get-candidate-property 'action candidate))
623 (defun ac-propertize-candidate (candidate &rest properties)
624 (apply 'propertize candidate properties))
626 (defun ac-get-candidate-property (prop candidate)
627 (get-text-property 0 prop candidate))
629 (defun ac-select-candidate (selection)
630 "Select candidate pointed by `SELECTION'."
631 (when ac-candidates
632 (let ((c1 (nth (+ (- ac-selection ac-menu-offset) ac-menu-scroll) ac-candidates))
633 (c2 (nth (+ (- selection ac-menu-offset) ac-menu-scroll) ac-candidates)))
634 (ac-menu-set-line-string ac-menu ac-selection c1
635 (or (ac-get-candidate-property 'candidate-face c1)
636 'ac-candidate-face))
637 (ac-menu-set-line-string ac-menu selection c2
638 (or (ac-get-candidate-property 'selection-face c2)
639 'ac-selection-face))
640 (setq ac-selection selection))))
642 (defun ac-start ()
643 "Start completion."
644 (interactive)
645 (let* ((point (save-excursion (funcall ac-prefix-function)))
646 (reposition (not (equal ac-point point))))
647 (if (null point)
648 (ac-abort)
649 (setq ac-buffer (current-buffer))
650 (setq ac-point point)
651 (when (not (equal ac-point ac-old-point))
652 (setq ac-old-point point))
653 (setq ac-prefix (buffer-substring-no-properties point (point)))
654 (setq ac-limit ac-candidate-max)
655 (if (or reposition (null ac-menu))
656 (save-excursion
657 (funcall ac-init-function)))
658 (let* ((candidates
659 (if (or ac-completing
660 (not (integerp ac-auto-start))
661 (>= (length ac-prefix) ac-auto-start))
662 (save-excursion
663 (funcall ac-candidate-function))))
664 (current-width (if ac-menu (ac-menu-width ac-menu) 0))
665 (width (let ((w '(0)) s)
666 (dotimes (i ac-candidate-menu-height)
667 (setq s (nth i candidates))
668 (if (stringp s) (push (string-width s) w)))
669 (apply 'max w))))
670 (if (or reposition
671 (null ac-menu)
672 (> width current-width)
673 (< width (- current-width 10)))
674 (ac-setup-menu point (* (ceiling (/ width 10.0)) 10)))
675 (if (and ac-dwim
676 (= (length candidates) 1)
677 (equal (car candidates) ac-prefix)
678 (null (ac-get-candidate-action (car candidates))))
679 (setq candidates nil))
680 (ac-update-candidates candidates)))))
682 (defun ac-trigger-command-p ()
683 "Return non-nil if `this-command' is a trigger command."
684 (or (memq this-command ac-trigger-commands)
685 (and ac-completing
686 (memq this-command
687 '(delete-backward-char
688 backward-delete-char
689 backward-delete-char-untabify)))))
691 (defun ac-current-physical-column ()
692 "Current physical column. (not logical column)"
693 (- (point) (save-excursion (vertical-motion 0) (point))))
695 (defun ac-on-pre-command ()
696 (progn ; ignore-errors
697 (if (and (not (ac-trigger-command-p))
698 (or (not (symbolp this-command))
699 (not (string-match "^ac-" (symbol-name this-command)))))
700 (ac-abort))))
702 (defun ac-on-post-command ()
703 (progn ; ignore-errors
704 (if (and (or ac-auto-start
705 ac-completing)
706 (not isearch-mode)
707 (ac-trigger-command-p))
708 (ac-start))))
710 (defun auto-complete-mode-maybe ()
711 "What buffer `auto-complete-mode' prefers."
712 (if (and (not (minibufferp (current-buffer)))
713 (memq major-mode ac-modes))
714 (auto-complete-mode 1)))
716 (require 'easy-mmode)
718 (define-minor-mode auto-complete-mode
719 "AutoComplete mode"
720 :lighter " AC"
721 :group 'auto-complete
722 (if auto-complete-mode
723 (progn
724 (funcall ac-setup-function)
725 (add-hook 'post-command-hook 'ac-on-post-command nil t)
726 (add-hook 'pre-command-hook 'ac-on-pre-command nil t)
727 (run-hooks 'auto-complete-mode-hook))
728 (remove-hook 'post-command-hook 'ac-on-post-command t)
729 (remove-hook 'pre-command-hook 'ac-on-pre-command t)
730 (ac-abort)))
732 (define-global-minor-mode global-auto-complete-mode
733 auto-complete-mode auto-complete-mode-maybe
734 :group 'auto-complete)
738 ;;;; Basic cache facility
740 (defvar ac-clear-variables-after-save nil)
742 (defun ac-clear-variable-after-save (variable)
743 (push variable ac-clear-variables-after-save))
745 (defun ac-clear-variables-after-save ()
746 (dolist (variable ac-clear-variables-after-save)
747 (set variable nil)))
751 ;;;; Sources implementation
753 (defvar ac-sources '(ac-source-words-in-buffer)
754 "Sources for completion.
756 Source takes a form of just function which returns candidates or alist:
758 init INIT-FUNC
759 INIT-FUNC will be called before creating candidate every time.
761 candidates CANDIDATE-FUNC
762 CANDIDATE-FUNC will return a list of string as candidates.
763 CANDIDATE-FUNC should care about `ac-limit' that is specified at limit for performance.
765 action ACTION-FUNC
766 ACTION-FUNC will be called when `ac-complete' is called.
768 limit LIMIT-NUM
769 A limit of candidates.
771 requires REQUIRES-NUM
772 This source will be included when `ac-prefix' length is larger than REQUIRES-NUM.")
773 (make-variable-buffer-local 'ac-sources)
775 (defvar ac-sources-prefix-function 'ac-sources-prefix-default
776 "Default prefix function for sources.
777 You should override this variable instead of ac-prefix-function.")
779 (defvar ac-current-sources nil
780 "Current working sources.")
782 (defvar ac-omni-completion-sources nil
783 "An alist of REGEXP and SOURCES.
784 If matched regexp, switch to omni-completion mode and
785 use SOURCES as `ac-sources'.")
786 (make-variable-buffer-local 'ac-omni-completion-sources)
788 (defvar ac-sources-omni-completion nil
789 "Non-nil means `auto-complete-mode' is now working on omni-completion.")
791 (defun ac-sources-setup ()
792 "Implementation for `ac-setup-function' by sources."
793 (make-local-variable 'ac-clear-variables-after-save)
794 (add-hook 'after-save-hook 'ac-clear-variables-after-save nil t))
796 (defun ac-sources-init ()
797 "Implementation for `ac-init-function' by sources."
798 (or ac-current-sources (setq ac-current-sources ac-sources))
799 (dolist (source ac-current-sources)
800 (let ((init-function (ac-get-source-property 'init source)))
801 (if init-function
802 (funcall init-function)))))
804 (defun ac-sources-cleanup ()
805 "Implementation for `ac-cleanup-function' by sources."
806 (setq ac-current-sources nil)
807 (setq ac-sources-omni-completion nil))
809 (defun ac-sources-prefix ()
810 "Implemention for `ac-prefix-function' by sources."
811 (let (point)
812 (dolist (pair ac-omni-completion-sources)
813 (when (looking-back (car pair))
814 (setq ac-current-sources (cdr pair))
815 (setq ac-sources-omni-completion t)
816 (setq ac-completing t)
817 (setq point (match-end 0))))
818 (or point
819 (if (and ac-completing ac-sources-omni-completion)
820 ac-point
821 (setq ac-current-sources ac-sources)
822 (setq ac-sources-omni-completion nil)
823 (funcall ac-sources-prefix-function)))))
825 (defun ac-sources-prefix-default ()
826 "Default implementation for `ac-sources-prefix-function'."
827 (require 'thingatpt)
828 (car-safe (bounds-of-thing-at-point 'symbol)))
830 (defun ac-sources-candidate ()
831 "Implementation for `ac-cadidates-function' by sources."
832 (let (candidates)
833 (dolist (source ac-current-sources)
834 (let* ((ac-limit (or (ac-get-source-property 'limit source) ac-limit))
835 (requires (ac-get-source-property 'requires source))
836 cand)
837 (when (or ac-sources-omni-completion
838 (>= (length ac-prefix)
839 (if (integerp requires)
840 requires
841 1)))
842 (setq cand
843 (delq nil
844 (mapcar (lambda (candidate)
845 (ac-propertize-candidate candidate
846 'action (ac-get-source-property 'action source)
847 'face (ac-get-source-property 'candidate-face source)
848 'candidate-face (ac-get-source-property 'candidate-face source)
849 'selection-face (ac-get-source-property 'selection-face source)))
850 (funcall (ac-get-source-property 'candidates source))))))
851 (if (and (> ac-limit 1)
852 (> (length cand) ac-limit))
853 (setcdr (nthcdr (1- ac-limit) (copy-sequence cand)) nil))
854 (setq candidates (append candidates cand))))
855 (delete-dups candidates)))
857 (defun ac-get-source-property (property source)
858 (if (symbolp source)
859 (setq source (symbol-value source)))
860 (if (and (functionp source)
861 (eq property 'candidates))
862 source
863 (if (consp source)
864 (assoc-default property source))))
868 ;;;; Standard sources
870 (defun ac-candidate-words-in-buffer ()
871 "Default implemention for `ac-candidate-function'."
872 (if (> (length ac-prefix) 0)
873 (let ((i 0)
874 candidate
875 candidates
876 (regexp (concat "\\b" (regexp-quote ac-prefix) "\\(\\s_\\|\\sw\\)*\\b")))
877 (save-excursion
878 ;; search backward
879 (goto-char ac-point)
880 (while (and (< i ac-limit)
881 (re-search-backward regexp nil t))
882 (setq candidate (match-string-no-properties 0))
883 (unless (member candidate candidates)
884 (push candidate candidates)
885 (setq i (1+ i))))
886 ;; search backward
887 (goto-char (+ ac-point (length ac-prefix)))
888 (while (and (< i ac-limit)
889 (re-search-forward regexp nil t))
890 (setq candidate (match-string-no-properties 0))
891 (unless (member candidate candidates)
892 (push candidate candidates)
893 (setq i (1+ i))))
894 (nreverse candidates)))))
896 (defvar ac-source-words-in-buffer
897 '((candidates . ac-candidate-words-in-buffer))
898 "Source for completing words in current buffer.")
900 (defvar ac-word-index nil
901 "Word index for individual buffer.")
903 (ac-clear-variable-after-save 'ac-word-index)
905 (defvar ac-source-words-in-all-buffer
906 '((init
907 . (lambda ()
908 (dolist (buffer (buffer-list))
909 (with-current-buffer buffer
910 (if (not (local-variable-p 'ac-word-index))
911 (make-local-variable 'ac-word-index))
912 (if (eq buffer ac-buffer)
913 (setq ac-word-index (ac-candidate-words-in-buffer))
914 (if (and (null ac-word-index)
915 (< (buffer-size) 102400))
916 (save-excursion
917 (goto-char (point-min))
918 (while (re-search-forward "\\b\\(\\s_\\|\\sw\\)+\\b" nil t)
919 (let ((candidate (match-string-no-properties 0)))
920 (if (not (member candidate ac-word-index))
921 (push candidate ac-word-index))))
922 (setq ac-word-index (nreverse ac-word-index)))))))))
923 (candidates
924 . (lambda ()
925 (let ((candidates)
926 (buffers (buffer-list)))
927 (while (and (< (length candidates) ac-limit)
928 buffers)
929 (setq candidates (append candidates (all-completions ac-prefix (buffer-local-value 'ac-word-index (car buffers)))))
930 (setq buffers (cdr buffers)))
931 candidates))))
932 "Source for completing words in all buffer.")
934 (defvar ac-source-symbols
935 '((candidates
936 . (lambda ()
937 (all-completions ac-prefix obarray))))
938 "Source for Emacs lisp symbols.")
940 (defvar ac-source-abbrev
941 `((candidates
942 . (lambda ()
943 (all-completions ac-prefix local-abbrev-table)))
944 (action
945 . expand-abbrev))
946 "Source for abbrev.")
948 (defvar ac-source-files-in-current-dir
949 '((candidates
950 . (lambda ()
951 (all-completions ac-prefix (directory-files default-directory)))))
952 "Source for listing files in current directory.")
954 (defun ac-filename-candidate ()
955 (let ((dir (file-name-directory ac-prefix)))
956 (ignore-errors
957 (delq nil
958 (mapcar (lambda (file)
959 (if (not (member file '("./" "../")))
960 (concat dir file)))
961 (file-name-all-completions
962 (file-name-nondirectory ac-prefix) dir))))))
964 (defvar ac-source-filename
965 '((candidates . ac-filename-candidate))
966 "Source for completing file name.")
968 (defvar ac-imenu-index nil
969 "Imenu index.")
971 (defun ac-imenu-candidate ()
972 (require 'imenu)
973 (let ((i 0)
974 (stack ac-imenu-index)
975 candidates
976 node)
977 (while (and stack
978 (< i ac-limit))
979 (setq node (pop stack))
980 (when (consp node)
981 (let ((car (car node))
982 (cdr (cdr node)))
983 (if (consp cdr)
984 (mapc (lambda (child)
985 (push child stack))
986 cdr)
987 (when (and (stringp car)
988 (string-match (concat "^" (regexp-quote ac-prefix)) car))
989 (push car candidates)
990 (setq i (1+ i)))))))
991 (nreverse candidates)))
993 (defvar ac-source-imenu
994 '((init
995 . (lambda ()
996 (require 'imenu)
997 (setq ac-imenu-index
998 (ignore-errors (imenu--make-index-alist)))))
999 (candidates . ac-imenu-candidate))
1000 "Source for imenu.")
1002 (defmacro ac-define-dictionary-source (name list)
1003 "Define dictionary source named `NAME'.
1004 `LIST' is a list of string.
1005 This is useful if you just want to define a dictionary/keywords source."
1006 `(defvar ,name
1007 '((candidates . (lambda () (all-completions ac-prefix ,list))))))
1011 ;;;; Popup menu
1013 (defun ac-menu-line (menu)
1014 "Line number of `MENU'."
1015 (nth 0 menu))
1017 (defun ac-menu-column (menu)
1018 "Column of `MENU'."
1019 (nth 1 menu))
1021 (defun ac-menu-width (menu)
1022 "Popup menu width of `MENU'."
1023 (nth 2 menu))
1025 (defun ac-menu-height (menu)
1026 "Popup menu height of `MENU'."
1027 (nth 3 menu))
1029 (defun ac-menu-overlays (menu)
1030 "Overlays that `MENU' contains."
1031 (nth 4 menu))
1033 (defun ac-menu-line-overlay (menu line)
1034 "Return a overlay of `MENU' at `LINE'."
1035 (aref (ac-menu-overlays menu) line))
1037 (defun ac-menu-hide-line (menu line)
1038 "Hide `LINE' in `MENU'."
1039 (let ((overlay (ac-menu-line-overlay menu line)))
1040 (overlay-put overlay 'invisible nil)
1041 (overlay-put overlay 'after-string nil)))
1043 (defun ac-menu-show-line (menu line)
1044 "Show `LINE' in `MENU'."
1045 (let ((overlay (ac-menu-line-overlay menu line)))
1046 (overlay-put overlay 'invisible t)))
1048 (defun ac-menu-set-line-string (menu line string &optional face)
1049 "Set contents of `LINE' in `MENU'."
1050 (let ((overlay (ac-menu-line-overlay menu line)))
1051 (overlay-put overlay 'real-string string)
1052 (funcall (overlay-get overlay 'set-string-function) menu overlay string face)))
1054 (defun ac-menu-create-line-string (menu string)
1055 "Adjust `STRING' into `MENU'."
1056 (let ((length 0)
1057 (width 0)
1058 (menu-width (ac-menu-width menu))
1059 (chars (append string nil)))
1060 (while (and
1061 chars
1062 (<= (setq width (+ width (char-width (car chars)))) menu-width))
1063 (setq length (1+ length))
1064 (setq chars (cdr chars)))
1065 (if (< length (length string))
1066 (setq string (substring string 0 length)))
1067 (let ((string-width (string-width string)))
1068 (if (< string-width menu-width)
1069 (setq string (concat string
1070 (make-string (- menu-width string-width) ? )))))
1071 string))
1073 (defun ac-menu-hide (menu)
1074 "Hide `MENU'."
1075 (dotimes (i (ac-menu-height menu))
1076 (ac-menu-hide-line menu i)))
1078 (defun ac-menu-last-line-of-buffer ()
1079 (save-excursion
1080 (not (eq (forward-line) 0))))
1082 (defun ac-menu-create (line column width height)
1083 "Create popup menu."
1084 (save-excursion
1085 (let ((overlays (make-vector height nil))
1086 (window (selected-window)))
1087 (goto-line line)
1088 (dotimes (i height)
1089 (move-to-column column)
1090 (let (overlay begin w current-column (prefix "") (postfix ""))
1091 (setq current-column (current-column))
1092 (cond
1093 ((> current-column column)
1094 (backward-char)
1095 (setq current-column (current-column))
1096 (if (< current-column column)
1097 (setq prefix (make-string (- column current-column) ? ))))
1098 ((< current-column column)
1099 (setq prefix (make-string (- column current-column) ? ))))
1101 (setq begin (point))
1102 (setq w (+ width (length prefix)))
1103 (while (and (not (eolp))
1104 (> w 0))
1105 (setq w (- w (char-width (char-after))))
1106 (forward-char))
1107 (if (< w 0)
1108 (setq postfix (make-string (- w) ? )))
1109 (if (ac-menu-last-line-of-buffer)
1110 (setq postfix (concat postfix "\n")))
1112 (setq overlay (make-overlay begin (point)))
1113 (overlay-put overlay 'window window)
1114 (overlay-put overlay 'prefix prefix)
1115 (overlay-put overlay 'postfix postfix)
1116 (overlay-put overlay 'width width)
1117 (overlay-put overlay 'set-string-function
1118 (lambda (menu overlay string &optional face)
1119 (overlay-put overlay
1120 'after-string
1121 (concat (overlay-get overlay 'prefix)
1122 (propertize (ac-menu-create-line-string menu string) 'face face)
1123 (overlay-get overlay 'postfix)))))
1124 (aset overlays i overlay))
1125 (forward-line))
1126 (let ((i 100))
1127 (mapc (lambda (overlay)
1128 (overlay-put overlay 'priority i)
1129 (setq i (1+ i)))
1130 (nreverse (append overlays nil))))
1131 (list line column width height overlays))))
1133 (defun ac-menu-delete (menu)
1134 "Delete `MENU'."
1135 (mapcar 'delete-overlay (ac-menu-overlays menu)))
1137 (provide 'auto-complete)
1138 ;;; auto-complete.el ends here