2016-01-15 10 views
8

Ich habe Hand über einige Legacy-Code konvertieren und zunächst möchte ichWie C Casts in C++ Casts in vim

(int)a + b; 

in

static_cast<int>(a) + b; 

Es ändern sind viele von ihnen und sie manuell zu tun ist sehr zeitaufwendig. Gibt es eine Möglichkeit, vim zu verwenden, um dies zu ermöglichen?

habe ich versucht, so etwas wie

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

aber es funktioniert nicht. Bitte um Rat.

+0

ich der Zeiger wirft auf dem Namen C++ Abgüsse umwandeln würde, für die Richtigkeit, aber diese Überlegungen gelten nicht für die Anzahl Typ wirft, was ich würde lassen Sie einfach an Ort und Stelle oder möglicherweise in die C++ - Notation 'int (a)' konvertieren (was dasselbe bedeutet). Ie., führen Sie nicht * unnötige neue Ausführlichkeit * ein. –

+3

Sie würden wahrscheinlich bessere Ergebnisse mit etwas wie [Clang-Tidy] (http://clang.llvm.org/extra/clang-tidy/checks/google-readability-casting.html) bekommen. – Jason

Antwort

6

Try this:

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

Diese Regex, wie pro Ihre Frage geht davon aus, dass es einen Raum nach dem Variablennamen sein:

Beispiel:
Für Testdaten folgende:

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

Ergebnis wird

sein
static_cast<int>(a) + b 
static_cast<float>(x) * y 
static_cast<int>(z+m) 

die Regex

(\(.*\)) Erklären - Spiel, was im Inneren ist
\([^ ]*\)() und erfassen - gefolgt von etwas, das kein Platz ist und erfassen sie

+0

Es könnte etwas zu flexibel sein, da alles in den Klammern, das nicht als C-Style-Cast gedacht ist, ebenfalls geändert wird, aber es funktioniert! – user3667089

+1

Wenn ich die Regex richtig verstehe, ist das '[^]' (nicht Leerzeichen) -Bit der Teil, der die Ausdrücke bestimmt, die in den Cast hineingehen.Das ist im Wesentlichen ein Parse-Problem, von ungebundener Komplexität - ein Regex kann es niemals lösen. '(int) (p + q)' wird zu 'static_cast ((p) + q)' geparst. OTOH, es ist ziemlich offensichtlich, dass 'z + m' besser geparst worden wäre, wenn wir' [^ + - * /%^& |?] 'Verwendet hätten. Keine schnelle Lösung für '(int) arr [i]' – MSalters

+1

@ user3667089: True, die Regex ist ziemlich einfach. Kann aber leicht so erweitert werden, dass nur einige der grundlegenden Datentypen übereinstimmen, indem Sie die Regex zu diesem ':% s/(\ (int \ | float \ | double \)) \ ([^] * \)/static_cast <\1> (\ 2)/g'. Aber froh, dass es dir auch in seiner jetzigen Form geholfen hat. – xk0der

0

Sie diese verwenden können:

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

Dies geht von einem Variablennamen aus immer ist a. Wenn dies nicht der Fall ist, können Sie a durch [a-z] ersetzen.

+0

Das Problem besteht darin, dass Sie Ausdrücke und keine Variablen umsetzen. Es gibt keinen regulären Ausdruck, der alle Ausdrücke und nur Ausdrücke erfassen kann. – MSalters

0

Ich habe mehrere Zuordnungen für diese Aufgabe in lh-cpp. In diesem Fall wird es ,,sc, oder ,,rc oder ,,dc sein. (hier ist , ist eigentlich meine <localleader>).

Es ist tatsächlich umgesetzt als:

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 

...