1a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; Clang Code-Completion minor mode, for use with C/Objective-C/C++.
2a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
3a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; Commentary:
4a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
5a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; This minor mode uses Clang's command line interface for code
6a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; completion to provide code completion results for C, Objective-C,
7a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; and C++ source files. When enabled, Clang will provide
8a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; code-completion results in a secondary buffer based on the code
9a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; being typed. For example, after typing "struct " (triggered via the
10a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; space), Clang will provide the names of all structs visible from
11a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; the current scope. After typing "p->" (triggered via the ">"),
12a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Clang will provide the names of all of the members of whatever
13a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; class/struct/union "p" points to. Note that this minor mode isn't
14a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; meant for serious use: it is meant to help experiment with code
15a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; completion based on Clang. It needs your help to make it better!
16a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;
17a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; To use the Clang code completion mode, first make sure that the
18d240724926ca8bb06a1e0c2c19b33b51d7de484bDouglas Gregor;; "clang" variable below refers to the "clang" executable,
19a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; which is typically installed in libexec/. Then, place
20a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; clang-completion-mode.el somewhere in your Emacs load path. You can
21a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; add a new load path to Emacs by adding some like the following to
22a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; your .emacs:
23a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;
24a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;   (setq load-path (cons "~/.emacs.d" load-path))
25a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;
26a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Then, use
27a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;
28a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;   M-x load-library
29a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;
30a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; to load the library in your Emacs session or add the following to
31a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; your .emacs to always load this mode (not recommended):
32a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;
33a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;   (load-library "clang-completion-mode")
34a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;
353f1a5a255318b137323b403d2d17152e4bdcdc23Douglas Gregor;; Once you have done this, you can set various parameters with
363f1a5a255318b137323b403d2d17152e4bdcdc23Douglas Gregor;;
373f1a5a255318b137323b403d2d17152e4bdcdc23Douglas Gregor;;   M-x customize-group RET clang-completion-mode RET
383f1a5a255318b137323b403d2d17152e4bdcdc23Douglas Gregor;;
39a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Finally, to try Clang-based code completion in a particular buffer,
403f1a5a255318b137323b403d2d17152e4bdcdc23Douglas Gregor;; use M-x clang-completion-mode. When "Clang" shows up in the mode
41a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; line, Clang's code-completion is enabled.
42a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;
43a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Clang's code completion is based on parsing the complete source
44a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; file up to the point where the cursor is located. Therefore, Clang
45a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; needs all of the various compilation flags (include paths, dialect
46a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; options, etc.) to provide code-completion results. Currently, these
47d240724926ca8bb06a1e0c2c19b33b51d7de484bDouglas Gregor;; need to be placed into the clang-flags variable in a format
48d240724926ca8bb06a1e0c2c19b33b51d7de484bDouglas Gregor;; acceptable to clang. This is a hack: patches are welcome to
49a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; improve the interface between this Emacs mode and Clang!
50a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;
51a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
52a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; Code:
53d240724926ca8bb06a1e0c2c19b33b51d7de484bDouglas Gregor;;; The clang executable
54d240724926ca8bb06a1e0c2c19b33b51d7de484bDouglas Gregor(defcustom clang "clang"
55d240724926ca8bb06a1e0c2c19b33b51d7de484bDouglas Gregor  "The location of the Clang compiler executable"
56a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  :type 'file
57a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  :group 'clang-completion-mode)
58a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
59d240724926ca8bb06a1e0c2c19b33b51d7de484bDouglas Gregor;;; Extra compilation flags to pass to clang.
60ed37836bbbf023c4b6015128b131e1238398c7dfDouglas Gregor(defcustom clang-flags nil
61a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  "Extra flags to pass to the Clang executable.
62a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas GregorThis variable will typically contain include paths, e.g., -I~/MyProject."
63ed37836bbbf023c4b6015128b131e1238398c7dfDouglas Gregor  :type '(repeat (string :tag "Argument" ""))
64a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  :group 'clang-completion-mode)
65a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
66a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; The prefix header to use with Clang code completion.
67a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(setq clang-completion-prefix-header "")
68a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
69a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; The substring we will use to filter completion results
70a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(setq clang-completion-substring "")
71a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
72a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; The current completion buffer
73a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(setq clang-completion-buffer nil)
74a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
75d240724926ca8bb06a1e0c2c19b33b51d7de484bDouglas Gregor(setq clang-result-string "")
76a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
77a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; Compute the current line in the buffer
78a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun current-line ()
79a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  "Return the vertical position of point..."
80a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (+ (count-lines (point-min) (point))
81a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor     (if (= (current-column) 0) 1 0)
82a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor     -1))
83a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
84a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; Set the Clang prefix header
85a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-prefix-header ()
86a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (interactive)
87a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (setq clang-completion-prefix-header
88a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor        (read-string "Clang prefix header> " "" clang-completion-prefix-header
89a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                     "")))
90a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
91a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Process "filter" that keeps track of the code-completion results
92a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; produced. We store all of the results in a string, then the
93a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; sentinel processes the entire string at once.
94a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-completion-stash-filter (proc string)
95d240724926ca8bb06a1e0c2c19b33b51d7de484bDouglas Gregor  (setq clang-result-string (concat clang-result-string string)))
96a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
97a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Filter the given list based on a predicate.
98a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun filter (condp lst)
99a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    (delq nil
100a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          (mapcar (lambda (x) (and (funcall condp x) x)) lst)))
101a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
102e47398abd39dc8f714c25ae2f99c13e1f0da90f5Gabor Greif;; Determine whether FIXME: explain better
103a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun is-completion-line (line)
104a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (or (string-match "OVERLOAD:" line)
105a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor      (string-match (concat "COMPLETION: " clang-completion-substring) line)))
106a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
1073f1a5a255318b137323b403d2d17152e4bdcdc23Douglas Gregor
1083f1a5a255318b137323b403d2d17152e4bdcdc23Douglas Gregor;; re-process the completions when further input narrows the field
109a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-completion-display (buffer)
1103f1a5a255318b137323b403d2d17152e4bdcdc23Douglas Gregor  (fill-buffer buffer))
1113f1a5a255318b137323b403d2d17152e4bdcdc23Douglas Gregor
1123f1a5a255318b137323b403d2d17152e4bdcdc23Douglas Gregor(defun fill-buffer (buffer)
113d240724926ca8bb06a1e0c2c19b33b51d7de484bDouglas Gregor  (let* ((all-lines (split-string clang-result-string "\n"))
114a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         (completion-lines (filter 'is-completion-line all-lines)))
115a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    (if (consp completion-lines)
116a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor        (progn
117e47398abd39dc8f714c25ae2f99c13e1f0da90f5Gabor Greif         ;; Erase the process buffer.
118a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         (let ((cur (current-buffer)))
119a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (set-buffer buffer)
120a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (goto-char (point-min))
121a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (erase-buffer)
122a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (set-buffer cur))
123a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
124e47398abd39dc8f714c25ae2f99c13e1f0da90f5Gabor Greif         ;; Display the process buffer.
125a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         (display-buffer buffer)
126a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
127a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         ;; Insert the code-completion string into the process buffer.
128a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         (with-current-buffer buffer
129a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (insert (mapconcat 'identity completion-lines "\n")))
130a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         ))))
131a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
132e47398abd39dc8f714c25ae2f99c13e1f0da90f5Gabor Greif;; Process "sentinel" that, on successful code completion, replaces the
133a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; contents of the code-completion buffer with the new code-completion results
134a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; and ensures that the buffer is visible.
135a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-completion-sentinel (proc event)
1363f1a5a255318b137323b403d2d17152e4bdcdc23Douglas Gregor  (fill-buffer (process-buffer proc)))
137a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
138a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-complete ()
1397ae4373bde78acf912d7c33423fd2c33606ee851John McCall  (let* ((cc-point (concat (buffer-file-name)
1407ae4373bde78acf912d7c33423fd2c33606ee851John McCall                           ":"
1417ae4373bde78acf912d7c33423fd2c33606ee851John McCall                           (number-to-string (+ 1 (current-line)))
1427ae4373bde78acf912d7c33423fd2c33606ee851John McCall                           ":"
1437ae4373bde78acf912d7c33423fd2c33606ee851John McCall                           (number-to-string (+ 1 (current-column)))))
1447ae4373bde78acf912d7c33423fd2c33606ee851John McCall         (cc-pch (if (equal clang-completion-prefix-header "") nil
1457ae4373bde78acf912d7c33423fd2c33606ee851John McCall                   (list "-include-pch"
1467ae4373bde78acf912d7c33423fd2c33606ee851John McCall                         (concat clang-completion-prefix-header ".pch"))))
1477ae4373bde78acf912d7c33423fd2c33606ee851John McCall         (cc-flags (if (listp clang-flags) clang-flags nil))
1487ae4373bde78acf912d7c33423fd2c33606ee851John McCall         (cc-command (append `(,clang "-cc1" "-fsyntax-only")
1497ae4373bde78acf912d7c33423fd2c33606ee851John McCall                             cc-flags
1507ae4373bde78acf912d7c33423fd2c33606ee851John McCall                             cc-pch
1517ae4373bde78acf912d7c33423fd2c33606ee851John McCall                             `("-code-completion-at" ,cc-point)
1527ae4373bde78acf912d7c33423fd2c33606ee851John McCall                             (list (buffer-file-name))))
1537ae4373bde78acf912d7c33423fd2c33606ee851John McCall         (cc-buffer-name (concat "*Clang Completion for " (buffer-name) "*")))
154e47398abd39dc8f714c25ae2f99c13e1f0da90f5Gabor Greif    ;; Start the code-completion process.
155a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    (if (buffer-file-name)
156a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor        (progn
157a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          ;; If there is already a code-completion process, kill it first.
158a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          (let ((cc-proc (get-process "Clang Code-Completion")))
159a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor            (if cc-proc
160a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                (delete-process cc-proc)))
161a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
162a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          (setq clang-completion-substring "")
163d240724926ca8bb06a1e0c2c19b33b51d7de484bDouglas Gregor          (setq clang-result-string "")
164a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          (setq clang-completion-buffer cc-buffer-name)
165a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
1667ae4373bde78acf912d7c33423fd2c33606ee851John McCall          (let ((cc-proc (apply 'start-process
1677ae4373bde78acf912d7c33423fd2c33606ee851John McCall                                (append (list "Clang Code-Completion" cc-buffer-name)
1687ae4373bde78acf912d7c33423fd2c33606ee851John McCall                                        cc-command))))
169a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor            (set-process-filter cc-proc 'clang-completion-stash-filter)
170a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor            (set-process-sentinel cc-proc 'clang-completion-sentinel)
171a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor            )))))
172a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
173a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Code-completion when one of the trigger characters is typed into
174a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; the buffer, e.g., '(', ',' or '.'.
175a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-complete-self-insert (arg)
176a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (interactive "p")
177a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (self-insert-command arg)
178a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (save-buffer)
179a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (clang-complete))
180a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
181a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; When the user has typed a character that requires the filter to be
182a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; updated, do so (and update the display of results).
183a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-update-filter ()
184a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (setq clang-completion-substring (thing-at-point 'symbol))
185a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (if (get-process "Clang Code-Completion")
186a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor      ()
187a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    (clang-completion-display clang-completion-buffer)
188a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    ))
189a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
190a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Invoked when the user types an alphanumeric character or "_" to
191a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; update the filter for the currently-active code completion.
192a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-filter-self-insert (arg)
193a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (interactive "p")
194a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (self-insert-command arg)
195a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (clang-update-filter)
196a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  )
197a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
198a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Invoked when the user types the backspace key to update the filter
199a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; for the currently-active code completion.
200a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-backspace ()
201a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (interactive)
202a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (delete-backward-char 1)
203a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (clang-update-filter))
204a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
205a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Invoked when the user types the delete key to update the filter
206a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; for the currently-active code completion.
207a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-delete ()
208a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (interactive)
209a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (delete-backward-char 1)
210a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (clang-update-filter))
211a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
212a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Set up the keymap for the Clang minor mode.
213a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defvar clang-completion-mode-map nil
214a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  "Keymap for Clang Completion Mode.")
215a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
216a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(if (null clang-completion-mode-map)
217a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    (fset 'clang-completion-mode-map
218a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          (setq clang-completion-mode-map (make-sparse-keymap))))
219a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
220a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(if (not (assq 'clang-completion-mode minor-mode-map-alist))
221a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    (setq minor-mode-map-alist
222a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          (cons (cons 'clang-completion-mode clang-completion-mode-map)
223a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                minor-mode-map-alist)))
224a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
225a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Punctuation characters trigger code completion.
226a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(dolist (char '("(" "," "." ">" ":" "=" ")" " "))
227a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (define-key clang-completion-mode-map char 'clang-complete-self-insert))
228a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
229a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Alphanumeric characters (and "_") filter the results of the
230a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; currently-active code completion.
231a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(dolist (char '("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O"
232a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
233a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o"
234a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
235a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                "_" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"))
236a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (define-key clang-completion-mode-map char 'clang-filter-self-insert))
237a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
238a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Delete and backspace filter the results of the currently-active
239a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; code completion.
240a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(define-key clang-completion-mode-map [(backspace)] 'clang-backspace)
241a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(define-key clang-completion-mode-map [(delete)] 'clang-delete)
242a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
243a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Set up the Clang minor mode.
244a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(define-minor-mode clang-completion-mode
245a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  "Clang code-completion mode"
246a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  nil
247d240724926ca8bb06a1e0c2c19b33b51d7de484bDouglas Gregor  " Clang"
248a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  clang-completion-mode-map)
249a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
250