auto-mode-alistを尊重するために(ファイルだけでなく)バッファーを取得する方法は?


13

Q:マッピングを尊重する新しいバッファを取得するにはどうすればよいauto-mode-alistですか?

ファイルを見つけると、Emacsはファイル拡張子とを比較しauto-mode-alistて、ファイルのバッファに使用するメジャーモードを決定します。情報を使用して、auto-mode-alist(まだ)ファイルが関連付けられていないバッファのモードを決定する方法はありますか?

つまり、ファイル拡張子のように見える名前を持つ新しいバッファを開くと、予期したモードで自動的に開くようにできますか?たとえば、a-new-buffer.elまだファイルに関連付けられていない新しいバッファを開く場合emacs-lisp-mode、デフォルトモードではなく開くようにします。


2
好奇心が強い:ユースケースは何ですか?IOW、なぜ/いつ/どのようなコンテキストでこれを行いたいですか?通常、バッファをファイルに関連付けて、そのモードをからauto-mode-alist取得する場合は、バッファをファイルに訪問します(これですべてが処理されます)。
ドリュー

5
私の典型的なユースケースの例は次のとおりorgです。a)で使用するために書いている新しい関数をテストするための一時バッファorg-mode。b)Rいくつかの迅速な統計操作を行うための一時的なバッファ。c)電子メールを作成するための一時的なテキストバッファ。いずれの場合も、訪問するファイルを作成するのではなく、適切なモードで開かれるスローアウェイバッファーが必要です。
ダン

2
訪問するファイルを作成C-x C-fない」などのファイル訪問コマンド。それは根本的な誤解です。彼らはあなたが探しているものを正確に実行します。これは、あるだけならば、あなたがしようとすると、バッファ保存ファイルが作成されることを。バッファを保存しようとしない場合、ファイルは作成されません。私がこれまでのところ理解していることから、あなたが望むのは、「ファイルを訪問する」ことです(実際には、適切なモードでバッファを開くことを意味します)。
ドリュー

8
Danと同様に、実際のファイルパスに関連付けたくない場合は常に一時バッファーを作成します。偽のファイルパスにアクセスすることはできますが、ディレクトリの選択(または現在のディレクトリの受け入れ)には少なくとも多少の摩擦があります。構成の残りの部分に応じて、他の副作用がある可能性があります。自動保存の動作ですか?Ibufferグループまたはパスによって決定される発射物プロジェクト?イドの確認プロンプト?とにかくバッファには名前が必要なので、名前を使用して一時バッファのモードを自動的に設定するのは理にかなっています。
グルーカス14年

@Drew、はい、それは理にかなっており、この質問に対する最も簡単な答えでしょう-答えとして投稿してください。アップグレードに値します。
ダン

回答:


8

訪問C-x C-f するファイル作成しないなどのファイル訪問コマンド。彼らはあなたが探していることをします。

ファイルが作成されるのは、バッファ 保存 しようとした場合のみです

バッファを保存しようとしない場合、ファイルは作成されません。何をしたい、私がこれまで理解したものから、することがあるファイルをご覧(実際に手段が適切なモードでバッファを開きます)。


4
目的に関係なく、3秒ごとに現在のファイルを絶えず保存する過活動の指がある場合はどうでしょうか。
マラバルバ14年

1
@Malabarba:実際、私はその指を持っています!;-)多分私たちの古いオナラのほとんどは-物事が常にクラッシュしたときに習慣を取り戻しました。しかし、とにかく、私は私が提案したことをします:捨てられたvisited-fileバッファで編集します。私の過活動筋肉の記憶が妨げられて保存しようとする場合、保存nしないようにヒットするか、(多くの場合)バッファーを保存するだけです。その後、作成したファイルをトスします。またはしないでください。)
ドリュー

1
@Malabarba一時ファイルの乱雑さを防ぐため、メジャーモード固有のスクラッチバッファーを使用し始めました。スクラッチがファイルに値する場合は、いつでも後で保存できます。
カウシャルモディ14年

1
@kaushalmodi:モード固有のバッファに対しては何もありませんが、「一時ファイルの混乱」は、バッファの混乱と同じくらい簡単にクリーンアップされます。;-)そして、モード固有のスクラッチバッファ内の機能亢進の指には、おそらく同じ問題があります。おそらくそれと同じです。*scratch*その指が自動的にヒットしたときに保存するように求められますC-x C-s
ドリュー

9

Juri Linkovのソリューションを何年も使用している場合。

のようなもので一時的なバッファを作成しますC-x b test.org C-jmajor-mode経由でファイルの拡張子によって決定されますauto-mode-alist

;; http://thread.gmane.org/gmane.emacs.devel/115520/focus=115794
(setq-default major-mode
              (lambda () (if buffer-file-name
                          (fundamental-mode)
                            (let ((buffer-file-name (buffer-name)))
                          (set-auto-mode)))))

効果をテストするには、試してみてください(prog1 (and (switch-to-buffer "my-new.org") major-mode) (kill-buffer "my-new.org")) => org-mode。クリーンemacs -qでテストは戻りfundamental-modeます。


1
それはとても賢いです!また、advice私が使用していたオプションよりもきれいです。私はその(prog1...)部分が何のためにあるのかを確信していませんが、その(setq-default major-mode ...)部分はとてもいいです。
ダン

1
JuriのEmacsサイトをチェックしてください。prog1あなたが得ること-testちょうどショーが期待major-modeバッファに切り替えるとき。setq-default部品を評価し、テストを実行します。それが戻るorg-mode ことなく、setq-defaultそれは戻りfundamental-modeます。
ラスマス14年

