[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[sup-talk] [PATCH] mutt-style pipe to interactive process support
Adds a new method maybe_interactive_pipe_message to ThreadViewMode which will
pipe a message to a process in the same manner as the mutt mutt_pipe_message
command, allowing interactive tools such as 'urlview' to reopen the tty for
IO.
Terminating your pipe command with the pipe character ('|') for "pipe back to
sup" will use the original behavior, capturing the output of the pipeline for
display in a sup buffer. Calling maybe_interactive_pipe_message with
maybe_interactive=false, or calling pipe_message will always use the old
behavior.
No keymap is provided in this patch. It is recommended to replace pipe_message
on '|' in keybindings.rb using a line like:
Redwood::ThreadViewMode::keymap.add! :maybe_interactive_pipe_message, "Pipe
message or attachment to an interactive shell command", '|'
---
lib/sup/mode.rb | 32 ++++++++++++++++++++++++
lib/sup/modes/thread-view-mode.rb | 48 +++++++++++++++++++++++++++++-------
2 files changed, 70 insertions(+), 10 deletions(-)
diff --git a/lib/sup/mode.rb b/lib/sup/mode.rb
index f5aee1c..8d6197d 100644
--- a/lib/sup/mode.rb
+++ b/lib/sup/mode.rb
@@ -101,6 +101,38 @@ EOS
end
end
+ def pipe_to_interactive_process command
+ read, write = IO.pipe
+
+ child_pid = fork
+ if child_pid
+ # main process
+ begin
+ read.close
+ yield write
+ rescue
+ warn "error writing to #{command}: #{$!}"
+ BufferManager.flash "error writing to #{command}: #{$!}"
+ ensure
+ write.close
+ Process.waitpid(child_pid)
+ end
+ else
+ # child
+ begin
+ write.close
+ $stdin.reopen(read)
+ exec(command)
+ rescue
+ # Can't access logger from child process, but can flash an error
+ BufferManager.flash "error running #{command}: #{$!}"
+ ensure
+ read.close
+ Kernel.exit!(127)
+ end
+ end
+ end
+
def pipe_to_process command
Open3.popen3(command) do |input, output, error|
err, data, * = IO.select [error], [input], nil
diff --git a/lib/sup/modes/thread-view-mode.rb b/lib/sup/modes/thread-view-mode.rb
index 088529b..bd7908c 100644
--- a/lib/sup/modes/thread-view-mode.rb
+++ b/lib/sup/modes/thread-view-mode.rb
@@ -661,6 +661,10 @@ EOS
private :dispatch
def pipe_message
+ maybe_interactive_pipe_message false
+ end
+
+ def maybe_interactive_pipe_message maybe_interactive=true
chunk = @chunk_lines[curpos]
chunk = nil unless chunk.is_a?(Chunk::Attachment)
message = @message_lines[curpos] unless chunk
@@ -669,20 +673,44 @@ EOS
command = BufferManager.ask(:shell, "pipe command: ")
return if command.nil? || command.empty?
+ if maybe_interactive and command[-1,1]=="|"
+ command = command.chop.strip
+ return if command.empty?
+ interactive = false
+ else
+ interactive = maybe_interactive
+ end
+
+ if interactive
+ pipe_to_interactive_process(command) do |stream|
+ if chunk
+ stream.print chunk.raw_content
+ else
+ message.each_raw_message_line { |l|
+ begin
+ stream.print l
+ rescue
+ warn "error writing to #{command}: #{$!}"
+ BufferManager.flash "error writing to #{command}: #{$!}"
+ break
+ end }
+ end
+ end
+ else
+ output = pipe_to_process(command) do |stream|
+ if chunk
+ stream.print chunk.raw_content
+ else
+ message.each_raw_message_line { |l| stream.print l }
+ end
+ end
- output = pipe_to_process(command) do |stream|
- if chunk
- stream.print chunk.raw_content
+ if output
+ BufferManager.spawn "Output of '#{command}'", TextMode.new(output.ascii)
else
- message.each_raw_message_line { |l| stream.print l }
+ BufferManager.flash "'#{command}' done!"
end
end
-
- if output
- BufferManager.spawn "Output of '#{command}'", TextMode.new(output.ascii)
- else
- BufferManager.flash "'#{command}' done!"
- end
end
private
--
1.6.4.4
_______________________________________________
sup-talk mailing list
sup-talk@rubyforge.org
http://rubyforge.org/mailman/listinfo/sup-talk