Automatic Package Installation for Emacs 24 – Part 2

EDIT 07/01/2014: I don’t recommend setting up packages like this anymore. I recommend reading
this post instead

About a year ago I wrote about installing packages on startup, automatically for Emacs 24. This used the native ELPA, looked for packages that weren’t already installed, and used package-install to install them.

Unfortunately, I realized that this method wasn’t nearly as functional as I wanted it to be. I’ll save my opinions for later. If you’re just looking for a great way to install packages for Emacs, I’ll just write it out here.

What I do

Here’s a baseline example of how to manage your packages:

    ;; Check for el-get, install if not exists
    (add-to-list 'load-path "~/.emacs.d/el-get/el-get")
    (unless (require 'el-get nil t)
(url-retrieve
 "https://raw.github.com/dimitri/el-get/master/el-get-install.el"
 (lambda (s)
   (goto-char (point-max))
   (eval-print-last-sexp))))

    ;; Set up packages
    (setq el-get-sources
'((:name flymake
   :description "Continuous syntax checking for Emacs."
   :type github
   :pkgname "illusori/emacs-flymake")

  (:name multiple-cursors
   :description "An experiment in adding multiple cursors to emacs"
   :type github
   :pkgname "magnars/multiple-cursors.el"
   :features multiple-cursors)

  (:name scala-mode
   :description "Major mode for editing Scala code."
   :type git
   :url "https://github.com/scala/scala-dist.git"
   :build `(("make -C tool-support/src/emacs" ,(concat "ELISP_COMMAND=" el-get-emacs)))
   :load-path ("tool-support/src/emacs")
   :features scala-mode-auto)

    (:name rainbow-mode :type elpa)

  (:name js2-mode
   :website "https://github.com/mooz/js2-mode#readme"
   :description "An improved JavaScript editing mode"
   :type github
   :pkgname "mooz/js2-mode"
   :prepare (autoload 'js2-mode "js2-mode" nil t))))

    ;; install any packages not installed yet
    (mapc (lambda (f)
      (let ((name (plist-get f :name)))
           (when (not (require name nil t)) (el-get-install name))))
    el-get-sources)

What does this do? Well:

  • Checks for installation of el-get, my package manager of choice, and installs it if one doesn’t exist
  • Sets a list of package definitions into el-get-sources
  • Looks through the whole list of el-get-sources, ad runs el-get-install if the package isn’t installed (verified via the ‘require’ command)

If I find a new package I want, whether it’s on github, elpa, or
otherwise, I first check if the package info already exists in
el-get’s huge list of recipes, or I write
it up myself. As an example, install an elpa package is as simple as:

(:name rainbow-mode :type elpa)

How about a git repository? In that case it’s just:

(:name scala-mode :type git :url "http://github.com/scala/scala-dist.git")

Or a shortened github version:

(:name scala-mode :type github :pkgname "scala/scala-dist.git")

Also in my system, I put my el-get-sources list into a different file and load it, it makes it way easier to manager than a huge chunk of data halfway through a bunch of code:

;; e.g. put the "el-get-sources" list in .emacs.elgetpackages
(load "~/.emacs.d/.emacs.elgetpackages")

Try it out for yourself! Watch as all of your favorite packages get installed on startup. Note that the install order might be different, as the cloning and installing process is performed asynchronously.

Why I do it this way

So why do I el-get now instead of package.el and ELPA?

When I started using ELPA. I was really satisfied. It was so easy to find and discover new packages, and installing them was a snap! However, with the rate at which emacs plugin development occurs, the packages are outdated quickly. In the world of github, and an incredibly active community, I found that my main issue was being able to install the most recent version of packages out there, and keeping them up to date.

ELPA is only as up to date as the package developers make it, and depending on the library, that’s not a lot. In addition, there are quite a lot of libraries out there which haven’t made it yet into a package.el repository.

So why wait? When adding a new package to your distributable emacs configuration is one line away, you don’t have to.

el-get provides basically everything I’m looking for:

  • a specific ‘github’ type for github repos. An absolute necessity, a lot of really good emacs extensions are on github.
  • generic git cloning. Great for the other libraries stores elsewhere
  • it even hooks into elpa for other packages!

Although I rarely use package.el or ELPA anymore. If I can find the github equivalent, I’ll use that instead. You’d be surprised how outdated existing libraries become.

This also provides the flexibility of allowing me to use my own version of various libraries, if need be. I no longer have to wait for pull requests to enjoy my fixes: I can just use my own repository, and switch back when the main repository catches up.

So if you want to stay on the cutting-edge, and not worry about the hassle of installing every single package you use on every machine you have, give this a shot.

fine, PyDev is better than Emacs for Python. I’m still using Emacs though.

Being part of a company that uses Python, I have a friend who loves
PyDev, an eclipse plugin that basically adapts the functionality of the
eclipse IDE to Python. Even though I’m still an Emacs greenhorn, I swear
my devotion to the text editor wouldn’t waver.

Until I saw what PyDev is capable of.

It’s actually quite amazing: PyDev basically provides practically every
useful eclipse feature for python. The list includes, but is not limited
to:

  • smart code completion with documentation
  • refactoring
  • code coverage
  • unit testing
  • automatic generation of methods and classes

Seriously, cheers to the devs who make this plugin: It’s fantastic. It’s
definitely a tool that I would use completely if all I did was code
Python.

But then I thought about why I was so vehement about switching from
Emacs, even when I was faced with a simple, easy to use tool that does
all the heavy lifting for me. And I realized it’s because I don’t just
code Python.

In any given work day, here’s my list of things I do:

  • write services and tools in python
  • manage configuration files in XML and YAML
  • test deploys and verify using a bash shell or ssh

So all in all, authoring python code is not the only thing I do. It’s
arguably not the major thing I do with my days either. What I need is a
text editor that is complex enough to assist me with modifying files
with complex regular expressions and easy file navigation, but also
versatile enough to do quick file discovery, and run commands in a
shell. Emacs can do all that. And if something else pops up in the
future, maybe Emacs isn’t the best solution, but I know it’ll have
something that’ll do the job. The advantage of having a single set of
hotkeys, a single environment do all of my daily task from, outweighs
the advantage for me of using a specified IDE. And if some day I switch
languages, Emacs will most likely contain a suite of tools, that I can
just plug and play, or I can write my own with a fully-featured
programming language.

And I think, ultimately, this is why anyone really uses Emacs. It’s not
only the problems your facing now. It’s knowing that you’re investing
time into an environment that’s flexible enough to face your diverse
challenges in the future.

Automatic Package installation using ELPA in Emacs 24

Emacs 24 includes many improvements over 23, but there is one particular
addition that makes me run around and go crazy with joy: a built-in
package management system, ELPA (Emacs 24 is still in development,
Bozhidar Batsov has a good guide on how to get it set up). I switched
over to Emacs almost a year ago, searching for something that would give
me an IDE with the following attributes:

  • Functionality (context-based completion, on the fly syntax checking)
  • Customization (key bindings, easily extensible)
  • Portability (minimal setup on new environments)

There are a lot of nice extensions that do well for the first two.
However, Portability was always tricky. To get some of the more power
coding features in Emacs, one needed to install large packages, and
there was no way to move these around short of zipping the whole thing
up or finding and installing all these packages again.

ELPA completes the trifecta I have been looking for. It was now easy to
have a list of packages to install. I have a GitHub repository to
contain all of my .emacs setup, so I can just clone a repository with
every new environment. To make the setup completely automatic, I needed
a method to automatically install packages that did not exist. After a
little research, I was able to figure it out:

;; Packages to install first (check if emacs is 24 or higher)(if (>= emacs-major-version 24)  (progn  ;; Add a larger package list    (setq package-archives '(("ELPA" . "http://tromey.com/elpa/")      ("gnu" . "http://elpa.gnu.org/packages/")      ("marmalade" . "http://marmalade-repo.org/packages/")))       (package-refresh-contents)       ;; Install flymake mode if it doesn't exist, then configure       (when (not (require 'flymake nil t))         (package-install 'flymake))       (global-set-key (kbd "C-; C-f") 'flymake-mode)       ;; flymake-cursor       (when (not (require 'flymake-cursor nil t))         (package-install 'flymake-cursor))       ;; Install rainbow mode if it doesn't exist, then configure       (when (not (require 'rainbow-mode nil t))         (package-install 'rainbow-mode))       (defun all-css-modes() (css-mode)         (rainbow-mode))       (add-to-list 'auto-mode-alist '("\.css

quot; . all-css-modes)) ))
NOTE!!! This must be run after ALL OTHER INITIALIZATIONS are run!
You can do this by placing it within a hook:

(add-hook 'after-init-hook '(lambda ()    (load "~/.emacs.loadpackages"))) ;; anything within the lambda will run after everything has initialized.

As you can see, I’ve put the above logic into a file called
“.emacs.loadpackages”. This is so I can remove it at easy if I want a
more bare environment.

I’d like to talk about this a little bit in detail. The first line
ensures that emacs is version 24 or higher:

(if (>= emacs-major-version 24) PACKAGE_STUFF_HERE)

I then add more repositories to the package manager, gnu and Marmalade
(the base package is a bit limited, in my opinion)

(setq package-archives '(    ("ELPA" . "http://tromey.com/elpa/")    ("gnu" . "http://elpa.gnu.org/packages/")    ("marmalade" . "http://marmalade-repo.org/packages/")))

This requires a refresh:

(package-refresh-contents)

And then onto the logic to see if a package exists! You can use require
to see if a package exists, nullifying the error message it usually
return by adding the true statement at the end. For example, this will
return true when the package fly-make cursor is not installed:

(not (require 'flymake-cursor nil t))

You can then add this to a complete clause:

(when (not (require 'flymake-cursor nil t))    (package-install 'flymake-cursor))

And you’re done!

Issues:

There a couple of things I’m still working on regarding this setup.
Although I haven’t gotten any environment breaking errors so far,
there’s not a lot of error checking, so I’m sure it can break if things
are not completely right. In addition, this does not work very well for
portable programmers, as Emacs will try to initialize ELPA, resulting in
an exception due to not being able to contact the server.

Please leave comments and suggestions!

My IDE in Emacs (mainly for Python)

I’m writing this article up to mainly keep track of the current state of
my IDE in Emacs, how to set one up, and to keep my to-do list.

Implemented Features

Default Emacs Library Includes

I use the following from the library that comes with Emacs (as of
version 23)

  • Viper-mode (viper-mode 3, though I’m sure 5 would be good too)
  • Windmove (through keybindings, for moving around windows easier)
  • hideshow (for code folding)
  • ibuffer (for listing on buffers when buffer switching)
  • ido (for listing of file in a directory in the minibuffer

Code to instantiate:

(setq viper-mode t)(require 'viper)(load-library "hideshow")(add-hook 'python-mode-hook 'hs-minor-mode)(require 'ido)(ido-mode 'both)

Keybindings

(global-set-key (kbd "C-x C-l") 'windmove-right)(global-set-key (kbd "C-x C-h") 'windmove-left)(global-set-key (kbd "C-x C-k") 'windmove-up)(global-set-key (kbd "C-x C-j") 'windmove-down)(global-set-key (kbd "C-x C-;") 'hippie-expand)(global-set-key (kbd "C-x C-g") 'find-name-dired)(global-set-key (kbd "C-c C-t") 'ansi-term)

Viper Keybindings (in .viper)

(setq viper-expert-level '3)(setq viper-inhibit-startup-message 't)(setq-default indent-tabs-mode nil) ; I think this makes tabs into spaces(setq viper-shift-width 4) ; don't touch or else...;; Makes searching w/ regex default(setq viper-re-search t) ; don't touch or else...;; The following is for hideshow to work ALMOST similar to vi folding;; (there were keybindings I didn't like)(define-key viper-vi-global-user-map "zt" 'hs-toggle-hiding)(define-key viper-vi-global-user-map "zM" 'hs-hide-all)(define-key viper-vi-global-user-map "zm" 'hs-hide-block)(define-key viper-vi-global-user-map "zR" 'hs-show-all)(define-key viper-vi-global-user-map "zr" 'hs-show-block)

Features implemented using external files

Yasnippet (for bundling and snippets)

Yasnippet provides me features along the lives of textmates bundling,
which I think definitely makes things faster in the long run. After all,
who wants to write boilerplate code?

http://manual.macromates.com/en/bundles

Yasnippet site:

http://code.google.com/p/yasnippet/

lusty-explorer.el (for a great tab completion file navigator)

Followed this emacs-fu guide:

http://emacs-fu.blogspot.com/2010/07/navigating-through-files-and-buffers.html

And downloaded the .el here:

http://www.emacswiki.org/emacs/LustyExplorer

Specifically I have the following in my .emacs:

(when (require 'lusty-explorer nil 'noerror)  ;; overrride the normal file-opening, buffer switching  (global-set-key (kbd "C-x C-f") 'lusty-file-explorer)  (global-set-key (kbd "C-x b")   'lusty-buffer-explorer))

Desired features

I have yet to implement this, but I would like:

  • Better file search (the ones I could find don’t do what I’m looking for)
    • Specifically, looking for a smart find that allow autocompletion
    • Looking for something along the lines of eclipse

Code folding in Emacs Viper-Mode

Code folding is a feature I’ve never really used, and for the most part
seem to have done find without. I generally use search to navigate from
place to place in my code, but I realize this isn’t always the most
efficient way to go, and code folding is very useful in a couple
aspects:

  • It helps focus me on what particular method or class I’m working on
    (way harder to tell when you’ve got several bunches of code in front
    of you at once)
  • Getting a good idea of the structure of the code (with everything
    folded, it’s much easier to see)

So I decided to play around with folding with my current development
environment. I use Emacs as my base, but viper-mode for the actual
text editing.

Emacs has some pretty good folding tools built-in. Namely, these are
FoldingMode and HideShow. I admit I didn’t play around with
FoldingMode a lot, as using it seems to involve manually adding the
folding points, something which I think is unnecessary 90% of the time.
Ideally, I’m looking for a folding extension that automatically
determines folding points, and leaves things as hands-off for me as
possible. One should be able to open a file, fold it up, and then open
and fold as necessary. I’m not looking to waste time adding commented
blocks of folding everywhere.

Thats where HideShow comes in. Armed with rules for an array of
programming languages, HideShow automatically looks for these patterns
and sets folding points appropriately. Exactly what I’m looking for.
Simply loading hideshow using .emacs:

(load-library "hideshow")

And activate the hideshow minor mode whenever you load the major mode of
your choice (for me it’s Python):

(add-hook 'python-mode-hook 'hs-minor-mode)

Now you have all the access to the wonderful world of dynamic folding!
Unfortunately, I didn’t really like the cumbersome keystrokes:

  • C-c @ M-C-s to unfold all
  • C-c @ C-h to fold
  • C-c @ C-s to unfold
  • C-c @ M-C-h to fold all
  • C-c @ C-c to toggle folding

Yeah, a six key-stroke succession is too much for me. So I assigned
these bindings to almost the same folding commands as VIM:

  • zm to unfold
  • zr to fold
  • zM to unfold all
  • zR to fold all
  • zt to toggle

To do this, I added configuration into the .viper file:

(define-key viper-vi-global-user-map "zt" 'hs-toggle-hiding)(define-key viper-vi-global-user-map "zM" 'hs-hide-all)(define-key viper-vi-global-user-map "zm" 'hs-hide-block)(define-key viper-vi-global-user-map "zR" 'hs-show-all)(define-key viper-vi-global-user-map "zr" 'hs-show-block)

(viper-vi-global-user-map tell viper it’s for any buffer in any state
with viper as a major mode). So far, this is working like a charm for
me. Here’s a screenshot with it at work:

image0

Feel free to comment if you have ideas/improvements!