Git Product home page Git Product logo

diffr's Introduction

diffr

Reviewing changes involves reading diffs. Sometimes, a line-oriented presentation of changes is not precise enough, especially when changes involve long lines or very similar consecutive lines.

This program processes such diffs, and outputs them (in the console) with additional diff information on top of the unified diff format, using text attributes.

It works hunk by hunk, recomputing the diff on a word-by-word basis.

The current implementation uses Myers' longest common subsequence algorithm.

crates.io crates.io Build Status

Demo Demo Demo

Installation

Arch Linux

Install from the AUR:

git clone https://aur.archlinux.org/diffr.git
cd diffr
makepkg -si

Homebrew

brew install diffr

From source

You will need the Rust compiler installed.

To install the latest published version:

cargo install diffr

Alternatively, you can build the development version:

git clone https://github.com/mookid/diffr.git
cd diffr
cargo install --path .

How to use it?

diffr tries to be a well behaved Unix program: it reads its input from stdin and writes to stdout.

One-off usage

git show HEAD | diffr

Integration with git

Add the following section to your .gitconfig file:

[core]
    pager = diffr | less -R
[interactive]
    diffFilter = diffr

Alternatively, you can run from the command line:

git config --global core.pager 'diffr | less -R'
git config --global interactive.difffilter diffr

Color customization

Use the --colors flag.

You can customize the display of diffing and common segments of added and removed lines.

For example,

diffr --colors refine-removed:background:200,0,0:foreground:white:bold

tweaks the red used for uniquely removed text;

The configuration used in the first screenshot is

diffr --colors refine-added:none:background:0x33,0x99,0x33:bold --colors added:none:background:0x33,0x55,0x33 --colors refine-removed:none:background:0x99,0x33,0x33:bold --colors removed:none:background:0x55,0x33,0x33

Display line numbers

The --line-numbers displays the line numbers of the hunk.

Related projects

This is improvement on the diff-highlight script distributed with git.

git itself provides both --word-diff and --color-words options to several commands.

diffr's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

diffr's Issues

Publish release?

diffr looks like a handy tool. I'd love to create and AUR package for it. It's best to build these against published releases instead of straight from git master though. I would be great if you could tag a release.

Highlighting of title of diffed file

Hey!
I see lines diff --git ..., index ..., --- src/main.rs, +++src/main.rs are highlighted in blue in your screenshot, and I very need it, but there are only added|refine-added|removed|refine-removed facenames in your docs.
Could you tell how did you highlight this section?
image

diffr highlights the whole lies instead of the last character of each line.

diffr highlights the whole lies instead of the last character of each line:

--- /dev/fd/63	2020-04-17 11:50:36.529229290 +0200
+++ /dev/fd/62	2020-04-17 11:50:36.529229290 +0200
@@ -1,27 +1,27 @@
-ATCACGG
-CGATGTG
-TTAGGCG
-TGACCAG
-ACAGTGG
-GCCAATG
-CAGATCG
-ACTTGAG
-GATCAGG
-TAGCTTG
-GGCTACG
-CTTGTAG
-AGTCAAG
+ATCACGA
+CGATGTA
+TTAGGCA
+TGACCAA
+ACAGTGA
+GCCAATA
+CAGATCA
+ACTTGAA
+GATCAGA
+TAGCTTA
+GGCTACA
+CTTGTAA
+AGTCAAC
 AGTTCCG
 ATGTCAG
-CCGTCCG
-GTAGAGG
-GTCCGCG
-GTGAAAG
-GTGGCCG
+CCGTCCC
+
+GTCCGCA
+GTGAAAC
+GTGGCCT
 GTTTCGG
-CGTACGG
-GAGTGGG
-GGTAGCG
-ACTGATG
-ATGAGCG
-ATTCCTG
+CGTACGT
+GAGTGGA
+
+ACTGATA
+
+ATTCCTT

[RFE] Use white as default color for letters

First of all, thanks for the better diff-highlight utility!

I was comparing diffr with the standard diff-highlight as provided by git, and although diffr gives better results, I noted its output somehow was less comfortable to look at. See:

git's diff-highlight:

Screenshot_20190929_212204

diffr:

Screenshot_20190929_212516

I figured, the reason is that "black" color more likely to blend with the dark "green" and "red" than white color. The diff-highlight for that reason makes foreground letters white.

