martedì 11 febbraio 2014

Gli strumenti per potenziare l'IDE di Delphi (Parte 3 - CnPack)

Aggiornato Marzo 2016

La terza puntata di questa serie dedicata agli strumenti per potenziare l'IDE di Delphi prende in esame un nuovo interessante tool, CnPack
Nome:CnPack
Sito:http://www.cnpack.org/
Sito progetto:https://github.com/cnpack/
Licenza:Open Source
Prezzo:0€



CnPack IDE Wizards è un insieme di strumenti per Delphi e C++ Builder compatibile con Delphi 5 - Delphi 10 Seattle e C++ Builder 5 - C++ Builder 10 Seattle tesi ad aumentare la produttività dell'IDE tramite "wizard" (così sono chiamati i singoli tool dal team di CnPack) e vari miglioramenti di diverse funzionalità.


Oltre ad essere gratuito è anche un progetto OpenSource ospitato su Google Code, quindi potete:

  1. Modificare parti dei tool che non vi piacciono o implementare nuove funzionalità.
  2. Migliorare la vostra conoscenza sulle Tools API e in generale sul codice ad un livello abbastanza elevato.

Menu

Come potete vedere dalla figura qui sotto i wizard (tool) di CnPack sono davvero numerosi.


In questo articolo, come nei precedenti presenterò una selezione (tuttavia abbastanza completa) di questi wizard che sono quelli che uso maggiormente io. Vi invito comunque ad esplorarli uno ad uno per trovare quelli che velocizzeranno maggiormente il vostro lavoro. La documentazione, nella forma di un file di Help agganciato alle finestre (invocabile con il classico F1) è molto buona soprattutto per un progetto Open Source.

Toolbars



Un aspetto interessante e da non sottovalutare sono le toolbar che vederete apparire una volta installato CnPack. Offrono i comandi accessibili in modo diretto ed intuitivo e soprattutto il vedercele davanti ci fanno ricordare che abbiamo a disposizione e a portata di "click" numerosissimi tool che ci offrono aiuto.

Source Highlight

Il cambiamento più evidente appena installato CnPack lo noterete aprendo un qualsiasi vostro sorgente.
Se avete unit (form) con codice con diversi cicli annidati, diversi costrutti if-then-else o istruzioni case complesse, provate ad aprirla e guardate di nuovo il codice... notate cambiamenti?


Come vedete nela figura sopra, tutti i blocchi di codice sono colorati in modo diverso e i begin..end sono uniti da linee (dello stesso colore) che mostrano alla prima occhiata l'indentazione e quindi il flusso del codice!

POtete notare anche l'evidenziazione di un identificatore (nell'esempio LSubIndex) che anche in questo caso mostra alla prima occhiata dove è stato usato

Come tutti i wizard di CnPack potete personalizzarne il comportamento e l'aspetto in modo significativo tramite la voce di menu Options, in questo caso potete  scegliere lo stile delle linee e il colore di evidenziazione degli identificatori (e se abilitare la funzionalità o meno).


Un inconveniente di questa funzionalità è che ovviamente richiede un certo tempo di calcolo e di rendering per mostrare la colorazione e l'evidenziazione e questo lo si può avvertire se avete unit di grandi dimensioni, proprio per questo potete notare l'ultima voce delle opzioni Disable Highlight when Unit Lines Exceeds che dice al wizard di disabilitare il syntax highlighting per le unit grandi dimensioni.

P.S.: Nel caso di unit "giganti" sarebbe opportuno provvedere ad una rifattorizzazione della stessa: imparate bene i comandi di refactoring e... via alle modifiche!


Form Design Wizard



La funzione più importante del Form Design Wizard, che potete avere anche come toolbar (molto più utile infase di design visuale), è quella di allineare, spostare e modificare i componenti sulla form, offrendo molte più opzioni rispetto alla toolbar di allineamento di Delphi.

Locate Components


