Perl パッケージ名の自動チェック(Emacs編)

http://perl-users.jp/articles/advent-calendar/2012/casual/13


のパッケージ名チェックを Emacs Lispで書いてみました。

コード

(defun cperl-get-package-name ()
  (save-excursion
    (goto-char (point-min))
    (if (re-search-forward "^\\s-*package\\s-+\\([^ ;]+\\)" nil t)
        (match-string-no-properties 1)
      "")))

(defun cperl-check-package-name ()
  (interactive)
  (let* ((path (file-name-sans-extension (buffer-file-name)))
         (package (replace-regexp-in-string "::" "/" (cperl-get-package-name)))
         (package-path (substring path (- (length path) (length package)))))
    (cond ((string= package "")
           (error "ぱっけーじせんげんがみつかりません><"))
          ((not (string= package-path package))
           (error (concat "ぱっけーじめいと、ほぞんされているぱすが、ちがうきがします!\n"
                          "ちゃんとなおしてください><"))))))

(defun cperl-check-package-name-hook ()
  (if (eq major-mode 'cperl-mode)
      (cperl-check-package-name)))

(add-hook 'after-save-hook 'cperl-check-package-name-hook)

イメージ

ただ個人的には

ファイルのひな形を挿入するときに自動的に入れればいいかなと思います。
Vimの snippetの枠組みはよくわからないですが、Emacsyasnippetでは
任意のコードが実行できるので、そこからパッケージ名を特定し、ひな形を
動的に生成できます。

snippet template
# name : Package template
# key  : package
# --
package `(yas/perl-package-name)`;
use strict;
use warnings;

$0

1;

__END__

関数

個人的には lib/以下にあるファイルにひな形としているので、
以下のような感じで、lib/からの相対パスを見ています。

(defun yas/perl-package-name ()
  (let ((file-path (file-name-sans-extension (buffer-file-name))))
    (if (string-match "lib/" file-path)
        (replace-regexp-in-string "/" "::"
                                  (car (last (split-string file-path "/lib/"))))
      (file-name-nondirectory file-path))))

展開後のコード

lib/MyApp/Foo.pmで "package"でsnippetを展開すると
以下のようになります。

package MyApp::Foo;
use strict;
use warnings;



1;

__END__

私は基本的にこうして package宣言しているのであまり package名を
間違えたということはありません。

おまけ(POD)

PODの部分も同じような感じにしています。

# name : POD template
# key  : pod
# --

=encoding utf-8

=for stopwords

=head1 NAME

${1:`(yas/perl-package-name)`} - $0

=head1 SYNOPSIS

=head1 DESCRIPTION

$1 is

=head1 AUTHOR

Your Name E<lt>Your Mail AddressE<gt>

=head1 COPYRIGHT

Copyright `(format-time-string "%Y")` - Your Name

=head1 SEE ALSO

=head1 LICENSE

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

まあどうするかは好みの問題でしょうが、何かしらの対策はやはり
すべきでしょうね。