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