3 puan yazan GN⁺ 2023-12-10 | 1 yorum | WhatsApp'ta paylaş
  • Gooey, Python 3 konsol uygulamalarını son kullanıcıların rahatça kullanabileceği GUI uygulamalarına dönüştürür; bunu da argparse bildirimi bulunan bir fonksiyona tek satırlık bir dekoratör ekleyerek yapar
  • Temel kurulum pip install Gooey ile yapılabilir ve @Gooey dekoratörü ile ArgumentParser birlikte kullanıldığında Gooey argümanları okuyup WX bileşenleri tabanlı bir UI oluşturur
  • Varsayılan widget seçimi yetersiz kaldığında GooeyParser, ArgumentParser yerine kullanılarak widget argümanıyla FileChooser, DateChooser, PasswordField, Slider gibi özel widget'lar seçilebilir
  • Hedef kullanıcı kitlesi doğrudan CLI kullanan geliştirici araçlarından ziyade, ofis tipi “çalıştır ve bitsin” script'leri veya programcı olmayanlara yönelik araçlardır; gelişmiş/temel/yapılandırmasız çalıştırma modları, menüler, ilerleme göstergesi, uluslararasılaştırma, ikon değiştirme ve paketlemeyi destekler
  • Dinamik doğrulama ve yaşam döngüsü olayları deneysel özellikler olarak işaretlenmiştir; optparse şu anda desteklenmez ve sistem ArgumentParser tabanlı kod ile isteğe bağlı olay aboneliğini varsayar

Konsol programını GUI'ye dönüştürme yöntemi

  • Gooey, konsol uygulamalarını son kullanıcıların daha kolay kullanabileceği GUI uygulamalarına dönüştürür
  • Temel kullanım, argparse bildirimi içeren bir fonksiyona @Gooey dekoratörü eklemektir
from gooey import Gooey

@Gooey
def main():
  parser = ArgumentParser(...)

# rest of code
  • Stil ve davranış dekoratör argümanlarıyla ayarlanabilir
    • advanced: gelişmiş ayar ekranının gösterilip gösterilmeyeceği
    • language: JSON tabanlı çeviri seçimi
    • auto_start: ayar ekranını atlayıp hemen çalıştırma
    • target: alt süreç olarak çalıştırılacak komutun belirtilmesi
    • program_name, program_description: GUI'de gösterilecek ad ve açıklama
    • default_size: GUI'nin başlangıç boyutu
    • dump_build_config, load_build_config: Gooey build ayarlarını JSON olarak kaydetme/yükleme
    • monospace_display: çıktı ekranında eş genişlikli yazı tipi kullanma

Kurulum ve örnekler

  • En kolay kurulum yöntemi pip'dir
pip install Gooey
  • Depoyu klonlayıp ardından setup.py çalıştırarak da kurulum yapılabilir
git clone https://github.com/chriskiehl/Gooey.git
python setup.py install
  • Hazır örnek script'ler Gooey Examples deposundan indirilebilir
  • Örnek deposu, Gooey'in çeşitli yerleşimlerini, widget'larını ve özelliklerini incelemek için sunulur

Neden gerekli

  • Gooey, komut istemini buna alışık olmayan kullanıcılara göstermek zorunda kalma sorununu azaltmak için oluşturulmuştur
  • Bir programın bir veya daha fazla iş yapabilmesi için seçenek alması gerekir ve daha önce bunun için ya GUI'nin elle oluşturulması ya da konsol uygulamasına argümanların nasıl aktarılacağının anlatılması gerekiyordu
  • Gooey, geliştiricinin alışık olduğu şekilde yapılandırılabilir programlar oluştururken, sunum ve etkileşimi GUI üzerinden sağlayabilmesini mümkün kılar

