क्या एक बेहतर तरीका है कि आप मल्टीप्ल डॉकस्ट्रिंग को इस्प्रिल में संभाल सकते हैं?


9

मैं उस तरह से नफरत करता हूं जो कि निश्चित रूप से (निश्चित रूप से अगर एलआईएसपी सामान्य नहीं है) मल्टीलाइन डोकस्ट्रिंग्स को संभालता है।

(defun foo ()
  "This is
a multi
liner
docstring"
  (do-stuff))

मुझे यकीन है कि काश मैं ऐसा कुछ कर पाता

(defun foo ()
  (eval-when-compile 
    (concat
      "This is\n"
       "a multi\n"
       "line\n"
       "docstring"))
  (do-stuff))

इतना है कि इंडेंटेशन सुसंगत था।

दुर्भाग्य से, eval-जब-संकलन काम नहीं करता है।

क्या किसी के पास कोई विचार है?


यह एक मैक्रो बनाने के लिए काफी आसान होना चाहिए जो एक में विस्तार करेगा defun। उस दृष्टिकोण की खामी - और यह एक बड़ा है - वह है किसी भी सॉफ़्टवेयर को भ्रमित करेगा (विशिष्ट कंपाइलर / दुभाषिया के अलावा) जो आपके कोड को खोज रहा है defun
हेराल्ड हैन्च-ऑलसेन

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

जवाबों:


7

बेशक एक my-defunमैक्रो आसान तरीका है। लेकिन एक सरल समाधान होगा

(advice-add 'eval-when-compile :filter-return
            (lambda (exp)
              (if (and (eq 'quote (car-safe exp))
                       (stringp (cadr exp)))
                  (cadr exp)
                exp)))

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

फिर भी, यह सभी मौजूदा कोड को ठीक नहीं करेगा, इसलिए शायद एक बेहतर उत्तर कुछ इस तरह है:

;; -*- lexical-binding:t -*-

(defun my-shift-docstrings (orig ppss)
  (let ((face (funcall orig ppss)))
    (when (eq face 'font-lock-doc-face)
      (save-excursion
        (let ((start (point)))
          (parse-partial-sexp (point) (point-max) nil nil ppss 'syntax-table)
          (while (search-backward "\n" start t)
            (put-text-property (point) (1+ (point)) 'display
                               (propertize "\n  " 'cursor 0))))))
    face))

(add-hook 'emacs-lisp-mode-hook
          (lambda ()
            (font-lock-mode 1)
            (push 'display font-lock-extra-managed-props)
            (add-function :around (local 'font-lock-syntactic-face-function)
                          #'my-shift-docstrings)))

जिसे केवल 2 स्थानों द्वारा डॉकस्ट्रिंग्स को स्थानांतरित करना चाहिए, लेकिन केवल बफ़र की वास्तविक सामग्री को प्रभावित किए बिना, प्रदर्शन पक्ष पर।


1
मुझे वास्तव में आपका दूसरा समाधान पसंद है। लेकिन सलाह के मेरे तर्कहीन डर ने मुझे पहली बार में परेशान कर दिया। :-)
मालाबार

6

आप इस तरह एक मैक्रो का उपयोग कर सकते हैं:

(defmacro my-defun (name arglist &rest forms)
  "Like `defun', but concatenates strings."
  (declare (indent defun))
  (let (doc-lines)
    (while (and (stringp (car-safe forms))
                (> (length forms) 1))
      (setq doc-lines
            (append doc-lines (list (pop forms)))))
    `(defun ,name ,arglist
       ,(mapconcat #'identity doc-lines "\n")
       ,@forms)))

तब आप अपने कार्यों को इस तरह परिभाषित कर सकते हैं:

(my-defun test (a)
  "Description"
  "asodksad"
  "ok"
  (interactive)
  (+ 1 a))

फिर भी, मैं दृढ़ता से इस तरह के एक मामूली लाभ के लिए मानकों के खिलाफ नहीं जाने की सलाह दूंगा। "अनियमित इंडेंटेशन" जो आपको सिर्फ 2 कॉलम से परेशान करता है, इसका उल्लेख नहीं करने से यह प्रलेखन की पहली पंक्ति को उजागर करने में मदद करता है जो अधिक महत्वपूर्ण है।


दरअसल, डिफॉन के शरीर का मूल्यांकन किया जाता है (जब फ़ंक्शन को कॉल किया जाता है) और फ़ंक्शन को परिभाषित करने पर यह मैक्रो-विस्तारित होता है। तो उसकी चाल / काम होनी चाहिए।
स्टीफन

@ सफ़्फ़ान यह सच है। भूल eval-when-compileएक स्थूल था।
मालाबार

-1

मैंने ऐसे पैकेज देखे हैं जो इस तरह से docstrings को परिभाषित करते हैं:

(defun my-function (x y) "
this is my docstring
that lines always lines up
across multiple lines."
  (+ x y))

पहली पंक्ति को पहली पंक्ति पर रखना और फिर अगले पर पाठ शुरू करना ताकि वे सभी पंक्तिबद्ध हों। यह निश्चित रूप से मानक नहीं है, लेकिन आप इसे करने वाले केवल एक ही नहीं होंगे।


1
यह एक बुरा विचार है। एप्रोपोस जैसे संदर्भों में, डॉकस्ट्रिंग की केवल पहली पंक्ति को दिखाया गया है, ताकि पहली पंक्ति जानकारी प्रदान करे (और अपने दम पर खड़ी हो)। इस तरह आपको एक खाली विवरण मिलता है।
गिल्स एसओ- बुराई को रोकना '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.