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 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