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.

     .emacs.d/
       init.el -> The real .emacs file.
       custom/
         01ruby.el
         02org.el
         03auto-complete.el
         04web-mode.el
    
  4. The .emacs file : Contents of init.el looks something like this:

     (require 'cask "~/.cask/cask.el")
     (cask-initialize)
     (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
     (windmove-default-keybindings)
    
     ;; 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
         "~/.emacs.d/.cask/24.3.50.1/elpa/auto-complete-20130724.1750/dict")
     (ac-config-default)
     (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)
     (smartparens-global-mode)
     (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)
     (projectile-global-mode)
     (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.
    (ac-flyspell-workaround)
    

    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!

Upgrading to Mountain Lion and your development environment

Hemant  - July 27, 2012  |   , , ,

Prem of thoughtbot already had some brief instructions about upgrading to mountain lion and then thanks to Kenny for adding much to those instructions.

What follows is my own upgrade path:

  1. Take backup via Time Machine or superduper!.
  2. Upgrade using installer from App store and reboot.
  3. Install XCode 4.4 from App store. Looks like, if you don’t care much about developing iOS or OSX applications, you can skip this step. But I didn’t.
  4. Install command line tools of XCode as instructed in Prem’s blog post.
  5. Change permissions of Homebrew directory.

     sudo chown -R `whoami` /usr/local
     brew update
    
  6. If you are like me, you still have few applications running on 1.8.7. Ruby versions before 1.9.3 can’t be easily compiled using llvm-gcc compiler. Install gcc-4.2 using homebrew:

     brew tap homebrew/dupes
     brew install apple-gcc42
    
  7. Configure apple-gcc42 as default compiler. Update your ~/.zshrc or ~/.bashrc and add following lines:

     export CC=/usr/local/bin/gcc-4.2
    

    Above line should take care of compiling ruby itself and many native gems which use proper compiler detection. Unfortunately this won’t work for few odd gems and hence, you also need to do:

     sudo ln -s /usr/local/bin/gcc-4.2 /usr/bin/gcc-4.2
    
  8. Install XQuartz. This step may require you to logout and login again.

  9. Even if you already had ruby 1.8.7/1.9.3 compiled, I will urge you to recompile new one - just to ensure everything works perfectly.

    For compiling Ruby 1.8.7/REE:

     export CPPFLAGS="-I/opt/X11/include"
     export CFLAGS="-I/opt/X11/include"
    

    For compiling ruby:

     rvm reinstall ree
     rvm reinstall 1.9.3
    

    You should be able to compile ruby 1.9.3 without requiring any of above flags.

  10. Some recommend reinstalling key packages that you have installed using homebrew before ML upgrade.I did not bother to reinstall all the packages, but I did reinstall imagemagick.

     brew unlink imagemagick
     brew install imagemagick
    
  11. At this point you should have a working ruby and rails setup. I faced a minor problem where I was running mysql using packages downloaded from Mysql website and they were installed in /usr/local and after I changed permissions to restore Homebrew setup, my Mysql installation broke. To restore the sanity:

    sudo chown -R _mysql:_mysql /usr/local/mysql-5.xx
    
  12. In some of Rails applications, Nokogiri was throwing warning about being compiled against different version of libxml2. To get rid of those, I simply nuked Rails.root/vendor/ruby and reinstalled the gems my app was using via bundle install.

  13. Mark has suggested these instructions for getting pow running with Safari 6.

  14. I found that automatic reconnecting to wi-fi after coming out of sleep was broken. To fix this, I removed all the remembered locations and then in Configure Network Prefrences -> TCP/IP changed Configure IPV6 to Link-local only.

  15. I also noticed that external monitor when plugged in, won’t be detected at all.To fix this I had to reset my PRAM. You can follow this article for more information on resetting PRAM.