← XeFM crftwr/xefm on GitHub · craftware

External Programs Feature

Overview

The External Programs feature allows you to execute custom external programs directly from XeFM with access to the current file manager state through environment variables. This extends XeFM’s functionality by integrating with external tools and scripts.

Key Bindings

The programs menu and the sub-shell are two different tools: X runs one of your configured PROGRAMS and returns to XeFM, while Shift-X drops you into an interactive shell in the current pane’s directory.

Configuration

External programs are configured in the PROGRAMS list in your config.py file. Each program entry needs:

Basic Configuration Example

PROGRAMS = [
    {'name': 'Git Status', 'command': ['git', 'status']},
    {'name': 'Git Log', 'command': ['git', 'log', '--oneline', '-10']},
    {'name': 'Disk Usage', 'command': ['du', '-sh', '.']},
]

Environment Variables

When you run external programs, XeFM provides information about your current state through environment variables:

Your scripts can use these variables to work with your current selection and location.

Usage

  1. Press X to open the programs dialog
  2. Use the searchable list to find and select a program
  3. Press Enter to launch it

The program runs in the background with the current pane as its working directory; the selected filenames (or the focused one) are also appended as command-line arguments. Its output — stdout and stderr — streams into the log pane, in both terminal and desktop mode, and a nonzero exit code is reported there too. XeFM stays fully responsive throughout.

By default the program’s input is closed at launch, so interactive terminal programs can’t run this way. Give such an entry 'options': {'terminal': True} instead: in terminal mode XeFM suspends its own display and hands the program the terminal — with the same working directory, arguments, and XEFM_* environment — then repaints when it exits, so vim, less, or a REPL work as expected:

{'name': 'View with less', 'command': ['less'], 'options': {'terminal': True}},

If the program exits with a nonzero code, XeFM waits for Enter before repainting, so whatever error output it left on the terminal stays readable.

In desktop mode there is no terminal to hand over, so a terminal: True entry is refused with an error in the log pane — as is sub-shell mode (Shift-X), which in terminal mode remains the tool for extended interactive command-line work.

Example Use Cases

Git Operations

File Operations

Development Tools

System Information

Creating Custom Scripts

On first launch XeFM creates a personal tools directory, ~/.xefm/tools/, and places an example in it: example_tool.py, which prints every XEFM_* variable and resolves the current selection to absolute paths. It is wired into the default PROGRAMS as Example Tool (show XeFM environment), so pressing X and running it shows exactly what your own scripts receive. (The directory is seeded once — if you delete the example, it stays deleted.)

To add a tool of your own:

  1. Drop a script into ~/.xefm/tools/ — copying example_tool.py is a good starting point.
  2. Add an entry to PROGRAMS in ~/.xefm/config.py:
{'name': 'My Tool', 'command': [xefm_python, xefm_tool('my_tool.py')]},

Tools are not limited to Python. The command field is an argument list passed straight to the operating system, so shell scripts and plain commands work the same way:

#!/bin/bash
# Simple script that processes selected files
echo "Working in: $XEFM_THIS_DIR"
echo "Selected files: $XEFM_THIS_SELECTED"
{'name': 'My Shell Script', 'command': ['bash', xefm_tool('my_script.sh')]},

Example integrations

XeFM ships with a few ready-made PROGRAMS entries that show how to wire a real external tool into the menu. Each is a single recipe pointing at a small helper script that reads the XEFM_* environment variables above. The helpers live in XeFM’s bundled tools directory (xefm/tools/) and are located at run time by xefm_tool('name'), which searches ~/.xefm/tools/ first and then that bundled directory. xefm_python is the interpreter XeFM is running under.

Beyond Compare (removed)

Earlier releases bundled Beyond Compare helper scripts (bcompare_files.py, bcompare_dirs.py) and menu entries driving them. Both are gone: XeFM’s built-in diff viewer compares the two selected files (=) and the two pane directories (Shift+=) — see Diff Viewer Feature. A config still referencing the old scripts will log a launch failure; remove those PROGRAMS entries, or — if you prefer Beyond Compare — write a small tool in ~/.xefm/tools/ that runs bcompare on XEFM_LEFT_DIR / XEFM_RIGHT_DIR (start from example_tool.py).

Visual Studio Code

One entry opens the current directory (and any selected files) in VS Code:

{'name': 'Open in VSCode',
 'command': [xefm_python, xefm_tool('vscode.py')]}

vscode.py reads XEFM_THIS_DIR and XEFM_THIS_SELECTED. If the current directory is inside a git repository it walks up to the repository root and opens that instead of the subdirectory, then adds any selected regular files (directories are skipped; filenames with spaces are handled). Requires the code command on your PATH — in VS Code, run Shell Command: Install ‘code’ command in PATH from the command palette.

Troubleshooting

Program Not Found

Permission Denied

No Output

Quick Reference