From Emacs to Atom

I want to start this post by stating I have nothing but respect, admiration, and love for the Emacs community. Emacs’ extensibility, community packages, and it’s choice to effectively be an editor built on a lisp VM is amazing, and anyone choosing Emacs as an editor is investing in something that can grow with your needs.

Nevertheless, there are compelling reasons to switch to Atom. I am saying goodbye to Emacs, and have started using Atom as my main text editor.

My History with Emacs

I learned about Emacs during my college years (roughly 2008), when I happened to attend a house party for a family friend. The friend was a software developer who retired many years ago, but upon learning of my interest in software, he began to regale me with story after story of how much he does in Emacs.

“I check my e-mail with Emacs.”

“I built a program that opens my garage door from Emacs.”

“I share the same editor across multiple computers using the remote Emacs client.”

In all honesty I wasn’t really impressed by the idea of a program that you use to literally do everything, but it seemed like a great kernel for a text editor. I was using vim at the time and what I always lamented at (which I know others would say it’s vim’s greatest strength) was the fact that it could only be used to modify text. When I write code, I do so much more than write the code itself. I wanted an environment that made executing additional tasks seamless:

  • Interact with version control (git push / pull, commit, add)
  • Code search
  • Running command line scripts
  • Running a REPL and unit tests

Thus I dove into Emacs. The built-in terminal emulator, the ability to build whole programs in a single .el file and load them up, adding significant functionality to the editor, meant a lot of my needs were met quickly, and without significant effort. This became even easier with the release of Emacs 24, which included a built-in library to retrieve and install third-party packages, reducing the need to copy and paste.

I continued pretty happily for several years. I made a couple videos showcasing my Emacs setup, published my dotfiles, and wrote some tutorials as well.

Enter Atom

In 2015, Atom was released. An editor that was inspired by the flexibility of Emacs, but was built on HTML5 technologies. Using web technologies to build out massive native applications is not an advantage in every respect, but there are strong wins in some important areas.

A Powerful UI Framework

HTML, CSS, and Javascript have all grown to support the needs of the massive range of uses that websites are now used for, and the result from tackling such a large breadth is a powerful, general system for laying out various windows, styling them appropriately. Combine that with highly optimized runtimes to render said windows (web browsers) and you have a system that is not just developer-friendly, but also user-friendly.

Large Pool of Experienced Developers

A large portion of software engineers are web developers, and thus work in web technologies. The ability to transfer even some of this expertise as one is extending their editor removes a large chunk of the learning curve.

Impressed, But Not Sold

Atom was conceptually the editor I always wanted: the power of Emacs, a flexible UI framework, and a core built on technologies that I knew well and could contribute to. If I was starting from scratch, I may have chosen Atom, even when it just came out of beta.

However, I wasn’t starting from scratch. There was years of expertise in elisp, finding the right packages, learning to use them, and familiarizing myself with keybindings and the Emacs way of doing things. It didn’t make sense to throw those out the window for a nascent editor.

The Catalyst: Atom IDE and Language Server Integration

Since Atom came out, there was another text editor that entered the scene: VSCode. Similar in design to Atom, VSCode took a more opinionated approach to how an editor should be organized, and what tools to use (in the vein of visual studio). The more open world of Atom wasn’t a first priority (for example, VSCode did not provide support for more than three text windows at a time until recently).

However, VSCode did directly lead to the creation of the language server protocol, which enables any text editor to take advantage of IDE-like features, as long as they build an interface to a JSON-RPC based API.

When Atom implemented it’s language client, it was impressive, and it made me want to try Atom. But making the switch would require me to port all of my existing tools to find equivalents, and most likely learn a new set of keybindings. I already had a lot of that in Emacs. However, there was a final factor that really made me switch.

Community Critical Mass

For almost any tool or program, you’ll find one that is better in almost every significant way, but yet has not taken off. As much as we’d like to believe software engineering is a purely merit-based field, the reality is it depends on socio-economic factors as much as every other discipline. Market and mind-share matters.

The most impressive part of the language server protocol is not that it was built, it’s who built it. Facebook was a major contributor, teaming up with Github to build a real IDE experience for Atom.

Facebook’s business practices aside, they have a giant and talented engineer base. With Facebook engineers supporting a plugin like the Atom IDE, there’s a strong chance that you will see that integration improved and supported for years to come. And Atom is also a blessed project from Github.

