CLI Uygulamaları için bash ve zsh Autocompletion (Otomatik Tamamlama)
25 Apr 2013Merhaba,
Front-end development’in en eski türlerinden biri olan CLI development’tir. Yani Command Line Interface. Her ne kadar HTML veya masaüstü arayüzleri gibi olmasa da o da en nihayetinde bir interface’dir. Bir front-end‘dir.
Bash’de autocompletion’u bilirsiniz. TAB karakterine basarak otomatik tamamlama yapmanızı sağlayan özelliktir.
$ sudo apt-<tab>
dediğinizde
$ sudo apt-<tab>
apt-get apt-add-repository
şeklinde tamamlamalarda bulunarak sizin bash üzerinde daha hızlı komut yazmanıza yardımcı olur.
Yazdığınız bir komuta bash autocompletion desteği vermek de bir o kadar basit.
Örnek üzerinden anlatırsak daha faydalı ve öğretici olacağını düşünüyorum. Adı fka
olan bir program yazmak istiyoruz diyelim. Öncelikle CLI uygulamamızın kısımlarını belirlememiz gerekiyor.
$ fka [modul] [komut] [opsiyon] [--opsiyon]
Temelde komutun kendisinden sonra 4 farklı komut aldığını gördük. Bunu şimdilik sadece 2 komut alacak şekilde ayarlayalım.
$ fka [modul] [komut]
Otomatik tamamlamak istediğimiz kısımlar bunlar olsun
$ fka blog new-post
şeklinde bir CLI front-end’i ile yeni bir blog metni yazabileceğimizi düşünelim.
$ fka <tab>
blog ftp site
gibi bir otomatik tamamlama olacak. Yani fka
komutunun 3 farklı modülü var ve bunlar blog
, site
ve ftp
. Autocompletion filtrelemesi olması için bir de ssh
ekleyelim.
$ fka <tab>
blog ftp site ssh
Yani kurguladığımız şekilde yaparsak
$ fka s<tab>
site ssh
şeklinde s ile başlayan ssh
ve site
değerlerini bizimle paylaşarak bize yardımcı olacak.
zsh’da Otomatik Tamamlama
ZSH güzel autocompletion’ları ile meşhur bir shell’dir. Bu yüzden olsa gerek, autocompletion yazmak zsh’da çok daha kolay ve güzeldir.
Öncelikle _fka_completion
adında bir fonksiyon yaratıyoruz, bu isim her şey olabilir çünkü daha sonra bu komutu compdef
ile fka
komutuna tanıtacağız.
Daha sonra bu fonksiyonumuz içerisinde argümanların neler olacağını belirtiyoruz.
Eğer 3 parçadan oluşan bir komut yazsaydık,
gibi bir bölüm daha eklememiz gerekecekti. Şimdilik ilk hedefimiz sadece ilk bölüm olduğu için 1 adet bırakalım.
Sonrasında ise completion’un bize gönderdiği $state
değişkeni ile hangi state’de olduğumuzu görüp ona uygun cevabı vermemiz gerekiyor.
dediğimiz zaman autocompletion methodumuz hazır olmuş oluyor. Şimdi bu fonksiyonu compdef
ile tanımlayalım.
Bu iki komutu yazdıktan sonra tekrar deneyelim:
% fka <tab>
blog ftp site ssh
Filtreleyelim:
% fka s<tab>
site ssh
bash’da Otomatik Tamamlama
zsh
da nasıl yapıldığını temel olarak gördüğümüze göre artık bunu bash üzerinde nasıl yapacağımızı görelim. Bash, Zsh’dan daha kolay ama daha kötü bir yazım şekline sahip. Filtrelemeyi de zsh’daki gibi kendisi yapmıyor, bizim yönetmemiz gerekiyor. Detaylarına bakalım.
dedikten sonra complete
komutuyla bu fonksiyonu tanıtalım:
Bu iki komutu yazdıktan sonra tekrar deneyelim:
$ fka <tab>
blog ftp site ssh
Filtreleyelim:
$ fka s<tab>
blog ftp site ssh
Filtreleyemediğimizi görüyoruz, çünkü bash COMPREPLY
ile gelen verilere izin vermiyor.
bash Otomatik Tamamlamada Filtreleme Yapmak
Filtrelemeyi madem COMPREPLY
ile yapamıyoruz, o halde biraz daha akıllı bir hale getirelim. Bu sefer compgen
komutunu ve filtreleme yapmak için ise grep
komutunu kullanalım.
compgen
kullanırken grep
yerine --
kullanmak daha doğru bir kullanım olacaktır.
Bu şekilde dönen tüm sonuçlar arasından uygun olan kelimeyi buluyoruz.
$ fka s<tab>
site ssh
zsh ve bash Otomatik Tamamlama Betiklerini Birleştirmek
Elimizde artık iki ayrı fonksiyon ve iki ayrı fonksiyon tanıtma komutu var. Fakat bunları tek bir yerde birleştirmemiz en doğrusu olacaktır.
Bunu yapmamızın en kolay yolu compdef
ve complete
komutlarının varlığına göre duck typing
yapmak. Eğer compdef
komutu varsa zsh, complete
komutu varsa bash içerisindeyizdir.
Yani fka
komutumuzun yeni hali şu şekilde olacak:
Alt Otomatik Tamamlamalar
Artık hem zshmodüldende bash’ta çalışan bir autocompletion’a sahibiz, fakat tam anlamıyla bitmiş sayılmaz. Çünkü başta bahsettiğimiz gibi iki parçadan oluşması gerekiyordu.
% fka blog new-post
diyebilmem için blog
yazdıktan sonraki ikinci kısmın da değişebilmesi gerekiyor.
zsh’da Alt Otomatik Tamamlamaları
Dolayısıyla yeni bir parça eklemek için zsh
da yapmamız gerekenler şu şekilde olacak:
Şimdi deneyelim:
% fka <tab>
blog ftp site ssh
% fka b<tab>
% fka blog <tab>
% fka blog new-<tab>
new-category new-post
bash’da Alt Otomatik Tamamlamaları
Şimdi aynı işlemi bash üzerinde yapalım.
Burada COMP_CWORD
değeri bize kaçıncı kelimede olduğumuzu gösteriyor. Aynı zamanda COMP_WORDS
ile tüm kelimeleri alabiliyoruz ve COMP_LINE
ile tüm komutu almamız da mümkün.
Şimdi buna bir alt modül daha ekleyelim:
Artık new-post
için yeni alt modüllerimiz mevcut.
$ fka blog new-post<tab>
title abstract
Dinamik Otomatik Tamamlama
Şimdiye dek yazdığımız tüm kod statik veri üzerinden ilerliyor gördüğümüz üzere. Bu kodu dinamik hale çevirmemiz gerekiyor. Bunun için gerekli bilgiler de elimizde mevcut aslında.
Bu durumda zsh
için compadd
komutu kullanılır.
Tabii eğer burada kullanılan ls
komutu yerine kendi komutunuzu yazdıysanız, bu durumda hangi durumda olduğunuzu gösteren veriyi göndermeniz gerekir.
Aynı durum bash
için şu şekilde olacaktır:
Aynı şekilde bunu kendi komutumuzla değiştirecek olursak:
Eksik olan kısımlar daha sonra tamamlanacaktır. Teşekkürler!