Well… I don't quite love the proposed query API, but well, I don't know. But it's not too crazy -- well, not more than a DB API would be crazy at least.
But maybe you could show real use cases of why this kind of API is good and fits everyone?
Below is the python code of that I can improve with the new API. As I mentioned, the initial code causes a half-second UI lag which is unbearable. And my session doesn't even have too much tags, although I use ProjectManager to load tags for the project so it's just not open files (this is when I work on Geany, not the Linux kernel). It was under 10000 tags when I profiled the python code.
Let me describe my use case and what I found when I searched for an existing good fit.
tm_workspace_find()
which does exact match (I need prefix matching). tm_workspace_find()
is tied to the use case of finding the destination of go-to-definition/declaraitontm_workspace_find_prefix()
which dedups. I don't want deduplication. tm_workspace_find_prefix()
is tied to the use case of showing candidates in the autocomplete listtm_tag_langs_compatible()
doesn't actually look for -1. I cannot specifiy a lang in the plugin.So I thought it would be more useful to implement a generic, query interface that can be used by Geany itself and plugins, instead of adding one more special-purpose tm_workspace_find_prefix_no_dedup_no_global
function. One could also add tons of parameters to tm_workspace_find()
to make it fit, but I really liked the idea of having a dedicated C file with a generic query API more. I always care about extensibility if stuff is in the plugin API. The query API can be easily extended with more filters or other stuff without breaking existing users, which is not possible with a single, one-size-fits-all function (new stuff would require new argments, therefore an API break).
The idea is also to use query API inside geany so that tm_workspace_find*
can be removed or refactored. The API is generic enough that tm_workspace_find
, tm_workspace_find_prefix
and tm_workspace_find_scope_members
can be replaced or implemented with the query interface.
Yes, it kind of resembles a DB query. This is quite on purpose because that makes it extensible. Plus, we could probably even replace tagmanager with sqlite and without having to change this interface :-)
def search_tags2(self, prefix):
print("search_tags2")
ws = self.geany_plugin.geany_data.app.tm_workspace
q = Geany.tm_query_create(ws, Geany.TMQuerySource.SESSION_TAGS);
q.add_name(prefix, len(prefix))
return q.exec(None, None)
def search_tags(self, prefix):
if (hasattr(Geany, "tm_query_create")):
return self.search_tags2(prefix)
ret = []
# This is super slow with lots of tags. pygobject seems to call getattr()
# for all elements on the first use, regardless of how it used
array = self.geany_plugin.geany_data.app.tm_workspace.tags_array
n = tag_bisect_left(array, prefix)
for tag in array[n:]:
if (tag.name.startswith(prefix)):
ret.append(tag)
else:
break
return ret
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.