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


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?

Відповіді:


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! ;)
Doorknob

2
Здається, це працює в зворотному напрямку від запиту: він створює файл заголовка з файлу .cpp.
200_успіх

... що також було б непогано, насправді, але, думаю, є деякі речі, про які неможливо пізнати визначення: наприклад, чи повинна бути декларація inline? Чи є аргументи за замовчуванням? Чи повинні імена аргументів залишитись?
Кайл Странд

@ 200_success Ах, ти маєш рацію (не знаю, чому я раніше не відповідав на твій коментар). Коли встигну, спробую відредагувати свою відповідь, щоб піти іншим шляхом.
Дорноб

3

:GOTOIMPLКоманда з LH-CPP може перейти до визначення функції з його декларації, або надати за замовчуванням порожнього визначення в разі , якщо не було.

Я можу придумати деякі особливості:

  • Команда вже розуміє , коментарі, специфікації винятків, ключові слова , які не повинні бути скопійовані (але , можливо , скопійовані в коментарях) ( virtual, static, ...).
  • Поточний обсяг функції декодується (простори імен :: класи :: ...) і правильно повідомляється (тобто він не буде префіксом, ns::якщо ми знаходимось у контексті namespace ns{чи в ньомуusing namespace ns;

Однак:

  • Шаблони ще не вивчені.
  • Тіло функції потрібно будувати вручну одна за одною - тобто я ще не знадобився часу на виконання: GOTOIMPL про всі декларації функції, на які могла б вказати ctags.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.