Indented soft wrap


#1

I cannot find how to enable soft wrap indenting to the same level or +1 extra tab. Is it possible? If not, it would be good to add this feature.


Shifted indentation for line wrapping
Using Atom as a distraction free Outliner
Word wrap stays within tag
#2

I’m also looking for this feature. Can’t find anything about it unfortunately…


#3

Can you be more specific in what exactly it is you want? I’m not sure what you’re asking for.


#4

ok, here is how it works now (Atom):

\begin{itemize}
   \item Aaaa aaa aaa aaaaaaa aaaaaa aaaaaa aaaaaa
aaa aaaa aaaaaa aaa.
   \item Aaaa aaa aaa aaaaaaa aaaaaa aaaaaa aaaaaa
aaa aaaa aaaaaa aaa.
\end{itemize}

Here is the indented soft wrap to the same level (Textmate & Sublime Text):

\begin{itemize}
   \item Aaaa aaa aaa aaaaaaa aaaaaa aaaaaa aaaaaa
   aaa aaaa aaaaaa aaa.
   \item Aaaa aaa aaa aaaaaaa aaaaaa aaaaaa aaaaaa
   aaa aaaa aaaaaa aaa.
\end{itemize}

Here is the indented soft wrap +1 tab (Textmate):

\begin{itemize}
   \item Aaaa aaa aaa aaaaaaa aaaaaa aaaaaa aaaaaa
      aaa aaaa aaaaaa aaa.
   \item Aaaa aaa aaa aaaaaaa aaaaaa aaaaaa aaaaaa
      aaa aaaa aaaaaa aaa.
\end{itemize}

#5

Thank you, that makes much more sense.


#6

I really, really miss this feature from other text editors, it helps give me indentation context when I’m writing code.


#7

I’m certainly a big fan of this it makes wrapped text so much more readable.


#8

I agree. I just got an invite this afternoon, but the wrapping is probably the first negative thing that I noticed (compared to Textmate 2). That said, I think the designs above (i.e. soft wrap to same level or plus one tab; each being better in different contexts) cover the things I see.

This seems to bother me most in a few cases:

  • Comments that are set off with a per-line prefix get really hard to read.
  • Similarly, lists in markdown are much harder to read when the second line wraps all the way to the gutter.
  • Some code just ends up having long lines (particularly Stata; it’s not as hard-wrap friendly as, e.g., Python).

#9

Yeah, I’m a big fan of this, too. Is there any way to get it to happen in Atom?


#10

:+1: here. this is a must!


#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).