I think, it would make sense for diffr to also use by default a color that blends less with the background, for example "white".

Native Debian package

@mookid I am working on a proposal to include diffr to the Debian packaging system.
The latest release happened on Mar 20, 2020 where diffr has a dependency on diffr-lib, an obstacle to the packaging as the dependency deserves a separate package.
Would you mind releasing version 1.5.0 containing #73, as well as other recent patches? I'll take care of packaging diffr and sending a proposal to Debian maintainers.

line wrapping

On a diff with very long lines, diffr helps but reading unified diff is still hard.

Implement a flag that wraps long lines before highlighting differences. This is almost as running diff -u file1 file2 | fold | diffr instead of diff -u file1 file2 | diffr, except that the fold command is aware of leading "+/-" characters.

see https://blog.robertelder.org/terminal-diff-tool/ that tries to do something clever.

[Debian package] Compilation warnings

Non-blocking issue for now but might affect integration in the future.

warning: unnecessary trailing semicolon
  --> src/tests_cli.rs:91:6
   |
91 |     };
   |      ^ help: remove this semicolon
   |
   = note: `#[warn(redundant_semicolons)]` on by default

warning: panic message is not a string literal
  --> src/tests_cli.rs:25:17
   |
25 | /                 format!(
26 | |                     "{}: expected empty, got\n\n{}",
27 | |                     quote_or_empty(prefix),
28 | |                     quote_or_empty(actual)
29 | |                 )
   | |_________________^
   |
   = note: `#[warn(non_fmt_panics)]` on by default
   = note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021
   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
   = note: the assert!() macro supports formatting, so there's no need for the format!() macro here
help: remove the `format!(..)` macro call
   |
25 ~
26 |                     "{}: expected empty, got\n\n{}",
27 |                     quote_or_empty(prefix),
28 |                     quote_or_empty(actual)
29 ~
   |

warning: panic message is not a string literal
  --> src/tests_cli.rs:33:17
   |
33 | /                 format!(
34 | |                     "{}: expected at least\n\n{}\n\ngot\n\n{}",
35 | |                     prefix,
36 | |                     quote_or_empty(exp),
37 | |                     quote_or_empty(actual)
38 | |                 )
   | |_________________^
   |
   = note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021
   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
   = note: the assert!() macro supports formatting, so there's no need for the format!() macro here
help: remove the `format!(..)` macro call
   |
33 ~
34 |                     "{}: expected at least\n\n{}\n\ngot\n\n{}",
 ...
37 |                     quote_or_empty(actual)
38 ~
   |

warning: panic message is not a string literal
  --> src/tests_cli.rs:42:17
   |
42 | /                 format!(
43 | |                     "{}: expected\n\n{}\n\ngot\n\n{}",
44 | |                     prefix,
45 | |                     quote_or_empty(exp),
46 | |                     quote_or_empty(actual)
47 | |                 )
   | |_________________^
   |
   = note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021
   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
   = note: the assert!() macro supports formatting, so there's no need for the format!() macro here
help: remove the `format!(..)` macro call
   |
42 ~
43 |                     "{}: expected\n\n{}\n\ngot\n\n{}",
 ...
46 |                     quote_or_empty(actual)
47 ~
   |

warning: panic message is not a string literal
  --> src/tests_cli.rs:94:9
   |
94 | /         format!(
95 | |             "unexpected status: expected {} got {}",
96 | |             string_of_status(descr.is_success),
97 | |             string_of_status(output.status.success()),
98 | |         )
   | |_________^
   |
   = note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021
   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
   = note: the assert!() macro supports formatting, so there's no need for the format!() macro here
help: remove the `format!(..)` macro call
   |
94 ~
95 |             "unexpected status: expected {} got {}",
96 |             string_of_status(descr.is_success),
97 |             string_of_status(output.status.success()),
98 ~
   |

warning: `diffr` (bin "diffr" test) generated 5 warnings
    Finished test [unoptimized + debuginfo] target(s) in 2.12s

Support --color-moved

Currently, diffs obtained from git with the --color-moved flag parsed and re-highlighted completely, and the code move special highlighting is lost.

The color-moved information should be preserved.

Wrong-looking edge cases

Hey!

First of all, you made a great tool, thank you.
I've brought you some examples where diffr works unexpected.

Screenshot 2019-10-08 at 20 38 41

diffr-weirdness-left.txt
diffr-weirdness-right.txt

