Archive of RubyForge sup-talk mailing list
 help / color / mirror / Atom feed
* [sup-talk] [PATCH] mutt-style pipe to interactive process support
@ 2010-06-26 16:30 Marc Hartstein
  2010-06-26 16:37 ` Marc Hartstein
  0 siblings, 1 reply; 2+ messages in thread
From: Marc Hartstein @ 2010-06-26 16:30 UTC (permalink / raw)
  To: sup-talk

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


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [sup-talk] [PATCH] mutt-style pipe to interactive process support
  2010-06-26 16:30 [sup-talk] [PATCH] mutt-style pipe to interactive process support Marc Hartstein
@ 2010-06-26 16:37 ` Marc Hartstein
  0 siblings, 0 replies; 2+ messages in thread
From: Marc Hartstein @ 2010-06-26 16:37 UTC (permalink / raw)
  To: sup-talk


[-- Attachment #1.1: Type: text/plain, Size: 771 bytes --]

Code review would be highly appreciated on this one. I did some research
and checking and I'm fairly confident that I got the multiprogramming
aspects correct, but I haven't done much with forked processes before,
so I'd appreciate another set of eyes on it.

As always, I'm receptive to style review to best integrate with the
predominant Sup programming style as well.

The primary motivation for this patch is that the one thing I've missed
most in moving from mutt is being able to use urlview to quickly open
urls in my browser. While urxvt helps me with short urls, anything
longer than my current viewport line gets broken in a way urxvt can't
detect, so I decided it was time to make the pipe command more powerful.

I've left the old code pathways fully intact.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 140 bytes --]

_______________________________________________
sup-talk mailing list
sup-talk@rubyforge.org
http://rubyforge.org/mailman/listinfo/sup-talk

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-06-26 16:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-26 16:30 [sup-talk] [PATCH] mutt-style pipe to interactive process support Marc Hartstein
2010-06-26 16:37 ` Marc Hartstein

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox