昨日、org-elementをthing-at-pointで扱えるようにしてみた けど、
今日はその続きで、M-↑/M-↓を行指定でやれるようにしてみます。
というのは、これらのコマンドは現在の要素(subtree/段落など)を
1つずつ上下に移動するものであり、多くの要素を繰り返し入れ替えるには
面倒だからです。
行指定ということならば、ace-jump-modeの汎用版ともいえるavy.el(レビュー) を
使うことにしました。
画面内の特定の場所を指定するならばぜひとも使いたいインターフェースです。
avy--line 関数は目的行を尋ね、位置とウィンドウのコンスセルを返します。
これを使って M-x avy-move-line-thing を作りました。
移動元・移動先を指定し、行・region・要素(org-mode)を移動するコマンドです。
文章を書く前にアイデアを集め、それを順番に並べ変えるときに
このコマンドを愛用しています。
(require 'org-element) (require 'avy) (defun org-element-at-point-bounds () (let ((e (org-element-at-point))) (cons (org-element-property :begin e) (org-element-property :end e)))) (put 'org-element 'bounds-of-thing-at-point 'org-element-at-point-bounds) (defun avy-move-line-thing () "移動元・移動先を指定し、行・region・要素(org-mode)を移動する。" (interactive) (let* ((avy-handler-function (lambda (char) (if (eq char ?\C-m) (throw 'done (list (point-at-bol))) (avy-handler-default char)))) (from (unless (region-active-p) (message "From: ") (car (avy--line)))) (to (progn (message "To: ") (set-marker (make-marker) (car (avy--line))))) bot content) (setq bot (if (region-active-p) (cons (region-beginning) (region-end)) (goto-char from) (bounds-of-thing-at-point (if (derived-mode-p 'org-mode) 'org-element 'line)))) (setq content (buffer-substring (car bot) (cdr bot))) (delete-region (car bot) (cdr bot)) (goto-char to) (insert content)))
以下のorg文書を例にすると
* 1 one * 2 two * 3 three
Fig1: dを指定し
Fig2: aを指定すれば
Fig3: 入れ替わる
org-mode以外でも
Fig4: s→aを指定すると
Fig5: 入れ替わる
Fig6: regionを指定し、aを指定すれば
Fig7: 入れ替わる!
本日もお読みいただき、ありがとうございました。参考になれば嬉しいです。