Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically break comments after a certain amount of characters

Tags:

sublimetext2

Is it possible to highlight a large comment block and automatically insert breaks after a certain length?

Simple Example

# This is a super long message that has too much information in it. Although inline comments are cool, this sentence should not be this long.

After

# This is a super long message that has too much information in it.
# Although inline comments are  cool, this sentence should not be this
# long.
like image 273
Brett Hardin Avatar asked Jun 07 '13 17:06

Brett Hardin


2 Answers

Yes! And it's simpler than the length of this answer might suggest!

Background

There's a command called wrap_lines which has the capability to to exactly what you want. wrap_lines is defined in Packages/Default/paragraph.py, line 112, and is sparsely documented at the Unofficial Docs' list of commands:

wrap_lines
Wraps lines. By default, it wraps lines at the first ruler’s column.

  • width [Int]: Specifies the column at which lines should be wrapped.

wrap_lines is already accessible via the items located in the Edit -> Wrap menu. There are options to wrap the paragraph in which the cursor lies at column 70, 78, 80, 100, and 120, as well as the first ruler. By default, Wrap Paragraph at Ruler is mapped to Alt+Q on Windows and Super+Alt+Q on OSX.

Working with Rulers

What do I mean by the first ruler? You might summon a ruler via View -> Ruler, but if you want more than one on-screen (or would rather have your rulers in writing), you can add a JSON array of integers—each of which defines a ruler—to any .sublime-settings file. The array I've added to my user preferences file, for example, looks like this:

"rulers":
[
    79,
    80,
    72
],

Thanks to that first ruler rule, Alt+Q will wrap a line that's longer than 79 characters at the 79-column mark, even though there's a ruler "before" it at column 72. "First ruler" doesn't mean the leftmost ruler, but the first defined ruler. If I moved 80, to index 0 like I have below, then the lines would wrap at 80 columns instead. Likewise for 72.

"rulers":
[
    80,
    79,
    72
],

Using a Key Binding

Rulers are for the weak, you say? You can also write a new key binding to wrap a line at a column of your choice! Just add something like this to your Preferences -> Key Bindings – User file:

{ "keys": ["alt+q"], "command": "wrap_lines", "args": {"width": 80} },

Removing the args object would instead wrap at the first ruler, like the Wrap Paragraph at Ruler command does. Wrap Paragraph at Ruler is actually defined just like that in the default Windows keymap file:

{ "keys": ["alt+q"], "command": "wrap_lines" },

Caveats

One of the best (and, in some cases, worst) things about the wrap_lines command is that it will detect any sequence of non-alphanumeric characters that begins the line and duplicate it when wrapping. It's great for writing comments, since the behavior that your example suggested does indeed happen:

# This is a super long message that has too much information in it. Although inline comments are cool, this sentence should not be this long, because having to scroll to the right to finish reading a comment is really annoying!

Becomes:

# This is a super long message that has too much information in it.
# Although inline comments are cool, this sentence should not be this
# long, because having to scroll to the right to finish reading a
# comment is really annoying!

But if the line happens to start with any other symbols, like the beginning of a quote, Sublime Text doesn't know any better than to wrap those, too. So this:

# "This is a super long message that has too much information in it. Although inline comments are cool, this sentence should not be this long, because having to scroll to the right to finish reading a comment is really annoying!"

Becomes this, which we probably don't want:

# "This is a super long message that has too much information in it.
# "Although inline comments are cool, this sentence should not be this
# "long, because having to scroll to the right to finish reading a
# "comment is really annoying!"

It's a good idea to be careful with what starts your original line. Also, the wrap_lines command targets the entire paragraph that your cursor is touching, not just the current line nor, surprisingly, only the working selection. This means that you can use the command again on a newly-wrapped series of lines to re-wrap them at a different column, but you might also end up wrapping some lines that you didn't want to—like if you're aligning a paragraph under a header in Markdown:

# Hey, this header isn't really there!
Be careful with what starts the original line. Also, the `wrap_lines` command **targets the entire paragraph**, not just the current line.

If the command is activated anywhere within that block of text, you'll get this:

# Hey, this header isn't really there! Be careful with what starts the
original line. Also, the `wrap_lines` command **targets the entire
paragraph**, not just the current line.

You can avoid this sort of issue with clever use of whitespace; another empty line between the header and the paragraph itself will fix the wrapping, so:

# Hey, this header isn't really there!

Be careful with what starts the original line. Also, the `wrap_lines` command **targets the entire paragraph**, not just the current line.

