Side-by-side semantic diff tool with theme support and hookable integration
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: screenshotting

+169 -139
docs/screenshot.png

This is a binary file and will not be displayed.

-11
docs/screenshot.tape
··· 1 - Output docs/screenshot.png 2 - 3 - Set Width 220 4 - Set Height 36 5 - Set Theme "nord" 6 - Set FontSize 13 7 - Set Padding 8 8 - 9 - Type "./result/bin/sdiff docs/demo_old.go docs/demo_new.go" 10 - Enter 11 - Sleep 800ms
+169 -128
flake.nix
··· 2 2 description = "sdiff — semantic side-by-side diff TUI"; 3 3 4 4 inputs = { 5 - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 5 + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 6 flake-parts.url = "github:hercules-ci/flake-parts"; 7 7 }; 8 8 9 - outputs = inputs@{ self, flake-parts, ... }: 10 - flake-parts.lib.mkFlake { inherit inputs; } { 11 - flake.overlays.default = final: _prev: 12 - { sdiff = self.packages.${final.system}.default; }; 9 + outputs = inputs @ { 10 + self, 11 + flake-parts, 12 + ... 13 + }: 14 + flake-parts.lib.mkFlake {inherit inputs;} { 15 + flake.overlays.default = final: _prev: {sdiff = self.packages.${final.system}.default;}; 16 + 17 + systems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin"]; 13 18 14 - systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; 19 + perSystem = {pkgs, ...}: let 20 + # ── C source trees for each tree-sitter grammar ────────────────── 21 + # go-tree-sitter bundles the tree-sitter C library under include/ and src/. 22 + # Tag v0.25.0 has no GitHub release tarball, so we pin by commit. 23 + src-go-tree-sitter = pkgs.fetchFromGitHub { 24 + owner = "tree-sitter"; 25 + repo = "go-tree-sitter"; 26 + rev = "adc13ffd8b2c0b01b878fda9f7c422ce0df5fad3"; # v0.25.0 27 + hash = "sha256-DVVhHQy0AEVyCig18JhlTVgttWaHJWRPdTSfwfFuKAk="; 28 + }; 29 + src-ts-go = pkgs.fetchFromGitHub { 30 + owner = "tree-sitter"; 31 + repo = "tree-sitter-go"; 32 + rev = "v0.25.0"; 33 + hash = "sha256-y7bTET8ypPczPnMVlCaiZuswcA7vFrDOc2jlbfVk5Sk="; 34 + }; 35 + src-ts-javascript = pkgs.fetchFromGitHub { 36 + owner = "tree-sitter"; 37 + repo = "tree-sitter-javascript"; 38 + rev = "v0.25.0"; 39 + hash = "sha256-2Jj/SUG+k8lHlGSuPZvHjJojvQFgDiZHZzH8xLu7suE="; 40 + }; 41 + src-ts-python = pkgs.fetchFromGitHub { 42 + owner = "tree-sitter"; 43 + repo = "tree-sitter-python"; 44 + rev = "v0.25.0"; 45 + hash = "sha256-F5XH21PjPpbwYylgKdwD3MZ5o0amDt4xf/e5UikPcxY="; 46 + }; 47 + src-ts-rust = pkgs.fetchFromGitHub { 48 + owner = "tree-sitter"; 49 + repo = "tree-sitter-rust"; 50 + rev = "v0.24.2"; 51 + hash = "sha256-Ls6tB6IxXDQDWwx0BJ7RgbheelC4MH8z97E7wwhkDcY="; 52 + }; 53 + src-ts-c = pkgs.fetchFromGitHub { 54 + owner = "tree-sitter"; 55 + repo = "tree-sitter-c"; 56 + rev = "v0.24.1"; 57 + hash = "sha256-gmzbdwvrKSo6C1fqTJFGxy8x0+T+vUTswm7F5sojzKc="; 58 + }; 59 + src-ts-cpp = pkgs.fetchFromGitHub { 60 + owner = "tree-sitter"; 61 + repo = "tree-sitter-cpp"; 62 + rev = "v0.23.4"; 63 + hash = "sha256-tP5Tu747V8QMCEBYwOEmMQUm8OjojpJdlRmjcJTbe2k="; 64 + }; 65 + src-ts-bash = pkgs.fetchFromGitHub { 66 + owner = "tree-sitter"; 67 + repo = "tree-sitter-bash"; 68 + rev = "v0.25.1"; 69 + hash = "sha256-ONQ1Ljk3aRWjElSWD2crCFZraZoRj3b3/VELz1789GE="; 70 + }; 71 + src-ts-json = pkgs.fetchFromGitHub { 72 + owner = "tree-sitter"; 73 + repo = "tree-sitter-json"; 74 + rev = "v0.24.8"; 75 + hash = "sha256-DNZC2cTy1C8OaMOpEHM6NoRtOIbLaBf0CLXXWCKODlw="; 76 + }; 77 + # TypeScript grammar bundles both typescript/ and tsx/ subdirectories 78 + src-ts-typescript = pkgs.fetchFromGitHub { 79 + owner = "tree-sitter"; 80 + repo = "tree-sitter-typescript"; 81 + rev = "v0.23.2"; 82 + hash = "sha256-CU55+YoFJb6zWbJnbd38B7iEGkhukSVpBN7sli6GkGY="; 83 + }; 84 + src-ts-ruby = pkgs.fetchFromGitHub { 85 + owner = "tree-sitter"; 86 + repo = "tree-sitter-ruby"; 87 + rev = "v0.23.1"; 88 + hash = "sha256-iu3MVJl0Qr/Ba+aOttmEzMiVY6EouGi5wGOx5ofROzA="; 89 + }; 90 + src-ts-nix = pkgs.fetchFromGitHub { 91 + owner = "nix-community"; 92 + repo = "tree-sitter-nix"; 93 + rev = "v0.3.0"; 94 + hash = "sha256-VNOPzeyhh/0jHzK0bwEX1kwSIUGoSlCXGhgjHbYvWKk="; 95 + }; 96 + in { 97 + packages.default = pkgs.buildGoModule { 98 + pname = "sdiff"; 99 + version = "0.1.0"; 100 + src = ./.; 15 101 16 - perSystem = { pkgs, ... }: 17 - let 18 - # ── C source trees for each tree-sitter grammar ────────────────── 19 - # go-tree-sitter bundles the tree-sitter C library under include/ and src/. 20 - # Tag v0.25.0 has no GitHub release tarball, so we pin by commit. 21 - src-go-tree-sitter = pkgs.fetchFromGitHub { 22 - owner = "tree-sitter"; repo = "go-tree-sitter"; 23 - rev = "adc13ffd8b2c0b01b878fda9f7c422ce0df5fad3"; # v0.25.0 24 - hash = "sha256-DVVhHQy0AEVyCig18JhlTVgttWaHJWRPdTSfwfFuKAk="; 25 - }; 26 - src-ts-go = pkgs.fetchFromGitHub { 27 - owner = "tree-sitter"; repo = "tree-sitter-go"; rev = "v0.25.0"; 28 - hash = "sha256-y7bTET8ypPczPnMVlCaiZuswcA7vFrDOc2jlbfVk5Sk="; 29 - }; 30 - src-ts-javascript = pkgs.fetchFromGitHub { 31 - owner = "tree-sitter"; repo = "tree-sitter-javascript"; rev = "v0.25.0"; 32 - hash = "sha256-2Jj/SUG+k8lHlGSuPZvHjJojvQFgDiZHZzH8xLu7suE="; 33 - }; 34 - src-ts-python = pkgs.fetchFromGitHub { 35 - owner = "tree-sitter"; repo = "tree-sitter-python"; rev = "v0.25.0"; 36 - hash = "sha256-F5XH21PjPpbwYylgKdwD3MZ5o0amDt4xf/e5UikPcxY="; 37 - }; 38 - src-ts-rust = pkgs.fetchFromGitHub { 39 - owner = "tree-sitter"; repo = "tree-sitter-rust"; rev = "v0.24.2"; 40 - hash = "sha256-Ls6tB6IxXDQDWwx0BJ7RgbheelC4MH8z97E7wwhkDcY="; 41 - }; 42 - src-ts-c = pkgs.fetchFromGitHub { 43 - owner = "tree-sitter"; repo = "tree-sitter-c"; rev = "v0.24.1"; 44 - hash = "sha256-gmzbdwvrKSo6C1fqTJFGxy8x0+T+vUTswm7F5sojzKc="; 45 - }; 46 - src-ts-cpp = pkgs.fetchFromGitHub { 47 - owner = "tree-sitter"; repo = "tree-sitter-cpp"; rev = "v0.23.4"; 48 - hash = "sha256-tP5Tu747V8QMCEBYwOEmMQUm8OjojpJdlRmjcJTbe2k="; 49 - }; 50 - src-ts-bash = pkgs.fetchFromGitHub { 51 - owner = "tree-sitter"; repo = "tree-sitter-bash"; rev = "v0.25.1"; 52 - hash = "sha256-ONQ1Ljk3aRWjElSWD2crCFZraZoRj3b3/VELz1789GE="; 53 - }; 54 - src-ts-json = pkgs.fetchFromGitHub { 55 - owner = "tree-sitter"; repo = "tree-sitter-json"; rev = "v0.24.8"; 56 - hash = "sha256-DNZC2cTy1C8OaMOpEHM6NoRtOIbLaBf0CLXXWCKODlw="; 57 - }; 58 - # TypeScript grammar bundles both typescript/ and tsx/ subdirectories 59 - src-ts-typescript = pkgs.fetchFromGitHub { 60 - owner = "tree-sitter"; repo = "tree-sitter-typescript"; rev = "v0.23.2"; 61 - hash = "sha256-CU55+YoFJb6zWbJnbd38B7iEGkhukSVpBN7sli6GkGY="; 62 - }; 63 - src-ts-ruby = pkgs.fetchFromGitHub { 64 - owner = "tree-sitter"; repo = "tree-sitter-ruby"; rev = "v0.23.1"; 65 - hash = "sha256-iu3MVJl0Qr/Ba+aOttmEzMiVY6EouGi5wGOx5ofROzA="; 66 - }; 67 - src-ts-nix = pkgs.fetchFromGitHub { 68 - owner = "nix-community"; repo = "tree-sitter-nix"; rev = "v0.3.0"; 69 - hash = "sha256-VNOPzeyhh/0jHzK0bwEX1kwSIUGoSlCXGhgjHbYvWKk="; 70 - }; 102 + vendorHash = null; 71 103 72 - in { 73 - packages.default = pkgs.buildGoModule { 74 - pname = "sdiff"; 75 - version = "0.1.0"; 76 - src = ./.; 104 + CC = "${pkgs.clang}/bin/clang"; 105 + nativeBuildInputs = [pkgs.clang]; 106 + env.CGO_ENABLED = "1"; 77 107 78 - vendorHash = null; 108 + # Copy C source files into vendor before the Go build runs. 109 + # go mod vendor only copies .go files; CGO bindings reference C sources 110 + # via relative paths (e.g. ../../src/parser.c), so we copy them here. 111 + preBuild = '' 112 + vendor=vendor/github.com/tree-sitter 79 113 80 - CC = "${pkgs.clang}/bin/clang"; 81 - nativeBuildInputs = [ pkgs.clang ]; 82 - env.CGO_ENABLED = "1"; 114 + # go-tree-sitter bundles the tree-sitter C library (include/ + src/) 115 + cp -r ${src-go-tree-sitter}/include $vendor/go-tree-sitter/include 116 + cp -r ${src-go-tree-sitter}/src $vendor/go-tree-sitter/src 83 117 84 - # Copy C source files into vendor before the Go build runs. 85 - # go mod vendor only copies .go files; CGO bindings reference C sources 86 - # via relative paths (e.g. ../../src/parser.c), so we copy them here. 87 - preBuild = '' 88 - vendor=vendor/github.com/tree-sitter 118 + # Grammar C sources (most grammars expose src/parser.c [+ scanner.c]) 119 + cp -r ${src-ts-go}/src $vendor/tree-sitter-go/src 120 + cp -r ${src-ts-javascript}/src $vendor/tree-sitter-javascript/src 121 + cp -r ${src-ts-python}/src $vendor/tree-sitter-python/src 122 + cp -r ${src-ts-rust}/src $vendor/tree-sitter-rust/src 123 + cp -r ${src-ts-c}/src $vendor/tree-sitter-c/src 124 + cp -r ${src-ts-cpp}/src $vendor/tree-sitter-cpp/src 125 + cp -r ${src-ts-bash}/src $vendor/tree-sitter-bash/src 126 + cp -r ${src-ts-json}/src $vendor/tree-sitter-json/src 89 127 90 - # go-tree-sitter bundles the tree-sitter C library (include/ + src/) 91 - cp -r ${src-go-tree-sitter}/include $vendor/go-tree-sitter/include 92 - cp -r ${src-go-tree-sitter}/src $vendor/go-tree-sitter/src 128 + # TypeScript grammar keeps sources under typescript/, tsx/, and common/ 129 + cp -r ${src-ts-typescript}/typescript $vendor/tree-sitter-typescript/typescript 130 + cp -r ${src-ts-typescript}/tsx $vendor/tree-sitter-typescript/tsx 131 + cp -r ${src-ts-typescript}/common $vendor/tree-sitter-typescript/common 93 132 94 - # Grammar C sources (most grammars expose src/parser.c [+ scanner.c]) 95 - cp -r ${src-ts-go}/src $vendor/tree-sitter-go/src 96 - cp -r ${src-ts-javascript}/src $vendor/tree-sitter-javascript/src 97 - cp -r ${src-ts-python}/src $vendor/tree-sitter-python/src 98 - cp -r ${src-ts-rust}/src $vendor/tree-sitter-rust/src 99 - cp -r ${src-ts-c}/src $vendor/tree-sitter-c/src 100 - cp -r ${src-ts-cpp}/src $vendor/tree-sitter-cpp/src 101 - cp -r ${src-ts-bash}/src $vendor/tree-sitter-bash/src 102 - cp -r ${src-ts-json}/src $vendor/tree-sitter-json/src 133 + cp -r ${src-ts-ruby}/src $vendor/tree-sitter-ruby/src 103 134 104 - # TypeScript grammar keeps sources under typescript/, tsx/, and common/ 105 - cp -r ${src-ts-typescript}/typescript $vendor/tree-sitter-typescript/typescript 106 - cp -r ${src-ts-typescript}/tsx $vendor/tree-sitter-typescript/tsx 107 - cp -r ${src-ts-typescript}/common $vendor/tree-sitter-typescript/common 135 + # nix-community grammar (no official Go bindings; binding.go hand-written in vendor) 136 + vendor_nix=vendor/github.com/nix-community/tree-sitter-nix 137 + cp -r ${src-ts-nix}/src $vendor_nix/src 138 + # scanner.c uses <tree_sitter/parser.h>; provide a shim since tree-sitter 0.24+ renamed it to api.h 139 + mkdir -p $vendor_nix/include/tree_sitter 140 + cp ${src-go-tree-sitter}/include/tree_sitter/api.h $vendor_nix/include/tree_sitter/api.h 141 + printf '#include "api.h"\n' > $vendor_nix/include/tree_sitter/parser.h 142 + ''; 143 + }; 108 144 109 - cp -r ${src-ts-ruby}/src $vendor/tree-sitter-ruby/src 145 + apps.update-screenshot = let 146 + tape = pkgs.writeText "sdiff-screenshot.tape" '' 147 + Set Shell "bash" 148 + Set FontSize 14 149 + Set Width 1600 150 + Set Height 600 110 151 111 - # nix-community grammar (no official Go bindings; binding.go hand-written in vendor) 112 - vendor_nix=vendor/github.com/nix-community/tree-sitter-nix 113 - cp -r ${src-ts-nix}/src $vendor_nix/src 114 - # scanner.c uses <tree_sitter/parser.h>; provide a shim since tree-sitter 0.24+ renamed it to api.h 115 - mkdir -p $vendor_nix/include/tree_sitter 116 - cp ${src-go-tree-sitter}/include/tree_sitter/api.h $vendor_nix/include/tree_sitter/api.h 117 - printf '#include "api.h"\n' > $vendor_nix/include/tree_sitter/parser.h 118 - ''; 119 - }; 152 + Env COLORTERM "truecolor" 153 + Env TERM "xterm-256color" 154 + Env PS1 "" 120 155 121 - apps.update-screenshot = { 122 - type = "app"; 123 - program = toString (pkgs.writeShellScript "update-screenshot" '' 124 - set -euo pipefail 125 - root=$(${pkgs.jujutsu}/bin/jj root) 126 - cd "$root" 127 - nix build 128 - ${pkgs.vhs}/bin/vhs docs/screenshot.tape 129 - echo "Screenshot updated: docs/screenshot.png" 130 - ''); 131 - }; 156 + Type "result/bin/sdiff docs/demo_old.go docs/demo_new.go" 157 + Enter 158 + Sleep 2s 159 + Screenshot docs/screenshot.png 160 + ''; 161 + in { 162 + type = "app"; 163 + program = toString (pkgs.writeShellScript "update-screenshot" '' 164 + set -euo pipefail 165 + root=$(${pkgs.lib.getExe pkgs.jujutsu} root) 166 + cd "$root" 167 + nix build 168 + ${pkgs.lib.getExe pkgs.vhs} ${tape} 169 + echo "Screenshot updated: docs/screenshot.png" 170 + ''); 171 + }; 132 172 133 - devShells.default = pkgs.mkShell { 134 - packages = [ 135 - pkgs.go 136 - pkgs.clang 137 - pkgs.gopls 138 - pkgs.gotools 139 - pkgs.delve 140 - ]; 141 - shellHook = '' 142 - export CC=clang 143 - export CGO_ENABLED=1 144 - # Use module cache (not vendor) in the dev shell so CGO can find 145 - # the C source files embedded in grammar modules. 146 - export GOFLAGS=-mod=mod 147 - ''; 148 - }; 173 + devShells.default = pkgs.mkShell { 174 + packages = [ 175 + pkgs.go 176 + pkgs.clang 177 + pkgs.gopls 178 + pkgs.gotools 179 + pkgs.delve 180 + pkgs.vhs 181 + ]; 182 + shellHook = '' 183 + export CC=clang 184 + export CGO_ENABLED=1 185 + # Use module cache (not vendor) in the dev shell so CGO can find 186 + # the C source files embedded in grammar modules. 187 + export GOFLAGS=-mod=mod 188 + ''; 149 189 }; 190 + }; 150 191 }; 151 192 }