views:

829

answers:

4

How can I make Emacs to complete words that are in C include files ?

#include <stdio.h>
int main(){
print//<-- this is where I want it to complete printf

What's the simplest way? (something simpler than Cedet)

A: 

You might want to try out M-/ (dabbrev-expand). This command attempts to complete the identifier immediately preceding the point (ie, where your cursor is) using the contents of the current buffer and then the contents of other buffers of the same mode. If the first completion offered isn't the one you want, just keep typing M-/. If you have the habit of keeping a single emacs session open continuously (which, if you don't have, you should really acquire), and have a handful of files from the current project open, you're quite likely to be able to find an the expansion you want for any particular prefix.

So, to answer you're original question, M-/ will find the printf completion you're looking for if (a) you've used printf anywhere else in the buffer you're editing, or (b) it appears in any other .c or .h file you have open in emacs.

Dale Hagglund
@Dale: (a) you've used printf anywhere else in the buffer you're editing, or (b) it appears in any other .c or .h file you have open in emacs. -- OK, but just as Liran, I'd like it to get into the included .h files.
Jay
As far as dabbrev-expand goes, the only answer is to open the include file, eg, stdio.h, in your emacs session. It looks like hippie-expand might be flexible enough if you're willing to write some custom lisp code to automatically load include files. There's also some interesting ideas at http://www.emacswiki.org/emacs/HippieExpand, in particular the notion of completing against tags. If these don't cover enough of the problem, you probably need to look at something like CEDET.
Dale Hagglund
A: 

You might also try hippie-expand, which has additional options regarding where it looks for completion information. I bind M-/ to hippie-expand, and then modified the order of the elements in hippie-expand-try-functions-list as follows:

(global-set-key (kbd "M-/") 'hippie-expand)
(setq hippie-expand-try-functions-list '(try-expand-dabbrev try-expand-dabbrev-all-buffers try-expand-dabbrev-from-kill try-complete-file-name-partially try-complete-file-name try-expand-all-abbrevs try-expand-list try-expand-line try-complete-lisp-symbol-partially try-complete-lisp-symbol))

This makes hippie-expand act like the normal M-/ at first, but repeated presses will yield more possible expansions.

Marc
I tried that but it didn't work. (Opened a clean Emacs session, evaluated the lines you suggested above, then opened a new C file and did just what Liran said. It didn't find printf...
Jay
+4  A: 

First generate tags for the source and include files you'd like to be able to autocomplete for. See my blogpost for tips on using tags if you didn't use tag tables before.

Now if you have a TAGS table that includes the stdio.h, then you can autocomplete 'printf' using the command `complete-tag'.

Perhaps bind `complete-tag' to a key:

(global-set-key [f3] 'complete-tag)
justinhj
Thank you! I've enjoyed the blog too :).
Liran Orevi
+3  A: 

Unlike complete-tag, dabbrev-expand, or hippie-expand (which does dabbrev-expand like things), the CEDET suite does exactly what the question describes. When asked to perform a completion, it looks and sees that you have included stdio.h, and then looks there for possible completions.

CEDET does a lot of other things related to completion as well which will provide very focused and correct suggestions, not just vaguely similar suggestions. A side affect is that CEDET takes more effort to setup. You need to teach it where you include files are, for example, and sometimes how to deal with macros, and what the project you are working on is like.

There is more detail on this here: link text

Eric