Code Completion does not work with Eigen library

General questions regarding the usage of CodeLite
ph4nt0m
CodeLite Curious
Posts: 2
Joined: Sun Jun 24, 2012 9:34 pm
Genuine User: Yes
IDE Question: C++
Contact:

Code Completion does not work with Eigen library

Post by ph4nt0m »

Hello,

I'm using CodeLite revision 5589 on Ubuntu 10.04. Code Completion (based on ctags) works really well for Qt and STL for example. But unfortunately it doesn't work with Eigen. Eigen is a header-only math library, so you don't need to compile it. I added

Code: Select all

/usr/include/eigen3
to the search paths of my workspace, which is the top folder that you can see in the attached screen shot. In my source file I #include <Eigen/Dense>, but then

Code: Select all

Eigen::Vector3d v;
is not recognized by CodeLite's completion engine ("Goto declaration" on "Vector3d" does not work for example).

It would be nice if you could help me to resolve this problem :)
    You do not have the required permissions to view the files attached to this post.
    User avatar
    eranif
    CodeLite Plugin
    Posts: 6372
    Joined: Wed Feb 06, 2008 9:29 pm
    Genuine User: Yes
    IDE Question: C++
    Contact:

    Re: Code Completion does not work with Eigen library

    Post by eranif »

    Hi,

    the way codelite searches for "included files" is currently a little bugged.

    For example, if you include a file named:

    Code: Select all

    #include <Eigen/Dense>
    and the search paths are set to point

    Code: Select all

    /usr/include/eigen3
    codelite will find this file, however the problem starts when the file itself is including another files relative to its position, in your example, Eigen/Dense includes other files:

    Code: Select all

    #include "Core"
    #include "LU"
    #include "Cholesky"
    #include "QR"
    #include "SVD"
    #include "Geometry"
    #include "Eigenvalues"
    
    so codelite will not be able to find them, since it is searching in the include paths it knows, which are: /usr/include, /usr/include/eigen3

    There is a bug for this in SF already opened.
    To fix this path problem, add /usr/include/eigen3/src as well to the include paths

    Another workaround ( a good one actually ;) ):

    Enable clang from the menu (note that you dont have to install anything, just to enable it from the menu):
    "Settings -> Tags Settings -> clang -> Enable clang code completion"
    This solved everything for me (when ctags failed to complete Vector3d, clang completed it for me)

    Another tip:
    If you computer is fast enough, remove the completion restrictions that codelite applies on code completion results to boost performance from:
    "Settings -> Tags Settings -> Display and behavior -> Number of items to display in the completion box" and change the value from 150 to 500

    and a little question:
    I installed Eigen and I managed codelite to code-complete for me, but it did not offer Vector3d...
    so I did a "find in files" and I could not find its declaration ( I did from both codelite itself and from Windows Explorer search + linux grep...) maybe you can give me a hint ;)

    Here is the output of the grep command I ran from the command line:

    Code: Select all

    root@eran-ubuntu: /tmp/eigen-eigen-ca142d0540d3 $ find . -name "*" | xargs grep --color -i -w vector3d
    ./doc/C00_QuickStartGuide.dox:Now look back at the second example program. We presented two versions of it. In the version in the left column, the matrix is of type \c MatrixXd which represents matrices of arbitrary size. The version in the right column is similar, except that the matrix is of type \c Matrix3d, which represents matrices of a fixed size (here 3-by-3). Because the type already encodes the size of the matrix, it is not necessary to specify the size in the constructor; compare <tt>MatrixXd m(3,3)</tt> with <tt>Matrix3d m</tt>. Similarly, we have \c VectorXd on the left (arbitrary size) versus \c Vector3d on the right (fixed size). Note that here the coefficients of vector \c v are directly set in the constructor, though the same syntax of the left example could be used too.
    ./doc/C00_QuickStartGuide.dox:The use of fixed-size matrices and vectors has two advantages. The compiler emits better (faster) code because it knows the size of the matrices and vectors. Specifying the size in the type also allows for more rigorous checking at compile-time. For instance, the compiler will complain if you try to multiply a \c Matrix4d (a 4-by-4 matrix) with a \c Vector3d (a vector of size 3). However, the use of many types increases compilation time and the size of the executable. The size of the matrix may also not be known at compile-time. A rule of thumb is to use fixed-size matrices for size 4-by-4 and smaller.
    ./doc/C01_TutorialMatrixClass.dox:Vector3d b(5.0, 6.0, 7.0);
    ./doc/examples/tut_arithmetic_dot_cross.cpp:  Vector3d v(1,2,3);
    ./doc/examples/tut_arithmetic_dot_cross.cpp:  Vector3d w(0,1,2);
    ./doc/examples/tut_arithmetic_add_sub.cpp:  Vector3d v(1,2,3);
    ./doc/examples/tut_arithmetic_add_sub.cpp:  Vector3d w(1,0,0);
    ./doc/examples/tut_arithmetic_scalar_mul_div.cpp:  Vector3d v(1,2,3);
    ./doc/snippets/HouseholderSequence_HouseholderSequence.cpp:Vector3d v0(1, v(1,0), v(2,0));
    ./doc/snippets/HouseholderSequence_HouseholderSequence.cpp:Vector3d v1(0, 1, v(2,1));
    ./doc/snippets/HouseholderSequence_HouseholderSequence.cpp:Vector3d v2(0, 0, 1);
    ./doc/snippets/HouseholderSequence_HouseholderSequence.cpp:Vector3d h = Vector3d::Random();
    ./doc/snippets/HouseholderSequence_HouseholderSequence.cpp:HouseholderSequence<Matrix3d, Vector3d> hhSeq(v, h);
    ./doc/snippets/MatrixBase_array.cpp:Vector3d v(1,2,3);
    ./doc/snippets/MatrixBase_isOrthogonal.cpp:Vector3d v(1,0,0);
    ./doc/snippets/MatrixBase_isOrthogonal.cpp:Vector3d w(1e-4,0,1);
    ./doc/snippets/MatrixBase_cwiseSqrt.cpp:Vector3d v(1,2,4);
    ./doc/snippets/MatrixBase_cwiseMax.cpp:Vector3d v(2,3,4), w(4,2,3);
    ./doc/snippets/MatrixBase_array_const.cpp:Vector3d v(-1,2,-3);
    ./doc/snippets/Tridiagonalization_householderCoefficients.cpp:Vector3d hc = triOfA.householderCoefficients();
    ./doc/snippets/MatrixBase_row.cpp:m.row(1) = Vector3d(4,5,6);
    ./doc/snippets/MatrixBase_cwiseMin.cpp:Vector3d v(2,3,4), w(4,2,3);
    ./doc/snippets/MatrixBase_cwiseQuotient.cpp:Vector3d v(2,3,4), w(4,2,3);
    ./doc/snippets/MatrixBase_col.cpp:m.col(1) = Vector3d(4,5,6);
    ./doc/snippets/HessenbergDecomposition_packedMatrix.cpp:Vector3d hc = hessOfA.householderCoefficients();
    ./Eigen/src/Eigen2Support/LeastSquares.h:    Vector3d points[5];
    ./Eigen/src/Eigen2Support/LeastSquares.h:    points[0] = Vector3d( 3.02, 6.89, -4.32 );
    ./Eigen/src/Eigen2Support/LeastSquares.h:    points[1] = Vector3d( 2.01, 5.39, -3.79 );
    ./Eigen/src/Eigen2Support/LeastSquares.h:    points[2] = Vector3d( 2.41, 6.01, -4.01 );
    ./Eigen/src/Eigen2Support/LeastSquares.h:    points[3] = Vector3d( 2.09, 5.55, -3.86 );
    ./Eigen/src/Eigen2Support/LeastSquares.h:    points[4] = Vector3d( 2.58, 6.32, -4.10 );
    ./Eigen/src/Eigen2Support/LeastSquares.h:    Vector3d coeffs; // will store the coefficients a, b, c
    ./unsupported/test/openglsupport.cpp:  Quaterniond qd(AngleAxisd(internal::random<double>(), Vector3d::Random()));
    ./unsupported/test/openglsupport.cpp:    Vector2d vd2; vd2.setRandom(); Vector3d vd23; vd23 << vd2, 0;
    ./unsupported/test/openglsupport.cpp:    Vector3d vd3; vd3.setRandom();
    ./unsupported/test/openglsupport.cpp:    Vector2d vd2; vd2.setRandom(); Vector3d vd23; vd23 << vd2, 1;
    ./unsupported/test/openglsupport.cpp:    Vector3d vd3; vd3.setRandom();
    ./unsupported/test/openglsupport.cpp:      typedef Vector3d Vector3d;
    ./unsupported/test/openglsupport.cpp:      VERIFY_UNIFORM(dv,v3d, Vector3d);
    ./unsupported/test/splines.cpp:    Vector3d pt = spline(u(i));
    ./unsupported/test/splines.cpp:    Vector3d pt = spline(u(i));
    ./test/nullary.cpp:    CALL_SUBTEST_6( testVectorType(Vector3d()) );
    ./test/array_for_matrix.cpp:    CALL_SUBTEST_7( lpNorm(Vector3d()) );
    ./test/commainitializer.cpp:  Vector3d vec[3];
    ./test/unalignedassert.cpp:  construct_at_boundary<Vector3d>(4);
    ./test/linearstructure.cpp:    CALL_SUBTEST_3( linearStructure(Vector3d()) );
    ./test/eigen2/eigen2_array.cpp:    CALL_SUBTEST_3( lpNorm(Vector3d()) );
    ./test/eigen2/eigen2_commainitializer.cpp:  Vector3d vec[3];
    ./test/eigen2/eigen2_linearstructure.cpp:    CALL_SUBTEST_3( linearStructure(Vector3d()) );
    ./test/array_replicate.cpp:    CALL_SUBTEST_3( replicate(Vector3d()) );
    root@eran-ubuntu: /tmp/eigen-eigen-ca142d0540d3 $
    
    Eran
    Make sure you have read the HOW TO POST thread
    User avatar
    eranif
    CodeLite Plugin
    Posts: 6372
    Joined: Wed Feb 06, 2008 9:29 pm
    Genuine User: Yes
    IDE Question: C++
    Contact:

    Re: Code Completion does not work with Eigen library

    Post by eranif »

    Nvm, I enabled clang and right clicked ' go to declaration ' and it pointed me to this line:

    src/Core/Matrix.h:

    Code: Select all

    EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<double>, cd)
    So my recommendation is: enable clang it will be very fast and accurate ;)

    Make sure you only enable the option 'Enable clang code completion'
    this will instruct codelite to use clang only when ctags fails so you will have the good of both worlds

    Here is some more info:
    http://www.codelite.org/LiteEditor/ClangIntegration35

    Eran
    Make sure you have read the HOW TO POST thread
    ph4nt0m
    CodeLite Curious
    Posts: 2
    Joined: Sun Jun 24, 2012 9:34 pm
    Genuine User: Yes
    IDE Question: C++
    Contact:

    Re: Code Completion does not work with Eigen library

    Post by ph4nt0m »

    Thank you for your answer. :D

    As you already found out, Eigen makes use of some interesting macros to define a bunch of typedefs for the most commonly used vector types. ;)

    Adding /usr/include/eigen3/Eigen/src to ctags' search paths didn't work for me. I think ctags just isn't able to translate/expand these macros, so it fails since the word "Vector3d" is not explicitly defined anywhere.

    But enabling clang did the trick. Completion works now, although it is rather slow on my (old) computer. After typing v. it needs several seconds to show the list of members. But I think this is all I can expect at the moment and since other libraries do not produce these issues (because ctags can obviously be used there), it is not that bad, really. ;)

    One more question: Is it correct that you have to enter the search paths twice, that means separately for ctags as well as for clang? Is there any situation where you would not want to enter exactly the same into both text fields?
    User avatar
    eranif
    CodeLite Plugin
    Posts: 6372
    Joined: Wed Feb 06, 2008 9:29 pm
    Genuine User: Yes
    IDE Question: C++
    Contact:

    Re: Code Completion does not work with Eigen library

    Post by eranif »

    eranif wrote: that means separately for ctags as well as for clang?
    clang only needs the paths to the 'standard' include files, like /usr/include, etc - theses are set for you by codelite.

    For the rest, codelite will take the paths from the project settings and will pass them to clang.
    In short: if your project can be compiled, clang will be able to complete for you

    Eran
    Make sure you have read the HOW TO POST thread
    Rabbit
    CodeLite Curious
    Posts: 2
    Joined: Sat Sep 10, 2011 11:42 pm
    Genuine User: Yes
    IDE Question: C++
    Contact:

    Re: Code Completion does not work with Eigen library

    Post by Rabbit »

    eranif wrote:
    eranif wrote: that means separately for ctags as well as for clang?
    clang only needs the paths to the 'standard' include files, like /usr/include, etc - theses are set for you by codelite.

    For the rest, codelite will take the paths from the project settings and will pass them to clang.
    In short: if your project can be compiled, clang will be able to complete for you

    Eran
    Related to this; does Codelite support Clang's inherent Obj-C code-completion? I've noticed that with Clang on, code completion of C functions and constructs works as expected, but Obj-C methods and classes are never suggested. I just thought this a little odd as Clang was designed with C and Obj-C as its core supported languages; my understanding of how Clang handles code completion and code suggestion is that it handles all code as Obj-C (as a strict superset of C, all valid C is valid Obj-C), so code-completion and suggestion for either language is handled through the same interface. In fact, from my understanding of how code-suggestion works with Clang: *snip*. Just looked this up; turns out clang_complete handles code suggestion as part of the same facility that handles code-completion. Instead of just returning a value that will complete what's currently being typed, it returns a value that should replace the current line.

    Of course, I haven't looked at Codelite's source so I don't know how complicated it is to handle output from Clang and to manipulate it so it's actually usable by the end user.

    From my own personal perspective, I would love it if Codelite supported Obj-C code completion. It's already the only full-fledged cross-platform IDE that supports compilation of Obj-C out of the box (CodeBlocks has to be setup first to do it); support for code-completion would make Codelite the only full-fledged cross-platform IDE that fully supports Obj-C, period. Considering that Obj-C is one of the fastest growing languages (and one many people are becoming more interested in writing cross-platform code with), I think that would give Codelite a major leg-up over other IDEs. Plus, the hardest work has already been done: the initial integration with Clang.
    User avatar
    eranif
    CodeLite Plugin
    Posts: 6372
    Joined: Wed Feb 06, 2008 9:29 pm
    Genuine User: Yes
    IDE Question: C++
    Contact:

    Re: Code Completion does not work with Eigen library

    Post by eranif »

    Rabbit wrote:I think that would give Codelite a major leg-up over other IDEs. Plus, the hardest work has already been done: the initial integration with Clang.
    IIRC, Obj-C files are suffixed with 'mm' right? try adding 'mm' to the 'C++' lexer family and see what happens (settings -> synatax highlight and fonts -> c++ -> File extensions

    It will probably fail, but there is a slight chance that something will work (you should have clang enabled)

    Eran
    Make sure you have read the HOW TO POST thread
    Rabbit
    CodeLite Curious
    Posts: 2
    Joined: Sat Sep 10, 2011 11:42 pm
    Genuine User: Yes
    IDE Question: C++
    Contact:

    Re: Code Completion does not work with Eigen library

    Post by Rabbit »

    eranif wrote:
    Rabbit wrote:I think that would give Codelite a major leg-up over other IDEs. Plus, the hardest work has already been done: the initial integration with Clang.
    IIRC, Obj-C files are suffixed with 'mm' right? try adding 'mm' to the 'C++' lexer family and see what happens (settings -> synatax highlight and fonts -> c++ -> File extensions

    It will probably fail, but there is a slight chance that something will work (you should have clang enabled)

    Eran
    The 'mm' file extension is for Obj-C++; 'm' is for plain Obj-C. I don't know if it's setup this way by default or if I did it in the past and don't remember, but both 'm' and 'mm' extensions are already set under the C++ lexer. Which reminds me: syntax-highlighting pretty much works already for Obj-C--all I had to do was add the Obj-C specific keywords to the lexer keyword set. Syntax highlighting probably works as well as it does because lexically, Obj-C is essentially the same thing as C. All it really does is add new keywords that are prefixed with '@' to define functionality, use [] brackets to send messages to objects, and self-documenting methods (the name of the method says not only what it does, but what variables go where).

    Simple example:

    Code: Select all

    main.m
    int main(int argc, char** argv)
    {
         MyObject *anObject = [[MyObject alloc] init];
        [anObject add: 15];
        [anObject subtract: 5];
    
        printf("Current Value: %d\n", [anObject value]);
        printf("Between 2 & 7? %d\n", [anObject betweenMin: 2 andMax: 7]);
    
        [anObject release];
    }
    
    MyObject.h
    @interface MyObject : ParentObject
    {
        int internalValue;
    }
    
    - (int)add:(int)aValue;
    - (int)subtract:(int)aValue;
    - (int)value;
    - (BOOL)betweenMin:(int)minValue andMax:(int)maxValue;
    
    @end
    
    MyObject.m
    @implementation
    - (int)add:(int)aValue
    {
        internalValue += aValue;
        return internalValue;
    }
    
    - (int)subtract:(int)aValue
    {
        internalValue -= aValue;
        return internalValue;
    }
    
    - (BOOL)betweenMin:(int)minValue andMax:(int)maxValue
    {
         return (internalValue > minValue) && (internalValue < maxValue);
    }
    
    - (int)value
    {
        return internalValue;
    }
    
    @end
    Post Reply