Tự động tạo các hàm ngoài nguyên mẫu hàm từ các tệp tiêu đề


10

Giới thiệu

Khi lập trình trong C và C ++ bạn thường chia nguyên mẫu chức năng của bạn và chức năng thực tế vào một .h/ .hpp.c/ .cpptập tin. Đáng buồn thay, rất khó để chuyển các nguyên mẫu hàm từ tệp này sang tệp khác và yêu cầu mở cả hai tệp cùng một lúc (hoặc bộ nhớ tốt), cũng như nhiều thao tác gõ không cần thiết, đặc biệt là khi thay đổi đối số hoặc tên thành viên thực hiện.

Thí dụ

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
}

Câu hỏi

Có cách nào để tự động tạo và cập nhật các chức năng trong foo.cppviệc sử dụng các định nghĩa và nguyên mẫu trong foo.hppkhông?

Câu trả lời:


3

Whew, cái này rất vui!

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

Bạn có thể tiếp tục và ánh xạ nó tới một tổ hợp phím trong .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>

Lưu ý rằng điều này giả định rằng hàm tạo là phương thức lớp đầu tiên xuất hiện. (Tôi có thể sửa nó, nhưng tôi muốn giữ nó đơn giản. Vui lòng đề cập trong một bình luận nếu bạn cần sửa nó.)

Điều này cũng giả sử rằng bộ đệm tệp tiêu đề của bạn trống và nằm ngay sau bộ đệm tệp nguồn của bạn.

Giải thích từng bước:

: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
Mặc dù điều này rất ấn tượng (tôi khá mới đối với vim, vì vậy tôi đang khám phá những điều mới mỗi ngày!), Tôi sợ rằng đây không phải là tất cả những gì tôi cần. Có lẽ tôi nên xem xét việc tạo plugin của riêng mình? Có vẻ như là một điều thú vị để làm.
Lukas

2
@Lukas Bằng cách nào không một ánh xạ trong .vimrc của bạn giải quyết vấn đề? Chỉ cần nhấn Ctrl-B sau đó sẽ tự động điền vào tệp tiêu đề cho bạn. (Tôi có lẽ nên làm rõ tệp tiêu đề trước khi thay thế bằng phiên bản cập nhật, nhưng tôi phải ngủ để tôi có thể làm điều đó sau.) Một plugin nghe có vẻ thú vị; giữ cho tôi cập nhật nếu bạn quyết định làm cho một. Và cảm ơn vì thử thách thú vị để nâng cao kỹ năng Vim của tôi! ;)
tay nắm cửa

2
Điều này dường như hoạt động theo hướng ngược lại với yêu cầu: nó tạo ra một tệp tiêu đề từ tệp .cpp.
200_success 6/2/2015

... Điều đó cũng tốt, thực sự, nhưng tôi nghĩ có một số điều không thể biết từ định nghĩa: ví dụ: tuyên bố có phải là inline? Có đối số mặc định? Các tên đối số có nên được bỏ qua?
Kyle Strand

@ 200_success Ah, bạn nói đúng (Tôi không biết tại sao tôi không trả lời bình luận của bạn trước đó). Khi tôi có thời gian, tôi sẽ cố gắng chỉnh sửa câu trả lời của mình để đi theo con đường khác.
Doorknob

2

Các :GOTOIMPLlệnh từ lh-cpp có thể nhảy đến một định nghĩa chức năng từ khai của nó, hoặc để cung cấp một định nghĩa trống mặc định trong trường hợp không được tìm thấy.

Một số tính năng tôi có thể nghĩ đến:

  • Lệnh đã hiểu ý kiến, thông số kỹ thuật ngoại lệ, từ khóa đó sẽ không được sao chép (nhưng có thể sao chép trong bình luận) ( virtual, static, ...).
  • Phạm vi hiện tại của hàm được giải mã (không gian tên :: class :: ...) và được báo cáo chính xác (nghĩa là nó sẽ không có tiền tố ns::nếu chúng ta ở trong namespace ns{hoặc một using namespace ns;bối cảnh.

Tuy nhiên:

  • Mẫu không (chưa) hiểu.
  • Cơ thể chức năng sẽ được xây dựng thủ công lần lượt - tức là tôi chưa dành thời gian để thực thi: GOTOIMPL trên tất cả các khai báo chức năng mà ctags có thể chỉ cho tôi.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.