Uygun kullanıcılar ve uygun olmayan durumlar

  • Kendiniz veya başka programcılar için yazılan yardımcı araçlar ya da çıktısı başka konsol uygulamalarına pipe edilecek araçlar için Gooey uygun olmayabilir
  • Ofis tipi çalıştırma script'leri, A noktasından B noktasına veri taşıyan araçlar ve programcı olmayanlara yönelik programlar için uygundur
  • Amaç, karmaşık bir uygulama geliştirirken GUI tarafını ek maliyet olmadan elde etmektir

İç çalışma ve argparse eşlemesi

  • Gooey, çalışma zamanında Python script'indeki ArgumentParser referanslarını parse eder
  • optparse şu anda desteklenmez
  • Çıkarılan argümanlara, sağladıkları action değerine göre component type atanır ve GUI oluşturmak için kullanılır
  • ArgumentParser._actions varsayılan olarak şu WX bileşenlerine eşlenir
    • store: TextCtrl
    • store_const, store_true, store_False, version: CheckBox
    • append: TextCtrl
    • count: DropDown
    • Mutually Exclusive Group: RadioGroup
    • choice: DropDown

GooeyParser ve özel widget'lar

  • Varsayılan widget seçimi yeterli değilse, ArgumentParser için drop-in replacement olan GooeyParser kullanılabilir
  • GooeyParser, gösterilecek bileşenin adını belirtmek için ek widget anahtar kelime argümanını sağlar
from gooey import Gooey, GooeyParser

@Gooey
def main():
  parser = GooeyParser(description="My Cool GUI Program!")
  parser.add_argument('Filename', widget="FileChooser")
  parser.add_argument('Date', widget="DateChooser")
  • Desteklenen özel widget'lar şunları içerir
    • DirChooser, FileChooser, MultiFileChooser
    • FileSaver, MultiFileSaver
    • DateChooser, TimeChooser
    • PasswordField
    • Listbox
    • BlockCheckbox
    • ColourChooser
    • FilterableDropdown
    • IntegerField, DecimalField
    • Slider
  • DateChooser ve TimeChooser tarafından uygulamaya aktarılan değerler her zaman ISO format olur; GUI'nin bazı bölümlerinde ise son kullanıcı ayarlarına göre yerelleştirilmiş değerler gösterilebilir
  • BlockCheckbox, uzun yardım metinleri olduğunda varsayılan satır içi onay kutusuna göre daha iyi bir görünüm sağlamak için metin bloğunu normal konumuna taşır ve kontrolün yanında kısa bir block_label gösterir

Uluslararasılaştırma

  • Gooey, görüntüleme dilini dekoratördeki language argümanıyla seçer
@Gooey(language='russian')
def main():
    ...
  • Tüm program metinleri harici JSON dosyalarında saklanır
  • Yeni dil desteği, gooey/languages/ dizinine anahtar/değer eklenerek sağlanır
  • Şu anda varsayılan olarak 18'den fazla çeviri sunulmaktadır

Genel ayarlar ve UI yapılandırması

  • Gooey'in genel görünümü ve davranışı dekoratör argümanlarıyla ayarlanır
  • Başlıca ayarlar şunlardır
    • encoding: görüntülenecek karakter kodlaması, varsayılan utf-8
    • advanced: tam ayar ekranı veya sadeleştirilmiş ekran seçimi
    • auto_start: yapılandırma olmadan hemen çalıştırma
    • target: Gooey'in kendini nasıl yeniden çalıştıracağını belirtme
    • suppress_gooey_flag: özel target kullanılırken ek CLI parametresi eklenmesini engelleme
    • fullscreen: tam ekran başlatma
    • image_dir: özel görsel/ikon dizini
    • language_dir: özel dil dosyası dizini
    • disable_stop_button, show_stop_warning: çalışırken durdurma düğmesi ve uyarı kontrolü
    • show_success_modal, show_failure_modal: başarı/başarısızlık özet pencerelerini gösterme
    • run_validators: program çağrısından önce doğrulama yapma
    • progress_regex, progress_expr: ilerleme metnini parse etme ve dönüştürme
    • navigation: TABBED veya SIDEBAR
    • body_bg_color, header_bg_color, footer_bg_color, sidebar_bg_color: renk ayarları
    • terminal_font_family, terminal_font_size, terminal_font_color: terminal görünüm yazı tipi ayarları
    • menus: özel menü grupları ve öğeleri
    • clear_before_run: yeniden çalıştırmada önceki çıktıyı temizleme

