ehuss / Sublime-Wrap-Plus

Enhanced "wrap lines" command for Sublime Text 2 or 3.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Doxygen-style /// comments are not properly wrapped

gnzlbg opened this issue · comments

Doxygen style:

/* This is a doxygen style
* comment in old C-style.
*/

work fine. But the doxygen style

/// This is a doxygen
/// style multiline
/// C++ comment.

gets wrapped as:

/// This is a doxygen / style multiline
// C++ comment.

which is wrong. The expected behavior is something like:

/// This is a doxygen style multiline
/// C++ comment.

Wow, old issue! I just discovered Wrap Plus and its excellent but then I immediately tripped up on Dartdoc comments that use ///. I took a look under the hood to see what's happening. Part of the problem is that the Dart package doesn't define /// as a real comment:

<dict>
    <key>name</key>
    <string>TM_COMMENT_BLOCK_START</string>
    <key>value</key>
    <string>/// </string>
</dict>

It should really look like this:

<dict>
    <key>name</key>
    <string>TM_COMMENT_START_2</string>
    <key>value</key>
    <string>/// </string>
</dict>

Note the name change. Without this change, Wrap Plus doesn't even see the /// comment syntax.

However this upstream change isn't enough. Wrap Plus iterates over comment styles and picks the first one that matches. Since // is a prefix of ///, it will match // even if the line begins with ///.

I suppose a better behavior is to look at all comment styles and pick the longest match. Here's an example patch:

diff --git a/wrap_plus.py b/wrap_plus.py
index 49dcc4d..0fafef6 100644
--- a/wrap_plus.py
+++ b/wrap_plus.py
@@ -89,8 +89,9 @@ class PrefixStrippingView(object):
             if line_strp.startswith(start):
                 ldiff = len(line) - len(line.lstrip())
                 p = line[:ldiff+len(start)]
-                self.required_comment_prefix = p
-                break
+                if self.required_comment_prefix is None or \
+                    len(self.required_comment_prefix) < len(p):
+                    self.required_comment_prefix = p

         # TODO: re.escape required_comment_prefix.

With the upstream change to the Dart package and this short diff for Wrap Plus, I have /// comment wrapping working very nicely.

@ehuss Are you still actively working on this project? Would you like me to submit a pull request? I'd be happy to try writing a test for this, too.

I tried your patch with the current version of the Dart package (1.3.7) and it doesn't seem to help. The line comment characters are still '// ' or '//'. The comment package in sublime does not look at TM_COMMENT_BLOCK. I do not know much about how these work, but why does the Dart package not define the triple slash as TM_COMMENT_START_2?

That's odd. I'm also using Dart 1.3.7. I just tested it on this text:

/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ultricies augue a efficitur luctus.
/// 
/// Aenean fermentum consectetur lectus et sollicitudin. Vestibulum venenatis efficitur tortor nec sollicitudin.

After alt+Q, I get this (my ruler is set at 80 chars):

/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ultricies
/// augue a efficitur luctus.
/// 
/// Aenean fermentum consectetur lectus et sollicitudin. Vestibulum
/// venenatis efficitur tortor nec sollicitudin.

Why does the Dart package use the wrong name? I dunno, I opened an issue but they don't seem to think it's a problem.

Update:

I've forked Sublime Wrap Plus and Dart Sublime Bundle. If you install these two packages from my repos, you should see the fixed behavior. I'm using dart 1.12.1 now.

Before my patch:

wrap plugin does not work

After my patch:

forked plugin does work

// comments still wrap correctly. /* ... */ block comments wrap correctly in JavaScript (the Dart plugin does not support them). I hope you can reproduce this so that I can send you a PR. I think this is a safe change for you to accept.

@mehaase:
Any chance of talking you into adding support for //! style comments as used for certain Rust documentation comments?

@c0gent I think that is already covered by this change. Wrap Plus doesn't care what the comment syntax is: it gets that from the language pakcage. So if your Rust package defines //! as a comment, then my patch should wrap it correctly.

But... if you want to know for sure, try uninstalling Wrap Plus and install the patched version from my repo.

@mehaase I've got your version of wrap plus installed. Apologies for my ignorance but I'm having trouble figuring out how to get it to actually detect the additional comment character (even the /// is not working properly).

So far I've added two new lines (comment start 3 and 4) in the RustComment.JSON-tmPreferences file:

{
    "name": "Rust Comments",
    "scope": "source.rust",
    "settings": {
        "shellVariables": [{"name": "TM_COMMENT_START", "value": "// "},
                           {"name": "TM_COMMENT_START_2", "value": "/*"},
                           {"name": "TM_COMMENT_END_2", "value": "*/"},
                           {"name": "TM_COMMENT_START_3", "value": "/// "},
                           {"name": "TM_COMMENT_START_4", "value": "//! "},
                           {"name": "TM_COMMENT_DISABLE_INDENT", "value": "no"}]
    },
    "uuid": "e36d2f49-c7b0-42fe-b902-a0ed36a258ca"
}

But no change. Obviously I'm doing it wrong (more like wandering around in the dark). Having an impossible time googling anything about it. Might I impose upon you for a bit of guidance? Is there a site or page somewhere I'm not finding that explains all of this?

Edit: I failed to mention that I also added these blocks in the appropriate place in the RustComment.tmPreferences file:

            <dict>
                <key>name</key>
                <string>TM_COMMENT_START_3</string>
                <key>value</key>
                <string>/*</string>
            </dict>
            <dict>
                <key>name</key>
                <string>TM_COMMENT_START_4</string>
                <key>value</key>
                <string>*/</string>
            </dict>

@c0gent You have the right idea. I just tried it and it works for me — only after some frustrating failure.

  1. That .JSON-tmPreferences isn't a valid Sublime Text configuration, as far as I know. You want the .tmPreferences one.
  2. Not sure if you pasted the wrong snippet, but the snippet you pasted defines /* ... */ comments.

The following works for me:

        <dict>
            <key>name</key>
            <string>TM_COMMENT_START_3</string>
            <key>value</key>
            <string>/// </string>
        </dict>
        <dict>
            <key>name</key>
            <string>TM_COMMENT_START_4</string>
            <key>value</key>
            <string>//! </string>
        </dict>

However I had a hard time getting ST3 to override the Rust package with this one file. I finally unzippped the whole package, renamed it to Rust, and dropped it in ~/.config/sublime-text-3/Packages/. Then I edited RustComment.tmPreferences as described above. Then I closed ST3 and re-opened it. (I don't know if all these steps are necessary, but I was getting frustrated and tried everything I could think of.)

demo of wrapping rust comments

Wow finally success.

First I realized after you mentioned it that I had actually screwed up my <dict> sections after trying to rearrange them (was trying to put the /// and //! as ...START_1 and ...2 just as a hail mary). After fixing that, still nothing, so I did the same thing you did and just copied the loose package from the zip... Nada.

I figured I might have screwed something else up (apparently I had) so I re-downloaded it from the repo, copied it into Packages and voila. Success.

You have no idea how grateful I am for getting me going in the right direction. Doing these doc comments manually has been a nightmare!

I wish there was somewhere we could put this information to help others who may run into the same problem.

Anyway, thanks a lot.