जब ऑर्ग-मोड में स्रोत फ़ाइलों को शामिल करके ऑटो स्टार्ट और एंड लाइनों की गणना कैसे करें?


10

मैं अपने प्रलेखन में नीचे है:

#+INCLUDE: "code/basic.sv" :src systemverilog :lines "14-117"

यहां लाइन 14 है, जहां मेरे पास है class basic extends ..और लाइन 116 वह जगह है जहां मेरे पास है endclass

क्या ऑटो को 14 और 117 (= 116 + 1) नंबर डालने का एक तरीका है ताकि मुझे हर बार मुझे संशोधित करने के लिए मैन्युअल रूप से अपडेट न करना पड़े code/basic.sv?


तो क्या आप हमेशा क्लास से एंडक्लास जाना चाहते हैं?
मालाबार

1
नहीं। यह एक उदाहरण था। मैं एक समाधान के बारे में सोच रहा हूं जहां मैं शुरुआत और अंत लाइनों के लिए regex प्रदान कर सकता हूं .. कुछ एक फ़ंक्शन का मूल्यांकन करेगाorg-include-src(FILE, LANGUAGE, REGEX_BEGIN, REGEX_END)
कौशल मोदी

एक तरीका यह है कि शामिल फ़ाइल में कुछ प्रकार के अनूठे मार्कर (शुरुआती छोर) रखकर, उन्हें एक फ़ंक्शन के साथ ढूंढें, जो org-export-before-processing-hookलाइन संख्याओं के लिए प्रीप्रोसेस करने के लिए झुका होगा । एक अन्य तरीका सिर्फ एक सुविधा अनुरोध मेल भेजने के लिए है ओआरजी मेलिंग सूची :)
kindahero

जवाबों:


8

यहाँ एक और विकल्प है। यह वह है जो आप नियमित अभिव्यक्ति को प्रति-शामिल आधार पर अनुकूलित करते हैं। यह कुछ वर्कफ़्लोज़ के साथ बेहतर रूप से फिट होना चाहिए क्योंकि आप एक्सटेंशन-आधारित परिभाषाओं तक सीमित नहीं हैं।

उपयोग करने के लिए

अपनी org-file में निम्नलिखित की तरह कुछ करें। ( :linesकीवर्ड वैकल्पिक है)

#+INCLUDE: "code/my-class.sv" :src systemverilog :range-begin "^class" :range-end "^endclass" :lines "14-80"

फ़ंक्शन "my-class.sv" पर जाएगा और उन दो regexps के लिए खोज करेगा, और फिर यह :linesमैच परिणाम के अनुसार कीवर्ड को अपडेट करेगा ।

यदि :range-beginगायब है, तो सीमा "-80" होगी।
यदि :range-endगायब है, तो सीमा "14-" होगी।

कोड

(add-hook 'before-save-hook #'endless/update-includes)

