MCPcopy Index your code
hub / github.com/HalFrgrd/flyline

github.com/HalFrgrd/flyline @v1.3.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.3.0 ↗ · + Follow
1,632 symbols 5,264 edges 46 files 236 documented · 14% updated 2d agov1.3.0 · 2026-07-05★ 68519 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Flyline

CI Downloads Latest Release Built With Ratatui

A Bash plugin for modern command line editing.

Demo

When Bash prompts you for a command, a library called readline handles your keystrokes. Readline lacks many features users have come to expect. Flyline is a readline replacement that provides an enhanced line editing experience with: - Intellisense style autosuggestions - Change directory using your prompt - Rich prompt customizations, (asynchronous widgets), and animations - Fuzzy history searching - Mouse support (click to move cursor, select text) - Improvements to Bash's tab completion - Synthesize tab completion suggestions with flycomp - Agent assisted command writing - Tooltips - Text selection - Auto close brackets and quotes - Syntax highlighting - Runs in the same process as Bash - Cursor animations and styles

Flyline is similar to ble.sh but is written in Rust and uses ratatui.rs to more easily draw complex user interfaces.

Who is it for?

  1. You want an out-of-the-box great shell experience without the hassle of setting up half a dozen plugins, plugin managers, keyboard shortcuts, and startup scripts (any one of which might phone home).
  2. You're a terminal power user who wants to fine-tune their shell experience by writing in a modern language like Rust. Flyline can be the starting platform for you; contributions welcome!

Installation

[!IMPORTANT] After installing, run flyline run-tutorial and if you don't like the mouse capturing: flyline mouse --mode disabled

Quick install: install.sh

[!TIP] Run the following command to download flyline and update your .bashrc to load the latest version. No need for sudo!

curl -sSfL https://github.com/HalFrgrd/flyline/releases/latest/download/install.sh | sh

On macOS you must first install a version of Bash that supports custom builtins: brew install bash

Arch Linux

Arch users can install the AUR package:

paru -S flyline

Download from releases

Download the latest libflyline.so for your system from the releases page. If you are on Linux, you probably want the gnu variant unless you know you are on a musl based Linux distro (e.g. Alpine, Chimera). Then, in your .bashrc (or in your current Bash session):

enable -f /path/to/libflyline.so flyline
flyline run-tutorial

Build from source

Clone the repo and run:

cargo build
enable -f /path/to/flyline_checkout/target/debug/libflyline.so flyline
flyline run-tutorial

Installation notes

Disable flyline with enable -d flyline.

BASH_LOADABLES_PATH

Taken from https://www.gnu.org/software/bash/manual/bash.html:

The -f option means to load the new builtin command name from shared object filename, on systems that support dynamic loading. If filename does not contain a slash, Bash will use the value of the BASH_LOADABLES_PATH variable as a colon-separated list of directories in which to search for filename. The default for BASH_LOADABLES_PATH is system-dependent, and may include "." to force a search of the current directory.

Bash 4.4 introduced BASH_LOADABLES_PATH Bash 5.2-alpha added a default value for BASH_LOADABLES_PATH. Check your Bash version with: bash --version

So on Bash at least as recent as 5.2, if you install flyline to one of: - /opt/local/lib/bash - /opt/pkg/lib/bash - /usr/lib/bash - /usr/local/lib/bash - /usr/pkg/lib/bash

Then you can simply run enable flyline.

Configuration

Flyline sets up its own tab completion so you can type flyline <Tab> in your shell to interactively browse and configure settings. Copy the commands into your .bashrc so they persist.

Explore this README and examples for what you can configure.

Rich prompts

Flyline supports dynamic content in PS1, RPS1 / RPROMPT, and PS1_FILL.

PS1

The PS1 environment variable sets the left prompt just like normal. See Bash prompt documentation, Arch Linux wiki, or Starship for more information. PS1 demo

PS1='\u@\h:\w$ '
PS1='\u@\h:\w\n$ '
PS1='\e[01;32m\u@\h\e[00m:\e[01;34m\w\e[00m\n$ '

