This module implements formatting logic for colored text diffs - both multiline and inline.
All formatting is generated in colored text format and can be later formatted in both plaintext and formatted manners using colortext.toString
Types
DiffFormatConf = object maxUnchanged*: int ## Max number of the unchanged lines after which ## they will be no longer show. Can be used to compact large diffs with ## small mismatched parts. maxUnchangedWords*: int ## Max number of the unchanged words in a ## single line. Can be used to compact long lines with small mismatches showLines*: bool ## Show line numbers in the generated diffs lineSplit*: proc (str: string): seq[string] ## Split line ## into chunks for formatting sideBySide*: bool ## Show line diff with side-by-side (aka github ## 'split' view) or on top of each other (aka 'unified') explainInvisible*: bool ## If diff contains invisible characters - ## trailing whitespaces, control characters, escapes and ANSI SGR ## formatting - show them directly. inlineDiffSeparator*: ColText ## Text to separate words in the inline split formatChunk*: proc (text: string; mode, secondary: SeqEditKind; inline: bool): ColText ## Format ## mismatched text. `mode` is the mismatch kind, `secondary` is used ## for `sekChanged` to annotated which part was deleted and which part ## was added. groupLine*: bool ## For multiline edit operations - group consecutive ## Edit operations into single chunks. groupInline*: bool ## For inline edit operations - group consecutive ## edit operations into single chunks. explainChar*: proc (ch: char): string ## Convert invisible character ## (whitespace or control) to human-readable representation -
- Diff formatting configuration Source Edit
Procs
proc colorDollar[T](arg: T): ColText
- Source Edit
func diffFormatter(useUnicode: bool = true): DiffFormatConf {....raises: [], tags: [].}
-
Default implementation of the diff formatter
- split lines by whitespace
- no hidden lines or workds
- deleted: red, inserted: green, changed: yellow
- explain invisible differences with unicode
proc formatDiffed(shifted: ShiftedDiff; oldSeq, newSeq: openArray[string]; conf: DiffFormatConf = diffFormatter()): ColText {. ...raises: [Exception], tags: [RootEffect].}
-
Format shifted multiline diff
oldSeq, newSeq - sequence of lines (no newlines in strings assumed) that will be formatted.
Source Edit proc formatDiffed(text1, text2: string; conf: DiffFormatConf = diffFormatter()): ColText {. ...raises: [Exception, KeyError], tags: [RootEffect].}
- Format diff of two text blocks via newline split and default formatDiffed implementation Source Edit
proc formatDiffed[T](oldSeq, newSeq: openArray[T]; conf: DiffFormatConf; eqCmp: proc ( a, b: T): bool = (proc (a, b: T): bool = a == b); strConv: proc (a: T): string = (proc (a: T): string = $a)): ColText
- Source Edit
proc formatDiffed[T](ops: seq[SeqEdit]; oldSeq, newSeq: seq[T]; conf: DiffFormatConf): tuple[oldLine, newLine: ColText]
- Generate colored formatting for the levenshtein edit operation using format configuration. Return old formatted line and new formatted line. Source Edit
proc formatInlineDiff(src, target: seq[string]; diffed: seq[SeqEdit]; conf: DiffFormatConf): ColText {....raises: [Exception], tags: [RootEffect].}
- Format inline edit operations for src and target sequences using list of sequence edit operations diffed, formatting the result using conf formatter. Consecutive edit operations are grouped together if conf.groupInline is set to true Source Edit
proc formatInlineDiff(src, target: string; conf: DiffFormatConf): ColText {. ...raises: [Exception], tags: [RootEffect].}
- Generate inline string editing annotation for the source and target string. Use conf for message mismatch configuration. Source Edit
proc formatLineDiff(old, new: string; conf: DiffFormatConf): tuple[ oldLine, newLine: ColText] {....raises: [Exception], tags: [RootEffect].}
- Format single line diff into old/new line edits. Optionally explain all differences using options from conf Source Edit
func hasInvisible(text: seq[string]): bool {....raises: [], tags: [].}
- Do any of strings in text have signficant invisible characters. Source Edit
func hasInvisible(text: string; startSet: set[char] = Invis + {' '}): bool {. ...raises: [], tags: [].}
- Does string have significant invisible characters? Source Edit
func splitKeepSeparator(str: string; sep: set[char] = {' '}): seq[string] {. ...raises: [], tags: [].}
- Default implementaion of the line splitter - split on sep characters but don't discard them - they will be present in the resulting output. Source Edit
func unified(conf: DiffFormatConf): bool {....raises: [], tags: [].}
- Check if config is used to build unified diff Source Edit