mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* misc/ruby-mode.el: fix here-doc strings with inner quotes. patches
by Nathan Weizenbaum <nex342 AT gmail.com> from [ruby-core:17615] through [ruby-core:17910]. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18150 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									56e28fcf98
								
							
						
					
					
						commit
						1bcbc29d95
					
				
					 2 changed files with 102 additions and 46 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,9 @@
 | 
			
		|||
Tue Jul 22 09:51:32 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* misc/ruby-mode.el: fix here-doc strings with inner quotes.  patches
 | 
			
		||||
	  by Nathan Weizenbaum <nex342 AT gmail.com> from [ruby-core:17615]
 | 
			
		||||
	  through [ruby-core:17910].
 | 
			
		||||
 | 
			
		||||
Tue Jul 22 04:26:16 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* include/ruby/intern.h (rb_str_buf_new2): optimization for literals.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,15 +49,27 @@
 | 
			
		|||
(defconst ruby-block-end-re "\\<end\\>")
 | 
			
		||||
 | 
			
		||||
(defconst ruby-here-doc-beg-re
 | 
			
		||||
  "<<\\(-\\)?\\(\\([a-zA-Z0-9_]+\\)\\|[\"]\\([^\"]+\\)[\"]\\|[']\\([^']+\\)[']\\)")
 | 
			
		||||
  "\\(<\\)<\\(-\\)?\\(\\([a-zA-Z0-9_]+\\)\\|[\"]\\([^\"]+\\)[\"]\\|[']\\([^']+\\)[']\\)")
 | 
			
		||||
 | 
			
		||||
(defconst ruby-here-doc-end-re
 | 
			
		||||
  "^\\([ \t]+\\)?\\(.*\\)\\(.\\)$")
 | 
			
		||||
 | 
			
		||||
(defun ruby-here-doc-end-match ()
 | 
			
		||||
  (concat "^"
 | 
			
		||||
	  (if (match-string 1) "[ \t]*" nil)
 | 
			
		||||
	  (if (match-string 2) "[ \t]*" nil)
 | 
			
		||||
	  (regexp-quote
 | 
			
		||||
	   (or (match-string 3)
 | 
			
		||||
	       (match-string 4)
 | 
			
		||||
	       (match-string 5)))))
 | 
			
		||||
	   (or (match-string 4)
 | 
			
		||||
	       (match-string 5)
 | 
			
		||||
	       (match-string 6)))))
 | 
			
		||||
 | 
			
		||||
(defun ruby-here-doc-beg-match ()
 | 
			
		||||
  (let ((contents (regexp-quote (concat (match-string 2) (match-string 3)))))
 | 
			
		||||
    (concat "<<"
 | 
			
		||||
            (let ((match (match-string 1)))
 | 
			
		||||
              (if (and match (> (length match) 0))
 | 
			
		||||
                  (concat "\\(?:-\\([\"']?\\)\\|\\([\"']\\)" (match-string 1) "\\)"
 | 
			
		||||
                          contents "\\(\\1\\|\\2\\)")
 | 
			
		||||
                (concat "-?\\([\"']\\|\\)" contents "\\1"))))))
 | 
			
		||||
 | 
			
		||||
