← XeFM crftwr/xefm on GitHub · craftware

File Lists

A pane can show a list of paths instead of a directory: files that live all over the disk, or on several machines, side by side in one listing, where every file operation works on them as it does anywhere else.

The list comes from outside XeFM. Search in the tool that is best at it — Everything, find, fd, rg -l, git ls-files, a build log, a column in a spreadsheet — and bring the paths in, by copying them or by running the command from XeFM.

Go → Open List opens one from three places, each an action you can bind to a key.

From the clipboard

Go → Open List → From Clipboard (open_list_from_clipboard) reads the clipboard as one path per line and shows those paths in the active pane.

find . -name '*.py' -mtime -1 | pbcopy        # macOS
rg -l TODO | clip                             # Windows

It is the reverse of Copy Full Path(s): select files anywhere, copy their paths, and importing them gives you the same rows back.

From a command

Go → Open List → From Command… (open_list_from_command) asks for a command, runs it in the pane’s directory, and shows the paths it prints — one step instead of piping to the clipboard and importing.

The dialog is a command field with the commands you have run listed below it, most recent first:

Key Does
typing Edits the command, and narrows the history (Migemo included)
↓ / ↑ Move through the history, copying each command into the field
Enter In the history: choose that command and go back to the field. In the field: run what it holds
Esc In the history: back to what you typed. Otherwise: close
Shift-Delete In the history: forget that command

Enter in the field always runs the field: typing rg -l runs rg -l, even with rg -l TODO in the history. To run an old command, press ↓ to it and Enter twice — once to choose it, once to run it — or change it in between; see Fields with a history.

rg -l TODO
git ls-files --modified
fd -e py -E tests
es.exe -path . ext:py           # Everything, under this folder
dir /s /b *.log                  # Windows, cmd

Everything’s command-line interface, es.exe, is a separate download from voidtools; put it on your PATH. Its query is Everything’s own search syntax (ext:, dm:thisweek, size:>100mb, |, !). It searches the whole index wherever it runs, so -path . is what limits it to the folder the pane is showing.

Output is read as UTF-8. On Windows the command’s console is switched to UTF-8 before it runs, so dir, es.exe and other console tools print Japanese and other non-English names intact whatever your system language; output from a program that ignores the console’s setting is read in the system’s code page instead. On macOS and Linux, a name that is not valid UTF-8 is kept byte for byte, so the file it names can still be opened.

From a file

Go → Open List → From File (open_list_from_file), or Open as List on a file’s right-click menu, opens the text file under the cursor as a list: one path per line. Select several list files first to open them as one list.

A list file can be anything that names files: an export from Everything (File → Export → TXT), a build log’s list of outputs, a .lst or .txt you keep beside a project, or the saved output of a command:

dir -Recurse -Name *.log > logs.txt         # Windows PowerShell

Playlists, and Enter

An M3U playlist (.m3u, .m3u8) is a list file too: one path per line, relative to the playlist’s folder. Its # lines — #EXTM3U, #EXTINF and the rest — are skipped. In any other list file a line starting with # is a path like any other.

Enter opens a playlist as a list, out of the box. open_with_os still hands it to your player. To make Enter open your own list files the same way, give their extension the 'list' handler in FILE_ASSOCIATIONS:

{
    'pattern': ['*.m3u', '*.m3u8', '*.lst'],
    'enter': 'list',
},

A config written before this rule shipped does not have it; add the entry above to get Enter on playlists. See File Associations.

Giving them keys

The three actions ship without a key. To give them one, add them to your config:

KEY_BINDINGS['open_list_from_clipboard'] = ['Ctrl-Shift-L']
KEY_BINDINGS['open_list_from_command'] = ['Ctrl-Shift-K']
KEY_BINDINGS['open_list_from_file'] = ['Ctrl-Shift-J']

What is read

These apply to every source.

Nothing else is interpreted: no wildcards, no CSV columns, no URLs other than the locations XeFM can open.

What you see

The list is a snapshot: files that appear on disk later are not added, and the pane is not watched for changes while it shows a list. Opening a folder from the list, or pressing Back, returns to an ordinary live directory.

Importing changes only what the pane shows. Nothing is copied, moved, or written.

From your own config

A config action can open a list the same way, with pane.open_list() — for a search written in Python. Unlike Open List → From Command, the action runs on the UI thread, so keep anything slow out of it.