Sözdizimini anlayan yapısal fark analiz aracı Difftastic
(difftastic.wilfred.me.uk)- Difftastic, dosyaları satır bazında değil kodun sözdizimsel yapısını temel alarak karşılaştıran bir CLI diff aracıdır
- İçeride kodu tree-sitter ile ayrıştırır; bu sayede biçimlendirme nedeniyle satırlar değişse bile gerçekten değişen ifadeleri daha iyi ayırt eder
- Kod biçimlendiricisinin öğeleri birden çok satıra bölmesi veya wrapper eklenmesi durumunda da, değişen yapıyı ve korunan içeriği birbirinden ayırarak gösterebilir
- Git ayar rehberi ve kurulum belgeleri sunulur; ayrıca birçok programlama diliyle JSON ve YAML gibi yapılandırılmış metin formatlarını destekler
- MIT lisansı ile yayımlanır; indirilebilir, değiştirilebilir ve paylaşılabilir, ayrıca mevcut diff akışına yapısal karşılaştırma eklemek için uygundur
Satırları değil, sözdizimsel yapıyı karşılaştırır
- Difftastic, dosyaları sözdizimine göre karşılaştıran bir CLI diff aracıdır
- Tipik satır bazlı diff'ten farklı olarak, kod yapısını anlayarak elde edilen sonuçları göstermeye odaklanır
- Kod tree-sitter ile ayrıştırılır
- Satır odaklı diff'te değişmiş gibi görünen iç ifadelerin gerçekten değişip değişmediğini ayırt edebilir
- Kod biçimlendiricisinin kodu birden çok satıra bölmesi durumunda da gerçek değişiklikleri gösterebilir
- Wrapper eklendiğinde ayraçları doğru şekilde eşleştirir
- İçerik de birlikte değişse bile eklenen wrapper'ı gösterebilir
@@ -5,6 +5,7 @@gibi diff hunk sözdizimi yerine, değişiklik öncesi ve sonrası dosyaların gerçek satır numaralarını gösterir
Desteklenen diller ve Git entegrasyonu
- Proje kaynakları GitHub, Manual, Install üzerinden sunulmaktadır
- Desteklenen programlama dillerine örnekler şunlardır
- C++, C#, Clojure, Dart, Erlang, Go, Haskell, Java, JavaScript, Kotlin, Lisp, Lua, OCaml, PHP, Python, R, Ruby, Rust, Scala, TypeScript
- Listenin tamamı kılavuzdaki desteklenen diller listesinde görülebilir
- Desteklenen dosya biçimlerine örnekler şunlardır
- HCL, HTML, JSON, YAML
- Listenin tamamı kılavuzdaki yapılandırılmış metin formatları listesinde görülebilir
- Git ile birlikte kullanılabilir ve kılavuzda Git ayarları için rehber bulunur
- Difftastic, MIT lisansı ile yayımlanır; indirilebilir, değiştirilebilir ve paylaşılabilir
1 yorum
Hacker News yorumları
Bilenler vardır ama bu araç tree-sitter(https://tree-sitter.github.io/tree-sitter/) üzerine inşa edilmiş; LSP’nin analiz için yaptığını ayrıştırma için yapıyor sayılır.
Kodu soyut sözdizimi ağacına (AST) dönüştürüyor ve bu AST’yi editörler veya diff araçları gibi istemcilerin kullanabilmesi için standart bir arayüz sağlıyor.
Böyle bir aracın onlarca dili doğrudan desteklemesi gerekmiyor; yalnızca tree-sitter’ı desteklemesi yeterli, böylece tree-sitter’ın desteklediği tüm dillerde otomatik olarak çalışabiliyor.
Yeni bir dil geliştiriyorsanız bir tree-sitter ayrıştırıcısı yazmanız yeterli; bunun sonucunda tree-sitter ile çalışan tüm araçlar o dili destekleyebilir hâle geliyor.
Bu iki büyük yenilik sayesinde bu tür araç geliştirmelerinde patlama yaşanıyor. Artık editörler, diff araçları vb. aynı işi tekrar tekrar yapmadan onlarca, hatta yüzlerce dili destekleyebiliyor; gerçekten harika.
Bu arada ekip arkadaşlarımızdan bazıları OCaml tree-sitter bağlamalarını sürdürüyor ve Semgrep çalışmalarının bir parçası olarak gramerlere de sık sık katkıda bulunuyor. Semgrep, kod arama ve bizzat kod parçaları olan sorguları AST eşleyicilerine ayrıştırmak için tree-sitter kullanıyor.
Bir linter yazarken çoğu zaman hedef dilin çalışma zamanını da beraberinde getirmeniz gerekir. Örneğin Python’da yerleşik
astmodülüyle bir ayrıştırıcı yazarsanız dil sürümü ve özelliklerle uyumlu olmanız gerekir; bu yüzden Python 2.7’de çalışan Pylint ile Python 3 kodunu ayrıştıramazsınız.Birden fazla dili hedeflediğinizde iş, başta düşündüğünüzden çok daha zahmetli hâle gelir.
tree-sitter’dan önce, güncel sözdizimini takip ettiğine dair garanti olduğu için çoğu durumda dilin yerleşik AST araçlarını kullanmak en iyi seçenekti.
Bana göre tree-sitter’ın dehası, geleneksel gramer yaklaşımlarına kıyasla dil ayrıştırıcılarını güncel tutmayı çok daha kolay hâle getirmesinde yatıyor.
tree-sitter’ın tasarım tercihleri hakkında daha fazla şey öğrenmek istiyorsanız Max Brunsfield’ın Strange Loop sunumunu şiddetle tavsiye ederim: https://www.youtube.com/watch?v=Jes3bD6P0To
Sonuç olarak difftastic’in yanı sıra neovim, Zed, Semgrep, GitHub kod arama gibi birçok yeni araç tree-sitter üzerine inşa edildi.
VHDL için bir tree-sitter grameri ve vurgulama sorguları seti yazmayı denedim; VHDL gramerini tree-sitter ile ifade etmekte çok zorlandım.
LSP, sorgu odaklı derleyiciler için standart bir arayüz kullanarak M adet editör ile N adet dil arasında gereken M×N entegrasyon sorununu gerçekten çözüyor.
tree-sitter ise bu sorunu çözmekten ziyade, editörlerde veya araçlarda N adet entegrasyon yazmayı çok daha kolay hâle getiriyor.
Common Lisp, eksiksiz bir Lisp uygulaması olmadan ayrıştırılamaz; Haskell grameri yeterince karmaşık olduğu için gramer eksik kalıyor; C/C++’ta yalnızca önişlemciye bakmak bile doğru ayrıştırmayı zorlaştırıyor; Perl ayrıştırması ise Turing-tamam.
Başka yerlerde önerildiği gibi, yeni ekosistemlerde ayrıştırıcıların yeniden yazılmasını istemek yerine, mevcut ayrıştırıcıların ek çıktı olarak üretebileceği bir biçim tanımlamak daha doğru görünüyor.
O zaman difftastic ile görsel satırlar yerine cümle bazlı değişiklikleri göstermek mümkün olabilir.
Denemelerde görsel satır bazlı diff tuhaf oluyor; çünkü değişen cümle genellikle görsel satırın ortasında başlıyor.
cargo ile kurduysanız difftastic ve ilgili araçları güncellemenin yolu şöyle:
cargo install cargo-updatecargo install-update --listcargo install-update --allcargo ile kurulabilen ilginç Rust projeleri de var.
https://mise.jdx.dev/ mise-en-place, https://asdf-vm.com/ için hızlı ve esnek bir alternatif.
https://github.com/ajeetdsouza/zoxide harika bir
cdalternatifi; gittiğiniz konumları kaydedip"z hel"gibi kısmi bir eşleşmeyle"~/projects/helloworld"dizinine gidebiliyor.https://github.com/bootandy/dust
duyu tamamlayan bir araç; hangi dizinlerin disk alanını çok kullandığını gösteriyor.ls, https://github.com/ClementTsang/bottom grafiklere sahip birhtop, https://github.com/sharkdp/bat ise sözdizimi vurgulamalı bircat.ls.dutürleri arasında en çok dua-cli hoşuma gidiyor.ncduklonu olan etkileşimli bir terminal UI’si.ncduda açık tema olmadığı için ararken keşfettim.ncduaçık ara en iyidualternatifi.git gibi araçların neden böyle bir şeyi varsayılan olarak sunmadığını neredeyse anlayamıyorum
difft’i yaklaşık 1 yıldır kullanıyorum; en büyük şikâyetim, difft olmayan ortamlarda başka diff araçlarına dönmeyi zorlaştırması
Anlam tabanlı diff araçları üzerine de araştırma yapılıp yapılmadığını merak ediyorum. Örneğin sözdizimi değişmiş ama anlamı aynı kalan durumları ele alan araçlar
Genel bir problem olarak bakınca zor görünüyor, ama küçük DSL’lerde ya da bazı dillerin alt kümelerinde mümkün veya faydalı olabilir
diffkullanmanın doğru olduğunu düşünüyorumgit çalıştırmak isteyeceğiniz neredeyse her sistemde zaten var; hızlı, küçük ve herkes temel kullanımını biliyor
Yine de bu varsayılanın kolayca değiştirilebilmesi güzel
Bir komut satırı aracı değil; VS Code eklentisi ve GitHub App
Nasıl çalıştığını ve difftastic’ten farklarını merak ediyorsanız https://semanticdiff.com/blog/semanticdiff-vs-difftastic/ adresine bakabilirsiniz
Yine de varsayılan olmaması gerektiğini düşünmemin nedenlerinden biri, boşluk farklarını gizlemesi. Yapılandırılabilir mi henüz kontrol etmedim
@@ -5,6 +5,7 @@sözdizimini okuyup okuyamadığını sormasına ve Difftastic’in değişiklik öncesi/sonrası dosyanın gerçek satır numaralarını gösterdiği açıklamasına tamamen katılıyorumHemen ekleyip
git diffdenedim; çok iyi çalışıyorGitHub’ın böyle bir şey çıkarmamış olması ürün inovasyonunda büyük bir boşluk gibi görünüyor
Sadece girinti değişse bile yardımcı olan bir özellik yok; genelde devasa bir silme ve ekleme olarak gösteriyor
GitHub’ın diff görüntüleyicisi daha akıllı olabilir ve olmalı
Gerçekte
foo.cpp.inilefoo.mk.indosyalarının farklı olduğunu bile ayırt edemiyorHerhangi bir
foo.tPerl olarak bildiriliyor ve bunu düzeltmenin yolu da yok. 10 yıllık bir ticket bile varHatta TS çekirdek geliştiricileri de gramer doğruluğu konusunda fazla takılmamayı öneriyor[1]
GitHub ya da benzer konumdaki servisler için bu kısıt çok kritik olabilir gibi görünüyor
[1] https://github.com/tree-sitter/tree-sitter/issues/130#issuec...
Bu araca geçmeyi denedim, ama değişmeyen kısımlara bile tuhaf biçimlendirme uyguladığı için fazla gürültülü geldi
Sonunda icdiff’e[0] geri döndüm
[0]: https://github.com/jeffkaufman/icdiff
Bir süre önce Semantic Merge’i[1] keşfetmiştim ama açık kaynak değildi
Bu araç birleştirme yapmıyor, sadece diff yapıyor; ama en azından açık kaynak ve diff’i çok daha okunabilir olduğu için şimdiden varsayılanım yaptım
Birleştirme işlevi ekleyecek şekilde genişletme planı olup olmadığını merak ediyorum
[1] https://docs.plasticscm.com/semanticmerge
AST birleştirme zor bir problem ve difftastic’in kapsamına girmiyor deniyor
Ayrıca AST diff, metin diff’i açısından kayıplı bir süreç. difftastic, sözdizimsel olarak anlamsız boşlukları yok sayıyor; ama birleştirme için boşlukların izlenmesi gerekiyor
Büyük bir ekipte C# projesinde dağınık bir refactoring yaparken gerçekten kurtarıcı bir araçtı
Önceki tartışmalar:
https://news.ycombinator.com/item?id=27768861 (297 puan | 3 yıl önce | 61 yorum)
https://news.ycombinator.com/item?id=32746258 (698 puan | 2 yıl önce | 90 yorum)
https://news.ycombinator.com/item?id=30841244 (983 puan | 2 yıl önce | 219 yorum)
Harika bir araç gibi görünüyor, ama birkaç büyük XML dosyasıyla kontrol ettiğimde değiştirilmiş satırlar normal yeşil, değiştirilmiş öznitelikler kalın yeşil göründüğü için görsel olarak ayırt etmek zordu
Belgelerde diff stilini değiştirmeyi ya da kalın olanlar için başka bir renk atamayı sağlayan bir yol bulamadım
Nasıl yapılacağını bilen var mı merak ediyorum
Bu özelliği desteklediğimi bu issue’ya[1] yorum olarak yazdım
İstediğiniz özellik aynı kapsama giriyorsa oraya görüş ekleyebilirsiniz; yeterince farklı bir özellik olduğunu düşünüyorsanız yeni bir issue açmanız da uygun olur
[1]: https://github.com/Wilfred/difftastic/issues/611
Arch Linux paketi 7 MB, ancak kurulumdan sonra 80 MB’a açılıyor; yalnızca
difftikili dosyasının bile 78 MB olması ilginçLZ4 sıkıştırması açık bir ZFS veri kümesinde
duçıktısının 17 MB gösterdiği söyleniyorİkili dosyanın içinde bu kadar iyi sıkıştırılabilen bir şeyi neden doğrudan sıkıştırılmış tutmadıklarını merak ediyorum. RAM’de açılırsa daha hızlı yüklenebilirmiş gibi görünüyor
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 görünüşe göre çok büyük miktarda koda ihtiyaç duyuyor ve bunun önemli bir kısmı tekrarlı ya da sıkıştırılabilir gibi duruyor
Belleğe eşlenir ve yalnızca gerçekten kullanılan kısımlar gerektiğinde yüklenir
Bu yüzden büyük bir ikili dosyayı sıkıştırmak, demand paging’in çalışmasını engeller ve aksine daha yavaş hale getirir
Birkaç yıl önce 280 MB’lık bir Windows EXE ile test etmiştim; yaklaşık 70 MB’a sıkıştı ama başlatılması özgün dosyadan birkaç saniye daha uzun sürdü
İkili dosyayı ağ üzerinden çalıştırmak gibi bazı senaryolarda mantıklı olabilir, ancak çoğu durumda sıkıştırılmamış ikili dosya daha hızlı başlar