Categoryelisp

Emacs interface to Ditz issue tracking system

Ditz はとても素晴らしいと思います! – ¬¬日常日記で知った、コンソールベースのBTSであるところのDitzがいい感じだなーと思った。しかしやっぱり、せっかくだからEmacsから使いたいと思ったので、それっぽいのを書いてみた。

まあ色々と微妙なところもあるけど、使っていくうちに改善していければいいな。まだあんまり使ってないのでアレだけど、プロジェクトのソースツリーの中に使い勝手のいいTODOリストをつっこんでおくというのは、普通なようでいて、けっこういいかもしれんね。なにやるんだっけー、って時に、単なるTODOリストや作業ログファイルじゃなくて、コマンド一発でリストされたり、編集できたりするのはいい感じ。あと、ditz htmlコマンドを使えば、ditz Issue Trackerこんな感じでHTMLファイルも書き出せたりするので、これを見えるとこに置いておけばよい。

Ditz自体の使い方については上記の紹介エントリや、DitzのREADMEを見ていただくとして、以下にditz.elのREADMEをコピペしておきます。コンソールから使うのと、そんなに変わらないのけど、せっかくEmacsから使うようにしたので、ちょっと楽になるかも。

基本的には、ditz-todoを使いまくる。ditz-add/ditz-add-releaseでタスクを追加し、作業の進捗につれて、ditz-todoでリストアップしたissueやreleaseを、s(show), c(close), r(release)して消していく感じ。

ともあれ、GitHubで公開しているので、フィードバックいただけるとありがたいです(リポジトリのフォーク→pull requestとか、コミッタに登録しろ!とか)。