Se avete form con molti componenti anche nascosti questa è l'utility che fa per voi, questa dialog vi consente infatti di cercare (filtrando per nome) tutti i componenti, visuali e non, che avete sul form. Una volta selezionato il componente dalla lista CnPack lo seleziona.

Convert to Code


Simile alla funzionalità "Components to Code" di GExperts questo wizard è utile per convertire un componente piazzato a design time in un blocco di codice per definirlo e inizializzarlo a run-time. La cosa in più rispetto a GExperts è la possibilità di copiare separatamente nella clipboard la definizione e l'inizializzazione. Anche il codice generato è migliore con commenti e soprattutto hanno evitato di usare il with, da molto considerato... il male!

Coding Toolset

I coding toolset sono per la maggior parte comandi che vi aiutano e assistono nella scrittura del codice, sono lanciati per lo più con tasti rapidi e quindi al prezzo di memorizzare altre scorciatoie da tastiera rendono alcune tra le più noiose operazioni quasi... divertenti!

Convert to String

Quante volte vi siete trovati nella condizione di dover riportare nel codice sorgente (ad esempio) uno statement SQL molto lungo e complesso? Sapete già che per formattarlo decentemente tra doppie virgolette, fine linea, indentazioni si spreca una quantità di tempo incredibile!

E se vi dicessi che CnPack ha un tool che fa esattamente questo?


La prima finestra mostra uno statement SQL scritto in un editor esterno la seconda immagine è presa da Delphi dopo che avevo incollato e convertito lo statement sopra, nessun altra operazione di editing è stata fatta!
Il tool in questione è il Convert to String che trovate sotto al menu Code Editor Wizard. Il tool è anche configurabile dalle opzioni di CnPack.

Eval Swap

Scambia le espressioni in un blocco di codice selezionato, ad esempio da A := B; a B := A; molto utile nei casi di load/save di dati (ad esempio da un dataset)

Toggle Uses/Include

Quando state scrivendo codice e avete bisogno di usare una funzione che si trova in una unit che non è ancora nelle clausole uses, il workflow più breve è questo: (se siete bravi ad usare i bookmark dell'IDE)

  1. salvo il bookmark alla posizione corrente
  2. vado in interface o implementation (se la unit è grande devo inoltre usare un cerca) 
  3. scrivo la unit nella clausola la uses
  4. ritorno al bookmark salvato
  5. cancello il bookmark
Usando la funzionalità Toggle Uses/Include per arrivare allo stesso punto:
  1. premo Ctrl-Alt-U 
  2. scrivo il nome della unit da usare 
  3. premo Esc ed è tutto fatto
Facile vero? Moltiplicate il tempo per le migliaia di volte che avete eseguito questa banale ma tediosa operazione e ditemi quanto tempo avreste risparmiato usando questo wizard! :-)

Toggle Var Field

Questa funzionalità e simile alla precedente solo dedicata alle variabili locali. Premete Ctrl-Shift-V e CnPack porta in cima alla funzione, se non c'è la parola chiave var, la aggiunge voi scrivete il nome ed il tipo della variabile e premendo Esc ritornate a lavorare.

Jump to Intf, Jump to Impl, Jump to Matched Keyword Tool 

Comandi comodi per saltare alla parte di interface/implementation di una unit, utile per gestire le clausole uses. I comandi sono invocabili anche dai pulsantini sulla toolbar.

Jump to Previous Identifier, Jump to Previous Identifier

Questa è un'altra funzione per cui vale la pena di installare CnPack (almeno per me). Usando Ctrl-Alt-Up e Ctrl-Alt-Down è possibile navigare all'interno di una unit selezionando l'identificatore (in realtà semplicemente una stringa di testo) precedente o successivo. Quindi se sono posizionato su una certa parola premendo Ctrl-Alt-Up mi sposterò nelle righe precedenti che contengono questa parola e premendo Ctrl-Alt-Down mi sposterò nelle righe successiveche contengono questa parola.

Con questa funzionalità l'uso della funziona ricerac si è drasticamente ridotto (nel mio caso) visto l'incredibile comodità di questo wizard.

