aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/ruby-mode.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/ruby-mode.el')
-rw-r--r--lisp/progmodes/ruby-mode.el54
1 files changed, 45 insertions, 9 deletions
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index c8fae7ba1e6..9dc2c4fb6c9 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -137,6 +137,7 @@ This should only be called after matching against `ruby-here-doc-beg-re'."
137 137
138(defconst ruby-symbol-chars "a-zA-Z0-9_" 138(defconst ruby-symbol-chars "a-zA-Z0-9_"
139 "List of characters that symbol names may contain.") 139 "List of characters that symbol names may contain.")
140
140(defconst ruby-symbol-re (concat "[" ruby-symbol-chars "]") 141(defconst ruby-symbol-re (concat "[" ruby-symbol-chars "]")
141 "Regexp to match symbols.") 142 "Regexp to match symbols.")
142 143
@@ -254,11 +255,13 @@ Also ignores spaces after parenthesis when 'space."
254 ("for" for-body "end") 255 ("for" for-body "end")
255 ("[" expseq "]") 256 ("[" expseq "]")
256 ("{" hashvals "}") 257 ("{" hashvals "}")
258 ("{" insts "}")
257 ("while" insts "end") 259 ("while" insts "end")
258 ("until" insts "end") 260 ("until" insts "end")
259 ("unless" insts "end") 261 ("unless" insts "end")
260 ("if" if-body "end") 262 ("if" if-body "end")
261 ("case" cases "end")) 263 ("case" cases "end"))
264 (formal-params ("opening-|" exp "|"))
262 (for-body (for-head ";" insts)) 265 (for-body (for-head ";" insts))
263 (for-head (id "in" exp)) 266 (for-head (id "in" exp))
264 (cases (exp "then" insts) ;; FIXME: Ruby also allows (exp ":" insts). 267 (cases (exp "then" insts) ;; FIXME: Ruby also allows (exp ":" insts).
@@ -285,10 +288,20 @@ Also ignores spaces after parenthesis when 'space."
285 (save-excursion 288 (save-excursion
286 (skip-chars-backward " \t") 289 (skip-chars-backward " \t")
287 (not (or (bolp) 290 (not (or (bolp)
288 (memq (char-before) '(?\; ?- ?+ ?* ?/ ?:)) 291 (and (memq (char-before) '(?\; ?- ?+ ?* ?/ ?: ?.))
292 ;; Make sure it's not the end of a regexp.
293 (not (eq (car (syntax-after (1- (point)))) 7)))
289 (and (memq (char-before) '(?\? ?=)) 294 (and (memq (char-before) '(?\? ?=))
290 (not (memq (char-syntax (char-before (1- (point)))) 295 (let ((tok (ruby-smie--backward-token)))
291 '(?w ?_)))))))) 296 (or (equal tok "?")
297 (string-match "\\`\\s." tok))))))))
298
299(defun ruby-smie--opening-pipe-p ()
300 (save-excursion
301 (if (eq ?| (char-before)) (forward-char -1))
302 (skip-chars-backward " \t\n")
303 (or (eq ?\{ (char-before))
304 (looking-back "\\_<do" (- (point) 2)))))
292 305
293(defun ruby-smie--forward-token () 306(defun ruby-smie--forward-token ()
294 (skip-chars-forward " \t") 307 (skip-chars-forward " \t")
@@ -299,12 +312,16 @@ Also ignores spaces after parenthesis when 'space."
299 (if (eolp) (forward-char 1) (forward-comment 1)) 312 (if (eolp) (forward-char 1) (forward-comment 1))
300 ";") 313 ";")
301 (forward-comment (point-max)) 314 (forward-comment (point-max))
315 (if (looking-at ":\\s.+")
316 (progn (goto-char (match-end 0)) (match-string 0)) ;; bug#15208.
302 (let ((tok (smie-default-forward-token))) 317 (let ((tok (smie-default-forward-token)))
303 (cond 318 (cond
304 ((member tok '("unless" "if" "while" "until")) 319 ((member tok '("unless" "if" "while" "until"))
305 (if (save-excursion (forward-word -1) (ruby-smie--bosp)) 320 (if (save-excursion (forward-word -1) (ruby-smie--bosp))
306 tok "iuwu-mod")) 321 tok "iuwu-mod"))
307 (t tok))))) 322 ((equal tok "|")
323 (if (ruby-smie--opening-pipe-p) "opening-|" tok))
324 (t tok))))))
308 325
309(defun ruby-smie--backward-token () 326(defun ruby-smie--backward-token ()
310 (let ((pos (point))) 327 (let ((pos (point)))
@@ -314,10 +331,14 @@ Also ignores spaces after parenthesis when 'space."
314 (progn (skip-chars-forward " \t") 331 (progn (skip-chars-forward " \t")
315 ";") 332 ";")
316 (let ((tok (smie-default-backward-token))) 333 (let ((tok (smie-default-backward-token)))
334 (when (and (eq ?: (char-before)) (string-match "\\`\\s." tok))
335 (forward-char -1) (setq tok (concat ":" tok))) ;; bug#15208.
317 (cond 336 (cond
318 ((member tok '("unless" "if" "while" "until")) 337 ((member tok '("unless" "if" "while" "until"))
319 (if (ruby-smie--bosp) 338 (if (ruby-smie--bosp)
320 tok "iuwu-mod")) 339 tok "iuwu-mod"))
340 ((equal tok "|")
341 (if (ruby-smie--opening-pipe-p) "opening-|" tok))
321 (t tok)))))) 342 (t tok))))))
322 343
323(defun ruby-smie-rules (kind token) 344(defun ruby-smie-rules (kind token)
@@ -332,7 +353,19 @@ Also ignores spaces after parenthesis when 'space."
332 ;; For (invalid) code between switch and case. 353 ;; For (invalid) code between switch and case.
333 ;; (if (smie-parent-p "switch") 4) 354 ;; (if (smie-parent-p "switch") 4)
334 0)) 355 0))
335 (`(:before . ,(or `"else" `"then" `"elsif")) 0) 356 (`(:before . "do")
357 (when
358 (save-excursion
359 (forward-word 1) ;Skip "do"
360 (skip-chars-forward " \t")
361 (and (equal (save-excursion (ruby-smie--forward-token)) "opening-|")
362 (save-excursion (forward-sexp 1)
363 (skip-chars-forward " \t")
364 (or (eolp)
365 (looking-at comment-start-skip)))))
366 ;; `(column . ,(smie-indent-virtual))
367 (smie-rule-parent)))
368 (`(:before . ,(or `"else" `"then" `"elsif" `"rescue")) 0)
336 (`(:before . ,(or `"when")) 369 (`(:before . ,(or `"when"))
337 (if (not (smie-rule-sibling-p)) 0)) ;; ruby-indent-level 370 (if (not (smie-rule-sibling-p)) 0)) ;; ruby-indent-level
338 ;; Hack attack: Since newlines are separators, don't try to align args that 371 ;; Hack attack: Since newlines are separators, don't try to align args that
@@ -903,6 +936,10 @@ Can be one of `heredoc', `modifier', `expr-qstr', `expr-re'."
903 (not (looking-at "[a-z_]")))) 936 (not (looking-at "[a-z_]"))))
904 (and (looking-at ruby-operator-re) 937 (and (looking-at ruby-operator-re)
905 (not (ruby-special-char-p)) 938 (not (ruby-special-char-p))
939 (save-excursion
940 (forward-char -1)
941 (or (not (looking-at ruby-operator-re))
942 (not (eq (char-before) ?:))))
906 ;; Operator at the end of line. 943 ;; Operator at the end of line.
907 (let ((c (char-after (point)))) 944 (let ((c (char-after (point))))
908 (and 945 (and
@@ -1825,11 +1862,11 @@ See `font-lock-syntax-table'.")
1825 "using") 1862 "using")
1826 'symbols)) 1863 'symbols))
1827 1 'font-lock-builtin-face) 1864 1 'font-lock-builtin-face)
1828 ;; Perl-ish keywords
1829 "\\_<\\(?:BEGIN\\|END\\)\\_>\\|^__END__$"
1830 ;; here-doc beginnings 1865 ;; here-doc beginnings
1831 `(,ruby-here-doc-beg-re 0 (unless (ruby-singleton-class-p (match-beginning 0)) 1866 `(,ruby-here-doc-beg-re 0 (unless (ruby-singleton-class-p (match-beginning 0))
1832 'font-lock-string-face)) 1867 'font-lock-string-face))
1868 ;; Perl-ish keywords
1869 "\\_<\\(?:BEGIN\\|END\\)\\_>\\|^__END__$"
1833 ;; variables 1870 ;; variables
1834 `(,(concat ruby-font-lock-keyword-beg-re 1871 `(,(concat ruby-font-lock-keyword-beg-re
1835 "\\_<\\(nil\\|self\\|true\\|false\\)\\>") 1872 "\\_<\\(nil\\|self\\|true\\|false\\)\\>")
@@ -1931,8 +1968,7 @@ The variable `ruby-indent-level' controls the amount of indentation.
1931 "\\)\\'")) 'ruby-mode)) 1968 "\\)\\'")) 'ruby-mode))
1932 1969
1933;;;###autoload 1970;;;###autoload
1934(dolist (name (list "ruby" "rbx" "jruby" "ruby1.9" "ruby1.8")) 1971(add-to-list 'interpreter-mode-alist (cons (purecopy "\\`\\(rbx\\|j?ruby\\(1\\.[89]\\)?\\)\\'") 'ruby-mode))
1935 (add-to-list 'interpreter-mode-alist (cons (purecopy name) 'ruby-mode)))
1936 1972
1937(provide 'ruby-mode) 1973(provide 'ruby-mode)
1938 1974