DBDelve
Dive deep into your data. A fast, native, multi-engine database client written in Rust. Free and open source, no telemetry.
j-menu is a TUI menu launcher for the terminal: type "j", press Enter, pick, and press Enter to run a per-project command (formerly jj-menu). YAML / TOML / JSON configuration and automatic entries fro
Developer toolsGitHub @cyberneuraOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
j-menu is a TUI menu launcher for the terminal: type "j", press Enter, pick, and press Enter to run a per-project command (formerly jj-menu). YAML / TOML / JSON configuration and automatic entries from package.json, Makefile, Cargo, and Gradle. macOS and Linux. MIT License.
Loading the full README.
Read the full README ↗A simple TUI menu launcher. Type j, press Enter, pick a command with the
arrow keys (or j/k), run it with Enter.
Website: https://www.cyberneura.com/app/j-menu
This is a Rust rewrite of the Python ytyng/jj-menu.
The idea is the same — a per-project list of commands you can reach in two
keystrokes — with a YAML/TOML/JSON configuration, submenus, prompted arguments,
and entries picked up automatically from package.json, Makefile, Cargo and
Gradle projects.
The selected command runs with the TTY fully attached, so ssh, vim, top
and anything else interactive behaves exactly as if you had typed it.
Unix-like systems only (macOS, Linux). A menu entry is a shell script run
through $SHELL -c, which has no meaningful Windows equivalent, so no Windows
binaries are published.
brew install cyberneura/tap/j-menu
cargo install j-menu
The binary is j-menu. Add the wrapper function to get the short j command,
and so that entries like cd /tmp or export FOO=1 affect your shell rather
than a child process:
# ~/.zshrc
eval "$(j-menu --shell-init zsh)"
# ~/.bashrc
eval "$(j-menu --shell-init bash)"
# ~/.config/fish/config.fish
j-menu --shell-init fish | source
Calling the binary by a path -- eval "$(~/src/j-menu/target/release/j-menu --shell-init zsh)" -- works too: the generated function then calls that same
path, so j works when the binary is not on PATH.
j is also the function autojump defines.
If you use autojump, rename the function on its first line, here to m:
eval "$(j-menu --shell-init zsh | sed '1s/^j()/m()/')" # bash, zsh
j-menu --shell-init fish | sed '1s/^function j$/function m/' | source
Or drop autojump for zoxide, whose
command is z.
This project was jj-menu until 0.3.0; the jj command now belongs to
Jujutsu. Configuration files are renamed with
it: .jj-menu.yaml becomes .j-menu.yaml, and ~/.config/jj-menu/ becomes
~/.config/j-menu/. The old names are not read.
The fish function needs fish 3.4 or newer. It relies on quoted command
substitution ("$(...)"), which is what keeps a multi-line entry in one piece;
older versions split it on newlines.
The wrapper also pushes the command into your shell history, so the usual recall-and-edit workflow keeps working.
Without the wrapper, j-menu runs the command itself; everything works except
changes to the shell's own state.
j-menu [OPTIONS]
--print Print the selected command instead of running it
--shell-init <SHELL> Print the shell function (bash, zsh, fish)
--cwd <DIR> Search for configuration from here instead of $PWD
--show-config List the configuration files that were loaded
-h, --help Show help
-V, --version Show the version
| Key | Action |
|---|---|
j, ↓, Ctrl-N | Down |
k, ↑, Ctrl-P | Up |
g, Home | First entry |
G, End | Last entry |
l, → | Open the detail view (help, submenu) |
h, ← | Back (leaves the menu at the top level) |
Enter | Run the entry |
/ | Incremental search |
q, Ctrl-C | Quit |
Esc | Drop the search, or quit when there is none |
/ narrows the list as you type: only the entries whose label contains what you
have typed stay on screen, matched without regard to case, and the cursor sits on
the first of them. Enter runs it. It is the fastest way through a long menu —
/dep then Enter.
The letter keys are text while you are typing, so moving around is ↑ / ↓
(or Ctrl-P / Ctrl-N) and ← / →, none of which can be typed. Esc (or
backspacing past the start) drops the search and shows everything again, leaving
the cursor on the entry it was on; Ctrl-U empties what you typed without
leaving the search. Ctrl-C quits the menu, from here as from anywhere else.
The search belongs to the level it was typed on: opening a submenu starts
unfiltered, and going back brings the filter with you. A filtered list keeps
saying /… above it after the search is accepted, so a menu that is missing
entries never looks like a menu that does not have them.
The help of the entry the cursor is on is shown in a block of its own, just
above the status line — three rows of it, or fewer on a terminal with no room to
spare. The block is reserved for the whole menu rather than sized to the entry,
so the list stays where it is as the cursor walks past entries that have help
and entries that do not, and a menu where nothing has a help spends no rows on
it at all. Help too long for the block carries on in the detail view, which
wraps it over as much as half the screen; a description longer than that is cut,
in both places.
Entries with a detail view are marked with >: those are the ones with a
submenu, a help text, or both. The view shows the help, the entry's own
command as a Run: ... line, and the submenu.
Arguments are not part of the detail view — they are prompted for when the entry runs, whichever level you run it from.
While entering an argument: Enter accepts, Esc cancels, and the usual
Ctrl-A / Ctrl-E / Ctrl-U motions work.
The menu is coloured: a cyan title, entries with a detail view (a submenu, a
help text, or both) in cyan, the selected row as a blue bar with a yellow *>
marker, the selected entry's help in grey above the status line, and a status
line carrying the command preview (or the entry count of a submenu). Only colours the
terminal itself defines (palette entries 0–15) are used, so it follows your
theme.
Set NO_COLOR to a non-empty value to turn the colours off; TERM=dumb does
the same. The selected row and the status line then fall back to reverse video,
so they stay visible.
This is the beginning of the README. Read the rest at the original. Read the full README ↗