···22{
33 perSystem =
44 { pkgs, ... }:
55- let
66- # Function to detect if we're running in a terminal environment
77- terminalDetectionFunction = ''
88- is_terminal_environment() {
99- # Check if we're running in a TTY
1010- if [ -t 0 ] || [ -t 1 ]; then
1111- return 0 # True, we're in a terminal
1212- fi
1313-1414- # Check if our parent process is a terminal
1515- parent_process=$(ps -o comm= $PPID 2>/dev/null || true)
1616- terminal_programs="bash zsh fish sh ksh csh tcsh dash xterm konsole gnome-terminal alacritty kitty terminal terminator urxvt rxvt xfce4-terminal iterm2 Terminal"
1717- for term in $terminal_programs; do
1818- if echo "$parent_process" | grep -q "$term"; then
1919- return 0 # True, parent is a terminal
2020- fi
2121- done
2222-2323- # Check if we're in an interactive environment
2424- if [ -n "$TERM" ] && [ "$TERM" != "dumb" ]; then
2525- # Check if we're in an SSH session
2626- if [ -n "$SSH_TTY" ] || [ -n "$SSH_CONNECTION" ] || [ -n "$SSH_CLIENT" ]; then
2727- return 0 # True, SSH session implies terminal
2828- fi
2929- fi
3030-3131- return 1 # False, not in a terminal
3232- }
3333- '';
3434- in
3535- {
55+ {
366 packages.menu =
377 if pkgs.stdenv.hostPlatform.isDarwin then
388 (pkgs.writeShellApplication {
···4010 runtimeInputs = [
4111 pkgs.choose-gui
4212 pkgs.fzf
4343- pkgs.procps
4413 ];
4514 text = ''
4615 set -efu
4747-4848- # Terminal detection function
4949- ${terminalDetectionFunction}
5050-5151- # Decide which menu program to use
5252- if is_terminal_environment; then
5353- # Use terminal-based menu
5454- cat | fzf "$@"
5555- else
5656- # Use GUI-based menu
5757- cat | choose "$@"
1616+1717+ # Create temporary files for input and output
1818+ TEMP_DIR=$(mktemp -d)
1919+ INPUT_FILE="$TEMP_DIR/input"
2020+ OUTPUT_FILE="$TEMP_DIR/output"
2121+2222+ # Set up trap to clean up temp dir on exit
2323+ trap 'rm -rf "$TEMP_DIR"' EXIT
2424+2525+ # Save stdin to file
2626+ cat > "$INPUT_FILE"
2727+2828+ # Try fzf first with terminal UI - explicitly store exit code
2929+ # This avoids issues with losing the exit code in a pipe
3030+ set +e
3131+ fzf "$@" < "$INPUT_FILE" > "$OUTPUT_FILE" 2>/dev/null
3232+ FZF_EXIT=$?
3333+ set -e
3434+3535+ # Handle fzf results based on exit code
3636+ if [ $FZF_EXIT -eq 0 ]; then
3737+ # Success - output result and exit
3838+ cat "$OUTPUT_FILE"
3939+ exit 0
4040+ elif [ $FZF_EXIT -eq 130 ]; then
4141+ # User pressed Escape - honor the cancellation
4242+ exit 130
5843 fi
4444+4545+ # If we get here, fzf failed with error (not cancellation)
4646+4747+ # Fall back to GUI
4848+ choose "$@" < "$INPUT_FILE"
5949 '';
6050 })
6151 else if pkgs.stdenv.hostPlatform.isLinux then
···6555 pkgs.rofi
6656 pkgs.wofi
6757 pkgs.fzf
6868- pkgs.procps
6958 ];
7059 text = ''
7160 set -efu
7272-7373- # Terminal detection function
7474- ${terminalDetectionFunction}
7575-7676- # Decide which menu program to use
7777- if is_terminal_environment; then
7878- # Use terminal-based menu
7979- cat | fzf "$@"
8080- elif [[ -n $WAYLAND_DISPLAY ]]; then
8181- # Use wofi in Wayland
8282- cat | wofi -d "$@"
8383- elif [[ -n $DISPLAY ]]; then
8484- # Use rofi in X11
8585- cat | rofi -dmenu "$@"
6161+ # Create temporary files for input and output
6262+ TEMP_DIR=$(mktemp -d)
6363+ INPUT_FILE="$TEMP_DIR/input"
6464+ OUTPUT_FILE="$TEMP_DIR/output"
6565+6666+ # Save stdin to file
6767+ cat > "$INPUT_FILE"
6868+6969+ # Try fzf first with terminal UI - explicitly store exit code
7070+ # This avoids issues with losing the exit code in a pipe
7171+ set +e
7272+ fzf "$@" < "$INPUT_FILE" > "$OUTPUT_FILE" 2>/dev/null
7373+ FZF_EXIT=$?
7474+ set -e
7575+7676+ # Handle fzf results based on exit code
7777+ if [ $FZF_EXIT -eq 0 ]; then
7878+ # Success - output result and exit
7979+ cat "$OUTPUT_FILE"
8080+ exit 0
8181+ elif [ $FZF_EXIT -eq 130 ]; then
8282+ # User pressed Escape - honor the cancellation
8383+ exit 130
8484+ fi
8585+8686+ # If we get here, fzf failed with error (not cancellation)
8787+8888+ # Fall back to GUI based on available display environment
8989+ if [ -n "''${WAYLAND_DISPLAY:-}" ]; then
9090+ wofi -d "$@" < "$INPUT_FILE"
9191+ elif [ -n "''${DISPLAY:-}" ]; then
9292+ rofi -dmenu "$@" < "$INPUT_FILE"
8693 else
8787- # No terminal or GUI environment, fallback to fzf
8888- cat | fzf "$@"
9494+ echo "Error: No suitable display environment available" >&2
9595+ exit 1
8996 fi
9097 '';
9191-9298 })
9399 else
94100 throw "unsupported system";