20

less itself isn't capable of doing syntax highlighting, according to this thread.

However, git diff nicely shows colored output in less, its default pager. When I redirect the output of git diff into a file, no color escape sequences are visible.

Does git diff know where it's being sent, and formats the output accordingly? How would one do that?


I just noticed that git colors the diff output (e.g. git diff), however, it doesn't know how to syntax highlighting in general. e.g.

git show 415fec6:log.tex

doesn't enable any TeX-like syntax.


Reading the git sources, I found the following hints

in diff.h:

int use_color;

I was previously referring to syntax highlighting, but that was not correct. What I mean is output coloring, see e.g.

example color output

Sebastian
  • 8,677
  • 4
  • 39
  • 49
  • 1
    Do you have any real syntax highlighting, or just the red and green color for removed and added lines? – Paŭlo Ebermann Sep 05 '14 at 19:43
  • 2
    BTW: to get git colouring into less: `git diff --color=always | less -r` (or `less -R` for ANSI). BTW: for other commands that don't paginate by default (`git diff` does) you can switch it on: `git -p some_git_command` – hyperpallium Aug 16 '19 at 06:30

3 Answers3

18

Git uses isatty() to check whether stdout is a tty: this is used to see if a pager must be used (pager.c) as well as colors (color.c).

ysdx
  • 1,818
  • 15
  • 14
14

Running:

git diff --color=always > output

shows the color escapes.

Damn I found it in git's color.c file:

static int check_auto_color(void)                                           
{                                                                           
  if (color_stdout_is_tty < 0)                                              
    color_stdout_is_tty = isatty(1);                                        
  if (color_stdout_is_tty || (pager_in_use() && pager_use_color)) {         
    char *term = getenv("TERM");                                            
    if (term && strcmp(term, "dumb"))                                       
      return 1;                                                             
  }                                                                         
  return 0;                                                                 
}  
Sebastian
  • 8,677
  • 4
  • 39
  • 49
3

less can support colour with -r --raw-control-chars and -R --RAW-CONTROL-CHARS

You could use Pythons pygmentize to do the highlighting and pipe it in.

To combine it all configure a less filter as described on superuser

Matt
  • 8,841
  • 1
  • 26
  • 32
  • the link is indeed interesting, thanks. Do you know if `git` is actually using pygmentize? Because it is not listed as a dependency. – Sebastian Sep 05 '14 at 12:39
  • btw, when I run `git diff` the child `less` process is not appended by any option (neither `-R` nor `-r`). However, I don't know if git calls it in a special way and thus the args are not visible in `htop`. – Sebastian Sep 05 '14 at 12:46
  • `git` outputs the colour escape code it's self. It's also written in `c` so adding Python would be a huge dependency. It might be able to control `less` via the environment – Matt Sep 05 '14 at 12:56
  • 1
    maybe via the `LESS` env var? – Matt Sep 05 '14 at 13:02
  • 3
    Yes, LESS=FRX is added to the environment (see [pager.c](https://github.com/git/git/blob/398dd4bd039680ba98497fbedffa415a43583c16/pager.c)). – ysdx Sep 05 '14 at 23:02