Sublime Forum

Paragraph wrap bug

#1

I’m using MultiMarkdown syntax and a ruler set at 80.

If I have a list item that is a long one, such as this:

* “Manna from Heaven” bread (¼ inch slice — contains 8 grams of protein, also counts as a protein)

then I see a bug when I try to wrap the paragraph at the ruler.

If I just put my cursor on the paragraph, but do not select any text, then invoke Wrap Paragraph at Ruler, I get this broken result (an inserted and undesired asterisk and quote at the start of the second line).

[code]* “Manna from Heaven” bread (¼ inch slice — contains 8 grams of protein,

  • "also counts as a protein)
    [/code]

But if I select the paragraph and then do Wrap Paragraph at Ruler, I get this correct result.

* “Manna from Heaven” bread (¼ inch slice — contains 8 grams of protein, also counts as a protein)

So there is some bug in the paragraph wrapping in the first case (with no selection) … perhaps the wrapping logic is trying to do something too clever??

0 Likes

Bug in paragraph.py
#2

I had the very same problem.
I fixed it by editing paragraph.py.

The prefix regexp is “^\W+”: it can be useful when the first character comments the text but it can be nasty when it is just a non alphanumeric control character such as * in Markdown lists or \ in latex for example…in that case every line gets artificially prepended with “”.

A simple fix is changing the first line of WrapLinesCommand

class WrapLinesCommand(sublime_plugin.TextCommand):
    line_prefix_pattern = re.compile(r"^\W+")

to

class WrapLinesCommand(sublime_plugin.TextCommand):
    line_prefix_pattern = re.compile(r"^\s+")

Which works in most cases. I wanted however to keep the “wrong” behaviour in the case the line is a comment.
So I changed paragraph.py again to get the expected behaviour: the prefix can contain whitespaces and optionally the single-line comment character;
to get this I added the definition

def get_linecomment(view, pt):
    shell_vars = view.meta_info("shellVariables", pt)
    if not shell_vars:
        return (], ])

    # transform the list of dicts into a single dict
    all_vars = {}
    for v in shell_vars:
        if 'name' in v and 'value' in v:
            all_vars[v['name']] = v'value']

    line_comments = ]
    block_comments = ]

    # transform the dict into a single array of valid comments
    suffixes = ""] + "_" + str(i) for i in xrange(1, 10)]
    for suffix in suffixes:
        start = all_vars.setdefault("TM_COMMENT_START" + suffix)
        end = all_vars.setdefault("TM_COMMENT_END" + suffix)
        mode = all_vars.setdefault("TM_COMMENT_MODE" + suffix)
        disable_indent = all_vars.setdefault("TM_COMMENT_DISABLE_INDENT" + suffix)

        if start:
            return start.strip()

    return ""

adapting the analogous one in comment.py and then changed few lines in WrapLinesCommand.run:

wrapper.width = width
comment = get_linecomment(self.view, s.begin())
if comment != "":
     self.line_prefix_pattern = re.compile(r"^\s*(" + re.escape(comment) + r")*\s?")
else:
     self.line_prefix_pattern = self.default_line_prefix_pattern
prefix = self.extract_prefix(s)

There’s another bug in WrapLinesCommand.run
after calculating the prefix to be repeated for every wrapped line it attempts to remove it from the text to avoid duplication

txt = self.view.substr(s)
if prefix:
    txt = txt.replace(prefix, u"")

which does not make sense: if our markdown list item the prefix is just a single space and the txt.replace removes all the spaces, not just the one at the beginning of each line of txt, i.e.:

wrapping
" * bla bla bla"
yields
" *blablabla"
even when the line needs no wrapping.

A simple fix is

if prefix:
    txt = txt.replace(prefix, u"", 1)
    txt = txt.replace('\n'+prefix, u"\n")

I hope this is helpful.

Where should I post this so that it can be considered as a fix for next release?

0 Likes

#3

You might want to try my replacement for the word-wrap command: github.com/ehuss/Sublime-Wrap-Plus
It will handle various things like bullet lists.

0 Likes

#4

[quote=“sapphirehamster”]You might want to try my replacement for the word-wrap command: github.com/ehuss/Sublime-Wrap-Plus
It will handle various things like bullet lists.[/quote]

That’s fantasic! Exactly what I needed. Thanks!


Dave

0 Likes