2012-01-05 4 views
2
私はあなたが期待通りに動作し、私の .emacsファイルに次のコード、している

設定モードは

;; Ruby 
(global-font-lock-mode 1) 
(autoload 'ruby-mode "ruby-mode" "Ruby editing mode." t) 
(setq auto-mode-alist (cons '("\\.rb$" . ruby-mode) auto-mode-alist)) 
(setq auto-mode-alist (cons '("\\.rsel$" . ruby-mode) auto-mode-alist)) 
(setq auto-mode-alist (cons '("\\.rhtml$" . html-mode) auto-mode-alist)) 
(setq auto-mode-alist (cons '("\\.erb$" . html-mode) auto-mode-alist)) 
(setq auto-mode-alist (cons '("\\.prawn$" . html-mode) auto-mode-alist)) 
(setq auto-mode-alist (cons '("Rakefile$" . ruby-mode) auto-mode-alist)) 

は、しかし、私の試みは少しそれを乾燥させるためには、失敗:

次のエラーと
(defun set-mode-for-filename-patterns (mode filename-pattern-list) 
    (mapcar 
    (lambda (filename-pattern) 
     (setq 
     auto-mode-alist 
     (cons '(filename-pattern . mode) auto-mode-alist))) 
    filename-pattern-list)) 

;; Ruby 
(global-font-lock-mode 1) 
(autoload 'ruby-mode "ruby-mode" "Ruby editing mode." t) 
(set-mode-for-filename-patterns 
    ruby-mode 
    '("\\.rb$" 
    "\\.rsel$" 
    "\\.rhtml$" 
    "\\.erb$" 
    "\\.prawn$" 
    "Rakefile$" 
    "Gemfile$")) 

...:

Debugger entered--Lisp error: (void-variable ruby-mode) 
    (set-mode-for-filename-patterns ruby-mode (quote ("\\.rb$" "\\.rsel$" "\\.rhtml$" "\\.erb$" "\\.prawn$" "Rakefile$" "Gemfile$"))) 
    eval-buffer(#<buffer *load*> nil "/home/duncan/.emacs" nil t) ; Reading at buffer position 1768 
    load-with-code-conversion("/home/duncan/.emacs" "/home/duncan/.emacs" t t) 
    load("~/.emacs" t t) 
    #[nil "\205\264 

私はここで少し混乱しています...特に、私は下にしないでください立て方ruby-modeは無効です&ですので、関数に渡すことはできませんが、となりますconsはペアになりますか?

すべてのポインタ(heh)は非常に高く評価されます。

答えて

4

(cons '("\\.rb$" . ruby-mode) ... 

ruby-modeは、引用されたリストの一部です。つまり、シンボル名として読み取られ、変数として評価されません。言い換えれば、Emacsはそれをシンボルruby-modeとみなし、それをそのまま受け入れます。フォームで

(set-mode-for-filename-patterns 
    ruby-mode 
    '("\\.rb$" 
    "\\.rsel$" 
    ... 

ruby-modeが引用されていない、ので、関数の引数として読み込まれます。関数の引数が評価されます。つまり、Emacsはruby-modeと読み、シンボルとして認識し、それを評価しようとします。シンボルを評価するということは、それが指し示す値を探していることを意味します。この場合は存在しません。

編集:

あなたの機能はまだ動作しません、別の問題があります。 set-mode-for-filename-patternsの中に引用されたリストを使用しました。これはあなたの元のコードでは正常に動作します:

(setq auto-mode-alist (cons '("\\.rb$" . ruby-mode) auto-mode-alist)) 

手動filename-patternmodeためを供給有効であるとして。あなたの関数の中では、と評価されたこれらのシンボルがと評価されています。その結果、リストから異なる文字列をauto-mode-alistに追加する代わりに、記号filename-patternが代わりに取得されます。この問題を解決するには

は、あなたが「ことを認識する必要があります(ファイル名のパターン。モード)filename-patternmodeと短所セルを生産するためのものです。これは私たちが作り出すことができます(consファイル名パターンモード)。だから、修正関数は次のようになります。

(defun set-mode-for-filename-patterns (mode filename-pattern-list) 
    (mapcar 
    (lambda (filename-pattern) 
     (setq 
     auto-mode-alist 
     (cons (cons filename-pattern mode) auto-mode-alist))) 
    filename-pattern-list)) 

し、補正関数呼び出しは次のとおりです。

(set-mode-for-filename-patterns 
    'ruby-mode 
    '("\\.rb$" 
    "\\.rsel$" 
    "\\.rhtml$" 
    "\\.erb$" 
    "\\.prawn$" 
    "Rakefile$" 
    "Gemfile$")) 
1

はここを見て:

(setq auto-mode-alist (cons '("\\.rb$" . ruby-mode) auto-mode-alist)) 
----------------------------^ 

この

は、あなたが次の フォームの評価を防ぐ意味 quoteあり、これ '("\\.rb$" . ruby-mode) (cons '"hello" 'ruby-mode)に相当します。

しかし、関数set-mode-for-filename-patternsを呼び出すと、 引数が最初に評価され、その結果が 関数に渡されます。だから評価(set-mode-for-filename-patterns ruby-mode ..)はエラーを起こします。なぜなら、emacs-lispインタプリタは、がruby-modeを変数として評価しようとしますが、にはの値がないので、エラー(void-variable ruby-mode)になります。あなたがここに欲しい 何なので、あなたがletruby-modeモードに値を設定している可能性があり、この(set-mode-for-filename-patterns 'ruby-mode ...)

ノートのようにそれ を引用する必要があり、シンボルruby-modeを渡すことです。ここ

(let ((ruby-mode 'ruby-mode)) 
    (set-mode-for-filename-patterns ruby-mode ...)) 

引数がフォーム(set-...)が評価されるとき、それは ruby-modeを評価し、(シンボル ruby-modeである)、それのための値を検索し、関数に渡すことができます。フォームで

1

私はset-mode-for-filename-patternsは面白い機能だと思います。私は自分の設定に追加するつもりですが、より最適化された実装を使用します。

ここでの実装はすべて、ファイル接尾辞ごとに変数auto-mode-alistに1つの項目を追加します。 Emacsは、ファイルを見つけるたびにこのリストを検索します。したがって、auto-mode-alistが短いほど、より高速なEmacsがファイルを見つけます。

(defun set-mode-for-filename-patterns (mode filename-pattern-list) 
    (push (cons (regexp-opt filename-pattern-list) mode) 
     auto-mode-alist))` 

これは、同じコールで動作します:

(set-mode-for-filename-patterns 
    'ruby-mode 
    '("\\.rb$" 
    "\\.rsel$" 
    "\\.rhtml$" 
    "\\.erb$" 
    "\\.prawn$" 
    "Rakefile$" 
    "Gemfile$")) 

あなたがauto-mode-alistの値を見れば、あなたのファイルを見つけるとき

このバージョンでは、起動時に、おそらく遅いですが速いです組み込みのモードの多くは、同じパフォーマンスの理由で正規表現を使用することがわかります。

ところで、正しいことをするにはregexp-optを信頼することをお勧めします。それが作る正規表現は、目(そして脳)にかなり難しいものです。

+0

'regexp-opt'に渡される引数リストのメンバは、それ自体正規表現ではありません。 http://stackoverflow.com/questions/11027783/how-can-i-cons-a-list-of-pairs-on-to-auto-mode-alist/11030085#11030085も参照してください。 – phils

関連する問題