NAME

cdif - word context diff

VERSION

Version 4.49

SYNOPSIS

cdif [option] file1 file2

cdif [option] [diff-data]

Options:

    -c, -Cn         context diff
    -u, -Un         unified diff
    -i              ignore case
    -b              ignore space change
    -w              ignore whitespace
    -t              expand tabs

    --rcs           use rcsdiff
    -r rev          RCS revision to compare
    -q              passed through to rcsdiff

    --diff=command      specify diff command
    --subdiff=command   specify backend diff command
    --stat              show statistical information
    --colormap=s        specify color map
    --sdif              sdif friendly option
    --[no]color         color or not            (default true)
    --[no]256           ANSI 256 color mode     (default true)
    --[no]cc            color command line      (default true)
    --[no]mc            color diff mark         (default true)
    --[no]tc            color normal text       (default true)
    --[no]uc            color unknown text      (default true)
    --[no]old           print old text          (default true)
    --[no]new           print new text          (default true)
    --[no]mrg           print merged text       (default true)
    --[no]command       print diff command line (default true)
    --[no]unknown       print unknown line      (default true)
    --[no]mark          print mark or not       (default true)
    --[no]prefix        read git --graph output (default true)
    --unit=s            word/letter/char/mecab  (default word)
    --[no]mecab         use mecab tokenizer     (default false)
    --prefix-pattern    prefix pattern
    --visible char=?    set visible attributes
    --[no]lenience      suppress unexpected input warning (default true)
    --limit length=#    skip word comparison for long lines (default 1000)
    --lxl               compare input data line-by-line
    --style=diff        print --lxl output in diff style
    --version           show version

DESCRIPTION

cdif is a post-processor of the Unix diff command. It highlights deleted, changed and added words based on word context (–unit=word by default). To compare text character by character, use option –unit=char. Option –unit=mecab calls the external mecab command as a tokenizer for Japanese text.

Given a single file, or no file at all, cdif reads that file or standard input as the output of a diff command. Besides normal diff, context diff and unified (combined) diff, the git(1)-compatible conflict marker format is accepted as input.

Lines that do not look like diff output are passed through untouched.

STARTUP and MODULE

cdif uses the Perl Getopt::EX module, and reads the ~/.cdifrc file at startup if there is one. You can define your own options and defaults there. The next line enables the –mecab option and adds a crossed-out effect to deleted words.

option default --mecab --cm DELETE=+X

Modules under App::cdif can be loaded by the -M option without the prefix. The next command loads the App::cdif::colors module.

$ cdif -Mcolors

Options can be defined in a module file as well. See Getopt::EX::Module for details.

COLOR

Each line is displayed in a different color. Every text segment has its own label, and the color for each label can be set by the –colormap option. See Getopt::EX::Colormap for details.

The standard module -Mcolors is loaded by default, and defines several color maps for light and dark screens. To use CMY colors on a dark screen, place the next line in your ~/.cdifrc.

option default --dark-cmy

Option –autocolor is defined in the default module to call the Getopt::EX::termcolor module. It sets the –light or –dark option according to the brightness of the terminal screen. You can set your preferred colors in ~/.cdifrc like this:

option --light --cmy
option --dark  --dark-cmy

The detection is done by the Getopt::EX::termcolor module, and works with macOS Terminal.app and iTerm.app, and other XTerm compatible terminals. That module reads the environment variable TERM_BGCOLOR as the terminal background color. For example, use 000 or #000000 for black and 555 or #FFFFFF for white.

Option –autocolor is set by default; to disable it, override it with something that does nothing.

option --autocolor --nop

EXIT STATUS

cdif always exits with status zero unless an error occurs.

