Difftastic, alat analisis perbedaan struktural yang memahami sintaks
(difftastic.wilfred.me.uk)- Difftastic adalah alat diff CLI yang membandingkan file berdasarkan struktur sintaks kode, bukan per baris
- Secara internal, alat ini mem-parsing kode dengan tree-sitter, sehingga dapat membedakan ekspresi yang benar-benar berubah meskipun barisnya berubah karena pemformatan
- Bahkan ketika pemformat kode memecah item ke beberapa baris atau pembungkus ditambahkan, alat ini dapat menampilkan secara terpisah struktur yang berubah dan isi internal yang tetap sama
- Tersedia panduan konfigurasi Git dan dokumentasi instalasi, serta mendukung banyak bahasa pemrograman dan format teks terstruktur seperti JSON dan YAML
- Dirilis dengan lisensi MIT, sehingga dapat diunduh, dimodifikasi, dan dibagikan, serta cocok untuk menambahkan perbandingan struktural ke alur diff yang sudah ada
Membandingkan struktur sintaks, bukan baris
- Difftastic adalah alat diff CLI yang membandingkan file berdasarkan sintaks
- Fokusnya adalah menampilkan hasil yang memahami struktur kode dibanding diff per baris biasa
- Kode di-parse dengan tree-sitter
- Bahkan ekspresi internal yang tampak berubah dalam diff berbasis baris dapat dibedakan apakah benar-benar berubah atau tidak
- Bahkan ketika pemformat kode memecah kode ke beberapa baris, alat ini tetap dapat menampilkan perubahan yang sebenarnya
- Jika pembungkus ditambahkan, pemisah dapat dicocokkan secara akurat
- Bahkan jika isi internal ikut berubah, alat ini dapat menandai pembungkus yang ditambahkan
- Alih-alih sintaks diff hunk seperti
@@ -5,6 +5,7 @@, alat ini menampilkan nomor baris sebenarnya dari file sebelum dan sesudah perubahan
Bahasa yang didukung dan integrasi Git
- Materi proyek tersedia di GitHub, Manual, Install
- Contoh bahasa pemrograman yang didukung adalah sebagai berikut
- C++, C#, Clojure, Dart, Erlang, Go, Haskell, Java, JavaScript, Kotlin, Lisp, Lua, OCaml, PHP, Python, R, Ruby, Rust, Scala, TypeScript
- Daftar lengkapnya dapat dilihat di daftar bahasa yang didukung pada manual
- Contoh format file yang didukung adalah sebagai berikut
- HCL, HTML, JSON, YAML
- Daftar lengkapnya dapat dilihat di daftar format teks terstruktur pada manual
- Dapat digunakan bersama Git, dan manual menyediakan panduan konfigurasi Git
- Difftastic dirilis dengan lisensi MIT, sehingga dapat diunduh, dimodifikasi, dan dibagikan
1 komentar
Komentar Hacker News
Sebagian orang mungkin sudah tahu, tetapi tool ini dibuat di atas tree-sitter(https://tree-sitter.github.io/tree-sitter/); bisa dibilang ia melakukan untuk parsing apa yang dilakukan LSP untuk analisis
Ia mengubah kode menjadi abstract syntax tree (AST), lalu menyediakan antarmuka standar agar AST itu bisa digunakan oleh klien seperti editor atau tool diff
Tool seperti ini tidak perlu mendukung puluhan bahasa secara langsung; cukup mendukung tree-sitter, maka ia otomatis bisa berjalan di semua bahasa yang didukung tree-sitter
Jika mengembangkan bahasa baru, Anda cukup membuat parser tree-sitter, dan semua tool yang menangani tree-sitter akan bisa mendukung bahasa tersebut
Berkat dua inovasi besar ini, peningkatan tool semacam ini melonjak pesat. Sekarang editor, tool diff, dan lainnya bisa mendukung puluhan hingga ratusan bahasa tanpa saling mengulang pekerjaan yang sama; ini benar-benar luar biasa
Sebagai konteks, beberapa anggota tim kami memelihara binding OCaml tree-sitter, dan sebagai bagian dari pekerjaan Semgrep, kami juga sering berkontribusi pada grammar-nya. Semgrep menggunakan tree-sitter untuk pencarian kode dan untuk mem-parse kueri yang merupakan potongan kode itu sendiri menjadi AST matcher
Saat membuat linter, sering kali Anda harus membawa serta runtime bahasa target. Misalnya, jika membuat parser dengan modul bawaan
astdi Python, Anda harus mencocokkan versi dan fitur bahasa, sehingga Pylint yang berjalan di Python 2.7 tidak bisa mem-parse kode Python 3Jika menargetkan banyak bahasa, ini menjadi jauh lebih merepotkan daripada yang awalnya dibayangkan
Sebelum tree-sitter, dalam banyak kasus pilihan terbaik adalah memakai tool AST bawaan bahasa, karena ada jaminan bahwa ia mengikuti sintaks terbaru
Menurut saya pribadi, kejeniusan tree-sitter ada pada bagaimana ia membuat parser bahasa jauh lebih mudah dijaga tetap mutakhir dibandingkan pendekatan grammar tradisional
Jika ingin tahu lebih jauh tentang pilihan desain tree-sitter, saya sangat merekomendasikan presentasi Strange Loop dari Max Brunsfield: https://www.youtube.com/watch?v=Jes3bD6P0To
Hasilnya, selain difftastic, berbagai tool baru seperti neovim, Zed, Semgrep, dan pencarian kode GitHub dibuat di atas tree-sitter
Saya pernah menulis grammar tree-sitter dan set kueri highlighting untuk VHDL, dan ada banyak kesulitan dalam mengekspresikan grammar VHDL dengan tree-sitter
LSP benar-benar menyelesaikan masalah integrasi M×N yang dibutuhkan antara M editor dan N bahasa, dengan menggunakan antarmuka standar untuk compiler berorientasi kueri
tree-sitter bukan menyelesaikan masalah itu, melainkan membuat pekerjaan menulis N integrasi di editor atau tool menjadi jauh lebih mudah
Common Lisp tidak bisa di-parse tanpa implementasi Lisp lengkap, grammar Haskell cukup rumit sehingga grammar-nya tidak lengkap, C/C++ sulit di-parse secara akurat bahkan hanya dari preprocessor-nya, dan parsing Perl bersifat Turing-complete
Seperti usulan yang pernah muncul di tempat lain, rasanya lebih tepat mendefinisikan format yang bisa dihasilkan parser yang sudah ada sebagai keluaran tambahan, alih-alih membuat ekosistem baru menulis ulang parser
Dengan begitu, difftastic sepertinya bisa menampilkan perubahan berdasarkan kalimat, bukan baris visual
Untuk esai, diff berdasarkan baris visual terasa aneh. Biasanya kalimat yang berubah dimulai di tengah baris visual
Jika Anda memasangnya lewat cargo, berikut cara memperbarui difftastic dan tool terkait
cargo install cargo-updatecargo install-update --listcargo install-update --allAda juga beberapa proyek Rust menarik yang bisa dipasang lewat cargo
https://mise.jdx.dev/ mise-en-place adalah pengganti https://asdf-vm.com/ yang cepat dan fleksibel
https://github.com/ajeetdsouza/zoxide adalah pengganti
cdyang hebat; ia menyimpan lokasi yang pernah dikunjungi lalu bisa berpindah ke"~/projects/helloworld"hanya dengan kecocokan sebagian seperti"z hel"https://github.com/bootandy/dust adalah tool pelengkap
duyang menunjukkan direktori mana yang memakai banyak ruang disklsyang tampilannya lebih bagus, https://github.com/ClementTsang/bottom adalahhtopdengan grafik, dan https://github.com/sharkdp/bat adalahcatdengan syntax highlightinglsyang lebih cantikdubaru, dua-cli adalah yang paling saya suka. Ini UI terminal interaktif yang merupakan klonncduSaya menemukannya saat mencari karena
ncdutidak punya light modencdujelas merupakan penggantiduterbaikSaya hampir tidak mengerti mengapa alat seperti git tidak menyediakan hal semacam ini secara default
Saya sudah memakai difft sekitar setahun, dan keluhan terbesar saya adalah difft membuat saya sulit kembali ke alat diff lain di lingkungan yang tidak punya difft
Saya penasaran apakah ada penelitian tentang alat diff berbasis semantik juga. Misalnya alat yang menangani kasus ketika sintaks berubah tetapi maknanya sama
Sebagai masalah umum ini tampak sulit, tetapi untuk DSL kecil atau subset dari beberapa bahasa mungkin saja bisa atau berguna
difflama sebagai defaultSudah ada di hampir semua sistem yang ingin menjalankan git, cepat, kecil, dan semua orang tahu cara pakai dasarnya
Meski begitu, bagus karena default itu bisa diubah dengan mudah
Ini bukan utilitas command-line, melainkan ekstensi VS Code dan GitHub App
Jika penasaran cara kerjanya dan perbedaannya dengan difftastic, lihat https://semanticdiff.com/blog/semanticdiff-vs-difftastic/
Namun salah satu alasan saya merasa ini tidak boleh menjadi default adalah karena ia menyembunyikan perbedaan whitespace. Saya belum mengecek apakah itu bisa dikonfigurasi
Saya sangat setuju dengan penjelasan yang menanyakan apakah orang bisa membaca sintaks
@@ -5,6 +5,7 @@, dan bahwa Difftastic menunjukkan nomor baris aktual dari file sebelum dan sesudah perubahanSaya langsung memasangnya dan mencoba
git diff, dan hasilnya sangat baikFakta bahwa GitHub belum merilis hal seperti ini tampak seperti celah besar dalam inovasi produk
Bahkan ketika hanya indentasi yang berubah, tidak ada fitur yang membantu, dan biasanya ditampilkan sebagai penghapusan dan penambahan besar-besaran
Penampil diff GitHub bisa dan seharusnya lebih pintar
Dalam praktiknya, ia bahkan tidak bisa membedakan bahwa
foo.cpp.indanfoo.mk.inberbedaFile
foo.tapa pun dinyatakan sebagai Perl dan tidak ada cara memperbaikinya. Bahkan ada tiket yang sudah berumur 10 tahunBahkan para pengembang inti TS menyarankan agar tidak terlalu memusingkan akurasi tata bahasanya[1]
Batasan ini tampaknya bisa menjadi fatal bagi GitHub atau layanan dengan posisi serupa
[1] https://github.com/tree-sitter/tree-sitter/issues/130#issuec...
Saya mencoba beralih ke alat ini, tetapi terasa terlalu berisik karena memakai format aneh bahkan pada bagian yang tidak berubah
Akhirnya saya kembali ke icdiff[0]
[0]: https://github.com/jeffkaufman/icdiff
Dulu saya menemukan Semantic Merge[1], tetapi itu bukan open source
Yang ini tidak melakukan merge dan hanya diff, tetapi setidaknya open source dan diff-nya jauh lebih enak dilihat, jadi saya sudah menjadikannya default
Saya penasaran apakah ada rencana memperluasnya dengan fitur merge
[1] https://docs.plasticscm.com/semanticmerge
Merge AST adalah masalah yang sulit dan tidak ditangani oleh difftastic
Selain itu, diff AST adalah proses yang lossy dari sudut pandang diff teks. difftastic mengabaikan whitespace yang tidak bermakna secara sintaksis, tetapi merge perlu melacak whitespace
Saat melakukan refactoring berantakan pada proyek C# di tim besar, alat itu benar-benar seperti penyelamat
Diskusi sebelumnya:
https://news.ycombinator.com/item?id=27768861 (297 poin | 3 tahun lalu | 61 komentar)
https://news.ycombinator.com/item?id=32746258 (698 poin | 2 tahun lalu | 90 komentar)
https://news.ycombinator.com/item?id=30841244 (983 poin | 2 tahun lalu | 219 komentar)
Tampaknya alat yang bagus, tetapi ketika saya mengeceknya dengan beberapa file XML besar, baris yang dimodifikasi ditampilkan hijau biasa dan atribut yang dimodifikasi hijau tebal, sehingga sulit dibedakan secara visual
Saya tidak menemukan cara di dokumentasi untuk mengubah gaya diff atau menetapkan warna lain untuk bagian yang tebal
Saya penasaran apakah ada yang tahu caranya
Saya menambahkan komentar pada issue ini[1] untuk mendukung fitur tersebut
Jika fitur yang Anda inginkan masih dalam kategori yang sama, Anda bisa menambahkan pendapat di sana; jika menurut Anda cukup berbeda, mungkin bisa membuka issue baru
[1]: https://github.com/Wilfred/difftastic/issues/611
Menarik bahwa paket Arch Linux ukurannya 7MB, tetapi setelah dipasang diekstrak menjadi 80MB, dan biner
difftsaja sudah 78MBPada dataset ZFS dengan kompresi LZ4 diaktifkan,
dukatanya menunjukkan 17MBSaya penasaran mengapa sesuatu di dalam biner yang bisa terkompresi sebaik ini tidak dibiarkan dalam bentuk terkompresi saja. Jika didekompresi di RAM, tampaknya bisa dimuat lebih cepat
Processed 1 file, 614 regular extents (614 refs), 0 inline.Type Perc Disk Usage Uncompressed ReferencedTOTAL 14% 10M 77M 77Mnone 100% 1.1M 1.1M 1.1Mzstd 12% 9.8M 76M 76MTree-sitter tampaknya membutuhkan kode dalam jumlah sangat besar, dan sebagian besarnya terlihat duplikatif atau bisa dikompresi
Ia dipetakan ke memori, dan hanya bagian yang benar-benar digunakan yang dimuat saat diperlukan
Jadi jika biner besar dikompresi, demand paging tidak akan bekerja dan justru menjadi lebih lambat
Beberapa tahun lalu saya menguji EXE Windows berukuran 280MB; memang bisa dikompresi menjadi sekitar 70MB, tetapi butuh beberapa detik lebih lama untuk mulai dibandingkan versi aslinya
Dalam beberapa skenario, seperti menjalankan biner lewat jaringan, ini bisa masuk akal, tetapi dalam kebanyakan kasus biner yang tidak dikompresi mulai lebih cepat