diff --git a/platforms/home-manager/modules/nmasur/presets/programs/helix.nix b/platforms/home-manager/modules/nmasur/presets/programs/helix.nix index fda4e43..c005967 100644 --- a/platforms/home-manager/modules/nmasur/presets/programs/helix.nix +++ b/platforms/home-manager/modules/nmasur/presets/programs/helix.nix @@ -7,6 +7,62 @@ let cfg = config.nmasur.presets.programs.helix; + + blame_file_pretty = pkgs.writeShellScriptBin "blame_file_pretty" '' + # Source: https://gist.github.com/gloaysa/828707f067e3bb20da18d72fa5d4963a + # Utility for Helix: open the patch for the commit that last touched the current line. + # If the line isn’t committed yet, it shows the working-tree diff for THIS file only. + # The script writes the diff to /tmp and prints the absolute path to stdout + # Adjust `context` to see more/fewer unchanged lines around the change (default: 3). + # + # usage: git-file_pretty.sh [context_lines] + # Helix mapping example: + # B = ':open %sh{ ~/.config/helix/utils/git-blame-commit.sh "%{buffer_name}" %{cursor_line} 3 }' + file="$1" + line="$2" + ctx="''${3:-3}" + + # blame the exact line + porc="$(git blame -L "$line",+1 --porcelain -- "$file")" || exit 1 + sha="$(printf '%s\n' "$porc" | awk 'NR==1{print $1}')" + commit_path="$(printf '%s\n' "$porc" | awk '/^filename /{print substr($0,10); exit}')" + + out="/tmp/hx-blame_$(basename "$file")_''${sha:-wt}.diff" + + if [ -z "$sha" ] || [ "$sha" = 0000000000000000000000000000000000000000 ] || [ "$sha" = "^" ]; then + # uncommitted line → working tree diff for this file + git --no-pager diff --no-color -U"$ctx" -- "$file" > "$out" + else + # committed line → only this file’s patch in that commit + git --no-pager show --no-color -M -C -U"$ctx" "$sha" -- "''${commit_path:-$file}" > "$out" + fi + + # "return" the path for :open %sh{…} + printf '%s' "$out" + ''; + + blame_line_pretty = pkgs.writeShellScriptBin "blame_line_pretty" '' + # Source: https://gist.github.com/gloaysa/828707f067e3bb20da18d72fa5d4963a + # Utility for Helix: pretty-print blame info for the line under the cursor. + # Quite basic. + # + # usage: blame_line_pretty + # Helix mapping example: + # b = ":run-shell-command ~/.config/helix/utils/blame_line_pretty.sh %{buffer_name} %{cursor_line}" + file="$1"; line="$2" + out="$(git blame -L "$line",+1 --porcelain -- "$file")" || return 1 + + sha="$(printf '%s\n' "$out" | awk 'NR==1{print $1}')" + author="$(printf '%s\n' "$out" | awk -F'author ' '/^author /{print $2; exit}')" + epoch="$(printf '%s\n' "$out" | awk '/^author-time /{print $2; exit}')" + # dd-mm-yyyy (macOS `date -r`; fallback to gdate if present) + date="$( (date -r "$epoch" +%d-%m-%Y\ %H:%M 2>/dev/null) || (gdate -d "@$epoch" +%d-%m-%Y\ %H:%M 2>/dev/null) || printf '%s' "$epoch")" + summary="$(printf '%s\n' "$out" | awk -F'summary ' '/^summary /{print $2; exit}')" + change="$(printf '%s\n' "$out" | tail -n 1)" + + printf "%s\n%s\n%s\n%s\n%s\n" "$sha" "$author" "$date" "$summary" "$change" + ''; + in { @@ -179,7 +235,9 @@ in ]; # Commandline git blame - space.B = ":echo %sh{git log -n1 --date=short --pretty=format:'%%h %%ad %%s' $(git blame -L %{cursor_line},+1 \"%{buffer_name}\" | cut -d' ' -f1)}"; + # space.B = ":echo %sh{git log -n1 --date=short --pretty=format:'%%h %%ad %%s' $(git blame -L %{cursor_line},+1 \"%{buffer_name}\" | cut -d' ' -f1)}"; + space.B = '':open %sh{ ${blame_line_pretty}/bin/blame_line_pretty "%{buffer_name}" %{cursor_line} 3 }''; + space.i = '':open %sh{ ${blame_file_pretty}/bin/blame_file_pretty "%{buffer_name}" %{cursor_line} 3 }''; # Extend selection above X = "select_line_above";