Bir zsh komut satırındaki tüm diğer adları çözümleme


12

Diğer adları iç içe yerleştirdim ve komutu çalıştırmadan önce hepsini çözmek istiyorum. Bunu nasıl yaparım?

Herhangi bir tuşa bağlı olmayan bir işlev varsa, o zaman M-x foobarbenim için de iyi. Hatta dış komutunu kullanabilirsiniz ( type, command, which, neyse). Ben her şeyi denedim Neden "hangi" kullanmıyorum? O zaman ne kullanılır? ama hiçbir şey işe yaramıyor.


3
C-x aimlecin altındaki diğer adı genişletir (tamamlama sistemini kullandığınızı varsayarsak).
Stéphane Chazelas

Doğru _expand_alias (^Xa): expands the word the cursor is on if it is an alias,. Bu yardımcı olur, ancak yine de bash bir bütün çizgi genişletmek ama zsh değil yazık.
WeSenseASoulInSearchOfYanıtlar

_expand_aliasDüzenleme arabelleği artık değişene kadar çağıran ikili bir komut yazmanın mümkün olduğunu varsayalım .
vinc17

Yanıtlar:


10

Ctrl-Alt-E bashgirişinin yalnızca takma adları genişletmediğini unutmayın. Ayrıca değişkenleri genişletir, komut değiştirme (!), İşlem değiştirme (!), Aritmetik genişletme ve tırnak işaretlerini kaldırır (dosya adı oluşturma (globbing) veya tilde genişletme yapmaz).

Takma adları genişletmek her zaman başaramaz. Bu yüzden kullanımları olmasına rağmen, sonucunun potansiyel olarak komut satırının anlamını değiştirdiğini, yan etkilere sahip olduğunu ve potansiyel olarak tehlikeli olduğunu fark etmek önemlidir.

Örneğin:

$ a=';w' b=1
$ alias foo=bar
$ b=2; echo $b $a; cd /tmp/dir && for i do foo $(pwd) <(ls); done

Eğer M-C-Eburaya basarsam, bu bana şunu verir:

$ b=2; echo 1 ;w; cd /tmp/dir && for i do foo / /dev/fd/63; done

Bu da bana tamamen farklı bir komut satırı verir (ve olsaydı neler olurdu hayal rm -rf *yerine pwdyukarıda) ve genişletmek değil foodiğer adı.

İle zsh, fonksiyonlar içinde genişletilen diğer adları ile ilgili Gilles' not oluşturmak için, bunu yapabilirsiniz:

expand-aliases() {
  unset 'functions[_expand-aliases]'
  functions[_expand-aliases]=$BUFFER
  (($+functions[_expand-aliases])) &&
    BUFFER=${functions[_expand-aliases]#$'\t'} &&
    CURSOR=$#BUFFER
}

zle -N expand-aliases
bindkey '\e^E' expand-aliases

Bu, takma adları yalnızca geçerli komut satırı sözdizimsel olarak geçerli olduğunda genişletir (böylece sözdizimi denetleyicisi olarak iki katına çıkar).

MCE'nin aksine bash, takma adları da tamamen çözer. Örneğin:

$ alias ll='ls -l'; alias ls='ls --color'
$ ll

Genişletilecek:

$ ls --color -l

Ayrıca sözdizimini standartlaştırdığına dikkat edin:

$ for i (*) cmd $i; foo

olarak değiştirilecek:

$ for i in *
        do
                cmd $i
        done
        foo

Bu adamcağız. Eğer varsa alias ls='ls --color've C-x aüzerine yazarsam ls, şunu elde ederim: \ls --color(böylece yeni lsbir takma ad olarak yanlış yorumlanmaz). Ama expand-aliasesseninle, anladım:, ls --colorsonuç belirsiz.
vinc17

@ vinc17, takma adı tam olarak çözmesi belirsiz değildir (bu bakımdan basheşdeğerden daha az hatalıdır ). Ancak bundan sonra komutu çalıştırırsanız, başka bir takma ad genişletme (in gibi bash) alırsınız, bu yüzden ideal olarak takma genişletmeyi geçici olarak devre dışı bırakmak istersiniz, örneğin bunu a (){ setopt localoptions noexpandalias; ...; }. _expand_aliasBuggy olduğunu söyleyebiliriz ve çalıştırıldığında takma adı genişletir \ls.
Stéphane Chazelas

@ vinc17, bu eğik çizgi tarafından yapılan görülen çıkış _expand_aliaskolayca gibi aptal edilir alias 'foo=repeat 3 foo'ya da alias ls='ls --color'; alias '\ls=echo fooled'. Burada mükemmel bir çözüm yok.
Stéphane Chazelas

İlgili _expand_aliasiçin alias 'foo=repeat 3 foo', ben bir hata olarak eksik ters eğik çizgi konusunda olacaktır. Ve alias '\ls=echo fooled'izin verilmemeli; Burada ben diyor ki, bash tercih: bash: alias: '\ls': invalid alias name.
vinc17

@ vinc17, bunun bir sınırlamadan başka bir şey olarak nasıl görülebileceğini göremiyorum bash. Ters eğik çizgi içeren takma adlardan hoşlanmıyorsanız, onları kullanmayın, ama neden kabuğun onları reddetmesini istersiniz? Takma adlar csh'de (nereden geldikleri) fakir bir adamın işlevlerinin yerini alırken, Bourne benzeri kabuklarda, işlevlerle yapılamayan hileler yapmak, , Yapabileceklerini kısıtlama noktasını görmüyorum.
Stéphane Chazelas

6

Bir işlev tanımına bir komut satırı doldurup işlevi yazdırırsanız, takma adlar genişletilir. Ayrıca normalleştirilmiş boşluk elde edersiniz.

% alias foo='bar -1'
% alias bar='qux -2'
% f () foo -3
% which f
f () {
        qux -2 -1 -3
}

Tüm bunları etkileşimli bir komuta koymak için bir zle widget'ı yapabilirsiniz. Bir işlevi doğrudan kodunu functionsdizideki bir girişe doldurarak tanımlayabilirsiniz ; okuduğunuzda normalleştirme efekti elde edersiniz.

normalize-command-line () {
  functions[__normalize_command_line_tmp]=$BUFFER
  BUFFER=${${functions[__normalize_command_line_tmp]#$'\t'}//$'\n\t'/$'\n'}
  ((CURSOR == 0 || CURSOR = #BUFFER)
  unset 'functions[__normalize_command_line_tmp]'
}
zle -N normalize-command-line
bindkey  normalize-command-line

Aynı normalleştirme etkisini preexeckancada alırsınız . Takma adlar ayrıca bir işlev otomatik yüklendiğinde genişletilir ( autoload -Utakma ad genişletmesini önlemek için yaygın olarak kullanılır).

_expand_aliasBir takma ad ise tamamlama fonksiyonu imlecin olduğu kelimeyi genişletir. aliasesDiziyi kullanır . Özyinelemeli değil. Kullanarak daha genel bir takma ad genişletici uygulayabilirsiniz aliases, ancak biraz zordur, çünkü takma adların genişletildiği konumları bulmak kabuk kabuğunun sözdizimiyle yakından bağlantılıdır.


2
autoload -UZsh belgeleri bunu önerdiğinden her zaman kullandım , ancak bunu okuyana -Ukadar aslında ne yaptığını hiç anlamadım :). Herkes ilgi için de, tek çağırabilir _expand_alias isabet komut satırında içine takma yazarak doğrudan işlev <Esc>, xsonra yazarak, minibuffer başlatmak için,_expand_alias<Enter>
the_velour_fog

2

Birçok iç içe süslü takma adınız varsa ve zsh'ın aslında ne yaptığını ve hangi sipariş seçeneklerinin komuta iletildiğinden emin değilseniz, zsh'yi her zaman seçenekle başlatabilirsiniz -x. Bu, komutları ve bağımsız değişkenleri yürütüldükçe yazdırır.

Bununla birlikte, bu seçeneğin hata ayıklama amacına yönelik olduğunu unutmayın, bu nedenle çağrıldıktan hemen sonra zsh -x(temelde .zshrc'nizin her bir işlevi / widget / eklentisi) çok fazla işe yaramaz şey yazdırır ve komut yürütme sırasında da özellikle ayrıntılı olabilir. tanımladıysanız preexecve precmdçengelseniz.

Ayrıca, yalnızca son olarak yürütülen komutları yazdırdığını ve ayrılmış komutların ayrı olarak yazdırıldığını belirtmeliyim.

alias a='echo a'
alias b='echo b'
alias c='echo c'
alias d='echo d'
a && b || c; d

Göreceksin

+zsh:1> echo a
a
+zsh:1> echo b
b
+zsh:1> echo d
d
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.