[!TIP] Do git metrics slow down your prompt loading time? See custom widget or example widgets for a solution.

RPS1 / RPROMPT

The RPS1 / RPROMPT variable sets the right prompt similarly to Zsh. RPS1 demo

RPS1='\t'
RPS1='\t\n<'
RPS1='\e[01;33m\t\n<\e[00m'

PS1_FILL

PS1_FILL fills the gap between the PS1 and RPS1 lines. PS1_FILL demo

PS1_FILL='-'
PS1_FILL='🯁🯂🯃🮲🮳' # finger pointing to running man
PS1_FILL='🯁🯂🯃🮲🮳 \D{%.3f}'

Final (transient) prompts

PS1_FINAL, RPS1_FINAL, and PS1_FILL_FINAL let you configure transient prompts. When a command is submitted, Flyline performs a final redraw using these environment variables instead of their standard counterparts. This keeps your terminal scrollback history clean by replacing complex, multi-line prompts with a minimal version.

Final prompts demo

PS1_FINAL='Ran at \D{%Y-%m-%d %H:%M:%S}> '
RPS1_FINAL=''
PS1_FILL_FINAL=''

Dynamic time in prompts

Flyline recognises the standard Bash time escape sequences and re-evaluates them on every prompt draw, so the time shown is always current:

Sequence Output
\t 24-hour time — HH:MM:SS
\T 12-hour time — HH:MM:SS
\@ 12-hour time with am/pm
\A 24-hour time — HH:MM
\D{format} Custom format (see below)

These can be placed in any of the supported prompt variables:

# Right prompt showing 24-hour time in green
RPS1='\e[01;32m\t\e[0m'

# Right prompt showing 12-hour am/pm time
RPS1='\e[01;34m\@\e[0m'

Custom time format with \D{format}

Use \D{format} with any Chrono format string to display the time exactly how you want it. This is similar to \D{format} in the Bash prompt documentation, but the format string is interpreted by Chrono rather than strftime.

# Show date and time
RPS1='\e[01;32m\D{%Y-%m-%d %H:%M:%S}\e[0m'

# Show only hours and minutes
RPS1='\D{%H:%M}'

Custom prompt widgets

Create custom prompt widgets with flyline create-prompt-widget. Flyline will replace strings in the prompt matching the widget name with the widget's output. The available widget types are animation, mouse-mode, copy-buffer, custom, and last-command-duration.

Animations

Create your own animations with flyline create-prompt-widget animation --name [your animation name here] [FRAMES].... Flyline will replace strings in the prompt matching the animation name with the animation:

Custom animation demo

More examples can be found in examples/animations.sh.

The block below is auto-generated from flyline create-prompt-widget animation --help:

Create a custom prompt animation that cycles through frames.

Instances of NAME in prompt strings (PS1, RPS1, PS1_FILL, and their _FINAL counterparts) are replaced
with the current animation frame on every render.  Frames may include
ANSI colour sequences written as `\e` (e.g. `\e[33m`).

Examples:
  flyline create-prompt-widget animation --name "MY_ANIMATION" --fps 10  ⣾ ⣷ ⣯ ⣟ ⡿ ⢿ ⣻ ⣽
  flyline create-prompt-widget animation --name "john" --ping-pong --fps 5  '\e[33m\u' '\e[31m\u' '\e[35m\u' '\e[36m\u'

See https://github.com/HalFrgrd/flyline/blob/master/examples/animations.sh for more details and example usage.

Usage: flyline create-prompt-widget animation [OPTIONS] --name <NAME> [FRAMES]...

Arguments:
  [FRAMES]...
          One or more animation frames (positional).  Use `\e` for the ESC character

Options:
      --name <NAME>
          Name to embed in prompt strings as the animation placeholder

      --fps <FPS>
          Playback speed in frames per second (default: 10)

          [default: 10]

      --ping-pong
          Reverse direction at each end instead of wrapping (ping-pong / bounce mode)

  -h, --help
          Print help (see a summary with '-h')

Mouse-mode widget

The block below is auto-generated from flyline create-prompt-widget mouse-mode --help:

