Mengendalikan Zig Fmt
(matklad.github.io)zig fmtdapat digunakan sebagai formatter yang bisa dikendalikan yang mencerminkan bentuk sintaks yang sudah ada di file, sehingga kode yang sama bisa ditata dalam beberapa layout berbeda- Pada pemanggilan fungsi, ada atau tidaknya trailing comma mengubah hasil; tanpa koma kode digabung menjadi satu baris, sedangkan dengan koma argumen ditempatkan per baris
- Alur kerja nyatanya adalah menentukan dulu tata letak kode yang diinginkan, menambahkan beberapa koma, lalu menekan pintasan format agar
zig fmtmenangani sisanya - Pada array, selain trailing comma, posisi line break pertama juga ikut tercermin, sehingga jika line break pertama ada setelah item ketiga maka penyelarasan dilakukan per 3 item
- Jika konkatenasi array
++digunakan dengan cermat, jumlah item per baris bisa dibuat berbeda-beda, dan saat mengirim pasangan--keydanvalueke subprocess, array argumen tetap dan array pasangan opsi bisa digabung untuk dirapikan
Cara mengendalikan zig fmt
zig fmtdapat digunakan sebagai formatter yang bisa dikendalikan karena ia melihat bentuk sintaks yang sudah ada di file saat ini dan bisa menata sintaks yang sama dengan beberapa cara berbeda- Pada pemanggilan fungsi, ada atau tidaknya trailing comma mengubah layout
f(1, 2, 3); // -> zig fmt -> f(1, 2, 3);f(1, 2, 3,); // -> zig fmt -> f( 1, 2, 3, ); - Alur penggunaan nyatanya adalah menentukan dulu tata letak kode yang diinginkan, menambahkan beberapa
,, lalu menekan pintasan format agarzig fmtmenangani sisanya - Alih-alih membiarkan formatter menebak layout, pendekatan yang lebih cocok bisa jadi adalah membiarkan pengguna meninggalkan pilihan inti itu secara langsung
- Kesimpulannya, 90% formatting yang baik bergantung pada baris kosong di antara blok logis dan pemilihan variabel perantara yang tepat, jadi lebih baik memanfaatkan pilihan-pilihan itu daripada menghilangkannya
Layout perataan kolom pada array
- Pada array, bukan hanya trailing comma yang menentukan agar elemen disusun satu per baris; posisi line break pertama juga diperhitungkan oleh
zig fmt.{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, }; - Jika line break pertama ada setelah item ketiga, hasilnya juga akan disejajarkan per 3 item
.{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, }; - Jika konkatenasi array
++digunakan dengan cermat, jumlah item per baris bisa dibuat berbeda-beda - Saat mengirim pasangan
--keydanvalueke subprocess, array argumen tetap dan array pasangan opsi bisa digabung lalu dirapikan seperti berikuttry run(&(.{ "aws", "s3", "sync", path, url } ++ .{ "--include", "*.html", "--include", "*.xml", "--metadata-directive", "REPLACE", "--cache-control", "max-age=0", }));
1 komentar
Opini di Lobste.rs
Saya ingat
gofmtjuga punya perilaku pengarah format yang mirip, dan saya lebih suka formatter seperti itu dibandingrustfmtMeski begitu, menurut saya bentuk otomatisasi format apa pun tetap lebih baik daripada tidak ada formatter sama sekali
Auto-formatter memaksakan kebiasaan standar, mengangkat orang yang tidak pandai menata format, tapi juga menurunkan kualitas orang yang justru pandai melakukannya
Saya akan memakainya saat kolaborasi jika sulit mempercayai apa yang diinginkan orang lain atau aturan format pribadi mereka, tapi saat bekerja sendiri saya sama sekali tidak akan memakainya
Saya punya selera sendiri dan formatter juga punya seleranya sendiri, dan keduanya berbeda secara tak terdamaikan
Meski begitu, isi yang ditunjukkan tulisan ini sendiri cukup mengesankan
Kalimat itu mengingatkan saya pada dialog mak comblang Yente di Fiddler on the Roof: “suami yang buruk pun—Tuhan jauhkanlah—masih lebih baik daripada tidak punya suami sama sekali!”
clang-formatdi beberapa proyek C++, dan itu mengerikanStabilitas antaversinya terlalu rendah, jadi upgrade
clang-formatberujung pada commit format yang menyentuh setiap baris kodeSaya benar-benar tidak yakin itu lebih baik daripada tidak punya formatter sama sekali
Auto-formatter terutama menyelesaikan masalah manusia dengan menghilangkan perdebatan remeh soal gaya di pull request
Tapi sekarang saat beralih ke pengembangan berbasis agen, masalah itu makin kurang penting
Saat ini mesin mengerjakan sebagian besar pekerjaan di beberapa proyek, dan dalam kondisi seperti itu rasanya justru lebih baik tidak menjalankan formatter
Saat menyusun argumen command line di Python, saya suka cara splat tuple ke dalam list, jadi contoh terakhir di tulisan itu mungkin akan saya tulis seperti ini
Terakhir kali saya lihat,
zig fmttidak punya cara untuk mengatur agar memakai batas 80 kolom alih-alih 100 kolom; apakah masih begitu?Kalau bekerja beberapa jam sehari, mata saya jadi tidak terlalu lelah kalau ukuran font terminal dibesarkan, dan perbedaan antara 80 kolom dan 100 kolom menentukan apakah dua split
vimdannerd treebisa diletakkan berdampingan atau tidakzig fmttidak punya batas kolomSebagai orang yang pernah memperkenalkan rigid formatter ke tim yang sebelumnya sama sekali tidak punya formatter, kadang saya merindukan kemampuan untuk tetap bisa memengaruhi format secara manual
Dalam hal itu, fleksibilitas Zig benar-benar keren
Hebat!
Apakah ada formatter TS/JS yang bekerja seperti ini?
Saya punya proyek yang memakai
maplibre-gl, dan ekspresi spesifikasi style-nya kadang diformat berlebihan sampai tidak kelihatan apa-apaSekarang saya berhenti memakai formatter, tapi karena terus debugging, menyalin, dan memberi komentar pada kode, jadinya kode saya mulai berantakan
Mungkin formatter Zig bisa dibuat untuk memformat bahasa lain juga :)
Misalnya, tidak ada cara untuk menyuruh formatter menaruh empat elemen per baris
Selain itu, kalau object literal menjadi terlalu panjang, pada akhirnya Prettier akan tetap mengubahnya ke format “setiap elemen di baris terpisah”, apa pun bentuk teks masukannya
Saya pernah kecewa dengan formatter yang ringan, yang pada dasarnya hanya memecah baris, jadi saya suka dan iri dengan gagasan bahwa fleksibilitas seperti ini bisa ada di dalam contoh yang lebih ketat :p
Baru-baru ini saat menjawab pertanyaan di fedi tentang menulis dan memformat Lisp dengan font proporsional, saya sempat menyinggung varian s-expression yang memakai spasi bermakna, yaitu wisp, Readable/Sweet expressions, serta SRFI 119 dan 110
Saya juga menambahkan pengamatan bahwa keluarga sintaks ini mengembalikan sebagian kendali atas pemenggalan baris lewat ekstensi notasi infiks opsional
Desainnya menarik, tapi saya tidak yakin saya menyukainya
Formatter saya menanganinya dengan cara berbeda: formatter mengabaikan trailing comma saat menentukan format, lalu selalu menambahkan trailing comma jika hasilnya multiline dan selalu menghapus trailing comma jika satu baris
Jadi tidak bisa “diarahkan”, tapi
f(1, 2, 3)akan tetap diformat konsisten tanpa peduli ada atau tidaknya trailing comma, maupun jumlah dan jenis spasi antar tokenTetap perlu ada tingkat pengarahan tertentu
Misalnya, jika ada list literal panjang
[<expr1>, <expr2>, ..., <expr100>], kebanyakan formatter akan menaruh satu ekspresi per baris, padahal bisa jadi Anda ingin menaruh sebanyak mungkin dalam satu barisMenentukan itu lewat trailing comma terasa aneh, dan secara umum pilihannya bisa jadi bukan 2 melainkan N
Menurut saya atribut lebih cocok untuk tujuan seperti ini
Misalnya, mungkin ini sudah ada, tapi bisa saja ada sesuatu seperti
#[rustfmt::list_layout(flow)]di depan statement untuk memengaruhi format list literal di dalam statement tersebutJika pengarahan terlalu banyak, itu justru merusak tujuan formatter untuk membuat format kode di seluruh ekosistem tetap konsisten dan mempermudah code review, jadi seharusnya dibatasi pada kasus tertentu saja
List literal yang panjang menurut saya memang contoh yang benar-benar layak
Di proyek saya juga ada contoh ketika format membantu review expected value pada test, seperti ini
Saya juga teringat satu perilaku “pengarah” lain di formatter Dart: pada list literal panjang, Anda bisa menambahkan baris komentar untuk mengelompokkan baris
Misalnya, untuk
[1, 2, 3, ..., 1000], formatter akan menaruh tiap elemen di baris terpisah, tapi Anda bisa mengelompokkannya secara manual seperti iniSaya tidak tahu apakah fitur seperti ini memang disengaja, atau hanya efek samping dari cara komentar diperlakukan
rustfmt, dan itu yang membuat saya gilaKadang ada kasus ketika batas panjang baris boleh saja terlewati karena pemanggilan fungsi justru lebih mudah dibaca kalau tidak dipecah, dan saya ingin bisa mencerminkan penilaian saya soal itu
Satu contoh yang terpikir adalah OpenGL
Biasanya saat memodifikasi atau memakai satu resource, misalnya inisialisasi tekstur, kita akan menulis banyak pemanggilan
gl.*secara berurutan, tapirustfmtmendorong pemecahan baris tanpa rasa apa pun selain tujuan robotik “baris terlalu panjang, harus dipecah”Contoh ini dibuat-buat untuk menunjukkan perilakunya dan tidak sepenuhnya sama dengan perilaku
rustfmtyang sebenarnyaBarisnya juga tidak sepanjang itu
Saya sedang mengetik dari ponsel sekarang, jadi tidak punya alat untuk membuat contoh yang 100% akurat Memecah rangkaian pemanggilan
gl.tex_parameteriseperti ini ke banyak baris sebenarnya lebih buruk, karena tiap pemanggilan justru lebih baik ditampilkan penuh dalam satu barisJika kolomnya sejajar, perbedaan antara dua baris jadi jauh lebih mudah dilihat
Versi yang dipecah mengurangi kedekatan visual dan lebih sulit dibaca
Mata jadi tidak bisa membandingkan dua baris itu dengan mudah
Ada juga kejadian lucu ketika formatter gagal total saat tidak bisa memformat sesuatu agar muat dalam batas jumlah karakter
Ini sering terjadi saat menulis kode compiler dan membuat pesan diagnostik sebagai string literal, karena pesannya bisa cukup panjang
rustfmttidak tahu bagaimana membaginya, lalu menyerah dan tidak memformat seluruh statement itu sama sekaliSeringnya bentuknya seperti ini Di sini, hanya karena pemanggilan
emit_diagnosticitu berupa expression, ia menyerah memformat seluruh statementmatch, dan itu bodoh sekaliSemua ini bisa dihindari kalau formatter tidak memaksa kode saya ke maksimum 100 kolom
Untuk orang yang, seperti saya, harus mencari tahu setelah melihat komentar di bagian akhir:
++adalah operator konkatenasi arrayJadi, kalau array dipecah menjadi dua, keduanya bisa diformat secara berbeda