Home

Awesome

tere - a faster alternative to cd + ls

tere is a terminal file explorer. It is a faster alternative to using cd and ls to browse folders in your terminal. tere only really does one thing: it provides a TUI for efficiently navigating to a folder, and then prints the path to that folder when you exit. By configuring your shell to cd to the printed folder, you can move around in your filesystem very quickly.

A gif showing what using tere looks like

Note that tere is not a file manager, it can only be used to browse folders, not to create, rename or delete them.

tere aims to be minimal and simple. It should be obvious how to use it. Navigating the file system should be efficient and require as few keystrokes as possible. A great source of inspiration for tere is the "type-ahead search" functionality found in many GUI file managers.

"Tere" means "hello" in Estonian. It also feels nice to type.

Setup

To use tere for changing directories, you need to install it, and then configure your shell to cd to the folder tere prints when it exits. Here's how to do it:

Step 1: Obtain a copy of tere

This can be done in various ways:

Step 2: Configure your shell to cd using tere

tere only prints a folder when it exits. To make your shell actually cd to this folder, you have to define a function or alias, since the working directory cannot be changed by a subprocess. See instructions for your shell below.

<details> <summary>Bash/Zsh</summary>

Put this in your .bashrc or .zshrc:

tere() {
    local result=$(command tere "$@")
    [ -n "$result" ] && cd -- "$result"
}
</details> <details> <summary>fish</summary>

Put this in your config.fish:

function tere
    set --local result (command tere $argv)
    [ -n "$result" ] && cd -- "$result"
end
</details> <details> <summary>Xonsh</summary>

Put this in your .xonshrc (Xonsh v0.10. or newer is required):

def _tere(args):
    result = $(tere @(args)).strip()
    if result:
        cd @(result)

aliases["tere"] = _tere
</details> <details> <summary>Nushell</summary>

Put this in your config.nu (Nushell 0.88.0 or newer is required):

def --wrapped --env tere [...args]: {
    let result = ( ^tere ...$args )
    if $result != "" {
        cd $result
    }
}
</details> <details> <summary>PowerShell</summary>

Put this in your $PROFILE:

function Invoke-Tere() {
    $result = . (Get-Command -CommandType Application tere) $args
    if ($result) {
        Set-Location $result
    }
}
Set-Alias tere Invoke-Tere
</details> <details> <summary>Windows Command Prompt (CMD)</summary>

Put this in a batch script file called tere.bat in a folder included in your PATH environment variable such as C:\Windows:

@echo off

rem set the location/path of the tere executable here...
SET TereEXE=C:\path\to\tere.exe

FOR /F "tokens=*" %%a in ('%TereEXE% %*') do SET OUTPUT=%%a
IF ["%OUTPUT%"] == [""] goto :EOF
cd %OUTPUT%

Note that if you want to make tere work with both PowerShell and CMD, you should not put tere.exe to a location that is in your PATH, because then the .exe will be run instead of the .bat. Place tere.exe somewhere that is not in your PATH, and use the full path to the exe in both the .bat file and in the PowerShell $PROFILE.

</details>

If tere is not in your PATH, use an absolute path to the tere binary in your shell config file. For example, for Bash/Zsh, you would need to replace local result=$(command tere "$@") with local result=$(/path/to/tere "$@"), or for PowerShell, replace (Get-Command -CommandType Application tere) with C:\path\to\tere.exe.

If instructions for your shell are missing, feel free to send a pull request that includes them! See the instructions below for some more information.

Step 3: That's it

The next time you open a new shell, the command tere should work. You can of course rename the shell function/alias to whatever you like. The shell configuration also acts as a config file for tere, just add the options you want (see tere --help).

Supported platforms

tere works on Linux, Windows and macOS. For Linux and Windows, binaries are provided in the releases. For Mac, you can install using Homebrew or Cargo, or build from source.

If you get libc errors on Linux, try the musl version.

User guide

Basic navigation

You can navigate folders in tere by moving the cursor around and by typing to search. By default, the cursor can be moved up or down using the arrow keys, and pressing <kbd>Enter</kbd> or the right arrow <kbd></kbd> to enter the highlighted folder. You can move to the parent folder by pressing <kbd>Enter</kbd> on the parent folder item .., or with the left arrow <kbd></kbd>. Once you have navigated to the folder you want, exit tere by pressing <kbd>Esc</kbd>. If you have configured your shell correctly, your shell's current working directory should now be set to that folder.

