Foo.c'den foo.h dosyasına nasıl otomatik olarak bir prototip ekleyebilirim?


11

Diyelim ki foo.c dosyasında bir C programı yazıyorum:

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

Foo.h içinde ilgili işlev prototipi ekleyecek bir komut istiyorum:

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

Bunun için mevcut Emacs çözümleri var mı?

Yanıtlar:


9

GÜNCELLEME : Bu sorunu ve daha fazlasını tamamen çözen Semantic Refactor paketini oluşturdum . Nasıl çalıştığını görmek için demolara bakabilirsiniz . Bu cümlenin ardından bu cevabın kalan metni eskidir ve sadece tarihsel bir sebepten dolayı oraya koymuştur.

ESKİ CEVAP :

senator-copy-tagİşlev imzasını doğru bir şekilde kopyalamak için kullanabilir , ardından kaynak dosyanıza geri yapıştırabilirsiniz. senator-copy-tagve Senatör komutları aşağıdakileri etkinleştirdiğinizde kullanılabilir semantic-mode:

(semantic-mode 1)

Semantik bir Emacs yerleşik paketidir.

Semantik Senatör'ü Mermi ile birleştirerek, işlev prototipini projenizdeki herhangi bir yerden başka bir dosyaya (aynı ada ancak farklı uzantıya sahip dosya) ekleme komutuyla birleştirebilirsiniz. Yalnızca bir dosya varsa, komut hemen bu dosyaya eklenir; birden fazla ise, bir dosya seçmeniz istenir; eğer yoksa, projenizdeki tüm dosyaları girmeniz istenir. Bir dosya seçtikten sonra, bilgi istemi geçerli arabellekte sonradan eklemeyi seçebileceğiniz Anlamsal etiketlerin bir listesini sunar.

Ben gönderilen bir PR için Emacs Refactor . PR'yi beklemeden denemek istiyorsanız tam kod: buraya tıklayın .

İşte bir demo ( START DEMOaltta gördüğünüzde başlar ):

mermi-semantik-insert fonksiyonlu-prototip

Prototip kopyalamak ve işlevini yerine getirmek için yalnızca Senatör'ü kullanabilirsiniz. Nokta, işlev imzası veya işlev gövdesi içinde herhangi bir yerde olduğu sürece, varsayılan senator-copy-tagolarak bağlı olan run , C-c , M-wtüm işlevi kopyalar: hem imza hem de gövde. Ancak, varsayılan senator-yank-tagolarak bağlı olan komutu çalıştırarak yalnızca imzayı yapıştırabilirsiniz C-c , C-y. Basılarak C-ytüm işlev imzası gövdesi ile birlikte yapıştırılır. senator-copy-taghatta bu gibi birden çok satıra genişletilmiş fonksiyon imzası ile çalışır:

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

Bu yaklaşım aynı ada sahip ara belleğe doğrudan eklenmese de, diğer durumlarda daha uygulanabilir. Kullanım durumunuz yalnızca aynı dizinde ve aynı ada ancak farklı uzantılara sahip iki dosyanız varsa çalışır. İşlev bildirimi ve işlev tanımı farklı adlara sahip farklı dosyalarda kalmalıdırsa ne olur?

EDIT2 : Semantik etiketleri kullanarak fonksiyon prototipinin akıllıca eklenmesi için bir örnek. Şu anda, yalnızca üst düzey Anlamsal etiketlerin göreli konumlarına ("önce" ve "sonra") dayanarak ekleyebilirsiniz. Ben Semantik etiketlerinin daha pozisyonlarla mevcuttur herhangi bir yerde eklemek için muktedir yapmak kullanıcıya güncellenir (bir etiket, bir zaman yani Class:, ek pozisyonları sunmalıdır public, projectedve private). Demo START DEMO, altta gördüğünüzde başlar :

mermi semantik-uç fonksiyonlu-prototype2

Bonus : .cppBir başlık dosyasındaki bir dosyada boş işlev tanımlarının bir listesini oluşturmak istiyorsanız member-function.el dosyasını kullanın . Ama yakında, Semantik + Mermi ile değiştireceğim.


3

Aşağıdaki komut bunu yapmalıdır. Testlerimi geçti ve harici bağımlılıkları yok.

(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 ";"))))))

2

Ben düşünüyorum şu (benim için çalışır) çalışması gerekir:

(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 ";")))

Kabul edilemez ise smartparenskendi kopyanızı hackleyebilmenize rağmen, bu gereklidir sp-backward-up-sexp.

Ayrıca, üstbilgiyi başlıkta (point)son bıraktığınız yere koyacağınızı da unutmayın . Nerede istediğini belirtmediğin için, bunun muhtemelen en iyisi olduğunu düşündüm. Tabii ki, sonunda eklemek istiyorsanız, (end-of-buffer)önce bir koyabilirsiniz (yank). Tabii ki noktanın yakınında yeni bir çizgi oluşturmak ve orada sormak gibi meraklı şeyler ekleyebilirsiniz, ama bu zevkinize kalmış.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.