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 I'm working ongeneral C code should be written using MISRA, while subdirectories 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 subdirectories 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