I love Emacs, but it’s primarily supported by a volunteer base, who have other fulltime jobs. It’s very difficult trying to get a group of developers to implement something like language server support, and maintain and contribute back for years to come.

And the active community is larger around Atom. As of October 2018, here’s the counts of packages on the major package repositories per editor:

Unfortunately, Emacs does not have the development community in the same way Atom and VSCode can. That’s a conversation worth diving into, but it doesn’t change the state of the world today.

Migrating to Atom

So, I migrated my Emacs setup to Atom. Since I was a relatively late adopter a majority of my desired features were already a part of the editor, or were available as an extension.

I don’t think it’s valuable to dive into exactly what my setup looks like, but if you’d like to learn more, you can check out an Atom plugin I’m working on:

https://atom.io/packages/chimera

I am not using Atom 100% of the time, and I haven’t opened Emacs in about a year. The migration process took a couple of weeks.

The Future

Today, I have a lot invested in Atom, and I like my experience. Language server integration was a missing pain point, and that ecosystem (along with Atom’s integrations with it) is getting better every day.

The biggest lost I faced with Atom was performance: due to its reliance on a browser-based renderer, performance suffers vs draw calls in a native GUI. There are also improvements that can be made to Atom to ensure more non-blocking UI actions.

The Atom team has been working on xray, a text editor designed for performance whose improvements will be incorporated into the editor.

VSCode has also been a lot better on the performance front than Atom (still orders of magnitude slower than native editors). I tried it out recently and found the performance gain for me has been imperceptible, so it’s probably not worth the effort to lose the extension and keybinding knowledge.

 

 

 

Emacs From Scratch, Part 3: Extending Emacs with Elisp

This is a series of tutorials geared around building up your own
customized environment, using emacs, from scratch.

You can find part 1 here
You can find part 2 here

Extending Emacs with Elisp

If you’ve followed the previous tutorials, you’re familiar with
loading configuration, and you now have a system that can download
packages for you from the various Emacs package repositories. Now
let’s dive into where Emacs get’s really fun: extending Emacs
yourself.

One of the things I love about modern programming is the idea of
feedback as quickly as possible: it’s great to see the result of the
changes of your code instantly. So let’s try writing a generic way to
do this. We’ll write a function that adds a hook to an Emacs buffer,
so when it saves, a shell command will run. (e.g. ‘python myscript.py’ for a
python script, or running unit tests, etc)

Create a file called my-methods.el, adding it to your .emacs.d/
directory. To write our command, we’ll need to do the following:

  • a hash to store (buffer, command) pairs to run
  • create a method to add a (buffer, command) pair to our hash
  • look in our hash if a buffer is saved, and run the command if the buffer exists in the hash
  • remove entries from our hash if the buffer is killed

So let’s start by adding our hash:

; my-methods.el
(setq my-command-buffer-hooks (make-hash-table))

(setq <name> <value>) will set a variable <name> to a value
<value>. This is one way of instantiating a variable in elisp. There
are other ways, such as defvar,
but I chose setq because we are simply defining an internal variable
for usage. Other variations which define variables typically provide
some other purpose, such as a user-customizable value or a constant.

Now that we have our hash table, let’s start adding to it! We’ll write
our first function to my-methods.el:

; my-methods.el

(defun my-command-on-save-buffer (c)
    "Run a command <c> every time the buffer is saved "
    (interactive "sShell command: ")
    (puthash (buffer-file-name) c my-command-buffer-hooks))

This method takes in a variable ‘c’, takes the current buffer, and
adds pair of (buffer-name, command-as-a-string) to our hash. This is a
short function, but it’s a dense amount of functionality, so it’s
worth explaining a bit further.

defun

Defun is the standard way to define a function. It uses the following syntax:

(defun <method_name> (<var_a> <var_b>...)
  <docstring>
  <interactive?>
  <method_body>)

Here’s a description of each:

  • <method_name>: a symbol to populate with the method
  • <var_a> <var_b>… : a list of symbols to populate with passed parameters
  • <docstring>: a string explaining what your method does
  • <interactive?>: options. we’ll take about this more in a second
  • <method_body>: a lisp expression which has access to <var_a> <var_b>… symbols described above.

So pretty standard for a method definition in any language, except for (interactive?).

interactive

