Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show refs in log in Gstatus #1713

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Conversation

Gelio
Copy link

@Gelio Gelio commented Mar 24, 2021

This is my attempt to close #1700. I have followed your advice and modified the functions you mentioned. Writing in VimScript was a new experience for me and I appreciate the fact that the change was relatively simple.

The PR adds displaying refs (the output of %d from git log's format=pretty) next to commit summaries in Gstatus.

It uses basic syntax highlighting for all refs.

Examples

image
image

autoload/fugitive.vim Outdated Show resolved Hide resolved
autoload/fugitive.vim Outdated Show resolved Hide resolved
@tpope
Copy link
Owner

tpope commented Mar 24, 2021

I think we should probably match git log --oneline, with the decorations up front in parentheses. I think starting a commit message with a parenthetical is suitably weird that we can ignore it. A problem with using « and » is that Vim still supports ASCII and simple 8 bit encodings, and well even default to it in some cases.

One thing I don't like is that (HEAD -> master, origin/master, origin/HEAD) is extremely common and distractingly wide.

tpope added a commit that referenced this pull request Mar 24, 2021
@@ -1701,14 +1701,14 @@ function! s:ReplaceCmd(cmd) abort
endfunction

function! s:QueryLog(refspec) abort
let lines = s:LinesError(['log', '-n', '256', '--pretty=format:%h%x09%s', a:refspec, '--'])[0]
let lines = s:LinesError(['log', '-n', '256', '--pretty=format:%h%x09%s%x09%D', a:refspec, '--'])[0]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use %d here as it's older. Parentheses can be stripped, or used wholesale in the format change I proposed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I've used the parenthesized refs directly, without stripping them only to reapply them later

@Gelio Gelio force-pushed the show-refs-in-status branch 2 times, most recently from c9f5633 to 1c8dc4d Compare March 24, 2021 19:00
@Gelio
Copy link
Author

Gelio commented Mar 24, 2021

I think we should probably match git log --oneline, with the decorations up front in parentheses.

Right, I've done that in the latest version.

One thing I don't like is that (HEAD -> master, origin/master, origin/HEAD) is extremely common and distractingly wide.

The only thing that comes to my mind is to only show 2-3 refs, and add ... if there are more, so it would be (HEAD -> master, origin/master, ...). Not sure if that's better, though

syntax/fugitive.vim Outdated Show resolved Hide resolved
@tpope
Copy link
Owner

tpope commented Mar 24, 2021

Poking around in some histories I occasionally see messages starting with (Hopefully) fix or (trivial). I don't have a solution, but I would be inclined to explore using syntax concealing to throw an extra character or two in there to disambiguate.

One thing I don't like is that (HEAD -> master, origin/master, origin/HEAD) is extremely common and distractingly wide.

The only thing that comes to my mind is to only show 2-3 refs, and add ... if there are more, so it would be (HEAD -> master, origin/master, ...). Not sure if that's better, though

I'm inclined to explore solutions of the form "if we're in the Unpulled from origin/master section, we don't need to show origin/master on the first commit". Also I think HEAD and origin/HEAD are pretty low value.

@Gelio
Copy link
Author

Gelio commented Mar 24, 2021

I am experimenting with concealing. So far I have managed to add a \x1f at the beginning of the refs parentheses to detect false positives, and it looks to be working:

image

Disregard the fact that the parentheses themselves are not shown. I will add them back in the final version.

The thing I am worried about is that because I have added the concealed text, when using h or l to move horizontally in the line, those characters are still there and it takes an additional step to go over them, and they are not shown. Is this expected? Am I missing some core function? I've set conceallevel=3 and concealcursor=nc

Also, if you've got a better idea for a character to disambiguate the refs parentheses (I've used \x1f), let me know

I'm inclined to explore solutions of the form "if we're in the Unpulled from origin/master section, we don't need to show origin/master on the first commit". Also I think HEAD and origin/HEAD are pretty low value.

I suppose I can pass a list of refs to ignore when s:QueryLog is called

@Gelio
Copy link
Author

Gelio commented Mar 24, 2021

FYI, the latest solution has concealing and does not highlight subjects that begin with parentheses

image

@tpope
Copy link
Owner

tpope commented Mar 24, 2021

The thing I am worried about is that because I have added the concealed text, when using h or l to move horizontally in the line, those characters are still there and it takes an additional step to go over them, and they are not shown. Is this expected? Am I missing some core function? I've set conceallevel=3 and concealcursor=nc

That's the correct behavior, and it's the biggest of the "tradeoffs" I alluded to. Another is that if you copy the line and paste it to another buffer, you'll see the concealed characters.

Also, if you've got a better idea for a character to disambiguate the refs parentheses (I've used \t), let me know

