clang-completion-mode.el revision a584fb353aa8496ace9cc2903e38c3c76bd127eb
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
18a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; "clang-cc" variable below refers to the "clang-cc" 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;;
35a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Finally, to try Clang-based code completion in a particular buffer,
36a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; use M-x clang-completion-mode. When "Clang-CC" shows up in the mode
37a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; line, Clang's code-completion is enabled.
38a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;
39a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Clang's code completion is based on parsing the complete source
40a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; file up to the point where the cursor is located. Therefore, Clang
41a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; needs all of the various compilation flags (include paths, dialect
42a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; options, etc.) to provide code-completion results. Currently, these
43a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; need to be placed into the clang-cc-flags variable in a format
44a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; acceptable to clang-cc. This is a hack: patches are welcome to
45a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; improve the interface between this Emacs mode and Clang!
46a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;
47a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
48a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; Code:
49a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; The clang-cc executable
50a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defcustom clang-cc "clang-cc"
51a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  "The location of the clang-cc executable of the Clang compiler.
52a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas GregorThis executable is typically installed into the libexec subdirectory."
53a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  :type 'file
54a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  :group 'clang-completion-mode)
55a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
56a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; Extra compilation flags to pass to clang-cc.
57a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defcustom clang-cc-flags ""
58a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  "Extra flags to pass to the Clang executable.
59a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas GregorThis variable will typically contain include paths, e.g., -I~/MyProject."
60a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  :type 'string
61a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  :group 'clang-completion-mode)
62a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
63a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; The prefix header to use with Clang code completion.
64a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(setq clang-completion-prefix-header "")
65a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
66a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; The substring we will use to filter completion results
67a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(setq clang-completion-substring "")
68a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
69a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; The current completion buffer
70a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(setq clang-completion-buffer nil)
71a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
72a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(setq clang-cc-result-string "")
73a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
74a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; Compute the current line in the buffer
75a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun current-line ()
76a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  "Return the vertical position of point..."
77a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (+ (count-lines (point-min) (point))
78a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor     (if (= (current-column) 0) 1 0)
79a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor     -1))
80a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
81a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;;; Set the Clang prefix header
82a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-prefix-header ()
83a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (interactive)
84a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (setq clang-completion-prefix-header
85a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor        (read-string "Clang prefix header> " "" clang-completion-prefix-header
86a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                     "")))
87a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
88a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Process "filter" that keeps track of the code-completion results
89a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; produced. We store all of the results in a string, then the
90a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; sentinel processes the entire string at once.
91a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-completion-stash-filter (proc string)
92a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (setq clang-cc-result-string (concat clang-cc-result-string string)))
93a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
94a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Filter the given list based on a predicate.
95a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun filter (condp lst)
96a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    (delq nil
97a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          (mapcar (lambda (x) (and (funcall condp x) x)) lst)))
98a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
99a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Determine whether
100a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun is-completion-line (line)
101a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (or (string-match "OVERLOAD:" line)
102a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor      (string-match (concat "COMPLETION: " clang-completion-substring) line)))
103a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
104a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-completion-display (buffer)
105a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (let* ((all-lines (split-string clang-cc-result-string "\n"))
106a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         (completion-lines (filter 'is-completion-line all-lines)))
107a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    (if (consp completion-lines)
108a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor        (progn
109a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         ;; Erase the process buffer
110a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         (let ((cur (current-buffer)))
111a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (set-buffer buffer)
112a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (goto-char (point-min))
113a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (erase-buffer)
114a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (set-buffer cur))
115a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
116a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         ;; Display the process buffer
117a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         (display-buffer buffer)
118a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
119a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         ;; Insert the code-completion string into the process buffer.
120a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         (with-current-buffer buffer
121a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (insert (mapconcat 'identity completion-lines "\n")))
122a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         ))))
123a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
124a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Process "sentinal" that, on successful code completion, replaces the
125a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; contents of the code-completion buffer with the new code-completion results
126a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; and ensures that the buffer is visible.
127a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-completion-sentinel (proc event)
128a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (let* ((all-lines (split-string clang-cc-result-string "\n"))
129a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         (completion-lines (filter 'is-completion-line all-lines)))
130a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    (if (consp completion-lines)
131a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor        (progn
132a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         ;; Erase the process buffer
133a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         (let ((cur (current-buffer)))
134a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (set-buffer (process-buffer proc))
135a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (goto-char (point-min))
136a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (erase-buffer)
137a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (set-buffer cur))
138a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
139a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         ;; Display the process buffer
140a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         (display-buffer (process-buffer proc))
141a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
142a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         ;; Insert the code-completion string into the process buffer.
143a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         (with-current-buffer (process-buffer proc)
144a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor           (insert (mapconcat 'identity completion-lines "\n")))
145a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor         ))))
146a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
147a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-complete ()
148a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (let ((ccstring (concat "-code-completion-at="
149a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                          (buffer-file-name)
150a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                          ":"
151a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                          (number-to-string (+ 1 (current-line)))
152a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                          ":"
153a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                          (number-to-string (+ 1 (current-column)))))
154a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor        (cc-buffer-name (concat "*Clang Completion for " (buffer-name) "*")))
155a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    ;; Start the code-completion process
156a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    (if (buffer-file-name)
157a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor        (progn
158a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          ;; If there is already a code-completion process, kill it first.
159a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          (let ((cc-proc (get-process "Clang Code-Completion")))
160a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor            (if cc-proc
161a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                (delete-process cc-proc)))
162a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
163a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          (setq clang-completion-substring "")
164a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          (setq clang-cc-result-string "")
165a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          (setq clang-completion-buffer cc-buffer-name)
166a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
167a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          (let ((cc-proc
168a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                 (if (equal clang-completion-prefix-header "")
169a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                     (start-process "Clang Code-Completion" cc-buffer-name
170a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                                    clang-cc "-fsyntax-only" ccstring
171a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                                    (buffer-file-name))
172a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                     (start-process "Clang Code-Completion" cc-buffer-name
173a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                                    clang-cc "-fsyntax-only" ccstring
174a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                                    "-include-pch"
175a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                                    (concat clang-completion-prefix-header ".pch")
176a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                                    (buffer-file-name)))))
177a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor            (set-process-filter cc-proc 'clang-completion-stash-filter)
178a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor            (set-process-sentinel cc-proc 'clang-completion-sentinel)
179a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor            )))))
180a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
181a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Code-completion when one of the trigger characters is typed into
182a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; the buffer, e.g., '(', ',' or '.'.
183a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-complete-self-insert (arg)
184a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (interactive "p")
185a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (self-insert-command arg)
186a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (save-buffer)
187a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (clang-complete))
188a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
189a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; When the user has typed a character that requires the filter to be
190a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; updated, do so (and update the display of results).
191a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-update-filter ()
192a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (setq clang-completion-substring (thing-at-point 'symbol))
193a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (if (get-process "Clang Code-Completion")
194a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor      ()
195a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    (clang-completion-display clang-completion-buffer)
196a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    ))
197a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
198a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Invoked when the user types an alphanumeric character or "_" to
199a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; update the filter for the currently-active code completion.
200a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-filter-self-insert (arg)
201a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (interactive "p")
202a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (self-insert-command arg)
203a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (clang-update-filter)
204a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  )
205a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
206a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Invoked when the user types the backspace key to update the filter
207a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; for the currently-active code completion.
208a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-backspace ()
209a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (interactive)
210a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (delete-backward-char 1)
211a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (clang-update-filter))
212a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
213a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Invoked when the user types the delete key to update the filter
214a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; for the currently-active code completion.
215a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defun clang-delete ()
216a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (interactive)
217a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (delete-backward-char 1)
218a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (clang-update-filter))
219a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
220a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Set up the keymap for the Clang minor mode.
221a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(defvar clang-completion-mode-map nil
222a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  "Keymap for Clang Completion Mode.")
223a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
224a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(if (null clang-completion-mode-map)
225a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    (fset 'clang-completion-mode-map
226a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          (setq clang-completion-mode-map (make-sparse-keymap))))
227a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
228a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(if (not (assq 'clang-completion-mode minor-mode-map-alist))
229a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor    (setq minor-mode-map-alist
230a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor          (cons (cons 'clang-completion-mode clang-completion-mode-map)
231a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                minor-mode-map-alist)))
232a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
233a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Punctuation characters trigger code completion.
234a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(dolist (char '("(" "," "." ">" ":" "=" ")" " "))
235a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (define-key clang-completion-mode-map char 'clang-complete-self-insert))
236a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
237a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Alphanumeric characters (and "_") filter the results of the
238a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; currently-active code completion.
239a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(dolist (char '("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O"
240a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
241a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o"
242a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
243a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor                "_" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"))
244a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  (define-key clang-completion-mode-map char 'clang-filter-self-insert))
245a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
246a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Delete and backspace filter the results of the currently-active
247a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; code completion.
248a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(define-key clang-completion-mode-map [(backspace)] 'clang-backspace)
249a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(define-key clang-completion-mode-map [(delete)] 'clang-delete)
250a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
251a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor;; Set up the Clang minor mode.
252a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor(define-minor-mode clang-completion-mode
253a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  "Clang code-completion mode"
254a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  nil
255a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  " Clang-CC"
256a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor  clang-completion-mode-map)
257a584fb353aa8496ace9cc2903e38c3c76bd127ebDouglas Gregor
258