Yerleşim ve çalıştırma modları

  • Gooey, girdileri varsayılan olarak positional ve optional olmak üzere iki gruba ayırır
  • argparse içindeki add_argument_group() kullanılarak girdiler mantıksal gruplar hâlinde düzenlenebilir ve her grubun yerleşimi ayarlanabilir
parser = ArgumentParser()
search_group = parser.add_argument_group(
    "Search Options",
    "Customize the search options"
)
search_group.add_argument(
    '--query',
    help='Base search string'
)
  • Desteklenen tam yerleşim seçenekleri arasında show_sidebar=True, show_sidebar=False, navigation='TABBED', tabbed_groups=True bulunur
  • Advanced

    • Varsayılan ekran full/advanced ayar ekranıdır
    • Çoğu uygulama için CLI yapısıyla uyumlu düz bir yerleşim uygundur
    • Birden çok yol veya küçük araç kombinasyonlarından oluşan CLI'ler için sütun yerleşimi uygundur
    • Sütun yerleşimi temel yolu sol sütunda, buna karşılık gelen argümanları sağda gösterir
    • Mevcut yerleşim şu anda parametreyle açıkça belirtilemez; yapı, kodda subparsers olup olmamasına göre belirlenir
  • Basic

    • advanced=False ayarlanırsa temel görünüme geçilir
    • Konsol uygulamalarına alışık ancak sade bir terminalden daha özenli bir arayüz isteyen kullanıcılar için uygundur
    @gooey(advanced=False)
    def main():
    
    # rest of code
    
  • No Config

    • auto_start=True ayarlanırsa ayar ekranı olmadan doğrudan görüntüleme alanına geçilir ve ana program çalıştırılır
    • Küçük, tek seferlik script'lerin görünümünü iyileştirmek için kullanılır
    @Gooey(auto_start=True)
    def main():
        ...
    

Menü özellikleri

  • Gooey 1.0.2'den itibaren üstte bir Menu Bar eklenebilir
  • Menüler @Gooey(menu=[{}, {}, ...]) biçiminde bir harita listesiyle tanımlanır
  • Her menü grubu name ve items alanlarına sahiptir
  • Her menü öğesi her zaman type ve menuTitle içerir
  • Desteklenen menü öğesi tipleri şunlardır
    • AboutDialog: ad, sürüm, lisans gibi program bilgilerini gösterme
    • MessageDialog: kullanıcıya bilgilendirici mesaj gösterme
    • Link: belirtilen URL'yi varsayılan tarayıcıda açma
    • HtmlDialog: sınırlı bir HTML alt kümesiyle iletişim penceresi gösterme

Dinamik doğrulama

  • Dynamic Validation deneysel bir özelliktir ve API değişebilir veya kaldırılabilir
  • Gooey, kullanıcı girdilerini programa göndermeden önce isteğe bağlı olarak ön doğrulama yapabilir
  • Bu özellik, Argparse argüman tiplerinin çoğunda kullanılabilen type parametresinden yararlanır
def must_be_exactly_ten(value):
    number = int(value)
    if number == 10:
        return number
    else:
        raise TypeError("Hey! you need to provide exactly the number 10!")
  • Doğrulama varsayılan olarak çalışmaz
  • Etkinleştirmek için VALIDATE_FORM olayına abone olunması gerekir
from gooey import Gooey, Events

