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

Add Mercurial to Git Prompt #2431

Closed
Siecje opened this issue Sep 26, 2015 · 31 comments
Closed

Add Mercurial to Git Prompt #2431

Siecje opened this issue Sep 26, 2015 · 31 comments
Assignees
Labels
enhancement release notes Something that is or should be mentioned in the release notes
Milestone

Comments

@Siecje
Copy link
Contributor

Siecje commented Sep 26, 2015

As of #1837 the Terlar's fish prompt supports Mercurial.

However it doesn't support Mercurial bookmarks.

The other issue is that you don't know that the Terlar prompt supports Mercurial.

Mercurial support should be added to Classic + Git and the named changed to Classic + Git + Mercurial

Here is my personal modification

function get_hg_info
    if test -d .hg
        set branch (hg branch)
        set bookmark (hg book | grep \* | cut -d' ' -f3)
        echo " ($branch|$bookmark)"
    end
end
@faho
Copy link
Member

faho commented Sep 26, 2015

There's really two parts to this:

  • Add bookmark support to __fish_hg_prompt
  • Add hg support to classic + git prompt

I've done the former, though somewhat differently from your solution.

if test -d .hg

This is probably insufficient as I don't believe hg adds a .hg directory in every subdirectory in a repository. It's easy to call hg root though, which exits non-zero when there's no root to be printed.

set bookmark (hg book | grep * | cut -d' ' -f3)

This is much easier with just hg bookmark -q. I also added a test if $bookmark is empty so we don't print a separator all the time. This test is necessary because hg bookmark doesn't exit non-zero when there's no bookmark.

Now, the latter I need to think about - for one I'd call it "Classic + VCS", because "Classic + Git + Mercurial" is a bit unwieldy and doesn't scale if someone implements e.g. fossil support (we do have someone who cares about completions for that). I also don't like adding every vcs again and again and again in every prompt, so I'd probably add a wrapper function "__fish_vcs_prompt" or so, that checks all vcsen we have functions for and then executes either the first or all matching functions (dunno yet).

@Siecje
Copy link
Contributor Author

Siecje commented Sep 26, 2015

Did you test hg bookmark -q with multiple bookmarks?

I think Classic + Git + Mercurial is explicit.
Another solution would be to have a description that is shown on the fish_config webpage.

@faho
Copy link
Member

faho commented Sep 26, 2015

Did you test hg bookmark -q with multiple bookmarks?

Urgh... it prints all of them, with no indication which one is current.

I think Classic + Git + Mercurial is explicit.

That's objectively true. However, my points still stand - it's rather long and would presumably get even longer if more VCSen get a prompt function ("Classic + Git + Mercurial + Svn + Fossil + Darcs"). It also nicely fits with making one function that calls all vcs prompt functions - then the prompt wouldn't gain mercurial support, it would receive support for every vcs we add, automatically.

@faho
Copy link
Member

faho commented Sep 26, 2015

Did you test hg bookmark -q with multiple bookmarks?

Urgh... it prints all of them, with no indication which one is current.

Fixed, thanks.

Edit:

Another solution would be to have a description that is shown on the fish_config webpage.

This might be a good idea regardless, though I'm not sure what the text would be. The only thing that comes to my mind is stuff like "A tasteful prompt for the discerning mind. Short pwd with a hint of username, with a smooth ">" finish".... and that's just ridiculous.

@faho faho self-assigned this Sep 26, 2015
@Siecje
Copy link
Contributor Author

Siecje commented Sep 26, 2015

The other option to get the current bookmark is in the file

cat (hg root)/.hg/bookmarks.current

But if no bookmark is selected then the file will not exist.

@faho
Copy link
Member

faho commented Sep 27, 2015

I've looked into this a bit and after changing __fish_git_prompt to __fish_vcs_prompt (that only calls the git and hg prompts), it feels a bit slower. I've profiled a bit and found that the hg function is slower than the hg by a factor of 3 when there's no repository and a factor of 6 when there is one (and that's after removing the redundant hg root check). Unfortunately it's completely dominated by hg calls, so the only way I can see to speed it up would be to read stuff in (hg root)/.hg/ by hand - anyone know where it stores branches and gets the status info from?

