[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master 955038c 302/433: Merge remote-tracking branch 'refs/remote
From: |
Dmitry Gutov |
Subject: |
[elpa] master 955038c 302/433: Merge remote-tracking branch 'refs/remotes/dgutov/erb' |
Date: |
Thu, 15 Mar 2018 19:44:24 -0400 (EDT) |
branch: master
commit 955038cf74fad90ca005518a8f4e7b77996f50fe
Merge: 38439a4 2ca7e6a
Author: Steve Purcell <address@hidden>
Commit: Steve Purcell <address@hidden>
Merge remote-tracking branch 'refs/remotes/dgutov/erb'
---
mmm-erb.el | 225 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 225 insertions(+)
diff --git a/mmm-erb.el b/mmm-erb.el
new file mode 100644
index 0000000..2a06315
--- /dev/null
+++ b/mmm-erb.el
@@ -0,0 +1,225 @@
+;;; mmm-erb.el --- ERB templates editing support
+
+;; Copyright (C) 2012 by Dmitry Gutov
+
+;; Author: Dmitry Gutov <address@hidden>
+
+;;{{{ GPL
+
+;; 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., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file contains the definition of JavaScript, CSS, ERB and EJS submode
+;; classes, and well as support functions for proper indentation.
+
+;; Usage:
+
+;; (require 'mmm-auto)
+;; (mmm-add-mode-ext-class 'html-erb-mode "\\.html\\(\\.erb\\)?\\'" 'html-js)
+;; (mmm-add-mode-ext-class 'html-erb-mode "\\.html\\(\\.erb\\)?\\'" 'html-css)
+;; (mmm-add-mode-ext-class 'html-erb-mode "\\.html\\.erb\\'" 'erb)
+;; (mmm-add-mode-ext-class 'html-erb-mode "\\.jst\\.ejs\\'" 'ejs)
+
+;; (add-to-list 'auto-mode-alist '("\\.html\\.erb\\'" . html-erb-mode))
+;; (add-to-list 'auto-mode-alist '("\\.jst\\.ejs\\'" . html-erb-mode))
+
+;;; Code:
+
+(require 'sgml-mode)
+(eval-when-compile (require 'cl))
+(require 'mmm-vars)
+
+(mmm-add-group
+ 'html-js
+ '((js-script-cdata
+ :submode js-mode
+ :face mmm-code-submode-face
+ :front "<script[^>]*>[ \t\n]*\\(//\\)?<!\\[CDATA\\[[ \t]*\n?"
+ :back "[ \t]*\\(//\\)?]]>[ \t\n]*</script>")
+ (js-script
+ :submode js-mode
+ :face mmm-code-submode-face
+ :front "<script[^>]*>[ \t]*\n?"
+ :back "[ \t]*</script>"
+ :insert ((?j js-tag nil @ "<script type=\"text/javascript\">\n"
+ @ "" _ "" @ "\n</script>" @)))))
+
+(mmm-add-group
+ 'html-css
+ '((css-cdata
+ :submode css-mode
+ :face mmm-code-submode-face
+ :front "<style[^>]*>[ \t\n]*\\(//\\)?<!\\[CDATA\\[[ \t]*\n?"
+ :back "[ \t]*\\(//\\)?]]>[ \t\n]*</style>")
+ (css
+ :submode css-mode
+ :face mmm-code-submode-face
+ :front "<style[^>]*>[ \t]*\n?"
+ :back "[ \t]*</style>"
+ :insert ((?c css-tag nil @ "<style type=\"text/css\">\n"
+ @ "" _ "" @ "\n</style>" @)))))
+
+(mmm-add-classes
+ '((erb :submode ruby-mode :front "<%[#=]?" :back "-?%>"
+ :match-face (("<%#" . mmm-comment-submode-face)
+ ("<%=" . mmm-output-submode-face)
+ ("<%" . mmm-code-submode-face))
+ :insert ((?% erb-code nil @ "<%" @ " " _ " " @ "%>" @)
+ (?# erb-comment nil @ "<%#" @ " " _ " " @ "%>" @)
+ (?= erb-expression nil @ "<%=" @ " " _ " " @ "%>" @)))
+ (ejs :submode js-mode :front "<%[#=]?" :back "-?%>"
+ :match-face (("<%#" . mmm-comment-submode-face)
+ ("<%=" . mmm-output-submode-face)
+ ("<%" . mmm-code-submode-face))
+ :insert ((?% ejs-code nil @ "<%" @ " " _ " " @ "%>" @)
+ (?# ejs-comment nil @ "<%#" @ " " _ " " @ "%>" @)
+ (?= ejs-expression nil @ "<%=" @ " " _ " " @ "%>" @)))))
+
+(pushnew '(indent-line-function buffer) mmm-save-local-variables)
+
+;;;###autoload
+(define-derived-mode html-erb-mode html-mode "ERB-HTML"
+ (setq sgml-unclosed-tags nil) ; Simplifies indentation logic.
+ (add-hook 'mmm-html-erb-mode-hook 'mmm-erb-process-submode nil t)
+ (add-hook 'mmm-ruby-mode-submode-hook 'mmm-erb-process-submode nil t)
+ (add-hook 'mmm-css-mode-submode-hook 'mmm-erb-process-submode nil t)
+ (add-hook 'mmm-js-mode-submode-hook 'mmm-erb-process-submode nil t))
+
+(defun mmm-erb-process-submode ()
+ (setq indent-line-function 'mmm-erb-indent-line))
+
+(defun mmm-erb-indent-line ()
+ (interactive)
+ (let ((offset (- (current-column) (current-indentation))))
+ (back-to-indentation)
+ (mmm-update-submode-region)
+ (if (and mmm-current-overlay mmm-current-submode
+ (< (overlay-start mmm-current-overlay) (point-at-bol)))
+ ;; Region starts before the current line (and contains indentation).
+ (mmm-erb-indent-line-submode)
+ (mmm-erb-indent-line-primary))
+ (when (> offset 0) (forward-char offset))))
+
+(defun mmm-erb-indent-line-submode ()
+ (let (added-whitespace)
+ (if (<= (overlay-end mmm-current-overlay)
+ (save-excursion (back-to-indentation) (point)))
+ ;; We're at a closing tag.
+ (mmm-erb-indent-to-region-start)
+ (save-restriction
+ (save-excursion
+ (goto-char (overlay-start mmm-current-overlay))
+ (when (not (looking-at "^\\|\\s-*$"))
+ ;; Submode region has text on the same line as the opening tag,
+ ;; pad it with whitespace to make the following lines line up.
+ (setq added-whitespace (current-column))
+ (insert-char ?\s added-whitespace)))
+ (narrow-to-region (overlay-start mmm-current-overlay)
+ (overlay-end mmm-current-overlay))
+ (funcall (mmm-erb-orig-indent-function mmm-current-submode))
+ (when added-whitespace
+ ;; Remove the padding.
+ (save-excursion
+ (goto-char (overlay-start mmm-current-overlay))
+ (delete-char added-whitespace))))
+ ;; If submode indent function moved us to bol,
+ ;; we're on the top level, indent according to the primary mode.
+ (when (zerop (current-indentation))
+ (mmm-erb-indent-to-region-start
+ (mmm-erb-indent-offset mmm-primary-mode))))))
+
+(defun mmm-erb-indent-to-region-start (&optional additional-offset)
+ (let ((indent (current-indentation)))
+ (indent-line-to
+ (save-excursion
+ (goto-char (1- (overlay-start mmm-current-overlay)))
+ (+ (current-indentation)
+ (or additional-offset 0))))))
+
+(defun mmm-erb-indent-line-primary ()
+ (let* ((here (point))
+ ;; Go before previous line's tag.
+ (start (progn (forward-line -1)
+ (back-to-indentation)
+ (let ((lcon (sgml-lexical-context)))
+ (when (eq (car lcon) 'tag)
+ ;; Tag spreads several lines.
+ (goto-char (cdr lcon))
+ (back-to-indentation)))
+ (point)))
+ (regions (mmm-regions-in start here))
+ (n 0))
+ ;; Collect indent modifier depending on type of tags.
+ (loop for region in regions
+ for type = (mmm-erb-scan-region region)
+ when type do
+ (if (eq type 'close)
+ (when (plusp n) (decf n))
+ (incf n (if (eq type 'close) 0 1))))
+ (let ((eol (progn (goto-char here) (end-of-line 1) (point))))
+ ;; Look for "else" and "end" instructions to adjust modifier.
+ ;; If a block start instruction comes first, abort.
+ (loop for region in (mmm-regions-in here eol)
+ for type = (mmm-erb-scan-region region)
+ until (eq type 'open)
+ when (memq type '(middle close)) do (decf n)))
+ (goto-char here)
+ (funcall (mmm-erb-orig-indent-function mmm-primary-mode))
+ (let* ((indent (current-indentation))
+ (indent-step (mmm-erb-indent-offset mmm-primary-mode)))
+ (indent-line-to (+ indent (if n (* indent-step n) 0))))))
+
+(defun mmm-erb-scan-region (region)
+ (when region ; Can be nil if a line is empty, for example.
+ (destructuring-bind (submode beg end) region
+ (let ((scan-fn (plist-get '(ruby-mode mmm-erb-scan-erb
+ js-mode mmm-erb-scan-ejs)
+ submode)))
+ (when scan-fn
+ (save-excursion
+ (goto-char beg)
+ (skip-syntax-forward "-")
+ (funcall scan-fn end)))))))
+
+(defun mmm-erb-scan-erb (limit)
+ (cond ((looking-at "\\(?:if\\|unless\\|for\\|while\\)\\b") 'open)
+ ((looking-at "\\(?:else\\|elsif\\)\\b") 'middle)
+ ((looking-at "end\\b\\|}") 'close)
+ ((re-search-forward (concat "\\(?: +do +\\| *{ *\\)"
+ "\\(?:|[A-Za-z0-9_, ]*|\\)? *") limit t)
+ 'open)))
+
+(defun mmm-erb-scan-ejs (limit)
+ (cond ((looking-at "\\(?:if\\|for\\|while\\)\\b") 'open)
+ ((looking-at "} *else\\b") 'middle)
+ ((looking-at "}") 'close)
+ ((re-search-forward " *{ *" limit t) 'open)))
+
+(defun mmm-erb-orig-indent-function (mode)
+ (cadr (assoc 'indent-line-function (get mode 'mmm-local-variables))))
+
+(defvar mmm-erb-offset-var-alist
+ '((html-erb-mode . sgml-basic-offset)
+ (nxml-mode . nxml-child-indent)))
+
+(defun mmm-erb-indent-offset (mode)
+ (let ((name (cdr (assoc mode mmm-erb-offset-var-alist))))
+ (when name (symbol-value name))))
+
+(provide 'mmm-erb)
- [elpa] master 5f82799 276/433: * version.texi: Release 0.4.8., (continued)
- [elpa] master 5f82799 276/433: * version.texi: Release 0.4.8., Dmitry Gutov, 2018/03/15
- [elpa] master fe07951 277/433: * mmm-myghty.el: New mode from Ben Bangert., Dmitry Gutov, 2018/03/15
- [elpa] master a71a299 207/433: # Updated, Dmitry Gutov, 2018/03/15
- [elpa] master 9aa2af2 239/433: * mmm-class.el (mmm-match-region): Fixed return values bug, so, Dmitry Gutov, 2018/03/15
- [elpa] master a98405e 281/433: Make reference to var font-lock-defaults-alist conditional; var is obsolete in Emacs 24., Dmitry Gutov, 2018/03/15
- [elpa] master a7b8c55 296/433: Do syntax highlighting and indentation in ERB buffers, Dmitry Gutov, 2018/03/15
- [elpa] master 37f9a4b 183/433: Released 0.4.6, Dmitry Gutov, 2018/03/15
- [elpa] master 1e46c43 306/433: Fix #8, Dmitry Gutov, 2018/03/15
- [elpa] master ed0b781 310/433: Merge pull request #9 from dgutov/master, Dmitry Gutov, 2018/03/15
- [elpa] master e5fe9e7 261/433: Implemented a 'local to submode class' keymap binding, using a dummy overlay., Dmitry Gutov, 2018/03/15
- [elpa] master 955038c 302/433: Merge remote-tracking branch 'refs/remotes/dgutov/erb',
Dmitry Gutov <=
- [elpa] master 7f9dbdb 292/433: Fix `mmm-insert-region' to not abort loop too soon, Dmitry Gutov, 2018/03/15
- [elpa] master 5289a0b 318/433: Save values of more cc-mode variables, Dmitry Gutov, 2018/03/15
- [elpa] master 034df4b 339/433: Revert c548593, for easier optimization, Dmitry Gutov, 2018/03/15
- [elpa] master e10b20f 347/433: Remove the angle brackets, Dmitry Gutov, 2018/03/15
- [elpa] master 0cb75f0 299/433: Correctly restore pre-indent position, Dmitry Gutov, 2018/03/15
- [elpa] master 9674355 328/433: Merge pull request #18 from prakashk/master, Dmitry Gutov, 2018/03/15
- [elpa] master 05a787e 291/433: Fix further compilation warnings in recent Emacsen, Dmitry Gutov, 2018/03/15
- [elpa] master e269a47 305/433: Require 'mmm-region from 'mmm-erb, avoiding compilation warnings about free variable references, Dmitry Gutov, 2018/03/15
- [elpa] master 961a127 263/433: Prevent bounds from going outside buffer (XEmacs complains), Dmitry Gutov, 2018/03/15
- [elpa] master 66b47cd 218/433: Released 0.4.7, Dmitry Gutov, 2018/03/15