Autocompleting functions based on first parameter

Hi everyone,

I am interested in improving clang's autocompletion to also suggest
free functions that can take the expression at the cursor as first
parameter, in addition to the methods its class has. I am interested
in opinions and suggestions on how to implement it.

Currently, YouCompleteMe and clang-complete, after typing (| = cursor position)

std::string str;
str.|

will suggest std::string's methods (std::string::size(),
std::string::push_back(), etc.), but not free functions such as
std::stoi, std::stod, std::hash, etc. These are operations on the
string as well, but for various reason are not members of std::string.
Adding them to the autocompletion would make them more discoverable.

When selecting a free function, eg. stoi, completion would change the
"str." line to

std::stoi(str, |

Languages such as C# have extension methods that allow keeping the
class definition smaller and have additional functionalities in
separate compilation units while still being discoverable using
autocompletion. Unfortunately there is nothing equivalent in C or C++.

This could be even more useful for C-style char*. Typing "str" and
then triggering autocompletion allows to browse a list of
string-related functions, but neither it is complete (eg. atoi won't
appear) nor contains only string-related functions (eg.
std::streambuf). Typing the argument first and then get a list of
operations might be more useful than having to know the operation
first.

Implementation

I think it is not possible to implement this in YouCompleteMe or
clang-complete only, support by clang is needed as it needs to know
the expression's and parameter's types and their conversions. After
looking at clang's C API for autocompletion that is used by
YouCompleteMe and clang-complete (clang_codeCompleteAt), I think
placing something at locations other than the cursor position or
replacing previous characters doesn't seem to be possible. That is,
there are only values in CodeCompletionString::ChunkKind that add
text, but nothing to remove, overwrite or change the cursor position.

Eg. Visual Studio can automatically replace "." and "->", depending on
whether the expression under the cursor is a class or
pointer-to-class. This seems to be impossible to implement with the
current interface.

There is also a concern that enumerating a lot of free functions could
lead to a significant delay.

Background

We are discussing a C++ interface for the Integer Set Library [1]
which would make its reference counting automatically handled by RAII
in Polly [2]. One point of discussion was whether to make C functions
members of its classes or free functions in the isl:: namespace.
Essentially, the choice between

intersect(set1, set2);

and

set1.intersect(set2);

The latter introduces an asymmetry between the arguments and raises
the question whether the method modifies the object and/or returns a
new one. It also does not do implicit conversions of the "this"
argument. On the plus side, it does not pollute the isl:: namespace,
is more object-oriented and allows browsing the interface using
code-completion. The last point would not be an issue anymore if code
completion also suggested functions.

Regards,
Michael

[1] http://isl.gforge.inria.fr/
[2] isl C++ bindings - Google Docs

Hi Michael,

I think this could be an interesting extension to the current code
completion engine.
Although I feel like sometimes it might lead to more annoying clutter that
users don't want,
so it would be a good idea to allow users to control it using some global
setting.

It certainly needs to be opt-in, even if only for the reason that it
might return new ChunkKinds the host program is not prepared for. This
could be an additional flag for CXCodeComplete_Flags. The host program
would then decide whether to expose this option to the user.

This could be even more useful for C-style char*. Typing "str" and
then triggering autocompletion allows to browse a list of
string-related functions, but neither it is complete (eg. atoi won't
appear) nor contains only string-related functions (eg.
std::streambuf). Typing the argument first and then get a list of
operations might be more useful than having to know the operation
first.

I'm not 100% convinced by the use of this feature for char * completions.
Would you suggest the free functions for char * after "." or "->" or perhaps
both?

I am not sure either. One could also add those entries if the cursor
position follows a valid expression, without an additional "." or
"->". On the other side these additional symbols would make the
intention clear to look for an operation instead of eg. a variable
name, and not clutter the normal list with additional entries. It
could also be controlled by flags.

Michael