From 868da65faaa217ea79d3754d4ce0bc45b5d9ce49 Mon Sep 17 00:00:00 2001 From: Nate Anderson Date: Wed, 22 Apr 2026 17:40:38 -0600 Subject: [PATCH] added space-@ to copy the current code line to clipboard of the git remote's viewer --- shared/modules/apps/helix.nix | 64 ++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/shared/modules/apps/helix.nix b/shared/modules/apps/helix.nix index daeee07..91d91b4 100644 --- a/shared/modules/apps/helix.nix +++ b/shared/modules/apps/helix.nix @@ -1,7 +1,64 @@ -{lib, config, ...}: +{lib, config, pkgs, ...}: let cfg = config.helixApp; + # Copies a permalink to the current buffer's line in the remote git viewer + # (GitHub/GitLab use /blob//, Gitea/Codeberg use /src/commit//). + # Errors are written to stderr (Helix shows them in the statusline); + # clipboard is only written on success. + copyRemoteLineLink = pkgs.writeShellApplication { + name = "helix-copy-remote-line-link"; + runtimeInputs = [ pkgs.git pkgs.wl-clipboard pkgs.coreutils ]; + text = '' + set -eu + file="''${1:?usage: $0 }" + line="''${2:?usage: $0 }" + + # Resolve symlinks so git can find the file in its real repo. + file=$(readlink -f -- "$file") \ + || { echo "could not resolve path: $file" >&2; exit 1; } + [ -e "$file" ] || { echo "file does not exist: $file" >&2; exit 1; } + dir=$(dirname -- "$file") + + url=$(git -C "$dir" config --get remote.origin.url) \ + || { echo "not a git repo or no origin remote" >&2; exit 1; } + [ -n "$url" ] || { echo "no origin remote" >&2; exit 1; } + + sha=$(git -C "$dir" rev-parse HEAD) \ + || { echo "could not resolve HEAD" >&2; exit 1; } + + rel=$(git -C "$dir" ls-files --full-name --error-unmatch -- "$file" 2>&1) \ + || { echo "file not tracked ($file): $rel" >&2; exit 1; } + + # Normalize: strip trailing .git, convert ssh form to https. + url="''${url%.git}" + case "$url" in + *@*:*) + userhost="''${url%%:*}" + host="''${userhost#*@}" + path="''${url#*:}" + url="https://$host/$path" + ;; + ssh://*) + rest="''${url#ssh://}" + userhost="''${rest%%/*}" + host="''${userhost#*@}" + path="''${rest#*/}" + url="https://$host/$path" + ;; + esac + + case "$url" in + *github.com*|*gitlab.com*) link="$url/blob/$sha/$rel#L$line" ;; + *) link="$url/src/commit/$sha/$rel#L$line" ;; + esac + + printf '%s' "$link" | wl-copy + + echo 'line copied to clipboard :3' + ''; + }; + # helix theming docs: https://docs.helix-editor.com/themes.html # Check current stylix theme: ~/.config/helix/themes/stylix.toml # And computed minimal: ~/.config/helix/themes/minimal.toml @@ -191,9 +248,8 @@ in o = ":config-open"; h = "hover"; k = "select_references_to_symbol_under_cursor"; - # Copy a permalink to the current line in the remote git viewer - # (GitHub/GitLab use /blob//, Gitea/Codeberg use /src/commit//). - "@" = ":sh f=%{buffer_name}; l=%{cursor_line}; d=$(dirname \"$f\"); url=$(git -C \"$d\" config --get remote.origin.url) || { echo \"not a git repo or no origin remote\" >&2; exit 1; }; [ -n \"$url\" ] || { echo \"no origin remote\" >&2; exit 1; }; sha=$(git -C \"$d\" rev-parse HEAD) || exit 1; rel=$(git -C \"$d\" ls-files --full-name --error-unmatch -- \"$f\" 2>&1) || { echo \"file not tracked: $rel\" >&2; exit 1; }; command -v wl-copy >/dev/null || { echo \"wl-copy not installed\" >&2; exit 1; }; url=\${url%%.git}; case \"$url\" in git@*) host=\${url#git@}; host=\${host%%:*}; path=\${url#*:}; url=\"https://$host/$path\" ;; esac; case \"$url\" in *github.com*|*gitlab.com*) link=\"$url/blob/$sha/$rel#L$l\" ;; *) link=\"$url/src/commit/$sha/$rel#L$l\" ;; esac; printf '%%s' \"$link\" | wl-copy"; + # Copy a permalink to the current line in the remote git viewer. + "@" = ":sh ${copyRemoteLineLink}/bin/helix-copy-remote-line-link %{buffer_name} %{cursor_line}"; }; g = {