Coder Social home page Coder Social logo

afnanenayet / diffsitter Goto Github PK

View Code? Open in Web Editor NEW
1.5K 10.0 27.0 1.9 MB

A tree-sitter based AST difftool to get meaningful semantic diffs

License: MIT License

Rust 88.79% Python 1.63% Shell 8.04% C++ 1.21% Go 0.14% Dockerfile 0.19%
diff ast rust tree-sitter parser

diffsitter's Introduction

diffsitter

CI CD codecov crates version GitHub release (latest by date) downloads license

asciicast

Disclaimer

diffsitter is very much a work in progress and nowhere close to production ready (yet). Contributions are always welcome!

Summary

diffsitter creates semantically meaningful diffs that ignore formatting differences like spacing. It does so by computing a diff on the AST (abstract syntax tree) of a file rather than computing the diff on the text contents of the file.

diffsitter uses the parsers from the tree-sitter project to parse source code. As such, the languages supported by this tool are restricted to the languages supported by tree-sitter.

diffsitter supports the following languages:

  • Bash
  • C#
  • C++
  • CSS
  • Go
  • Java
  • OCaml
  • PHP
  • Python
  • Ruby
  • Rust
  • Typescript/TSX
  • HCL

Examples

Take the following files:

a.rs

fn main() {
    let x = 1;
}

fn add_one {
}

b.rs

fn



main

()

{
}

fn addition() {
}

fn add_two() {
}

The standard output from diff will get you:

