In tmux hg output contains some control chars - mercurial

I am trying to switch from screen to tmux. When I run hg status, I get damaged output like this:
It doesn't happen to git, it doesn't happen with screen. Any advice will be very appreciated. Thanks.

Hmm, it seems like hg is doing something very strange. My guess is it has got completely the wrong idea about how to show colour, but there should be no reason for it to do anything different in tmux than screen.
What does echo $TERM show inside tmux before you run hg? What does it show outside tmux?
Have you created a .hgrc or similar configuration file? What's in it?
Is it the same if you do \hg --pager never --color always status?
What does \hg --pager never --color always status|od show?

Based on an answer from Nicholas Marriott and comment from Rudi: the problem seems to be that $TERM is set to screen in tmux (whilst std. gnome-terminal has it set to xterm-256color and screen to screen.xterm-256color).
Therefore the solution (at least the one working for me) is to set terminal in the ~/.tmux.conf as follows:
set -g default-terminal "screen.xterm-256color"
Note: using hg --pager never also works, however that is not an acceptable solution.

Related

Reliably check if there are dirty or untracked files in working set

I'm trying to write some scripts for doing some simple housekeeping tasks in mercurial and one of the things I frequently need to do is check if the working set is "empty" (depending on context, that could mean untracked files or modified tracked files).
The hg status command exits with exit status 0 unless there was an internal error, in which case it exits with exit status 255.
If a few of my scripts, I'm doing something silly like capturing the output of the hg status command and checking whether it's empty or not.
In other cases I'm checking the exit status of hg id -i | grep -qvF + to check whether there are dirty tracked files.
Both of these seem a little brittle. Are there dedicated subcommands for "querying" the repository to see if there are "untracked files" or "dirty tracked files" or "removed files" or various other interesting things in the working set?
hg status is the command to check for modifications of the working directory with respect to the checked-out revision - thus you are doing the right thing.
You can get away with exclusively using hg status. Using the --mard (or --modified --added --removed --deleted) flags will yield empty if the tracked files didn't change. And using -u or --unknown will show files which are neither ignored nor tracked - and empty output should always indicate no changes to tracked files nor any non-ignored files (but there might be new files which match one of the ignore patterns).
The output format of these commands (at least in the English original, thus LC_ALL=C hg status) is treated by mercurial as API, thus you should be able to rely on it.
Depending on your actual use-case you might want to look at the mercurial command server - but for a script which runs occasionally it might be quite over the top.
test -z "$(hg status -mard --template x)" && echo clean || echo dirty
Seems to work

How to get the working directory of the command from an hg hook?

