Hatena::ブログ(Diary)

技術日記@kiwanami

2011-07-23

[emacs][ui] Emacs用カレンダー calfw v1.2 リリース

もうちょっと早く紹介記事を書くつもりだったのですが、orgmode の本家 ML から召喚されて、2週間ほど ML での対応やパッチ取り込み、細かい機能追加などを行っておりました。ということで、 v1.0 から飛んで v1.2 になりました。

calfw ?

Emacs 上でふつうに使えることを目指したカレンダーアプリです。こんな感じのよくあるレイアウトで表示します。

画面イメージ

以前の記事もある程度参考になると思いますが、設定方法が変わっていますので気をつけてください。

以前(v0.2.1)からの主な変更点

  • API の整備
    • カレンダーのネタ提供をグローバル変数をやめて、構築時の引数で指定
    • cfw:source でスケジュールを構築、複数組み合わせ
  • UIの強化

画面と操作

画面概要

こんな感じで、上にナビゲーションやビューを変更するツールバー、下側にカレンダーのネタを提供するステータスバーが付いています。よくあるカレンダーアプリと同じような構成です。

画面概要:ツールバーとステータスバー

今のところ以下の4種類のビューがあります。

ビューの種類:月、2週、1週、1日

カレンダーの表示内容は以下のようです。(以前のものの再掲)

カレンダーの表示内容

SPC キーで Macクイックルックのように、その日の詳細バッファをさっと開いて確認することが出来ます。もう一度 SPC を押すと引っ込みます。

詳細バッファの表示

キーバインド

cfw:calendar-mode-map で以下のように定義しています。

操作
[left], b, h 前の日
[right], f, l 次の日
[up], p, k 前の週
[down], n, j 次の週
^ 週の頭
$ 週末
[home] 月の初め
[end] 月末
M-v, [PgUp], < 前の月
C-v, [PgDown], > 次の月
t 今日へ
g 日付指定移動 (YYYY/MM/DD)
ビュー
M 月表示
W 週表示
T 2週表示
D 日表示
操作
r 内容更新
SPC 日の詳細表示 ( Mac の Quicklook 的)
RET, [click] 定義に移動 (howm, orgmode)
q バッファ隠す

以前のユーザー向け

既に calfw を使われている方は以下の点を確認して必要があれば設定を修正してください。先日紹介いただいた Ubuntu Recipe の記事 の内容からも変更が有ります。

howm : 設定に変更無し
  • 以前の記事通りであれば変わらないはず
  • アップデートしたらそのまま使えるはず
  • 期間スケジュールの対応 (new!)
    • [2011/07/04]@4 と書くと 7/4 〜 7/7 までの期間スケジュール表示になる
ical : 設定に変更が必要
  • まるっきり変わってしまったので、次の節の「導入方法」の内容を参照
org : 設定に修正が必要
  • cfw:install-org-schedules の廃止
    • cfw:install-org-schedules の行を消すだけで OK
  • org 用の設定をいくつか追加

導入方法

必要なものはEmacs本体(手元では23.2で試しています)だけです。

ダウンロード

カレンダー本体 calfw.el については auto-install.elで以下の式を評価して入れるか、ダウンロードしてload-pathの場所に置いてください。

;; auto-installを使う場合
(auto-install-from-url "https://github.com/kiwanami/emacs-calfw/raw/master/calfw.el")

ダウンロード

他の拡張も合わせて使うような人は git clone しておくと便利かもしれません。

後、GentooDebian にはパッケージがあるそうです。メンテナーの皆さんありがとうございます。

基本設定

以下のコードを評価すると今月のカレンダーが表示されます。

