How can I send an line in TextMate to an irb process running in an Terminal window?
Asked Answered
V

2

3

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:

  1. Copies the current selection, or if there is none, the current line.
  2. Pastes it in the topmost Terminal window that is running irb.
  3. 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?

Verada answered 24/12, 2010 at 5:23 Comment(1)
Doesn't there have to be a way to just run the code in Textmate?Colza
I
6

You must create a Bundle Command and a keyboard shortcut to do this.

  1. In TextMate go to Bundles -> Bundle Editor
  2. Create a new Command inside our own Bundle. Call it "Execute in Terminal"
  3. Set "Save" to Nothing, set "Input" to Selected Text and "or" to Line.
  4. Set "Output to Discard
  5. In "Activation" choose your own shortcut. I chose Apple Shift U
  6. Paste the command below into the "Command" box (formatting is causing me trouble)
  7. Close the Bundle Editor and then choose Bundles -> Bundle Editor -> Reload Bundles
  8. Create a new document containing the line 'puts "Hello World"'
  9. Open up IRB in Terminal
  10. Select the line you have just written in Textmate and press your keyboard shortcut.
  11. 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`
Indigent answered 28/12, 2010 at 20:16 Comment(1)
This seems so common, any idea where there's not a standard Bundle for it?Glycerin
L
0

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)

  1. Run gem install daemons
  2. Run an irb server. The file is below.
  3. In TextMate go to Bundles -> Bundle Editor
  4. Create a new Command inside our own Bundle. Call it "Execute in Terminal"
  5. Set "Save" to Nothing, set "Input" to Selected Text and "or" to Line.
  6. Set "Output to Discard
  7. In "Activation" choose your own shortcut. I chose Apple Shift U
  8. Paste the command below into the "Command" box (formatting is causing me trouble)
  9. Close the Bundle Editor and then choose Bundles -> Bundle Editor -> Reload Bundles
  10. Create a new document containing the lines @@hi = "Hello World" and @@hi + "ya"
  11. Select the first line you have just written in Textmate and press your keyboard shortcut.
  12. Do the same with the second line
  13. 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
Lagoon answered 17/12, 2011 at 12:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.