2010-05-16 15 views
11

La finalización en miembros de clase que son contenedores de STL está fallando.Vim + OmniCppComplete: Completar en Miembros de clase que son contenedores de STL

La finalización en objetos locales que son contenedores STL funciona bien.

Por ejemplo, dados los siguientes archivos:

// foo.h 
#include <string> 

class foo { 
public: 
    void set_str(const std::string &); 

    std::string get_str_reverse(void); 

private: 
    std::string str; 
}; 

// foo.cpp 
#include "foo.h" 

using std::string; 

string 
foo::get_str_reverse (void) 
{ 
    string temp; 

    temp.assign(str); 
    reverse(temp.begin(), temp.end()); 

    return temp; 
}  /* ----- end of method foo::get_str ----- */ 

void 
foo::set_str (const string &s) 
{ 
    str.assign(s); 
}  /* ----- end of method foo::set_str ----- */ 

he generado las etiquetas para estos dos archivos usando:

ctags -R --c++-kinds=+pl --fields=+iaS --extra=+q . 

Cuando escribo temp. en el CPP me sale una lista de string miembro funciona como se esperaba. Pero si escribo str., omnicppcomplete escupe "Patrón no encontrado".

Me he dado cuenta de que la finalización de temp. solo funciona si tengo la declaración using std::string;.

¿Cómo puedo completar el trabajo en los miembros de mi clase que son contenedores STL?

Editar

me encontré con que la terminación de los miembros que son contenedores STL funciona si hago las modificaciones seguimiento a la cabecera:

// foo.h 
#include <string> 

using std::string; 

class foo { 
public: 
    void set_str(const string &); 

    string get_str_reverse(void); 

private: 
    string str; 
}; 

Básicamente, si añado using std::string; y luego retire la std:: nombre el calificador de espacio del miembro string str; y regenere el archivo de etiquetas, luego OmniCppComplete puede completarlo en str..

No parece importar si tengo let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"] establecido en el .vimrc.

El problema es que poner declaraciones using en los archivos de encabezado parece un gran no-no, así que estoy de vuelta al punto de partida.

+0

Lo curioso: yo probamos su prueba y para mí es exactamente lo contrario! str funciona y la temperatura no ... ¿qué versión de ctags estás utilizando por cierto? – UncleZeiv

+0

en realidad la temperatura funciona igual si lo hago ': dejar OmniCpp_DefaultNamespaces = [" std "]' – UncleZeiv

+0

@UncleZeiv: Estoy usando ctags 5.7 en Ubuntu 8.04. Descubrí que no parece importar si he configurado Default_Namespaces. Ver mi edición arriba. –

Respuesta

0

intente configurar esta variable:

let OmniCpp_NamespaceSearch=1 

Si funciona, no se olvide de ponerlo en el archivo de configuración .vimrc!

+0

Ya lo tenía encendido y no hace ninguna diferencia. –

+0

Encontré una solución si estás interesado. –

+0

¿Puedes publicarlo aquí? –

1

Me mudé recientemente a Ubuntu 10.04, que incluye ctags 5.8 y ya no tengo este problema con las clases STL como string, sin embargo, la finalización todavía no funciona con contenedores como el vector.

Este es mi viejo respuesta para ctags 5.7:

Si bien es un poco de un truco, he encontrado una solución que no contamina los archivos de cabecera con using directivas y proporciona OmniCppComplete con todo lo necesita completar miembros de la clase que son contenedores STL.

#include <string> 

#if 0 
using std::string; 
#else 
# define string std::string 
#endif 

class foo { 
public: 
    void set_str(const string &); 

    string get_str_reverse(void); 

private: 
    string str; 
}; 

#ifdef string 
# undef string 
#endif 

A continuación, modifique la línea en el archivo .vimrc que genera los ctags de la siguiente manera:

map <C-F12> :!ctags -R --c++-kinds=+pl --fields=+iaS --extra=+q --if0=yes .<CR> 

¿Cómo funciona esto? Cuando ctags ve la opción --if0=yes que tomará la rama #if 0 de la directiva de preprocesador y genera la entrada necesaria en el archivo tags:

str omnitest.h /^ string str;$/;" m class:foo access:private 

OmniCppComplete ve la falsa using std::string; y cuando no se puede encontrar una definición para que string busca en el espacio de nombre std y lo encuentra allí.

Y al compilar con g ++ la salida es lo que queremos. Esto se puede comprobar mediante la ejecución de los archivos a través del preprocesador:

$ g++ omnitest.cpp -E | less 

Al final se verá:

# 2 "omnitest.h" 2 

class foo { 
public: 
    void set_str(const std::string &); 

    std::string get_str_reverse(void); 

private: 
    std::string str; 
}; 
# 2 "omnitest.cpp" 2 

using std::string; 

string foo::get_str_reverse (void) 
{ 
    string temp; 

    temp.assign(str); 
    reverse(temp.begin(), temp.end()); 

    return temp; 
} 

void foo::set_str (const string &s) 
{ 
    str.assign(s); 
} 

Así, por ejemplo, si escribo this->str. en una de las funciones miembro ya! me da una lista de miembros de cadenas para completar.

Esta técnica se puede utilizar para cualquier conjunto de contenedores STL e incluso se puede automatizar para modificar el encabezado al registrarse o salir de un repositorio de Subversion usando un script Perl.

De esa manera sus compañeros no tienen que ver sus hacks feo :-)

+0

bueno ... ¡realmente es un hack terrible! :) A menudo uso #if 0 para comentar cosas así que no usaría esa definición particular. Aparte de eso, me alegra que hayas encontrado una solución que te convenga, pero aún me pregunto por qué no puedo reproducir tu error ... si tengo otras ideas de lo que podría estar mal en tu entorno, te lo haré saber :) – UncleZeiv

Cuestiones relacionadas