A colleague provided me with a clang-format style file for a C++ project we are working on. I installed clang-format.el in order to be able to format a buffer from emacs. Reformatting works as expected. Emacs default c-mode indentation is still completely different, though.
I find it quite disturbing to destroy the source code formatting when editing and restore it later. Is there any way to read a clang-format file and apply the corresponding cc-mode options?
clang-format is located in clang/tools/clang-format and can be used to format C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# code.
You can install clang-format and git-clang-format via npm install -g clang-format . To automatically format a file according to Electron C++ code style, run clang-format -i path/to/electron/file.cc . It should work on macOS/Linux/Windows.
Configuring Style with clang-format clang-format file located in the closest parent directory of the input file.
Like most tools, it is not perfect nor covers every single case, but it is good enough to be helpful. clang-format can be used for several purposes: Quickly reformat a block of code to the kernel style. Specially useful when moving code around and aligning/sorting.
I am not aware if there is any direct conversion tool. However, you can try to use following trick:
Concatenate decent amount of C++ files from your project into single one (for instance cat *.cpp > single.cpp
)
Apply clang-format to that single.cpp
Open single.cpp
within Emacs
Use guess feature of CC-mode: M-x c-guess-no-install
and then M-x c-guess-view
I'm a bit late on this, but hopefully someone will still find this useful. I've posted the relevant portion of my clang-format config below, which provides the functionality you want.
(use-package clang-format
:after (s)
:init
(defun get-clang-format-option (config-str field is-num)
"Retrieve a config option from a clang-format config.
CONFIG-STR is a string containing the entire clang-format config.
FIELD is specific option, e.g. `IndentWidth'. IS-NUM is a
boolean that should be set to 1 if the option is numeric,
otherwise assumed alphabetic."
(if is-num
(let ((primary-match (s-match (concat "^" field ":[ \t]*[0-9]+") config-str)))
(if primary-match
(string-to-number (car (s-match "[0-9]+" (car primary-match))))
0))
(let ((primary-match (s-match (concat "^" field ":[ \t]*[A-Za-z]+") config-str)))
(if primary-match
(car (s-match "[A-Za-z]+$" (car primary-match)))
""))))
:hook (c-mode-common . (lambda ()
(let* ((clang-format-config
(shell-command-to-string "clang-format -dump-config"))
(c-offset (get-clang-format-option clang-format-config "IndentWidth" t))
(tabs-str (get-clang-format-option clang-format-config "UseTab" nil))
(base-style
(get-clang-format-option clang-format-config "BasedOnStyle" nil)))
(progn
(if (> c-offset 0)
(setq-local c-basic-offset c-offset)
(if (not (equal "" base-style))
(cond ((or (equal "LLVM" base-style)
(equal "Google" base-style)
(equal "Chromium" base-style)
(equal "Mozilla" base-style))
(setq-local c-basic-offset 2))
((equal "WebKit" base-style)
(setq-local c-basic-offset 4)))))
(if (not (equal "" tabs-str))
(if (not (string-equal "Never" tabs-str))
(setq-local indent-tabs-mode t)
(setq-local indent-tabs-mode nil))
(if (not (equal "" base-style))
(cond ((or (equal "LLVM" base-style)
(equal "Google" base-style)
(equal "Chromium" base-style)
(equal "Mozilla" base-style)
(equal "WebKit" base-style))
(setq-local indent-tabs-mode nil))))))))))
I use use-package. If you don't, you will have to make some minor adjustments. Additionally, note that I use s.el for string manipulation.
The code looks for "IndentWidth" and "UseTab". If it finds "UseTab" and it isn't set to "Never", I set indent-tabs-mode
to t
. Otherwise I set it to nil
. The value for "IndentWidth" goes to c-basic-offset
. If these fields are not found, but "BasedOnStyle" is found, the appropriate values are set based on that style. I have not included the Microsoft style since my version of clang-format won't give me a config dump for it (presumably it's in a later version). "IndentWidth" and "UseTab" override the behavior of "BasedOnStyle" which accords with clang-format's behavior. Finally, note that c-basic-offset
and indent-tabs-mode
are set as buffer local variables so this setup works as expected when working on several files with different configs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With