(defconst ruby-delimiter
 | 
			
		||||
  (concat "[?$/%(){}#\"'`.:]\\|<<\\|\\[\\|\\]\\|\\<\\("
 | 
			
		||||
| 
						 | 
				
			
			@ -172,7 +184,7 @@ Also ignores spaces after parenthesis when 'space."
 | 
			
		|||
 | 
			
		||||
(eval-when-compile (require 'cl))
 | 
			
		||||
(defun ruby-imenu-create-index-in-block (prefix beg end)
 | 
			
		||||
  (let ((index-alist '()) (case-fold-search nil)
 | 
			
		||||
  (let ((index-alist '())
 | 
			
		||||
        name next pos decl sing)
 | 
			
		||||
    (goto-char beg)
 | 
			
		||||
    (while (re-search-forward "^\\s *\\(\\(class\\>\\(\\s *<<\\)?\\|module\\>\\)\\s *\\([^\(<\n ]+\\)\\|\\(def\\|alias\\)\\>\\s *\\([^\(\n ]+\\)\\)" end t)
 | 
			
		||||
| 
						 | 
				
			
			@ -220,6 +232,7 @@ Also ignores spaces after parenthesis when 'space."
 | 
			
		|||
(defun ruby-mode-variables ()
 | 
			
		||||
  (set-syntax-table ruby-mode-syntax-table)
 | 
			
		||||
  (setq local-abbrev-table ruby-mode-abbrev-table)
 | 
			
		||||
  (setq case-fold-search nil)
 | 
			
		||||
  (make-local-variable 'indent-line-function)
 | 
			
		||||
  (setq indent-line-function 'ruby-indent-line)
 | 
			
		||||
  (make-local-variable 'require-final-newline)
 | 
			
		||||
| 
						 | 
				
			
			@ -235,6 +248,8 @@ Also ignores spaces after parenthesis when 'space."
 | 
			
		|||
  (setq indent-tabs-mode ruby-indent-tabs-mode)
 | 
			
		||||
  (make-local-variable 'parse-sexp-ignore-comments)
 | 
			
		||||
  (setq parse-sexp-ignore-comments t)
 | 
			
		||||
  (make-local-variable 'parse-sexp-lookup-properties)
 | 
			
		||||
  (setq parse-sexp-lookup-properties t)
 | 
			
		||||
  (make-local-variable 'paragraph-start)
 | 
			
		||||
  (setq paragraph-start (concat "$\\|" page-delimiter))
 | 
			
		||||
  (make-local-variable 'paragraph-separate)
 | 
			
		||||
| 
						 | 
				
			
			@ -645,7 +660,6 @@ The variable ruby-indent-level controls the amount of indentation.
 | 
			
		|||
  (save-excursion
 | 
			
		||||
    (beginning-of-line)
 | 
			
		||||
    (let ((indent-point (point))
 | 
			
		||||
	  (case-fold-search nil)
 | 
			
		||||
	  state bol eol begin op-end
 | 
			
		||||
	  (paren (progn (skip-syntax-forward " ")
 | 
			
		||||
			(and (char-after) (matching-paren (char-after)))))
 | 
			
		||||
| 
						 | 
				
			
			@ -1090,7 +1104,7 @@ balanced expression is found."
 | 
			
		|||
      (setq font-lock-variable-name-face font-lock-type-face))
 | 
			
		||||
 | 
			
		||||
  (setq ruby-font-lock-syntactic-keywords
 | 
			
		||||
	'(
 | 
			
		||||
	`(
 | 
			
		||||
	  ;; #{ }, #$hoge, #@foo are not comments
 | 
			
		||||
	  ("\\(#\\)[{$@]" 1 (1 . nil))
 | 
			
		||||
	  ;; the last $', $", $` in the respective string is not variable
 | 
			
		||||
| 
						 | 
				
			
			@ -1106,7 +1120,76 @@ balanced expression is found."
 | 
			
		|||
	   (4 (7 . ?/))
 | 
			
		||||
	   (6 (7 . ?/)))
 | 
			
		||||
	  ("^\\(=\\)begin\\(\\s \\|$\\)" 1 (7 . nil))
 | 
			
		||||
	  ("^\\(=\\)end\\(\\s \\|$\\)" 1 (7 . nil))))
 | 
			
		||||
	  ("^\\(=\\)end\\(\\s \\|$\\)" 1 (7 . nil))
 | 
			
		||||
	  (,(concat ruby-here-doc-beg-re ".*\\(\n\\)")
 | 
			
		||||
	   ,(+ 1 (regexp-opt-depth ruby-here-doc-beg-re))
 | 
			
		||||
           (ruby-here-doc-beg-syntax))
 | 
			
		||||
	  (,ruby-here-doc-end-re 3 (ruby-here-doc-end-syntax))))
 | 
			
		||||
 | 
			
		||||
  (defun ruby-in-non-here-doc-string-p ()
 | 
			
		||||
    (let ((syntax (syntax-ppss)))
 | 
			
		||||
      (or (nth 4 syntax)
 | 
			
		||||
          ;; In a string *without* a generic delimiter
 | 
			
		||||
          ;; If it's generic, it's a heredoc and we don't care
 | 
			
		||||
          ;; See `parse-partial-sexp'
 | 
			
		||||
          (numberp (nth 3 syntax)))))
 | 
			
		||||
 | 
			
		||||
  (defun ruby-in-here-doc-p ()
 | 
			
		||||
    (save-excursion
 | 
			
		||||
      (let ((old-point (point)))
 | 
			
		||||
        (beginning-of-line)
 | 
			
		||||
        (catch 'found-beg
 | 
			
		||||
          (while (re-search-backward ruby-here-doc-beg-re nil t)
 | 
			
		||||
            (if (not (or (syntax-ppss-context (syntax-ppss))
 | 
			
		||||
                         (ruby-here-doc-find-end old-point)))
 | 
			
		||||
                (throw 'found-beg t)))))))
 | 
			
		||||
 | 
			
		||||
  (defun ruby-here-doc-find-end (&optional limit)
 | 
			
		||||
    "Expects the point to be on a line with one or more heredoc
 | 
			
		||||
openers. Returns the buffer position at which all heredocs on the
 | 
			
		||||
line are terminated, or nil if they aren't terminated before the
 | 
			
		||||
buffer position `limit' or the end of the buffer."
 | 
			
		||||
    (save-excursion
 | 
			
		||||
      (beginning-of-line)
 | 
			
		||||
      (catch 'done
 | 
			
		||||
        (let ((eol (save-excursion (end-of-line) (point)))
 | 
			
		||||
              ;; Fake match data such that (match-end 0) is at eol
 | 
			
		||||
              (end-match-data (progn (looking-at ".*$") (match-data)))
 | 
			
		||||
              beg-match-data end-re)
 | 
			
		||||
          (while (re-search-forward ruby-here-doc-beg-re eol t)
 | 
			
		||||
            (setq beg-match-data (match-data))
 | 
			
		||||
            (setq end-re (ruby-here-doc-end-match))
 | 
			
		||||
 | 
			
		||||
            (set-match-data end-match-data)
 | 
			
		||||
            (goto-char (match-end 0))
 | 
			
		||||
            (unless (re-search-forward end-re limit t) (throw 'done nil))
 | 
			
		||||
            (setq end-match-data (match-data))
 | 
			
		||||
 | 
			
		||||
            (set-match-data beg-match-data)
 | 
			
		||||
            (goto-char (match-end 0)))
 | 
			
		||||
          (set-match-data end-match-data)
 | 
			
		||||
          (goto-char (match-end 0))
 | 
			
		||||
          (point)))))
 | 
			
		||||
 | 
			
		||||
  (defun ruby-here-doc-beg-syntax ()
 | 
			
		||||
    (save-excursion
 | 
			
		||||
      (goto-char (match-beginning 0))
 | 
			
		||||
      (unless (or (ruby-in-non-here-doc-string-p)
 | 
			
		||||
                  (ruby-in-here-doc-p))
 | 
			
		||||
        (string-to-syntax "|"))))
 | 
			
		||||
 | 
			
		||||
  (defun ruby-here-doc-end-syntax ()
 | 
			
		||||
    (save-excursion
 | 
			
		||||
      (goto-char (match-end 0))
 | 
			
		||||
      (let ((old-point (point))
 | 
			
		||||
            (beg-exists (re-search-backward (ruby-here-doc-beg-match) nil t))
 | 
			
		||||
            (eol (save-excursion (end-of-line) (point))))
 | 
			
		||||
        (if (and beg-exists ; If there is a heredoc that matches this line...
 | 
			
		||||
                 (null (syntax-ppss-context (syntax-ppss))) ; And that's not inside a heredoc/string/comment...
 | 
			
		||||
                 (progn (goto-char (match-end 0)) ; And it's the last heredoc on its line...
 | 
			
		||||
                        (not (re-search-forward ruby-here-doc-beg-re eol t)))
 | 
			
		||||
                 (eq old-point (ruby-here-doc-find-end old-point))) ; And it ends at this point...
 | 
			
		||||
            (string-to-syntax "|")))))
 | 
			
		||||
 | 
			
		||||
  (if (featurep 'xemacs)
 | 
			
		||||
      (put 'ruby-mode 'font-lock-defaults
 | 
			
		||||
| 
						 | 
				
			
			@ -1147,35 +1230,7 @@ balanced expression is found."
 | 
			
		|||
      (modify-syntax-entry ?_ "w" tbl)
 | 
			
		||||
      tbl))
 | 
			
		||||
 | 
			
		||||
  (defun ruby-font-lock-here-docs (limit)
 | 
			
		||||
    (if (re-search-forward ruby-here-doc-beg-re limit t)
 | 
			
		||||
	(let (beg)
 | 
			
		||||
	  (beginning-of-line)
 | 
			
		||||
          (forward-line)
 | 
			
		||||
	  (setq beg (point))
 | 
			
		||||
	  (if (re-search-forward (ruby-here-doc-end-match) nil t)
 | 
			
		||||
	      (progn
 | 
			
		||||
		(set-match-data (list beg (point)))
 | 
			
		||||
		t)))))
 | 
			
		||||
 | 
			
		||||
  (defun ruby-font-lock-maybe-here-docs (limit)
 | 
			
		||||
    (let (beg)
 | 
			
		||||
      (save-excursion
 | 
			
		||||
	(if (re-search-backward ruby-here-doc-beg-re nil t)
 | 
			
		||||
	    (progn
 | 
			
		||||
	      (beginning-of-line)
 | 
			
		||||
              (forward-line)
 | 
			
		||||
	      (setq beg (point)))))
 | 
			
		||||
      (if (and beg
 | 
			
		||||
	       (let ((end-match (ruby-here-doc-end-match)))
 | 
			
		||||
                 (and (not (re-search-backward end-match beg t))
 | 
			
		||||
		      (re-search-forward end-match nil t))))
 | 
			
		||||
	  (progn
 | 
			
		||||
	    (set-match-data (list beg (point)))
 | 
			
		||||
	    t)
 | 
			
		||||
          nil)))
 | 
			
		||||
 | 
			
		||||
  (defvar ruby-font-lock-keywords
 | 
			
		||||
  (defconst ruby-font-lock-keywords
 | 
			
		||||
    (list
 | 
			
		||||
     ;; functions
 | 
			
		||||
     '("^\\s *def\\s +\\([^( \t\n]+\\)"
 | 
			
		||||
| 
						 | 
				
			
			@ -1224,6 +1279,8 @@ balanced expression is found."
 | 
			
		|||
	     "\\|")
 | 
			
		||||
	    "\\)\\>\\)")
 | 
			
		||||
	   2)
 | 
			
		||||
     ;; here-doc beginnings
 | 
			
		||||
     (list ruby-here-doc-beg-re 0 'font-lock-string-face)
 | 
			
		||||
     ;; variables
 | 
			
		||||
     '("\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(nil\\|self\\|true\\|false\\)\\>"
 | 
			
		||||
       2 font-lock-variable-name-face)
 | 
			
		||||
| 
						 | 
				
			
			@ -1237,13 +1294,6 @@ balanced expression is found."
 | 
			
		|||
       0 font-lock-comment-face t)
 | 
			
		||||
     '(ruby-font-lock-maybe-docs
 | 
			
		||||
       0 font-lock-comment-face t)
 | 
			
		||||
     ;; "here" document
 | 
			
		||||
     '(ruby-font-lock-here-docs
 | 
			
		||||
       0 font-lock-string-face t)
 | 
			
		||||
     '(ruby-font-lock-maybe-here-docs
 | 
			
		||||
       0 font-lock-string-face t)
 | 
			
		||||
     `(,ruby-here-doc-beg-re
 | 
			
		||||
       0 font-lock-string-face t)
 | 
			
		||||
     ;; general delimited string
 | 
			
		||||
     '("\\(^\\|[[ \t\n<+(,=]\\)\\(%[xrqQwW]?\\([^<[{(a-zA-Z0-9 \n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\3\\)\\)"
 | 
			
		||||
       (2 font-lock-string-face))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue