Skip to content

andornaut/filectrl

Repository files navigation

FileCtrl

FileCtrl is a light, opinionated, responsive, theme-able, and simple Text User Interface (TUI) file manager for Linux and macOS

image

Installation

You can download and install a pre-built binary for Linux or macOS:

curl -sL https://github.com/andornaut/filectrl/releases/latest/download/filectrl-linux -o filectrl
chmod +x filectrl
sudo mv filectrl /usr/local/bin/

On macOS, allow the unsigned filectrl binary to be executed:

xattr -d com.apple.quarantine filectrl

Building

  1. git clone and cd into this repository
  2. Run cargo build --release && sudo cp target/release/filectrl /usr/local/bin/

Usage

Run filectrl --help to view the available command line arguments and options:

Usage: filectrl [-c <config>] [--write-default-config] [--write-default-themes] [--colors-256] [--] [<directory>]

FileCTRL is a light, opinionated, responsive, theme-able, and simple Text User Interface (TUI) file manager for Linux and macOS

Positional Arguments:
  directory         path to a directory to navigate to

Options:
  -c, --config      path to a configuration file
  --write-default-config
                    write the default config to ~/.config/filectrl/config.toml,
                    then exit
  --write-default-themes
                    write default theme files to ~/.config/filectrl/, then exit
  --colors-256      force 256-color theme (disables truecolor detection)
  --help, help      display usage information

Copy / paste

When you copy/cut a file or directory, FileCtrl puts ${operation} ${path} into your clipboard buffer (where operation is "cp" or "mv"). If you then paste into a second FileCtrl window, this second instance of FileCtrl will perform the equivalent of: ${operation} ${path} ${current_directory}, e.g. cp filectrl.desktop ~/.local/share/applications/. Under the hood, FileCtrl doesn't actually invoke cp or mv, but implements similar operations using the Rust standard library.

Keyboard controls

Normal mode

Actions Shortcuts
Quit q
Navigate /h, /j, /k, /l
Go to home directory ~
Go to parent directory /b/Backspace
Open /f/l/Enter/Space
Open custom o
Select first row Home/g/^
Select last row End/G/$
Jump to middle row z
Page down Ctrl+f/Ctrl+d/PgDn
Page up Ctrl+b/Ctrl+u/PgUp
Delete Delete
Filter /
Clear filter/alerts/clipboard/progress Esc, a, c, p
Refresh Ctrl+r/F5
Rename r/F2
New window w
Open terminal t
Copy/Cut/Paste selected Ctrl+c, Ctrl+x, Ctrl+v
Sort by name, modified, size n, m, s
Toggle help ?

Prompt mode

Actions Shortcuts
Submit Enter
Cancel Esc
Reset to initial value Ctrl+z
Move cursor /
Move cursor by word Ctrl+/Ctrl+
Jump to line start/end Ctrl+a/Ctrl+e, Home/End
Select text Shift+/Shift+
Select to beginning/end of line Shift+Home/Shift+End
Select by word Ctrl+Shift+/Ctrl+Shift+
Select all Ctrl+Shift+A
Copy/Cut/Paste text Ctrl+c, Ctrl+x, Ctrl+v
Delete before/after cursor Backspace/Delete

Note

Ctrl+Shift keybindings require a terminal that supports the kitty keyboard protocol (e.g. Alacritty). tmux users must also add the following to ~/.tmux.conf:

set -g extended-keys on
set -ga terminal-features ",*:extkeys"

Configuration

The configuration is drawn from the first of the following:

  1. The path specified by the command line option: --config
  2. The default path, if it exists: ~/.config/filectrl/config.toml
  3. The built-in default configuration

Run filectrl --write-default-config to write the default configuration to ~/.config/filectrl/config.toml.

Opening in other applications