@Gooey(use_events=[Events.VALIDATE_FORM])
def main():
    ...
  • Bu özellik içeride yoğun Monkey Patching kullandığı için şu anda opt-in olarak sunulmaktadır

Yaşam döngüsü olayları ve UI kontrolü

  • Gooey 1.2.0'dan itibaren programa yaşam döngüsü kancaları sunar
  • Bu özellik de deneyseldir ve API değişebilir veya kaldırılabilir
  • Şu anda iki ana kanca vardır
    • on_success
    • on_error
  • Her iki kanca da süreç tamamlandıktan sonra çalışır
  • Handler'lar parse edilmiş Argparse nesnesini ve mevcut Gooey UI durumunu alır; güncellenmiş bir durum döndürürlerse bu UI'ye yansıtılabilir
  • Handler'lar GooeyParser oluşturulurken bağlanır
parser = GooeyParser(
    on_success=my_success_handler,
    on_failure=my_failure_handler)
  • Kullanmak için olaylara açıkça abone olunmalıdır
from gooey import Gooey, Events

@Gooey(use_events=[Events.ON_SUCCESS, Events.ON_ERROR])
def main():
    ...

İlerleme ve zaman gösterimi

  • Gooey, mevcut metin tabanlı ilerleme çıktısını okuyarak Progress Bar çalıştırabilir
  • Basit durumlarda Progress 83% gibi bir metin regex ile eşleştirilip ilerleme değerine dönüştürülür
@Gooey(progress_regex=r"^progress: (\d+)%$")
  • Daha karmaşık çıktılar için progress_expr, regex eşleşme sonuçlarını dönüştürmekte kullanılabilir
@Gooey(progress_regex=r"^progress: (?P<current>\d+)/(?P<total>\d+)$",
       progress_expr="current / total * 100")
  • hide_progress_msg=True belirtilirse, ilerlemeyle eşleşen metin çıktısı konsolda gizlenebilir
  • timing_options kullanılarak geçen süre ve kalan süre gösterilebilir
  • Zaman gösterimi yalnızca progress_regex ve progress_expr kullanıldığında çalışır

İkonlar ve paketleme

  • Gooey, varsayılan olarak 6 ikon sağlar; image_dir argümanıyla özel bir görsel dizini belirtilerek bunlar geçersiz kılınabilir
  • Görseller dosya adına göre aranır ve üzerine yazılabilecek dosya adları şunlardır
    • program_icon.png
    • success_icon.png
    • running_icon.png
    • loading_icon.gif
    • config_icon.png
    • error_icon.png
  • Çalıştırılabilir dosya paketleme için PyInstaller kullanım örneği sunulur
  • Özet prosedür, uygulama köküne build.spec koymak, ardından APPPNAME, name, pathex değerlerini projeye göre düzenleyip komutu çalıştırmaktır
pyinstaller -F --windowed build.spec

