* [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