Keyboard key Description
f Open the selected file using the default application configured in your environment
o Open the selected file using the program configured by: openers.open_selected_file
t Open the current directory in the program configured by: openers.open_current_directory
w Open a new filectrl window in the terminal configured by: openers.open_new_window
# Use [openers.linux] on Linux, or [openers.macos] on macOS.
# %s is replaced by the relevant path at runtime.
[openers.linux]
# %s will be replaced by the path to the current working directory:
open_current_directory = "alacritty --working-directory %s"
open_new_window = "alacritty --command filectrl %s"
# %s will be replaced by the path to the selected file or directory:
open_selected_file = "pcmanfm %s"

[openers.macos]
open_current_directory = "open %s"
open_new_window = "open -a Terminal %s"
open_selected_file = "open %s"

Theming

All colors can be changed by editing the [theme] (truecolor) and [theme256] (256-color) sections inline in the configuration file:

filectrl --write-default-config
vim ~/.config/filectrl/config.toml

You can see all of the available theme variables in the default configuration.

External theme files

You can store themes in separate files and switch between them by setting theme_file and/or theme256_file in config.toml:

# Replaces the inline [theme] section with the contents of the specified file
theme_file = "my-theme.toml"
# Replaces the inline [theme256] section
theme256_file = "my-theme-256.toml"
  • Relative paths are resolved from the directory containing the config file (e.g. ~/.config/filectrl/)
  • Absolute paths are used as-is
  • When set, the external file completely replaces the corresponding inline [theme]/[theme256] section
  • If the file doesn't exist or can't be parsed, FileCtrl exits with an error

To get started with custom themes, export the built-in defaults as standalone files:

filectrl --write-default-themes
# Creates:
#   ~/.config/filectrl/default-theme.toml
#   ~/.config/filectrl/default-theme-256.toml

Then copy, rename, and edit them:

cp ~/.config/filectrl/default-theme.toml ~/.config/filectrl/solarized.toml
vim ~/.config/filectrl/solarized.toml

And point your config at the new file:

theme_file = "solarized.toml"

Desktop entry

You can make filectrl the default application for opening directories. Start by copying the filectrl.desktop file to ~/.local/share/applications/:

cp filectrl.desktop ~/.local/share/applications/
xdg-mime default filectrl.desktop inode/directory
update-desktop-database ~/.local/share/applications/

Developing

  • andornaut@github /til/rust
  • See Cargo.toml for dependencies.
  • Download files and folders of various types to test colors
  • The fixtures/ directory contains a committed file tree for manual UI testing. Navigate into it with cargo run to exercise rendering edge cases:
    • file_dates/ — files with mtimes in each date-colour bucket (< 1 min, < 1 hour, < 1 day, < 1 month, < 1 year, > 1 year)
    • file_sizes/ — sparse files covering every size-colour bucket (bytes → GiB)
    • file_types/ — named pipe, symlinks, executable, and directory permission variants (other-writable, sticky)
    • no_delete/ — read-only parent directory (chmod 555); navigate here to trigger delete/rename permission errors
    • scrolling/ — 53 entries with long filenames interspersed to exercise scrolling and multi-row truncation
    • Plus: executables, symlinks, hidden files, Unicode names, special characters, and long filenames
cargo clippy
cargo fix --allow-dirty --allow-staged
cargo test
cargo run
cargo build --release
./target/debug/filectrl
sudo cp ./target/debug/filectrl /usr/local/bin/

# Log to ./err
RUST_LOG=debug cargo run 2>err

Git hooks

Changing cargo-husky configuration:

  1. Edit the [dev-dependencies.cargo-husky] section of Cargo.toml
  2. rm .git/hooks/pre-commit (or other hook file)
  3. cargo clean
  4. cargo test
  5. Verify that the changes have been applied to .git/hooks/pre-commit

Releasing

The project uses GitHub Actions to automate the release process. To release a new version:

  1. Ensure you are on the main branch and have pulled the latest changes.

  2. Create and push a new semantic version tag:

    git tag -a v1.0.0 -m "Release v1.0.0"
    git push origin v1.0.0
  3. The GitHub Actions release workflow will automatically trigger, build the binaries for Linux and macOS, and create a new GitHub Release with the artifacts.

About

A light, opinionated, responsive, theme-able, and simple Text User Interface (TUI) file manager for Linux and macOS

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages