lib/sup/modes/edit_message_async_mode.rb (3220B) - raw
1 module Redwood
2
3 class EditMessageAsyncMode < LineCursorMode
4
5 HookManager.register "async-edit", <<EOS
6 Runs when 'H' is pressed in async edit mode. You can run whatever code
7 you want here - though the default case would be launching a text
8 editor. Your hook is assumed to not block, so you should use exec() or
9 fork() to launch the editor.
10
11 Once the hook has returned then sup will be responsive as usual. You will
12 still need to press 'E' to exit this buffer and send the message.
13
14 Variables:
15 file_path: The full path to the file containing the message to be edited.
16
17 Return value: None
18 EOS
19
20 register_keymap do |k|
21 k.add :run_async_hook, "Run the async-edit hook", 'H'
22 k.add :edit_finished, "Finished editing message", 'E'
23 k.add :path_to_clipboard, "Copy file path to the clipboard", :enter
24 end
25
26 def initialize parent_edit_mode, file_path, msg_subject
27 @parent_edit_mode = parent_edit_mode
28 @file_path = file_path
29 @orig_mtime = File.mtime @file_path
30
31 @text = ["ASYNC MESSAGE EDIT",
32 "", "Your message with subject:", msg_subject, "is saved in a file:", "", @file_path, "",
33 "You can edit your message in the editor of your choice and continue to",
34 "use sup while you edit your message.", "",
35 "Press <Enter> to have the file path copied to the clipboard.", "",
36 "When you have finished editing, select this buffer and press 'E'.",]
37 run_async_hook()
38 super()
39 end
40
41 def lines; @text.length end
42
43 def [] i
44 @text[i]
45 end
46
47 def killable?
48 if file_being_edited?
49 if !BufferManager.ask_yes_or_no("It appears the file is still being edited. Are you sure?")
50 return false
51 end
52 end
53
54 @parent_edit_mode.edit_message_async_resume true
55 true
56 end
57
58 def unsaved?
59 !file_being_edited? && !file_has_been_edited?
60 end
61
62 protected
63
64 def edit_finished
65 if file_being_edited?
66 if !BufferManager.ask_yes_or_no("It appears the file is still being edited. Are you sure?")
67 return false
68 end
69 end
70
71 @parent_edit_mode.edit_message_async_resume
72 BufferManager.kill_buffer buffer
73 true
74 end
75
76 def path_to_clipboard
77 if system("which xsel > /dev/null 2>&1")
78 # linux/unix path
79 IO.popen('xsel --clipboard --input', 'r+') { |clipboard| clipboard.puts(@file_path) }
80 BufferManager.flash "Copied file path to clipboard."
81 elsif system("which pbcopy > /dev/null 2>&1")
82 # mac path
83 IO.popen('pbcopy', 'r+') { |clipboard| clipboard.puts(@file_path) }
84 BufferManager.flash "Copied file path to clipboard."
85 else
86 BufferManager.flash "No way to copy text to clipboard - try installing xsel."
87 end
88 end
89
90 def run_async_hook
91 HookManager.run("async-edit", {:file_path => @file_path})
92 end
93
94 def file_being_edited?
95 # check for common editor lock files
96 vim_lock_file = File.join(File.dirname(@file_path), '.'+File.basename(@file_path)+'.swp')
97 emacs_lock_file = File.join(File.dirname(@file_path), '.#'+File.basename(@file_path))
98
99 return true if File.exist?(vim_lock_file) || File.exist?(emacs_lock_file)
100
101 false
102 end
103
104 def file_has_been_edited?
105 File.mtime(@file_path) > @orig_mtime
106 end
107
108 end
109
110 end