Show different text depending on whether mouse capture is enabled.

Instances of NAME in prompt strings (PS1, RPS1, PS1_FILL, and their _FINAL counterparts) are replaced
with ENABLED_TEXT when mouse capture is on, and DISABLED_TEXT when off.

Examples:
  flyline create-prompt-widget mouse-mode '🖱️' '🔴'
  # Now use FLYLINE_MOUSE_MODE in your prompt:
  PS1='\u@\h:\w [FLYLINE_MOUSE_MODE] $ '

  flyline create-prompt-widget mouse-mode --name MOUSE_MODE "on " "off"

Usage: flyline create-prompt-widget mouse-mode [OPTIONS] <ENABLED_TEXT> <DISABLED_TEXT>

Arguments:
  <ENABLED_TEXT>
          Text to display when mouse capture is enabled

  <DISABLED_TEXT>
          Text to display when mouse capture is disabled

Options:
      --name <NAME>
          Name to embed in prompt strings as the widget placeholder. Defaults to `FLYLINE_MOUSE_MODE`

          [default: FLYLINE_MOUSE_MODE]

  -h, --help
          Print help (see a summary with '-h')

Copy-buffer widget

Render clickable text in your prompt that copies the current command buffer to the clipboard via OSC 52.

flyline create-prompt-widget copy-buffer '[copy]'
# Now use FLYLINE_COPY_BUFFER in your prompt:
RPS1=' FLYLINE_COPY_BUFFER'

Custom command widget

The block below is auto-generated from flyline create-prompt-widget custom --help:

Run a shell command and display its output in the prompt.

The output is passed through Bash's decode_prompt_string so Bash prompt
escape sequences (e.g. \u, \w, ANSI colour codes) are fully supported.

Examples:
  # Non-blocking (default): runs in the background; shows the previous output
  # while the command is running (empty on the first render).
  flyline create-prompt-widget custom --name CUSTOM_WIDGET1 --command 'run_slow_git_metrics.sh'
  # PS1 usage:
  PS1='\u@\h:\w [CUSTOM_WIDGET1] $ '

  # Non-blocking with previous output placeholder while the new output is being computed.
  flyline create-prompt-widget custom --name CUSTOM_WIDGET1 --command 'run_slow_git_metrics.sh' --placeholder prev

  # Blocking: waits for the command to finish before showing the prompt.
  flyline create-prompt-widget custom --name CUSTOM_WIDGET2 --command 'run_something.sh' --block

  # Blocking with a 500 ms timeout; falls back to placeholder if slower.
  flyline create-prompt-widget custom --name CUSTOM_WIDGET3 --command 'run_slow.sh --flag' --block 500 --placeholder prev

Usage: flyline create-prompt-widget custom [OPTIONS] --name <NAME> --command <COMMAND>

Options:
      --name <NAME>
          Name to embed in prompt strings as the widget placeholder

      --command <COMMAND>
          Command string to run; include any flags in the same string, e.g. --command './widget.sh --someflag'

      --block [<MS>]
          Block until the command finishes, optionally with a timeout in milliseconds. With no value, polls indefinitely (i32::MAX ms ≈ 24.8 days).  If the timeout expires the command continues running in the background and subsequent renders will pick up its output

      --placeholder <PLACEHOLDER>
          What to show while the command is running.  Either a number (spaces) or 'prev' (use the previous output of the command)

  -h, --help
          Print help (see a summary with '-h')

Last-command-

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Shape

Function 931
Method 528
Class 103
Enum 66
Interface 4

Languages

Rust100%
Python1%

Modules by API surface

src/text_buffer.rs156 symbols
src/tab_completion_context.rs133 symbols
src/prompt_manager.rs126 symbols
src/app/actions/keyboard.rs113 symbols
src/dparser.rs93 symbols
src/active_suggestions.rs90 symbols
src/bash_funcs.rs79 symbols
src/unicode_helpers.rs74 symbols
src/content_builder.rs67 symbols
src/content_utils.rs52 symbols
src/history.rs51 symbols
src/palette.rs42 symbols

For agents

$ claude mcp add flyline \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page