Secara otomatis membuat fungsi dari prototipe fungsi dari file header

10

Intro

Saat pemrograman dalam C dan C ++ Anda biasanya membagi prototipe fungsi dan fungsi aktual menjadi file .h/ .hppdan .c/ .cpp. Sayangnya sangat membosankan untuk mentransfer prototipe fungsi dari satu file ke file lainnya, dan membutuhkan membuka kedua file pada saat yang sama (atau memori yang baik), serta banyak pengetikan yang tidak perlu, terutama ketika perubahan pada argumen atau nama anggota terbuat.

Contoh

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
}

Pertanyaan

Apakah ada cara untuk secara otomatis membuat dan memperbarui fungsi dalam foo.cppmenggunakan definisi dan prototipe foo.hpp?

Lukas
sumber

Jawaban:

3

Wah, ini menyenangkan!

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

Anda dapat melanjutkan dan memetakannya ke satu penekanan tombol di .vimrc Anda:

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>

Perhatikan bahwa ini mengasumsikan bahwa konstruktor adalah metode kelas pertama yang muncul. (Saya bisa memperbaikinya, tapi saya lebih suka membuatnya sederhana. Mohon sebutkan dalam komentar jika Anda perlu memperbaikinya.)

Ini juga mengasumsikan bahwa buffer file header Anda kosong dan terletak tepat setelah buffer file sumber Anda.

Penjelasan langkah demi langkah:

: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
Gagang pintu
sumber
1
Meskipun ini mengesankan (saya agak baru untuk vim, jadi saya menemukan hal-hal baru setiap hari!), Saya khawatir ini sama sekali bukan yang saya butuhkan. Mungkin saya harus melihat ke dalam membuat plugin sendiri? Sepertinya hal yang menyenangkan untuk dilakukan.
Lukas
2
@Lukas Dengan cara apa pemetaan di .vimrc Anda tidak menyelesaikan masalah? Cukup menekan Ctrl-B maka secara otomatis akan mengisi file header untuk Anda. (Saya mungkin harus membuatnya jelas file header sebelum menggantinya dengan versi yang diperbarui, tetapi saya harus tidur jadi saya akan melakukannya nanti.) Sebuah plugin terdengar menarik; terus perbarui saya jika Anda memutuskan untuk membuatnya. Dan terima kasih atas tantangan yang menarik untuk mempertajam keterampilan Vim saya! ;)
Gagang pintu
2
Ini tampaknya bekerja berlawanan dari permintaan: ini menciptakan file header dari file .cpp.
200_sukses
... yang sebenarnya juga menyenangkan, tetapi saya pikir ada beberapa hal yang tidak dapat diketahui dari definisi: misalnya, apakah deklarasi seharusnya inline? Apakah ada argumen baku? Haruskah nama argumen dihilangkan?
Kyle Strand
@ 200_sukses Ah, Anda benar (saya tidak tahu mengapa saya tidak membalas komentar Anda sebelumnya). Ketika saya punya waktu, saya akan mencoba mengedit jawaban saya untuk sebaliknya.
Gagang pintu
2

The :GOTOIMPLperintah dari lh-cpp mampu melompat ke definisi fungsi dari deklarasi, atau untuk memberikan definisi kosong default dalam kasus tidak ditemukan.

Beberapa fitur yang dapat saya pikirkan:

  • Perintah sudah mengerti komentar, spesifikasi pengecualian, kata kunci yang tidak akan disalin (tapi mungkin disalin dalam komentar) ( virtual, static, ...).
  • Cakupan fungsi saat ini diterjemahkan (namespaces :: classes :: ...) dan dilaporkan dengan benar (artinya tidak akan diawali dengan ns::jika kita berada di dalam namespace ns{atau using namespace ns;konteks.

Namun:

  • Template belum (belum) dipahami.
  • Function body harus dibangun secara manual satu demi satu - yaitu saya belum meluangkan waktu untuk mengeksekusi: GOTOIMPL pada semua deklarasi fungsi yang dapat ditunjukkan oleh ctags kepada saya.
Luc Hermitte
sumber