バッファ間を手軽に行き来する

ここからhttp://q.hatena.ne.jp/1137478760
このサイトを発見!。便利そうなので少しいじって導入。
http://www-tsujii.is.s.u-tokyo.ac.jp/~yoshinag/tips/elisp_tips.html#buffer

変えたところ。

  • バッファ間の移動する処理に名前をつけた
    • goto-prev-buffer
    • goto-next-buffer
  • easy-buffer-move.elという名前で別のファイルに分けた(.emacsが長くなるのが嫌なので…)

作ったファイルはこんな感じ。(easy-buffer-move)

(defvar my-ignore-blst             ; 移動の際に無視するバッファのリスト
  '("*Help*" "*Compile-Log*" "*Mew completions*" "*Completions*"
     "*Apropos*" "*Buffer List*"));; "*Shell Command Output*"))
(defvar my-visible-blst nil)       ; 移動開始時の buffer list を保存
(defvar my-bslen 15)               ; buffer list 中の buffer name の最大長
(defvar my-blist-display-time 2)   ; buffer list の表示時間
(defface my-cbface                 ; buffer list 中で current buffer を示す face
  '((t (:foreground "wheat" :underline t))) nil)

(defun my-visible-buffers (blst)
  (if (eq blst nil) '()
    (let ((bufn (buffer-name (car blst))))
      (if (or (= (aref bufn 0) ? ) (member bufn my-ignore-blst))
          ;; ミニバッファと無視するバッファには移動しない
          (my-visible-buffers (cdr blst))
        (cons (car blst) (my-visible-buffers (cdr blst)))))))

(defun my-show-buffer-list (prompt spliter)
  (let* ((len (string-width prompt))
         (str (mapconcat
               (lambda (buf)
                 (let ((bs (copy-sequence (buffer-name buf))))
                   (when (> (string-width bs) my-bslen) ;; 切り詰め 
                     (setq bs (concat (substring bs 0 (- my-bslen 2)) "..")))
                   (setq len (+ len (string-width (concat bs spliter))))
                   (when (eq buf (current-buffer)) ;; 現在のバッファは強調表示
                     (put-text-property 0 (length bs) 'face 'my-cbface bs))
                   (cond ((>= len (frame-width)) ;; frame 幅で適宜改行
                          (setq len (+ (string-width (concat prompt bs spliter))))
                          (concat "\n" (make-string (string-width prompt) ? ) bs))
                         (t bs))))
               my-visible-blst spliter)))
    (let (message-log-max)
      (message "%s" (concat prompt str))
      (when (sit-for my-blist-display-time) (message nil)))))

(defun my-operate-buffer (pos)
  (unless (window-minibuffer-p (selected-window));; ミニバッファ以外で
    (unless (eq last-command 'my-operate-buffer)
      ;; 直前にバッファを切り替えてなければバッファリストを更新
      (setq my-visible-blst (my-visible-buffers (buffer-list))))
    (let* ((blst (if pos my-visible-blst (reverse my-visible-blst))))
      (switch-to-buffer (or (cadr (memq (current-buffer) blst)) (car blst))))
    (my-show-buffer-list (if pos "[-->] " "[<--] ") (if pos " > "  " < " )))
  (setq this-command 'my-operate-buffer))

;;元の設定
;;(global-set-key [?\C-,] (lambda () (interactive) (my-operate-buffer nil)))
;;(global-set-key [?\C-.] (lambda () (interactive) (my-operate-buffer t)))

(defun goto-prev-buffer () (interactive)
  (my-operate-buffer nil))

(defun goto-next-buffer () (interactive)
  (my-operate-buffer t))

(global-set-key [?\C-\;] 'goto-prev-buffer) 
(global-set-key [?\C-:] 'goto-next-buffer) 
;;"C-\;"と"C-:"で移動。
(provide 'easy-buffer-move)

.emacs

;;add-load-path
(add-to-list 'load-path "~/box/fuga/hoge)) ;;.elが格納されているディレクトリのパス

;;easy-buffle-move
(require 'easy-buffer-move)
(global-set-key [?\C-\;] 'goto-prev-buffer)
(global-set-key [?\C-:] 'goto-next-buffer)

すごく便利!!

(sicp23)m2.61~m2.62

今度はソートされている集合の話

(use pre-sicp)

(define (element-of-set? x set)
  (cond ((null? set) #f)
        ((= x (car set) #t))
        ((< x (car set)) #f)
        (else (element-of-set? x (cdr set)))))

(define (intersection-set set1 set2)
  (if (or (null? set1) (null? set2))
      '()
      (let ((x1 (car set1)) (x2 (car set2)))
        (cond ((= x1 x2)
               (cons x1
                     (intersection-set (cdr set1)
                                       (cdr set2))))
              ((< x1 x2)
               (intersection-set (cdr set1) set2))
              ((< x2 x1)
               (intersection-set set1 (cdr set2)))))))

(intersection-set '(1 2 3 4) '(2 4 6 8))
;;	 gosh> (2 4)

;;m2.61
(define (adjoin-set x set)
  (if (< x (car set))
      (cons x set)
      (cons (car set) (adjoin-set x (cdr set)))))

;; 順序づけられていない場合、要素が集合内に存在していないかどうか調べるには、
;; その集合内のすべての要素を調べなければならない。
;; 一方、順序づけられていた場合、最低でも加えたい要素以下の数が存在しないことを確かめれば済む。
;; (これで、おおよそ半分ぐらいのステップ数で済む)

(adjoin-set 3 '(1 2 4))
;;	 gosh> (1 2 3 4)


;;m2.62
(define (union-set set1 set2)
      (cond ((null? set1) set2)
            ((null? set2) set1)
            (else
             (let ((x1 (car set1))(x2 (car set2)))
               (cond 
                ((= x1 x2)
                 (cons x1 (union-set (cdr set1) (cdr set2))))
                ((< x1 x2)
                 (cons x1 (union-set (cdr set1) set2)))
                ((< x2 x1)
                 (cons x2 (union-set set1 (cdr set2)))))))))

;; letの位置が重要。
;; (elseの前につけてしまうと、最後にset1もしくはset2が空になったときに,
;; 「pair required, but got ()」というエラーがでてしまう。)

;; あとは、O(n)かどうかについて考える。
;; どちらかの集合がnullである場合を除くと、行われる処理は3種類存在する。
;; この3種類の処理は最低でもset1,2のどちらかの要素数が1つ減る。
;; 比較は現在さしている要素(x1とx2)だけですむので、
;; ステップ数の最大は (+ (length set1) (length set2))になる。
;; なのでたぶんO(n)を満たしている。

(union-set '(1 2 3 4 5) '(2 4 6 8))
;;	 gosh> (1 2 3 4 5 6 8)