Becomes:

# Hey, this header isn't really there!

Be careful with what starts the original line. Also, the
`wrap_lines` command **targets the entire paragraph**, not just
the current line.

Since the operation is so fast, you shouldn't have much trouble with tracking down the causes of any errors you encounter, starting over, and creatively avoiding them. Sublime Text usually doesn't have any trouble with mixing together comments and non-comments in code, so if you're lucky, you won't ever have to worry about it!

like image 58
angerson Avatar answered Nov 28 '22 09:11

angerson


In SublimeText3

(and any earlier versions w/regular expression support, i.e. all of them):

Here is the search/replace that inserts a newline every 48 characters:

Find:

(.{48}){1}

Replace:

\1\n

Explanation:

  • The parentheses form a group so that replace can reference matches with \1.
  • The . matches any character, and the {n} matches exactly n of them.
  • The replace command takes each match group and back-substitutes it with a newline \n appended.

Note: \1 technically refers to only the first match found, but using "replace all" handles the remaining regex matches as well).


Real-world example:

Suppose you are formatting public keys, which copied directly from a browser without the header/footer provides the following for the Google Internet Authority:

9c 2a 04 77 5c d8 50 91 3a 06 a3 82 e0 d8 50 48 bc 89 3f f1 19 70 1a 88 46 7e e0 8f c5 f1 89 ce 21 ee 5a fe 61 0d b7 32 44 89 a0 74 0b 53 4f 55 a4 ce 82 62 95 ee eb 59 5f c6 e1 05 80 12 c4 5e 94 3f bc 5b 48 38 f4 53 f7 24 e6 fb 91 e9 15 c4 cf f4 53 0d f4 4a fc 9f 54 de 7d be a0 6b 6f 87 c0 d0 50 1f 28 30 03 40 da 08 73 51 6c 7f ff 3a 3c a7 37 06 8e bd 4b 11 04 eb 7d 24 de e6 f9 fc 31 71 fb 94 d5 60 f3 2e 4a af 42 d2 cb ea c4 6a 1a b2 cc 53 dd 15 4b 8b 1f c8 19 61 1f cd 9d a8 3e 63 2b 84 35 69 65 84 c8 19 c5 46 22 f8 53 95 be e3 80 4a 10 c6 2a ec ba 97 20 11 c7 39 99 10 04 a0 f0 61 7a 95 25 8c 4e 52 75 e2 b6 ed 08 ca 14 fc ce 22 6a b3 4e cf 46 03 97 97 03 7e c0 b1 de 7b af 45 33 cf ba 3e 71 b7 de f4 25 25 c2 0d 35 89 9d 9d fb 0e 11 79 89 1e 37 c5 af 8e 72 69

After search and replace (all), you get:

9c 2a 04 77 5c d8 50 91 3a 06 a3 82 e0 d8 50 48 
bc 89 3f f1 19 70 1a 88 46 7e e0 8f c5 f1 89 ce 
21 ee 5a fe 61 0d b7 32 44 89 a0 74 0b 53 4f 55 
a4 ce 82 62 95 ee eb 59 5f c6 e1 05 80 12 c4 5e 
94 3f bc 5b 48 38 f4 53 f7 24 e6 fb 91 e9 15 c4 
cf f4 53 0d f4 4a fc 9f 54 de 7d be a0 6b 6f 87 
c0 d0 50 1f 28 30 03 40 da 08 73 51 6c 7f ff 3a 
3c a7 37 06 8e bd 4b 11 04 eb 7d 24 de e6 f9 fc 
31 71 fb 94 d5 60 f3 2e 4a af 42 d2 cb ea c4 6a 
1a b2 cc 53 dd 15 4b 8b 1f c8 19 61 1f cd 9d a8 
3e 63 2b 84 35 69 65 84 c8 19 c5 46 22 f8 53 95 
be e3 80 4a 10 c6 2a ec ba 97 20 11 c7 39 99 10 
04 a0 f0 61 7a 95 25 8c 4e 52 75 e2 b6 ed 08 ca 
14 fc ce 22 6a b3 4e cf 46 03 97 97 03 7e c0 b1 
de 7b af 45 33 cf ba 3e 71 b7 de f4 25 25 c2 0d 
35 89 9d 9d fb 0e 11 79 89 1e 37 c5 af 8e 72 69
like image 28
EntangledLoops Avatar answered Nov 28 '22 10:11

EntangledLoops