Keyboard shortcuts

tere has the following keyboard shortcuts by default:

DescriptionDefault shortcut(s)Action name
Enter directory under cursor<kbd>Enter</kbd> or <kbd></kbd> or <kbd>Alt</kbd>-<kbd></kbd> or <kbd>Alt</kbd>-<kbd>l</kbd> or if not searching, <kbd>Space</kbd>ChangeDir
Go to parent directory<kbd></kbd> or <kbd>Alt</kbd>-<kbd></kbd> or <kbd>Alt</kbd>-<kbd>h</kbd> or if not searching, <kbd>Backspace</kbd> or <kbd>-</kbd>ChangeDirParent
Go to home directory<kbd>~</kbd> or <kbd>Ctrl</kbd>-<kbd>Home</kbd> or <kbd>Ctrl</kbd>-<kbd>Alt</kbd>-<kbd>h</kbd>ChangeDirHome
Go to root directory<kbd>/</kbd> or <kbd>Alt</kbd>-<kbd>r</kbd>ChangeDirRoot
Move cursor up<kbd></kbd> or <kbd>Alt</kbd>-<kbd>k</kbd>CursorUp
Move cursor down<kbd></kbd> or <kbd>Alt</kbd>-<kbd>j</kbd>CursorDown
Move cursor up by one screen<kbd>Page Up</kbd> or <kbd>Ctrl</kbd>-<kbd>u</kbd> or <kbd>Alt</kbd>-<kbd>u</kbd>CursorUpScreen
Move cursor down by one screen<kbd>Page Down</kbd> or <kbd>Ctrl</kbd>-<kbd>d</kbd> or <kbd>Alt</kbd>-<kbd>d</kbd>CursorDownScreen
Move cursor to the top<kbd>Home</kbd> or <kbd>Alt</kbd>-<kbd>g</kbd>CursorTop
Move cursor to the bottom<kbd>End</kbd> or <kbd>Alt</kbd>-<kbd>Shift</kbd>-<kbd>g</kbd>CursorBottom
Erase a character from the search<kbd>Backspace</kbd> if searchingEraseSearchChar
Clear the search<kbd>Esc</kbd> if searchingClearSearch
Toggle filter search<kbd>Alt</kbd>-<kbd>f</kbd>ChangeFilterSearchMode
Change case sensitivity mode<kbd>Alt</kbd>-<kbd>c</kbd>ChangeCaseSensitiveMode
Change gap search mode<kbd>Ctrl</kbd>-<kbd>f</kbd>ChangeGapSearchMode
Change sorting mode<kbd>Alt</kbd>-<kbd>s</kbd>ChangeSortMode
Refresh current directory<kbd>Ctrl</kbd>-<kbd>r</kbd>RefreshListing
Show help screen<kbd>?</kbd>Help
Exit tere<kbd>Esc</kbd> or <kbd>Alt</kbd>-<kbd>q</kbd>Exit
Enter directory and exit tere<kbd>Alt</kbd>-<kbd>Enter</kbd> or <kbd>Ctrl</kbd>-<kbd>Space</kbd>ChangeDirAndExit
Exit tere without changing directory<kbd>Ctrl</kbd>-<kbd>c</kbd>ExitWithoutCd

Some of the shortcuts starting with <kbd>Alt</kbd> should be familiar to Vim users.

Customizing keyboard shortcuts

All of the keyboard shortcuts listed above can be customized using the --map (or -m) CLI option. Keyboard mappings can be either of the form --map key-combination:action or --map key-combination:context:action, where key-combination is a key combination, such as ctrl-x, action is a valid action name (for example Exit or ChangeDir, see the table above or --help for a full list of actions), and the optional context specifies the context in which the mappling applies (for example Searching and NotSearching, see --help). To remove a mapping, use --map key-combination:None. Multiple mappings can be made by providing --map multiple times, or by using a comma-separated list of mappings: --map combination1:action1,combination2:action2.

For further details and examples, see the output of --help.

Searching

To search for an item in the current folder, just type some letters. tere will incrementally highlight all folders that match the search query.

While searching, moving the cursor up or down jumps between only the items that match the search. The search query, as well as the number of matching items is shown at the bottom of the screen.

If only one folder matches your current search, tere will highlight it, and change the working directory to that folder. This way you can navigate folders very quickly.

