Clang Format

I often write code in C or C++ and frequently use clang-format to automatically format the code I'm writing. Although, occasionally I get into a situation where I should use a different coding style while I'm in a particular subdirectory.

As an example, in one project that I am working on, general C code should be written using the MISRA style, while sub-directories with Linux kernel modules should be written with the usual Linux Kernel Coding Style.

The simplest thing to do in this case is to create .clang-format files in each of the sub-directories and an overriding project .clang-format file for the whole project. This works just fine but I found it a bit tedious to copy these files around so I figured I might as well automate the creation of these files instead. Using the clang-format Emacs package, I created a small wrapper function to do just that:

(use-package clang-format
  :if (executable-find "clang-format")
  :ensure t
  :bind ("C-c f" . clang-format-create-style)
  (defvar my-clang-styles
     (concat user-emacs-directory "styles/") :full "[^.]")
    "My collection of clang-format styles.")

  (defun clang-format--find-or-create-style ()
    "Find or create a `.clang-format' file with style and root directory."
    (let* ((dir default-directory)
	   (prefix current-prefix-arg)
	   (styles my-clang-styles)
	   (found (unless prefix (locate-dominating-file dir ".clang-format")))
	   (root  (or found (read-directory-name "Root directory: " nil nil t)))
	   (style (or found (completing-read "Style: " styles nil t nil nil styles))))
      (unless found
	(copy-file style (concat root ".clang-format")))
      (list (region-beginning) (region-end))))

  (defun clang-format-create-style (beg end)
    "Use clang-format to automatically format the selected region.

Creates a `.clang-format' file at a selected root directory and
with the selected style before formatting the region [BEG, END]
if such a file does not already exist.

When `universal-argument' is set, always query for root directory
and style."
    (interactive (clang-format--find-or-create-style))
    (clang-format-region beg end)))

The way this function works is that when called with a prefix-argument (i.e., C-u), or when a .clang-format file is not found, it queries for one from the ~/.emacs.d/styles and asks for the root-directory where the file should be placed. This is similar to how the various ctag addons work and I've found it to be pretty convenient.


Comments powered by Disqus