Tôi chắc chắn nó có thể được thực hiện ngắn hơn và tốt hơn, nhưng bây giờ tôi đã có những điều sau đây:
(defun ruby-get-containing-block()
(let ((pos (point))
(block nil))
(save-match-data
(save-excursion
(catch 'break
;; If in the middle of or at end of do, go back until at start
(while (and (not (looking-at "do"))
(string-equal (word-at-point) "do"))
(backward-char 1))
;; Keep searching for the containing block (i.e. the block that begins
;; before our point, and ends after it)
(while (not block)
(if (looking-at "do\\|{")
(let ((start (point)))
(ruby-forward-sexp)
(if (> (point) pos)
(setq block (cons start (point)))
(goto-char start))))
(if (not (search-backward-regexp "do\\|{" (point-min) t))
(throw 'break nil))))))
block))
(defun ruby-goto-containing-block-start()
(interactive)
(let ((block (ruby-get-containing-block)))
(if block
(goto-char (car block)))))
(defun ruby-flip-containing-block-type()
(interactive)
(save-excursion
(let ((block (ruby-get-containing-block)))
(goto-char (car block))
(save-match-data
(let ((strings (if (looking-at "do")
(cons
(if (= 3 (count-lines (car block) (cdr block)))
"do\\(*|[^|]+|\\)? *\n *\\(.*?\\) *\n *end"
"do\\(*|[^|]+|\\)? *\\(\\(.*\n?\\)+\\) *end")
"{\\1 \\2 }")
(cons
"{\\(*|[^|]+|\\)? *\\(\\(.*\n?\\)+\\) *}"
(if (= 1 (count-lines (car block) (cdr block)))
"do\\1\n\\2\nend"
"do\\1\\2end")))))
(when (re-search-forward (car strings) (cdr block) t)
(replace-match (cdr strings) t)
(delete-trailing-whitespace (match-beginning 0) (match-end 0))
(indent-region (match-beginning 0) (match-end 0))))))))
Có hai chức năng được liên kết với phím: ruby-goto-containing-block-start
và ruby-flip-containing-block-type
.
Hoặc lệnh hoạt động ở bất kỳ đâu trong khối và hy vọng họ có thể bỏ qua các khối sẽ bị bỏ qua - mặc dù đó không phải là vấn đề nếu bạn chuyển sang định dạng chặn ngắn.
ruby-flip-containing-block-type
thu gọn ba dòng làm .. khối kết thúc thành một dòng {} và ngược lại. Nếu các khối không chính xác 3 dòng và 1 dòng dài, nó nên để chúng một mình.
Tôi đang sử dụng tính năng này trên thiết lập ruby của mình ngay bây giờ, vì vậy tôi sẽ đánh giá cao các cải tiến.
Tốt. Điều duy nhất cần lưu ý là trong Emacs bạn cần phải đặt C-q C-J trong Regex thay vì \ n để phù hợp với các dòng mới :) – Gabriel
Ha! Cảm ơn người đàn ông (Tôi là một người sử dụng vim vì vậy tôi không chắc chắn về công cụ đó ... Tôi sẽ tìm kiếm cú pháp và sửa đổi câu trả lời của tôi). – Ziggy
Tính năng này có hoạt động đệ quy không? Tôi không quen với sự hỗ trợ regex của emacs. – jtbandes