To stop searching, press <kbd>Esc</kbd> or erase all search characters by pressing <kbd>Backspace</kbd>.

Note that by default, tere searches only folders and not files, since tere cannot do anything with files. This can be changed with the --files option. For further details, see below, or check the output of --help.

By default, the searching uses "smart case", meaning that if the query contains only lowercase letters, case is ignored, but if there are uppercase letters, the search is case sensitive. This can be changed with the --ignore-case and --case-sensitive options, or with the keyboard shortcut <kbd>Alt</kbd>-<kbd>c</kbd> by default.

Additionally, in the default search mode, "gap search" (sometimes also known as fuzzy search) is enabled. This means that the search matches any folder name as long as it starts with the same character as the search query, and contains the rest of the query characters, even if there are other characters between them. For example, searching for dt would match both DeskTop and DocumenTs. With the --gap-search-anywhere option, the first character of the query doesn't have to match the first character of a folder/file name. The gap search can be disabled with the --normal-search and --normal-search-anywhere options, which only allow matching consecutive characters, either from the start or anywhere within the folder/file name, respsectively. The gap search behavior can also be changed with the keyboard shortcut <kbd>Ctrl</kbd>-<kbd>f</kbd> by default. See --help for details.

Mouse navigation

Although tere is mainly keyboard-focused, it is also possible to navigate using the mouse. To maximize compatibility, mouse support is off by default, and has to be enabled with the option --mouse=on. With the mouse enabled, you can change to a folder by clicking on it, and move to the parent folder by right-clicking.

CLI options

You can adjust the behavior of tere by passing the following CLI options to it:

Some options have two or more versions that override each other (for example --filter-search and --no-filter-search). For such options, whichever is passed last wins. This way, you can have one option as the default in your shell's rc file, but you can sometimes manually override that option when running tere.

Similar projects

The idea of tere is by no means unique. There are actually quite a few CLI applications that attempt to make folder navigation faster. Below is a non-exhaustive list of such programs. The purpose of this section is to justify the existence of tere by showing how it is different from all these applications in subtle but important ways.

If there is a program that should be mentioned here, feel free to open an issue or pull request about it!

Terminal file browsers

These programs are designed for basically the same task as tere: navigate to a folder in the terminal and then cd to it.

Fuzzy matching and history-based navigation

These programs have a very similar goal as tere, to speed up filesystem navigation. However, these kinds of programs are not well suited for exploration, as they require that you visit a folder before you can jump to it. They also differ from tere in philosophy; tere aims to be deterministic, while the results of a fuzzy match or "frecency"-based query vary depending on your previous queries.

Terminal file managers

There are quite a few terminal file managers, and they can often be used in the same way as tere, for example using the --choosedir option of ranger. However, they have a huge number of other features compared to tere, which usually leads to a more complex UI and a higher learning curve. File managers are also not entirely focused on navigation, and therefore often require extra keystrokes to search and navigate folders. File management is not in the scope of tere, so these programs are not directly comparable to it.

Other similar programs

Hacking

To compile tere from source, follow the standard procedure:

  1. Install the Rust toolchain
  2. git clone git@github.com:mgunyho/tere.git
  3. cd tere
  4. Run cargo build (--release for the release version)

This will place the tere binary in the folder target/debug, or target/release if you used --release.

New features should go on the develop branch before they are released, and they should be mentioned in CHANGELOG.md.

To set up cross-compilation for other platforms (e.g. when making a release), run (on Debian):

# Support for linux without dependence on glibc
rustup target add x86_64-unknown-linux-musl

# Windows support
sudo apt install gcc-mingw-w64
rustup target add x86_64-pc-windows-gnu

# ARM (raspberry pi) support
sudo apt install gcc-aarch64-linux-gnu
rustup target add aarch64-unknown-linux-gnu

# NOTE: macOS is not available

Then, the build-release.sh script should work.

For further details, see the rustup guide, and the rustc platform support page, and consult your favourite search engine for help on cross-compilation.

Testing a new shell integration

To check that a new shell alias works correctly, you should verify the following:

Making a new release

Here's a checklist of things to do for a new release. The release binaries should be compiled on Linux with a suitably old version of glibc for compatibility (Debian 11 / glibc 2.31 as of 2024 September).

License

Copyright 2024 András Márton Gunyhó. Licensed under the EUPL, see the LICENSE file.