色々考えてみたけど。
alignモドキを早くしようとして色々考えてみたのに何故か遅くなった奴のをメモ。というか、どうやると早くなるのか余り理解していないので、単純にコードが短くなっただけのような気はするけど、速度は3倍近く遅くなったという。やっぱりマクロの中身が何をしているのとかを理解しないと駄目なのかもしれない。
;早いと思ったのに早くなかった奴の墓場。 ;------------------------------------------------------------ ;x語目をインデント (defun level-indent (from to &optional (level 1)) (interactive "*r" ) (if (> from to) (rotatef from to)) (save-excursion (save-restriction (narrow-to-region from to) (let ((max-colum 1)) (goto-char from) ;リージョン内でlevel番目の単語が一番後ろにある行を調べ、その位置を記憶 (while (progn (goto-any-word-level level) (if (and (< max-colum (current-column)) (not (eolp))) (setq max-colum (current-column))) (forward-line))) ;ここから調べた後ろの所まで他の行に空白を入れ込む (goto-char from) (while (progn (goto-any-word-level level) ;indentの所に移動した時点で行末でなければ (unless (eolp) ;ここで実際に空白を挿入 (insert " " (1+ (- max-colum (current-column)))) (if (looking-at "[ \t ]*") (delete-region (match-beginning 0) (match-end 0)))) (sit-for .001) ; 動きが見えてるほうが固まってるのと区別できていいかなぁと (forward-line))) )))) ;------------------------------------------------------------ ;リージョン範囲で兎に角インデント (defun any-indent (from to &optional (max 1)) (interactive "*r" ) (if (> from to) (rotatef from to)) (save-excursion (save-restriction (narrow-to-region from to ) ; 一応危険な書き換えがないように。 (handler-case ; indent-regionが出来ないモードもあるようなので。 (indent-region from to) (error (c) (plain-error "このモードは特定のインデントがないかも"))) ;一番大きい単語の所をチェック (goto-char from ) (while (progn (goto-any-word-level max) (while (not (eolp)) (let ((cp (point)) (eol (and (goto-eol) (point)))) (goto-char cp) (scan-buffer "[ \t ]*[^ \t ]*" :regexp t :tail t :limit eol) (if (not (eolp)) (setq max (1+ max))))) (forward-line))) (let ((level 1)) ;indentを実行する (while (>= max level) (level-indent (point-min) (point-max) level) (do-events) ; フリーズしたようになるのを防ぐ (setq level (+ level 1)))) )))
早くするのは諦めることにした。取り合えず動けばいいことに。