Collector


Il collector è un utile strumento che consente di aver vari "snippet" di testo tutti in un unico posto, dimeticatevi di copie del notepad aperte e pezzi di codice che si perdono.. In collector potete avere più tab aperti, prendere codice dall'IDE e incollarlo nell'IDE.


MessageBox


Quando devi costruire le DialogBox non ti ricordi mai gli enumerativi dei pulsanti e delle icone? non ti ricordi le costanti dei valori di ritorno?

Beh allora devi proprio usare il wizard MessageBox di CnPack che visualmente ti aiuta a creare la tua Message Dialog senza impazzire tra opzioni e costanti impossibili da ricordare.

In aggiunta permette di scegliere tra diverse API per invocare la finestra: la MessageDlg di Delphi, Application. MessageBox oppure la MessageBox API, ovviamente pensa lui a cambiare tipo di parametri, effettuare conversioni di tipo ecc... tutto quello che dovete fare è premere il pulsante OK ed il codice apparirà come per incanto nell'editor.

Replace in Files


Ricercare e sostituire testo in file diversi non è mai stato così semplice. Con questo tool è possibile applicare trasformazioni di testo ad un insieme anche grande di file in un'unica operazione. Sebbene questo tool sia molto potente e  semplice da usare io preferisco il "Grep Search" di GExperts (vedi precedente articolo)

Tab Orders

Una corretta impostazione del Tab Order all'interno delle proprie form è molto importante per permettere all'utente di navigare da tastiera la nostra applicazione e riuscire ad effettuare data-entry il più velocemente possibile ma, ahimè, è anche molto facile dimenticarsi alla fine della progettazione della form di impostare correttamente l'ordine.


Il wizard Tab Orders di CnPack ci viene in aiuto in diversi modi:

Visualizzazione

Per visualizzare il numerino corrispondente all'ordine del controllo direttamente sul form la voce di menu è Display Tab Orders

Modifica

Per modificare l'ordine sulla form corrente, su tutte le form aperte o su tutte le form del progetto seguendo regole impostabile dal sottomenu Options

Auto aggiornamento

