Class: RuVim::Stream::Run

Inherits:
RuVim::Stream show all
Defined in:
lib/ruvim/stream/run.rb

Instance Attribute Summary collapse

Attributes inherited from RuVim::Stream

#state, #stop_handler

Instance Method Summary collapse

Methods inherited from RuVim::Stream

#live?

Constructor Details

#initialize(command:, buffer_id:, queue:, stop_handler: nil, &notify) ⇒ Run

Returns a new instance of Run.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/ruvim/stream/run.rb', line 9

def initialize(command:, buffer_id:, queue:, stop_handler: nil, &notify)
  super(stop_handler: stop_handler)
  @command = command
  @io = nil
  @pid = nil
  @exit_status = nil
  @state = :live
  stream = self
  @thread = Thread.new do
    shell = ENV["SHELL"].to_s
    shell = "/bin/sh" if shell.empty?
    PTY.spawn(shell, "-c", command) do |r, _w, pid|
      stream.io = r
      stream.pid = pid
      begin
        while (chunk = r.readpartial(4096))
          text = Buffer.decode_text(chunk).delete("\r")
          queue << { type: :stream_data, buffer_id: buffer_id, data: text }
          notify.call
        end
      rescue EOFError, Errno::EIO
        # expected: PTY raises EIO when child process exits
      end
      _status = Process.waitpid2(pid)[1] rescue nil
      stream.io = nil
      queue << { type: :stream_eof, buffer_id: buffer_id, status: _status }
      notify.call
    end
  rescue StandardError => e
    stream.io = nil
    queue << { type: :stream_error, buffer_id: buffer_id, error: e.message.to_s }
    notify.call
  end
end

Instance Attribute Details

#commandObject

Returns the value of attribute command.



7
8
9
# File 'lib/ruvim/stream/run.rb', line 7

def command
  @command
end

#exit_statusObject

Returns the value of attribute exit_status.



7
8
9
# File 'lib/ruvim/stream/run.rb', line 7

def exit_status
  @exit_status
end

#ioObject

Returns the value of attribute io.



7
8
9
# File 'lib/ruvim/stream/run.rb', line 7

def io
  @io
end

#pidObject

Returns the value of attribute pid.



7
8
9
# File 'lib/ruvim/stream/run.rb', line 7

def pid
  @pid
end

#threadObject

Returns the value of attribute thread.



7
8
9
# File 'lib/ruvim/stream/run.rb', line 7

def thread
  @thread
end

Instance Method Details

#statusObject



44
45
46
47
48
49
50
51
52
# File 'lib/ruvim/stream/run.rb', line 44

def status
  case @state
  when :live then "run"
  when :closed
    code = @exit_status&.exitstatus
    code ? "run/exit #{code}" : "run/EOF"
  when :error then "run/error"
  end
end

#stop!Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/ruvim/stream/run.rb', line 54

def stop!
  pid = @pid; @pid = nil
  if pid
    Process.kill(:TERM, pid) rescue nil
    Process.waitpid(pid) rescue nil
  end
  io = @io; @io = nil
  begin
    io&.close unless io&.closed?
  rescue IOError
    nil
  end
  thread = @thread; @thread = nil
  if thread&.alive?
    thread.kill
    thread.join(0.05)
  end
  @state = :closed
end