sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit 15934c136dfceebfd0b00439e8bc7f7e43b9e6ac
parent 79d16576664e81ff07372b94831d70314ebbc32e
Author: Matthieu Rakotojaona <matthieu.rakotojaona@gmail.com>
Date:   Thu, 27 Feb 2014 01:55:50 +0100

Add follow uri

Diffstat:
M lib/sup.rb | 1 +
M lib/sup/modes/thread_view_mode.rb | 44 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/lib/sup.rb b/lib/sup.rb
@@ -8,6 +8,7 @@ require 'fileutils'
 require 'locale'
 require 'ncursesw'
 require 'rmail'
+require 'uri'
 begin
   require 'fastthread'
 rescue LoadError
diff --git a/lib/sup/modes/thread_view_mode.rb b/lib/sup/modes/thread_view_mode.rb
@@ -42,6 +42,14 @@ Return value:
   None.
 EOS
 
+  HookManager.register "goto", <<EOS
+Open the uri given as a parameter.
+Variables:
+      uri: The uri
+Return value:
+  None.
+EOS
+
   register_keymap do |k|
     k.add :toggle_detailed_header, "Toggle detailed header", 'h'
     k.add :show_header, "Show full message header", 'H'
@@ -80,6 +88,8 @@ EOS
     k.add :kill_and_next, "Kill this thread, kill buffer, and view next", '&'
     k.add :toggle_wrap, "Toggle wrapping of text", 'w'
 
+    k.add :goto_uri, "Goto uri under cursor", 'g'
+
     k.add_multi "(a)rchive/(d)elete/mark as (s)pam/mark as u(N)read:", '.' do |kk|
       kk.add :archive_and_kill, "Archive this thread and kill buffer", 'a'
       kk.add :delete_and_kill, "Delete this thread and kill buffer", 'd'
@@ -722,6 +732,40 @@ EOS
     [user_labels, super].join(" -- ")
   end
 
+  def goto_uri
+    return unless (chunk = @chunk_lines[curpos]) && chunk.is_a?(Chunk::Text)
+    return unless HookManager.enabled? "goto"
+
+    # @text is a list of lines with this format:
+    # [
+    #   [[:text_color, "Some text"]]
+    #   [[:text_color, " continued here"]]
+    # ]
+
+    linetext = @text.slice(curpos, @text.length).flatten(1)
+      .take_while{|d| d[0] == :text_color and d[1].strip != ""} # Only take up to the first "" alone on its line
+      .map{|d| d[1].strip}.join("").strip
+
+
+    (linetext || "").scan(URI::regexp).each do |matches|
+      begin
+        link = $& # ruby magic: $& is the whole regexp match
+        u = URI.parse(link)
+        next unless u.absolute?
+        next unless ["http", "https"].include?(u.scheme)
+
+        reallink = Shellwords.escape(u.to_s)
+        BufferManager.flash "Going to #{reallink} ..."
+        HookManager.run "goto", :uri => reallink
+        BufferManager.completely_redraw_screen
+
+      rescue URI::InvalidURIError => e
+        debug "not a uri: #{e}"
+        # Do nothing, this is an ok flow
+      end
+    end
+  end
+
 private
 
   def initial_state_for m