开发工具 Emacs 24 Rails Development Environment - From *scratch* to Productive in 5 Minutes

sectic · 2012年04月26日 · 最后由 doitian 回复于 2012年04月27日 · 4179 次阅读

http://viget.com/extend/emacs-24-rails-development-environment-from-scratch-to-productive-in-5-minu

I’m a big fan of Emacs. My fellow employees at Viget enjoy a number of different editors including Textmate and Vim. I strongly believe that everyone should use an editor they feel productive in and most importantly, an editor they enjoy. So, I have no interest in engaging in any kind of editor holy war here.

I’d like to show you how you can go from a default installation of Emacs HEAD (24) to a workable Rails development environment in only a few minutes. I will make the following assumptions:

You are running Mac OSX 10.6 You have Xcode (< 4 beta) installed You have homebrew installed and working You have installed git using homebrew You are using rvm to manage your rubies and have a default configured. You have a basic understanding of Emacs These instructions could likely be tweaked for different systems without too much fuss.

Let’s begin!

INSTALLING EMACS HEAD

To do this we’ll use homebrew, observe:

$ brew install emacs --cocoa --use-git-head --HEAD $ mv /usr/local/Cellar/emacs/HEAD/Emacs.app /Applications/ $ mkdir ~/.emacs.d $ echo ";; emacs configuration" > ~/.emacs.d/init.el This will leave you will a fresh copy of Emacs and a blank configuration file.

CONFIGURING THE BASICS

At the risk of editorializing I’ll say that Emacs doesn’t have the most desirable configuration defaults. That’s ok! It only takes a few lines of elisp to make a more pleasant experience.

So, go ahead and launch Emacs like you would any other application. You will be presented with the illustrious Emacs logo and some instructions on how to use the editor. If you are new to Emacs consider taking the Emacs tutorial presented in the default splash screen. Otherwise:

Navigate (C-x C-f) to ~/.emacs.d/init.el and insert the following after our singular comment at the top:

(push "/usr/local/bin" exec-path) (setq make-backup-files nil) (setq auto-save-default nil) (setq-default tab-width 2) (setq-default indent-tabs-mode nil) (setq inhibit-startup-message t) (fset 'yes-or-no-p 'y-or-n-p) (delete-selection-mode t) (scroll-bar-mode -1) (tool-bar-mode -1) (blink-cursor-mode t) (show-paren-mode t) (column-number-mode t) (set-fringe-style -1) (tooltip-mode -1) The most important bit of configuration is the first line. We are pushing “/usr/local/bin” onto the exec-path list giving Emacs the ability to use git (presuming it’s installed via hombrew and the binary resides in /usr/local/bin).

In the interest of aesthetics I will add two additional lines to our configuration:

(set-frame-font "Menlo-16") (load-theme 'tango) The first line changes the default font while the second line uses one of Emacs 24’s new features: built-in themes.

ELPA & EL-GET

Emacs 24 comes with ELPA package management built-in, however, the default repository of libraries excludes many we will need. So we’ll configure Emacs to use the tromey repository.

el-get is a new package management library written by Dimitri Fontaine. It’s great. It’s also fundamental in making our quick configuration possible.

Install el-get in the following manner:

$ cd ~/.emacs.d $ mkdir el-get $ cd el-get $ git clone git://github.com/dimitri/el-get.git We can now add the following lines to our configuration to load ELPA w/ an alternate repository and el-get.

(require 'package) (setq package-archives (cons '("tromey" . "http://tromey.com/elpa/") package-archives)) (package-initialize) (add-to-list 'load-path "~/.emacs.d/el-get/el-get") (require 'el-get) At this point it’s a good idea to evaluate the init.el buffer and refresh the elpa package list, in Emacs:

(M-x) eval-buffer (M-x) package-refresh-contents PACKAGE INSTALLATION

el-get can use a number of package retrieval protocols. Most relevant to us: ELPA and git. Drop the following configuration in your init.el:

(setq el-get-sources '((:name ruby-mode :type elpa :load "ruby-mode.el") (:name inf-ruby :type elpa) (:name ruby-compilation :type elpa) (:name css-mode :type elpa) (:name textmate :type git :url "git://github.com/defunkt/textmate.el" :load "textmate.el") (:name rvm :type git :url "http://github.com/djwhitt/rvm.el.git" :load "rvm.el" :compile ("rvm.el") :after (lambda() (rvm-use-default))) (:name rhtml :type git :url "https://github.com/eschulte/rhtml.git" :features rhtml-mode) (:name yaml-mode :type git :url "http://github.com/yoshiki/yaml-mode.git" :features yaml-mode))) (el-get 'sync) Now evaluate the buffer again:

(M-x) eval-buffer This will start pulling down and compiling our list of packages.

At this point you have all you need to hack on Ruby and Rails applications. There is, however, some simple configuration that will further enhance your Rails development experience.

CUSTOMIZING RUBY AND ERB MODES

