Operating on numbers in place in any emacs buffer is one of the cool
features that no one thinks they need, but is surprisingly handy,
especially for converting bit-masks between decimal and hexadecimal
during programming. Akinori Musha's operate-on-number package makes it very
easy to set it up with a single keybinding. The only minor issue is
that the instructions for setting it up refer to smartrep while my preferred package
for setting up such keybindings is hydra. Assuming a recent enough version
of hydra (where an escaping bug has been fixed), here
is the elisp code needed to set up operate-on-number using
hydra:

firestarter is an emacs package used for running arbitrary commands
upon saving a file. Out of the box, it comes with support for running
shell commands, elisp functions and arbitrary emacs lisp code. The
most interesting and likely most common use case is to run shell
commands. firestarter provides an interesting format specification
for shell commands, e.g., %f is replaced by the name of the file
backing the buffer, %p by the path to the file, etc.

As someone working with embedded devices for most of which are
connected to some remote machine in some lab, and as one who prefers
to edit code within emacs from files on a local filesystem (see below
for reasons), I often run into the issue of copying local edits to a
remote machine during normal edit-compile-run cycles. So my ideal set
up would have been to use firestarter to copy the files over every
time any files in such a project were saved from emacs. A directory
local variable
with contents along the lines of

(firestarter."scp %p remotemachine:/path/to/project/%r")

in the root directory of the project would have been great, if %r
could represent the path of the file relative to the project root.
Unfortunately, firestarter does not provide
such a format specifier. However, since this is emacs, it is easy to
whip up a function to do what we want:

(defunravi/find-path-name-relative-to-project-root()"Find path of current buffer file relative to project root"(interactive)(let*((root-dir(and(buffer-file-name)(or(and(fboundp'magit-get-top-dir)(magit-get-top-dir))(and(fboundp'vc-root-dir)(vc-root-dir))(locate-dominating-file(buffer-file-name)".git")(locate-dominating-file(buffer-file-name)dir-locals-file))))(relative-name(androot-dir(file-relative-name(buffer-file-name)root-dir))))relative-name))(defunravi/apply-shell-command-relative-to-project(command-template)"Apply shell command relative to projectCOMMAND-TEMPLATE should be a string with the following substitutions allowed:%p: full path to file name%r: path relative to project root%f: file name%N: unquoted relative path name (should be used extremely carefully)"(interactive"sEnter command template: ")(let*((path(shell-quote-argument(or(buffer-file-name)"")))(rel-name(ravi/find-path-name-relative-to-project-root))(rel-path(shell-quote-argument(orrel-name"")))(file(shell-quote-argument(file-name-nondirectory(orpath""))))(cmd(andrel-name(format-speccommand-template(format-spec-make?ppath?rrel-path?ffile?Nrel-name)))))(ifcmd(shell-commandcmd)(if(not(buffer-file-name))(message"Not in a file buffer")(message"Unable to find project root")))))

Writing error messages and docstrings was actually harder than writing
the code itself. There are two interesting bits:

try magit-get-top-dir before other methods to get the root
directory since it works with files in the project yet to be added
to version control

use dir-locals-file (normally .dir-locals.el) to set
project root in case everything else fails

It is trivial to extend this to many other version control systems.
With the above, we can use firestarter to copy files:

Of course, one could say that remote editing with emacs tramp accomplishes the same goal by
editing remote files. However, for large projects, essential tools
such as helm-ls-git,
git-messenger, and
helm-ag are far more
responsive and usable with local filesystems. A lot of the remote
systems I use have ancient versions of tools which are painful to even
contemplate using on a regular basis.

Company mode is an excellent completion mechanism for emacs, much better than its documentation would lead one to believe. The best keybinding for company mode completion to common prefix is TAB, which, however, is also the best keybinding for yasnippet. The simplest solution would seem to be to use company mode to drive yasnippet. Such a back end for company mode already exists: company-yasnippet bundled with company mode. By default, company-yasnippet is not enabled since it is painful to use with other back ends. My solution has been to bind shift+TAB (called <backtab> in emacs keymap lingo) to company-yasnippet and not enable it by default, but the problem is that the default company mode completion is activated after typing in a snippet prefix, and sets up a transient keymap that simply ignores shift+TAB. We can work around the problem with a little bit of elisp:

