Branch: refs/heads/master Author: Jiří Techet techet@gmail.com Committer: Enrico Tröger enrico.troeger@uvena.de Date: Sun, 09 Jan 2022 22:32:40 UTC Commit: 424882040f890288e98e11e99c2adb8d1bd32a27 https://github.com/geany/geany/commit/424882040f890288e98e11e99c2adb8d1bd32a...
Log Message: ----------- Handle calltips of Python constructors like D constructors
There were two different ways of how __init__() (or this() in D) constructor calltips were attached to classes so when typing 'MyClass(' the parameters from the constructor were taken:
1. For Python, the arglist of __init__() was attached to the class and when invoking the class, the arglist was shown. The disadvantage of this approach was that it allowed attaching arglist of only one constructor but not multiple ones.
2. For D the query for the calltip was done at the runtime, searching for the constructor inside the corresponding class, allowing multiple constructor tooltips to be shown.
Since (2) allows multiple constructors, it is a better approach and can be used for Python too. In addition, this patch creates full scope of the searched constructor so it works also for deeply nested classes.
Modified Paths: -------------- src/editor.c src/tagmanager/tm_ctags.c tests/ctags/cython_sample.pyx.tags tests/ctags/py_constructor_arglist.py.tags tests/ctags/simple.py.tags
Modified: src/editor.c 17 lines changed, 12 insertions(+), 5 deletions(-) =================================================================== @@ -1850,8 +1850,6 @@ static gint find_start_bracket(ScintillaObject *sci, gint pos) static gchar *find_calltip(const gchar *word, GeanyFiletype *ft) { GPtrArray *tags; - const TMTagType arg_types = tm_tag_function_t | tm_tag_prototype_t | - tm_tag_method_t | tm_tag_macro_with_arg_t; TMTag *tag; GString *str = NULL; guint i; @@ -1868,12 +1866,21 @@ static gchar *find_calltip(const gchar *word, GeanyFiletype *ft)
tag = TM_TAG(tags->pdata[0]);
- if (ft->id == GEANY_FILETYPES_D && + if ((ft->id == GEANY_FILETYPES_D || ft->id == GEANY_FILETYPES_PYTHON) && (tag->type == tm_tag_class_t || tag->type == tm_tag_struct_t)) { + const TMTagType arg_types = tm_tag_function_t | tm_tag_prototype_t | + tm_tag_method_t | tm_tag_macro_with_arg_t; + const gchar *scope_sep = tm_parser_context_separator(ft->lang); + gchar *scope = EMPTY(tag->scope) ? g_strdup(tag->name) : + g_strjoin(scope_sep, tag->scope, tag->name, NULL); + g_ptr_array_free(tags, TRUE); - /* user typed e.g. 'new Classname(' so lookup D constructor Classname::this() */ - tags = tm_workspace_find("this", tag->name, arg_types, NULL, ft->lang); + /* user typed e.g. 'new Classname(' so lookup D constructor Classname::this() + * same for Python __init__() */ + tags = tm_workspace_find(ft->id == GEANY_FILETYPES_D ? "this" : "__init__", + scope, arg_types, NULL, ft->lang); + g_free(scope); if (tags->len == 0) { g_ptr_array_free(tags, TRUE);
Modified: src/tagmanager/tm_ctags.c 33 lines changed, 0 insertions(+), 33 deletions(-) =================================================================== @@ -154,36 +154,6 @@ static gboolean init_tag(TMTag *tag, TMSourceFile *file, const tagEntryInfo *tag }
-/* add argument list of __init__() Python methods to the class tag */ -static void update_python_arglist(const TMTag *tag, TMSourceFile *source_file) -{ - guint i; - const gchar *parent_tag_name; - - if (tag->type != tm_tag_method_t || tag->scope == NULL || - g_strcmp0(tag->name, "__init__") != 0) - return; - - parent_tag_name = strrchr(tag->scope, '.'); - if (parent_tag_name) - parent_tag_name++; - else - parent_tag_name = tag->scope; - - /* going in reverse order because the tag was added recently */ - for (i = source_file->tags_array->len; i > 0; i--) - { - TMTag *prev_tag = (TMTag *) source_file->tags_array->pdata[i - 1]; - if (g_strcmp0(prev_tag->name, parent_tag_name) == 0) - { - g_free(prev_tag->arglist); - prev_tag->arglist = g_strdup(tag->arglist); - break; - } - } -} - - static gint write_entry(tagWriter *writer, MIO * mio, const tagEntryInfo *const tag, void *user_data) { TMSourceFile *source_file = user_data; @@ -197,9 +167,6 @@ static gint write_entry(tagWriter *writer, MIO * mio, const tagEntryInfo *const return 0; }
- if (tm_tag->lang == TM_PARSER_PYTHON) - update_python_arglist(tm_tag, source_file); - g_ptr_array_add(source_file->tags_array, tm_tag);
/* output length - we don't write anything to the MIO */
Modified: tests/ctags/cython_sample.pyx.tags 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -1,5 +1,5 @@ # format=tagmanager -CDefClass�1�(self)�0 +CDefClass�1�0 StdClass�1�0 __init__�128�(self)�CDefClass�0 c_method�128�(self,int i)�CDefClass�0
Modified: tests/ctags/py_constructor_arglist.py.tags 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -3,7 +3,7 @@ HttpResponse HttpResponseBadRequest�32768�0 InterfaceDataValidationError�32768�0 RequestContext�32768�0 -SomeClass�1�(self, filename, pathsep='', treegap=64)�0 +SomeClass�1�0 __init__�128�(self, filename, pathsep='', treegap=64)�SomeClass�0 btopen�32768�0 csrf_exempt�32768�0
Modified: tests/ctags/simple.py.tags 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -14,7 +14,7 @@ even_more foo�16�(�0 ignored_function�16�()�_test�0 more_nesting�16�()�_test.ignored_function�0 -one�1�(self, filename, pathsep='', treegap=64)�0 +one�1�0 only�128�(arg)�two�0 public_function�128�(self, key)�one�0 so_is_this�1�one�0
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).