1862 lines
63 KiB
Org Mode
1862 lines
63 KiB
Org Mode
#+PROPERTY: tangle init2.el
|
||
#+STARTUP: content
|
||
#+OPTIONS: author:nil num:nil toc:nil
|
||
#+MACRO: key @@html:<kbd>$1</kbd>@@@@ascii:`$1'@@
|
||
#+HTML_HEAD: <link href="https://ryuslash.org/org.css" rel="stylesheet" type="text/css">
|
||
|
||
* Introduction
|
||
|
||
Inspired by [[Other such projects][other such projects]], here is my Emacs initialization
|
||
file.
|
||
|
||
*Note:* This is not my entire Emacs initialization file. It's a
|
||
work-in-progress.
|
||
|
||
** Setup
|
||
|
||
I could use org-babel to load this file, but I don't like my
|
||
initialization file having too many dependencies, especially big
|
||
dependencies, and org is big. It may be strange for you to read
|
||
this, as I have placed my entire Emacs configuration in an org-mode
|
||
file, but here are the make targets I use to tangle and
|
||
subsequently byte-compile my init file:
|
||
|
||
#+BEGIN_SRC makefile :tangle no
|
||
%.elc: %.el
|
||
emacs -Q -batch -eval "(byte-compile-file \"$<\")"
|
||
|
||
init.el: init.org
|
||
emacs -Q -batch -l "ob-tangle" -eval "(org-babel-tangle-file \"init.org\")
|
||
#+END_SRC
|
||
|
||
Executing the second target (either through make, or manually) will
|
||
get you my Emacs initialization file in plain Emacs Lisp.
|
||
|
||
*Note:* If you look at this file in its source form you will notice
|
||
that I actually tangle ~init.org~ into ~init2.el~. This is a temporary
|
||
measure so that I can gradually move my configuration from my
|
||
existing ~init.el~ file into ~init.org~ without much trouble. Once I
|
||
have emptied out my ~init.el~ I will instruct babel to tangle into
|
||
~init.el~, this code already reflects that.
|
||
|
||
** The ~oni:~ prefix
|
||
|
||
To keep my functions and variables from ever accidentally
|
||
interfering with other packages or Emacs internal variables I
|
||
prefix all the functions I write and variables I declare with ~oni:~.
|
||
You don't have to copy it if you copy anything from this file, as
|
||
long as you do it consistently.
|
||
|
||
I sometimes forget to do this, though.
|
||
|
||
** The ~depends-on~ snippets
|
||
|
||
At certain points in this document you will find bits of code that
|
||
look like:
|
||
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(depends-on "somepackage")
|
||
#+END_SRC
|
||
|
||
These calls are from the Cask DSL. They specify that my
|
||
configuration depends on some package found in one of the ELPA
|
||
repositories I have setup.
|
||
|
||
These snippets don't belong in your =init.el=, but instead in a
|
||
separate =Cask= file, and only if you use Cask, not if you just use
|
||
the standard ~package.el~.
|
||
|
||
** Other such projects
|
||
|
||
As stated, this project is inspired and influenced by other
|
||
literate configurations. Here is a list of some of the ones I've
|
||
found:
|
||
|
||
- [[http://sachac.github.io/.emacs.d/Sacha.html][Sacha Chua]]
|
||
- [[http://www.wisdomandwonder.com/wordpress/wp-content/uploads/2014/03/C3F.html][Grant Rettke]]
|
||
- [[https://github.com/wasamasa/dotemacs][Vasilij Schneidermann]]
|
||
|
||
* Preparation
|
||
|
||
Some things have to be done to make sure that everything works as it
|
||
should. This includes enabling lexical binding, loading Cask and
|
||
keeping some comments.
|
||
|
||
** Use lexical binding
|
||
|
||
For some of my functions, and general coolness, lexical binding is
|
||
a must. Without it, closures don't work for example. This line
|
||
needs to appear at the beginning of the file to work.
|
||
|
||
#+BEGIN_SRC emacs-lisp :padline no
|
||
;; -*- lexical-binding: t -*-
|
||
#+END_SRC
|
||
|
||
** Keep package.el from changing my init
|
||
|
||
Some time ago my init file was changed by Emacs. It added a single
|
||
line of code and some explanatory comments. Apparently I need to
|
||
keep this comment in my initialization file so that Emacs doesn't
|
||
try to add the code again. I actually use [[http://cask.readthedocs.org/en/latest/][Cask]] to manage and load
|
||
my packages so I don't need this.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
;; (package-initialize)
|
||
#+END_SRC
|
||
|
||
** Load Cask
|
||
|
||
I use Cask to manage my installed packages and for that to work I
|
||
need to load Cask at the start of the initialization file. This
|
||
should be executed both when byte-compiling and loading at run-time
|
||
so that other bits and pieces can byte-compile without warnings or
|
||
errors.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(eval-and-compile
|
||
(require 'cask "~/projects/ext/cask/cask.el")
|
||
(cask-initialize))
|
||
#+END_SRC
|
||
|
||
** Some helper functions
|
||
|
||
Certain functions make life a lot easier when configuring Emacs.
|
||
These don't generally belong to any one specific customization, but
|
||
make things look a lot prettier.
|
||
|
||
*** Optimized ~with-eval-after-load~
|
||
|
||
First offered [[http://www.lunaryorn.com/2013/05/01/byte-compiling-eval-after-load.html][here]] and then later updated [[http://www.lunaryorn.com/2013/06/25/introducing-with-eval-after-load.html][here]] (when
|
||
~with-eval-after-load~ was added). Makes for very nice on-demand
|
||
settings loading.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
;; http://www.lunaryorn.com/2013/06/25/introducing-with-eval-after-load/
|
||
(defmacro stante-after (feature &rest forms)
|
||
"After FEATURE is loaded, evaluate FORMS.
|
||
|
||
FEATURE may be an unquoted feature symbol or a file name, see
|
||
`eval-after-load'."
|
||
(declare (indent 1) (debug t))
|
||
`(,(if (or (not byte-compile-current-file)
|
||
(if (symbolp feature)
|
||
(require feature nil :noerror)
|
||
(load feature :no-message :no-error)))
|
||
`progn
|
||
(message "stante-after: cannot find %s" feature)
|
||
'with-no-warnings)
|
||
(with-eval-after-load ',feature ,@forms)))
|
||
#+END_SRC
|
||
|
||
*** Turn off minor modes
|
||
|
||
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 settings
|
||
|
||
Sometimes a mode just needs to change a certain setting to a
|
||
specific value.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defmacro change-settings (&rest settings)
|
||
"Create a function that changes the value of NAME to VALUE."
|
||
`(lambda () (setq ,@settings)))
|
||
#+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
|
||
|
||
*** 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-local whitespace-style '(face tabs))
|
||
(whitespace-mode))
|
||
#+END_SRC
|
||
|
||
** Useful functions
|
||
|
||
During your editing in Emacs you will undoubtedly find the need to
|
||
define your own editing functions or macros. Here are mine.
|
||
|
||
*** Delete the contents of the string at point
|
||
|
||
First we define the function. It was inspired by [[http://www.masteringemacs.org/][Mickey's post on
|
||
swapping quote symbols]], mostly copied even. First we check if we
|
||
are even in a string, and if not we throw an error, after that we
|
||
move back to the beginning of the string, store that point, go to
|
||
the end of the string (using =forward-sexp=) and then delete the
|
||
region between the two points (non-inclusive).
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun oni:delete-string-contents ()
|
||
(interactive)
|
||
|
||
(unless (nth 3 (syntax-ppss))
|
||
(error "You must be in a string for this command to work"))
|
||
|
||
(save-excursion
|
||
(while (nth 3 (syntax-ppss)) (forward-char -1))
|
||
|
||
(let ((bos (point)))
|
||
(forward-sexp)
|
||
(delete-region (1+ bos) (1- (point))))))
|
||
#+END_SRC
|
||
|
||
Since for interactive functions it's kind of a pain to have to use
|
||
a personal "namespace" I prefer naming them regularly as if they're
|
||
just part of the environment. If ever Emacs comes up with a similar
|
||
function with the same name, I'd prefer using the built-in version.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(unless (fboundp 'delete-string-contents)
|
||
(defalias 'delete-string-contents 'oni:delete-string-contents))
|
||
#+END_SRC
|
||
|
||
Lastly, any function worth using often should probably be easily
|
||
accessible with a keybinding. In my case the {{{key(C-c i s)}}} is
|
||
inspired by the Vim keybindings like {{{key(ci")}}}.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(global-set-key (kbd "C-c i s") 'delete-string-contents)
|
||
#+END_SRC
|
||
|
||
* General customization
|
||
|
||
These customizations don't belong with any specific mode.
|
||
|
||
** Set some personal information
|
||
|
||
This information is used by some emacs commands and modules to make
|
||
your life easier.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq user-full-name "Tom Willemse"
|
||
user-mail-address "tom@ryuslash.org")
|
||
#+END_SRC
|
||
|
||
** Turn-off menu bar
|
||
|
||
The menu bar is one of the UI elements which work best with mouses.
|
||
Sure you can change your toolkit's key bindings to allow you to
|
||
more easily navigate, but {{{key(M-x)}}} or {{{key(M-`)}}}[fn:1]
|
||
are easier if you don't use the mouse. Long story short: It has got
|
||
to go.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(menu-bar-mode -1)
|
||
#+END_SRC
|
||
|
||
I also do this in my =.Xdefaults= file, as that is applied sooner:
|
||
|
||
#+BEGIN_SRC conf-xdefaults :tangle no
|
||
Emacs.menuBar: off
|
||
#+END_SRC
|
||
|
||
** Turn-off tool bar
|
||
|
||
The toolbar is another such thing, and it takes up quite a bit more
|
||
space too. Icons can look pretty cool, but in the end if you're not
|
||
going to click them they don't really server much of a purpose.
|
||
Again: It has got to go.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(tool-bar-mode -1)
|
||
#+END_SRC
|
||
|
||
I also do this in my =.Xdefaults= as those settings are applied
|
||
sooner.
|
||
|
||
#+BEGIN_SRC conf-xdefaults :tangle no
|
||
Emacs.toolBar: off
|
||
#+END_SRC
|
||
|
||
** Turn-off blinking cursor
|
||
|
||
I suppose a blinking cursor doesn't get lost very easily. But on
|
||
the other hand, it can induce quite a few more headaches.
|
||
|
||
I've noticed that I don't really lose my cursor position all that
|
||
much, really, so there doesn't seem to be any point in making it
|
||
blink. Here we go again: It has got to go.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(blink-cursor-mode -1)
|
||
#+END_SRC
|
||
|
||
I also do this in my =.Xdefaults=, as those settings are applied
|
||
sooner.
|
||
|
||
#+BEGIN_SRC conf-xdefaults :tangle no
|
||
Emacs.cursorBlink: off
|
||
#+END_SRC
|
||
|
||
** Turn-off line numbers
|
||
|
||
As I'm currently using svg-mode-line-themes[fn:2] for my ~mode-line~
|
||
I don't need to show these. Also I didn't really use them much, I
|
||
don't often need to know what line I'm on.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(line-number-mode -1)
|
||
#+END_SRC
|
||
|
||
** Turn-off tooltips
|
||
|
||
Tooltips are another one of those UI elements that aren't quite
|
||
keyboard-friendly. As usually this information is shown just as well
|
||
in the echo area, this is not necessary.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(tooltip-mode -1)
|
||
#+END_SRC
|
||
|
||
** Change cursor type
|
||
|
||
I prefer using a bar as a cursor, as opposed to a box. Using a bar
|
||
is a better way of representing the location of the cursor, in my
|
||
opinion.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq-default cursor-type 'bar)
|
||
#+END_SRC
|
||
|
||
I use a bar cursor that's already pretty thin, so having an even
|
||
thinner one in inactive windows is not very clear. Even when I was
|
||
using a box cursor I didn't like seeing a hollow box everywhere my
|
||
focus /wasn't/.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq-default cursor-in-non-selected-windows nil)
|
||
#+END_SRC
|
||
|
||
** Truncate long lines
|
||
|
||
Sometimes, very long lines can't help but show up in code. The
|
||
default of wrapping lines around to the next line and showing an
|
||
image in the fringe is very visually disturbing to me when looking
|
||
at code[fn:3]. So I prefer to have it just run off the screen.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq-default truncate-lines t)
|
||
#+END_SRC
|
||
|
||
** Change default frame settings
|
||
|
||
Usually, most of these settings would be done with functions like
|
||
=set-frame-font= or =scroll-bar-mode=, but working with the Emacs
|
||
Daemon sometimes creates extra complications, because you might
|
||
start a graphical environment at some point (I usually do
|
||
immediately), but the startup process isn't.
|
||
|
||
*** Use a fantastic font
|
||
|
||
I've tried several fonts, and all of them were nice, but came up
|
||
short on some way. Some didn't have italic variants, some had
|
||
dotted zeroes instead of dashed zeroes, some even had entirely
|
||
clear zeroes which make them look like ~O~'s, others had
|
||
boring-looking parentheses[fn:4]. Not Fantasque Sans
|
||
Mono[fn:5][fn:6], it is awesome. If your web browser supports web
|
||
fonts you should also see it used in the code blocks here.
|
||
|
||
For normal Emacs setups you might use the =set-frame-font= function
|
||
like so:
|
||
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(set-frame-font "Fantasque Sans Mono-15" nil t)
|
||
#+END_SRC
|
||
|
||
However, this doesn't work when running Emacs as a Daemon. You
|
||
could (especially with lexical binding) add an
|
||
=after-make-frame-functions= hook or something similar, but I find
|
||
it easier to just specify the font in the =default-frame-alist=.
|
||
|
||
#+NAME: default-frame-font
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(font . "Fantasque Sans Mono-15")
|
||
#+END_SRC
|
||
|
||
I also do this in my =.Xdefaults= as those settings are applied
|
||
sooner.
|
||
|
||
#+BEGIN_SRC conf-xdefaults :tangle no
|
||
Emacs.font: Fantasque Sans Mono-15
|
||
#+END_SRC
|
||
|
||
*** Hide the scroll bar
|
||
|
||
The scroll-bar is almost just as informative as the current line
|
||
number and buffer position information shown in the (my) mode
|
||
line. As I don't usually need to know where I am, other than the
|
||
current line number occasionally, and I don't use the mouse, the
|
||
scroll bar doesn't add anything and only takes up space. Once
|
||
more: It has got to go.
|
||
|
||
Normally you would use something along the lines of:
|
||
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(scroll-bar-mode -1)
|
||
#+END_SRC
|
||
|
||
However, this doesn't work when running Emacs as a Daemon. So
|
||
instead I specify it in the =default-frame-alist=.
|
||
|
||
#+NAME: default-frame-scroll-bar
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(vertical-scroll-bars . nil)
|
||
#+END_SRC
|
||
|
||
*** Bringing it all together
|
||
|
||
So I've explained the reasons for each individual setting, but to
|
||
get them to work they have to be put in the =default-frame-alist=.
|
||
Here is the final setting:
|
||
|
||
#+BEGIN_SRC emacs-lisp :noweb yes
|
||
(setq default-frame-alist
|
||
`(<<default-frame-font>>
|
||
<<default-frame-scroll-bar>>))
|
||
#+END_SRC
|
||
|
||
** Set the frame title
|
||
|
||
Show the buffer name in the frame title to make multiple frames
|
||
identifiable by the buffer they're showing.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq frame-title-format '(:eval (concat "GNU Emacs: " (buffer-name))))
|
||
#+END_SRC
|
||
|
||
** Don't show dialog boxes
|
||
|
||
Unfortunately this doesn't remove /all/ dialog boxes, but at least it
|
||
keeps some of them from popping up. According to the docstring it
|
||
should only change anything for when the mouse is used, which I
|
||
don't ever do, but I still feel safer keeping this in my
|
||
configuration.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq use-dialog-box nil)
|
||
#+END_SRC
|
||
|
||
** Split windows equally
|
||
|
||
When splitting windows, give them all an equal amount of space. For
|
||
those very few time that I have more than two windows in my Emacs
|
||
frame it is much nicer to have each of them get ~33% space instead
|
||
of 50%, 25% and 25%. The way I have my desktop set-up I don't ever
|
||
split my windows horizontally.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq window-combination-resize t)
|
||
#+END_SRC
|
||
|
||
** Keep the cursor steady when scrolling
|
||
|
||
When scrolling through the buffer with, for example, {{{key(C-v)}}}
|
||
or {{{key(M-v)}}}, I find it much more intuitive to have the cursor
|
||
stay in the relative screen position from before. Otherwise I get
|
||
confused every time.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq scroll-preserve-screen-position t)
|
||
#+END_SRC
|
||
|
||
** Don't show a mode line for completions
|
||
|
||
One of the things I dislike about Emacs is its rigidity concerning
|
||
windows and other UI elements. One very simple way to make it
|
||
/feel/ less so is to show less of it where possible. A mode line for
|
||
completion buffers creates more separation than necessary, and I
|
||
can't recall a single time where I've used the completion's mode
|
||
line for anything.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'completion-list-mode-hook
|
||
(lambda () (setq mode-line-format nil)))
|
||
#+END_SRC
|
||
|
||
** Use pixels, not columns/rows to resize frames.
|
||
|
||
As of Emacs 24.4 frames can resize to pixel sizes instead of
|
||
columns and rows. This keeps annoying gaps from forming when using
|
||
a tiling window manager. The real difference is that when this is
|
||
done now, the actual text portions of the window get the extra
|
||
space, not some fringe or margin. This looks much nicer.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq frame-resize-pixelwise t)
|
||
#+END_SRC
|
||
|
||
** Don't just quit Emacs with {{{key(C-x C-c)}}} in the daemon
|
||
|
||
When working with Emacs as a daemon, which I do almost all of the
|
||
time, I prefer using {{{key(C-x C-c)}}} to close the current frame
|
||
instead of the entire session. Before this change I would
|
||
occasionally close my session by mistake.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun oni:close-client-window ()
|
||
"Close a client's frames."
|
||
(interactive)
|
||
(server-save-buffers-kill-terminal nil))
|
||
|
||
(when (daemonp)
|
||
(global-set-key (kbd "C-x C-c") 'oni:close-client-window))
|
||
#+END_SRC
|
||
|
||
** Don't minimize the frame with {{{key(C-z)}}}
|
||
|
||
One of the more annoying things that can happen is accidentally
|
||
minimizing the frame you're working with. This doesn't really matter
|
||
if you're working on a normal stacking window manager, but with a
|
||
tiling window manager and no task bar this just causes the Emacs
|
||
frame to hang until it is refocused or disappear with no way to get
|
||
it back.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(when (or window-system (daemonp))
|
||
(global-unset-key (kbd "C-z")))
|
||
#+END_SRC
|
||
|
||
** Lazily load some buffers
|
||
|
||
Don't load all buffers right away. Having a lot of buffers and
|
||
switching between projects a lot can take up quite a bit of time.
|
||
|
||
*Note:* See my [[Vacuous defvar][note]] on vacuous defvar for this use of =defvar=.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defvar desktop-restore-eager)
|
||
(setq desktop-restore-eager 5)
|
||
#+END_SRC
|
||
|
||
** Ask for a ~y~ or ~n~, not ~yes~ or ~no~.
|
||
|
||
Emacs starts out asking for you to type ~yes~ or ~no~ with most
|
||
important questions. It is possible that this is used for such
|
||
important questions where accidentally saying ~yes~ when you meant ~no~
|
||
would be catastrophic (or at least could be). However, I've never
|
||
(so far) had this problem, and I find it quite tedious to have to
|
||
write out ~yes~ or ~no~ and then press {{{key(RET)}}}, give me a simple
|
||
~y~ or ~n~ with no {{{key(RET)}}} required and I'm quite happy.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defalias 'yes-or-no-p 'y-or-n-p)
|
||
#+END_SRC
|
||
|
||
** Use =hippie-expand=, not =dabbrev-expand=
|
||
|
||
I've never actually used =dabbrev-expand=, and only rarely use
|
||
=hippie-expand= really, but since =hippie-expand= also includes a
|
||
=dabbrev= expander and a lot more than just that, it seems alright to
|
||
do this.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defalias 'dabbrev-expand 'hippie-expand)
|
||
#+END_SRC
|
||
|
||
** Setting up =load-path=
|
||
|
||
First, to help, I create a function that takes a path, adds it to
|
||
=load-path= and then checks to see if there is a file named
|
||
~loaddefs.el~ in the given path. If there is, it loads it. This
|
||
~loaddefs.el~ file is something that is created from autoload cookies
|
||
in the files in some of these paths.
|
||
|
||
Since the =load-path= is also important during byte-compilation, this
|
||
function should be defined both at run-time and compile-time.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(eval-and-compile
|
||
(defun oni:loadpath-add-and-autoload (path)
|
||
"Add PATH to `load-path' and load a `loaddefs.el' if it exists."
|
||
(add-to-list 'load-path path)
|
||
(let ((loaddefs (concat path "/loaddefs.el")))
|
||
(when (file-exists-p loaddefs)
|
||
(load loaddefs)))))
|
||
#+END_SRC
|
||
|
||
After that I add some directories to my =load-path= so I can use these
|
||
libraries when wanted. One of these is the ~site-lisp~ directory in my
|
||
~.emacs.d~ directory, which is where I keep most of my personal
|
||
non-ELPA modules (like module-specific initialization files). There
|
||
are also some directories I include in ~vendor-lisp~, which is where I
|
||
keep modules that I didn't write myself and, for some reason, can't
|
||
or don't want to use ELPA for. Again it is important to realize that
|
||
this information is relevant both at run-time and compile-time, so
|
||
we wrap it with an =eval-and-compile=.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(eval-and-compile
|
||
(mapc #'oni:loadpath-add-and-autoload
|
||
'("~/.emacs.d/site-lisp"
|
||
"~/.emacs.d/vendor-lisp/mozrepl"
|
||
"~/.emacs.d/vendor-lisp/eap" "/usr/share/emacs/site-lisp"
|
||
"/usr/lib/node_modules/tern/emacs/"
|
||
"~/.emacs.d/vendor-lisp/habitrpg.el")))
|
||
#+END_SRC
|
||
|
||
** Turn off bidirectional text
|
||
|
||
To speed things up a little, and because I have no contacts at all
|
||
(so far) who use right-to-left text, there is no reason for me to
|
||
use bidirectional text. For this reason I tell Emacs to always use
|
||
left-to-right by default, instead of checking each paragraph.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq-default bidi-paragraph-direction 'left-to-right)
|
||
#+END_SRC
|
||
|
||
** Don't use tabs
|
||
|
||
There is a war going on out there. Actually there are several, but
|
||
the one I'm talking about here is the one about tabs vs. spaces. I
|
||
have been deeply entrenched in the spaces camp for quite a while.
|
||
Indentation always gets screwy for me if I don't use the exact same
|
||
=tab-width= everyone else uses. I just like the consistency of using
|
||
spaces.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq-default indent-tabs-mode nil)
|
||
#+END_SRC
|
||
|
||
** Use four spaces for indentation
|
||
|
||
I once, long ago, started out with using eight spaces for each
|
||
level of indentation. Although I think, technically, I was using
|
||
tabs. This means that even just 3 levels of indentation take up a
|
||
/huge/ amount of space that can't be used for anything else. Since I
|
||
also try to limit the length of the lines in my code, this can make
|
||
for very little code per line.
|
||
|
||
I also tried (and enjoyed) two spaces, but after a while, looking
|
||
at bigger files, I noticed that it all becomes a blur. Two spaces
|
||
is not a big-enough visual difference to make code read nicely, in
|
||
my opinion.
|
||
|
||
So far, I have quite enjoyed four spaces for most code[fn:8].
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq-default tab-width 4)
|
||
#+END_SRC
|
||
|
||
** Keep the message buffer from growing too large
|
||
|
||
Keep at most one-thousand messages in the ~*Messages*~ buffer. I can
|
||
leave my Emacs session running for quite long times, sometimes
|
||
days, at a time. If there are a lot of messages it can get a little
|
||
tricky to manage/search.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq message-log-max 1000)
|
||
#+END_SRC
|
||
|
||
** Reject SSL/TLS certificates that don't check out
|
||
|
||
You just can't trust the internet. And I'd prefer to know if
|
||
something goes wrong.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defvar gnutls-verify-error)
|
||
|
||
(setq gnutls-verify-error t)
|
||
#+END_SRC
|
||
|
||
** Use Conkeror to browse URLs
|
||
|
||
Use the generic browse-url function to open URLs in Conkeror.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(stante-after browse-url
|
||
(setq browse-url-browser-function 'browse-url-generic)
|
||
(setq browse-url-generic-program "conkeror"))
|
||
#+END_SRC
|
||
|
||
* Major mode customization
|
||
|
||
Many major modes offer and require some customization. I use the
|
||
term major mode somewhat loosely here because some of these
|
||
customizations don't actually deal with major modes, but full-on
|
||
applications or frameworks like Gnus and Elnode.
|
||
|
||
** Org mode
|
||
|
||
Org mode offers /a lot/ of customization options. Most of mine are in
|
||
a separate file.
|
||
|
||
Store org id locations in my Emacs data directory.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package org-id
|
||
:defer t
|
||
:config
|
||
(setq org-id-locations-file
|
||
(concat user-emacs-directory "data/org-id-locations")))
|
||
#+END_SRC
|
||
|
||
*** Add org-mode appointments to the diary
|
||
|
||
Diary offers reminders, which can be useful when scheduling
|
||
appointments.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defadvice org-agenda-redo (after ext:org-agenda-redo-add-appts)
|
||
"Pressing `r' on the agenda will also add appointments."
|
||
(setq appt-time-msg-list nil)
|
||
(org-agenda-to-appt))
|
||
#+END_SRC
|
||
|
||
** Ansi term
|
||
|
||
I don't use ansi term much. Though I probably should do it more.
|
||
Eshell is much nicer for many reasons but it can't handle
|
||
everything.
|
||
|
||
*** Close ansi-term buffer after exit
|
||
|
||
After the ansi-term process ends it leaves a buffer. I don't use
|
||
ansi term in such a way that this has ever been useful, so just kill
|
||
the ansi-term buffer after the process quits, no matter the exit
|
||
status. Usually this comes about when I press {{{key(C-d)}}} at the
|
||
command prompt.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defadvice term-handle-exit (after oni:kill-buffer-after-exit activate)
|
||
"Kill the term buffer if the process finished."
|
||
(kill-buffer (current-buffer)))
|
||
#+END_SRC
|
||
|
||
*** Fix some term keybindings
|
||
|
||
=ansi-term= passes along a lot of characters correctly, but things
|
||
like =forward-delete-word= are not, by default. This is confusing when
|
||
you see one thing and another is sent. Passing the correct keys
|
||
directly to the terminal fixes this problem.
|
||
|
||
*Note:* See my [[Vacuous defvar][note]] on vacuous defvar for this use of =defvar=.
|
||
|
||
*Note:* See my [[Function declarations][note]] on function declarations about the use of
|
||
=declare-function=.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defvar term-raw-map)
|
||
(declare-function term-send-raw-string "term")
|
||
|
||
(defun oni:set-term-keys ()
|
||
(cl-flet ((zcommand (key)
|
||
(lambda ()
|
||
(interactive) (term-send-raw-string key))))
|
||
(define-key term-raw-map
|
||
(kbd "C-<backspace>") (zcommand "\C-H"))))
|
||
|
||
(add-hook 'term-mode-hook #'oni:set-term-keys)
|
||
#+END_SRC
|
||
|
||
** Gnus
|
||
|
||
Gnus is a very powerful news reader that also handles Email quite
|
||
well. I've been using it for a while now, though not to its full
|
||
extent I'm sure. This section contains customization for multiple
|
||
major modes that are all closely related to Gnus.
|
||
|
||
*** Use the right dictionary
|
||
|
||
One of the caveats of using two (or more) languages in a single
|
||
installation of Gnus is that ispell sometimes gets confused. Having
|
||
come across a stackoverflow question[fn:7] about just this subject
|
||
it was easy to modify the source code posted there to come up with
|
||
this.
|
||
|
||
*Note:* See my [[Function declarations][note]] on function declarations about the use of
|
||
=declare-function=.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(declare-function message-narrow-to-headers-or-head "message")
|
||
(declare-function message-fetch-field "message")
|
||
|
||
(defun oni:switch-ispell-dictionary ()
|
||
(save-excursion
|
||
(message-narrow-to-headers-or-head)
|
||
(when (string-match (rx (and "@" (or "aethon" "picturefix") ".nl>") eol)
|
||
(message-fetch-field "From"))
|
||
(ispell-change-dictionary "nl_NL"))))
|
||
|
||
(add-hook 'message-setup-hook 'oni:switch-ispell-dictionary)
|
||
#+END_SRC
|
||
|
||
*** Don't let shr use background color
|
||
|
||
Reading mail in Gnus is very nice, but shr has become a little too
|
||
good at its job. Add to this the many occasions when a background is
|
||
specified without specifying a foreground, plus a color theme that
|
||
is the inverse of what is usually expected, and you can get
|
||
hard-to-read HTML messages, gray foreground and gray background.
|
||
|
||
I've looked at the other possible renderers, but they don't look
|
||
very nice compared to shr. So just remove its ability to add
|
||
background colors.
|
||
|
||
*Note:* See my [[Function declarations][note]] on function declarations about the use of
|
||
=declare-function=.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(declare-function shr-colorize-region "shr")
|
||
|
||
(defun oni:shr-colorize-remove-last-arg (args)
|
||
"If ARGS has more than 3 items, remove the last one."
|
||
(if (> (length args) 3)
|
||
(butlast args)
|
||
args))
|
||
|
||
(with-eval-after-load 'shr
|
||
(advice-add #'shr-colorize-region :filter-args
|
||
#'oni:shr-colorize-remove-last-arg))
|
||
#+END_SRC
|
||
|
||
*** Init file
|
||
|
||
I put my gnus initialization file right where I put all my
|
||
module-specific initialization files. Gnus is special, though: It
|
||
loads the file every time you start it. That keeps it from using a
|
||
simple =(eval-after-load 'gnus '(load "gnus-init"))=.
|
||
|
||
*Note:* See my [[Vacuous defvar][note]] on vacuous defvar for this use of =defvar=.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defvar gnus-init-file)
|
||
(setq gnus-init-file "~/.emacs.d/site-lisp/gnus-init")
|
||
#+END_SRC
|
||
|
||
** SQL
|
||
|
||
This is a generic comint mode for multiple SQL implementations such
|
||
as PostgreSQL and MariaDB (MySQL).
|
||
|
||
*** Remember SQL input
|
||
|
||
Remembering input between sessions is a good thing.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(stante-after sql
|
||
(setf sql-input-ring-file-name
|
||
(expand-file-name "~/.emacs.d/etc/sqliinput")))
|
||
#+END_SRC
|
||
|
||
** Python
|
||
|
||
I used to code Python for a living, that's not so much the case
|
||
anymore. And for almost everything I will prefer Lisp over Python.
|
||
So these customizations might be a little old or badly tested.
|
||
|
||
*** Show package name instead of file name
|
||
|
||
When working with python, knowing which package I'm in usually tells
|
||
me more about what I'm doing than the file name, especially when
|
||
working with django where almost every app will have a ~tests.py~ and
|
||
a ~models.py~. Of course =uniquify= fixes this pretty well too, though
|
||
in this case, it's less cool (imo).
|
||
|
||
First we define two functions that help us determine the package
|
||
name of the current file and the parent package name of the current
|
||
file. Finally we define a third function which determines the full
|
||
package name of the current buffer.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun oni:python--get-current-module-name ()
|
||
"Get the name of the current python module.
|
||
|
||
This is very simply just the filename of the current buffer with
|
||
the extension and pyath removed."
|
||
(file-name-sans-extension
|
||
(file-name-nondirectory (buffer-file-name))))
|
||
|
||
(defun oni:python--get-parent-module-name (&optional dir)
|
||
"This gets the currend file's parent module.
|
||
|
||
This function recursively gathers the parent package name of
|
||
either DIR or the current buffer's file name. Any directory where
|
||
an `__init__.py' file is found is considered to be a package.
|
||
|
||
This function returns either the parent package, with its
|
||
parents, or nil if the current directory isn't a python
|
||
package.."
|
||
(let* ((base (directory-file-name
|
||
(file-name-directory (or dir (buffer-file-name)))))
|
||
(package (file-name-nondirectory base)))
|
||
(if (file-exists-p (concat base "/__init__.py"))
|
||
(let ((parent (oni:python--get-parent-module-name base)))
|
||
(if parent
|
||
(concat parent "." package)
|
||
package))
|
||
nil)))
|
||
|
||
(defun oni:python-package-name ()
|
||
(let ((current-module (oni:python--get-current-module-name)))
|
||
(if (file-exists-p "__init__.py")
|
||
(concat (oni:python--get-parent-module-name)
|
||
"." current-module)
|
||
current-module)))
|
||
#+END_SRC
|
||
|
||
After all this we make Emacs show the package name rather than the
|
||
file name in the mode-line.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun oni:python-package-buffer-identification ()
|
||
"Have `mode-line-buffer-identification' show the python package name."
|
||
(setq mode-line-buffer-identification
|
||
'(:eval (oni:python-package-name))))
|
||
|
||
(add-hook 'python-mode-hook #'oni:python-package-buffer-identification)
|
||
#+END_SRC
|
||
|
||
** Elnode
|
||
|
||
Elnode is an awesome project and I'm still looking for a moment
|
||
where I have the inspiration and time to actually do something with
|
||
it. I started at some point, but then I couldn't get the cookies to
|
||
work and I switched over to using Common Lisp, only to eventually
|
||
stop developing the project because there was not chance of it
|
||
seeing any use in the foreseeable future.
|
||
|
||
*** Don't start =elnode= when Emacs starts
|
||
|
||
There is one little annoyance and that is the fact that elnode
|
||
will start itself up when Emacs starts. I don't want that.
|
||
|
||
This bit of code can't be put in an =eval-after-load= or anything
|
||
like that because by the time it would be evaluated, elnode would
|
||
already have started.
|
||
|
||
*Note:* See my [[Vacuous defvar][note]] on vacuous defvar for this use of =defvar=.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defvar elnode-do-init)
|
||
(setq elnode-do-init nil)
|
||
#+END_SRC
|
||
|
||
** js2
|
||
|
||
=js2-mode= isn't just an "improved" JavaScript mode, it's a full-on
|
||
JavaScript parser. It's easy to notice typo's and such when Emacs
|
||
can show you that a certain variable is or isn't declared. It does
|
||
come with some baggage, as it's not immediately clear how I can
|
||
specify which global names exist. For simple files it is fine to do
|
||
something like:
|
||
|
||
#+BEGIN_SRC js2 :tangle no
|
||
/*global $ Routes jQuery */
|
||
#+END_SRC
|
||
|
||
Which will tell =js2-mode= that =$=, =Routes= and =jQuery= are known to be
|
||
define elsewhere. This doesn't work well for big lists of globals.
|
||
|
||
*** Add some known symbols for .conkerorrc/init.js to js2-mode
|
||
|
||
Conkeror has a lot of functions, and I don't like seeing them all as
|
||
unknowns. So add them to known symbols.
|
||
|
||
*Note:* See my [[Vacuous defvar][note]] on vacuous defvar for this use of =defvar=.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defvar js2-additional-externs)
|
||
|
||
(defun oni:js2-add-conkeror-symbols ()
|
||
"Add known/used conkeror symbols to additional externs."
|
||
(when (string-suffix-p ".conkerorrc/init.js" (buffer-file-name))
|
||
(setq js2-additional-externs
|
||
'( ;; Functions
|
||
"add_hook" "check_buffer" "co_return" "content_buffer"
|
||
"define_browser_object_class" "define_key" "define_webjump"
|
||
"dumpln" "get_current_profile" "get_home_directory"
|
||
"get_recent_conkeror_window"
|
||
"hints_minibuffer_annotation_mode" "interactive" "load_spec"
|
||
"load_spec_uri_string" "load_url_in_new_buffer" "make_file"
|
||
"make_uri" "mode_line_adder"
|
||
"open_download_buffer_automatically" "prefix_completer"
|
||
"read_browser_object" "register_user_stylesheet"
|
||
"remove_hook" "require" "send_http_request" "session_pref"
|
||
"shell_command_blind" "theme_load"
|
||
;; Variables
|
||
"Cc" "Ci" "browser_object_history_url" "browser_object_links"
|
||
"buffer_count_widget" "buffer_icon_widget" "content_buffer"
|
||
"content_buffer_form_keymap" "content_buffer_normal_keymap"
|
||
"content_buffer_text_keymap" "content_policy_accept"
|
||
"content_policy_bytype" "content_policy_reject" "cwd"
|
||
"default_base_keymap" "default_global_keymap"
|
||
"downloads_status_widget" "external_content_handlers"
|
||
"hint_digits" "load_paths" "read_buffer_show_icons"
|
||
"read_url_handler_list" "session_auto_save_auto_load"
|
||
"theme_load_paths" "title_format_fn" "url_remoting_fn"
|
||
;; Keyword argument
|
||
"$alternative" "$browser_object" "$completer" "$completions"
|
||
"$initial_value" "$options" "$prompt" "$sort_order"
|
||
"$use_bookmarks" "$use_history" "$use_webjumps"))))
|
||
|
||
(add-hook 'js2-init-hook #'oni:js2-add-conkeror-symbols)
|
||
#+END_SRC
|
||
|
||
** Eww
|
||
|
||
I've been excited about the "Emacs Web Wowser" since I first read
|
||
about it on the mailing list. Previously I'd used some integration
|
||
with w3 which was ok, but it certainly didn't match up to a
|
||
fully-integrated Emacs application.
|
||
|
||
This application uses =shr= just like Gnus, so there is some overlap
|
||
here with reading Emails.
|
||
|
||
*** Teach eww about <code> tags
|
||
|
||
Strangely enough, ~eww~ doesn't seem to be aware of =<code>= HTML tags.
|
||
Luckily it's trivial to teach it. It does know about =<pre>= HTML
|
||
tags, and basically I just want =<code>= tags to be treated almost as
|
||
=<pre>= tags, so to do that we just have to define a =shr-tag-code=
|
||
function. I've copied the =shr-tag-pre= function and removed the calls
|
||
to =ensure-newline=, because =<code>= tags are inline tags.
|
||
|
||
In order to remain a little future-proof, it should only be done if
|
||
it doesn't already exist.
|
||
|
||
*Note:* See my [[Vacuous defvar][note]] on vacuous defvar for this use of =defvar=.
|
||
|
||
*Note:* See my [[Function declarations][note]] on function declarations about the use of
|
||
=declare-function=.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defvar shr-folding-mode)
|
||
(declare-function shr-indent "shr")
|
||
(declare-function shr-generic "shr")
|
||
|
||
(with-eval-after-load 'shr
|
||
(unless (fboundp 'shr-tag-code)
|
||
(defun shr-tag-code (cont)
|
||
(let ((shr-folding-mode 'none))
|
||
(shr-indent)
|
||
(shr-generic cont)))))
|
||
#+END_SRC
|
||
|
||
*** Setup eww-lnum
|
||
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(depends-on "eww-lnum")
|
||
#+END_SRC
|
||
|
||
As recommended in the [[https://github.com/m00natic/eww-lnum][README]], set the keys in the =eww-mode-map=.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defvar eww-mode-map)
|
||
|
||
(with-eval-after-load 'eww
|
||
(define-key eww-mode-map "f" 'eww-lnum-follow)
|
||
(define-key eww-mode-map "F" 'eww-lnum-universal))
|
||
#+END_SRC
|
||
|
||
** Scheme
|
||
|
||
I really like programming in Lisp. One of the more comfortable
|
||
Lisps is Scheme because most of the implementations I've worked
|
||
with are more like other compiled or interpreted languages, whereas
|
||
Common Lisp usually re-compiles on every load. Aside from that,
|
||
there are some neat programs written in some scheme dialects and of
|
||
course scsh is the most awesome shell scripting language ever
|
||
conceived.
|
||
|
||
*** Use scheme-mode for scsh interpreted files
|
||
|
||
Set the major mode for files interpreted by scsh (for example, by
|
||
having ~#!/usr/local/bin/scsh~ at the top) to use =scheme-mode=.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-to-list 'interpreter-mode-alist '("scsh" . scheme-mode))
|
||
#+END_SRC
|
||
|
||
*** Set default scheme implementation
|
||
|
||
Set the default implementation for geiser to guile so it doesn't ask
|
||
which implementation to use every time.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(stante-after geiser-impl
|
||
(setq geiser-default-implementation 'guile))
|
||
#+END_SRC
|
||
|
||
** SCSS
|
||
|
||
SCSS is a CSS preprocessor that makes writing CSS files much more
|
||
fun. Add autocompletion and some custom imenu function.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'scss-mode-hook 'auto-complete-mode)
|
||
(add-hook 'scss-mode-hook 'scss-imenu-setup)
|
||
#+END_SRC
|
||
|
||
** Dired
|
||
|
||
Dired is an excellent file manager.
|
||
|
||
*** Change listings in dired
|
||
|
||
The number of bytes a file is doesn't usually tell me much when it's
|
||
something like ~292837~. I prefer seeing just how many Kb or Mb a
|
||
certain file is. I also don't need to see the ~.~ and ~..~ directories
|
||
when I insert directories into the current dired buffer, as there is
|
||
a great chance that the current and parent directory are already
|
||
shown in the buffer.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defvar dired-subdir-switches)
|
||
|
||
(with-eval-after-load 'dired
|
||
(setq dired-listing-switches "-alh"
|
||
dired-subdir-switches "-Alh"))
|
||
#+END_SRC
|
||
|
||
** PHP
|
||
|
||
I occasionally write PHP for work. Not usually in my free time, but
|
||
there are some open source PHP projects that I sometimes tinker
|
||
with.
|
||
|
||
*** Show tabs and spaces in indent
|
||
|
||
I'm working with some WordPress plugins nowadays and their style
|
||
guide insists on using tabs, not spaces... I'd like to know that
|
||
I'm following this rule.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'php-mode-hook #'oni:whitespace-only-tabs)
|
||
#+END_SRC
|
||
|
||
** Web
|
||
|
||
Web mode is good for files that contain a lot of HTML, CSS and
|
||
JavaScript together. Most other major modes or multi-major modes
|
||
don't quite do it.
|
||
|
||
*** Turn off the fill column indicator
|
||
|
||
~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
|
||
|
||
*** Show tabs in indentation
|
||
|
||
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
|
||
|
||
*** Use tabs for indentation
|
||
|
||
Set =indent-tabs-mode= for ~web-mode~ as well.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defvar web-mode-code-indent-offset)
|
||
(defvar web-mode-markup-indent-offset)
|
||
|
||
(add-hook 'web-mode-hook
|
||
(change-settings indent-tabs-mode t
|
||
web-mode-code-indent-offset 4
|
||
web-mode-markup-indent-offset 4))
|
||
#+END_SRC
|
||
|
||
*** Use it for Embedded Ruby HTML files
|
||
|
||
Use it for ~.html.erb~ files.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(oni:eval-after-init
|
||
(add-to-list 'auto-mode-alist '("\\.html\\.erb$" . web-mode)))
|
||
#+END_SRC
|
||
|
||
*** Use it for HTML-heavy PHP 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
|
||
|
||
** PO mode
|
||
|
||
Autoload =po-mode=, because it didn't come with an autloads file or
|
||
cookie.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(autoload 'po-mode "po-mode" nil t)
|
||
#+END_SRC
|
||
|
||
Automatically enable =po-mode= for files that end in =.po= or that have
|
||
a =.po= extension followed by others (such as =.po.erb=).
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-to-list 'auto-mode-alist '("\\.po\\'\\|\\.po\\." . po-mode))
|
||
#+END_SRC
|
||
|
||
** Magit
|
||
|
||
Recently Magit gained the annoying habit of producing a /huge/ warning
|
||
message whenever you don't tell it that you've already seen it. To
|
||
tell it you've already seen the message you need to specify the
|
||
following.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(eval-and-compile
|
||
(defvar magit-last-seen-setup-instructions "1.4.0"))
|
||
#+END_SRC
|
||
|
||
I use a =defvar= here in order to keep the byte-compiler from
|
||
complaining about an undefined variable. It needs to be specified
|
||
before magit is loaded otherwise magit will keep complaining.
|
||
|
||
*** Project directory
|
||
|
||
I keep all my projects in =~/projects/=, so Magit shouldn't have to
|
||
look anywhere else.
|
||
|
||
#+NAME: magit-repo-dirs
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(setq magit-repository-directories '("~/projects/"))
|
||
#+END_SRC
|
||
|
||
*** Show fine differences
|
||
|
||
I like to see all the little differences in diffs that I can. They
|
||
really help reading diffs. I also just want to see them on all
|
||
diffs and not the selected one, which would make an unnecessary
|
||
amount of navigation required to properly read the diffs.
|
||
|
||
#+NAME: magit-diff-refine-hunk
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(setq magit-diff-refine-hunk 'all)
|
||
#+END_SRC
|
||
|
||
*** Delay setting
|
||
|
||
The settings in the previous sections should only be set after
|
||
Magit has loaded.
|
||
|
||
#+BEGIN_SRC emacs-lisp :noweb yes
|
||
(stante-after magit
|
||
<<magit-repo-dirs>>
|
||
<<magit-diff-refine-hunk>>)
|
||
#+END_SRC
|
||
|
||
** Lui
|
||
|
||
These settings will be tangled to =site-lisp/lui-init.el= and loaded
|
||
when lui.el is loaded.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(with-eval-after-load 'lui
|
||
(require 'lui-init))
|
||
#+END_SRC
|
||
|
||
** Circe
|
||
|
||
These settings will be tangled to =site-lisp/circe-init.el= and
|
||
loaded when Circe is loaded.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(with-eval-after-load 'circe
|
||
(require 'circe-init))
|
||
#+END_SRC
|
||
|
||
#+INCLUDE: init-circe.org :minlevel 3
|
||
|
||
** Twig
|
||
|
||
Since twig is essentially a HTML template language, many tags must
|
||
be edited. Tagedit is good for restructuring existing tag
|
||
structures and adding single tags, whereas emmet mode is good when
|
||
you know more about the HTML hierarchy you're going to add.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'twig-mode-hook 'tagedit-mode)
|
||
(add-hook 'twig-mode-hook 'emmet-mode)
|
||
#+END_SRC
|
||
|
||
Since Twig is a /template/ language, and thus not just HTML, electric
|
||
pairing is a blessing.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'twig-mode-hook 'electric-pair-local-mode)
|
||
#+END_SRC
|
||
|
||
Both HTML and Twig mode aren't traditional text modes, so
|
||
=auto-fill-mode= doesn't make sense.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'twig-mode-hook (turn-off auto-fill-mode))
|
||
#+END_SRC
|
||
|
||
** Ruby
|
||
|
||
Turn on =abbrev-mode= in Ruby buffers.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'ruby-mode-hook 'abbrev-mode)
|
||
#+END_SRC
|
||
|
||
Turn on [[Electric pair]] mode.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'ruby-mode-hook #'electric-pair-local-mode)
|
||
#+END_SRC
|
||
|
||
Turn on [[Electric indent]] mode.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'ruby-mode-hook #'electric-indent-local-mode)
|
||
#+END_SRC
|
||
|
||
Turn on [[Automatic syntax checking on-the-fly][Flycheck]] mode.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'ruby-mode-hook 'flycheck-mode)
|
||
#+END_SRC
|
||
|
||
Turn on Yard mode.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'ruby-mode-hook 'yard-mode)
|
||
#+END_SRC
|
||
|
||
Turn on [[Eldoc]] mode.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'ruby-mode-hook 'eldoc-mode)
|
||
#+END_SRC
|
||
|
||
Turn on Ruby tools mode.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'ruby-mode-hook 'ruby-tools-mode)
|
||
#+END_SRC
|
||
|
||
Turn on Ruby refactor mode.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'ruby-mode-hook 'ruby-refactor-mode-launch)
|
||
#+END_SRC
|
||
|
||
Turn on [[Robe]] mode.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'ruby-mode-hook 'robe-mode)
|
||
#+END_SRC
|
||
|
||
Set Fill Column Indicator column to the community Ruby Style Guide
|
||
recommended value.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'ruby-mode-hook 'oni:ruby-set-rsg-margin)
|
||
#+END_SRC
|
||
|
||
* Minor mode customization
|
||
|
||
Many minor modes also offer a bit of customization possibilities.
|
||
|
||
** Robe
|
||
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(depends-on "robe")
|
||
#+END_SRC
|
||
|
||
Robe is a Ruby completion and documentation lookup library.
|
||
|
||
** Eldoc
|
||
|
||
Seeing the arguments to a function whilst typing its name is
|
||
excellent.
|
||
|
||
*** Show eldoc when evaluating expressions
|
||
|
||
Thanks to [[http://endlessparentheses.com/sweet-new-features-in-24-4.html][this post]] it was brought to my attention that eldoc mode
|
||
can be enabled when evaluating expressions using {{{key(M-:)}}}.
|
||
|
||
I vaguely remember having had this before, I just don't know how or
|
||
why it stopped working.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'eval-expression-minibuffer-setup-hook #'eldoc-mode)
|
||
#+END_SRC
|
||
|
||
** Electric pair
|
||
|
||
Electric pairing of delimiters is one of those features that is
|
||
just so essential to my feeling comfortable with an editor. Most of
|
||
the time I don't even use it, really. It's just that I'm so used to
|
||
having it and when I /do/ expect it to be there it is so frustrating
|
||
when it's not, or when it doesn't work properly.
|
||
|
||
This functionality, much like [[Electric indent]] isn't something I
|
||
want enabled in all modes, though for different reasons, and for a
|
||
time there was only the global =electric-pair-mode=. Again I'm very
|
||
happy that a local version was added.
|
||
|
||
The reason that I don't want it enabled for all modes is that some
|
||
modes (mostly Lisp-like language modes) have better alternatives.
|
||
But most non-Lisp-like language modes I really do need to have it.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'c-mode-hook #'electric-pair-local-mode)
|
||
(add-hook 'coffee-mode-hook #'electric-pair-local-mode)
|
||
(add-hook 'css-mode-hook #'electric-pair-local-mode)
|
||
(add-hook 'haml-mode-hook #'electric-pair-local-mode)
|
||
(add-hook 'java-mode-hook #'electric-pair-local-mode)
|
||
(add-hook 'js2-mode-hook #'electric-pair-local-mode)
|
||
(add-hook 'lua-mode-hook #'electric-pair-local-mode)
|
||
(add-hook 'python-mode-hook #'electric-pair-local-mode)
|
||
(add-hook 'scss-mode-hook #'electric-pair-local-mode)
|
||
(add-hook 'sh-mode-hook #'electric-pair-local-mode)
|
||
#+END_SRC
|
||
|
||
*** Remove whitespace when closing delimiters
|
||
|
||
In =electric-pair-mode=, skip over and delete white space if it stands
|
||
between the cursor and the closing delimiter.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq electric-pair-skip-whitespace 'chomp)
|
||
#+END_SRC
|
||
|
||
** Electric indent
|
||
|
||
Automatically indenting code upon typing certain characters can be
|
||
very useful for certain modes where the indentation level can
|
||
easily be determined. One of the first things I liked about Emacs
|
||
was the way the {{{key(TAB)}}} key worked: It indents to the
|
||
"proper" level of indentation, instead of adding a tab character.
|
||
It quickly grew into a habit to press tab several times when
|
||
editing a line or a block of code. Electric indent is just an
|
||
extension of this that, for the most part, allows me to forget
|
||
about pressing tab.
|
||
|
||
It doesn't fit all modes though. When I worked in Python a lot I
|
||
was fighting the electric indent a lot more than it was helping me.
|
||
This is because instead of scope influencing indentation as in most
|
||
languages I've worked with, indentation determines scope in Python,
|
||
as anyone who's looked at it for more than a minute or two will
|
||
know. This means that any line can usually have several "proper"
|
||
indentation levels, depending on the meaning of meaning of that
|
||
line.
|
||
|
||
So, almost all modes use =electric-indent-local-mode=, but a few
|
||
don't. So I'm also very happy that recently this mode was added,
|
||
because =electric-indent-mode= is a global minor mode and I only want
|
||
to use it in some 99% of the available modes.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'css-mode-hook #'electric-indent-local-mode)
|
||
(add-hook 'js2-mode-hook #'electric-indent-local-mode)
|
||
(add-hook 'php-mode-hook #'electric-indent-local-mode)
|
||
(add-hook 'scss-mode-hook #'electric-indent-local-mode)
|
||
(add-hook 'sh-mode-hook #'electric-indent-local-mode)
|
||
#+END_SRC
|
||
|
||
*** Switch keys back
|
||
|
||
When =electric-indent-mode= is enabled the default function bound to
|
||
{{{key(C-j)}}} (=electric-newline-and-maybe-indent=) stops indenting
|
||
after adding a newline, whilst {{{key(RET)}}} starts doing it.
|
||
Since I use {{{key(C-j)}}} almost exclusively and don't use
|
||
{{{key(RET)}}} at all, it's really not useful to me. So I want to
|
||
switch the two when =electric-indent-mode= is enabled.
|
||
|
||
This is very simple. First I define a simple function that checks
|
||
if the =electric-indent-mode= variable is set (which it should be if
|
||
the mode is turned on) and if so I set the proper keys /locally/. If
|
||
=electric-indent-mode= is /not/ set, which happens when the mode is
|
||
turned off, I remove the local keybindings.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun oni:switch-newline-keys ()
|
||
"Switch the `C-j' and `RET' keys in the local buffer."
|
||
(if electric-indent-mode
|
||
(progn
|
||
(local-set-key (kbd "C-j") 'newline)
|
||
(local-set-key (kbd "RET") 'electric-newline-and-maybe-indent))
|
||
(local-unset-key (kbd "C-j"))
|
||
(local-unset-key (kbd "RET"))))
|
||
#+END_SRC
|
||
|
||
And then I add it to the electric indent mode's hook.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'electric-indent-local-mode-hook #'oni:switch-newline-keys)
|
||
#+END_SRC
|
||
|
||
** Auto completion
|
||
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(depends-on "auto-complete")
|
||
#+END_SRC
|
||
|
||
I'm not a great fan of any type of auto completion functionality in
|
||
programming. I think it's basically only good for getting really
|
||
long names in your file faster. I started programming in C#, in
|
||
Visual Studio, and they have their very powerful Intellisense
|
||
mechanism, which I used a lot. What I noticed though was that it
|
||
was keeping me from learning the APIs. Whenever I wrote some code,
|
||
all but the most basic and most-used calls I wrote from memory.
|
||
Many others were done after a few seconds of browsing through the
|
||
Intellisense pop-up.
|
||
|
||
Because of this, I disable the normal auto-complete pop-up.
|
||
|
||
#+NAME: auto-complete-dont-show
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(setq ac-auto-show-menu nil)
|
||
#+END_SRC
|
||
|
||
On the rare occasion that I do call up the pop-up to see what the
|
||
completions I have available to me are, I don't want it to show the
|
||
quick help. The quick help usually shows up as a big extra pop-up
|
||
next to the completion list and it gets very messy when combined
|
||
with some other modes that add overlays to the buffer.
|
||
|
||
#+NAME: auto-complete-no-quickhelp
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(setq ac-use-quick-help nil)
|
||
#+END_SRC
|
||
|
||
To keep the byte-compiler from complaining about undefined
|
||
variables, I only want this to be done after =auto-complete= is
|
||
loaded, not sooner.
|
||
|
||
#+BEGIN_SRC emacs-lisp :noweb yes
|
||
(stante-after auto-complete
|
||
<<auto-complete-dont-show>>
|
||
<<auto-complete-no-quickhelp>>)
|
||
#+END_SRC
|
||
|
||
** Highlight indentation
|
||
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(depends-on "hl-indent")
|
||
#+END_SRC
|
||
|
||
Some languages base their ideas of scope on levels of indentation.
|
||
When these languages get long functions/branches it can get tricky
|
||
to see where these blocks end. Of course if you have such large
|
||
functions you might have other problems, but this is sometimes out
|
||
of your hands. To help, I use =hl-indent-mode=.
|
||
|
||
For other languages it might look fun for a little while as well,
|
||
but since they don't care about indentation as much it can
|
||
sometimes get messy.
|
||
|
||
First, =hl-indent-mode= doesn't have an =;;;###autoload= cookie for its
|
||
main entry-point, so I add it manually:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(autoload 'hl-indent-mode "hl-indent" nil t)
|
||
#+END_SRC
|
||
|
||
Then I enable it for the languages I want.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'python-mode-hook #'hl-indent-mode)
|
||
(add-hook 'yaml-mode-hook #'hl-indent-mode)
|
||
(add-hook 'haml-mode-hook #'hl-indent-mode)
|
||
#+END_SRC
|
||
|
||
** Django helper
|
||
:PROPERTIES:
|
||
:ORDERED: t
|
||
:END:
|
||
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(depends-on "pony-mode")
|
||
#+END_SRC
|
||
|
||
Autoload =pony-mode= because it doesn't come with an autoload cookie.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(autoload 'pony-mode "pony-mode" nil t)
|
||
#+END_SRC
|
||
|
||
Turn on =compilation-shell-minor-mode= when =pony-mode= is enabled.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun oni:turn-on-compilation-shell-for-pony ()
|
||
"Turn on option `compilation-shell-minor-mode' for `pony-minor-mode'."
|
||
(add-hook 'pony-minor-mode-hook 'compilation-shell-minor-mode nil t))
|
||
|
||
(add-hook 'comint-mode-hook #'oni:turn-on-compilation-shell-for-pony)
|
||
#+END_SRC
|
||
|
||
** Automatic syntax checking on-the-fly
|
||
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(depends-on "flycheck")
|
||
(depends-on "flycheck-cask")
|
||
(depends-on "flycheck-commit-check" :git "git://github.com/ryuslash/flycheck-commit-check.git")
|
||
#+END_SRC
|
||
|
||
Flycheck provides awesome syntax checkers for many languages.
|
||
Enable it for the languages I use.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'haml-mode-hook 'flycheck-mode)
|
||
(add-hook 'emacs-lisp-mode-hook 'flycheck-mode)
|
||
(add-hook 'git-commit-mode-hook 'flycheck-mode)
|
||
(add-hook 'go-mode-hook 'flycheck-mode)
|
||
(add-hook 'html-mode-hook 'flycheck-mode)
|
||
(add-hook 'js2-mode-hook 'flycheck-mode)
|
||
(add-hook 'lua-mode-hook 'flycheck-mode)
|
||
(add-hook 'perl-mode-hook 'flycheck-mode)
|
||
(add-hook 'php-mode-hook 'flycheck-mode)
|
||
(add-hook 'python-mode-hook 'flycheck-mode)
|
||
(add-hook 'rst-mode-hook 'flycheck-mode)
|
||
(add-hook 'rust-mode-hook 'flycheck-mode)
|
||
(add-hook 'sh-mode-hook 'flycheck-mode)
|
||
(add-hook 'texinfo-mode-hook 'flycheck-mode)
|
||
#+END_SRC
|
||
|
||
Whenever flycheck is started, try using it with Cask.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'flycheck-mode-hook 'flycheck-cask-setup)
|
||
#+END_SRC
|
||
|
||
Load my own git commit checker.
|
||
|
||
#+NAME: flycheck-commit-checker
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(require 'flycheck-commit-check)
|
||
#+END_SRC
|
||
|
||
Disable certain checkers.
|
||
|
||
#+NAME: flycheck-delete-checkers
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(mapc (lambda (c) (delq c flycheck-checkers))
|
||
'(python-pylint python-pyflakes))
|
||
#+END_SRC
|
||
|
||
Set the highlighting mode to columns so I can see (if possible)
|
||
where errors/warnings belong.
|
||
|
||
#+NAME: flycheck-columns
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(setq flycheck-highlighting-mode 'columns)
|
||
#+END_SRC
|
||
|
||
Try not to display the errors. A jumpy echo area makes me nervous
|
||
and {{{key(C-c ! l)}}} is a nicer way to look at it usually. It
|
||
still doesn't keep it from being displayed, only when nothing else
|
||
is displayed though.
|
||
|
||
#+NAME: flycheck-display
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(setq flycheck-display-errors-function (lambda (_) nil))
|
||
#+END_SRC
|
||
|
||
Do most of these things after flycheck is loaded.
|
||
|
||
#+BEGIN_SRC emacs-lisp :noweb yes
|
||
(stante-after flycheck
|
||
<<flycheck-commit-checker>>
|
||
<<flycheck-delete-checkers>>
|
||
<<flycheck-columns>>
|
||
<<flycheck-display>>)
|
||
#+END_SRC
|
||
|
||
** Show a “beacon” when cursor position changes
|
||
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(depends-on "beacon")
|
||
#+END_SRC
|
||
|
||
=beacon-mode= is a new minor mode that shows a temporary gradient
|
||
whenever the cursor screen position changes in a (somewhat)
|
||
unpredictable way. For example, when you switch buffers, when the
|
||
window scrolls because you’ve reached the top of the window, etc.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(beacon-mode)
|
||
#+END_SRC
|
||
|
||
*** Don’t show a beacon everywhere
|
||
|
||
Beacon by default already doesn’t show in certain buffers with
|
||
certain major modes, currently only =magit-status-mode= disables the
|
||
beacon. I have some more that I’d like to add.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(stante-after beacon
|
||
(setq beacon-dont-blink-major-modes
|
||
(append beacon-dont-blink-major-modes
|
||
'(circe-channel-mode
|
||
circe-server-mode
|
||
magit-diff-mode
|
||
gnus-summary-mode
|
||
gnus-group-mode))))
|
||
#+END_SRC
|
||
|
||
*** Show a beacon when recentering
|
||
|
||
Somehow I always get confused when I recenter my screen, is it in
|
||
the center, top or bottom? Beacon disables itself for the
|
||
recentering command, and I want it enabled, even though this is
|
||
completely predictable.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(stante-after beacon
|
||
(setq beacon-dont-blink-commands
|
||
(delq 'recenter-top-bottom beacon-dont-blink-commands)))
|
||
#+END_SRC
|
||
|
||
** Hightlight numbers mode
|
||
|
||
I find this regular expression to work better at identifying
|
||
general numbers as the default one doesn't consider numbers
|
||
starting with a sign or a decimal point.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(stante-after highlight-numbers
|
||
(setq highlight-numbers-generic-regexp
|
||
"\\_<[-+]?[[:digit:]]+\\(?:\.[[:digit:]]+\\)?.*?\\_>"))
|
||
#+END_SRC
|
||
|
||
** Emmet mode
|
||
|
||
I'm one of the strange people who use {{{key(C-j)}}} instead of
|
||
{{{key(RET)}}} to insert a new line (and indent), so Emmet mode's
|
||
default binding of using {{{key(C-j)}}} to expand a line is very
|
||
disruptive to me.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(stante-after emmet-mode
|
||
(define-key emmet-mode-keymap (kbd "C-j") nil)
|
||
(define-key emmet-mode-keymap (kbd "RET") #'emmet-expand-line))
|
||
#+END_SRC
|
||
|
||
* Applications
|
||
|
||
Emacs has a number of packages that are basically applications
|
||
within Emacs. These are the ones I use or have used in the past, and
|
||
may again use in the future.
|
||
|
||
** Elfeed
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package elfeed
|
||
:ensure t
|
||
:defer t)
|
||
#+END_SRC
|
||
|
||
* Final touches
|
||
|
||
These options and calls need to come last so they don't interfere
|
||
with the rest of the initialization process, or get interfered with.
|
||
|
||
** Load custom file
|
||
|
||
I don't really use the Emacs customization interface much, but I
|
||
have used it as a kind-of persistent datastore, specifically for
|
||
desktop-registry[fn:9]. I do very much like the idea of it, it's a
|
||
very cool thing to have. I also use ~custom.el~ for storing some
|
||
things that I really can't store in a public viewing location like
|
||
this file or the git repository it lives in.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq custom-file "~/.emacs.d/custom.el")
|
||
(load custom-file)
|
||
#+END_SRC
|
||
|
||
* Notes
|
||
|
||
Here are some random or somewhat general notes about things you may
|
||
run into when looking through my Emacs init.
|
||
|
||
** Vacuous defvar
|
||
|
||
A =defvar= without a value like =(defvar some-variable)= tells the
|
||
byte-compiler that the variable will appear, but doesn't give it a
|
||
value. It should only count for the file where it is used and once
|
||
the file with the /actual/ =defvar= is loaded it will be populated with
|
||
its value, contrary to what would happen if you'd given it a value
|
||
before loading its original file.
|
||
|
||
** Function declarations
|
||
|
||
The function =declare-function= tells the byte-compiler where to find
|
||
a certain function. This keeps the byte-compiler from complaining
|
||
about certain functions possibly not being defined at run-time.
|
||
|
||
* Footnotes
|
||
|
||
[fn:1] This runs =tmm-menubar=, which lets you navigate the menubar in a
|
||
text-driven way. I don't ever use it because I know what all my
|
||
favorite functions are called, but it seems a great deal more
|
||
efficient than having to click on everything.
|
||
|
||
[fn:2] https://github.com/sabof/svg-mode-line-themes
|
||
|
||
[fn:3] It works fine for me with something like jabber chats and the
|
||
like.
|
||
|
||
[fn:4] I like to program in Lisp, parentheses are important to me!
|
||
Parentheses should be nice and round, not almost like bars!
|
||
|
||
[fn:5] https://github.com/belluzj/fantasque-sans
|
||
|
||
[fn:6] Used to be Cosmic Sans Neue Mono, the name changed because
|
||
people misread it as "Comic" (me included, which was the original
|
||
reason I checked it out, for laughs) and hate Comic Sans, and also
|
||
because there was already a Cosmic Sans font as well, which could
|
||
cause confusion.
|
||
|
||
[fn:7] http://stackoverflow.com/questions/22175214/automatically-switch-language-in-gnus-depending-on-recipient
|
||
|
||
[fn:8] I still use 2 spaces for some languages, like HTML.
|
||
|
||
[fn:9] http://code.ryuslash.org/desktop-registry/about/
|