最近社内でvim勉強会があったりして「vimもいいなぁ」と思っていたのですが、やっぱりキーバインドに慣れなくってEmacsに戻ってきました。最近EmacsでPerl関連の設定を見なおしたので、メモがてら書いておきます。自分がPerlのコードを書くときに使っているelispは以下の5つです。
- cperl-mode
- flymake + set-perl5lib
- anything + auto-complete + perl-completion
これらを一つ一つ紹介していきます。
cperl-mode
cperl-mode はこんな感じで設定しています。とりあえず色付けと適切なインデントがなされればいいかなという感じ。
(autoload 'cperl-mode "cperl-mode" "alternate mode for editing Perl programs" t)
(add-to-list 'auto-mode-alist '("\.\([pP][Llm]\|al\|t\|cgi\)\'" . cperl-mode))
(add-to-list 'interpreter-mode-alist '("perl" . cperl-mode))
(add-to-list 'interpreter-mode-alist '("perl5" . cperl-mode))
(add-to-list 'interpreter-mode-alist '("miniperl" . cperl-mode))
;;; cperl-mode is preferred to perl-mode
;;; "Brevity is the soul of wit"
(defalias 'perl-mode 'cperl-mode)
(setq cperl-indent-level 4
cperl-continued-statement-offset 4
cperl-close-paren-offset -4
cperl-label-offset -4
cperl-comment-column 40
cperl-highlight-variables-indiscriminately t
cperl-indent-parens-as-block t
cperl-tab-always-indent nil
cperl-font-lock t)
(add-hook 'cperl-mode-hook
'(lambda ()
(progn
(setq indent-tabs-mode nil)
(setq tab-width nil)
; perl-completion
(require 'auto-complete)
(require 'perl-completion)
(add-to-list 'ac-sources 'ac-source-perl-completion)
(perl-completion-mode t)
)))
; perl tidy
; sudo aptitude install perltidy
(defun perltidy-region ()
"Run perltidy on the current region."
(interactive)
(save-excursion
(shell-command-on-region (point) (mark) "perltidy -q" nil t)))
(defun perltidy-defun ()
"Run perltidy on the current defun."
(interactive)
(save-excursion (mark-defun)
(perltidy-region)))
(global-set-key "C-ct" 'perltidy-region)
(global-set-key "C-cC-t" 'perltidy-defun)
flymake + set-perl5lib
flymake はEmacs自体に含まれているソースコードチェッカーです。set-perl5lib はここからダウンロードできます。この設定を入れるとコードを書いているときに裏でsyntax checkが走って、エラーになっている箇所を赤くしてくれます。これのおかげでしょうもないtypoに簡単にきづけるので、だいぶコードを書くのが速くなりました。かなりおすすめの設定です。
なお、自分は C-c e でエラーが発生している箇所にジャンプしてエラーメッセージをミニバッファに表示するように設定しています。
;; flymake for perl
(defvar flymake-perl-err-line-patterns '*1
(defun flymake-perl-init ()
(let* *2
(local-file (file-relative-name
temp-file
(file-name-directory buffer-file-name))))
(list "perl" (list "-wc" local-file))))
(defun flymake-perl-load ()
(interactive)
(set-perl5lib)
(defadvice flymake-post-syntax-check (before flymake-force-check-was-interrupted)
(setq flymake-check-was-interrupted t))
(ad-activate 'flymake-post-syntax-check)
(setq flymake-allowed-file-name-masks (append flymake-allowed-file-name-masks flymake-allowed-perl-file-name-masks))
(setq flymake-err-line-patterns flymake-perl-err-line-patterns)
(flymake-mode t))
(add-hook 'cperl-mode-hook '(lambda () (flymake-perl-load)))
(defun next-flymake-error ()
(interactive)
(flymake-goto-next-error)
(let *3
(string= "font-lock-string-face"
(get-char-property (point) 'face))))
'(require-snippet-condition . force-in-comment)))
;; yasnippet 公式提供のものと、
;; 自分用カスタマイズスニペットをロード同名のスニペットが複数ある場合、
;; あとから読みこんだ自分用のものが優先される。
;; また、スニペットを変更、追加した場合、
;; このコマンドを実行することで、変更・追加が反映される。
(defun yas/load-all-directories ()
(interactive)
(yas/reload-all)
(mapc 'yas/load-directory-1 my-snippet-directories))
;;; 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))))
(setq yas/root-directory (expand-file-name "~/.emacs.d/snippets"))
(defvar my-snippet-directories
(list (expand-file-name "~/.emacs.d/mysnippets")))
(yas/initialize)
(yas/load-directory "~/.emacs.d/snippets")
(yas/load-all-directories)
まとめ
以上の設定をすると
- ソースの色付け
- シンタックスチェック
- シンボルの補完
- モジュールのドキュメントを引く
- snippetによるタイプ量の削減
ができるようになります。EclipseのようなIDEにはまだ及びませんが、これでだいぶコードを書くのが速くなるかと思います。
情報源
を参考にさせてもらいました。ありがとうございます。
[tmkm-amazon]4774143278[/tmkm-amazon]
*1:"\(.*\) at \([^ n]+\) line \([0-9]+\)[,.n]" 2 3 nil 1)))
(defconst flymake-allowed-perl-file-name-masks '(("\.pl$" flymake-perl-init)
("\.pm$" flymake-perl-init)
("\.t$" flymake-perl-init)
*2:temp-file (flymake-init-create-temp-buffer-copy
'flymake-create-temp-inplace
*3:err (get-char-property (point) 'help-echo)))
(when err
(message err))))
(global-set-key "C-ce" 'next-flymake-error)
auto-complete + perl-completion
auto-complete と perl-completion を組み合わせてPerlのモジュールや関数、変数を補完する設定をしています。設定する elisp は先ほどの cperl-mode のところに含まれているので割愛します。下記のような感じで補完候補が出てきます。
また、perl-completion にはデフォルトで C-c s するとカーソルのあるモジュールのドキュメントをanything インタフェースで開くことができます。
yasnippet
yasnippet は任意のキーワードを打ってTABを押すと、そのキーワードを登録しておいたテンプレート(snippet)で置換してくれるものです。うまく使えばかなりのタイプ量が減らせるのでコードを書くのが早くなります。自分は例えば
use strict;
use warnings;
というsnippetを "usestwa" というキーワードで登録しています。
yasnippetには予め用意されているものがあるのですが、自分はそれとは別にディレクトリを作成して(~/.emacs.d/mysnippets)、そこに自分で作ったsnippetを置いています。以下がyasnippetの設定です。
(require 'yasnippet)
(require 'dropdown-list)
(setq yas/text-popup-function #'yas/dropdown-list-popup-for-template)
(setq yas/buffer-local-condition
'(or (not (or (string= "font-lock-comment-face"
(get-char-property (point) 'face