From b62c2476da7bb4a2dcef0ea2eca6b6f5a89061fd Mon Sep 17 00:00:00 2001 From: rootiest Date: Sun, 10 May 2026 01:36:14 -0400 Subject: [PATCH] feat(functions,bindings): add smart-execute, fast-cli; refactor qalc and rm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add _smart_execute: context-aware Ctrl+Enter that routes to qalc when the buffer ends with '=', or falls through to standard execute otherwise - Refactor qalc_eval → _qalc_eval (private helper, same behavior) - Bind Ctrl+Enter to _smart_execute in all vi modes - Add fast-cli wrapper (fast.com speed test) and fast placeholder with a friendly ANSI redirect message - Add speedtest-fast abbreviation expanding to fast-cli - Enhance _replace_command_token to handle sudo-prefixed commands: places cursor at index 5 (between sudo and the replacement slot) - Improve rm error reporting: colored output, culprit-path listing, and cleaned technical detail for non-missing-file errors - Add SPDX copyright headers to cat, ld, claude-docs, claude-pr functions - Update README: Ctrl+Enter binding, fast-cli/fast functions, speedtest-fast abbr --- README.md | 9 ++++ conf.d/abbr.fish | 3 ++ conf.d/key_bindings.fish | 6 ++- functions/{qalc_eval.fish => _qalc_eval.fish} | 3 +- functions/_replace_command_token.fish | 35 +++++++++++-- functions/_smart_execute.fish | 29 +++++++++++ functions/cat.fish | 1 + functions/claude-docs.fish | 4 ++ functions/claude-pr.fish | 4 ++ functions/fast-cli.fish | 7 +++ functions/fast.fish | 41 +++++++++++++++ functions/ld.fish | 1 + functions/rm.fish | 50 +++++++++++++++++-- 13 files changed, 181 insertions(+), 12 deletions(-) rename functions/{qalc_eval.fish => _qalc_eval.fish} (88%) create mode 100644 functions/_smart_execute.fish create mode 100644 functions/fast-cli.fish create mode 100644 functions/fast.fish diff --git a/README.md b/README.md index e2aaa0d..f61a3b2 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,7 @@ Beyond standard shell and FZF bindings, these custom interactive shortcuts are a | `Ctrl+F` | Interactive History Substitution | Behaves like `!!:s/old/new/` in Bash. Performs substitution on the previous command using `old/new` syntax. When no text is entered, prepends `sudo` to the previous command. The `old/new/n` syntax will perform substitution on the command `n` lines previous in the history. | | `Ctrl+Alt+U` | Replace Command Token | Strips the first token (the command) from the current line. **If the line is empty**, it pulls the previous command and strips its first token, placing the cursor at the start for a quick replacement (e.g., changing `mkdir` to `cd` while keeping the paths). | | `Ctrl+Alt+=` | Inline Qalculate! Evaluation | Passes the current command-line buffer to `qalc` (Qalculate!) and prints the result, then clears the buffer. Allows rapid-fire math without leaving the shell — type `150 * 1.08`, press `Ctrl+Alt+=`, and see `162` immediately. | +| `Ctrl+Enter` | Smart Execute | Context-aware Enter key. Empty buffer → standard Enter. Buffer ending with `=` → evaluates it as a math expression via `qalc` (same as `Ctrl+Alt+=`). Any other content → executes the command normally. | --- @@ -244,6 +245,8 @@ rm -f file.txt # Falls through to standard rm -f | `gip4` | Show public IPv4 address only | | `gip6` | Show public IPv6 address (or error if unavailable) | | `ports` | List all active TCP listeners via `lsof` | +| `fast-cli` | Run a bandwidth speed test using fast.com | +| `fast` | Friendly error shown when `fast` is typed instead of `fast-cli` | ### Clipboard @@ -439,6 +442,12 @@ Named context shortcuts (e.g. `dcr`, `dck`) live in `~/.config/.user-dots/fish/l | `sscs` | `sudo systemctl start` | | `sscr` | `sudo systemctl restart` | +### Speed Test + +| Abbr | Expands To | +|---|---| +| `speedtest-fast` | `fast-cli` (speed test via fast.com) | + ### Beads (bd) | Abbr | Expands To | diff --git a/conf.d/abbr.fish b/conf.d/abbr.fish index 3d52ffb..a9e89db 100644 --- a/conf.d/abbr.fish +++ b/conf.d/abbr.fish @@ -97,6 +97,9 @@ abbr -a lX lx abbr -a lT lt # Full tree listing abbr -a lsT lstree +### speed-test alternates +# Speedtest using fast.com +abbr -a speedtest-fast fast-cli # Window Creation (OS Windows) if test "$TERM" = xterm-kitty diff --git a/conf.d/key_bindings.fish b/conf.d/key_bindings.fish index 5ea3980..b725bc3 100644 --- a/conf.d/key_bindings.fish +++ b/conf.d/key_bindings.fish @@ -52,7 +52,8 @@ function fish_user_key_bindings bind ctrl-g __insert_previous_path_head bind ctrl-f __interactive_history_sub bind ctrl-alt-u _replace_command_token - bind ctrl-alt-= qalc_eval + bind ctrl-alt-= _qalc_eval + bind ctrl-enter _smart_execute # Set bindings for all Vi modes: # 'default' is Vi-Command, 'insert' is Vi-Insert, 'visual' is Vi-Visual @@ -60,6 +61,7 @@ function fish_user_key_bindings bind --mode $mode ctrl-g __insert_previous_path_head bind --mode $mode ctrl-f __interactive_history_sub bind --mode $mode ctrl-alt-u _replace_command_token - bind --mode $mode ctrl-alt-= qalc_eval + bind --mode $mode ctrl-alt-= _qalc_eval + bind --mode $mode ctrl-enter _smart_execute end end diff --git a/functions/qalc_eval.fish b/functions/_qalc_eval.fish similarity index 88% rename from functions/qalc_eval.fish rename to functions/_qalc_eval.fish index c4d7a48..212810f 100644 --- a/functions/qalc_eval.fish +++ b/functions/_qalc_eval.fish @@ -1,7 +1,8 @@ # Copyright (C) 2026 Rootiest # SPDX-License-Identifier: AGPL-3.0-or-later -function qalc_eval +# Returns the result of a qalc calculation +function _qalc_eval # Get the current command line buffer set -l cmd (commandline) diff --git a/functions/_replace_command_token.fish b/functions/_replace_command_token.fish index 378f8cd..cd75d3f 100644 --- a/functions/_replace_command_token.fish +++ b/functions/_replace_command_token.fish @@ -1,10 +1,35 @@ # Copyright (C) 2026 Rootiest # SPDX-License-Identifier: AGPL-3.0-or-later -# Removes the first token from the command line and places the cursor at the start -function _replace_command_token --description 'Remove first token from commandline and place cursor at start' +# Removes the first token from the command line and places the cursor at the position for replacement. +# If the command starts with 'sudo', preserves 'sudo' and removes the next token instead. +function _replace_command_token --description 'Remove first command token (or first after sudo) and place cursor for replacement' set -l cmd (commandline) - set -l rest (string replace -r '^\S+' '' -- $cmd) - commandline -- $rest - commandline -C 0 + + # 1. Logic for commands starting with sudo + if string match -rq '^sudo\s+' -- "$cmd" + # regex explanation: + # ^sudo\s+ -> Matches 'sudo' and the following whitespace + # \S+ -> Matches the actual command (e.g., 'rm') + # \s* -> Consumes the space after the command so it's not captured + # (.*) -> Captures everything else (the arguments) into $1 + set -l rest (string replace -r '^sudo\s+\S+\s*(.*)' 'sudo $1' -- "$cmd") + commandline -- "$rest" + + # Place cursor between the two spaces after sudo + # 'sudo ' is 5 characters (indices 0-4), so index 5 is the sweet spot + commandline -C 5 + + # 2. Logic for standard commands (no sudo) + else + # regex explanation: + # ^\S+ -> Matches the first word/command + # \s* -> Consumes the trailing space + # (.*) -> Captures the rest of the line into $1 + set -l rest (string replace -r '^\S+\s*(.*)' ' $1' -- "$cmd") + commandline -- "$rest" + + # Place cursor at index 0 to immediately start typing the replacement + commandline -C 0 + end end diff --git a/functions/_smart_execute.fish b/functions/_smart_execute.fish new file mode 100644 index 0000000..f2fe8d9 --- /dev/null +++ b/functions/_smart_execute.fish @@ -0,0 +1,29 @@ +# Copyright (C) 2026 Rootiest +# SPDX-License-Identifier: AGPL-3.0-or-later + +# Executes different functions based on the command line content +function _smart_execute --description 'Execute different functions based on the command line content' + # Get the current command line buffer + set -l cmd (commandline) + + # 1. Handle empty buffer (Standard Enter behavior) + if test -z "$cmd" + commandline -f execute + return + end + + # 2. Dispatch based on buffer content + switch "$cmd" + case '*=' + # If it ends in =, run qalc + _qalc_eval + +# case 'g *' +# # EXAMPLE FUTURE EXTENSION +# _some_git_helper + + case '*' + # Default: execute the command line as-is + commandline -f execute + end +end diff --git a/functions/cat.fish b/functions/cat.fish index bca4d0a..ab7de68 100644 --- a/functions/cat.fish +++ b/functions/cat.fish @@ -1,6 +1,7 @@ # Copyright (C) 2026 Rootiest # SPDX-License-Identifier: AGPL-3.0-or-later +# Use bat for files and ls for directories when using cat function cat --wraps='bat' --description 'Use bat for files and ls for directories' # If no arguments are provided, cat usually waits for stdin. # We'll maintain that behavior by skipping the directory check if $argv is empty. diff --git a/functions/claude-docs.fish b/functions/claude-docs.fish index db795cc..b957a9d 100644 --- a/functions/claude-docs.fish +++ b/functions/claude-docs.fish @@ -1,3 +1,7 @@ +# Copyright (C) 2026 Rootiest +# SPDX-License-Identifier: AGPL-3.0-or-later + +# Update README.md with recent changes using Claude-code function claude-docs --description 'Claude-code: Sync README with recent changes' claude "Analyze the recent changes and update the README.md to ensure all features, setup instructions, and examples are 100% accurate. Prune any obsolete information." end diff --git a/functions/claude-pr.fish b/functions/claude-pr.fish index 4b272a9..8f6ab35 100644 --- a/functions/claude-pr.fish +++ b/functions/claude-pr.fish @@ -1,3 +1,7 @@ +# Copyright (C) 2026 Rootiest +# SPDX-License-Identifier: AGPL-3.0-or-later + +# Create a new git branch, commit, push, and PR using Claude-code function claude-pr --description 'Claude-code: New branch, commit, push, and PR' claude "Act as a senior engineer. Execute this sequence: 1. Create a new git branch (kebab-case). 2. Stage changes and write a Conventional Commit message. 3. Self-verify the changes by running relevant build/test commands or linting. 4. Push to remote. 5. Create a PR to 'main' including a summary of changes and a 'Manual Verification' section containing a Markdown checklist (- [ ]) of specific, bite-sized steps required to manually verify the functionality." end diff --git a/functions/fast-cli.fish b/functions/fast-cli.fish new file mode 100644 index 0000000..2abf4be --- /dev/null +++ b/functions/fast-cli.fish @@ -0,0 +1,7 @@ +# Copyright (C) 2026 Rootiest +# SPDX-License-Identifier: AGPL-3.0-or-later + +# Run a speed test using fast.com +function fast-cli --description "Run a speed test using fast.com" + command fast $argv +end diff --git a/functions/fast.fish b/functions/fast.fish new file mode 100644 index 0000000..8cacc83 --- /dev/null +++ b/functions/fast.fish @@ -0,0 +1,41 @@ +# # Copyright (C) 2026 Rootiest +# # SPDX-License-Identifier: AGPL-3.0-or-later +# +# # Placeholder for a future implementation of a "fast" function +# function fast --description 'Placeholder for future fast utility' +# # Defining Catppuccin Mocha colors +# set -l flamingo F2CDCD +# set -l blue 89B4FA +# set -l mauve cba6f7 +# set -l mantle 181825 +# +# echo -e "" +# echo -n (set_color $flamingo)" 󰊠 "(set_color --bold)"The '" +# echo -n (set_color $mauve)"fast" +# echo -n (set_color $flamingo)"' command is not currently available." +# echo -e "" +# echo -n (set_color $blue)" Did you mean: " +# echo -n (set_color --bold $mauve)"fast-cli" +# echo -n (set_color --italics $blue)"?"(set_color normal) +# echo -e "\n" +# end + +# Copyright (C) 2026 Rootiest +# SPDX-License-Identifier: AGPL-3.0-or-later + +# Placeholder for a future implementation of a "fast" function +function fast --description 'Placeholder for future fast utility' + # ANSI Escape Codes (Standard 16-color palette) + set -l bold "\e[1m" + set -l italic "\e[3m" + set -l red "\e[31m" + set -l blue "\e[34m" + set -l yellow "\e[33m" + set -l magenta "\e[35m" + set -l reset "\e[0m" + + # Using printf for reliable ANSI rendering + printf " %b %bThe command: %b%bfast%b%b is currently unavailable.%b\n" "$yellow" "$bold" "$reset" "$magenta" "$reset" "$yellow" "$reset" + printf " %bDid you mean: %b%bfast-cli%b%b?%b\n" "$blue" "$reset" "$bold$magenta" "$reset" "$italic$blue" "$reset" + printf "\n" +end diff --git a/functions/ld.fish b/functions/ld.fish index 1e03074..430c0e4 100644 --- a/functions/ld.fish +++ b/functions/ld.fish @@ -1,6 +1,7 @@ # Copyright (C) 2026 Rootiest # SPDX-License-Identifier: AGPL-3.0-or-later +# Run lazydocker on the current Docker context function ld --description 'Run lazydocker on the current Docker context' # Fetch the host endpoint of the currently active Docker context set -l current_host (docker context inspect --format '{{.Endpoints.docker.Host}}') diff --git a/functions/rm.fish b/functions/rm.fish index c9c40dd..c0f470f 100644 --- a/functions/rm.fish +++ b/functions/rm.fish @@ -66,12 +66,54 @@ function rm --description 'Ultimate rm: trash, list, empty, and secure-erase' set -a trash_paths $arg end end - if type -q trash; and set -q trash_paths[1] - trash put $trash_paths - # Refresh Dolphin view + set -l trash_output (trash put $trash_paths 2>&1) + set -l exit_status $status + + if test $exit_status -ne 0 + # 1. Extract the core message (e.g., "No such file or directory") + set -l raw_msg (string replace -r '.*Message: (.+?) \(os error.*' '$1' -- "$trash_output") + + # 2. Find which paths are actually missing + set -l culprits + for p in $trash_paths + if not test -e "$p" + set -a culprits "$p" + end + end + + # 3. Display Logic + set_color red --bold + echo -n "error: " + set_color normal + echo $raw_msg + + if set -q culprits[1] + # If we found missing files, show the user's source paths + for c in $culprits + set_color blue + echo -n " ↳ Source: " + set_color normal + echo $c + end + else + # 1. Strip ANSI escape codes (color) so regex works correctly + # 2. Remove the 'error: ' prefix + # 3. Unescape quotes and trim whitespace + set -l clean_detail (string replace -ra '\e\[[^m]*m' '' -- "$trash_output" \ + | string replace -r '^error: ' '' \ + | string unescape \ + | string trim) + + set_color yellow + echo -n " ↳ Technical detail: " + set_color normal + echo $clean_detail + end + end + dbus-send --type=signal /OrgKdeKDirNotify org.kde.KDirNotify.FilesChanged stringArray:"trash:/" >/dev/null 2>&1 & - return + return $exit_status end end