[emacs] 二分移動
二分移動コマンドを書いてみました。行内を二分探索の要領で移動します。
ctrl+U ctrl+U ctrl+U ctrl+Fとかよく打つ人にお勧めです。
defvarとか使い方よくわかってないのでまずいところあったら教えてくださると嬉しいです。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 二分移動 (defvar binary-move-fence-beginning nil) (defvar binary-move-fence-end nil) (defvar binary-move-overlay nil) (defun binary-move-set-overlay () (if binary-move-overlay (move-overlay binary-move-overlay binary-move-fence-beginning binary-move-fence-end (current-buffer)) (progn (setq binary-move-overlay (make-overlay binary-move-fence-beginning binary-move-fence-end)) (make-face 'binary-move-face) (set-face-background 'binary-move-face "LightSteelBlue1") ) (overlay-put binary-move-overlay 'face 'binary-move-face)) ) (defun binary-move-forward (arg) (interactive "p") (while (save-excursion (beginning-of-line) (looking-at "[ \t]*$")) (next-line)) (dotimes (i arg) (if (or (eq last-command 'binary-move-forward) (eq last-command 'binary-move-backward)) (setq binary-move-fence-beginning (point)) (progn (setq binary-move-fence-beginning (point)) (setq binary-move-fence-end (line-end-position)))) (binary-move-set-overlay) (goto-char (/ (+ binary-move-fence-beginning binary-move-fence-end) 2)) (if (= (1- arg) i) (sit-for 1.0)) (move-overlay binary-move-overlay (point) (point)) )) (defun binary-move-backward (arg) (interactive "p") (while (save-excursion (beginning-of-line) (looking-at "[ \t]*$")) (previous-line) (end-of-line)) (dotimes (i arg) (if (or (eq last-command 'binary-move-forward) (eq last-command 'binary-move-backward)) (setq binary-move-fence-end (point)) (progn (setq binary-move-fence-beginning (line-beginning-position)) (setq binary-move-fence-end (point)))) (binary-move-set-overlay) (goto-char (/ (+ binary-move-fence-beginning binary-move-fence-end) 2)) (if (= (1- arg) i) (sit-for 1.0)) (move-overlay binary-move-overlay (point) (point)) )) (global-set-key [?\C-\M-,] 'binary-move-backward) (global-set-key [?\C-\M-.] 'binary-move-forward)
暇つぶし
遅延評価のカスタマイズって
言語がサポートすれば簡単にサポートできるはずなのに
なんでそれやってる言語ってみかけないのかね、
なんて思ってたが
最近は私ごときでは
言語オタクとはとても名乗れない状況なので
誰か教えてくれないかななんておもいつつ
C++で実装してみることにした。
(それ自体すでに存在しそうな気もする)
テンプレートパラ−メータへのキャストあたりを
使うと、字面上で普通の変数と区別できなくなってしまうが、
とりあえずそれをやってみる。
クラス名はschemeに習ってpromise。
あとせっかくなので遅延評価じゃなくてスレッドにしてみた。
#include <boost/thread.hpp> #include <iostream> template < class T > class promise { public: template < class F > // T () promise(F f) : thread_(boost::bind( &stub<F>, boost::ref(value_), f )) { } ~promise() { thread_.join(); } operator T () { thread_.join(); return value_; } private: template < class F > static void stub(T& value, F f) { value = f(); } private: T value_; boost::thread thread_; }; int main() { promise<int> p([]()->int{ return std::cin.get(); }); std::cout << (int)p << std::endl; return 0; }
まあなんかそれなりに使えそうな気がしないでもない。
キャストだと字面でわからなくて危険なので、forceとかしてみようか。
T force() {
thread_.join();
return value_;
}
でも字面が面倒だとlambdaをautoで持つのとどう違うのか、という
疑問が生ずるな。
ならいっそのこともっと手を抜いて
template < class R > operator R () { thread_.join(); return static_cast<R>(static_cast<T>(value_)); }
とするか。
気が向いたらcopyableにしとくかな。
内部でthread_pool使うようにしたら
TopCoderでmemoization代わりに使ったりできないかな。