README for emacs-ditz
=====================
* Description
emacs-ditz provides ditz.el, Emacs interface to Ditz issue tracking
system. You can get Ditz from http://ditz.rubyforge.org/.
* Usage
(1) Checkout from repository.
$ git clone git://github.com/kentaro/emacs-ditz.git
(2) Add the checkout directory into your load-path.
(add-to-list 'load-path "/path/to/emacs-ditz")
(3) Load dzit.el.
(require 'ditz)
(4) Set some variables as you like.
;; Path to the ditz command (default: "ditz")
(setq ditz-program "/path/to/ditz")
;; If you don't want to always set issue dir when you run commands,
;; ditz.el provides automatic finding functionality. Add the
;; settings below:
;; Issue directory name (default: "bugs")
(setq ditz-issue-directory "issues")
;; Enable automatic finding functionality.
(setq ditz-find-issue-directory-automatically-flag t))
(5) Run M-x ditz-init to initialize your ditz issues.
(6) Run M-x ditz-add-release to add a new release.
(7) Run M-x ditz-add to add a new issue
(8) M-x ditz-status, ditz-todo, ditz-log are useful for
browsing your issues.
(9) To change issues/releases' status:
[1] Run M-x ditz-todo to list issues up.
[2] Enter the keys below on underlined strings:
- "s": ditz-show         (Show issue's detail)
- "e": ditz-edit         (Edit issue's detail)
- "a": ditz-assign       (Assign/reassign issue to a release)
- "c": ditz-close        (Close issue)
- "r": ditz-release      (Mark release as done)
- "g": ditz-reload       (Reload status/todo/log buffer)
- "q": ditz-close-buffer (Close ditz-mode buffer)
(10) M-x ditz-html generates HTML files including all statuses.
(11) For the usage of Ditz itself, see the document below:
http://ditz.rubyforge.org/README.txt
* AUTHOR
Kentaro Kuribayashi
http://kentarok.org/

yasnippet関連の設定

ここ数日、yasnippetに限らず.emacsいじりやelisp書きに没頭し過ぎて、公私各方面での活動に支障をきたしているので、ここらでとりあえずyasnippet関連の設定でも晒して、Emacsいじりを切り上げることにしたい。昨日、ver 0.4.0が出て、さらにいろいろ便利になった。しかし、まだいろいろと流動的かつ人柱的なので、根気がないと大変かも。

以下、注釈(コメントでも書いてるけど)。

;; yasnippet
;; http://code.google.com/p/yasnippet/
(require 'yasnippet)
;; メニューは使わない
(setq yas/use-menu nil)
;; トリガはSPC, 次の候補への移動はTAB
(setq yas/trigger-key (kbd "SPC"))
(setq yas/next-field-key (kbd "TAB"))
;;; [2008-03-20]
;;; ポップアップをdropdown-listにする
;; ver 0.4.0からyasnippel.el内にdropdown-list.elが含まれるようになった
;; が、いまのところ、それだとリストの選択肢でC-mしてもinsertされない。
;; 理由はわからないが、とりあえず自前で用意したものをrequireするとうま
;; く行く。
(require 'dropdown-list)
(setq yas/text-popup-function
#'yas/dropdown-list-popup-for-template)
;;; [2008-03-20]
;;; コメントやリテラルではスニペットを展開しない
;; ver 0.4.0からそれを利用して、コメント・リテラルの中では、スニペット
;; で特に指定されない限り、展開を行わない。
(setq yas/buffer-local-condition
'(or (not (or (string= "font-lock-comment-face"
(get-char-property (point) 'face))
(string= "font-lock-string-face"
(get-char-property (point) 'face))))
'(require-snippet-condition . force-in-comment)))
;;; [2008-03-15]
;;; 複数のディレクトリからスニペットを読み込む。
;; yasnippetのsnippetを置いてあるディレクトリ
(setq yas/root-directory (expand-file-name "~/dev/yasnippet/snippets"))
;; 自分用スニペットディレクトリ(リストで複数指定可)
(defvar my-snippet-directories
(list (expand-file-name "~/dev/yasnippet-snippets/common")  ; CodeRepos
(expand-file-name "~/dev/yasnippet-snippets/kentaro") ; CodeRepos
(expand-file-name "~/.emacs.d/snippets")))            ; Private
;; yasnippet公式提供のものと、自分用カスタマイズスニペットをロード同名
;; のスニペットが複数ある場合、あとから読みこんだ自分用のものが優先され
;; る。また、スニペットを変更、追加した場合、このコマンドを実行すること
;; で、変更・追加が反映される。
(defun yas/load-all-directories ()
(interactive)
(yas/reload-all)
(mapc 'yas/load-directory-1 my-snippet-directories))
;;; [2008-03-17]
;;; yasnippet展開中はflymakeを無効にする
(defvar flymake-is-active-flag nil)
(defadvice yas/expand-snippet
(before inhibit-flymake-syntax-checking-while-expanding-snippet activate)
(setq flymake-is-active-flag
(or flymake-is-active-flag
(assoc-default 'flymake-mode (buffer-local-variables))))
(when flymake-is-active-flag
(flymake-mode-off)))
(add-hook 'yas/after-exit-snippet-hook
'(lambda ()
(when flymake-is-active-flag
(flymake-mode-on)
(setq flymake-is-active-flag nil))))
;;; [2008-03-19]
;;; yasnippetを使って、ttのディレクティヴを補完
;; スニペットに`(tt-directives)`と書いて置くと補完読み込みする。
;; http://clouder.jp/yoshiki/mt/archives/000377.html から。
;; TODO: minor-modeでフェイスを定義して、色をつけたい。
(defvar tt-directives
'(
("IF")
("UNLESS")
("ELSIF")
("ELSE")
("FOREACH")
("WHILE")
("FILTER")
("GET")
("CALL")
("MACRO")
("SET")
("DEFAULT")
("INSERT")
("INCLUDE")
("BLOCK")
("END")
("PROCESS")
("WRAPPER")
("SWITCH")
("CASE")
("USE")
("PERL")
("RAWPERL")
("TRY")
("THROW")
("FINAL")
("CATCH")
("NEXT")
("LAST")
("RETURN")
("STOP")
("CLEAR")
("META")
("TAGS")
))
(defun tt-insert-directive ()
(let ((directive (completing-read "Directive Name: " tt-directives nil t)))
(when (and directive
(not (string= directive "")))
(concat "[%- " directive " %]"))))
;; yasnippet初期化
(yas/initialize)
(yas/load-all-directories)

yasnippetのスニペット展開中にflymakeするのを防ぐ

2008-03-19追記: 不具合があったので、少し修正しました。

yasnippet超便利なのですが、flymakeしてると、yasnippetのフェイスがflymakeのフェイスで上書きされちゃうことがよくある。そこでこんな設定を追加してみた。つーか、yas/expandにもフック欲しいな。要望しておこう。

flymakeが有効か否かを調べる方法は、id:elimんに教えてもらったお!id:elim++

;; yasnippet展開中はflymakeを無効にする
(defvar flymake-is-active-flag nil)
(defadvice yas/expand-snippet
(before inhibit-flymake-syntax-checking-while-expanding-snippet activate)
(setq flymake-is-active-flag
(or flymake-is-active-flag
(assoc-default 'flymake-mode (buffer-local-variables))))
(when flymake-is-active-flag
(flymake-mode-off)))
(add-hook 'yas/after-exit-snippet-hook
'(lambda ()
(when flymake-is-active-flag
(flymake-mode-on)
(setq flymake-is-active-flag nil))))

yasnippetのトリガをスペースキーにする


とか書いてたら、ver 3.0に上がって、この方法はそっこーでobsoleteになった。まぁそういアツさが、できたばかりのものを触る醍醐味でもあるかと。

yasnippetのトリガはデフォルトではTABキーなのですが、これは変更することが可能です。僕はいまんとこabbrevを使っていないので、abbrevと同じ感じで使えるよう、スペースキーにしてみました。こんな感じで、スニペットがなかった場合に実行されるyas/default-trigger-fallbackを定義してやる必要があります。

しかしこれって、スニペット補完を意図していない場所でスペース押すたびにも実行されるんだろうからかなlり富豪的過ぎる感じがするけど、まあいいじゃないか!!!しばらくこんなんで様子見。

(setq yas/trigger-key " ")
;; 対応するsnippetがない場合はSPCを挿入する
(fset 'yas/default-trigger-fallback
(lambda ()
(interactive)
(insert yas/trigger-key)))

yasnippetのスニペットをCodeReposで共有しよう!

yasnippetがすごい!!!!1112345!」で話題にしたyasnippetは、スニペットをあれこれ登録しまくってこそ、真にその力を発揮するわけですが、こういうのはやっぱりみんなで作ってこそだよねーというわけで、CodeReposで共有しましょう!!!とりあえず、まずはPerl用に、Test::Moreのスニペットを作って、CodeReposに上げておきました。

/config/yasnippet – CodeRepos::Share – Trac

スニペットの作り方に関しては、HowtoDefineSnippet – yasnippet – Google Codeを見れば、だいたいわかります。というか、配布物の中に例がたくさんあるので、ディレクトリ配置や、テンプレートを適当に真似て書けばオケです。

公式の配布物と合わせて、CodeRepos等での共有スニペットや、あるいは自分で書いたスニペットを利用する場合には、ちょっと設定を書く必要があります。yasnippetのサイトに書いてある通りの設定をすると、スニペットを置くディレクトリをひとつしか指定できないのでこんな感じで。

(require 'yasnippet)
;; yasnippetのsnippetを置いてあるディレクトリ
(setq yas/root-directory (expand-file-name "~/dev/yasnippet/snippets"))
;; 自分用スニペットディレクトリ(リストで複数指定可)
(defvar my-snippet-directories (list (expand-file-name "~/dev/yasnippet-snippets")))
;; yasnippet公式提供のものと、自分用カスタマイズスニペットをロード
;; 同名のスニペットが複数ある場合、あとから読みこんだ自分用のものが優先
;; される。また、スニペットを変更、追加した場合、このコマンドを実行する
;; ことで、変更・追加が反映される。
(defun yas/load-all-directories ()
(interactive)
(yas/reload-all)
(mapc 'yas/load-directory-1 my-snippet-directories))
;; yasnippet初期化
(yas/initialize)
(yas/load-all-directories)

My .emacs files on 2008/03/13

現在、僕の中で第3期にあたる空前のEmacsブームが訪れており、.emacsを整理したり、新しいelispをあれこれ試したり、自分でelispを書いたりしている。

ちょっと前の話になるけど、「Software Design 2008年2月号」のEmacs特集が素晴しくて、また、その特集でもid:rubikitchさんが取り上げているanything.elがすげー!すげー!というわけで、超盛り上がる。というかその特集、その他も素晴しい記事だらけ過ぎて永久保存版まくり。僕もそのうち、EmacsWikiにあれこれ書いたりできるようになりたい!!!

んでもって以前、CodeReposEmacsの設定を晒したりしたのだったが、参考にしていただいていたりするので、設定部分に関して整理したものを、改めて更新してみたり。

/dotfiles/emacs/kentaro – CodeRepos::Share – Trac

これぐらいでも、設定だけで合計にして約1,900行ぐらいになるのだけど、しかしすごいひとはまったくレベルの違うすごさなので僕ごときじゃアレなのだが、しかしまぁ、あんまりにもすご過ぎるとなにがなんだかわからないので、むしろこのぐらいでもなんかの役に立ったりもするのかもしれないとも思ったりもする。

それにしてもEmacsつーのはアレですな。まったくもって初心者を脱け出せる気がしない奥の深さ。しかしそろそろ、なんかやるたびにEmacsの設定を見直して先に進まないのをどうにかしたいものです……。

Emacsからackの検索結果を使う

よくわかんないけど、こんなんでいんじゃねもうもう。quickfixって何。vimとかわかりません><

(defun ack ()
(interactive)
(let ((grep-find-command "ack --nocolor --nogroup "))
(call-interactively 'grep-find)))

ちなみにackは、CPANのApp::Ackから入れるとackなのだけど、debianのパッケージだとack-grepなので注意を要する。あと、最近anything.el(素敵!!!)を使いはじめたので、そこに出すようにしてみようかと思ったりもしたけど、それはそれで微妙な気もした。どうだろ。

auto-save-buffers-enhanced更新

auto-save-buffers-enhancedなんてのを、以前作ったりしました。名前から察せられる通り、「Emacsでファイルの自動保存 (auto-save-buffers)」の機能拡張版というか、なんというか、まぁそんな感じのものです。具体的には、以下の機能を追加しています。

  1. 監視/無視対象ファイルの正規表現を複数指定できる
  2. cvs, svn, svk, gitといったヴァージョン管理システムの管理下にあるファイルのみを監視対象にすることができる

auto-save-buffers-enhancedの、僕以外ではいまのところ唯一なのではないかと思われるユーザである、CLONのtypesterさんが、上記の2番目について、そういうのあるといいよねーとかいってた(「unknownplace.org – 2007/10/18 – こうだったらいいのに auto-save-buffers」)ので、作ったのでした。

ところで最近、空前のgitブームが湧きおこったりしているのですが、auto-save-buffers-enhancedの以前のリヴィジョンでは、gitに対応していなかったりしたので、僕以外ではいまのところ唯一なのではないかと思われるユーザである、CLONのtypesterさんに対応を迫られたりしたので、ちょっとやってみたりしました(まぁ、僕はgitを未だにインストールすらしてないわけですがw)。ついでに、いろいろバグがあったので、修正したり

そんなわけで、久々に更新したので、たまには過去の成果もageておきます。

Taskpaperもどきを作りかけて放置した記録

ほとんどテキストエディタ | ZEROFACES」というエントリで知ったTaskpaperというタスク管理ツールが、シンプルの極みでいい感じかなーと思った。こういうの。

んで、使ってみようかと思ったら、$18.95のシェアウェアだってんで、じゃあもうEmacsでやろうと思って久々にelispを書いたりしてたんだけど、そもそもEmacsにはその手のものは他にたくさんあるのだし、もっと問題なのは、僕自身にしてからが、タスク管理ツールを使いこなせたためしがないということであってみれば、元のTaskpaperは、タグとか、プロジェクトごとにタブで見ることができたりするけど、そこまで行く途中でやる気を失ったり……。単にちょっと、たまにはelispを書いてみたかっただけという気がする。

とりあえずCodeReposに置いてあったりします。ごく単純なメジャーモードのサンプル的ななにか、みたいな。

一応こんな。もすこしちゃんと作るかなーと思いつつ、というか、CodeReposにあるので、誰か……。

これだけじゃなんなので、こんな感じの設定を書いてみた。`M-x taskpaper‘したら、新規フレームに今日の日付けのファイルを開きます。一日の始めにその日のtaskpaperを開いて、それを常に見える場所にでも置いておけば、なんかそれっぽい感じになるんじゃないかしら。そうでもないかしら、ね。

(require 'taskpaper)
;; taskpaperファイルを置くディレクトリ
(setq taskpaper-dir (expand-file-name "~/.taskpaper/"))
;; `M-x taskpaper'で、今日の日付けのファイルを新しいフレームで開く
(defun taskpaper ()
(interactive)
(let ((filename (concat taskpaper-dir
(format-time-string "%Y-%m-%d.taskpaper"))))
(find-file-other-frame filename)))

simple-hatena-modeリリース

はてなダイアリーライターEmacsから使えるようにし、はてなダイアリー/グループ日記を簡単に更新するためのメジャーモード、simple-hatena-modeをリリースしました。設定方法や利用方法については、以下のドキュメントをご覧ください。

同様の機能を提供するelispについては、すでにいくつかのものが存在しますが、simple-hatena-modeには、それらと比べて以下の利点があります。

  • 複数のアカウントに対応。
  • それぞれのアカウントのグループ日記に対応。

僕は、複数のidとグループであちこちに日記を書いているので、とても便利です。というか、そもそもはこれが欲しくて作ったのでした。
なお、simpleという名前がついているのに全然シンプルでない件については、スルーしてやってください。作っているうちに全然シンプルじゃなくなることはよくあることですが、設定を簡単にするための方法については、TODOとして考え中です。
というか、僕はelispとか全然書けないので、こういう機能があったらなーと思っても、なかなか実装できません。「こんな機能があるといいね」とか「ここはこうしたほうがいんじゃね?」という方は、是非ともCodeReposのコミット権を取得して(誰でも簡単にもらえます)、ガンガン変更しちゃってください。お願いします。

本パッケージの利用に際して問題がある場合は、以下に挙げる先行実装を試してみていただきたいと思います。また、simple-hatena-mode.elの作成に際しては、大いに参考にさせていただきました。ありがとうございます。

© 2020 栗林健太郎

Theme by Anders NorénUp ↑