これは、私のbuffer-list-update-hookよりもずっとエレガントです。ありがとう!
グルーカス14

これは受け入れられた答えであるはずです、なぜなら私たちがなぜそれを尋ねるのが間違っているのかを言うのではなく、実際に質問に答えるからです:)
Shlomi

6

@Drewのコメントと@glucasの回答から得られたアイデアを使用して、アドバイスに基づいた方法を見つけました。これは、だれにも役立つ場合に備えて、ここに記録します。

短いバージョン:afterアドバイスを使用して、バッファにファイル名が関連付けられているかどうかを照会し、関連付けられていない場合は一時的に設定し、残りのset-auto-mode機械に詳細を処理させます。少しのテスト(広範囲ではない)の後、うまく機能しているようです。

ido-switch-bufferとvanilla についてswitch-to-bufferは、2つのアドバイスがあります。

(defadvice ido-switch-buffer (after set-mode activate)
  (unless buffer-file-name
    (let ((buffer-file-name (buffer-name)))
      (set-auto-mode t))))

(defadvice switch-to-buffer (after set-mode activate)
  (unless buffer-file-name
    (let ((buffer-file-name (buffer-name)))
      (set-auto-mode t))))

find-file私の指は脳よりも先に進むことができるので、@ Drew が挙げたポイントに加えて、このオプションが役立ちます。筋肉の記憶find-fileは、私が必要とすることを完全に行う前に、スイッチからバッファーへの領域に入ることがよくあります。現在、両方のオプションが利用可能です。

更新:上記のコードの小さなですが、イライラさせる可能性のあるバグ:バッファーに切り替えるたびに、モードフックを再実行します。以下は、/tmpディレクトリから実際のファイル名を取得し、その問題を回避します。

(defadvice ido-switch-buffer (after set-mode activate)
  (unless buffer-file-name
    (setq buffer-file-name (concat "/tmp/" (buffer-name)))
    (set-auto-mode t)))

良さそうに見え、数回の繰り返しで私の答えが蓄積した問題をクリーンアップします。:-)ここで繰り返しますが、何らかの理由で実際のファイルパスを設定したくない場合は、バッファローカル変数を使用して、モードを複数回設定しないようにすることができます。
グルーカス14年

5

このset-auto-mode関数は、バッファーに関連付けられたファイルに基づいてモードを設定します。buffer-file-nameモードを設定するためにバッファ名から一時的に設定する関数は次のとおりです。

(defun my/set-buffer-mode (buffer &optional again)
  "Set the mode for BUFFER from the name.  
When called repeatedly for the same buffer only set the mode the first
time, unless the optional argument AGAIN is specified.
Does nothing if the buffer is associated with a file."

  (with-current-buffer buffer
    (when again (kill-local-variable 'my/buffer-mode-set))
    (unless (or buffer-file-name 
            (local-variable-p 'my/buffer-mode-set))
      (let ((buffer-file-name (buffer-name)))
        (set-auto-mode t)
        (setq-local my/buffer-mode-set t)))))

アドバイスを使用してバッファの名前が変更されたときにこれを実行できます。

(defadvice rename-buffer (after my/rename-update-mode activate)
  (my/set-buffer-mode (current-buffer) 'again))

これをフックして新しいバッファに影響を与える最適な場所がわからない。ここではを使用してbuffer-list-update-hookいますが、必要以上に呼び出される場合があります。

(add-hook 'buffer-list-update-hook
      '(lambda ()
         (my/set-buffer-mode (car (buffer-list)))))

上記の回答は、いくつかの問題に対処するために修正されました。特に、予想される現在のバッファで呼び出されていなかったbuffer-list-update-hookので、使用に戻りましたchange-major-mode-hook。記録については、おそらく@Danが答えで示したように、スイッチバッファー関数をアドバイスする方が理にかなっています。
グルーカス14年

3

* scratch *バッファーは、作業中のファイルと同じメジャーモードを持つ一時バッファーを作成する目的で使用できます。

ここにあなたの問題を解決するかもしれないemacs SEの答え:

同じメジャーモードのファイルと* scratch *バッファーをすばやく切り替えるにはどうすればよいですか?

参照された質問と回答は両方とも私によって投稿されました。関数の答えは次のことを行います。

  • ファイルでXメジャーモードで作業している場合、この関数を呼び出すと*scratch-X-mode*、まだ存在しない場合に呼び出される新しいスクラッチバッファーが作成され、この新しく作成されたバッファーに切り替わります。
  • *scratch-X-mode*既に存在する場合は、単にそのバッファに切り替えます。
  • そのスクラッチバッファーでこの関数を再度呼び出すと、元々作業していたファイルバッファーに戻ります。

0

ここには良い答えがいくつかありますが、もう1つ追加したかったのです。Emacsにはたくさんの機能があり、多くの場合、いくつかの方法があります。拡張子に関係なく、emacsにそのタイプを伝えるタグをファイルの先頭に追加できます。たとえば、これを追加する:

# -*-Python-*-

ファイルの先頭で、emacsに、.py拡張子がなくてもPythonファイルであることを知らせます。#行の先頭はPythonスタイルのコメントであることに注意してください。ファイルの種類ごとに、異なるコメントを使用できます。たとえば、Lispファイルを指定するには;、コメント行を開始し、次のようにemacsでモードを設定するために使用します。

; -*- mode: Lisp;-*-

ファイル変数の指定およびファイルモードの選択を参照してください。


はい。ただし、ここでの質問は、新しい一時バッファ(たとえば、switch-buffer)を作成し、モードを以外に自動的に設定することですfundamental-mode
グルーカス14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.