2011-10-20 12 views
44

जहां तक ​​मैं emacs में जानता हूं, सी ++ में टेम्पलेट सूची के समापन '>' चरित्र के इंडेंटेशन स्तर को अनुकूलित करने का कोई तरीका नहीं है।सी ++ टेम्पलेट्स और एमएक्स: इंडेंटेशन को अनुकूलित करना

template < 
    typename T1, 
    typename T2, 
    typename T3 
    > 
class X; 

कुछ इस तरह मैं क्या चाहते हैं:: वर्तमान में मेरी Emacs खरोज योजना करता

template < 
    typename T1, 
    typename T2, 
    typename T3 
> 
class X; 

मांगपत्र चर टेम्पलेट आर्ग-शेष भाग शून्य करने के लिए '>' चरित्र ठीक से इंडेंट होगा स्थापना, लेकिन टेम्पलेट तर्क सूची के वास्तविक निकाय को अनइंडेंट करने की लागत पर।

वहां emacs गुरुओं से कोई सुझाव?

संपादित करें:

मैं इसे कुछ निम्नलिखित हैक के साथ काम मिल गया:

(defun indent-templates (elem) 
    (c-langelem-col elem t) 
    (let ((current-line 
     (buffer-substring-no-properties 
      (point-at-bol) (point-at-eol)))) 
    (if (string-match-p "^\\s-*>" current-line) 
     0 
     '+))) 

और फिर टेम्पलेट आर्ग-शेष भाग की स्थापना इंडेंट-टेम्पलेट्स के लिए अपने कस्टम विषय में, आला:

(c-add-style "my-style" 
      '("stroustrup" 
       ;; ... Other stuff ... 
       (template-args-cont . indent-templates)))) 

लेकिन यह अभी भी बहुत छोटी है। यह ज्यादातर समय काम करता है, लेकिन कभी-कभी emacs भ्रमित हो जाता है यह सोचता है कि एक टेम्पलेट सूची एक arglist है, और फिर Hilarity ensues।

+1

मुझे यकीन नहीं है कि यह संभव है, लेकिन यदि आप इस पृष्ठ पर जानकारी पा सकते हैं: http://www.gnu.org/software/emacs/manual/html_mono/ccmode.html#Customizing- इंडेंटेशन – rve

+0

असल में , मुझे लगता है कि यदि आप अपना खुद का लाइन-अप फ़ंक्शन लिखते हैं तो यह संभव हो सकता है। मेरी पिछली टिप्पणी से दस्तावेज़ इस पर अधिक जानकारी देता है। – rve

+6

ध्यान दें कि Emacs C++ - मोड समय-समय पर टेम्पलेट तर्कों के बारे में उलझन में पड़ता है, इसलिए यह वास्तव में आपके कोड में कोई समस्या नहीं हो सकती है ... [निष्पक्ष होने के लिए, वास्तव में सही होने के लिए यह बहुत मुश्किल है, क्योंकि कई अर्थों के कारण '<' and '>' सी ++ में (कभी-कभी एक संतुलित डिलीमीटर के रूप में, कभी-कभी ऑपरेटर के रूप में), जब तक कि आप सी ++ से अधिक वास्तविक पार्सिंग नहीं करते हैं - मोड करता है ...] – snogglethorpe

उत्तर

2

सबसे अच्छा समाधान है कि मैं पाया है एक कस्टम (और अपेक्षाकृत सीधा) खरोज समारोह लिख रहा है।

कोड

(defun c++-template-args-cont (langelem) 
"Control indentation of template parameters handling the special case of '>'. 
Possible Values: 
0 : The first non-ws character is '>'. Line it up under 'template'. 
nil : Otherwise, return nil and run next lineup function." 
    (save-excursion 
    (beginning-of-line) 
    (if (re-search-forward "^[\t ]*>" (line-end-position) t) 
     0))) 

(add-hook 'c++-mode-hook 
      (lambda() 
      (c-set-offset 'template-args-cont 
          '(c++-template-args-cont c-lineup-template-args +)))) 

यह मामलों है कि मैं भी साथ टेम्पलेट्स कई स्तरों गहरी नेस्ट सामने आने वाले ही करता है।

यह कैसे काम करता

कोड इंडेंट के लिए, खरोज कार्यों की एक सूची प्रदान की जाती है, तो Emacs उन्हें क्रम में की कोशिश करेंगे और अगर एक वर्तमान में क्रियान्वित किया जा रहा रिटर्न nil, यह अगले एक आह्वान करेंगे। मैंने जो किया है, उस सूची की शुरुआत में एक नया इंडेंटेशन फ़ंक्शन जोड़ा गया है जो यह पता लगाता है कि लाइन पर पहला गैर-व्हाइटस्पेस वर्ण '>' है, और यदि यह है, तो इंडेंटेशन को स्थिति 0 पर सेट करें (जो इसे लाइन करेगा उद्घाटन टेम्पलेट के साथ)।

template < 
    template < 
    typename T, 
    typename U, 
    typename... Args 
    > class... CS 
> 

क्योंकि यह परवाह नहीं करता क्या के बाद '>': यह भी मामला इस प्रकार है जहाँ आप टेम्पलेट टेम्पलेट पैरामीटर शामिल हैं। इसलिए इंडेंटेशन फ़ंक्शन की सूची कैसे काम करती है, इसके परिणामस्वरूप, '>' पहला अक्षर नहीं है, फ़ंक्शन nil देता है और सामान्य इंडेंटेशन फ़ंक्शन लागू होता है।

0

टैब बदलने के बाद यह एक अलग दृष्टिकोण है, लेकिन Yasnippet जैसे स्निपेट सिस्टम का उपयोग करने के बारे में क्या है (उदाहरण here देखें)।

एकमात्र मुद्दा यह है कि यदि आप दस्तावेज़ "एम-एक्स इंडेक्स-क्षेत्र" (या वह अनुभाग) को दोबारा सुधारते हैं, तो यह शायद अन्य टैब नियमों पर वापस जायेगा।

1

टिप्पणियां

मुझे लगता है कि की हिस्सा समस्या आप अनुभव है कि जब आप का दृष्टांत टेम्पलेट्स, Emacs सीसी मोड में एक ही template-args-cont संरचना के साथ यह विचार है। इसलिए, इसे ध्यान में रखते हुए, मैंने आपके मूल विचार पर विस्तार किया और इसे मेरी पसंद के अनुरूप बनाने की कोशिश की; मैंने कोड वर्बोज़ बनाया ताकि आशा है कि हर कोई मेरे इरादे को समझ सके। :) यह तत्काल होने पर समस्याएं उत्पन्न नहीं होनी चाहिए, और यह टेम्पलेट टेम्पलेट पैरामीटर के लिए भी काम करता प्रतीत होता है! इसे तब तक आज़माएं जब तक कि अधिक Elisp कौशल वाले कोई बेहतर समाधान प्रदान न कर सके!

आप किसी भी 'लड़ाई' (अर्थात बारी या टूट खरोज) अनुभव करते हैं, सीपीपी फ़ाइल सी-एक्ससी वीदर्ज पुन: लोड और फिर से इंडेंट प्रयास करें। कभी-कभी टेम्पलेट टेम्पलेट पैरामीटर के साथ emacs arglist-cont-nonempty के रूप में आंतरिक तर्क दिखाता है और यहां तक ​​कि template-args-const के साथ भी आगे की ओर दिखाता है, लेकिन पुनः लोड हमेशा राज्य को पुनर्स्थापित करता है।

प्रयोग

क्या आप इस नीचे दिए गए कोड का उपयोग कर और एक प्रवेश अपने c-offsets-alist को जोड़कर बाहर की कोशिश करना चाहते हैं के लिए:

(template-args-cont . brian-c-lineup-template-args)

और सेट चर

(setq brian-c-lineup-template-closebracket t) 

मैं वास्तव में थोड़ा अलग संरेखण पसंद करता हूं:

(setq brian-c-lineup-template-closebracket 'under) 

कोड

(defvar brian-c-lineup-template-closebracket 'under 
    "Control the indentation of the closing template bracket, >. 
Possible values and consequences: 
'under : Align directly under (same column) the opening bracket. 
t  : Align at the beginning of the line (or current indentation level. 
nil : Align at the same column of previous types (e.g. col of class T).") 

(defun brian-c-lineup-template--closebracket-p() 
    "Return t if the line contains only a template close bracket, >." 
    (save-excursion 
    (beginning-of-line) 
    ;; Check if this line is empty except for the trailing bracket, > 
    (looking-at (rx (zero-or-more blank) 
      ">" 
      (zero-or-more blank))))) 

(defun brian-c-lineup-template--pos-to-col (pos) 
    (save-excursion 
    (goto-char pos) 
    (current-column))) 

(defun brian-c-lineup-template--calc-open-bracket-pos (langelem) 
    "Calculate the position of a template declaration opening bracket via LANGELEM." 
    (save-excursion 
    (c-with-syntax-table c++-template-syntax-table 
     (goto-char (c-langelem-pos langelem)) 
     (1- (re-search-forward "<" (point-max) 'move))))) 

(defun brian-c-lineup-template--calc-indent-offset (ob-pos) 
    "Calculate the indentation offset for lining up types given the opening 
bracket position, OB-POS." 
    (save-excursion 
    (c-with-syntax-table c++-template-syntax-table 
     ;; Move past the opening bracket, and check for types (basically not space) 
     ;; if types are on the same line, use their starting column for indentation. 
     (goto-char (1+ ob-pos)) 
     (cond ((re-search-forward (rx 
       (or "class" 
        "typename" 
        (one-or-more (not blank)))) 
       (c-point 'eol) 
       'move) 
     (goto-char (match-beginning 0)) 
     (current-column)) 
     (t 
     (back-to-indentation) 
     (+ c-basic-offset (current-column))))))) 

(defun brian-c-lineup-template-args (langelem) 
    "Align template arguments and the closing bracket in a semi-custom manner." 
    (let* ((ob-pos (brian-c-lineup-template--calc-open-bracket-pos langelem)) 
    (ob-col (brian-c-lineup-template--pos-to-col ob-pos)) 
    (offset (brian-c-lineup-template--calc-indent-offset ob-pos))) 

    ;; Optional check for a line consisting of only a closebracket and 
    ;; line it up either at the start of indentation, or underneath the 
    ;; column of the opening bracket 
    (cond ((and brian-c-lineup-template-closebracket 
      (brian-c-lineup-template--closebracket-p)) 
     (cond ((eq brian-c-lineup-template-closebracket 'under) 
      (vector ob-col)) 
      (t 
      0))) 
     (t 
     (vector offset))))) 
+0

वाह, इसके लिए धन्यवाद। अगर मैं कुछ समय (घरों को स्थानांतरित करने की प्रक्रिया में) करता हूं तो मैं इसे सप्ताहांत में आज़मा दूंगा। – bstamour

संबंधित मुद्दे