From 8e3362f9442c0d2b7da341ba31c6881a167e849f Mon Sep 17 00:00:00 2001 From: Sameer Rahmani Date: Thu, 6 Jun 2013 21:22:40 +0430 Subject: [PATCH] Rails support added, with tomorrow theme --- conf/dotkuso | 34 +- conf/emacs.d/ecb/.gitignore | 5 - conf/emacs.d/rhtml/rhtml-erb.el | 321 ++++ conf/emacs.d/rhtml/rhtml-fonts.el | 177 ++ conf/emacs.d/rhtml/rhtml-mode.el | 107 ++ conf/emacs.d/rhtml/rhtml-navigation.el | 63 + conf/emacs.d/rhtml/rhtml-ruby-hook.el | 93 + conf/emacs.d/rhtml/rhtml-sgml-hacks.el | 522 ++++++ conf/emacs.d/rinari/rinari.el | 948 ++++++++++ .../rinari/util/cucumber-mode-compilation.el | 215 +++ conf/emacs.d/rinari/util/inf-ruby/inf-ruby.el | 375 ++++ conf/emacs.d/rinari/util/jump/README | 12 + conf/emacs.d/rinari/util/jump/Rakefile | 24 + conf/emacs.d/rinari/util/jump/findr.el | 258 +++ conf/emacs.d/rinari/util/jump/inflections.el | 157 ++ conf/emacs.d/rinari/util/jump/jump.el | 325 ++++ conf/emacs.d/rinari/util/jump/test/elunit.el | 338 ++++ conf/emacs.d/rinari/util/jump/test/init.el | 107 ++ .../test/jump-fake-app/animals/chicken.rb | 7 + .../jump/test/jump-fake-app/animals/pig.rb | 19 + .../jump/test/jump-fake-app/foods/pork.rb | 19 + .../rinari/util/ruby-compilation-rspec.el | 32 + conf/emacs.d/rinari/util/ruby-compilation.el | 356 ++++ conf/emacs.d/rinari/util/test/ert/TODO | 22 + .../rinari/util/test/ert/ert-functional.el | 99 ++ conf/emacs.d/rinari/util/test/ert/ert.el | 1578 +++++++++++++++++ conf/emacs.d/rinari/util/test/ert/ert.texinfo | 309 ++++ .../util/test/ert/test/badly-indented.el | 3 + .../util/test/ert/test/ert-selftests.el | 594 +++++++ .../util/test/ert/test/well-indented.el | 2 + .../rinari/util/test/ruby-mode-test.el | 39 + conf/emacs.d/themes/color-theme-tomorrow.el | 609 +++++++ conf/emacs.d/themes/tomorrow-day-theme.el | 2 + .../themes/tomorrow-night-blue-theme.el | 2 + .../themes/tomorrow-night-bright-theme.el | 2 + .../themes/tomorrow-night-eighties-theme.el | 2 + conf/emacs.d/themes/tomorrow-night-theme.el | 2 + 37 files changed, 7771 insertions(+), 8 deletions(-) delete mode 100644 conf/emacs.d/ecb/.gitignore create mode 100644 conf/emacs.d/rhtml/rhtml-erb.el create mode 100644 conf/emacs.d/rhtml/rhtml-fonts.el create mode 100644 conf/emacs.d/rhtml/rhtml-mode.el create mode 100644 conf/emacs.d/rhtml/rhtml-navigation.el create mode 100644 conf/emacs.d/rhtml/rhtml-ruby-hook.el create mode 100644 conf/emacs.d/rhtml/rhtml-sgml-hacks.el create mode 100644 conf/emacs.d/rinari/rinari.el create mode 100644 conf/emacs.d/rinari/util/cucumber-mode-compilation.el create mode 100755 conf/emacs.d/rinari/util/inf-ruby/inf-ruby.el create mode 100644 conf/emacs.d/rinari/util/jump/README create mode 100644 conf/emacs.d/rinari/util/jump/Rakefile create mode 100644 conf/emacs.d/rinari/util/jump/findr.el create mode 100644 conf/emacs.d/rinari/util/jump/inflections.el create mode 100644 conf/emacs.d/rinari/util/jump/jump.el create mode 100644 conf/emacs.d/rinari/util/jump/test/elunit.el create mode 100644 conf/emacs.d/rinari/util/jump/test/init.el create mode 100644 conf/emacs.d/rinari/util/jump/test/jump-fake-app/animals/chicken.rb create mode 100644 conf/emacs.d/rinari/util/jump/test/jump-fake-app/animals/pig.rb create mode 100644 conf/emacs.d/rinari/util/jump/test/jump-fake-app/foods/pork.rb create mode 100644 conf/emacs.d/rinari/util/ruby-compilation-rspec.el create mode 100644 conf/emacs.d/rinari/util/ruby-compilation.el create mode 100644 conf/emacs.d/rinari/util/test/ert/TODO create mode 100644 conf/emacs.d/rinari/util/test/ert/ert-functional.el create mode 100644 conf/emacs.d/rinari/util/test/ert/ert.el create mode 100644 conf/emacs.d/rinari/util/test/ert/ert.texinfo create mode 100644 conf/emacs.d/rinari/util/test/ert/test/badly-indented.el create mode 100644 conf/emacs.d/rinari/util/test/ert/test/ert-selftests.el create mode 100644 conf/emacs.d/rinari/util/test/ert/test/well-indented.el create mode 100644 conf/emacs.d/rinari/util/test/ruby-mode-test.el create mode 100644 conf/emacs.d/themes/color-theme-tomorrow.el create mode 100644 conf/emacs.d/themes/tomorrow-day-theme.el create mode 100644 conf/emacs.d/themes/tomorrow-night-blue-theme.el create mode 100644 conf/emacs.d/themes/tomorrow-night-bright-theme.el create mode 100644 conf/emacs.d/themes/tomorrow-night-eighties-theme.el create mode 100644 conf/emacs.d/themes/tomorrow-night-theme.el diff --git a/conf/dotkuso b/conf/dotkuso index c9d8bc2..40385e6 100644 --- a/conf/dotkuso +++ b/conf/dotkuso @@ -9,12 +9,11 @@ (global-linum-mode) ;; Setting up color them ------------------------------------------------------- -(require 'color-theme) (eval-after-load "color-theme" '(progn (color-theme-initialize) - (color-theme-arjen) - )) + (color-theme-tomorrow-night-eighties) +)) ;; Setting up customization ----------------------------------------------------- (custom-set-variables @@ -270,3 +269,32 @@ l;; css flymake ---------------------------------------------------------------- (global-set-key (kbd "C-x p") 'git-gutter:previous-diff) (global-set-key (kbd "C-x n") 'git-gutter:next-diff) ;;/git-gutter;; + +;; Yaml mode -------------------------------------- +(require 'yaml-mode) +(add-to-list 'auto-mode-alist '("\\.yml$" . yaml-mode)) + +(add-hook 'yaml-mode-hook + '(lambda () + (define-key yaml-mode-map "\C-m" 'newline-and-indent))) + + +(autoload 'inf-ruby "inf-ruby" "Run an inferior Ruby process" t) +(autoload 'inf-ruby-setup-keybindings "inf-ruby" "" t) +(eval-after-load 'ruby-mode + '(add-hook 'ruby-mode-hook 'inf-ruby-setup-keybindings)) + +(add-to-list 'load-path "~/.kuso.d/rinari") +(require 'rinari) + +(setq rinari-tags-file-name "TAGS") + + +(add-to-list 'load-path "~/.kuso.d/rhtml") +(require 'rhtml-mode) +(add-hook 'rhtml-mode-hook + (lambda () (rinari-launch))) + + + +(show-paren-mode t) diff --git a/conf/emacs.d/ecb/.gitignore b/conf/emacs.d/ecb/.gitignore deleted file mode 100644 index a19c46a..0000000 --- a/conf/emacs.d/ecb/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.elc -*~ -/TAGS -/html-help/ -/info-help/ diff --git a/conf/emacs.d/rhtml/rhtml-erb.el b/conf/emacs.d/rhtml/rhtml-erb.el new file mode 100644 index 0000000..b232811 --- /dev/null +++ b/conf/emacs.d/rhtml/rhtml-erb.el @@ -0,0 +1,321 @@ +;;; +;;; rhtml-erb.el - ERB tag support for `rhtml-mode' +;;; + +;; ***** BEGIN LICENSE BLOCK ***** +;; Version: MPL 1.1/GPL 2.0/LGPL 2.1 + +;; The contents of this file are subject to the Mozilla Public License Version +;; 1.1 (the "License"); you may not use this file except in compliance with +;; the License. You may obtain a copy of the License at +;; http://www.mozilla.org/MPL/ + +;; Software distributed under the License is distributed on an "AS IS" basis, +;; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +;; for the specific language governing rights and limitations under the +;; License. + +;; The Original Code is ERB Tag Support for RHTML-MODE. + +;; The Initial Developer of the Original Code is +;; Paul Nathan Stickney . +;; Portions created by the Initial Developer are Copyright (C) 2006 +;; the Initial Developer. All Rights Reserved. + +;; Contributor(s): + +;; Alternatively, the contents of this file may be used under the terms of +;; either the GNU General Public License Version 2 or later (the "GPL"), or +;; the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +;; in which case the provisions of the GPL or the LGPL are applicable instead +;; of those above. If you wish to allow use of your version of this file only +;; under the terms of either the GPL or the LGPL, and not to allow others to +;; use your version of this file under the terms of the MPL, indicate your +;; decision by deleting the provisions above and replace them with the notice +;; and other provisions required by the GPL or the LGPL. If you do not delete +;; the provisions above, a recipient may use your version of this file under +;; the terms of any one of the MPL, the GPL or the LGPL. + +;; ***** END LICENSE BLOCK ***** + + +;;; History +;; 2006SEP12 - Created + +;; Brief note on conventions: +;; DELIM - refers to the things like <% and %> +;; TAG - refers to entire <%ERB%> area, -including- the delims + +;; (load-file "~/.emacs.d/macro-utils.el") +;; (defmacro symbol-name-or-nil (symbol) +;; (once-only (symbol) +;; `(if ,symbol (symbol-name ,symbol)))) +;; (put 'symbol-name-or-nil 'lisp-indent-function 1) + + +(defconst rhtml-erb-open-delim + "<%" + "ERB opening tag. +Due to implementation of `sgml-mode', this absolutely must begin with a +< and be at least two characters long to work correctly.") + +(defconst rhtml-erb-close-delim + "%>" + "ERB ending tag. +I don't think this has any restrictions.") + +(defconst rhtml-erb-open-delim-len + (length rhtml-erb-open-delim)) + +(defconst rhtml-erb-close-delim-len + (length rhtml-erb-open-delim)) + +(defconst rhtml-erb-delim-re + (concat rhtml-erb-open-delim "\\|" rhtml-erb-close-delim)) + +(defconst rhtml-erb-tag-open-re + (concat rhtml-erb-open-delim "\\(?:-=\\|[-=#]?\\)?")) + +;; specific tags +(defconst rhtml-erb-exec-tag-open-re + (concat rhtml-erb-open-delim "\\(?:-\\(?:[^=#]\\|$\\)\\|[^-=#]\\|$\\)") + "<%, and who would have thought it would be so complicated?") +(defconst rhtml-erb-out-tag-open-re + (concat rhtml-erb-open-delim "-?=") + "<%=") +(defconst rhtml-erb-comment-tag-open-re + (concat rhtml-erb-open-delim "-?#") + "<%#") + +(defconst rhtml-erb-tag-body-re + "\\(?:.\\|\n\\)*?") + +(defconst rhtml-erb-tag-close-re + (concat "-?" rhtml-erb-close-delim)) + +(defconst rhtml-erb-tag-re + (concat "\\(" rhtml-erb-tag-open-re "\\)" + "\\(" rhtml-erb-tag-body-re "\\)" + "\\(" rhtml-erb-tag-close-re "\\)")) + +(defun rhtml-erb-delim-type (start-delim) + "Return `exec', `out', `comment' or nil dependin on the type of delimeter this is." + (flet ((match? (regex) + (eq (string-match regex start-delim) 0))) + (cond ((match? rhtml-erb-exec-tag-open-re) + 'exec) + ((match? rhtml-erb-out-tag-open-re) + 'out) + ((match? rhtml-erb-comment-tag-open-re) + 'comment)))) + +(defun rhtml-erb-middle-offset (prev-line-start cur-line-start) + "Helper method for modified `sgml-calculate-indent'. +Calculates adjustment of branches like \"else\". PREV-LINE-START +and CUR-LINE-START should be the first non-white space on each +line, respectively." + (save-excursion + (+ (progn + (goto-char cur-line-start) + (if (rhtml-scan-for-erb-tags '(erb-middle)) sgml-basic-offset 0)) + (progn + (goto-char prev-line-start) + (if (rhtml-scan-for-erb-tags '(erb-middle)) (- sgml-basic-offset) 0))))) + +(defconst rhtml-erb-block-open-re + (concat "[]A-Za-z_)}][ ]+do[ ]+\\(?:|[A-Za-z_, ]*|\\)?[ ]*" rhtml-erb-tag-close-re)) + +(defconst rhtml-erb-brace-block-open-re + (concat "[ ]+{[ ]+\\(?:|[A-Za-z_, ]*|\\)?[ ]*" rhtml-erb-tag-close-re) + "Slightly less strictive to allow for \"hash = {\n\".") + +(defmacro rhtml-erb-block-open-p () + "Guess if a Ruby fragment opens a block with do. +Returns `block' or `brace-block' on success." + `(re-search-forward ,rhtml-erb-block-open-re nil t)) + +(defmacro rhtml-erb-brace-block-open-p () + "Guess if a Ruby fragment opens a brace block (with {) +Returns `block' or `brace-block' on success." + `(re-search-forward ,rhtml-erb-brace-block-open-re nil t)) + +(defun rhtml-at-erb-tag-p () + "Returns (TAG-START . TAG-END) if at beginning of ERB tag." + (if (looking-at rhtml-erb-tag-re) + (cons (match-beginning 0) (match-end 0)))) + +(defun rhtml-skip-erb-tag () + "Skips over an ERB tag starting at (POINT); returns non-nil if succesful. +If the search is successful (POINT) will be advanced." + (let ((found (rhtml-at-erb-tag-p))) + (when found + (goto-char (cdr found))))) + +(defun rhtml-erb-tag-type-p (type) + (memq type '(erb-open erb-middle erb-close erb-data))) + +(defun rhtml-scan-for-erb-tags (tags) + "Like `rhtml-scan-erb-tag' but will only return (ERB-TYPE . NAME) +if (memq ERB-TYPE tags)." + (let ((start (point)) + (tag-info (rhtml-scan-erb-tag))) + (if (memq (car tag-info) tags) + tag-info + ;; reset on failure + (goto-char start) + nil))) + + +(defun rhtml-scan-erb-tag () + "Scans an ERB tag moving (POINT) to the end and returning (ERB-TYPE . NAME) on success. +ERB-TYPE is `erb-open', `erb-data', `erb-middle', or `erb-close'. +NAME is something like \"erb-brace-block\" or \"erb-start-form-tag\" that is +used for level-matching." + (let* ((erb-tag (rhtml-at-erb-tag-p)) + (erb-tag-end (cdr erb-tag))) + (cond (erb-tag + ;; Lead-in + (looking-at rhtml-erb-tag-open-re) + (goto-char (match-end 0)) + (skip-whitespace-forward) + (prog1 + (save-restriction + (narrow-to-region (point) erb-tag-end) ;(- end 2)) + (cond ((looking-at "if \\|unless ") + (cons 'erb-open "erb-multi-block")) + ((looking-at "for\\b\\|while ") + (cons 'erb-open "erb-block")) + ((rhtml-erb-block-open-p) + (cons 'erb-open "erb-block")) + ((rhtml-erb-brace-block-open-p) + (cons 'erb-open "erb-brace-block")) + ((looking-at "else \\|elsif") + (cons 'erb-middle "erb-middle")) + ((looking-at "end\\b") + (cons 'erb-close "erb-block")) + ((looking-at "}") + (cons 'erb-close "erb-brace-block")) + ((looking-at "start_form_tag\\b") + (cons 'erb-open "erb-form-tag")) + ((looking-at "end_form_tag\\b") + (cons 'erb-close "erb-form-tag")) + (t + (cons 'erb-data "erb-data")))) + (goto-char erb-tag-end))) + (t ;no match + (cons nil nil))))) + +;; TODO - simply by removing point parameter +(defun rhtml-erb-tag-region (&optional point) + "If inside a ERB tag returns (START . END) of the tag, otherwise nil. +If POINT is specified it will be used instead of (POINT)." + (if point + (save-excursion + (goto-char point) + (rhtml-erb-tag-region)) + (let ((prev (save-excursion ; -> (STR . START) + (skip-chars-forward rhtml-erb-open-delim) + (when (re-search-backward rhtml-erb-delim-re nil t) + (cons (match-string 0) (match-beginning 0))))) + (next (save-excursion ; -> (STR . END) + (skip-chars-backward rhtml-erb-open-delim) + (when (re-search-forward rhtml-erb-delim-re nil t) + (cons (match-string 0) (match-end 0)))))) + ;; limit matches to valid regions + (when (and (string= (car prev) rhtml-erb-open-delim) + (string= (car next) rhtml-erb-close-delim)) + (cons (cdr prev) (cdr next)))))) + +(defun rhtml-erb-regions (begin end) + "Returns a list of elements in the form (TYPE START END) where type is +`exec', `comment', `out'." + (let* (tag-start regions last-tag-end) + (catch 'done + (save-excursion + (goto-char begin) + (while t + (when (not (search-forward rhtml-erb-open-delim end t)) + (throw 'done regions)) + (setq tag-start (- (point) 2)) + (when (not (search-forward rhtml-erb-close-delim end t)) + (throw 'done regions)) + ;; erb tag + (push (list + (case (char-after (+ tag-start 2)) + (?= 'out) (?# 'comment) (t 'exec)) + tag-start (point)) + regions)))))) + +;; PST -- what is the point? At the very least it needs a better name. +(defun rhtml-erb-regions2 (begin end) + "Returns a list of elements in the form (TYPE START END) where type is +`exec', `comment', `out' or, for non-ERb secions, `other'." + (let* (tag-start regions last-tag-end) + (catch 'done + (save-excursion + (goto-char begin) + (while t + + (when (not (search-forward rhtml-erb-open-delim end t)) + ;; no more erb tags + (push (list 'other (or last-tag-end begin) end) + regions) + (throw 'done regions)) + (setq tag-start (- (point) 2)) + + (when (not (search-forward rhtml-erb-close-delim end t)) + (throw 'done regions)) + ;; other section + ;; PST -- may catch partial start tag + (when (> (point) (or last-tag-end begin)) + (push (list 'other begin (point)) + regions)) + (setq last-tag-end (point)) + + ;; erb tag + (push (list + (case (char-after (+ tag-start 2)) + (?= 'out) (?# 'comment) (t 'exec)) + tag-start (point)) + regions)))))) + +(defun rhtml-union-region-containing-erb-tags (r-start r-end) + "Returns (START . END) for a region which is an aggregate of +the region defined by R-START, R-END and any ERB tags which +start, stop, or are contained in the region." + (let* ((unopened-tag (rhtml-erb-tag-region r-start)) + (unclosed-tag (rhtml-erb-tag-region r-end)) + (new-start (or (and unopened-tag (car unopened-tag)) r-start)) + (new-end (or (and unclosed-tag (cdr unclosed-tag)) r-end))) + (cons new-start new-end))) + +(defun rhtml-widen-to-erb-tag () + "Widens the buffer to the ERB tag. +If no ERB tag is found the buffer will be reset to pre-state. +The point is advanced to the beginning of the new region (even if no ERB found)." + (let ((r-start (point-min)) + (r-end (point-max))) + (widen) + (let ((region (rhtml-erb-tag-region))) + (when region + (setq r-start (car region)) + (setq r-end (cdr region))) + (narrow-to-region r-start r-end) + (goto-char (point-min))))) + +(defun rhtml-region-has-erb-tag-p (start end) + "Returns non-nil if the region bounded by START and END +contains an ERB tag." + (save-excursion + (goto-char start) + (re-search-forward rhtml-erb-tag-re end t))) + + +;; utility functions + +(defun skip-whitespace-forward () + "Skip forward common ([ \t\r\n]) whitespace." + (skip-chars-forward " \t\r\n")) + +;; +(provide 'rhtml-erb) \ No newline at end of file diff --git a/conf/emacs.d/rhtml/rhtml-fonts.el b/conf/emacs.d/rhtml/rhtml-fonts.el new file mode 100644 index 0000000..59cc7e6 --- /dev/null +++ b/conf/emacs.d/rhtml/rhtml-fonts.el @@ -0,0 +1,177 @@ +;;; +;;; rhtml-fonts.el - font-lock-based fontification support for `rhtml-mode' +;;; + +;; This file is not part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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. + + +;; 2007 MAR 22 - Rewrote to work with jit-lock-mode, cleanup +;; 2007 MAR 28 - PST: changed to GPL license from MPL (using font-lock code) + + +(defvar rhtml-in-erb-keywords + '(;("\\([A-Z][0-9a-zA-Z_]*\\)" . (1 font-lock-type-face prepend)) + ("[^_]\\<\\(alias\\|and\\|begin\\|break\\|case\\|catch\\|class\\|def\\|do\\|elsif\\|else\\|fail\\|ensure\\|for\\|end\\|if\\|in\\|module\\|next\\|not\\|or\\|raise\\|redo\\|rescue\\|retry\\|return\\|then\\|throw\\|super\\|unless\\|undef\\|until\\|when\\|while\\|yield\\|render\\)\\>[^_]" . + (1 font-lock-keyword-face prepend)) + ("\\(@[0-9a-zA-Z_]*\\)" . (1 font-lock-variable-name-face prepend)) + ("\\(:[0-9a-zA-Z_]*\\)" . (1 font-lock-constant-face prepend)))) + +(defvar rhtml-font-lock-syntactic-keywords + '(("\\(<\\)!--" (1 "< b")) + ("--[ \t\n]*\\(>\\)" (1 "> b")) + ("\\(<\\)%" (1 "<")) + ("%\\(>\\)" (1 ">")) + "Override `sgml-mode' syntactic keywords to support ERb tags.")) + +(defun rhtml-activate-fontification () + "Activate font-lock fontification support for the current buffer." + ;; PST: note `jit-lock-mode' seems to play okay with + ;; `font-lock-mode' (but I'm still fighting with `font-lock-mode') + + (font-lock-mode t) + (jit-lock-mode t) + + ;; PST -- ERb regions are treated syntactically as comments but have + ;; their `face' text property cleared and are overwritten. + (set (make-local-variable 'font-lock-syntactic-keywords) + 'rhtml-font-lock-syntactic-keywords) + + (add-hook 'jit-lock-functions 'rhtml-fontify-region t t)) + +(defun rhtml-fontify-buffer () + (interactive) + (jit-lock-refontify)) + +(defun rhtml-fontify-erb-block (type begin end) + (let ((delim-face (cdr (assoc type erb-type-to-delim-face))) + (body-face (cdr (assoc type erb-type-to-face))) + (open-start begin) + (open-end (+ begin (if (eq type 'exec) 2 3))) + (close-start (- end 2)) + (close-end end)) + ;; apply edging and base + (font-lock-append-text-property open-start open-end 'face delim-face) + (when body-face + (font-lock-append-text-property open-end close-start 'face body-face)) + (font-lock-append-text-property close-start close-end 'face delim-face) + ;; apply normal ERb fontification + (when (not (eq type 'comment)) + (let ((font-lock-keywords rhtml-in-erb-keywords) + (case-fold-search nil)) + (font-lock-fontify-keywords-region open-end close-start))))) + +(defun rhtml-font-unfontify-region (beg end) + "Taken from ``font-lock.el''. Similar to +`font-lock-default-unfontify-region' but does not clear syntactical +information. This is useful to keep syntactical state without the +colorization." + (remove-list-of-text-properties + beg end (append + font-lock-extra-managed-props + '(face font-lock-multiline)))) + +(defun rhtml-fontify-region (begin end) + ;; PST -- hack to greedily grab more ERb tags to update (ensures + ;; that the current ERb tag is updated entirely) + (save-excursion + (goto-char begin) + (search-backward rhtml-erb-open-delim nil t) + (setq begin (point)) + (goto-char end) + (search-forward rhtml-erb-close-delim nil t) + (setq end (point))) + ;; fontify ERb tags -- fontification has already been applied by + ;; font-lock-mode for sgml-mode so we need to clear faces (but not + ;; syntactical information) + (mapc (lambda (i) + (rhtml-font-unfontify-region (nth 1 i) (nth 2 i)) + (apply 'rhtml-fontify-erb-block i)) + (rhtml-erb-regions begin end))) + + +;; ERB faces - each type of ERB tag has it's own face properties + +(defface erb-face + '((((class color) (min-colors 88) (background dark)) + :background "#383838") + (((class color) (min-colors 88) (background light)) + ;; :background "azure") + :background "snow2") + (((class color) (min-colors 16) (background dark)) + :background "blue3") + (((class color) (min-colors 16) (background light)) + :background "azure") + (((class color) (min-colors 8)) + :background "blue") + (((type tty) (class mono)) + :inverse-video t) + (t :background "gray")) + "Default inherited face for ERB tag body" + :group 'rhtml-faces) + +(defface erb-delim-face + '((t (:inherit font-lock-preprocessor-face :bold t :italic t))) + "Default inherited face for ERB tag delimeters" + :group 'rhtml-faces) + +(defface erb-exec-face + `((t (:inherit erb-face))) + "Basic face for Ruby embedded into HTML" + :group 'rhtml-faces) + +(defface erb-exec-delim-face + `((t (:inherit erb-delim-face :weight bold))) + "Basic face for Ruby embedded into HTML" + :group 'rhtml-faces) + +(defface erb-out-face + `((t (:inherit erb-face))) + "Basic face for Ruby embedded into HTML" + :group 'rhtml-faces) + +(defface erb-out-delim-face + `((((background dark)) :foreground "#aaffff" :background "#383838") + (t (:inherit erb-delim-face :weight bold :foreground "darkred"))) + "Basic face for Ruby embedded into HTML" + :group 'rhtml-faces) + +(defface erb-comment-face + `((((background dark)) :foreground "lightgreen") + (t (:inherit erb-face :weight bold :foreground "darkgreen"))) + "Basic face for Ruby embedded into HTML" + :group 'rhtml-faces) + +(defface erb-comment-delim-face + `((((background dark)) :foreground "lightgreen") + (t (:inherit erb-delim-face :weight bold :foreground "darkgreen"))) + "Basic face for Ruby embedded into HTML" + :group 'rhtml-faces) + + +(defvar erb-type-to-face + '((exec . erb-exec-face) + (out . erb-out-face) + (comment . erb-comment-face))) + +(defvar erb-type-to-delim-face + '((exec . erb-exec-delim-face) + (out . erb-out-delim-face) + (comment . erb-comment-delim-face))) + +;; +(provide 'rhtml-fonts) \ No newline at end of file diff --git a/conf/emacs.d/rhtml/rhtml-mode.el b/conf/emacs.d/rhtml/rhtml-mode.el new file mode 100644 index 0000000..a36ef9e --- /dev/null +++ b/conf/emacs.d/rhtml/rhtml-mode.el @@ -0,0 +1,107 @@ +;;; rhtml-mode.el --- major mode for editing RHTML files + +;; ***** BEGIN LICENSE BLOCK ***** +;; Version: MPL 1.1/GPL 2.0/LGPL 2.1 + +;; The contents of this file are subject to the Mozilla Public License Version +;; 1.1 (the "License"); you may not use this file except in compliance with +;; the License. You may obtain a copy of the License at +;; http://www.mozilla.org/MPL/ + +;; Software distributed under the License is distributed on an "AS IS" basis, +;; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +;; for the specific language governing rights and limitations under the +;; License. + +;; The Original Code is RHTML-MODE. + +;; The Initial Developer of the Original Code is +;; Paul Nathan Stickney . +;; Portions created by the Initial Developer are Copyright (C) 2006 +;; the Initial Developer. All Rights Reserved. + +;; Contributor(s): +;; Phil Hagelberg + +;; Alternatively, the contents of this file may be used under the terms of +;; either the GNU General Public License Version 2 or later (the "GPL"), or +;; the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +;; in which case the provisions of the GPL or the LGPL are applicable instead +;; of those above. If you wish to allow use of your version of this file only +;; under the terms of either the GPL or the LGPL, and not to allow others to +;; use your version of this file under the terms of the MPL, indicate your +;; decision by deleting the provisions above and replace them with the notice +;; and other provisions required by the GPL or the LGPL. If you do not delete +;; the provisions above, a recipient may use your version of this file under +;; the terms of any one of the MPL, the GPL or the LGPL. + +;; ***** END LICENSE BLOCK ***** + + +(require 'rhtml-fonts) ;; basic fontification + +;; don't require if you don't want it... +(require 'rhtml-sgml-hacks) ;; indent erb with sgml + +;;;###autoload +(define-derived-mode rhtml-mode + html-mode "RHTML" + "Embedded Ruby Mode (RHTML)" + (interactive) + (abbrev-mode) + ;; disable if you don't want it... + (rhtml-activate-fontification)) + +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.html\\.erb$" . rhtml-mode)) + +(define-key ruby-mode-map + "\C-c\C-v" (lambda () (interactive) (toggle-buffer 'rails-view))) +(define-key rhtml-mode-map + "\C-c\C-b" 'rinari-find-by-context) + +(defun extract-partial (begin end partial-name) + (interactive "r\nsName your partial: ") + (kill-region begin end) + (find-file (concat "_" partial-name "\\.html\\.erb")) + (yank) + (pop-to-buffer nil) + (insert (concat "<%= render :partial => '" partial-name "' %>\n"))) + +;; PST -- uses rhtml-erb-regions which is defined in rhtml-font which +;; should be moved. +(defun rhtml-dashize (&optional mode) + "Add or remove dashes from the end of ERb blocks. The dash tells ERb to +strip the following newline. This function will NOT add or remove dashes +from blocks that end in a # or #- sequence. + +MODE controls how dashes are added or removed. If MODE is `strip' then all +ERb blocks will have the dash removed. If MODE is `add' then all blocks +will have a dash added. If MODE is `auto' or nil then ERb blocks which are +followed by a newline will have a dash added while all other blocks will +have the dash removed." + (interactive "cDashize mode: s) strip, a) add, x) auto (default)") + (let ((real-mode (case mode + ((?s strip) 'strip) + ((?a add) 'add)))) + (mapc (lambda (i) + (let ((end (nth 2 i))) + (save-excursion + (goto-char (- end 2)) + (case (or real-mode + (if (eq (char-after end) ?\n) + 'add + 'strip)) + (strip + (when (and (eq (char-before) ?-) + (not (eq (char-before (1- (point))) ?#))) + (delete-backward-char 1))) + (add + (unless (memq (char-before) '(?# ?-)) + (insert "-"))))))) + ;; seq. + (rhtml-erb-regions (point-min) (point-max))))) + + +(require 'rhtml-navigation) +(provide 'rhtml-mode) diff --git a/conf/emacs.d/rhtml/rhtml-navigation.el b/conf/emacs.d/rhtml/rhtml-navigation.el new file mode 100644 index 0000000..55d4440 --- /dev/null +++ b/conf/emacs.d/rhtml/rhtml-navigation.el @@ -0,0 +1,63 @@ +;; TODO -- need a license boiler-plate + +;; Handy RHTML functions +;; (C) 2006 Phil Hagelberg + +;; Ripped from the previous rhtml-mode, sorry about making it break +;; too :( -- pst +(defun rails-root (file-path) + "Guess the project root of the given FILE-PATH." + (or (vc-git-root file-path) + (vc-svn-root file-path) + file-path)) + +(defun rhtml-controller-name-from-view () + (let* ((dirname (expand-file-name ".")) + (controller-with-module + (and (string-match "app/views/\\(.*\\)$" dirname) + (match-string 1 dirname)))) + (concat (rails-root (expand-file-name ".")) + "/app/controllers/" + controller-with-module + "_controller.rb"))) + +(defun rhtml-find-action () + (interactive) + (let ((action (file-name-sans-extension (file-name-nondirectory buffer-file-name)))) + (find-file (rhtml-controller-name-from-view)) + (beginning-of-buffer) + (search-forward-regexp (concat "def *" action)) + (recenter))) + +(defun rinari-find-by-context () + (interactive) + (mapc (lambda (rule) (let ((pattern (car rule)) (line (current-line))) + (if (string-match pattern line) (apply (cdr rule) (match-strings line))))) + ;; rules (warning; ALL matches will be acted upon, not just first!) + '((":partial +=> +['\":]\\([a-zA-Z_]+\\)['\" ]" . rhtml-find-partial) + (":controller +=> +['\":]\\([a-zA-Z_]+\\)['\" ,]?.*:action +=> +['\":]\\([a-zA-Z_]+\\)['\" ,]?" + . rinari-find-action) + (":action +=> +['\":]\\([a-zA-Z_]+\\)['\"]?" . rinari-find-action) + ) + )) + +(defun rhtml-find-partial (partial) + (interactive "MPartial: ") + (find-file (concat "_" partial "\\.html\\.erb"))) + +;; utility functions + +(defun current-line () + (save-excursion + (beginning-of-line) + (set-mark-command nil) + (end-of-line) + (buffer-substring-no-properties (mark) (point)))) + +(defun match-strings (string &optional n) + (let* ((n (or n 1)) + (this-match (match-string n string))) + (when this-match + (append (list this-match) (match-strings string (+ 1 n)))))) + +(provide 'rhtml-navigation) diff --git a/conf/emacs.d/rhtml/rhtml-ruby-hook.el b/conf/emacs.d/rhtml/rhtml-ruby-hook.el new file mode 100644 index 0000000..3c00cf4 --- /dev/null +++ b/conf/emacs.d/rhtml/rhtml-ruby-hook.el @@ -0,0 +1,93 @@ +;;; +;;; rhtml-ruby-hook.el - `ruby-mode' access for `rhtml-mode' +;;; + +;; ***** BEGIN LICENSE BLOCK ***** +;; Version: MPL 1.1/GPL 2.0/LGPL 2.1 + +;; The contents of this file are subject to the Mozilla Public License Version +;; 1.1 (the "License"); you may not use this file except in compliance with +;; the License. You may obtain a copy of the License at +;; http://www.mozilla.org/MPL/ + +;; Software distributed under the License is distributed on an "AS IS" basis, +;; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +;; for the specific language governing rights and limitations under the +;; License. + +;; The Original Code is RUBY-MODE Hook Support for RHTML-MODE. + +;; The Initial Developer of the Original Code is +;; Paul Nathan Stickney . +;; Portions created by the Initial Developer are Copyright (C) 2006 +;; the Initial Developer. All Rights Reserved. + +;; Contributor(s): + +;; Alternatively, the contents of this file may be used under the terms of +;; either the GNU General Public License Version 2 or later (the "GPL"), or +;; the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +;; in which case the provisions of the GPL or the LGPL are applicable instead +;; of those above. If you wish to allow use of your version of this file only +;; under the terms of either the GPL or the LGPL, and not to allow others to +;; use your version of this file under the terms of the MPL, indicate your +;; decision by deleting the provisions above and replace them with the notice +;; and other provisions required by the GPL or the LGPL. If you do not delete +;; the provisions above, a recipient may use your version of this file under +;; the terms of any one of the MPL, the GPL or the LGPL. + +;; ***** END LICENSE BLOCK ***** + + +;;; +;;; Provide an API to 'hook' into Ruby-mode, or rather, provide access +;;; to a temporary `ruby-mode' buffer which can be used to apply +;;; various ruby-mode stuff, primarily indenting. +;;; + +;;; History: + +;; 2006SEP18 +;; - initial implementation + +(require 'rhtml-erb) +(require 'ruby-mode) ; for well, `ruby-mode' + +(defvar rhtml-ruby-temp-buffer-name + "*rhtml-ruby-hook temp buffer*" + "Buffer name to use for temporary Ruby buffer. Should begin with a * or + space as those carry special meaning.") + +(defun rhtml-ruby-temp-buffer () + "Returns the temporary ruby buffer creating it if needed." + (or (get-buffer rhtml-ruby-temp-buffer-name) + (let ((ruby-buffer (get-buffer-create rhtml-ruby-temp-buffer-name))) + (with-current-buffer ruby-buffer + (buffer-disable-undo) + (ruby-mode)) + ruby-buffer))) + +(defun rhtml-copy-to-ruby-temp (begin end) + "Buffer to copy from should be selected. BEGIN and END are points in the +current buffer. All existing text in the temporary buffer is replaced." + (let ((source-buffer (current-buffer)) + (temp-buffer (rhtml-ruby-temp-buffer))) + (with-current-buffer temp-buffer + (delete-region (point-min) (point-max)) + (insert-buffer-substring source-buffer begin end)))) + +(defun rhtml-ruby-indent-at (indent-pos) + "Returns the indentation for INDENT-POS inside the temporary Ruby buffer +after updating the indenting." + (with-current-buffer (rhtml-ruby-temp-buffer) + (indent-region 0 indent-pos) ; force update + (goto-char indent-pos) + (ruby-calculate-indent))) + +(defun rthml-insert-from-ruby-temp () + "Insert the contents of `rhtml-ruby-temp-buffer' into the current +buffer." + (insert-from-buffer (rhtml-ruby-temp-buffer))) + + +(provide 'rhtml-ruby-hook) \ No newline at end of file diff --git a/conf/emacs.d/rhtml/rhtml-sgml-hacks.el b/conf/emacs.d/rhtml/rhtml-sgml-hacks.el new file mode 100644 index 0000000..77a63a4 --- /dev/null +++ b/conf/emacs.d/rhtml/rhtml-sgml-hacks.el @@ -0,0 +1,522 @@ +;;; +;;; rhtml-sgml-hacks.el --- add ERB contextual indenting support to sgml-mode +;;; + +;;; Initial Developer: Paul Stickney , 2006 + +;; 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 of +;; the License, 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; if not, write to the Free +;; Software Foundation, 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + + +;;; README + +;; +;; Hacks to sgml-mode *against* Emacs 22.0.5 (2006/09/01 build) +;; - diff'ing and editing for your version may be required! +;; Changes to original code marked with ``PST''. +;; +;; Note: `sgml-mode' indenting in Emacs 21 seems very broken. +;; Please use sgml-mode.el from Emacs 22. +;; +;; Hints to use Emacs 22 sgml-mode with Emacs 21: +;; 1) Replace all occurances of "?\s" with "?\ ". I have no idea what +;; ?\s is supposed to mean (super?) but this lets it eval in Emacs 21. +;; 2) Comment the line containing 'defvaralias'. No reference seems to +;; be made to the alias anyway. +;; 3) Make sure sgml-mode.el is in load-path before stock version and restart +;; emacs. You will have problems if the old `sgml-mode' is +;; loaded first. +;; + +;;; History + +;; 2006SEP12 +;; - Created +;; 2006SEP14 +;; - enable/disable hacks use setf so they no longer require feature reloading +;; 2006SEP15 +;; - Revert back to old style unloading +;; 2006SEP19 +;; - Ruby code inside ERB blocks is now indented. See `rhtml-ruby-hook'. +;; 2006SEP22 +;; - < inside ERB tags correctly ignored. + +(eval-when-compile + (require 'cl)) + +(require 'rhtml-erb) +(require 'sgml-mode) ; Force load here, make sure our functions will munge in. +(require 'rhtml-ruby-hook) ; For sub-indenting + + +;; Crude method of hack control +;; TODO replace, see below +;; +(defun rhtml-disable-sgml-hacks () + "Try to return `sgml-mode' to its normal state." + (rhtml-remove-feature 'rhtml-sgml-hacks) + (rhtml-reload-feature 'sgml-mode)) + +(defun rhtml-enable-sgml-hacks () + "Reload `sgml-mode' hacks. Might be useful after +`rhtml-disable-sgml-hacks'." + (rhtml-reload-feature 'sgml-mode) + (rhtml-reload-feature 'rhtml-sgml-hacks)) + +(defun rhtml-remove-feature (feature) + (setq features (delq feature features))) +(defun rhtml-reload-feature (feature) + (rhtml-remove-feature feature) + (require feature)) + + +;;; Failed attempt at non feature-realoding +;;; (What is wrong?) +;; Save original functions +;; +;; (defconst rhtml-dirty-functions +;; '(sgml-get-context +;; sgml-calculate-indent +;; sgml-lexical-context +;; sgml-beginning-of-tag +;; sgml-parse-tag-backward) +;; "Functions to back up.") +;; (setq rhtml-hacks-backed-up nil) +;; (defconst rhtml-sgml-backup-prop 'rhtml-sgml-definition) +;; (defconst rhtml-hack-backup-prop 'rhtml-hack-definition) + +;; (defun rhtml-backup-functions (prop) +;; (dolist (fn rhtml-dirty-functions) +;; (put fn prop (symbol-function fn)))) + +;; (defun rhtml-restore-functions (prop) +;; (dolist (fn rhtml-dirty-functions) +;; (setf fn (get fn prop)))) + +;; ;; Backup sgml-mode functions so we can restore them later +;; (rhtml-backup-functions rhtml-sgml-backup-prop) + +;; (defun rhtml-disable-sgml-hacks () +;; "Restore normal functions." +;; ;; Backup rhtml-sgml-hacks functions if not done yet. +;; ;; Without (correctly) doing so we will accidently mix definitions! +;; (unless rhtml-hacks-backed-up +;; (rhtml-backup-functions rhtml-hack-backup-prop) +;; (setq rhtml-hacks-backed-up t)) +;; (rhtml-restore-functions rhtml-sgml-backup-prop)) + +;; (defun rhtml-enable-sgml-hacks () +;; "Restore hacked functions." +;; (rhtml-restore-functions rhtml-hack-backup-prop)) + + + +;; PST - handling of `erb-*' +(defun sgml-get-context (&optional until) + "Determine the context of the current position. +By default, parse until we find a start-tag as the first thing on a line. +If UNTIL is `empty', return even if the context is empty (i.e. +we just skipped over some element and got to a beginning of line). + +The context is a list of tag-info structures. The last one is the tag +immediately enclosing the current position. + +Point is assumed to be outside of any tag. If we discover that it's +not the case, the first tag returned is the one inside which we are." + (let ((here (point)) + (stack nil) + (ignore nil) + (context nil) + tag-info) + ;; CONTEXT keeps track of the tag-stack + ;; STACK keeps track of the end tags we've seen (and thus the start-tags + ;; we'll have to ignore) when skipping over matching open..close pairs. + ;; IGNORE is a list of tags that can be ignored because they have been + ;; closed implicitly. + (skip-chars-backward " \t\n") ; Make sure we're not at indentation. + (while + (and (not (eq until 'now)) + (or stack + (not (if until (eq until 'empty) context)) + (not (sgml-at-indentation-p)) + (and context + (/= (point) (sgml-tag-start (car context))) + (sgml-unclosed-tag-p (sgml-tag-name (car context))))) + (setq tag-info (ignore-errors (sgml-parse-tag-backward)))) + + ;; This tag may enclose things we thought were tags. If so, + ;; discard them. + (while (and context + (> (sgml-tag-end tag-info) + (sgml-tag-end (car context)))) + (setq context (cdr context))) + + (cond + ((> (sgml-tag-end tag-info) here) + ;; Oops!! Looks like we were not outside of any tag, after all. + (push tag-info context) + (setq until 'now)) + + ;; start-tag + ((memq (sgml-tag-type tag-info) '(open erb-open)) ;; PST + (cond + ((null stack) + (if (member-ignore-case (sgml-tag-name tag-info) ignore) + ;; There was an implicit end-tag. + nil + (push tag-info context) + ;; We're changing context so the tags implicitly closed inside + ;; the previous context aren't implicitly closed here any more. + ;; [ Well, actually it depends, but we don't have the info about + ;; when it doesn't and when it does. --Stef ] + (setq ignore nil))) + ((eq t (compare-strings (sgml-tag-name tag-info) nil nil + (car stack) nil nil t)) + (setq stack (cdr stack))) + ;; PST - "erb-block" closes both "erb-block" and "erb-multi-block" + ((and (member (sgml-tag-name tag-info) '("erb-block" "erb-multi-block")) + (string= (car stack) '"erb-block")) + (setq stack (cdr stack))) + ;; /PST + (t + ;; The open and close tags don't match. + (if (not sgml-xml-mode) + (unless (sgml-unclosed-tag-p (sgml-tag-name tag-info)) + (message "Unclosed tag <%s>" (sgml-tag-name tag-info)) + (let ((tmp stack)) + ;; We could just assume that the tag is simply not closed + ;; but it's a bad assumption when tags *are* closed but + ;; not properly nested. + (while (and (cdr tmp) + (not (eq t (compare-strings + (sgml-tag-name tag-info) nil nil + (cadr tmp) nil nil t)))) + (setq tmp (cdr tmp))) + (if (cdr tmp) (setcdr tmp (cddr tmp))))) + (message "Unmatched tags <%s> and " + (sgml-tag-name tag-info) (pop stack))))) + + (if (and (null stack) (sgml-unclosed-tag-p (sgml-tag-name tag-info))) + ;; This is a top-level open of an implicitly closed tag, so any + ;; occurrence of such an open tag at the same level can be ignored + ;; because it's been implicitly closed. + (push (sgml-tag-name tag-info) ignore))) + + ;; end-tag + ((memq (sgml-tag-type tag-info) '(close erb-close)) ;; PST + (if (sgml-empty-tag-p (sgml-tag-name tag-info)) + (message "Spurious : empty tag" (sgml-tag-name tag-info)) + (push (sgml-tag-name tag-info) stack))) + )) + + ;; return context + context)) + + + +;; PST - added calulations for ERB tags +;; *** Bug when point at end? +(defun sgml-calculate-indent (&optional lcon) + "Calculate the column to which this line should be indented. +LCON is the lexical context, if any." + (unless lcon (setq lcon (sgml-lexical-context))) + + ;; Indent comment-start markers inside