I'm working on a commit hook for Mercurial and running into problems with relative paths.
Say my hook wants to look at the contents of the files being committed and warn if any contain the phrase "xyzzy". However, the user has decided to call commit from a subfolder and pass in the name of the file as a pattern...
C:\clone\subdir> hg commit file.txt -m 'test'
My hook is called with C:\clone as the working directory, but HG_PATS contains simply file.txt with no subdir\ prefix. How can I get the working directory of the hg command itself? I can't find a way to do this in docs.
The only way I can figure out how to get it is look up the process tree to find the first hg.exe and get its working directory. But that's not exactly portable to other OS's. (And I know I could write an extension, but would really like to avoid that.)
If you use the pretxncommit hook then you are given $HG_NODE which is the commit id, but the commit hasn't been finalized at that point so you can still return 1 to cancel it.
Then you could use
hg log -r $HG_NODE --template '{files}'
to get the list of files in the commit, and it gives you the full path relative to the repo root.
It's not exactly what you were after but it might get you close enough to let you do the content examination you want.
Thanks for the answers and comments, but after some more research I determined there's no clean way to do what I want from an external hook. I did implement the CWD hack I mentioned in my question. Not a ton of code, but quite nasty, and on Windows it requires undocumented access to external process CWD via tlist.exe. It works, but..yuck.
The right way to do this appears to be to write an in-process hook (example library at hghooklib). Usual versioning caveats apply as with writing any extension, though I think for our hooks the interface to hg is simple enough that we'll be ok.
(In my question I mentioned I didn't want to write an extension, but I was thinking of a full extension like hgeol. A hook-only extension with a single function entry point feels more constrained and simple, which is what I want at this point.)

Hg pager extension doesn't work for 'blame'

I am using Merucrial with the pager extension, and I am trying to configure out to use the pager for blame, but it's not working.
I have in my .hgrc file:
[extensions]
pager =
[pager]
pager = less -FRX
attend = diff, status, help, log, blame
The other commands - diff, status, help, and log are correctly routed through the pager, but blame is not. Any ideas as to why?
blame is an alias for annotate. If you specify annotate rather than blame in the .hgrc, it works fine.
I guess the pager.attend attribute does not accept aliases, it needs the name of the original command.
I filed a bug for this.

How to search Mercurial for a particular change?

I added a function to file on an a branch I can't remember. I want to port that function to a different branch. How can I search Mercurial to find it?
I know the name of the function and the file I put it in.
I'm using TortoiseHg, and it's got a search bar at the top. I'm not sure which Mecurial command it's using internally..maybe hg log?
But so far I've got
user('me') and file('glob:class/database.php') and ????('myfunctionname')
Not sure what filter I can use to search diff contents.
Also, I don't really know how those filename patterns work, I seem to have to search from the base; can't I do an exact match on filename, excluding directories?
I believe the grep command is what you're looking for:
hg grep 'myfunctionname' -r "user('me') and file('class/database.php')"
You can match a specific file in the file revset query by specifying its full path. Use **file.extension to find any file.extension anywhere in the repository. See the Mercurial docs on file patterns for more information. They are a little unclear on how to match any file with a specific name anywhere in the repo, however, so you'll probably have to do experiment a little.

tmux status bar configuration

How is the status bar is customized? I noticed in this youtube video (at 3:05 - image below), the status bar looks very different than the default one that I see after installing tmux on my Mac OS X.
In particular, I like how the middle of the status bar shows the current program and the left side shows the name of only the current session. In comparison, my setup shows the name of all of the sessions and doesn't show the current application (for the currently focused pane).
If anyone could show me a sample configuration that could do this or show me where I can find the customization rules, that would be great! Thanks!
Update: In case anyone is curious, I was able to customize a status bar that is similar to the one seen in the video (minor tweaks) and you can find my config file on my github if you'd like to see an example.
The man page has very detailed descriptions of all of the various options (the status bar is highly configurable). Your best bet is to read through man tmux and pay particular attention to those options that begin with status-.
So, for example, status-bg red would set the background colour of the bar.
The three components of the bar, the left and right sections and the window-list in the middle, can all be configured to suit your preferences. status-left and status-right, in addition to having their own variables (like #S to list the session name) can also call custom scripts to display, for example, system information like load average or battery time.
The option to rename windows or panes based on what is currently running in them is automatic-rename. You can set, or disable it globally with:
setw -g automatic-rename [on | off]
The most straightforward way to become comfortable with building your own status bar is to start with a vanilla one and then add changes incrementally, reloading the config as you go.1
You might also want to have a look around on github or bitbucket for other people's conf files to provide some inspiration. You can see mine here2.
1 You can automate this by including this line in your .tmux.conf:
bind R source-file ~/.tmux.conf \; display-message "Config reloaded..."
You can then test your new functionality with Ctrlb,Shiftr. tmux will print a helpful error message—including a line number of the offending snippet—if you misconfigure an option.
2 Note: I call a different status bar depending on whether I am in X or the console - I find this quite useful.
I used tmux-powerline to fully pimp my tmux status bar. I was googling for a way to change to background of the status bar when your typing a tmux command. When I stumbled on this post I thought I should mention it for completeness.
Update: This project is in a maintenance mode and no future functionality is likely to be added. tmux-powerline, with all other powerline projects, is replaced by the new unifying powerline. However this project is still functional and can serve as a lightweight alternative for non-python users.
I have been playing about with tmux today, trying to customised a little here and there, managed to get battery info displaying on the status right with a ruby script.
Copy the ruby script from http://natedickson.com/blog/2013/04/30/battery-status-in-tmux/ and save it as:
battinfo.rb in ~/bin
To make it executable make sure to run:
chmod +x ~/bin/battinfo.rb
edit your ~/.tmux.config and include this line
set -g status-right "#[fg=colour155]#(pmset -g batt | ~/bin/battinfo.rb) | #[fg=colour45]%d %b %R"
Do C-b, :show which will show you all your current settings. /green, nnn will find you which properties have been set to green, the default. Do C-b, :set window-status-bg cyan and the bottom bar should change colour.
List available colours for tmux
You can tell more easily by the titles and the colours as they're actually set in your live session :show, than by searching through the man page, in my opinion. It is a very well-written man page when you have the time though.
If you don't like one of your changes and you can't remember how it was originally set, you can open do a new tmux session. To change settings for good edit ~/.tmux.conf with a line like set window-status-bg -g cyan. Here's mine: https://gist.github.com/9083598