Aggiungi argomenti dal comando precedente al completamento zsh


22

In zsh (oltre a bash) puoi usare alcune espansioni di parole della cronologia per indicare argomenti di comandi precedenti.

Questo esempio mostra come ottenere il 2o parametro dal comando precedente nella cronologia con !:#espansione:

% echo foo bar baz
foo bar baz
% echo !:2
echo bar
bar

Spesso dimentico esattamente quale sia il parametro # di un particolare argomento e la digitazione !:#non è sempre così rapida quando ricordo quale argomento . So meta-.di sostituire l'ultimo argomento, ma a volte non è l'ultimo argomento che voglio.

Vorrei aggiungere gli argomenti del comando precedente come suggerimenti per completare qualsiasi comando che sto scrivendo in zsh.

Sono stato in grado di capire come creare una funzione di shell in grado di creare una matrice di argomenti (0..N) dall'ultimo comando e associarlo a un comando particolare.

_last_command_args() {
    last_command=$history[$[HISTCMD-1]]
    last_command_array=("${(s/ /)last_command}") 
    _sep_parts last_command_array
}

# trying to get last_command_args to be suggested for any command, this just works for foo
compdef _last_command_args foo

Questo è quello che sembra per aver completato solo il punto in cui ho premuto il tasto Tab su <TAB>:

% echo bar baz qux
bar baz qux
% foo <TAB>
bar   baz   echo  qux 

Funziona benissimo per completare il comando "pippo", ma vorrei che fossero opzioni su qualsiasi espansione zsh che faccio. Penso che abbia qualcosa a che fare con le cose del completatore di zstyle, ma dopo alcune ore di hacking ho capito di essere fuori dalla mia profondità.

Come posso ottenere gli argomenti dal mio comando precedente come completamenti suggeriti per qualsiasi comando in zsh?

Ho tutto il mio file compinstall zshrc condiviso su bitbucket se questo aiuta. Molti di questi sono paralizzati da una varietà di fonti e alcuni di essi li ho hackerati insieme.

AGGIORNARE:

@Julien La risposta di Nicoulaud mi ha avvicinato, la sto contrassegnando come accettata in quanto mi ha portato dove dovevo trovare.

Con la mia configurazione particolare, usando il suggerito:

zstyle ':completion:*' completer _last_command_args _complete

Non ha funzionato abbastanza per me poiché stava causando il completamento della scheda per visualizzare solo l'elenco degli argomenti dell'ultimo comando (anche se in realtà sarebbe completo anche di nomi di file, ma non li visualizzava). Cambiando l'ordine per _complete _last_command_argsfare il contrario. Visualizzerebbe i nomi di file normali, ma non last_command_args

Immagino che questo abbia qualcosa a che fare con il modo in cui funziona il completatore. Penso che visualizzi solo l'output del primo metodo che ritorna correttamente, ma ho problemi ad analizzare la fonte zsh per capire appieno cosa sta succedendo. Sono stato in grado di modificare il mio metodo per includere una chiamata in _completemodo che mostrasse sia i comandi dell'ultimo argomento sia i normali elementi di completamento automatico. Non abbastanza separato, ma funziona abbastanza bene per me.

Ecco la funzione completa che ho usato insieme alle altre cose di zstyle che ho:

# adds the arguments from the last commadn to the autocomplete list
# I wasn't able to get this to work standalone and still print out both regular
# completion plus the last args, but this works well enough.
_complete_plus_last_command_args() {
    last_command=$history[$[HISTCMD-1]]
    last_command_array=("${(s/ /)last_command}") 
    _sep_parts last_command_array
    _complete 
}


_force_rehash() {
  (( CURRENT == 1 )) && rehash
  return 1  # Because we didn't really complete anything
}

zstyle ':completion:::::' completer _force_rehash _complete_plus_last_command_args _approximate 

Altre linee di zstyle che ho, non necessarie per farlo funzionare, ma potrebbero influenzare il motivo per cui questo funziona per me:

zstyle -e ':completion:*:approximate:*' max-errors 'reply=( $(( ($#PREFIX + $#SUFFIX) / 3 )) )'
zstyle ':completion:*:descriptions' format "- %d -"
zstyle ':completion:*:corrections' format "- %d - (errors %e})"
zstyle ':completion:*:default' list-prompt '%S%M matches%s'
zstyle ':completion:*' group-name ''
zstyle ':completion:*:manuals' separate-sections true
zstyle ':completion:*' menu select
zstyle ':completion:*' verbose yes

Ora, se sono in una directory con file1.txte file2.txt, e il mio ultimo comando è stato echo foo bar baz, ottengo questo per il completamento automatico che è proprio quello che volevo:

% ls
bar   baz   echo  foo 
- files -
file1.txt   file2.txt 

2
Questa è un'idea spettacolare
Michael Mrozek

2
Per integrare ^[ .( insert-last-word), mi piace copy-earlier-word, che scorre tra le parole della riga raggiunte da insert-last-word. Per il tuo .zshrc:autoload copy-earlier-word && zle -N copy-earlier-word && bindkey '^[,' copy-earlier-word
Gilles 'SO- smetti di essere malvagio' il

@Gilles grazie! Questo mi avvicina alla funzionalità se non riesco a ottenere il completamento automatico completo. ~ 80% delle volte, se non è l'ultimo argomento, è il penultimo argomento che voglio e C-. + C-, è abbastanza buono.
Ted Naleid,

Risposte:


6

Puoi aggiungere il tuo completatore all'elenco dei completatori utilizzati per impostazione predefinita:

zstyle ':completion:*' completer _last_command_args _complete

1
Se sono presenti _last_command_argscompletamenti, gli altri non vengono visualizzati. Come li ottieni oltre ai soliti?
Gilles 'SO- smetti di essere malvagio' il

1
Grazie per la risposta, questo mi ha avvicinato abbastanza da far funzionare qualcosa per me, quindi lo accetto. Quello che ho fatto diversamente è notato come un aggiornamento alla domanda sopra. La tua soluzione non ha stampato sia gli argomenti dell'ultimo comando sia i file, ecc. Dal normale completatore. Ho composto _completeall'interno della funzione che ho creato e funziona proprio come volevo.
Ted Naleid,

Hai ragione, la mia risposta non è corretta.
nicoulaj,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.