aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Gutov2012-04-24 11:51:14 -0400
committerStefan Monnier2012-04-24 11:51:14 -0400
commit85222d4485aaaf5b308859988ac3d06212e6bf3f (patch)
tree63d3b6bfe1b178feb247b8189ef9cd98e264094c
parent257440aa1c368048203a111db15f5a791a07f53f (diff)
downloademacs-85222d4485aaaf5b308859988ac3d06212e6bf3f.tar.gz
emacs-85222d4485aaaf5b308859988ac3d06212e6bf3f.zip
* lisp/progmodes/ruby-mode.el: Handle general delimited literals.
(ruby-syntax-general-delimiters-goto-beg) (ruby-syntax-propertize-general-delimiters): New functions. (ruby-syntax-propertize-function): Use them to handle GDL. (ruby-font-lock-keywords): Move old handling of GDL... (ruby-font-lock-syntactic-keywords): .. to here. (ruby-calculate-indent): Adjust indentation for GDL. Fixes: debbugs:6286
-rw-r--r--lisp/ChangeLog10
-rw-r--r--lisp/progmodes/ruby-mode.el52
2 files changed, 56 insertions, 6 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index b1f1ad99b23..03fbfd83255 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,13 @@
12012-04-24 Dmitry Gutov <dgutov@yandex.ru>
2
3 * progmodes/ruby-mode.el: Handle general delimited literals (bug#6286).
4 (ruby-syntax-general-delimiters-goto-beg)
5 (ruby-syntax-propertize-general-delimiters): New functions.
6 (ruby-syntax-propertize-function): Use them to handle GDL.
7 (ruby-font-lock-keywords): Move old handling of GDL...
8 (ruby-font-lock-syntactic-keywords): .. to here.
9 (ruby-calculate-indent): Adjust indentation for GDL.
10
12012-04-24 Leo Liu <sdl.web@gmail.com> 112012-04-24 Leo Liu <sdl.web@gmail.com>
2 12
3 * progmodes/python.el: Move hideshow setup to the end. 13 * progmodes/python.el: Move hideshow setup to the end.
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 66aa256f947..05a4042b67d 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -794,8 +794,8 @@ and `\\' when preceded by `?'."
794;; (not (or (eolp) (looking-at "#") 794;; (not (or (eolp) (looking-at "#")
795;; (and (eq (car (nth 1 state)) ?{) 795;; (and (eq (car (nth 1 state)) ?{)
796;; (looking-at "|")))))) 796;; (looking-at "|"))))))
797 (or (not (eq ?/ c)) 797 ;; not a regexp or general delimited literal
798 (null (nth 0 (ruby-parse-region (or begin parse-start) (point))))) 798 (null (nth 0 (ruby-parse-region (or begin parse-start) (point))))
799 (or (not (eq ?| (char-after (point)))) 799 (or (not (eq ?| (char-after (point))))
800 (save-excursion 800 (save-excursion
801 (or (eolp) (forward-char -1)) 801 (or (eolp) (forward-char -1))
@@ -1118,6 +1118,7 @@ See `add-log-current-defun-function'."
1118 "Syntactic keywords for Ruby mode. See `syntax-propertize-function'." 1118 "Syntactic keywords for Ruby mode. See `syntax-propertize-function'."
1119 (goto-char start) 1119 (goto-char start)
1120 (ruby-syntax-propertize-heredoc end) 1120 (ruby-syntax-propertize-heredoc end)
1121 (ruby-syntax-general-delimiters-goto-beg)
1121 (funcall 1122 (funcall
1122 (syntax-propertize-rules 1123 (syntax-propertize-rules
1123 ;; #{ }, #$hoge, #@foo are not comments 1124 ;; #{ }, #$hoge, #@foo are not comments
@@ -1137,7 +1138,10 @@ See `add-log-current-defun-function'."
1137 ("^\\(=\\)begin\\_>" (1 "!")) 1138 ("^\\(=\\)begin\\_>" (1 "!"))
1138 ;; Handle here documents. 1139 ;; Handle here documents.
1139 ((concat ruby-here-doc-beg-re ".*\\(\n\\)") 1140 ((concat ruby-here-doc-beg-re ".*\\(\n\\)")
1140 (7 (prog1 "\"" (ruby-syntax-propertize-heredoc end))))) 1141 (7 (prog1 "\"" (ruby-syntax-propertize-heredoc end))))
1142 ;; Handle percent literals: %w(), %q{}, etc.
1143 ("\\(?:^\\|[[ \t\n<+(,=]\\)\\(%\\)[qQrswWx]?\\([[:punct:]]\\)"
1144 (1 (prog1 "|" (ruby-syntax-propertize-general-delimiters end)))))
1141 (point) end)) 1145 (point) end))
1142 1146
1143 (defun ruby-syntax-propertize-heredoc (limit) 1147 (defun ruby-syntax-propertize-heredoc (limit)
@@ -1163,6 +1167,41 @@ See `add-log-current-defun-function'."
1163 ;; Make extra sure we don't move back, lest we could fall into an 1167 ;; Make extra sure we don't move back, lest we could fall into an
1164 ;; inf-loop. 1168 ;; inf-loop.
1165 (if (< (point) start) (goto-char start)))))) 1169 (if (< (point) start) (goto-char start))))))
1170
1171 (defun ruby-syntax-general-delimiters-goto-beg ()
1172 (let ((state (syntax-ppss)))
1173 ;; Move to the start of the literal, in case it's multiline.
1174 ;; TODO: determine the literal type more reliably here?
1175 (when (eq t (nth 3 state))
1176 (goto-char (nth 8 state))
1177 (beginning-of-line))))
1178
1179 (defun ruby-syntax-propertize-general-delimiters (limit)
1180 (goto-char (match-beginning 2))
1181 (let* ((op (char-after))
1182 (ops (char-to-string op))
1183 (cl (or (cdr (aref (syntax-table) op))
1184 (cdr (assoc op '((?< . ?>))))))
1185 parse-sexp-lookup-properties)
1186 (ignore-errors
1187 (if cl
1188 (progn ; paired delimiters
1189 ;; Delimiter pairs of the same kind can be nested
1190 ;; inside the literal, as long as they are balanced.
1191 ;; Create syntax table that ignores other characters.
1192 (with-syntax-table (make-char-table 'syntax-table nil)
1193 (modify-syntax-entry op (concat "(" (char-to-string cl)))
1194 (modify-syntax-entry cl (concat ")" ops))
1195 (modify-syntax-entry ?\\ "\\")
1196 (save-restriction
1197 (narrow-to-region (point) limit)
1198 (forward-list)))) ; skip to the paired character
1199 ;; single character delimiter
1200 (re-search-forward (concat "[^\\]\\(?:\\\\\\\\\\)*"
1201 (regexp-quote ops)) limit nil))
1202 ;; if we reached here, the closing delimiter was found
1203 (put-text-property (1- (point)) (point)
1204 'syntax-table (string-to-syntax "|")))))
1166 ) 1205 )
1167 1206
1168 ;; For Emacsen where syntax-propertize-rules is not (yet) available, 1207 ;; For Emacsen where syntax-propertize-rules is not (yet) available,
@@ -1207,6 +1246,10 @@ This should only be called after matching against `ruby-here-doc-end-re'."
1207 (4 (7 . ?/)) 1246 (4 (7 . ?/))
1208 (6 (7 . ?/))) 1247 (6 (7 . ?/)))
1209 ("^=en\\(d\\)\\_>" 1 "!") 1248 ("^=en\\(d\\)\\_>" 1 "!")
1249 ;; general delimited string
1250 ("\\(^\\|[[ \t\n<+(,=]\\)\\(%[xrqQwW]?\\([^<[{(a-zA-Z0-9 \n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\3\\)\\)"
1251 (3 "\"")
1252 (5 "\""))
1210 ("^\\(=\\)begin\\_>" 1 (ruby-comment-beg-syntax)) 1253 ("^\\(=\\)begin\\_>" 1 (ruby-comment-beg-syntax))
1211 ;; Currently, the following case is highlighted incorrectly: 1254 ;; Currently, the following case is highlighted incorrectly:
1212 ;; 1255 ;;
@@ -1415,9 +1458,6 @@ See `font-lock-syntax-table'.")
1415 1 font-lock-variable-name-face) 1458 1 font-lock-variable-name-face)
1416 '("\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+" 1459 '("\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+"
1417 0 font-lock-variable-name-face) 1460 0 font-lock-variable-name-face)
1418 ;; general delimited string
1419 '("\\(^\\|[[ \t\n<+(,=]\\)\\(%[xrqQwW]?\\([^<[{(a-zA-Z0-9 \n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\3\\)\\)"
1420 (2 font-lock-string-face))
1421 ;; constants 1461 ;; constants
1422 '("\\(^\\|[^_]\\)\\b\\([A-Z]+\\(\\w\\|_\\)*\\)" 1462 '("\\(^\\|[^_]\\)\\b\\([A-Z]+\\(\\w\\|_\\)*\\)"
1423 2 font-lock-type-face) 1463 2 font-lock-type-face)