1 yorum

 
GN⁺ 2023-12-10
Hacker News yorumları
  • Ha, bu benim projem ^_^ neden HN'in en tepesine çıkmış ki?
    argparse ile ilgili yorumlara kısaca cevap vermek gerekirse, Gooey artık epey eski bir proje ve başladığı dönemde argparse sağlam bir seçimdi
    Bu günlerde Gooey'nin kendisi JSON ile çalışıyor ve argparse'tan ayrılmış durumda, ama başka bir arayüz yapan neredeyse hiç kimse olmadığı için argparse hâlâ başlıca “resmî” arayüz olarak kalıyor
    İlginç yanı, yalnızca Python değil rastgele bir çalıştırılabilir dosyayı da çağırabiliyor olması; bu da onu oldukça kullanışlı kılıyor: https://chriskiehl.com/article/gooey-as-a-universal-frontend
    Son commit'in 2 yıl önce olduğuna dair yoruma gelince, insan yaş aldıkça ve öncelikleri değiştikçe niş bir yazılımı ücretsiz biçimde sürdürmeye devam etmek için gerekçe bulmak zorlaşıyor :( teselli eder mi bilmiyorum ama bu konuda hep suçluluk hissediyorum
    Garip şekilde, yaşadığım yerin her yanında “GOOEY” grafitileri var; sanki bakımsız bırakılmış issue tracker'ı sürekli hatırlatan kalıcı bir bildirim gibiler haha

    • argparse hâlâ gayet iyi bir seçim. Çok yaygın kullanılıyor, dokümantasyonu iyi ve nispeten kolay
      Typer ve Click de kullanışlı, ama Typer'ın “tutorial” tarzı belgelerinde Typer.App()'in hangi argümanları aldığı gibi soruların cevabını aramak bana oldukça zor geliyor
      Şu anda üzerinde çalıştığım programda kullanıcılar argüman ayrıştırmayı kendileri başlatıyor, bu yüzden argparse iyi uyuyor. Kullanıcılara metin tabanlı bir UI seçeneği sunmak istiyorum ama Textualize galiba Click gerektiriyordu; Textual'ı doğrudan koda ekleyip UI oluşturmaya da çalıştım, fakat saatler harcamama rağmen başlayamadım bile
    • Gerçekten harika bir fikir. API'den ayrılmış arayüzleri seviyorum
      Bugünlerde uygulamaları programlama yoluyla kontrol edememekten kaynaklanan can sıkıcı durumlar çok fazla. Dürüst olmak gerekirse, her uygulama özelliği için bir API olmasını zorunlu kılan bir yasa olsa keşke
    • Harika proje! Merak ettiğim bir şey var: neden sys.argv'yi geçerli çalışma dizinindeki yerel bir dosyaya döküyorsunuz? https://github.com/chriskiehl/Gooey/blob/be4b11b8f27f500e732...
      tmp.txt pek benzersiz bir ad sayılmaz; bir şeyi mi kaçırıyorum diye merak ettim
    • “Bu günlerde Gooey'nin kendisi JSON ile çalışıyor ve argparse'tan ayrılmış durumda” kısmı çok hoş
      Başlığı görüp tıklamadan önce “kesin argparse'a sıkı sıkıya bağlıdır” diye düşünmüştüm, ama iyi anlamda şaşırdım
      Ben koyu bir getopt hayranıyım, çünkü geliştirici rahatlığından çok kullanıcı rahatlığını önemserim. Kullanıcının, geliştiricinin hangi programlama dilini ya da seçenek ayrıştırma kütüphanesini seçtiğini umursamak zorunda olmaması gerekir
      argparse, Click, Go'nun flag/X11 stili ve daha birçok kütüphane, yarım yüzyılda birikmiş kolektif kas hafızasına işlemiş gelenekleri bozuyor. Ama arada bir katman varsa iki tarafın da avantajını elde etmek mümkün gibi görünüyor
    • Gooey'nin bu kadar eski olmasının sebebi ihmal edilmiş olması. Bunu eleştirmek için söylemiyorum, sadece gerçek bu
      Daha kötüsü, onun yerini alabilecek uygulanabilir bir alternatif de çıkmadı ve iki fork'tan hiçbiri de traction kazanamadı
  • Bu, “argparse tabanlı” diye sınırlandırılmamalı mı?
    argparse basit kullanım senaryoları için iyi, ama Click tabanlı CLI'lar da çok ve popüler CLI kütüphanelerinin önemli bir kısmı Click üzerine kurulu. argparse veya Click kullanmayan Python CLI araçları da var, ama bu ikisi muhtemelen en popüler olanlar
    Click ile de çalıştığı doğrulandı mı? Şu anda yalnızca argparse ile ilgili şeyler görüyorum. Cevap hayırsa, “neredeyse tümü” ifadesi açıkça yanlış olur ve daha doğru başlık “neredeyse tüm argparse tabanlı Python komut satırı programlarını tam teşekküllü GUI uygulamalarına dönüştürmek” olur
    Son anlamlı commit'in 2 yıldan daha eski olması da var. Bu tek başına kötü bir şey değil, ama açık issue sayısına bakınca projeye çok güven vermiyor
    Yine de harika bir proje. Bundan daha fazlasını görmek isterim. README'de dendiği gibi bu bir güç çarpanı araç; biri CLI ile otomasyon kurup bunu teknik olmayan ofis çalışanlarıyla kolayca paylaşabilir. Access'in veritabanları için yaptığı şeye benziyor
    Access'te olduğu gibi, ölçek ya da karmaşıklık artınca sınırlarına toslarsınız, ama küçük ofis kullanımları için fazlasıyla “yeterince iyi” olabilir

    • argparse'ta ne eksik görüyorsunuz, merak ettim. Benim eğilimim harici bağımlılıkları en aza indirmek yönünde
    • Önceki işyerimde tam olarak bu amaç için kullandım. Çok sayıda işi otomatikleştirdim ve ekip için araçlar yaptım, ama çoğu Python programcısı değildi; bu yüzden script'lerin üstüne Gooey ile basit bir GUI ekledik. Son derece iyi çalıştı
    • Tam olarak argparse ile yapılamayan şey ne?
  • İlgili bağlantılar:
    Gooey: Turn almost any Python command line program into a GUI application - https://news.ycombinator.com/item?id=27490291 - Haziran 2021, 115 yorum
    Gooey: Turn command line programs into GUI applications - https://news.ycombinator.com/item?id=8218785 - Ağustos 2014, 74 yorum

  • İşletim sistemleri ve kabukların, belirli bir ayrıştırma kütüphanesine bel bağlamadan programların nasıl çalıştırıldığını daha iyi anlayabilmesi güzel olurdu
    Programlar tipli JSON/proto biçiminde iletişim kursa ve yalnızca beklenen girdi/çıktı tiplerine bakarak kabuk komutlarının yapılandırılması, otomatik tamamlama ya da tam teşekküllü bir GUI elde edilebilse güzel olurdu
    Şu anda ise dikkatlice pipet takılarak yapılmış bir düzey en iyi seçenek gibi görünüyor. Programların her biri farklı kabuklar için birden fazla otomatik tamamlama dosyası dışa aktarmak zorunda, programdan programa ve ayrıştırma kütüphanesinden kütüphaneye bayrak stilleri çok değişiyor ve elbette GUI de yok

    • Artık PowerShell diye bir şey var. Daha ciddi bir yanıt vermek gerekirse, bunu gerçekten denemiş tek işletim sistemi muhtemelen Plan 9 olmuştur
    • İşletim sistemi düzeyinde yerel desteği olan genel amaçlı bir gRPC değişim/CLI API gibi bir şey mi kastediyorsun? Bu oldukça hoş olabilir
      Ancak gRPC'nin temel sorunu, buna ben de dahilim, birçok geliştiricinin bunu dil içinde doğal hissettiren çözümlere kıyasla biraz hantal bulması olabilir
    • PowerShell denemekte fayda var. Temelde Microsoft'un .NET ekosistemi etkileşimli komut satırı hâline getirilmiş durumda
      PowerShell'in özünü oluşturan statik tiplerden tam anlamıyla yararlanıp yararlanamadığından emin değilim, ama komut satırında nesneleri alıp verme yeteneği neredeyse benzersiz
      Linux'ta jc(https://github.com/kellyjonbrazil/jc) ve jq(https://jqlang.github.io/jq/) birleştirilerek komut satırı zincirlenebilir, ama bu yine de PowerShell'in yerleşik yeteneklerine kıyasla iki adım daha fazla iş demek
  • GUI bazen konfor yemeği gibi hissettiriyor. Çünkü nadiren kullanılan bir CLI'nin yaratabileceği bilişsel yük olmadan GUI arayüzünü sadece gözden geçirebiliyorsun
    Biraz farklı bir konu ama birkaç ay önce burada CUDATEXT editörünü öğrendim; tek dosyalık Python API ile MENU, INPUTS gibi rastgele GUI öğelerini kullanmayı sağlıyor. Bunlar editörün kendisinin de kullandığı öğeler
    Şu anda bu tür basit GUI öğeleriyle yapılandırma yapıyor ve doğrudan editörün içinde blog oluşturuyorum

  • Bakmaya değer başka bir şey:
    “Textual: Python için hafif bir uygulama çatısı. Basit bir Python API ile gelişmiş kullanıcı arayüzleri oluşturun ve uygulamaları terminalde ve web tarayıcısında çalıştırın” https://github.com/textualize/textual/

  • Bu harika yazılımı yaptığın için teşekkür etmek istiyorum. Gooey'yi seviyorum ve onu birçok programda sıkça kullandım
    Benim için, Python betiğinin önemli işleri yaptığı ve artık programcı olmayanların da kullanması gereken o tam alana mükemmel uyuyor

  • Bu bana naked objects fikrini hatırlatıyor. Fikir, bir Java sınıfında birkaç anotasyon ve tema tanımlayarak tüm GUI'nin ya da bir web frontend uygulamasının üretilmesiydi
    Çok havalı bir fikirdi ama bildiğim kadarıyla sonunda pek yolunda gitmedi

    • Django'nun da benzer bir felsefesi var. Bir modeli tanımlarsın, bu doğrudan veritabanı tablosuna yansır ve o modelden formlar otomatik üretilebilir
      Bence sorun, sunum, etki alanı ve altyapı gibi dikey kaygıların birbirine bağlanması. Etki alanı modelinin ekran temsili ve veritabanı temsili basitse bu sorun olmuyor
      Ama çok sayıda kolaylık özelliği olan karmaşık bir arayüz yapmak istediğinde, bu gereksinimlerin etki alanı katmanına sızması gerekiyor. Tersi yönde, karmaşık bir etki alanı modeli kurmak istediğinde ise dil düzeyinde değişmezleri zorlamak gerçekçi olmuyor. Çünkü Model referansı olan herhangi bir kod onu keyfine göre kurcalayabiliyor
  • Bunun tersini yapan bir şey de güzel olurdu

    • GUI üzerinden argparse'tan alınan bilgilere dayanarak parametre süpürmesi ayarlayıp, sonuçları uygun şekilde çalıştıran ve kaydeden bir kabuk betiğine geri dönüştürebilmek güzel olurdu
    • WYSIWYG editörünün CLI üretmesini mi kastediyorsun? Kulağa oldukça hoş geliyor ama kaçınılmaz olarak bazı kısıtları olur gibi. Birinin böyle bir yaklaşımı denediğini merak ediyorum ama aklıma bir örnek gelmiyor
  • Eski Macintosh Programmer's Workshop, yani 80'ler ve 90'larda Mac OS için kullanılan metin tabanlı kabuk MPW'de, neredeyse her komut için Commando adlı benzer bir özellik vardı
    Commando bilgileri cmdo kaynağında saklanıyordu. Genişletilmiş öznitelik desteği bu kadar tutarsız olmasaydı bugün de benzer bir şey yapılabilirdi
    Bakınca A/UX'te de Commando olduğunu gördüm. Finder'da bir terminal komutuna çift tıklayınca CLI seçeneklerini seçtiğin bir Commando kutusu açılıyor, ardından komut bir kabuk penceresinde çalışıyordu. Bugünün Finder'ında bir terminal komutunu çalıştırırsan, sadece bağımsız değişken olmadan bir kabuk penceresinde çalışıyor
    https://cohost.org/boredzo/post/804893-i-still-want-a-moder
    http://toastytech.com/guis/aux3.html