Creazione automatica di funzioni dai prototipi di funzioni dai file di intestazione


10

Intro

Quando si programma in C e C ++ di solito si dividono i prototipi delle funzioni e le funzioni effettive in un file .h/ .hppe .c/ .cpp. Purtroppo è molto noioso trasferire i prototipi di funzione da un file a un altro e richiede l'apertura di entrambi i file contemporaneamente (o una buona memoria), oltre a un sacco di digitazione non necessaria, soprattutto quando le modifiche agli argomenti o ai nomi dei membri sono fatto.

Esempio

foo.hpp:

int someFunction(int someArgument);

class someClass
{
     public:
     someClass();
     ~someClass();

     int anotherFunction(int anotherArgument);
};

foo.cpp:

#include "foo.hpp"

int someFunction(int someArgument)
{
    // Code goes here
}

someClass::someClass()
{
    // Code goes here
}

someClass::~someClass()
{
    // Code goes here   
}

int someClass::anotherFunction(int anotherArgument)
{
    // Code goes here
}

Domanda

Esiste un modo per creare e aggiornare automaticamente le funzioni foo.cpputilizzando le definizioni e i prototipi in foo.hpp?

Risposte:


3

Accidenti, questo è stato divertente!

:g/.*\n^{/yank A<cr>:bn<cr>pkdd:%s/$/;/<cr>:g/::/d B<cr>A<cr><cr>class <cr>{<cr>};<esc>"BP:%s/[^ ]\+:://<cr>j%jyt(kk$p=ipjA<cr>public:<esc>

Puoi andare avanti e mapparlo a una singola sequenza di tasti nel tuo .vimrc:

nnoremap <C-b> :g/.*\n^{/yank A<cr>:bn<cr>pkdd:%s/$/;/<cr>:g/::/d B<cr>A<cr><cr>class <cr>{<cr>};<esc>"BP:%s/[^ ]\+:://<cr>j%jyt(kk$p=ipjA<cr>public:<esc>

Si noti che ciò presuppone che il costruttore sia il primo metodo di classe da visualizzare. (Potrei risolverlo, ma preferirei mantenerlo semplice. Per favore, menzionalo in un commento se hai bisogno di risolverlo.)

Ciò presuppone inoltre che il buffer del file di intestazione sia vuoto e si trovi direttamente dopo il buffer del file di origine.

Spiegazione dettagliata:

:g/.*\n^{/yank A<cr>            Yank all the function definitions (power of g!)
:bn<cr>                         Move to the header file buffer
pkdd                            Put in the function definitions
:%s/$/;/<cr>                    Add semicolons
:g/::/d B<cr>                   Grab the class methods and put them in register B
A<cr><cr>class <cr>{<cr>};<esc> Self-explanatory, add class skeleton
"BP                             Put the class methods in the class
:%s/[^ ]\+:://<cr>              Remove someClass::
j%jyt(kk$p                      Add the actual class name
=ip                             Fix indentation
jA<cr>public:<esc>              Add the `public:' modifier

1
Anche se questo è impressionante (sono piuttosto nuovo per Vim, quindi sto scoprendo cose nuove ogni giorno!), Temo che questo non sia affatto ciò di cui ho bisogno. Forse dovrei cercare di creare il mio plugin? Sembra una cosa divertente da fare.
Lukas,

2
@Lukas In che modo una mappatura nel tuo .vimrc non risolve il problema? Basta premere Ctrl-B per compilare automaticamente il file di intestazione per te. (Probabilmente dovrei chiarire il file di intestazione prima di sostituirlo con una versione aggiornata, ma devo dormire in modo da poterlo fare in seguito.) Un plugin sembra interessante; tienimi aggiornato se decidi di crearne uno. E grazie per l'interessante sfida per affinare le mie abilità in Vim! ;)
Doorknob,

2
Questo sembra funzionare nella direzione opposta alla richiesta: crea un file header dal file .cpp.
200_successo

... che sarebbe anche bello, in realtà, ma penso che ci siano alcune cose che non possono essere conosciute dalla definizione: ad esempio, la dichiarazione dovrebbe essere inline? Ci sono argomenti predefiniti? I nomi degli argomenti dovrebbero essere elisi?
Kyle Strand,

@ 200_success Ah, hai ragione (non so perché non ho risposto al tuo commento prima). Quando avrò tempo, proverò a modificare la mia risposta per andare dall'altra parte.
Maniglia della porta,

2

Il :GOTOIMPLcomando di lh-cpp è in grado di passare a una definizione di funzione dalla sua dichiarazione o di fornire una definizione vuota predefinita nel caso in cui non sia stata trovata alcuna.

Alcune caratteristiche che mi vengono in mente:

  • Il comando comprende già i commenti, le specifiche di eccezione, le parole chiave che non possono essere copiati (ma forse copiati all'interno dei commenti) ( virtual, static, ...).
  • L'attuale ambito della funzione è decodificato (namespace :: classes :: ...) e riportato correttamente (cioè non avrà il prefisso ns::se ci troviamo all'interno namespace ns{o in un using namespace ns;contesto.

Tuttavia:

  • I modelli non sono (ancora) compresi.
  • Il corpo della funzione deve essere creato manualmente uno dopo l'altro, ovvero non ho ancora avuto il tempo di eseguire: GOTOIMPL su tutte le dichiarazioni di funzione che i tag potrebbero indicarmi.
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.