diakonos 0.8.6 → 0.8.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +18 -0
- data/LICENCE +1 -1
- data/README +3 -3
- data/diakonos-256-colour.conf +1 -0
- data/diakonos.conf +237 -108
- data/lib/diakonos.rb +425 -2680
- data/lib/diakonos/array.rb +1 -1
- data/lib/diakonos/bignum.rb +4 -1
- data/lib/diakonos/bookmark.rb +7 -8
- data/lib/diakonos/buffer-hash.rb +55 -13
- data/lib/diakonos/buffer-management.rb +73 -0
- data/lib/diakonos/buffer.rb +327 -259
- data/lib/diakonos/clipboard.rb +4 -4
- data/lib/diakonos/config.rb +304 -0
- data/lib/diakonos/ctag.rb +3 -3
- data/lib/diakonos/display.rb +288 -0
- data/lib/diakonos/enumerable.rb +2 -2
- data/lib/diakonos/fixnum.rb +12 -8
- data/lib/diakonos/functions.rb +1420 -0
- data/lib/diakonos/grep.rb +78 -0
- data/lib/diakonos/hash.rb +26 -19
- data/lib/diakonos/help.rb +92 -0
- data/lib/diakonos/hooks.rb +13 -0
- data/lib/diakonos/interaction.rb +139 -0
- data/lib/diakonos/keycode.rb +3 -3
- data/lib/diakonos/keying.rb +124 -0
- data/lib/diakonos/list.rb +55 -0
- data/lib/diakonos/logging.rb +24 -0
- data/lib/diakonos/readline.rb +44 -25
- data/lib/diakonos/regexp.rb +1 -1
- data/lib/diakonos/sessions.rb +70 -0
- data/lib/diakonos/sized-array.rb +4 -4
- data/lib/diakonos/string.rb +44 -37
- data/lib/diakonos/text-mark.rb +1 -1
- data/lib/diakonos/vendor/fuzzy_file_finder.rb +353 -0
- data/test/buffer-test.rb +5 -5
- data/test/diakonos-test.rb +2 -2
- metadata +27 -14
data/lib/diakonos/clipboard.rb
CHANGED
@@ -7,18 +7,18 @@ module Diakonos
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def [] ( arg )
|
10
|
-
|
10
|
+
@clips[ arg ]
|
11
11
|
end
|
12
12
|
|
13
13
|
def clip
|
14
|
-
|
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
|
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
|
-
|
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
|
data/lib/diakonos/ctag.rb
CHANGED
@@ -11,12 +11,12 @@ class CTag
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def to_s
|
14
|
-
|
14
|
+
"#{@file}:#{@command} (#{@kind}) #{@rest}"
|
15
15
|
end
|
16
16
|
|
17
17
|
def == ( other )
|
18
|
-
|
19
|
-
other
|
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
|