Full Code of mattgreen/lucid.fish for AI

master b6aca138ce47 cached
3 files
12.8 KB
3.2k tokens
1 requests
Download .txt
Repository: mattgreen/lucid.fish
Branch: master
Commit: b6aca138ce47
Files: 3
Total size: 12.8 KB

Directory structure:
gitextract_at4l8shz/

├── LICENSE
├── README.md
└── functions/
    └── fish_prompt.fish

================================================
FILE CONTENTS
================================================

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2020 Matt Green

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# lucid

A minimalist, high-performance fish prompt with async git dirty checks that just work.

![Preview](https://user-images.githubusercontent.com/56996/98549007-9520be80-22dd-11eb-884f-b688c9fd26cf.png)

## Features

* Classy, minimal left prompt that surfaces only actionable information
* Asynchronous git dirty state prevents prompt-induced lag even on [massive repositories](https://github.com/llvm/llvm-project)
* Shows current git branch/detached HEAD commit, action (if any), and dirty state
* Restrained use of color and Unicode symbols
* Single file, well-commented, zero-dependency implementation

## Installation

### System Requirements

* [Fish](https://fishshell.com/) ≥ 3.1.0

Install with [Fisher](https://github.com/jorgebucaran/fisher):

```console
fisher install mattgreen/lucid.fish
```

## Performance

Initial rendering is fast enough, considering that the LLVM repo has over **361,000 commits**:

```shell
~/Projects/llvm-project on master •
❯ time fish_prompt

~/Projects/llvm-project on master •
❯
________________________________________________________
Executed in   14.05 millis    fish           external
   usr time    5.96 millis    2.10 millis    3.86 millis
   sys time    6.87 millis    2.54 millis    4.33 millis
```

lucid fetches most git information synchronously. This minimizes the amount of flicker induced by prompt redraws, which can be distracting. This initial time encompasses:

1. getting the git working directory
2. retrieving the current branch
3. figuring out the current action (merge, rebase)
4. starting the async dirty check

This information is memoized to avoid re-computation during prompt redraws, which occur upon completion of the git dirty check, or window resizes.

## Customization

* `lucid_dirty_indicator`: displayed when a repository is dirty. Default: `•`
* `lucid_clean_indicator`: displayed when a repository is clean. Should be at least as long as `lucid_dirty_indicator` to work around a fish bug. Default: ` ` (a space)
* `lucid_cwd_color`: color used for current working directory. Default: `green`
* `lucid_git_color`: color used for git information. Default: `blue`
* `lucid_git_status_in_home_directory`: if set, git information is also
   displayed in the home directory. Default: not set
* `lucid_skip_newline`: if set, doesn't insert a newline before the prompt.
   Default: not set
* `lucid_prompt_symbol`: the prompt symbol. Default: `❯`
* `lucid_prompt_symbol_error`: the prompt symbol when an error occurs.
   Default: `❯`
* `lucid_prompt_symbol_color`: the color of the prompt symbol.
   Default: `$fish_color_normal`
* `lucid_prompt_symbol_error_color`: the color of the prompt symbol when an
   error occurs. Default: `$fish_color_normal`

## Design

Each prompt invocation launches a background job responsible for checking dirty status. If the previous job did not complete, it is killed prior to starting a new job. The dirty check job relays the dirty status back to the main shell via an exit code. This works because there's only three distinct states that can result from a dirty check: dirty, not dirty, or error. Systems programming FTW!

After launching the job, the parent process immediately registers a completion handler for the job. In there, we scoop up the exit status, then update the prompt based on what was found.

The rest is book-keeping and careful coding. There may be a few more opportunities for optimization. Send a PR if you find any!

### Previous Design Iterations

The tough problem here is keeping the execution time low, and communicating the dirty status from the job back to the parent.

Here are a few other approaches that didn't pan out:

* **IPC via universal variables**: variable contents are round-tripped by disk, which is a non-starter
* **IPC via named FIFO**: fish is unable to hold the reader side of a named FIFO open, causing writers to block indefinitely
* **IPC via tmpfs**: macOS does not have a `tmpfs` filesystem available by default
* **Other POSIX IPC facilities**: these would necessitate a third-party binary dependency

## Known Issues

* fish has a bug involving multi-line prompts not being redrawn correctly. You usually see this when invoking `fzf`.
* lucid uses a background job to asynchronously fetch dirty status. If you try to exit while a dirty status has not completed, fish will warn you it is still running. Unfortunately, lucid is not able to `disown` the job because it needs to collect the exit status from it.

## License

[MIT](LICENSE)


================================================
FILE: functions/fish_prompt.fish
================================================
# Default appearance options. Override in config.fish if you want.
if ! set -q lucid_dirty_indicator
    set -g lucid_dirty_indicator "•"
end

if ! set -q lucid_prompt_symbol
    set -g lucid_prompt_symbol "❯"
end

if ! set -q lucid_prompt_symbol_error
    set -g lucid_prompt_symbol_error "❯"
end

if ! set -q lucid_prompt_symbol_color
    set -g lucid_prompt_symbol_color "$fish_color_normal"
end

if ! set -q lucid_prompt_symbol_error_color
    set -g lucid_prompt_symbol_error_color "$fish_color_normal"
end

# This should be set to be at least as long as lucid_dirty_indicator, due to a fish bug
if ! set -q lucid_clean_indicator
    set -g lucid_clean_indicator (string replace -r -a '.' ' ' $lucid_dirty_indicator)
end

if ! set -q lucid_cwd_color
    set -g lucid_cwd_color green
end

if ! set -q lucid_git_color
    set -g lucid_git_color blue
end

# State used for memoization and async calls.
set -g __lucid_cmd_id 0
set -g __lucid_git_state_cmd_id -1
set -g __lucid_git_static ""
set -g __lucid_dirty ""

# Increment a counter each time a prompt is about to be displayed.
# Enables us to distingish between redraw requests and new prompts.
function __lucid_increment_cmd_id --on-event fish_prompt
    set __lucid_cmd_id (math $__lucid_cmd_id + 1)
end

# Abort an in-flight dirty check, if any.
function __lucid_abort_check
    if set -q __lucid_check_pid
        set -l pid $__lucid_check_pid
        functions -e __lucid_on_finish_$pid
        command kill $pid >/dev/null 2>&1
        set -e __lucid_check_pid
    end
end

function __lucid_git_status
    # Reset state if this call is *not* due to a redraw request
    set -l prev_dirty $__lucid_dirty
    if test $__lucid_cmd_id -ne $__lucid_git_state_cmd_id
        __lucid_abort_check

        set __lucid_git_state_cmd_id $__lucid_cmd_id
        set __lucid_git_static ""
        set __lucid_dirty ""
    end

    # Fetch git position & action synchronously.
    # Memoize results to avoid recomputation on subsequent redraws.
    if test -z $__lucid_git_static
        # Determine git working directory
        set -l git_dir (command git --no-optional-locks rev-parse --absolute-git-dir 2>/dev/null)
        if test $status -ne 0
            return 1
        end

        set -l position (command git --no-optional-locks symbolic-ref --short HEAD 2>/dev/null)
        if test $status -ne 0
            # Denote detached HEAD state with short commit hash
            set position (command git --no-optional-locks rev-parse --short HEAD 2>/dev/null)
            if test $status -eq 0
                set position "@$position"
            end
        end

        # TODO: add bisect
        set -l action ""
        if test -f "$git_dir/MERGE_HEAD"
            set action "merge"
        else if test -d "$git_dir/rebase-merge"
            set action "rebase"
        else if test -d "$git_dir/rebase-apply"
            set action "rebase"
        end

        set -l state $position
        if test -n $action
            set state "$state <$action>"
        end

        set -g __lucid_git_static $state
    end

    # Fetch dirty status asynchronously.
    if test -z $__lucid_dirty
        if ! set -q __lucid_check_pid
            # Compose shell command to run in background
            set -l check_cmd "git --no-optional-locks status -unormal --porcelain --ignore-submodules 2>/dev/null | head -n1 | count"
            set -l cmd "if test ($check_cmd) != "0"; exit 1; else; exit 0; end"

            begin
                # Defer execution of event handlers by fish for the remainder of lexical scope.
                # This is to prevent a race between the child process exiting before we can get set up.
                block -l

                set -g __lucid_check_pid 0
                command fish --private --command "$cmd" >/dev/null 2>&1 &
                set -l pid (jobs --last --pid)

                set -g __lucid_check_pid $pid

                # Use exit code to convey dirty status to parent process.
                function __lucid_on_finish_$pid --inherit-variable pid --on-process-exit $pid
                    functions -e __lucid_on_finish_$pid

                    if set -q __lucid_check_pid
                        if test $pid -eq $__lucid_check_pid
                            switch $argv[3]
                                case 0
                                    set -g __lucid_dirty_state 0
                                    if status is-interactive
                                        commandline -f repaint
                                    end
                                case 1
                                    set -g __lucid_dirty_state 1
                                    if status is-interactive
                                        commandline -f repaint
                                    end
                                case '*'
                                    set -g __lucid_dirty_state 2
                                    if status is-interactive
                                        commandline -f repaint
                                    end
                            end
                        end
                    end
                end
            end
        end

        if set -q __lucid_dirty_state
            switch $__lucid_dirty_state
                case 0
                    set -g __lucid_dirty $lucid_clean_indicator
                case 1
                    set -g __lucid_dirty $lucid_dirty_indicator
                case 2
                    set -g __lucid_dirty "<err>"
            end

            set -e __lucid_check_pid
            set -e __lucid_dirty_state
        end
    end

    # Render git status. When in-progress, use previous state to reduce flicker.
    set_color $lucid_git_color
    echo -n $__lucid_git_static ''

    if ! test -z $__lucid_dirty
        echo -n $__lucid_dirty
    else if ! test -z $prev_dirty
        set_color --dim $lucid_git_color
        echo -n $prev_dirty
        set_color normal
    end

    set_color normal
end

function __lucid_vi_indicator
    if [ $fish_key_bindings = "fish_vi_key_bindings" ]
        switch $fish_bind_mode
            case "insert"
                set_color green
                echo -n "[I] "
            case "default"
                set_color red
                echo -n "[N] "
            case "visual"
                set_color yellow
                echo -n "[S] "
            case "replace"
                set_color blue
                echo -n "[R] "
        end
        set_color normal
    end
end

# Suppress default mode prompt
function fish_mode_prompt
end

function fish_prompt
    set -l last_pipestatus $pipestatus
    set -l cwd (pwd | string replace "$HOME" '~')

    if test -z "$lucid_skip_newline"
        echo ''
    end

    set_color $lucid_cwd_color
    echo -sn $cwd
    set_color normal

    if test $cwd != '~'; or test -n "$lucid_git_status_in_home_directory"
        set -l git_state (__lucid_git_status)
        if test $status -eq 0
            echo -sn " on $git_state"
        end
    end

    echo ''
    __lucid_vi_indicator

    set -l prompt_symbol "$lucid_prompt_symbol"
    set -l prompt_symbol_color "$lucid_prompt_symbol_color"

    for status_code in $last_pipestatus
        if test "$status_code" -ne 0
            set prompt_symbol "$lucid_prompt_symbol_error"
            set prompt_symbol_color "$lucid_prompt_symbol_error_color"
            break
        end
    end

    set_color "$prompt_symbol_color"
    echo -n "$prompt_symbol "
    set_color normal
end
Download .txt
gitextract_at4l8shz/

├── LICENSE
├── README.md
└── functions/
    └── fish_prompt.fish
Condensed preview — 3 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (14K chars).
[
  {
    "path": "LICENSE",
    "chars": 1067,
    "preview": "MIT License\n\nCopyright (c) 2020 Matt Green\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
  },
  {
    "path": "README.md",
    "chars": 4507,
    "preview": "# lucid\n\nA minimalist, high-performance fish prompt with async git dirty checks that just work.\n\n![Preview](https://user"
  },
  {
    "path": "functions/fish_prompt.fish",
    "chars": 7569,
    "preview": "# Default appearance options. Override in config.fish if you want.\nif ! set -q lucid_dirty_indicator\n    set -g lucid_di"
  }
]

About this extraction

This page contains the full source code of the mattgreen/lucid.fish GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 3 files (12.8 KB), approximately 3.2k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!