vim couldn't jump a definition navigation for template functions - vim

I have a .h file who contains these code:
template<BLA>
func1() {}
// something
template<BLA>
func2() {
func1();
}
when I typed the command GoToDefinition, the error appeared :"YCM : 'RuntimeError : can't jump to definition.'".
Do I miss something? And how to find the definition?
By the way, I have this in my .vimrc:
let g:ycm_global_ycm_extra_conf = ' ~/ycm_extra_conf.py'
**************second edit*******************
I reinstalled my YCM, and I tried ctags for YCM by this command :
ctags -R --fields=+l
It works, and thanks.

Last time I've checked, YCM understanding of a source code is restricted to one translation unit. It'll be very difficult for it to find where a function is defined as it's likely to be in another translation unit.
In other words, it should work as long as you want to jump to a definition that is in the same .cpp file as the one your are currently editing.
Thus, it should also work when trying to access to a template function definition from it's call site -- as we're supposed to include the related code. If it doesn't, it could be related to an improper understanding of the source code by clang engine YCM is using, or to YCM not configured to use clang.
Regarding tags, they could do the job, but indeed, in C++, you'll want a way to narrow the tags presented. That's what had me started lh-tags: it presents all matching tags and it permits to filter them on various criteria (filename, kind, scope, ...)

Related

Trying (and failing) to get cscope/ctags to locate C++ functions in a mixed C / C++ project

I've used both cscope and exuberant-ctags with VIM with great results on pure C projects. However, I've now moved on to a large mixed C / C++ / Java project with a lot of crufty old code and I'm trying to use cscope to gain insight into the code flow. I'm having trouble getting cscope to recognize some functions that reside in a C++ file.
For example, in this particular project, there is a C function named "verifySignature" that's defined as global. There's a different function also named "verifySignature" that's defined as a static function within a .cpp file.
When I use <ctrl-]> or <g]> in VIM, or when I use standalone cscope to find the definition, it invariably takes me to the C function even when VIM is editing the file where the static C++ function is defined (this led to profound confusion before I realized that there were two 'verifySignature' functions and I was looking at the wrong one).
When I use cscope to find functions that call 'verifySignature', it only lists the invocations of the C function. It's as if cscope is unaware of the C++ function.
However, when I use <ctrl-\ s>, or when I use standalone cscope to find the symbol, it lists both functions as well as every place where either function is called.
So it -does- know about the C++ function, it just doesn't always show it.
As another data point, I renamed the C++ function to 'verifySignature2' so that its name is unique across the codebase leaving everything else unchanged (still static, etc), rebuilt my cscope/ctags databases and searched again. This time, <ctrl-]> in VIM and 'find global definition' had no trouble finding the C++ routine.
Based on this, I'd almost be inclined to say that cscope ignores static symbols if there's a global symbol with the same name. Except I have anecdotal evidence from pure 'C' projects that that's not true. So I'm scratching my head...
I'm generating the cross reference files using the following commands:
> find . -regextype posix-extended -regex '.*\.(c|C|cpp|h|hpp|s|S|java)' > cscope.files
> usr/bin/cscope -b -q -f cscope.out
> /usr/bin/ctags --c++-kinds=+p --fields=+iaS --extra=+q -L cscope.files
Am I doing something wrong?
YouCompleteMe would also help you write code, beside navigating it with its GoTo* commands, and showing type/function/whatever signatures in a pop-up menu. You might also want to give a look at tagbar.

Can ack/ag/grep print function name?

Is it possible to print the function or class name in which a keyword occurs when using ack or ag? This is something I have highly desired for quite some time.
I think it would be quite tricky, as different programming languages have different ways of enclosing functions/classes.
Note that my goal right is for searching through C source code, however I would prefer a generic solution which covers more languages/syntax.
Author of ack here. No, I don't know of any greplike tool that understands anything about the text files that it's searching. It's something that people ask for all the time, but I've never even thought about implementing it.
You said "I think it would be quite tricky, as different programming languages have different ways of enclosing functions/classes." You're exactly right. Also, consider things like comments
/* void foo() */
and literal strings
printf( "void foo()" );
that would cause problems for any search tool. Neither of those instances of the string void foo() is actually a function declaration.
Check out the More Tools page on beyondgrep.com. Something like cscope might help you.
As commented by #Inian, it would be difficult to get a robust solution using ack, ag and grep as they are not aware of the grammar of the languages.
However, for my case of looking inside C source code files, I used ack with an OR condition to include lines which are starting with the function definitions. In my case, all my functions were either returning int or nothing. Hence, the following code printed out function definition lines alongwith the lines containing the KEYWORD:
ack 'KEYWORD|^void|^int'
Although none of the programs you listed currently have this functionality, Git uses language-based regexps to implement git grep -L (search within a function name). This blog post describes how it works. The current list of regexps are in the git source tree here, and can be extended as described in the blog above.
Also, ctags provides a universal way to enumerate tags from files of multiple languages, but I haven't (yet) found a way to integrate this output with git grep -L yet.

