diakonos 0.8.6 → 0.8.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,18 +7,18 @@ module Diakonos
7
7
  end
8
8
 
9
9
  def [] ( arg )
10
- return @clips[ arg ]
10
+ @clips[ arg ]
11
11
  end
12
12
 
13
13
  def clip
14
- return @clips[ 0 ]
14
+ @clips[ 0 ]
15
15
  end
16
16
 
17
17
  # text is an array of Strings
18
18
  # Returns true iff a clip was added,
19
19
  # and only non-nil text can be added.
20
20
  def addClip( text )
21
- return false if text == nil
21
+ return false if text.nil?
22
22
  @clips.unshift text
23
23
  @clips.pop if @clips.length > @max_clips
24
24
  true
@@ -40,7 +40,7 @@ module Diakonos
40
40
  last_clip = @clips[ 0 ]
41
41
  last_clip.pop if last_clip[ -1 ] == ""
42
42
  @clips[ 0 ] = last_clip + text
43
- return true
43
+ true
44
44
  end
45
45
  end
46
46
 
@@ -0,0 +1,304 @@
1
+ module Diakonos
2
+
3
+ BOL_ZERO = 0
4
+ BOL_FIRST_CHAR = 1
5
+ BOL_ALT_ZERO = 2
6
+ BOL_ALT_FIRST_CHAR = 3
7
+
8
+ EOL_END = 0
9
+ EOL_LAST_CHAR = 1
10
+ EOL_ALT_END = 2
11
+ EOL_ALT_LAST_CHAR = 3
12
+
13
+ class Diakonos
14
+ attr_reader :token_regexps, :close_token_regexps, :token_formats, :diakonos_conf
15
+
16
+ def fetch_conf( location = "v#{VERSION}" )
17
+ require 'open-uri'
18
+ found = false
19
+ puts "Fetching configuration from #{location}..."
20
+
21
+ begin
22
+ open( "http://github.com/Pistos/diakonos/tree/#{location}/diakonos.conf?raw=true" ) do |http|
23
+ text = http.read
24
+ if text =~ /key/ and text =~ /colour/ and text =~ /lang/
25
+ found = true
26
+ File.open( @diakonos_conf, 'w' ) do |f|
27
+ f.puts text
28
+ end
29
+ end
30
+ end
31
+ rescue OpenURI::HTTPError => e
32
+ $stderr.puts "Failed to fetch from #{location}."
33
+ end
34
+
35
+ found
36
+ end
37
+
38
+ def loadConfiguration
39
+ # Set defaults first
40
+
41
+ existent = 0
42
+ conf_dirs = [
43
+ '/usr/local/etc/diakonos.conf',
44
+ '/usr/etc/diakonos.conf',
45
+ '/etc/diakonos.conf',
46
+ '/usr/local/share/diakonos/diakonos.conf',
47
+ '/usr/share/diakonos/diakonos.conf'
48
+ ]
49
+
50
+ conf_dirs.each do |conf_dir|
51
+ @global_diakonos_conf = conf_dir
52
+ if FileTest.exists? @global_diakonos_conf
53
+ existent += 1
54
+ break
55
+ end
56
+ end
57
+
58
+ @diakonos_conf = ( @config_filename or ( @diakonos_home + '/diakonos.conf' ) )
59
+ existent += 1 if FileTest.exists? @diakonos_conf
60
+
61
+ if existent < 1
62
+ if @testing
63
+ File.open( @diakonos_conf, 'w' ) do |f|
64
+ f.puts File.read( './diakonos.conf' )
65
+ end
66
+ else
67
+ puts "diakonos.conf not found in any of:"
68
+ conf_dirs.each do |conf_dir|
69
+ puts " #{conf_dir}"
70
+ end
71
+ puts " ~/.diakonos/"
72
+ puts "At least one configuration file must exist."
73
+ $stdout.puts "Would you like to download one right now from the Diakonos repository? (y/n)"; $stdout.flush
74
+ answer = $stdin.gets
75
+
76
+ case answer
77
+ when /^y/i
78
+ if not fetch_conf
79
+ fetch_conf 'master'
80
+ end
81
+ end
82
+ end
83
+
84
+ if not FileTest.exists?( @diakonos_conf )
85
+ puts "Terminating..."
86
+ exit 1
87
+ end
88
+ end
89
+
90
+ @logfilename = @diakonos_home + "/diakonos.log"
91
+ @keychains = Hash.new
92
+ @token_regexps = Hash.new
93
+ @close_token_regexps = Hash.new
94
+ @token_formats = Hash.new
95
+ @indenters = Hash.new
96
+ @unindenters = Hash.new
97
+ @filemasks = Hash.new
98
+ @bangmasks = Hash.new
99
+ @closers = Hash.new
100
+
101
+ @settings = Hash.new
102
+ # Setup some defaults
103
+ @settings[ "context.format" ] = Curses::A_REVERSE
104
+
105
+ @keychains[ Curses::KEY_RESIZE ] = [ "redraw", nil ]
106
+ @keychains[ RESIZE2 ] = [ "redraw", nil ]
107
+
108
+ @colour_pairs = Array.new
109
+
110
+ begin
111
+ parseConfigurationFile( @global_diakonos_conf )
112
+ parseConfigurationFile( @diakonos_conf )
113
+
114
+ # Session settings override config file settings.
115
+
116
+ @session[ 'settings' ].each do |key,value|
117
+ @settings[ key ] = value
118
+ end
119
+
120
+ @clipboard = Clipboard.new @settings[ "max_clips" ]
121
+ @log = File.open( @logfilename, "a" )
122
+
123
+ if @buffers
124
+ @buffers.each_value do |buffer|
125
+ buffer.configure
126
+ end
127
+ end
128
+ rescue Errno::ENOENT
129
+ # No config file found or readable
130
+ end
131
+ end
132
+
133
+ def parseConfigurationFile( filename )
134
+ return if not FileTest.exists? filename
135
+
136
+ lines = IO.readlines( filename ).collect { |l| l.chomp }
137
+ lines.each do |line|
138
+ # Skip comments
139
+ next if line[ 0 ] == ?#
140
+
141
+ command, arg = line.split( /\s+/, 2 )
142
+ next if command.nil?
143
+ command = command.downcase
144
+ case command
145
+ when "include"
146
+ parseConfigurationFile arg.subHome
147
+ when "key"
148
+ if arg
149
+ if / / === arg
150
+ keystrings, function_and_args = arg.split( / {2,}/, 2 )
151
+ else
152
+ keystrings, function_and_args = arg.split( /;/, 2 )
153
+ end
154
+ keystrokes = Array.new
155
+ keystrings.split( /\s+/ ).each do |ks_str|
156
+ code = ks_str.keyCode
157
+ if code
158
+ keystrokes.concat code
159
+ else
160
+ puts "unknown keystring: #{ks_str}"
161
+ end
162
+ end
163
+ if function_and_args.nil?
164
+ @keychains.deleteKeyPath( keystrokes )
165
+ else
166
+ function, function_args = function_and_args.split( /\s+/, 2 )
167
+ @keychains.setKeyPath(
168
+ keystrokes,
169
+ [ function, function_args ]
170
+ )
171
+ end
172
+ end
173
+ when /^lang\.(.+?)\.tokens\.([^.]+)(\.case_insensitive)?$/
174
+ getTokenRegexp( @token_regexps, arg, Regexp.last_match )
175
+ when /^lang\.(.+?)\.tokens\.([^.]+)\.open(\.case_insensitive)?$/
176
+ getTokenRegexp( @token_regexps, arg, Regexp.last_match )
177
+ when /^lang\.(.+?)\.tokens\.([^.]+)\.close(\.case_insensitive)?$/
178
+ getTokenRegexp( @close_token_regexps, arg, Regexp.last_match )
179
+ when /^lang\.(.+?)\.tokens\.(.+?)\.format$/
180
+ language = $1
181
+ token_class = $2
182
+ @token_formats[ language ] = ( @token_formats[ language ] or Hash.new )
183
+ @token_formats[ language ][ token_class ] = arg.toFormatting
184
+ when /^lang\.(.+?)\.format\..+$/
185
+ @settings[ command ] = arg.toFormatting
186
+ when /^colou?r$/
187
+ number, fg, bg = arg.split( /\s+/ )
188
+ number = number.to_i
189
+ fg = fg.toColourConstant
190
+ bg = bg.toColourConstant
191
+ @colour_pairs << {
192
+ :number => number,
193
+ :fg => fg,
194
+ :bg => bg
195
+ }
196
+ when /^lang\.(.+?)\.indent\.indenters(\.case_insensitive)?$/
197
+ case_insensitive = ( $2 != nil )
198
+ if case_insensitive
199
+ @indenters[ $1 ] = Regexp.new( arg, Regexp::IGNORECASE )
200
+ else
201
+ @indenters[ $1 ] = Regexp.new arg
202
+ end
203
+ when /^lang\.(.+?)\.indent\.unindenters(\.case_insensitive)?$/
204
+ case_insensitive = ( $2 != nil )
205
+ if case_insensitive
206
+ @unindenters[ $1 ] = Regexp.new( arg, Regexp::IGNORECASE )
207
+ else
208
+ @unindenters[ $1 ] = Regexp.new arg
209
+ end
210
+ when /^lang\.(.+?)\.indent\.preventers(\.case_insensitive)?$/,
211
+ /^lang\.(.+?)\.indent\.ignore(\.case_insensitive)?$/,
212
+ /^lang\.(.+?)\.context\.ignore(\.case_insensitive)?$/
213
+ case_insensitive = ( $2 != nil )
214
+ if case_insensitive
215
+ @settings[ command ] = Regexp.new( arg, Regexp::IGNORECASE )
216
+ else
217
+ @settings[ command ] = Regexp.new arg
218
+ end
219
+ when /^lang\.(.+?)\.filemask$/
220
+ @filemasks[ $1 ] = Regexp.new arg
221
+ when /^lang\.(.+?)\.bangmask$/
222
+ @bangmasks[ $1 ] = Regexp.new arg
223
+ when /^lang\.(.+?)\.closers\.(.+?)\.(.+?)$/
224
+ @closers[ $1 ] ||= Hash.new
225
+ @closers[ $1 ][ $2 ] ||= Hash.new
226
+ @closers[ $1 ][ $2 ][ $3.to_sym ] = case $3
227
+ when 'regexp'
228
+ Regexp.new arg
229
+ when 'closer'
230
+ begin
231
+ eval( "Proc.new " + arg )
232
+ rescue Exception => e
233
+ showException(
234
+ e,
235
+ [
236
+ "Failed to process Proc for #{command}.",
237
+ ]
238
+ )
239
+ end
240
+ end
241
+ when "context.visible", "context.combined", "eof_newline", "view.nonfilelines.visible",
242
+ /^lang\.(.+?)\.indent\.(?:auto|roundup|using_tabs|closers)$/,
243
+ "found_cursor_start", "convert_tabs", 'delete_newline_on_delete_to_eol',
244
+ 'suppress_welcome', 'strip_trailing_whitespace_on_save',
245
+ 'find.return_on_abort', 'fuzzy_file_find'
246
+ @settings[ command ] = arg.to_b
247
+ when "context.format", "context.separator.format", "status.format"
248
+ @settings[ command ] = arg.toFormatting
249
+ when "logfile"
250
+ @logfilename = arg.subHome
251
+ when "context.separator", "status.left", "status.right", "status.filler",
252
+ "status.modified_str", "status.unnamed_str", "status.selecting_str",
253
+ "status.read_only_str", /^lang\..+?\.indent\.ignore\.charset$/,
254
+ /^lang\.(.+?)\.tokens\.([^.]+)\.change_to$/,
255
+ /^lang\.(.+?)\.column_delimiters$/,
256
+ "view.nonfilelines.character",
257
+ 'interaction.blink_string', 'diff_command', 'session.default_session'
258
+ @settings[ command ] = arg
259
+ when /^lang\..+?\.comment_(?:close_)?string$/
260
+ @settings[ command ] = arg.gsub( /^["']|["']$/, '' )
261
+ when "status.vars"
262
+ @settings[ command ] = arg.split( /\s+/ )
263
+ when /^lang\.(.+?)\.indent\.size$/, /^lang\.(.+?)\.(?:tabsize|wrap_margin)$/
264
+ @settings[ command ] = arg.to_i
265
+ when "context.max_levels", "context.max_segment_width", "max_clips", "max_undo_lines",
266
+ "view.margin.x", "view.margin.y", "view.scroll_amount", "view.lookback", 'grep.context'
267
+ @settings[ command ] = arg.to_i
268
+ when "view.jump.x", "view.jump.y"
269
+ value = arg.to_i
270
+ if value < 1
271
+ value = 1
272
+ end
273
+ @settings[ command ] = value
274
+ when "bol_behaviour", "bol_behavior"
275
+ case arg.downcase
276
+ when "zero"
277
+ @settings[ "bol_behaviour" ] = BOL_ZERO
278
+ when "first-char"
279
+ @settings[ "bol_behaviour" ] = BOL_FIRST_CHAR
280
+ when "alternating-zero"
281
+ @settings[ "bol_behaviour" ] = BOL_ALT_ZERO
282
+ else # default
283
+ @settings[ "bol_behaviour" ] = BOL_ALT_FIRST_CHAR
284
+ end
285
+ when "eol_behaviour", "eol_behavior"
286
+ case arg.downcase
287
+ when "end"
288
+ @settings[ "eol_behaviour" ] = EOL_END
289
+ when "last-char"
290
+ @settings[ "eol_behaviour" ] = EOL_LAST_CHAR
291
+ when "alternating-last-char"
292
+ @settings[ "eol_behaviour" ] = EOL_ALT_FIRST_CHAR
293
+ else # default
294
+ @settings[ "eol_behaviour" ] = EOL_ALT_END
295
+ end
296
+ when "context.delay", 'interaction.blink_duration', 'interaction.choice_delay'
297
+ @settings[ command ] = arg.to_f
298
+ end
299
+ end
300
+ end
301
+ protected :parseConfigurationFile
302
+
303
+ end
304
+ end
@@ -11,12 +11,12 @@ class CTag
11
11
  end
12
12
 
13
13
  def to_s
14
- return "#{@file}:#{@command} (#{@kind}) #{@rest}"
14
+ "#{@file}:#{@command} (#{@kind}) #{@rest}"
15
15
  end
16
16
 
17
17
  def == ( other )
18
- return (
19
- other != nil and
18
+ (
19
+ other and
20
20
  @file == other.file and
21
21
  @command == other.command and
22
22
  @kind == other.kind and
@@ -0,0 +1,288 @@
1
+ module Diakonos
2
+ DO_REDRAW = true
3
+ DONT_REDRAW = false
4
+
5
+ class Diakonos
6
+ attr_reader :win_main, :display_mutex
7
+
8
+ def initializeDisplay
9
+ @win_main.close if @win_main
10
+ @win_status.close if @win_status
11
+ @win_interaction.close if @win_interaction
12
+ @win_context.close if @win_context
13
+
14
+ Curses::init_screen
15
+ Curses::nonl
16
+ Curses::raw
17
+ Curses::noecho
18
+
19
+ if Curses::has_colors?
20
+ Curses::start_color
21
+ Curses::init_pair( Curses::COLOR_BLACK, Curses::COLOR_BLACK, Curses::COLOR_BLACK )
22
+ Curses::init_pair( Curses::COLOR_RED, Curses::COLOR_RED, Curses::COLOR_BLACK )
23
+ Curses::init_pair( Curses::COLOR_GREEN, Curses::COLOR_GREEN, Curses::COLOR_BLACK )
24
+ Curses::init_pair( Curses::COLOR_YELLOW, Curses::COLOR_YELLOW, Curses::COLOR_BLACK )
25
+ Curses::init_pair( Curses::COLOR_BLUE, Curses::COLOR_BLUE, Curses::COLOR_BLACK )
26
+ Curses::init_pair( Curses::COLOR_MAGENTA, Curses::COLOR_MAGENTA, Curses::COLOR_BLACK )
27
+ Curses::init_pair( Curses::COLOR_CYAN, Curses::COLOR_CYAN, Curses::COLOR_BLACK )
28
+ Curses::init_pair( Curses::COLOR_WHITE, Curses::COLOR_WHITE, Curses::COLOR_BLACK )
29
+ @colour_pairs.each do |cp|
30
+ Curses::init_pair( cp[ :number ], cp[ :fg ], cp[ :bg ] )
31
+ end
32
+ end
33
+
34
+ @win_main = Curses::Window.new( main_window_height, Curses::cols, 0, 0 )
35
+ @win_main.keypad( true )
36
+ @win_status = Curses::Window.new( 1, Curses::cols, Curses::lines - 2, 0 )
37
+ @win_status.keypad( true )
38
+ @win_status.attrset @settings[ 'status.format' ]
39
+ @win_interaction = Curses::Window.new( 1, Curses::cols, Curses::lines - 1, 0 )
40
+ @win_interaction.keypad( true )
41
+
42
+ if @settings[ 'context.visible' ]
43
+ if @settings[ 'context.combined' ]
44
+ pos = 1
45
+ else
46
+ pos = 3
47
+ end
48
+ @win_context = Curses::Window.new( 1, Curses::cols, Curses::lines - pos, 0 )
49
+ @win_context.keypad( true )
50
+ else
51
+ @win_context = nil
52
+ end
53
+
54
+ @win_interaction.refresh
55
+ @win_main.refresh
56
+
57
+ @buffers.each_value do |buffer|
58
+ buffer.reset_win_main
59
+ end
60
+ end
61
+
62
+ def getTokenRegexp( hash, arg, match )
63
+ language = match[ 1 ]
64
+ token_class = match[ 2 ]
65
+ case_insensitive = ( match[ 3 ] != nil )
66
+ hash[ language ] = ( hash[ language ] or Hash.new )
67
+ if case_insensitive
68
+ hash[ language ][ token_class ] = Regexp.new( arg, Regexp::IGNORECASE )
69
+ else
70
+ hash[ language ][ token_class ] = Regexp.new arg
71
+ end
72
+ end
73
+
74
+ def redraw
75
+ loadConfiguration
76
+ initializeDisplay
77
+ updateStatusLine
78
+ updateContextLine
79
+ @current_buffer.display
80
+ end
81
+
82
+ def main_window_height
83
+ # One line for the status line
84
+ # One line for the input line
85
+ # One line for the context line
86
+ retval = Curses::lines - 2
87
+ if @settings[ "context.visible" ] and not @settings[ "context.combined" ]
88
+ retval = retval - 1
89
+ end
90
+ retval
91
+ end
92
+
93
+ def main_window_width
94
+ Curses::cols
95
+ end
96
+
97
+ # Display text on the interaction line.
98
+ def setILine( string = "" )
99
+ Curses::curs_set 0
100
+ @win_interaction.setpos( 0, 0 )
101
+ @win_interaction.addstr( "%-#{Curses::cols}s" % string )
102
+ @win_interaction.refresh
103
+ Curses::curs_set 1
104
+ string.length
105
+ end
106
+
107
+ def set_status_variable( identifier, value )
108
+ @status_vars[ identifier ] = value
109
+ end
110
+
111
+ def buildStatusLine( truncation = 0 )
112
+ var_array = Array.new
113
+ @settings[ "status.vars" ].each do |var|
114
+ case var
115
+ when "buffer_number"
116
+ var_array.push bufferToNumber( @current_buffer )
117
+ when "col"
118
+ var_array.push( @current_buffer.last_screen_col + 1 )
119
+ when "filename"
120
+ name = @current_buffer.nice_name
121
+ var_array.push name[ ([ truncation, name.length ].min)..-1 ]
122
+ when "modified"
123
+ if @current_buffer.modified?
124
+ var_array.push @settings[ "status.modified_str" ]
125
+ else
126
+ var_array.push ""
127
+ end
128
+ when "num_buffers"
129
+ var_array.push @buffers.length
130
+ when "num_lines"
131
+ var_array.push @current_buffer.length
132
+ when "row", "line"
133
+ var_array.push( @current_buffer.last_row + 1 )
134
+ when "read_only"
135
+ if @current_buffer.read_only
136
+ var_array.push @settings[ "status.read_only_str" ]
137
+ else
138
+ var_array.push ""
139
+ end
140
+ when "selecting"
141
+ if @current_buffer.changing_selection
142
+ var_array.push @settings[ "status.selecting_str" ]
143
+ else
144
+ var_array.push ""
145
+ end
146
+ when 'session_name'
147
+ var_array.push @session[ 'name' ]
148
+ when "type"
149
+ var_array.push @current_buffer.original_language
150
+ when /^@/
151
+ var_array.push @status_vars[ var ]
152
+ end
153
+ end
154
+ str = nil
155
+ begin
156
+ status_left = @settings[ "status.left" ]
157
+ field_count = status_left.count "%"
158
+ status_left = status_left % var_array[ 0...field_count ]
159
+ status_right = @settings[ "status.right" ] % var_array[ field_count..-1 ]
160
+ filler_string = @settings[ "status.filler" ]
161
+ fill_amount = (Curses::cols - status_left.length - status_right.length) / filler_string.length
162
+ if fill_amount > 0
163
+ filler = filler_string * fill_amount
164
+ else
165
+ filler = ""
166
+ end
167
+ str = status_left + filler + status_right
168
+ rescue ArgumentError => e
169
+ str = "%-#{Curses::cols}s" % "(status line configuration error)"
170
+ end
171
+ str
172
+ end
173
+ protected :buildStatusLine
174
+
175
+ def updateStatusLine
176
+ str = buildStatusLine
177
+ if str.length > Curses::cols
178
+ str = buildStatusLine( str.length - Curses::cols )
179
+ end
180
+ Curses::curs_set 0
181
+ @win_status.setpos( 0, 0 )
182
+ @win_status.addstr str
183
+ @win_status.refresh
184
+ Curses::curs_set 1
185
+ end
186
+
187
+ def updateContextLine
188
+ if @win_context
189
+ @context_thread.exit if @context_thread
190
+ @context_thread = Thread.new do ||
191
+
192
+ context = @current_buffer.context
193
+
194
+ Curses::curs_set 0
195
+ @win_context.setpos( 0, 0 )
196
+ chars_printed = 0
197
+ if context.length > 0
198
+ truncation = [ @settings[ "context.max_levels" ], context.length ].min
199
+ max_length = [
200
+ ( Curses::cols / truncation ) - @settings[ "context.separator" ].length,
201
+ ( @settings[ "context.max_segment_width" ] or Curses::cols )
202
+ ].min
203
+ line = nil
204
+ context_subset = context[ 0...truncation ]
205
+ context_subset = context_subset.collect do |line|
206
+ line.strip[ 0...max_length ]
207
+ end
208
+
209
+ context_subset.each do |line|
210
+ @win_context.attrset @settings[ "context.format" ]
211
+ @win_context.addstr line
212
+ chars_printed += line.length
213
+ @win_context.attrset @settings[ "context.separator.format" ]
214
+ @win_context.addstr @settings[ "context.separator" ]
215
+ chars_printed += @settings[ "context.separator" ].length
216
+ end
217
+ end
218
+
219
+ @iline_mutex.synchronize do
220
+ @win_context.attrset @settings[ "context.format" ]
221
+ @win_context.addstr( " " * ( Curses::cols - chars_printed ) )
222
+ @win_context.refresh
223
+ end
224
+ @display_mutex.synchronize do
225
+ @win_main.setpos( @current_buffer.last_screen_y, @current_buffer.last_screen_x )
226
+ @win_main.refresh
227
+ end
228
+ Curses::curs_set 1
229
+ end
230
+
231
+ @context_thread.priority = -2
232
+ end
233
+ end
234
+
235
+ def displayEnqueue( buffer )
236
+ @display_queue_mutex.synchronize do
237
+ @display_queue = buffer
238
+ end
239
+ end
240
+
241
+ def displayDequeue
242
+ @display_queue_mutex.synchronize do
243
+ if @display_queue
244
+ Thread.new( @display_queue ) do |b|
245
+ @display_mutex.lock
246
+ @display_mutex.unlock
247
+ b.display
248
+ end
249
+ @display_queue = nil
250
+ end
251
+ end
252
+ end
253
+
254
+ def showMessage( message, non_interaction_duration = @settings[ 'interaction.choice_delay' ] )
255
+ terminateMessage
256
+
257
+ @message_expiry = Time.now + non_interaction_duration
258
+ @message_thread = Thread.new do
259
+ time_left = @message_expiry - Time.now
260
+ while time_left > 0
261
+ setILine "(#{time_left.round}) #{message}"
262
+ @win_main.setpos( @saved_main_y, @saved_main_x )
263
+ sleep 1
264
+ time_left = @message_expiry - Time.now
265
+ end
266
+ setILine message
267
+ @win_main.setpos( @saved_main_y, @saved_main_x )
268
+ end
269
+ end
270
+
271
+ def terminateMessage
272
+ if @message_thread and @message_thread.alive?
273
+ @message_thread.terminate
274
+ @message_thread = nil
275
+ end
276
+ end
277
+
278
+ def refreshAll
279
+ @win_main.refresh
280
+ if @win_context
281
+ @win_context.refresh
282
+ end
283
+ @win_status.refresh
284
+ @win_interaction.refresh
285
+ end
286
+
287
+ end
288
+ end