我经常发现自己转换代码是这样的:
before do
:something
end
Run Code Online (Sandbox Code Playgroud)
至
before { :something }
Run Code Online (Sandbox Code Playgroud)
有没有办法在emacs中自动执行此任务?我使用ruby-mode和rinary,但它们在这里不太有用.
我相信它可以做得更短更好,但是现在我有以下几点:
(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))))))))
Run Code Online (Sandbox Code Playgroud)
键有两个功能:ruby-goto-containing-block-start和ruby-flip-containing-block-type.
这两个命令都可以在块内的任何位置工作,并且希望它们可以跳过应该跳过的块 - 尽管如果要转换为短块格式,这应该不是问题.
的ruby-flip-containing-block-type塌陷三行做..端块到单线{},反之亦然.如果块不是正好3行而是1行长,那么它应该不管它们.
我现在在我的ruby设置上使用它,所以我希望改进.
| 归档时间: |
|
| 查看次数: |
924 次 |
| 最近记录: |