1,2c1,12
< fn main() {
<     let x = 1;
---
> fn
>
>
>
> main
>
> ()
>
> {
> }
>
> fn addition() {
5c15
< fn add_one {
---
> fn add_two() {

You can see that it picks up the formatting differences for the main function, even though they aren't semantically different.

Check out the output from diffsitter:

test_data/short/rust/a.rs -> test_data/short/rust/b.rs
======================================================

9:
--
+ }

11:
---
+ fn addition() {

1:
--
-     let x = 1;

14:
---
+ fn add_two() {

4:
--
- fn add_one {

Note: the numbers correspond to line numbers from the original files.

You can also filter which tree sitter nodes are considered in the diff through the config file.

Since it uses the AST to calculate the difference, it knows that the formatting differences in main between the two files isn't a meaningful difference, so it doesn't show up in the diff.

diffsitter has some nice (terminal aware) formatting too:

screenshot of rust diff

It also has extensive logging if you want to debug or see timing information:

screenshot of rust diff with logs

Node filtering

You can filter the nodes that are considered in the diff by setting include_nodes or exclude_nodes in the config file. exclude_nodes always takes precedence over include_nodes, and the type of a node is the kind of a tree-sitter node. The kind directly corresponds to whatever is reported by the tree-sitter API, so this example may occasionally go out of date.

This feature currently only applies to leaf nodes, but we could exclude nodes recursively if there's demand for it.

"input-processing": {
    // You can exclude different tree sitter node types - this rule takes precedence over `include_kinds`.
    "exclude_kinds": ["string_content"],
    // You can specifically allow only certain tree sitter node types
    "include_kinds": ["method_definition"],
}

Installation

Packaging status

Published binaries

This project uses Github actions to build and publish binaries for each tagged release. You can download binaries from there if your platform is listed. We publish nightly releases as well as tagged stable releases.

Cargo

You can build from source with cargo using the following command:

cargo install diffsitter --bin diffsitter

If you want to generate completion files and other assets you can install the diffsitter_completions binary with the following command:

cargo install diffsitter --bin diffsitter_completions

Homebrew

You can use my tap to install diffsitter:

brew tap afnanenayet/tap
brew install diffsitter
# brew install afnanenayet/tap/diffsitter

Arch Linux (AUR)

@samhh has packaged diffsitter for arch on the AUR. Use your favorite AUR helper to install diffsitter-bin.

Alpine Linux

Install package diffsitter from the Alpine Linux repositories (on v3.16+ or Edge):

apk add diffsitter

Tree-sitter grammars are packaged separately (search for tree-sitter-*). You can install individual packages you need or the virtual package tree-sitter-grammars to install all of them.

Building with Docker

We also provide a Docker image that builds diffsitter using the standard Rust base image. It separates the compilation stage from the run stage, so you can build it and run with the following command (assuming you have Docker installed on your system):

docker build -t diffsitter .
docker run -it --rm --name diffsitter-interactive diffsitter

Usage

For detailed help you can run diffsitter --help (diffsitter -h provides brief help messages).

You can configure file associations and formatting options for diffsitter using a config file. If a config is not supplied, the app will use the default config, which you can see with diffsitter dump-default-config. It will look for a config at ${XDG_HOME:-$HOME}/.config/diffsitter/config.json5 on macOS and Linux, and the standard directory for Windows. You can also refer to the sample config.

You can override the default config path by using the --config flag or set the DIFFSITTER_CONFIG environment variable.

Note: the tests for this crate check to make sure the provided sample config is a valid config.

Git integration

To see the changes to the current git repo in diffsitter, you can add the following to your repo's .git/config and run git difftool.

[diff]
        tool = diffsitter

[difftool]
        prompt = false

[difftool "diffsitter"]
        cmd = diffsitter "$LOCAL" "$REMOTE"

Shell Completion

You can generate shell completion scripts using the binary using the gen-completion subcommand. This will print the shell completion script for a given shell to STDOUT.

You should use the help text for the most up to date usage information, but general usage would look like this:

diffsitter gen-completion bash > completion.bash

We currently support the following shells (via clap_complete):

  • Bash
  • Zsh
  • Fish
  • Elvish
  • Powershell

Dependencies

diffsitter is usually compiled as a static binary, so the tree-sitter grammars/libraries are baked into the binary as static libraries. There is an option to build with support for dynamic libraries which will look for shared library files in the user's default library path. This will search for library files of the form libtree-sitter-{lang}.{ext}, where lang is the language that the user is trying to diff and ext is the platform-specific extension for shared library files (.so, .dylib, etc). The user can override the dynamic library file for each language in the config as such:

{
    "grammar": {
        // You can specify the dynamic library names for each language
        "dylib-overrides": {
            // with a filename
            "rust": "libtree-sitter-rust.so",
            // with an absolute path
            "c": "/usr/lib/libtree-sitter-c.so",
            // with a relative path
            "cpp": "../libtree-sitter-c.so",
        },
    }
}

The above excerpt was taken from the sample config.

Questions, Bugs, and Support

If you notice any bugs, have any issues, want to see a new feature, or just have a question, feel free to open an issue or create a discussion post.

If you file an issue, it would be preferable that you include a minimal example and/or post the log output of diffsitter (which you can do by adding the -d/--debug flag).

Contributing

See CONTRIBUTING.md.

Similar Projects

diffsitter's People

Contributors

0323pin avatar 0xdevalias avatar afnanenayet avatar bar9 avatar byron avatar clashthebunny avatar dependabot-preview[bot] avatar dependabot[bot] avatar enricozb avatar jaens avatar jirutka avatar kellenff avatar windwardly avatar

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

diffsitter's Issues

Provide an option to skip building grammars or provide paths to prebuilt ones

Is your feature request related to a problem?

Not related to a problem.

Context

I'm working on packaging this for the AUR as diffsitter as opposed to diffsitter-bin, which provides a prebuilt binary. Unfortunately I can't do this as cargo insists on building the grammars listed as submodules. The issue is that I've already packaged most of these grammars separately (see here), all of which compile from source.

Describe the solution you'd like
I'd like to see a way to either bypass compiling the grammars or provide a path to a prebuilt one.

Describe alternatives you've considered
As a workaround, I've tried to patch Cargo.toml such that it would not build the grammars, but it hasn't worked.

[BUG] Out of Bounds error while diffing two Terraform files

Describe the bug
Out of Bounds error while diffing two Terraform files

To Reproduce
Steps to reproduce the behavior:

  1. Configure diffsitter to treat .tf files as hcl.
{
  "grammar": {
    "file-associations": {
      "tf": "hcl"
    }
  }
}
  1. Create two Terraform files:
cat <<EOF > test-a.tf
locals {
}
EOF
cat <<EOF > test-b.tf
locals {
  foo = "foo"
}
EOF
  1. Diff the two files:
❯ diffsitter test-a.tf test-b.tf
  1. An error is generated:
thread 'main' panicked at 'byte index 14 is out of bounds of `  foo = "foo"`', src/formatting.rs:440:43

Expected behavior
The diff should be printed without any error.

Log output/screenshots

❯ RUST_BACKTRACE=full diffsitter --debug test-a.tf test-b.tf
 2022-11-16T20:11:09.402Z DEBUG diffsitter > Checking if test-a.tf can be parsed
 2022-11-16T20:11:09.402Z INFO  diffsitter::parse > Deduced language "hcl" from extension "tf" provided from user mappings
 2022-11-16T20:11:09.402Z INFO  diffsitter::parse > Using tree-sitter parser for language hcl
 2022-11-16T20:11:09.402Z INFO  diffsitter::parse > Succeeded loading grammar for hcl
 2022-11-16T20:11:09.402Z DEBUG diffsitter        > Checking if test-b.tf can be parsed
 2022-11-16T20:11:09.402Z INFO  diffsitter::parse > Deduced language "hcl" from extension "tf" provided from user mappings
 2022-11-16T20:11:09.402Z INFO  diffsitter::parse > Using tree-sitter parser for language hcl
 2022-11-16T20:11:09.402Z INFO  diffsitter::parse > Succeeded loading grammar for hcl
 2022-11-16T20:11:09.402Z DEBUG diffsitter        > Extensions for both input files are supported
 2022-11-16T20:11:09.402Z DEBUG diffsitter        > Reading test-a.tf to string
 2022-11-16T20:11:09.402Z INFO  diffsitter        > Will deduce filetype from file extension
 2022-11-16T20:11:09.402Z INFO  diffsitter::parse > Deduced language "hcl" from extension "tf" provided from user mappings
 2022-11-16T20:11:09.402Z INFO  diffsitter::parse > Using tree-sitter parser for language hcl
 2022-11-16T20:11:09.402Z INFO  diffsitter::parse > Succeeded loading grammar for hcl
 2022-11-16T20:11:09.402Z DEBUG diffsitter::parse > Constructed parser
 2022-11-16T20:11:09.402Z DEBUG diffsitter::parse > Parsed AST
 2022-11-16T20:11:09.402Z INFO  TimerFinished     > parse::parse_file(), Elapsed=225.133µs
 2022-11-16T20:11:09.403Z DEBUG diffsitter        > Reading test-b.tf to string
 2022-11-16T20:11:09.403Z INFO  diffsitter        > Will deduce filetype from file extension
 2022-11-16T20:11:09.403Z INFO  diffsitter::parse > Deduced language "hcl" from extension "tf" provided from user mappings
 2022-11-16T20:11:09.403Z INFO  diffsitter::parse > Using tree-sitter parser for language hcl
 2022-11-16T20:11:09.403Z INFO  diffsitter::parse > Succeeded loading grammar for hcl
 2022-11-16T20:11:09.403Z DEBUG diffsitter::parse > Constructed parser
 2022-11-16T20:11:09.403Z DEBUG diffsitter::parse > Parsed AST
 2022-11-16T20:11:09.403Z INFO  TimerFinished     > parse::parse_file(), Elapsed=73.527µs
 2022-11-16T20:11:09.403Z INFO  TimerFinished     > ast::from_ts_tree(), Elapsed=18.268µs
 2022-11-16T20:11:09.403Z INFO  TimerFinished     > ast::process(), Elapsed=37.945µs
 2022-11-16T20:11:09.403Z INFO  TimerFinished     > ast::from_ts_tree(), Elapsed=3.375µs
 2022-11-16T20:11:09.403Z INFO  TimerFinished     > ast::process(), Elapsed=9.209µs
 2022-11-16T20:11:09.403Z INFO  TimerFinished     > diff::compute_edit_script(), Elapsed=4.517µs
 2022-11-16T20:11:09.403Z INFO  diffsitter::formatting > Detected terminal width: 104 columns
 2022-11-16T20:11:09.403Z INFO  diffsitter::formatting > Using stack style horizontal for title
 2022-11-16T20:11:09.403Z DEBUG diffsitter::formatting > Printing remaining old hunks
 2022-11-16T20:11:09.403Z DEBUG diffsitter::formatting > Printing remaining new hunks
 2022-11-16T20:11:09.403Z DEBUG diffsitter::formatting > Printing hunk (lines 1 - 1)
 2022-11-16T20:11:09.403Z DEBUG diffsitter::formatting > Title string has length of 3
 2022-11-16T20:11:09.403Z DEBUG diffsitter::formatting > Printing line 1
thread 'main' panicked at 'byte index 14 is out of bounds of `  foo = "foo"`', src/formatting.rs:440:43
stack backtrace:
   0:        0x10026b306 - __mh_execute_header
   1:        0x10021093b - __mh_execute_header
   2:        0x1002672e0 - __mh_execute_header
   3:        0x10026ebbb - __mh_execute_header
   4:        0x10026f428 - __mh_execute_header
   5:        0x10026ef24 - __mh_execute_header
   6:        0x10026ee99 - __mh_execute_header
   7:        0x10026ee55 - __mh_execute_header
   8:        0x10036da03 - __mh_execute_header
   9:        0x10036deec - __mh_execute_header
  10:        0x100185de8 - __mh_execute_header
  11:        0x10019468b - __mh_execute_header
  12:        0x1001a9096 - __mh_execute_header
  13:        0x1001ab227 - __mh_execute_header
  14:     0x7ff809791310 - <unknown>
 2022-11-16T20:11:09.404Z INFO  TimerFinished          > formatting::print(), Elapsed=727.907µs
test-a.tf -> test-b.tf
======================

1:
--
+   foo = "foo"%

Platform:
OS: macOS 13 (Ventura)

Support ignoring differences that only consist of variable/function name changes (eg. within minified JavaScript)

Is your feature request related to a problem? Please describe.

Currently, when diffing minimized bundled JavaScript code, there's a significant amount of 'noise' due to the bundler often changing the minified variable names between builds. This can obscure the real changes and make the diff output less useful for understanding code changes.

Describe the solution you'd like

I propose adding a feature to diffsitter that ignores changes in variable/function names within minified JavaScript code. This improvement would drastically reduce the noise in diffs of minimized source builds, allowing for a clearer focus on the actual code changes rather than the fluctuation of variable names.

Describe alternatives you've considered
As workarounds, I've experimented with various git diff modes like patience, histogram, and minimal to somewhat reduce the diff size. For instance, changing the diff algorithm can alter the number of lines in the diff output significantly:

⇒ git diff --diff-algorithm=default -- unpacked/_next/static/chunks/pages/_app.js | wc -l
  116000

⇒ git diff --diff-algorithm=patience -- unpacked/_next/static/chunks/pages/_app.js | wc -l
   35826

Nonetheless, these approaches still capture variable name changes, which can introduce a substantial amount of 'noise', especially in larger files.

Other potential solutions include pre-processing the files to normalize variable/function names or post-processing the diff output to filter out sections where the only changes involve variable/function names.

Additional context

The ideal solution would provide diff output in text format, but the actual diffing would occur at the AST level, ignoring variable/function name changes.

I suspect this might be possible already (at least to some degree) with the following; though I haven't found any good examples/docs to help explain how to use it better yet:

  • https://github.com/afnanenayet/diffsitter
    • A tree-sitter based AST difftool to get meaningful semantic diffs

    • You can also filter which tree sitter nodes are considered in the diff through the config file.

    • https://github.com/afnanenayet/diffsitter#node-filtering
      • You can filter the nodes that are considered in the diff by setting include_nodes or exclude_nodes in the config file. exclude_nodes always takes precedence over include_nodes, and the type of a node is the kind of a tree-sitter node.

        This feature currently only applies to leaf nodes, but we could exclude nodes recursively if there's demand for it.

I'm going to hopefully play around with it a bit more now, but wanted to capture this while it was fresh in my mind.

See Also

[BUG] Fails to build with `dynamic-grammar-libs` feature since 0.7.0

$ cargo build --locked --no-default-features --features dynamic-grammar-libs
...
error[E0432]: unresolved import `crate::parse::supported_languages`
 --> src/main.rs:9:5
  |
9 | use crate::parse::supported_languages;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `supported_languages` in `parse`

For more information about this error, try `rustc --explain E0432`.
error: could not compile `diffsitter` due to previous error

This problem came with 0.7.0, the previous version compiled fine.

Environment:

  • Alpine Linux Edge
  • rust 1.60.0

[BUG] core dump comparing two C files

Describe the bug
I wanted to try out diffsitter, so I tried diffing two C files with diffsitter 0.8.1 built from pkgsrc on NetBSD/amd64, but it dumped core.

To Reproduce
Check out https://github.com/nih-at/libzip/
Run

diffsitter lib/zip_source_winzip_aes_*
zsh: segmentation fault (core dumped)  diffsitter lib/zip_source_winzip_aes_*```

Expected behavior
I wanted to see a diff instead.

Log output/screenshots

wiz@exadelic:~/Projects/nih/libzip> diffsitter --debug lib/zip_source_winzip_aes_*
 2023-11-17T21:59:31.121Z DEBUG diffsitter > Checking if lib/zip_source_winzip_aes_decode.c can be parsed
 2023-11-17T21:59:31.122Z INFO  libdiffsitter::parse > Deduced language "c" from extension "c" from default mappings
 2023-11-17T21:59:31.122Z INFO  libdiffsitter::parse > Loading dynamic library from libtree-sitter-c.so
 2023-11-17T21:59:31.122Z DEBUG libdiffsitter::parse > Using name tree_sitter_c for dynamic function
 2023-11-17T21:59:31.123Z INFO  libdiffsitter::parse > Succeeded loading grammar for c
 2023-11-17T21:59:31.123Z DEBUG diffsitter           > Checking if lib/zip_source_winzip_aes_encode.c can be parsed
 2023-11-17T21:59:31.123Z INFO  libdiffsitter::parse > Deduced language "c" from extension "c" from default mappings
 2023-11-17T21:59:31.123Z INFO  libdiffsitter::parse > Loading dynamic library from libtree-sitter-c.so
 2023-11-17T21:59:31.123Z DEBUG libdiffsitter::parse > Using name tree_sitter_c for dynamic function
 2023-11-17T21:59:31.123Z INFO  libdiffsitter::parse > Succeeded loading grammar for c
 2023-11-17T21:59:31.123Z DEBUG diffsitter           > Extensions for both input files are supported
 2023-11-17T21:59:31.123Z DEBUG libdiffsitter        > Reading lib/zip_source_winzip_aes_decode.c to string
 2023-11-17T21:59:31.123Z INFO  libdiffsitter        > Will deduce filetype from file extension
 2023-11-17T21:59:31.123Z INFO  libdiffsitter::parse > Deduced language "c" from extension "c" from default mappings
 2023-11-17T21:59:31.123Z INFO  libdiffsitter::parse > Loading dynamic library from libtree-sitter-c.so
 2023-11-17T21:59:31.123Z DEBUG libdiffsitter::parse > Using name tree_sitter_c for dynamic function
 2023-11-17T21:59:31.124Z INFO  libdiffsitter::parse > Succeeded loading grammar for c
zsh: segmentation fault (core dumped)  diffsitter --debug lib/zip_source_winzip_aes_*

Here's the backtrace:

(gdb) bt
#0  ts_language_version (self=0x74406e1fed20) at src/./language.c:11
#1  0x00000000009eb2f4 in tree_sitter::Parser::set_language::h2cb43d5a19f629d1 ()
#2  0x00000000009c551f in libdiffsitter::parse::parse_file::h673ec514b7a95acb ()
#3  0x00000000009d4c18 in libdiffsitter::generate_ast_vector_data::hee8e02d6202e3ba7 ()
#4  0x000000000099a07f in diffsitter::main::h80217524e615fc00 ()
#5  0x00000000009a78c3 in std::sys_common::backtrace::__rust_begin_short_backtrace::h71ea8733c7c5e234 ()
#6  0x00000000009abddd in std::rt::lang_start::{{closure}}::hffa38383312f03fc ()
#7  0x0000000000afdf87 in std::panicking::try::h0d6cfe1f8828421a ()
#8  0x0000000000ada19b in std::rt::lang_start_internal::h927544304a5690c7 ()
#9  0x000000000099b675 in main ()

Platform:
NetBSD-10.99.10/amd64

Additional context
I do have tree-sitter-c 0.20.5 installed in my default search path.
I didn't configure diffsitter in any way to look for it though.

Modular rendering for diffs

diffsitter should support a modular rendering system that takes diff information and outputs them in different formats with a generic interface.

This would take care of issues like #158, keeps the codebase cleaner, and makes things more extensible for the future for other rendering modes. For example, I was thinking of also adding a mode to output as JSON.

Options to only show functional changes in diffs

Is your feature request related to a problem? Please describe.

I noticed that diffsitter returns 0 when the two files have the same AST, which is awesome. However, it still produces output if there are nonfunctional changes. Example programs:

package main

import "fmt"

func main() {
	a := "string"
	fmt.Println(a)
}
package main

import "fmt"

// comments in the file
func main() {
	b := "string"
	fmt.Println(b)
}

Produces:

diffsitter a/main.go b/main.go                                                                                                                      main  
a/main.go -> b/main.go
======================

4:
--
+ // comments in the file

6 - 7:
------
+       b := "string"
+       fmt.Println(b)

5 - 6:
------
-       a := "string"
-       fmt.Println(a)

In the event that you have something like a mass refactor which you expect not to have functional changes, if one ends up showing up you are not easily able to find it.

Describe the solution you'd like

I would like it if there were a setting which, when enabled, would make diffsitter print only the changes which meaningfully alter the AST.

Describe alternatives you've considered

I thought about writing my own but it would only support Go. This project seems like a great base to bring this to many languages.

Additional context

I am not sure but I would suspect the various different semantics between languages may make this a somewhat complicated request (I don't know off the top of my head but I suspect, software being the way it is, that there may exist a language or framework where merely changing a variable name has functional impacts).

Docs - Explicitly state where the config file lives

I'd open a PR for that, but I can't commit on the repo on my local machine (HEAD of main is 0d9dc2e) due to an error:

error: 'grammars/tree-sitter-bash' does not have a commit checked out
fatal: updating files failed

It's not a branch, not a tag, and the ref resolves a seemingly empty object. git show --format='%B' grammars/tree-sitter-bash | cat returns nothing (and exit with 0)

Anyhow this is the change I want to make:

The ${XDG_HOME:-$HOME} is there because XDG_HOME is not a thing on macOS.' .

diff --git a/README.md b/README.md
index 0a5c2d4..40db186 100644
--- a/README.md
+++ b/README.md
@@ -183,9 +183,9 @@ ## Usage
 You can configure file associations and formatting options for `diffsitter`
 using a config file. If a config is not supplied, the app will use the default
 config, which you can see with `diffsitter --cmd dump_default_config`. It will
-look for a config at `$XDG_HOME/.config` on macOS and Linux, and the standard
-directory for Windows. You can also refer to the
-[sample config](/assets/sample_config.json5).
+look for a config at `${XDG_HOME:-$HOME}/.config/diffsitter/config.json5` on
+macOS and Linux, and the standard directory for Windows. You can also refer to
+the [sample config](/assets/sample_config.json5).
 
 *Note: the tests for this crate check to make sure the provided sample config
 is a valid config.*
diff --git a/assets/sample_config.json5 b/assets/sample_config.json5
index c4f1c63..f6587fb 100644
--- a/assets/sample_config.json5
+++ b/assets/sample_config.json5
@@ -1,5 +1,7 @@
 // This is a JSON5 file, so you can use comments and trailing commas, which
 // makes it a lot more convenient for configs.
+// It should be in ${XDG_HOME:-$HOME}/.config/diffsitter/config.json5
+
 {
     // Set options for terminal formatting here
     "formatting": {

[BUG] difffsitter compilation fails on Ubuntu/Debian for grammars with C++ sources

Describe the bug

If you try to build diffsitter with cargo build, you get the follower linker error:

Note: Seen in Github actions, which uses Ubuntu, and tested on aarch64 Debian (via QEMU on an M1 Mac)

To Reproduce

Clone the repo on Debian/Ubuntu, try running cargo build.

Expected behavior
Everything should build normally without errors.

Log output/screenshots

debian@debian:~/diffsitter$ cargo b
   Compiling diffsitter v0.7.1 (/home/debian/diffsitter)
error: linking with `cc` failed: exit status: 1
  |
  = note: "cc" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.10hsy3n80ijqvi4m.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.11ewwa96u9y23vv2.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.12knftlhv38chton.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.13hzyd8385gtqnto.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.142efmrmtsutlfth.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.142qtigqw5fa34d0.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.15z4t4w4bv7zvkgd.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.16bozstbwxfm6u6c.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.17noxhu49c211sfn.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.17w1vlb00xfz6qz7.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.182utarbyloywqxk.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1aqr2mxng9o29kr2.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1ftcid4af59u2ov.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1ght1xao0esg2g1g.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1h3vtfrdea4zr531.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1iqgi9qdsl8nvvrm.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1itsrd57988t3lra.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1jajnwmz7gl2azql.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1o2s8txxysej4e7g.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1otyo9fbknxb34xb.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1ov3ol0bhayg0t72.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1r7j5gg0qlviez39.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1r9kn9sbyo8igosr.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1rkn7gfgyrqkdzni.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1s3aizt59savhkax.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1t4on7csgoqc1ptd.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1twnas07778457fb.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1v7pzwoudpinjylw.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1xz8scto2o4ya09z.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1zem86q0ohn1tnnb.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.1zp778viwwjveuai.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.22mniyxpswfmpx8u.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.23q0c7sdp0mwpmkq.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.24x97j6dwrw7wbvg.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2512n92fgzpflj7p.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.267wug5qyjfewybu.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.269mlet1jk5stqw2.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.26az24s78p17vj26.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.293vir2x2uti3aoz.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.29nhqf9b4wdzqwq0.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2d2zkkukapl4y6v0.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2dti8f46cejf1grd.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2dvr3lsddaed606t.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2f6nnwj3g7zyxhk1.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2fhy119aljuaq1sd.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2fqf1n92b84cbj8e.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2h1ev5nol4ssuxj5.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2i941ntk5utf2px0.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2lbe868bsq5wy70d.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2lkx4ja1kxwqs3ik.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2m1b3xjv0ramau7h.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2m7e7tl82h7pvop.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2mf1xsys4fd054g8.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2ph28kj0uztrp2yd.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2ppc6j6v2aqm3l4f.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2q4hxtvbd8vb3atl.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2q66n9q1v00dhhqx.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2t9dnq4j7lkbf042.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2tolv99nk833l3t6.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2ummuaqzttnmjy99.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2w8wfom4g6nv8e1d.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2x4czl2kubeqyg2i.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2xsj98nmot1bon4p.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2yp5k92ps4qnvl4d.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.2z41cpwmw929o4nw.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.30jdp5szqm4oxk60.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.31vutgyxdjnc3f2g.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.32bm5vw3849yx7ii.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.332zxp4wtmgzttkk.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.339iwdgaxy8kagz4.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3824bwh1w74s5hxx.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.399gb7nglc1iyxe4.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.39t4ipte5upbxs1c.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3a5xsdhen31ipnus.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3ayv9uqofgbkc95q.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3ewulzyi87qvvjk4.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3g25rk9cbumhbq9k.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3gqoy1y6beshcux7.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3gr09xleatqirgpc.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3i0r9qegcs30ws74.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3ju0g4ivnw3tw6i5.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3kug8h768jgulj96.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3ltibmj8e7ybebib.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3nw2ffxdqzjc1zpg.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3o968all0ex38ix0.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3paztmlginqjjdok.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3pol6ia6joo1fcuw.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3pz9g2com2lue5pw.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3q00nl7bbch434g2.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3qbdsjf1wfiemxv0.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3r328r597rzwmk41.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3rehlcmepntd05sw.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3ssejmse3qeynzz.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3to20g680l8hzgtd.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3tz5pegg25on7471.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3uzymu6fte746xxk.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3v94078j1yp3tpw1.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3w5bfq7itvcbpll8.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3w65h2r476hb96lb.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.3waaha2pfib0aiiz.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.40ltt2qbc8owojap.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4249tsbm0uszgyv3.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.45bqw7l4qq6mtu7c.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.45h4rmxv09e09g18.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4791ur0co0gpnzvu.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.481b2eijoe4dyqft.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.49s27yzss6gshdxo.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4b6ljrxls9bbjnt3.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4bbyuxyflpv5n08x.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4bh72ukt70a72mhu.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4bovvkrrkv19580z.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4d429nf0cdg0y2c3.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4ej64w9vm6aokdqw.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4go1xb47oxs47iky.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4iijz4yurkbn4tk9.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4jiec9o6ccy5w6of.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4kkr53z9zz0bo2h9.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4koqce48ukmlsmio.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4l20avs5k5rqfjm3.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4md9t0xtw9lf2oo5.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4n86i6cy6w2483zc.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4nars5fpms7wr6vw.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4ntfivf2wxxzjz5z.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4o36y78h14q3lvqi.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4ob1e3176zqj3j9g.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4qhjxs77ftej8jgq.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4r0f6dabx3w8q6i4.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4r0urddm7fcg8uw7.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4tfape6d3adi8k5g.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4tv82vaoyt7kg48x.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4u8so2m1xw0gijk5.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4vxg3m7pynavliiy.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4z0bhddxo784mij4.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4z35ky2c6cx89mb2.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4zgwz26pqzh812wt.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.4zw9xvqekrzczz0q.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.52sf0k1x1v81lyoj.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.52vl4getkq3jd777.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.545mfo4dix212bzh.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.55mxgg9udeisdlvs.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.562l1hvqjryndb8x.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.56e00fxd8jah85qv.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.593y5d5n0pyjqs5t.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.5bax3zjim8g0bxyj.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.5bzafkdobrsxgbj2.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.5cn42w69pi6osqd.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.5doxxzlk2po2ph73.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.5g872fmf12xljm4y.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.7rnv106mjirv10m.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.9dtfugz92lf9d1u.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.agasaq7l64szu31.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.c0d9czrrhpaeqz6.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.dir168q0xmp80gq.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.djxalp4i66haidk.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.ea277hy7pl6pmh6.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.fy9410kpecdxbxy.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.gbb3zotjvie3aqk.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.h9cvrmgm2td6zw5.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.hfiq8c8k6agtisj.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.hlfg0oz7ik4pp25.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.htadn8mari2d7dj.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.i1usatffmy0k2f2.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.j0g0jows12ibsuk.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.jpsyxxgadboa2xk.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.k2idl49pqjbjt5o.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.kfwkug0calduo8n.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.mmpu6e6yk7ty7gp.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.nhcli4zgpilwdbt.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.p91fcq16ty8v8ym.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.p9ch4i9dq454zzk.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.qxtvs6wk9xlw003.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.r6ij4xx97g773o9.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.s81jp9eka4hjtms.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.sl2kdruhgelj54l.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.sm32um56xbqp322.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.up19tk5ui5g32fk.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.vfbsumb1vj08rvh.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.xmok3n04urjtfec.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.y8rw30w8ud3rbnh.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.yfsd6rn4katrxdq.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.z3rv5x6e28gwbdj.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.ziyfba89ih97eod.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.zrffgudpejeehzk.rcgu.o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574.ig8iasl38et3sv9.rcgu.o" "-Wl,--as-needed" "-L" "/home/debian/diffsitter/target/debug/deps" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out" "-L" "/home/debian/diffsitter/target/debug/build/tree-sitter-3089f0ff9cddce13/out" "-L" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "-ljson" "-lgo" "-lruby-cpp-compile-diffsiter" "-ljava" "-lbash-cpp-compile-diffsiter" "-lhcl-cpp-compile-diffsiter" "-ltypescript" "-locaml-cpp-compile-diffsiter" "-ltsx" "-lcss" "-lcpp-cpp-compile-diffsiter" "-lhcl" "-lbash" "-lrust" "-lphp-cpp-compile-diffsiter" "-lpython-cpp-compile-diffsiter" "-Wl,-Bdynamic" "-lstdc++" "-Wl,-Bstatic" "-lruby" "-lphp" "-lpython" "-locaml" "-lcpp" "-lc_sharp" "/home/debian/diffsitter/target/debug/deps/libpretty_env_logger-bb585d90c8df2503.rlib" "/home/debian/diffsitter/target/debug/deps/libenv_logger-64c7345006a627d1.rlib" "/home/debian/diffsitter/target/debug/deps/libhumantime-8d4313982f40ad0b.rlib" "/home/debian/diffsitter/target/debug/deps/libquick_error-f5339b5953b81510.rlib" "/home/debian/diffsitter/target/debug/deps/libxdg-8f63ec880e0a89d9.rlib" "/home/debian/diffsitter/target/debug/deps/libdirs-fb604ce62818563d.rlib" "/home/debian/diffsitter/target/debug/deps/libdirs_sys-eeba71531acde346.rlib" "/home/debian/diffsitter/target/debug/deps/libstrum-090cfe08a4d423ca.rlib" "/home/debian/diffsitter/target/debug/deps/libphf-ccd5bfd8615ebd67.rlib" "/home/debian/diffsitter/target/debug/deps/libphf_shared-f765583ed4074dd5.rlib" "/home/debian/diffsitter/target/debug/deps/libsiphasher-8e418103afb19697.rlib" "/home/debian/diffsitter/target/debug/deps/libserde_json-da5b101f2beaacf1.rlib" "/home/debian/diffsitter/target/debug/deps/libryu-c83b6f5ed20250a4.rlib" "/home/debian/diffsitter/target/debug/deps/libitoa-ec32d2d2270d46db.rlib" "/home/debian/diffsitter/target/debug/deps/libunicode_segmentation-5c15225f06f56329.rlib" "/home/debian/diffsitter/target/debug/deps/libtree_sitter-fb38ad3d17ef8301.rlib" "/home/debian/diffsitter/target/debug/deps/libconsole-270338aa8a050e37.rlib" "/home/debian/diffsitter/target/debug/deps/libregex-b2f61d604c4d3ddc.rlib" "/home/debian/diffsitter/target/debug/deps/libaho_corasick-d0394ca5d9b870c6.rlib" "/home/debian/diffsitter/target/debug/deps/libmemchr-523bf9e63938c0eb.rlib" "/home/debian/diffsitter/target/debug/deps/libregex_syntax-ffdcd873bf5a38c9.rlib" "/home/debian/diffsitter/target/debug/deps/libonce_cell-b06163f4266f732a.rlib" "/home/debian/diffsitter/target/debug/deps/liblogging_timer-d2cd6947e5372529.rlib" "/home/debian/diffsitter/target/debug/deps/libthiserror-ea09fbd52dcf71f8.rlib" "/home/debian/diffsitter/target/debug/deps/liblog-ddbb6a1ffa64ee7f.rlib" "/home/debian/diffsitter/target/debug/deps/libcfg_if-23b8bb8e45cee01d.rlib" "/home/debian/diffsitter/target/debug/deps/libjson5-ebbab77d492ce413.rlib" "/home/debian/diffsitter/target/debug/deps/libserde-7e1a997830777951.rlib" "/home/debian/diffsitter/target/debug/deps/libpest-630459567d33af4a.rlib" "/home/debian/diffsitter/target/debug/deps/libucd_trie-6ec538c1d63d2b67.rlib" "/home/debian/diffsitter/target/debug/deps/libanyhow-341f9f18b2ec548d.rlib" "/home/debian/diffsitter/target/debug/deps/libclap_complete-543e84697f166943.rlib" "/home/debian/diffsitter/target/debug/deps/libclap-d89f77afe5b30a3a.rlib" "/home/debian/diffsitter/target/debug/deps/libstrsim-5f25ca42efb952fe.rlib" "/home/debian/diffsitter/target/debug/deps/libatty-5b97ba6f6f03ac30.rlib" "/home/debian/diffsitter/target/debug/deps/libunicase-4c63a709c7197299.rlib" "/home/debian/diffsitter/target/debug/deps/libtermcolor-a4440a3d9481b84f.rlib" "/home/debian/diffsitter/target/debug/deps/libtextwrap-676806958ff71e67.rlib" "/home/debian/diffsitter/target/debug/deps/libterminal_size-5786930dff7c7818.rlib" "/home/debian/diffsitter/target/debug/deps/liblibc-823de496db8d9047.rlib" "/home/debian/diffsitter/target/debug/deps/libunicode_width-73591fae18d63abf.rlib" "/home/debian/diffsitter/target/debug/deps/libindexmap-97f5f80d45917771.rlib" "/home/debian/diffsitter/target/debug/deps/libhashbrown-249fc22e8aefa8bd.rlib" "/home/debian/diffsitter/target/debug/deps/libclap_lex-f73ce118c94f17ae.rlib" "/home/debian/diffsitter/target/debug/deps/libos_str_bytes-c0d84cc80571f695.rlib" "/home/debian/diffsitter/target/debug/deps/libbitflags-c5a20feb4672066a.rlib" "/home/debian/diffsitter/target/debug/deps/liblazy_static-c4365fea64834937.rlib" "-Wl,--start-group" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/libstd-7d5a620ab77655ab.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/libpanic_unwind-2de0d40477269ad1.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/libobject-59ae13aa5b85e878.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/libmemchr-25c2a8eab25c758c.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/libaddr2line-484db03cffcca5b6.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/libgimli-77337fc21bd1cca4.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/librustc_demangle-8399fd816afb0bb6.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/libstd_detect-dbd9d453a2c2347c.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/libhashbrown-f5e9f9d7692ae465.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/libminiz_oxide-0ae529ce319bd2e0.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/libadler-91ebd391b9f3e29e.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-79cdd974e440af93.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/libunwind-fb4f5845224d8c3b.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/libcfg_if-12a6b9815d90b1e4.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/liblibc-b0a59add1f3108e8.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/liballoc-cc0694ace9be0e66.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/librustc_std_workspace_core-5a84de01a2ad7b8c.rlib" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/libcore-d1ce211496f525c3.rlib" "-Wl,--end-group" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/libcompiler_builtins-9453083e1ae0beda.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-L" "/home/debian/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib" "-o" "/home/debian/diffsitter/target/debug/deps/diffsitter-9ab6316895539574" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro,-znow" "-nodefaultlibs"
  = note: /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libhcl.a(parser.o):(.data.rel.ro.language.4321+0xb8): undefined reference to `tree_sitter_hcl_external_scanner_create'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libhcl.a(parser.o):(.data.rel.ro.language.4321+0xc0): undefined reference to `tree_sitter_hcl_external_scanner_destroy'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libhcl.a(parser.o):(.data.rel.ro.language.4321+0xc8): undefined reference to `tree_sitter_hcl_external_scanner_scan'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libhcl.a(parser.o):(.data.rel.ro.language.4321+0xd0): undefined reference to `tree_sitter_hcl_external_scanner_serialize'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libhcl.a(parser.o):(.data.rel.ro.language.4321+0xd8): undefined reference to `tree_sitter_hcl_external_scanner_deserialize'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libbash.a(parser.o):(.data.rel.ro.language.4844+0xb8): undefined reference to `tree_sitter_bash_external_scanner_create'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libbash.a(parser.o):(.data.rel.ro.language.4844+0xc0): undefined reference to `tree_sitter_bash_external_scanner_destroy'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libbash.a(parser.o):(.data.rel.ro.language.4844+0xc8): undefined reference to `tree_sitter_bash_external_scanner_scan'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libbash.a(parser.o):(.data.rel.ro.language.4844+0xd0): undefined reference to `tree_sitter_bash_external_scanner_serialize'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libbash.a(parser.o):(.data.rel.ro.language.4844+0xd8): undefined reference to `tree_sitter_bash_external_scanner_deserialize'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libruby.a(parser.o):(.data.rel.ro.language.4987+0xb8): undefined reference to `tree_sitter_ruby_external_scanner_create'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libruby.a(parser.o):(.data.rel.ro.language.4987+0xc0): undefined reference to `tree_sitter_ruby_external_scanner_destroy'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libruby.a(parser.o):(.data.rel.ro.language.4987+0xc8): undefined reference to `tree_sitter_ruby_external_scanner_scan'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libruby.a(parser.o):(.data.rel.ro.language.4987+0xd0): undefined reference to `tree_sitter_ruby_external_scanner_serialize'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libruby.a(parser.o):(.data.rel.ro.language.4987+0xd8): undefined reference to `tree_sitter_ruby_external_scanner_deserialize'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libphp.a(parser.o):(.data.rel.ro.language.5163+0xb8): undefined reference to `tree_sitter_php_external_scanner_create'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libphp.a(parser.o):(.data.rel.ro.language.5163+0xc0): undefined reference to `tree_sitter_php_external_scanner_destroy'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libphp.a(parser.o):(.data.rel.ro.language.5163+0xc8): undefined reference to `tree_sitter_php_external_scanner_scan'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libphp.a(parser.o):(.data.rel.ro.language.5163+0xd0): undefined reference to `tree_sitter_php_external_scanner_serialize'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libphp.a(parser.o):(.data.rel.ro.language.5163+0xd8): undefined reference to `tree_sitter_php_external_scanner_deserialize'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libpython.a(parser.o):(.data.rel.ro.language.4668+0xb8): undefined reference to `tree_sitter_python_external_scanner_create'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libpython.a(parser.o):(.data.rel.ro.language.4668+0xc0): undefined reference to `tree_sitter_python_external_scanner_destroy'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libpython.a(parser.o):(.data.rel.ro.language.4668+0xc8): undefined reference to `tree_sitter_python_external_scanner_scan'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libpython.a(parser.o):(.data.rel.ro.language.4668+0xd0): undefined reference to `tree_sitter_python_external_scanner_serialize'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libpython.a(parser.o):(.data.rel.ro.language.4668+0xd8): undefined reference to `tree_sitter_python_external_scanner_deserialize'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libocaml.a(parser.o):(.data.rel.language.5120+0xb8): undefined reference to `tree_sitter_ocaml_external_scanner_create'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libocaml.a(parser.o):(.data.rel.language.5120+0xc0): undefined reference to `tree_sitter_ocaml_external_scanner_destroy'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libocaml.a(parser.o):(.data.rel.language.5120+0xc8): undefined reference to `tree_sitter_ocaml_external_scanner_scan'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libocaml.a(parser.o):(.data.rel.language.5120+0xd0): undefined reference to `tree_sitter_ocaml_external_scanner_serialize'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libocaml.a(parser.o):(.data.rel.language.5120+0xd8): undefined reference to `tree_sitter_ocaml_external_scanner_deserialize'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libcpp.a(parser.o):(.data.rel.ro.language.5509+0xb8): undefined reference to `tree_sitter_cpp_external_scanner_create'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libcpp.a(parser.o):(.data.rel.ro.language.5509+0xc0): undefined reference to `tree_sitter_cpp_external_scanner_destroy'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libcpp.a(parser.o):(.data.rel.ro.language.5509+0xc8): undefined reference to `tree_sitter_cpp_external_scanner_scan'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libcpp.a(parser.o):(.data.rel.ro.language.5509+0xd0): undefined reference to `tree_sitter_cpp_external_scanner_serialize'
          /usr/bin/ld: /home/debian/diffsitter/target/debug/build/diffsitter-1cd35836c2b26ac7/out/libcpp.a(parser.o):(.data.rel.ro.language.5509+0xd8): undefined reference to `tree_sitter_cpp_external_scanner_deserialize'
          collect2: error: ld returned 1 exit status
          
  = help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)

error: could not compile `diffsitter` due to previous error

Platform:
OS: Linux, specifically Ubuntu/Debian so far.

Additional context

I noticed that this seems to be an issue only with grammars that have C++ source files.

[BUG] README 'usage' section has incorrect command for dump-default-config

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Look at the 'usage' section of the README: https://github.com/afnanenayet/diffsitter#usage
  2. Copy the suggested command for dumping the default config: diffsitter --cmd dump_default_config
  3. Run it and notice that you get an error (see below)
  4. Eventually bruteforce your way to discovering the actual command (see below)
  5. Wonder why this isn't in the -h / --help
  6. Go back and look and then realise it is but you just missed it somehow
⇒ diffsitter --cmd dump_default_config
error: unexpected argument '--cmd' found

  tip: to pass '--cmd' as a value, use '-- --cmd'

Usage: diffsitter [OPTIONS] [OLD] [NEW] [COMMAND]

For more information, try '--help'.

⇒ diffsitter -- --cmd dump_default_config
Error: Unsupported file type with no fallback command specified.

⇒ diffsitter FAKE FAKE2 dump_default_config
error: unrecognized subcommand 'dump_default_config'

  tip: a similar subcommand exists: 'dump-default-config'

Usage: diffsitter [OPTIONS] [OLD] [NEW] [COMMAND]

For more information, try '--help'.

⇒ diffsitter FAKE FAKE2 dump-default-config
{
  // ..snip..
}

⇒ diffsitter dump-default-config
{
  // ..snip..
}

Expected behavior
The usage section of the docs should provide the correct command to use.

Log output/screenshots
N/A

Platform:
OS: N/A

Additional context
I should read the help output closer before trying to bruteforce my way to a solution.

JSON output mode

We should support outputting diff information as JSON so other tools can process the output in a structured way.

This is blocked by #396

Support git identifiers when running under git diff

Is your feature request related to a problem? Please describe.
diffsitter currently displays the filenames it's comparing. With git diff one of the files is a temporary file path which is not informative.

Describe the solution you'd like
diffsitter should display the revisions being compared instead of the file paths if called with information about revisions.

[BUG] nightly deployment is failing

Describe the bug
The nightly deployment is failing w/ Github actions.

To Reproduce
Run the nightly GitHub actions release job.

Expected behavior
That the CI releases a nightly pre-release.

Log output/screenshots
Can check Github actions.

Platform:
OS: All

Additional context
It's because of a case where the job will fail if an existing nightly job doesn't exist. We unconditionally try to delete the previous nightly release but if it doesn't exist the job will fail, blocking us from deploying nightly.

provide context in the form of unchanged lines or AST nodes

Is your feature request related to a problem? Please describe.
When using diffsitter as tool for git diff, line numbers don't make it immediately obvious where the change occurred.

Describe the solution you'd like
It would be nice if some surrounding context (3 lines before, 3 lines after) could be given, similar to how regular git diff and diff -C3 do it.

Describe alternatives you've considered
An alternative would be to allow machine-readable types of output (eg. json) for me or anyone else to write a new front-end around the logic of diffsitter.

Additional context
If it's not as obvious what counts as a line in AST-land, I would also be happy if I could get 10 AST nodes before and 10 AST nodes after the change (or some other configurable amount).

Handle unknown files gracefully

Is your feature request related to a problem? Please describe.

In this discussion which spanned from #155 it was noted that diffsitter cannot handle files it does not have the grammar for. This is an issue when trying to show diff in a git repository with a mix of supported and unsupported files.

Describe the solution you'd like
It would be nice if diffsitter was able to show diffs the same way that diff shows diff when the files are not supported. I'd be happy even if it only invoked diff in the background

Describe alternatives you've considered
With an intermediary script I guess it could achieve naively this way: diffsitter "$@" || diff "$@". It has been suggested to use .gitattribute for the git case, but this won't scale beyond the git usecase.

Investigate parsing documents concurrently

Is your feature request related to a problem? Please describe.
Right now documents are parsed serially, though they are not dependent on each other and could be parsed in parallel.

Describe the solution you'd like
Investigate whether parsing documents in parallel yields a noticeable performance gain.

Describe alternatives you've considered
We could parsing serial as-is because it's been extremely fast in my experience, and the overhead of sending data back and forth between threads might negate the speed gains from parsing both documents in parallel.

Additional context
N/A

feature request: show output in 2 columns

Any plans to make the output in 2 columns like delta and difftastic?

In this example, I find the difftastic's version really pretty.

delta:
image

diffsitter:
image

difftastic:
image

Markdown support

I am struggling to find a semantic diff tool for Markdown files. In essence I want to see the diff, independent of at which I wrap my lines in the markdown paragraphs.

For example the Markdown

This is a text.

and

This is
a text.

should be equivalent.

Add ts and tsx file associations to defaults

As noted by another user, we should add the typescript grammar file associations to the defaults in diffsitter.

          Running `diffsitter` `0.8.1` on macOS via homebrew:
⇒ diffsitter --version
diffsitter 0.8.1

It lists support for typescript / tsx:

⇒ diffsitter list
This program was compiled with support for:
- bash
- c_sharp
- cpp
- css
- go
- hcl
- java
- json
- ocaml
- php
- python
- ruby
- rust
- tsx
- typescript

Yet by default, it will fail to run against a JavaScript file:

⇒ git difftool --tool diffsitter HEAD~1 HEAD -- unpacked/_next/static/\[buildHash\]/_buildManifest.js
Error: Unsupported file type with no fallback command specified.

Until a file-association override is added to the config (${XDG_HOME:-$HOME}/.config/diffsitter/config.json5):

// ..snip..
  "grammar": {
    "dylib-overrides": null,
    "file-associations": {
      "js": "typescript",
      "jsx": "tsx"
    },
  },
// ..snip..

This would seem like a useful thing to be included in the default config that diffsitter uses:

⇒ diffsitter dump-default-config
{
  "file-associations": null,
  "formatting": {
    "default": "unified",
    "unified": {
      "addition": {
        "highlight": null,
        "regular-foreground": "green",
        "emphasized-foreground": "green",
        "bold": true,
        "underline": false,
        "prefix": "+ "
      },
      "deletion": {
        "highlight": null,
        "regular-foreground": "red",
        "emphasized-foreground": "red",
        "bold": true,
        "underline": false,
        "prefix": "- "
      }
    },
    "json": {
      "pretty_print": false
    },
    "custom": {}
  },
  "grammar": {
    "dylib-overrides": null,
    "file-associations": null
  },
  "input-processing": {
    "split-graphemes": true,
    "exclude-kinds": null,
    "include-kinds": null
  },
  "fallback-cmd": null
}

I also noted that modifying that default config to add the file-associations to the root key didn't seem to work; it only seemed to work when I added them to the grammar version of file-associations.

Originally posted by @0xdevalias in #152 (comment)

[BUG] crash when comparing c++ files between git tags

Describe the bug

diffsitter crashes when comparing c++ files between git tags like git difftool tagname^ tagname.

To Reproduce

  1. set .git/config like in https://github.com/afnanenayet/diffsitter#git-integration
[diff]
        tool = diffsitter
[difftool]
        prompt = false
[difftool "diffsitter"]
        cmd = diffsitter "$LOCAL" "$REMOTE" --debug
  1. create a tag to commit.
  2. run git difftool tagname^ tagname

Expected behavior
it does not crash.

Log output/screenshots

Details
 !  ~/r/c/Monoclysm   Mono  git difftool filter^ filter -- --debug                                                                                                                                              2023년 04월 28일 (금) 오전 12시 50분 37초 ~/r/c/Monoclysm   Mono  diffsitter filter^ filter                                                                                                                                                               2023년 04월 28일 (금) 오전 12시 50분 39초Error: Unsupported file type with no fallback command specified.
 !  ~/r/c/Monoclysm   Mono  diffsitter filter^ filter^C                                                                                                                                                         2023년 04월 28일 (금) 오전 12시 50분 46초 !  ~/r/c/Monoclysm   Mono  code .git/config                                                                                                                                                                    2023년 04월 28일 (금) 오전 12시 50분 46초 ~/r/c/Monoclysm   Mono  git difftool filter^ filter                                                                                                                                                     116ms  2023년 04월 28일 (금) 오전 12시 51분 13초 2023-04-27T15:51:22.492Z DEBUG diffsitter > Checking if /tmp/git-blob-6VqWI8/Cataclysm.sln can be parsed
 2023-04-27T15:51:22.492Z ERROR diffsitter::parse > Was not able to find a language string for extension sln
 2023-04-27T15:51:22.492Z ERROR diffsitter        > Extension sln not supported
Error: Unsupported file type with no fallback command specified.
 2023-04-27T15:51:22.502Z DEBUG diffsitter > Checking if /dev/null can be parsed
Error: Unsupported file type with no fallback command specified.
 2023-04-27T15:51:22.514Z DEBUG diffsitter > Checking if /tmp/git-blob-hnWfJ3/distribute.bat can be parsed
 2023-04-27T15:51:22.514Z ERROR diffsitter::parse > Was not able to find a language string for extension bat
 2023-04-27T15:51:22.514Z ERROR diffsitter        > Extension bat not supported
Error: Unsupported file type with no fallback command specified.
 2023-04-27T15:51:22.524Z DEBUG diffsitter > Checking if /tmp/git-blob-mG4MTa/calendar.cpp can be parsed
 2023-04-27T15:51:22.524Z INFO  diffsitter::parse > Deduced language "cpp" from extension "cpp" from default mappings
 2023-04-27T15:51:22.524Z INFO  diffsitter::parse > Using tree-sitter parser for language cpp
 2023-04-27T15:51:22.524Z INFO  diffsitter::parse > Succeeded loading grammar for cpp
 2023-04-27T15:51:22.524Z DEBUG diffsitter        > Checking if /tmp/git-blob-L5Iuoo/calendar.cpp can be parsed
 2023-04-27T15:51:22.524Z INFO  diffsitter::parse > Deduced language "cpp" from extension "cpp" from default mappings
 2023-04-27T15:51:22.524Z INFO  diffsitter::parse > Using tree-sitter parser for language cpp
 2023-04-27T15:51:22.524Z INFO  diffsitter::parse > Succeeded loading grammar for cpp
 2023-04-27T15:51:22.524Z DEBUG diffsitter        > Extensions for both input files are supported
 2023-04-27T15:51:22.524Z DEBUG diffsitter        > Reading /tmp/git-blob-mG4MTa/calendar.cpp to string
 2023-04-27T15:51:22.524Z INFO  diffsitter        > Will deduce filetype from file extension
 2023-04-27T15:51:22.524Z INFO  diffsitter::parse > Deduced language "cpp" from extension "cpp" from default mappings
 2023-04-27T15:51:22.524Z INFO  diffsitter::parse > Using tree-sitter parser for language cpp
 2023-04-27T15:51:22.524Z INFO  diffsitter::parse > Succeeded loading grammar for cpp
 2023-04-27T15:51:22.524Z DEBUG diffsitter::parse > Constructed parser
 2023-04-27T15:51:22.527Z DEBUG diffsitter::parse > Parsed AST
 2023-04-27T15:51:22.527Z INFO  TimerFinished     > parse::parse_file(), Elapsed=3.199784ms
 2023-04-27T15:51:22.528Z DEBUG diffsitter        > Reading /tmp/git-blob-L5Iuoo/calendar.cpp to string
 2023-04-27T15:51:22.528Z INFO  diffsitter        > Will deduce filetype from file extension
 2023-04-27T15:51:22.528Z INFO  diffsitter::parse > Deduced language "cpp" from extension "cpp" from default mappings
 2023-04-27T15:51:22.528Z INFO  diffsitter::parse > Using tree-sitter parser for language cpp
 2023-04-27T15:51:22.528Z INFO  diffsitter::parse > Succeeded loading grammar for cpp
 2023-04-27T15:51:22.528Z DEBUG diffsitter::parse > Constructed parser
 2023-04-27T15:51:22.530Z DEBUG diffsitter::parse > Parsed AST
 2023-04-27T15:51:22.530Z INFO  TimerFinished     > parse::parse_file(), Elapsed=2.764685ms
 2023-04-27T15:51:22.531Z INFO  TimerFinished     > ast::from_ts_tree(), Elapsed=972.108µs
 2023-04-27T15:51:22.533Z INFO  TimerFinished     > ast::process(), Elapsed=2.665082ms
 2023-04-27T15:51:22.534Z INFO  TimerFinished     > ast::from_ts_tree(), Elapsed=891.149µs
 2023-04-27T15:51:22.536Z INFO  TimerFinished     > ast::process(), Elapsed=2.527398ms
 2023-04-27T15:51:22.536Z INFO  TimerFinished     > diff::compute_edit_script(), Elapsed=105.815µs
 2023-04-27T15:51:22.536Z INFO  diffsitter::formatting > Detected terminal width: 253 columns
 2023-04-27T15:51:22.536Z INFO  diffsitter::formatting > Using stack style horizontal for title
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing hunk (lines 234 - 238)
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Title string has length of 11
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing line 234
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End line 234
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing line 235
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End line 235
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing line 236
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End line 236
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing line 237
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End line 237
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing line 238
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End line 238
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End hunk (lines 234 - 238)
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing hunk (lines 240 - 241)
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Title string has length of 11
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing line 240
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End line 240
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing line 241
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End line 241
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End hunk (lines 240 - 241)
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing hunk (lines 243 - 247)
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Title string has length of 11
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing line 243
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End line 243
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing line 244
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End line 244
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing line 245
/tmp/git-blob-mG4MTa/calendar.cpp -> /tmp/git-blob-L5Iuoo/calendar.cpp
======================================================================

234 - 238:
----------
+ bool calendar::is_dusk() const
+ {
+     const time_duration now = time_past_midnight(*this);
+     const time_duration sunrise = time_past_midnight(this->sunrise());
+     const time_duration sunset = time_past_midnight(this->sunset());

240 - 241:
----------
+     return  (sunset < now && now < sunset + twilight_duration) || (sunrise - twilight_duration < now && now < sunrise);
+ }

243 - 247:
----------
+ bool calendar::is_noon() const
+ {
+     const time_ 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End line 245
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing line 246
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End line 246
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing line 247
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End line 247
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End hunk (lines 243 - 247)
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing hunk (lines 249 - 250)
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Title string has length of 11
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing line 249
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End line 249
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > Printing line 250
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End line 250
 2023-04-27T15:51:22.536Z DEBUG diffsitter::formatting > End hunk (lines 249 - 250)
 2023-04-27T15:51:22.536Z INFO  TimerFinished          > formatting::print(), Elapsed=354.232µs
duration now = time_past_midnight(*this);
+     const time_duration sunrise = time_past_midnight(this->sunrise());
+     const time_duration sunset = time_past_midnight(this->sunset());

249 - 250:
----------
+     return sunrise < now && now < sunset;
+ }
 2023-04-27T15:51:22.577Z DEBUG diffsitter > Checking if /tmp/git-blob-l8uwZi/calendar.h can be parsed
 2023-04-27T15:51:22.577Z INFO  diffsitter::parse > Deduced language "c" from extension "h" from default mappings
 2023-04-27T15:51:22.577Z INFO  diffsitter::parse > Using tree-sitter parser for language c
 2023-04-27T15:51:22.577Z DEBUG diffsitter::parse > Failed to load candidate grammar for c: The program was not compiled with support for c
 2023-04-27T15:51:22.577Z ERROR diffsitter::parse > Failed to load all candidate grammars for c
 2023-04-27T15:51:22.577Z ERROR diffsitter        > Extension h not supported
Error: Unsupported file type with no fallback command specified.
 2023-04-27T15:51:22.587Z DEBUG diffsitter > Checking if /tmp/git-blob-FCCi4D/cata_tiles.cpp can be parsed
 2023-04-27T15:51:22.587Z INFO  diffsitter::parse > Deduced language "cpp" from extension "cpp" from default mappings
 2023-04-27T15:51:22.587Z INFO  diffsitter::parse > Using tree-sitter parser for language cpp
 2023-04-27T15:51:22.587Z INFO  diffsitter::parse > Succeeded loading grammar for cpp
 2023-04-27T15:51:22.587Z DEBUG diffsitter        > Checking if /tmp/git-blob-UxNGZU/cata_tiles.cpp can be parsed
 2023-04-27T15:51:22.587Z INFO  diffsitter::parse > Deduced language "cpp" from extension "cpp" from default mappings
 2023-04-27T15:51:22.587Z INFO  diffsitter::parse > Using tree-sitter parser for language cpp
 2023-04-27T15:51:22.587Z INFO  diffsitter::parse > Succeeded loading grammar for cpp
 2023-04-27T15:51:22.587Z DEBUG diffsitter        > Extensions for both input files are supported
 2023-04-27T15:51:22.587Z DEBUG diffsitter        > Reading /tmp/git-blob-FCCi4D/cata_tiles.cpp to string
 2023-04-27T15:51:22.587Z INFO  diffsitter        > Will deduce filetype from file extension
 2023-04-27T15:51:22.587Z INFO  diffsitter::parse > Deduced language "cpp" from extension "cpp" from default mappings
 2023-04-27T15:51:22.587Z INFO  diffsitter::parse > Using tree-sitter parser for language cpp
 2023-04-27T15:51:22.587Z INFO  diffsitter::parse > Succeeded loading grammar for cpp
 2023-04-27T15:51:22.587Z DEBUG diffsitter::parse > Constructed parser
 2023-04-27T15:51:22.598Z DEBUG diffsitter::parse > Parsed AST
 2023-04-27T15:51:22.598Z INFO  TimerFinished     > parse::parse_file(), Elapsed=11.02616ms
Error: stream did not contain valid UTF-8
 2023-04-27T15:51:22.610Z DEBUG diffsitter > Checking if /tmp/git-blob-1mzHdQ/cata_tiles.h can be parsed
 2023-04-27T15:51:22.610Z INFO  diffsitter::parse > Deduced language "c" from extension "h" from default mappings
 2023-04-27T15:51:22.610Z INFO  diffsitter::parse > Using tree-sitter parser for language c
 2023-04-27T15:51:22.610Z DEBUG diffsitter::parse > Failed to load candidate grammar for c: The program was not compiled with support for c
 2023-04-27T15:51:22.610Z ERROR diffsitter::parse > Failed to load all candidate grammars for c
 2023-04-27T15:51:22.610Z ERROR diffsitter        > Extension h not supported
Error: Unsupported file type with no fallback command specified.
 2023-04-27T15:51:22.619Z DEBUG diffsitter > Checking if /tmp/git-blob-0IwUlB/lightmap.h can be parsed
 2023-04-27T15:51:22.619Z INFO  diffsitter::parse > Deduced language "c" from extension "h" from default mappings
 2023-04-27T15:51:22.619Z INFO  diffsitter::parse > Using tree-sitter parser for language c
 2023-04-27T15:51:22.619Z DEBUG diffsitter::parse > Failed to load candidate grammar for c: The program was not compiled with support for c
 2023-04-27T15:51:22.619Z ERROR diffsitter::parse > Failed to load all candidate grammars for c
 2023-04-27T15:51:22.619Z ERROR diffsitter        > Extension h not supported
Error: Unsupported file type with no fallback command specified.
 2023-04-27T15:51:22.631Z DEBUG diffsitter > Checking if /tmp/git-blob-zutKhu/map.cpp can be parsed
 2023-04-27T15:51:22.631Z INFO  diffsitter::parse > Deduced language "cpp" from extension "cpp" from default mappings
 2023-04-27T15:51:22.631Z INFO  diffsitter::parse > Using tree-sitter parser for language cpp
 2023-04-27T15:51:22.631Z INFO  diffsitter::parse > Succeeded loading grammar for cpp
 2023-04-27T15:51:22.631Z DEBUG diffsitter        > Checking if /tmp/git-blob-bLry7g/map.cpp can be parsed
 2023-04-27T15:51:22.631Z INFO  diffsitter::parse > Deduced language "cpp" from extension "cpp" from default mappings
 2023-04-27T15:51:22.631Z INFO  diffsitter::parse > Using tree-sitter parser for language cpp
 2023-04-27T15:51:22.631Z INFO  diffsitter::parse > Succeeded loading grammar for cpp
 2023-04-27T15:51:22.631Z DEBUG diffsitter        > Extensions for both input files are supported
 2023-04-27T15:51:22.631Z DEBUG diffsitter        > Reading /tmp/git-blob-zutKhu/map.cpp to string
 2023-04-27T15:51:22.631Z INFO  diffsitter        > Will deduce filetype from file extension
 2023-04-27T15:51:22.631Z INFO  diffsitter::parse > Deduced language "cpp" from extension "cpp" from default mappings
 2023-04-27T15:51:22.631Z INFO  diffsitter::parse > Using tree-sitter parser for language cpp
 2023-04-27T15:51:22.631Z INFO  diffsitter::parse > Succeeded loading grammar for cpp
 2023-04-27T15:51:22.631Z DEBUG diffsitter::parse > Constructed parser
 2023-04-27T15:51:22.659Z DEBUG diffsitter::parse > Parsed AST
 2023-04-27T15:51:22.659Z INFO  TimerFinished     > parse::parse_file(), Elapsed=28.538961ms
 2023-04-27T15:51:22.660Z DEBUG diffsitter        > Reading /tmp/git-blob-bLry7g/map.cpp to string
 2023-04-27T15:51:22.660Z INFO  diffsitter        > Will deduce filetype from file extension
 2023-04-27T15:51:22.660Z INFO  diffsitter::parse > Deduced language "cpp" from extension "cpp" from default mappings
 2023-04-27T15:51:22.660Z INFO  diffsitter::parse > Using tree-sitter parser for language cpp
 2023-04-27T15:51:22.660Z INFO  diffsitter::parse > Succeeded loading grammar for cpp
 2023-04-27T15:51:22.660Z DEBUG diffsitter::parse > Constructed parser
 2023-04-27T15:51:22.688Z DEBUG diffsitter::parse > Parsed AST
 2023-04-27T15:51:22.688Z INFO  TimerFinished     > parse::parse_file(), Elapsed=28.291725ms
 2023-04-27T15:51:22.698Z INFO  TimerFinished     > ast::from_ts_tree(), Elapsed=10.144177ms
 2023-04-27T15:51:22.713Z INFO  TimerFinished     > ast::process(), Elapsed=25.464658ms
 2023-04-27T15:51:22.723Z INFO  TimerFinished     > ast::from_ts_tree(), Elapsed=9.756224ms
 2023-04-27T15:51:22.739Z INFO  TimerFinished     > ast::process(), Elapsed=25.519236ms
 2023-04-27T15:51:22.742Z INFO  TimerFinished     > diff::compute_edit_script(), Elapsed=2.833481ms
 2023-04-27T15:51:22.742Z INFO  diffsitter::formatting > Detected terminal width: 253 columns
 2023-04-27T15:51:22.742Z INFO  diffsitter::formatting > Using stack style horizontal for title
 2023-04-27T15:51:22.742Z DEBUG diffsitter::formatting > Printing hunk (lines 5748 - 5751)
 2023-04-27T15:51:22.742Z DEBUG diffsitter::formatting > Title string has length of 13
 2023-04-27T15:51:22.742Z DEBUG diffsitter::formatting > Printing line 5748
 2023-04-27T15:51:22.742Z TRACE os_info::imp           > linux::current_platform is called
 2023-04-27T15:51:22.788Z TRACE os_info::imp::lsb_release > lsb_release command returned Output { status: ExitStatus(unix_wait_status(0)), stdout: "LSB Version:\tcore-11.2ubuntu1-noarch:security-11.2ubuntu1-noarch\nDistributor ID:\tUbuntu\nDescription:\tUbuntu 22.10\nRelease:\t22.10\nCodename:\tkinetic\n", stderr: "" }
 2023-04-27T15:51:22.788Z TRACE os_info::imp::lsb_release > Trying to parse "LSB Version:\tcore-11.2ubuntu1-noarch:security-11.2ubuntu1-noarch\nDistributor ID:\tUbuntu\nDescription:\tUbuntu 22.10\nRelease:\t22.10\nCodename:\tkinetic\n"
 2023-04-27T15:51:22.788Z TRACE os_info::imp::lsb_release > Parsed as 'Some("Ubuntu")' distribution and 'Some("22.10")' version
 2023-04-27T15:51:22.789Z TRACE os_info::imp              > Returning Info { os_type: Ubuntu, version: Version { version: Custom("22.10"), edition: None }, bitness: X64 }
Well, this is embarrassing.

diffsitter had a problem and crashed. To help us diagnose the problem you can send us a crash report.

We have generated a report file at "/tmp/report-811f0bf2-8ba8-4502-9b89-9a2300fadad6.toml". Submit an issue or email with the subject of "diffsitter Crash Report" and include the report as an attachment.

- Homepage: https://github.com/afnanenayet/diffsitter
- Authors: Afnan Enayet <[email protected]>

We take privacy seriously, and do not perform any automated error collection. In order to improve the software, we rely on people to submit reports.

Thank you kindly!
 2023-04-27T15:51:22.832Z INFO  TimerFinished             > formatting::print(), Elapsed=90.625644ms
/tmp/git-blob-zutKhu/map.cpp -> /tmp/git-blob-bLry7g/map.cpp
============================================================

5748 - 5751:
------------
+     /*if (apparent_light > 1) {⏎  

Platform:
Operating System: Kubuntu 22.10
Kernel Version: 6.3.0-060300-generic (64-bit)

Additional context
generated code report
report.toml.tar.gz

[BUG] build error with `dynamic-grammar-libs`

Describe the bug
Build fails when compiling with dynamic grammars and not static grammars.

To Reproduce
Steps to reproduce the behavior:

cargo build --no-default-features --features dynamic-grammar-libs

Expected behavior
A clear and concise description of what you expected to happen.
diffsitter should build as normal.

Log output/screenshots
Please provide the output with the --debug flag

   Compiling libc v0.2.109
   Compiling proc-macro2 v1.0.33
   Compiling unicode-xid v0.2.2
   Compiling syn v1.0.82
   Compiling cfg-if v1.0.0
   Compiling autocfg v1.0.1
   Compiling crossbeam-utils v0.8.5
   Compiling ppv-lite86 v0.2.15
   Compiling version_check v0.9.3
   Compiling lazy_static v1.4.0
   Compiling memchr v2.4.1
   Compiling crossbeam-epoch v0.9.5
   Compiling siphasher v0.3.7
   Compiling proc-macro-hack v0.5.19
   Compiling scopeguard v1.1.0
   Compiling proc-macro2 v0.4.30
   Compiling anyhow v1.0.51
   Compiling rayon-core v1.9.1
   Compiling regex-syntax v0.6.25
   Compiling log v0.4.14
   Compiling ucd-trie v0.1.3
   Compiling serde_derive v1.0.130
   Compiling unicode-xid v0.1.0
   Compiling serde v1.0.130
   Compiling unicode-width v0.1.9
   Compiling maplit v1.0.2
   Compiling syn v0.15.44
   Compiling unicode-segmentation v1.8.0
   Compiling ryu v1.0.6
   Compiling quick-error v1.2.3
   Compiling rustversion v1.0.6
   Compiling either v1.6.1
   Compiling vec_map v0.8.2
   Compiling ansi_term v0.12.1
   Compiling paw-raw v1.0.0
   Compiling serde_json v1.0.72
   Compiling cargo-emit v0.2.1
   Compiling strsim v0.8.0
   Compiling bitflags v1.3.2
   Compiling termcolor v1.1.2
   Compiling once_cell v1.8.0
   Compiling itoa v0.4.8
   Compiling strum v0.23.0
   Compiling memoffset v0.6.5
   Compiling rayon v1.5.1
   Compiling proc-macro-error-attr v1.0.4
   Compiling proc-macro-error v1.0.4
   Compiling phf_shared v0.10.0
   Compiling pest v2.1.3
   Compiling libloading v0.7.2
   Compiling textwrap v0.11.0
   Compiling humantime v1.3.0
   Compiling heck v0.3.3
   Compiling crossbeam-channel v0.5.1
   Compiling pest_meta v2.1.3
   Compiling aho-corasick v0.7.18
   Compiling atty v0.2.14
   Compiling dirs-sys v0.3.6
   Compiling terminal_size v0.1.17
   Compiling getrandom v0.2.3
   Compiling jobserver v0.1.24
   Compiling num_cpus v1.13.0
   Compiling quote v1.0.10
   Compiling quote v0.6.13
   Compiling clap v2.34.0
   Compiling dirs v3.0.2
   Compiling rand_core v0.6.3
   Compiling cc v1.0.72
   Compiling regex v1.5.4
   Compiling xdg v2.4.0
   Compiling rand_chacha v0.3.1
   Compiling crossbeam-deque v0.8.1
   Compiling env_logger v0.7.1
   Compiling console v0.15.0
   Compiling tree-sitter v0.20.1
   Compiling rand v0.8.4
   Compiling pretty_env_logger v0.4.0
   Compiling phf_generator v0.10.0
   Compiling pest_generator v2.1.3
   Compiling logging_timer_proc_macros v1.0.0
   Compiling logging_timer v1.0.0
   Compiling phf_macros v0.10.0
   Compiling thiserror-impl v1.0.30
   Compiling paw-attributes v1.0.2
   Compiling structopt-derive v0.4.18
   Compiling pest_derive v2.1.0
   Compiling strum_macros v0.23.1
   Compiling paw v1.0.0
   Compiling phf v0.10.0
   Compiling thiserror v1.0.30
   Compiling structopt v0.3.25
   Compiling diffsitter v0.6.7 (/build/diffsitter/src/diffsitter)
error[E0433]: failed to resolve: use of undeclared type `GrammarCompileInfo`
   --> build.rs:228:15
    |
228 |             ..GrammarCompileInfo::default()
    |               ^^^^^^^^^^^^^^^^^^ use of undeclared type `GrammarCompileInfo`

error[E0433]: failed to resolve: use of undeclared type `GrammarCompileInfo`
   --> build.rs:258:15
    |
258 |             ..GrammarCompileInfo::default()
    |               ^^^^^^^^^^^^^^^^^^ use of undeclared type `GrammarCompileInfo`

error[E0433]: failed to resolve: use of undeclared type `GrammarCompileInfo`
   --> build.rs:270:15
    |
270 |             ..GrammarCompileInfo::default()
    |               ^^^^^^^^^^^^^^^^^^ use of undeclared type `GrammarCompileInfo`

error[E0433]: failed to resolve: use of undeclared type `GrammarCompileInfo`
   --> build.rs:276:15
    |
276 |             ..GrammarCompileInfo::default()
    |               ^^^^^^^^^^^^^^^^^^ use of undeclared type `GrammarCompileInfo`

error[E0433]: failed to resolve: use of undeclared type `GrammarCompileInfo`
   --> build.rs:282:15
    |
282 |             ..GrammarCompileInfo::default()
    |               ^^^^^^^^^^^^^^^^^^ use of undeclared type `GrammarCompileInfo`

error[E0433]: failed to resolve: use of undeclared type `GrammarCompileInfo`
   --> build.rs:294:15
    |
294 |             ..GrammarCompileInfo::default()
    |               ^^^^^^^^^^^^^^^^^^ use of undeclared type `GrammarCompileInfo`

error[E0412]: cannot find type `GrammarCompileInfo` in this scope
   --> build.rs:222:22
    |
222 | fn grammars() -> Vec<GrammarCompileInfo<'static>> {
    |                      ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:224:9
    |
224 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:226:19
    |
226 |             path: PathBuf::from("grammars/tree-sitter-rust"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:230:9
    |
230 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:232:19
    |
232 |             path: PathBuf::from("grammars/tree-sitter-cpp"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:236:9
    |
236 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:238:19
    |
238 |             path: PathBuf::from("grammars/tree-sitter-python"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:242:9
    |
242 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:244:19
    |
244 |             path: PathBuf::from("grammars/tree-sitter-bash"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:248:9
    |
248 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:250:19
    |
250 |             path: PathBuf::from("grammars/tree-sitter-ocaml/ocaml"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:254:9
    |
254 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:256:19
    |
256 |             path: PathBuf::from("grammars/tree-sitter-go"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:260:9
    |
260 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:262:19
    |
262 |             path: PathBuf::from("grammars/tree-sitter-ruby"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:266:9
    |
266 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:268:19
    |
268 |             path: PathBuf::from("grammars/tree-sitter-java"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:272:9
    |
272 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:274:19
    |
274 |             path: PathBuf::from("grammars/tree-sitter-c-sharp"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:278:9
    |
278 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:280:19
    |
280 |             path: PathBuf::from("grammars/tree-sitter-css"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:284:9
    |
284 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:286:19
    |
286 |             path: PathBuf::from("grammars/tree-sitter-php"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:290:9
    |
290 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:292:19
    |
292 |             path: PathBuf::from("grammars/tree-sitter-json"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:296:9
    |
296 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:298:19
    |
298 |             path: PathBuf::from("grammars/tree-sitter-hcl"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:302:9
    |
302 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:304:19
    |
304 |             path: PathBuf::from("grammars/tree-sitter-typescript/typescript"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

error[E0422]: cannot find struct, variant or union type `GrammarCompileInfo` in this scope
   --> build.rs:308:9
    |
308 |         GrammarCompileInfo {
    |         ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0433]: failed to resolve: use of undeclared type `PathBuf`
   --> build.rs:310:19
    |
310 |             path: PathBuf::from("grammars/tree-sitter-typescript/tsx"),
    |                   ^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
22  | use std::path::PathBuf;
    |

Some errors have detailed explanations: E0412, E0422, E0433.
For more information about an error, try `rustc --explain E0412`.
error: could not compile `diffsitter` due to 37 previous errors
warning: build failed, waiting for other jobs to finish...
error: build failed
�[1m�[31m==> ERROR:�(B�[m�[1m A failure occurred in build().�(B�[m
�[1m    Aborting...�(B�[m

Platform:
MacOS, Linux

Additional context
Filing behalf of @lmartinez-mirror from this comment: #167 (comment)

[BUG] Homebrew broken?

Describe the bug

brew tap afnanenayet/tap
brew install diffsitter
==> Fetching afnanenayet/tap/diffsitter
==> Downloading https://github.com/afnanenayet/diffsitter/releases/download/v0.8.0/diffsitter-aarch64-apple-darwin.tar.gz
Already downloaded: /Users/deniz/Library/Caches/Homebrew/downloads/cc8a65cb5f87749cbf24af6649eb83ab0eedd0dc9b1aa57f2f9a30982eaacd06--diffsitter-aarch64-apple-darwin.tar.gz
==> Installing diffsitter from afnanenayet/tap
Error: An exception occurred within a child process:
  Errno::ENOENT: No such file or directory - git-diffsitter

Is this a misconfiguration on my side? Or is something borked with the distribution on Homebrew?

Additional context

brew --version
Homebrew 4.0.24-44-g8759f07sw_vers
ProductName:		macOS
ProductVersion:		13.4
BuildVersion:		22F66

[BUG] Out of bounds index diffing Go code

Describe the bug
I get an out of bounds index error when diffing Go code:

thread 'main' panicked at 'byte index 6 is out of bounds of `   do()`', src/formatting.rs:403:43

To Reproduce

Have a file a.go:

package main

import "fmt"

func main() {
	b := "string"
	fmt.Println(b)
	c := "hi"
	fmt.Println(c)
}

Have a file b.go:

package main

import "fmt"

func main() {
	do()
}

func do() {
	b := "string"
	fmt.Println(b)
	c := "hi"
	fmt.Println(c)
}

Run the following to see the error:

$ env RUST_BACKTRACE=1 cargo run --package diffsitter --bin diffsitter a.go b.go
   Compiling diffsitter v0.7.1 (/Users/ekilmer/src/diffsitter)
    Finished dev [unoptimized + debuginfo] target(s) in 1.44s
     Running `target/debug/diffsitter a.go b.go`
thread 'main' panicked at 'byte index 6 is out of bounds of `   do()`', src/formatting.rs:403:43
stack backtrace:
   0: rust_begin_unwind
             at /rustc/0da281b6068a7d889ae89a9bd8991284cc9b7535/library/std/src/panicking.rs:575:5
   1: core::panicking::panic_fmt
             at /rustc/0da281b6068a7d889ae89a9bd8991284cc9b7535/library/core/src/panicking.rs:65:14
   2: core::str::slice_error_fail_rt
   3: core::str::slice_error_fail
             at /rustc/0da281b6068a7d889ae89a9bd8991284cc9b7535/library/core/src/str/mod.rs:86:9
   4: core::str::traits::<impl core::slice::index::SliceIndex<str> for core::ops::range::Range<usize>>::index
             at /rustc/0da281b6068a7d889ae89a9bd8991284cc9b7535/library/core/src/str/traits.rs:218:21
   5: core::str::traits::<impl core::ops::index::Index<I> for str>::index
             at /rustc/0da281b6068a7d889ae89a9bd8991284cc9b7535/library/core/src/str/traits.rs:65:9
   6: diffsitter::formatting::DiffWriter::print_line
             at ./src/formatting.rs:403:43
   7: diffsitter::formatting::DiffWriter::print_hunk
             at ./src/formatting.rs:354:13
   8: diffsitter::formatting::DiffWriter::print
             at ./src/formatting.rs:227:21
   9: diffsitter::run_diff
             at ./src/main.rs:182:5
  10: diffsitter::main
             at ./src/main.rs:275:13
  11: core::ops::function::FnOnce::call_once
             at /rustc/0da281b6068a7d889ae89a9bd8991284cc9b7535/library/core/src/ops/function.rs:251:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
a.go -> b.go
============

5 - 8:
------
+       do()

Expected behavior
I expect no error and a diff.

Log output/screenshots
See above

Platform:
OS: macOS 13.0
Rust: rustc 1.66.0-nightly (0da281b60 2022-10-27)

Additional context
I was able to debug and make a patch that allows the tool to finish without crashing. I'm not very familiar with Rust or this project, so this patch could probably use some improvement.

Patch:

diff --git a/src/formatting.rs b/src/formatting.rs
index 00d822b..f5077cf 100644
--- a/src/formatting.rs
+++ b/src/formatting.rs
@@ -388,6 +388,9 @@ fn print_line(
 
         // We keep printing ranges until we've covered the entire line
         for entry in &line.entries {
+            if entry.text.eq_ignore_ascii_case("\n") || entry.text.eq_ignore_ascii_case("\r") {
+                continue;
+            }
             // The range of text to emphasize
             // TODO(afnan) deal with ranges spanning multiple rows
             let emphasis_range = entry.start_position().column..entry.end_position().column;

Output with patch:

$ cargo run --package diffsitter --bin diffsitter a.go b.go
    Finished dev [unoptimized + debuginfo] target(s) in 0.17s
     Running `target/debug/diffsitter a.go b.go`
a.go -> b.go
============

5 - 8:
------
+       do()
+ }
+
+ func do() {

color256 variant doesn't work in config

The Color struct is an enum that supports colors as well as a 256 bit color value. The TOML format currently doesn't seem to support the 256 bit color option.

Hashicorp Config Language (HCL) support

This project is super useful and I am trying to work it into my workflow.

I live in HCL, the language of Terraform, a lot of the time, and it would be awesome to be able to compare HCL changes with this AST-aware method.

I'm aware the tree-sitter project does not presently support HCL. Should I push an issue up there, and link it here, or something like that?

Check validity of selected renderer up front

Right now diffsitter parses and computes the diffs for documents before checking whether the selected renderer is valid (and whether the custom renderer map is valid). This check should be performed early so the program can exit with an error without delay.

How diffsitter works, How performant it is and What cases are exemplatory good and bad

Difftastic has a complete section dedicated what methods it uses, but has the performance not written in the repo but in the inspired projects:
https://github.com/Wilfred/difftastic#how-it-works
Could you elaborate what algorithm you use for the diff? A* and dijkstra for graph difference are the most prominent ones, where A* is much more performant on multiple changes (in a function) but has overall worse results.

Performance of examples (ideally with benchmarks), Known problems and Non-Goals would complete the first impression.

I am asking due for an evaluation of neovim what to use, but I am not affiliated or core member (only neovim user) and would like to see things moving forward.

diffsitter_src.tar.gz is not a gzipped tar and there’s no top-level directory

The file name suggests that it’s a gzipped tar, but it’s not. It’s also a well established practice to put all files in a tarball under the top-level directory which name corresponds to the tarball name (e.g. diffsitter_src.tar.gz -> diffsitter_src).

$ wget https://github.com/afnanenayet/diffsitter/releases/download/v0.6.8/diffsitter_src.tar.gz

$ tar -xzf diffsitter_src.tar.gz
gzip: invalid magic
tar: Child returned status 1
tar: Error is not recoverable: exiting now

$ file diffsitter_src.tar.gz
diffsitter_src.tar.gz: POSIX tar archive

$ tar -xf diffsitter_src.tar.gz

$ ls -1
CODEOWNERS
Cargo.lock
Cargo.toml
Cross.toml
LICENSE
README.md
assets
bin
build.rs
clippy.toml
deployment
docs
grammars
rustfmt.toml
src
test_data

[BUG] Subdirectory for grammar rust was not found

Describe the bug

Building diffsitter yields the following error:

error: failed to run custom build command for `diffsitter v0.7.2 (/usr/pkgsrc/wip/diffsitter/work/diffsitter-0.7.2)`

Caused by:
  process didn't exit successfully: `/usr/pkgsrc/wip/diffsitter/work/diffsitter-0.7.2/target/release/build/diffsitter-b2fc85f3d27f4d0e/build-script-build` (exit status: 1)
  --- stderr
  Error: Subdirectory for grammar rust was not found
warning: build failed, waiting for other jobs to finish...
*** Error code 101

Stop.

To Reproduce
Steps to reproduce the behavior:

  1. Build diffsitter on NetBSD

Expected behavior
Complete build.

Log output/screenshots
See above

Platform:
OS: NetBSD-9.99.107, Rust-1.65.0

Additional context
Build in offline-mode.

[BUG] build script does not rerun if the grammar subdirectory changes

The build script currently only tells Cargo to rerun if each of the directories for an already registered grammar changes, not if the grammar subdirectory itself changes. It should emit an instruction to rerun if the grammars subdirectory changes at all to stay on the safe side.

[BUG] `"exclude-kinds": ["string"]` does not work for Python

Describe the bug
I found that "exclude-kinds": ["string"] does not work for Python strings (e.g., doc string and strings in assignments). Please correct me if my configuration is incorrect.

To Reproduce

  • old.py:
a = "b"
  • new.py:
a = "a"

Comparing them with the config file to exclude strings

Expected behavior

No diff should be found.

Log output/screenshots

=================================================================

0:
--
+a = "a"

0:
--
-a = "b"

Platform:
OS: Linux

Additional context

After diving deep into the source code, I tried to add debug output in function should_include_node at input_processing.rs. I add a line to print the kind out:

        debug!("node: kind: {:?}", node.kind());

The log looks like this:

 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::input_processing > node: kind: "identifier"
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::input_processing > node: kind: "="
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::input_processing > node: kind: "string_start"
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::input_processing > node: kind: "string_content"
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::input_processing > node: kind: "string_end"
 2024-03-05T04:23:16.289Z INFO  TimerFinished                   > ast::process(), Elapsed=54.622µs
 2024-03-05T04:23:16.289Z INFO  TimerFinished                   > ast::from_ts_tree(), Elapsed=5.999µs
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::input_processing > node: kind: "identifier"
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::input_processing > node: kind: "="
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::input_processing > node: kind: "string_start"
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::input_processing > node: kind: "string_content"
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::input_processing > node: kind: "string_end"
 2024-03-05T04:23:16.289Z INFO  TimerFinished                   > ast::process(), Elapsed=35.604µs
 2024-03-05T04:23:16.289Z INFO  TimerFinished                   > diff::compute_edit_script(), Elapsed=12.949µs
 2024-03-05T04:23:16.289Z INFO  libdiffsitter::render::unified  > Using stack style vertical for title
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::render::unified  > Printing hunk (lines 0 - 0)
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::render::unified  > Title string has length of 3
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::render::unified  > Printing line 0
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::render::unified  > End line 0
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::render::unified  > End hunk (lines 0 - 0)
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::render::unified  > Printing hunk (lines 0 - 0)
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::render::unified  > Title string has length of 3
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::render::unified  > Printing line 0
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::render::unified  > End line 0
 2024-03-05T04:23:16.289Z DEBUG libdiffsitter::render::unified  > End hunk (lines 0 - 0)

It looks like there is no kind string for the nodes, and changing string to string_content in the config file leads me to the expected output. I'm not sure if this is the expected behavior, but I assume it's not, as the README specifies string to be excluded.

Please let me know if further information is needed. Thanks!

diffsitter should check the tree-sitter language version and report a better error upon mismatch

The tree-sitter grammars define ABI versions so that you can make sure a dynamically loaded grammar works with whatever version of the tree-sitter library you're using. It seems like right now if we have a mismatch the program will segfault which is a horrible UX.

We should try to check the version and post a more informative error to the user telling them that the grammar tree-sitter is trying to load is not compatible with the version of the library that 's bundled in diffsitter.

This is handles #763

Add support for git diff

Is your feature request related to a problem? Please describe.
Tools like https://github.com/jeffkaufman/icdiff are able to act like a git diff viewer. Diffsitter would be exceptionally good for that purpose.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Can be achieve manually via diffsitter <(git show hashA:myFile) <(git show hashB:myFile)

Grammar associations don't work from root key

It seems like our grammar associations don't work from the root key. Either make it work or update the docs to make it clear to users how to configure things properly.

          Running `diffsitter` `0.8.1` on macOS via homebrew:
⇒ diffsitter --version
diffsitter 0.8.1

It lists support for typescript / tsx:

⇒ diffsitter list
This program was compiled with support for:
- bash
- c_sharp
- cpp
- css
- go
- hcl
- java
- json
- ocaml
- php
- python
- ruby
- rust
- tsx
- typescript

Yet by default, it will fail to run against a JavaScript file:

⇒ git difftool --tool diffsitter HEAD~1 HEAD -- unpacked/_next/static/\[buildHash\]/_buildManifest.js
Error: Unsupported file type with no fallback command specified.

Until a file-association override is added to the config (${XDG_HOME:-$HOME}/.config/diffsitter/config.json5):

// ..snip..
  "grammar": {
    "dylib-overrides": null,
    "file-associations": {
      "js": "typescript",
      "jsx": "tsx"
    },
  },
// ..snip..

This would seem like a useful thing to be included in the default config that diffsitter uses:

⇒ diffsitter dump-default-config
{
  "file-associations": null,
  "formatting": {
    "default": "unified",
    "unified": {
      "addition": {
        "highlight": null,
        "regular-foreground": "green",
        "emphasized-foreground": "green",
        "bold": true,
        "underline": false,
        "prefix": "+ "
      },
      "deletion": {
        "highlight": null,
        "regular-foreground": "red",
        "emphasized-foreground": "red",
        "bold": true,
        "underline": false,
        "prefix": "- "
      }
    },
    "json": {
      "pretty_print": false
    },
    "custom": {}
  },
  "grammar": {
    "dylib-overrides": null,
    "file-associations": null
  },
  "input-processing": {
    "split-graphemes": true,
    "exclude-kinds": null,
    "include-kinds": null
  },
  "fallback-cmd": null
}

I also noted that modifying that default config to add the file-associations to the root key didn't seem to work; it only seemed to work when I added them to the grammar version of file-associations.

Originally posted by @0xdevalias in #152 (comment)

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.