2011-07-15 40 views

Trả lời

13

ruby-mode trong Emacs 24.3 và mới hơn có lệnh ruby-toggle-block.

Ràng buộc mặc định là C-c {.

1

Bạn có thể sử dụng cụm từ thông dụng đi qua dòng mới.

/làm (C-q C-j \?) * (. *) (C-q C-j \?) * Kết thúc/

và thay thế bằng

{\2 } 

Something như thế có thể làm việc. Sau đó bạn có thể tùy chỉnh nó cho đến khi nó thực hiện chính xác những gì bạn cần và liên kết nó với một macro để bạn có thể whip nó ra và gây ấn tượng với bạn bè của bạn bất cứ lúc nào!

Tôi đã thử nghiệm các quy trình trên trong vi (trình soạn thảo lựa chọn của tôi) và chúng hoạt động. Vì vậy, một cái gì đó tương tự nên làm việc cho bạn.

Để biết thêm thông tin, hãy đảm bảo thanh toán emacs wiki!

+0

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

+0

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

+0

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

1

Here là một hàm. Tôi là một người mới bắt đầu. Nó chỉ đi một chiều; từ làm đến {. Hãy cho tôi biết nếu nó làm việc cho bạn.

+0

Không làm việc cho tôi: messes lên toàn bộ tập tin. Nhưng ít nhất tôi có một ý tưởng làm thế nào để làm điều đó, nhờ – iosadchii

+1

@iosadchii thêm giải pháp của bạn như là một câu trả lời ở đây, và chấp nhận nó.Tôi có thể muốn "lấy cảm hứng" bởi nó – vhallac

5

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-startruby-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.

+1

1 cho nỗ lực tốt. – ocodo

Các vấn đề liên quan