So:

  • it shouldn't highlight if there are only added or only removed changes
  • , :reward and :reward , is bouncing
  • campaign_path(object) should be ignored altogether, and there is a redundant ) highlighted

And sorry, I don't speak rust and can't help improving it

Documentation: wrong syntax description

diffr --help prints this:

            color_spec = face-name + ':' + attributes
            attributes = <empty>
                       | attribute + ':' + attributes

This means that a color_spec always ends with a colon, but I'm sure this wasn't intended. Maybe reword like this:

            color_spec = face-name + ':' + attributes
            attributes = attribute
                       | attribute + ':' + attributes

This is more restrictive than the original grammar because it requires at least one attribute. I don't know if that matches the implementation. But it would be easy to fix by allowing color_spec to expand to either a bare face-name or to face-name + ':' + attributes.

Don't highlight leading spaces

For performance reason, consecutive whitespaces are considered one word. The downside of this design decision is that when lines differ on the indentation, leading spaces are highlighted, which gives little interesting information:

image

One possible improvement would be either

  • never highlight leading spaces
  • process again the leading word of each line and highlight only the added spaces (harder, as keeping track of matching lines is required).

Question about highlighting trailing WS

Is there a a way to highlight trailing ws in git logs using diffr?
I have a few commits that failed on jenkins due to the fact that I've missed those since ws is indistinguishable from normal changes and doesn't stand out except that lines are a tad longer...

This is what i'm using today

[core]
	editor = '/usr/bin/nvim'
	pager = diffr --colors refine-added:none:background:0x33,0x99,0x33:bold --colors added:none:background:0x33,0x55,0x33 --colors refine-removed:none:background:0x99,0x33,0x33:bold --colors removed:none:background:0x55,0x33,0x33 | less -R
[interactive]
	difffilter = diffr --colors refine-added:none:background:0x33,0x99,0x33:bold --colors added:none:background:0x33,0x55,0x33 --colors refine-removed:none:background:0x99,0x33,0x33:bold --colors removed:none:background:0x55,0x33,0x33

highlights unchanged parts.

diffr seems to highlight unchanged parts. At least when there are a different number of leading spaces and dashes following those spaces.

$ diff -u <(printf '    -01234;\n    --abc;\n    --def;\n') <(printf '      -01234;\n      --abc;\n      --def;\n') | diffr
--- /dev/fd/63	2019-07-22 10:03:08.009841265 +0200
+++ /dev/fd/62	2019-07-22 10:03:08.013841298 +0200
@@ -1,3 +1,3 @@
-    -01234;
-    --abc;
-    --def;
+      -01234;
+      --abc;
+      --def;

The second dash in --def is colored in read, which shouldn't be the case.

$ diff -u <(printf '    -01234;\n    --abc;\n    --def;\n    --jkl;\n    --poi;\n') <(printf '      -01234;\n      --abc;\n      --def;\n      --jkl;\n      --poi;\n') | diffr
--- /dev/fd/63	2019-07-22 10:10:29.065613277 +0200
+++ /dev/fd/62	2019-07-22 10:10:29.065613277 +0200
@@ -1,5 +1,5 @@
-    -01234;
-    --abc;
-    --def;
-    --jkl;
-    --poi;
+      -01234;
+      --abc;
+      --def;
+      --jkl;
+      --poi;

In this case the following dashes are highligthed:

  • -01234 : first dash
  • --abc: second dash
  • --poi: second dash

In both cases it should only highlight the leading spaces as that is the only part that changed.

With underscores the highlighting works fine:

$ diff -u <(printf '    _01234;\n    __abc;\n    __def;\n    __jkl;\n    __poi;\n') <(printf '      _01234;\n      __abc;\n      __def;\n      __jkl;\n      __poi;\n') | diffr
--- /dev/fd/63	2019-07-22 10:25:01.873156289 +0200
+++ /dev/fd/62	2019-07-22 10:25:01.877156323 +0200
@@ -1,5 +1,5 @@
-    _01234;
-    __abc;
-    __def;
-    __jkl;
-    __poi;
+      _01234;
+      __abc;
+      __def;
+      __jkl;
+      __poi;

Feature Request: line numbers

Not sure if this is out of scope for this project but I've always wanted line numbers for diffs instead of the @@ -xxx,y +xxx,y @@ syntax. Would be especially useful when there are large chunks.

