I’ve been running Emacs for like 25 years. But I’ve never really configured it with anything fancy.
Sure, I’ve set some shortcut keys, and enabled global-font-lock-mode
and set indent size, but that’s almost it.
All my coding is done in tmux&Emacs. One project gets exactly one tmux
session. Window 0 is emacs. Window 1 is make && ./a.out
(sometimes
split panes to tail logs or run both server and client), and to run
git
commands. The remaining windows are used for various things like
reading manpages etc….
I have that same workflow whether I’m editing a blog post or doing kernel programming.
This way I can work at my desk with large and plentiful screens, and then move to my laptop and everything continues working exactly the same.
tmux I’ve customized, but not that much with Emacs.
So, step one to get my coding environment to be less 1995, and more 2020: make my editor understand my code, and show me stuff about it.
I’m learning as I’m going, and writing what I’m learning. As always if you see something wrong then please leave a comment.
Code annotations and other semantic understanding
The way to do this is to make your editor talk the Language Server
Protocol (LSP) with something that understands the language. For C++
that’s clangd
.
apt install clangd lsp-mode
Then we need to make this LSP thingy understand how to compile the
code. That’s a bit tricky since there may be system-local defines and
stuff. You may have had to provide flags to ./configure
to make it
build.
This information needs to end up in a file called
compile_commands.json
The way I found to do this is using scan-build
.
pip install scan-build
cat >> Makefile.am
lsp:
~/.local/bin/intercept-build make
^D
./bootstrap.sh && ./configure && make clean && make lsp
Now we just need to activate it in Emacs. That’s done by (lsp
t)
. But better yet, let’s trigger it when loading C++ code.
Let’s add this to ~/.emacs.d/init.el
:
(add-hook 'c++-mode-hook 'development-mode)
(defun development-mode ()
"Start dev stuff"
(interactive)
(lsp t)
(setq show-trailing-whitespace t)
(setq indent-tabs-mode nil))
Ok, that looks WHAT THE FUCK?!
Ok, after some searching lets add this to
~/.emacs.d/init.el` too:
Ok, that’s better. And we get nice context aware tab completion. Ok, now I feel like I’ve joined the 21st century.
Auto-format code on save
clang again comes to the rescue. Specifically clang-format
.
apt install clang-format
And more for ~/.emacs.d/init.el
:
(defun clang-format-save-hook-for-this-buffer ()
"Create a buffer local save hook."
(add-hook 'before-save-hook
(lambda ()
(progn
(when (locate-dominating-file "."".clang-format")
(clang-format-buffer))
;; Continue to save.
nil))
nil
;; Buffer local hook.
t)
)
(add-hook 'c++-mode-hook (lambda () (clang-format-save-hook-for-this-buffer)))
From Stackoverflow.
Summary
There, now I’ve advanced the state of my programming environment by about 20 years. If you were already doing this in 1995, then good for you.