So what is interactive? Well, it’s an optional expression, which, if
passed in to defun, makes the method ‘interactive’. Interactive
basically means it’s one of the command that can be run by ‘M-x’: it
becomes a publicly exposed command that an Emacs user should be able
to run.

(interactive) by itself results in a command that does not ask the
user for input. In other words, it’s only useful for commands that
have no variables.

If we want the user to be able to type some input, we need to add in a
string into interactive, like our example above:

(interactive "sShell Command:")

So this will take in a single string. So how do we know it always
takes a string and only a string? Well, it’s the first ‘s’ in the
“sShell Command”. The first character is called an ‘interactive code’:
it’s a way to express what the expected input is. Specifying the
proper interactive code is important: codes such as ‘D’ (directory
name) or ‘C’ (emacs command) can provide auto-completion, making your
function all the more useful.

Multiple arguments can be passed by delimiting with newlines:

(interactive "sA String:\nDA Directory")

A full list of interactive codes can be found here: interactive codes

puthash/gethash/remhash

So the one thing that might be a little strange if you work in a
primarily OOP environment: (puthash <map> <key> <value>) instead of
something like <map>.put(<key> <value>).

elisp is a functional language, which means that everything is,
essentially, a function or data. There is no real concept of
object-oriented programming: if you want to modify an object, you call
a method with the object as the argument, not an object calling a method.

To work with a hash, elisp provides puthash/gethash/remhash. You can
read more here: hash-access

So at this point, you should have all the info you need to understand
the my-command-on-save-buffer option.

Now let’s add a couple more functions to complete our hook.

my-command-on-buffer-run-hook

Add the following to you my-methods.el:

; .emacs.d/my-methods.el

(defun my-command-buffer-kill-hook ()
  "Remove a key from <command-buffer-hooks> if it exists"
  (remhash (buffer-file-name) my-command-buffer-hooks))

This function removes the current buffer from the hooks hash. Pretty
straightforward with what we know now.

And this one:

; .emacs.d/my-methods.el

(defun my-command-buffer-run-hook ()
  "Run a command if it exists in the hook"
  (let ((hook (gethash (buffer-file-name) my-command-buffer-hooks)))
    (when hook
        (shell-command hook))))

This is the actual function that runs the hook. Note the extra check wrappend in a with.
(when is a shorthand for if with only one argument. It’s more
lisp-esque to provide shorthands like this).

Finally we need to add the hooks so that these function actually run:

; .emacs.d/my-methods.el

;; add hooks
(add-hook 'kill-buffer-hook 'my-command-buffer-kill-hook)
(add-hook 'after-save-hook 'my-command-buffer-run-hook)

Emacs provides a nice hook implementation. pass in the hook name you
want to listen to, and the function name you want to call.

And that’s it! give it a shot. In fact, let’s try it our Emacs
now. open up my-methods.el and type: M-x eval-buffer. Voila! you know
have your my-command-on-save-buffer. Emacs has the ability to evaluate
code with it’s lisp interpreter, which allows modifying the global
state of the editor itself. By evaluating our code, we basically just
added the functions we writing to the actual emacs instance we’ve been working in!

Now this is what I’m saying when I love modern programming. Getting
automated feedback faster is always better, and Emacs is great at
providing fast feedback on editor changes. You don’t even have to
restart your process! You can modify the environment you’re working
in, as you’re working on it, and see the changes instantly!

Anyway, let’s try our new functions with a test file.

Open a file /tmp/tmp.txt, save it (C-x C-s), and run: M-x
my-command-on-buffer-save. It’ll ask you far a shell argument.

Type in the following:

echo 'hello world'

Now type something and save your file. boom! The output should be in
the mini-buffer (you can see the full output in the *Shell Command Output* buffer).

Congrats! You’ve just written your first functional elisp function. And it’s pretty useful too.

If you want to learn more about developing elisp code, you can’t go
wrong with the elisp manual.
Like most languages, some things are not going to be the most
intuitive in the beginning. However, as you become more comfortable
elisp will start to feel like just another amazing feature of Emacs.

The other way to learn a lot is by looking at other people’s emacs
packages and files. Go to melpa, find
a package you like, and click the ‘source’ link, and start reading!

Summary

Here’s what we learned:

  • elisp is a functional languages: everything is done through functions
  • defun is used te define methods, and can have docstrings and can be interactive
  • elisp uses hashes, and uses puthash/gethash/remhash
  • Emacs can evaluate code and modify it’s interpreter on the fly