But since in the worst case (a directory that's both a git and an hg repository) on my system (i7 with data stored on spinning rust) this all adds up to about 0.3 seconds (best case of no repo being 0.1 seconds), it's probably still worth it for git and hg.

For other VCSs we might however want to add fish_vcs_prompt (i.e. naming the function without the dunderscore) as a customization point so all the fossil or bzr users out there can just add it and have every prompt use it.

Anyone have an opinion on this?

@Siecje
Copy link
Contributor Author

Siecje commented Sep 27, 2015

Branch can be found in

cat (hg root)/.hg/branch

What do you want to get from hg status?

@faho
Copy link
Member

faho commented Sep 27, 2015

cat (hg root)/.hg/branch

Ah, I thought it'd be something like that. What I didn't think is that file doesn't exist unless there's more than one branch. Is the default branch name always, well, "default"?

What do you want to get from hg status?

If any files have been added/deleted/modified/copied/untracked/unmerged - basically the first two characters of hg status (another format isn't a problem).

@Siecje
Copy link
Contributor Author

Siecje commented Sep 27, 2015

There will always be at least one branch called default. So the file will always be there.

I'm not sure if the information from hg status is available in a file.
What do you use it for?

@faho
Copy link
Member

faho commented Sep 27, 2015

There will always be at least one branch called default. So the file will always be there.

No - at least not with my mercurial 3.5.1. If I just do mkdir flounder; cd flounder; hg init, hg branch will display "default" and .hg/branch will not exist.

What do you use it for?

For display - for every one of those things a symbol will be shown, and if at least one of added, modified, copied or deleted is true the branch name will be shown in a special color.

@Siecje
Copy link
Contributor Author

Siecje commented Sep 27, 2015

You're right .hg/branch does not exist, even after making a commit.
I don't use branches (I use bookmarks) so I assume the file was created when I pulled from remote.
But if doesn't exist then it should be default or maybe hidden because not everyone uses named branches in Mercurial.

a symbol will be shown, and if at least one of added, modified, copied or deleted is true the branch name will be shown in a special color.

Cool! I don't see special symbols or different colours in the prompt when I modify a git repo, is this a new feature?

@faho
Copy link
Member

faho commented Sep 27, 2015

Cool! I don't see special symbols or different colours in the prompt when I modify a git repo, is this a new feature?

It's a feature of the hg prompt (though I do believe the git prompt has similar stuff, it might be locked behind some weird variables - the code for that is.... a bit complicated).

(To be clear, when I talk about "$vcs prompt" in this context, I mean the _fish$vcs_prompt function that is supposed to be used by a prompt)

@Siecje
Copy link
Contributor Author

Siecje commented Sep 27, 2015

The __terlar_git_prompt does have similar stuff.

I found a blog post describing how to avoid hg calls.
http://patrickoscity.de/blog/building-a-fast-mercurial-prompt/

It has a pattern for finding the hg root without using hg root

So the only hg call would be hg status for the advanced features.

@faho
Copy link
Member

faho commented Sep 27, 2015

It has a pattern for finding the hg root without using hg root

Huh... I tried writing something like that and it looked earily similar - I even used the "find_hg_root" name. The only difference was I used pushd, popd and actually did the cd. It turned out slower than the original. With the dirname $dir stuff (though I used string replace instead) it cuts the time in half.

So the only hg call would be hg status for the advanced features.

Yeah, I think I can live with that.

@faho
Copy link
Member

faho commented Sep 28, 2015

@Siecje: Please check faho@3ae99e3. I've tested for a bit and it seems to work (and rather quickly at that), but since I don't really use hg I'm bound to miss something.

@Siecje
Copy link
Contributor Author

Siecje commented Sep 28, 2015

I didn't install the latest version of fish. I don't know how. I tried setting it as my prompt though and I don't have string.

So string replace ... fails.

I don't like how the branch and bookmark are separated by a / it makes it seem like a path.

Maybe something like /path (branch|bookmark)>

@faho
Copy link
Member

faho commented Sep 28, 2015

I didn't install the latest version of fish. I don't know how.

https://github.com/fish-shell/fish-shell#building https://github.com/fish-shell/fish-shell/wiki/Nightly-builds is probably better.

I don't like how the branch and bookmark are separated by a / it makes it seem like a path.

I picked the "/" because I was too lazy to mask the "|" while I was fiddling with other solutions. I'll make the switch. (Edit: see faho@1a1eb14)

Maybe something like /path (branch|bookmark)>

/path as in hg root? Or as in $PWD? The latter this has nothing to do with - that's the prompt functions job, this is just a function to print some hg-related stuff suitable for inclusion in a prompt.

@faho
Copy link
Member

faho commented Sep 30, 2015

@Siecje:

Okay, I've now profiled and optimized this as far as it's gonna go - the remaining 80% of the time (about 8ms on my system) is spent doing one hg status call, but replacing that requires some binary manipulation which shells aren't good at - so we'd have to fork a bunch of processes, and we can't count on anything nice being available.

There's a sort -u call still in there, but it doesn't harm the situation for small repos and for large ones (got any testcases?) I'm willing to bet it improves the situation - in particular the -u part, since we need to iterate over it multiple times. Plus, all this is over 8ms - it's fun, though.

I've changed the display slightly - it's now |($branch) if no bookmark is current, and |($branch|$bookmark) if there is.

The issue I have is that, excluding the pipe symbol, this is like the git prompt if no bookmark is present, but I like the separation the parens give. Any suggestions? Put hg: in front, and git: for the git prompt?

@Siecje
Copy link
Contributor Author

Siecje commented Oct 1, 2015

I'm not seeing the round brackets.

I don't mind that it is the same as the git prompt (remove the | before the branch/bookmark)

($branch) or ($branch|$bookmark)

@faho
Copy link
Member

faho commented Oct 1, 2015

I'm not seeing the round brackets.

Sorry, I forgot to push. Should be there now.

I don't mind that it is the same as the git prompt

Well, the idea was that I want to call both of them in a fish_vcs_prompt function which is then the only function used in our sample prompts. In that case, it's not just nice to know if there is a "branch" in some vcs, but also for which vcs this is valid (and it could also be multiple - try git init; hg init).

Of course we could also just check that in fish_vcs_prompt and then print a "hg: " and "git: " prefix for the respective functions if they produce output or exit non-zero (which would need a redefinition of when they exit non-zero - currently they exit zero if there's no repo).

@derekstavis
Copy link

I'm in the process of writing a Oh My Fish plugin for abstracting VCS. You may want to give a look here: https://github.com/derekstavis/plugin-vcs

Different than other approaches, it works by attaching to PWD changes and autoloading the adequate VCS implementation. It also employ a memoisation technique, which has it's pros (speed) and cons (mkdir test; cd test; git init . don't update the prompt).

I have shamelessly incorporated some lines from your hg optimizations, @faho :trollface:

@faho
Copy link
Member

faho commented Oct 13, 2015

I have shamelessly incorporated some lines from your hg optimizations, @faho :trollface:

No problem, go ahead.

Different than other approaches, it works by attaching to PWD changes and autoloading the adequate VCS implementation.

I took a look and it's a bit more complicated than what I have in mind (which is just a __fish_vcs_prompt function that executes all known vcs-prompt functions). It also assumes there's only one vcs per directory, which isn't strictly speaking true - I made a hybrid hg and git repo for testing.

I haven't pushed anything because I haven't quite figured out what the output should look like - presumably all vcs-prompts should be a bit consistent (though they should implement the features the vcs provides), but that also means it's possible that you get a vcs-prompt and then don't know which vcs it's for. My idea was to print "git: " before a git-prompt, though that would make the prompt a bit longer.

@derekstavis
Copy link

I took a look and it's a bit more complicated than what I have in mind

Yeah, it looks pretty complicated at a glance, and I still need to decide out the best approach (events, caching, etc).

... (which is just a __fish_vcs_prompt function that executes all known vcs-prompt functions). It also assumes there's only one vcs per directory, which isn't strictly speaking true - I made a hybrid hg and git repo for testing.

I don't like the idea of handling multiple VCS in the same directory, although yes, it can happen and I don't know how to solve the user preferences. In the implementation I opted by testing top-down, in a way that git > hg > svn (which is true in real world).

My idea was to print "git: " before a git-prompt, though that would make the prompt a bit longer.

You can also define, by "API", that the result of __fish_vcs_prompt is a strictly-ordered list, in which if the VCS exist, it will be there, else it's a empty string "".

@faho
Copy link
Member

faho commented Oct 13, 2015

You can also define, by "API", that the result of __fish_vcs_prompt is a strictly-ordered list, in which if the VCS exist, it will be there, else it's a empty string "".

That doesn't really apply if I want to drop-in "__fish_vcs_prompt" as a replacement for "__fish_git_prompt" in all sample prompts.

@derekstavis
Copy link

That doesn't really apply if I want to drop-in "__fish_vcs_prompt" as a replacement for "__fish_git_prompt" in all sample prompts.

Ah. I see your point. I'm not familiar with builtin prompts code, but as most refactorings, drop-in replacements which adds features are very hard to do, and, well, if you are refactoring, what's the additional effort of changing some lines around?

@faho
Copy link
Member

faho commented Oct 14, 2015

So, here's what my current solution looks like with the classic + git prompt (the only change being __fish_git_prompt to __fish_vcs_prompt) and my actual right prompt:

screenshot_20151014_144021

@Siecje: Does that look okay to you?

@Siecje
Copy link
Contributor Author

Siecje commented Oct 14, 2015

@faho My vote would be to not show git: and hg: before the VCS info.

If someone does use both in the same folder then they can either learn which one is shown first or create a custom prompt.

@faho
Copy link
Member

faho commented Oct 14, 2015

If someone does use both in the same folder then they can either learn which one is shown first or create a custom prompt.

It's not just about having a directory with both (which yes, is rather silly). What happens when you cd into a directory and you can't remember which VCS it is?

Or maybe that actually doesn't happen.

@derekstavis
Copy link

What happens when you cd into a directory and you can't remember which VCS it is?

I dream with powerline patched fonts with VCS glyphs 👓

@Siecje
Copy link
Contributor Author

Siecje commented Oct 15, 2015

What happens when you cd into a directory and you can't remember which VCS it is?

You try one command and then the other.

@faho faho added the release notes Something that is or should be mentioned in the release notes label Dec 16, 2015
@faho
Copy link
Member

faho commented Dec 16, 2015

This has been fixed by merging #2592. Thanks and sorry for the delay!

@faho faho closed this as completed Dec 16, 2015
@faho faho added this to the 2.3.0 milestone Mar 6, 2016
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement release notes Something that is or should be mentioned in the release notes
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants