helix-editor / helix

A post-modern modal text editor.
https://helix-editor.com
Mozilla Public License 2.0
32.99k stars 2.44k forks source link

Git blame and URL #3035

Open mangas opened 2 years ago

mangas commented 2 years ago

Describe your feature request

Would be great to add a git blame hint (toggle on config)

As part of this, being able to go to the repo url with a key bind is very useful.

Both of these are provided by this vscode extension

Happy to also give a hand with this if the maintainers agree with this belonging on the editor itself as opposed to a plugin later (I feel like in the latter case we could add it now and move it out later)

the-mikedavis commented 2 years ago

Blame information I think could fit well into the core. See also https://github.com/helix-editor/helix/issues/227

For opening the repo url, if you mean just opening up the main repository page, you can do that currently with a binding like

[keys.normal]
space.o = ":sh gh repo view --web"

for github repos.

Provider-specific features (like in the plugin should not be in core: provider-specific logic like how to format git forge URLs is undesirable for core unless it's based on an open standard (which does not seem to exist for any of the popular git forges).

mangas commented 2 years ago

For github i was thinking something like this where you can just get the repo open on a browser pointing to the exact file, branch and line. I think despite this being provider it's quite easily extendable and could work even before there are plugins. Later it could just be moved to plugins once they are available?

the-mikedavis commented 2 years ago

I think that would be handy in a plugin but that's the provider-specific logic that I think is distasteful to add to core. I think it's ok in a git-lens-like plugin that focuses on it and can be added I suspect without too much effort in a fork. I'd prefer that it wouldn't be merged in here though, even temporarily.

IMO, code that belongs in plugins shouldn't be added to core unless it can help advance other core features. File tree (#200) is a good example of this which was scoped as a plugin but is making its way into core (#2377). It adds a tree UI component that could be re-used else-where like in DAP or #1075.

heliostatic commented 2 years ago

Since gh accepts filename and line number as arguments for browse, we just need to be able to pass current filename and line number as arguments in the :sh gh browse command.

Is that currently possible, @the-mikedavis ? If not, that does seem like a generally useful enhancement.

mangas commented 2 years ago

there could be some special vars that would get interpolated before running the command, eg: :sh gh $file_name $line_number browse (command won't be correct, it's just to demonstrate the point). This may indeed be useful for a number of commands

the-mikedavis commented 2 years ago

Hmm no I don't think we have any replacements set up yet but I think those would be a welcome contribution if they work across operating systems 👍

aikomastboom commented 2 years ago

Simple :sh command substitutions #3134

icecreammatt commented 1 year ago

Thanks to the great work done by @obxhdx https://github.com/helix-editor/helix/issues/196#issuecomment-1572672233 and https://www.reddit.com/r/HelixEditor/comments/13x9a3z/integrating_fuzzylive_grepping_into_helix_my/ I was able to take what was done there and hack in a Git Blame in a similar fashion with Wezterm.

Dependencies:

Configs

Helix Config

B = ":pipe-to wezterm cli split-pane -- helix-git-blame"

The regex is a bit complex since I needed to account for the Explorer view code branch I'm using. I'm not sure if there is a simpler way to get the file and line number out of helix. But this work well for now. If the terminal is split vertically and isn't fully showing the file name the git blame will not work.

Shell Script in my path

#!/usr/bin/env bash

# ~/bin/helix-git-blame

HELIX_PANE_ID=$(wezterm cli get-pane-direction Up)
FILE_LINE=$(wezterm cli get-text --pane-id $HELIX_PANE_ID)

RES=$(echo $FILE_LINE | rg -e "(?:NOR|INS|SEL)\s+(\S*)\s[^│]* (\d+):*.*" -o --replace '$1 $2')
FILE=$(echo $RES | choose 0)
LINE=$(echo $RES | choose 1)

git blame -L $LINE,+100 $FILE --color-by-age --color-lines | 
  fzf --ansi \
      --border \
      --delimiter ':' \
      --height '100%' \
      --multi \
      --print-query --exit-0 \
      --scrollbar '▍'

Demo

out

H4ckint0sh commented 1 year ago

@icecreammatt Thanks and i made a working copy of it for those that using tmux like me.

config.toml

B = ":pipe-to tmux split-window -v helix-git-blame"

helix-git-blame

#!/usr/bin/env bash

# ~/bin/helix-git-blame

# Select Original pane 
ORIGINAL_PANE=$(tmux select-pane -U)

# Capture the output of the original pane
PANE_OUTPUT=$(tmux capture-pane -p -t $ORIGINAL_PANE)

# Back to the bottom pane 
tmux select-pane -D

# Extract file and line information
RES=$(echo "$PANE_OUTPUT" | rg -e "(?:NOR|INS|SEL)\s+(\S*)\s[^│]* (\d+):*.*" -o --replace '$1 $2')
FILE=$(echo $RES | choose 0)
LINE=$(echo $RES | choose 1)

# Run git blame and fzf commands
git blame -L $LINE,+100 $FILE --color-by-age --color-lines | 
  fzf --ansi \
      --border \
      --delimiter ':' \
      --height '100%' \
      --multi \
      --print-query --exit-0 \
      --scrollbar '▍'
nilsherzig commented 9 months ago

I adapted this idea to open the current line as a link to github / gitlab (other sites should be easy to add). :)

#!/usr/bin/env bash
HELIX_PANE_ID=$(wezterm cli get-pane-direction Up)
FILE_LINE=$(wezterm cli get-text --pane-id "$HELIX_PANE_ID")

RES=$(echo "$FILE_LINE" | rg -e "(?:NOR|INS|SEL)\s+(\S*)\s[^│]* (\d+):*.*" -o --replace '$1 $2')
FILE_PATH=$(echo "$RES" | choose 0)
LINE_NUMBER=$(echo "$RES" | choose 1)

# Extract the current Git branch name
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)

# Extract the base URL for the remote repository (GitLab or GitHub)
REMOTE_URL=$(git remote get-url origin)

# Determine if the remote URL is for GitLab or GitHub
if [[ $REMOTE_URL == *"gitlab.com"* ]]; then
    # GitLab
    BASE_URL=$(echo "$REMOTE_URL" | sed -e 's/git@gitlab.com://' -e 's/.git$//' -e 's/:/\//g')
    COMPLETE_URL="https://gitlab.com/${BASE_URL}/-/blame/${BRANCH_NAME}/${FILE_PATH}#L${LINE_NUMBER}"
elif [[ $REMOTE_URL == *"github.com"* ]]; then
    # GitHub
    BASE_URL=$(echo "$REMOTE_URL" | sed -e 's/git@github.com://' -e 's/.git$//' -e 's/:/\//g')
    COMPLETE_URL="https://github.com/${BASE_URL}/blame/${BRANCH_NAME}/${FILE_PATH}#L${LINE_NUMBER}"
else
    echo "Remote repository is not supported. Only GitLab and GitHub URLs are supported."
    exit 1
fi

# Open in the default web browser
xdg-open "$COMPLETE_URL" || open "$COMPLETE_URL"

has to be run like this (to get the current line and filename): "b" = ":pipe-to wezterm cli split-pane -- ~/dotfiles/scripts/open-gitweb.sh"

https://github.com/helix-editor/helix/assets/72463901/baec72ef-824f-4e51-b8ad-0bee697b21fe