Something like

diff --git a/src/index.js b/src/index.js
index d46a912..d34f309 100644
--- a/src/index.js
+++ b/src/index.js
@@ -13,7 +13,8 @@ const Button = ({ value, color, events }) => {
  13: };
  14: const textStyle = {
  15:     flex: 0,
- 16:     fontFamily: 'sans-serif',
+ 16:     fontFamily: 'serif',
+ 17:     color: white,
  18: };
  19: return (
  20:     <div {...events} style={containerStyle}>

Improve highlighting of commented code

On the following example:

@
-fn func(a,b,c) {
-  x = g(a,b)
-  y = if x {
-          h(b,c)
-      } else {
-          0
-      }
-  return x + y
-}
+// fn func(a,b,c) {
+//   x = g(a,b)
+//   y = if x {
+//           h(b,c)
+//       } else {
+//           0
+//       }
+//   return x + y
+// }

diffr displays the diff like that:
image

which is correct, but the highlighting of the whitespace-only tokens is distracting.

[Debian package] Unit tests failing

Run inside schroot, Debian unstable.

warning: `diffr` (bin "diffr" test) generated 5 warnings
    Finished test [unoptimized + debuginfo] target(s) in 2.12s
     Running `/<<PKGBUILDDIR>>/target/x86_64-unknown-linux-gnu/debug/deps/diffr-0adc4b1ff5ef71b1`

running 38 tests
test diffr_lib::tests_lib::compress_path_test ... ok
test diffr_lib::tests_lib::diff_sequences_test_1 ... ok
test diffr_lib::tests_lib::diff_sequences_test_2 ... ok
test diffr_lib::tests_lib::diff_sequences_test_3 ... ok
test diffr_lib::tests_lib::diff_sequences_test_4 ... ok
test diffr_lib::tests_lib::diff_sequences_test_7 ... ok
test diffr_lib::tests_lib::diff_sequences_test_6 ... ok
test diffr_lib::tests_lib::find_splitting_point_test ... ok
test diffr_lib::tests_lib::diff_sequences_test_5 ... ok
test diffr_lib::tests_lib::issue15_2 ... ok
test diffr_lib::tests_lib::diff_sequences_test_8 ... ok
test diffr_lib::tests_lib::range_equality_test ... ok
test diffr_lib::tests_lib::split_lines_test ... ok
test diffr_lib::tests_lib::issue27 ... ok
test diffr_lib::tests_lib::split_lines_append_test ... ok
test diffr_lib::tests_lib::test_get_lcs ... ok
test diffr_lib::tests_lib::issue15 ... ok
test diffr_lib::tests_lib::tokenize_test ... ok
test tests_app::first_after_escape_test ... ok
test tests_app::parse_line_number_test ... ok
test diffr_lib::tests_lib::test_optimize_partition ... ok
test tests_app::skip_all_escape_code_test ... ok
test tests_app::skip_token_test ... ok
test tests_app::test_width ... ok
test diffr_lib::tests_lib::to_usize_checked_negative_test - should panic ... ok
test tests_cli::color_invalid_attribute_name ... FAILED
test tests_cli::color_invalid_color_not_done ... FAILED
test tests_cli::color_invalid_color_value_ansi ... FAILED
test tests_cli::color_invalid_color_value_name ... FAILED
test tests_cli::color_invalid_color_value_rgb ... FAILED
test tests_cli::color_ok ... FAILED
test tests_cli::color_invalid_face_name ... FAILED
test tests_cli::color_only_face_name ... FAILED
test tests_cli::color_ok_multiple ... FAILED
test tests_cli::debug_flag ... FAILED
test tests_cli::line_numbers_style ... FAILED
test tests_cli::test_bad_argument ... FAILED
test diffr_lib::tests_lib::test_lcs_random ... ok

failures:

---- tests_cli::color_invalid_attribute_name stdout ----
thread 'tests_cli::color_invalid_attribute_name' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/tests_cli.rs:83:29
stack backtrace:
   0: rust_begin_unwind
             at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
   3: core::result::Result<T,E>::expect
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1055:23
   4: diffr::tests_cli::test_cli
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:83:17
   5: diffr::tests_cli::color_invalid_attribute_name
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:140:5
   6: diffr::tests_cli::color_invalid_attribute_name::{{closure}}
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:139:1
   7: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
   8: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- tests_cli::color_invalid_color_not_done stdout ----
thread 'tests_cli::color_invalid_color_not_done' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/tests_cli.rs:83:29
stack backtrace:
   0: rust_begin_unwind
             at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
   3: core::result::Result<T,E>::expect
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1055:23
   4: diffr::tests_cli::test_cli
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:83:17
   5: diffr::tests_cli::color_invalid_color_not_done
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:180:5
   6: diffr::tests_cli::color_invalid_color_not_done::{{closure}}
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:179:1
   7: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
   8: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- tests_cli::color_invalid_color_value_ansi stdout ----
thread 'tests_cli::color_invalid_color_value_ansi' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/tests_cli.rs:83:29
stack backtrace:
   0: rust_begin_unwind
             at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
   3: core::result::Result<T,E>::expect
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1055:23
   4: diffr::tests_cli::test_cli
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:83:17
   5: diffr::tests_cli::color_invalid_color_value_ansi
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:160:5
   6: diffr::tests_cli::color_invalid_color_value_ansi::{{closure}}
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:159:1
   7: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
   8: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- tests_cli::color_invalid_color_value_name stdout ----
thread 'tests_cli::color_invalid_color_value_name' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/tests_cli.rs:83:29
stack backtrace:
   0: rust_begin_unwind
             at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
   3: core::result::Result<T,E>::expect
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1055:23
   4: diffr::tests_cli::test_cli
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:83:17
   5: diffr::tests_cli::color_invalid_color_value_name
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:150:5
   6: diffr::tests_cli::color_invalid_color_value_name::{{closure}}
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:149:1
   7: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
   8: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- tests_cli::color_invalid_color_value_rgb stdout ----
thread 'tests_cli::color_invalid_color_value_rgb' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/tests_cli.rs:83:29
stack backtrace:
   0: rust_begin_unwind
             at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
   3: core::result::Result<T,E>::expect
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1055:23
   4: diffr::tests_cli::test_cli
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:83:17
   5: diffr::tests_cli::color_invalid_color_value_rgb
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:170:5
   6: diffr::tests_cli::color_invalid_color_value_rgb::{{closure}}
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:169:1
   7: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
   8: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- tests_cli::color_ok stdout ----
thread 'tests_cli::color_ok' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/tests_cli.rs:83:29
stack backtrace:
   0: rust_begin_unwind
             at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
   3: core::result::Result<T,E>::expect
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1055:23
   4: diffr::tests_cli::test_cli
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:83:17
   5: diffr::tests_cli::color_ok
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:190:5
   6: diffr::tests_cli::color_ok::{{closure}}
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:189:1
   7: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
   8: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- tests_cli::color_invalid_face_name stdout ----
thread 'tests_cli::color_invalid_face_name' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/tests_cli.rs:83:29
stack backtrace:
   0: rust_begin_unwind
             at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
   3: core::result::Result<T,E>::expect
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1055:23
   4: diffr::tests_cli::test_cli
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:83:17
   5: diffr::tests_cli::color_invalid_face_name
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:120:5
   6: diffr::tests_cli::color_invalid_face_name::{{closure}}
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:119:1
   7: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
   8: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- tests_cli::color_only_face_name stdout ----
thread 'tests_cli::color_only_face_name' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/tests_cli.rs:83:29
stack backtrace:
   0: rust_begin_unwind
             at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
   3: core::result::Result<T,E>::expect
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1055:23
   4: diffr::tests_cli::test_cli
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:83:17
   5: diffr::tests_cli::color_only_face_name
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:130:5
   6: diffr::tests_cli::color_only_face_name::{{closure}}
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:129:1
   7: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
   8: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- tests_cli::color_ok_multiple stdout ----
thread 'tests_cli::color_ok_multiple' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/tests_cli.rs:83:29
stack backtrace:
   0: rust_begin_unwind
             at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
   3: core::result::Result<T,E>::expect
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1055:23
   4: diffr::tests_cli::test_cli
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:83:17
   5: diffr::tests_cli::color_ok_multiple
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:200:5
   6: diffr::tests_cli::color_ok_multiple::{{closure}}
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:199:1
   7: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
   8: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- tests_cli::debug_flag stdout ----
thread 'tests_cli::debug_flag' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/tests_cli.rs:83:29
stack backtrace:
   0: rust_begin_unwind
             at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
   3: core::result::Result<T,E>::expect
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1055:23
   4: diffr::tests_cli::test_cli
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:83:17
   5: diffr::tests_cli::debug_flag
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:110:5
   6: diffr::tests_cli::debug_flag::{{closure}}
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:109:1
   7: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
   8: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- tests_cli::line_numbers_style stdout ----
thread 'tests_cli::line_numbers_style' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/tests_cli.rs:83:29
stack backtrace:
   0: rust_begin_unwind
             at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
   3: core::result::Result<T,E>::expect
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1055:23
   4: diffr::tests_cli::test_cli
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:83:17
   5: diffr::tests_cli::line_numbers_style
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:218:5
   6: diffr::tests_cli::line_numbers_style::{{closure}}
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:214:1
   7: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
   8: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- tests_cli::test_bad_argument stdout ----
thread 'tests_cli::test_bad_argument' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/tests_cli.rs:83:29
stack backtrace:
   0: rust_begin_unwind
             at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
   3: core::result::Result<T,E>::expect
             at /usr/src/rustc-1.63.0/library/core/src/result.rs:1055:23
   4: diffr::tests_cli::test_cli
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:83:17
   5: diffr::tests_cli::test_bad_argument
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:248:5
   6: diffr::tests_cli::test_bad_argument::{{closure}}
             at /usr/share/cargo/registry/diffr-0.1.5/src/tests_cli.rs:247:1
   7: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
   8: core::ops::function::FnOnce::call_once
             at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.


failures:
    tests_cli::color_invalid_attribute_name
    tests_cli::color_invalid_color_not_done
    tests_cli::color_invalid_color_value_ansi
    tests_cli::color_invalid_color_value_name
    tests_cli::color_invalid_color_value_rgb
    tests_cli::color_invalid_face_name
    tests_cli::color_ok
    tests_cli::color_ok_multiple
    tests_cli::color_only_face_name
    tests_cli::debug_flag
    tests_cli::line_numbers_style
    tests_cli::test_bad_argument

test result: FAILED. 26 passed; 12 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s

error: test failed, to rerun pass `--bin diffr`
dh_auto_test: error: /usr/share/cargo/bin/cargo test --all returned exit code 101
make[1]: *** [debian/rules:6: override_dh_auto_test] Error 25
make[1]: Leaving directory '/<<PKGBUILDDIR>>'
make: *** [debian/rules:3: binary] Error 2
dpkg-buildpackage: error: debian/rules binary subprocess returned exit status 2

Suggestion: More Precise Coloring Options

My Use Case

(Since it's a bit hard to describe what I'm looking for without context.)

At a high level, I simply want my eyes to be naturally drawn to the relevant parts of modified lines.

When looking at a diff, I want changed lines to be highlighted green/red as usual.

However, for "modified" lines (i.e. lines which are not added or removed in full) I want to put more emphases on the specific parts of the line that have changed.
Sort of "double-highlighting", first highlighted green/red because the line is added/removed, then highlighted even more because this part of the line is what actually changed.

However, I don't want this "double-highlighting" to apply to new or removed lines, only modified lines.

Currently Targetable --color Faces:

Currently there are two main color pallets which can be customized:

  1. added/removed, which applies to entire lines, and
  2. refine-added/refine-removed, which applies to any added or removed text (within either a modified line or fully added/removed line).

refined-added and refined-removed are currently applied to completely added or completely removed lines.

For my use case above, it's not currently possible to target changed sections within changed lines, without affecting purely added/removed lines.

Proposal

I suggest the following two targetable --color faces:

  • unchanged-added and unchanged-removed - for the parts of modified lines which are not changed, and
  • only-added and only-removed - for lines which are added/removed in full.

With these, it would be possible to separate full-line changes from changes withing lines, and color each individually.

And for purely backwards-compatibility reasons:

  • unchanged-added/unchanged-removed should inherit from added/removed, and
  • only-added/only-removed should inherit from refine-added/refine-removed.

If all options were specified, then added/removed would only apply to the +/- at the start of each line (and probably leading whitespace).

(One more note: I've described everything above as added/removed vs changed lines, but it may be more appropriate to implement this on changed blocks instead.)

Thoughts?

Leading +,- in diffs should receive common segment highlighting per GitHub

Currently, in diffr's output, the leading + and - are highlighted with unique segment highlighting. This is not how GitHub diffs work, where the leading + and - receive common segment highlighting.

Relative to GitHub, diffr's current behavior is visually distracting. The leading + or - would be better off receiving common segment highlighting.

Not encoding-aware, operates on individual bytes

As far as I can tell, it seems like diffr is not aware of encodings in any way and simply operates on and compares individual bytes. (At least I haven’t found any way to specify an encoding.)

This leads to issues with multi-byte encodings such as UTF-8 (not to mention “wide” encodings like UTF-16 or UTF-32) where diffr will split up bytes belonging to a single encoded character when (for example) the byte sequences for a changed character have a common prefix, so that diffr will insert different highlighting markup for these constituent characters.

Here is an example:

1.txt:

θ

2.txt:

α

diff -u 1.txt 2.txt | diffr:

�[0m--- 1.txt  2023-08-04 13:01:35.764424632 -0400�[0m
�[0m+++ 2.txt  2023-08-04 13:01:42.592564739 -0400�[0m
�[0m@@ -1 +1 @@�[0m
�[0m�[31m-�[0m�[0m�[31m��[0m�[0m�[1m�[38;2;255;255;255m�[41m��[0m�[0m�[31m�[0m
�[0m�[32m+�[0m�[0m�[32m��[0m�[0m�[1m�[38;2;255;255;255m�[42m��[0m�[0m�[32m�[0m

or, as displayed by less in my terminal:

Screenshot from 2023-08-04 13-16-05

I really need this crate as a library. :)

In upcoming release cargo-crev will have cargo crev diff command. Underneath it calls diff -r <src> <dst> on two directories. I was thinking ... "I'll start with this, and switch to some library later". And now I see reddit post about diffr. :)

Anyway... Please split this crate in two (or more) parts: one binary and library. This way I can just import it, and not rely on diff binary (plus the better formatting, nice!). If you had some examples / other crates for actually generating diff between directories, that would be awesome too.

Fails to compile with rustc 1.34.2 due to using ".copied"

On an older server running Debian 9 with rustc 1.34.2, pulling the latest git commit and building it fails with the error error[E0658]: use of unstable library feature 'iter_copied' (see issue #57127) due to the change in 9666edc

I was able to patch the source to undo that change, leading to it successfully building. I used the following command:

perl -i -pe 's/\.copied/.cloned/g' diffr-lib/src/lib.rs diffr-lib/src/test.rs src/main.rs

Why was this change made? Is it needed? I don't know rust at all.

Inserted code line messes up the downwards coloring

If I write this Python code:

    print()
    subprocess.call(['timew', 'untag', '@1'] + old_tags + [':yes'])
    subprocess.call(['timew', 'tag', '@1'] + new_tags + [':yes'])

... and then extend it by inserting a new line and modifying the last two lines the following way:

    ids = subprocess.check_output(['timew', 'get', 'dom.tracked.ids'])
    print()
    subprocess.call(['timew', 'untag'] + ids + old_tags + [':yes'])
    subprocess.call(['timew', 'tag'] + ids + new_tags + [':yes'])

Then I get some strange output:
image

The second subprocess.call() line is colored correctly.
But the first subprocess.call() line seems to get excessive coloring.

The latter gets a bit reduced if I reduce arguments in the new inserted line, eg:
image

Now if I reduce it even more, colors seem to start working more or less properly:
image

Is there a way to compare 2 files on windows?

Ideally without requiring additional tools. I tried fc file1 file2 | diffr but it didn't work (I've heard fc is the equivalent of the diff command from linux). I'm on window 7 so I can't ue WSL, and I'd rather not have to install cygwin just to compare 2 files.

Allow specifying binary path in tests

Currently, the path that the tests use to find the diffr binary expects that the tests are being run from cargo:

diffr/src/test_cli.rs

Lines 59 to 65 in 2c87325

fn diffr_path() -> PathBuf {
let mut dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
dir.push("target");
dir.push("debug");
dir.push("diffr");
dir
}

This can cause issues when packaging diffr for distributions (see NixOS/nixpkgs#69505, where doCheck = false disables running the package's tests).

It would be great if there was a way to provide the path, with $CARGO_MANIFEST_DIR/target/debug/diffr being a fallback, perhaps through a DIFFR_TESTS_BINARY_PATH environment variable or something like that.

Improve default coloring contrast

IntelliJ Idea Terminal:
image
image
Konsole:
image

I understand that the tool should by default only highlight the character changes and leave everything else untouched - however, white on bright green is barely legible, especially if, as in the first two examples the white isn't a pure white.

Couldn't you use a dark green background or smth?

Relation

Seems this originates from #31 - if the reason is that you don't want to add any colors, maybe you could make the text on the green background black again.

I figured, the reason is that "black" color more likely to blend with the dark "green" and "red" than white color.

Idk why, but in my case it is a bright and not a dark green ^^

Prioritize common prefix

- note: AAA
+ note: BBB CCC

In this diff, diffr aligns the space in the removed line with the space in the middle of the added line, rather than the space in the common prefix of both strings.

diffr

Is this a limitation of the algorithm or something that can be fixed on your end? It would be nicer to prioritize maximally long common prefixes so that we see "AAA" as removed and "BBB CCC" as added.

Another way to frame the problem would be to minimize the number of snakes. The above diff can be described with 1 snake but diffr_lib currently produces 2.

I haven't looked at the algorithm but it seems like a longest common subsequence tie being broken the wrong way, where maybe a simple heuristic for ties could produce much cleaner diffs.

"error: Unknown option" while building

Could please help me compiling your project a bit :)

First, I have rustup 1.18.3 (435397f48 2019-05-22) and cargo 1.36.0 (c4fcfb725 2019-05-15) installed. And $HOME/.cargo/bin is present in my $PATH.

Now, I cloned your repository, and if I try to run cargo build in it, it installs crates (I see those in $HOME/.cargo/registry/index) and then fails saying "error: Unknown option".

And if I try to run rusts src/main.rs, it fails saying something like the following:

error[E0432]: unresolved import `clap`
 --> src/main.rs:1:5
  |
1 | use clap::{App, Arg};
  |     ^^^^ maybe a missing `extern crate clap;`?

error[E0433]: failed to resolve: maybe a missing `extern crate termcolor;`?
 --> src/main.rs:7:5
  |
7 | use termcolor::{
  |     ^^^^^^^^^ maybe a missing `extern crate termcolor;`?
[rest skipped]

As if it doesn't see installed crates from $HOME/.cargo/registry for some reason... So, what could be wrong here? Any hints may be? :)

Thanks.

Ignore word-level diff on new or deleted lines

Can word-level diff be ignored for lines which are completely new or completely removed from a given diff? With the default configuration, added/removed lines are highlighted in there entirety.

Failing Tests

Hi, The following tests fail for me when building:


---- test_cli::color_ok stdout ----
thread 'test_cli::color_ok' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/test_cli.rs:83:17

---- test_cli::color_ok_multiple stdout ----
thread 'test_cli::color_ok_multiple' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/test_cli.rs:83:17

---- test_cli::debug_flag stdout ----
thread 'test_cli::debug_flag' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/test_cli.rs:83:17

---- test_cli::color_only_face_name stdout ----
thread 'test_cli::color_only_face_name' panicked at 'spawn: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/test_cli.rs:83:17


failures:
    test_cli::color_invalid_attribute_name
    test_cli::color_invalid_color_not_done
    test_cli::color_invalid_color_value_ansi
    test_cli::color_invalid_color_value_name
    test_cli::color_invalid_color_value_rgb
    test_cli::color_invalid_face_name
    test_cli::color_ok
    test_cli::color_ok_multiple
    test_cli::color_only_face_name
    test_cli::debug_flag

Do you happen to know how I can make them pass?

Default parameters from environment variable

I always use a certain set of switches (--colors refine-added:none:background:0x33,0x66,0x33:bold --colors added:none:background:0x33,0x44,0x33 --colors refine-removed:none:background:0x66,0x33,0x33:bold --colors removed:none:background:0x44,0x33,0x33) and would like to have that whereever I invoke diffr, currently I have to always work with aliases. An environment variable for default flags as fzf has with FZF_DEFAULT_OPTS would be great.

Support for diff3

It would be nice if diffr could support diff3 as generated by git during merges.
Currently it simply ignores changes from on side.

how to use with git commit --verbose?

When running git commit --verbose git opens vim with
the diff so you can see whats being commited.
But this diff is not filtered using diffr.
I searched on the git documentation and could not find anything.

I am not getting colors

I am only getting bold text for all changes, no colors. Are there some term requirements? Or required options that I am missing? diff-highlight works fine (by default)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.