*iroi*

mechairoi の Blog

Template-ToolkitのMACROとかBLOCKをctagsで

Exuberant ctagsで使えます.
~/.ctags にいい加減な正規表現を書く.

なんかmacだと動かない?
なんか他の環境では動かないらしい。
正規表現書き換えたら動いた。ctagsのバージョンとかは

$ ctags --version
Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
  Compiled: Jan 11 2011, 00:09:44
  Addresses: <@>, http://ctags.sourceforge.net
  Optional compiled features: +wildcards, +regex

perlのflymakeの設定

  • buffer localにしたかったのでPERL5LIBにsetenvせず起動オプションで -Mlib glob.
  • 常にgitを使うのでgitプロジェクトの一番上を起点にしている.
;; -- flymake
(add-to-list 'flymake-allowed-file-name-masks
             '("\\.t$" flymake-perl-init)) ; pm, pl は設定されてる.

(defconst my-flymake-perl-lib-suffix-list
  '("lib" "t/lib" "modules/*/lib" "modules/*/t/lib"))

(defun my-flymake-perl-options ()
  (when my-current-git-root
    (mapcar (lambda (suffix)
              (format "-Mlib glob qw(%s%s) " my-current-git-root suffix))
            my-flymake-perl-lib-suffix-list)))

;; override (flymake.el)
(defun flymake-perl-init ()
  (let* ((temp-file   (flymake-init-create-temp-buffer-copy
                       'flymake-create-temp-inplace))
         (local-file  (file-relative-name
                       temp-file
                       (file-name-directory buffer-file-name))))
    (list "perl" (append '("-wc ") (my-flymake-perl-options) (list local-file)))))

;; -- hook

(add-hook 'cperl-mode-hook 'my-cperl-mode-init)
(defun my-cperl-mode-init ()
  (let ((root (my-git-root)))
    (set (make-local-variable 'my-current-git-root) root)
    (when root (my-make-tags-if-need root t)))
  (flymake-mode t))

;; -- my-git

(defun my-git-root ()
  (flet ((iter (path)
               (let ((p (and path (vc-git-root path))))
                 (or (and p (iter (my-parent-directory p))) p))))
    (iter (if (buffer-file-name)
              (file-name-directory (buffer-file-name))
            default-directory))))

(defun my-parent-directory (path)
  (file-name-directory (directory-file-name (file-name-directory path))))

GTAGSのパスを指定したanything-gtagsのsourceを作る.

(バッファが属する)ProjectのTAGSと(global-modeに応じた)LibraryのTAGSとか同時に使いたいです.

anything-gtags.el でプロジェクトのGTAGSは既に使えるので, GTAGSファイルのパスを指定できるsourceを作って, 複数のsourceを扱うのはanythingにおまかせすることにしました. anything便利.

使い方はこんな感じ. ~/perl5に インストールしているperlのモジュールが入っていてGTAGSを作ってあります.

(defvar anything-c-source-gtags-select-with-home-perl-lib
  (anything-c-source-gtags-select-with-root "GTAGS ~/perl5" "~/perl5"))

(defun my-anything-gtags-select ()
  (interactive)
  (anything-other-buffer
     '(anything-c-source-gtags-select
       anything-c-source-gtags-select-with-home-perl-lib)
     "*anything gtags*"))

( perl用のGTAGSの作り方は gtags(GNU global)をperlとかで使う - *iroi* )

gtags.elやanything-gtags.el内部で使われているglobalコマンドは環境変数GTAGSROOTがあるとカレントディレクトリより優先してそっちを見るようなので、環境変数をdynamic-scope内でローカルに書き換えるマクロを作って囲んだだけです.

Test::Class でメソッドの単体テストを elisp でさくっと

Test::Class でメソッドの単体テストを vim script でさくっと - #生存戦略 、それは - subtechが便利過ぎる!!!のでemacsでもしたいです.

(defun run-perl-method-test ()
  (interactive)
  (let ((command compile-command))
    (save-excursion
      (when (or
             (re-search-backward "\\bsub\s+\\([_[:alpha:]]+\\)\s*:\s*Test" nil t)
             (re-search-forward "\\bsub\s+\\([_[:alpha:]]+\\)\s*:\s*Test" nil t))
        (setq command
              (format "TEST_METHOD=%s perl -w %s"
                      (match-string 1) (expand-file-name buffer-file-name)))))
    (when command (compile command))))

いつもテスト通らなくて本体を修正するので, 候補が無かったらグローバルに前回のを実行するようにした.

gtags(GNU global)をperlとかで使う

etagsは使いにくいしgtagsは対応ファイルフォーマットが少ないしと思って色々調べていたらExuberant ctagsを使ってGTAGSを作れるようなのでやってみた.ちゃんとした機能ではなくgtagsのプラギン例のようです. ctagsが元になってるので global -rはできないですが、global -cなどはperlで使えてます. 以下手順.

  • Exuberant ctagsをインストール
$ ctags --version
Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
  Compiled: Aug 17 2010, 17:33:33
  Addresses: <?@?>, http://ctags.sourceforge.net
  Optional compiled features: +wildcards, +regex

普通は入れてますね. emacs付属のとかだと駄目です.

plugin-example/READMEに書いてあるようにctagsのパスをつけて

./configure --with-exuberant-ctags=/usr/bin/ctags; make; sudo make install;
  • このままだとpackage名でjumpできず *.pm, *.tがperlのコードして扱われないので, 設定ファイルを修正してやります.
cp /usr/local/share/gtags/gtags.conf ~/.globalrc
--- /usr/local/share/gtags/gtags.conf	2010-11-28 15:25:21.167584987 +0900
+++ .globalrc	2010-11-28 17:20:45.211584987 +0900
@@ -34,18 +34,19 @@
 # See gtags(1).
 #---------------------------------------------------------------------
 common:\
-	:skip=GPATH,GTAGS,GRTAGS,GSYMS,HTML/,HTML.pub/,html/,tags,TAGS,ID,y.tab.c,y.tab.h,cscope.out,cscope.po.out,cscope.in.out,SCCS/,RCS/,CVS/,CVSROOT/,{arch}/,autom4te.cache/:
+	:skip=GPATH,GTAGS,GRTAGS,GSYMS,HTML/,HTML.pub/,html/,tags,TAGS,ID,y.tab.c,y.tab.h,cscope.out,cscope.po.out,cscope.in.out,SCCS/,RCS/,CVS/,CVSROOT/,{arch}/,autom4te.cache/,.git/:
 gtags:\
 	:tc=common:\
 	:langmap=c\:.c.h,yacc\:.y,asm\:.s.S,java\:.java,cpp\:.c++.cc.cpp.cxx.hxx.hpp.C.H,php\:.php.php3.phtml:
 #
 # plugin parser
 #
 plugin-example|Example of function layer plugin parser:\
-	:tc=common:extractmethod:\
+	:tc=common:\
 	:langmap=c\:.c.h,yacc\:.y,asm\:.s.S,java\:.java,cpp\:.c++.cc.cpp.cxx.hxx.hpp.C.H,php\:.php.php3.phtml:\
 	:langmap=fortran\:.f.for.f77.f90.f95,pascal\:.p.pas,c#\:.cs,lisp\:.l.el.lisp,scheme\:.scm:\
-	:langmap=awk\:.awk,ruby\:.rb,perl\:.pl,python\:.py,vim\:.vim,sh\:.sh:\
+	:langmap=awk\:.awk,ruby\:.rb,perl\:.pl.pm.t,python\:.py,sh\:.sh:\
 	:gtags_parser=c\:/usr/local/lib/gtags/exuberant-ctags.la:\
 	:gtags_parser=yacc\:/usr/local/lib/gtags/exuberant-ctags.la:\
 	:gtags_parser=asm\:/usr/local/lib/gtags/exuberant-ctags.la:\

(*.vimはSession.vimがあるとgtagsが死んでしまうので消した)

gtags --gtagslabel=plugin-example

でそれっぽいGTAGSとかのファイルが生成されて使えます.

globalの機能が全て使えるわけでは無いですが,
etagsのelispがなんとも近寄り難い感じだったので満足です.

使わないけどもhtagsでHTMLも生成出来た.