diff --git a/prelude-ruby.el b/prelude-ruby.el index 0925698..dddb065 100644 --- a/prelude-ruby.el +++ b/prelude-ruby.el @@ -52,15 +52,15 @@ (require 'yari) ; TODO fix ruby-end and package ruby-block for marmalade -;(require 'ruby-block) -;(require 'ruby-end) +(require 'ruby-block) +(require 'ruby-end) (defun prelude-ruby-mode-hook () (prelude-coding-hook) (inf-ruby-keys) ;; turn off the annoying input echo in irb (setq comint-process-echoes t) - ;(ruby-block-mode t) + (ruby-block-mode t) (local-set-key (kbd "C-h r") 'yari)) (add-hook 'ruby-mode-hook 'prelude-ruby-mode-hook) diff --git a/vendor/ruby-block.el b/vendor/ruby-block.el new file mode 100644 index 0000000..922fb4d --- /dev/null +++ b/vendor/ruby-block.el @@ -0,0 +1,253 @@ +;;; ruby-block.el --- highlight matching block + +;; Copyright (C) 2007-2009 khiker + +;; Author: khiker +;; Keywords: languages, faces, ruby + +;; This file 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, or (at your option) +;; any later version. + +;; This file 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 GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Usage: + +;; Add this line to your .emacs +;; +;; (require 'ruby-block) +;; (ruby-block-mode t) +;; +;; In addition, you can also add this line too. +;; +;; ;; do overlay +;; (setq ruby-block-highlight-toggle 'overlay) +;; ;; display to minibuffer +;; (setq ruby-block-highlight-toggle 'minibuffer) +;; ;; display to minibuffer and do overlay +;; (setq ruby-block-highlight-toggle t) +;; +;; Default is minibuffer. +;; +;; Tested on Emacs 22.3.2 and Emacs 23.0.95.2. + +;;; Note: + +;; A ruby-mode.el is necessary to use this package. + +;;; Code: + +(require 'ruby-mode) + +;; Variables: + +(defconst ruby-block-version "0.0.8" + "Ruby block package version.") + +(defconst ruby-block-keyword-list + (list "end" "for" "while" "until" "if" "class" "module" + "case" "unless" "def" "begin" "do") + "Keyword for highlighting.") + +(defconst ruby-block-keyword-regex + "\\(end\\|for\\|while\\|until\\|if\\|class\\|module\\|case\\|unless\\|def\\|begin\\|do\\)" + "Rregular expression to look for correspondence.") + +(defgroup ruby-block nil + "Ruby block" + :tag "Ruby block" + :group 'ruby-block) + +(defcustom ruby-block-delay 0.50 + "*Time in seconds to delay before showing a matching paren." + :type 'number + :group 'ruby-block) + +(defcustom ruby-block-highlight-face 'highlight + "*Face for block highlighting." + :type 'face + :group 'ruby-block) + +(defcustom ruby-block-highlight-toggle 'minibuffer + "*How do you display corresponding line. +Default is minibuffer. display to minibuffer. + +The possible choice is as follows. + +nil => nothing +minibuffer => minibuffer +overlay => overlay +t => minibuffer and overlay" + :type '(choice (const :tag "nothing" nil) + (const :tag "minibuffer" minibuffer) + (const :tag "overlay" overlay) + (const :tag "minibuffer and overlay" t)) + :group 'ruby-block) + +(defvar ruby-block-timer nil) + +(defvar ruby-block-highlight-overlay nil) + + +;; Functions: + +(define-minor-mode ruby-block-mode + "In ruby-mode, Displays the line where there is keyword corresponding +to END keyword. this is Minor mode for ruby-mode only." + :init-value t + :global nil + :keymap nil + :lighter " RBlock" + (if ruby-block-mode + (ruby-block-start-timer) + (ruby-block-stop-timer))) + +(defun ruby-block-start-timer () + "start timer." + (when ruby-block-timer + (cancel-timer ruby-block-timer)) + (setq ruby-block-timer + (run-with-idle-timer ruby-block-delay t 'ruby-block-hook))) + +(defun ruby-block-stop-timer () + "stop timer." + (when ruby-block-timer + (cancel-timer ruby-block-timer) + (setq ruby-block-timer nil))) + +(defun ruby-block-hook () + "When Major-mode is ruby-mode, this package is running." + (if (eq major-mode 'ruby-mode) + (condition-case err + (ruby-block-function) + (error + (setq ruby-block-mode nil) + (message "Error: %S; ruby-block-mode now disabled." err))) + (setq ruby-block-mode nil))) + +(defun ruby-block-get-line-start-pos () + (save-excursion + (let ((xor '(lambda (a b) (and (or a b) (not (and a b))))) + (point (point)) + (count 0)) + (while (and (not (funcall xor (bobp) (eolp))) + (> point (point-min))) + (setq point (1- point)) + (goto-char (1- (point)))) + ;; delete linefeed of start point. + (when (and (eolp) (>= (point-max) (1+ point))) + (setq point (1+ point))) + point))) + +(defun ruby-block-get-line-end-pos () + (save-excursion + (let ((xor '(lambda (a b) (and (or a b) (not (and a b))))) + (point (point))) + (while (and (not (funcall xor (eobp) (eolp))) + (>= (point-max) point)) + (setq point (1+ point)) + (goto-char (1+ (point)))) + point))) + +(defun ruby-block-function () + "Point position's word decides behavior." + (let ((current (current-word))) + (setq current (car (member current ruby-block-keyword-list))) + (cond + ;; not keyword + ((null current) + nil) + ;; keyword "end" + ((and (string= "end" current) + (eq 'font-lock-keyword-face (get-text-property (point) 'face))) + (let ((point (ruby-block-get-corresponding-point)) + (slinep 0)(elinep 0)) + ;; get whole line(exists point). and, display minibuffer. + (when (> point 0) + (save-excursion + (goto-char point) + (setq slinep (ruby-block-get-line-start-pos) + elinep (ruby-block-get-line-end-pos))) + ;; display line contents to minibuffer + (when (or (eq ruby-block-highlight-toggle t) + (eq ruby-block-highlight-toggle 'minibuffer)) + (message "%d: %s" (1+ (count-lines (point-min) slinep)) + (buffer-substring slinep elinep))) + ;; do overlay. + (when (or (eq ruby-block-highlight-toggle t) + (eq ruby-block-highlight-toggle 'overlay)) + (ruby-block-do-highlight slinep elinep))))) + ;; keyword except "end" + (t + nil)))) + +(defun ruby-block-get-corresponding-point () + "Get point of corresponding line." + (let ((orig-col (- (point) (ruby-block-get-line-start-pos))) + (recent-col (- (point) (ruby-block-get-line-start-pos))) + (count 1)(check t)(point 0)(face "")(string "")) + (save-excursion + (while check + (if (re-search-backward ruby-block-keyword-regex (point-min) t 1) + (setq point (match-beginning 1) + face (get-text-property point 'face) + string (current-word)) + (setq point -1 face "" string "" check nil)) + (when (and (eq face 'font-lock-keyword-face) + (not (string= string "elsif")) + (member string ruby-block-keyword-list) + ;; case: STMT if(or unless, while, untill) EXPR + (if (member string '("if" "unless" "while" "until")) + (let ((col (- point (ruby-block-get-line-start-pos)))) + (if (or (> (+ orig-col 3) col) + (> (+ recent-col 3) col)) + t nil)) + t)) + (if (and (string= string "end") check) + (setq count (1+ count) + recent-col (- (point) (ruby-block-get-line-start-pos))) + (setq count (1- count)))) + (when (= count 0) + (setq check nil))) + point))) + +(defun ruby-block-do-highlight (beg end) + "Do overlay corresponding line." + (if ruby-block-highlight-overlay + (move-overlay ruby-block-highlight-overlay beg end) + (setq ruby-block-highlight-overlay (make-overlay beg end))) + (overlay-put ruby-block-highlight-overlay + 'face ruby-block-highlight-face) + (add-hook 'pre-command-hook 'ruby-block-highlight-done)) + +(defun ruby-block-highlight-done () + "After do overlay, restore the line to original color." + (remove-hook 'pre-command-hook 'ruby-block-highlight-done) + (if ruby-block-highlight-overlay + (delete-overlay ruby-block-highlight-overlay))) + +(defun ruby-block-highlight-toggle () + "Switch on/off for ruby-block-mode." + (interactive) + (if ruby-block-highlight-toggle + (setq ruby-block-highlight-toggle nil) + (setq ruby-block-highlight-toggle t))) + +(provide 'ruby-block) + +;; Local Variables: +;; Coding: iso-2022-7bit +;; End: + +;;; ruby-block.el ends here diff --git a/vendor/ruby-end.el b/vendor/ruby-end.el new file mode 100644 index 0000000..d034df7 --- /dev/null +++ b/vendor/ruby-end.el @@ -0,0 +1,138 @@ +;;; ruby-end.el --- Automatic insertion of end blocks for Ruby + +;; Copyright (C) 2010 Johan Andersson + +;; Author: Johan Andersson +;; Maintainer: Johan Andersson +;; Version: 0.1.0 +;; Keywords: speed, convenience +;; URL: http://github.com/rejeep/ruby-end + +;; This file is NOT part of GNU Emacs. + + +;;; 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 3, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + + +;;; Commentary: + +;; ruby-end is a minor mode for Emacs that can be used with ruby-mode +;; to automatically close blocks by inserting "end" when typing a +;; block-keyword, followed by a space. +;; +;; To use ruby-end-mode, make sure that this file is in Emacs load-path: +;; (add-to-list 'load-path "/path/to/directory/or/file") +;; +;; Then require ruby-end: +;; (require 'ruby-end) +;; +;; ruby-end-mode is automatically started in ruby-mode. + + +;;; Code: + +(defvar ruby-end-expand-key "SPC" + "Space key name.") + +(defvar ruby-end-mode-map + (let ((map (make-sparse-keymap)) + (key (read-kbd-macro ruby-end-expand-key))) + (define-key map key 'ruby-end-space) + map) + "Keymap for `ruby-end-mode'.") + +(defcustom ruby-end-check-statement-modifiers t + "*Disable or enable expansion (insertion of end) for statement modifiers" + :type 'boolean + :group 'ruby) + +(defconst ruby-end-expand-postfix-modifiers-before-re + "\\(?:if\\|unless\\|while\\)" + "Regular expression matching statements before point.") + +(defconst ruby-end-expand-prefix-check-modifiers-re + "^\\s-*" + "Prefix for regular expression to prevent expansion with statement modifiers") + +(defconst ruby-end-expand-prefix-re + "\\(?:^\\|\\s-+\\)" + "Prefix for regular expression") + +(defconst ruby-end-expand-keywords-before-re + "\\(?:^\\|\\s-+\\)\\(?:do\\|def\\|class\\|module\\|case\\|for\\|begin\\)" + "Regular expression matching blocks before point.") + + +(defconst ruby-end-expand-after-re + "\\s-*$" + "Regular expression matching after point.") + +(defun ruby-end-space () + "Called when SPC-key is pressed." + (interactive) + (cond + ((ruby-end-expand-p) + (ruby-end-insert-end) + (insert " ")) + (t + (let ((ruby-end-mode nil)) + (call-interactively + (key-binding + (read-kbd-macro ruby-end-expand-key))))))) + +(defun ruby-end-insert-end () + "Closes block by inserting end." + (save-excursion + (newline) + (insert "end") + (indent-according-to-mode))) + +(defun ruby-end-expand-p () + "Checks if expansion (insertion of end) should be done." + (let ((ruby-end-expand-statement-modifiers-before-re + (concat + (if ruby-end-check-statement-modifiers + ruby-end-expand-prefix-check-modifiers-re + ruby-end-expand-prefix-re) + ruby-end-expand-postfix-modifiers-before-re))) + (and + (ruby-end-code-at-point-p) + (or + (looking-back ruby-end-expand-statement-modifiers-before-re) + (looking-back ruby-end-expand-keywords-before-re)) + (looking-at ruby-end-expand-after-re)))) + +(defun ruby-end-code-at-point-p () + "Checks if point is code, or comment or string." + (let ((properties (text-properties-at (point)))) + (and + (null (memq 'font-lock-string-face properties)) + (null (memq 'font-lock-comment-face properties))))) + +;;;###autoload +(define-minor-mode ruby-end-mode + "Automatic insertion of end blocks for Ruby." + :init-value nil + :lighter " end" + :keymap ruby-end-mode-map) + +(add-hook 'ruby-mode-hook 'ruby-end-mode) + +(provide 'ruby-end) + +;;; ruby-end.el ends here