npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fish-mode

v1.0.0

Published

Fish shell for ! commands in Oh My Pi — /fish on/off toggle with autocomplete

Readme

fish-mode

Route ! commands through fish shell inside Oh My Pi. Same aliases, abbreviations, functions, and completions you use in your terminal — now inside Pi.

For daily fish users. If you have personal aliases (gst → git status, gco → git checkout), abbreviations (gs expands to git status), or custom functions, and every ! command in Pi forces you back to bash — fish-mode fixes exactly that.

pi install npm:fish-mode

Demo

/fish on
  ┌─ Fish mode ON ─────────────────────────────┐
  │ ! commands run through fish                │
  └────────────────────────────────────────────┘

!git push --force-wi<Tab>
  --force-with-lease    --force-with-lease=<refname>

!gst
  On branch main
  nothing to commit, working tree clean

!echo $fish_pid
  12345

Usage

Toggle

| Command | Effect | | ------- | ------ | | /fish on | Route ! commands through fish | | /fish off | Back to bash (default) |

State is saved to .pi/fish-mode/config.json in the project directory. Survives Pi restarts.

Running commands

Type ! followed by your command as usual. When fish mode is active, everything after ! goes straight to fish -c.

!ls -la
!git log --oneline -10
!docker ps
!python3 script.py

Autocomplete

When typing on a line starting with !, press Tab to get fish-native completions. Supports:

  • Files & directories — !ls <Tab> shows file list
  • Git — !git che<Tab> → checkout, cherry-pick
  • Docker — !docker cont<Tab> → container
  • Any completion fish knows — including from plugins like fisher, oh-my-fish

Completions fall back to Pi's default provider when the line doesn't start with ! or fish mode is off.


How it works

Command routing

fish-mode listens to user_bash events. Every time you type a command in Pi:

  1. Check if fish mode is active
  2. Check if the command starts with !
  3. If yes → strip !, run the rest through fish -c
  4. Return stdout + stderr to Pi for display

Debounce

user_bash fires on every keystroke, not just on Enter. Typing !fastfetch fires 10 times: !f, !fa, !fas, ... Without debounce, each keystroke would execute a command.

fish-mode uses counter-based debounce (150ms): each event increments a counter, waits 150ms, and skips if the counter changed (meaning you're still typing). Only the final command — when you stop typing for 150ms — gets executed.

Autocomplete provider

On session start (session_start), fish-mode registers an autocomplete provider wrapping the default one:

  1. Line starts with ! and fish mode is active → calls fish -c "complete -C '<line>'" for fish-native completions
  2. Otherwise → falls back to Pi's default provider

The provider is registered only once per session to avoid leaks on session restart.

State persistence

Uses atomic write (write .tmp file then rename) to prevent config corruption on mid-write crash.


Requirements

  • fish shell ≥ 3.0 (apt install fish, brew install fish, pacman -S fish, ...)
  • Oh My Pi

If fish is not installed, the extension still loads but stays inactive. /fish on will show an error notification.


FAQ

Does this change Pi's default shell? No. Only ! commands are affected. Everything else uses bash as normal.

Do fish aliases work? Yes. fish -c loads your full fish config: ~/.config/fish/config.fish, aliases, abbreviations, functions — everything.

Do fish abbreviations work? Yes, but only when you press Space or Enter after the abbreviation — same as in a real fish terminal.

Does state survive restarts? Yes. State is saved to disk and persists across Pi restarts.

Is it slow? Negligibly. The user_bash handler only spawns a subprocess when fish mode is active and the command starts with !. Autocomplete calls fish but has a 500ms timeout.

Does it work with fish plugins (fisher, oh-my-fish, tide, ...)? Yes. fish -c loads your entire fish config, including all installed plugins.

Are multi-line commands supported? No. Single-line ! commands only.

How do I uninstall? /fish off to disable. To fully remove: delete the symlink from the extensions folder and remove .pi/fish-mode/config.json.


License

MIT