oinume journal

Scratchpad of what I learned

Perl開発環境としてのEmacsの設定

最近社内でvim勉強会があったりして「vimもいいなぁ」と思っていたのですが、やっぱりキーバインドに慣れなくってEmacsに戻ってきました。最近EmacsPerl関連の設定を見なおしたので、メモがてら書いておきます。自分が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

flymakeEmacs自体に含まれているソースコードチェッカーです。set-perl5lib はここからダウンロードできます。この設定を入れるとコードを書いているときに裏でsyntax checkが走って、エラーになっている箇所を赤くしてくれます。これのおかげでしょうもないtypoに簡単にきづけるので、だいぶコードを書くのが速くなりました。かなりおすすめの設定です。

 

flymake_perl

 

なお、自分は 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-completeperl-completion を組み合わせてPerlのモジュールや関数、変数を補完する設定をしています。設定する elisp は先ほどの cperl-mode のところに含まれているので割愛します。下記のような感じで補完候補が出てきます。

 

perl_completion

 

また、perl-completion にはデフォルトで C-c s するとカーソルのあるモジュールのドキュメントをanything インタフェースで開くことができます。

perl_completion_pod

 

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