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)
:init
(defvar my-clang-styles
(directory-files
(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.