;;; rails-ruby.el --- provide features for ruby-mode ;; Copyright (C) 2006 Dmitry Galinsky ;; Authors: Dmitry Galinsky ;; Keywords: ruby rails languages oop ;; $URL: svn+ssh://rubyforge/var/svn/emacs-rails/trunk/rails-ruby.el $ ;; $Id: rails-ruby.el 190 2007-04-27 19:04:46Z dimaexe $ ;;; License ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License ;; as published by the Free Software Foundation; either version 2 ;; of the License, or (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program; if not, write to the Free Software ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ;;; Code: (require 'inf-ruby) ;; setup align for ruby-mode (require 'align) (defconst align-ruby-modes '(ruby-mode) "align-perl-modes is a variable defined in `align.el'.") (defconst ruby-align-rules-list '((ruby-comma-delimiter (regexp . ",\\(\\s-*\\)[^/ \t\n]") (modes . align-ruby-modes) (repeat . t)) (ruby-symbol-after-func (regexp . "^\\s-*\\w+\\(\\s-+\\):\\w+") (modes . align-ruby-modes))) "Alignment rules specific to the ruby mode. See the variable `align-rules-list' for more details.") (add-to-list 'align-perl-modes 'ruby-mode) (add-to-list 'align-dq-string-modes 'ruby-mode) (add-to-list 'align-sq-string-modes 'ruby-mode) (add-to-list 'align-open-comment-modes 'ruby-mode) (dolist (it ruby-align-rules-list) (add-to-list 'align-rules-list it)) ;; other stuff (defun ruby-newline-and-indent () (interactive) (newline) (ruby-indent-command)) (defun ruby-toggle-string<>simbol () "Easy to switch between strings and symbols." (interactive) (let ((initial-pos (point))) (save-excursion (when (looking-at "[\"']") ;; skip beggining quote (goto-char (+ (point) 1)) (unless (looking-at "\\w") (goto-char (- (point) 1)))) (let* ((point (point)) (start (skip-syntax-backward "w")) (end (skip-syntax-forward "w")) (end (+ point start end)) (start (+ point start)) (start-quote (- start 1)) (end-quote (+ end 1)) (quoted-str (buffer-substring-no-properties start-quote end-quote)) (symbol-str (buffer-substring-no-properties start end))) (cond ((or (string-match "^\"\\w+\"$" quoted-str) (string-match "^\'\\w+\'$" quoted-str)) (setq quoted-str (substring quoted-str 1 (- (length quoted-str) 1))) (kill-region start-quote end-quote) (goto-char start-quote) (insert (concat ":" quoted-str))) ((string-match "^\:\\w+$" symbol-str) (setq symbol-str (substring symbol-str 1)) (kill-region start end) (goto-char start) (insert (format "'%s'" symbol-str)))))) (goto-char initial-pos))) (defun run-ruby-in-buffer (cmd buf) "Run CMD as a ruby process in BUF if BUF does not exist." (let ((abuf (concat "*" buf "*"))) (when (not (comint-check-proc abuf)) (set-buffer (make-comint buf rails-ruby-command nil cmd))) (inferior-ruby-mode) (make-local-variable 'inferior-ruby-first-prompt-pattern) (make-local-variable 'inferior-ruby-prompt-pattern) (setq inferior-ruby-first-prompt-pattern "^>> " inferior-ruby-prompt-pattern "^>> ") (pop-to-buffer abuf))) (defun complete-ruby-method (prefix &optional maxnum) (if (capital-word-p prefix) (let* ((cmd "x = []; ObjectSpace.each_object(Class){|i| x << i.to_s}; x.map{|i| i.match(/^%s/) ? i.gsub(/^%s/, '') : nil }.compact.sort{|x,y| x.size <=> y.size}") (cmd (if maxnum (concat cmd (format "[0...%s]" maxnum)) cmd))) (el4r-ruby-eval (format cmd prefix prefix))) (save-excursion (goto-char (- (point) (+ 1 (length prefix)))) (when (and (looking-at "\\.") (capital-word-p (word-at-point)) (el4r-ruby-eval (format "::%s rescue nil" (word-at-point)))) (let* ((cmd "%s.public_methods.map{|i| i.match(/^%s/) ? i.gsub(/^%s/, '') : nil }.compact.sort{|x,y| x.size <=> y.size}") (cmd (if maxnum (concat cmd (format "[0...%s]" maxnum)) cmd))) (el4r-ruby-eval (format cmd (word-at-point) prefix prefix))))))) ;; flymake ruby support (require 'flymake nil t) (defconst flymake-allowed-ruby-file-name-masks '(("\\.rb\\'" flymake-ruby-init) ("\\.rxml\\'" flymake-ruby-init) ("\\.builder\\'" flymake-ruby-init) ("\\.rjs\\'" flymake-ruby-init)) "Filename extensions that switch on flymake-ruby mode syntax checks.") (defconst flymake-ruby-error-line-pattern-regexp '("^\\([^:]+\\):\\([0-9]+\\): *\\([\n]+\\)" 1 2 nil 3) "Regexp matching ruby error messages.") (defun flymake-ruby-init () (condition-case er (let* ((temp-file (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace)) (local-file (file-relative-name temp-file (file-name-directory buffer-file-name)))) (list rails-ruby-command (list "-c" local-file))) ('error ()))) (defun flymake-ruby-load () (when (and (buffer-file-name) (string-match (format "\\(%s\\)" (string-join "\\|" (mapcar 'car flymake-allowed-ruby-file-name-masks))) (buffer-file-name))) (setq flymake-allowed-file-name-masks (append flymake-allowed-file-name-masks flymake-allowed-ruby-file-name-masks)) (setq flymake-err-line-patterns (cons flymake-ruby-error-line-pattern-regexp flymake-err-line-patterns)) (flymake-mode t) (local-set-key (rails-key "d") 'flymake-display-err-menu-for-current-line))) (when (featurep 'flymake) (add-hook 'ruby-mode-hook 'flymake-ruby-load)) (provide 'rails-ruby)