Often the code you’re writing would be depending on the version of
some external tool (say git) or Emacs itself. Version checks in Emacs are pretty
easy - just use the built-in functions version=, version<= or version=.
Let’s illustrate this with an
example. Prelude requires at
least GNU Emacs 24.1 to run and on startup it performs the following
(when(version<emacs-version"24.1")(error"Prelude requires at least GNU Emacs 24.1"))
Simple and effective. The version functions are pretty smart and recognize most popular version formats correctly.
Note that version string “1” is equal to “1.0”, “1.0.0”, “220.127.116.11”,
etc. That is, the trailing “.0”s are insignificant. Also, version
string “1” is higher (newer) than “1pre”, which is higher than “1beta”,
which is higher than “1alpha”. Also, “-CVS” and “-NNN” are treated
as alpha versions.
If you’re writing an Emacs package you can also add an explicit Emacs version dependency in the packge metadata:
;; Package-Requires: ((emacs "24.1"))
That way users of older Emacsen would not see a version of your package targeting newer Emacsen.
Some time ago I showed you how to do
Google queries from Emacs. The
approach used in that articles is pretty generic and can be used for
the creation of various similar commands. Let’s create a command that
searches in YouTube:
(defunyoutube()"Search YouTube with a query or region if any."(interactive)(browse-url(concat"http://www.youtube.com/results?search_query="(url-hexify-string(ifmark-active(buffer-substring(region-beginning)(region-end))(read-string"Search YouTube: "))))))
This command will display the query results in your default browser.
I’d suggest binding the command to C-c y if you plan to use it regularly.
youtube is available in
Prelude(but with a prelude-
If there is something that people love as much as tweaking their
editing configurations it’s probably the selection of color themes. A
good color theme can make your work much more pleasant and a bad one
that literally impair your vision. It’s a fact of life that I’m a firm
supporter of low-contrast color themes with dark backgrounds - I find
them easy on the eyes and I feel that they don’t strain the eyes as
much as most themes. I’ve even ported a couple of popular themes to
Emacs - Zenburn and
In this short article we’ll see how color theming has changed in Emacs
24 and I’ll share with you a few tips on theme creation and
While editing you often have to increment or decrement some number
(usually an integer) by some step. Obviously this is trivial when the
number is something like 10, but not pretty pleasant when the number
is 2343566 and you want to increment it by 943. Most of the time,
however, you’ll probably be incrementing or decrementing by 1.
A long time ago I found a bit of code by
Ryan Thompson to help us deal
with such tasks. Here’s a slightly modified version of the original code:
(require'thingatpt)(defunthing-at-point-goto-end-of-integer()"Go to end of integer at point."(let((inhibit-changing-match-datat));; Skip over optional sign(when(looking-at"[+-]")(forward-char1));; Skip over digits(skip-chars-forward"[[:digit:]]");; Check for at least one digit(unless(looking-back"[[:digit:]]")(error"No integer here"))))(put'integer'beginning-op'thing-at-point-goto-end-of-integer)(defunthing-at-point-goto-beginning-of-integer()"Go to end of integer at point."(let((inhibit-changing-match-datat));; Skip backward over digits(skip-chars-backward"[[:digit:]]");; Check for digits and optional sign(unless(looking-at"[+-]?[[:digit:]]")(error"No integer here"));; Skip backward over optional sign(when(looking-back"[+-]")(backward-char1))))(put'integer'beginning-op'thing-at-point-goto-beginning-of-integer)(defunthing-at-point-bounds-of-integer-at-point()"Get boundaries of integer at point."(save-excursion(let(begend)(thing-at-point-goto-beginning-of-integer)(setqbeg(point))(thing-at-point-goto-end-of-integer)(setqend(point))(consbegend))))(put'integer'bounds-of-thing-at-point'thing-at-point-bounds-of-integer-at-point)(defunthing-at-point-integer-at-point()"Get integer at point."(let((bounds(bounds-of-thing-at-point'integer)))(string-to-number(buffer-substring(carbounds)(cdrbounds)))))(put'integer'thing-at-point'thing-at-point-integer-at-point)(defunincrement-integer-at-point(&optionalinc)"Increment integer at point by one.With numeric prefix arg INC, increment the integer by INC amount."(interactive"p")(let((inc(orinc1))(n(thing-at-point'integer))(bounds(bounds-of-thing-at-point'integer)))(delete-region(carbounds)(cdrbounds))(insert(int-to-string(+ninc)))))(defundecrement-integer-at-point(&optionaldec)"Decrement integer at point by one.With numeric prefix arg DEC, decrement the integer by DEC amount."(interactive"p")(increment-integer-at-point(-(ordec1))))
The code is based on the popular built-in library thing-at-point and
extends it to make it aware of integer numbers. The commands
increment-integer-at-point and decrement-integer-at-point operate
with a step of 1 by default, but with a prefix argument you can select
any step you desire. Unlike other similar commands floating in the
Internet, these two handle correctly numbers like -3434 and
I’d suggest binding these commands to C-c + and C-c -:
Programming code is often filled with comment annotations indicating stuff that should be done in the future.
# REFACTOR: Decouple and clean up this crap.# crappy code omitted
Normally Emacs doesn’t highlight such comment annotations, unless
you’re using some minor mode like
fic-mode. I find such mode overkill given the fact we can cook a pretty decent solution in just about 5 lines of code:
(defunfont-lock-comment-annotations()"Highlight a bunch of well known comment annotations.This functions should be added to the hooks of major modes for programming."(font-lock-add-keywordsnil'(("\\<\\(FIX\\(ME\\)?\\|TODO\\|OPTIMIZE\\|HACK\\|REFACTOR\\):"1font-lock-warning-facet))))(add-hook'prog-mode-hook'font-lock-comment-annotations)
And that’s all there is to it. This code is not perfect, since it
would highlight FIXME: everywhere in the source code (as opposed to
only in comments), but it’s extremely highly unlikely that it’ll
appear outside of the source comments anyways.
As usual Prelude users get this
functionally for free out-of-the-box.
Emacs users have a lot of power at their disposal, but in one
department they are always short - the number of available
non-complex keybindings that they can leverage.
Obviously nobody likes pressing keybindings like C-p C-v k (or
something like that). One way to get your hands on some extra
keybindings is to utilize the Super key (it’s the Windows key on
Win keyboards and the Command key on Mac keyboards (although most
people remap Command to Meta and Option to Super)). One great
thing about Super is that you generally have two of them, which
makes them touch-typing friend. Since almost no packages use those
keys you’re left with plenty of options.
Prelude defines a bunch of
global keybindings that use the Super key.
;; make some use of the Super key(define-keyglobal-map[?\s-d]'projectile-find-dir)(define-keyglobal-map[?\s-e]'er/expand-region)(define-keyglobal-map[?\s-f]'projectile-find-file)(define-keyglobal-map[?\s-g]'projectile-grep)(define-keyglobal-map[?\s-j]'prelude-top-join-line)(define-keyglobal-map[?\s-k]'prelude-kill-whole-line)(define-keyglobal-map[?\s-l]'goto-line)(define-keyglobal-map[?\s-m]'magit-status)(define-keyglobal-map[?\s-o]'prelude-open-line-above)(define-keyglobal-map[?\s-w]'delete-frame)(define-keyglobal-map[?\s-x]'exchange-point-and-mark)(define-keyglobal-map[?\s-p]'projectile-switch-project)
If you find pressing Super comfortable obviously you have the
potential to add quite a lot more keybindings to this list.
P.S. Some keyboards (notably laptop ones) have a Fn key as well
that’s also usable in Emacs keybindings. Somewhat funny that key is
known in Emacs as Hyper (Star Wars fans are undoubtedly adding a
Hyper-Space keybinding to their setups right about now).
One of the well known features of
Prelude is that it saves buffers
with changes in them automatically when you jump between
windows. This is achieved with several simple defadvices and without
going into many details the advice code for that feature might look like this:
;; automatically save buffers associated with files on buffer switch;; and on windows switch(defadviceswitch-to-buffer(beforeswitch-to-buffer-auto-saveactivate)(prelude-auto-save))(defadviceother-window(beforeother-window-auto-saveactivate)(prelude-auto-save))(defadvicewindmove-up(beforeother-window-auto-saveactivate)(prelude-auto-save))(defadvicewindmove-down(beforeother-window-auto-saveactivate)(prelude-auto-save))(defadvicewindmove-left(beforeother-window-auto-saveactivate)(prelude-auto-save))(defadvicewindmove-right(beforeother-window-auto-saveactivate)(prelude-auto-save))
Ouch - that a lot of redundant code! Luckily we can take care of the
redundancy by introducing a macro to generate multiple advices with
the same body:
(defmacroadvise-commands(advice-namecommands&restbody)"Apply advice named ADVICE-NAME to multiple COMMANDS.The body of the advice is in BODY."`(progn,@(mapcar(lambda(command)`(defadvice,command(before,(intern(concat(symbol-namecommand)"-"advice-name))activate),@body))commands)))
Looks a bit scary, doesn’t it? But it allows us to reduce the original code down to:
;; advise all window switching functions(advise-commands"auto-save"(switch-to-bufferother-windowwindmove-upwindmove-downwindmove-leftwindmove-right)(prelude-auto-save))
macroexpand can show us how the macro gets expanded:
Obviously if we want the macro to be truly universal we should factor
out the hardcoded before and activatedefadvice params, but
that’s beside the point. The point is that when you need to generate
some code Emacs Lisp’s macros have your back.
Almost every Emacs user knows that M-g M-g and M-g g (both bound to
go-to-line) will take him to the line of his choosing (provided he
knows the number of the target line, of course).
Surprisingly few Emacs users know that there is a similar way to jump
to a column by its number - M-g TAB (bound to
move-to-column). Interactively you cannot jump past the end of the
line you’re currently on, but you can always cook your own version of
the command to get around that limitation:
locate is one extremely popular Unix command that allows you to
search for files in a pre-built database.
One little know fact is that Emacs provides a wrapper around the
command you can invoke with M-x locate. You’ll be prompted to enter
a search string and you’ll be presented with a list of matching
filenames from locate’s database. Many of dired keybindings are
available in the results buffer (which will be using locate-mode major mode).
If you’d like you may change the command invoked by Emacs to supply the
results by altering the locate-command variable. Here’s how you can
start using OSX’s mdfind (the command-line interface to Spotlight)
instead of locate:
Obviously any command that takes a string argument and returns a list
of files would do here. In all likelihood you’ll never want to use
anything other than the default locate command, though.
Emacs’s Lisp interpreter is able to interpret two kinds of code:
humanly readable code (stored in files with .el extension) and
machine optimized code (called byte-compiled code), which is not
humanly readable. Byte-compiled code runs faster than humanly readable
code. Java or .NET developers should already be familiar with the
concept of byte-code, since it’s pretty central on those platforms.
You can transform humanly readable code into byte-compiled code by
running one of the compile commands such as byte-compile-file. The
resulting byte-code is stored into .elc files. One can also
byte-compile Emacs Lisp source files using Emacs in batch mode.
Here’s how you can compile everything in your .emacs.d folder:
Of course we can easily create an Emacs command that does the same thing:
(defunbyte-compile-init-dir()"Byte-compile all your dotfiles."(interactive)(byte-recompile-directoryuser-emacs-directory0))
user-emacs-directory is an Emacs variable that points to your init
dir (usually ~/.emacs.d on UNIX systems). This command will
recompile even files that were already compiled before (meaning a file
with the same name and the .elc extension instead of .el
existed). You can try the new command with M-x
You have to keep in mind that Emacs will load code from the .elc
files if present alongside the .el files, so you’ll have to take
steps to ensure you don’t have stale .elc files lying around. I’d
suggest the following solution:
(defunremove-elc-on-save()"If you're saving an elisp file, likely the .elc is no longer valid."(add-hook'after-save-hook(lambda()(if(file-exists-p(concatbuffer-file-name"c"))(delete-file(concatbuffer-file-name"c"))))nilt))(add-hook'emacs-lisp-mode-hook'remove-elc-on-save)
This code will make Emacs delete the some_file.elc file, every time the
some_file.el file in the same folder is saved.
A couple of closing notes:
If you don’t have any custom computationally
intensive defuns in your init directory - it probably doesn’t make sense
to byte-compile it.
Packages installed via package.el will be automatically byte-compiled during the installation process.
The code presented here is part of
Prelude. As a matter of fact
Prelude will byte-compile itself during the installation process (if
you used the installed script, that is). Prelude will also recompile
itself when M-x prelude-update is invoked.