Updating GNU Global GTAGS file when Emacs is idle

GNU Global is a very useful code navigation tool. In order for it to work well, it needs to be run regularly. Until now, I used the after-save-hook, to keep it up to date. However, when using emacs-eclim (also see Eclim), saving becomes so frequent that performance takes a massive hit. So I whipped up this small code snippet to run Global only when Emacs is idle for some number of seconds (default is 10):


(defcustom my-gtags-update-idle-time 10
"Number of idle seconds before an incremental gtags update is launched"
:group 'my-group ;; Put whatever customization group you like here
:type 'integer
)
(run-with-idle-timer my-gtags-update-idle-time t
(lambda ()
(if (not (minibufferp) )
(progn
(message "Running gtags...")
(global-update-incrementally)
)
)
)
)

Switching to a Java package implementation in Emacs

There already quite a few methods to switch between header and implementation of C and C++ sources in Emacs. Maybe I will put one of those here as well later. But now I needed something different: In a big project, I would like to point at a line like import com.foo.tech.implementation.SomeClass; and Emacs automatically visits the file where this class has been implemented. I wrote two small Elisp functions to perform this:

(defun my-switch-to-java-implementation (packagename classname)
"Tries to switch to the java source file containing the package packagename and
the class classname."
(with-temp-buffer
(shell-command-to-string
(format "%s %s -iname '*.java' | xargs egrep -l '%s' | sort -u | xargs egrep -l 'class %s' | head -n 1"
"find"
"path/to/your/java/sources"
packagename
classname
)
(current-buffer) )
(if (= (count-lines (point-min) (point-max) ) 1)
(progn
(search-forward "n")
(replace-match "")
(find-file (buffer-string))
)
(message "Could not find suitable implementation.")
)
)
)

(defun my-switch-to-java-implementation-at-point ()
"Tries to switch to the java source file which contains the package and class imported
in the current line."
(interactive)
(save-excursion
(beginning-of-line)
(if (looking-at "^import \(.*\)\.\(.+\);$")
(let ( (packagename (buffer-substring (match-beginning 1) (match-end 1) ) )
(classname (buffer-substring (match-beginning 2) (match-end 2) ) ) )
(my-switch-to-java-implementation packagename classname)
)
(message "This is not an import")
)
)
)

You basically call my-switch-to-java-implementation-at-point (e.g. by binding it to a key) when you are on the import line. Emacs then launches find and grep to look for the definition of your class. Of course, using something like GNU Global would be faster, but also a bit more tricky, since it does not use the packagename, but rather only the class name, which might be used multiple times in your project.
Also note that you have to set the path to your Java source files. I suggest you make a customizable variable of that, or use your ede-project-root or something similar.

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.

Limiting the number of lines in the compilation window

For large projects, the output in the compilation window can become quite large. Furthermore, I use the ANSI coloring functionality, so that colored build systems look nice. These two things together can slow down Emacs significantly. However, when the compilation buffer gets so long, the output is most probably only success messages anyway. The errors would already have stopped the compilation process. So I wrote the following function to trim the compilation buffer:


(defun my-limit-compilation-buffer ()
"This function limits the length of the compilation buffer.
It uses the variable my-compilation-buffer-length to determine
the maximum allowed number of lines. It will then delete the first
N+50 lines of the buffer, where N is the number of lines that the
buffer is longer than the above mentioned variable allows."
(toggle-read-only)
(buffer-disable-undo)
(let ((num-lines (count-lines (point-min) (point-max))))
(if (> num-lines my-compilation-buffer-length)
(let ((beg (point)))
(goto-char (point-min))
(forward-line
(+
(- num-lines my-compilation-buffer-length)
(/ my-compilation-buffer-length 10) ) )
(delete-region (point-min) (point))
(goto-char beg)
)
)
)
(buffer-enable-undo)
(toggle-read-only)
)

Of course, now you still have to register this function to be actually applied to the compilation buffer, so I read about customization variables. And out came this, to introduce a customizable variable for toggling the compilation-trimming behaviour:


(defun set-my-compilation-buffer-length (symbol value)
(set-default symbol value)
(if value
(add-hook 'compilation-filter-hook 'my-limit-compilation-buffer)
(remove-hook 'compilation-filter-hook 'my-limit-compilation-buffer)
)
)

(defcustom my-compilation-buffer-length 2500
"The maximum number of lines that the compilation buffer is allowed to store"
:set 'set-my-compilation-buffer-length)

This is my first shot at such “complex” Emacs Lisp functions, so maybe it’s not optimal, and I don’t know much about the Emacs Lisp API either. Improvement suggestions are welcome!
Update: Over at Stackoverflow someone pointed me to a function that is already built into Emacs. So here’s the alternative solution:


(add-hook 'compilation-filter-hook 'comint-truncate-buffer)
(setq comint-buffer-maximum-size 2000)

This function is used for other comint buffers as well, such as the shell.

Emacs whitespace-mode

I just found out about whitespace-mode. Very useful if whitespaces are of syntactic value. For example in Makefiles. Emacs’ makefile-mode already shows leading spaces as pink, but leading and trailing spaces might be problematic in other cases as well. The whitespace-mode shows all kinds of spaces, eight spaces are highlighted in bright yellow (“no tab”), tabs are also visualized, as are newline characters.

Make emacsclient work with raise-frame

Emacs has the wonderful emacsclient for quickly editing files in Emacs from external tools, e.g. the shell. I am using the following alias to edit a file using emacsclient:


alias ec='emacsclient -n'

However, then Emacs’s window does not get raised, nor activated. There is also a bug in Emacs’ raise-frame function, which hinders any efforts. The best solution so far for this is described here, which uses wmctrl to activate and raise Emacs. My Emacs runs on Desktop 1, so I use wmctrl also to first switch to my Emacs desktop. You could probably make a more elaborate function which first finds the desktop that Emacs is running on, but this is good enough for me. So here is the slightly adjusted code snippet from the above link:


;;
;; Start emacs server
;;
(server-start)
(defadvice raise-frame (after make-it-work (&optional frame) activate)
"Work around some bug? in raise-frame/Emacs/GTK/Metacity/something.
Katsumi Yamaoka posted this in
http://article.gmane.org/gmane.emacs.devel:39702"
(call-process
"wmctrl" nil nil nil "-s" "1")
(call-process
"wmctrl" nil nil nil "-i" "-R"
(frame-parameter (or frame (selected-frame)) 'outer-window-id)))
(add-hook 'server-switch-hook 'raise-frame)

Quickly toggle last two buffers in Emacs

I don’t have much interesting stuff to post this month, so I’ll just go with one little snippet for Emacs. Next months will be better, I promise!
In Emacs, you can switch buffers by hitting C-x b and typing a buffer name. If you just hit C-x b RET, Emacs will just go to the last buffer. This is an awful lot of keys for such a simple function. So quite a long time ago, I found this useful small function, but I forgot where. In my config I’ve bound it to F4. I use the function keys quite a bit for file and buffer operations, maybe because I am a big fan of the Midnight Commander


(global-set-key [f4] (lambda ()
(interactive)
(switch-to-buffer
(other-buffer
(current-buffer) nil)
)))

Emacs other-window backwards

I am currently writing a lot of text in Emacs, and I need to work on multiple files in parallel. So I use the split window functionality a lot. With C-x o you can switch to the next split window. However, it would be nice to go backward as well. The solution is simple, and is given on Stackoverflow and some other blogs:

(defun prev-window ()

(interactive)
(other-window -1))
(global-set-key (kbd "C-x p") 'prev-window)

Just put this in you init.el, and you can cycle backwards using C-x p.