glimmer-cs-gladiator 0.2.2 → 0.4.0
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 +30 -15
- data/VERSION +1 -1
- data/lib/glimmer-cs-gladiator.rb +23 -0
- data/lib/models/glimmer/gladiator/command.rb +8 -4
- data/lib/models/glimmer/gladiator/dir.rb +59 -24
- data/lib/models/glimmer/gladiator/file.rb +46 -25
- data/lib/views/glimmer/gladiator.rb +98 -17
- data/lib/views/glimmer/gladiator/text_editor.rb +21 -12
- metadata +13 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b17d21c81f04c1f1fc1ad516013d9e62a6abeb0900096b1bd13c95c6cf10ccd
|
4
|
+
data.tar.gz: 78d41ab949f3f40c71f2abfa26310a32f3720eecb64dcf5b90d2f155c2b35345
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bff6362c1eb4cc711c507ac90aa34e5a5b11653fe7b48f475bd829b37fdb1a87ca6b2317b35ff11f14f287aebfe2e35dee5e47ea2e9575f74c7b9971a1231b77
|
7
|
+
data.tar.gz: dc19f782cfb448e32f8054fee66797001af383cdcbedf26aeed3a3beaddef4309edefa4ca59c9be4192cd534d8a670bed35bd691ee458e3c5d22a43938e9d5e2
|
data/README.md
CHANGED
@@ -1,17 +1,20 @@
|
|
1
|
-
# <img src='https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-cs-gladiator-logo.svg' height=85 /> Gladiator 0.
|
2
|
-
## [Glimmer Custom Shell](https://github.com/AndyObtiva/glimmer#custom-shell-gem)
|
1
|
+
# <img src='https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-cs-gladiator-logo.svg' height=85 /> Gladiator 0.4.0 - [Ugliest Text Editor Ever](https://www.reddit.com/r/ruby/comments/hgve8k/gladiator_glimmer_editor_ugliest_text_editor_ever/)
|
2
|
+
## [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=40 /> Glimmer Custom Shell](https://github.com/AndyObtiva/glimmer-dsl-swt#custom-shell-gem)
|
3
3
|
[](http://badge.fury.io/rb/glimmer-cs-gladiator)
|
4
4
|
|
5
5
|

|
6
6
|
|
7
|
-
|
7
|
+
(Now, slightly less ugly with Ruby syntax highlighting colors)
|
8
|
+
|
9
|
+
Gladiator (short for Glimmer Editor) is a [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) sample project under on-going development that demonstrates how to build a text editor in Ruby using [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) (JRuby Desktop Development GUI Library).
|
8
10
|
It is not intended to be a full-fledged editor by any means, yet mostly a fun educational exercise in using [Glimmer](https://github.com/AndyObtiva/glimmer).
|
9
11
|
Gladiator is also a personal tool for shaping an editor exactly the way I like, with all the keyboard shortcuts I prefer.
|
10
|
-
I leave building truly professional text editors to software tooling experts who would hopefully use [Glimmer](https://github.com/AndyObtiva/glimmer) one day. Otherwise, I have been happily using Gladiator to develop all my [open-source projects](https://github.com/AndyObtiva) since May 2020.
|
12
|
+
I leave building truly professional text editors to software tooling experts who would hopefully use [Glimmer](https://github.com/AndyObtiva/glimmer) one day. Otherwise, I have been happily using Gladiator to develop all my [open-source projects](https://github.com/AndyObtiva) since May of 2020.
|
11
13
|
|
12
14
|
## Features
|
13
15
|
|
14
16
|
Gladiator currently supports the following text editing features (including keyboard shortcuts with Mac CMD=CTRL on Windows/Linux):
|
17
|
+
- Ruby Syntax Highlighting with colors
|
15
18
|
- File explorer navigation with context menu to open file, rename, delete, add new file, add new directory, or refresh tree (CMD+T)
|
16
19
|
- File lookup by name ignoring slashes, underscores, and dots to ease lookup (CMD+R)
|
17
20
|
- Watch open file for external changes to automatically refresh in editor
|
@@ -30,18 +33,20 @@ Gladiator currently supports the following text editing features (including keyb
|
|
30
33
|
- Indent/Unindent line/selection (CMD+] & CMD+[)
|
31
34
|
- Insert/Prefix New Line (CMD+ENTER & CMD+SHIFT+ENTER)
|
32
35
|
- Drag and Drop Text Editor Split Screen (drag a file from File Tree or File Lookup List, and it splits the screen)
|
36
|
+
- Run current Ruby file via Run Menu (CMD+SHIFT+R)
|
37
|
+
- Change Split Orientation to Horizontal/Vertical via View Menu (CMD+SHIFT+O)
|
33
38
|
|
34
39
|
## Platforms
|
35
40
|
|
36
|
-
- Mac: Gladiator works best on the Mac.
|
37
|
-
- Windows: Gladiator works
|
38
|
-
- Linux: Gladiator works with handicaps on Linux (performing text editing operations causes scroll jitter)
|
41
|
+
- Mac: Gladiator works best on the Mac. This is the platform it is most used on and receives the most maintenance for.
|
42
|
+
- Windows: Gladiator works OK on Windows, but has some annoying bugs.
|
43
|
+
- Linux: Gladiator works with very bad handicaps on Linux (performing text editing operations causes scroll jitter)
|
39
44
|
|
40
45
|
## Pre-requisites
|
41
46
|
|
42
|
-
- [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer) (
|
43
|
-
- [JRuby](https://www.jruby.org/download): Same version required by [Glimmer](https://github.com/AndyObtiva/glimmer)
|
44
|
-
- [JDK](https://www.oracle.com/java/technologies/javase-downloads.html): Same version required by [Glimmer](https://github.com/AndyObtiva/glimmer)
|
47
|
+
- [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) (JRuby Desktop Development GUI Library): '>= 4.17.2.0', '< 5.0.0.0' (dependency included in Ruby gem).
|
48
|
+
- [JRuby](https://www.jruby.org/download): Same version required by [Glimmer](https://github.com/AndyObtiva/glimmer-dsl-swt)
|
49
|
+
- [JDK](https://www.oracle.com/java/technologies/javase-downloads.html): Same version required by [Glimmer](https://github.com/AndyObtiva/glimmer-dsl-swt)
|
45
50
|
|
46
51
|
## Setup Instructions
|
47
52
|
|
@@ -73,6 +78,12 @@ You may run the `gladiator` command to bring up the text editor in the project d
|
|
73
78
|
gladiator
|
74
79
|
```
|
75
80
|
|
81
|
+
On Windows, you may need to run with extra memory via this command instead:
|
82
|
+
|
83
|
+
```
|
84
|
+
gladiator -J-Xmx3000M
|
85
|
+
```
|
86
|
+
|
76
87
|
If you are in a different directory from the project you would like to edit, then pass its path as an argument:
|
77
88
|
|
78
89
|
```
|
@@ -93,7 +104,7 @@ To reuse Gladiator as a Glimmer Custom Shell inside another Glimmer application,
|
|
93
104
|
following to the application's `Gemfile`:
|
94
105
|
|
95
106
|
```
|
96
|
-
gem 'glimmer-cs-gladiator', '~> 0.
|
107
|
+
gem 'glimmer-cs-gladiator', '~> 0.4.0'
|
97
108
|
```
|
98
109
|
|
99
110
|
Run:
|
@@ -102,7 +113,7 @@ Run:
|
|
102
113
|
jruby -S bundle
|
103
114
|
```
|
104
115
|
|
105
|
-
And, then instantiate the Gladiator [custom shell](https://github.com/AndyObtiva/glimmer#custom-shells) in your [Glimmer](https://github.com/AndyObtiva/glimmer) application via the `gladiator` keyword assuming you already have `include Glimmer` in your class, module, or main object.
|
116
|
+
And, then instantiate the Gladiator [custom shell](https://github.com/AndyObtiva/glimmer-dsl-swt#custom-shells) in your [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) application via the `gladiator` keyword assuming you already have `include Glimmer` in your class, module, or main object.
|
106
117
|
|
107
118
|
## Env Var Options
|
108
119
|
|
@@ -125,7 +136,10 @@ It currently remembers:
|
|
125
136
|
- Last opened file
|
126
137
|
- Caret position
|
127
138
|
- Top line position
|
139
|
+
- Window size
|
128
140
|
- Opened tabs
|
141
|
+
- Split tabs
|
142
|
+
- Ignore Paths
|
129
143
|
|
130
144
|
## Gotcha
|
131
145
|
|
@@ -152,11 +166,12 @@ The signal TERM is in use by the JVM and will not work correctly on this platfor
|
|
152
166
|
|
153
167
|
## Copyright
|
154
168
|
|
155
|
-
|
156
|
-
|
169
|
+
[MIT](https://opensource.org/licenses/MIT)
|
170
|
+
|
171
|
+
Copyright (c) 2020 Andy Maleh. See [LICENSE.txt](LICENSE.txt) for further details.
|
157
172
|
|
158
173
|
--
|
159
174
|
|
160
|
-
Built with [Glimmer](https://github.com/AndyObtiva/glimmer) (
|
175
|
+
[<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=40 />](https://github.com/AndyObtiva/glimmer) Built with [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) (JRuby Desktop Development GUI Library)
|
161
176
|
|
162
177
|
Gladiator icon made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a>
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/lib/glimmer-cs-gladiator.rb
CHANGED
@@ -4,3 +4,26 @@ require 'filewatcher'
|
|
4
4
|
require 'clipboard'
|
5
5
|
require 'puts_debuggerer'
|
6
6
|
require 'views/glimmer/gladiator'
|
7
|
+
|
8
|
+
# Custom Composite Initializer (avoid default margins)
|
9
|
+
Glimmer::SWT::WidgetProxy::DEFAULT_INITIALIZERS['composite'] = lambda do |composite|
|
10
|
+
if composite.get_layout.nil?
|
11
|
+
layout = GridLayout.new
|
12
|
+
composite.layout = layout
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Custom LayoutProxy initialize method (avoid default margins)
|
17
|
+
module Glimmer
|
18
|
+
module SWT
|
19
|
+
class LayoutProxy
|
20
|
+
def initialize(underscored_layout_name, widget_proxy, args)
|
21
|
+
@underscored_layout_name = underscored_layout_name
|
22
|
+
@widget_proxy = widget_proxy
|
23
|
+
args = SWTProxy.constantify_args(args)
|
24
|
+
@swt_layout = self.class.swt_layout_class_for(underscored_layout_name).new(*args)
|
25
|
+
@widget_proxy.swt_widget.setLayout(@swt_layout)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
module Glimmer
|
2
2
|
class Gladiator
|
3
|
-
class Command
|
3
|
+
class Command
|
4
4
|
class << self
|
5
|
+
include Glimmer
|
6
|
+
|
5
7
|
def command_history
|
6
8
|
@command_history ||= {}
|
7
9
|
end
|
@@ -11,7 +13,7 @@ module Glimmer
|
|
11
13
|
command_history[file] ||= [Command.new(file)]
|
12
14
|
end
|
13
15
|
|
14
|
-
def do(file, method = nil, command: nil)
|
16
|
+
def do(file, method = nil, command: nil)
|
15
17
|
command ||= Command.new(file, method)
|
16
18
|
command_history_for(file)&.last&.next_command = command
|
17
19
|
command.do
|
@@ -20,11 +22,13 @@ module Glimmer
|
|
20
22
|
|
21
23
|
def undo(file)
|
22
24
|
return if command_history_for(file).size <= 1
|
23
|
-
command_history_for(file).pop
|
25
|
+
command = command_history_for(file).pop
|
26
|
+
command&.undo
|
24
27
|
end
|
25
28
|
|
26
29
|
def redo(file)
|
27
|
-
command_history_for(file).last
|
30
|
+
command = command_history_for(file).last
|
31
|
+
command&.redo
|
28
32
|
end
|
29
33
|
end
|
30
34
|
|
@@ -9,32 +9,44 @@ module Glimmer
|
|
9
9
|
|
10
10
|
class << self
|
11
11
|
def local_dir
|
12
|
-
@local_dir
|
13
|
-
|
14
|
-
|
12
|
+
unless @local_dir
|
13
|
+
@local_dir = new(ENV['LOCAL_DIR'] || '.', true)
|
14
|
+
# @local_dir.refresh
|
15
|
+
@filewatcher = Filewatcher.new(@local_dir.path)
|
15
16
|
@thread = Thread.new(@filewatcher) do |fw|
|
16
17
|
fw.watch do |filename, event|
|
17
18
|
if @last_update.nil? || (Time.now.to_f - @last_update) > REFRESH_DELAY
|
18
|
-
|
19
|
+
@local_dir.refresh if !filename.include?('new_file') && !@local_dir.selected_child_path_history.include?(filename) && filename != @local_dir.selected_child_path
|
19
20
|
end
|
20
21
|
@last_update = Time.now.to_f
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
25
|
+
@local_dir
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
27
|
-
attr_accessor :selected_child, :filter, :children, :filtered_path_options, :filtered_path, :
|
28
|
-
attr_reader :name, :parent
|
29
|
-
attr_writer :all_children
|
29
|
+
attr_accessor :selected_child, :filter, :children, :filtered_path_options, :filtered_path, :display_path, :ignore_paths
|
30
|
+
attr_reader :name, :parent, :path, :is_local_dir
|
31
|
+
attr_writer :all_children
|
30
32
|
|
31
|
-
def initialize(path)
|
32
|
-
@
|
33
|
-
|
33
|
+
def initialize(path, is_local_dir = false)
|
34
|
+
@is_local_dir = is_local_dir
|
35
|
+
self.path = ::File.expand_path(path)
|
34
36
|
@name = ::File.basename(::File.expand_path(path))
|
37
|
+
@ignore_paths = ['packages', 'tmp', 'vendor']
|
35
38
|
self.filtered_path_options = []
|
36
39
|
end
|
37
40
|
|
41
|
+
def path=(the_path)
|
42
|
+
@path = the_path
|
43
|
+
generate_display_path
|
44
|
+
end
|
45
|
+
|
46
|
+
def generate_display_path
|
47
|
+
is_local_dir ? path : @display_path = @path.sub(Dir.local_dir.path, '').sub(/^\//, '')
|
48
|
+
end
|
49
|
+
|
38
50
|
def name=(the_name)
|
39
51
|
self.display_path = display_path.sub(/#{Regexp.escape(@name)}$/, the_name)
|
40
52
|
@name = the_name
|
@@ -48,7 +60,20 @@ module Glimmer
|
|
48
60
|
end
|
49
61
|
|
50
62
|
def retrieve_children
|
51
|
-
::Dir.glob(::File.join(@
|
63
|
+
@children = ::Dir.glob(::File.join(@path, '*')).reject do |p|
|
64
|
+
# TODO make sure to configure ignore_paths in a preferences dialog
|
65
|
+
Dir.local_dir.ignore_paths.reduce(false) do |result, ignore_path|
|
66
|
+
result || p.include?(ignore_path)
|
67
|
+
end
|
68
|
+
end.map do |p|
|
69
|
+
::File.file?(p) ? Gladiator::File.new(p) : Gladiator::Dir.new(p)
|
70
|
+
end.sort_by do |c|
|
71
|
+
c.path.to_s.downcase
|
72
|
+
end.sort_by do |c|
|
73
|
+
c.class.name
|
74
|
+
end.each do |child|
|
75
|
+
child.retrieve_children if child.is_a?(Dir)
|
76
|
+
end
|
52
77
|
end
|
53
78
|
|
54
79
|
def selected_child_path_history
|
@@ -65,11 +90,11 @@ module Glimmer
|
|
65
90
|
|
66
91
|
def refresh(async: true, force: false)
|
67
92
|
return if @refresh_paused && !force
|
68
|
-
|
69
|
-
|
93
|
+
retrieve_children
|
94
|
+
collect_all_children
|
70
95
|
refresh_operation = lambda do
|
71
|
-
|
72
|
-
|
96
|
+
notify_observers(:children)
|
97
|
+
notify_observers(:all_children)
|
73
98
|
end
|
74
99
|
if async
|
75
100
|
async_exec(&refresh_operation)
|
@@ -84,23 +109,31 @@ module Glimmer
|
|
84
109
|
else
|
85
110
|
@filter = value
|
86
111
|
end
|
87
|
-
|
112
|
+
@last_filtered = filtered.to_a
|
113
|
+
self.filtered_path_options = @last_filtered.map(&:display_path)
|
114
|
+
@last_filter = @filter
|
88
115
|
end
|
89
116
|
|
90
117
|
def filtered
|
91
118
|
return if filter.nil?
|
92
|
-
|
93
|
-
|
94
|
-
|
119
|
+
children_files = !@last_filter.to_s.empty? && filter.downcase.start_with?(@last_filter.downcase) ? @last_filtered : all_children_files
|
120
|
+
children_files.select do |child|
|
121
|
+
child_path = child.path.to_s.sub(Dir.local_dir.path, '')
|
122
|
+
child_path.downcase.include?(filter.downcase) ||
|
123
|
+
child_path.downcase.gsub(/[_\/.-]/, '').include?(filter.downcase.gsub(/[_\/.-]/, ''))
|
95
124
|
end.sort_by {|c| c.path.to_s.downcase}
|
96
125
|
end
|
97
126
|
|
98
127
|
def all_children
|
99
|
-
@all_children ||=
|
128
|
+
@all_children ||= collect_all_children
|
100
129
|
end
|
101
130
|
|
102
|
-
def
|
103
|
-
|
131
|
+
def collect_all_children
|
132
|
+
@all_children = children.reduce([]) do |output, child|
|
133
|
+
addition = [child]
|
134
|
+
addition += child.collect_all_children if child.is_a?(Dir)
|
135
|
+
output + addition
|
136
|
+
end
|
104
137
|
end
|
105
138
|
|
106
139
|
def all_children_files
|
@@ -108,9 +141,11 @@ module Glimmer
|
|
108
141
|
end
|
109
142
|
|
110
143
|
def selected_child_path=(selected_path)
|
144
|
+
full_selected_path = selected_path.include?(Dir.local_dir.path) ? selected_path : ::File.join(Dir.local_dir.path, selected_path)
|
111
145
|
return if selected_path.nil? ||
|
112
|
-
::Dir.exist?(
|
113
|
-
(selected_child &&
|
146
|
+
::Dir.exist?(full_selected_path) ||
|
147
|
+
(selected_child && selected_child.path == full_selected_path)
|
148
|
+
selected_path = full_selected_path
|
114
149
|
if ::File.file?(selected_path)
|
115
150
|
@selected_child&.write_dirty_content
|
116
151
|
new_child = Gladiator::File.new(selected_path)
|
@@ -5,16 +5,15 @@ module Glimmer
|
|
5
5
|
class File
|
6
6
|
include Glimmer
|
7
7
|
|
8
|
-
attr_accessor :dirty_content, :line_numbers_content, :selection, :
|
9
|
-
attr_reader :name
|
10
|
-
|
8
|
+
attr_accessor :dirty_content, :line_numbers_content, :selection, :line_number, :find_text, :replace_text, :top_pixel, :display_path, :case_sensitive
|
9
|
+
attr_reader :name, :path
|
10
|
+
|
11
11
|
def initialize(path)
|
12
12
|
raise "Not a file path: #{path}" unless ::File.file?(path)
|
13
13
|
@command_history = []
|
14
|
-
@display_path = path
|
15
14
|
@name = ::File.basename(path)
|
16
|
-
|
17
|
-
@
|
15
|
+
self.path = ::File.expand_path(path)
|
16
|
+
@top_pixel = 0
|
18
17
|
@selection_count = 0
|
19
18
|
@selection = Point.new(0, 0 + @selection_count)
|
20
19
|
read_dirty_content = ::File.read(path)
|
@@ -42,10 +41,22 @@ module Glimmer
|
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
44
|
+
def path=(the_path)
|
45
|
+
@path = the_path
|
46
|
+
generate_display_path
|
47
|
+
end
|
48
|
+
|
49
|
+
def generate_display_path
|
50
|
+
@display_path = @path.sub(Dir.local_dir.path, '').sub(/^\//, '')
|
51
|
+
end
|
52
|
+
|
45
53
|
# to use for widget data-binding
|
46
54
|
def content=(value)
|
47
|
-
|
48
|
-
|
55
|
+
value = value.gsub("\t", ' ')
|
56
|
+
if dirty_content != value
|
57
|
+
Command.do(self) # record a native (OS-widget) operation
|
58
|
+
self.dirty_content = value
|
59
|
+
end
|
49
60
|
end
|
50
61
|
|
51
62
|
def content
|
@@ -53,24 +64,30 @@ module Glimmer
|
|
53
64
|
end
|
54
65
|
|
55
66
|
def caret_position=(value)
|
67
|
+
old_top_pixel = top_pixel
|
56
68
|
self.selection = Point.new(value, value + selection_count.to_i)
|
57
|
-
|
58
|
-
async_exec do
|
59
|
-
self.top_index = line_index_for_caret_position(value)
|
60
|
-
end
|
61
|
-
end
|
69
|
+
self.top_pixel = old_top_pixel
|
62
70
|
end
|
63
71
|
|
64
72
|
def caret_position
|
65
73
|
selection.x
|
66
74
|
end
|
75
|
+
|
76
|
+
def selection_count
|
77
|
+
selection.y - selection.x
|
78
|
+
end
|
67
79
|
|
80
|
+
def selection_count=(value)
|
81
|
+
self.selection = Point.new(caret_position, caret_position + value.to_i)
|
82
|
+
end
|
83
|
+
|
68
84
|
def name=(the_name)
|
69
|
-
|
85
|
+
new_path = path.sub(/#{Regexp.escape(@name)}$/, the_name)
|
70
86
|
@name = the_name
|
71
|
-
|
72
|
-
|
73
|
-
|
87
|
+
if ::File.exists?(path)
|
88
|
+
FileUtils.mv(path, new_path)
|
89
|
+
self.path = new_path
|
90
|
+
end
|
74
91
|
end
|
75
92
|
|
76
93
|
def dirty_content=(the_content)
|
@@ -126,10 +143,10 @@ module Glimmer
|
|
126
143
|
current_line.to_s.match(/^(\s+)/).to_a[1].to_s
|
127
144
|
end
|
128
145
|
|
129
|
-
def current_line
|
146
|
+
def current_line
|
130
147
|
lines[line_number - 1]
|
131
148
|
end
|
132
|
-
|
149
|
+
|
133
150
|
def delete!
|
134
151
|
FileUtils.rm(path)
|
135
152
|
end
|
@@ -201,8 +218,9 @@ module Glimmer
|
|
201
218
|
old_caret_position = self.caret_position
|
202
219
|
self.dirty_content = new_lines.join("\n")
|
203
220
|
if old_selection_count.to_i > 0
|
204
|
-
|
205
|
-
|
221
|
+
caret_position_value = caret_position_for_line_index(old_caret_position_line_index)
|
222
|
+
selection_count_value = (caret_position_for_line_index(old_end_caret_line_index + 1) - caret_position_value)
|
223
|
+
self.selection = Point.new(caret_position_value, caret_position_value + selection_count_value)
|
206
224
|
else
|
207
225
|
self.caret_position = old_caret_position + delta
|
208
226
|
end
|
@@ -230,8 +248,9 @@ module Glimmer
|
|
230
248
|
end
|
231
249
|
self.dirty_content = new_lines.join("\n")
|
232
250
|
if old_selection_count.to_i > 0
|
233
|
-
|
234
|
-
|
251
|
+
caret_position_value = caret_position_for_line_index(old_caret_position_line_index)
|
252
|
+
selection_count_value = (caret_position_for_line_index(old_end_caret_line_index + 1) - caret_position_value)
|
253
|
+
self.selection = Point.new(caret_position_value, caret_position_value + selection_count_value)
|
235
254
|
else
|
236
255
|
new_caret_position = old_caret_position + delta
|
237
256
|
new_caret_position = [new_caret_position, old_caret_position_line_caret_position].max
|
@@ -281,7 +300,7 @@ module Glimmer
|
|
281
300
|
all_lines = lines
|
282
301
|
the_line_index = line_index_for_caret_position(caret_position)
|
283
302
|
line_position = line_position_for_caret_position(caret_position)
|
284
|
-
found =
|
303
|
+
found = found_text?(caret_position)
|
285
304
|
2.times do |i|
|
286
305
|
rotation = the_line_index
|
287
306
|
all_lines.rotate(rotation).each_with_index do |the_line, the_index|
|
@@ -293,6 +312,7 @@ module Glimmer
|
|
293
312
|
if occurrence_index
|
294
313
|
self.caret_position = caret_position_for_line_index(the_index) + start_position + occurrence_index
|
295
314
|
self.selection_count = find_text.to_s.size
|
315
|
+
self.selection = Point.new(self.caret_position, self.caret_position + self.selection_count)
|
296
316
|
return
|
297
317
|
end
|
298
318
|
end
|
@@ -339,7 +359,8 @@ module Glimmer
|
|
339
359
|
new_dirty_content = dirty_content
|
340
360
|
new_dirty_content[caret_position, find_text.size] = replace_text.to_s
|
341
361
|
self.dirty_content = new_dirty_content
|
342
|
-
find_next
|
362
|
+
find_next
|
363
|
+
find_next if replace_text.to_s.include?(find_text) && !replace_text.to_s.start_with?(find_text)
|
343
364
|
end
|
344
365
|
|
345
366
|
def page_up
|
@@ -15,12 +15,13 @@ module Glimmer
|
|
15
15
|
class Gladiator
|
16
16
|
include Glimmer::UI::CustomShell
|
17
17
|
|
18
|
+
APP_ROOT = ::File.expand_path('../../../..', __FILE__)
|
18
19
|
COMMAND_KEY = OS.mac? ? :command : :ctrl
|
19
20
|
|
20
21
|
class << self
|
21
22
|
attr_accessor :drag_and_drop
|
22
23
|
attr_accessor :drag
|
23
|
-
end
|
24
|
+
end
|
24
25
|
|
25
26
|
## Add options like the following to configure CustomShell by outside consumers
|
26
27
|
#
|
@@ -28,6 +29,8 @@ module Glimmer
|
|
28
29
|
# option :width, 320
|
29
30
|
# option :height, 240
|
30
31
|
|
32
|
+
attr_accessor :split_orientation
|
33
|
+
|
31
34
|
## Uncomment before_body block to pre-initialize variables to use in body
|
32
35
|
#
|
33
36
|
#
|
@@ -72,6 +75,8 @@ module Glimmer
|
|
72
75
|
@text_editor&.text_widget&.setFocus
|
73
76
|
end
|
74
77
|
end
|
78
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'o'
|
79
|
+
self.split_orientation = split_orientation == swt(:horizontal) ? swt(:vertical) : swt(:horizontal)
|
75
80
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == ']'
|
76
81
|
@tab_folder.swt_widget.setSelection((@tab_folder.swt_widget.getSelectionIndex() + 1) % @tab_folder.swt_widget.getItemCount) if @tab_folder.swt_widget.getItemCount > 0
|
77
82
|
@text_editor&.text_widget&.setFocus
|
@@ -132,10 +137,10 @@ module Glimmer
|
|
132
137
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 'l'
|
133
138
|
@line_number_text.swt_widget.selectAll
|
134
139
|
@line_number_text.swt_widget.setFocus
|
135
|
-
elsif
|
140
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'r'
|
136
141
|
@filter_text.swt_widget.selectAll
|
137
142
|
@filter_text.swt_widget.setFocus
|
138
|
-
elsif
|
143
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 't'
|
139
144
|
select_tree_item unless @rename_in_progress
|
140
145
|
@tree.swt_widget.setFocus
|
141
146
|
elsif key_event.keyCode == swt(:esc)
|
@@ -147,10 +152,12 @@ module Glimmer
|
|
147
152
|
}
|
148
153
|
}
|
149
154
|
|
155
|
+
@split_orientation = swt(:horizontal)
|
150
156
|
local_dir = ENV['LOCAL_DIR'] || '.'
|
151
157
|
@config_file_path = ::File.join(local_dir, '.gladiator')
|
152
158
|
@config = {}
|
153
|
-
|
159
|
+
load_config_ignore_paths
|
160
|
+
# Dir.local_dir.all_children # pre-caches children
|
154
161
|
}
|
155
162
|
|
156
163
|
## Uncomment after_body block to setup observers for widgets in body
|
@@ -222,7 +229,7 @@ module Glimmer
|
|
222
229
|
observe(Dir.local_dir, 'selected_child.caret_position') do
|
223
230
|
save_config
|
224
231
|
end
|
225
|
-
observe(Dir.local_dir, 'selected_child.
|
232
|
+
observe(Dir.local_dir, 'selected_child.top_pixel') do
|
226
233
|
save_config
|
227
234
|
end
|
228
235
|
load_config
|
@@ -236,7 +243,12 @@ module Glimmer
|
|
236
243
|
text "Gladiator - #{::File.expand_path(Dir.local_dir.path)}"
|
237
244
|
minimum_size 520, 250
|
238
245
|
size 1440, 900
|
239
|
-
grid_layout
|
246
|
+
grid_layout(2, false)
|
247
|
+
on_swt_show {
|
248
|
+
swt_widget.setSize(@config[:shell_width], @config[:shell_height]) if @config[:shell_width] && @config[:shell_height]
|
249
|
+
swt_widget.setLocation(@config[:shell_x], @config[:shell_y]) if @config[:shell_x] && @config[:shell_y]
|
250
|
+
@loaded_config = true
|
251
|
+
}
|
240
252
|
on_swt_close {
|
241
253
|
Dir.local_dir.selected_child&.write_dirty_content
|
242
254
|
}
|
@@ -252,6 +264,46 @@ module Glimmer
|
|
252
264
|
on_shell_deactivated {
|
253
265
|
@text_editor&.file&.write_dirty_content
|
254
266
|
}
|
267
|
+
|
268
|
+
menu_bar {
|
269
|
+
menu {
|
270
|
+
text '&View'
|
271
|
+
menu {
|
272
|
+
text '&Split'
|
273
|
+
menu_item(:radio) {
|
274
|
+
text '&Horizontal'
|
275
|
+
selection bind(self, :split_orientation, on_read: ->(o) { o == swt(:horizontal)}, on_write: ->(b) { b ? swt(:horizontal) : swt(:vertical)})
|
276
|
+
}
|
277
|
+
menu_item(:radio) {
|
278
|
+
text '&Vertical'
|
279
|
+
selection bind(self, :split_orientation, on_read: ->(o) { o == swt(:vertical)}, on_write: ->(b) { b ? swt(:vertical) : swt(:horizontal)})
|
280
|
+
}
|
281
|
+
}
|
282
|
+
}
|
283
|
+
menu {
|
284
|
+
text '&Run'
|
285
|
+
# menu_item {
|
286
|
+
# text 'Launch Glimmer &App'
|
287
|
+
# on_widget_selected {
|
288
|
+
# parent_path = Dir.local_dir.path
|
289
|
+
## current_directory_name = ::File.basename(parent_path)
|
290
|
+
## assumed_shell_script = ::File.join(parent_path, 'bin', current_directory_name)
|
291
|
+
## assumed_shell_script = ::Dir.glob(::File.join(parent_path, 'bin', '*')).detect {|f| ::File.file?(f) && !::File.read(f).include?('#!/usr/bin/env')} if !::File.exist?(assumed_shell_script)
|
292
|
+
## load assumed_shell_script
|
293
|
+
# FileUtils.cd(parent_path) do
|
294
|
+
# system 'glimmer run'
|
295
|
+
# end
|
296
|
+
# }
|
297
|
+
# }
|
298
|
+
menu_item {
|
299
|
+
text '&Current File'
|
300
|
+
on_widget_selected {
|
301
|
+
load Dir.local_dir.selected_child.path
|
302
|
+
}
|
303
|
+
}
|
304
|
+
}
|
305
|
+
}
|
306
|
+
|
255
307
|
composite {
|
256
308
|
grid_layout 1, false
|
257
309
|
layout_data(:fill, :fill, false, true) {
|
@@ -389,9 +441,13 @@ module Glimmer
|
|
389
441
|
|
390
442
|
# row 1
|
391
443
|
|
444
|
+
label {
|
445
|
+
text 'File:'
|
446
|
+
}
|
447
|
+
|
392
448
|
@file_path_label = styled_text(:none) {
|
393
449
|
layout_data(:fill, :fill, true, false) {
|
394
|
-
horizontal_span
|
450
|
+
horizontal_span 2
|
395
451
|
}
|
396
452
|
background color(:widget_background)
|
397
453
|
editable false
|
@@ -432,7 +488,7 @@ module Glimmer
|
|
432
488
|
text 'Find:'
|
433
489
|
}
|
434
490
|
@find_text = text {
|
435
|
-
layout_data(:fill, :
|
491
|
+
layout_data(:fill, :center, true, false) {
|
436
492
|
minimum_width 400
|
437
493
|
}
|
438
494
|
text bind(Dir.local_dir, 'selected_child.find_text')
|
@@ -490,6 +546,7 @@ module Glimmer
|
|
490
546
|
height_hint 480
|
491
547
|
}
|
492
548
|
sash_width 10
|
549
|
+
orientation bind(self, :split_orientation)
|
493
550
|
@tab_folder = tab_folder {
|
494
551
|
drag_source(DND::DROP_COPY) {
|
495
552
|
transfer [TextTransfer.getInstance].to_java(Transfer)
|
@@ -511,22 +568,39 @@ module Glimmer
|
|
511
568
|
}
|
512
569
|
}
|
513
570
|
|
571
|
+
def load_config_ignore_paths
|
572
|
+
# TODO eliminate duplication with load_config
|
573
|
+
if ::File.exists?(@config_file_path)
|
574
|
+
config_yaml = ::File.read(@config_file_path)
|
575
|
+
return if config_yaml.to_s.strip.empty?
|
576
|
+
@config = YAML.load(config_yaml)
|
577
|
+
Dir.local_dir.ignore_paths = @config[:ignore_paths] if @config[:ignore_paths]
|
578
|
+
Dir.local_dir.ignore_paths ||= ['packages', 'tmp']
|
579
|
+
else
|
580
|
+
@loaded_config = true
|
581
|
+
end
|
582
|
+
end
|
583
|
+
|
514
584
|
def load_config
|
515
585
|
if ::File.exists?(@config_file_path)
|
516
586
|
config_yaml = ::File.read(@config_file_path)
|
517
587
|
return if config_yaml.to_s.strip.empty?
|
518
588
|
@config = YAML.load(config_yaml)
|
519
|
-
@config[:
|
589
|
+
Dir.local_dir.ignore_paths = @config[:ignore_paths] if @config[:ignore_paths]
|
590
|
+
Dir.local_dir.ignore_paths ||= ['packages', 'tmp']
|
591
|
+
open_file_paths1 = @config[:open_file_paths1] || @config[:open_file_paths]
|
592
|
+
open_file_paths2 = @config[:open_file_paths2]
|
593
|
+
open_file_paths1.to_a.each do |file_path|
|
594
|
+
Dir.local_dir.selected_child_path = file_path
|
595
|
+
end
|
596
|
+
Gladiator.drag = true
|
597
|
+
open_file_paths2.to_a.each do |file_path|
|
520
598
|
Dir.local_dir.selected_child_path = file_path
|
521
599
|
end
|
600
|
+
Gladiator.drag = false
|
522
601
|
Dir.local_dir.selected_child_path = @config[:selected_child_path] if @config[:selected_child_path]
|
523
602
|
Dir.local_dir.selected_child&.caret_position = Dir.local_dir.selected_child&.caret_position_for_caret_position_start_of_line(@config[:caret_position].to_i) if @config[:caret_position]
|
524
|
-
Dir.local_dir.selected_child&.
|
525
|
-
body_root.on_swt_show {
|
526
|
-
swt_widget.setSize(@config[:shell_width], @config[:shell_height]) if @config[:shell_width] && @config[:shell_height]
|
527
|
-
swt_widget.setLocation(@config[:shell_x], @config[:shell_y]) if @config[:shell_x] && @config[:shell_y]
|
528
|
-
@loaded_config = true
|
529
|
-
}
|
603
|
+
Dir.local_dir.selected_child&.top_pixel = @config[:top_pixel].to_i if @config[:top_pixel]
|
530
604
|
else
|
531
605
|
@loaded_config = true
|
532
606
|
end
|
@@ -536,15 +610,21 @@ module Glimmer
|
|
536
610
|
return unless @loaded_config
|
537
611
|
child = Dir.local_dir.selected_child
|
538
612
|
return if child.nil?
|
613
|
+
tab_folder1 = @tab_folder1 || @tab_folder
|
614
|
+
tab_folder2 = @tab_folder2
|
615
|
+
open_file_paths1 = tab_folder1&.swt_widget&.items.to_a.map {|i| i.get_data('file_path')}
|
616
|
+
open_file_paths2 = tab_folder2&.swt_widget&.items.to_a.map {|i| i.get_data('file_path')}
|
539
617
|
@config = {
|
540
618
|
selected_child_path: child.path,
|
541
619
|
caret_position: child.caret_position,
|
542
|
-
|
620
|
+
top_pixel: child.top_pixel,
|
543
621
|
shell_width: swt_widget&.getBounds&.width,
|
544
622
|
shell_height: swt_widget&.getBounds&.height,
|
545
623
|
shell_x: swt_widget&.getBounds&.x,
|
546
624
|
shell_y: swt_widget&.getBounds&.y,
|
547
|
-
|
625
|
+
open_file_paths1: open_file_paths1,
|
626
|
+
open_file_paths2: open_file_paths2,
|
627
|
+
ignore_paths: Dir.local_dir.ignore_paths
|
548
628
|
}
|
549
629
|
config_yaml = YAML.dump(@config)
|
550
630
|
::File.write(@config_file_path, config_yaml) unless config_yaml.to_s.empty?
|
@@ -644,6 +724,7 @@ module Glimmer
|
|
644
724
|
end
|
645
725
|
new_file_path = ::File.expand_path(::File.join(directory_path, 'new_file'))
|
646
726
|
FileUtils.touch(new_file_path)
|
727
|
+
# TODO look into refreshing only the parent directory to avoid slowdown
|
647
728
|
Dir.local_dir.refresh(async: false, force: true)
|
648
729
|
new_tree_item = @tree.depth_first_search {|ti| ti.getData.path == new_file_path}.first
|
649
730
|
@tree.swt_widget.showItem(new_tree_item)
|
@@ -16,13 +16,13 @@ module Glimmer
|
|
16
16
|
composite {
|
17
17
|
layout_data :fill, :fill, true, true
|
18
18
|
grid_layout 2, false
|
19
|
-
@line_numbers_text =
|
19
|
+
@line_numbers_text = code_text(:border, :multi) {
|
20
20
|
layout_data(:right, :fill, false, true)
|
21
21
|
font name: 'Consolas', height: OS.mac? ? 15 : 12
|
22
22
|
background color(:widget_background)
|
23
23
|
foreground rgb(75, 75, 75)
|
24
24
|
text bind(file, 'line_numbers_content')
|
25
|
-
|
25
|
+
top_pixel bind(file, 'top_pixel', read_only: true)
|
26
26
|
on_focus_gained {
|
27
27
|
@text&.swt_widget.setFocus
|
28
28
|
}
|
@@ -33,15 +33,15 @@ module Glimmer
|
|
33
33
|
@text&.swt_widget.setFocus
|
34
34
|
}
|
35
35
|
}
|
36
|
-
|
36
|
+
|
37
|
+
@text = code_text {
|
37
38
|
layout_data :fill, :fill, true, true
|
38
39
|
font name: 'Consolas', height: OS.mac? ? 15 : 12
|
39
40
|
foreground rgb(75, 75, 75)
|
40
41
|
text bind(file, :content)
|
41
42
|
focus true
|
42
|
-
selection bind(file,
|
43
|
-
|
44
|
-
top_index bind(file, 'top_index')
|
43
|
+
selection bind(file, :selection)
|
44
|
+
top_pixel bind(file, :top_pixel)
|
45
45
|
drop_target(DND::DROP_COPY) {
|
46
46
|
transfer [TextTransfer.getInstance].to_java(Transfer)
|
47
47
|
on_drag_enter { |event|
|
@@ -57,12 +57,21 @@ module Glimmer
|
|
57
57
|
|
58
58
|
on_focus_lost {
|
59
59
|
file&.write_dirty_content
|
60
|
-
}
|
61
|
-
|
60
|
+
}
|
61
|
+
on_verify_key { |key_event|
|
62
62
|
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')
|
63
63
|
key_event.doit = !Command.redo(file)
|
64
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'r'
|
65
|
+
Dir.local_dir.selected_child.write_dirty_content
|
66
|
+
begin
|
67
|
+
load Dir.local_dir.selected_child.path
|
68
|
+
rescue => e
|
69
|
+
puts e.full_message
|
70
|
+
end
|
64
71
|
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'z'
|
65
72
|
key_event.doit = !Command.undo(file)
|
73
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'a'
|
74
|
+
key_event.widget.selectAll
|
66
75
|
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == '/'
|
67
76
|
Command.do(file, :comment_line!)
|
68
77
|
key_event.doit = false
|
@@ -105,13 +114,13 @@ module Glimmer
|
|
105
114
|
end
|
106
115
|
}
|
107
116
|
on_verify_text { |verify_event|
|
108
|
-
|
109
|
-
case
|
110
|
-
when
|
117
|
+
# TODO convert these into File commands to support Undo/Redo
|
118
|
+
case verify_event.text
|
119
|
+
when "\n"
|
111
120
|
if file.selection_count.to_i == 0
|
112
121
|
verify_event.text += file.current_line_indentation
|
113
122
|
end
|
114
|
-
when
|
123
|
+
when "\t"
|
115
124
|
if file.selection_count.to_i > 0
|
116
125
|
Command.do(file, :indent!)
|
117
126
|
verify_event.doit = false
|
metadata
CHANGED
@@ -1,35 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-cs-gladiator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
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-10-23 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
17
|
- !ruby/object:Gem::Version
|
18
|
-
version:
|
18
|
+
version: 4.17.4.2
|
19
19
|
- - "<"
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 5.0.0.0
|
22
22
|
name: glimmer-dsl-swt
|
23
|
-
type: :runtime
|
24
23
|
prerelease: false
|
24
|
+
type: :runtime
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 4.17.4.2
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 5.0.0.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
requirement: !ruby/object:Gem::Requirement
|
35
35
|
requirements:
|
@@ -37,8 +37,8 @@ dependencies:
|
|
37
37
|
- !ruby/object:Gem::Version
|
38
38
|
version: 1.1.1
|
39
39
|
name: filewatcher
|
40
|
-
type: :runtime
|
41
40
|
prerelease: false
|
41
|
+
type: :runtime
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
@@ -51,8 +51,8 @@ dependencies:
|
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: 1.3.4
|
53
53
|
name: clipboard
|
54
|
-
type: :runtime
|
55
54
|
prerelease: false
|
55
|
+
type: :runtime
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - "~>"
|
@@ -65,8 +65,8 @@ dependencies:
|
|
65
65
|
- !ruby/object:Gem::Version
|
66
66
|
version: 3.5.0
|
67
67
|
name: rspec
|
68
|
-
type: :development
|
69
68
|
prerelease: false
|
69
|
+
type: :development
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
72
|
- - "~>"
|
@@ -79,8 +79,8 @@ dependencies:
|
|
79
79
|
- !ruby/object:Gem::Version
|
80
80
|
version: 2.3.9
|
81
81
|
name: jeweler
|
82
|
-
type: :development
|
83
82
|
prerelease: false
|
83
|
+
type: :development
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - '='
|
@@ -93,8 +93,8 @@ dependencies:
|
|
93
93
|
- !ruby/object:Gem::Version
|
94
94
|
version: '0'
|
95
95
|
name: simplecov
|
96
|
-
type: :development
|
97
96
|
prerelease: false
|
97
|
+
type: :development
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
100
|
- - ">="
|
@@ -144,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '0'
|
146
146
|
requirements: []
|
147
|
-
rubygems_version: 3.
|
147
|
+
rubygems_version: 3.1.4
|
148
148
|
signing_key:
|
149
149
|
specification_version: 4
|
150
150
|
summary: Gladiator (Glimmer Editor) - Glimmer Custom Shell
|