2015-11-11 18 views
32

Sto cercando un'impostazione clang-format per impedire allo strumento di rimuovere interruzioni di riga.Interruzioni di riga in formato clang

Ad esempio, ho il mio ColumnLimit impostato su 120, ed ecco cosa succede quando riformatto del codice di esempio.

Prima:

#include <vector> 
#include <string> 

std::vector<std::string> get_vec() 
{ 
    return std::vector<std::string> { 
     "this is a test", 
     "some of the lines are longer", 
     "than other, but I would like", 
     "to keep them on separate lines" 
    }; 
} 

int main() 
{ 
    auto vec = get_vec(); 
} 

Dopo:

#include <vector> 
#include <string> 

std::vector<std::string> get_vec() 
{ 
    return std::vector<std::string>{"this is a test", "some of the lines are longer", "than other, but I would like", 
     "to keep them on separate lines"}; 
} 

int main() 
{ 
    auto vec = get_vec(); 
} 

Quello che vorrei è che lo strumento interrompe le righe che sono più di 120 caratteri, ma non decide di combinare linee solo perché sono meno di 120 caratteri.

Esiste una simile opzione? Nulla nei documenti si è distinto per me.

+0

Per il tuo particolare esempio, impostare 'AllowShortFunctionsOnASingleLine: None' funzionerà. – dejvuth

+0

Bene, questo impedisce di scartare 'main', ma sono più preoccupato per l'inizializzazione del vettore in generale. Se il vettore è stato inizializzato in questo modo in un'altra (più lunga) funzione, verrebbe comunque scartato. – zmb

+0

Mi chiedo se modificare le varie opzioni di "penalità" possa essere d'aiuto, ma sembrano tutte penalizzazioni associate a linee di rottura, non "smantellamento" di esse. – zmb

risposta

22

Così, dopo aver pasticciato nel codice del formato clang e ha fatto alcune patch, ecco i miei due centesimi:

  • formato Clang è basata su,

    • analisi dell'AST utilizzando libclang, che sostanzialmente elimina TES tutti gli spazi
    • rompere la sequenza di token in "linee da scartare", che sono come le linee di codice "logiche"
    • applicazione di regole/informazioni di configurazione per dividere a volte fino "linee da scartare" in unità più piccole
    • Spit tutto indietro di nuovo con nuovo spazio/indentazione

    Non è facile far rispettare il whitepsace originale, che viene sballottato quando si analizza il codice.

  • È possibile controllare dove si colloca interruzioni di linea, più facilmente, da

    • impostando il limite di colonna
    • utilizzando i "parametri confezione bin" Opzioni
    • sanzioni impostazione per vari tipi di rotture - - break after return type di una funzione, interruzione prima del parametro first call, interruzione di una stringa letterale, interruzione di un commento ...
    • immissione di commenti alla fine di una riga (il formato clang non può rimuovere il commento e deve quindi dividere la riga)
    • utilizzare il clangore formato off/on direttive

Ecco una cosa che si potrebbe provare:

std::vector<std::string> get_vec() 
{ 
    return std::vector<std::string> { // 
     "this is a test",    // 
     "some of the lines are longer", // 
     "than other, but I would like", // 
     "to keep them on separate lines" // 
    }; 
} 

Il vantaggio di questo corso // clang-format off è che, se in seguito si modifica la scheda larghezza o qualche altra opzione, quelle linee di codice otterranno comunque quelle modifiche di formattazione in modo da non dover andare manualmente nelle regioni // clang-format off per risolverle. Comunque è ancora un po 'un trucco, YMMV.

In definitiva, clang-format consiste nell'imporre un formato uniforme su un intero codice base, assicurandosi che tutti i valori letterali stringa siano formattati nello stesso stile in tutto il programma. Se vuoi avere un controllo a livello micro sulle decisioni di interruzione di linea, non è proprio nello spirito dello strumento, e dovrai fare cose come disabilitarlo.

Questo a volte può essere frustrante esp. quando si vuole fare le cose con gli array e hanno colonne allineate o qualcosa del genere - per esempio, ecco qualche codice naturale da lua C api:

