Emacs Lispを書いてみた - Perlモジュール名にカーソルを合わせて M-.するとソースを開く

id:higepon:20060131:1138681298の続き。

などの情報をいただきました。

というわけで id:miyamukoさんのxyzzyの例をまねして、初めて実用的なEmacs Lispを書いてみました。

;; cperl-modeでモジュール名にカーソルを合わせてM-.でソース開く
(setq perl-find-module-libdir "x:/oop/lib") ; libディレクトリのPath

;; M-.
(add-hook 'cperl-mode-hook
          (function (lambda ()
                      (define-key cperl-mode-map "\M-." 'perl-find-module)
)))

(defun perl-module-to-file (libdir module)
  (concat libdir "/" (replace-regexp-in-string "::" "\/" module) ".pm"))

(defun perl-find-module ()
  (interactive)
  (let*
      (
       (begin (save-excursion (skip-chars-backward "a-zA-Z0-9_:") (point)))
       (end (save-excursion (skip-chars-forward "a-zA-Z0-9_:") (point)))
       (module (buffer-substring begin end))
       )
    (message module)
    (find-file (perl-module-to-file perl-find-module-libdir module)
    )
))


早速同僚のid:hideokiから、libディレクトリは複数指定したいね。
と言われたのですがそろそろギブです。

追記:ただいま改良中(perldocを使おう)

Perlモジュール名にカーソルを合わせて M-.するとソースを開く2

id:higepon:20060201:1138776917の続き
id:naoyaから perldoc を使ったほうが何かと便利と言われたので新版。


変更・改善点は

  • perldocを利用しているので、Hoge::Fooが Hoge.pmに定義されているような場合も対応可能
  • PERL5LIBを利用して複数のパスから探すことが可能。(id:miyamukoさんに感謝)


PERL5LIBさえきちんと指定しておけば、CPANモジュール・自プロジェクトのモジュール区別なくソースが見られるのでかなり幸せです。

;;(setenv "PERL5LIB" "/cygdrive/x/oop/lib")

(defun  perl-find-module ()
  (interactive)
  (let
      (end begin module path-to-module)
    (save-excursion
      (setq begin (save-excursion (skip-chars-backward "a-zA-Z0-9_:") (point)))
      (setq end (save-excursion (skip-chars-forward "a-zA-Z0-9_:") (point)))
      (setq module (buffer-substring begin end))
      )
    (shell-command (concat "perldoc -lm " module) "*perldoc*")
    (save-window-excursion
      (switch-to-buffer "*perldoc*")
      (setq end (point))
      (setq begin (save-excursion (beginning-of-line) (point)))
      (setq path-to-module (buffer-substring begin end))
      )
    (message path-to-module)
    (find-file path-to-module)
))

(add-hook 'cperl-mode-hook
          (function (lambda ()
                      (define-key cperl-mode-map "\M-." 'perl-find-module)
)))

letを細かく分ければもう少し変数を局所化できそうだなぁ。
あとは*perldoc*とかいう一時バッファを使っているんだけどこれは普通はどうやるんだろう?
採点求む。

追記:
arinoさんの指摘により let* -> letに書き換えました。