Finish re-organizing init.org

This commit is contained in:
Tom Willemse 2015-09-28 23:03:06 +02:00
parent cb49188ed7
commit 2488743abd

View file

@ -151,6 +151,103 @@
(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.
@ -842,84 +939,23 @@
(setq elnode-do-init nil)
#+END_SRC
* Minor mode customization
** js2
Many minor modes also offer a bit of customization possibilities.
=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:
** Robe
#+BEGIN_SRC emacs-lisp :tangle no
(depends-on "robe")
#+BEGIN_SRC js2 :tangle no
/*global $ Routes jQuery */
#+END_SRC
Robe is a Ruby completion and documentation lookup library.
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.
*** Adding completions to autocomplete
To add Robe completions to autocomplete whenever robe is started,
I use the =robe-mode-hook= to enable this so that it doesn't try to
get any completions when robe isn't running.
#+BEGIN_SRC emacs-lisp
(add-hook 'robe-mode-hook #'ac-robe-setup)
#+END_SRC
* 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-settings (&rest settings)
"Create a function that changes the value of NAME to VALUE."
`(lambda () (setq ,@settings)))
#+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
** 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
* Add some known symbols for .conkerorrc/init.js to js2-mode
*** 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.
@ -964,7 +1000,17 @@
(add-hook 'js2-init-hook #'oni:js2-add-conkeror-symbols)
#+END_SRC
* Teach eww about <code> tags
** 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
@ -994,29 +1040,12 @@
(shr-generic cont)))))
#+END_SRC
* Use scheme-mode for scsh interpreted files
*** Setup eww-lnum
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))
#+BEGIN_SRC emacs-lisp :tangle no
(depends-on "eww-lnum")
#+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
(defvar geiser-default-implementation)
(with-eval-after-load 'geiser
(setq geiser-default-implementation 'guile))
#+END_SRC
* Setup eww-lnum
As recommended in the [[https://github.com/m00natic/eww-lnum][README]], set the keys in the =eww-mode-map=.
#+BEGIN_SRC emacs-lisp
@ -1027,20 +1056,50 @@
(define-key eww-mode-map "F" 'eww-lnum-universal))
#+END_SRC
* Don't compile scss files
** Scheme
By default =scss-mode= tries compiling a file each time it's saved. I
don't have SCSS properly installed globally so this always fails,
highly annoying.
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
(defvar scss-compile-at-save)
(with-eval-after-load 'scss-mode
(setq scss-compile-at-save nil))
(add-to-list 'interpreter-mode-alist '("scsh" . scheme-mode))
#+END_SRC
* Change listings in dired
*** 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
@ -1057,100 +1116,12 @@
dired-subdir-switches "-Alh"))
#+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
* 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
* 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
* Programming
Emacs is a real programmer's editor, especially so because it's so
programmable itself. It also offers modes for a lot of programming
languages and 3rd-party packages offer even more.
** SCSS
- Enable auto-completion
#+BEGIN_SRC emacs-lisp
(declare-function auto-complete-mode "auto-complete")
(add-hook 'scss-mode-hook #'auto-complete-mode)
#+END_SRC
- Enable imenu
#+BEGIN_SRC emacs-lisp
(declare-function scss-imenu-setup "scss-imenu")
(add-hook 'scss-mode-hook #'scss-imenu-setup)
#+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
@ -1161,7 +1132,55 @@
(add-hook 'php-mode-hook #'oni:whitespace-only-tabs)
#+END_SRC
*** Use web-mode for HTML-heavy files
** 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
@ -1182,42 +1201,6 @@
(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
(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 ~.html.erb~ files.
#+BEGIN_SRC emacs-lisp
(oni:eval-after-init
(add-to-list 'auto-mode-alist '("\\.html\\.erb$" . web-mode)))
#+END_SRC
** PO mode
Autoload =po-mode=, because it didn't come with an autloads file or
@ -1234,11 +1217,133 @@
(add-to-list 'auto-mode-alist '("\\.po\\'\\|\\.po\\." . po-mode))
#+END_SRC
* Minor modes
** Magit
Emacs offers a lot of minor modes and even more can be found in the
ELPA, MELPA and Marmalade repositories. These offer a lot of
customization possibilities and added features.
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
* 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.
*** Adding completions to autocomplete
To add Robe completions to autocomplete whenever robe is started,
I use the =robe-mode-hook= to enable this so that it doesn't try to
get any completions when robe isn't running.
#+BEGIN_SRC emacs-lisp
(add-hook 'robe-mode-hook #'ac-robe-setup)
#+END_SRC
** 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 'ruby-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
@ -1307,37 +1412,6 @@
(add-hook 'electric-indent-local-mode-hook #'oni:switch-newline-keys)
#+END_SRC
** Electric pairing
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 'ruby-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
** Auto completion
#+BEGIN_SRC emacs-lisp :tangle no
@ -1516,55 +1590,6 @@
<<flycheck-display>>)
#+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
* Final touches
These options and calls need to come last so they don't interfere