Commenting out line or region in Emacs

What I always wanted: commenting or uncommenting a line or region using emacs. Of course, there is comment-region, but this is much nicer:


(defun comment-or-uncomment-line-or-region ()
"Comments or uncomments the current line or region."
(interactive)
(if (region-active-p)
(comment-or-uncomment-region (region-beginning) (region-end))
(comment-or-uncomment-region (line-beginning-position) (line-end-position))
)
)

(define-key c-mode-base-map (kbd "C-/") 'comment-or-uncomment-line-or-region)

See also the corresponding Stackoverflow question.

A nice C++ autocomplete configuration for Emacs

Update: I have written a new blog post about this, with updated information and using new and current packages.

Autocompletion for C++ in Emacs is a hot topic — at least for Emacs users. At least for Emacs users who code C++… So here is my setup that I use, and which works reasonably well. I use the autocomplete package with the autocomplete-clang extension.

You can get the autocomplete package at github and the clang extension is available also on many repositories on github I used the one by brianjcj. Under OS X I use clang 3.1, under Linux I use clang 3.0. You may have to point autocomplete to the correct binary via the customizable variable ac-clang-executable.

So basically you have to clone the autocomplete package, clone the clang extension and copy the auto-complete-clang.el file into the same folder. I used ~/bin/emacs/auto-complete, but you can choose any directory. Maybe you have your own site-lisp folder.

(defcustom mycustom-system-include-paths '("./include/" "/opt/local/include" "/usr/include" )
"This is a list of include paths that are used by the clang auto completion."
:group 'mycustom
:type '(repeat directory)
)

(add-to-list 'load-path "~/bin/emacs/auto-complete")
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories "~/bin/emacs/auto-complete/ac-dict")
(ac-config-default)
(require 'auto-complete-clang)
(setq clang-completion-suppress-error 't)
(setq ac-clang-flags
(mapcar (lambda (item)(concat "-I" item))
(append
mycustom-system-include-paths
)
)
)

(defun my-ac-clang-mode-common-hook()
(define-key c-mode-base-map (kbd "M-/") 'ac-complete-clang)
)

(add-hook 'c-mode-common-hook 'my-ac-clang-mode-common-hook)

The key binding to M-/ is useful on US-keyboard, you may change that to your liking. So to start autocompletion, just type something and hit M-/. Clang will try to parse your file up to point and give useful completions. If it cannot parse your source, the cursor at point will turn red, and the minibuffer will show the error message. Most likely you forgot to add some include paths to mycustom-system-include-paths, or you really do have a syntax error.

The customizable variable mycustom-system-include-paths can be named arbitrarily. Many thanks to the helpful people over at stackoverflow for supplying me with the answer how to make a directory list nicely customizable.

Xcode 4.3, boost and the directory /Developer

Xcode 4.3 changed a lot. Most notably, all the stuff that was once under /Developer now resides under /Application/Xcode.app/Contents/Developer. And the SDKs have moved under the *.platform subdirectories. This breaks a lot of stuff. Especially auto-detecting build systems, such as boost jam. Will write back when I have some work arounds…

Update: I prepared a quick-fix for boost, so it compiles with Xcode 4.3 and builds the framework (see boost ticket #6686. However, I still get compile errors in my project, since clang is very picky and complains about boost:

I think this might be a genuine boost bug. It’s probably already known, but I haven’t checked. Will post another update when I find something.
The quick fix is also available in my github repo, see here.

Update 2: This is a known error, and it has been fixed in later revisions of boost (I am using 1.48 right now). The solution here is that instead of size, there should be size_arg. I wonder how this could ever have worked…

What about C++11 in Xcode?

This started out as a very small problem: I am using C++, Objective C++ and Objective C mixed in one project. This usually works pretty well. However, when including MapKit, the compiler choked on an Objective C++ file. It seems the MapKit.h header wants to use isinf(). This function has been introduced with ISO C 99, but it it is not included in ISO C++ 98. Hence the failure of Xcode’s gcc and clang compilers.

To work around this problem I was thinking of trying to set the project settings to use ISO C++ 11, or C++ 0x, since Xcode’s compilers are not that up to date. This is pretty easy:

And I guess this would work for most people. However, I am also using boost in this project. And I guess it is rather up to date, concerning the new language specification. However this also means that there is a problem with clang’s support of the language. I get a ton of errors in boost when switching to C++ 0x in clang:

In short, I think the C++ 11 support is not quite there yet with Xcode 4.2 and clang 3.0. I will try to post updates when future Xcode releases are coming out. If, alternatively, someone has hints on how to compile boost with clang 3.0, I am also glad to try that out.

Update: There is a fork on gitorious of the boost on iPhone build script, which already uses the clang compiler. I hacked the script even more to use –std=c++0x as a flag and it builds fine. Now I will try to link this new framework to an iOS project compiled with clang using C++ 0x.

Update 2: I found the root of the problem. The fantastic people over at #boost on freenode helped me figuring it out. In short: boost::fusion defines nil, which is an Objective C keyword. Thus we get lots of problems. Objective C defines nil and Nil in objc/objc.h. A minimal program that compiles successfully:

#include <boost/phoenix/core/reference.hpp>
#import <CoreFoundation/CoreFoundation.h>

int main()
{
return 1;
}

Using this command line:

/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang++ 
-isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk
-framework Foundation -Fpath/to/boost/framework --std=c++0x -arch armv7
-stdlib=libc++ -mthumb -miphoneos-version-min=5.0 foo.mm -o foo

If you swap the to include / import statements, the program will not compile, since now the ObjC nil makes boost break. There is a boost ticket tracking this issue, with a proposed patch attached, which renames the boost nil to nil_.

Update 3: The patch works fine, but now I get internal compiler errors from clang. The compile triggers a segmentation violation at some point during the compilation of my project. I guess clang 3.0 is still a bit experimental. I submitted a bug report and will revert to using the default settings of Xcode for the time being.