2016-01-15 6 views
8

मैं कुछ विरासत कोड पर हाथ मिला है और पहले मैं बदलना चाहते में C++ शैली डाली सी शैली डाली कन्वर्ट करने के लिएकैसे vim

(int)a + b; 

में
static_cast<int>(a) + b; 

वहाँ उनमें से एक बहुत कुछ कर रहे हैं और उन्हें मैन्युअल रूप से करने में बहुत समय लगता है। ऐसा करने के लिए विम का उपयोग करने का कोई तरीका है?

मैं की तरह

:%s/\(int\).* /static_cast<int>(\2)/g 

कुछ करने की कोशिश की, लेकिन यह काम नहीं करता। कृपया सलाह दें।

+0

मैं बदल जाएगा सूचक नामित सी ++ डाले, शुद्धता के लिए करने के लिए डाले, लेकिन इन विचारों संख्या प्रकार के लिए लागू नहीं डाले, जो मैं सिर्फ जगह में छोड़ चाहते हैं या संभवतः सी ++ नोटेशन 'int (ए)' में परिवर्तित करें (जिसका अर्थ है)। यानी, * अनावश्यक नई verbosity * परिचय नहीं है। –

+3

आपको शायद [clang-tidy] (http://clang.llvm.org/extra/clang-tidy/checks/google-readability-casting.html) जैसे कुछ का उपयोग करके बेहतर परिणाम मिलेंगे। – Jason

उत्तर

6

इस प्रयास करें:

:%s/(\(.*\))\([^ ]*\)/static_cast<\1>(\2)/g 

इस regex, आपके सवाल के अनुसार, यह मानता है कि वहाँ चर नाम के बाद एक जगह हो जाएगा:

उदाहरण:
परीक्षण डाटा निम्नलिखित के लिए:

(int)a + b 
(float)x * y 
(int)z+m 

परिणाम

होगा
static_cast<int>(a) + b 
static_cast<float>(x) * y 
static_cast<int>(z+m) 

regex

(\(.*\)) की व्याख्या - मैच जो कुछ भी अंदर () और यह
\([^ ]*\) कब्जा है - कुछ भी द्वारा पीछा किया जो एक स्थान नहीं है और कब्जा यह

+0

यह थोड़ा बहुत लचीला हो सकता है क्योंकि ब्रैकेट्स में से कुछ भी नहीं है जो सी स्टाइल कास्ट के रूप में नहीं है, लेकिन यह भी काम करता है! – user3667089

+1

अगर मैं सही ढंग से रेगेक्स को समझता हूं, तो '[^] '(स्पेस नहीं) बिट वह हिस्सा है जो कास्ट के अंदर जाने वाली शर्तों को निर्धारित करता है।यह अनिवार्य रूप से एक पार्स समस्या है, अनबाउंड जटिलता - एक रेगेक्स इसे कभी हल नहीं कर सकता है। '(int) (पी + क्यू)' 'static_cast ((पी) + क्यू) को पार्स किया गया है। ओटीओएच, यह काफी स्पष्ट है कि अगर हमने '[^ + - * /%^& |?] '' का उपयोग किया था तो' z + m' बेहतर पार्स किया गया होगा। '(Int) arr के लिए कोई त्वरित समाधान नहीं [i]' – MSalters

+1

@ user3667089: सच है, रेगेक्स बहुत सरल है। लेकिन इस '% s/(\ (int \ | float \ | double \)) में regex को बदलकर कुछ बुनियादी डेटा प्रकारों से मेल खाने के लिए आसानी से विस्तार किया जा सकता है) \ ([^] * \)/static_cast <\1> (\ 2)/जी'। लेकिन खुशी है कि इससे आपको इसके वर्तमान रूप में भी मदद मिली। – xk0der

0

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

%s/(int)\(a\)/static_cast<int>(\1)/g 

यह वैरिएबल नाम मान रहा है हमेशा a है। यदि ऐसा नहीं है तो आप a[a-z] के साथ प्रतिस्थापित कर सकते हैं।

+0

समस्या यह है कि आप अभिव्यक्तियों को कास्ट करते हैं, चर नहीं। कोई नियमित अभिव्यक्ति नहीं है जो सभी अभिव्यक्तियों और केवल अभिव्यक्तियों को कैप्चर कर सकती है। – MSalters

0

मेरे पास इस कार्य के लिए lh-cpp में कई मैपिंग हैं।

उस स्थिति में, यह ,,sc, या ,,rc, या ,,dc होगा। (यहां, , वास्तव में मेरा <localleader> है)।

यह वास्तव में लागू हो जाता है के रूप में:

function! s:ConvertToCPPCast(cast_type) 
    " Extract text to convert 
    let save_a = @a 
    normal! gv"ay 
    " Strip the possible brackets around the expression 
    let expr = matchstr(@a, '^(.\{-})\zs.*$') 
    let expr = substitute(expr, '^(\(.*\))$', '\1', '') 
    " 
    " Build the C++-casting from the C casting 
    let new_cast = substitute(@a, '(\(.\{-}\)).*', 
    \ a:cast_type.'<\1>('.escape(expr, '\&').')', '') 
    " Do the replacement 
    exe "normal! gvs".new_cast."\<esc>" 
    let @a = save_a 
endfunction 

vnoremap <buffer> <LocalLeader><LocalLeader>dc 
    \ <c-\><c-n>:'<,'>call <sid>ConvertToCPPCast('dynamic_cast')<cr> 
    nmap <buffer> <LocalLeader><LocalLeader>dc viw<LocalLeader><LocalLeader>dc 

...