swyddfa / esbonio

A language server for working with Sphinx projects.
https://docs.esbon.io/
122 stars 21 forks source link

Preview does not appear to update toctree #705

Open alcarney opened 6 months ago

alcarney commented 6 months ago

I'm not entirely sure why, but for themes like furo where the documentation's toctree is rendered as a sidebar, the sidebar is not updated when documents are added to/removed from the toctree.

alcarney commented 4 months ago

Unsurprisingly, the way esbonio is running Sphinx breaks a few assumptions. For this situation in particular there are some caches that are causing Sphinx to process stale toctree data leading to the sidebars not reacting to changes being made.

The first is that on the BuildEnvironment class the top-level doctree is cached

@functools.cached_property
def master_toctree(self) -> nodes.document:
    return self.get_doctree(self.config.root_doc)

and since this field is pickled, the stale data can even persist across restarts of the Sphinx process. It should however, be simple enough to override this in the sphinx agent to be a regular @property.

The other cache is in the get_doctree() method

def get_doctree(self, docname: str) -> nodes.document:
    """Read the doctree for a file from the pickle and return it."""
    try:
        serialised = self._pickled_doctree_cache[docname]
    except KeyError:
        filename = path.join(self.doctreedir, docname + '.doctree')
        with open(filename, 'rb') as f:
            serialised = self._pickled_doctree_cache[docname] = f.read()

    doctree = pickle.loads(serialised)
    doctree.settings.env = self
    doctree.reporter = LoggingReporter(self.doc2path(docname))
    return doctree

by editing this method to not use a cache at all I can confirm this fixes the stale toctree issue, however I'm sure for larger projects this will greatly hurt performance of incremental updates.

So I expect a more elegant solution will be for the sphinx agent to clear the relevant fields from the cache when it knows a document has been updated.