kokomadeyonda (xyttr Advent Calendar 12日目)

この記事はxyttr Advent Calendar 2011の記事です。

月曜日なので(?)小ネタ。
カーソル位置より下のツイートを削除します。

(in-package :xyttr)

(defun kokomadeyonda ()
  (interactive)
  (w/buffer-modifying ()
    (forward-entry)
    (w/entry ((:id _id))
      (whenlet start (entry-point)
        (delete-region start (point-max))
        (recenter)
        (setf #0=(timeline-alldata buffer-timeline)
              (delete-if #'(lambda (e) (w/json (id) e (<= id _id))) #0#))))
    (w/entry (id)
      (setf (timeline-first-id buffer-timeline) id))))

(define-key *xyttr-timeline-keymap* '(#\C-k #\C-k) 'kokomadeyonda)

栞ならマーク(Ctrl+Space)とかでも良いですが、何度も遡って読み返す事もなければ綺麗サッパリ消しちゃいましょう。



以下、補足としてコード上の初出要素の解説。

◆ マクロ w/buffer-modifying ((&optional buf) &body body)

bufで指定したread-onlyなバッファ(省略時はselected-buffer)を、一時的に書き込み可能な状態にしてbodyを評価します。
もうちょっと良い名前が欲しいんだけど思いつかない…

◆ マクロ w/entryのリネーム束縛構文

(w/entry (id text)
  ...)

という書き方は2日目に説明しましたが、以下のように書くと束縛するシンボルの名前を変更できます。

(w/entry ((:field-name sym) ...)
  (do-something sym))

:field-name がjsonのキー名で、symが値を束縛するシンボルです。
user.screen_name や user.profile_image_url等の長い名前の値を使い回す時は、この構文を使って短い名前で束縛しておくと良いです。

(w/entry ((:user.screen_name name)
          (:user.profile_image_url imgurl))
  (format nil "<img src=\"~A\"> ~A~%" imgurl name))

◆ xyttr::buffer-timeline

バッファーローカル変数xyttr::buffer-timelineには、タイムラインの各種パラメータ(使用API, APIパラメータ, リロード間隔等)や取得済みツイートデータ等がxyttr::timeline構造体として保存されています。

;; timeline構造体定義
(defstruct timeline
  user        ; ユーザー名 (= screen_name)
  tokens      ; 未使用 (アクセストークンを保管する予定)
  mode        ; タイムラインモード名 (:home-timeline, :user-timeline, etc)
  apifunc     ; 使用API (#'api-home-timeline-async, #'api-user-timeline-async, etc)
  params      ; リロード/次ページ取得時にapifuncへ渡す基本パラメータ
  auto-reload ; 自動リロードの間隔 (秒数 or nil)
  (unread 0)  ; 未読件数
  request     ; リロード/次ページ取得リクエストのキャンセルオブジェクト
  alldata     ; 表示中の全ツイートデータのリスト
  last-id     ; 最新ツイートのid (リロード時に使用)
  first-id    ; 最古ツイートのid (次ページ取得時に使用)
  (page 0)    ; 未使用
  )

全ツイートデータへシーケンシャルにアクセスしたい場合はこの変数からデータを取得すると良いです。

;; 表示中のツイート数を表示
(msgbox "~D" (length (timeline-alldata buffer-timeline)))

alldata以外のスロットの内容の書き換えは、間違うとリロード処理が狂ったりするので注意してください。