glimmer-cs-gladiator 0.1.3 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +27 -17
- data/VERSION +1 -0
- data/bin/gladiator +8 -1
- data/lib/models/glimmer/gladiator/command.rb +75 -0
- data/lib/models/glimmer/gladiator/dir.rb +62 -19
- data/lib/models/glimmer/gladiator/file.rb +89 -8
- data/lib/views/glimmer/gladiator.rb +313 -66
- data/lib/views/glimmer/gladiator/text_editor.rb +48 -20
- metadata +14 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1fedd5416ae759bea0cbfa6d14572cedd58f74d14c544a187efb9310c5954c3
|
4
|
+
data.tar.gz: fd0d141721cb77e391c6a07aea9bbb637d326c22374ffc5e2f157487116f59a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19c5ae152d5bbe45f434c06da679b1779b844ad180cca79a945f4368d05bb50a2342ca5d085a1ad7c8b06b6aa5a97548c98d4487ee66f0b0be3f4a16089c7d74
|
7
|
+
data.tar.gz: 3acdffb642c32c894af12b9f4fa27f51a4b04eba7c13dbedc6a5c89e6dc97da7dd1cd79c3c93a75c2c0e7318866d3de33b58ad269ffee29b221632ff21b02348
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Gladiator (Glimmer Editor) 0.1.
|
1
|
+
# Gladiator (Glimmer Editor) 0.1.8 - Glimmer Custom Shell
|
2
2
|
[](http://badge.fury.io/rb/glimmer-cs-gladiator)
|
3
3
|
|
4
4
|

|
@@ -9,25 +9,35 @@ Gladiator is also a personal tool for shaping an editor exactly the way I like.
|
|
9
9
|
I leave building truly professional text editors to software tooling experts who would hopefully use Glimmer one day.
|
10
10
|
|
11
11
|
Gladiator currently supports the following text editing features:
|
12
|
-
- File explorer navigation to open file
|
13
|
-
- File lookup by name
|
14
|
-
-
|
12
|
+
- File explorer navigation to open file, rename, delete, add new file, add new directory, or refresh tree (CMD+T)
|
13
|
+
- File lookup by name ignoring slashes, underscores, and dots to ease lookup (CMD+R)
|
14
|
+
- Watch open file for external changes to automatically refresh in editor
|
15
|
+
- Watch project subdirectories for changes to automatically refresh in file explorer/file lookup
|
16
|
+
- Find & Replace (CMD+F)
|
15
17
|
- Show Line Numbers
|
16
|
-
- Jump to Line
|
17
|
-
- Multiple tab support
|
18
|
-
- Remember
|
19
|
-
- Autosave on focus out/quit/open new file
|
20
|
-
-
|
21
|
-
-
|
22
|
-
-
|
23
|
-
-
|
24
|
-
-
|
25
|
-
-
|
18
|
+
- Jump to Line (CMD+L)
|
19
|
+
- Multiple tab support (CMD+SHIFT+[ & CMD+SHIFT+] for tab navigation. CMD+1-9 to jump to a specific tab)
|
20
|
+
- Remember opened tabs, caret position, top line, window size, and window location
|
21
|
+
- Autosave on focus out/quit/open new file
|
22
|
+
- Duplicate Line(s)/selection (CMD+D)
|
23
|
+
- Kill Line(s)/selection (CMD+K)
|
24
|
+
- Move line/selection up (CMD+UP)
|
25
|
+
- Move line/selection down (CMD+DOWN)
|
26
|
+
- Comment/Uncomment line/selection (CMD+/)
|
27
|
+
- Indent/Unindent line/selection (CMD+] & CMD+[)
|
28
|
+
- Insert/Prefix New Line (CMD+ENTER & CMD+SHIFT+ENTER)
|
29
|
+
|
30
|
+
## Platforms
|
31
|
+
|
32
|
+
- Mac: Gladiator works best on the Mac.
|
33
|
+
- Linux: Gladiator works with handicaps on Linux (performing text editing operations causes scroll jitter)
|
34
|
+
- Windows: Not tested on Windows yet, but should theoretically work there too.
|
26
35
|
|
27
36
|
## Pre-requisites
|
28
37
|
|
29
|
-
-
|
30
|
-
-
|
38
|
+
- [Glimmer](https://github.com/AndyObtiva/glimmer) (Ruby Desktop Development GUI Library): '>= 0.8.0', '< 2.0.0' (dependency included in Ruby gem).
|
39
|
+
- [JRuby](https://www.jruby.org/download): Same version required by [Glimmer](https://github.com/AndyObtiva/glimmer)
|
40
|
+
- [JDK](https://www.oracle.com/java/technologies/javase-downloads.html): Same version required by [Glimmer](https://github.com/AndyObtiva/glimmer)
|
31
41
|
|
32
42
|
## Setup Instructions
|
33
43
|
|
@@ -51,7 +61,7 @@ To reuse Gladiator as a Glimmer Custom Shell inside another Glimmer application,
|
|
51
61
|
following to the application's `Gemfile`:
|
52
62
|
|
53
63
|
```
|
54
|
-
gem 'glimmer-cs-gladiator', '0.1.
|
64
|
+
gem 'glimmer-cs-gladiator', '0.1.8'
|
55
65
|
```
|
56
66
|
|
57
67
|
Run:
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.8
|
data/bin/gladiator
CHANGED
@@ -3,4 +3,11 @@
|
|
3
3
|
require 'glimmer/launcher'
|
4
4
|
|
5
5
|
gladiator_runner = File.expand_path('../gladiator_runner.rb', __FILE__)
|
6
|
-
Glimmer::Launcher.new([gladiator_runner, '-J-Xrs'] + ARGV)
|
6
|
+
launcher = Glimmer::Launcher.new([gladiator_runner, '-J-Xrs'] + ARGV)
|
7
|
+
launcher.application_paths.to_a.each do |file|
|
8
|
+
if file != gladiator_runner
|
9
|
+
launcher.application_paths.delete(file)
|
10
|
+
ENV['LOCAL_DIR'] ||= file
|
11
|
+
end
|
12
|
+
end
|
13
|
+
launcher.launch
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Glimmer
|
2
|
+
class Gladiator
|
3
|
+
class Command
|
4
|
+
class << self
|
5
|
+
def command_history
|
6
|
+
@command_history ||= {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def command_history_for(file)
|
10
|
+
# keeping a first command to make redo support work by remembering next command after undoing all
|
11
|
+
command_history[file] ||= [Command.new(file)]
|
12
|
+
end
|
13
|
+
|
14
|
+
def do(file, method = nil, command: nil)
|
15
|
+
command ||= Command.new(file, method)
|
16
|
+
command_history_for(file)&.last&.next_command = command
|
17
|
+
command.do
|
18
|
+
command_history_for(file) << command
|
19
|
+
end
|
20
|
+
|
21
|
+
def undo(file)
|
22
|
+
return if command_history_for(file).size <= 1
|
23
|
+
command_history_for(file).pop.undo
|
24
|
+
end
|
25
|
+
|
26
|
+
def redo(file)
|
27
|
+
command_history_for(file).last&.redo
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_accessor :file, :method, :next_command, :previous_file_content, :previous_file_caret_position, :previous_file_selection_count
|
32
|
+
|
33
|
+
def initialize(file, method = nil)
|
34
|
+
@file = file
|
35
|
+
@method = method
|
36
|
+
end
|
37
|
+
|
38
|
+
def native?
|
39
|
+
@method.nil?
|
40
|
+
end
|
41
|
+
|
42
|
+
def do
|
43
|
+
return if native?
|
44
|
+
backup
|
45
|
+
execute
|
46
|
+
end
|
47
|
+
|
48
|
+
def undo
|
49
|
+
return if native?
|
50
|
+
restore
|
51
|
+
end
|
52
|
+
|
53
|
+
def redo
|
54
|
+
return if next_command.nil?# || next_command.native?
|
55
|
+
Command.do(next_command.file, command: next_command)
|
56
|
+
end
|
57
|
+
|
58
|
+
def backup
|
59
|
+
@previous_file_dirty_content = @file.dirty_content.clone
|
60
|
+
@previous_file_caret_position = @file.caret_position
|
61
|
+
@previous_file_selection_count = @file.selection_count
|
62
|
+
end
|
63
|
+
|
64
|
+
def restore
|
65
|
+
@file.dirty_content = @previous_file_dirty_content.clone
|
66
|
+
@file.caret_position = @previous_file_caret_position
|
67
|
+
@file.selection_count = @previous_file_selection_count
|
68
|
+
end
|
69
|
+
|
70
|
+
def execute
|
71
|
+
@file.send(@method)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -15,41 +15,66 @@ module Glimmer
|
|
15
15
|
@thread = Thread.new(@filewatcher) do |fw|
|
16
16
|
fw.watch do |filename, event|
|
17
17
|
if @last_update.nil? || (Time.now.to_f - @last_update) > REFRESH_DELAY
|
18
|
-
dir.refresh if filename != dir.selected_child_path
|
18
|
+
dir.refresh if !filename.include?('new_file') && !dir.selected_child_path_history.include?(filename) && filename != dir.selected_child_path
|
19
19
|
end
|
20
20
|
@last_update = Time.now.to_f
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
24
|
-
end
|
24
|
+
end
|
25
25
|
end
|
26
26
|
|
27
|
-
attr_accessor :selected_child, :filter, :children, :filtered_path_options, :filtered_path
|
28
|
-
attr_reader :
|
27
|
+
attr_accessor :selected_child, :filter, :children, :filtered_path_options, :filtered_path, :path, :display_path
|
28
|
+
attr_reader :name, :parent
|
29
|
+
attr_writer :all_children, :children
|
29
30
|
|
30
31
|
def initialize(path)
|
31
|
-
@
|
32
|
+
@display_path = path
|
33
|
+
@path = ::File.expand_path(@display_path)
|
34
|
+
@name = ::File.basename(::File.expand_path(path))
|
32
35
|
self.filtered_path_options = []
|
33
36
|
end
|
37
|
+
|
38
|
+
def name=(the_name)
|
39
|
+
self.display_path = display_path.sub(/#{Regexp.escape(@name)}$/, the_name)
|
40
|
+
@name = the_name
|
41
|
+
new_path = ::File.expand_path(display_path)
|
42
|
+
FileUtils.mv(path, new_path)
|
43
|
+
self.path = display_path
|
44
|
+
end
|
34
45
|
|
35
46
|
def children
|
36
47
|
@children ||= retrieve_children
|
37
48
|
end
|
38
|
-
|
49
|
+
|
39
50
|
def retrieve_children
|
40
|
-
::Dir.glob(::File.join(@
|
51
|
+
::Dir.glob(::File.join(@display_path, '*')).map {|p| ::File.file?(p) ? Gladiator::File.new(p) : Gladiator::Dir.new(p)}.sort_by {|c| c.path.to_s.downcase }.sort_by {|c| c.class.name }
|
41
52
|
end
|
42
53
|
|
43
|
-
def
|
54
|
+
def selected_child_path_history
|
55
|
+
@selected_child_path_history ||= []
|
56
|
+
end
|
57
|
+
|
58
|
+
def pause_refresh
|
59
|
+
@refresh_paused = true
|
60
|
+
end
|
61
|
+
|
62
|
+
def resume_refresh
|
63
|
+
@refresh_paused = false
|
64
|
+
end
|
65
|
+
|
66
|
+
def refresh(async: true, force: false)
|
67
|
+
return if @refresh_paused && !force
|
44
68
|
new_all_children = retrieve_all_children
|
45
|
-
new_children = retrieve_children
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
69
|
+
new_children = retrieve_children
|
70
|
+
refresh_operation = lambda do
|
71
|
+
self.all_children = new_all_children
|
72
|
+
self.children = new_children
|
73
|
+
end
|
74
|
+
if async
|
75
|
+
async_exec(&refresh_operation)
|
76
|
+
else
|
77
|
+
sync_exec(&refresh_operation)
|
53
78
|
end
|
54
79
|
end
|
55
80
|
|
@@ -66,7 +91,7 @@ module Glimmer
|
|
66
91
|
return if filter.nil?
|
67
92
|
all_children_files.select do |child|
|
68
93
|
child.path.downcase.include?(filter.downcase) ||
|
69
|
-
child.path.downcase.gsub(/[_
|
94
|
+
child.path.downcase.gsub(/[_\/\.]/, '').include?(filter.downcase)
|
70
95
|
end.sort_by {|c| c.path.to_s.downcase}
|
71
96
|
end
|
72
97
|
|
@@ -75,7 +100,7 @@ module Glimmer
|
|
75
100
|
end
|
76
101
|
|
77
102
|
def retrieve_all_children
|
78
|
-
::Dir.glob(::File.join(@
|
103
|
+
::Dir.glob(::File.join(@display_path, '**', '*')).map {|p| ::File.file?(p) ? Gladiator::File.new(p) : Gladiator::Dir.new(p)}
|
79
104
|
end
|
80
105
|
|
81
106
|
def all_children_files
|
@@ -83,28 +108,46 @@ module Glimmer
|
|
83
108
|
end
|
84
109
|
|
85
110
|
def selected_child_path=(selected_path)
|
86
|
-
if selected_path
|
111
|
+
return if selected_path.nil? ||
|
112
|
+
::Dir.exist?(selected_path) ||
|
113
|
+
(selected_child && ::File.expand_path(selected_child.path) == ::File.expand_path(selected_path))
|
114
|
+
if ::File.file?(selected_path)
|
87
115
|
@selected_child&.write_dirty_content
|
88
116
|
new_child = Gladiator::File.new(selected_path)
|
89
117
|
begin
|
90
118
|
unless new_child.dirty_content.nil?
|
91
119
|
self.selected_child&.stop_filewatcher
|
120
|
+
selected_child_path_history << new_child.path if new_child && !selected_child_path_history.include?(new_child.path)
|
92
121
|
self.selected_child = new_child
|
93
122
|
self.selected_child.start_filewatcher
|
94
123
|
end
|
95
124
|
rescue
|
96
125
|
# no op
|
97
126
|
end
|
127
|
+
else
|
128
|
+
refresh
|
98
129
|
end
|
99
130
|
end
|
100
131
|
|
101
132
|
def selected_child_path
|
102
133
|
@selected_child&.path
|
103
134
|
end
|
135
|
+
|
136
|
+
def delete!
|
137
|
+
FileUtils.rm_rf(path)
|
138
|
+
end
|
104
139
|
|
105
140
|
def to_s
|
106
141
|
path
|
107
142
|
end
|
143
|
+
|
144
|
+
def eql?(other)
|
145
|
+
self.path.eql?(other&.path)
|
146
|
+
end
|
147
|
+
|
148
|
+
def hash
|
149
|
+
self.path.hash
|
150
|
+
end
|
108
151
|
end
|
109
152
|
end
|
110
153
|
end
|
@@ -5,14 +5,18 @@ module Glimmer
|
|
5
5
|
class File
|
6
6
|
include Glimmer
|
7
7
|
|
8
|
-
attr_accessor :dirty_content, :line_numbers_content, :
|
9
|
-
attr_reader :
|
8
|
+
attr_accessor :dirty_content, :line_numbers_content, :selection, :selection_count, :line_number, :find_text, :replace_text, :top_index, :path, :display_path, :case_sensitive
|
9
|
+
attr_reader :name
|
10
10
|
|
11
11
|
def initialize(path)
|
12
12
|
raise "Not a file path: #{path}" unless ::File.file?(path)
|
13
|
+
@command_history = []
|
13
14
|
@display_path = path
|
14
15
|
@name = ::File.basename(path)
|
15
16
|
@path = ::File.expand_path(path)
|
17
|
+
@top_index = 0
|
18
|
+
@selection_count = 0
|
19
|
+
@selection = Point.new(0, 0 + @selection_count)
|
16
20
|
read_dirty_content = ::File.read(path)
|
17
21
|
begin
|
18
22
|
# test read dirty content
|
@@ -21,8 +25,9 @@ module Glimmer
|
|
21
25
|
lines_text_size = lines.size.to_s.size
|
22
26
|
self.line_numbers_content = lines.size.times.map {|n| (' ' * (lines_text_size - (n+1).to_s.size)) + (n+1).to_s }.join("\n")
|
23
27
|
end
|
28
|
+
@line_number = 1
|
24
29
|
self.dirty_content = read_dirty_content
|
25
|
-
observe(self, :
|
30
|
+
observe(self, :selection) do
|
26
31
|
self.line_number = line_index_for_caret_position(caret_position) + 1
|
27
32
|
end
|
28
33
|
observe(self, :line_number) do
|
@@ -36,6 +41,42 @@ module Glimmer
|
|
36
41
|
# no op in case of a binary file
|
37
42
|
end
|
38
43
|
end
|
44
|
+
|
45
|
+
# to use for widget data-binding
|
46
|
+
def content=(value)
|
47
|
+
Command.do(self) # record a native (OS-widget) operation
|
48
|
+
self.dirty_content = value
|
49
|
+
end
|
50
|
+
|
51
|
+
def content
|
52
|
+
dirty_content
|
53
|
+
end
|
54
|
+
|
55
|
+
def caret_position=(value)
|
56
|
+
self.selection = Point.new(value, value + selection_count.to_i)
|
57
|
+
if OS.linux?
|
58
|
+
async_exec do
|
59
|
+
self.top_index = line_index_for_caret_position(value)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def caret_position
|
65
|
+
selection.x
|
66
|
+
end
|
67
|
+
|
68
|
+
def name=(the_name)
|
69
|
+
self.display_path = display_path.sub(/#{Regexp.escape(@name)}$/, the_name)
|
70
|
+
@name = the_name
|
71
|
+
new_path = ::File.expand_path(display_path)
|
72
|
+
FileUtils.mv(path, new_path)
|
73
|
+
self.path = new_path
|
74
|
+
end
|
75
|
+
|
76
|
+
def dirty_content=(the_content)
|
77
|
+
@dirty_content = the_content if ::File.exist?(path)
|
78
|
+
notify_observers(:content)
|
79
|
+
end
|
39
80
|
|
40
81
|
def start_filewatcher
|
41
82
|
@filewatcher = Filewatcher.new(@path)
|
@@ -65,6 +106,7 @@ module Glimmer
|
|
65
106
|
end
|
66
107
|
|
67
108
|
def write_dirty_content
|
109
|
+
return unless ::File.exist?(path)
|
68
110
|
format_dirty_content_for_writing!
|
69
111
|
::File.write(path, dirty_content) if ::File.exists?(path)
|
70
112
|
rescue => e
|
@@ -73,12 +115,39 @@ module Glimmer
|
|
73
115
|
end
|
74
116
|
|
75
117
|
def write_raw_dirty_content
|
118
|
+
return unless ::File.exist?(path)
|
76
119
|
::File.write(path, dirty_content) if ::File.exists?(path)
|
77
120
|
rescue => e
|
78
121
|
puts "Error in writing raw dirty content for #{path}"
|
79
122
|
puts e.full_message
|
80
123
|
end
|
81
|
-
|
124
|
+
|
125
|
+
def current_line_indentation
|
126
|
+
current_line.to_s.match(/^(\s+)/).to_a[1].to_s
|
127
|
+
end
|
128
|
+
|
129
|
+
def current_line
|
130
|
+
lines[line_number - 1]
|
131
|
+
end
|
132
|
+
|
133
|
+
def delete!
|
134
|
+
FileUtils.rm(path)
|
135
|
+
end
|
136
|
+
|
137
|
+
def prefix_new_line!
|
138
|
+
the_lines = lines
|
139
|
+
the_lines[line_number-1...line_number-1] = [current_line_indentation]
|
140
|
+
self.dirty_content = the_lines.join("\n")
|
141
|
+
self.caret_position = caret_position_for_line_index(line_number-1) + current_line_indentation.size
|
142
|
+
end
|
143
|
+
|
144
|
+
def insert_new_line!
|
145
|
+
the_lines = lines
|
146
|
+
the_lines[line_number...line_number] = [current_line_indentation]
|
147
|
+
self.dirty_content = the_lines.join("\n")
|
148
|
+
self.caret_position = caret_position_for_line_index(line_number) + current_line_indentation.size
|
149
|
+
end
|
150
|
+
|
82
151
|
def comment_line!
|
83
152
|
old_lines = lines
|
84
153
|
return if old_lines.size < 1
|
@@ -150,7 +219,7 @@ module Glimmer
|
|
150
219
|
delta = 0
|
151
220
|
line_indices_for_selection(caret_position, selection_count).each do |the_line_index|
|
152
221
|
the_line = old_lines[the_line_index]
|
153
|
-
if the_line.start_with?(' ')
|
222
|
+
if the_line.to_s.start_with?(' ')
|
154
223
|
new_lines[the_line_index] = the_line.sub(/ /, '')
|
155
224
|
delta = -2
|
156
225
|
elsif the_line.start_with?(' ')
|
@@ -207,7 +276,7 @@ module Glimmer
|
|
207
276
|
end
|
208
277
|
|
209
278
|
def find_next
|
210
|
-
return if find_text.to_s.empty?
|
279
|
+
return if find_text.to_s.empty?
|
211
280
|
all_lines = lines
|
212
281
|
the_line_index = line_index_for_caret_position(caret_position)
|
213
282
|
line_position = line_position_for_caret_position(caret_position)
|
@@ -218,8 +287,8 @@ module Glimmer
|
|
218
287
|
the_index = (the_index + rotation)%all_lines.size
|
219
288
|
start_position = 0
|
220
289
|
start_position = line_position + find_text.to_s.size if i == 0 && the_index == the_line_index && found_text?(caret_position)
|
221
|
-
text_to_find_in = the_line
|
222
|
-
occurrence_index = text_to_find_in.index(find_text.to_s.downcase)
|
290
|
+
text_to_find_in = the_line[start_position..-1]
|
291
|
+
occurrence_index = case_sensitive ? text_to_find_in&.index(find_text.to_s) : text_to_find_in&.downcase&.index(find_text.to_s.downcase)
|
223
292
|
if occurrence_index
|
224
293
|
self.caret_position = caret_position_for_line_index(the_index) + start_position + occurrence_index
|
225
294
|
self.selection_count = find_text.to_s.size
|
@@ -273,18 +342,22 @@ module Glimmer
|
|
273
342
|
end
|
274
343
|
|
275
344
|
def page_up
|
345
|
+
self.selection_count = 0
|
276
346
|
self.line_number = [(self.line_number - 15), 1].max
|
277
347
|
end
|
278
348
|
|
279
349
|
def page_down
|
350
|
+
self.selection_count = 0
|
280
351
|
self.line_number = [(self.line_number + 15), lines.size].min
|
281
352
|
end
|
282
353
|
|
283
354
|
def home
|
355
|
+
self.selection_count = 0
|
284
356
|
self.line_number = 1
|
285
357
|
end
|
286
358
|
|
287
359
|
def end
|
360
|
+
self.selection_count = 0
|
288
361
|
self.line_number = lines.size
|
289
362
|
end
|
290
363
|
|
@@ -388,6 +461,14 @@ module Glimmer
|
|
388
461
|
def to_s
|
389
462
|
path
|
390
463
|
end
|
464
|
+
|
465
|
+
def eql?(other)
|
466
|
+
self.path.eql?(other&.path)
|
467
|
+
end
|
468
|
+
|
469
|
+
def hash
|
470
|
+
self.path.hash
|
471
|
+
end
|
391
472
|
end
|
392
473
|
end
|
393
474
|
end
|
@@ -1,8 +1,19 @@
|
|
1
|
+
begin
|
2
|
+
require 'puts_debuggerer' if ENV['puts_debuggerer'].to_s.downcase == 'true'
|
3
|
+
rescue LoadError
|
4
|
+
# no op
|
5
|
+
end
|
6
|
+
require 'fileutils'
|
7
|
+
require 'os'
|
8
|
+
|
1
9
|
require 'models/glimmer/gladiator/dir'
|
2
10
|
require 'models/glimmer/gladiator/file'
|
11
|
+
require 'models/glimmer/gladiator/command'
|
3
12
|
|
4
13
|
require 'views/glimmer/gladiator/text_editor'
|
5
14
|
|
15
|
+
java_import 'org.eclipse.swt.custom.TreeEditor'
|
16
|
+
|
6
17
|
Clipboard.implementation = Clipboard::Java
|
7
18
|
Clipboard.copy(Clipboard.paste) # pre-initialize library to avoid slowdown during use
|
8
19
|
|
@@ -10,6 +21,8 @@ module Glimmer
|
|
10
21
|
# Gladiator (Glimmer Editor)
|
11
22
|
class Gladiator
|
12
23
|
include Glimmer::UI::CustomShell
|
24
|
+
|
25
|
+
COMMAND_KEY = OS.mac? ? :command : :ctrl
|
13
26
|
|
14
27
|
## Add options like the following to configure CustomShell by outside consumers
|
15
28
|
#
|
@@ -22,68 +35,117 @@ module Glimmer
|
|
22
35
|
#
|
23
36
|
before_body {
|
24
37
|
Display.setAppName('Gladiator')
|
25
|
-
local_dir = ENV['LOCAL_DIR'] || '.'
|
26
|
-
@config_file_path = ::File.join(local_dir, '.gladiator')
|
27
|
-
@config = {}
|
28
|
-
Gladiator::Dir.local_dir.all_children # pre-caches children
|
29
38
|
@display = display {
|
30
39
|
on_event_keydown { |key_event|
|
31
|
-
if
|
32
|
-
if @text_editor
|
40
|
+
if key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'f'
|
41
|
+
if @text_editor&.text_widget&.getSelectionText && @text_editor&.text_widget&.getSelectionText&.size.to_i > 0
|
33
42
|
@find_text.swt_widget.setText @text_editor.text_widget.getSelectionText
|
34
43
|
end
|
35
44
|
@find_text.swt_widget.selectAll
|
36
45
|
@find_text.swt_widget.setFocus
|
37
|
-
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask,
|
46
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'c'
|
38
47
|
Clipboard.copy(Gladiator::Dir.local_dir.selected_child.path)
|
39
|
-
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask,
|
48
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'g'
|
40
49
|
Gladiator::Dir.local_dir.selected_child.find_previous
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask,
|
50
|
-
|
50
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'w'
|
51
|
+
@tab_folder.swt_widget.getItems.each do |tab_item|
|
52
|
+
Dir.local_dir.selected_child_path_history.delete(tab_item.getData('file_path'))
|
53
|
+
tab_item.getData('proxy').dispose
|
54
|
+
end
|
55
|
+
@tab_item = @text_editor = Dir.local_dir.selected_child = nil
|
56
|
+
@filter_text.swt_widget.selectAll
|
57
|
+
@filter_text.swt_widget.setFocus
|
58
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :alt) && extract_char(key_event) == 'w'
|
59
|
+
other_tab_items.each do |tab_item|
|
60
|
+
Dir.local_dir.selected_child_path_history.delete(tab_item.getData('file_path'))
|
61
|
+
tab_item.getData('proxy').dispose
|
62
|
+
end
|
63
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'w'
|
64
|
+
if selected_tab_item
|
65
|
+
Dir.local_dir.selected_child_path_history.delete(Dir.local_dir.selected_child.path)
|
66
|
+
selected_tab_item.getData('proxy').dispose
|
67
|
+
if selected_tab_item.nil?
|
68
|
+
@tab_item = @text_editor = Dir.local_dir.selected_child = nil
|
69
|
+
@filter_text.swt_widget.selectAll
|
70
|
+
@filter_text.swt_widget.setFocus
|
71
|
+
else
|
72
|
+
@text_editor.text_widget.setFocus
|
73
|
+
end
|
74
|
+
end
|
75
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == ']'
|
76
|
+
@tab_folder.swt_widget.setSelection((@tab_folder.swt_widget.getSelectionIndex() + 1) % @tab_folder.swt_widget.getItemCount) if @tab_folder.swt_widget.getItemCount > 0
|
77
|
+
@text_editor.text_widget.setFocus
|
78
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == '['
|
79
|
+
@tab_folder.swt_widget.setSelection((@tab_folder.swt_widget.getSelectionIndex() - 1) % @tab_folder.swt_widget.getItemCount) if @tab_folder.swt_widget.getItemCount > 0
|
80
|
+
@text_editor.text_widget.setFocus
|
81
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '1'
|
82
|
+
@tab_folder.swt_widget.setSelection(0) if @tab_folder.swt_widget.getItemCount >= 1
|
83
|
+
@text_editor.text_widget.setFocus
|
84
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '2'
|
85
|
+
@tab_folder.swt_widget.setSelection(1) if @tab_folder.swt_widget.getItemCount >= 2
|
86
|
+
@text_editor.text_widget.setFocus
|
87
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '3'
|
88
|
+
@tab_folder.swt_widget.setSelection(2) if @tab_folder.swt_widget.getItemCount >= 3
|
89
|
+
@text_editor.text_widget.setFocus
|
90
|
+
@tab_folder.swt_widget.setSelection(3) if @tab_folder.swt_widget.getItemCount >= 4
|
51
91
|
@text_editor.text_widget.setFocus
|
52
|
-
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask,
|
53
|
-
@tab_folder.swt_widget.setSelection(
|
92
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '5'
|
93
|
+
@tab_folder.swt_widget.setSelection(4) if @tab_folder.swt_widget.getItemCount >= 5
|
54
94
|
@text_editor.text_widget.setFocus
|
55
|
-
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask,
|
56
|
-
|
95
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '4'
|
96
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '6'
|
97
|
+
@tab_folder.swt_widget.setSelection(5) if @tab_folder.swt_widget.getItemCount >= 6
|
57
98
|
@text_editor.text_widget.setFocus
|
58
|
-
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask,
|
99
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '7'
|
100
|
+
@tab_folder.swt_widget.setSelection(6) if @tab_folder.swt_widget.getItemCount >= 7
|
101
|
+
@text_editor.text_widget.setFocus
|
102
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '8'
|
103
|
+
@tab_folder.swt_widget.setSelection(7) if @tab_folder.swt_widget.getItemCount >= 8
|
104
|
+
@text_editor.text_widget.setFocus
|
105
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '9'
|
59
106
|
@tab_folder.swt_widget.setSelection(@tab_folder.swt_widget.getItemCount - 1) if @tab_folder.swt_widget.getItemCount > 0
|
60
107
|
@text_editor.text_widget.setFocus
|
61
|
-
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask,
|
108
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 'g'
|
62
109
|
Gladiator::Dir.local_dir.selected_child.find_next
|
63
|
-
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask,
|
110
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 'l'
|
64
111
|
@line_number_text.swt_widget.selectAll
|
65
112
|
@line_number_text.swt_widget.setFocus
|
66
|
-
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask,
|
113
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 'r'
|
67
114
|
@filter_text.swt_widget.selectAll
|
68
115
|
@filter_text.swt_widget.setFocus
|
69
|
-
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask,
|
116
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 't'
|
117
|
+
select_tree_item unless @rename_in_progress
|
70
118
|
@tree.swt_widget.setFocus
|
119
|
+
elsif key_event.keyCode == swt(:esc)
|
120
|
+
if @text_editor
|
121
|
+
Dir.local_dir.selected_child_path = @text_editor.file.path
|
122
|
+
@text_editor.text_widget.setFocus
|
123
|
+
end
|
71
124
|
end
|
72
125
|
}
|
73
126
|
}
|
127
|
+
|
128
|
+
local_dir = ENV['LOCAL_DIR'] || '.'
|
129
|
+
@config_file_path = ::File.join(local_dir, '.gladiator')
|
130
|
+
@config = {}
|
131
|
+
Gladiator::Dir.local_dir.all_children # pre-caches children
|
74
132
|
}
|
75
133
|
|
76
134
|
## Uncomment after_body block to setup observers for widgets in body
|
77
135
|
#
|
78
136
|
after_body {
|
137
|
+
observe(Gladiator::Dir.local_dir, 'children') do
|
138
|
+
select_tree_item unless @rename_in_progress
|
139
|
+
end
|
79
140
|
observe(Gladiator::Dir.local_dir, 'selected_child') do
|
141
|
+
select_tree_item unless @rename_in_progress
|
80
142
|
selected_file = Gladiator::Dir.local_dir.selected_child
|
81
|
-
found_tab_item =
|
143
|
+
found_tab_item = selected_tab_item
|
82
144
|
if found_tab_item
|
83
145
|
@tab_folder.swt_widget.setSelection(found_tab_item)
|
84
146
|
@tab_item = found_tab_item.getData('tab_item')
|
85
147
|
@text_editor = found_tab_item.getData('text_editor')
|
86
|
-
|
148
|
+
elsif selected_file
|
87
149
|
@tab_folder.content {
|
88
150
|
@tab_item = tab_item { |the_tab_item|
|
89
151
|
text selected_file.name
|
@@ -98,6 +160,7 @@ module Glimmer
|
|
98
160
|
@tab_item.swt_tab_item.setData('file_path', selected_file.path)
|
99
161
|
@tab_item.swt_tab_item.setData('tab_item', @tab_item)
|
100
162
|
@tab_item.swt_tab_item.setData('text_editor', @text_editor)
|
163
|
+
@tab_item.swt_tab_item.setData('proxy', @tab_item)
|
101
164
|
}
|
102
165
|
@tab_folder.swt_widget.setSelection(@tab_item.swt_tab_item)
|
103
166
|
body_root.pack_same_size
|
@@ -136,6 +199,9 @@ module Glimmer
|
|
136
199
|
on_control_moved {
|
137
200
|
save_config
|
138
201
|
}
|
202
|
+
on_shell_deactivated {
|
203
|
+
@text_editor&.file&.write_dirty_content
|
204
|
+
}
|
139
205
|
composite {
|
140
206
|
grid_layout 1, false
|
141
207
|
layout_data(:fill, :fill, false, true) {
|
@@ -144,69 +210,117 @@ module Glimmer
|
|
144
210
|
@filter_text = text {
|
145
211
|
layout_data :fill, :center, true, false
|
146
212
|
text bind(Gladiator::Dir.local_dir, 'filter')
|
147
|
-
|
213
|
+
on_key_pressed { |key_event|
|
148
214
|
if key_event.keyCode == swt(:tab) ||
|
149
215
|
key_event.keyCode == swt(:cr) ||
|
150
|
-
key_event.keyCode == swt(:lf) ||
|
151
216
|
key_event.keyCode == swt(:arrow_up) ||
|
152
217
|
key_event.keyCode == swt(:arrow_down)
|
153
218
|
@list.swt_widget.select(0) if @list.swt_widget.getSelectionIndex() == -1
|
154
219
|
@list.swt_widget.setFocus
|
155
|
-
elsif key_event.keyCode == swt(:esc)
|
156
|
-
@text_editor.text_widget.setFocus
|
157
220
|
end
|
158
221
|
}
|
159
222
|
}
|
160
223
|
composite {
|
224
|
+
fill_layout(:vertical) {
|
225
|
+
spacing 5
|
226
|
+
}
|
161
227
|
layout_data(:fill, :fill, true, true)
|
162
228
|
@list = list(:border, :h_scroll, :v_scroll) {
|
163
|
-
layout_data(:fill, :fill, true, true) {
|
164
|
-
#exclude bind(Gladiator::Dir.local_dir, :filter) {|f| !f}
|
165
|
-
}
|
166
229
|
#visible bind(Gladiator::Dir, 'local_dir.filter') {|f| !!f}
|
167
230
|
selection bind(Gladiator::Dir.local_dir, :filtered_path)
|
168
231
|
on_mouse_up {
|
169
232
|
Gladiator::Dir.local_dir.selected_child_path = @list.swt_widget.getSelection.first
|
170
233
|
}
|
171
234
|
on_key_pressed { |key_event|
|
172
|
-
if Glimmer::SWT::SWTProxy.include?(key_event.keyCode, :cr)
|
235
|
+
if Glimmer::SWT::SWTProxy.include?(key_event.keyCode, :cr)
|
173
236
|
Gladiator::Dir.local_dir.selected_child_path = @list.swt_widget.getSelection.first
|
174
|
-
@text_editor
|
237
|
+
@text_editor&.text_widget&.setFocus
|
175
238
|
end
|
176
239
|
}
|
177
240
|
}
|
178
241
|
@tree = tree(:virtual, :border, :h_scroll, :v_scroll) {
|
179
|
-
layout_data(:fill, :fill, true, true) {
|
180
|
-
#exclude bind(Gladiator::Dir.local_dir, :filter) {|f| !!f}
|
181
|
-
}
|
182
242
|
#visible bind(Gladiator::Dir, 'local_dir.filter') {|f| !f}
|
183
|
-
items bind(Gladiator::Dir, :local_dir), tree_properties(children: :children, text: :
|
184
|
-
|
185
|
-
|
243
|
+
items bind(Gladiator::Dir, :local_dir), tree_properties(children: :children, text: :name)
|
244
|
+
menu {
|
245
|
+
@open_menu_item = menu_item {
|
246
|
+
text 'Open'
|
247
|
+
on_widget_selected {
|
248
|
+
Gladiator::Dir.local_dir.selected_child_path = extract_tree_item_path(@tree.swt_widget.getSelection.first)
|
249
|
+
}
|
250
|
+
}
|
251
|
+
menu_item(:separator)
|
252
|
+
menu_item {
|
253
|
+
text 'Delete'
|
254
|
+
on_widget_selected {
|
255
|
+
tree_item = @tree.swt_widget.getSelection.first
|
256
|
+
delete_tree_item(tree_item)
|
257
|
+
}
|
258
|
+
}
|
259
|
+
menu_item {
|
260
|
+
text 'Refresh'
|
261
|
+
on_widget_selected {
|
262
|
+
Gladiator::Dir.local_dir.refresh
|
263
|
+
}
|
264
|
+
}
|
265
|
+
menu_item {
|
266
|
+
text 'Rename'
|
267
|
+
on_widget_selected {
|
268
|
+
rename_selected_tree_item
|
269
|
+
}
|
270
|
+
}
|
271
|
+
menu_item {
|
272
|
+
text 'New Directory'
|
273
|
+
on_widget_selected {
|
274
|
+
add_new_directory_to_selected_tree_item
|
275
|
+
}
|
276
|
+
}
|
277
|
+
menu_item {
|
278
|
+
text 'New File'
|
279
|
+
on_widget_selected {
|
280
|
+
add_new_file_to_selected_tree_item
|
281
|
+
}
|
282
|
+
}
|
283
|
+
}
|
284
|
+
on_event_menudetect { |event|
|
285
|
+
path = extract_tree_item_path(@tree.swt_widget.getSelection.first)
|
286
|
+
@open_menu_item.swt_widget.setEnabled(!::Dir.exist?(path)) if path
|
287
|
+
}
|
288
|
+
on_mouse_up {
|
289
|
+
Gladiator::Dir.local_dir.selected_child_path = extract_tree_item_path(@tree.swt_widget.getSelection&.first)
|
290
|
+
@text_editor&.text_widget&.setFocus
|
186
291
|
}
|
187
292
|
on_key_pressed { |key_event|
|
188
|
-
if Glimmer::SWT::SWTProxy.include?(key_event.keyCode, :cr)
|
189
|
-
Gladiator::Dir.local_dir.selected_child_path = @tree.swt_widget.getSelection&.first
|
190
|
-
@text_editor
|
293
|
+
if Glimmer::SWT::SWTProxy.include?(key_event.keyCode, :cr)
|
294
|
+
Gladiator::Dir.local_dir.selected_child_path = extract_tree_item_path(@tree.swt_widget.getSelection&.first)
|
295
|
+
@text_editor&.text_widget&.setFocus
|
191
296
|
end
|
192
297
|
}
|
193
298
|
on_paint_control {
|
194
299
|
root_item = @tree.swt_widget.getItems.first
|
195
300
|
if root_item && !root_item.getExpanded
|
196
|
-
root_item.setExpanded
|
301
|
+
root_item.setExpanded(true)
|
197
302
|
end
|
198
303
|
}
|
199
304
|
}
|
200
305
|
}
|
306
|
+
|
307
|
+
@tree_editor = TreeEditor.new(@tree.swt_widget);
|
308
|
+
@tree_editor.horizontalAlignment = swt(:left);
|
309
|
+
@tree_editor.grabHorizontal = true;
|
310
|
+
@tree_editor.minimumHeight = 20;
|
311
|
+
|
201
312
|
}
|
202
313
|
@editor_container = composite {
|
203
314
|
grid_layout 1, false
|
204
315
|
layout_data :fill, :fill, true, true
|
205
316
|
composite {
|
206
|
-
grid_layout
|
317
|
+
grid_layout 3, false
|
318
|
+
|
319
|
+
# row 1
|
320
|
+
|
207
321
|
@file_path_label = styled_text(:none) {
|
208
322
|
layout_data(:fill, :fill, true, false) {
|
209
|
-
horizontal_span
|
323
|
+
horizontal_span 3
|
210
324
|
}
|
211
325
|
background color(:widget_background)
|
212
326
|
editable false
|
@@ -219,36 +333,65 @@ module Glimmer
|
|
219
333
|
@file_path_label.swt_widget.setSelection(0, 0)
|
220
334
|
}
|
221
335
|
}
|
336
|
+
|
337
|
+
# row 2
|
338
|
+
|
222
339
|
label {
|
223
340
|
text 'Line:'
|
224
341
|
}
|
225
342
|
@line_number_text = text {
|
226
343
|
layout_data(:fill, :fill, true, false) {
|
227
|
-
minimum_width
|
344
|
+
minimum_width 400
|
228
345
|
}
|
229
346
|
text bind(Gladiator::Dir.local_dir, 'selected_child.line_number', on_read: :to_s, on_write: :to_i)
|
230
347
|
on_key_pressed { |key_event|
|
231
348
|
if key_event.keyCode == swt(:cr)
|
232
|
-
@text_editor
|
349
|
+
@text_editor&.text_widget&.setFocus
|
233
350
|
end
|
234
351
|
}
|
352
|
+
on_verify_text { |event|
|
353
|
+
event.doit = !event.text.match(/^\d*$/).to_a.empty?
|
354
|
+
}
|
235
355
|
}
|
356
|
+
label
|
357
|
+
|
358
|
+
# row 3
|
359
|
+
|
236
360
|
label {
|
237
361
|
text 'Find:'
|
238
362
|
}
|
239
363
|
@find_text = text {
|
240
364
|
layout_data(:fill, :fill, true, false) {
|
241
|
-
minimum_width
|
365
|
+
minimum_width 400
|
242
366
|
}
|
243
367
|
text bind(Gladiator::Dir.local_dir, 'selected_child.find_text')
|
244
368
|
on_key_pressed { |key_event|
|
369
|
+
if key_event.stateMask == swt(COMMAND_KEY) && key_event.keyCode == swt(:cr)
|
370
|
+
Dir.local_dir.selected_child.case_sensitive = !Dir.local_dir.selected_child.case_sensitive
|
371
|
+
Gladiator::Dir.local_dir.selected_child&.find_next
|
372
|
+
end
|
245
373
|
if key_event.keyCode == swt(:cr)
|
246
|
-
Gladiator::Dir.local_dir.selected_child
|
247
|
-
elsif key_event.keyCode == swt(:esc)
|
248
|
-
@text_editor.text_widget.setFocus
|
374
|
+
Gladiator::Dir.local_dir.selected_child&.find_next
|
249
375
|
end
|
250
376
|
}
|
251
377
|
}
|
378
|
+
composite {
|
379
|
+
row_layout
|
380
|
+
button(:check) {
|
381
|
+
selection bind(Dir.local_dir, 'selected_child.case_sensitive')
|
382
|
+
on_key_pressed { |key_event|
|
383
|
+
if key_event.keyCode == swt(:cr)
|
384
|
+
Gladiator::Dir.local_dir.selected_child&.find_next
|
385
|
+
end
|
386
|
+
}
|
387
|
+
}
|
388
|
+
label {
|
389
|
+
text 'Case-sensitive'
|
390
|
+
}
|
391
|
+
}
|
392
|
+
|
393
|
+
# row 4
|
394
|
+
|
252
395
|
label {
|
253
396
|
text 'Replace:'
|
254
397
|
}
|
@@ -258,16 +401,17 @@ module Glimmer
|
|
258
401
|
}
|
259
402
|
text bind(Gladiator::Dir.local_dir, 'selected_child.replace_text')
|
260
403
|
on_focus_gained {
|
261
|
-
Gladiator::Dir.local_dir.selected_child
|
404
|
+
Gladiator::Dir.local_dir.selected_child&.ensure_find_next
|
262
405
|
}
|
263
406
|
on_key_pressed { |key_event|
|
264
407
|
if key_event.keyCode == swt(:cr)
|
265
|
-
Gladiator::Dir.local_dir.selected_child
|
266
|
-
|
267
|
-
|
408
|
+
if Gladiator::Dir.local_dir.selected_child
|
409
|
+
Command.do(Gladiator::Dir.local_dir.selected_child, :replace_next!)
|
410
|
+
end
|
268
411
|
end
|
269
412
|
}
|
270
413
|
}
|
414
|
+
label
|
271
415
|
}
|
272
416
|
@tab_folder = tab_folder {
|
273
417
|
layout_data(:fill, :fill, true, true)
|
@@ -281,14 +425,19 @@ module Glimmer
|
|
281
425
|
config_yaml = ::File.read(@config_file_path)
|
282
426
|
return if config_yaml.to_s.strip.empty?
|
283
427
|
@config = YAML.load(config_yaml)
|
428
|
+
@config[:open_file_paths].to_a.each do |file_path|
|
429
|
+
Gladiator::Dir.local_dir.selected_child_path = file_path
|
430
|
+
end
|
284
431
|
Gladiator::Dir.local_dir.selected_child_path = @config[:selected_child_path] if @config[:selected_child_path]
|
285
|
-
Gladiator::Dir.local_dir.selected_child&.caret_position = Gladiator::Dir.local_dir.selected_child&.caret_position_for_caret_position_start_of_line(@config[:caret_position]) if @config[:caret_position]
|
286
|
-
Gladiator::Dir.local_dir.selected_child&.top_index = @config[:top_index] if @config[:top_index]
|
287
|
-
body_root.on_event_show
|
432
|
+
Gladiator::Dir.local_dir.selected_child&.caret_position = Gladiator::Dir.local_dir.selected_child&.caret_position_for_caret_position_start_of_line(@config[:caret_position].to_i) if @config[:caret_position]
|
433
|
+
Gladiator::Dir.local_dir.selected_child&.top_index = @config[:top_index].to_i if @config[:top_index]
|
434
|
+
body_root.on_event_show {
|
288
435
|
swt_widget.setSize(@config[:shell_width], @config[:shell_height]) if @config[:shell_width] && @config[:shell_height]
|
289
|
-
swt_widget.setLocation(@config[:shell_x], @config[:shell_y]) if @config[:shell_x] && @config[:shell_y]
|
436
|
+
swt_widget.setLocation(@config[:shell_x], @config[:shell_y]) if @config[:shell_x] && @config[:shell_y]
|
290
437
|
@loaded_config = true
|
291
|
-
|
438
|
+
}
|
439
|
+
else
|
440
|
+
@loaded_config = true
|
292
441
|
end
|
293
442
|
end
|
294
443
|
|
@@ -304,11 +453,109 @@ module Glimmer
|
|
304
453
|
shell_height: swt_widget&.getBounds&.height,
|
305
454
|
shell_x: swt_widget&.getBounds&.x,
|
306
455
|
shell_y: swt_widget&.getBounds&.y,
|
456
|
+
open_file_paths: Dir.local_dir.selected_child_path_history,
|
307
457
|
}
|
308
458
|
config_yaml = YAML.dump(@config)
|
309
459
|
::File.write(@config_file_path, config_yaml) unless config_yaml.to_s.empty?
|
310
460
|
rescue => e
|
311
461
|
puts e.full_message
|
312
462
|
end
|
463
|
+
|
464
|
+
def selected_tab_item
|
465
|
+
@tab_folder.swt_widget.getItems.detect { |ti| ti.getData('file_path') == Gladiator::Dir.local_dir.selected_child&.path }
|
466
|
+
end
|
467
|
+
|
468
|
+
def other_tab_items
|
469
|
+
@tab_folder.swt_widget.getItems.reject { |ti| ti.getData('file_path') == Gladiator::Dir.local_dir.selected_child&.path }
|
470
|
+
end
|
471
|
+
|
472
|
+
def extract_tree_item_path(tree_item)
|
473
|
+
return if tree_item.nil?
|
474
|
+
if tree_item.getParentItem
|
475
|
+
::File.join(extract_tree_item_path(tree_item.getParentItem), tree_item.getText)
|
476
|
+
else
|
477
|
+
Dir.local_dir.path
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
def select_tree_item
|
482
|
+
return unless Gladiator::Dir.local_dir.selected_child&.name
|
483
|
+
tree_items_to_select = @tree.depth_first_search { |ti| ti.getData.path == Gladiator::Dir.local_dir.selected_child.path }
|
484
|
+
@tree.swt_widget.setSelection(tree_items_to_select)
|
485
|
+
end
|
486
|
+
|
487
|
+
def delete_tree_item(tree_item)
|
488
|
+
file = tree_item.getData
|
489
|
+
parent_path = ::File.dirname(file.path)
|
490
|
+
file.delete! # TODO consider supporting command undo/redo
|
491
|
+
Dir.local_dir.refresh(async: false)
|
492
|
+
parent_tree_item = @tree.depth_first_search {|ti| ti.getData.path == parent_path}.first
|
493
|
+
@tree.swt_widget.showItem(parent_tree_item)
|
494
|
+
parent_tree_item.setExpanded(true)
|
495
|
+
# TODO close text editor tab
|
496
|
+
# if file.is_a?(::File)
|
497
|
+
# close tab
|
498
|
+
# end
|
499
|
+
end
|
500
|
+
|
501
|
+
def rename_selected_tree_item
|
502
|
+
Dir.local_dir.pause_refresh
|
503
|
+
tree_item = @tree.swt_widget.getSelection.first
|
504
|
+
rename_tree_item(tree_item)
|
505
|
+
end
|
506
|
+
|
507
|
+
def add_new_directory_to_selected_tree_item
|
508
|
+
Dir.local_dir.pause_refresh
|
509
|
+
tree_item = @tree.swt_widget.getSelection.first
|
510
|
+
directory_path = extract_tree_item_path(tree_item)
|
511
|
+
if !::Dir.exist?(directory_path)
|
512
|
+
tree_item = tree_item.getParentItem
|
513
|
+
directory_path = ::File.dirname(directory_path)
|
514
|
+
end
|
515
|
+
new_directory_path = ::File.expand_path(::File.join(directory_path, 'new_directory'))
|
516
|
+
FileUtils.mkdir_p(new_directory_path)
|
517
|
+
Dir.local_dir.refresh(async: false, force: true)
|
518
|
+
new_tree_item = @tree.depth_first_search {|ti| ti.getData.path == new_directory_path}.first
|
519
|
+
@tree.swt_widget.showItem(new_tree_item)
|
520
|
+
rename_tree_item(new_tree_item, true)
|
521
|
+
end
|
522
|
+
|
523
|
+
def add_new_file_to_selected_tree_item
|
524
|
+
Dir.local_dir.pause_refresh
|
525
|
+
tree_item = @tree.swt_widget.getSelection.first
|
526
|
+
directory_path = extract_tree_item_path(tree_item)
|
527
|
+
if !::Dir.exist?(directory_path)
|
528
|
+
tree_item = tree_item.getParentItem
|
529
|
+
directory_path = ::File.dirname(directory_path)
|
530
|
+
end
|
531
|
+
new_file_path = ::File.expand_path(::File.join(directory_path, 'new_file'))
|
532
|
+
FileUtils.touch(new_file_path)
|
533
|
+
Dir.local_dir.refresh(async: false, force: true)
|
534
|
+
new_tree_item = @tree.depth_first_search {|ti| ti.getData.path == new_file_path}.first
|
535
|
+
@tree.swt_widget.showItem(new_tree_item)
|
536
|
+
rename_tree_item(new_tree_item, true)
|
537
|
+
end
|
538
|
+
|
539
|
+
def rename_tree_item(tree_item, open_afterwards = false)
|
540
|
+
@tree.edit_tree_item(
|
541
|
+
tree_item,
|
542
|
+
after_write: -> (edited_tree_item) {
|
543
|
+
file = edited_tree_item.getData
|
544
|
+
file_path = file.path
|
545
|
+
# TODO rename file in tab title
|
546
|
+
Dir.local_dir.selected_child_path = file_path if open_afterwards
|
547
|
+
Dir.local_dir.resume_refresh
|
548
|
+
},
|
549
|
+
after_cancel: -> {
|
550
|
+
Dir.local_dir.resume_refresh
|
551
|
+
}
|
552
|
+
)
|
553
|
+
end
|
554
|
+
|
555
|
+
def extract_char(event)
|
556
|
+
event.keyCode.chr
|
557
|
+
rescue => e
|
558
|
+
nil
|
559
|
+
end
|
313
560
|
end
|
314
|
-
end
|
561
|
+
end
|
@@ -17,11 +17,11 @@ module Glimmer
|
|
17
17
|
grid_layout 2, false
|
18
18
|
@line_numbers_text = text(:multi) {
|
19
19
|
layout_data(:right, :fill, false, true)
|
20
|
-
font name: 'Consolas', height: 15
|
20
|
+
font name: 'Consolas', height: OS.mac? ? 15 : 12
|
21
21
|
background color(:widget_background)
|
22
22
|
foreground rgb(75, 75, 75)
|
23
23
|
text bind(file, 'line_numbers_content')
|
24
|
-
top_index bind(file, 'top_index')
|
24
|
+
top_index bind(file, 'top_index', read_only: true)
|
25
25
|
on_focus_gained {
|
26
26
|
@text&.swt_widget.setFocus
|
27
27
|
}
|
@@ -34,27 +34,42 @@ module Glimmer
|
|
34
34
|
}
|
35
35
|
@text = text(:multi, :border, :h_scroll, :v_scroll) {
|
36
36
|
layout_data :fill, :fill, true, true
|
37
|
-
font name: 'Consolas', height: 15
|
37
|
+
font name: 'Consolas', height: OS.mac? ? 15 : 12
|
38
38
|
foreground rgb(75, 75, 75)
|
39
|
-
text bind(file,
|
39
|
+
text bind(file, :content)
|
40
40
|
focus true
|
41
|
-
|
41
|
+
selection bind(file, 'selection')
|
42
42
|
selection_count bind(file, 'selection_count')
|
43
43
|
top_index bind(file, 'top_index')
|
44
44
|
on_focus_lost {
|
45
45
|
file&.write_dirty_content
|
46
46
|
}
|
47
47
|
on_key_pressed { |key_event|
|
48
|
-
if key_event.stateMask == swt(
|
49
|
-
|
50
|
-
elsif key_event.stateMask == swt(
|
51
|
-
|
52
|
-
elsif key_event.stateMask == swt(
|
53
|
-
file
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
48
|
+
if (Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'z') || (key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'y')
|
49
|
+
key_event.doit = !Command.redo(file)
|
50
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'z'
|
51
|
+
key_event.doit = !Command.undo(file)
|
52
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == '/'
|
53
|
+
Command.do(file, :comment_line!)
|
54
|
+
key_event.doit = false
|
55
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'k'
|
56
|
+
Command.do(file, :kill_line!)
|
57
|
+
key_event.doit = false
|
58
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'd'
|
59
|
+
Command.do(file, :duplicate_line!)
|
60
|
+
key_event.doit = false
|
61
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == '['
|
62
|
+
Command.do(file, :outdent!)
|
63
|
+
key_event.doit = false
|
64
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == ']'
|
65
|
+
Command.do(file, :indent!)
|
66
|
+
key_event.doit = false
|
67
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && key_event.keyCode == swt(:cr)
|
68
|
+
Command.do(file, :prefix_new_line!)
|
69
|
+
key_event.doit = false
|
70
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && key_event.keyCode == swt(:cr)
|
71
|
+
Command.do(file, :insert_new_line!)
|
72
|
+
key_event.doit = false
|
58
73
|
elsif key_event.keyCode == swt(:page_up)
|
59
74
|
file.page_up
|
60
75
|
key_event.doit = false
|
@@ -67,20 +82,24 @@ module Glimmer
|
|
67
82
|
elsif key_event.keyCode == swt(:end)
|
68
83
|
file.end
|
69
84
|
key_event.doit = false
|
70
|
-
elsif key_event.stateMask == swt(
|
71
|
-
file
|
85
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && key_event.keyCode == swt(:arrow_up)
|
86
|
+
Command.do(file, :move_up!)
|
72
87
|
key_event.doit = false
|
73
|
-
elsif key_event.stateMask == swt(
|
74
|
-
file
|
88
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && key_event.keyCode == swt(:arrow_down)
|
89
|
+
Command.do(file, :move_down!)
|
75
90
|
key_event.doit = false
|
76
91
|
end
|
77
92
|
}
|
78
93
|
on_verify_text { |verify_event|
|
79
94
|
key_code = verify_event.keyCode
|
80
95
|
case key_code
|
96
|
+
when swt(:cr)
|
97
|
+
if file.selection_count.to_i == 0
|
98
|
+
verify_event.text += file.current_line_indentation
|
99
|
+
end
|
81
100
|
when swt(:tab)
|
82
101
|
if file.selection_count.to_i > 0
|
83
|
-
file
|
102
|
+
Command.do(file, :indent!)
|
84
103
|
verify_event.doit = false
|
85
104
|
else
|
86
105
|
verify_event.text = ' '
|
@@ -90,6 +109,15 @@ module Glimmer
|
|
90
109
|
}
|
91
110
|
}
|
92
111
|
}
|
112
|
+
|
113
|
+
|
114
|
+
def extract_char(event)
|
115
|
+
event.keyCode.chr
|
116
|
+
rescue => e
|
117
|
+
nil
|
118
|
+
end
|
119
|
+
|
93
120
|
end
|
94
121
|
end
|
95
122
|
end
|
123
|
+
|
metadata
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-cs-gladiator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
|
-
- - "
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: 0.8.0
|
19
|
+
- - "<"
|
17
20
|
- !ruby/object:Gem::Version
|
18
|
-
version: 0.
|
21
|
+
version: 2.0.0
|
19
22
|
name: glimmer
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.8.0
|
30
|
+
- - "<"
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
32
|
+
version: 2.0.0
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
requirement: !ruby/object:Gem::Requirement
|
29
35
|
requirements:
|
@@ -124,9 +130,11 @@ extra_rdoc_files:
|
|
124
130
|
files:
|
125
131
|
- LICENSE.txt
|
126
132
|
- README.md
|
133
|
+
- VERSION
|
127
134
|
- bin/gladiator
|
128
135
|
- bin/gladiator_runner.rb
|
129
136
|
- lib/glimmer-cs-gladiator.rb
|
137
|
+
- lib/models/glimmer/gladiator/command.rb
|
130
138
|
- lib/models/glimmer/gladiator/dir.rb
|
131
139
|
- lib/models/glimmer/gladiator/file.rb
|
132
140
|
- lib/views/glimmer/gladiator.rb
|