-
-
Save takaxp/1599131 to your computer and use it in GitHub Desktop.
(defun my-find-headings () | |
(let ((eob (point-max)) | |
(head-list '())) | |
(save-excursion | |
(goto-char (point-min)) | |
(while (when (search-forward-regexp "^\*\\([^*]\\|$\\)" eob t) | |
(setq head-list (cons (match-beginning 0) head-list)) | |
(forward-line)))) | |
(reverse head-list))) |
eobpはbufferがnarrow状態のときはそこまでしか見てくれません。
また、実際にはsearch-forward-regexpがnilを返した時点でやめられるので、
さらにまとめるとこんな感じでしょうか。
(defun my-find-headings ()
(let ((end (point-max))
(head-list '()))
(save-excursion
(goto-char (point-min))
(while (when (search-forward-regexp "^\*\\([^*]\\|$\\)" end t)
(add-to-list 'head-list (match-beginning 0) t)
(forward-line))))
head-list))
buffer内容は変更しないので(point-max)を繰り返し呼ぶことはせずに
一度取得した値を使い回しています。add-to-listとcons+reverseの
どちらが効率的かはちょっと分かりませんがスライド数がせいぜい数十なら
どちらを選んでも計算量が大きく変わることはないでしょうね。
あ.確かにwhile内部ですね point-max はOrz
ちなみに head-list を '() を nil としないは理由がありますか?
スライド数が数十だと,実は既存の実装でもあまり問題にならなかったりします.
5000千行,スライド数400,キーボードリピート30[ms] という環境でもたつくので,レア環境と言えばそこまでなのですが,でもこの実装はとり込もうと思います!
'()
を使うのは、(これから値を追加していく)空のリストであることを強調したつもりです。
nil
だとnil
であることに(真偽などの)意味があるような気がしてしまうので…。
スライド数が多くなるなら、cons
で結合しておいて最後にnreverse
するのが一番速いと思います。
append
にしてもadd-to-list
にしても毎ループごとにリストの末尾まで辿らないといけませんから。
add-to-list
は破壊的なので、add-to-list
とappend
ならadd-to-list
の方が速いと思います。
うう.たくさんのコメントありがとうございます(T-T)
ノウハウを色々と教えていただいたので本当に勉強になりますっ
リファクタリングしてみました.
リストは reverse する方が高速なのか検証したいところ '-'