Автоматическое создание функций из прототипов функций из заголовочных файлов

10

вступление

При программировании на C и C ++ вы обычно разделяете свои прототипы функций и реальные функции на .h/ .hppи .c/ .cppфайл. К сожалению, перенос прототипов функций из одного файла в другой очень утомителен и требует одновременного открытия обоих файлов (или хорошей памяти), а также большого количества ненужной типизации, особенно когда изменения в аргументах или именах элементов сделали.

пример

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
}

Вопрос

Есть ли способ автоматически создавать и обновлять функции при foo.cppиспользовании определений и прототипов в foo.hpp?

Lukas
источник

Ответы:

3

Вот это было весело!

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

Вы можете пойти дальше и отобразить это одним нажатием клавиши в вашем .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>

Обратите внимание, что это предполагает, что конструктор является первым методом класса, который появится. (Я мог бы это исправить, но я бы предпочел, чтобы это было просто. Пожалуйста, укажите в комментарии, если вам нужно это исправить.)

Это также предполагает, что буфер вашего файла заголовка пуст и расположен непосредственно после буфера исходного файла.

Пошаговое объяснение:

: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
Хотя это впечатляет (я довольно новичок в vim, поэтому каждый день открываю для себя новые вещи!), Боюсь, это совсем не то, что мне нужно. Может мне стоит заняться созданием собственного плагина? Это кажется забавным занятием.
Лукас
2
@Lukas Каким образом отображение в вашем .vimrc не решает проблему? Простое нажатие Ctrl-B автоматически заполнит файл заголовка для вас. (Вероятно, мне следует прояснить файл заголовка, прежде чем заменять его обновленной версией, но мне нужно поспать, чтобы я мог сделать это позже.) Плагин звучит интересно; держите меня в курсе, если вы решите сделать один. И спасибо за интересный вызов оттачивать мои навыки Vim! ;)
дверная ручка
2
Кажется, это работает в противоположном направлении от запроса: он создает заголовочный файл из файла .cpp.
200_success
... что также было бы неплохо, на самом деле, но я думаю, что есть некоторые вещи, которые не могут быть известны из определения: например, должно ли быть объявление inline? Есть ли аргументы по умолчанию? Должны ли имена аргументов быть исключены?
Кайл Стрэнд,
@ 200_success Ах, ты прав (я не знаю, почему я не ответил на твой комментарий ранее). Когда у меня будет время, я постараюсь изменить свой ответ, чтобы пойти другим путем.
дверная ручка
3

Команда :GOTOIMPLиз lh-cpp может перейти к определению функции из ее объявления или предоставить пустое определение по умолчанию, если ничего не найдено.

Некоторые особенности, которые я могу придумать:

  • Команда уже понимает , комментарии, спецификации исключений, ключевые слова , которые не должны быть скопированы (но , возможно , скопированные в комментариях) ( virtual, static, ...).
  • Текущий объем функции декодируется (namespaces :: classes :: ...) и корректно передается (т. Е. Он не будет префиксом, ns::если мы внутри namespace ns{или в using namespace ns;контексте).

Однако:

  • Шаблоны (пока) не поняты.
  • Тело функции должно быть построено вручную одна за другой - то есть я еще не потратил время на выполнение: GOTOIMPL на всех объявлениях функций, которые ctags может указывать мне.
Люк Эрмитт
источник