static luaL_Reg const methods[] = { 
    {"matches",    &dispatch::intf_match_unit}, 
    {"to_recall",    &dispatch::intf_put_recall_unit}, 
    {"to_map",    &dispatch::intf_put_unit}, 
    {"erase",     &dispatch::intf_erase_unit}, 
    {"clone",     intf_copy_unit}, 
    {"extract",    &dispatch::intf_extract_unit}, 
    {"advance",    intf_advance_unit}, 
}; 

Quando clang formato corre su questo, è in genere non andare a allineare il colonna di destra, sta per posizionarlo un numero fisso di spazi dopo le virgole e non c'è molto che tu possa fare a riguardo.

Oppure, se si dispone di 4 x 4 a matrice per l'uso con OpenGL:

 constexpr float shadow_skew_hardcoded[16] = 
     { 1.0f, 0.0f, 0.0f, 0.0f, 
      0.5f, 0.5f, 0.0f, 0.0f, 
      0.0f, 0.0f, 1.0f, 0.0f, 
      0.0f, 0.0f, 0.0f, 1.0f }; 

Se si lascia correre clang-formato su cose come questa è solo andare a storpiare loro, e per quanto ne so non c'è modo semplice per rendi la formattazione gradevole, quindi non devi fare altro che ricorrere al "sacco di commenti banali" o usare il formato clang quando hai qualcosa di simile. Questi sono solo limiti intrinseci dello strumento. Se non sei felice di dover fare cose del genere, probabilmente non è lo strumento adatto a te.

+0

Ottima risposta. Il tuo suggerimento sembra un po 'meglio di '// clang-format off', e la spiegazione del perché si comporta in questo modo ha molto senso. – zmb

+0

ColumnLimit 0 conserva ancora le interruzioni di riga. Come lo spieghi? – KindDragon

6

Al momento non ho visto nulla nello documentation che ti consentisse di farlo.

L'impostazione di ColumnLimit su 0 conserva comunque il testo a capo.

clang-format-mp-3.4 test.c -style="{ ColumnLimit: 0 }"

#include <vector> 
#include <memory> 
#include <string> 

int main() { 
    std::vector<std::string> vec = { 
    "this is a test", 
    "with some strings", 
    "that I want on separate lines" 
    }; 
} 
+1

Vuole anche impostare 'ColumnLimit' su 120? – Danh

+1

Giusto. Ciò preserva il mio involucro, ma non fa nulla per correggere linee troppo lunghe (il che è uno dei principali vantaggi dello strumento, IMO). – zmb

+0

Questo è un compromesso, ma un gioco da ragazzi per me. Sono felice di lasciare che i programmatori eseguano il wrapping a 100 manualmente, se il formato clang non viene manipolato con le nuove linee nelle definizioni dell'array, nelle mie espressioni 'std :: cout' più complesse, il mio' enum', i miei elenchi di parametri, ... – Gauthier

9

non sono sicuro che si clang-format per fare esattamente quello che vuoi, ma è possibile dire clang-formato di lasciare sezioni di codice da soli. Lo uso esattamente per il tipo di scenario di cui parli, blocchi di codice in cui una formattazione molto particolare rende più facile la lettura.

std::vector<std::string> get_vec() 
{ 
    // clang-format off 
    return std::vector<std::string> { 
     "this is a test", 
     "some of the lines are longer", 
     "than other, but I would like", 
     "to keep them on separate lines" 
    }; 
    // clang-format on 
} 

See: http://clang.llvm.org/docs/ClangFormatStyleOptions.html#disabling-formatting-on-a-piece-of-code

+0

Non sto dicendo che questa è una cattiva risposta, ma che soluzione assolutamente orribile al problema. Riordina il codice con i commenti per far funzionare la formattazione automatica. – Martin

+0

Forse, ma in pratica l'ho usato raramente dove voglio rompere le regole di formattazione. Di solito apprezzo avere un out come questo, e non apprezzo il fatto che venga abusato da "ingombrare il tuo codice". L'uso errato di uno strumento è spesso dovuto all'utente – MattG

Problemi correlati