QA@IT

Emacsを使って`.phtml`をweb-modeで、`.php`をphp-modeで開く方法

2749 PV

Emacsで .phtmlをweb-modeで、.phpをphp-modeで開きたいのですが、

(add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode))

として php-mode に関しては関連付けを何も明示的に指定しないにもかかわらず
phtmlを開いた時に php-mode になってしまいます。

おそらくパッケージの内部で既に拡張子との関連付けも行われているのだと思いますが
その解除方法がわかりませんでした。

(remove-to-list 'auto-mode-alist '("\\.phtml\\'" . php-mode)) のような事がしたかったのですが
remove-to-list は存在しませんでした。リストから特定の要素を除去するにはどうすればよいのでしょうか?

  • 回答を追記しました。 -
  • loopマクロ版はご指摘の通り間違えてましたので修正しました。 -

回答

もっといいやり方がありそうですが、alistから削除するのであれば

(setq auto-mode-alist 
       (delq (assoc "\\.phtml\\'" auto-mode-alist) auto-mode-alist))

ではいかがでしょう。
連想配列からキーを元に要素を求め(assoc)
連想配列から取り除いたもの(delq)を
連想配列に再設定してます(setq)


ちなみに removeは存在しますが要素のインデックスを指定する必要があります。
remove-from-listは無いようですね。
(add-to-listがaddの特殊版(重複を意識するバージョン)ですが、対になる適切な処理が特にないからでしょうかね?)


追記:2013/10/05
指摘を受けて loopマクロ版修正:11:27

既に追加された後で削除されたいとのことですが、その場合は以下のようなものでどうでしょう。

((lambda (aml) 
   (while aml
     (if (equal 
         (car aml) 
         '("\\.phtml\\'" . php-mode))
       (setq auto-mode-alist (delq (car aml) auto-mode-alist)))
     (setq aml (cdr aml)) ) ) 
 auto-mode-alist)

loopマクロを使えば以下の様に少なくできますが、clパッケージをロードしないといけないので初期処理にしては
大げさかなのかもしれません(その辺の定石には疎いので実際良いのか悪いのかはわかりません)。

(require 'cl)
(loop for item in auto-mode-alist
   when (equal '("\\.phtml\\'" . php-mode) item)
     do (setq auto-mode-alist (delq item auto-mode-alist)) )

assocと違ってすべての "\\.phtml\\'"php-modeのドット対が削除されます。

編集 履歴 (3)
  • 回答有難うございます。keyとvalueが一致するなら削除するのはややこしい処理になってしまうんでしょうか?この削除方法だと web-mode と .phtml の紐付けが先に行われたら何も割り当てられなくなってしまうとおもうんですが。 -
  • 追記しました。 -
  • ありがとうございます、設定出来ました。aml を auto-mode-alist に単純に置換して使っているんですがこの呼び方でよかったんでしょうか…? -
  • 失礼しました、loopマクロの方はご指摘の通りamlじゃなくてauto-mode-alistじゃないとだめですね。確認用のコードのままでした、直しておきます。lambda使っている方はそのままでいいはずです。 -

M-x customize-variable して php-file-patterns を指定すると設定画面になるので、そこで変更すればよいと思います。

php-file-patterns は php-mode.el で、以下のように定義されていました。

(defcustom php-file-patterns '("\\.php[s34]?\\'" "\\.phtml\\'" "\\.inc\\'")
  "List of file patterns for which to automatically invoke `php-mode'."
  :type '(repeat (regexp :tag "Pattern"))
  :set (lambda (sym val)
         (set-default sym val)
         (let ((php-file-patterns-temp val))
           (while php-file-patterns-temp
             (add-to-list 'auto-mode-alist
                          (cons (car php-file-patterns-temp) 'php-mode))
             (setq php-file-patterns-temp (cdr php-file-patterns-temp)))))
  :group 'php)
編集 履歴 (0)
  • `php-file-patterns` が [No match]になってしまいました。インストールした php-mode が違うのものだったのかもしれません。 https://github.com/ejmr/php-mode あとできれば関数を呼び出して設定する方法はどこがどうなってるか自分にはわかるにくいので自分で初期化ファイルに書く方法をできれば使いたいです。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。