2013-04-05 29 views
8

Voglio scrivere un comando, il comando avrebbe questo formato:Come passare argomenti da: comando a funzione?

[range]MyCMD[!] [count] [oneArg] [flags] 

o

[range]MyCMD[!] [oneArg] [count] [flags] 

simile a

:[range]P[rint] [count] [flags] 

o

:[range]d[elete] [x] {count} 

Il comando MyCMD alla fine chiamerà una funzione per fare un po 'di lavoro. Ho scritto questa linea (non funzionerà)

command! -nargs=+ -range -bang -count=0 MyCMD <line1>,<line2>call MyFUNC(<q-args>, "<bang>","<count>", .... ..) 

Qui il problema è, come gestire tali argomenti:

  • problema 1 ho letto l'aiuto, -range e -count non può essere usato allo stesso tempo, ma ho bisogno di entrambi. Ho anche dato un'occhiata ad alcuni comandi di vim, come: delete,: print, quando usiamo quei comandi, potremmo dare sia range e count. Inoltre ho trovato che vim doc ha due voci dello stesso comando se è disponibile un {count} o [count]. come:

    :[range]d[elete] [x]  
    :[range]d[elete] [x] {count} 
    

o

:[range]p[rint] [flags] 
:[range]p[rint] {count} [flags] 

perché? perché non solo con [count]? (Questo sarebbe un'altra piccola domanda)

  • problema 2 dal mio disegno, tutti questi argomenti sono opzionali, hanno valori di default (vedere la tabella qui sotto). Come posso passare quegli argomenti a funzionare (ho controllato <q-args> and <f-args>) e come posso distinguere quali input utente sono per quale argomento? per esempio utente dà

    :MyCMD 5 g

    5 is count? or arg? 
    g is arg or flag? 
    or '5 g' is arg? 
    

ecco i valori predefiniti per args:

argName | Default value | description 
    ------------------------------------- 
    range | current line | this could be get by function xxx () range 
    count | 0    | this could be get by <count> 
    bang | ""   | this is easy too, with <bang> 
    arg  | " "   | this argument could have space 
    flags | ""   | no space allowed for flags 
    ------------------------------------- 

grazie.

risposta

9

Per il tuo comando personalizzato complesso, non puoi fare affidamento esclusivamente sulle opzioni di analisi limitate di Vim; puoi farlo gestire l'intervallo con -range, ma devi analizzare tu stesso la tua combinazione di argomenti.

:command! -nargs=* -range -bang MyCMD <line1>,<line2>call MyFUNC(<bang>0, <q-args>) 

All'interno MyFUNC (che dovrebbe probabilmente essere definito con :function MyFUNC(...) range ad essere invocate solo una volta), split() gli argomenti su spazi vuoti. In alternativa, è possibile definire la funzione per utilizzare un numero variabile di argomenti e utilizzare <f-args>, ma si noti che il numero di argomenti della funzione è limitato (a 20 IIRC).

Il <bang>0 è un bel trucco per trasformare il botto in un booleano, che di solito è quello che ti serve.

+0

thx Ingo !. Sì, vorrei analizzare gli argomenti nella mia funzione, ma non conosco la strada giusta. ci sono 3 argomenti da analizzare. conteggio, arg e bandiere. tutti sono opzionali. forse dovrei definire un formato, ad es. per "arg", il valore deve essere racchiuso tra virgolette, poiché gli spazi sono consentiti ... potrebbe essere un po 'più semplice, quindi controllare il numero o la stringa di flag .. o rompere un comando in più comandi, questa sarebbe l'ultima scelta Farei. altri suggerimenti? – Kent

+0

e conosci la ragione di questa "altra piccola domanda" nel mio post? Ho cercato la risposta per il mio problema ieri, e l'ho notato. grazie. – Kent

+0

Se i tuoi argomenti sono troppo ambigui per essere analizzati, ripenserò la sintassi; forse imporre più uniformità o dare ulteriori suggerimenti di che tipo è con sigilli. –

0

Devo fare domande difficili. Non ho alcuna soluzione, ma qui sono le mie conclusioni.

:command! -range -bang -nargs=* MY echo [<bang>0, <line1>, <line2>, <count>, <q-args>] 

Dopo aver eseguito i seguenti scenari:

:MY 
[0, 3, 3, -1, ''] 
:MY! 
[1, 3, 3, -1, ''] 
:%MY 
[0, 1, 10, 10, ''] 
:%MY 4 
[0, 1, 10, 10, '4'] 
:MY 4 
[0, 3, 3, -1, '4'] 
:%MY flag 
[0, 1, 10, 10, 'flag'] 
:MY flag 
[0, 3, 3, -1, 'flag'] 
:%MY 4 flag 
[0, 1, 10, 10, '4 flag'] 

Ora con -count invece di -range

:command! -count -bang -nargs=* MY echo [<bang>0, <line1>, <line2>, <count>, <q-args>] 

Risultati:

:MY 
[0, 3, 1, 0, ''] 
:MY! 
[1, 3, 1, 0, ''] 
:%MY 
[0, 1, 10, 10, ''] 
:%MY 4 
[0, 1, 4, 4, ''] 
:MY 4 
[0, 3, 4, 4, ''] 
:%MY flag 
[0, 1, 10, 10, 'flag'] 
:MY flag 
[0, 3, 1, 0, 'flag'] 
:%MY 4 flag 
[0, 1, 4, 4, 'flag'] 

Come yo puoi vederlo non è facile. Il mio suggerimento sarebbe quello di utilizzare -range con il tuo comando. E quindi analizzare lo <q-args> cercando un numero tramite \d\+.

+0

grazie, Peter. cercare '\ d +' non è abbastanza, dato che 'arg' potrebbe essere qualsiasi stringa, incluso numero, spazi. – Kent

Problemi correlati