问题
I often code with a TextMate window open, and an irb process in a Terminal window adjacent to it. I want to be able to press a key sequence in TextMate which does the following:
- Copies the current selection, or if there is none, the current line.
- Pastes it in the topmost Terminal window that is running irb.
- Presses enter so that the line of code is executed in the irb window.
I used this style of interactive development when coding in R and found it very convenient. I'm pretty sure emacs and SLIME also lets you work like this. Is it possible with Ruby and TextMate?
回答1:
You must create a Bundle Command and a keyboard shortcut to do this.
- In TextMate go to Bundles -> Bundle Editor
- Create a new Command inside our own Bundle. Call it "Execute in Terminal"
- Set "Save" to Nothing, set "Input" to Selected Text and "or" to Line.
- Set "Output to Discard
- In "Activation" choose your own shortcut. I chose Apple Shift U
- Paste the command below into the "Command" box (formatting is causing me trouble)
- Close the Bundle Editor and then choose Bundles -> Bundle Editor -> Reload Bundles
- Create a new document containing the line 'puts "Hello World"'
- Open up IRB in Terminal
- Select the line you have just written in Textmate and press your keyboard shortcut.
- Watch as "Hello World" appears in IRB.
The command:
#!/usr/bin/ruby
input = STDIN.gets
`osascript << EOF
tell application "Terminal"
activate
end tell
delay 1
tell application "System Events"
keystroke "#{input.gsub('"', '\"')}"
keystroke return
end tell
EOF`
回答2:
Suppose you don't want to look over at the Terminal, but instead want the result to show up in TextMate, like in a Smalltalk workspace.
In essence, you want to run ruby within text mate, but you want variables to be remembered between executions. You can have that.
(Thanks stef for instructions on how to add a new command)
- Run
gem install daemons
- Run an irb server. The file is below.
- In TextMate go to Bundles -> Bundle Editor
- Create a new Command inside our own Bundle. Call it "Execute in Terminal"
- Set "Save" to Nothing, set "Input" to Selected Text and "or" to Line.
- Set "Output to Discard
- In "Activation" choose your own shortcut. I chose Apple Shift U
- Paste the command below into the "Command" box (formatting is causing me trouble)
- Close the Bundle Editor and then choose Bundles -> Bundle Editor -> Reload Bundles
- Create a new document containing the lines
@@hi = "Hello World"
and@@hi + "ya"
- Select the first line you have just written in Textmate and press your keyboard shortcut.
- Do the same with the second line
- Watch as "hiya" appears in text mate.
The irb server:
#!/usr/bin/env ruby -w
require 'rubygems'
require 'daemons'
require 'socket'
LARGE = 100000000
PIPE = "/tmp/.irbservepipe"
def kill_pipe
`rm -f #{PIPE}`
end
def respond_to(pipe)
inp = pipe.recv LARGE
inp.nil? and return
begin
out = eval(inp)
rescue Exception => e
out = e
end
pipe.send out.inspect, 0
end
def ensure_server
["EXIT", "INT", "HUP", "TERM"].each {|ea| trap( ea ) { kill_pipe }}
File.exists?(PIPE) and kill_pipe
server = UNIXServer.new(PIPE)
loop {
c = server.accept
respond_to c
c.close
}
end
Daemons.daemonize
ensure_server
The command:
#!/usr/bin/env macruby -w
require 'socket'
LARGE = 100000000
PIPE = "/tmp/.irbservepipe"
input = STDIN.read
socket = UNIXSocket.new(PIPE)
socket.send input, 0
puts socket.recv LARGE
来源:https://stackoverflow.com/questions/4524400/how-can-i-send-an-line-in-textmate-to-an-irb-process-running-in-an-terminal-wind