diff --git a/emacs/.emacs.d/init.org b/emacs/.emacs.d/init.org index d103983..040208f 100644 --- a/emacs/.emacs.d/init.org +++ b/emacs/.emacs.d/init.org @@ -51,6 +51,61 @@ You don't have to copy it if you copy anything from this file, as long as you do it consistently. +* Some general-purpose functions and macros + + A configuration as big as mine is bound to have some functions and + macros that are used in many places. + +** Turn off + + This macro creates a function that will turn off a minor mode that + passed to it. + + #+BEGIN_SRC emacs-lisp + (defmacro turn-off (func) + "Create a function that will turn off FUNC when called." + `(lambda () (eval (,func -1)))) + #+END_SRC + +** Change setting + + Sometimes a mode just needs to change a certain setting to a + specific value. + + #+BEGIN_SRC emacs-lisp + (defmacro change-setting (name value) + "Create a function that changes the value of NAME to VALUE." + `(lambda () (setq ,name ,value))) + #+END_SRC + +** Whitespace only with tabs + + In some modes I want to see the tabs in a buffer. Though I don't + want to be overwhelmed by seeing all spaces and line endings. + + #+BEGIN_SRC emacs-lisp + (defvar whitespace-style) + + (defun oni:whitespace-only-tabs () + (setq whitespace-style '(face tabs tab-mark)) + (whitespace-mode)) + #+END_SRC + +** Eval after init + + Some things can only really work after all other initialization + functions have completed. For example, any functions that require + any ELPA packages to be loaded, unless you want to load it in your + init manually (and have it loaded again later on after your config + has run). + + #+BEGIN_SRC emacs-lisp + (defmacro oni:eval-after-init (&rest body) + "Defer execution of BODY until after Emacs init." + (declare (indent 0)) + `(add-hook 'emacs-startup-hook #'(lambda () ,@body))) + #+END_SRC + * Use lexical binding For some of these functions, and general coolness, lexical binding @@ -1107,13 +1162,53 @@ I'm following this rule. #+BEGIN_SRC emacs-lisp - (defun oni:enable-whitespace-for-php () - (setq whitespace-style '(face tabs tab-mark)) - (whitespace-mode)) - - (add-hook 'php-mode-hook #'oni:enable-whitespace-for-php) + (add-hook 'php-mode-hook #'oni:whitespace-only-tabs) #+END_SRC +*** Use web-mode for HTML-heavy files + + I have to work with a lot of PHP and HTML interspersed. This makes + a difficult case since ~php-mode~ very deliberately doesn't support + that very well. On the other hand I really don't like ~web-mode~ for + PHP /without/ any HTML in it. So I decided to name the files that + contain mostly HTML with some PHP ~.html.php~ and have them load + ~web-mode~ instead of ~php-mode~, whilst keeping the association for + plain ~.php~ files as it is. + + Something tricky about doing this is that if this setting gets + evaluated /before/ ~php-mode~ is loaded it'll be further down the list + from ~php-mode~'s definition. This would cause the ~php-mode~ auto + mode definition from being accepted first (since ~.html.php~ also + matches ~.php~) and consequently render this definition useless. + + #+BEGIN_SRC emacs-lisp + (oni:eval-after-init + (add-to-list 'auto-mode-alist '("\\.html\\.php$" . web-mode))) + #+END_SRC + +** Web + + ~web-mode~ has some quirks, such as not being able to handle the + fact that ~fci-mode~ puts a red line at the 80-column margin. This is + annoying to say the least. + + #+BEGIN_SRC emacs-lisp + (declare-function fci-mode "fci-mode") + (add-hook 'web-mode-hook (turn-off fci-mode)) + #+END_SRC + + Just like in ~php-mode~ I want to see the tabs. + + #+BEGIN_SRC emacs-lisp + (add-hook 'web-mode-hook #'oni:whitespace-only-tabs) + #+END_SRC + + Set =indent-tabs-mode= for ~web-mode~ as well. + + #+BEGIN_SRC emacs-lisp + (add-hook 'web-mode-hook (change-setting indent-tabs-mode t)) + #+END_SRC + * Load custom file I don't really use the Emacs customization interface much, but I