(require 'calfw) ; 初回一度だけ
(cfw:open-calendar-buffer) ; カレンダー表示

calfw 自体はカレンダーが必要なアプリケーションのためのコンポーネントという立場なので、それ自体ではカレンダーが表示されるだけで余りうれしくありません。

howm などのスケジュールを管理するアプリと一緒に使うことで威力を発揮します。

スケジュール管理との組み合わせ

howm

howmのスケジュールやTODOをカレンダー内に表示することが出来ます。まず以下の追加プログラムインストールします。

最小限の連携コードは以下のようです。

(require 'calfw-howm)
(cfw:install-howm-schedules)
(define-key howm-mode-map (kbd "M-C") 'cfw:open-howm-calendar)

これで、 howm-mode 使用時(howmのメニューなど)で M-C で howm のカレンダーを表示することが出来ます。

また、予定のある日付で Enter キーを押すと、日付で howm の記事を検索します。ここから予定の編集などが出来ます。qでカレンダーバッファを終了(kill-buffer)します。

HowmとElscreenの連携を使っている人は、バインド先のコマンドはこちらの方が良いかもしれません。

(define-key howm-mode-map (kbd "M-C") 'cfw:elscreen-open-howm-calendar)

こちらは新しいスクリーンを作成してそちらでカレンダーを表示します。

さらに、howmのメニューファイルに以下の行を追加すると、そこにカレンダーを表示させます。

%here%(cfw:howm-schedule-inline)

この場合、以下のような画面になります。

Howmのメニューに表示!

さらに、このカレンダー内部では前述の日付移動のキーバインドが使えますので、メニュー内で日付や月の移動、またその日の予定一覧の表示が出来ます。

さらに、自分は予定は一つのメモ(「2010年予定」とか)に集約しているのですが、そうするとカレンダーから日付を選んで予定を入力するように出来ます。自分が使っているHowm連携のコードは以下のようです。

;; howm and calendar framework

(defvar my-howm-schedule-page "2011年予定") ; 予定を入れるメモのタイトル

(defun my-cfw-open-schedule-buffer ()
  (interactive)
  (let* 
      ((date (cfw:cursor-to-nearest-date))
       (howm-items 
        (howm-folder-grep
         howm-directory
         (regexp-quote my-howm-schedule-page))))
    (cond
     ((null howm-items) ; create
      (howm-create-file-with-title my-howm-schedule-page nil nil nil nil))
     (t
      (howm-view-open-item (car howm-items))))
    (goto-char (point-max))
    (unless (bolp) (insert "\n"))
    (insert
     (format "[%04d-%02d-%02d]@ "
             (calendar-extract-year date)
             (calendar-extract-month date)
             (calendar-extract-day date)))))

(eval-after-load "howm-menu"
  '(progn
     (require 'calfw-howm)
     (cfw:install-howm-schedules)
     (define-key howm-mode-map (kbd "M-C") 'cfw:elscreen-open-howm-calendar)
     (define-key cfw:howm-schedule-map (kbd "i") 'my-cfw-open-schedule-buffer)
     (define-key cfw:howm-schedule-inline-keymap (kbd "i") 'my-cfw-open-schedule-buffer)
     ))

(setq cfw:howm-schedule-summary-transformer 
  (lambda (line) (split-string (replace-regexp-in-string "^[^@!]+[@!] " "" line) " / ")))

これで普通のスケジュール管理(Google Calendar, iCal, Outlookなど)と同じように、「カレンダーから開いている日を探して予定を入れる」というユースケースが実現できるようになりました。

org

Emacs の万能情報管理ツール orgmode との連携です。現在、 orgmode の本家 ML で機能追加などが議論されています。

org-agenda をカレンダーで表示するには、 Emacs の設定ファイルの適当なところに以下のように1行加えます。

(require 'calfw-org)

後は、 M-x cfw:open-org-calendar とすると、カレンダーで表示されるはずです。グローバルキーバインドに割り当てておけば、一発で開くことが出来て多分便利です。

org-agenda のカレンダー表示

cfw:org-agenda-schedule-args の変数に :scheduled :sexp :closed :deadline :todo :timestamp などを入れることによって、表示する内容を多少絞ることが出来ます。

google calendar

Google CalendariCal などの iCalendar(ICS)形式を表示することができます。(現在まだ繰り返しスケジュールが表示できません)

Google Calendar との最小限の連携コードは以下のようです。

(require 'calfw-ical)

(defun open-my-ical ()
  (interactive)
  (cfw:open-ical-calendar "http://www.google.com/calendar/ical/.../basic.ics"))

この場合 M-x open-my-ical とするとカレンダーが開きます。

適当なキーにバインドすると便利だと思います。

Google CalendarURL はカレンダーの設定の以下の場所から取得できます。

Google Calendar での URL の確認

ローカルの ICS ファイルを指定することも出来ます。

また、複数のカレンダーを同時に表示することも出来ます。次の「混ぜて表示」のコードを参照してください。

混ぜて表示

org と ical のスケジュールを混ぜて表示させることが出来ます。以下のような感じで cfw:open-calendar-buffer を使います。

(require 'calfw-org)
(require 'calfw-ical)

(defun my-open-calendar ()
  (interactive)
  (cfw:open-calendar-buffer
   :view 'month
   :contents-sources
   (list 
    (cfw:org-create-source "Seagreen4") ; color
    (cfw:ical-create-source "my calendar" "https://www.google.com/calendar/ical/../basic.ics" "Pink")
    (cfw:ical-create-source "共有スケジュール" "https://www.google.com/calendar/ical/../basic.ics" "#2952a3"))))
    ;; title, URL, color

M-x my-open-calendar とすると、org と ical を一緒に表示することが出来ます。

cfw:open-calendar-buffer やカスタマイズの詳細については次回の記事に書く予定です。

その他

MHC とか diary とか、他にもスケジュールを管理するアプリがあります。

diary については、現在取りかかりのコードをもらったので後で追加すると思います。

カスタマイズ

ここでは簡単なカスタマイズだけ書きます。詳細な拡張方法などについては次回の記事に書く予定です。

キーバインド

カレンダー全体のキーバインドを変更する場合は cfw:calendar-mode-map で設定します。

個別のカレンダーごと、あるいはカレンダーのソースごとに追加のキーバインドを設定することが出来ます。(次回予定)

祝日設定

日本用の祝日を表示させるために japanese-holiday.el を入れておくと便利です。

自分の所では以下のように書いています。

(add-hook 'calendar-load-hook
          (lambda ()
            (require 'japanese-holidays)
            (setq calendar-holidays
                  (append japanese-holidays local-holidays other-holidays))))
月、曜日の表記

月や曜日の表示は calendar.el の設定をそのまま使っています。以下のコードを修正すれば変更できると思います。

;; 月
(setq calendar-month-name-array
  ["January" "February" "March"     "April"   "May"      "June"
   "July"    "August"   "September" "October" "November" "December"])

;; 曜日
(setq calendar-day-name-array
      ["Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday"])

;; 週の先頭の曜日
(setq calendar-week-start-day 0) ; 日曜日は0, 月曜日は1
Face (色とか)

calfw.el の先頭に face の設定があります。その設定を参考に調整すると良いと思います。

以下の方々の設定がとても参考になると思います。

次回予定

例によって時期は未定ですが、以下の項目を予定しています。

(2011/07/25 追記:複数icalendar表示のコード追加)

@h_kenken@h_kenken 2011/07/27 13:35 ical-calendar-contents-sourcesは無くなっちゃったんでしょうか。
howm-schedule-inline で googleカレンダーを表示したいのですがどうしたら良いでしょうか。

@h_kenken@h_kenken 2011/07/27 14:23 いつも便利に使わせていただいております。

kiwanamikiwanami 2011/07/27 15:25 howmと他を混ぜる方法が無くなってました。すいません。
ちょっと直してみます。

@h_kenken@h_kenken 2011/07/27 15:32 手元では cfw:howm-schedule-inline-sources とか適当に作っちゃって contents-sources に突っ込んじゃいました。
公式での対応よろしくお願いいたします。

@h_kenken @h_kenken 2011/07/27 15:35 色とか換えられたり前より便利。

kiwanamikiwanami 2011/07/27 16:12 今 github の master に push しました。
https://gist.github.com/1108833
こんな感じの設定を書くことでhowmにカレンダーを追加できます。どうでしょうか?

kiwanamikiwanami 2011/07/27 16:14 行き違いになってしました。多分、同じような修正になっていると思います!

@h_kenken@h_kenken 2011/07/27 16:54 お、ありがとうございます。

@yasuhito@yasuhito 2013/10/21 23:40 GitHub にチケットとして出すべきかもしれませんが質問させてください。
calfw に表示する/しないアイテムのカスタマイズはどこでできるでしょうか?

自分は org-mode と calfw を組み合わせて使っています。org-mode に habit をたくさん登録しているため、calfw で見ると毎日の予定が habit に埋もれてしまいます。もしこのあたりがカスタマイズできるようでしたら教えてくださいませ。

kiwanamikiwanami 2013/10/22 00:32 ちょっと自分がorg-modeを真面目に使ってないのでよくわからないのですが、確かにヘビーに使っていると項目が多くなって大変そうですよね。
calfwはorg-agenda-get-day-entriesで項目を取ってきているので、この関数の最後のパラメーターで取ってくるものを調整できるようです。これは、cfw:org-agenda-schedule-args で制御できるのですが、 :todo とか '(:scheduled :timestamp) とか設定するとよさそうです。試してませんが、以下の感じで。

(setq cfw:org-agenda-schedule-args '(:todo))

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証