ethnaで対応するactionやview、templateにジャンプするelispを書いた

というか、だいぶ前に作って使っていたのだけど、今回anythingのsourceを作る練習をするためにそれをanything化してみた。

で、ethnaのジャンプ用elisp

;;; ethna用
(defvar ethna-jump-template-subdir '("ja_JP/"))

(defun ethna-jump-action-and-view (from to)
  (find-file
   (replace-regexp-in-string (concat "/" from "/") (concat "/" to "/") (buffer-file-name))))

(defun ethna-jump-from-action-or-view-to-template (part)
  (interactive)
  (let ((template-file
		 (downcase
		  (replace-regexp-in-string
		   ".php" ".tpl"
		   (replace-regexp-in-string
			"Do.php" "done.tpl"
			(replace-regexp-in-string
			 (concat "/app/" part "/")
			 (concat "/template/" (car ethna-jump-template-subdir))
			 (buffer-file-name)))))))
	(if (file-writable-p template-file)	(find-file template-file))))

(defun ethna-jump-from-template-to-action-or-view (part)
  (let* ((tpl-dir "/template")
		 (subpath
		  (replace-regexp-in-string
		   (car ethna-jump-template-subdir) "" (substring
									(buffer-file-name)
									(+ (search tpl-dir (buffer-file-name)) (length tpl-dir)))))
		 (proj-dir (car (split-string (buffer-file-name) tpl-dir))))
	(find-file
	 (concat proj-dir (concat "/app/" part)
			 (replace-regexp-in-string ".tpl" ".php"
									   (mapconcat 'capitalize
												  (split-string subpath "/") "/") t)))))

(defun ethna-jump-to-action ()
  (interactive)
  (cond ((search "/app/view/" (buffer-file-name)) (ethna-jump-action-and-view "view" "action"))
		((search "/template/" (buffer-file-name)) (ethna-jump-from-template-to-action-or-view "action"))))

(defun ethna-jump-to-view ()
  (interactive)
  (cond ((search "/app/action/" (buffer-file-name)) (ethna-jump-action-and-view "action" "view"))
		((search "/template/" (buffer-file-name)) (ethna-jump-from-template-to-action-or-view "view"))))

(defun ethna-jump-to-template ()
  (interactive)
  (cond ((search "/app/action/" (buffer-file-name)) (ethna-jump-from-action-or-view-to-template "action"))
		((search "/app/view/" (buffer-file-name)) (ethna-jump-from-action-or-view-to-template "view"))))

(provide 'ethna-jump)

.emacsにこんな感じで書いてます。

(require 'ethna-jump)
(defvar anything-c-source-ethna-jump
  '((name . "Ethna jump")
	(candidates . (lambda () (list "action" "view" "template")))
	(action . (("Find file" . (lambda (part)
						   (cond
							((string= part "action") (ethna-jump-to-action))
							((string= part "view") (ethna-jump-to-view))
							((string= part "template") (ethna-jump-to-template)))))))))
(setq anything-sources (cons anything-c-source-ethna-jump anything-sources))

(add-hook  'php-mode-hook
           (lambda ()
			 (define-key php-mode-map "\C-xa" 'ethna-jump-to-action)
			 (define-key php-mode-map "\C-xv" 'ethna-jump-to-view)
			 (define-key php-mode-map "\C-xt" 'ethna-jump-to-template)))
(add-hook  'html-mode-hook
           (lambda ()
			 (define-key html-mode-map "\C-xa" 'ethna-jump-to-action)
			 (define-key html-mode-map "\C-xv" 'ethna-jump-to-view)
			 (define-key html-mode-map "\C-xt" 'ethna-jump-to-template)))

elispの関数調べながらこねこね作りました。仕事で使ってるローカルルール用のコードも入ってるので意味不明なところもあるかもしれないです。
でもいちおう動いてます。

ほんとはethna-jump-modeみたいなマイナーモードを作って、そのときだけanything-sourcesに追加するようにしたいんだけど、まだやり方がわからない。