glimmer-cs-gladiator 0.2.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1de235cba50741874f8719322e8c35ffea667929d465e23f3fd2df8a4866acb4
4
- data.tar.gz: 20273095f8e93bff72840e3094ff5f203bc57bf78e0c7ee8b14e0765f7025ca5
3
+ metadata.gz: 1b17d21c81f04c1f1fc1ad516013d9e62a6abeb0900096b1bd13c95c6cf10ccd
4
+ data.tar.gz: 78d41ab949f3f40c71f2abfa26310a32f3720eecb64dcf5b90d2f155c2b35345
5
5
  SHA512:
6
- metadata.gz: 5aba5bf9ad1ba8f077486dbc0d04da40c2138bf02c32d0565e27a520935da088d811e51bd9c90f868ce24c0775add77914e3dbebdfa4abb89f9333719f79cdcb
7
- data.tar.gz: cbb76756dae0901141a3c3b2d69849d1aed409e26d1f7a8ff1fa30a410c3e11edfecd93c4ff03e35023aa2ee64a7dccad276878bb563f94c1298c144e93dfc4d
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.2 - [Ugliest Text Editor Ever](https://www.reddit.com/r/ruby/comments/hgve8k/gladiator_glimmer_editor_ugliest_text_editor_ever/)
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
  [![Gem Version](https://badge.fury.io/rb/glimmer-cs-gladiator.svg)](http://badge.fury.io/rb/glimmer-cs-gladiator)
4
4
 
5
5
  ![Gladiator](images/glimmer-gladiator.png)
6
6
 
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).
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 well on Windows.
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) (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)
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.2.2'
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
- Copyright (c) 2020 Andy Maleh. See [LICENSE.txt](LICENSE.txt) for
156
- further details.
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) (Ruby Desktop Development GUI Library).
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.2.2
1
+ 0.4.0
@@ -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.undo
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&.redo
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 ||= new(ENV['LOCAL_DIR'] || '.').tap do |dir|
13
- dir.refresh
14
- @filewatcher = Filewatcher.new(dir.path)
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
- dir.refresh if !filename.include?('new_file') && !dir.selected_child_path_history.include?(filename) && filename != dir.selected_child_path
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, :path, :display_path
28
- attr_reader :name, :parent
29
- attr_writer :all_children, :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
- @display_path = path
33
- @path = ::File.expand_path(@display_path)
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(@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 }
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
- new_all_children = retrieve_all_children
69
- new_children = retrieve_children
93
+ retrieve_children
94
+ collect_all_children
70
95
  refresh_operation = lambda do
71
- self.all_children = new_all_children
72
- self.children = new_children
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
- self.filtered_path_options = filtered.to_a.map(&:display_path)
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
- all_children_files.select do |child|
93
- child.path.downcase.include?(filter.downcase) ||
94
- child.path.downcase.gsub(/[_\/\.]/, '').include?(filter.downcase)
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 ||= retrieve_all_children
128
+ @all_children ||= collect_all_children
100
129
  end
101
130
 
102
- def retrieve_all_children
103
- ::Dir.glob(::File.join(@display_path, '**', '*')).map {|p| ::File.file?(p) ? Gladiator::File.new(p) : Gladiator::Dir.new(p)}
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?(selected_path) ||
113
- (selected_child && ::File.expand_path(selected_child.path) == ::File.expand_path(selected_path))
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, :selection_count, :line_number, :find_text, :replace_text, :top_index, :path, :display_path, :case_sensitive
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
- @path = ::File.expand_path(path)
17
- @top_index = 0
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
- Command.do(self) # record a native (OS-widget) operation
48
- self.dirty_content = value
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
- if OS.linux?
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
- self.display_path = display_path.sub(/#{Regexp.escape(@name)}$/, the_name)
85
+ new_path = path.sub(/#{Regexp.escape(@name)}$/, the_name)
70
86
  @name = the_name
71
- new_path = ::File.expand_path(display_path)
72
- FileUtils.mv(path, new_path)
73
- self.path = new_path
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
- self.caret_position = caret_position_for_line_index(old_caret_position_line_index)
205
- self.selection_count = (caret_position_for_line_index(old_end_caret_line_index + 1) - self.caret_position)
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
- self.caret_position = caret_position_for_line_index(old_caret_position_line_index)
234
- self.selection_count = (caret_position_for_line_index(old_end_caret_line_index + 1) - self.caret_position)
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 Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 'r'
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 Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 't'
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
- Dir.local_dir.all_children # pre-caches children
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.top_index') do
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 2, false
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 3
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, :fill, true, false) {
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[:open_file_paths].to_a.each do |file_path|
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&.top_index = @config[:top_index].to_i if @config[:top_index]
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
- top_index: child.top_index,
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
- open_file_paths: Dir.local_dir.selected_child_path_history,
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 = text(:multi) {
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
- top_index bind(file, 'top_index', read_only: true)
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
- @text = text(:multi, :border, :h_scroll, :v_scroll) {
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, 'selection')
43
- selection_count bind(file, 'selection_count')
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
- on_key_pressed { |key_event|
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
- key_code = verify_event.keyCode
109
- case key_code
110
- when swt(:cr)
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 swt(:tab)
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.2.2
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-07-21 00:00:00.000000000 Z
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: 0.4.1
18
+ version: 4.17.4.2
19
19
  - - "<"
20
20
  - !ruby/object:Gem::Version
21
- version: 2.0.0
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: 0.4.1
29
+ version: 4.17.4.2
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: 2.0.0
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.0.6
147
+ rubygems_version: 3.1.4
148
148
  signing_key:
149
149
  specification_version: 4
150
150
  summary: Gladiator (Glimmer Editor) - Glimmer Custom Shell