glimmer-cs-gladiator 0.1.3 → 0.1.8

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