Many thanks for your input. There are small errors in your post (notably segment order inversion in the linked list, the 3rd and 2nd segments are in the wrong order - the picture above that list is however correct), but it was definitely very useful to help me in the debug process.

I have understood what's happening. When toggling the -elide state of seg4 (the "text_hidden" segment), in the first iteration of the (1) loop], the lastBranchPtr is obtained by TkBTreeFindStartOfElidedRange()]. This function supposes (and checks through asserts) that the segment from which it is requested to start its search for the branch segment is elided. With the given reproducible script, at the time this gets called, that segment is not seen as elided since the elide state of the tag pertaining to this segment already has its state toggled to the desired new state (here: 0). And the assert (correctly) triggers.

I can think of at least two possible fixes:

  a.  Temporarily restore the elide state of the tag before calling TkBTreeFindStartOfElidedRange(), and do the reverse manoeuver after this call. This is already in the code] for finding the elide state of the segment predecessing the start of the considered range, that is to set the value of 'actualElided'.

  b.  Instead of starting the search for the branch segment from the first segment of the range where the elide state must be toggled, start the search from the segment that precedes it. This must work because this predecessing segment is always elided (actualElided=1) at this place of the code.

Fix a. is easy to understand, is straightforward to implement, and is safe. I have implemented it in [4bce1cc132].

Fix b. is more elegant (instead of passing <code>*firstSegPtr</code>, just pass <code>(*firstSegPtr)->prevPtr</code> to TkBTreeFindStartOfElidedRange()) but it is more difficult to do correctly since there might be cases where <code>(*firstSegPtr)->prevPtr</code> could be NULL, which would need to be handled by looking at the previous line (and what if there is no previous line, and so on). I have to think about this.

At this point, could you perhaps try fix a. and confirm whether it works in your large aplication? We could perhaps decide to be satisfied enough by this fix.