TextMate: Insert text into self.down
∞UPDATE: I got everything working and it's all packaged up here. There's an installation script this time as well.
Thanks to a helpful thread on the TextMate mailing list I have the beginning of a solution to insert text at 2 (or more) locations in a file.
I implemented this for a new snippet I was working on for migrations, rename_column
. Since the command is the same in self.up and self.down simply doing a reverse search for rename_column
in my hackish macro didn't return the cursor the desired location.
That's enough introduction, here's the program to do the insertion:
#!/usr/bin/env ruby
def indent(s)
s =~ /^(\s*)/
' ' * $1.length
end
up_line = 'rename_column "${1:table}", "${2:column}", "${3:new_name}"$0'
down_line = "rename_column \"$$1\", \"$$3\", \"$$2\"\n"
# find the end of self.down and insert 2nd line
lines = STDIN.read.to_a.reverse
ends_seen = 0
lines.each_with_index do |line, i|
ends_seen += 1 if line =~ /^\s*end\b/
if ends_seen == 2
lines[i..i] = [lines[i], indent(lines[i]) * 2 + down_line]
break
end
end
# return the new text, escaping special chars
print up_line + lines.reverse.to_s.gsub('[$`\\]', '\\\\\1').gsub('\\$\\$', '$')
Save this as a command in your Rails, or syncPeople on Rails, bundle. The command options should be as follows:
- Save: Nothing
- Input: Selected Text or Nothing
- Output: Insert as Snippet
- Activation: Whatever you want, I'm going to use a macro described below and leave this empty
- Scope Selector: source.ruby.rails
The first modification it needs is to get the lines to insert as command line arguments so we can use it for other snippets. Secondly, regardless of the Re-indent pasted text setting the text returned is indented incorrectly.
The macro I'm thinking of to invoke this is tab-triggered and will simply:
- Select word (
⌃W
) - Delete (
⌫
) - Select to end of file (
⇧⌘↓
) - Run command "Put in self.down"