glimmer-cs-gladiator 0.1.7 → 0.2.3
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 +58 -17
- data/VERSION +1 -0
- data/lib/glimmer-cs-gladiator.rb +1 -0
- data/lib/models/glimmer/gladiator/command.rb +75 -0
- data/lib/models/glimmer/gladiator/dir.rb +41 -20
- data/lib/models/glimmer/gladiator/file.rb +22 -6
- data/lib/views/glimmer/gladiator.rb +257 -112
- data/lib/views/glimmer/gladiator/text_editor.rb +32 -14
- metadata +7 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8a4a941695d12f14347c9892758f974e5909455a73020eee8d635c4c38e86a3
|
4
|
+
data.tar.gz: 929ff0b362ca29394e80f918b65fbdb911892449d9876a4eca14a7ec4c01b8df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 993c7ae4684351d97b8b583cf5f59aef4a6d2aec5a68d8c121b6a95bc4e2ee035d6d21f677c8cd79febd5b4379e81808f4b0b977a1aadb388ddba4ab74694b4b
|
7
|
+
data.tar.gz: 32d823df2493950f822fdcfceb28fc5d2b6998152ab233dd0e8668f013d0bd5301dd6ec220d4719bd88683f53bbbd33ddbdceac03bb8d1f02fa77bee2cc432b6
|
data/README.md
CHANGED
@@ -1,15 +1,18 @@
|
|
1
|
-
#
|
1
|
+
# <img src='https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-cs-gladiator-logo.svg' height=85 /> Gladiator 0.2.3 - [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#custom-shell-gem)
|
2
3
|
[](http://badge.fury.io/rb/glimmer-cs-gladiator)
|
3
4
|
|
4
5
|

|
5
6
|
|
6
|
-
Gladiator (short for Glimmer Editor) is a Glimmer sample project under on-going development.
|
7
|
-
It is not intended to be a full-fledged editor by any means, yet mostly a fun educational exercise in using Glimmer
|
8
|
-
Gladiator is also a personal tool for shaping an editor exactly the way I like.
|
9
|
-
I leave building truly professional text editors to software tooling experts who would hopefully use Glimmer one day.
|
7
|
+
Gladiator (short for Glimmer Editor) is a [Glimmer](https://github.com/AndyObtiva/glimmer) sample project under on-going development that demonstrates how to build a text editor in [Glimmer](https://github.com/AndyObtiva/glimmer) (Ruby Desktop Development GUI Library).
|
8
|
+
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
|
+
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.
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
## Features
|
13
|
+
|
14
|
+
Gladiator currently supports the following text editing features (including keyboard shortcuts with Mac CMD=CTRL on Windows/Linux):
|
15
|
+
- File explorer navigation with context menu to open file, rename, delete, add new file, add new directory, or refresh tree (CMD+T)
|
13
16
|
- File lookup by name ignoring slashes, underscores, and dots to ease lookup (CMD+R)
|
14
17
|
- Watch open file for external changes to automatically refresh in editor
|
15
18
|
- Watch project subdirectories for changes to automatically refresh in file explorer/file lookup
|
@@ -26,33 +29,63 @@ Gladiator currently supports the following text editing features:
|
|
26
29
|
- Comment/Uncomment line/selection (CMD+/)
|
27
30
|
- Indent/Unindent line/selection (CMD+] & CMD+[)
|
28
31
|
- Insert/Prefix New Line (CMD+ENTER & CMD+SHIFT+ENTER)
|
32
|
+
- Drag and Drop Text Editor Split Screen (drag a file from File Tree or File Lookup List, and it splits the screen)
|
29
33
|
|
30
34
|
## Platforms
|
31
35
|
|
32
36
|
- Mac: Gladiator works best on the Mac.
|
37
|
+
- Windows: Gladiator works well on Windows.
|
33
38
|
- 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.
|
35
39
|
|
36
40
|
## Pre-requisites
|
37
41
|
|
38
|
-
-
|
39
|
-
-
|
42
|
+
- [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer) (Ruby Desktop Development GUI Library): '>= 0.1.0', '< 2.0.0' (dependency included in Ruby gem).
|
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)
|
40
45
|
|
41
46
|
## Setup Instructions
|
42
47
|
|
43
|
-
Install Gladiator gem by running (`jgem`, `jruby -S gem`, or `gem` directly if you have RVM):
|
48
|
+
Install Gladiator gem by running (`jgem`, `jruby -S gem`, or `gem` directly if you have [RVM](https://rvm.io/)):
|
44
49
|
|
45
50
|
```
|
46
51
|
jgem install glimmer-cs-gladiator
|
47
52
|
```
|
48
53
|
|
49
|
-
|
54
|
+
Or add to a JRuby project Bundler `Gemfile` under the `:developement` group:
|
55
|
+
|
56
|
+
```
|
57
|
+
group :development do
|
58
|
+
gem 'glimmer-cs-gladiator'
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
62
|
+
Run (`jruby -S bundle` or `bundle` directly if you have [RVM](https://rvm.io/)):
|
63
|
+
|
64
|
+
```
|
65
|
+
jruby -S bundle
|
66
|
+
```
|
67
|
+
|
68
|
+
## Usage
|
69
|
+
|
70
|
+
You may run the `gladiator` command to bring up the text editor in the project directory you would like to edit:
|
50
71
|
|
51
72
|
```
|
52
73
|
gladiator
|
53
74
|
```
|
54
75
|
|
55
|
-
|
76
|
+
If you are in a different directory from the project you would like to edit, then pass its path as an argument:
|
77
|
+
|
78
|
+
```
|
79
|
+
gladiator relative-or-absolute-path/to/project
|
80
|
+
```
|
81
|
+
|
82
|
+
Note: If you cloned this project and bundle installed, you may invoke via `bin/gladiator` instead.
|
83
|
+
|
84
|
+
If your project is not a JRuby project, then you cannot install [glimmer-cs-gladiator](https://rubygems.org/gems/glimmer-cs-gladiator), so you must install in a separate JRuby environment and invoke by passing the project path as per command above. Alternatively, you may clone this project, and invoke gladiator via `bin/gladiator` (that's how I use Gladiator for most of my projects):
|
85
|
+
|
86
|
+
```
|
87
|
+
bin/gladiator relative-or-absolute-path/to/project
|
88
|
+
```
|
56
89
|
|
57
90
|
### Glimmer Custom Shell Reuse
|
58
91
|
|
@@ -60,7 +93,7 @@ To reuse Gladiator as a Glimmer Custom Shell inside another Glimmer application,
|
|
60
93
|
following to the application's `Gemfile`:
|
61
94
|
|
62
95
|
```
|
63
|
-
gem 'glimmer-cs-gladiator', '0.
|
96
|
+
gem 'glimmer-cs-gladiator', '~> 0.2.3'
|
64
97
|
```
|
65
98
|
|
66
99
|
Run:
|
@@ -69,7 +102,7 @@ Run:
|
|
69
102
|
jruby -S bundle
|
70
103
|
```
|
71
104
|
|
72
|
-
And, then instantiate the Gladiator custom shell in your Glimmer application via the `gladiator` keyword.
|
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.
|
73
106
|
|
74
107
|
## Env Var Options
|
75
108
|
|
@@ -92,6 +125,7 @@ It currently remembers:
|
|
92
125
|
- Last opened file
|
93
126
|
- Caret position
|
94
127
|
- Top line position
|
128
|
+
- Opened tabs
|
95
129
|
|
96
130
|
## Gotcha
|
97
131
|
|
@@ -118,5 +152,12 @@ The signal TERM is in use by the JVM and will not work correctly on this platfor
|
|
118
152
|
|
119
153
|
## Copyright
|
120
154
|
|
121
|
-
|
122
|
-
|
155
|
+
[MIT](https://opensource.org/licenses/MIT)
|
156
|
+
|
157
|
+
Copyright (c) 2020 Andy Maleh. See [LICENSE.txt](LICENSE.txt) for further details.
|
158
|
+
|
159
|
+
--
|
160
|
+
|
161
|
+
[<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](https://github.com/AndyObtiva/glimmer) (Ruby Desktop Development GUI Library)
|
162
|
+
|
163
|
+
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
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.3
|
data/lib/glimmer-cs-gladiator.rb
CHANGED
@@ -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
|
@@ -9,29 +9,32 @@ 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
29
|
attr_accessor :selected_child, :filter, :children, :filtered_path_options, :filtered_path, :path, :display_path
|
28
30
|
attr_reader :name, :parent
|
29
|
-
attr_writer :all_children
|
31
|
+
attr_writer :all_children
|
30
32
|
|
31
|
-
def initialize(path)
|
33
|
+
def initialize(path, is_local_dir = false)
|
32
34
|
@display_path = path
|
33
35
|
@path = ::File.expand_path(@display_path)
|
34
36
|
@name = ::File.basename(::File.expand_path(path))
|
37
|
+
@display_path = @path.sub(Dir.local_dir.path, '').sub(/^\//, '') unless is_local_dir
|
35
38
|
self.filtered_path_options = []
|
36
39
|
end
|
37
40
|
|
@@ -48,7 +51,15 @@ module Glimmer
|
|
48
51
|
end
|
49
52
|
|
50
53
|
def retrieve_children
|
51
|
-
::Dir.glob(::File.join(@
|
54
|
+
@children = ::Dir.glob(::File.join(@path, '*')).map do |p|
|
55
|
+
::File.file?(p) ? Gladiator::File.new(p) : Gladiator::Dir.new(p)
|
56
|
+
end.sort_by do |c|
|
57
|
+
c.path.to_s.downcase
|
58
|
+
end.sort_by do |c|
|
59
|
+
c.class.name
|
60
|
+
end.each do |child|
|
61
|
+
child.retrieve_children if child.is_a?(Dir)
|
62
|
+
end
|
52
63
|
end
|
53
64
|
|
54
65
|
def selected_child_path_history
|
@@ -65,11 +76,11 @@ module Glimmer
|
|
65
76
|
|
66
77
|
def refresh(async: true, force: false)
|
67
78
|
return if @refresh_paused && !force
|
68
|
-
|
69
|
-
|
79
|
+
retrieve_children
|
80
|
+
collect_all_children
|
70
81
|
refresh_operation = lambda do
|
71
|
-
|
72
|
-
|
82
|
+
notify_observers(:children)
|
83
|
+
notify_observers(:all_children)
|
73
84
|
end
|
74
85
|
if async
|
75
86
|
async_exec(&refresh_operation)
|
@@ -84,23 +95,31 @@ module Glimmer
|
|
84
95
|
else
|
85
96
|
@filter = value
|
86
97
|
end
|
87
|
-
|
98
|
+
@last_filtered = filtered.to_a
|
99
|
+
self.filtered_path_options = @last_filtered.map(&:display_path)
|
100
|
+
@last_filter = @filter
|
88
101
|
end
|
89
102
|
|
90
103
|
def filtered
|
91
104
|
return if filter.nil?
|
92
|
-
|
93
|
-
|
94
|
-
|
105
|
+
children_files = !@last_filter.to_s.empty? && filter.downcase.start_with?(@last_filter.downcase) ? @last_filtered : all_children_files
|
106
|
+
children_files.select do |child|
|
107
|
+
child_path = child.path.to_s.sub(Dir.local_dir.path, '')
|
108
|
+
child_path.downcase.include?(filter.downcase) ||
|
109
|
+
child_path.downcase.gsub(/[_\/.-]/, '').include?(filter.downcase.gsub(/[_\/.-]/, ''))
|
95
110
|
end.sort_by {|c| c.path.to_s.downcase}
|
96
111
|
end
|
97
112
|
|
98
113
|
def all_children
|
99
|
-
@all_children ||=
|
114
|
+
@all_children ||= collect_all_children
|
100
115
|
end
|
101
116
|
|
102
|
-
def
|
103
|
-
|
117
|
+
def collect_all_children
|
118
|
+
@all_children = children.reduce([]) do |output, child|
|
119
|
+
addition = [child]
|
120
|
+
addition += child.collect_all_children if child.is_a?(Dir)
|
121
|
+
output + addition
|
122
|
+
end
|
104
123
|
end
|
105
124
|
|
106
125
|
def all_children_files
|
@@ -108,9 +127,11 @@ module Glimmer
|
|
108
127
|
end
|
109
128
|
|
110
129
|
def selected_child_path=(selected_path)
|
130
|
+
full_selected_path = selected_path.include?(Dir.local_dir.path) ? selected_path : ::File.join(Dir.local_dir.path, selected_path)
|
111
131
|
return if selected_path.nil? ||
|
112
|
-
::Dir.exist?(
|
113
|
-
(selected_child &&
|
132
|
+
::Dir.exist?(full_selected_path) ||
|
133
|
+
(selected_child && selected_child.path == full_selected_path)
|
134
|
+
selected_path = full_selected_path
|
114
135
|
if ::File.file?(selected_path)
|
115
136
|
@selected_child&.write_dirty_content
|
116
137
|
new_child = Gladiator::File.new(selected_path)
|
@@ -5,14 +5,16 @@ module Glimmer
|
|
5
5
|
class File
|
6
6
|
include Glimmer
|
7
7
|
|
8
|
-
attr_accessor :line_numbers_content, :selection, :selection_count, :line_number, :find_text, :replace_text, :top_index, :path, :display_path
|
9
|
-
attr_reader :name
|
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
|
+
@display_path = @path.sub(Dir.local_dir.path, '').sub(/^\//, '')
|
16
18
|
@top_index = 0
|
17
19
|
@selection_count = 0
|
18
20
|
@selection = Point.new(0, 0 + @selection_count)
|
@@ -40,6 +42,16 @@ module Glimmer
|
|
40
42
|
# no op in case of a binary file
|
41
43
|
end
|
42
44
|
end
|
45
|
+
|
46
|
+
# to use for widget data-binding
|
47
|
+
def content=(value)
|
48
|
+
Command.do(self) # record a native (OS-widget) operation
|
49
|
+
self.dirty_content = value
|
50
|
+
end
|
51
|
+
|
52
|
+
def content
|
53
|
+
dirty_content
|
54
|
+
end
|
43
55
|
|
44
56
|
def caret_position=(value)
|
45
57
|
self.selection = Point.new(value, value + selection_count.to_i)
|
@@ -64,6 +76,7 @@ module Glimmer
|
|
64
76
|
|
65
77
|
def dirty_content=(the_content)
|
66
78
|
@dirty_content = the_content if ::File.exist?(path)
|
79
|
+
notify_observers(:content)
|
67
80
|
end
|
68
81
|
|
69
82
|
def start_filewatcher
|
@@ -149,6 +162,7 @@ module Glimmer
|
|
149
162
|
line_indices_for_selection(caret_position, selection_count).reverse.each do | the_line_index |
|
150
163
|
delta = 0
|
151
164
|
the_line = old_lines[the_line_index]
|
165
|
+
return if the_line.nil?
|
152
166
|
if the_line.strip.start_with?('# ')
|
153
167
|
new_lines[the_line_index] = the_line.sub(/# /, '')
|
154
168
|
delta -= 2
|
@@ -210,7 +224,7 @@ module Glimmer
|
|
210
224
|
if the_line.to_s.start_with?(' ')
|
211
225
|
new_lines[the_line_index] = the_line.sub(/ /, '')
|
212
226
|
delta = -2
|
213
|
-
elsif the_line
|
227
|
+
elsif the_line&.start_with?(' ')
|
214
228
|
new_lines[the_line_index] = the_line.sub(/ /, '')
|
215
229
|
delta = -1
|
216
230
|
end
|
@@ -264,7 +278,7 @@ module Glimmer
|
|
264
278
|
end
|
265
279
|
|
266
280
|
def find_next
|
267
|
-
return if find_text.to_s.empty?
|
281
|
+
return if find_text.to_s.empty?
|
268
282
|
all_lines = lines
|
269
283
|
the_line_index = line_index_for_caret_position(caret_position)
|
270
284
|
line_position = line_position_for_caret_position(caret_position)
|
@@ -275,8 +289,8 @@ module Glimmer
|
|
275
289
|
the_index = (the_index + rotation)%all_lines.size
|
276
290
|
start_position = 0
|
277
291
|
start_position = line_position + find_text.to_s.size if i == 0 && the_index == the_line_index && found_text?(caret_position)
|
278
|
-
text_to_find_in = the_line
|
279
|
-
occurrence_index = text_to_find_in&.index(find_text.to_s.downcase)
|
292
|
+
text_to_find_in = the_line[start_position..-1]
|
293
|
+
occurrence_index = case_sensitive ? text_to_find_in&.index(find_text.to_s) : text_to_find_in&.downcase&.index(find_text.to_s.downcase)
|
280
294
|
if occurrence_index
|
281
295
|
self.caret_position = caret_position_for_line_index(the_index) + start_position + occurrence_index
|
282
296
|
self.selection_count = find_text.to_s.size
|
@@ -340,10 +354,12 @@ module Glimmer
|
|
340
354
|
end
|
341
355
|
|
342
356
|
def home
|
357
|
+
self.selection_count = 0
|
343
358
|
self.line_number = 1
|
344
359
|
end
|
345
360
|
|
346
361
|
def end
|
362
|
+
self.selection_count = 0
|
347
363
|
self.line_number = lines.size
|
348
364
|
end
|
349
365
|
|
@@ -1,18 +1,12 @@
|
|
1
|
-
begin
|
2
|
-
require 'puts_debuggerer' if ENV['puts_debuggerer'].to_s.downcase == 'true'
|
3
|
-
rescue LoadError
|
4
|
-
# no op
|
5
|
-
end
|
6
1
|
require 'fileutils'
|
7
2
|
require 'os'
|
8
3
|
|
9
4
|
require 'models/glimmer/gladiator/dir'
|
10
5
|
require 'models/glimmer/gladiator/file'
|
6
|
+
require 'models/glimmer/gladiator/command'
|
11
7
|
|
12
8
|
require 'views/glimmer/gladiator/text_editor'
|
13
9
|
|
14
|
-
java_import 'org.eclipse.swt.custom.TreeEditor'
|
15
|
-
|
16
10
|
Clipboard.implementation = Clipboard::Java
|
17
11
|
Clipboard.copy(Clipboard.paste) # pre-initialize library to avoid slowdown during use
|
18
12
|
|
@@ -23,89 +17,118 @@ module Glimmer
|
|
23
17
|
|
24
18
|
COMMAND_KEY = OS.mac? ? :command : :ctrl
|
25
19
|
|
20
|
+
class << self
|
21
|
+
attr_accessor :drag_and_drop
|
22
|
+
attr_accessor :drag
|
23
|
+
end
|
24
|
+
|
26
25
|
## Add options like the following to configure CustomShell by outside consumers
|
27
26
|
#
|
28
27
|
# options :title, :background_color
|
29
28
|
# option :width, 320
|
30
29
|
# option :height, 240
|
31
|
-
|
30
|
+
|
32
31
|
## Uncomment before_body block to pre-initialize variables to use in body
|
33
32
|
#
|
34
33
|
#
|
35
34
|
before_body {
|
36
35
|
Display.setAppName('Gladiator')
|
37
36
|
@display = display {
|
38
|
-
|
37
|
+
on_swt_keydown { |key_event|
|
39
38
|
if key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'f'
|
40
|
-
if @text_editor
|
39
|
+
if @text_editor&.text_widget&.getSelectionText && @text_editor&.text_widget&.getSelectionText&.size.to_i > 0
|
41
40
|
@find_text.swt_widget.setText @text_editor.text_widget.getSelectionText
|
42
41
|
end
|
43
42
|
@find_text.swt_widget.selectAll
|
44
43
|
@find_text.swt_widget.setFocus
|
45
44
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'c'
|
46
|
-
Clipboard.copy(
|
45
|
+
Clipboard.copy(Dir.local_dir.selected_child.path)
|
47
46
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'g'
|
48
|
-
|
47
|
+
Dir.local_dir.selected_child.find_previous
|
49
48
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'w'
|
50
49
|
@tab_folder.swt_widget.getItems.each do |tab_item|
|
51
50
|
Dir.local_dir.selected_child_path_history.delete(tab_item.getData('file_path'))
|
52
|
-
tab_item.getData('proxy')
|
51
|
+
tab_item.getData('proxy')&.dispose
|
53
52
|
end
|
53
|
+
close_tab_folder
|
54
54
|
@tab_item = @text_editor = Dir.local_dir.selected_child = nil
|
55
55
|
@filter_text.swt_widget.selectAll
|
56
56
|
@filter_text.swt_widget.setFocus
|
57
|
-
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && key_event
|
57
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :alt) && extract_char(key_event) == 'w'
|
58
58
|
other_tab_items.each do |tab_item|
|
59
59
|
Dir.local_dir.selected_child_path_history.delete(tab_item.getData('file_path'))
|
60
|
-
tab_item.getData('proxy')
|
60
|
+
tab_item.getData('proxy')&.dispose
|
61
61
|
end
|
62
62
|
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'w'
|
63
63
|
if selected_tab_item
|
64
64
|
Dir.local_dir.selected_child_path_history.delete(Dir.local_dir.selected_child.path)
|
65
|
-
selected_tab_item.getData('proxy')
|
65
|
+
selected_tab_item.getData('proxy')&.dispose
|
66
|
+
close_tab_folder
|
66
67
|
if selected_tab_item.nil?
|
67
68
|
@tab_item = @text_editor = Dir.local_dir.selected_child = nil
|
68
69
|
@filter_text.swt_widget.selectAll
|
69
70
|
@filter_text.swt_widget.setFocus
|
70
71
|
else
|
71
|
-
@text_editor
|
72
|
+
@text_editor&.text_widget&.setFocus
|
72
73
|
end
|
73
74
|
end
|
74
75
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == ']'
|
75
|
-
@tab_folder.swt_widget.setSelection(
|
76
|
-
@text_editor
|
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
|
77
78
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == '['
|
78
|
-
@tab_folder.swt_widget.setSelection(
|
79
|
-
@text_editor
|
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, :ctrl) && extract_char(key_event) == ']'
|
82
|
+
if @tab_folder2
|
83
|
+
if @tab_folder == @tab_folder1
|
84
|
+
@tab_folder = @tab_folder2
|
85
|
+
else
|
86
|
+
@tab_folder = @tab_folder1
|
87
|
+
end
|
88
|
+
@tab_item = @tab_folder.swt_widget.getData('selected_tab_item')
|
89
|
+
Dir.local_dir.selected_child = @tab_item&.swt_tab_item&.getData('file')
|
90
|
+
@tab_item&.swt_tab_item&.getData('text_editor')&.text_widget&.setFocus
|
91
|
+
end
|
92
|
+
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :ctrl) && extract_char(key_event) == '['
|
93
|
+
if @tab_folder2
|
94
|
+
if @tab_folder == @tab_folder2
|
95
|
+
@tab_folder = @tab_folder1
|
96
|
+
else
|
97
|
+
@tab_folder = @tab_folder2
|
98
|
+
end
|
99
|
+
@tab_item = @tab_folder.swt_widget.getData('selected_tab_item')
|
100
|
+
Dir.local_dir.selected_child = @tab_item&.swt_tab_item&.getData('file')
|
101
|
+
@tab_item&.swt_tab_item&.getData('text_editor')&.text_widget&.setFocus
|
102
|
+
end
|
80
103
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '1'
|
81
104
|
@tab_folder.swt_widget.setSelection(0) if @tab_folder.swt_widget.getItemCount >= 1
|
82
|
-
@text_editor
|
105
|
+
@text_editor&.text_widget&.setFocus
|
83
106
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '2'
|
84
107
|
@tab_folder.swt_widget.setSelection(1) if @tab_folder.swt_widget.getItemCount >= 2
|
85
|
-
@text_editor
|
108
|
+
@text_editor&.text_widget&.setFocus
|
86
109
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '3'
|
87
110
|
@tab_folder.swt_widget.setSelection(2) if @tab_folder.swt_widget.getItemCount >= 3
|
88
|
-
@text_editor
|
111
|
+
@text_editor&.text_widget&.setFocus
|
89
112
|
@tab_folder.swt_widget.setSelection(3) if @tab_folder.swt_widget.getItemCount >= 4
|
90
|
-
@text_editor
|
113
|
+
@text_editor&.text_widget&.setFocus
|
91
114
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '5'
|
92
115
|
@tab_folder.swt_widget.setSelection(4) if @tab_folder.swt_widget.getItemCount >= 5
|
93
|
-
@text_editor
|
116
|
+
@text_editor&.text_widget&.setFocus
|
94
117
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '4'
|
95
118
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '6'
|
96
119
|
@tab_folder.swt_widget.setSelection(5) if @tab_folder.swt_widget.getItemCount >= 6
|
97
|
-
@text_editor
|
120
|
+
@text_editor&.text_widget&.setFocus
|
98
121
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '7'
|
99
122
|
@tab_folder.swt_widget.setSelection(6) if @tab_folder.swt_widget.getItemCount >= 7
|
100
|
-
@text_editor
|
123
|
+
@text_editor&.text_widget&.setFocus
|
101
124
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '8'
|
102
125
|
@tab_folder.swt_widget.setSelection(7) if @tab_folder.swt_widget.getItemCount >= 8
|
103
|
-
@text_editor
|
126
|
+
@text_editor&.text_widget&.setFocus
|
104
127
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '9'
|
105
128
|
@tab_folder.swt_widget.setSelection(@tab_folder.swt_widget.getItemCount - 1) if @tab_folder.swt_widget.getItemCount > 0
|
106
|
-
@text_editor
|
129
|
+
@text_editor&.text_widget&.setFocus
|
107
130
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 'g'
|
108
|
-
|
131
|
+
Dir.local_dir.selected_child.find_next
|
109
132
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 'l'
|
110
133
|
@line_number_text.swt_widget.selectAll
|
111
134
|
@line_number_text.swt_widget.setFocus
|
@@ -118,7 +141,7 @@ module Glimmer
|
|
118
141
|
elsif key_event.keyCode == swt(:esc)
|
119
142
|
if @text_editor
|
120
143
|
Dir.local_dir.selected_child_path = @text_editor.file.path
|
121
|
-
@text_editor
|
144
|
+
@text_editor&.text_widget&.setFocus
|
122
145
|
end
|
123
146
|
end
|
124
147
|
}
|
@@ -127,51 +150,79 @@ module Glimmer
|
|
127
150
|
local_dir = ENV['LOCAL_DIR'] || '.'
|
128
151
|
@config_file_path = ::File.join(local_dir, '.gladiator')
|
129
152
|
@config = {}
|
130
|
-
|
153
|
+
Dir.local_dir.all_children # pre-caches children
|
131
154
|
}
|
132
155
|
|
133
156
|
## Uncomment after_body block to setup observers for widgets in body
|
134
157
|
#
|
135
158
|
after_body {
|
136
|
-
observe(
|
159
|
+
observe(Dir.local_dir, 'children') do
|
137
160
|
select_tree_item unless @rename_in_progress
|
138
161
|
end
|
139
|
-
observe(
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
@text_editor = found_tab_item.getData('text_editor')
|
147
|
-
elsif selected_file
|
148
|
-
@tab_folder.content {
|
149
|
-
@tab_item = tab_item { |the_tab_item|
|
150
|
-
text selected_file.name
|
151
|
-
fill_layout :horizontal
|
152
|
-
@text_editor = the_text_editor = text_editor(file: selected_file)
|
153
|
-
on_event_show {
|
154
|
-
Gladiator::Dir.local_dir.selected_child = selected_file
|
155
|
-
@tab_item = the_tab_item
|
156
|
-
@text_editor = the_text_editor
|
157
|
-
}
|
162
|
+
observe(Dir.local_dir, 'selected_child') do |selected_file|
|
163
|
+
if selected_file
|
164
|
+
if Gladiator.drag && !@tab_folder2
|
165
|
+
@tab_folder1 = @tab_folder
|
166
|
+
@tab_folder_sash_form.content {
|
167
|
+
@tab_folder = @tab_folder2 = tab_folder
|
168
|
+
@tab_folder.swt_widget.setData('proxy', @tab_folder)
|
158
169
|
}
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
170
|
+
end
|
171
|
+
select_tree_item unless @rename_in_progress
|
172
|
+
found_tab_item = selected_tab_item
|
173
|
+
if found_tab_item
|
174
|
+
@tab_folder.swt_widget.setSelection(found_tab_item)
|
175
|
+
@tab_item = found_tab_item.getData('proxy')
|
176
|
+
@text_editor = found_tab_item.getData('text_editor')
|
177
|
+
@tab_folder.swt_widget.setData('selected_tab_item', @tab_item)
|
178
|
+
elsif selected_file
|
179
|
+
@tab_folder.content {
|
180
|
+
@tab_item = tab_item { |the_tab_item|
|
181
|
+
text selected_file.name
|
182
|
+
fill_layout :horizontal
|
183
|
+
@text_editor = the_text_editor = text_editor(file: selected_file)
|
184
|
+
@tab_folder.swt_widget.setData('selected_tab_item', @tab_item)
|
185
|
+
@text_editor.text_proxy.content {
|
186
|
+
on_focus_gained {
|
187
|
+
tab_folder = the_text_editor.swt_widget.getParent.getParent
|
188
|
+
@tab_folder = tab_folder.getData('proxy')
|
189
|
+
@tab_item = the_tab_item
|
190
|
+
@text_editor = the_text_editor
|
191
|
+
@tab_folder.swt_widget.setData('selected_tab_item', @tab_item)
|
192
|
+
@tab_folder.swt_widget.setSelection(@tab_item.swt_tab_item)
|
193
|
+
Dir.local_dir.selected_child = @tab_item.swt_tab_item.getData('file')
|
194
|
+
}
|
195
|
+
}
|
196
|
+
on_swt_show {
|
197
|
+
@tab_item = the_tab_item
|
198
|
+
@text_editor = the_text_editor
|
199
|
+
@tab_folder = @tab_item.swt_widget.getParent.getData('proxy')
|
200
|
+
@tab_folder.swt_widget.setData('selected_tab_item', @tab_item)
|
201
|
+
@tab_folder.swt_widget.setSelection(@tab_item.swt_tab_item)
|
202
|
+
Dir.local_dir.selected_child = selected_file
|
203
|
+
async_exec {
|
204
|
+
@text_editor&.text_widget&.setFocus
|
205
|
+
}
|
206
|
+
}
|
207
|
+
}
|
208
|
+
@tab_item.swt_tab_item.setData('file_path', selected_file.path)
|
209
|
+
@tab_item.swt_tab_item.setData('file', selected_file)
|
210
|
+
@tab_item.swt_tab_item.setData('text_editor', @text_editor)
|
211
|
+
@tab_item.swt_tab_item.setData('proxy', @tab_item)
|
212
|
+
}
|
213
|
+
@tab_folder.swt_widget.setSelection(@tab_item.swt_tab_item)
|
214
|
+
body_root.pack_same_size
|
215
|
+
end
|
216
|
+
@text_editor&.text_widget&.setFocus
|
166
217
|
end
|
167
218
|
end
|
168
|
-
observe(
|
219
|
+
observe(Dir.local_dir, 'selected_child') do
|
169
220
|
save_config
|
170
221
|
end
|
171
|
-
observe(
|
222
|
+
observe(Dir.local_dir, 'selected_child.caret_position') do
|
172
223
|
save_config
|
173
224
|
end
|
174
|
-
observe(
|
225
|
+
observe(Dir.local_dir, 'selected_child.top_index') do
|
175
226
|
save_config
|
176
227
|
end
|
177
228
|
load_config
|
@@ -182,15 +233,15 @@ module Glimmer
|
|
182
233
|
#
|
183
234
|
body {
|
184
235
|
shell {
|
185
|
-
text "Gladiator - #{::File.expand_path(
|
186
|
-
minimum_size
|
236
|
+
text "Gladiator - #{::File.expand_path(Dir.local_dir.path)}"
|
237
|
+
minimum_size 520, 250
|
187
238
|
size 1440, 900
|
188
239
|
grid_layout 2, false
|
189
|
-
|
190
|
-
|
240
|
+
on_swt_close {
|
241
|
+
Dir.local_dir.selected_child&.write_dirty_content
|
191
242
|
}
|
192
243
|
on_widget_disposed {
|
193
|
-
|
244
|
+
Dir.local_dir.selected_child&.write_dirty_content
|
194
245
|
}
|
195
246
|
on_control_resized {
|
196
247
|
save_config
|
@@ -208,7 +259,7 @@ module Glimmer
|
|
208
259
|
}
|
209
260
|
@filter_text = text {
|
210
261
|
layout_data :fill, :center, true, false
|
211
|
-
text bind(
|
262
|
+
text bind(Dir.local_dir, 'filter')
|
212
263
|
on_key_pressed { |key_event|
|
213
264
|
if key_event.keyCode == swt(:tab) ||
|
214
265
|
key_event.keyCode == swt(:cr) ||
|
@@ -220,35 +271,48 @@ module Glimmer
|
|
220
271
|
}
|
221
272
|
}
|
222
273
|
composite {
|
274
|
+
fill_layout(:vertical) {
|
275
|
+
spacing 5
|
276
|
+
}
|
223
277
|
layout_data(:fill, :fill, true, true)
|
224
278
|
@list = list(:border, :h_scroll, :v_scroll) {
|
225
|
-
|
226
|
-
|
227
|
-
minimum_height 400
|
228
|
-
}
|
229
|
-
#visible bind(Gladiator::Dir, 'local_dir.filter') {|f| !!f}
|
230
|
-
selection bind(Gladiator::Dir.local_dir, :filtered_path)
|
279
|
+
#visible bind(Dir, 'local_dir.filter') {|f| !!f}
|
280
|
+
selection bind(Dir.local_dir, :filtered_path)
|
231
281
|
on_mouse_up {
|
232
|
-
|
282
|
+
Dir.local_dir.selected_child_path = @list.swt_widget.getSelection.first
|
233
283
|
}
|
234
284
|
on_key_pressed { |key_event|
|
235
285
|
if Glimmer::SWT::SWTProxy.include?(key_event.keyCode, :cr)
|
236
|
-
|
237
|
-
@text_editor
|
286
|
+
Dir.local_dir.selected_child_path = @list.swt_widget.getSelection.first
|
287
|
+
@text_editor&.text_widget&.setFocus
|
238
288
|
end
|
239
289
|
}
|
290
|
+
drag_source(DND::DROP_COPY) {
|
291
|
+
transfer [TextTransfer.getInstance].to_java(Transfer)
|
292
|
+
on_drag_set_data { |event|
|
293
|
+
Gladiator.drag = true
|
294
|
+
list = event.widget.getControl
|
295
|
+
event.data = list.getSelection.first
|
296
|
+
}
|
297
|
+
}
|
240
298
|
}
|
241
299
|
@tree = tree(:virtual, :border, :h_scroll, :v_scroll) {
|
242
|
-
|
243
|
-
|
300
|
+
#visible bind(Dir, 'local_dir.filter') {|f| !f}
|
301
|
+
items bind(Dir, :local_dir), tree_properties(children: :children, text: :name)
|
302
|
+
drag_source(DND::DROP_COPY) {
|
303
|
+
transfer [TextTransfer.getInstance].to_java(Transfer)
|
304
|
+
on_drag_set_data { |event|
|
305
|
+
Gladiator.drag = true
|
306
|
+
tree = event.widget.getControl
|
307
|
+
tree_item = tree.getSelection.first
|
308
|
+
event.data = tree_item.getData.path
|
309
|
+
}
|
244
310
|
}
|
245
|
-
#visible bind(Gladiator::Dir, 'local_dir.filter') {|f| !f}
|
246
|
-
items bind(Gladiator::Dir, :local_dir), tree_properties(children: :children, text: :name)
|
247
311
|
menu {
|
248
312
|
@open_menu_item = menu_item {
|
249
313
|
text 'Open'
|
250
314
|
on_widget_selected {
|
251
|
-
|
315
|
+
Dir.local_dir.selected_child_path = extract_tree_item_path(@tree.swt_widget.getSelection.first)
|
252
316
|
}
|
253
317
|
}
|
254
318
|
menu_item(:separator)
|
@@ -262,7 +326,7 @@ module Glimmer
|
|
262
326
|
menu_item {
|
263
327
|
text 'Refresh'
|
264
328
|
on_widget_selected {
|
265
|
-
|
329
|
+
Dir.local_dir.refresh
|
266
330
|
}
|
267
331
|
}
|
268
332
|
menu_item {
|
@@ -284,17 +348,21 @@ module Glimmer
|
|
284
348
|
}
|
285
349
|
}
|
286
350
|
}
|
287
|
-
|
351
|
+
on_swt_menudetect { |event|
|
288
352
|
path = extract_tree_item_path(@tree.swt_widget.getSelection.first)
|
289
353
|
@open_menu_item.swt_widget.setEnabled(!::Dir.exist?(path)) if path
|
290
354
|
}
|
291
355
|
on_mouse_up {
|
292
|
-
Gladiator
|
293
|
-
|
356
|
+
if Gladiator.drag_and_drop
|
357
|
+
Gladiator.drag_and_drop = false
|
358
|
+
else
|
359
|
+
Dir.local_dir.selected_child_path = extract_tree_item_path(@tree.swt_widget.getSelection&.first)
|
360
|
+
@text_editor&.text_widget&.setFocus
|
361
|
+
end
|
294
362
|
}
|
295
363
|
on_key_pressed { |key_event|
|
296
364
|
if Glimmer::SWT::SWTProxy.include?(key_event.keyCode, :cr)
|
297
|
-
|
365
|
+
Dir.local_dir.selected_child_path = extract_tree_item_path(@tree.swt_widget.getSelection&.first)
|
298
366
|
@text_editor&.text_widget&.setFocus
|
299
367
|
end
|
300
368
|
}
|
@@ -317,15 +385,18 @@ module Glimmer
|
|
317
385
|
grid_layout 1, false
|
318
386
|
layout_data :fill, :fill, true, true
|
319
387
|
composite {
|
320
|
-
grid_layout
|
388
|
+
grid_layout 3, false
|
389
|
+
|
390
|
+
# row 1
|
391
|
+
|
321
392
|
@file_path_label = styled_text(:none) {
|
322
393
|
layout_data(:fill, :fill, true, false) {
|
323
|
-
horizontal_span
|
394
|
+
horizontal_span 3
|
324
395
|
}
|
325
396
|
background color(:widget_background)
|
326
397
|
editable false
|
327
398
|
caret nil
|
328
|
-
text bind(
|
399
|
+
text bind(Dir.local_dir, 'selected_child.path')
|
329
400
|
on_mouse_up {
|
330
401
|
@file_path_label.swt_widget.selectAll
|
331
402
|
}
|
@@ -333,6 +404,9 @@ module Glimmer
|
|
333
404
|
@file_path_label.swt_widget.setSelection(0, 0)
|
334
405
|
}
|
335
406
|
}
|
407
|
+
|
408
|
+
# row 2
|
409
|
+
|
336
410
|
label {
|
337
411
|
text 'Line:'
|
338
412
|
}
|
@@ -340,16 +414,20 @@ module Glimmer
|
|
340
414
|
layout_data(:fill, :fill, true, false) {
|
341
415
|
minimum_width 400
|
342
416
|
}
|
343
|
-
text bind(
|
417
|
+
text bind(Dir.local_dir, 'selected_child.line_number', on_read: :to_s, on_write: :to_i)
|
344
418
|
on_key_pressed { |key_event|
|
345
419
|
if key_event.keyCode == swt(:cr)
|
346
|
-
@text_editor
|
420
|
+
@text_editor&.text_widget&.setFocus
|
347
421
|
end
|
348
422
|
}
|
349
423
|
on_verify_text { |event|
|
350
424
|
event.doit = !event.text.match(/^\d*$/).to_a.empty?
|
351
425
|
}
|
352
426
|
}
|
427
|
+
label
|
428
|
+
|
429
|
+
# row 3
|
430
|
+
|
353
431
|
label {
|
354
432
|
text 'Find:'
|
355
433
|
}
|
@@ -357,13 +435,34 @@ module Glimmer
|
|
357
435
|
layout_data(:fill, :fill, true, false) {
|
358
436
|
minimum_width 400
|
359
437
|
}
|
360
|
-
text bind(
|
438
|
+
text bind(Dir.local_dir, 'selected_child.find_text')
|
361
439
|
on_key_pressed { |key_event|
|
440
|
+
if key_event.stateMask == swt(COMMAND_KEY) && key_event.keyCode == swt(:cr)
|
441
|
+
Dir.local_dir.selected_child.case_sensitive = !Dir.local_dir.selected_child.case_sensitive
|
442
|
+
Dir.local_dir.selected_child&.find_next
|
443
|
+
end
|
362
444
|
if key_event.keyCode == swt(:cr)
|
363
|
-
|
445
|
+
Dir.local_dir.selected_child&.find_next
|
364
446
|
end
|
365
447
|
}
|
366
448
|
}
|
449
|
+
composite {
|
450
|
+
row_layout
|
451
|
+
button(:check) {
|
452
|
+
selection bind(Dir.local_dir, 'selected_child.case_sensitive')
|
453
|
+
on_key_pressed { |key_event|
|
454
|
+
if key_event.keyCode == swt(:cr)
|
455
|
+
Dir.local_dir.selected_child&.find_next
|
456
|
+
end
|
457
|
+
}
|
458
|
+
}
|
459
|
+
label {
|
460
|
+
text 'Case-sensitive'
|
461
|
+
}
|
462
|
+
}
|
463
|
+
|
464
|
+
# row 4
|
465
|
+
|
367
466
|
label {
|
368
467
|
text 'Replace:'
|
369
468
|
}
|
@@ -371,36 +470,59 @@ module Glimmer
|
|
371
470
|
layout_data(:fill, :fill, true, false) {
|
372
471
|
minimum_width 300
|
373
472
|
}
|
374
|
-
text bind(
|
473
|
+
text bind(Dir.local_dir, 'selected_child.replace_text')
|
375
474
|
on_focus_gained {
|
376
|
-
|
475
|
+
Dir.local_dir.selected_child&.ensure_find_next
|
377
476
|
}
|
378
477
|
on_key_pressed { |key_event|
|
379
478
|
if key_event.keyCode == swt(:cr)
|
380
|
-
|
479
|
+
if Dir.local_dir.selected_child
|
480
|
+
Command.do(Dir.local_dir.selected_child, :replace_next!)
|
481
|
+
end
|
381
482
|
end
|
382
483
|
}
|
383
484
|
}
|
485
|
+
label
|
384
486
|
}
|
385
|
-
@
|
386
|
-
layout_data(:fill, :fill, true, true)
|
487
|
+
@tab_folder_sash_form = sash_form {
|
488
|
+
layout_data(:fill, :fill, true, true) {
|
489
|
+
width_hint 640
|
490
|
+
height_hint 480
|
491
|
+
}
|
492
|
+
sash_width 10
|
493
|
+
@tab_folder = tab_folder {
|
494
|
+
drag_source(DND::DROP_COPY) {
|
495
|
+
transfer [TextTransfer.getInstance].to_java(Transfer)
|
496
|
+
event_data = nil
|
497
|
+
on_drag_start {|event|
|
498
|
+
Gladiator.drag = true
|
499
|
+
tab_folder = event.widget.getControl
|
500
|
+
tab_item = tab_folder.getItem(Point.new(event.x, event.y))
|
501
|
+
event_data = tab_item.getData('file_path')
|
502
|
+
}
|
503
|
+
on_drag_set_data { |event|
|
504
|
+
event.data = event_data
|
505
|
+
}
|
506
|
+
}
|
507
|
+
}
|
508
|
+
@tab_folder.swt_widget.setData('proxy', @tab_folder)
|
387
509
|
}
|
388
510
|
}
|
389
511
|
}
|
390
512
|
}
|
391
|
-
|
513
|
+
|
392
514
|
def load_config
|
393
515
|
if ::File.exists?(@config_file_path)
|
394
516
|
config_yaml = ::File.read(@config_file_path)
|
395
517
|
return if config_yaml.to_s.strip.empty?
|
396
518
|
@config = YAML.load(config_yaml)
|
397
519
|
@config[:open_file_paths].to_a.each do |file_path|
|
398
|
-
|
520
|
+
Dir.local_dir.selected_child_path = file_path
|
399
521
|
end
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
body_root.
|
522
|
+
Dir.local_dir.selected_child_path = @config[:selected_child_path] if @config[:selected_child_path]
|
523
|
+
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&.top_index = @config[:top_index].to_i if @config[:top_index]
|
525
|
+
body_root.on_swt_show {
|
404
526
|
swt_widget.setSize(@config[:shell_width], @config[:shell_height]) if @config[:shell_width] && @config[:shell_height]
|
405
527
|
swt_widget.setLocation(@config[:shell_x], @config[:shell_y]) if @config[:shell_x] && @config[:shell_y]
|
406
528
|
@loaded_config = true
|
@@ -412,7 +534,7 @@ module Glimmer
|
|
412
534
|
|
413
535
|
def save_config
|
414
536
|
return unless @loaded_config
|
415
|
-
child =
|
537
|
+
child = Dir.local_dir.selected_child
|
416
538
|
return if child.nil?
|
417
539
|
@config = {
|
418
540
|
selected_child_path: child.path,
|
@@ -430,12 +552,31 @@ module Glimmer
|
|
430
552
|
puts e.full_message
|
431
553
|
end
|
432
554
|
|
555
|
+
def close_tab_folder
|
556
|
+
if @tab_folder2 && !selected_tab_item
|
557
|
+
if @tab_folder == @tab_folder2
|
558
|
+
@tab_folder2.swt_widget.dispose
|
559
|
+
@tab_folder = @tab_folder1
|
560
|
+
else
|
561
|
+
@tab_folder1.swt_widget.dispose
|
562
|
+
@tab_folder = @tab_folder1 = @tab_folder2
|
563
|
+
end
|
564
|
+
@tab_folder2 = nil
|
565
|
+
|
566
|
+
@tab_item = @tab_folder.swt_widget.getData('selected_tab_item')
|
567
|
+
@text_editor = @tab_item.swt_tab_item.getData('text_editor')
|
568
|
+
Dir.local_dir.selected_child = @tab_item.swt_tab_item.getData('file')
|
569
|
+
|
570
|
+
body_root.pack_same_size
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
433
574
|
def selected_tab_item
|
434
|
-
@tab_folder.swt_widget.getItems.detect { |ti| ti.getData('file_path') ==
|
575
|
+
@tab_folder.swt_widget.getItems.detect { |ti| ti.getData('file_path') == Dir.local_dir.selected_child&.path }
|
435
576
|
end
|
436
577
|
|
437
578
|
def other_tab_items
|
438
|
-
@tab_folder.swt_widget.getItems.reject { |ti| ti.getData('file_path') ==
|
579
|
+
@tab_folder.swt_widget.getItems.reject { |ti| ti.getData('file_path') == Dir.local_dir.selected_child&.path }
|
439
580
|
end
|
440
581
|
|
441
582
|
def extract_tree_item_path(tree_item)
|
@@ -448,15 +589,16 @@ module Glimmer
|
|
448
589
|
end
|
449
590
|
|
450
591
|
def select_tree_item
|
451
|
-
return unless
|
452
|
-
tree_items_to_select = @tree.depth_first_search { |ti| ti.getData.path ==
|
592
|
+
return unless Dir.local_dir.selected_child&.name
|
593
|
+
tree_items_to_select = @tree.depth_first_search { |ti| ti.getData.path == Dir.local_dir.selected_child.path }
|
453
594
|
@tree.swt_widget.setSelection(tree_items_to_select)
|
454
595
|
end
|
455
596
|
|
456
597
|
def delete_tree_item(tree_item)
|
598
|
+
return if tree_item.nil?
|
457
599
|
file = tree_item.getData
|
458
600
|
parent_path = ::File.dirname(file.path)
|
459
|
-
file.delete!
|
601
|
+
file.delete! # TODO consider supporting command undo/redo
|
460
602
|
Dir.local_dir.refresh(async: false)
|
461
603
|
parent_tree_item = @tree.depth_first_search {|ti| ti.getData.path == parent_path}.first
|
462
604
|
@tree.swt_widget.showItem(parent_tree_item)
|
@@ -465,6 +607,8 @@ module Glimmer
|
|
465
607
|
# if file.is_a?(::File)
|
466
608
|
# close tab
|
467
609
|
# end
|
610
|
+
rescue => e
|
611
|
+
puts e.full_message
|
468
612
|
end
|
469
613
|
|
470
614
|
def rename_selected_tree_item
|
@@ -477,6 +621,7 @@ module Glimmer
|
|
477
621
|
Dir.local_dir.pause_refresh
|
478
622
|
tree_item = @tree.swt_widget.getSelection.first
|
479
623
|
directory_path = extract_tree_item_path(tree_item)
|
624
|
+
return if directory_path.nil?
|
480
625
|
if !::Dir.exist?(directory_path)
|
481
626
|
tree_item = tree_item.getParentItem
|
482
627
|
directory_path = ::File.dirname(directory_path)
|
@@ -5,10 +5,11 @@ module Glimmer
|
|
5
5
|
|
6
6
|
options :file
|
7
7
|
|
8
|
-
attr_reader :text_widget
|
8
|
+
attr_reader :text_proxy, :text_widget
|
9
9
|
|
10
10
|
after_body {
|
11
11
|
@text_widget = @text.swt_widget
|
12
|
+
@text_proxy = @text
|
12
13
|
}
|
13
14
|
|
14
15
|
body {
|
@@ -36,35 +37,52 @@ module Glimmer
|
|
36
37
|
layout_data :fill, :fill, true, true
|
37
38
|
font name: 'Consolas', height: OS.mac? ? 15 : 12
|
38
39
|
foreground rgb(75, 75, 75)
|
39
|
-
text bind(file,
|
40
|
+
text bind(file, :content)
|
40
41
|
focus true
|
41
42
|
selection bind(file, 'selection')
|
42
43
|
selection_count bind(file, 'selection_count')
|
43
44
|
top_index bind(file, 'top_index')
|
45
|
+
drop_target(DND::DROP_COPY) {
|
46
|
+
transfer [TextTransfer.getInstance].to_java(Transfer)
|
47
|
+
on_drag_enter { |event|
|
48
|
+
event.detail = DND::DROP_COPY
|
49
|
+
}
|
50
|
+
on_drop { |event|
|
51
|
+
Gladiator.drag_and_drop = true
|
52
|
+
Dir.local_dir.selected_child = nil
|
53
|
+
Dir.local_dir.selected_child_path = event.data
|
54
|
+
Gladiator.drag = false
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
44
58
|
on_focus_lost {
|
45
59
|
file&.write_dirty_content
|
46
60
|
}
|
47
61
|
on_key_pressed { |key_event|
|
48
|
-
if key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == '
|
49
|
-
|
50
|
-
|
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
|
+
key_event.doit = !Command.redo(file)
|
64
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'z'
|
65
|
+
key_event.doit = !Command.undo(file)
|
66
|
+
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == '/'
|
67
|
+
Command.do(file, :comment_line!)
|
68
|
+
key_event.doit = false
|
51
69
|
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'k'
|
52
|
-
file
|
70
|
+
Command.do(file, :kill_line!)
|
53
71
|
key_event.doit = false
|
54
72
|
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'd'
|
55
|
-
file
|
73
|
+
Command.do(file, :duplicate_line!)
|
56
74
|
key_event.doit = false
|
57
75
|
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == '['
|
58
|
-
file
|
76
|
+
Command.do(file, :outdent!)
|
59
77
|
key_event.doit = false
|
60
78
|
elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == ']'
|
61
|
-
file
|
79
|
+
Command.do(file, :indent!)
|
62
80
|
key_event.doit = false
|
63
81
|
elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && key_event.keyCode == swt(:cr)
|
64
|
-
file
|
82
|
+
Command.do(file, :prefix_new_line!)
|
65
83
|
key_event.doit = false
|
66
84
|
elsif key_event.stateMask == swt(COMMAND_KEY) && key_event.keyCode == swt(:cr)
|
67
|
-
file
|
85
|
+
Command.do(file, :insert_new_line!)
|
68
86
|
key_event.doit = false
|
69
87
|
elsif key_event.keyCode == swt(:page_up)
|
70
88
|
file.page_up
|
@@ -79,10 +97,10 @@ module Glimmer
|
|
79
97
|
file.end
|
80
98
|
key_event.doit = false
|
81
99
|
elsif key_event.stateMask == swt(COMMAND_KEY) && key_event.keyCode == swt(:arrow_up)
|
82
|
-
file
|
100
|
+
Command.do(file, :move_up!)
|
83
101
|
key_event.doit = false
|
84
102
|
elsif key_event.stateMask == swt(COMMAND_KEY) && key_event.keyCode == swt(:arrow_down)
|
85
|
-
file
|
103
|
+
Command.do(file, :move_down!)
|
86
104
|
key_event.doit = false
|
87
105
|
end
|
88
106
|
}
|
@@ -95,7 +113,7 @@ module Glimmer
|
|
95
113
|
end
|
96
114
|
when swt(:tab)
|
97
115
|
if file.selection_count.to_i > 0
|
98
|
-
file
|
116
|
+
Command.do(file, :indent!)
|
99
117
|
verify_event.doit = false
|
100
118
|
else
|
101
119
|
verify_event.text = ' '
|
metadata
CHANGED
@@ -1,32 +1,32 @@
|
|
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.2.3
|
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-07-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: 0.
|
18
|
+
version: 0.4.1
|
19
19
|
- - "<"
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: 2.0.0
|
22
|
-
name: glimmer
|
22
|
+
name: glimmer-dsl-swt
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0.
|
29
|
+
version: 0.4.1
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 2.0.0
|
@@ -100,20 +100,6 @@ dependencies:
|
|
100
100
|
- - ">="
|
101
101
|
- !ruby/object:Gem::Version
|
102
102
|
version: '0'
|
103
|
-
- !ruby/object:Gem::Dependency
|
104
|
-
requirement: !ruby/object:Gem::Requirement
|
105
|
-
requirements:
|
106
|
-
- - "~>"
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
version: 0.8.1
|
109
|
-
name: puts_debuggerer
|
110
|
-
type: :development
|
111
|
-
prerelease: false
|
112
|
-
version_requirements: !ruby/object:Gem::Requirement
|
113
|
-
requirements:
|
114
|
-
- - "~>"
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
version: 0.8.1
|
117
103
|
description: Gladiator (short for Glimmer Editor) is a Glimmer sample project under
|
118
104
|
on-going development. It is not intended to be a full-fledged editor by any means,
|
119
105
|
yet mostly a fun educational exercise in using Glimmer to build a text editor. Gladiator
|
@@ -130,9 +116,11 @@ extra_rdoc_files:
|
|
130
116
|
files:
|
131
117
|
- LICENSE.txt
|
132
118
|
- README.md
|
119
|
+
- VERSION
|
133
120
|
- bin/gladiator
|
134
121
|
- bin/gladiator_runner.rb
|
135
122
|
- lib/glimmer-cs-gladiator.rb
|
123
|
+
- lib/models/glimmer/gladiator/command.rb
|
136
124
|
- lib/models/glimmer/gladiator/dir.rb
|
137
125
|
- lib/models/glimmer/gladiator/file.rb
|
138
126
|
- lib/views/glimmer/gladiator.rb
|