33 KiB
Mike Gerwitz's Emacs Configuration
- Introduction
- General Settings
- User Interface
- <<<Session>>>
- Files and <<<Version Control>>>
- Mode Hooks and Configuration
- Editing
- Web Browsing
- Security and Cryptography
Introduction
This is my personal Emacs configuration. It is written in a literate style; this file serves as both a document and the configuration source code.
This is a work-in-progress; I am still relatively new to Emacs (I have been using Vim for over a decade, and Emacs only since late 2014). But even so, there's a lot here; you'd be surprised how quickly you can accumulate configuration options and actual code to customize Emacs. And that really speaks to its flexibility and appeal to developers: nearly everything is written in lisp, and nearly everything can be changed, often at runtime. The amount of customization the average Emacs user performs does not mean that Emacs is too complicated or does a poor job at configuration.
Contract this to my Vim configuration, which struggles to even reach 200 lines after over a decade (but I do use a number of plugins). There's beauty in that too.
Please forgive any atrocities that could be handled more elegantly or efficiently (and send me a patch!).
Lexical Binding
All variables in this file are lexically bound—that is, they are bound to the scope of the containing expression rather than being defined globally. This is what you would expect from most sane languages, such as Scheme.
;; -*- lexical-binding: t -*-
Word of Warning
Do not edit the generated file. It will be overridden during re-tangling.
;;;
;;; WARNING: This source file is the tangled output
;;; of init.org; do not modify!
;;;
General Settings
Package Archives
These are the archives from which I may download packages. This will be refined as I explore them in more detail.
(setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/")
("org" . "http://orgmode.org/elpa/")
("marmalade" . "http://marmalade-repo.org/packages/")
("melpa" . "http://melpa.milkbox.net/packages/")))
Packages installed from the archives are initialized simply:
(package-initialize)
Bookmarks
If I take the time to save my position in a buffer, I would prefer that I do
not lose that information. Setting bookmark-save-flag
will automatically
save after each modification.
(setq bookmark-save-flag 1)
User Interface
The editor is my canvas. That may sound corny, but I'm looking at this thing for a good part of every day of my life; it needs to be pleasing to both the eyes and the fingers. If returning to your editor—buffers open and waiting; cursor beckoning—is not titillating, then your editor is either misconfigured or not for you. (Or maybe you don't care, which is really a shame.)
<<<Evil Mode>>>
Evil mode is an extensible vi layer for Emacs. I have always been attracted to a number of Emacs features, most notably its use of a Lisp dialect. The barrier was its keybindings, which are inferior to those of Vim.
A combination of the two, however, is potent.
Evil has since grown into an excellent project that provides a surprisingly strong Vim-like experience in Emacs. There are some rough edges, and not all things are wholly consistent, but development continues and I will continue to submit patches to help things along.
Before loading evil mode: the default is to leave the default Emacs C-u
keybinding, which is universal-argument
; this is very inconvenient, since
I use C-u
very frequently, which is PgUp
(<prior>
) in Vim.
(setq evil-want-C-u-scroll t)
(evil-mode t)
Suspending Emacs
Evil overrides C-z
, for whatever perverted reason, to enter "Emacs"
mode rather than suspending Emacs. I do not like this
behavior. Instead, I have C-z
in Normal mode continue to suspend
Emacs. In Insert mode, however, it retains Evil's functionality and
enters "Emacs" mode; this makes sense, I think, because Emacs is
similar to Insert mode in that most keybindings echo.
(evil-define-key 'normal global-map
;; note that you can still return to Emacs mode in insert mode
"\C-z" 'suspend-emacs)
UI Stripping
The first thing that a new (or unconfigured) user encounters is the splash screen. It provides little value to an experienced user and is annoying.
(setq inhibit-splash-screen t)
I am accustomed to the beautifully simple interface of Vim—which I have used exclusively for over a decade. Therefore, I strip the text-mode UI (and the GUI) of annoyances such as the menu bar.
(menu-bar-mode -1)
(tool-bar-mode -1)
I do not use the Emacs GUI—I am fond of the command line and a terminal does just fine. This also fits well into my use of GNU screen and SSH, allowing me to re-attach to remote sessions with ease. But in the event that it happens to load (maybe the 'nox' package was not installed), or I choose to load it, I want it to be as consistent with the texi-mode UI as possible.
(when (display-graphic-p)
(scroll-bar-mode -1)
(fringe-mode 0)
(tooltip-mode -1)
(use-diablog-box nil)
(add-to-list 'default-frame-alist
'(font . "DejaVu Sans Mono-7")))
Layout
Your window layout defines how you perceive and interact with a significant portion of your virtual world. It provides a physical presence to the content of this virtual world, defining where in the physical world it is rendered. Humans have a place for most things in their environment; I see no difference here.
Window Height
I open a lot of files in my editor in a single session (which I leave
running as long as my screen session remains running, which is usually
until the box is rebooted, which is quite rare). In Vim, I would
manage this with a generous number of splits spread across various
tabs. Spacial orientation is important for me (allowing a file to
"live" in a certain location in the physical world) and offers a
number of benefits, so I produce a number of vertical splits (as much
as six, depending on the resolution, but I find that four is a sweet
spot), and numerous horizontal splits within them. I then "focus" on
a window within the split by maximizing its height to the available
space; in Vim, I set the minimum window height to 0
, so this shrinks
all other windows in the vertical split down to their status/mode
lines.
I do it often enough that I have a shortcut for doing so:
(defun evil-window-select-expand (direction)
"Select window in DIRECTION and expand to fill available frame height"
(windmove-do-window-select direction)
(evil-window-set-height nil))
;; move up/down a window and expand to full height
(mapc #'(lambda (assoc)
(eval `(evil-define-key 'normal global-map
,(car assoc)
(lambda ()
(interactive)
(evil-window-select-expand ,(cdr assoc))))))
'(("\C-k" . 'up)
("\C-j" . 'down)))
Unfortunately, Emacs' default behavior prohibits a zero-height
window: window-min-height
respects window-safe-min-height
, which
defaults to 1
. Changing the latter to 0
will cause the first
visible line in the window to render, but the mode line is not
rendered. I'll explore changing the rendering logic in the future;
for now, I will live with a minimum window height of 1
.
(setq window-min-height 1)
Minibuffer Height
The minibuffer (displayed at the very bottom of the editor when invoking a command, for instance) is able to display multiple lines of text. The default behavior is to allow the minibuffer to grow in height, but not return to its original height as its content shrinks (e.g. erasing newlines); this is annoying to me, and prods at my [minor] OCD.
The better behavior is to resize to fit the contents, always.
(setq resize-mini-windows t)
Window Layout Undo/Redo
It should be obvious from the previous sections that I would be rather displeased if my window layout were to be disrupted, since that could easily destroy months of accumulating buffers and layout organization. This could happen for a number of reasons, including my unfamiliarity with Emacs, me fat-fingering keys, or rude packages modifying the layout and not restoring it.
Winner Mode is packaged with Emacs since version 20. It allows you to
undo and redo layout changes using C <LEFT>
and C <RIGHT>
.
(winner-mode)
I have saved myself many times using this package.
Frames
In Vim, I made aggressive use of tabs to organize my many splits into coherent groups. When I first moved to Emacs, this made for an awkward transition: Emacs has a concept of frames, and they are not rendered like tabs (at least not without help). On the CLI, with the default behavior, you wouldn't even be able to tell that they exist.
To my surprise, I ended up finding Emacs' frames to be superior to Vim's tabs. I'll write more about that when I get the chance.
Cycling Frames
Vim cycles tabs using gt
(next tab) and gT
(previous tab). Since
I do not display frames as tabs, this is admittedly of limited use to
me when I have a large number of frames open; however, it can still be
useful under certain circumstances.
(evil-define-key 'normal global-map
"gt" 'other-frame
"gT" (lambda (n)
(interactive "p")
(other-frame (- n))))
Selecting Frame By Name
One powerful feature that Vim lacks (without a plugin) is the ability
to name tabs, which becomes important when you (ab)use them the way I
do. Emacs has this support built-in; you can set frame names with
set-frame-name
. The frame name is displayed, by default, in the
mode line before the filename.
This means that we can select a frame using its name rather than its
position in the ring (like Vim). Emacs provides no default keybinding
for select-frame-by-name
, so I provide my own:
(evil-define-key 'normal global-map
"\C-w/" 'select-frame-by-name)
Switching Between Two Frames
I often find myself switching between two frames during
development. Reasons vary, but two projects may be strongly related
or concurrently developed; a single project may be organized into
separate frames for spacial recognition; I may be suffering from
context switching due to work on multiple, different projects;
etc. The two frames could be wholly arbitrary. Switching between
them can be frustrating, even with the minimal work of typing C-x b
...
with autocompletion. That frustration makes switching a
displeasure, which means that something is wrong with my editor
configuration.
(defun select-prev-frame-name ()
(interactive)
(let ((name (cadr frame-name-history)))
(if name
(progn
(select-frame-by-name name)
(setq frame-name-history
(cons name frame-name-history)))
(user-error "No previous frame"))))
select-prev-frame-name
uses Emacs' built-in frame-name-history
to
determine the name of the previously visited frame and raise it. I
bind this for convenience:
(evil-define-key 'normal global-map
"\C-w," 'select-prev-frame-name)
Minibuffer
Icomplete
icomplete-mode
provides a massive increase in life expectancy for
Emacs users by doing its best to provide suggestions for command
completion in the minibuffer. You should use it.
(icomplete-mode)
Recursive Buffers
The default behavior of Emacs does not permit recursive minibuffers—that is, minibuffer commands while within a minibuffer. It's too arbitrary of a restriction for me, and is something that occasionally comes in handy.
(setq enable-recursive-minibuffers t)
Mode Line
Emacs users do some pretty kinky stuff with their mode lines, especially in graphical environments. I don't do much of anything at the moment (most of my useful information is part of my GNU screen hardstatus line).
Point Column
I do want to know the column position of point; this is useful for a variety
of things, including observing line length and column numbers for error
messages. In the case of the latter, I normally use the Vim
(Evil-supported) command N|
, which takes me to column N
, but having the
column number in the mode line allows me to verify that I didn't fat-finger
the number.
(column-number-mode 1)
Scrolling
The first order of business is to get scrolling into a sane state with
evil mode. In particular, the use of C-u
to scroll up.
Emacs uses C-u
as a command modifier. Since evil mode allows
the use of Emacs commands, it retains this key binding by
default. Fortunately, this can be corrected with a simple
configuration value:
(setq evil-want-C-u-scroll t)
<<<Scroll Margin>>>
It is useful to be able to see lines of text that surround point; this allows scanning without having to move point or scroll the window, which is slower than moving your eyeballs, and is more distracting. Having point at the very first or last line of a window also makes me feel a bit uncomfortable—like having no peripheral vision. It also helps to visually state, without looking at the mode line, whether the window has reached the end of the buffer.
We do not want too much of a scroll margin (as it is called), since
that would reduce the effective amount of lines visible on the screen
during editing—if wanted to edit the last line in a window, and the
scroll margin was $n$, then I'd lose $n$ lines at the top when I
scroll to it. Further, using evil-window-bottom
(L
in Normal
mode) takes into account the scroll margin, meaning the last $n$ lines
of the window are not as easily accessible. Similar arguments can be
made for evil-scroll-line-to-bottom
(zb
in Normal mode) and
others.
All of that said, I have found a three-line scroll margin to treat me well over the years.
(setq scroll-margin 3)
Tracking Point
<<<sec:tracking-point>>> When point moves off of the screen, the default Emacs behavior is to re-center point in the window at that line. This is odd to me, but perhaps because it's not something that I am used to happening; the sudden jump of such a large amount of text (considering modern resolutions and my terminal font size) disrupts me.
Instead, the window should scroll just enough to keep point on the screen, subject to the scroll margin.
(setq scroll-conservatively 1)
Recentering
There are other operations (in addition to tracking point) that cause point to be recentered. The default behavior on a TTY is to redraw the entire frame when this occurs, possibly to cater to buggy VTEs. This is highly undesirable for me—it is both a performance issue and terrible eye sore due to my high terminal resolution. Fortunately, this behavior can be disabled.
(setq recenter-redisplay nil)
In the rare instances where redrawing is actually an issue, there is
always redraw-display
.
<<<Line Numbering>>>
Line numbering is useful for eyeballing text when line numbers are referenced (e.g. error messages when compiling source code), for getting an idea of where you are in a file, peer programming, and other things. I have used line numbers for over a decade. They are not enabled by default in Emacs (or Vim/vi).
I originally used <<<linum mode>>> for line numbering, but found that it was far too slow for my large terminal resolution. So, I gave <<<nlinum mode>>> a try; this was much faster, but was still a bottleneck. So I wrote a more strongly optimized procedure to handle rendering:
;; line numbering (we ignore nlinum-format for performance)
(setq nlinum-format-function
(lambda (line width)
(let ((str (concat (number-to-string line) " ")))
(when (< (length str) width)
;; Left pad to try and right-align the line-numbers.
(setq str (concat (make-string (- width (length str)) ?0)
str)))
(put-text-property 0 width 'face 'linum str)
;; FIXME: this relies on the fact that the format has a
;; trailing space
(put-text-property (1- width) width 'face 'hidden str)
str)))
That helped considerably. But I was still left disappointed by profiler results when trying to determine slowdowns.
As it turns out, I don't need line numbers; I've been experimenting with leaving line numbers disabled, and things have been going well; my eyes are adjusting moving to the mode line if I need the line number, and I find that it's rare that I even need that. For instance, if I need to visit a particular line, I enter the line number, not scroll to it.
I will, however enable nlinum mode in peer programming situations or code review, since it facilities discussion. Line numbers also help to provide context when navigating large files.
(evil-define-key 'normal global-map
"\C-n" 'nlinum-mode)
Sentences
<<<Sentence mode>>> is a minor mode that will highlight the entire sentence under point. I find this useful not only as a reading aid, but also compositionally—it allows me to see the length of sentences in my work and points out suspicious sentences that may be run-ons; yada. I use semi-colons aggressively in my written works as well, so sentence highlighting consequently highlights groups of ideas.
(require 'sentence-highlight)
See Mode Hooks for major modes making use of this minor mode.
Errors
The command ]e
is analogous to ]s
below. A negative numeric argument
can be used to cause next-error
to go back, but a Vim-like ]e
is still
provided for convenience.
(evil-define-key 'normal global-map
"]e" 'next-error
"[e" (lambda (&optional arg reset)
(interactive "P")
(next-error (- (prefix-numeric-value arg))
reset)))
Spell Checking
Vim's spell checking keybindings are useful. Unfortunately, I have not yet
put the time into a solution for [s
; flyspell-goto-previous-error
does
not exist and flyspell-goto-next-error
is not written such that this is
easy to do. flyspell-check-previous-highlighted-word
searches backwards,
but then invokes spelling correction, which is not desirable. A solution
will likely involve Flyspell refactoring and a patch.
(evil-define-key 'normal global-map
"]s" 'flyspell-goto-next-error)
Hidden Content
When modes permit customization via faces, it is sometimes useful to be able to hide text entirely.
(defface hidden '((t (:foreground nil :background nil)))
"Hide text")
<<<Session>>>
Session management allows you to continue where you left off at an earlier point in time, usually restoring buffers, windows, frames, and other configuration options. This is especially important for myself, since I use (usually) a single Emacs session with many hundreds of buffers, a dozen or more frames (each named), and often dozens of windows per frame, spatially memorized. I simply cannot afford to lose such a session.
Session saving is provided by Emacs' built-in <<<desktop mode>>>.
(setq desktop-restore-frames t
desktop-resture-in-current-display t
desktop-restore-forces-onscreen nil)
To ensure that no information is lost, I save desktop sessions on auto-save:
(add-hook 'auto-save-hook
'desktop-save-in-desktop-dir-quiet)
The -quiet
suffix there is to ensure that saving does not produce errors
if we are not the owner of the session:
(defun desktop-save-in-desktop-dir-quiet ()
(interactive)
(if (eq (desktop-owner) (emacs-pid))
(desktop-save desktop-dirname)))
Saving Session Frame Names
<<sec:frame-name>> I am unsure why the default is to not save frame names (it may have simply been overlooked; I should probably ask), but that is deeply frustrating due to the number of frames that I maintain. Fortunately, it is an easy problem to solve:
;; this first line is suggested by the frameset-filter-alist docs
(setq frameset-filter-alist (copy-tree frameset-filter-alist))
(add-to-list 'frameset-filter-alist
'(name . nil))
Command History
Have you ever been in a situation where you know you did something a number of days ago, but you don't remember exactly how you did it? Of course!
My shell history length is quite large, but I don't think that such is
necessary with Emacs, since most commands issued to Emacs are not
M-x
-commands.
(setq history-length 1024)
Files and <<<Version Control>>>
<<<sec:version-control>>>
Backups
With modern source code management systems, old-school version control using backups following a naming convention are not often needed. That said, there are two particular cases where it is still valuable: for files that are not [yet] under version control, or as a save-my-ass feature in the event that work had not been committed.
(setq version-control t
backup-directory-alist '(("." . "~/tmp/"))
auto-save-file-name-transforms '((".*" "~/tmp/" t))
kept-new-versions 100
kept-old-versions 20
delete-old-versions t)
On a similar note, Emacs creates lock files by default—they are intended to prevent users from concurrently editing the same file using Emacs (or any other editor that checks for the lock). Since all my shared editing is done via a VCS, this does nothing but create annoying files.
;; not defined until Emacs 24.3
(setq create-lockfiles nil)
Reverting
Emacs' concept of "reverting" involves discarding changes in a buffer and loading the contents of its respective file from disk. Most editors have some sort of facility for handling this type of situation, as it is an important one: overwriting a file with changes to an out-of-date version risks clobbering data. Emacs does, fortunately, prompt in such a situation.
When working with version control systems—namely Git, in my situation—switching branches may yield file changes. I switch branches regularly, and it is important that my editor reflects those (often vast) changes; waiting until I have already made modifications to a file before discovering that it has changed is unacceptable.
(global-auto-revert-mode)
Mode Hooks and Configuration
<<<sec:mode-hooks>>> Here I define all the minor modes that shall be enabled when the corresponding major mode(s) take effect.
(defun disable-mode-fn (mode)
"Return function to disable `MODE'"
(lambda ()
(if (boundp mode)
(funcall mode -1)
(warn (concat
"disable-mode-fn: unknown mode: "
(symbol-name mode))))))
(defconst my-mode-hooks
`((turn-on-auto-fill . (text-mode-hook
prog-mode-hook))
;; perf issues
;; (fci-mode . (prog-mode-hook))
;; highlight lines (no global mode, since that makes disabling
;; it per-buffer a PITA)
(hl-line-mode . (text-mode-hook
prog-mode-hook))
(show-paren-mode . (prog-mode-hook))
(electric-pair-mode . (prog-mode-hook))
(which-function-mode . (prog-mode-hook))
(flyspell-prog-mode . (prog-mode-hook))
(js2-mode . (js-mode-hook))
(flyspell-mode . (text-mode-hook))
(whitespace-mode . (text-mode-hook
prog-mode-hook))
;; skimpy tabbing
(,(apply-partially 'set-tab-width 2) . (shell-mode-hook
nxml-mode-hook))
;; knock it off prog modes
(,(apply-partially 'set-fill-column 76) . (prog-mode-hook))
(sentence-highlight-mode . (text-mode-hook))
;; these modes do not cooperate with electric-pair-mode
(,(disable-mode-fn 'electric-pair-mode) . (nxml-mode-hook))
;; flyspell is too much atop of the slow nxml processing
(,(disable-mode-fn 'flyspell-mode) . (nxml-mode-hook))
;; FIXME: until I can figure out a consistent solution to face
;; precedence; it highlights whitespace in its own face, unless you load
;; whitespace-mode after it, so we'll get rid of it for now
(,(disable-mode-fn 'whitespace-mode) . (message-mode-hook))
;; no line highlighting in terminals
(,(disable-mode-fn 'hl-line-mode) . (term-mode-hook))
;; nxml's parent mode is text-mode, but I treat it more like a
;; programming language
(,(disable-mode-fn 'sentence-highlight-mode) . (nxml-mode-hook)))
"List of pairs defining functions to be applied to hooks
The purpose of this is to be able to determine, at a glance, all modes to
which the given function or minor mode apply. It is trivial to see the
reverse by inspecting the runtime value of those hooks.")
;; apply mode hooks
(mapc (lambda (pair)
(let ((f (car pair))
(modes (cdr pair)))
(mapc (lambda (mode)
(add-hook mode f t))
modes)))
my-mode-hooks)
File Extensions
(add-to-list
'auto-mode-alist
'("\\.md\\'" . markdown-mode))
Ediff
Most modern resolutions are wide-screen; that is the case for me, even on my
laptop. The name split-window-horizontally
is deceptive: it's what is
more often referred to in other software as a "vertical split": two
side-by-side windows.
(setq ediff-split-window-function
'split-window-horizontally)
JavaScript
js-mode
's indentation strategy is abhorrent.
(add-hook 'js-mode-hook
(lambda ()
(setq indent-line-function 'indent-relative)))
Editing
I'm told that Emacs is an operating system. I'm also told that it is an editor. I've been convinced of both.
<<<Fill Column>>> (<<<Line Length>>>)
The fill column determines what column line wrapping should occur beyond. The default value is 70. In general, I'm okay with this, but it deserves a bit of discussion. Line length is one of those religious debates that nobody will win. But I can tell you why many hackers and technical people tend toward smaller line lengths, and why I choose the lengths that I do.
TODO; I don't have the time for my line-length dissertation right now.
My default line length is 76. My rationale:
- Standard Unix terminal column size of 80;
- Minus three characters (reasonable) for line numbering (77);
- Minus another character to delimit line number from text (76).
Further, the above also allows for (without line numbering) up to three levels of nested quotes using the standard block quote delimiter (">"; see Replying (to mail)).
(setq-default fill-column 76)
That is not always an appropriate default, though; I may override it for other modes. See also Mode Hooks.
Whitespace
Various types of whitespace are important to recognize. With a fixed-width font (which, if you're reading this document, you should be using!), we don't have to worry so much about the number of spaces between printable characters, since that can be fairly well eye-balled. But leading and trailing whitespace are of particular importance.
Leading whitespace is used for indentation, and is generally either tabs or spaces. Distinguishing between the two is vital for consistency, and sometimes semantically (e.g. Makefiles' need for tabs in recipes). Trailing whitespace is almost always a bad thing, so that should be made apparent. Newlines can be recognized by, well, a line break.
(setq-default
whitespace-style '(face
spaces
tabs
newline
space-mark
tab-mark
trailing))
TODO: How do I address Unicode NBR? Carriage returns?
Tab Width and Stops
It is important to respect others' whitespace decisions; if tabs already exist, then they should be retained. Certain languages (e.g. Make) also assign meaning to tab characters.
But just setting the tab width is not enough; in Emacs, the act of tabbing
is governed by tab stops. I therefore define set-tab-width
to both set
the tab width for display of the tab character and to generate the proper
tab-stop-list
:
(defun set-tab-width (width)
"Set tab width to WIDTH and generate tab stops"
(interactive "nTab width: ")
(setq tab-width width)
(setq tab-stop-list
(number-sequence width 120 width)))
I use this primarily in mode hooks, but I do generally prefer a default of four characters:
(defun global-set-tab-width (width)
"Set tab width to WIDTH and generate tab stops"
(interactive "nTab width: ")
(setq-default tab-width width)
(setq-default tab-stop-list
(number-sequence width 120 width)))
(global-set-tab-width 4)
Indentation
One thing that really annoys me is when my editor tries to be too smart: especially about something like indentation, which is so precise and variable. There are certain languages with strong indentation standards where this is okay (e.g. Lisp); but for the most part, no.
Triggering re-indentation is trivial enough (C-M-\
); I don't want it to
happen every time I start a new line.
(set 'electric-indent-chars
(remq ?\n electric-indent-chars))
Indentation, by default, by my preference, should never insert tabs.
(setq-default indent-tabs-mode nil)
TODO: But some projects I work on (such as GNU screen) do use tabs; write
a hook that will detect this and properly set indent-tabs-mode
.
Indentation should also be done automatically when hitting RET
, kind of
like Vim's autoindent
:
(define-key global-map
(kbd "RET") 'newline-and-indent)
Indentation Depth
Certain modes provide their own indentation settings, and my indentation preferences vary depending on language. This list is incomplete.
(setq sh-indentation 2
sh-basic-offset 2)
Searching
Proper searching of text is an art—and I don't mean from a parsing standpoint. Knowing how to navigate and mark portions of a text can be a powerful productivity boost.
Hi Lock mode is one of those simple things that can really have a great impact when you're trying to grok something with a number of pieces. It is also great during presentations or peer programming/review:
(global-hi-lock-mode t)
Sentences
It is beneficial to be able to recognize, at a glance, the length of a complete sentence; it helps to understand the scope of an idea or set of ideas.
(require 'sentence-highlight)
Org Mode
Web Browsing
There's more to be said on this topic; consider this section a TODO. I do most things from the command line, so w3m is a suitable default.
(require 'w3m)
(setq browse-url-browser-function
'w3m-browse-url)
With that said, there are situations where I may wish to toggle between w3m and my default browser (w3m obviously does not support certain modern web browser features).
(define-key global-map
(kbd "\C-C \C-X \C-W")
(lambda ()
(interactive)
(setq browse-url-browser-function
(if (eq browse-url-browser-function 'browse-url-default-browser)
'w3m-browse-url
'browse-url-default-browser))
(message (symbol-name browse-url-browser-function))))
Security and Cryptography
GnuPG
Emacs' GnuPG (GPG) interface is <<<EasyPG>>>.
GPG Pinentry
The GPG pinentry dialog is a neat console-based dialog that consumes the TTY and prompts for a password. In general, this works well; with Emacs, I noticed that it fights for input.
To avoid the problem, I disable pinentry indirectly by clearing out the
GPG_AGENT_INFO
environment variable.
(defadvice epg--start (around advice-epg-disable-agent activate)
(setenv "GPG_AGENT_INFO" nil)
ad-do-it)