- Karena keterbatasan editor Howl (pengembangan dihentikan, pencarian lambat, tidak kompatibel dengan SSH, tidak mendukung terminal), penulis akhirnya mengembangkan editor teks TUI baru sendiri
- Ia mencoba 13 editor termasuk Helix, VS Code, Vim, Neovim, dan Emacs, tetapi tidak ada yang memenuhi rasa pengoperasian (Fingerspitzengefühl) yang diinginkan
- Pada awalnya, ia hanya mengimplementasikan fitur minimum yang dipersonalisasi, sementara performa, Unicode, dan dukungan multibahasa ditempatkan sebagai prioritas belakangan lalu diperluas secara bertahap
- Selama proses pengembangan, ia membangun sendiri mesin regex, file browser, rendering berbasis TUI, dan integrasi buffer terminal
- Ia juga menerapkan banyak teknik optimasi performa untuk pencarian seluruh proyek, syntax highlighting, pemrosesan cache, dan distribusi kerja multithread
- Hasilnya, ia menyelesaikan alat yang benar-benar cocok dengan workflow pribadinya, dan mengatakan telah mendapatkan kembali produktivitas serta kesenangan dalam pemrograman
Keterbatasan editor lama dan pencarian alternatif
- Masalah pada editor Howl yang dipakai sekitar 10 tahun menjadi pemicu utama untuk membuat editor sendiri
- Pengembangannya telah berhenti selama bertahun-tahun, sehingga ia harus mempertahankan fork sendiri, tetapi karena ditulis dalam MoonScript, perubahan yang mendalam sulit dilakukan
- Performa pencarian file di seluruh proyek kurang memadai sehingga alur kerja sering terputus
- Karena merupakan editor GUI, editor ini tidak bisa dipakai secara remote melalui koneksi SSH
- Tidak ada terminal terintegrasi, sehingga perintah eksternal tidak bisa dijalankan dengan interaksi langsung, dan sebagian besar kode escape ANSI tidak didukung
- Ia mencoba 13 editor seperti Helix, VS Code, Sublime Text, Vim, Zed, Neovim, Emacs, Geany, Micro, Lite XL, Lapce, GNOME Builder, dan Kakoune
- Masing-masing punya kelebihan, tetapi tidak memenuhi rasa pengoperasian (Fingerspitzengefühl) yang ia cari
- Helix adalah yang paling lama dipakai, tetapi setelah sebulan ia kehilangan minat
Strategi pengembangan awal
- Pada tahap awal, ia membatasi cakupan seminimal mungkin
- Tidak membuat fitur untuk pengguna selain dirinya, dan semua pengaturan dibuat hardcoded
- Optimasi performa ditunda, dan ia memulai dengan buffer berbasis
String
- Dukungan penuh untuk grapheme Unicode tidak diutamakan; selama simbol
£ menempati satu kolom, itu dianggap cukup
- Syntax highlighting hanya mendukung beberapa bahasa yang sering dipakai, sementara sisanya ditangani dengan highlighting berbasis delimiter umum
- Pada percobaan kedua, ia lebih dulu membangun framework TUI sederhana, tetapi seiring waktu sebagian besar dibuang dan diganti dengan pendekatan yang lebih langsung serta rinci
Menerapkan dogfooding
- Setelah editor mencapai ambang fitur minimum untuk membuka, mengedit, dan menyimpan satu file, ia mulai menjalankan tiga kebiasaan
- Menggunakan editor buatannya sendiri sebagai pengganti
nano untuk mengedit file sistem atau menulis catatan, sehingga memaksa diri memakainya
- Setiap kali menemukan fitur yang hilang, bug, perilaku aneh, atau batasan, ia mencatatnya di
README.md proyek
- Masalah yang cukup menjengkelkan akan langsung diperbaiki
- Tiga kebiasaan ini meningkatkan jumlah kerja dari sekitar 1 jam per bulan menjadi beberapa jam per minggu
- Dari total sekitar 10.000 baris kode, hampir semuanya ditulis dalam 6 bulan terakhir
Kontrol kursor
- Kontrol kursor adalah area yang sulit diimplementasikan
- Kombinasi tombol seperti
ctrl + shift + left tampak wajar bagi pengguna, tetapi logikanya rumit untuk diwujudkan
- Saran utamanya adalah mengimplementasikan input tingkat tinggi sebagai kombinasi operasi primitif
- Contoh: backspace per kata dipecah menjadi perpindahan kursor per kata + pemilihan rentang + penghapusan
- Saat mengimplementasikan undo/redo, tiga operasi ini harus dikelompokkan menjadi satu grup agar hasilnya terasa intuitif
- Dari sini ia memahami mengapa editor modal mengekspos operasi primitif tersebut langsung kepada pengguna
File browser
- File browser Howl adalah alasan utama mengapa ia sulit beralih ke editor lain
- Fuzzy filter yang diperbarui seketika sangat unggul, sehingga dengan 1–2 penekanan tombol biasanya file yang diinginkan sudah ditemukan
- Jika file belum ada, file bisa dibuat langsung secara inline
- Saat mengetik
~/, editor otomatis berpindah ke direktori home
- Menampilkan pratinjau file yang akan dibuka dari jendela editor utama
- Ia tidak puas dengan cara editor lain menyelesaikan pembukaan file melalui ketergantungan pada mouse, dialog GTK bawaan, atau tebakan nama file
- Dalam implementasinya sendiri, ia menyimpulkan bahwa tiga kriteria sederhana sudah cukup tanpa metode rumit seperti Levenshtein distance
- Apakah nama file diawali dengan frasa filter
- Apakah nama file mengandung frasa filter
- Waktu modifikasi/akses yang paling baru
- Pencocokan huruf besar-kecil yang tidak sensitif diizinkan, tetapi kecocokan kapitalisasi yang tepat diberi peringkat sedikit lebih tinggi
- Bahkan di proyek dengan puluhan ribu file, setelah 2 penekanan tombol, file yang dicari berada di dua hasil teratas dengan probabilitas sekitar 95%
Mesin regex
- Regex dipakai di tiga tempat: pencarian seluruh proyek, syntax highlighting, dan pencarian dalam buffer
- Alasan ia membuat sendiri alih-alih memakai crate
regex-automata
- Ia perlu menangani edge case yang sensitif terhadap konteks, seperti sintaks raw string di Rust
- Proyek ini sendiri merupakan latihan untuk membangun dan memahami stack sendiri
- Implementasi awal memakai crate parsing
chumsky untuk mem-parsing sintaks regex dan menelusuri AST pada setiap karakter, yang sangat lambat
- Setelah itu dilakukan optimasi bertahap
- Single-pass optimizer: mengubah grup pencocokan karakter yang berulang menjadi satu node
String, sehingga pencarian string eksak bisa dilakukan
- Ekstraksi prefiks umum: misalnya dari
hel[(lo)p] ditemukan prefiks umum hel, sehingga pencocokan hanya dilakukan pada posisi tersebut → memberi peningkatan besar pada pencarian seluruh proyek
- AST walker diimplementasikan ulang sebagai threaded code VM berbasis pemanggilan dinamis Rust
- Threaded code VM lalu diubah menjadi bentuk CPS (Continuation-Passing Style), sehingga tiap instruksi VM melakukan tail-call ke instruksi berikutnya dan memanfaatkan optimasi compiler
- Pemanggilan fungsi dinamis Rust yang lambat dibungkus tanpa vtable lookup, sehingga codegen banyak instruksi regex menyusut menjadi hanya beberapa instruksi mesin
- Sebisa mungkin, instruksi regex diimplementasikan pada level byte alih-alih code point Unicode; berkat desain UTF-8, teknik optimasi ASCII tetap efektif pada code point multibyte
- Ia juga mencoba kompilasi ke rantai jump LUT, tetapi benchmark menunjukkan hanya sekitar 20–30% lebih cepat daripada threaded code, dengan fleksibilitas jauh berkurang, sehingga tidak dipakai
- Hasil akhirnya: untuk syntax highlighting Rust yang paling kompleks, file binding hasil generate otomatis sepanjang 50.000 baris bisa di-highlight penuh dari kondisi dingin dalam kurang dari 10 milidetik
Cache syntax highlighting
- Pada awalnya, setiap perubahan menyebabkan seluruh file di-highlight ulang, tetapi ini menimbulkan penurunan performa pada file besar
- Ia lalu membuat cache highlighting token on-demand
- Token di-highlight dalam chunk dengan ukuran yang kurang lebih sama
- Saat ada perubahan (damage) pada buffer, hanya chunk yang bertumpang tindih dengan posisi itu atau yang sesudahnya yang di-invalidasi
- Bahkan pada kasus paling pesimistis (mengedit di tengah file besar), status highlighting sebelum titik damage tetap dipertahankan, dan bagian di bawah area layar tidak perlu diproses karena informasi highlight tidak diminta
- Karena pendekatannya demand-driven, ini juga bekerja normal pada banyak panel yang melihat bagian berbeda dari buffer yang sama
Pencarian seluruh proyek
- Proses pencarian terdiri dari 4 tahap
- Menentukan root proyek dengan mencari direktori
.git/ ke arah atas dari direktori saat ini
- Menelusuri semua direktori di root proyek secara rekursif dan mencocokkan pola pencarian ke isi file
- Dari tiap kecocokan positif, mengambil snippet file dan menerapkan syntax highlighting untuk pratinjau hasil
- Memberi peringkat hasil berdasarkan jarak traversal dari path saat ini (file yang lebih dekat mendapat peringkat lebih tinggi)
- Diterapkan aturan filtering bawaan untuk menghindari direktori build dan sejenisnya
- Pemrosesan dilakukan secara multithread, dengan distribusi kerja antar-thread menggunakan metode dasar work-stealing
- Ia juga menyelesaikan masalah deteksi terminasi dalam struktur khusus tempat semua thread sekaligus menjadi konsumen dan produsen
- Thread yang sedang menunggu menaikkan penghitung atomik; jika penghitung mencapai jumlah worker dan antrean kerja kosong, maka seluruh proses dihentikan
- Berkat optimasi regex dan kecepatan SSD modern, pencarian pola sederhana bahkan pada codebase besar seperti Veloren nyaris selesai seketika
- Pada flamegraph, sebagian besar waktu berada dalam kondisi IO-bound
- Kemampuan untuk mencari di codebase besar secepat pikiran dari dalam editor sangat membantu produktivitas
Buffer emulator terminal
- Pada editor berbasis panel, kemampuan menggunakan satu panel sebagai jendela terminal sangat praktis
- Ia sempat ingin membuat parser ANSI sendiri, tetapi dukungan fitur rendering terminal modern seperti OSC52 dan ekstensi keyboard Kitty terlalu luas
- Dengan memanfaatkan crate
alacritty_terminal, ia dapat menggunakan ulang parser escape sequence dan logika manajemen status terminal milik emulator terminal Alacritty
- Hasilnya, fitur ini dapat menggantikan fungsi inti
screen/tmux, sambil menyediakan dukungan escape sequence yang lebih kaya
Optimasi rendering
- Walau berbasis TUI, bandwidth saat koneksi mobile jarak jauh tetap penting
- Double buffering: mempertahankan dua salinan internal layar terminal
- Saat redraw, frame sebelumnya dibandingkan dengan frame saat ini dan hanya sel yang berubah yang dikeluarkan sebagai escape sequence ANSI
- Sequence untuk perpindahan kursor, perubahan mode gaya, dan sejenisnya juga hanya dikeluarkan saat benar-benar diperlukan
- Pada sebagian besar emulator terminal (kecuali Ghostty), menampilkan file besar dengan
cat di panel terminal editor lalu menutup editor ternyata lebih cepat daripada menjalankan cat langsung di terminal host
- Karena
alacritty_terminal memblokir biaya pemrosesan byte stdout terhadap terminal host
Kesimpulan: buat alatmu sendiri
- Editor yang ia buat sendiri kini menjadi alat yang benar-benar pas dengan workflow-nya
- Ia menentang anggapan umum bahwa membuat editor atau alat sendiri hanyalah penderitaan yang sia-sia
- Ada empat keuntungan
- Kustomisasi sempurna: hanya melakukan apa yang diinginkan, tidak lebih dan tidak kurang
- Mempelajari beragam teknologi: memperoleh pemahaman mendalam tentang regex, ANSI, pseudo-terminal (pty), desain TUI, detail UTF-8, dan teknologi lain yang berguna secara umum
- Peningkatan produktivitas jangka panjang: karena memahami alat sendiri sepenuhnya dan menanamkan fitur yang sesuai workflow pribadi, gesekan dengan alat berkurang
- Kesenangan murni: menyelesaikan masalah-masalah yang utuh dan merasakan hasilnya di ujung jari membangkitkan kembali kecintaan pada pemrograman, sampai bisa tersenyum lebar dan tertawa sendiri saat menulis kode untuk pertama kalinya setelah bertahun-tahun
- Ia menekankan bahwa tidak harus editor teks, tetapi siapa pun sebaiknya membuat alatnya sendiri, dan tidak menyerahkan bagian sulit ke kotak statistik (AI dan sejenisnya), melainkan menikmati tantangan itu sendiri
5 komentar
Sebenarnya, hal yang paling mengejutkan di tulisan ini adalah satu kata itu.
Fingerspitzengefühl
Finger(jari) + Spitzen(ujung) + Gefühl(perasaan)
Bahasa Jerman yang bahkan punya kata untuk menggambarkan sensasi kendali di ujung jari itu benar-benar... ah..
Ternyata
Fingerjuga bahasa Jerman. Kukira bahasa Inggris...Karena berada dalam rumpun bahasa yang sama, mereka berbagi banyak kosakata dasar.
Memang bahasa Jerman memungkinkan kombinasi kata yang nyaris tak terbatas, haha
Pendapat Hacker News
Sangat menyenangkan dibaca dari awal sampai akhir. Aku bahkan menyarankan teman-temanku untuk mencoba membuat text editor sendiri
Aku sudah memakai editorku sendiri bernama ‘Left’ selama hampir 10 tahun. Awalnya memang belum sempurna, tapi aku terus mengembangkannya dengan memodifikasi Left menggunakan Left. Kegembiraan saat membuka alat yang kubuat sendiri setiap pagi rasanya membayar 20 kali lipat dari waktu yang kuhabiskan
Ada ungkapan, “Dalam hidup, setidaknya sekali kamu harus membangun rumah, menanam pohon, dan membuat editor.” Aku mulai dari yang terakhir
Itu adalah kutipan dari editor bergaya Vi berbasis PicoLisp, Vip
Aku juga membuat text editor sendiri dari nol. Karena fiturnya cukup banyak, aku aktif memanfaatkan alat eksternal seperti LSP, tree-sitter, dan fzf.
Aku merancangnya agar bisa dikustomisasi dengan sederhana hanya lewat modifikasi kode, ala gaya suckless.
Beberapa minggu pertama penuh bug, tetapi semakin sering diperbaiki, semakin stabil jadinya. Bisa lihat proyekku hat
Adakah rekomendasi library pengeditan teks?
GUI wajib ada, jadi aku juga harus menangani font renderer dan graphics context secara langsung.
Kalau hanya untuk console, itu tidak bisa kupakai, tetapi kalau cuma membuat GUI, tidak ada kemampuan editnya, jadi aku butuh keduanya.
Anehnya, sulit menemukan library berbentuk API murni yang memenuhi kebutuhan seperti ini.
Kebanyakan berupa editor yang sudah jadi, atau sudah setingkat framework besar.
Akan bagus kalau ada mesin pengeditan dasar saja yang bisa menangani file teks berukuran besar dengan cepat
Dengan alat seperti trolley, bahkan bisa dibungkus agar terasa seperti UI native berbasis ghostty
Sebagai gantinya, kombinasi SDL dan SDL_ttf cukup bagus. SDL3_ttf juga meningkatkan pemrosesan string
Aku pernah mengimplementasikan ulang editor “kilo” buatan antirez.
Kode aslinya dan tutorialnya sangat bagus, jadi ini proyek yang luar biasa untuk mempelajari mode terminal dan dasar-dasar bahasa C
Aku punya kenangan membuat editor sendiri untuk file COBOL dan ASM pada era 90-an.
Ada syntax highlighting, buffering cepat, bahkan screensaver.
Itu berjalan di Pentium 120, dan dalam ingatanku seribu kali lebih cepat daripada VSCode sekarang
Waktu itu kami menulis semua tag HTML dengan huruf besar
Ini editor zte yang dibuat tokoh utama artikel ini
Kalimat “tahan godaan untuk mendorong bagian yang sulit ke dalam kotak statistik” benar-benar membekas bagiku
Aku juga memakai editor buatanku sendiri. Orang lain memang tidak terlalu peduli, tapi nilai yang kudapat dari alat buatan sendiri sangat besar
Ada juga fitur ‘browser’ sederhana yang bisa membuka tautan dengan F5
Josh Barretto adalah jenius yang membuat port Super Mario 64 GBA. Kalau dia membuat editor, aku pasti mau mencobanya