(defun endless/update-includes (&rest ignore)
  "Update the line numbers of #+INCLUDE:s in current buffer.
Only looks at INCLUDEs that have either :range-begin or :range-end.
This function does nothing if not in org-mode, so you can safely
add it to `before-save-hook'."
  (interactive)
  (when (derived-mode-p 'org-mode)
    (save-excursion
      (goto-char (point-min))
      (while (search-forward-regexp
              "^\\s-*#\\+INCLUDE: *\"\\([^\"]+\\)\".*:range-\\(begin\\|end\\)"
              nil 'noerror)
        (let* ((file (expand-file-name (match-string-no-properties 1)))
               lines begin end)
          (forward-line 0)
          (when (looking-at "^.*:range-begin *\"\\([^\"]+\\)\"")
            (setq begin (match-string-no-properties 1)))
          (when (looking-at "^.*:range-end *\"\\([^\"]+\\)\"")
            (setq end (match-string-no-properties 1)))
          (setq lines (endless/decide-line-range file begin end))
          (when lines
            (if (looking-at ".*:lines *\"\\([-0-9]+\\)\"")
                (replace-match lines :fixedcase :literal nil 1)
              (goto-char (line-end-position))
              (insert " :lines \"" lines "\""))))))))

(defun endless/decide-line-range (file begin end)
  "Visit FILE and decide which lines to include.
BEGIN and END are regexps which define the line range to use."
  (let (l r)
    (save-match-data
      (with-temp-buffer
        (insert-file file)
        (goto-char (point-min))
        (if (null begin)
            (setq l "")
          (search-forward-regexp begin)
          (setq l (line-number-at-pos (match-beginning 0))))
        (if (null end)
            (setq r "")
          (search-forward-regexp end)
          (setq r (1+ (line-number-at-pos (match-end 0)))))
        (format "%s-%s" l r)))))

2
यह भी खूब रही! अब मैं एक ही फ़ाइल से कई स्निपेट्स निर्यात करने के लिए इसका उपयोग कर सकता हूं। स्निपेट 1 #+INCLUDE: "code/basic.sv" :src systemverilog :range-begin "// Example 1" :range-end "// End of Example 1":। स्निपेट 2 #+INCLUDE: "code/basic.sv" :src systemverilog :range-begin "// Example 2" :range-end "// End of Example 2":। अमल निर्दोष है! इसे जल्दी लागू करने के लिए धन्यवाद !
कौशल मोदी

5

सबसे अच्छा तरीका मुझे लगता है कि निर्यात करने से ठीक पहले या मूल्यांकन करने से पहले इन नंबरों को अपडेट करना है।

अद्यतन करनेवाला

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

(add-hook 'before-save-hook #'endless/update-includes)

(defun endless/update-includes (&rest ignore)
  "Update the line numbers of all #+INCLUDE:s in current buffer.
Only looks at INCLUDEs that already have a line number listed!
This function does nothing if not in org-mode, so you can safely
add it to `before-save-hook'."
  (interactive)
  (when (derived-mode-p 'org-mode)
    (save-excursion
      (goto-char (point-min))
      (while (search-forward-regexp
              "^\\s-*#\\+INCLUDE: *\"\\([^\"]+\\)\".*:lines *\"\\([-0-9]+\\)\""
              nil 'noerror)
        (let* ((file (expand-file-name (match-string-no-properties 1)))
               (lines (endless/decide-line-range file)))
          (when lines
            (replace-match lines :fixedcase :literal nil 2)))))))

द रेगेक्स

यह वह जगह है जहाँ आप regexps को परिभाषित करते हैं जिसका उपयोग पहली और अंतिम लाइनों के रूप में किया जाएगा। आप प्रत्येक फ़ाइल एक्सटेंशन के लिए regexps की सूची दे सकते हैं।

(defcustom endless/extension-regexp-map 
  '(("sv" ("^class\\b" . "^endclass\\b") ("^enum\\b" . "^endenum\\b")))
  "Alist of regexps to use for each file extension.
Each item should be
    (EXTENSION (REGEXP-BEGIN . REGEXP-END) (REGEXP-BEGIN . REGEXP-END))
See `endless/decide-line-range' for more information."
  :type '(repeat (cons string (repeat (cons regexp regexp)))))

पृष्ठभूमि कार्यकर्ता

यह वह आदमी है जो ज्यादातर काम करता है।

(defun endless/decide-line-range (file)
  "Visit FILE and decide which lines to include.
The FILE's extension is used to get a list of cons cells from
`endless/extension-regexp-map'. Each cons cell is a pair of
regexps, which determine the beginning and end of region to be
included. The first one which matches is used."
  (let ((regexps (cdr-safe (assoc (file-name-extension file)
                                  endless/extension-regexp-map)))
        it l r)
    (when regexps
      (save-match-data
        (with-temp-buffer
          (insert-file file)
          (while regexps
            (goto-char (point-min))
            (setq it (pop regexps))
            (when (search-forward-regexp (car it) nil 'noerror)
              (setq l (line-number-at-pos (match-beginning 0)))
              (when (search-forward-regexp (cdr it) nil 'noerror)
                (setq regexps nil
                      r (line-number-at-pos (match-end 0))))))
          (when r (format "%s-%s" l (+ r 1))))))))

1
अगर मैं सुझाव दे सकता हूं, तो दो कार्यों को संपादित करें और फिर पहले एक को एमएक्स के साथ लागू करें। यह बहुत जानकारीपूर्ण होना चाहिए। :-)
मालाबार

समारोह अपने आप ठीक चलता है। लेकिन हुक को उस फ़ंक्शन को कॉल करने के लिए एक तर्क पारित करने की आवश्यकता है। डॉक्स से org-export-before-processing-hook, के लिए Every function in this hook will be called with one argument: the back-end currently used, as a symbol। जैसा कि हम कोई तर्क नहीं दे रहे हैं, हमें त्रुटि मिलती है run-hook-with-args: Wrong number of arguments। अब मुझे यकीन नहीं है कि क्या तर्क जोड़ूं endless/update-includes... (&optional dummy)?
कौशल मोदी

@kaushalmodi उफ़, मेरी बुर। मैंने जवाब अपडेट कर दिया है। आप लिखी हुई बात का भी उपयोग कर सकते हैं।
मालाबार

ठीक है .. जोड़ना (&optional dummy)वास्तव में काम किया! लेकिन हुक के माध्यम से फ़ंक्शन को कॉल करने का एक दिलचस्प साइड-इफेक्ट। यदि मैं फ़ंक्शन का उपयोग करके कॉल करता हूं M-x, तो यह .orgफ़ाइल को अपडेटेड लाइन नंबरों के साथ संशोधित करता है । लेकिन अगर मैं केवल html में निर्यात करता हूं और हुक को फ़ंक्शन को कॉल करने की अनुमति देता हूं, तो अपडेट की गई लाइन संख्या केवल निर्यात की गई फ़ाइल में दिखाई देती है, न कि .orgफ़ाइल में।
कौशल मोदी

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