sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit 43a80cf28a6cd50942dcd19e5a0fb43243d4c331
parent 0cebe2e868771a1b064f44094a0a29fcf4eaac9b
Author: Hamish Downer <dmishd@gmail.com>
Date:   Tue, 15 Feb 2011 23:17:39 +0000

Async edit mode sort-of works

You can edit a message in an external editor, and then go back to sup
and have your changes picked up by the edit-mode, but the buffer
management still leaves something to be desired.

Diffstat:
M lib/sup.rb | 1 +
M lib/sup/modes/edit-message-async-mode.rb | 103 +++++++++++++++++++++++++------------------------------------------------------
M lib/sup/modes/edit-message-mode.rb | 21 +++++++++++++++------
3 files changed, 49 insertions(+), 76 deletions(-)
diff --git a/lib/sup.rb b/lib/sup.rb
@@ -370,6 +370,7 @@ require "sup/horizontal-selector"
 require "sup/modes/line-cursor-mode"
 require "sup/modes/help-mode"
 require "sup/modes/edit-message-mode"
+require "sup/modes/edit-message-async-mode"
 require "sup/modes/compose-mode"
 require "sup/modes/resume-mode"
 require "sup/modes/forward-mode"
diff --git a/lib/sup/modes/edit-message-async-mode.rb b/lib/sup/modes/edit-message-async-mode.rb
@@ -1,40 +1,22 @@
-# edit-message-async-mode
-#
-<<<<<<< HEAD
+require 'thread'
+
 module Redwood
 
 class EditMessageAsyncMode < LineCursorMode
-  # TODO:
-  #
-  # * set up keymap - just X to say you're done
-  attr_reader :status
-  bool_reader :edited
 
   register_keymap do |k|
     k.add :edit_finished, "Finished editing message", 'E'
   end
-=======
-
-class EditMessageAsyncMode < Mode
-  # TODO:
-  #
-  # * set up keymap - just X to say you're done
 
-  # * generate buffer text
-  # * override mode bits - killable etc.
->>>>>>> 5222f0defb5bcf3752ac3a59ad1ea60ecfa0e82e
-
-  # * initialize function - need
-  # ** file path
-  # ** info to restart edit mode it started in
-<<<<<<< HEAD
-  def initialize file_path, title, finish_condition
+  def initialize parent_edit_mode, file_path
+    @parent_edit_mode = parent_edit_mode
     @file_path = file_path
-    @finish_condition = finish_condition
-    @title = title
     
-    @text = []
-    super {}
+    @text = ["Your message is saved in a file:", "", @file_path, "", 
+             "You can edit your message in the editor of your choice and continue to",
+             "use sup while you edit your message.", "",
+             "When you have finished editing, select this buffer and press 'E'.",]
+    super() 
   end
 
   def lines; @text.length end
@@ -43,60 +25,41 @@ class EditMessageAsyncMode < Mode
     @text[i]
   end
 
-protected
-  # * override mode bits - killable etc.
+  def killable?
+    !file_being_edited?
+  end
 
-  def edit_finished
-=======
-  def initialize
+  def unsaved?
+    !file_being_edited?
   end
 
+protected
+
   def edit_finished
-    #
->>>>>>> 5222f0defb5bcf3752ac3a59ad1ea60ecfa0e82e
-    # We need a edit_message_async_resume method, but maybe that 
-    # should be in another mode?? The below code should run in it
- 
-    # first make sure any external editor has exited
-<<<<<<< HEAD
-    File.open(@file_path, 'r') { |f|
-      if !f.flock(File::LOCK_EX|File::LOCK_NB)
-        # ask user to check that any editor of that file has exited
-        # press E again when they are ready
-        return false
-      end
-    }
-    # now we resume no matter what
-    # first we send the signal to the buffer that killed us
-    # then we kill ourselves
+    if file_being_edited?
+      BufferManager.flash "Please check that #{@file_path} is not open in any editor and try again"
+      return false
+    end
+
+    @parent_edit_mode.edit_message_async_resume
     BufferManager.kill_buffer buffer
   end
 
-  # this will be called if <Enter> is pressed
+  def file_being_edited?
+    begin
+      File.open(@file_path, 'r') { |f|
+        return true if !f.flock(File::LOCK_EX|File::LOCK_NB)
+      }
+    rescue
+      return true
+    end
+    false
+  end
+
   # nothing useful to do, so make it a no-op until we think of something better
-  # to do ...
   def select
     nil
   end
 end
 
-=======
-    File.open(@file.path, 'r') { |f|
-      while !f.flock(File::LOCK_EX|File::LOCK_NB)
-        # ask user to check that any editor of that file has exited
-        # press enter when ready to continue
-      end
-    }
-    @edited = true if File.mtime(@file.path) > @mtime
-
-    return @edited unless @edited
-
-    header, @body = parse_file @file.path
-    @header = header - NON_EDITABLE_HEADERS
-    handle_new_text @header, @body
-    update
-
-    @edited
-  end
->>>>>>> 5222f0defb5bcf3752ac3a59ad1ea60ecfa0e82e
 end
diff --git a/lib/sup/modes/edit-message-mode.rb b/lib/sup/modes/edit-message-mode.rb
@@ -1,6 +1,7 @@
 require 'tempfile'
 require 'socket' # just for gethostname!
 require 'pathname'
+require 'thread'
 
 module Redwood
 
@@ -80,7 +81,7 @@ EOS
     k.add :edit_cc, "Edit Cc:", 'c'
     k.add :edit_subject, "Edit Subject", 's'
     k.add :edit_message, "Edit message", :enter
-    k.add :edit_message_async, "Edit message asynchronously", 'X'
+    k.add :edit_message_async, "Edit message asynchronously", 'E'
     k.add :save_as_draft, "Save as draft", 'P'
     k.add :attach_file, "Attach a file", 'a'
     k.add :delete_attachment, "Delete an attachment", 'd'
@@ -193,15 +194,20 @@ EOS
     @file.close
 
     @mtime = File.mtime @file.path
-    
+
     # put up buffer saying you can now edit the message in another
     # terminal or app, and continue to use sup in the meantime.
-    # When you are done, navigate back to this buffer and press
-    # X to resume
-    mode = EditMessageAsync.new @file.path, condition_var
-    BufferManager.spawn "Waiting for message \"#{m.subj}\" to be finished", mode
+    @async_mode = EditMessageAsyncMode.new self, @file.path
+    BufferManager.spawn "Waiting for message \"#{@header["Subject"]}\" to be finished", @async_mode
 
     # hide ourselves, and wait for signal to resume from async mode ...
+    buffer.hidden = true
+  end
+
+  def edit_message_async_resume
+    buffer.hidden = false
+    @async_mode = nil
+    BufferManager.focus_on buffer
 
     @edited = true if File.mtime(@file.path) > @mtime
 
@@ -216,6 +222,9 @@ EOS
   end
 
   def killable?
+    if !@async_mode.nil?
+      return false if @async_mode.killable?
+    end
     !edited? || BufferManager.ask_yes_or_no("Discard message?")
   end