diredバッファでは、そのディレクトリの最も重要なファイルにポイントを置きます


14

Emacsのディレクトリにアクセスする時間の90%は、最初に特定のファイルにポイントを移動して開くことです。多くの場合、開く必要があるファイルは非常に予測可能です。例えば:

  • .texこのディレクトリにファイルがある場合、通常はに直接進みmaster.texます。
  • Androidプロジェクトのルートでは、通常はAndroidManifest.xmlです。
  • emacsパッケージを開発するディレクトリでは、ほとんどの場合、パッケージのメインソースファイルです。通常は、常にではありませんが、.elこのディレクトリにある唯一のファイルです。

これらのディレクトリを開くときに、これらのファイルに自動的にポイントを置く方法はありますか?

これは多くの利便性を提供します(単にヒットするだけで開くことができますRET)が、他のファイルにアクセスする柔軟性を提供します。

回答:


16

のカスタム関数を作成しdired-initial-position-hookます。この関数では、さまざまな関数を使用してファイルを検索し、最終的にdired-goto-fileポイントを移動して「最適な」ファイルに移動できます。

(defun my-dired-goto-important-file ()
  "Go to an important file in the current dired buffer."
  (unless (bound-and-true-p save-place)
    (let ((candidates '("master.tex" "AndroidManifest.xml"))
          candidate)
      (while (and candidates
                  (not (dired-goto-file (expand-file-name (pop candidates)))))
        nil))))

(add-hook 'dired-initial-position-hook #'my-dired-goto-important-file)

以下では、この機能の特定の側面を説明し、潜在的な拡張機能を強調します。

ファイルへのジャンプ

dired-goto-filenil現在のdiredバッファにファイルが存在しない場合に返されるため、事前のチェックなしで呼び出しても安全です。ただしdired-goto-file絶対ファイル名(相対名でエラー)が必要expand-file-nameです。

ファイルを検索する

Diredは、ファイルを検索するための簡単なAPIを提供していません。通常、バッファ内のすべての行を反復するのと同じように、すべてのファイルを反復できます。

(let (files)
  (goto-char (point-min))
  (while (not (eobp))
    (let ((filename (dired-get-filename nil 'no-error)))
      (when filename
        (push filename files)))
    (forward-line 1))
  ;; Now `files' is a list of files, which you can search for patterns
  ;; …
  )

ただし、マーキング機能を使用する方が便利です。既存のインタラクティブマークを失わないように、「異常な」マーカー文字を使用するよう注意してください。

(unwind-protect
    (when (dired-mark-files-regexp (rx ".tex" string-end) ?t)
      (dired-goto-file (expand-file-name "master.tex")))
  (dired-unmark-all-files ?t))

場所モードを保存

また、プレイスモードを有効にした場合は、保存モードについても注意する必要があります。Diredバッファーでは、Save Placeモードは他のモードのようにポイント値を記憶せず、最後のファイル名ポイントがオンでした。このファイル名は、私たちと同じように復元します:フックしdired-initial-position-hookて呼び出しますdired-goto-file(実際、そこからコードを盗みました:))。

フックが場所の保存の前に来る場合、場所の保存モードは無条件に位置を上書きします。ただし、(このフックをセットアップした後に場所の保存が有効になっている場合のように)フックの前に来ると、実際には関数は場所の保存を上書きしますが、これは望ましくありません。ただし、任意のバッファと同様に、Save Placeはローカル変数save-placeを非nil値に設定するため、単純に確認して、Save Placeはファイル名を復元しませんでした。

Save Placeを「ルーズ」にしたい場合は、のチェックを外し、Save Place Modeを最初に有効にしてから引数の非nil値で呼び出して、Save Placeの後にsave-placeフックが実行されることを確認します。add-hookAPPEND


素晴らしい答え。定義することもできますbound-and-true-p。:-)
マラバルバ

@Malabarba bound-and-true-pはからの組み込みマクロですbindings.el
lunaryorn 14

親愛なる神様、私が気分を悪くすることはありません。それを知らなかったという事実や、私もチェックしなかったという事実です。
マラバルバ14

@Malabarba気にしないで、この関数の存在を発見するのに(文字通り)1年かかりました。
lunaryorn 14

はい、それは私が今まで聞いたこともない素晴らしい機能です!
sanityinc 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.