Class: Controller
- Inherits:
-
Object
- Object
- Controller
- Defined in:
- lib/controller.rb
Overview
A spawned command that is controlling the terminal window,
and on request receives events (mouse buttons etc.
Instance Method Summary collapse
- #determine_shell ⇒ Object
-
#device_attr_primary ⇒ Object
Device Attributes replies.
-
#device_attr_secondary ⇒ Object
DA2 (CSI > c): terminal id 0 (VT100), firmware version, cartridge 0.
-
#device_attr_tertiary ⇒ Object
DA3 (CSI = c): DECRPTUI unit id, a DCS string (! | DDDDDDDD ST).
-
#initialize(term, config = {}) ⇒ Controller
constructor
A new instance of Controller.
- #keypress(data) ⇒ Object
- #mouse_digits(event, x, y, release) ⇒ Object
- #mouse_report(mode, event, x, y, release) ⇒ Object
- #mouse_x10(event, x, y) ⇒ Object
-
#paste(data) ⇒ Object
These are semantically different, though practically similar currently.
- #read ⇒ Object
- #report_position(x, y) ⇒ Object
- #report_size(w, h) ⇒ Object
- #run(*args) ⇒ Object
Constructor Details
#initialize(term, config = {}) ⇒ Controller
Returns a new instance of Controller.
6 7 8 9 10 |
# File 'lib/controller.rb', line 6 def initialize(term, config = {}) @term = term @config = config @shell = determine_shell end |
Instance Method Details
#determine_shell ⇒ Object
12 13 14 15 |
# File 'lib/controller.rb', line 12 def determine_shell # Try config file first, then ENV["SHELL"], then fallback to /bin/sh @config[:shell] || ENV["SHELL"] || "/bin/sh" end |
#device_attr_primary ⇒ Object
Device Attributes replies. Each query has a distinct reply type; sending the wrong type (e.g. the DA3 DCS below in answer to a DA1/DA2 query) makes hosts like tmux fail to consume it, so it leaks into the pane as visible text.
DA1 (CSI c): identify as a VT100 with Advanced Video Option.
49 50 |
# File 'lib/controller.rb', line 49 def device_attr_primary = @wr.write("\e[?1;2c") # DA2 (CSI > c): terminal id 0 (VT100), firmware version, cartridge 0. |
#device_attr_secondary ⇒ Object
DA2 (CSI > c): terminal id 0 (VT100), firmware version, cartridge 0.
51 52 |
# File 'lib/controller.rb', line 51 def device_attr_secondary = @wr.write("\e[>0;10;1c") # DA3 (CSI = c): DECRPTUI unit id, a DCS string (! | DDDDDDDD ST). |
#device_attr_tertiary ⇒ Object
DA3 (CSI = c): DECRPTUI unit id, a DCS string (! | DDDDDDDD ST).
53 |
# File 'lib/controller.rb', line 53 def device_attr_tertiary = @wr.write("\x1bP!|00000000\x1b\\") |
#keypress(data) ⇒ Object
62 |
# File 'lib/controller.rb', line 62 def keypress(data) = @wr.write(data) |
#mouse_digits(event, x, y, release) ⇒ Object
72 73 74 |
# File 'lib/controller.rb', line 72 def mouse_digits(event, x, y, release) @wr.write("\e[<#{event};#{x + 1};#{y + 1}#{release ? "m" : "M"}") end |
#mouse_report(mode, event, x, y, release) ⇒ Object
64 65 66 67 68 69 70 |
# File 'lib/controller.rb', line 64 def mouse_report(mode, event, x, y, release) case mode when :digits then mouse_digits(event, x, y, release) else # Currently only x10 mouse_x10(event, x, y) end end |
#mouse_x10(event, x, y) ⇒ Object
76 77 78 79 |
# File 'lib/controller.rb', line 76 def mouse_x10(event, x, y) raise "FIXME; untested and likely broken; Test w/htop" @wr.write("\e[M#{event.to_i.chr}#{x.chr}#{y.chr}") end |
#paste(data) ⇒ Object
These are semantically different, though practically similar currently. These are separate so they can be treated differently (bracketed etc.) in the future
61 |
# File 'lib/controller.rb', line 61 def paste(data) = @wr.write(data) |
#read ⇒ Object
36 37 38 39 40 41 |
# File 'lib/controller.rb', line 36 def read @master.read_nonblock(128) rescue IO::EAGAINWaitReadable IO.select([@master], [], [], nil) retry end |
#report_position(x, y) ⇒ Object
56 |
# File 'lib/controller.rb', line 56 def report_position(x, y) = @wr.write("\e[#{y + 1};#{x + 1}R") |
#report_size(w, h) ⇒ Object
55 |
# File 'lib/controller.rb', line 55 def report_size(w, h) = (@master.winsize = [h, w]) |
#run(*args) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/controller.rb', line 17 def run(*args) cmd = args.empty? ? @shell : [@shell, '-c', args.join(' ')] @master, @wr, @pid = *PTY.spawn(*cmd) Thread.new do loop do begin @term.write(self.read) Thread.pass rescue Errno::EIO # The child closed the pty (it exited): EIO on read is normal # here. Exit with the child's status. # FIXME: Not sure if this really belongs *here*? exit(Process.wait(@pid)) end end end end |