Gistの表示 (xyttr Advent Calendar 4日目)
この記事はxyttr Advent Calendar 2011の記事です。
今回はタイムラインに流れてきたGistの内容をxyzzy内で表示する拡張を書いてみます。
githubはGists APIを提供していて、JSON形式で簡単にGistの投稿内容を取得できます。
これを使ってコマンドを作りましょう。
(in-package :xyttr) ;;; カーソル下のGist URLの内容を表示する (defun show-gist () (interactive) ; カーソル下のURLを取得 (whenlet url (expand-focused-url) ; gistのURLだったらIDを取得 (whenlet id (and (string-match "https://gist\\.github\\.com/\\([0-9]+\\)\\(#.+\\)?$" url) (match-string 1)) ; Gists APIを使って投稿内容を取得する (let ((res (xhr:xhr-get (concat "https://api.github.com/gists/" id) :key #'xhr:xhr-response-text))) ; 投稿者名/投稿日時/permalink/投稿内容を抽出 (w/json (user.login updated_at html_url files) (json:json-decode res) ; テンポラリバッファに出力 (with-output-to-temp-buffer ((format nil "*gist:~A*" id) t t) (format t "# ~A~%# ~A [~A]~%" html_url (or user.login "anonymous") updated_at) (dolist (f files) (w/json (filename content size) (cdr f) (format t "# ~A [~A bytes]~%~40@{-~}~%~A~%~%" filename size content))))))))) (define-key *xyttr-timeline-keymap* '#\g 'show-gist)
上記のコードは投稿内容が複数ファイルでも1バッファに詰めこんで表示します。
ファイルごとにバッファを分けて表示したいなーという場合は次のようにします。
(in-package :xyttr) ;; Gistのファイル1個表示 (defun popup-gist-file (id filename content) (let ((buf (get-buffer-create (concat "gist/" id "/" filename)))) (erase-buffer buf) (with-output-to-buffer (buf) (princ content)) (set-buffer buf) ;; せっかくなのでメジャーモード設定 (whenlet mode (assoc filename *auto-mode-alist* :test #'(lambda (fn pat) (string-match pat fn))) (funcall (cdr mode))) (set-buffer-modified-p nil buf))) ;; コマンド本体 (defun show-gist2 () (interactive) (whenlet url (expand-focused-url) (whenlet id (and (string-match "https://gist\\.github\\.com/\\([0-9]+\\)\\(#.+\\)?$" url) (match-string 1)) (let* ((res (xhr:xhr-get (concat "https://api.github.com/gists/" id) :key #'xhr:xhr-response-text)) (files (json-value (json:json-decode res) files))) (dolist (f files) (w/json (filename content) (cdr f) (popup-gist-file id filename content))))))) (define-key *xyttr-timeline-keymap* '#\G 'show-gist2)
保存したいなーと思ったらC-x C-n→パス指定→C-x C-s あるいは M-x save-as-dialogから保存するのが簡単です。
以上、Gist表示コマンドの実装例でした。