Setting up Emacs as Ruby development environment on OSX

Hemant  - October 17, 2013  |   , , ,

Learning and setting up Emacs can be intimidating and while some folks find much use in using a pre-configured setup like - Emacs Prelude, I personally think it is better that someone new to Emacs installs each and every module himself and learns from it. I am assuming OSX as development environment here but the instructions should work well enough on Linux as well.

  1. Install Emacs : Install Emacs using Homebrew. I personally do not recommend using Emacs for OSX distribution. You can find out why here.

     brew install emacs --use-git-head --cocoa --srgb

    There is a bug in Emacs HEAD that prevents it to be working with Cask and thus try not to use Emacs HEAD.

  2. Install a Package Manager : I use pallet for managing various packages. Think of pallet as Bundler/Maven for Emacs. Follow instructions available in section For newly installed Emacs. Once you have pallet installed each package you install via package-install command will automatically update the Cask and you can checkin the file in version control system and carry it around.

    Sometimes you have to install a package directly from git. I personally use Git Subtrees for adding packages from git. Feel free to use submodules or directly copying files as well.

  3. Structuring your Customization : Over last couple of years I personally have been using following style of structuring my emacs setup.

       init.el -> The real .emacs file.
  4. The .emacs file : Contents of init.el looks something like this:

     (require 'cask "~/.cask/cask.el")
     (require 'pallet)
     (add-to-list 'load-path "~/.emacs.d/custom")
     (add-to-list 'load-path "~/.emacs.d/other_paths)
     (load "00common-setup.el")
     (load "01ruby.el")
     (load "02org.el")
  5. Global Config : I use a lot of global configuration stuff which isn’t mode specific, some important ones are:

     ;; Navigate between windows using Alt-1, Alt-2, Shift-left, shift-up, shift-right
     ;; Enable copy and pasting from clipboard
     (setq x-select-enable-clipboard t)

    You can see complete file on, 00common-setup.el. If you are completely new to Emacs you should use C-h t (That is press Control-h and then t) to launch inbuilt Emacs tutorial from within Emacs.

Packages You need

For complete list of package see my Caskfile. Also some packages I use straight from git and hence may not be listed in Caskfile. With that out of the way, I will try to cover most important packages I love and use everyday:

  1. auto-complete : You can install it via package-install and below is my configuration of auto-complete mode:

     (require 'auto-complete-config)
     (add-to-list 'ac-dictionary-directories
     (setq ac-ignore-case nil)
     (add-to-list 'ac-modes 'enh-ruby-mode)
     (add-to-list 'ac-modes 'web-mode)

    It gives me access to all powerful auto-completion system for Emacs. Below is a screenshot.

    [Emacs auto-complete](/assets/images/emacs/auto-complete-7a77150cd11c64f1b5f22de4b0a52d72de61d7358109e0654dcf074cce7971cf.png

  2. ag : You should use silver searcher and corresponding Emacs mode ag. They beat likes of ack or grep hands down.

  3. enh-ruby-mode : Personally I am big fan of Enhanced Ruby Mode. It gives you better syntax highligting, better indentation schemes and code intelligence without running flymake kind of thing.

    ![enhanced ruby mode](/assets/images/emacs/enh-ruby-mode-adedbb79b2f586b70a48d9d3cebe318592a5db4e6867523124409c524dc2c4ff.png

    You can see rest of my enh-ruby-mode specific configuration in file 01ruby.el. You will notice that I have included a mini rspec-mode there , which allows me to run specs of a complete file or just spec under the cursor.

  4. smartparens : smartparens mode is too much of a moving target and hence I always use it from git. My smartparens configuration is:

     (require 'smartparens-config)
     (require 'smartparens-ruby)
     (show-smartparens-global-mode t)
     (sp-with-modes '(rhtml-mode)
       (sp-local-pair "<" ">")
       (sp-local-pair ""))

    SmartParens mode is many things. It automatically inserts closing parethesis, tags, end’s depending on major-mode. Highlights them, allows you to move between them. Allows you to wrap existing texts. However you may not even have to go through their documentation, it mostly just works.

  5. Projectile Mode : Projectile is one among many ways of handling projects in Emacs. My projectile configuration looks like:

     (require 'grizzl)
     (setq projectile-enable-caching t)
     (setq projectile-completion-system 'grizzl)
     ;; Press Command-p for fuzzy find in project
     (global-set-key (kbd "s-p") 'projectile-find-file)
     ;; Press Command-b for fuzzy switch buffer
     (global-set-key (kbd "s-b") 'projectile-switch-to-buffer)
     [![It allows me to do:](/assets/images/emacs/emacs4-2be08a609329db017ab61dafd234d821fe408e5fffa0f0002957e8ca52fc0a65.gif](/assets/images/emacs/emacs4-2be08a609329db017ab61dafd234d821fe408e5fffa0f0002957e8ca52fc0a65.gif)
  6. Rainbow Mode : Add color to your css/scss. Check screenshot below:

    Add color

  7. Robe Mode : Robe mode is what makes Emacs full featured IDE even comparable to likes of RubyMine etc.

Robe mode:

Robe can also integrate with `auto-complete` mode to provide more intelligent auto-completion.
I personally do not use that feature because it makes things slower.
  1. Highlight indentation for Emacs : Highlight Indentation mode allows you to see indentation guides. My setup for the mode is:

     (require 'highlight-indentation)
     (add-hook 'enh-ruby-mode-hook
               (lambda () (highlight-indentation-current-column-mode)))
     (add-hook 'coffee-mode-hook
               (lambda () (highlight-indentation-current-column-mode)))
  2. Yasnippet : Yasnippet is Emacs snippet library. Out of box it won’t work with enh-ruby-mode because it searches for ruby-mode. You can make it work by copying ruby-mode snippets to enh-ruby-mode folder.

  3. Flyspell : If you are like me, you make lot of typos in code comments, strings etc. Using Flyspell mode you need not worry about it - interfering with programming language keywords etc. My setup for Flyspell is :

    (require 'flyspell)
    (setq flyspell-issue-message-flg nil)
    (add-hook 'enh-ruby-mode-hook
              (lambda () (flyspell-prog-mode)))
    (add-hook 'web-mode-hook
              (lambda () (flyspell-prog-mode)))
    ;; flyspell mode breaks auto-complete mode without this.

    If you are on OSX you may have to run brew install ispell to make it work.

  4. Rinari : With Projectile mode, I am finding less and less use of this mode. But this is your canonical rails mode for Emacs. Get it via package-install or Rinari Github repo.

  5. dash-at-point : If you are on OSX you should totally use Dash. Using dash-at-point you can view documentation of methods, classes etc right from Emacs.

  6. multiple-cursors : Multiple Cursors is Emacs answer to multi-line editing feature of Sublime etc. Anything I can add here is probably better covered in this Emacs Rocks screencast.

  7. textmate.el : textmate.el allows me to quickly move between methods in a file, independent of programming language mode (and without ctags). It has many other utilities.

  8. WebMode : For a long time Emacs users were mostly stuck with half-assed multi-language mode when editing html templates. WebMode is like breath of fresh air for those who mix - ruby/js/css/coffee in their HTML!

Apart from aforementioned modes, I still use too many other modes - sometimes even unknowingly! Some modes that deserve honourable mention but I don’t use them is - Magit, Expand Region. If you do lot of Javascript then have a look at - Swank-js. If you are coming from Vim and looking for decent nerdtree replacement, you can try Dirtree or ECB or Project explorer.

Learning Emacs in a way is - as deep as you are willing go. For resources I recommend:

I hope you enjoyed this article and if you want to keep updated with latest stuff we are building or blogging about, follow us on twitter @codemancershq.

Non native fullscreen for OSX on emacs 24.3

Hemant  - July 5, 2013  |   , ,

Since upgrading to Emacs 24.3 I have been missing ns-toggle-fullscreen. This feauture has been replaced in newer version of Emacs with native OSX fullscreen.

Needless to say native OSX fullscreen can be painful when you are on multiple monitors and even on single monitor setup I find it unusable.

After searching high and low, I found the magic variable which can make Emacs 24.3 behave like old fashioned full screen. Emacs no longer moves to a new desktop and everything works as expected:

Download nightly version of Emacs from Emacs for OSX and add following to .emacs

(setq ns-use-native-fullscreen nil)

After that, when you use toggle-frame-fullscreen Emacs should be on fullscren but you should still have access to other monitor and things should be fine and dandy!

Poor man's rspec mode for emacs

Hemant  - March 27, 2013  |   , ,

For whatever reason rspec-mode didn’t work for me. I couldn’t either get it to use current version of Ruby or it used to crap out on Bundler detection.

Annoyed, I decided to write a very simple rspec-mode that works almost always. More importantly it runs rspec from root of current project directory using your current shell and hence you don’t need to configure RVM or rbenv from Emacs. Whatever version of Ruby your shell has it will run using that. As a bonus it runs rspec in a comint buffer that means if you are using pry or a debugger you can interact with it from Emacs itself.

(require 'compile)
;; Find root directory by searching for Gemfile
(defun* get-closest-gemfile-root (&optional (file "Gemfile"))
  (let ((root (expand-file-name "/")))
     for d = default-directory then (expand-file-name ".." d)
     if (file-exists-p (expand-file-name file d))
     return d
     if (equal d root)
     return nil)))

(defun rspec-compile-file ()
  (compile (format "cd %s;bundle exec rspec %s"
                   (file-relative-name (buffer-file-name) (get-closest-gemfile-root))
                   ) t))

(defun rspec-compile-on-line ()
  (compile (format "cd %s;bundle exec rspec %s -l %s"
                   (file-relative-name (buffer-file-name) (get-closest-gemfile-root))
                   ) t))

(add-hook 'enh-ruby-mode-hook
          (lambda ()
            (local-set-key (kbd "C-c l") 'rspec-compile-on-line)
            (local-set-key (kbd "C-c k") 'rspec-compile-file)

An astute reader will notice that I am not using default ruby-mode. You can change the hook to ruby-mode-hook if you are using default ruby-mode. So last few lines will become:

(add-hook 'ruby-mode-hook
          (lambda ()
            (local-set-key (kbd "C-c l") 'rspec-compile-on-line)
            (local-set-key (kbd "C-c k") 'rspec-compile-file)