Sed ile Zsh otomatik tamamlama işlevi


1

Bir ZSH otomatik tamamlama işlevi yazmakta zorlanıyorum. Amacım otomatik tamamlama ta 'nın ve tk 'de listelenen projelerle ilk argümanı tmux list-sessions ve tmuxinator list.

İşte şimdiye kadar sahip olduğum şey:

tmux list-sessions şuna benzeyen verileri çıkarır:

dotfiles: 1 windows (created Tue Apr 15 21:54:51 2014) [123x48]
goodbye: 1 windows (created Tue Apr 15 21:51:34 2014) [123x48]
hello: 1 windows (created Tue Apr 15 21:42:03 2014) [123x48]

tmuxinator list çıktılar:

tmuxinator projects:
dotfiles           landonschropp.com

İşte benim girişimim:

tmux-list-sessions-autofill() {

  # get the tmux and tmuxinator sessions
  TMUX_SESSIONS=$( tmux list-sessions | cut -d: -f1 )
  TMUXINATOR_SESSIONS=$( tmuxinator list | tail -n +2 | gsed -e 's/\s\+/\n/g' )

  # remove duplicates
  SESSIONS=$( echo "$TMUX_SESSIONS\n$TMUXINATOR_SESSIONS" | sort | uniq )

  # set the autocomplete values
  reply=( $(echo $SESSIONS) )
}

compctl -K tmux-list-sessions-autofill ta
compctl -K tmux-list-sessions-autofill tk
  • tmux list-sessions | cut -d: -f1 Proje isimleri dışındaki her şeyi kaldırır.
  • tmuxinator list | tail -n +2 | gsed -e 's/\s\+/\n/g' ilk satırı kaldırır ve boşluk ile yeni satırları değiştirir.
  • echo "$TMUX_SESSIONS\n$TMUXINATOR_SESSIONS" | sort | uniq yinelenen çizgileri kaldırır.
  • kullanıyorum gsed çünkü ben OS X’de ve sed biraz vidalı.

Benim işlevim işe yarıyor ama Gerçekten mi yavaş. Ben bir kabuk komut dosyası acemi, bu yüzden bunu başarmak için daha etkili bir yol olduğundan eminim. Darboğazım nerede ve nasıl düzeltebilirim?


Bu iki komutu ekarte edebilir misin? tmux list-sessions ve tmuxinator list gecikmeye neden olur mu? İlgilenirim time tmuxinator list, time tmuxinator list | tail -n +2 ve time tmuxinator list | tail -n +2 | gsed -e 's/\s\+/\n/g'. Analog komutla, gecikmeye bir komutun neden olup olmadığını ya da yalnızca toplamda sonuçlanıp sonuçlanmayacağını izleyebilirsiniz.
mpy

Oh, vay, zaman komutunu bilmiyordum. Bu oldukça havalı. Her komutu 5 kez çalıştırdım ve sonucun ortalaması aldım. time tmux list-sessions 0.05s aldı time tmuxinator list 0,716 aldı. time tmuxinator list | tail -n +2 ve time tmuxinator list | tail -n +2 | gsed -e 's/\s\+/\n/g' önemli bir gecikme eklemedi. Sanırım bunun için tmuxinator'da bir sorun açacağım. Yardım için teşekkürler!
LandonSchropp

Memnun oldum, tıkanıklığı buldun. Oturum listelerini ayrıştırmak için yalnızca yerleşik zsh özelliklerini kullanan bir yanıt yazdım. Zsh'in güçlerini kullanmak istiyorsun, değil mi? ;)
mpy

Yanıtlar:


2
  1. Gecikmeyi izlemek için builtin komutunu kullanabilirsiniz. time bir borudaki tüm komutların katkılarını listeleyebilecek:

    zsh% time sleep 2 | date | sleep 1
    sleep 2  0.00s user 0.00s system 0% cpu 2.003 total
    date  0.00s user 0.00s system 0% cpu 0.004 total
    sleep 1  0.00s user 0.00s system 0% cpu 1.004 total
    
  2. (Yorumunuza göre) harici komuttur tmuxinator list gözle görülür bir gecikmeye neden olan, yine de tamamlama işlevinizi optimize edebilirsiniz. Çok fazla harici komut kullandınız ( sed, cut, ...) çıktıyı ayrıştırmak için. Burada sadece zsh'nin yerleşik yeteneklerini kullanan bir yaklaşım göstereceğim.

    tmux-list-sessions-autofill() {
      local -aU SESSIONS
      SESSIONS=("${(@)${(f)$(tmux list-sessions)}/:*/}")
      SESSIONS+=("${(@)${(f)$(tmuxinator list-sessions)}[2,-1]/[ $'\t']*/}")
      reply=(${(i)SESSIONS})
    }
    

    Bu ilk bakışta karmaşık görünebilir, ancak bir kere alıştıktan sonra, zsh parametresinin genişlemesi çok güçlü. Baştan aşağı:

    • local -aU yerel bir parametre açıkladı SESSIONS, bir dizidir ( a ) ve U dizi değerlerini benzersiz tutar . +
    • ilk önce oturumları al tmux list-sessions, içeriden dışarıya açıklanır:
      • $(tmux list-sessions) harici komutun çıktısını alır
      • ${(f)$(tmux list-sessions)} sonucu böler \n
      • ${(@)${(f)$(tmux list-sessions)}/:*/} Her dizi elemanında çalışır ( (@) ) ve bir arama yapar & amp; değiştirmek /from/to, buz. ilk kolondan sonra ve sonra her şeyin kaldırılması.
      • Şimdi, $SESSIONS içerecek (dotfiles goodbye hello). kullanım print -l $SESSIONS Her dizi öğesini tek bir satıra yazdırmak için.
    • sonraki, neredeyse aynı prosedür için tmuxinator list, bu ilavelerle:
      • Son öğeye yalnızca ikinciyi kullanın ( [2,-1] )
      • a'dan sonraki (ve dahil) her şeyi sil space veya tab ( $'\t' ) karakter
      • bu elemanları ekle ( += ) için SESSIONS dizi
    • Sonunda, geri SESSIONS dizi sıralanmış büyük / küçük harf duyarlı (i)

Tüm bu açılımlar, daha uzun, genel biçimini kullanır. ${parameter} kestirme not yerine $parameter. Görmek man zshexpn sözdizimi ve toplum hakkında çok daha iyi bir açıklama için Parametre Genişletme Bayrakları (sevmek (f) ).


+ Göre Bart Schaefer U bayrak gerekli değildir, çünkü tamamlama kodu, dahili tamamlama listesini benzersiz kılar, bu yüzden gereksiz girişleri dizilerden kaldırmak gerçekten yardımcı olmaz bunları sadece tamamlama için kullanırken önceden edin.


Bu harika! Bunları yazmaya zaman ayırdığınız için çok teşekkür ederim. Gerçekten çok yardımcı oldu.
LandonSchropp

@LandonSchropp Hey, ekstra ödül için çok teşekkürler :) Yine de gerekli değildi - sana bazı ipuçları verebilirim sevindim.
mpy

Gerekli olmayabilir, ama yardım etmek için kendi yolundan çıktığını hissettim ve teşekkür etmek istedim. :)
LandonSchropp

-1

İşte başka bir alternatif :)

tmux-list-sessions-autofill() {
    reply=( `tmux list-sessions | sed "s/:.*//g"` );
}

===== EDIT =====

Bu yüzden @ NetworkKingPin'in yorumuna cevap olarak cevabımı burada formüle ediyorum.

@LandonSchropp'un orijinal yayınında, yalnızca tmux-list-sessions-autofill() Bunun için işlev:

tmux-list-sessions-autofill() {
    reply=( `tmux list-sessions -F '#{session_name}'` ); 
}

Orijinal gönderimde kullandığımı fark et sed oturum adlarının yanı sıra diğer bilgileri silmek için. Ama bu sefer bir kullanıyorum -F söyleyen argüman tmux için sadece oturum adlarını yazdırabilir ve diğer bilgileri atlayabilirsiniz.

Bu benim için harika çalışıyor. Umarım bu yeterince açıktır.


Alternatifinizi açıklamak, Soruyu bu şekilde anladığını soran Kişi için daha iyi olacaktır.
NetworkKingPin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.