Folding: show text in place of ellipsis


#1

Hi everyone!

I am writing a package and need an ability to show some arbitrary text in place of folded code region. This text is to serve as a preview. For example:

(I obtained the second one by modifying DOM through the developer console).

As far as I know Atom’s API only allows to show ellipsis in place of a folded code region. I tried different workarounds using block/overlay decorations and direct DOM modifications from code. But these all do not play well, especially when unfolding is performed or some code around my custom foldings is folded too.
Is there any way to create such kind of foldings with preview text?


#2

Your package only has to change CSS. Add this to your styles.less and you’ll see:

span.fold-marker::before {
    content: "<A,B,C>";
}

#3

Hi, thanks for your reply! If I understand your advice correctly, it will make any foldings look like < A,B,C >… But in my package I need to show different text preview for different foldings. For example:

template<
    typename A,
    class B,
    typename C
>
class MyClass {};

template<
    typename D,
    typename E
>
class OtherClass {};

should turn to

template<A,B,C>
class MyClass {};

template<D,E>
class OtherClass {};

#4

Added a screenshot to clarify what I mean


#5

Right, and I’m not sure how you’d target specific folds, because the API doesn’t seem to support that. You might be able to use the text of the first line of the fold and the first line after it to figure out your line numbers and parse your contents from there.


#6

Parsing is performed by an external tool in my case. External tool tells me what parts of the file with source code should be folded and what the preview text should be in each part. So the question is only how to display it using Atom API.


#7

Well, you’ll still need to find the right span.fold-marker in order to manipulate its CSS.


#8

As far as I understand, we are talking about the following approach:

  1. Find span.fold-marker corresponding to folded block of code.
  2. Manipulate it to add preview text.

Actually, I have already tried to implement it that way. The problem is that out changes can be wiped out because, as I noticed, content of a text editor is re rendered under some circumstances. For instance, if we unfold line 1 in the last example, out changes are lost:

Not to mention that, as you noticed, implementation of the first step of this approach is hard. In my experiments I used MutationObserver to track editor’s DOM modifications. Of course this is a bad way to solve the problem.

So I think manipulating DOM is not a good idea at all. But maybe there are other ways?


#9

Not without an API method to let you get an object associated with the fold.

Atom does rewrite the DOM constantly. Your package would have to use editor.onDidChange() or editor.onDidStopChanging() to reapply its tweaks.


#10

I found a way to implement foldings with preview. The solution is limited, but it uses no hacks, only Atom’s API. Basically, I fold prefix of the text to make its length equal to the length of preview using TextEditor.foldSelectedLines. Then I use overlay decoration that is placed above folded text to hide it completely. Decoration contains preview text.

This is now a part of my package for folding templates in C++.