Final Code

Note: this includes code from part one

.emacs:

(load "~/.emacs.d/my-loadpackages.el")
(load "~/.emacs.d/my-methods.el")
(add-hook 'after-init-hook '(lambda ()
  (load "~/.emacs.d/my-noexternals.el")))

.emacs.d/my-methods:

;  ~/.emacs.d/my-methods.el

(setq my-command-buffer-hooks (make-hash-table))

(defun my-command-on-save-buffer (c)
    "Run a command <c> every time the buffer is saved "
    (interactive "sShell command: ")
    (puthash (buffer-file-name) c my-command-buffer-hooks))

(defun my-command-buffer-kill-hook ()
  "Remove a key from <command-buffer-hooks> if it exists"
  (remhash (buffer-file-name) my-command-buffer-hooks))

(defun my-command-buffer-run-hook ()
  "Run a command if it exists in the hook"
  (let ((hook (gethash (buffer-file-name) my-command-buffer-hooks)))
    (when hook
        (shell-command hook))))

;; add hooks
(add-hook 'kill-buffer-hook 'my-command-buffer-kill-hook)
(add-hook 'after-save-hook 'my-command-buffer-run-hook)

.emacs.d/my-noexternals.el:

; ~/.emacs.d/my-noexternals.el

;; Remove scrollbars, menu bars, and toolbars
(when (fboundp 'menu-bar-mode) (menu-bar-mode -1))
(when (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))

;; Wind-move
(global-set-key (kbd "C-c C-j") 'windmove-left)
(global-set-key (kbd "C-c C-k") 'windmove-down)
(global-set-key (kbd "C-c C-l") 'windmove-up)
(global-set-key (kbd "C-c C-;") 'windmove-right)

.emacs.d/my-packages.el:

; ~/.emacs.d/my-packages.el
(require 'cl)

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/") t)
(add-to-list 'package-archives
             '("marmalade" . "http://marmalade-repo.org/packages/") t)
(package-initialize)

(defvar required-packages
  '(
    magit
    yasnippet
  ) "a list of packages to ensure are installed at launch.")

; method to check if all packages are installed
(defun packages-installed-p ()
  (loop for p in required-packages
        when (not (package-installed-p p)) do (return nil)
        finally (return t)))

; if not all packages are installed, check one by one and install the missing ones.
(unless (packages-installed-p)
  ; check for new packages (package versions)
  (message "%s" "Emacs is now refreshing its package database...")
  (package-refresh-contents)
  (message "%s" " done.")
  ; install the missing packages
  (dolist (p required-packages)
    (when (not (package-installed-p p))
      (package-install p))))

.emacs.d/my-loadpackages.el:

; ~/.emacs.d/my-loadpackages.el
; loading package
(load "~/.emacs.d/my-packages.el")

(require 'magit)
(define-key global-map (kbd "C-c m") 'magit-status)

(require 'yasnippet)
(yas-global-mode 1)
(yas-load-directory "~/.emacs.d/snippets")
(add-hook 'term-mode-hook (lambda()
    (setq yas-dont-activate t)))

What’s Next

That’s it for now! You should now have the basic set of knowledge to
start hacking and trying things yourself:

  • an automated way to install packages and define the ones you want
  • a place to load the packages, and augment behaviour
  • an introduction to coding new functions yourself

If there’s other things you want to me to cover or discuss, leave a
comment with your suggestions.

Happy hacking!

Further Reading / References

Emacs From Scratch, Part 2: Package management

This is a series of tutorials geared around building up your own
customized environment, using emacs, from scratch.
You can find part 1 here
You can find part 3 here

Installing and Managing Packages

Requirements

To follow along with this tutorial, all you need is an existing
installation of Emacs 24, or package.el. I note 24 specifically because if you have
Linux, your distribution might not have an Emacs package that is version 24 or higher.

You can find out your emacs version with the ‘M-x emacs-version’ in
your Emacs. If you don’t have 24, Bozhidar Batsov wrote a great guide
on installing emacs 24.

Conversely, you can install package.el.
Simple add it somewhere to your .emacs.d and load it as shown in part 1.

Background

Text editors tend to be limited in the initial functionality they
provide. Even Emacs, which provides a larger set of base functionality
and features than most, will probably not have everything you
want. Luckily, like most other editors these days, Emacs provides
methodology to extend your text editor by taking code others have written. Vim and Sublime call them
plugins, Emacs calls them packages.

As of Emacs 24, packages management is now included by default. This means you have a way to:

  • install packages: M-x package-install <package>
  • list all existing packages: M-x list-packages

But we have a couple steps to go until we reach package management nirvana.

The Code

For this tutorial, let’s add two separate files into our ~/.emacs.d/ directory:

  • my-packages.el
  • my-loadpackages.el

And load .emacs.loadpackages files in your ~/.emacs:

(load "~/.emacs.d/my-loadpackages.el")

We’re going to split our code up into two parts: one file to define
what packages we want to install, and another to load and set up those
packages.

Adding packages archives

Emacs 24’s packages manager allows the adding of additional package
archives, the places where package.el looks for packages to
install. In your my-packages.el, let’s tell Emacs to add some more
package archives:

; my-packages.el
(require 'package)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/") t)
(add-to-list 'package-archives
             '("marmalade" . "http://marmalade-repo.org/packages/") t)
(package-initialize)

So what are these package archives? Here’s some info about them:

  • melpa is a package archive managed
    by Milkypostman. It’s the easiest package archive to add packages
    too, and is automatically updated when the package is. The go-to
    source for up to date, and the vast majority of, packages. However
    it’s worth noting that with cutting-edge comes instability, so that
    is a risk of stability one should be aware of. It’s worth noting I’ve never been
    broken for any package I’ve installed via melpa, however.
  • marmalade is another third-party
    package manager. Marmalade tends to be more stable, due to the
    requirement that developers explicitely upload new versions of their
    packages.

I personally use both (and the built-in Emacs 24 package-archive), but
if you don’t want to use one or the other, remove the offending
statements from above.

The code above does the following:

  • loads the package ‘package’ via the require keyword
  • installs relevant package managers
  • initializes the package system so definitions are loaded

Installing and Loading Packages on Startup

Now that we have the package repositories we like, it’s time to
install some packages! First, choose a package you’d like to
install. I’m going to install magit, a very nice version
control major mode for git, and yasnippet, a package to easily
parameterize and inject templates as needed (e.g. a java class template).
Remember, you can always find more package by using ‘M-x list-packages’

If you wanted to install these manually, all you would have to do is ‘M-x
package-install <package>’. However, I believe in reproduceability, so I’m
going to explain a method that will automatically install desired
missing packages on startup.

(To give proper attribution, I adapted this method from snippets in this file
in emacs-prelude.)

The first step is to define a list of packages you want installed on
startup. In your my-packages.el, after the package archives have been
initialized, let’s create a list and store our desired packages in them:

; my-packages.el
; defvar is the correct way to declare global variables
; you might see setq as well, but setq is supposed to be use just to set variables,
; not create them.
(defvar required-packages
  '(
    magit
    yasnippet
  ) "a list of packages to ensure are installed at launch.")

Now that required-packages is defined, we can use it to install some
packages! Let’s add a few more lines to install these packages for us:

Add the following to my-packages.el:

; my-packages.el
(require 'cl)

; method to check if all packages are installed
(defun packages-installed-p ()
  (loop for p in required-packages
        when (not (package-installed-p p)) do (return nil)
        finally (return t)))

; if not all packages are installed, check one by one and install the missing ones.
(unless (packages-installed-p)
  ; check for new packages (package versions)
  (message "%s" "Emacs is now refreshing its package database...")
  (package-refresh-contents)
  (message "%s" " done.")
  ; install the missing packages
  (dolist (p required-packages)
    (when (not (package-installed-p p))
      (package-install p))))

So what does this code do? Well:

  • package-installed-p is from package.el and checks if a package is installed
  • packages-installed-p checks if all desired packages are installed
  • the unless clause:
    • first checks if all packages are installed. If they are, no need to do extra work.
    • if not all packages are installed:
      • refresh the package indices
      • install each non-installed package.

So whenever I want to install a package, I just add it to the list. If
you share your .emacs configuration across machines, or have to start
from scratch, this makes it very easy to build an environment. Even if
you completely blow away your existing packages.

Give it a try! shut down your emacs now and start it back up, and you
should install the magit and yasnippet packages.

Loading and Configuring Packages

So now we have packages installing automatically. How do we use them?

Each package has it’s own configuration, so it’s best to read the
README or documentation. However, almost all packages require you to
require it first. Let’s add a few lines to our .emacs.d/my-loadpackages.el:

; my-loadpackages.el
; loading package
(load "~/.emacs.d/my-packages.el")

(require 'magit)
(define-key global-map (kbd "C-c m") 'magit-status)

(require 'yasnippet)
(yas-global-mode 1)
(yas-load-directory "~/.emacs.d/snippets")
(add-hook 'term-mode-hook (lambda()
    (setq yas-dont-activate t)))

So each package section starts with a “require”, which loads a
particular package into the existing emacs environment. This is
required before configuring anything related no that package. Notice
that I also use the require as a section header, defining what package
is related to what configuration.

One thing to note here is that once a package is loaded via require,
it’s methods are globally available EVERYWHERE. There’s no concept of
importing just for the file in emacs lisp, you just add everything to
this global context. However, most packages use a prefix, (such as
‘yas’ for yasnippet commands) so it doesn’t seem too cluttered.

Here we also see another use of add-hook, but it’s different this
time: this time we hook it to a particular major mode. This means that
this particular hook will activate when that major-mode is
activated. This is useful when you want to activate specific behaviour
for when you’re editing a particular kind of text (e.g. binding a
shortcut to open up a python interpreter if you’re in a python major mode)

As an aside, here’s the configuration I’m setting here:

  • binding C-c m to magit-status: this is an example of a custom
    shortcut for my environment. Wherever I am, I can hit C-c m and see
    the status of the git repository I’m in (if I’m in one).
  • yas-global-mode: this ensures that yasnippet is activated
    globally. Since yasnippet doesn’t typically interfere with anything,
    and I’ve found that any sort of text I’m modifying benefits from
    snippets, It’s a good default to have.
  • yas-load-directory: this allows me to load snippets from a specific
    location. I have custom snippets I store in there.
  • (add-hook ‘term-mode-hook…): this is a little hack that needs to
    exist. Otherwise, tab-complete doesn’t work in Emacs’ terminal
    emulators such as ansi-mode.

Summary

Here’s what we learned:

  • emacs has a built-in (as of Emacs 24) package management system.
  • can install third-party repositories by adding entries to package-archives
  • can install packages manually with M-x install-package
  • packages can be loaded via (require ‘<package-name>)

Final Code

Note: this includes code from part one

.emacs:

(load "~/.emacs.d/my-loadpackages.el")
(add-hook 'after-init-hook '(lambda ()
  (load "~/.emacs.d/my-noexternals.el")
))

.emacs.d/my-noexternals.el:

; ~/.emacs.d/my-noexternals.el

;; Remove scrollbars, menu bars, and toolbars
(when (fboundp 'menu-bar-mode) (menu-bar-mode -1))
(when (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))

;; Wind-move
(global-set-key (kbd "C-c C-j") 'windmove-left)
(global-set-key (kbd "C-c C-k") 'windmove-down)
(global-set-key (kbd "C-c C-l") 'windmove-up)
(global-set-key (kbd "C-c C-;") 'windmove-right)

.emacs.d/my-packages.el:

; ~/.emacs.d/my-packages.el
(require 'cl)

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/") t)
(add-to-list 'package-archives
             '("marmalade" . "http://marmalade-repo.org/packages/") t)
(package-initialize)

(defvar required-packages
  '(
    magit
    yasnippet
  ) "a list of packages to ensure are installed at launch.")

; method to check if all packages are installed
(defun packages-installed-p ()
  (loop for p in required-packages
        when (not (package-installed-p p)) do (return nil)
        finally (return t)))

; if not all packages are installed, check one by one and install the missing ones.
(unless (packages-installed-p)
  ; check for new packages (package versions)
  (message "%s" "Emacs is now refreshing its package database...")
  (package-refresh-contents)
  (message "%s" " done.")
  ; install the missing packages
  (dolist (p required-packages)
    (when (not (package-installed-p p))
      (package-install p))))

.emacs.d/my-loadpackages.el:

; ~/.emacs.d/my-loadpackages.el
; loading package
(load "~/.emacs.d/my-packages.el")

(require 'magit)
(define-key global-map (kbd "C-c m") 'magit-status)

(require 'yasnippet)
(yas-global-mode 1)
(yas-load-directory "~/.emacs.d/snippets")
(add-hook 'term-mode-hook (lambda()
    (setq yas-dont-activate t)))

What’s Next

Next tutorial, we’ll talk about writing our own methods and modifying behaviour ourselves.

Further Reading / References

Emacs From Scratch, Part 1: Extending Emacs basics

This is a series of tutorials geared around building up your own
customized environment, using emacs, from scratch.

You can find part 2 here
You can find part 3 here

This tutorial is geared toward those who are starting with extending
Emacs, and want to learn the pieces you need to know to really extend
and build your custom environment. If you want to just get started
with a rocking environment and don’t care about understanding the
nitty-gritty, I’d suggest looking at emacs-prelude

We’re going to go in-depth on discussing the following topics:

  • extending your base emacs with init-files, and some good practices there
  • managing and installing packages, and doing so automatically
  • binding command and keys to installed packages
  • writing some custom code, and integrating it into your emacs environment

If you follow all these tutorials word for word, you’ll end up with
the building blocks to set up your own personalized emacs environment. Here’s mine:

My Emacs Setup

However, I would recommend picking and choosing the parts that best
suit your purposes. Please leave comments if I’m not going in-depth
enough to provide the tools to do so.

So let’s begin!

The Tutorial

Emacs Lisp

To follow these tutorials, you need to have a very rudimentary
understanding of emacs lisp. Basically just remeber this:

(method arg1 arg2 ...)

Is how methods are called: the first element in a parentheses is the
method being called, and the subsequent elements are it’s arguments.

You can also nest calls into calls, like this:

(foo (bar bar-argument) foo-argument)

This nesting of statements is what starts the chain of parentheses
that lisp and lisp dialects are famous for.

Init-Files

init-files are the files that emacs loads on startup. This is similar
to the rc files that you often see with shells/terminals, vim, or a
variety of other tools.

Emacs has a few standard places to add an init-file, but those are
already well documented in the manual.
If you want to know more, feel free to read there.

For the most part, however, there are two main locations where
init-files lie: the .emacs file and the .emacs.d directory in the user
root.

Unlike some other init files, Emacs’s initialization is basically
evaluating the init-files with it’s built-in elisp (Emacs Lisp)
interpreter. This is what provides Emacs users with real power: since
the great majority of Emacs is written directly in elisp, it is
possible to extend any of that code with your init-file, or even
evaluating code on the fly after the system starts up. This is a stark
contrast to other extensibile architectures, which only allow a
discrete set of configs or apis from which to modify application
behaviour. When you hear someone say Emacs is “infinitely extensible”,
this is what they mean: you can practically modify whatever you want
in Emacs!

But before we get to this awesome power, it’s first best to learn some
ways to organize your init-files. Emacs init-files can get huge, and
having good practices now will help you manage all the pieces in the long run.

The .emacs.d directory is the de-facto place to store configuration
files beyond the .emacs file. Package managers add their packages
there, packages add their configuration there, so it’s also a good
place to add our custom configuration.

For our example, let’s disable the menu, scroll and tool bars. This
removes all of the dropdown gui menus, so all we have are the buffers
left. You might think this is crippling at first, but learning your keybindings
will make you way more efficient in the long run.

You can name your files whatever you want, but I’ve found it’s easy to
find files if you prefix them. I prefix all of my init-files with
“my-“. This also has the advantage of signifying it’s a personal
configuration.

So let’s make a file now called “my-noexternals”. This signifies to me
that these are configs for components that are native to Emacs (don’t
depend on third-party packages, or “externals”). Let’s disable the menu, tool, and
scroll bar now:

; ~/.emacs.d/my-noexternals.el

;; Remove scrollbars, menu bars, and toolbars
; when is a special form of "if", with no else clause, it reads:
; (when <condition> <code-to-execute-1> <code-to-execute2> ...)
(when (fboundp 'menu-bar-mode) (menu-bar-mode -1))
(when (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))

Now that we have that, we need to load our my-noexternals.el file in
our .emacs. Add the following line to ~/.emacs:

; ~/.emacs
(load "~/.emacs.d/my-noexternals.el")

And now when you start emacs, you’ll have the bars disabled! Of
course, you’re welcome to enable whatever you like, I was just using
this as an example.

Rebinding Keys

Now let’s say we want to re-bind keys. elisp has a command for that as
well, and it’s called global-set-key. It works like this:

(global-set-key <keychord> <function-name>)

An easy way to declare the key chord you want to use is by using the
“kbd” command, which evaluates a keychord formatted in typical emacs
key-chord fashion, and evaluates it to something global-set-key can
understand. As an example:

(global-set-key (kbd "C-c C-j") 'foo)

Would make C-c C-j (<Ctrl + c> followed by <Ctrl + j>) run the “foo” function.

As a personal preference, I like
navigating through my open windows with vim-like movement (hjkl). As a
compromise, I bind the following commands:

; ~/my-noexternals.el

;; Wind-move

(global-set-key (kbd "C-c C-j") 'windmove-left)
(global-set-key (kbd "C-c C-k") 'windmove-down)
(global-set-key (kbd "C-c C-l") 'windmove-up)
(global-set-key (kbd "C-c C-;") 'windmove-right)

windmove-<direction> is a command that moves your window focus to the
first window in the direction specified. I bind them to the chords C-c
C-(jkl;), because C-c C-h is a help command.

Using Hooks

However, the problem with some keybindings is that they get overridden
depending on the order global-set-key gets run. This is especially a
problem when using external packages, which can sometimes override
keys with their own configuration. This is not a common practice now,
but can still happend.

To help ensure your commands run in a particular order, Emacs provides
hooks into it’s startup (along with several other places, but we’ll
get into that later). So let’s modify our .emacs so my-noexternals.el
gets loaded at the very end, after everything else has run:

; ~/.emacs

(add-hook 'after-init-hook '(lambda ()
  (load "~/.emacs.d/my-noexternals.el")
))

The “add-hook” command allows you to hook methods to run at a
particular time, and the “‘after-init-hook” tells emacs to run the
method after everything else in the init-file loaded.

Note that in this example, I used a lambda/anonymous method versus an
explicit function. It’s typically the standard to do lambdas in hooks
over, say, defining a function and passing it.

Summary

So to recap, here’s the useful things we learned:

  • ~/.emacs and ~/.emacs.d/ are the standard locations to add init-files
  • splitting out ~/.emacs into several other files and loading those is a lot easier to manage
  • (load <filename>) will evaluate a file
  • (global-set-key <keychord> <function-name>) will set <keychord> to run <function-name>
  • (add-hook <hook> <lambda>) to run lambda at a particular event
  • the “‘after-init-hook” event will run functions after the rest of the init-file has finished loading.

Final Code

.emacs:

(add-hook 'after-init-hook '(lambda ()
  (load "~/.emacs.d/my-noexternals.el")
))

.emacs.d/my-noexternals.el:

; ~/.emacs.d/my-noexternals.el

;; Remove scrollbars, menu bars, and toolbars
(when (fboundp 'menu-bar-mode) (menu-bar-mode -1))
(when (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))

;; Wind-move
(global-set-key (kbd "C-c C-j") 'windmove-left)
(global-set-key (kbd "C-c C-k") 'windmove-down)
(global-set-key (kbd "C-c C-l") 'windmove-up)
(global-set-key (kbd "C-c C-;") 'windmove-right)

What’s Next

Next tutorial, we’ll talk about package management.
You can find part 2 here

Further Reading / References

Increment-Decrement for Emacs

Here’s a small increment/decrement function I wrote, because I like how vim has one:

;; check if string is an integer
(defun string-integer-p (string)
  (if (string-match "\\`[-+]?[0-9]+\\'" string)
      t
    nil))

;; Decrement Int
(defun decrement ()
  "Decrement the integer that the cursor is on."
  (interactive)
  (let ((x (thing-at-point 'symbol)))
    (when (string-integer-p x)
      (let ((x-int (string-to-number x))
            (bds (bounds-of-thing-at-point 'symbol)))
        (progn
          (delete-region (car bds) (cdr bds))
          (insert (number-to-string (- x-int 1)))
        )
      )
    )
  )
)

;; Increment Int
(defun increment ()
  "Increment the integer that the cursor is on."
  (interactive)
  (let ((x (thing-at-point 'symbol)))
    (when (string-integer-p x)
      (let ((x-int (string-to-number x))
            (bds (bounds-of-thing-at-point 'symbol)))
        (progn
          (delete-region (car bds) (cdr bds))
          (insert (number-to-string (+ x-int 1)))
        )
      )
    )
  )
)

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