2011/02/08

which-func-mode で関数名をヘッダーラインに表示するやつをトグルする

which-func-mode って普段は必要なけど、既存の Emacs Lisp にはクソ長い関数が多いのでたまに必要になる。Emacsテクニックバイブル ~作業効率をカイゼンする200の技~ の P.259 に載ってたのを toggle できるようにした。

(defun toggle-which-func-mode ()
  (interactive)
  (let ((comp (not which-func-mode)))
    (which-func-mode comp)
    (if which-func-mode
        (progn
          (delete (assoc 'which-func-mode mode-line-format) mode-line-format)
          (setq-default header-line-format '(which-func-mode ("" which-func-format))))
      (setq-default header-line-format nil))))

追記

ちょっとバグってた。
(defun toggle-which-func-mode ()
  (interactive)
  (which-func-mode)
  (if which-func-mode
      (progn
        (delete (assoc 'which-func-mode mode-line-format)
                mode-line-format)
        (setq-default header-line-format
                      '(which-func-mode ("" which-func-format))))
    (setq-default header-line-format nil)))

Emacsテクニックバイブル ~作業効率をカイゼンする200の技~

org-mode と linum

org-mode で linum 出してると激遅なのでここを参考に消した。

ところで、bookmark に現れる org-remember-last-stored が目障り。
消したいけど消し方がわからない。

org-remember.el をの中をざっくり探したら org-remember-handler 中でセットされてるっぽかったから、org-remember-handler 内で bookmark-set を identity 関数でシャドウする advice を書いてみたりしたけど、うまくいかなかった。。

Emacsテクニックバイブル ~作業効率をカイゼンする200の技~

2011/02/07

basic 認証、digest 認証

gauche で。

basic 認証

(use rfc.http)
(use rfc.base64)

(define *user* "user")
(define *pass* "password")

(define *server* "hoge.com")
(define *request-uri* "/foo/bar.html")

(define (basic-auth user pass)
  (string-append
   "Basic "
   (base64-encode-string (string-append user ":" pass))))

(receive (status header body)
    (http-get *server* *request-uri*
              :authorization (basic-auth *user* *pass*))

digest 認証

取りあえず動いたっぽい。
(use srfi-1 :only (iota))
(use srfi-13 :only (string-concatenate))
(use srfi-14))
(use rfc.http)
(use rfc.md5)
(use text.tree :only (tree->string))
(use util.list :only (intersperse))
(use math.mt-random)


(define *user* "user")
(define *pass* "password")

(define *server* "hoge.com")
(define *request-uri* "/foo/bar/baz.html")

(define *nc* "00000001")


;; --- random string

(define rand
  (let1 m (make <mersenne-twister>)
    (^ (:optional (len 2))
       (mt-random-integer m len))))

(define (random-char src)
  (string-ref src (rand (string-length src))))

(define (random-string src len)
  (let rec ((len len)(acc '()))
    (if (zero? len)
        (list->string acc)
        (rec (- len 1)(cons (random-char src) acc)))))

(define (sequential-src :optional (len 255))
  (list->string (map integer->char (iota len))))


(define (nonce str)
  (regexp-replace-all*
   (rxmatch->string #/nonce=\".+?\"/ str)
   #/nonce=/ "" #/\"/ ""))

(define (realm str)
  (regexp-replace-all*
   (rxmatch->string #/Digest realm=\".+?\"/ str)
   #/Digest realm=/ "" #/\"/ ""))

(define (qop str)
  (regexp-replace-all*
   (rxmatch->string #/qop=\".+?\"/ str)
   #/qop=/ "" #/\"/ ""))

(define (algorithm str)
  (regexp-replace-all*
   (rxmatch->string #/algorithm=.+?\,/ str)
   #/algorithm=/ "" #/\,/ ""))


(define (make-a1 user pass realm)
  (string-concatenate (intersperse ":" (list user realm pass))))

(define (make-a2 method request-uri)
  (string-append method ":" request-uri))

(define (make-responce a1 a2 nonce nc cnonce qop)
  (let1 dh-md5 (^s (digest-hexify (md5-digest-string s)))
    (dh-md5 (string-concatenate
             (intersperse ":" (list (dh-md5 a1) nonce nc
                                    cnonce qop (dh-md5 a2)))))))

(define (make-cnonce)
  (digest-hexify (md5-digest-string (random-string (sequential-src) 8))))


;; --- test
(receive (status header body)
    (http-get *server* *request-uri*)
  (let ((str (tree->string header))
        (cnonce (make-cnonce)))
    (let1 res (make-responce (make-a1 *user* *pass* (realm str))
                             (make-a2 "GET" *request-uri*)
                             (nonce str) *nc*
                             cnonce
                             (qop str))
      (http-get *server* *request-uri* :authorization #`"Digest username=\",|*user*|\", realm=\",(realm str)\", nonce=\",(nonce str)\", uri=\",|*request-uri*|\", algorithm=MD5, qop=,(qop str), nc=00000001,  cnonce=\",|cnonce|\", response=\",|res|\""))))

ちょっと無理がありつつも。。

(define-class <md5-header> ()
  ((header :init-keyword :header)
   (realm)(nonce)(algorithm)(qop)))

(define-class <md5-cred> ()
  ((server :init-keyword :server)
   (request-uri :init-keyword :request-uri)
   (user :init-keyword :user)
   (password :init-keyword :password)
   (nc :init-keyword :nc :init-value "00000001")
   (method :init-keyword :method :init-value "GET")
   (realm)(nonce)(algorithm)(qop)(cnonce)(a1)(a2)(response)))

(define (md5-header-initialize! mh header)
  (let1 header (tree->string header)
    (slot-set! mh 'realm (realm header))
    (slot-set! mh 'nonce (nonce header))
    (slot-set! mh 'algorithm (algorithm header))
    (slot-set! mh 'qop (qop header)))
  mh)

(define (construct-md5-cred! cred mh)
  (slot-set! cred 'realm (~ mh 'realm))
  (slot-set! cred 'nonce (~ mh 'nonce))
  (slot-set! cred 'algorithm (~ mh 'algorithm))
  (slot-set! cred 'qop (~ mh 'qop))
  (slot-set! cred 'cnonce (make-cnonce))
  (slot-set! cred 'a1 (make-a1 (~ cred 'user)
                               (~ cred 'password)(~ cred 'realm)))
  (slot-set! cred 'a2 (make-a2 (~ cred 'method)(~ cred 'request-uri)))
  (slot-set! cred 'response
             (make-responce (~ cred 'a1)(~ cred 'a2)(~ cred 'nonce)
                            (~ cred 'nc)(~ cred 'cnonce)(~ cred 'qop)))
  cred)

(define (construct-cred-string cred)
  (let ((user (~ cred 'user))
        (realm (~ cred 'realm))
        (nonce (~ cred 'nonce))
        (uri (~ cred 'request-uri))
        (algorithm (~ cred 'algorithm))
        (qop (~ cred 'qop))
        (nc (~ cred 'nc))
        (cnonce (~ cred 'cnonce))
        (response (~ cred 'response)))
    #`"Digest username=\",|user|\", realm=\",|realm|\", nonce=\",|nonce|\", uri=\",|uri|\", algorithm=,|algorithm|, qop=,|qop|, nc=,|nc|,  cnonce=\",|cnonce|\", response=\",|response|\""))


;; --- test
(receive (status header body)
    (http-get *server* *request-uri*)
  (let ((mh (make <md5-header>
              :server *server*
              :request-uri *request-uri*))
        (cred (make <md5-cred>
                :server *server*
                :request-uri *request-uri*
                :user *user*
                :password *pass*)))
    (md5-header-initialize! mh header)
    (construct-md5-cred! cred mh)
    (let1 str (construct-cred-string cred)
      (http-get *server* *request-uri* :authorization str))))

不完全文字列


不完全文字列・・・って?
md5-digest-string はなんで不完全文字列が返ってくるの。。

参考


追記

すごく参考になりました。ありがとうございます!
@valvallow 豆知識:正規表現リテラルの中ではダブルクォートはエスケープしなくてもいいです。 (してもいいです。 正規表現リテラルは Gauche 特有なのでそれを解釈できないエディタの混乱を回避するためにあえてエスケープすることもあります。)
@valvallow 正規表現でマッチした一部を抜き出したいときは括弧で囲んどけばいいですよ。 こんな感じ。 (define(nonce str)((#/nonce=\"(.+?)\"/ str)1))

これ読みてー・・・

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

ランダムな文字列

(use math.mt-random)
(use srfi-14)
(use srfi-1 :only (iota))

(define rand
  (let1 m (make <mersenne-twister>)
    (^ (:optional (len 2))
       (mt-random-integer m len))))

(define (random-char src)
  (string-ref src (rand (string-length src))))

(define (random-string src len)
  (let rec ((len len)(acc '()))
    (if (zero? len)
        (list->string acc)
        (rec (- len 1)(cons (random-char src) acc)))))

(define (sequential-src :optional (len 255))
  (list->string (map integer->char (iota len))))



;; --- test

(dotimes (i 10)
  (print (random-string (char-set->string #[a-zA-Z0-9])
                        (+ 10 (rand 6)))))
;; Bp5xazgBweRl
;; NFihHScYVLrGj
;; KDBNedcogJB
;; YVY5VhDX4c
;; rcSM5CdB8UbUth
;; PDNbRy7l30e3Sn
;; Yn79nl6WyhSn
;; M4ugWYCllpq
;; jItJYe1G5PoM
;; pHCOxjYPra
;; #t


(use rfc.md5)
(use util.digest)
(dotimes (i 10)
  (print (digest-hexify (md5-digest-string (random-string (sequential-src 128) 10)))))
;; 2eccd115ab4cf544972215127d01efb7
;; c6542575cddcbc67a4a151ab042005ff
;; 31edccbadce32cdd3239e16999cfdbc9
;; 13fac266ff5713cc76f665c90db06dfe
;; 61b741f33bdaf81533f23b1837b85f59
;; ad5a55d2992279d8cd9104f8174c7fe1
;; 044bc4528cb92291d060c5b2c40ec4c3
;; 393b43b9cb3db1b758ba9cdc57a75f1e
;; 2c2de35251b753aef7db21b8c50911aa
;; 44fb0ae9f60707329d9ed9c811f8bbad
;; #t


Scheme手習い

2011/02/06

bash のプロンプトに git の branch を表示する


昨日の #9LISP@s1mple さんに教えてもらいました。

この辺を参考にやってみました。
これは良い。Emacs の dired もこんな感じにできないかなー。


あとこんなコマンド
$ find . type f -print0 | xargs -0 grep "hoge"
と sl と dyndns を教えてもらった。
ip アドレス直打ちで serversman にアクセスしてたので、ドメインを取ろうか迷ってるって言ったら、無料の ddns サービスで良いんじゃね?みたいな。

追記

git の branch を表示するようにしてから、Emacs の tramp からアクセスできなくなってしまいました。。で、どうやらプロンプトの色が原因のようです。
ls は、端末エミュレーターが色を変更するための ANSI エスケープシークエンスを出力します。しかしながら、このエスケープ シークエンスは TRAMP を混乱させます。
白黒の設定にしたらつながるようになりました・・・。というのもシャクなので、tramp 用のユーザを作りました。というのもシャクなんですけどね。。

bashクックブック

2011/02/04

知っておくべき大衆プログラマ心理

知っておくべき大衆心理

・有名人につられる
・できないことをしたいと思う、夢がある
・多数派にいたいと思う
・真実を求める
・権威が好き
・自分が他人からどう見られるかを気にする
・心配性 (不安症)
・ステータスに憧れる

  • ポール・グレアムにつられる
  • Lisp ですごいことをしたいと思う、すごいプログラマになりたい夢がある
  • Java 派にいたいと思う
  • はてブを求める
  • 言語の中の人が好き
  • 自分のコードが他人からどう見られるかを気にする
  • 中二病
  • ハッカーに憧れる

情熱プログラマー ソフトウェア開発者の幸せな生き方

2011/02/03

日記(git, dired, emacs, org, ajaxterm)

どうでも良いような小ネタを1つの記事にするのもいい加減面倒。というかウザい。1つの日記にまとめて書いた方が良いかもー。でもタイトルの付け方がわからなくなるし、あとで見るとき探しにくいんだー。。
org-remember でメモ取るくらい手軽にブログの記事が書けるようにできないかな。

git

仕事でも使うので、もっとちゃんと思想(?)とか使い方とか知っておこうと思いました。

で、Pro Git の和訳を一通り読みました。
今までも github を適当に使ってたんですが、使い方間違ってました。すごく間違ってました。もっと早く読んでおけばよかった。ブランチのとこすげー。

今まで仕事でつかったことがあるのは VSS だけでした。VSS とはなんだったのか。

ajaxterm.py

serversman で ps eaxl したら ajaxterm.py ってのがありました。検索してみたら web から使えるターミナルとのこと。
使わないので停止しました。

dired

マークして R するとファイルをまとめて移動できる。
v で view-mode で開ける。

Meta key + Fn

Emacs で F1(ヘルプ)、 F3 と F4 (キーボードマクロの登録と実行)以外はよく使うコマンドに割当てているんですが、一つのキーに複数のコマンドを登録できたら良いのになーと。思ったら、C と M との同時押しを割当てれば良いわけか。
  • F1 : help
  • F2 : org-remember
  • F5 : 職場の org メモ(読み取り専用)
  • F6 : ローカルの org メモ
  • F7 : .emacs + view-mode
  • F8 : goto-chg.el の goto-last-change
  • F9 : point-undo.el の point-undo
  • F10 : view-mode
  • F11 : linum
  • F12 : frame-arrange.el の frange:cycle-arrange-config-gen の戻り値

としていました。それに加えて
  • M-F2 : もう一つの org-remember
  • M-F6 : もう一つの org メモ
  • M-F12 : nav
にしてみました。

今のところ大丈夫だけど、あんまりやり過ぎると流石に憶えきれないかも。

org

org-mode も org-remember もまじで便利。特に org-remember と org-agenda が。
org-remember に [T]odo とか [M]emo とかをたくさん登録し過ぎると不便になるので、カテゴリごとに分けれたら良いのに。。と思ったらできました。こういう時ダイナミックスコープって便利なんだなー。と、rubikitch さんの org-remember-code-reading を見て気づいた。

The Org Mode 7 Reference Manual - Organize Your Life with GNU Emacs

postgres timestamp

どうも postgres 初心者です。date 型と time 型はあるけど、datetime 型ってないの?ドキュメントには datetime ってあるけど、pgAdmin で見あたらない。。
ということで  @kikuchan98 さんに聞いてみたら、どうやら欲しいのは timestamp 型っぽい。
postgres=# select current_timestamp;
   now
   -------------------------------
   2011-02-02 13:50:27.402093+09
   (1 行)

   postgres=# select extract(epoch from current_timestamp);
   date_part
   ------------------
   1296622247.69678
   (1 行)

   postgres=#


たまに日付を扱うときに int 型で扱ってる DB ありませんか。datetime 型じゃなくて int 型を使うメリットって何かあるんでしょうか。話によると varchar なとこもあったりするそうでェ。
実際、昔勤めていた会社が日付を int 型で扱ってたんですよね。20110203 みたいな。理由を聞いてもハッキリしたことは教えてもらえませんでした。なんとなく、だったのかな。お陰で日付を扱うのが面倒でしたよ。


新標準PostgreSQL (オープンソースRDBMSシリーズ)

Emacs の dired の表示項目を変更したかった


けど、あんまりできなかった。

普段は通常の表示で良いんですが、ファイル名だけ表示したいこととかないですか。dired-listing-switches ってのがあると知って喜んだんですが、思ったほど融通が利かないようで。

dired を開くときに「通常の表示」と「指定した項目だけの表示(例えば項目名だけとか)」ってな感じでトグルできると嬉しいようなそうでもないような。

そういえばこんなのが。
新しいの入れたら nav-toggle なくなってる・・・?
(require 'nav)
(define-key global-map (kbd "M-<f12>") 'nav)
q で終了か。

Emacsテクニックバイブル ~作業効率をカイゼンする200の技~

2011/02/01

「ランダムにビット列を作っていったら、[0,0,1] が最初に登場するのは、いつ頃でしょう?」

ランダムにビット列を作っていったら、[0,0,1] が最初に登場するのは、いつ頃でしょう?
自分でも試してみました。リストでも良いですよね。
(use math.mt-random)
(use srfi-1)

(define rand
  (let1 m (make <mersenne-twister>)
    (^ ()
       (mt-random-integer m 2))))

(define (first-occurrence pat)
  (let rec ((ls '()))
    (let ((plen (length pat))
          (llen (length ls)))
      (if (and (<= plen llen)
               (equal? (split-at ls plen) pat))
          llen
          (rec (cons (rand) ls))))))


(define (times i expr)
  (let rec ((i i)(acc '()))
    (if (or (negative? i)(zero? i))
        acc
        (let1 r (expr i)
          (rec (- i 1)(cons r acc))))))

(define (average ls)
  (round->exact (/ (apply + ls)(length ls))))

;; ;(time (average (times 10000 (^ _ (first-occurrence '(0 0 1))))))
;; ; real   0.313
;; ; user   0.313
;; ; sys    0.000
;; 8

;; ;(time (average (times 10000 (^ _ (first-occurrence '(0 0 0))))))
;; ; real   0.563
;; ; user   0.562
;; ; sys    0.000
;; 14

ほんまや。

プログラミングのための確率統計