OPTIONS

  • -[cCuUibwtT]

    Almost the same as for the diff command.

  • –rcs, -rrev, -q

    Use rcsdiff instead of the normal diff command, and take the remaining argument as an RCS file name. Option -rrev names the revision to compare against, and -q is passed to rcsdiff as it is. –rcs is not required when either of the other two is given.

      cdif -r1.3 file
    
  • unit=[word,letter,char,mecab,0,``]
  • by=[word,letter,char,mecab,0,``]

    Specify the unit of comparison. The default is word, comparing each line word by word. Specify char to compare character by character. Unit letter is almost the same as word, but does not count an underscore as part of a word.

    When mecab is given as the unit, the mecab command is called as a tokenizer for non-ASCII text; ASCII text is still compared word by word. The external mecab command has to be installed.

    Given an empty string, as in --unit=, or 0, cdif does not compare the text at all. Colorization is still applied.

  • –mecab

    Shortcut for –unit=mecab.

  • –diff=command

    Specify the diff command to use.

  • –subdiff=command

    Specify the backend diff command used to find word differences. It accepts normal and unified diff format.

    To use the git diff command, do not forget the -U0 option.

      --subdiff="git diff -U0 --no-index --histogram"
    
  • [no-]color

    Use ANSI color escape sequences in the output.

  • –colormap=colormap, –cm=colormap

    Basic colormap format is :

      FIELD=COLOR
    

    where the FIELD is one from these :

      COMMAND  Command line
      OMARK    Old mark
      NMARK    New mark
      UTEXT    Same text
      OTEXT    Old text
      NTEXT    New text
      OCHANGE  Old change part
      NCHANGE  New change part
      APPEND   Appended part
      DELETE   Deleted part
    

    and additional Common and Merged FIELDs for git-diff combined format.

      CMARK    Common mark
      CTEXT    Common text
      MMARK    Merged mark
      MTEXT    Merged text
    

    You can give several fields the same color by joining them with = :

      FIELD1=FIELD2=...=COLOR
    

    A wildcard can also be used for the field name :

      *CHANGE=BDw
    

    Multiple fields can be specified by repeating the option :

      --cm FIELD1=COLOR1 --cm FIELD2=COLOR2 ...
    

    or combined with comma (,) :

      --cm FIELD1=COLOR1,FIELD2=COLOR2, ...
    

    Color specification is a combination of single uppercase character representing 8 colors :

      R  Red
      G  Green
      B  Blue
      C  Cyan
      M  Magenta
      Y  Yellow
      K  Black
      W  White
    

    and alternative (usually brighter) colors in lowercase :

      r, g, b, c, m, y, k, w
    

    or RGB values and 24 grey levels on an ANSI 256-color or full-color terminal :

      (255,255,255)      : 24bit decimal RGB colors
      #000000 .. #FFFFFF : 24bit hex RGB colors
      #000    .. #FFF    : 12bit hex RGB 4096 colors
      000 .. 555         : 6x6x6 RGB 216 colors
      L00 .. L25         : Black (L00), 24 grey levels, White (L25)
    

    or color names enclosed in angle brackets :

      <red> <blue> <green> <cyan> <magenta> <yellow>
      <aliceblue> <honeydew> <hotpink> <moccasin>
      <medium_aqua_marine>
    

    with other special effects :

      D  Double-struck (boldface)
      I  Italic
      U  Underline
      S  Stand-out (reverse video)
    

    The above is a simplified summary; see Getopt::EX::Colormap for the complete specification.

    Defaults are :

      COMMAND => "555/222E"
      OMARK   => "CS"
      NMARK   => "MS"
      UTEXT   => ""
      OTEXT   => "C"
      NTEXT   => "M"
      OCHANGE => "K/445"
      NCHANGE => "K/445"
      DELETE  => "K/544"
      APPEND  => "K/544"
    
      CMARK   => "GS"
      MMARK   => "YS"
      CTEXT   => "G"
      MTEXT   => "Y"
    

    This is equivalent to :

      cdif --cm 'COMMAND=555/222E,OMARK=CS,NMARK=MS' \
           --cm 'UTEXT=,OTEXT=C,NTEXT=M,*CHANGE=BD/445,DELETE=APPEND=RD/544' \
           --cm 'CMARK=GS,MMARK=YS,CTEXT=G,MTEXT=Y'
    
  • –colormap=&func
  • –colormap=sub{...}

    You can also give the name of a Perl subroutine, or its definition, to be called for the matched words. The target word is passed in the variable $_, and the return value of the subroutine is displayed.

    The next option produces wdiff-like output.

      --cm '*'= \
      --cm DELETE=OCHANGE='sub{"[-$_-]"}' \
      --cm APPEND=NCHANGE='sub{"{+$_+}"}'
    

    See “FUNCTION SPEC” in Getopt::EX::Colormap for details.

  • [no-]cc, [no-]commandcolor
  • [no-]mc, [no-]markcolor
  • [no-]tc, [no-]textcolor
  • [no-]uc, [no-]unknowncolor

    Enable or disable color for the corresponding field.

  • –sdif

    Turn off the options that get in the way when the output is fed to sdif: –commandcolor, –markcolor, –textcolor and –unknowncolor.

  • [no-]old, [no-]new, [no-]mrg

    Print, or do not print, the old/new/merged text in diff output.

  • [no-]command

    Print, or do not print, the command lines preceding diff output.

  • [no-]unknown

    Print, or do not print, lines that do not look like diff output.

  • [no-]mark

    Print, or do not print, the marks at the head of diff output lines. For now this option is effective only for unified diff.

    The next example produces output identical to new, apart from the visual effects.

      cdif -U100 --no-mark --no-old --no-command --no-unknown old new
    

    These options are provided for the watchdiff(1) command.

  • [no-]prefix

    Understand a prefix in front of the diff output, such as the one git –graph produces. True by default.

  • –prefix-pattern=pattern

    Specify the prefix pattern as a regular expression. Default pattern is:

      (?:\| )*(?:  )*
    

    This pattern matches git graph style and whitespace indented diff output.

  • –visible charname=[0,1]

    Set the visible attribute for the given characters. A visible character is converted to the corresponding Unicode symbol. Visible by default: nul, bel, bs, vt, np, cr, esc, del, and all non-breaking/special spaces. Invisible by default: ht, nl, sp.

      NAME    CODE    Unicode NAME                      DEFAULT
      ------  ------  --------------------------------  -------
      nul     \000    SYMBOL FOR NULL                   YES
      soh     \001    SYMBOL FOR SOH                    YES
      bel     \007    SYMBOL FOR BELL                   YES
      bs      \010    SYMBOL FOR BACKSPACE              YES
      ht      \011    SYMBOL FOR HORIZONTAL TABULATION  NO
      nl      \012    SYMBOL FOR NEWLINE                NO
      vt      \013    SYMBOL FOR VERTICAL TABULATION    YES
      np      \014    SYMBOL FOR FORM FEED              YES
      cr      \015    SYMBOL FOR CARRIAGE RETURN        YES
      esc     \033    SYMBOL FOR ESCAPE                 YES
      sp      \040    SYMBOL FOR SPACE                  NO
      del     \177    SYMBOL FOR DELETE                 YES
      nbsp    \240    OPEN BOX (No-Break Space)         YES
      nnbsp   U+202F  OPEN BOX (Narrow No-Break Space)  YES
      ensp    U+2002  OPEN BOX (En Space)               YES
      emsp    U+2003  OPEN BOX (Em Space)               YES
      thinsp  U+2009  OPEN BOX (Thin Space)             YES
      hairsp  U+200A  OPEN BOX (Hair Space)             YES
      zwsp    U+200B  OPEN BOX (Zero Width Space)       YES
      idesp   U+3000  OPEN BOX (Ideographic Space)      YES
    

    Since there are no dedicated Unicode symbols for nbsp and other special space characters, OPEN BOX is used instead.

    Several characters can be given at once: join them with a comma (,), as in --visible ht=1,sp=1, or with an equal sign (=), as in --visible ht=sp=1. Character names accept a wildcard, as in --visible '*=1'.

    The sdif command also supports the –visible option, with better visibility for horizontal tabs.

  • –stat

    Print statistical information at the end of the output, showing the total number of appended, deleted and changed words as cdif counts them. Refilling text inserts and deletes a great many newlines, so the figures are followed by a second set that leaves those newlines out.

  • [no-]lenience

    Suppress the warning message for unexpected input from the diff command. True by default.

  • –limit key=value

    Set resource limits. Available keys are:

    • length=#

      Skip word comparison for lines longer than # characters. Default is 1000. Extremely long lines, such as those found in SVG data, can make word-level diff processing very slow with no useful result. When this limit is exceeded, the section is still displayed with basic colorization but without fine-grained word highlighting. Set to 0 to disable this limit.

  • –linebyline, –lxl
  • –style=style

    Compare the input line by line. The input is taken as a sequence of line pairs, and the two lines of each pair are compared against each other.

    Suppose you have a document with old and new text on lines beginning with OLD: and NEW: labels.

      OLD: this is old text
      NEW: and this is updated document
    

    Only that old/new part can be compared, using greple’s -Mtee module as follows.

      greple -Mtee cdif --lxl -- --cm=N -GE '^OLD: (.*\n)^NEW: (.*\n)'
    

    The -Mtee module sends the matched parts to a filter command and replaces them with its output. See App::Greple::tee for details.

    You can use the teip(1) command as well.

      teip -g '^(OLD|NEW):' -- cdif --lxl
    

    Given the --style=diff option, the two strings are printed in diff format, which can be fed to the sdif command as follows.

      cdif --lxl --style=diff ... | sdif --no-cdif
    

    diff is currently the only valid value for --style, and it affects nothing but the behavior of the --lxl option.

MODULE OPTIONS

default

default      --autocolor
--nop        do nothing

-Mcolors

The following options are available by default. Run perldoc -m App::cdif::colors to see the actual settings.

--light
--green
--cmy
--mono

--dark
--dark-green
--dark-cmy
--dark-mono

GIT

See “GIT” in App::sdif for how to use the sdif family under GIT.

ENVIRONMENT

  • CDIFOPTS

    Environment variable CDIFOPTS is used to set default options.

  • LESS
  • LESSANSIENDCHARS

    Since cdif emits the ANSI Erase Line terminal sequence, it helps to let the less command know about it.

      LESS=-cR
      LESSANSIENDCHARS=mK
    

AUTHOR

Kazumasa Utashiro

LICENSE

Copyright 1992-2026 Kazumasa Utashiro

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO

App::sdif, https://github.com/kaz-utashiro/sdif-tools

sdif(1), watchdiff(1)

Getopt::EX::Colormap

App::Greple::tee

https://taku910.github.io/mecab/

BUGS

cdif is not very fast by nature, because it runs the normal diff command as a back end to compare words.