* toggle block was harder than I thought but quite solid now...

This commit is contained in:
capitaomorte 2010-04-06 21:55:31 +00:00
parent 100ab284d5
commit 71d1b9b7c5

View File

@ -17,64 +17,91 @@
((string-match "_" fn) (replace-match "" nil nil fn)) ((string-match "_" fn) (replace-match "" nil nil fn))
(t fn)))) (t fn))))
(defun yas/ruby-chomp (x)
"Chomp string X, return nil if X became empty"
(let ((len (length x))
(start 0)
(end (1- (length x))))
(unless (zerop len)
(while (and (< start len)
(memq (aref x start)
'(? ?\t ?\n)))
(setq start (1+ start)))
(while (and (> end start)
(memq (aref x end)
'(? ?\t ?\n)))
(setq end (1- end)))
(unless (<= end start)
(substring x start (1+ end))))))
(defvar yas/ruby-block-start-regexp ".*[\s\t\n]\\(do\\)[\s\t\n]\\(|.*|\\)?")
(defun yas/ruby-toggle-single-multi-line-block () (defun yas/ruby-toggle-single-multi-line-block ()
(interactive) (interactive)
(let* ((do-block-start (save-excursion (let* ((do-block-bounds (save-excursion
(ruby-beginning-of-block) (when (or (save-excursion (beginning-of-line)
(when (search-forward-regexp ".*[^\w]\\(do\\)[^\w]\\(|.*|\\)?" nil t) (looking-at yas/ruby-block-start-regexp))
(match-beginning 1)))) (save-excursion (ruby-beginning-of-block)
(brace-block-start (condition-case nil (looking-at yas/ruby-block-start-regexp)))
(cons (match-beginning 1)
(progn (goto-char (match-beginning 1))
(ruby-end-of-block) (point))))))
(brace-block-bounds (condition-case nil
(let ((syntax-info (syntax-ppss))) (let ((syntax-info (syntax-ppss)))
(if (fourth syntax-info) (if (fourth syntax-info)
(goto-char (ninth syntax-info))) (goto-char (ninth syntax-info)))
(while (progn (up-list -1) (not (eq (char-after) ?{)))) (while (progn (up-list -1) (not (eq (char-after) ?{))))
(point)) (cons (point)
(progn (forward-sexp) (point))))
(error nil))) (error nil)))
(block-region)) (block-region)
(if (and do-block-start brace-block-start) (statements))
(if (< do-block-start brace-block-start) (if (and do-block-bounds brace-block-bounds)
(setq do-block-start nil) (if (< (car do-block-bounds) (car brace-block-bounds))
(setq brace-block-start nil))) (setq do-block-bounds nil)
(cond (do-block-start (setq brace-block-bounds nil)))
(message "found a do block") (cond (do-block-bounds
(goto-char do-block-start) ;; (and do-block-bounds
(ruby-end-of-block) ;; (<= (point) (cdr do-block-bounds)))
(setq block-region (buffer-substring (+ 2 do-block-start) (point))) ;; (message "found a do block")
(delete-region do-block-start (+ 3(point))) (goto-char (car do-block-bounds))
(setq block-region (buffer-substring-no-properties (+ 2 (car do-block-bounds)) (cdr do-block-bounds)))
(setq statements (mapcar #'yas/ruby-chomp
(split-string block-region "\n")))
(delete-region (car do-block-bounds) (+ 3 (cdr do-block-bounds)))
(insert "{") (insert "{")
(mapc #'(lambda (string) (mapc #'(lambda (string)
(let* ((chomped (replace-regexp-in-string "^[\s\t]*\\(.*\\)[\s\t]*$" "\\1" string)) (let* ((lastchar (and (not (zerop (length string)))
(lastchar (and (not (zerop (length chomped))) (aref string (1- (length string))))))
(aref chomped (1- (length chomped))))))
(when lastchar (when lastchar
(insert " " chomped) (insert " " string)
(unless (member lastchar '(?; (unless (member lastchar '(?;
?|)) ?|))
(insert ";"))))) (insert ";")))))
(split-string block-region "\n")) statements)
(delete-backward-char 1)
(insert " }") (insert " }")
(backward-char 1)) (backward-char 1))
(brace-block-start (brace-block-bounds
(message "found a brace block") ;; (message "found a brace block")
(goto-char brace-block-start) (goto-char (car brace-block-bounds))
(forward-sexp) (setq block-region (buffer-substring (1+ (car brace-block-bounds)) (1- (cdr brace-block-bounds))))
(setq block-region (buffer-substring (+ 1 brace-block-start) (1- (point)))) (delete-region (car brace-block-bounds) (cdr brace-block-bounds))
(delete-region brace-block-start (point))
(insert "do") (insert "do")
(when (string-match "\\(|.*|\\).*" block-region) (when (string-match "\\(|.*|\\).*" block-region)
(insert " " (match-string 1 block-region)) (insert " " (match-string 1 block-region))
(setq block-region (substring block-region (match-end 1)))) (setq block-region (substring block-region (match-end 1))))
(setq statements (mapcar #'yas/ruby-chomp
(split-string block-region ";")))
(mapc #'(lambda (string) (mapc #'(lambda (string)
(let* ((chomped (replace-regexp-in-string "^[\s\t]*\\(.*\\)[\s\t]*$" "\\1" string))) (insert "\n" string)
(unless (zerop (length chomped))
(insert "\n" chomped)
(indent-according-to-mode))))
(split-string block-region ";"))
(insert "\nend")
(backward-char 3)
(indent-according-to-mode)) (indent-according-to-mode))
statements)
(save-excursion
(insert "\nend")
(indent-according-to-mode)))
(t (t
(message "found no block at all"))))) (message "No enclosing block found.")))))
(defvar yas/ruby-require-regexps (defvar yas/ruby-require-regexps
'(("abbrev" . ("abbrev")) '(("abbrev" . ("abbrev"))
@ -226,6 +253,7 @@
;; ;;
;; Substitutions for: condition ;; Substitutions for: condition
;; ;;
;; 7990EE60-C850-4779-A8C0-7FD2C853B99B =yyas> 'force-in-comment
;; 451A0596-1F72-4AFB-AF2F-45900FABB0F7 =yyas> (not (yas/ruby-end-is-block-end-p)) ;; 451A0596-1F72-4AFB-AF2F-45900FABB0F7 =yyas> (not (yas/ruby-end-is-block-end-p))
;; (string.quoted.double.ruby|string.interpolated.ruby) - string source =yyas> (and (yas/ruby-in-interpolated-string-p) 'force-in-comment) ;; (string.quoted.double.ruby|string.interpolated.ruby) - string source =yyas> (and (yas/ruby-in-interpolated-string-p) 'force-in-comment)
;; text.html.ruby, text.html source.ruby =yyas> (yas/unimplemented) ;; text.html.ruby, text.html source.ruby =yyas> (yas/unimplemented)
@ -234,7 +262,6 @@
;; ;;
;; Substitutions for: binding ;; Substitutions for: binding
;; ;;
;; # as in Commands/New Method.yasnippet
;; $ =yyas> C-s-M ;; $ =yyas> C-s-M
;; ^W =yyas> s-C-W ;; ^W =yyas> s-C-W
;; # =yyas> # ;; # =yyas> #
@ -696,8 +723,6 @@
;; # as in Commands/Enclose in _ (RDoc comments).yasnippet ;; # as in Commands/Enclose in _ (RDoc comments).yasnippet
;; DAA69A0C-FC1E-4509-9931-DFFB38B4D6AE =yyas> (yas/unknown) ;; DAA69A0C-FC1E-4509-9931-DFFB38B4D6AE =yyas> (yas/unknown)
;; ;;
;; # as in Macros/Toggle Single Multi Line Block.yasnippet
;;
;; # as in Commands/Omit from RDoc.yasnippet ;; # as in Commands/Omit from RDoc.yasnippet
;; BF4CA9F1-51CD-48D4-8357-852234F59046 =yyas> (yas/unknown) ;; BF4CA9F1-51CD-48D4-8357-852234F59046 =yyas> (yas/unknown)
;; ;;