Mar 11, 2016

Showing mercurial current branch in ConEmu prompt

As a long time git user, I had a relatively hard time when I started using mercurial CVS; one of the things that I really missed (this one goes to the list of annoyances) was the lack of support for showing the current branch in the console. In the following screenshot you can see that GIT console does show me the current branch (in the example, ofx)


Considering that I have a terrible memory and usually have at least 5 ~ 6 consoles open at any given time, it is not hard to conclude that, from time to time, I simply forget which is the current branch in each console. 

Since mercurial do not provide any help (other than keeping issuing hg branch command all the time ;), it happened, not once, but many times, that I found myself working in one console under the assumption that I was operating on branch Foo when in fact I was working in a completely different one.

Some days ago I had the idea of using mercurial hooks to detect when I am changing branches and setting the console prompt accordingly, but that did not worked out very well. To be fair, mercurial hooks worked as expected; the problem was that my hook was run by hg.exe process which itself is spawned from the console when one type, for instance, hg up -r Foo to change to branch Foo and this process (hg.exe) would need to change the PROMPT of its parent console, which is not allowed (at least AFAIK).

My next step was check whether ConEmu (it is not a secret that I'm in love with ConEmu ;))  had some support to achieve my goal and bingo! ConEmu support some extended ANSI codes, more specifically $E ] 9 ; 7 ; ”cmd“$E\  which allows one to execute the command specified in the string (cmd) and use its output as part of the PROMP string. 

With that information, I just created the following batch file:

@echo off
IF NOT EXIST .hg GOTO NOT_A_MERCURIAL_REPO
hg branch
GOTO END

:NOT_A_MERCURIAL_REPO
@echo !repo
:END

and set the PROMP to:

SET PROMPT=$E[32m$E]9;8;"USERNAME"$E\@$E]9;8;"COMPUTERNAME"$E\$S$E[1D$S$E[92m$P$E[90m$E[38;5;14m $Q$G $E]9;7;"path_to_above.bat"$E\$E[90m$G$E[m$S

and voalá!



In the picture above you can see that when the current directory is not a mercurial repository the string "!repo" is shown (I'll probably change that later and in this case will show nothing); also, as soon as I initialized a local repository the PROMPT changed to indicate that I was in the default branch. 

Now, the only missing bit was to configure ConEmu to automatically set that prompt when it creates a new console, which can be done by specifying a custom batch file (in my case I created a file named ConEmuInit.cmd):




Basically I copied the original file (that can be found in "%ConEmuBaseDir%\CmdInit.cmd") and change it accordingly.

Now I am happier ;) The changes of making mistakes are small now :)

Edit:
If you are using CONEMU  Build 160609 or newer you'll need to include you bath in a white list in order to CONEMU to run it:



EDIT (06/Feb/2018)
The path set above is case sensitive! (I've spent 3 hours hunting ghosts) i.e, if you use D:\utils\branch.bat in the PROMPT variable, adding d:\utils\branch.bat will not work.
 
Happy coding

Leia este post em Português!

No comments: