Bagaimana saya bisa secara otomatis memasukkan prototipe ke foo.h dari foo.c?

11

Misalkan saya sedang menulis program C di file foo.c:

int add_numbers(int x, int y, int z) {
    // Very complex implementation here.
    return x + y + z;
}

Saya ingin perintah yang akan menyisipkan prototipe fungsi yang sesuai di foo.h:

int add_numbers(int x, int y, int z);

Apakah ada solusi Emacs yang ada untuk ini?

Wilfred Hughes
sumber

Jawaban:

9

PEMBARUAN : Saya membuat paket Semantic Refactor yang sepenuhnya menyelesaikan masalah ini dan banyak lagi. Anda dapat melihat demo untuk melihat cara kerjanya. Teks yang tersisa dari jawaban ini, setelah kalimat ini, sudah tua dan meletakkannya di sana hanya untuk alasan historis.

JAWABAN TUA :

Anda dapat menggunakan senator-copy-taguntuk secara akurat menyalin tanda tangan fungsi, lalu menempel kembali di file sumber Anda. senator-copy-tagdan perintah Senator tersedia saat Anda mengaktifkan semantic-mode:

(semantic-mode 1)

Semantic adalah paket bawaan Emacs.

Anda dapat menggabungkan Senator Semantik dengan Proyektil ke dalam perintah untuk menyisipkan prototipe fungsi ke file lain (file dengan nama yang sama tetapi ekstensi berbeda) dari mana saja di proyek Anda. Jika hanya ada satu file lain, perintah memasukkan segera ke file itu; jika lebih dari satu, Anda diminta untuk memilih file; jika tidak ada, Anda akan diminta untuk seluruh file di proyek Anda. Setelah Anda memilih file, prompt menawarkan daftar tag Semantic di buffer saat ini yang dapat Anda pilih untuk disisipkan.

Saya menyerahkan PR ke Emacs Refactor . Kode lengkap jika Anda ingin mencoba tanpa menunggu PR: klik di sini .

Ini demo (dimulai ketika Anda melihat START DEMOdi bawah):

proyektil-semantik-masukkan-fungsi-prototipe

Anda juga dapat menggunakan hanya Senator untuk menyalin dan memfungsikan prototipe. Selama titik berada di mana saja di dalam fungsi tanda tangan atau fungsi tubuh, jalankan senator-copy-tag, yang terikat C-c , M-wsecara default, itu menyalin seluruh fungsi: baik tanda tangan dan tubuh. Namun, Anda hanya dapat menempelkan tanda tangan jika Anda ingin dengan menjalankan perintah senator-yank-tag, yang terikat C-c , C-ysecara default. Menekan C-ytempelkan seluruh tanda tangan fungsi beserta tubuhnya. senator-copy-tagbahkan bekerja dengan tanda tangan fungsi diperluas pada beberapa baris seperti ini:

void 
func(int a,
     int b, 
     int c)
{
    .....
}

Meskipun pendekatan ini tidak memasukkan secara langsung ke buffer dengan nama yang sama, itu lebih berlaku dalam kasus lain. Kasing penggunaan Anda hanya berfungsi jika Anda memiliki dua file di direktori yang sama dan dengan nama yang sama tetapi ekstensi berbeda. Bagaimana jika deklarasi fungsi dan definisi fungsi harus tetap di file yang berbeda dengan nama yang berbeda?

EDIT2 : Berikut adalah contoh untuk penyisipan cerdas prototipe fungsi menggunakan tag Semantic. Saat ini, Anda hanya dapat menyisipkan berdasarkan posisi relatif ("sebelum" dan "setelah") tag Semantic tingkat atas. Saya akan update untuk membuat pengguna dapat memasukkan di tempat di mana tag Semantic yang tersedia, dengan posisi yang lebih (yaitu ketika tag adalah Class, itu harus menawarkan posisi tambahan: public, projecteddan private). Demo dimulai ketika Anda melihat START DEMOdi bagian bawah:

projectile-semantic-insert-function-prototype2

Bonus : Jika Anda ingin membuat daftar definisi fungsi kosong dalam .cppfile dari file header, gunakan member-functions.el . Tapi segera, saya akan menggantinya dengan Semantic + Projectile.

Tu Do
sumber
3

Perintah berikut harus melakukannya. Itu lulus tes saya, dan tidak memiliki dependensi eksternal.

(defun endless/copy-proto-to-header-file ()
  (interactive)
  (save-excursion
    ;; c-mode's `beginning-of-defun' should be robust enough.
    (beginning-of-defun)
    (let ((l (point)))
      (search-forward-regexp " *{")
      (let ((proto (buffer-substring l (match-beginning 0))))
        (ff-find-other-file)
        ;; If other file is already open, we don't want to move point.
        (save-excursion
          (goto-char (point-max))
          ;; Do some more movement here if you want.
          (insert "\n" proto ";"))))))
Malabarba
sumber
2

Saya pikir yang berikut ini harus bekerja (itu bekerja untuk saya):

(defun c-copy-function-signature-to-header ()
  (interactive)
  (save-excursion
    (let ((last-point -1))
      (while (/= (point) last-point)
        (setq last-point (point))
        (sp-backward-up-sexp))
      (kill-ring-save (point) (line-beginning-position))
      (ff-find-other-file)
      (yank)
      ;; clean whitespace between closing paren and opening curly 
      (delete-trailing-whitespace
        (line-beginning-position)
        (line-end-position))
      (insert ";")))

Ini memerlukan smartparens, meskipun Anda mungkin dapat meretas salinan Anda sendiri sp-backward-up-sexpjika itu tidak dapat diterima.

Perhatikan juga bahwa ini akan menempatkan tajuk di mana pun Anda meninggalkan yang (point)terakhir di tajuk. Karena Anda tidak menentukan di mana Anda menginginkannya, saya pikir ini mungkin yang terbaik. Tentu saja, jika Anda ingin menambahkannya di akhir, Anda dapat meletakkan (end-of-buffer)sebelum (yank). Tentu saja Anda dapat menambahkan hal-hal yang lebih bagus seperti membuat garis baru di dekat titik dan menarik di sana, tapi itu terserah selera Anda.

PythonNut
sumber