One idea is to prepend "() " to any commit message that starts with ( and lacks decorations, and then conceal only empty parentheses. Then the cursor weirdness would be limited to weird commit messages instead of every decorated line.

I'm inclined to explore solutions of the form "if we're in the Unpulled from origin/master section, we don't need to show origin/master on the first commit". Also I think HEAD and origin/HEAD are pretty low value.

I suppose I can pass a list of refs to ignore when s:QueryLog is called

Ignoring the parameter a:refspec is probably a good start. Whatever crude hacks you come up with for this are fine. Let me reiterate that the bottleneck probably won't be implementation, it's the design. Aim to get it good enough for you to use, and use it a while, and report back with your thoughts.

And just to make sure expectations are clear: I won't be merging until after the next stable release at the very earliest, and there are no guarantees I won't bail entirely.

@Gelio
Copy link
Author

Gelio commented Mar 24, 2021

One idea is to prepend "() " to any commit message that starts with ( and lacks decorations, and then conceal only empty parentheses. Then the cursor weirdness would be limited to weird commit messages instead of every decorated line.

Good idea, I'll investigate it tomorrow

Ignoring the parameter a:refspec is probably a good start. Whatever crude hacks you come up with for this are fine.

I've added a separate parameter to avoid hacks with splitting the a:refspec by ... I've also added hiding HEAD. origin/HEAD can be hidden if we have a list of all remotes, but I'm not sure that's worth the time investment at this phase

Aim to get it good enough for you to use, and use it a while, and report back with your thoughts.

And just to make sure expectations are clear: I won't be merging until after the next stable release at the very earliest, and there are no guarantees I won't bail entirely.

Sure thing, thanks for all the guidance and open communication

@tpope
Copy link
Owner

tpope commented Mar 25, 2021

I've added a separate parameter to avoid hacks with splitting the a:refspec by ... I've also added hiding HEAD. origin/HEAD can be hidden if we have a list of all remotes, but I'm not sure that's worth the time investment at this phase

Sounds like a job for --decorate-refs-exclude= or maybe --decorate=full, but you're probably right about the time investment.

@Gelio
Copy link
Author

Gelio commented Mar 25, 2021

One idea is to prepend "() " to any commit message that starts with ( and lacks decorations, and then conceal only empty parentheses. Then the cursor weirdness would be limited to weird commit messages instead of every decorated line.

That was a great tip, I've just implemented that:

image
image

I've pushed that as a separate commit. If you'd like to merge the PR any time in the future, let me know if you'd prefer them squashed.

Sounds like a job for --decorate-refs-exclude= or maybe --decorate=full

Thanks for the pointers again, I'll see what I can do.


Overall, I'd like to thank you for the support so far. I feel I have learned a ton with this PR 🙂

@Gelio
Copy link
Author

Gelio commented Mar 25, 2021

Sounds like a job for --decorate-refs-exclude= or maybe --decorate=full

Thanks for the pointers again, I'll see what I can do.

After a few minutes of testing, looks like --decorate-refs-exclude is essentially what I have implemented as part of this PR, but it requires adding additional stars (or prefixing the remote refs with refs/remotes) to work:

git log --decorate --decorate-refs-exclude='*origin/master' --all
git log --decorate --decorate-refs-exclude='refs/remotes/origin/master' --all

I did not come up with a useful case for --decorate=full


I have also experimented a bit with syntax highlighting only the refs, and not the commas in the refs list, but failed again. It either did not highlight anything at all or highlighted the whole line. I guess I'll leave it be for now

@tpope
Copy link
Owner

tpope commented Mar 25, 2021

After a few minutes of testing, looks like --decorate-refs-exclude is essentially what I have implemented as part of this PR, but it requires adding additional stars (or prefixing the remote refs with refs/remotes) to work:

git log --decorate --decorate-refs-exclude='*origin/master' --all
git log --decorate --decorate-refs-exclude='refs/remotes/origin/master' --all

I think we wanna exclude master in the unpushed section and origin/master in the unpulled section, since those are always gonna be the top line. That is, we always wanna exclude the first half of a..b. The caller of s:QueryLog() is in a position to pass in the refs/.. part. head is always refs/heads/, while pull is usually refs/remotes, unless fetch_remote is ., in which case it's also refs/heads/, and same for push. The conditionals that define fetch_remote and push_remote are probably a good place to add fetch_ref and push_ref.

I have also experimented a bit with syntax highlighting only the refs, and not the commas in the refs list, but failed again. It either did not highlight anything at all or highlighted the whole line. I guess I'll leave it be for now

The fix is another level of contains. Don't highlight fugitiveRefs, create a fugitiveRef that's contained in it and highlight that. This part isn't very important right now.

@Gelio
Copy link
Author

Gelio commented Mar 25, 2021

I think we wanna exclude master in the unpushed section and origin/master in the unpulled section, since those are always gonna be the top line. That is, we always wanna exclude the first half of a..b. The caller of s:QueryLog() is in a position to pass in the refs/.. part. head is always refs/heads/, while pull is usually refs/remotes, unless fetch_remote is ., in which case it's also refs/heads/, and same for push. The conditionals that define fetch_remote and push_remote are probably a good place to add fetch_ref and push_ref.

Thanks for a detailed answer. The rules make sense, I'll try to incorporate it sometime soon

The fix is another level of contains. Don't highlight fugitiveRefs, create a fugitiveRef that's contained in it and highlight that. This part isn't very important right now.

I was trying to implement exactly this earlier today, but I think I overcomplicated it. I've managed to do it starting fresh. Thanks!

image

Display refs (the output of %d from git log's format=pretty) next
to commit summaries in Gstatus.

Use basic syntax highlighting for all refs.
Use a special marker and concealing to avoid false-positives when commit
subjects begin with parentheses.

Obvious refs (e.g. "HEAD", "origin/master" when showing unpulled changes
from "origin/master") are hidden.
Subject lines that begin with an open parenthesis and have no other refs
attached have their first parenthesised text syntax highlighted.

Use concealed artificial parentheses in such cases.
Stop highlighting comma separators and arrows in the list of refs shown
in Gstatus.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature request] Display branch names in Gstatus
2 participants