Emacs, ruby: конвертировать конец блока в фигурные скобки и наоборот - PullRequest
5 голосов
/ 15 июля 2011

Я часто нахожу себя конвертирующим код следующим образом:

before do 
  :something
end

в

before { :something }

Есть ли способ автоматизировать эту задачу в emacs?Я использую режим ruby-mode и rinary, но здесь они не слишком полезны.

Ответы [ 4 ]

13 голосов
/ 19 сентября 2012

ruby-mode в Emacs 24.3 и новее имеет команду ruby-toggle-block.

Связывание по умолчанию: C-c {.

5 голосов
/ 21 июля 2011

Я уверен, что это можно сделать короче и лучше, но сейчас у меня есть следующее:

(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))))))))

Есть две функции, которые должны быть связаны с клавишами: ruby-goto-containing-block-start и ruby-flip-containing-block-type.

Любая команда работает в любом месте внутри блока, и, надеюсь, они могут пропустить блоки, которые должны быть пропущены - хотя это не должно быть проблемой, если вы конвертируете в формат короткого блока.

ruby-flip-containing-block-type сворачивает три строки do .. end в одну строку {} и наоборот.Если блоки не точно 3 строки и 1 строка длиной, они должны быть оставлены в покое.

Сейчас я использую это в своей настройке ruby, поэтому я буду признателен за улучшения.

1 голос
/ 16 июля 2011

Здесь - это функция. Я начинающий elisp. Это идет только в одну сторону; от делать до {. дайте мне знать, если это работает для вас.

1 голос
/ 15 июля 2011

Вы можете использовать регулярное выражение, которое пересекает символы новой строки.

/ do (Cq Cj \?) * (. *) (Cq Cj \?) * End /

и заменить на

{\2 } 

Нечто подобное может сработать.Затем вы можете настроить его до тех пор, пока он не сделает именно то, что вам нужно, и привязать его к макросу, чтобы вы могли в любое время извлечь его и произвести впечатление на своих друзей!

Я протестировал приведенные выше регулярные выражения в vi (мой редактор на выбор)и они работали.Так что нечто подобное должно работать для вас.

Для получения дополнительной информации, обязательно ознакомьтесь с emacs wiki !

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...