[TxMt] Elastic tabstops

Eric Peden eric at ericpeden.com
Sat Jul 8 08:56:27 UTC 2006


On Tue, Jul 04, 2006 at 10:41:25AM +0100, Drew McLellan wrote:
>I'd like to see this as an editing mode, automatically managing real  
>tabs/spaces for me.
>
>I use tabs for aligning assignment blocks, and so often find myself  
>going back up to add extra tabs when the left side of the assignments  
>becomes longer than I expected. Example (using 4 spaces for a tab here):
>
>$a    = 'A';
>$bb   = 'B';
>$ccc  = 'C';
>
>If I were to enter a forth line with a really long variable name, I'd  
>*love* for the behaviour to be result in:
>
>$a                = 'A';
>$bb               = 'B';
>$ccc              = 'C';
>$really_long_name = 'foo';
>
>.. but for that to be done with real tabs. I think the suggested  
>convention of using a blank line to clear the alignment is a good one.

I wonder if this behavior could be done with a very fancy "Insert as
Snippet" command, similar to the technique Duane used to implement his
MASC editing[1]. In the example above if you could magically convert the
text:

  $a    = 'A';
  $bb   = 'B';
  $ccc  = 'C';

into the snippet:

  \$a${1/(.{1,4}$|.)/ /g}  = 'A';
  \$bb${1/(.{1,4}$|.)/ /g} = 'B';
  \$ccc${1/(.{1,4}$|.)/ /g}= 'C';
  ${1:\$variable} = '${2:value}';

Then you get auto-expanding columns. (Try pasting the above code into a
dummy snippet and then inserting that snippet to try it out.) The magic
number 4 in the '.{1,4}' construct is the length of the longest value in
that "field". A command to generate this snippet would need to:

* Parse the input text into fields/tab-stops.
* Find the longest length of each field/tab-stop.
* Generate placeholder substitutions for each field along the lines of
  what's given above.
* Return that text as a snippet.

I'm not sure how well the regex substitution would perform if, say,
every one of the 1000 lines in your file had several fields per line.

This replacement technique also has another annoyance: if the text
you're adding is shorter than the current field, the new field won't
get padded to the correct width. I'm not sure how to trick a regex into
*adding* characters. You could do something like:

  ${1/(...)|(..)|(.)/(1? )(2?  )(3?   )/}

but if your field is 30 characters wide you'd have to cover the 29 cases
where your new entry is shorter than that.

I also have no idea how you'd handle things like fields that spill over
onto multiple lines. Maybe this'll inspire somebody, though.

[1]: http://blog.inquirylabs.com/2006/04/25/textmate-snippets-like-youve-never-seen-them-before/

-- 
eric



More information about the textmate mailing list