glimmer-cs-gladiator 0.5.3 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +212 -0
- data/README.md +62 -27
- data/VERSION +1 -1
- data/glimmer-cs-gladiator.gemspec +70 -0
- data/images/glimmer-cs-gladiator-logo.png +0 -0
- data/lib/models/glimmer/gladiator/command.rb +41 -8
- data/lib/models/glimmer/gladiator/dir.rb +44 -16
- data/lib/models/glimmer/gladiator/file.rb +140 -71
- data/lib/views/glimmer/gladiator.rb +649 -253
- data/lib/views/glimmer/gladiator/text_editor.rb +123 -95
- metadata +16 -13
Binary file
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Glimmer
|
2
2
|
class Gladiator
|
3
3
|
class Command
|
4
|
+
include Glimmer
|
5
|
+
|
4
6
|
class << self
|
5
7
|
include Glimmer
|
6
8
|
|
@@ -13,11 +15,18 @@ module Glimmer
|
|
13
15
|
command_history[file] ||= [Command.new(file)]
|
14
16
|
end
|
15
17
|
|
16
|
-
def do(file, method = nil, command: nil)
|
17
|
-
command
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
def do(file, method = nil, *args, command: nil)
|
19
|
+
if command.nil?
|
20
|
+
command ||= Command.new(file, method, *args)
|
21
|
+
command.previous_command = command_history_for(file).last
|
22
|
+
unless command_history_for(file).last.method == :change_content! && method == :change_content!
|
23
|
+
command_history_for(file).last.next_command = command
|
24
|
+
end
|
25
|
+
command.do
|
26
|
+
command_history_for(file) << command unless command_history_for(file).last.method == :change_content! && method == :change_content!
|
27
|
+
else
|
28
|
+
command_history_for(file) << command
|
29
|
+
end
|
21
30
|
end
|
22
31
|
|
23
32
|
def undo(file)
|
@@ -30,15 +39,22 @@ module Glimmer
|
|
30
39
|
command = command_history_for(file).last
|
31
40
|
command&.redo
|
32
41
|
end
|
42
|
+
|
43
|
+
def clear(file)
|
44
|
+
command_history[file] = [Command.new(file)]
|
45
|
+
end
|
33
46
|
end
|
34
47
|
|
35
|
-
attr_accessor :file, :method, :
|
48
|
+
attr_accessor :file, :method, :args, :previous_command, :next_command,
|
49
|
+
:file_dirty_content, :file_caret_position, :file_selection_count, :previous_file_dirty_content, :previous_file_caret_position, :previous_file_selection_count
|
36
50
|
|
37
|
-
def initialize(file, method = nil)
|
51
|
+
def initialize(file, method = nil, *args)
|
38
52
|
@file = file
|
39
53
|
@method = method
|
54
|
+
@args = args
|
40
55
|
end
|
41
56
|
|
57
|
+
|
42
58
|
def native?
|
43
59
|
@method.nil?
|
44
60
|
end
|
@@ -56,6 +72,9 @@ module Glimmer
|
|
56
72
|
|
57
73
|
def redo
|
58
74
|
return if next_command.nil?# || next_command.native?
|
75
|
+
@file.dirty_content = next_command.file_dirty_content.clone
|
76
|
+
@file.caret_position = next_command.file_caret_position
|
77
|
+
@file.selection_count = next_command.file_selection_count
|
59
78
|
Command.do(next_command.file, command: next_command)
|
60
79
|
end
|
61
80
|
|
@@ -63,6 +82,10 @@ module Glimmer
|
|
63
82
|
@previous_file_dirty_content = @file.dirty_content.clone
|
64
83
|
@previous_file_caret_position = @file.caret_position
|
65
84
|
@previous_file_selection_count = @file.selection_count
|
85
|
+
if @method == :change_content!
|
86
|
+
@previous_file_caret_position = @file.last_caret_position
|
87
|
+
@previous_file_selection_count = @file.last_selection_count
|
88
|
+
end
|
66
89
|
end
|
67
90
|
|
68
91
|
def restore
|
@@ -72,7 +95,17 @@ module Glimmer
|
|
72
95
|
end
|
73
96
|
|
74
97
|
def execute
|
75
|
-
@file.
|
98
|
+
@file.start_command
|
99
|
+
@file.send(@method, *@args)
|
100
|
+
@file.end_command
|
101
|
+
@file_dirty_content = @file.dirty_content.clone
|
102
|
+
@file_caret_position = @file.caret_position
|
103
|
+
@file_selection_count = @file.selection_count
|
104
|
+
if previous_command.method == :change_content! && @method == :change_content!
|
105
|
+
previous_command.file_dirty_content = @file_dirty_content
|
106
|
+
previous_command.file_caret_position = @file_caret_position
|
107
|
+
previous_command.file_selection_count = @file_selection_count
|
108
|
+
end
|
76
109
|
end
|
77
110
|
end
|
78
111
|
end
|
@@ -6,8 +6,6 @@ module Glimmer
|
|
6
6
|
include Glimmer
|
7
7
|
include Glimmer::DataBinding::ObservableModel
|
8
8
|
|
9
|
-
REFRESH_DELAY = 7
|
10
|
-
|
11
9
|
attr_accessor :selected_child, :filter, :children, :filtered_path_options, :filtered_path, :display_path, :ignore_paths
|
12
10
|
attr_reader :name, :parent, :path
|
13
11
|
attr_writer :all_children
|
@@ -15,19 +13,30 @@ module Glimmer
|
|
15
13
|
def initialize(path, project_dir = nil)
|
16
14
|
@project_dir = project_dir
|
17
15
|
if is_local_dir
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
16
|
+
@filewatcher = Filewatcher.new(path)
|
17
|
+
Thread.new(@filewatcher) do |fw|
|
18
|
+
begin
|
19
|
+
fw.watch do |filename, event|
|
20
|
+
# TODO do fine grained processing of events for enhanced performance (e.g. dir refresh vs file change)
|
21
|
+
# TODO do fine grained file change only without a refresh delay for enhanced performance
|
22
|
+
begin
|
23
|
+
if !@refresh_in_progress && !filename.include?('new_file') && (event != :updated || find_child_file(filename).nil?)
|
24
|
+
Thread.new {
|
25
|
+
refresh
|
26
|
+
}
|
27
|
+
end
|
28
|
+
rescue => e
|
29
|
+
puts e.full_message
|
30
|
+
end
|
31
|
+
end
|
32
|
+
rescue => e
|
33
|
+
puts e.full_message
|
34
|
+
end
|
35
|
+
end
|
27
36
|
end
|
28
37
|
self.path = ::File.expand_path(path)
|
29
38
|
@name = ::File.basename(::File.expand_path(path))
|
30
|
-
@ignore_paths = ['.gladiator', '.git', 'coverage', 'packages', 'tmp', 'vendor']
|
39
|
+
@ignore_paths = ['.gladiator', '.git', 'coverage', 'packages', 'node_modules', 'tmp', 'vendor']
|
31
40
|
self.filtered_path_options = []
|
32
41
|
end
|
33
42
|
|
@@ -67,7 +76,7 @@ module Glimmer
|
|
67
76
|
result || p.include?(ignore_path)
|
68
77
|
end
|
69
78
|
end.map do |p|
|
70
|
-
::File.file?(p) ?
|
79
|
+
::File.file?(p) ? File.new(p, project_dir) : Dir.new(p, project_dir)
|
71
80
|
end.sort_by do |c|
|
72
81
|
c.path.to_s.downcase
|
73
82
|
end.sort_by do |c|
|
@@ -76,6 +85,22 @@ module Glimmer
|
|
76
85
|
child.retrieve_children if child.is_a?(Dir)
|
77
86
|
end
|
78
87
|
end
|
88
|
+
|
89
|
+
def find_child_file(child_path)
|
90
|
+
depth_first_search_file(self, child_path)
|
91
|
+
end
|
92
|
+
|
93
|
+
def depth_first_search_file(dir, file_path)
|
94
|
+
dir.children.each do |child|
|
95
|
+
if child.is_a?(File)
|
96
|
+
return child if child.path.include?(file_path)
|
97
|
+
else
|
98
|
+
result = depth_first_search_file(child, file_path)
|
99
|
+
return result unless result.nil?
|
100
|
+
end
|
101
|
+
end
|
102
|
+
nil
|
103
|
+
end
|
79
104
|
|
80
105
|
def selected_child_path_history
|
81
106
|
@selected_child_path_history ||= []
|
@@ -91,6 +116,7 @@ module Glimmer
|
|
91
116
|
|
92
117
|
def refresh(async: true, force: false)
|
93
118
|
return if @refresh_paused && !force
|
119
|
+
@refresh_in_progress = true
|
94
120
|
retrieve_children
|
95
121
|
collect_all_children
|
96
122
|
refresh_operation = lambda do
|
@@ -102,6 +128,7 @@ module Glimmer
|
|
102
128
|
else
|
103
129
|
sync_exec(&refresh_operation)
|
104
130
|
end
|
131
|
+
@refresh_in_progress = false
|
105
132
|
end
|
106
133
|
|
107
134
|
def filter=(value)
|
@@ -144,7 +171,7 @@ module Glimmer
|
|
144
171
|
def selected_child_path=(selected_path)
|
145
172
|
return (project_dir.selected_child = nil) if selected_path.nil?
|
146
173
|
# scratchpad scenario
|
147
|
-
if selected_path.empty? #
|
174
|
+
if selected_path.empty? # Scratchpad
|
148
175
|
@selected_child&.write_dirty_content
|
149
176
|
return (self.selected_child = File.new)
|
150
177
|
end
|
@@ -154,7 +181,7 @@ module Glimmer
|
|
154
181
|
selected_path = full_selected_path
|
155
182
|
if ::File.file?(selected_path)
|
156
183
|
@selected_child&.write_dirty_content
|
157
|
-
new_child =
|
184
|
+
new_child = find_child_file(selected_path)
|
158
185
|
begin
|
159
186
|
unless new_child.dirty_content.nil?
|
160
187
|
self.selected_child&.stop_filewatcher
|
@@ -175,6 +202,7 @@ module Glimmer
|
|
175
202
|
end
|
176
203
|
|
177
204
|
def selected_child=(new_child)
|
205
|
+
return if selected_child == new_child
|
178
206
|
file_properties = @selected_child&.backup_properties if @selected_child == new_child
|
179
207
|
@selected_child = new_child
|
180
208
|
@selected_child.restore_properties(file_properties) if file_properties
|
@@ -191,7 +219,7 @@ module Glimmer
|
|
191
219
|
def eql?(other)
|
192
220
|
self.path.eql?(other&.path)
|
193
221
|
end
|
194
|
-
|
222
|
+
|
195
223
|
def hash
|
196
224
|
self.path.hash
|
197
225
|
end
|
@@ -3,7 +3,7 @@ module Glimmer
|
|
3
3
|
class File
|
4
4
|
include Glimmer
|
5
5
|
|
6
|
-
attr_accessor :
|
6
|
+
attr_accessor :line_numbers_content, :line_number, :find_text, :replace_text, :top_pixel, :display_path, :case_sensitive, :caret_position, :selection_count, :last_caret_position, :last_selection_count, :line_position
|
7
7
|
attr_reader :name, :path, :project_dir
|
8
8
|
|
9
9
|
def initialize(path='', project_dir=nil)
|
@@ -13,33 +13,55 @@ module Glimmer
|
|
13
13
|
@name = path.empty? ? 'Scratchpad' : ::File.basename(path)
|
14
14
|
self.path = ::File.expand_path(path) unless path.empty?
|
15
15
|
@top_pixel = 0
|
16
|
+
@caret_position = 0
|
16
17
|
@selection_count = 0
|
17
|
-
@
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
18
|
+
@last_selection_count = 0
|
19
|
+
@line_number = 1
|
20
|
+
@init = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def init_content
|
24
|
+
unless @init
|
25
|
+
@init = true
|
26
|
+
begin
|
27
|
+
# test read dirty content
|
28
|
+
observe(self, :dirty_content) do
|
29
|
+
line_count = lines.empty? ? 1 : lines.size
|
30
|
+
lines_text_size = [line_count.to_s.size, 4].max
|
31
|
+
old_top_pixel = top_pixel
|
32
|
+
self.line_numbers_content = line_count.times.map {|n| (' ' * (lines_text_size - (n+1).to_s.size)) + (n+1).to_s }.join("\n")
|
33
|
+
self.top_pixel = old_top_pixel
|
34
|
+
end
|
35
|
+
the_dirty_content = read_dirty_content
|
36
|
+
the_dirty_content.split("\n") # test that it is not a binary file (crashes to rescue block otherwise)
|
37
|
+
self.dirty_content = the_dirty_content
|
38
|
+
observe(self, :caret_position) do |new_caret_position|
|
39
|
+
update_line_number_from_caret_position(new_caret_position)
|
40
|
+
end
|
41
|
+
observe(self, :line_number) do |new_line_number|
|
33
42
|
line_index = line_number - 1
|
34
43
|
new_caret_position = caret_position_for_line_index(line_index)
|
35
|
-
|
44
|
+
current_caret_position = caret_position
|
45
|
+
line_index_for_new_caret_position = line_index_for_caret_position(new_caret_position)
|
46
|
+
line_index_for_current_caret_position = line_index_for_caret_position(current_caret_position)
|
47
|
+
self.caret_position = new_caret_position unless (current_caret_position && line_index_for_new_caret_position == line_index_for_current_caret_position)
|
36
48
|
end
|
49
|
+
rescue # in case of a binary file
|
50
|
+
stop_filewatcher
|
37
51
|
end
|
38
|
-
rescue
|
39
|
-
# no op in case of a binary file
|
40
52
|
end
|
41
53
|
end
|
42
|
-
|
54
|
+
|
55
|
+
def update_line_number_from_caret_position(new_caret_position)
|
56
|
+
new_line_number = line_index_for_caret_position(caret_position) + 1
|
57
|
+
current_line_number = line_number
|
58
|
+
unless (current_line_number && current_line_number == new_line_number)
|
59
|
+
self.line_number = new_line_number
|
60
|
+
# TODO check if the following line is needed
|
61
|
+
self.line_position = caret_position - caret_position_for_line_index(line_number - 1) + 1
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
43
65
|
def path=(the_path)
|
44
66
|
@path = the_path
|
45
67
|
generate_display_path
|
@@ -49,6 +71,15 @@ module Glimmer
|
|
49
71
|
return if @path.empty?
|
50
72
|
@display_path = @path.sub(project_dir.path, '').sub(/^\//, '')
|
51
73
|
end
|
74
|
+
|
75
|
+
def name=(the_name)
|
76
|
+
new_path = path.sub(/#{Regexp.escape(@name)}$/, the_name) unless scratchpad?
|
77
|
+
@name = the_name
|
78
|
+
if !scratchpad? && ::File.exist?(path)
|
79
|
+
FileUtils.mv(path, new_path)
|
80
|
+
self.path = new_path
|
81
|
+
end
|
82
|
+
end
|
52
83
|
|
53
84
|
def scratchpad?
|
54
85
|
path.to_s.empty?
|
@@ -66,50 +97,74 @@ module Glimmer
|
|
66
97
|
send("#{property}=", value)
|
67
98
|
end
|
68
99
|
end
|
100
|
+
|
101
|
+
def caret_position=(value)
|
102
|
+
@last_caret_position = @caret_position
|
103
|
+
@caret_position = value
|
104
|
+
end
|
69
105
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
Command.do(self) # record a native (OS-widget) operation
|
75
|
-
self.dirty_content = value
|
76
|
-
end
|
106
|
+
def selection_count=(value)
|
107
|
+
#@last_selection_count = @selection_count
|
108
|
+
@selection_count = value
|
109
|
+
@last_selection_count = @selection_count
|
77
110
|
end
|
78
111
|
|
112
|
+
def dirty_content
|
113
|
+
init_content
|
114
|
+
@dirty_content
|
115
|
+
end
|
116
|
+
|
117
|
+
def dirty_content=(the_content)
|
118
|
+
# TODO set partial dirty content by line(s) for enhanced performance
|
119
|
+
@dirty_content = the_content
|
120
|
+
old_caret_position = caret_position
|
121
|
+
old_top_pixel = top_pixel
|
122
|
+
|
123
|
+
notify_observers(:content)
|
124
|
+
if @formatting_dirty_content_for_writing
|
125
|
+
self.caret_position = old_caret_position
|
126
|
+
self.top_pixel = old_top_pixel
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
79
130
|
def content
|
80
131
|
dirty_content
|
81
132
|
end
|
82
133
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
134
|
+
# to use for widget data-binding
|
135
|
+
def content=(value)
|
136
|
+
value = value.gsub("\t", ' ')
|
137
|
+
if dirty_content != value
|
138
|
+
Command.do(self, :change_content!, value)
|
139
|
+
end
|
87
140
|
end
|
88
|
-
|
89
|
-
def
|
90
|
-
|
141
|
+
|
142
|
+
def change_content!(value)
|
143
|
+
self.dirty_content = value
|
144
|
+
update_line_number_from_caret_position(caret_position)
|
91
145
|
end
|
92
146
|
|
93
|
-
def
|
94
|
-
|
147
|
+
def start_command
|
148
|
+
@commmand_in_progress = true
|
95
149
|
end
|
96
|
-
|
97
|
-
def
|
98
|
-
|
150
|
+
|
151
|
+
def end_command
|
152
|
+
@commmand_in_progress = false
|
99
153
|
end
|
100
|
-
|
101
|
-
def
|
102
|
-
|
103
|
-
@name = the_name
|
104
|
-
if !scratchpad? && ::File.exist?(path)
|
105
|
-
FileUtils.mv(path, new_path)
|
106
|
-
self.path = new_path
|
107
|
-
end
|
154
|
+
|
155
|
+
def command_in_progress?
|
156
|
+
@commmand_in_progress
|
108
157
|
end
|
109
158
|
|
110
|
-
def
|
111
|
-
|
112
|
-
|
159
|
+
def close
|
160
|
+
stop_filewatcher
|
161
|
+
remove_all_observers
|
162
|
+
initialize(path, project_dir)
|
163
|
+
Command.clear(self)
|
164
|
+
end
|
165
|
+
|
166
|
+
def read_dirty_content
|
167
|
+
path.empty? ? '' : ::File.read(path)
|
113
168
|
end
|
114
169
|
|
115
170
|
def start_filewatcher
|
@@ -117,15 +172,13 @@ module Glimmer
|
|
117
172
|
@filewatcher = Filewatcher.new(@path)
|
118
173
|
@thread = Thread.new(@filewatcher) do |fw|
|
119
174
|
fw.watch do |filename, event|
|
120
|
-
|
121
|
-
|
122
|
-
# test read dirty content
|
123
|
-
read_dirty_content.split("\n")
|
124
|
-
async_exec do
|
175
|
+
async_exec do
|
176
|
+
begin
|
125
177
|
self.dirty_content = read_dirty_content if read_dirty_content != dirty_content
|
178
|
+
rescue StandardError, Errno::ENOENT
|
179
|
+
# in case of a binary file
|
180
|
+
stop_filewatcher
|
126
181
|
end
|
127
|
-
rescue
|
128
|
-
# no op in case of a binary file
|
129
182
|
end
|
130
183
|
end
|
131
184
|
end
|
@@ -135,21 +188,28 @@ module Glimmer
|
|
135
188
|
@filewatcher&.stop
|
136
189
|
end
|
137
190
|
|
138
|
-
def format_dirty_content_for_writing!
|
139
|
-
new_dirty_content = dirty_content.split("\n").map {|line| line.strip.empty? ? line : line.rstrip }.join("\n")
|
140
|
-
new_dirty_content = "#{new_dirty_content.gsub("\r\n", "\n").gsub("\r", "\n").sub(/\n+\z/, '')}\n"
|
141
|
-
self.dirty_content = new_dirty_content if new_dirty_content != self.dirty_content
|
142
|
-
end
|
143
|
-
|
144
191
|
def write_dirty_content
|
145
|
-
|
192
|
+
# TODO write partial dirty content by line(s) for enhanced performance
|
193
|
+
return if scratchpad? || !::File.exist?(path) || !::File.exists?(path) || read_dirty_content == dirty_content
|
146
194
|
format_dirty_content_for_writing!
|
147
|
-
::File.write(path, dirty_content)
|
148
|
-
rescue => e
|
195
|
+
::File.write(path, dirty_content)
|
196
|
+
rescue StandardError, ArgumentError => e
|
149
197
|
puts "Error in writing dirty content for #{path}"
|
150
198
|
puts e.full_message
|
151
199
|
end
|
152
200
|
|
201
|
+
def format_dirty_content_for_writing!
|
202
|
+
return if @commmand_in_progress
|
203
|
+
# TODO f ix c ar e t pos it ion after formatting dirty content (diff?)
|
204
|
+
new_dirty_content = dirty_content.to_s.split("\n").map {|line| line.strip.empty? ? line : line.rstrip }.join("\n")
|
205
|
+
new_dirty_content = "#{new_dirty_content.gsub("\r\n", "\n").gsub("\r", "\n").sub(/\n+\z/, '')}\n"
|
206
|
+
if new_dirty_content != self.dirty_content
|
207
|
+
@formatting_dirty_content_for_writing = true
|
208
|
+
self.dirty_content = new_dirty_content
|
209
|
+
@formatting_dirty_content_for_writing = false
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
153
213
|
def write_raw_dirty_content
|
154
214
|
return if scratchpad? || !::File.exist?(path)
|
155
215
|
::File.write(path, dirty_content) if ::File.exists?(path)
|
@@ -185,7 +245,7 @@ module Glimmer
|
|
185
245
|
self.caret_position = caret_position_for_line_index(line_number) + current_line_indentation.size
|
186
246
|
self.selection_count = 0
|
187
247
|
end
|
188
|
-
|
248
|
+
|
189
249
|
def comment_line!
|
190
250
|
old_lines = lines
|
191
251
|
return if old_lines.size < 1
|
@@ -219,6 +279,7 @@ module Glimmer
|
|
219
279
|
new_caret_position = old_caret_position + delta
|
220
280
|
new_caret_position = [new_caret_position, old_caret_position_line_caret_position].max
|
221
281
|
self.caret_position = new_caret_position
|
282
|
+
self.selection_count = 0
|
222
283
|
end
|
223
284
|
end
|
224
285
|
|
@@ -243,6 +304,7 @@ module Glimmer
|
|
243
304
|
self.selection_count = (caret_position_for_line_index(old_end_caret_line_index + 1) - self.caret_position)
|
244
305
|
else
|
245
306
|
self.caret_position = old_caret_position + delta
|
307
|
+
self.selection_count = 0
|
246
308
|
end
|
247
309
|
end
|
248
310
|
|
@@ -274,6 +336,7 @@ module Glimmer
|
|
274
336
|
new_caret_position = old_caret_position + delta
|
275
337
|
new_caret_position = [new_caret_position, old_caret_position_line_caret_position].max
|
276
338
|
self.caret_position = new_caret_position
|
339
|
+
self.selection_count = 0
|
277
340
|
end
|
278
341
|
end
|
279
342
|
|
@@ -311,6 +374,7 @@ module Glimmer
|
|
311
374
|
self.selection_count = (caret_position_for_line_index(old_end_caret_line_index + 1) - self.caret_position)
|
312
375
|
else
|
313
376
|
self.caret_position = old_caret_position + delta
|
377
|
+
self.selection_count = 0
|
314
378
|
end
|
315
379
|
end
|
316
380
|
|
@@ -455,13 +519,18 @@ module Glimmer
|
|
455
519
|
write_dirty_content
|
456
520
|
load path
|
457
521
|
end
|
458
|
-
rescue SyntaxError, StandardError => e
|
522
|
+
rescue LoadError, SyntaxError, StandardError => e
|
523
|
+
# TODO consider showing a message dialog or error message console in the future
|
459
524
|
puts e.full_message
|
460
525
|
end
|
461
526
|
end
|
462
527
|
|
463
528
|
def lines
|
464
|
-
dirty_content.
|
529
|
+
need_padding = dirty_content.to_s.end_with?("\n")
|
530
|
+
splittable_content = need_padding ? "#{dirty_content} " : dirty_content
|
531
|
+
the_lines = splittable_content.split("\n")
|
532
|
+
the_lines[-1] = the_lines[-1].strip if need_padding
|
533
|
+
the_lines
|
465
534
|
end
|
466
535
|
|
467
536
|
def line_for_caret_position(caret_position)
|
@@ -471,7 +540,7 @@ module Glimmer
|
|
471
540
|
def line_index_for_caret_position(caret_position)
|
472
541
|
dirty_content[0...caret_position.to_i].count("\n")
|
473
542
|
end
|
474
|
-
|
543
|
+
|
475
544
|
def caret_position_for_line_index(line_index)
|
476
545
|
cp = lines[0...line_index].join("\n").size
|
477
546
|
cp += 1 if line_index > 0
|