Indented soft wrap


#11

Another vote for this feature!


#12

+1. Here’s a screenshot comparing Atom (left) to ST3 (right)


#13

HTML already does this with <ul>. And atom is based on HTML5 technologies. Why can’t the editor simply internally wrap each line in a <li> and allow the display to handle itself according to user-defined CSS margins?

Then, we could have something called “advanced tab mode” where tabs could be converted to tab characters or spaces according to user preferences when the file is saved, but the editor display would work using HTML elements. Each “tab” could create a new <ul> element, and each “newline” should create a new <li> element, and the user could simply define “margin-left” however he/she wants using CSS.

If Atom already uses an HTML based rendering system, this seems quite doable.


#14

Because wrapping lines isn’t as simple as that.

If you have four spaces indent for a line that may span more that two rows, the second row, which will start at four spaces but will also wrap, may wrap at a different place than it would have with a zero spaces indent. So this is just not a question of pure display.


#15

Vote for this essential feature!


#16

Perhaps I misunderstood your reply, but I think you misunderstood my concept. I am not thinking of wrapping display lines in <li> elements, but doing so internally. Consider this html:

function foo() {
    var long_string = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.';

    var my_obj = function() {
        // Nothing much happens here;
        return;
    }
}

Not knowing how atom renders its text to chromium, I have no idea what this actually looks like, but I imagine, atom could render the text to this before sending it to chromium for display:

<li>function foo()</li>
<li>{</li>
<ul><li>var long_string = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.';</li>
</ul>
<li></li>
<ul><li>var my_obj = function() {</li>
        <ul><li>// Nothing much happens here;</li>
        <li>return;</li>
    </ul><li>}</li>
</ul><li>}</li>

Note that every real line is wrapped in an <li> element and every tab character adds another <ul> wrap.

Combined with display CSS like this:

ul {margin-left: 10px;}

we would have what we want.

In fact, we could even have the CSS read something like this:

ul.li {margin-left:15px;}
ul.li::first-line {margin-left:-5px;}

Or an even simpler approach could be had by simply replacing all “tab” characters with an element like <li class="tablevel{tablevel}"> where the CSS could specify the amount of left-margin for each tablevel.

Granted, it is more complex than my comment initially indicated, but I still think this approach could work.

I’d be interested in implementing this feature in a plugin if the text rendering can somehow be accessed by plugins.


#17

My bad, I didn’t understood at all ^^.

Ok I see your point know. But AFAIK you won’t be able to do that without braking a lot of stuff.
First it means you have to bypass almost completely the display buffer (responsible of managing on screen lines and wrapping).
By doing so you’ll also break the cursors, selections and markers, that relies on display buffer conversions methods (from buffer to screen, and from screen to buffer).

And at that point the Atom team is in the process of migrating the actual line rendering to React (which will imply a lot of changes in the API). So if you want to just hack the thing at a higher-level it will probably break at some point in the migration process (we have this kind of issues in the minimap, as we rely on how Atom build the lines HTML to avoid reinventing the wheel)

The best course of action I see is to play by the rules and trying to implement indent directly in the core, but I tried to do some TDD on that and I found that I would have to touch a lot of core classes: DisplayBuffer of course, but also TokenizedLine which provides a method to split it in two and used by the DisplayBuffer, there’s also the Editor and EditorView classes that need to take care of indents in soft-wrapped lines. And I probably didn’t see other affected classes yet.


#18

We all agree that this feature should be implemented at some point, but it isn’t a trivial fix or I’m sure someone would have made the fix by now given the amount of demand for it :grinning:


#19

@abe I’m grateful that you are looking into this. I had no idea it would be as difficult as all that. It appears that all the modern open source editors are struggling to implement this feature, as I have posted to the forums for Brackets.io and also LightTable.

The most interesting thing I have heard back from those posts has come from the LightTable forum. Apparently, LightTable is based on CodeMirror and with a small hack, CodeMirror is able to do this.

Here’s the link to the demo on the CodeMirror website:

http://codemirror.net/demo/indentwrap.html

And the relevant code in the source looks like this:

<script>
  var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
    lineNumbers: true,
    lineWrapping: true,
    mode: "text/html"
  });
  var charWidth = editor.defaultCharWidth(), basePadding = 4;
  editor.on("renderLine", function(cm, line, elt) {
    var off = CodeMirror.countColumn(line.text, null, cm.getOption("tabSize")) * charWidth;
    elt.style.textIndent = "-" + off + "px";
    elt.style.paddingLeft = (basePadding + off) + "px";
  });
  editor.refresh();
</script>

I don’t know anything about React or the Atom buffer since I’m new to Atom, but I will say that LightTable’s text rendering appears to be much faster than Atom’s and yet it relies heavily on the CodeMirror javascript backend.


#20

This is also an issue in Github, FWIW.

I’m a little surprised this isn’t already fixed. For me, I’m sticking with Sublime until Atom has this feature. Easy or hard to fix, seems like a pretty big deal (or it is to me anyway).


#21

I would also greatly appreciate this feature being implemented. I find it very difficult to visualize my code if multiple lines are not indented together. Maybe if it doesn’t come to fruition with the development team someone could create a package that would add the feature.


#22

Big +1 here. Coming from Kdevelop and miss same-level indentation sorely.


#23

Just adding my +1 for this - it is really the only thing I don’t like about Atom. I do understand the difficulty of implementing it. Whoever figures it out should get an Atom Medal of Honor…


#24

I’ll add my +1 as well. This feature would be amazing!


#25

This is currently being fixed as we speak-see:


#26

@Wliu, I updated it for you. Also see my post:


#27

I mentioned this in the comments to the merged PR (linked below), but I’m repeating it here, as there are different people in each thread.

In short, it would be really nice to have an option for specifying a hanging indent for soft-wrapped lines, like @AlexLog’s third example above.


#28

I added an issue for hanging indents for soft-wrapped lines, as suggested in the PR discussion thread. If it’s something that you’re interested in seeing, please express some support (and offer any suggestions) in the issue below.


#29

Hi, I want to check whether this is now a default feature of Atom? Actually sometimes I need an indentation just like the first example of @AlexLog, as it is the first-line indent for natural writing (e.g., for writing a documentation in plain text). Is there a way to enable such indentation? e.g., apply a negative value to soft wrap hanging indent in Atom current setting, which I tried but failed.

Thanks for anyone could help me with this issue :smile:


#30

For anyone who finds this (almost 3 years later!) because it’s high up in the search results, the Soft Wrap feature in Atom now indents the same as the original line on every wrapped line by default.

For those like me who want even more indentation on wrapped lines, you can do that, too. Just modify Settings -> Editor -> Soft Wrap Hanging Indent to the number of spaces you’d like wrapped lines to be indented (in addition to the indentation already there to match the original line). I set mine to “5” but you can do whatever you want (excluding negative numbers).