cantino/mcfly

McFly - fly through your shell history

McFly replaces your default ctrl-r shell history search with an intelligent search engine that takes into account

McFly replaces your default ctrl-r shell history search with an intelligent search engine that takes into account your working directory and the context of recently executed commands. McFly's suggestions are prioritized in real time with a small neural network.

TL;DR: an upgraded ctrl-r where history results make sense for what you're working on right now.

Features

  • Rebinds ctrl-r to bring up a full-screen reverse history search prioritized with a small neural network.
  • Augments your shell history to track command exit status, timestamp, and execution directory in a SQLite database.
  • Maintains your normal shell history file as well so that you can stop using McFly whenever you want.
  • Unicode support throughout.
  • Includes a simple action to scrub any history item from the McFly database and your shell history files.
  • Designed to be extensible for other shells in the future.
  • Written in Rust, so it's fast and safe.

Prioritization

The key feature of McFly is smart command prioritization powered by a small neural network that runs in real time. The goal is for the command you want to run to always be one of the top suggestions.

When suggesting a command, McFly takes into consideration:

  • The directory where you ran the command. You're likely to run that command in the same directory in the future.
  • What commands you typed before the command (e.g., the command's execution context).
  • How often you run the command.
  • When you last ran the command.
  • If you've selected the command in McFly before.
  • The command's historical exit status. You probably don't want to run old failed commands.

Installation

Install with Homebrew (on OS X or Linux)

  1. Install the tap:

    brew tap cantino/mcfly
    
  2. Install mcfly:

    brew install mcfly
    
  3. Add the following to the end of your ~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish file, as appropriate, changing /usr/local to your brew --prefix if needed:

    Bash:

    eval "$(mcfly init bash)"
    

    Zsh:

    eval "$(mcfly init zsh)"
    

    Fish:

    mcfly init fish | source
    
  4. Run . ~/.bashrc / . ~/.zshrc / source ~/.config/fish/config.fish or restart your terminal emulator.

Uninstalling with Homebrew

  1. Remove mcfly:
    brew uninstall mcfly
    
  2. Remove the tap:
    brew untap cantino/mcfly
    
  3. Remove the lines you added to ~/.bashrc / ~/.zshrc / ~/.config/fish/config.fish.

Install with MacPorts (on OS X)

  1. Update the ports tree

    sudo port selfupdate
    
  2. Install mcfly:

    sudo port install mcfly
    
  3. Add the following to the end of your ~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish file, as appropriate:

    Bash:

    eval "$(mcfly init bash)"
    

    Zsh:

    eval "$(mcfly init zsh)"
    

    Fish:

    mcfly init fish | source
    
  4. Run . ~/.bashrc / . ~/.zshrc / source ~/.config/fish/config.fish or restart your terminal emulator.

Uninstalling with MacPorts

  1. Remove mcfly:
    sudo port uninstall mcfly
    
  2. Remove the lines you added to ~/.bashrc / ~/.zshrc / ~/.config/fish/config.fish.

Installing using our install script

  1. curl -LSfs https://raw.githubusercontent.com/cantino/mcfly/master/ci/install.sh | sh -s -- --git cantino/mcfly

  2. Add the following to the end of your ~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish file, respectively:

    Bash:

    eval "$(mcfly init bash)"
    

    Zsh:

    eval "$(mcfly init zsh)"
    

    Fish:

    mcfly init fish | source
    
  3. Run . ~/.bashrc / . ~/.zshrc / source ~/.config/fish/config.fish or restart your terminal emulator.

Installing manually from GitHub

  1. Download the latest release from GitHub.

  2. Install to a location in your $PATH. (For example, you could create a directory at ~/bin, copy mcfly to this location, and add export PATH="$PATH:$HOME/bin" to your .bashrc / .zshrc, or run set -Ua fish_user_paths "$HOME/bin" for fish.)

  3. Add the following to the end of your ~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish file, respectively:

    Bash:

    eval "$(mcfly init bash)"
    

    Zsh:

    eval "$(mcfly init zsh)"
    

    Fish:

    mcfly init fish | source
    
  4. Run . ~/.bashrc / . ~/.zshrc / source ~/.config/fish/config.fish or restart your terminal emulator.

Install manually from source

  1. Install Rust 1.40 or later

  2. Run git clone https://github.com/cantino/mcfly and cd mcfly

  3. Run cargo install --path .

  4. Ensure ~/.cargo/bin is in your $PATH.

  5. Add the following to the end of your ~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish file, respectively:

    Bash:

    eval "$(mcfly init bash)"
    

    Zsh:

    eval "$(mcfly init zsh)"
    

    Fish:

    mcfly init fish | source
    
  6. Run . ~/.bashrc / . ~/.zshrc / source ~/.config/fish/config.fish or restart your terminal emulator.

iTerm2

To avoid McFly's UI messing up your scrollback history in iTerm2, make sure this option is unchecked:

Settings

A number of settings can be set via environment variables. To set a setting you should add the following snippets to your ~/.bashrc / ~/.zshrc / ~/.config/fish/config.fish.

Light Mode

To swap the color scheme for use in a light terminal, set the environment variable MCFLY_LIGHT.

bash / zsh:

export MCFLY_LIGHT=TRUE

fish:

set -gx MCFLY_LIGHT TRUE

VIM Key Scheme

By default Mcfly uses an emacs inspired key scheme. If you would like to switch to the vim inspired key scheme, set the environment variable MCFLY_KEY_SCHEME.

bash / zsh:

export MCFLY_KEY_SCHEME=vim

fish:

set -gx MCFLY_KEY_SCHEME vim

Fuzzy Searching

To enable fuzzy searching, set MCFLY_FUZZY.

bash / zsh:

export MCFLY_FUZZY=true

fish:

set -gx MCFLY_FUZZY true

Results Count

To change the maximum number of results shown, set MCFLY_RESULTS (default: 10).

bash / zsh:

export MCFLY_RESULTS=50

fish:

set -gx MCFLY_RESULTS 50

Slow startup

If you have a very large history database and you notice that McFly launches slowly, you can set MCFLY_HISTORY_LIMIT to something like 10000 to limit how many records are considered when searching. In this example, McFly would search only the latest 10,000 entries.

Possible Future Features

  • Add a screencast to README.
  • Learn common command options and autocomplete them in the suggestion UI?
  • Sort command line args when coming up with the template matching string.
  • Possible prioritization improvements:
    • Cross validation & explicit training set selection.
    • Learn command embeddings

Development

Running tests

cargo test

Releasing (notes for @cantino)

  1. Edit Cargo.toml and bump the version.
  2. Edit CHANGELOG.txt
  3. Recompile (cargo build).
  4. git add -p
  5. git ci -m 'Bumping to vx.x.x'
  6. git tag vx.x.x
  7. git push origin head --tags
  8. Let the build finish.
  9. Edit the new Release on Github.
  10. Edit pkg/brew/mcfly.rb and update the version and SHAs. (shasum -a 256 ...)
  11. Edit ../homebrew-mcfly/pkg/brew/mcfly.rb too.
  12. Compare with diff ../homebrew-mcfly/pkg/brew/mcfly.rb ../mcfly/pkg/brew/mcfly.rb ; diff ../homebrew-mcfly/HomebrewFormula/mcfly.rb ../mcfly/HomebrewFormula/mcfly.rb
  13. git add -p && git ci -m 'Update homebrew' && git push
  14. cd ../homebrew-mcfly && git add -p && git ci -m 'Update homebrew' && git push && cd ../mcfly
  15. cargo publish
Issues

Collection of the latest Issues

HimDek

HimDek

Comment Icon1

Database Location in the README says $XDG_DATA_DIR/mcfly/history.db which defaults to ~/.local/share/mcfly/history.db would be used as the location for McFly's SQLite database if ~/.mcfly/ doesnot exist.

However, there is no such environment variable named $XDG_DATA_DIR specified neither in the XDG Base Directory Specification nor in the Arch Wiki on the same topic. The one that is the specification is $XDG_DATA_DIRS whose default value is /usr/local/share/:/usr/share/, which clearly is not the one applicable here.

In my system, following the XDG Base Directory Specification, I have $XDG_DATA_HOME set to $HOME/.local/share/, but $XDG_DATA_DIR is not set. However, after I moved the SQLite database file of McFly to ~/.local/share/mcfly/history.db, it seems to be working as expected.

NOTE: When I installed McFly, I probably did not have $XDG_DATA_HOME set but now I do.

So, which environment variable does McFly exactly use for determining its database location?

JanPokorny

JanPokorny

bug
Comment Icon1

Steps to reproduce:

  1. Configure fish to use latest mcfly (0.6.0)
  2. Type cat | touch hello
  3. Press CTRL-R
  4. Observe:
  • McFly crashed
  • The command touch hello was actually executed! Try ls hello to confirm the file now exists

It seems that this happens every time there's a pipe in the typed command, and it executes the part of command after the pipe.

rrpolanco

rrpolanco

Comment Icon2

New user here so apologies if I missed something. I installed mcfly and after invoking it via Ctrl+r and exiting, now my Home/End keybindings stopped working. This behavior prevents me from auto completing zsh suggestions.

I'm using wezterm with zsh 5.8.

owenlamont

owenlamont

Comment Icon3

I saw this mentioned on an earlier issue but was wondering if it would be possible to also support Powershell. I'm completely ignorant of how much effort this would involve or if it is possible at all but I'd love to use mcfly if possible from there.

dithpri

dithpri

Comment Icon4

I pretty much exclusively use zsh. However, I sometimes need to run bash (or run it from nix-shell). I've had no problems with this until I installed McFly.

Since McFly exports HISTFILE when loaded in an interactive zsh shell: https://github.com/cantino/mcfly/blob/75808a60c78f65e90767ee53c9468086fcdf0cc5/mcfly.zsh#L13=

If bash is run from such a shell, because HISTFILE is exported, bash's HISTFILE is the same as zsh's. As it happens, the default history file size for bash is 500. So, every time I run bash, my zsh history file gets truncated:

Moreover, bash saves its history to the zsh HISTFILE...

The workaround is to set a different HISTFILE in .bashrc, but this is most definitely a bug introduced by McFly exporting the HISTFILE variable. McFly should honour the variable not being exported and define its own variables for internal use instead of exporting ones that don't belong to it.

Suggestion: export MCFLY_HISTFILE="${HISTFILE:-$HOME/.zsh_history}" (as it seems to be done for fish)

Same goes for the bash script https://github.com/cantino/mcfly/blob/75808a60c78f65e90767ee53c9468086fcdf0cc5/mcfly.bash#L13=

ssahaxd

ssahaxd

Comment Icon4

Keyboard inputs are not visible on the terminal after interrupting a command.

image After interrupting the first command I typed this which was not visible on the terminal.

alespg

alespg

Comment Icon4

Hi! i love this tool, but i have found this annoying issue:

After using mcfly to recover a command, if you use the classic up arrow key to navigate through history, first result is the last command used, but next is the whole mcfly intarface and next, it breaks. Is this a known issue? is there any way to avoid it?

Thank you!

rkachach

rkachach

Comment Icon1

I don't know if it's possible or not but it would be great if you can keep the terminal visible when running mcfly. Right now mcfly just ocupy the whole terminal during its execution and only you get it back once you select the command. BTW: fzf for example already works like this by default.

arijit-hal

arijit-hal

enhancement
Comment Icon10

Hi, Is there a way to add a keybinding to copy a highlighted command from mcfly's heads-up display directly to the system clipboard? Presently, the only way I can achieve this consistently across several terminal emulators (kitty, gnome-terminal etc.) is by using the edit option (pressing TAB) and then copying the result into the emulator's internal buffer (using Ctrl+U). Thanks!

Efreak

Efreak

bug
Comment Icon4

The 'which' error will have a pull request coming, it showed up when I updated mcfly to see if this had been fixed (I first installed a week ago, didn't initialize until now)

This should be a gif and/or a video embed below, github is doing something weird.

Screen_Recording_20211219-115148_Termux 720

mcfly is version 0.5.11, since I forgot to include that (I suggest adding it to the top right of the UI, currently that space is unused)

bowiz2

bowiz2

enhancement
Comment Icon1

Hey!

So mcfly saves the timestamp of each run command, and it would be useful if there was a flag/env var that enabled showing the last time you ran a command in your shell history.

Or, alternatively, a history style command for mcfly that would output the timestamp + command in a friendly less-able way.

It's possible right now to query sqlite and run something like select cmd,datetime(when_run, 'unixepoch', 'localtime') from commands where cmd LIKE "%the_command%";, but a more user friendly solution would be super useful.

Hope others think this useful and someone is motivated to develop it 😄

varenc

varenc

Comment Icon4

I'm just trying out mcfly and love it so far, but I don't want to fully commit to it yet. I'd like to keep using it side-by-side with my fzf history searcher.

I discovered there's no easy way to change the shell key bindings. And because the init script is returned from the mcfly binary I can't change it there without recompiling.

My solution for now is to init mcfly, then just redefine my key binding the way I like it like this:

Which totally works, but a mcfly option to define the key binding would be nice! Albeit, that might be a bit too niche and people like me that care can work around it easily enough.

Cheers

arjan-s

arjan-s

Comment Icon0

When I connect using SSH to a server where mcfly is installed, passing back the selected command to bash doesn't work. Pressing Enter or Tab both just return me to bash without the command executed or visible. This works fine on my local workstation, but not after SSH'ing to my server which runs exactly the same software.

Software details: Arch Linux Bash 5.1.8 Powerline-go 1.21.0 (although I have the same problem without powerline-go)

Also, I couldn't find documentation or tips on how to debug these kind of issues. Perhaps that would be a good addition to the readme?

mkrier

mkrier

Comment Icon6

$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.5 LTS Release: 18.04 Codename: bionic

When I open a new terminal window it doesn't start. I do have this is in my ~/.bashrc eval "$(mcfly init bash)"

I have to run . ~/.bashrc / . ~/.zshrc / source ~/.config/fish/config.fish every time to get it working.

Update: after some fiddling, now that doesn't work either:

$ . ~/.bashrc / . ~/.zshrc / source ~/.config/fish/config.fish mcfly: command not found

For some background:

$ brew install mcfly ==> Installing mcfly from cantino/mcfly ==> Downloading https://github.com/cantino/mcfly/releases/download/v0.5.8/mcfly- Already downloaded: /home/bog/.cache/Homebrew/downloads/73d5014ecee22bb29f360c8768b113a1a2f2059dc9619dd2e6d676fba9f356ee--mcfly-v0.5.8-x86_64-unknown-linux-musl.tar.gz ==> Caveats ONE MORE STEP!

Add the following to the end of your ~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish file.

Bash: eval "$(mcfly init bash)"

Zsh: eval "$(mcfly init zsh)"

Fish: mcfly init fish | source ==> Summary 🍺 /home/linuxbrew/.linuxbrew/Cellar/mcfly/v0.5.8: 3 files, 5.3MB, built in 3 seconds [email protected]:~$ mcfly mcfly: command not found

Also can someone explain to me how to get "insert code" working in the editor here? It either puts everything on one line or doesn't work at all.

joehillen

joehillen

Comment Icon1

Screenshot from 2021-06-23 12-58-02

I've been using the Tango color scheme (with a different background color) for gnome-terminal for over a decade, and this is one of the only times that I can think of that it's not worked for a program or the program has not had a way to customize it's color scheme (light is also not legible). I'm also not a fan of the grey text. Perhaps the default should be simpler (like the default color for text with no background, blue background with black text for menu), and give more options for specific customizations.

Versions

Find the latest versions by id

v0.6.1 - Jul 16, 2022

0.6.1 - Jul 16, 2022

  • Avoid return 0 to prevent re-sourcing .zshrc from erroring
  • Vim mode improvement (thanks @fabiogibson!)
  • Allow switching between rank and time-based sorting with F1 (thanks @navazjm!)
  • Dependency security updates

v0.6.0 - Mar 23, 2022

0.6.0 - Mar 22, 2022

  • Allow disabling of menu (thanks @michaelnavs!)
  • Prevent subshells from having multiple mcfly PROMPT_COMMAND hooks in bash (thanks @nfultz!)
  • Errors during history import do not prevent other lines from importing (thanks @qouoq!)
  • Store configuration in XDG directories when ~/.mcfly does not yet exist (thanks @Awernx!)

v0.5.13 - Jan 24, 2022

0.5.13 - Jan 24, 2022

  • Fix 'illegal byte sequence' due to incorrect TIOCSTI cast (thanks @arunpersaud!)

v0.5.12 - Jan 12, 2022

0.5.12 - Jan 12, 2022

  • Automatically detect if Zsh extended history is used (thanks @vmax!)

v0.5.11 - Dec 12, 2021

0.5.11 - Dec 12, 2021

  • Avoid using builtins to fix WSL bug

v0.5.10 - Nov 06, 2021

0.5.10 - Nov 6, 2021

  • Fix zsh utf-8 history encoding (thanks @onriv!)
  • Support Ctrl-p and Ctrl-n in vim mode (thanks @otherJL0!)
  • Make MCFLY_FUZZY a tuneable int (thanks @dmfay!)
  • Prevent errors when running bash inside of fish (thanks @btglr!)

v0.5.9 - Aug 29, 2021

0.5.9 - Aug 29, 2021

  • Prefer unaliased commands in bash/zsh (thanks @Mic92!)
  • Fix zsh source message (thanks @hlascelles!)
  • Prevent potentially unsafe variable substitution in paths (thanks @CreativeCactus!)

v0.5.8 - Aug 02, 2021

0.5.8 - Aug 1, 2021

  • Option to place interface at bottom of screen (thanks @agrism)
  • Option to sort by recency (thanks @agrism)
  • Option to skip prompting on command deletion (thanks @goddade)

v0.5.7 - Jun 27, 2021

  • Document MCFLY_RESULTS config value
  • Initialize database inside a transaction for speed (thanks @SafariMonkey!)
  • Move to cantino/homebrew-mcfly for tap install
  • Show run time of commands (thanks @dmfay!)
  • Clean PROMPT_COMMAND before joining with a semicolon in Bash
  • Fix zsh interactivity test
  • Make ^d delete forward (thanks @rbutoi!)
  • Move to Github Actions for build and add install script instructions (thanks @praveenperera!)

v0.5.6 - Apr 01, 2021

0.5.6 - Apr 1, 2021

  • Fix fish shell initialization (thanks @domoritz)
  • Fix fish shell escaping (thanks @scooter-dangle!)

v0.5.5 - Mar 13, 2021

0.5.5 - Mar 12, 2021

  • Fixed a crash during init without any history
  • Fixed issue when deleting all history (thanks @akinnane!)
  • Add MCFLY_HISTORY_LIMIT to limit history search

v0.5.4 - Mar 01, 2021

0.5.4 - Feb 28, 2021

  • Switched to mcfly init pattern for shell config files (thanks @b3nj5m1n!)

v0.5.3 - Jan 17, 2021

Fixes #107

v0.5.2 - Dec 11, 2020

0.5.2 - Dec 10, 2020

  • Bash 4+ should no longer have a cluttered terminal buffer (thanks @CreativeCactus)
  • Vim mode now starts in insert mode (thanks @JamJar00)

v0.5.1 - Dec 06, 2020

Fuzzy searching via the MCFLY_FUZZY option from @dmfay.

v0.5.0 - Aug 22, 2020

Thanks to @tjkirch, McFly now supports the fish shell.

v0.4.1 - Jun 29, 2020

v0.4.0 - Jun 28, 2020

Mcfly now supports zsh! The README has instructions on how to include it in your .zshrc.

v0.3.6 - Dec 16, 2019

  • Optional VI-style keybindings from @JamJar00
  • Fix Windows build

v0.3.5 - Aug 30, 2019

This small release only changes mcfly.bash, causing MCFLY_HISTORY to be rebuilt if it is deleted, which can happen on OS X if the temporary directory is cleaned up.

v0.3.4 - May 25, 2019

0.3.4 - May 24, 2019

  • Only read 256 bytes for session id generation (thanks @SuperSandro2000!)
  • Prevent adding empty commands
  • Try using unlock_notify to prevent race condition with locked DB.
  • Ensure stdin is a tty to fix issue with Sublime Text 3 (thanks @abuzze!)

v0.3.3 - Feb 11, 2019

Fix version which was incorrectly displayed by --version.

v0.3.2 - Feb 10, 2019

The urandom fix in this release may fix an issue with Sublime Text 3 (#46).

  • Fix 'cat /dev/urandom' not closing (thanks @Melkor333!)
  • Update to Rust 2018
  • Error gracefully when .bash_history is not found
  • Add more Xes for Slackware Linux (thanks @aik099)

v0.3.1 - Dec 25, 2018

Quick follow-up on the previous release.

0.3.1 - Dec 25, 2018

  • Fix background color on Light Mode

v0.3.0 - Dec 25, 2018

0.3.0 - Dec 25, 2018

  • Support users who have set -o vi (thanks @Asdalo21)
  • Remove Regex dependency for a smaller binary.
  • Add support for Light Mode - enable with export MCFLY_LIGHT=TRUE (thanks @mshron)
  • Fix broken Rust install link (thanks @bperel)

v0.2.5 - Dec 09, 2018

  • Prevent clobbering of command return statuses (thanks @gwk)
  • Add Ctrl-n and Ctrl-p mappings (thanks @greyblake)
  • Support spaces in HISTFILE (thanks @markusjevringgoeuro)

v0.2.4 - Dec 05, 2018

0.2.4 - Dec 4, 2018

  • Important update: fixes bug where historical directory paths would be incorrectly updated when a directory that was a prefix of another was moved, resulting in historical directory references that never actually existed.
  • Silences logs when moving / renaming directories.
  • Fixes importing of shell history that contains invalid UTF8 characters.

v0.2.3 - Dec 05, 2018

v0.2.2 - Nov 28, 2018

Due to feedback, mcfly-bash.sh has been renamed to mcfly.bash. You'll need to update your ~/.bashrc files accordingly.

v0.2.1 - Nov 22, 2018

Detect when directories are moved or renamed and update the history. You can also record moves retroactively with mcfly move old_path new_path.

Information - Updated Aug 04, 2022

Stars: 4.3K
Forks: 118
Issues: 82

Repositories & Extras

A Full-Text Search Engine in Rust

Toshi will always target stable Rust and will try our best to never make any use of unsafe Rust

A Full-Text Search Engine in Rust

Ternary search tree collection in rust with similar API to std::collections as it possible

Ternary search tree is a type of trie (sometimes called a prefix tree) where nodes are arranged in a manner similar to a binary search...

Ternary search tree collection in rust with similar API to std::collections as it possible

Sonic-channel is a rust client for the sonic search backend

Quick and easy way to get started with search in rust

Sonic-channel is a rust client for the sonic search backend

txtai: AI-powered search engine for Rust

Overview of the functionality provided by txtai

txtai: AI-powered search engine for Rust

recon_metadata, book details and metadata search library written in Rust using

recon_metadata, book details and metadata search library written in reqwest

recon_metadata, book details and metadata search library written in Rust using

Roogle is a Rust API search engine, which allows you to search functions by names...

Roogle is a Rust API search engine, which allows you to search functions by names and type signatures

Roogle is a Rust API search engine, which allows you to search functions by names...

Non-official rust library to search Nyaa

si does not provide any APIs so I thought it would be cool to have a way to do so in Rust and that's why...

Non-official rust library to search Nyaa

Roogle is a Rust API search engine, which allows you to search functions by names...

Roogle is a Rust API search engine, which allows you to search functions by names and type signatures

Roogle is a Rust API search engine, which allows you to search functions by names...

SerpApi Search in Rust

This Rust package enables to scrape and parse search results from Google, Bing, Baidu, Yandex, Yahoo, Ebay, Apple, Youtube, Naver, Home depot and more

SerpApi Search in Rust

Elerons - ELectRONics Search with Rust

Elerons is a command line tool for electronic component selection and design optimization facilitated by engineering know-how infused into the software itself

Elerons - ELectRONics Search with Rust

roc -- cli rust documentation that rocks

go doc style command line searching through documentation for rust crates

roc -- cli rust documentation that rocks
Facebook Instagram Twitter GitHub Dribbble
Privacy