Per aggiornare automaticamente il Tab Order ogni volta che aggiungo un controllo sulla form dovete spuntare la voce di menu Auto Update Tab Orders
    Con l'ausilio di questo tool non potete più dire di esservi scordati l'impostazione del Tab Order!

    Source Templates


    Con questo semplice tool è possibile applicare template, soprattutto per commenti, al sorgente. Esempi possono essere l'intestazione della unit oppure l'intestazione di procedure e funzioni ecc...

    Convenzioni e stile di programmazione

    Prima di introdurre il Prefix Wizard ritengo necessarie due parole su un aspetto importante (non solo in Delphi) ma spesso trascurato: le convenzioni per l'assegnazione dei nomi alle variabili, campi, classi e componenti, e più in generale lo stile di scrittura del codice sorgente, che non può e non deve essere lasciato al caso o alle preferenze personali (pure legittime) del singolo programmatore soprattutto se facente parte di un team.

    L'argomento è piuttosto vasto ed intendo, prossimamente, scrivere un articolo dedicato, qui metterò invece i punti salienti.

    Le "Coding Conventions" sono un insieme di regole o meglio ancora un insieme di linee guida che coprono: le convenzioni di nome per gli identificatori, la scrittura dei commenti, l'indentazione, ecc...
    Il primo testo sull'argomento è stato pubblicato nel 1978, si chiama The Elements of Programming Style di Kernighan e Plauger ed il libro è una sorta di "introvabile" infatti le copie nuove arrivano fino a 200$!
    Pur avendo una 30ina d'anni gli argomenti sono ancora di attualità visto che a distanza di tutto questo tempo la maggior parte dei programmatori continua a non seguirli!

    Le principali regolette che enuncia il testo sono tutt'altro che complicate da mettere in pratica, le mie preferite:
    1. Use variable names that mean something.
    2. Format a program to help the reader understand it.
    3. Write clearly, don't sacrifice clarity for efficiency
    4. Let the machine do the dirty work.
    5. Choose variable names that won't be confused.
    6. Write first in easy-to-understand pseudo language; then translate into whatever language you have to use.
    7. Modularize. Use procedures and functions. (e visto che Delphi è un linguaggio ad oggetti: classi)
    8. Don't patch bad code -- rewrite it.
    9. Test input for plausibility and validity.
    10. Make sure all variables are initialized before use.
    11. Make it right before you make it faster.
    12. Make it fail-safe before you make it faster.
    13. Make it clear before you make it faster.Don't strain to re-use code; reorganize instead.
    14. Instrument your programs. Measure before making efficiency changes.
    15. Make sure comments and code agree. :-)
    16. Don't just echo the code with comments -- make every comment count.
    17. Don't comment bad code -- rewrite it. (una delle mie preferite!)
    e per ultimo quella che riesco a seguire:
    1. Don't over-comment. (tranquilli, non mi capita mai! ;-) )

    Se notate ai primi due posti ci sono le regole per il naming e di formattazione che sono le due regole che CnPack ci aiuta a seguire.

    Come nominare le variabili e i componenti?

    La notazione più famosa è la "Hungarian Notation" introdotta da Charles Simonyi diventato poi Chief architect in Microsoft (gli effetti di questa notazione li vediamo nel nome dei parametri della API Windows e nei tipi di dato del registry).
    Sostanzialmente la regola dice di prefissare le variabili con il tipo del dato da esse rappresentato quindi lParam è un parametro di tipo long, szParam è un parametro di tipo stringa e così via...

    Parlando di Delphi ritengo questa regola molto utile per nominare i componenti visuali messi sul form, meno per le variabili, i campi e le proprietà che a mio avviso devono seguire una differente notazione (il prefisso, IMO, deve indicare lo "scope" F per i campi di classe, L per le variabili locali, ecc... ma questo non è l'argomento di questo articolo).
    Altra regola è quella di dare (oltre al prefisso) un nome "decente" ai vostri componenti, non avrete mica Button1..Button37 sulle vostre form vero?? :-)

    Beh se così fosse troverete nel Prefix Wizard un valido alleato per aiutarvi a superare la tipica pigrizia del programmatore.

    Prefix Wizard

    Questa funzionalità penso sia la più amata e assieme la più odiata di CnPack. Il wizard permette di rinominare i componenti sul form per aggiungere un prefisso secondo regole impostabile dall'utente.
    Le tre modalità di nomina dei componenti sono:

    Prompt


    Con le impostazioni di default una volta installato CnPack noterete che ogni volta che piazzate un controllo su una form vi appare una finestrella che vi chiede di impostare il nome del componente (e questa è la parte più odiata perchè, per chi installa CnPack e non conosce ancora la funzionalità, questi ulteriori passi sembrano un'inutile complicazione)
    La prima finestra vi chiede di inputare il nome del componente mettendo un prefisso di default per il tipo di componente, se non vi piace il prefisso premete il pulsante Modify Prefix e lo cambiate ad questa dialog. 

    Automatic


    Nella finestra delle opzioni basta togliere il check alla voce Show Dialog when Add New Component or Rename e quando si mettono nuovi componenti sul form questi verranno automaticamente nominati.

    Io non consiglio questa modalità perché benché i componenti abbiano il prefisso "giusto" questi verranno nominati (ad esempio per i pulsanti) btn1, btn2, ecc... vanificando l'obbiettivo di avere componenti con nomi "sensati" btnSalva, btnVerifica, ecc...

    Manual


    Il prefisso dei componenti si può cambiare manualmente, e soprattutto, processando tutti i componenti del form corrente, di tutte le form aperte o di tutte le form del progetto o del gruppo di progetti.

    Una volta confermata questa dialog, se ci sono componenti da processare (che hanno prefisso diverso da quello voluto), vengono mostrati nella seguente finestra da dove è possibile variare anche il nome del componente stesso.


    Property Corrector

    Avere la connessione ad un database aperta a design-time è una delle feature più comode di Delphi (che altri importanti strumenti di programmazione hanno copiato solo nelle ultime versioni mentre i programmatori Delphi l'hanno usata fin dalla prima versione). Vedere i dati nelle griglie e negli altri controlli è davvero impagabile! Peccato che (almeno a me) è successo più di una volta (per mia disattenzione) di mandare al cliente l'applicativo che appena lanciato tenta di connettersi a localhost (o qualsiasi altro indirizzo usato per lo sviluppo) perchè ci siamo dimenticati di mettere a false la connection al database.


    Con questo wizard è possibile processare tutti i componenti sulla form o su tutte le form del progetto e settare automaticamente le proprietà a valori voluti. Oltre alle connessioni database questo wizard può essere utile anche per settare la posizione delle form, o impostare in un sol colpo l'altezza dei pulsanti , ecc... 

    Sebbene questo wizard sia utile e potente i GExperts hanno un tool simile che però viene invocato direttamente in compilazione e quindi ci solleva dalla responsabilità di ricordarci di lanciare il wizard.

    Project Enhancements


    Browse Current File's Dir, Browse Project Dir, Browse Output Dir

    Comandi comodi per saltare direttamente ai folder più usati in un progetto.

    List Units, List Forms, List Used



    Altro wizard (per me) insostituibile. Le finestre che vedete sopra si sostituiscono alle dialog standard di Delphi View Unit (Ctrl-F12), View Form (Shift-F12).
    Come potete notare già dalle schermate sono molto più potenti rispetto a quelle standard, supoprtano la ricerca inline, come testo contenuto o iniziale, permettono di filtrare l'elenco sul progetto attivo o su tutti i progetti del project group e molto altro.
    Come dovete fare per invocarle? Nulla, quando installate i CnPack queste finestre vengono mostrate al posto di quelle standard ed invocate dalla stessa combinazione di tasti. Ovviamente potete disabilitarle e tornare alle precedenti... 
    Ma perchè mai? :-)

    Project Backup


    Comodo per effettuare velocemente un backup di tutto il progetto, è possibile anche aggiungere file che non appartengono in senso stretto al codice sorgente.

    Ricordo che comunque questo tool non è un rimpiazzo per un version control che rimane lo strumento principe per la gestione della storia del proprio codice sorgente.

    Project CleanUp


    Altro wizard molto comodo e di immediata comprensione, con in più la possibilità di non cancellare dcu/obj se non esistono i corrispondenti file sorgenti.

    Project Dir Builder

    Quando si hanno diversi progetti all'attivo è prassi comune standardizzasi su un layout di progetto pensato e ben definito, sfruttando poi la possibilità di Delphi di mettere nei path percorsi relativi un layout come quello che vedete in figura sopra (che solitamente adotto io per i miei progetti)  aiuta a rendere la gestione (version control, deployment, ecc...) operazioni gestibili automaticamente, quindi scriptabili, quindi automatizzabili.


    Questo wizard permette di definire vari layout di progetto e poi applicarli ad una directory (creerà per voi tutta la struttura ad albero)

    INI Reader & Writer (Menu Repository List)

    Adesso uso sempre meno i file INI visto che da anni ho costruito classi che gestiscono la configurazione in XML dei miei applicativi ma quante volte avete scritto righe e righe di codice sempre uguale che legge/scrive i valori in un file INI? Se siete programmatori da più di qualche giorno il numero sicuramente è dell'ordine delle migliaia!


    Questo wizard è in grado di prendere come input un normalissimo file INI con multiple sezioni, valori, ecc... e generare una unit pascal con una classe pronta all'uso solamente referenziando le proprietà (che ovviamente si chiameranno come le voci del file INI).
    Avercelo avuto prima, vero? :-)

    Explorer


    Wizard molto comodo per avere smepre a fianco una vista sulle directory del progetto. La finestra è una finestra explorer-like e il click destro sugli elementi apre il normale menu contestuale di windows.

    Historical File Snapshot


    Permette di salvare i file più usati in un progetto e successivamente riaprirli senza tutte le volte aprirli manualmente uno per uno, soprattutto se i file da aprire non sono aggiunti alla lista del dpr ma sono solamente nel search path del progetto.

    Procedure List

    Parecchio utile per navigare il codice sorgente in modo potente e facile allo stesso tempo. In questo caso già i tasti rapidi di Delphi Ctrl-Shift-Up/Down rendono la navigazione nel codice sorgente davvero immediato ma questo expert aggiunge un'interfaccia visuale che a volte è comoda per "vedere" in un'unica occhiata i metodi di una classe.


    Anche se altri tool hanno strumenti simili (i GExperts hanno appunto la "Procedure List") ma questo è a mio avviso il più completo e il più comodo.
    In più questo wizard aggiunge la funzionalità anche alla toolbar per un uso ancora più immediato.


    Uses Clean


    Molto comodo quando si cambiano spesso componenti su un form. Si corre il rischio di includere unit non più necessarie, quindi ricordatevi di lanciare questo wizard almeno prima di effetuare le build definitive per fare un poco di pulizia.

    IDE Enhancements


    Code Input Helper

    Una sorta di CodeComplete (a mio avviso più veloce e completo), funziona per tutti questi casi:
    • When input in the uses section, all unit names available will be listed.
    • Compiler directives. When input '{$', all compiler directives will be listed.
    • Comments in XML Style. When input '///', all comment templates in XML Style will be listed.
    • Comments in JavaDoc Style. When input '{*', all comment templates in JavaDoc Style will be listed.
    • Code Templates defined in IDE. Such as trycf, forb and etc.
    • User-defined identifiers, compiler directives, comment templates, code templates and etc.
    • Macros are supported in code template.
    Trovo insostituibile il completamento automatico nella scritture delle unit nelle uses (qui il completamento di Delphi non è così preciso e potente), nella scrittura delle direttive del compilatore (io uso parecchio le {$REGION ...} per comodità di lettura del sorgente) e nella scrittura dei TODO perchè digitando //t questo wizard mi prepara una riga TODO standard con data/ora utente e mi posiziona nel punto in cui devo inserire la descrizione.
    Questo wizard è inoltre davvero molto configurabile con la dialog delle opzioni.


    Editor Enhancements Wizard

    Questo wizard contiene diverse funzionalità per arricchire l'editor, le toolbar, ecc...
    Le opzioni sono davvero tante, vi consiglio di guardarle tutte perchè davvero possono aiutarvi a digitare codice molto più velocemente.

    IDE Config Backup/Restore

    Questo è un tool importantissimo perchè vi può salvare diverse ore di configurazione di una nuova installazione di Delphi e permette di effettuare un backup (in un formato binario) di tutti i settaggi dell'IDE di Delphi).


    Questa operazione è in realtà molto semplice per chiunque abbia un minimo di dimestichezza con il Registry Editor di Windows, infatti basta salvare le chiavi di registro di Delphi a patto di conoscerne la locazione ed il significato (la gestione delle chiavi di registry di Delphi sarà oggetto di un prossimo articolo sul blog)   

    Se invece non volete preoccuparvi di queste cose semplicemente usate questo Expert che in più vi da la possibilità di eliminare quelle chiavi usate solo per salvare la history dei file o delle operazioni fatte.


    CnPack Options

    Dopo anni di uso dei CnPack non ho (nemmeno lontanamente) visto e cambiato tutte le opzioni che mostrano le finestre dei settings! Divertitevi! :-)


    Conclusioni

    Ricordo ancora che i wizard di CnPack sono molti di più rispetto a quelli presentati in questo articolo, vi esorto a provarli per trovare quelli migliori per voi.

    Nel prossimo articolo prenderemo in esame uno strumento che si occupa della gestione dei commenti/documentazione: DevJet DocumentInsight.

    Se avete quesiti o proposte di recensione di altri tool scrivetemi o lasciate un commento su questo blog.