I make life easier, that is to say I've been writing software for 9+ years. Eschew hype; focus on delivery and performance.
Living in Switzerland 🇨🇠since 2017.
I make life easier, that is to say I've been writing software for 9+ years. Eschew hype; focus on delivery and performance.
Living in Switzerland 🇨🇠since 2017.
I've been using Emacs on and off for around half a year, maybe a little bit more, more recently I've been using it daily because I've been using Org-mode more and I've been editing code with it.
Something that has always bothered me about Emacs is how dang difficult it is to manage indentation configs and stuff like that. I've never been able to have a nice clean way to have a per-filetype based indentation config.
This is coming from the perspective of an adept Vim user, as it isn't actually that hard in Emacs, it's just tedious, while in Vim it's just one line.
For a while I was just using the editorconfig Emacs plugin, but it doesn't
work right, since it only checks the config for a file once, and that is when
the file is opened. If the .editorconfig
file changes you need to close/open
the file or close Emacs and open the file again.
BTW if you don't use editorconfig in your projects, this is a great chance to start now. It only makes sense to use it.
After a bit I started playing around with hooks.
Now for me the problem with hooks is that they're a bit verbose. That's not really a problem, it's just me not used to how verbose Lisp can get sometimes.
I am here to help you out with Emacs hooks.
This is quite simple, if you're not familiar with Emacs' built-in help system,
you really should look into it (C-h C-h
).
Do C-h v
to look for a variable, then start typing the name of the mode, let's
say shell-script
and then press tab, or ?
works as well. Probably one of
the last results you'll get is shell-script-mode-hook
. Try it for other modes
you're interested in, you'll probably be able to find them this way.
Now there are some caveats, apparently not all hooks are made equal. For
example, javascript-mode-hook
doesn't do anything, but js-mode-hook
does,
even though the major mode is called javascript-mode
.
Now it took me a bit, but I deviced a system that works pretty nicely and is not very verbose for my tastes, it is a bit tedious though if you don't have Lispy or Paredit.
Anyway, the strategy I have is simple. First I define a default indentation setup:
;; default
(setq-default tab-width 4)
(setq-default tab-stop-list (number-sequence 4 100 4))
(setq-default indent-tabs-mode 1)
You can find out what tab-width
, tab-stop-list
and indent-tabs-mode
do
with C-h v
, and about what number-sequence
does with C-h f
.
Those are some defaults that I want to have on every file for which I haven't defined something else.
Next I define a utility function:
(defun my-tabs-stuff (tabs length)
(setq indent-tabs-mode tabs)
(setq tab-width length)
(setq tab-stop-list (number-sequence length 100 length)))
What this function does is it just tells the buffer in which it is being run if
we should use real tabs or fake/space tabs (indent-tabs-mode
), then it goes on
to tell it how long a real tab should look (tab-width
) and what Emacs should
treat as a tab when dealing with spaces (tab-stop-list
). That's all our
function does.
Then we go on to define hook functions, these are the functions we are going to refer to as the function that gets called when the hook is triggered.
(defun my-emacs-lisp-hook ()
(my-tabs-stuff nil 2))
(defun my-shell-script-hook ()
(my-tabs-stuff 1 4))
(defun my-js-hook ()
(my-tabs-stuff 1 2))
So we are just defining one function per mode, which in my case only call one
function each, the function being my-tabs-stuff
and passing it the arguments
for what I want as indentation settings in that mode.
Now all that's left is to add these functions to the hooks:
(add-hook 'emacs-lisp-mode-hook 'my-emacs-lisp-hook)
(add-hook 'shell-script-mode-hook 'my-shell-script-hook)
(add-hook 'js-mode-hook 'my-js-hook)
;(setq js2-mode-hook js-mode-hook)
Note the last one, you can basically alias one mode's hooks to another's by using something like what you see in the last line.
Hopefully that helps you out, I've wasted too much time with Emacs figuring this out, or not figuring it out and suffering the consequences. So hopefully this saves you some time. :)