Automatisches Erstellen von Funktionen aus Funktionsprototypen aus Header-Dateien

10

Intro

Beim Programmieren in C und C ++ teilen Sie normalerweise Ihre Funktionsprototypen und tatsächlichen Funktionen in eine .h/ .hppund .c/ .cppDatei auf. Leider ist es sehr mühsam, die Funktionsprototypen von einer Datei in eine andere zu übertragen, und erfordert das gleichzeitige Öffnen beider Dateien (oder einen guten Speicher) sowie viele unnötige Eingaben, insbesondere wenn Änderungen an den Argumenten oder Mitgliedsnamen vorgenommen werden gemacht.

Beispiel

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
}

Frage

Gibt es eine Möglichkeit, die Funktionen bei foo.cppVerwendung der Definitionen und Prototypen in automatisch zu erstellen und zu aktualisieren foo.hpp?

Lukas
quelle

Antworten:

3

Puh, das hat Spaß gemacht!

: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>

Sie können dies einem einzelnen Tastendruck in Ihrer .vimrc zuordnen:

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>

Beachten Sie, dass dies voraussetzt, dass der Konstruktor die erste Klassenmethode ist, die angezeigt wird. (Ich könnte das beheben, aber ich möchte es lieber einfach halten. Bitte erwähnen Sie in einem Kommentar, wenn Sie das beheben müssen.)

Dies setzt auch voraus, dass Ihr Header-Dateipuffer leer ist und sich direkt hinter Ihrem Quelldateipuffer befindet.

Schrittweise Erklärung:

: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
Türknauf
quelle
1
Das ist zwar beeindruckend (ich bin ziemlich neu in Vim, also entdecke ich jeden Tag neue Dinge!), Aber ich fürchte, das ist überhaupt nicht das, was ich brauche. Vielleicht sollte ich mir überlegen, mein eigenes Plugin zu erstellen? Es scheint eine lustige Sache zu sein.
Lukas
2
@Lukas Inwiefern löst ein Mapping in Ihrer .vimrc das Problem nicht? Durch einfaches Drücken von Strg-B wird die Header-Datei automatisch für Sie ausgefüllt. (Ich sollte wahrscheinlich die Header-Datei löschen, bevor ich sie durch eine aktualisierte Version ersetze, aber ich muss schlafen, damit ich das später tun kann.) Ein Plugin klingt interessant; Halten Sie mich auf dem Laufenden, wenn Sie sich für eine entscheiden. Und danke für die interessante Herausforderung, meine Vim-Fähigkeiten zu verbessern! ;)
Türknauf
2
Dies scheint in der entgegengesetzten Richtung zur Anforderung zu funktionieren: Es wird eine Header-Datei aus der CPP-Datei erstellt.
200_erfolg
... was eigentlich auch schön wäre, aber ich denke, es gibt einige Dinge, die aus der Definition nicht bekannt sind: zB soll die Erklärung sein inline? Gibt es Standardargumente? Sollten die Argumentnamen entfernt werden?
Kyle Strand
@ 200_success Ah, du hast recht (ich weiß nicht, warum ich nicht früher auf deinen Kommentar geantwortet habe). Wenn ich Zeit habe, werde ich versuchen, meine Antwort zu bearbeiten, um in die andere Richtung zu gehen.
Türknauf
2

Der :GOTOIMPLBefehl von lh-cpp kann aus seiner Deklaration zu einer Funktionsdefinition springen oder eine leere Standarddefinition angeben, falls keine gefunden wurde.

Einige Funktionen, die mir einfallen:

  • Der Befehl bereits versteht Kommentare, Ausnahme - Spezifikationen, Schlüsselwörter , die dürfen nicht kopiert werden (innerhalb von Kommentaren aber möglicherweise kopiert) ( virtual, static, ...).
  • Der aktuelle Funktionsumfang wird dekodiert (Namespaces :: classes :: ...) und korrekt gemeldet (dh es wird kein Präfix vorangestellt, ns::wenn wir uns innerhalb namespace ns{oder in einem using namespace ns;Kontext befinden.

Jedoch:

  • Vorlagen werden (noch) nicht verstanden.
  • Funktionskörper sollen manuell nacheinander erstellt werden - dh ich habe mir noch nicht die Zeit genommen, Folgendes auszuführen: GOTOIMPL für alle Funktionsdeklarationen, auf die ctags mich hinweisen könnten.
Luc Hermitte
quelle