rails-ruby.el
1 ;;; rails-ruby.el --- provide features for ruby-mode 2 3 ;; Copyright (C) 2006 Dmitry Galinsky <dima dot exe at gmail dot com> 4 5 ;; Authors: Dmitry Galinsky <dima dot exe at gmail dot com> 6 7 ;; Keywords: ruby rails languages oop 8 ;; $URL: svn://rubyforge.org/var/svn/emacs-rails/trunk/rails-ruby.el $ 9 ;; $Id: rails-ruby.el 190 2007-04-27 19:04:46Z dimaexe $ 10 11 ;;; License 12 13 ;; This program is free software; you can redistribute it and/or 14 ;; modify it under the terms of the GNU General Public License 15 ;; as published by the Free Software Foundation; either version 2 16 ;; of the License, or (at your option) any later version. 17 18 ;; This program is distributed in the hope that it will be useful, 19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 ;; GNU General Public License for more details. 22 23 ;; You should have received a copy of the GNU General Public License 24 ;; along with this program; if not, write to the Free Software 25 ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 26 27 ;;; Code: 28 29 (require 'inf-ruby) 30 31 ;; setup align for ruby-mode 32 (require 'align) 33 34 (defconst align-ruby-modes '(ruby-mode) 35 "align-perl-modes is a variable defined in `align.el'.") 36 37 (defconst ruby-align-rules-list 38 '((ruby-comma-delimiter 39 (regexp . ",\\(\\s-*\\)[^/ \t\n]") 40 (modes . align-ruby-modes) 41 (repeat . t)) 42 (ruby-symbol-after-func 43 (regexp . "^\\s-*\\w+\\(\\s-+\\):\\w+") 44 (modes . align-ruby-modes))) 45 "Alignment rules specific to the ruby mode. 46 See the variable `align-rules-list' for more details.") 47 48 (add-to-list 'align-perl-modes 'ruby-mode) 49 (add-to-list 'align-dq-string-modes 'ruby-mode) 50 (add-to-list 'align-sq-string-modes 'ruby-mode) 51 (add-to-list 'align-open-comment-modes 'ruby-mode) 52 (dolist (it ruby-align-rules-list) 53 (add-to-list 'align-rules-list it)) 54 55 ;; other stuff 56 57 (defun ruby-newline-and-indent () 58 (interactive) 59 (newline) 60 (ruby-indent-command)) 61 62 (defun ruby-toggle-string<>simbol () 63 "Easy to switch between strings and symbols." 64 (interactive) 65 (let ((initial-pos (point))) 66 (save-excursion 67 (when (looking-at "[\"']") ;; skip beggining quote 68 (goto-char (+ (point) 1)) 69 (unless (looking-at "\\w") 70 (goto-char (- (point) 1)))) 71 (let* ((point (point)) 72 (start (skip-syntax-backward "w")) 73 (end (skip-syntax-forward "w")) 74 (end (+ point start end)) 75 (start (+ point start)) 76 (start-quote (- start 1)) 77 (end-quote (+ end 1)) 78 (quoted-str (buffer-substring-no-properties start-quote end-quote)) 79 (symbol-str (buffer-substring-no-properties start end))) 80 (cond 81 ((or (string-match "^\"\\w+\"$" quoted-str) 82 (string-match "^\'\\w+\'$" quoted-str)) 83 (setq quoted-str (substring quoted-str 1 (- (length quoted-str) 1))) 84 (kill-region start-quote end-quote) 85 (goto-char start-quote) 86 (insert (concat ":" quoted-str))) 87 ((string-match "^\:\\w+$" symbol-str) 88 (setq symbol-str (substring symbol-str 1)) 89 (kill-region start end) 90 (goto-char start) 91 (insert (format "'%s'" symbol-str)))))) 92 (goto-char initial-pos))) 93 94 (defun run-ruby-in-buffer (cmd buf) 95 "Run CMD as a ruby process in BUF if BUF does not exist." 96 (let ((abuf (concat "*" buf "*"))) 97 (when (not (comint-check-proc abuf)) 98 (set-buffer (make-comint buf rails-ruby-command nil cmd))) 99 (inferior-ruby-mode) 100 (make-local-variable 'inferior-ruby-first-prompt-pattern) 101 (make-local-variable 'inferior-ruby-prompt-pattern) 102 (setq inferior-ruby-first-prompt-pattern "^>> " 103 inferior-ruby-prompt-pattern "^>> ") 104 (pop-to-buffer abuf))) 105 106 (defun complete-ruby-method (prefix &optional maxnum) 107 (if (capital-word-p prefix) 108 (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}") 109 (cmd (if maxnum (concat cmd (format "[0...%s]" maxnum)) cmd))) 110 (el4r-ruby-eval (format cmd prefix prefix))) 111 (save-excursion 112 (goto-char (- (point) (+ 1 (length prefix)))) 113 (when (and (looking-at "\\.") 114 (capital-word-p (word-at-point)) 115 (el4r-ruby-eval (format "::%s rescue nil" (word-at-point)))) 116 (let* ((cmd "%s.public_methods.map{|i| i.match(/^%s/) ? i.gsub(/^%s/, '') : nil }.compact.sort{|x,y| x.size <=> y.size}") 117 (cmd (if maxnum (concat cmd (format "[0...%s]" maxnum)) cmd))) 118 (el4r-ruby-eval (format cmd (word-at-point) prefix prefix))))))) 119 120 ;; flymake ruby support 121 122 (require 'flymake nil t) 123 124 (defconst flymake-allowed-ruby-file-name-masks 125 '(("\\.rb\\'" flymake-ruby-init) 126 ("\\.rxml\\'" flymake-ruby-init) 127 ("\\.builder\\'" flymake-ruby-init) 128 ("\\.rjs\\'" flymake-ruby-init)) 129 "Filename extensions that switch on flymake-ruby mode syntax checks.") 130 131 (defconst flymake-ruby-error-line-pattern-regexp 132 '("^\\([^:]+\\):\\([0-9]+\\): *\\([\n]+\\)" 1 2 nil 3) 133 "Regexp matching ruby error messages.") 134 135 (defun flymake-ruby-init () 136 (condition-case er 137 (let* ((temp-file (flymake-init-create-temp-buffer-copy 138 'flymake-create-temp-inplace)) 139 (local-file (file-relative-name 140 temp-file 141 (file-name-directory buffer-file-name)))) 142 (list rails-ruby-command (list "-c" local-file))) 143 ('error ()))) 144 145 (defun flymake-ruby-load () 146 (when (and (buffer-file-name) 147 (string-match 148 (format "\\(%s\\)" 149 (string-join 150 "\\|" 151 (mapcar 'car flymake-allowed-ruby-file-name-masks))) 152 (buffer-file-name))) 153 (setq flymake-allowed-file-name-masks 154 (append flymake-allowed-file-name-masks flymake-allowed-ruby-file-name-masks)) 155 (setq flymake-err-line-patterns 156 (cons flymake-ruby-error-line-pattern-regexp flymake-err-line-patterns)) 157 (flymake-mode t) 158 (local-set-key (rails-key "d") 'flymake-display-err-menu-for-current-line))) 159 160 (when (featurep 'flymake) 161 (add-hook 'ruby-mode-hook 'flymake-ruby-load)) 162 163 (provide 'rails-ruby)