मैं foo.c से स्वचालित रूप से foo.h में एक प्रोटोटाइप कैसे डाल सकता हूं?


11

मान लीजिए कि मैं एक फ़ाइल में एक सी प्रोग्राम लिख रहा हूँ foo.c:

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

मुझे एक कमांड चाहिए जो foo.h में एक संबंधित फ़ंक्शन प्रोटोटाइप सम्मिलित करेगा:

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

क्या इसके लिए कोई मौजूदा Emacs समाधान हैं?

जवाबों:


9

अद्यतन : मैंने सिमेंटिक रिफैक्टर पैकेज बनाया है जो इस समस्या को पूरी तरह से हल करता है। आप डेमो पर गौर कर सकते हैं कि यह कैसे काम करता है। इस उत्तर का शेष पाठ, इस वाक्य के बाद, पुराना है और इसे केवल ऐतिहासिक कारण के लिए रखा गया है।

पुराने उत्तर :

आप senator-copy-tagफ़ंक्शन हस्ताक्षर की सटीक प्रतिलिपि बनाने के लिए उपयोग कर सकते हैं , फिर अपनी स्रोत फ़ाइल में वापस पेस्ट कर सकते हैं । senator-copy-tagऔर सीनेटर कमांड उपलब्ध हैं जब आप सक्षम होते हैं semantic-mode:

(semantic-mode 1)

सिमेंटिक एक एमएसीएस बिल्ट-इन पैकेज है।

आप अपने प्रोजेक्ट में कहीं से भी फंक्शन प्रोटोटाइप को दूसरी फाइल (एक ही नाम के साथ फाइल लेकिन अलग-अलग एक्सटेंशन में फाइल) में डालने के लिए प्रोजेक्टाइल के साथ सिमेंटिक सेनेटर को जोड़ सकते हैं। यदि केवल एक अन्य फ़ाइल है, तो कमांड उस फ़ाइल में तुरंत सम्मिलित करता है; यदि एक से अधिक है, तो आपको एक फ़ाइल का चयन करने के लिए कहा जाता है; यदि कोई नहीं है, तो आपको अपनी परियोजना में संपूर्ण फ़ाइलों के लिए संकेत दिया जाता है। आपके द्वारा किसी फ़ाइल का चयन करने के बाद, एक संकेत वर्तमान बफर में सिमेंटिक टैग की एक सूची प्रदान करता है जिसे आप बाद में सम्मिलित करना चुन सकते हैं।

मैंने Emacs Refactor को PR सबमिट किया । पूर्ण कोड यदि आप पीआर की प्रतीक्षा किए बिना प्रयास करना चाहते हैं: यहां क्लिक करें

यहाँ एक डेमो है (यह तब शुरू होता है जब आप START DEMOनीचे देखते हैं ):

फेंकने-अर्थ-डालने-समारोह-प्रोटोटाइप

आप प्रोटोटाइप की प्रतिलिपि बनाने और कार्य करने के लिए केवल सीनेटर का उपयोग कर सकते हैं। जब तक बिंदु कहीं भी फ़ंक्शन हस्ताक्षर या फ़ंक्शन बॉडी के अंदर है, तब तक चलाएं senator-copy-tag, जो C-c , M-wडिफ़ॉल्ट रूप से बाध्य है , यह संपूर्ण फ़ंक्शन की प्रतिलिपि बनाता है: हस्ताक्षर और निकाय दोनों। हालाँकि, आप केवल हस्ताक्षर को चिपका सकते हैं यदि आप कमांड चलाकर चाहते हैं senator-yank-tag, जो C-c , C-yडिफ़ॉल्ट रूप से बाध्य है । दबाने C-yअपने शरीर के साथ-साथ पूरे समारोह हस्ताक्षर पेस्ट करें। senator-copy-tagयहां तक ​​कि फ़ंक्शन हस्ताक्षर के साथ कई लाइनों पर इस तरह से विस्तार किया गया है:

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

यद्यपि यह दृष्टिकोण सीधे उसी नाम के साथ बफर में सम्मिलित नहीं होता है, यह अन्य मामलों में अधिक लागू होता है। आपका उपयोग मामला केवल तभी काम करता है जब आपके पास एक ही निर्देशिका में दो फ़ाइल हों और एक ही नाम लेकिन अलग-अलग एक्सटेंशन हों। क्या होगा अगर फंक्शन डिक्लेरेशन और फंक्शन डेफिनेशन अलग-अलग नामों के साथ अलग-अलग फाइलों में रहना चाहिए?

EDIT2 : यहाँ सेमेटिक टैग्स का उपयोग करके फंक्शन प्रोटोटाइप के स्मार्ट सम्मिलन के लिए एक उदाहरण दिया गया है। वर्तमान में, आप केवल शीर्ष स्तर के शब्दार्थ टैग के सापेक्ष पदों ("पहले" और "बाद में") के आधार पर सम्मिलित कर सकते हैं। मैं उपयोगकर्ता बनाने के लिए अद्यतन करेगा किसी भी जगह है जहाँ सिमेंटिक टैग उपलब्ध हैं, अधिक पदों के साथ में सम्मिलित करने के लिए सक्षम होने के लिए (यानी जब एक टैग एक है Class, यह अतिरिक्त पदों की पेशकश करनी चाहिए: public, projectedऔर private)। जब आप START DEMOनीचे देखते हैं तो डेमो शुरू होता है :

फेंकने-अर्थ-डालने-समारोह-prototype2

बोनस : यदि आप .cppहेडर फ़ाइल से किसी फ़ाइल में रिक्त फ़ंक्शन परिभाषाओं की सूची बनाना चाहते हैं , तो सदस्य-फ़ंक्शन का उपयोग करें । लेकिन जल्द ही, मैं इसे सिमेंटिक + प्रोजेक्टाइल से बदल दूंगा।


3

निम्न आदेश इसे करना चाहिए। इसने मेरे परीक्षण पास कर लिए, और इसकी कोई बाहरी निर्भरता नहीं थी।

(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

मुझे लगता है कि निम्नलिखित को काम करना चाहिए (यह मेरे लिए काम करता है):

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

इसके लिए आवश्यकता होती है smartparens, हालांकि आप sp-backward-up-sexpअस्वीकार्य होने पर अपनी स्वयं की प्रति हैक करने में सक्षम हो सकते हैं ।

यह भी ध्यान दें कि यह हेडर को वहीं रखेगा जहां आपने हेडर में (point)आखिरी छोड़ा था । जैसा कि आपने निर्दिष्ट नहीं किया कि आप इसे कहाँ चाहते हैं, मैंने सोचा कि यह शायद सबसे अच्छा था। बेशक, यदि आप इसे अंत में जोड़ना चाहते हैं, तो आप (end-of-buffer)पहले से डाल सकते हैं (yank)। बेशक आप बिंदु के पास एक नई लाइन बनाने और वहाँ yanking की तरह कट्टरपंथी सामान जोड़ सकते हैं, लेकिन यह आपके स्वाद पर निर्भर है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.