English | 日本語
ファイル拡張子の関連付け機能を使うと、XeFM がさまざまな種類のファイルを開く、表示する、編集するときに使うプログラムを、拡張子に基づいて設定できます。XeFM がいろいろなファイルの種類をどう扱うかを柔軟にカスタマイズできます。
ファイルの関連付けでは、XeFM がファイルの種類ごとに、開く・表示する・編集するのに使うプログラムを設定できます。たとえば、画像の表示にはプレビューを、編集には Photoshop を使う、といった設定ができます。
~/.xefm/config.py に次のように追加します。
FILE_ASSOCIATIONS = [
# Images: Multiple patterns, Preview for viewing, Photoshop for editing
{
'pattern': ['*.jpg', '*.jpeg', '*.png', '*.gif'],
'open|view': ['open', '-a', 'Preview'], # Same for open and view
'edit': ['open', '-a', 'Photoshop']
},
# Videos: QuickTime for viewing, Final Cut for editing
{
'pattern': ['*.mp4', '*.mov'],
'open|view': ['open', '-a', 'QuickTime Player'],
'edit': ['open', '-a', 'Final Cut Pro']
},
# PDFs: Preview for viewing, Acrobat for editing
{
'pattern': '*.pdf',
'open|view': ['open', '-a', 'Preview'],
'edit': ['open', '-a', 'Adobe Acrobat']
}
]
ファイルの関連付けは、~/.xefm/config.py ファイルの FILE_ASSOCIATIONS リストで設定します。
FILE_ASSOCIATIONS = [
{
'pattern': '*.ext' or ['*.ext1', '*.ext2'], # Single or multiple
'open|view': ['command', 'args'], # Combined actions
'edit': ['command', 'args'] # Separate action
}
]
| を使って、同じコマンドを複数のアクションに割り当てられますファイルのパターンごとに、最大 4 つのアクションを設定できます。
| アクション | 実行するもの | 動作 | 値 |
|---|---|---|---|
| enter | open_item(Enter) |
気軽に開く — XeFM の中で 処理 | 内蔵ハンドラーの名前 |
| open | open_with_os |
意図して開く — 別のアプリに渡す | コマンド |
| view | view_file |
ファイルを表示 | コマンド |
| edit | edit_file |
ファイルを編集 | コマンド |
キーはキーマッププリセットによって異なります。キーマッププリセットを参照してください。
open_item と open_with_os は、意図的に異なる操作になっています。
Enter は XeFM の外に出ません。 ディレクトリに入り、アーカイブをブラウズし、ファイルを内蔵ビューアーで開きます。アプリケーションを起動したりフォーカスを奪ったりしないので、安心して頼れます。open_with_os はファイルを実際のアプリケーションに渡します。 プレビューや IDE、OS の既定のアプリを本当に使いたいときに使ってください。デスクトップのウィンドウでは、通常のキーに加えて、開くときと同じ Enter に修飾キーを付けても動作します。enter の段階は XeFM の中にとどまるので、その値には起動するプログラムではなく 内蔵ハンドラー の名前を書きます。
| 値 | 効果 |
|---|---|
'viewer' |
内蔵のテキスト/Markdown ビューアーで開く |
'navigate' |
ファイルをアーカイブとしてブラウズする(*.jar、*.whl に便利) |
'list' |
ファイルを 1 行に 1 つのパスのファイルリストとして開く(*.m3u、*.m3u8 の既定) |
None |
何もしない |
| (ルールなし) | XeFM の既定:ディレクトリとアーカイブには入り、ファイルは表示する |
{
'pattern': '*.csv',
'enter': 'viewer', # Enter -> built-in viewer
'open': ['open', '-a', 'Numbers'], # open_with_os -> Numbers
}
プログラムは 2 つの形式で指定できます。
'open': ['open', '-a', 'Preview']
'open': 'open -a Preview'
'edit': None # No editor configured for this file type
view の場合、None はもっと具体的な意味になり、内蔵ビューアーを使う ことを表します。テキストファイルを参照してください。
これを宣言する必要はありません。 XeFM が画面を明け渡すかどうかは、設定したプログラムではなく、実行しているバックエンドで決まります。
| モード | プログラムを起動したときの動作 |
|---|---|
ターミナル(--backend tui) |
XeFM は一時停止し、プログラムがターミナルを使います。プログラムが終了すると XeFM が復帰して再描画します |
| デスクトップモード | 明け渡すターミナルがないので、プログラムは切り離して起動され、XeFM は操作できる状態のままです |
そのため、'view': ['less'] はターミナルモードでそのまま動作します。フラグは要りません。
{
'pattern': '*.log',
'view': ['less'], # terminal mode hands the display over and waits
'edit': ['code'], # a GUI editor in the same entry is fine
}
実際の帰結は TEXT_EDITOR と同じで、実行するモードに合ったプログラムを選んでください。 デスクトップモードで実行中に設定したターミナルプログラムは描画するターミナルがないので表示されません。ターミナルモードで GUI のランチャーを使うと動作し、XeFM が復帰するときに短い再描画が入ります。
この機能の初期の案では、エントリごとに
'terminal': Trueフラグがありました。これは削除されました。XeFM がすでに判断できることと重複しており、ターミナルのビューアーと GUI のエディターを混ぜた 1 つのエントリを表現できず、しかも失敗したときに安全ではなかったためです。lessに付け忘れるとターミナルが壊れました。手書きの設定に残ったterminalキーは無視されます。
関連するファイルのパターンをまとめます。
{
'pattern': ['*.jpg', '*.jpeg', '*.png', '*.gif']
}
拡張子ごとに同じ設定を繰り返す必要がありません。
パイプ | 演算子を使って、同じコマンドを複数のアクションに割り当てます。
{
'open|view': ['open', '-a', 'Preview']
}
open と view が同じプログラムを使うことがはっきりわかり、意図が明確になります。
パターンが 1 つなら文字列で:
'pattern': '*.pdf'
複数ならリストで:
'pattern': ['*.mp4', '*.mov', '*.avi']
旧形式(冗長):
FILE_ASSOCIATIONS = {
'*.jpg': {
'open': ['open', '-a', 'Preview'],
'view': ['open', '-a', 'Preview'],
'edit': ['open', '-a', 'Photoshop']
},
'*.jpeg': {
'open': ['open', '-a', 'Preview'],
'view': ['open', '-a', 'Preview'],
'edit': ['open', '-a', 'Photoshop']
},
# ... repeat for each extension
}
新形式(コンパクト):
FILE_ASSOCIATIONS = [
{
'pattern': ['*.jpg', '*.jpeg', '*.png', '*.gif'],
'open|view': ['open', '-a', 'Preview'],
'edit': ['open', '-a', 'Photoshop']
}
]
削減効果:行数が 75% 減ります。
FILE_ASSOCIATIONS のエントリは、上から下へ順に調べられます。そのため、一般的なルールの前に特定のルールを書いておけば、ファイルの扱いを細かく制御できます。
XeFM があるファイルとアクションに対応するプログラムを探すときは、次のようにします。
最初に一致したエントリが優先されます。ただし、そのエントリにアクションがある場合に限ります。
FILE_ASSOCIATIONS = [
# Specific: Test files
{
'pattern': 'test_*.py',
'open': ['pytest', '-v'],
'edit': ['vim']
},
# General: All Python files
{
'pattern': '*.py',
'open': ['python3'],
'view': ['less'],
'edit': ['vim']
}
]
動作:
test_main.py + open → pytest -v(最初のエントリに一致)test_main.py + view → less(最初のエントリに ‘view’ がないので、2 番目のエントリを使用)script.py + open → python3(最初のパターンに一致しないので、2 番目のエントリを使用)FILE_ASSOCIATIONS = [
# Specific: README files with special viewer
{
'pattern': 'README*',
'view': ['glow'] # Markdown renderer
},
# General: All markdown files
{
'pattern': '*.md',
'open': ['typora'],
'view': ['less'],
'edit': ['vim']
}
]
動作:
README.md + view → glow(最初のエントリに一致)README.md + open → typora(最初のエントリに ‘open’ がないので、2 番目のエントリを使用)notes.md + view → less(最初のパターンに一致しないので、2 番目のエントリを使用)設定すると、XeFM は次の場面でこれらの関連付けを使います。
Enter は enter アクションを使います。外部プログラムを起動することはありません。
動作:
'viewer' は内蔵ビューアーで開き、'navigate' はファイルをアーカイブとしてブラウズし、'list' はファイルリストとして開き、None は何もしませんopen_with_os に割り当てたキーを示す警告をログに出します現在、画像で *“No built-in viewer for photo.png — press
open_with_os は open アクションを使います。
動作:
None なら何も起動しません(あるファイルの種類を OS に決して渡さないようにするにはこうします)open / xdg-open / start)を使いますファイルの上で view_file(File → View File)を実行すると、XeFM はファイルの関連付けの view アクションを使います。
動作:
None なら、内蔵のテキストビューアーで開きますリモートのファイルとアーカイブ内のファイルは、常に内蔵ビューアーを使います。外部プログラムが開けるディスク上のパスがないためです。
edit_file(File → Edit File)を実行すると、XeFM はファイルの関連付けの edit アクションを使って、選択したファイル(何も選択していなければフォーカスのあるファイル)を編集します。
動作(ファイルごと):
None なら、エディターが設定されていないことを伝えて止まりますTEXT_EDITOR を使います同じプログラムになるファイルは 1 回の起動でまとめて渡される(vim a.txt b.txt)ので、複数ファイルの編集は 1 つのエディターのセッションになります。いろいろなファイルが混ざった選択では、エディターごとに 1 回ずつ起動されることもあります。
ローカルのファイルだけが対象です。リモートのパスとアーカイブ内のパスはスキップされます(混ざった選択では個別にスキップされ、それぞれログに 1 行出ます)。
{
'pattern': ['*.jpg', '*.png'],
'open|view': ['open', '-a', 'Preview'], # Same for both
'edit': ['open', '-a', 'Photoshop'] # Different editor
}
使い方:
photo.jpg の上で Enter → プレビューで開きますphoto.jpg の上で view_file → プレビューで開きます(Enter と同じ)photo.jpg の上で edit_file → Photoshop で開きます{
'pattern': '*.avi',
'open|view': ['open', '-a', 'VLC'],
'edit': None # No editor configured
}
使い方:
movie.avi の上で Enter → VLC で開きますmovie.avi の上で view_file → VLC で開きますmovie.avi の上で edit_file → “No editor configured” というメッセージを表示します{
'pattern': '*.txt',
'open': ['open', '-e'], # TextEdit
'edit': ['vim'] # Terminal editor
# 'view' omitted - will use built-in text viewer
}
使い方:
readme.txt の上で Enter → テキストエディットで開きますreadme.txt の上で view_file → 内蔵のテキストビューアーで開きます(シンタックスハイライト付き)readme.txt の上で edit_file → vim で開きます注:view アクションを省略すると、XeFM はテキストファイルに内蔵のテキストビューアーを使えます。内蔵ビューアーはシンタックスハイライトを備え、コードやテキストファイルの閲覧に最適化されています。
ファイルに関連付けが設定されていない場合:
view_file:内蔵のテキストビューアーで開きます。ビューアーはバイト列を読み、テキストはシンタックスハイライト付きで表示し、バイナリはプレースホルダーを表示しますedit_file:設定項目 TEXT_EDITOR を使いますXeFM は拡張子ではなく、バイト列を読んでテキストかどうかを判定します。 XeFM には「テキストの拡張子」の一覧は意図的にどこにもありません。そのような一覧は、拡張子のないファイル(Makefile、README)、未知の拡張子、紛らわしい拡張子では間違えますが、内容を調べればこの 3 つとも労せず正しく判定できます。
内蔵ビューアーは次のように判定します。
utf-8、次に latin-1、次に cp1252 として デコードしてみます[Binary file — cannot display as text] と表示しますlatin-1 で表示しますXeFM 全体での目安は 能力はバイト列から判定し、好みは拡張子で設定する です。拡張子が決めるのは どのアプリケーションを使いたいか であって、ファイルがテキストとして読めるかどうかではありません。
view アクションには 3 つの場合があり、そのうち 2 つは同じ結果になります。
view の値 |
効果 |
|---|---|
コマンド(例:['less']) |
その外部ビューアーを起動する |
None |
内蔵ビューアーを使う(テキストは表示、バイナリはプレースホルダー) |
| (一致するルールなし) | None と同じ — フォールバックで内蔵ビューアー |
つまり view では、None と「ルールがまったくない」ことは同じです。この違いが意味を持つのは open と edit だけで、そこでは None は「このファイルの種類ではこのアクションを使えない」ことを意味し、フォールバックを止めます。'view': None を明示的に設定するのは、後にあるより一般的なエントリがコマンドを指定するかもしれない場合に、内蔵ビューアーを 確実に 使いたいときだけです。
| アクション | 関連付けあり | 関連付けなし — テキスト | 関連付けなし — バイナリ |
|---|---|---|---|
| Enter | 内蔵ハンドラーまたは設定した open | 内蔵ビューアー | 外部で開くキーを使うよう警告 |
View(view_file) |
設定したビューアー(None なら内蔵) |
内蔵ビューアー | 内蔵ビューアーがプレースホルダーを表示 |
Edit(edit_file) |
設定したエディター | 設定項目 TEXT_EDITOR |
設定項目 TEXT_EDITOR |
上の設定できるアクションのほかに、XeFM にはファイルを OS に渡す固定の操作が 2 つあります。
アクション:open_with_os。open アクションと同じキーです。
これは open_with_os で説明した、意図して開く段階です。XeFM はまず関連付けの中から open コマンドを探し、なければ(明示的に None でもなければ)OS の既定のアプリケーションを使います。macOS では open、Linux では xdg-open、Windows では start です。選択したファイルを開き、何も選択していなければフォーカスのあるファイルを開きます。この受け渡しは open コマンドのようにファイルごとに設定することは できません。その種類のファイルに OS が登録しているものが使われます。
アクション:reveal_in_os。
OS のファイルマネージャーを、その項目を選択した状態で開きます。
open -R で Finderexplorer でエクスプローラーこのアクションは選択項目ではなく、常に フォーカスのある 項目を使います。フォーカスのある項目がディレクトリの場合は、中身を表示するために開くのではなく、その親の中で(選択された項目として)表示します。OS 側に出てドラッグ&ドロップをしたり、ネイティブのコンテキストメニューを使ったりするのに便利です。
OS の既定のアプリではなく自分で設定したツールを実行するには、X で外部プログラムのメニューを開きます(外部プログラムを参照)。
複数の画像の拡張子をまとめ、開くのと表示するのに同じプログラムを使います。
{
'pattern': ['*.jpg', '*.jpeg', '*.png', '*.gif'],
'open|view': ['open', '-a', 'Preview'],
'edit': ['open', '-a', 'Photoshop']
}
{
'pattern': ['*.mp4', '*.mov'],
'open|view': ['open', '-a', 'QuickTime Player'],
'edit': ['open', '-a', 'Final Cut Pro']
},
{
'pattern': '*.avi',
'open|view': ['open', '-a', 'VLC'],
'edit': None # No editor configured
}
{
'pattern': '*.pdf',
'open|view': ['open', '-a', 'Preview'],
'edit': ['open', '-a', 'Adobe Acrobat']
}
{
'pattern': '*.txt',
'open': ['open', '-e'], # TextEdit on macOS
'edit': ['vim']
# 'view' omitted - uses built-in text viewer
},
{
'pattern': ['*.py', '*.js'],
'open': ['open', '-a', 'Visual Studio Code'],
'edit': ['vim']
# 'view' omitted - uses built-in text viewer with syntax highlighting
}
ファイルの関連付けは、ワイルドカードのパターンで照合します。
*.pdf - すべての PDF ファイルに一致*.jpg - すべての JPG ファイルに一致*.tar.gz - 圧縮された tar アーカイブに一致パターンの照合では大文字と小文字を区別しないので、*.PDF と *.pdf は同じものとして扱われます。
プラットフォームごとに異なるプログラムを設定できます。
import platform
FILE_ASSOCIATIONS = []
if platform.system() == 'Darwin': # macOS
FILE_ASSOCIATIONS.append({
'pattern': ['*.jpg', '*.png'],
'open|view': ['open', '-a', 'Preview'],
'edit': ['open', '-a', 'Photoshop']
})
elif platform.system() == 'Linux':
FILE_ASSOCIATIONS.append({
'pattern': ['*.jpg', '*.png'],
'open': ['xdg-open'],
'view': ['eog'], # Eye of GNOME
'edit': ['gimp']
})
XeFM には、よく使われるファイルの種類に対する既定の関連付けが用意されています。
これらの既定は、設定ファイルでどれでも上書きできます。
複数のアクションに同じプログラム:特にメディアファイルでは、’open’ と ‘view’ の両方に同じプログラムを使うのが一般的です。
専用のエディター:閲覧用のアプリケーションとは別の、編集専用のソフトウェアには ‘edit’ アクションを使ってください。
アクションを使えなくする:あるファイルの種類であるアクションを使えなくしたい場合は、そのアクションを None に設定してください。
コマンドを試す:設定に追加する前に、コマンドがターミナルから動作することを確認してください。
絶対パスを使う:プログラムが PATH にない場合は、実行ファイルの絶対パスを使ってください。
特定のパターンを先に:設定では、より特定的なパターンを常に一般的なパターンより前に置いてください。
意図を書き残す:エントリをその順序にした理由をコメントで説明してください。
XeFM がプログラムを見つけられない場合:
違うプログラムが開く場合:
アクションが表示されない場合:
None になっていないか)確認してくださいファイルが想定したパターンに一致しない場合:
*.ext の形式を使います)テストを実行して、すべてが動作することを確認します。
python3 test/test_file_associations.py
doc/dev/FILE_ASSOCIATIONS_IMPLEMENTATION.mddoc/XEFM_USER_GUIDE.md