Vim Cmake integration

I have a cmake project. I want to do the following easily
search the declaration, definition and references of any variable, function, etc. under the cursor, which may be declared in an external header file whose path is added using INCLUDE_DIRECTORIES in CMakeLists.txt
rename a variable, function, etc. that is declared in the project
How can I set this up?
You can try to use vim plugin cmake4vim in order to integrate CMake to Vim.
This plugin helps to work with cmake targets and allows to generate compilation database file (compile_commands.json). A lot of plugins use this file for code completion, jump to definition and etc. (for example YCM)
Also you can use vim lsp plugins (for example vim-lsp) these plugins use language servers for code completion, refactoring and another good features.
But CMake project integration (cmake cache generation, project compilation, etc.) and search the declaration, definition and etc are different tasks. And different plugins and tools solve these tasks.
You can tell Vim where to look for includes by adding entries to the path option. I don't have enough experience with Cmake to know how to pull paths from CMakeLists.txt, though.
See :help 'path'.
Assuming a properly set path, it is possible to use the built-in :dsearch and related commands to search for definitions across includes.
The define option has a prescriptive name but it could be used to find any specific pattern so you could alter it to match declarations, too, or really anything.
See :help include-search and :help 'define'.
Vim has no built-in concept of "reference". :isearch and friends should work for that but they will probably be too noisy.
Renaming is usually done with something like:
:grep foo paths
:cwindow
:cdo s/foo/bar/gc
YouCompleteMe will help you. It uses compilation_database.json, witch can be generated by cmake.
This plugin also provides autocompetion for many languages.
I use functions in vim and assign them to a hotkey.
https://developer.ibm.com/tutorials/l-vim-script-2/
it gives you more an IDE feel. but at the end of the day you get a bit more control.

Is type inferred ctags jumping possible in vim?

Given the following code:
// MyClass.h
class A {
void foo();
}
class B {
void foo();
}
// MyClass.cpp
void main() {
A a();
a.foo();
}
Given that I am using vim and have my ctags generated, if I place my cursor over the foo() in main() and hit ctrl+], I will get a list of the implementations of foo, as there are more than one. If there was only one, then it would jump immediately to that implementation.
Is there a way in vim for the type of a to be inferenced such that when I hit ctrl+], it immediately jumps to the implementation of A::foo() rather than supplying me with a list of choices? It seems like such a plugin should exist and I am just unable to find it.
Update: It appears that there is currently no solution to this problem, so I have selected exclipy's answer below. Should a solution present itself and a new answer be made available, I will update the answer to this question.
What you want to do isn't possible unless Vim can actually parse the entire C++ translation unit, as a C++ compiler would. This is far beyond the scope of ctags, which uses very simple heuristics to merely tokenize the vicinity of the cursor.
So the obvious solution to this is... plug a C++ parser into Vim! There is actually a plugin called clang_complete, which already does most of the heavy lifting of hooking into the Clang C++ parser. From this base, it should be a simple matter to extend it to use the Clang API to implement jump-to-definition.
In fact, I have started working on such a feature, through two projects: clang_indexer, which crawls the source tree to build an index on disk, and my fork of clang_complete, which adds the feature of querying the index for usages of the symbol under the cursor. This is actually a bit more than what you're after because I'm aiming for a "find all references" feature (with the option of filtering the results to just definitions).
It's at a very early stage and I'm only doing it for myself, so don't expect it to be very polished solution.

LaTeX: How to find package(s) that a command belongs to?