Choosing between C mode and C++ mode in emacs for header files can be a bit of a chore if both types of header files have a .h extension. As usual, a package for solving this problem already exists: dummy-h-mode. One of the heuristics that it uses is to search for an implementation file and then to check the extension of that implementation file for a hint on the mode. This heuristic works very well, but with a minor annoyance that it tries to handle Objective C headers as well. In my use case, I sometimes have purely template-based C++ code and a test implementation in Matlab or octave:

mycode.h
mycode.m

dummy-h-mode unfortunately parses the Matlab/octave file as an Objective C file. Since I do not use Objective C, I used a quick and dirty hack to avoid it:

We could simply avoid checking for .m files, but that would involve intrusive changes to dummy-h-mode. Instead, in the code above, we look at the result of obtaining the major mode by one of the file-based methods (checking the implementation, or checking the number of files), and set it to nil if the result is Objective C. When one method returns nil, dummy-h-mode goes on to the next heuristic. In my case, looking at keywords is almost always sufficient since most of my C++ code is in some namespace which clearly indicates the correct mode.

Composing mail without the assistance of emacs is painful for serious emacs users. KMail (supplemented with emacsclient) had been my email client of choice for more than a decade. While KMail continues to be an excellent mail client, I started looking more into moving my entire email flow into emacs. Sending mail from emacs is pretty easy with smtpmail; so the only issue was finding a way to fetch and display email. After trawling The Interwebz, mu4e seemed to fit in best with my workflow.

Initial setup

Setting up mu4e was pretty easy since its parent package mu can be set up as a git submodule (or as a git subtree) of an emacs initialization directory and can then be compiled in place. Most of the initial setup is straightforward since the built in manual is pretty comprehensive; Rob Stewart's excellent guide is a handy summary for the impatient. The only other initial setup choice was between offlineimap and mbsync. After initial attempts at setting up both, I ended up choosing mbsync.

Fetching email with mbsync

While the mbsync man page is pretty comprehensive, it can be a little intimidating to set it up for use with mu4e. The basic setup for one email account is similar to the following:

The set up above is typical for Google mail. There are a couple of interesting bits, however. First, the use of SSL requires that certificate bundles be available to mbsync. On Fedora Linux 19 and later, the easiest way is to install ca-certificates.noarch using the package manager. The location of installed certificates is provided to mbsync via the CertificateFile directive.

The second and more interesting part is the handling of passwords.

Using GPG for mbsync passwords

The basic idea is that every time a password is needed, an particular file is decrypted and loaded. The key for the decryption can be prompted for and be stashed by gpg-agent. The first step is to create a GPG key, which is covered very well elsewhere. The standard authentication mechanism for gnus and smtpmail can be reused to store login information for mbsync. For any one account, the password for IMAP access and the password for sending email (usually the same) can be added to ~/.authinfo.gpg:

automatically fetches the password for the given account from authinfo.gpg. It is easy now with a couple of simple modifications to ~/.gnupg/gpg-agent.conf to make sure that the password prompt appears under X and that the key is stashed:

Fedora 17 (Beefy Miracle) provides optimized BLAS
and LAPACK libraries using
ATLAS. ATLAS libraries should be tuned to
the machine on which they are used. However, as Fedora supports a wide variety
of hardware with the same x86_64 binaries, a more complex mechanism is needed
for enabling optimized ATLAS libraries. The scheme consists of installing two
ATLAS packages:

However, if compiling an application that uses blas, the linker complains that
libcblas.so and friends are not found in the linker search path. For some
reason, the Fedora maintainers do not provide automatic symbolic links for the
compiled libraries. The fix is to manually make the alternatives visible:

