This is one more attempt on unifying `TMTag`s and externally provided symbols 
for the symbol tree before giving up and making the plugins create the symbol 
tree by themselves (which leads to quite a significant code duplication). This 
time (unlike the previous attempts) I'm quite happy with the result though. 
I called the new structure `GeanySymbol` - could be renamed to something else 
if someone has better idea.

The idea is to make `GeanySymbol` operate in two modes:
- either it is backed by a `TMTag` and created using `GeanySymbol 
*geany_symbol_new_from_tag(TMTag *tag)`
- or it is created by some external source such as the LSP plugin using
```C
GeanySymbol *geany_symbol_new(gchar *name, gchar *detail, gchar *scope, gchar 
*file,
        TMParserType lang, glong kind, gulong line, gulong pos, guint icon)
``` 
The corresponding structure looks this way:
```C
typedef struct GeanySymbol
{
        gchar *name;
        gchar *detail;
        gchar *scope;
        gchar *file;
        TMParserType lang;
        gulong line;
        gulong pos;
        glong kind;
        guint icon;

        TMTag *tag;

        gint refcount; /* the reference count of the symbol */
} GeanySymbol;
```
where either `tag != NULL` when using `geany_symbol_new_from_tag()`, or `tag == 
NULL` for `geany_symbol_new()`.

The important part is that the members of `GeanySymbol` cannot be accessed 
directly from other files but only using getters that either use the `tag` or 
the member of `GeanySymbol` such as
```C
const gchar *geany_symbol_get_name(const GeanySymbol *sym)
{
        if (sym->tag)
                return sym->tag->name;
        return sym->name;
}
```

By this interface, all callers like the symbol tree implementation are 
completely shielded from the details of where the symbol comes from. The bulk 
of the diffs inside `symbols.c` is pretty much just using this interface 
instead of using `TMTag` directly and renaming `tag` to `symbol`. 
`get_symbol_name()` and `get_symbol_tooltip()` were moved to `GeanySymbol` 
implementation, and also (previously inlined) 
`geany_symbol_get_name_with_scope()` was moved there too.

The additional `PluginExtension` interface for using these symbols would be 
more or less identical to what I proposed in 
https://github.com/geany/geany/pull/3850, i.e.
```C
        gboolean (*doc_symbols_provided)(GeanyDocument *doc);
        GPtrArray *(*doc_symbols_get)(GeanyDocument *doc);
```
and
- either additional `void (*doc_symbols_request)(GeanyDocument *doc, GCallback 
on_done);` in this interface making Geany request the extension for symbols 
(asynchronously)
- or some `symbol_tree_reload()` function the plugin could call which would 
make Geany re-request symbols using `doc_symbols_get()` after the plugin gets 
them e.g. from the LSP server

@b4n How does something like this sound? The implementation here is incomplete 
(only tested with the `TMTag` "backend" of `GeanySymbol`) but I 
don't want to continue in case you have some reservations regarding this 
approach.
You can view, comment on, or merge this pull request online at:

  https://github.com/geany/geany/pull/3910

-- Commit Summary --

  * Possible extension interface for symbol tree

-- File Changes --

    M meson.build (3)
    M src/Makefile.am (1)
    M src/sidebar.c (7)
    M src/sidebar.h (2)
    A src/symbol.c (341)
    A src/symbol.h (67)
    M src/symbols.c (426)
    M src/symbols.h (2)

-- Patch Links --

https://github.com/geany/geany/pull/3910.patch
https://github.com/geany/geany/pull/3910.diff

-- 
Reply to this email directly or view it on GitHub:
https://github.com/geany/geany/pull/3910
You are receiving this because you are subscribed to this thread.

Message ID: <geany/geany/pull/[email protected]>

Reply via email to