Explicitly splitting long lines in TextMate

This post was written on 2006/11/11 at 01:41:49 by Horst Gutmann

Sometimes, when you're just in the flow of typing text (like for a paper) you might forget about some of the personal rules you set up on how you want your textfiles formated. I, for example, prefer it, when the length of each line isn't above 78 characters. I don't really want this an automatic method for formating source code files, but at least for some LaTeX/reST/Markdown texts this would be nice. But while TextMate offers a small command in the "Text" menu to unwrap paragraphs, I didn't find anything for actually splitting (and not just softwrapping) long lines.

Not really a problem so let's write a simple command for this. And here is the result. I don't know if it works in all cases, but I tested it for situations where nothing is selected or whole lines are selected and it seems to work there.

Warning: Don't try this command when you don't have full lines selected. This command wasn't built for this and I haven't yet found a way to check what kind of stuff got selected :) And don't try it on program source code ;-)



!/usr/bin/env python

import os,sys from sys import stdout,stdin

def split_line(line,max_len,tab_size): if len(line) <= max_len: return [line,]

prefix = &apos;&apos;
prefix_length = 0
if line[0] in (&apos; &apos;,&quot;\t&quot;):
    for c in line:
        if c not in (&apos; &apos;,&quot;\t&quot;):
            break
        else:
            prefix += c
            if c == &apos;\t&apos;:
                prefix_length+=tab_size

lines = []
current_line = []
line_no = 0
words = line.split(&quot; &quot;)
chars = prefix_length
if len(words)==1:
    return [line,]
while len(words) &gt; 0:
    if (chars+len(words[0])) &lt;= max_len:
        word = words.pop(0)
        current_line.append(word)
        chars += len(word)+1
    else:
        if line_no &gt; 0:
            lines.append(&quot;%s%s&quot;%(prefix,&quot; &quot;.join(current_line)))
        else:
            lines.append(&quot; &quot;.join(current_line))
        current_line = []
        line_no+=1
        chars = prefix_length
if len(current_line) &gt; 0:
    if line_no &gt; 0:
        lines.append(&quot;%s%s&quot;%(prefix,&quot; &quot;.join(current_line)))
    else:
        lines.append(&quot; &quot;.join(current_line))
return lines

if name == 'main': max_len = int(os.getenv('TM_WRAP_LENGTH',78)) tab_size = int(os.getenv('TM_TAB_SIZE',4)) for line in stdin: stdout.write("n".join(split_line(line,max_len,tab_size)))

And here's the configuration for this command. I simply put it into a dummy bundle handling all my private extensions to the "Text" bundle ... well, actually this is the first extensions ;-)

Make a command for replacing text coming from 'selected text' or 'current line'

Warning: The usual stuff. Use this on your own risk etc.

I hope this might be useful for some of you :-)

Comments:

  • Russ Brooks (Guest)

    It believe this is built in to TextMate, Horst.

    1. Take a very long line and highlight the first 80 chars or so.

    2. Press the Option key once and release. This turns it into a column selection, but nothing apparent will change on screen.

    3. Control-Q. The line is broken up into multiple lines.

    It works if the text is indented too, whether that be Tabs or Spaces. Just begin your selection at the first non-whitespace character. The left margin it creates will be lined up with the left side of your selection.

    Nov. 24, 2009, 8:54 p.m.

  • zerok

    Thanks, but If you take a look at the date of this post you will notice that it is about 3 years old. Back then, IIRC, the behaviour of the built-in command was perhaps not really what I wanted out of it. Or it wasn't even included back then :-)

    Nov. 24, 2009, 8:59 p.m.

*'d input fields are required.