Note that root permissions are required to issue the commands above. For an
i686 machine which uses a different optimized ATLAS package, you will need to
modify the library path to lib (replacing lib64) and will also need to pick
the correct library directory names, e.g., via

rpm -ql atlas-devel atlas-XXX-devel

Now, the choice of the ATLAS library packages can be configured easily:

If you followed the guidelines in multi-seat configuration on Fedora 17
to set up your
configuration, you will find some rules in /etc/udev/rules.d/72-* that Fedora
automatically sets up for you. Those rules are rather cryptic and hard to
maintain; please move those rules to a backup location (outside rules.d).

We will continue the example by developing our own udev rules. To recap, here is
the list of hardware that corresponds to seat2 in this example:

We need to identify some feature of these devices that can be used to specify
udev rules assigning them to seat2. In order to do so, we will first need to
see the attributes of these devices and their parents. We will tackle the
keyboard first (a few lines were stripped for brevity):

The keyboard can be identified easily by its name and there are no other devices
on the machine with the same name. The udev rule needs to assign an environment
variable called ID_SEAT to the correct device:

Note that we have also added a match on the TAG attribute to ensure that we do
not try to use devices that are not assignable to a seat (such as hard disks). A
similar solution works for the mouse as well. However, the video card is a
little more complex. The udev attributes for the video card is as follows:

There does not seem to be an obvious property on which to match. After trawling
through various devices, we find that the one property that is different between
the two video cards: they both have the same vendor id, but different subsystem
device ids. (This makes sense since they are both RadeonHD cards, albeit with
different model numbers.) Then the udev rules follow easily:

On reboot, devices will be assigned correctly to their respective seats. In
theory, everything should work fine. However, our current testing reveals a need
to boot into runlevel 3 and then manually invoke runlevel 5. We believe that
this may have something to do with a udev race in dracut. Until it is fixed,
the manual step of booting into runlevel 3 and changing manually into runlevel 5
will be needed.

Occasionally, we find that the GDM login screen turns blank. Once logged in,
this does not occur (at least with KDE). Our current workaround for this case is
to restart the X server for that particular seat by pressing Ctrl-Alt-Backspace.

Fedora 17 (Beefy Miracle) adds rudimentary
support for multi-seat configurations. However,
documentation
on setting up multi-seat configurations is rather sparse. The following guide
should get you started. This guide assumes that you are comfortable working on
the command line and that you know how to change init levels.

Multi-seat support on Linux is essentially at a beta state. While we think
that the risk is small, please be aware that you can damage your system.

Hardware requirements

Two video cards

Two mice

Two keyboards

On the test system, we will use an ASRock motherboard with two ATI/AMD RadeonHD
video cards: HD6850 and HD2400XT. The 6850 is on the PCIe x16 slot and the 2400
is on the PCIe x4 slot.

Step 1: Identifying hardware

Once all hardware is installed and Fedora 17 is running on your primary monitor,
reboot and enter into run-level 3 by adding the number 3 in grub2 (note
artificial line-breaks inserted for formatting and not needed in actual
command-line):

The list above has been rearranged and modified for ease of presentation: the
hardware list has been separated into two with a separator line. We will use all
the hardware below the line as part of a second seat that we will seat2.

We will assume that we are initially connected to the system on seat0 via the
6850 and using the Logitech Unifying Device as our keyboard and mouse. Please
ensure that you are not currently using hardware on seat0 that will be mapped
to seat2. Note that the session index may be different on your system.

Step 2: Assigning devices to the second seat

In order to test that multi-seat deployment works correctly, we will first
assign hardware manually to the second seat; eventually, we will automate it
using udev. Seats are created based on graphics cards. Hence we will start by
assigning a graphics card:

If your display manager is set to GDM, start runlevel 5, and you should see
an independent login screen on each monitor. GDM does tend to be flaky and you
may need to switch a couple of times between runlevels 3 and 5 before you see
login screens on both seats.