It is a simple question to which I am not able to find the answer:
Given a LaTeX command, how do I find out what package(s) it belongs to or comes from?
For example, given the \qquad horizontal spacing command, what package does it come from? Especially troublesome since it works without including any package!
Given a LaTeX command, how do I find out what package(s) it belongs to or comes from?
Consult your references:
If it's in the index to the TeXbook, it's inherited from TeX, the engine that drives LaTeX.
Otherwise, if it's in the index to the LaTeX manual, it's probably defined in latex.ltx or in one of the standard class files, not in a package.
Otherwise, if it's in the index to The LaTeX Companion, the page number probably tells you what package it's from.
Otherwise, you could do some fancy grepping on the results of find /usr/share/texmf -name '*.sty', but be prepared for a painful exercise.
Or, you could ask on http://stackoverflow.com. But then some idiot will respond by asking why you want to know...
You can search http://www.ctan.org/tex-archive/info/symbols/comprehensive/ for that information and more.
Remember that LaTeX is a macro language on top of TeX, and all the macros are made up of TeX which doesn't need to be imported. \qquad is in that category.
As far as I know, there is no really good general answer to this. But there are a number of techniques you might try for any given command. In the case of \qquad, it's part of basic TeX. Remember that you can always use TeX in interactive mode:
$ tex '\show\qquad'
This is TeX, Version 3.141592 (Web2C 7.5.6)
> \qquad=macro:
->\hskip 2em\relax .
\show\qquad
? x
No pages of output.
Some macros are added by LaTeX on top of TeX, such as \begin:
$ tex '\show\begin'
This is TeX, Version 3.141592 (Web2C 7.5.6)
> \begin=undefined.
\show\begin
? x
No pages of output.
whereas
$ latex '\show\begin'
This is pdfTeXk, Version 3.141592-1.40.3 (Web2C 7.5.6)
%&-line parsing enabled.
entering extended mode
LaTeX2e
Babel and hyphenation patterns for english, usenglishmax, dumylang, noh
yphenation, greek, monogreek, ancientgreek, ibycus, pinyin, loaded.
> \begin=macro:
#1->\#ifundefined {#1}{\def \reserved#a {\#latex#error {Environment #1 undefine
d}\#eha }}{\def \reserved#a {\def \#currenvir {#1}\edef \#currenvline {\on#line
}\csname #1\endcsname }}\#ignorefalse \begingroup \#endpefalse \reserved#a .
\show\begin
? x
No pages of output.
Everything else comes from packages. If you really wanna know which package a macro comes from (other than by google or grepping your texmf tree), you can check after each package you load whether it's defined. Try defining this before any \usepackage commands:
\let\oldusepackage\usepackage
\renewcommand\usepackage[1]{
\oldusepackage{#1}
\ifcsname includegraphics\endcsname
\message{^^Jincludegraphics is defined in #1^^J}
\let\usepackage\oldusepackage
\fi}
Then when you run latex on your .tex file, look for a line in the output that says includegraphics is defined in graphicx. It's not likely, but some devious packages might do bad things with \usepackage so there's a chance this might not work. Another alternative would be to simply define the command you're interested in before loading any packages:
\newcommand\includegraphics{}
Then you might get an error message when the package that defines the command is loading. This is actually less reliable than the former approach, since many packages use \def and \let to define their macros rather than \newcommand, bypassing the "already-defined" check. You could also just insert a check by hand in between each load: \ifcsname includegraphics\endcsname\message{^^Jdefined after graphicx^^J}\fi
Due to lack of reputation I cannot comment on Steve's answer, which was very helpful to me, but I would like to extend it a bit.
First, in his second approach (fiddling with usepackage) the case where usepackage has optional arguments is not dealt with. Secondly, packages are often loaded by other packages via RequirePackage which makes it hard to find the actual place of definition of a command. So my refinement of Steve's answer is:
\usepackage{xargs}
\let\oldusepackage\usepackage
\let\oldRequirePackage\RequirePackage
\renewcommandx{\usepackage}[3][1,3]{
\oldusepackage[#1]{#2}[#3]
\ifcsname includegraphics\endcsname
\message{^^Jincludegraphics is defined in #2^^J}
\let\usepackage\oldusepackage
\let\RequirePackage\oldRequirePackage
\fi}
\renewcommandx{\RequirePackage}[3][1,3]{
\oldRequirePackage[#1]{#2}[#3]
\ifcsname includegraphics\endcsname
\message{^^Jincludegraphics is defined in #2^^J}
\let\usepackage\oldusepackage
\let\RequirePackage\oldRequirePackage
\fi}
The xargs package is used here to get the unusual options of usepackage right (first and third parameter are optional).
Putting this directly after documentclass should tell where includegraphics is defined.

Resources