If we look carefully at our previous el-get package list code, we notice that the entry for rvm has an :after parameter. This parameter takes whatever function passed and executes it after the package is loaded. This is the perfect place to add per-mode hooks to our configuration. In the instance of rvm the rvm-use-default command is run after the rvm library loads.

In the interest of keeping line length to a minimum, I will create hook functions for each mode I want to configure post-load. Insert the following functions into your init.el above the previous el-get-sources definition:

(defun ruby-mode-hook () (autoload 'ruby-mode "ruby-mode" nil t) (add-to-list 'auto-mode-alist '("Capfile" . ruby-mode)) (add-to-list 'auto-mode-alist '("Gemfile" . ruby-mode)) (add-to-list 'auto-mode-alist '("Rakefile" . ruby-mode)) (add-to-list 'auto-mode-alist '("\.rake\'" . ruby-mode)) (add-to-list 'auto-mode-alist '("\.rb\'" . ruby-mode)) (add-to-list 'auto-mode-alist '("\.ru\'" . ruby-mode)) (add-hook 'ruby-mode-hook '(lambda () (setq ruby-deep-arglist t) (setq ruby-deep-indent-paren nil) (setq c-tab-always-indent nil) (require 'inf-ruby) (require 'ruby-compilation)))) (defun rhtml-mode-hook () (autoload 'rhtml-mode "rhtml-mode" nil t) (add-to-list 'auto-mode-alist '("\.erb\'" . rhtml-mode)) (add-to-list 'auto-mode-alist '("\.rjs\'" . rhtml-mode)) (add-hook 'rhtml-mode '(lambda () (define-key rhtml-mode-map (kbd "M-s") 'save-buffer)))) (defun yaml-mode-hook () (autoload 'yaml-mode "yaml-mode" nil t) (add-to-list 'auto-mode-alist '("\.yml$" . yaml-mode)) (add-to-list 'auto-mode-alist '("\.yaml$" . yaml-mode))) (defun css-mode-hook () (autoload 'css-mode "css-mode" nil t) (add-hook 'css-mode-hook '(lambda () (setq css-indent-level 2) (setq css-indent-offset 2)))) Now we can add :after parameters to ruby-mode, rhtml-mode, yaml-mode, and css-mode. Now our el-get package list looks more like this:

(setq el-get-sources '((:name ruby-mode :type elpa :load "ruby-mode.el" :after (lambda () (ruby-mode-hook))) (:name inf-ruby :type elpa) (:name ruby-compilation :type elpa) (:name css-mode :type elpa :after (lambda () (css-mode-hook))) (:name textmate :type git :url "git://github.com/defunkt/textmate.el" :load "textmate.el") (:name rvm :type git :url "http://github.com/djwhitt/rvm.el.git" :load "rvm.el" :compile ("rvm.el") :after (lambda() (rvm-use-default))) (:name rhtml :type git :url "https://github.com/eschulte/rhtml.git" :features rhtml-mode :after (lambda () (rhtml-mode-hook))) (:name yaml-mode :type git :url "http://github.com/yoshiki/yaml-mode.git" :features yaml-mode :after (lambda () (yaml-mode-hook))))) We’ve now got file extension detection and nice ruby indentation. At this point, you are finished. You can now develop your Ruby and Rails application in Emacs!

BONUS ROUND

The experienced Emacs Rails developer will notice that I haven’t included rinari. While rinari is a great library filled will all manner of helpful shortcuts, I never found myself using any of them save for one: running a single test buffer. Using functionality from the textmate.el library, I wrote two simple functions for the purpose of running a single test buffer:

(defun is-rails-project () (when (textmate-project-root) (file-exists-p (expand-file-name "config/environment.rb" (textmate-project-root))))) (defun run-rails-test-or-ruby-buffer () (interactive) (if (is-rails-project) (let* ((path (buffer-file-name)) (filename (file-name-nondirectory path)) (test-path (expand-file-name "test" (textmate-project-root))) (command (list ruby-compilation-executable "-I" test-path path))) (pop-to-buffer (ruby-compilation-do filename command))) (ruby-compilation-this-buffer))) This function determines if you are in a rails project or not. If in a Rails project the function assumes the buffer you are running is a test file, it then runs that file and outputs the results in a separate buffer. If not in a rails project, the function assumes that you are simply wanting to run any Ruby buffer, it does so outputting the results in a separate buffer. To my knowledge this function will not work with specs, however, it should be relatively trivial to make it do so.

Now, bind run-rails-test-or-ruby-buffer to a key combination (I use M-r) and you’ll be able to run Ruby files and Rails tests with minimal fuss. If you use rvm and/or gemsets like I do, you’ll want to use the command (M-x) rvm-use within a project, selecting the project’s Ruby version and gemset before running any tests or files in Emacs.

I hope you enjoyed configuring Emacs with me as much as I did. This configuration is one that could grow into a more mature and full-featured one, but as it is, will enable you to start hacking on Rails projects immediately. Please leave any questions you might have in the comments below. Thanks!

Gist of the full init.el: https://gist.github.com/785133

重装系统的时候碰到的。有版权问题的话再删吧。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号