redcar 0.2.9dev → 0.3.0dev

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/ROADMAP.md +2 -2
  2. data/Rakefile +4 -4
  3. data/lib/redcar/boot.rb +3 -0
  4. data/lib/redcar/install.rb +3 -3
  5. data/lib/redcar/runner.rb +1 -1
  6. data/lib/redcar/usage.rb +5 -0
  7. data/plugins/application/features/step_definitions/tree_steps.rb +6 -0
  8. data/plugins/application/features/support/env.rb +59 -1
  9. data/plugins/application/icons/darwin-file.png +0 -0
  10. data/plugins/application/icons/darwin-folder.png +0 -0
  11. data/plugins/application/lib/application.rb +4 -0
  12. data/plugins/application/lib/application/command/executor.rb +3 -1
  13. data/plugins/application/lib/application/dialog.rb +5 -0
  14. data/plugins/application/lib/application/treebook.rb +30 -0
  15. data/plugins/application/lib/application/window.rb +3 -3
  16. data/plugins/application/spec/application/treebook_spec.rb +27 -0
  17. data/plugins/application/spec/application/window_spec.rb +2 -2
  18. data/plugins/application_swt/lib/application_swt.rb +1 -0
  19. data/plugins/application_swt/lib/application_swt/dialog_adapter.rb +12 -0
  20. data/plugins/application_swt/lib/application_swt/swt_wrapper.rb +4 -7
  21. data/plugins/application_swt/lib/application_swt/treebook.rb +33 -0
  22. data/plugins/application_swt/lib/application_swt/window.rb +63 -12
  23. data/plugins/auto_indenter/lib/auto_indenter.rb +12 -0
  24. data/plugins/auto_indenter/lib/auto_indenter/document_controller.rb +27 -0
  25. data/plugins/auto_indenter/plugin.yaml +12 -0
  26. data/plugins/edit_view/features/step_definitions/notebook_steps.rb +1 -1
  27. data/plugins/edit_view/features/step_definitions/tab_steps.rb +11 -0
  28. data/plugins/edit_view/features/step_definitions/window_steps.rb +2 -2
  29. data/plugins/edit_view/features/support/env.rb +4 -26
  30. data/plugins/edit_view/lib/edit_view.rb +2 -1
  31. data/plugins/edit_view/lib/edit_view/document.rb +46 -14
  32. data/plugins/edit_view/lib/edit_view/document/controller.rb +30 -0
  33. data/plugins/edit_view/lib/edit_view/{mirror.rb → document/mirror.rb} +1 -1
  34. data/plugins/edit_view_swt/lib/edit_view_swt.rb +22 -0
  35. data/plugins/edit_view_swt/lib/edit_view_swt/document.rb +29 -0
  36. data/plugins/project/features/open_directory_tree.feature +17 -0
  37. data/plugins/project/features/step_definitions/directory_steps.rb +4 -0
  38. data/plugins/project/lib/project.rb +51 -0
  39. data/plugins/project/lib/project/dir_controller.rb +14 -0
  40. data/plugins/project/lib/project/dir_mirror.rb +18 -3
  41. data/plugins/project/lib/project/file_mirror.rb +1 -1
  42. data/plugins/redcar/redcar.rb +3 -0
  43. data/plugins/repl/lib/repl/internal_mirror.rb +1 -1
  44. data/plugins/tree/lib/tree.rb +17 -0
  45. data/plugins/tree/lib/tree/controller.rb +12 -0
  46. data/plugins/{tree_view/lib/tree_view → tree/lib/tree}/mirror.rb +1 -1
  47. data/plugins/{tree_view → tree}/plugin.yaml +4 -4
  48. data/plugins/{tree_view → tree}/spec/spec_helper.rb +0 -0
  49. data/plugins/tree_view_swt/lib/tree_view_swt.rb +122 -0
  50. metadata +21 -7
  51. data/plugins/tree_view/lib/tree_view.rb +0 -7
data/ROADMAP.md CHANGED
@@ -13,8 +13,8 @@ The features of this release are chosen to be the minimum to make Redcar self-ho
13
13
  * File editing (done)
14
14
  * Multiple notebook panes (done)
15
15
  * Multiple windows (done)
16
- * _Basic_ project pane
17
- * Auto-indenter
16
+ * _Basic_ project pane (done)
17
+ * Auto-indenter (done)
18
18
  * Tests passing on 3 platforms
19
19
 
20
20
  0.3.1dev - *Developer preview*
data/Rakefile CHANGED
@@ -79,9 +79,9 @@ task :build do
79
79
  sh("ant jar -f vendor/java-mateview/build.xml")
80
80
  cp("vendor/java-mateview/lib/java-mateview.rb", "plugins/edit_view_swt/vendor/")
81
81
  cp("vendor/java-mateview/release/java-mateview.jar", "plugins/edit_view_swt/vendor/")
82
- Dir["vendor/java-mateview/lib/*.jar"].each do |fn|
83
- FileUtils.cp(fn, "plugins/edit_view_swt/vendor/")
84
- end
82
+ # Dir["vendor/java-mateview/lib/*.jar"].each do |fn|
83
+ # FileUtils.cp(fn, "plugins/edit_view_swt/vendor/")
84
+ # end
85
85
  end
86
86
 
87
87
  desc "Package jars and submodules into big tar file"
@@ -121,7 +121,7 @@ spec = Gem::Specification.new do |s|
121
121
 
122
122
  # Change these as appropriate
123
123
  s.name = "redcar"
124
- s.version = "0.2.9dev"
124
+ s.version = "0.3.0dev"
125
125
  s.summary = "A JRuby text editor. (Installing the gem will take a while as it downloads assets during the install.)"
126
126
  s.author = "Daniel Lucraft"
127
127
  s.email = "dan@fluentradical.com"
@@ -14,6 +14,8 @@ require 'freebase/freebase'
14
14
  require 'redcar/ruby_extensions'
15
15
  require 'redcar/usage'
16
16
 
17
+ require 'forwardable'
18
+
17
19
  # ## Loading and Initialization
18
20
  #
19
21
  # Every feature in Redcar is written as a plugin. This module contains a few
@@ -101,5 +103,6 @@ module Redcar
101
103
  end
102
104
 
103
105
  usage = Redcar::Usage.new
106
+ usage.version_string
104
107
  usage.version_requested
105
108
  usage.help_requested
@@ -3,10 +3,10 @@ require 'rbconfig'
3
3
  require 'open-uri'
4
4
  require 'fileutils'
5
5
 
6
- # Methods used in gem installation hooks
7
- #
8
- # Cribbed from the zerg and zerg_support gems by Victor Costan (big woop!)
9
6
  module Redcar
7
+ # Methods used in gem installation hooks
8
+ #
9
+ # Cribbed from the zerg and zerg_support gems by Victor Costan (big woop!)
10
10
  class Install
11
11
 
12
12
  # tricks rubygems into believeing that the extension compiled and worked out
@@ -11,7 +11,7 @@ module Redcar
11
11
  # our vendored jarred one (useful for gems).
12
12
  def spin_up
13
13
  bin = "#{File.dirname(__FILE__)}/../../bin/redcar"
14
- jruby_complete = Dir[File.dirname(__FILE__) + "/../jruby-complete*.jar"].first
14
+ jruby_complete = Dir[File.dirname(__FILE__) + "/../jruby-complete-1.4.0.jar"].first
15
15
  args = []
16
16
  if false
17
17
  command = "jruby #{java_args} \"#{bin}\" #{ARGV.join(' ')}"
@@ -2,6 +2,11 @@
2
2
  module Redcar
3
3
 
4
4
  class Usage
5
+ def version_string
6
+ str = "Redcar #{Redcar::VERSION} (jruby )"
7
+ puts str
8
+ end
9
+
5
10
  def version_requested
6
11
  if ARGV.include?("-v")
7
12
  puts "Redcar #{Redcar::VERSION}"
@@ -0,0 +1,6 @@
1
+ Then /^I should see "([^\"]*)" in the tree$/ do |rows|
2
+ rows = rows.split(",").map {|r| r.strip}
3
+ rows.each do |row|
4
+ top_tree.items.include?(row).should be_true
5
+ end
6
+ end
@@ -9,6 +9,26 @@ module SwtHelper
9
9
  def first_shell
10
10
  Redcar::ApplicationSWT.display.get_shells.to_a.first
11
11
  end
12
+
13
+ def sash_form
14
+ first_shell.getChildren.to_a.first
15
+ end
16
+
17
+ def tree_book
18
+ sash_form.getChildren.to_a.first
19
+ end
20
+
21
+ def top_tree
22
+ r = tree_book.getLayout.topControl
23
+ r.extend(TreeHelpers)
24
+ r
25
+ end
26
+
27
+ module TreeHelpers
28
+ def items
29
+ getItems.to_a.map {|item| item.getText}
30
+ end
31
+ end
12
32
  end
13
33
 
14
34
  class FakeDialogAdapter
@@ -24,9 +44,47 @@ class FakeDialogAdapter
24
44
  @responses[:open_file]
25
45
  end
26
46
 
47
+ def open_directory(*args)
48
+ @responses[:open_directory]
49
+ end
50
+
27
51
  def save_file(*args)
28
52
  @responses[:save_file]
29
53
  end
30
54
  end
31
55
 
32
- World(SwtHelper)
56
+ World(SwtHelper)
57
+
58
+ After do
59
+ Redcar.app.windows.each do |win|
60
+ while tree = win.treebook.trees.first
61
+ Redcar::ApplicationSWT.sync_exec do
62
+ win.treebook.remove_tree(tree)
63
+ end
64
+ end
65
+ win.notebooks.each do |notebook|
66
+ while tab = notebook.tabs.first
67
+ Redcar::ApplicationSWT.sync_exec do
68
+ tab.close
69
+ end
70
+ end
71
+ end
72
+ if win.notebooks.length == 2
73
+ Redcar::ApplicationSWT.sync_exec do
74
+ win.close_notebook
75
+ end
76
+ end
77
+ end
78
+ while Redcar.app.windows.length > 1
79
+ Redcar::ApplicationSWT.sync_exec do
80
+ Redcar.app.windows.last.close
81
+ end
82
+ end
83
+ end
84
+
85
+
86
+
87
+
88
+
89
+
90
+
@@ -11,6 +11,7 @@ require 'application/menu/builder'
11
11
  require 'application/notebook'
12
12
  require 'application/tab'
13
13
  require 'application/tab/command'
14
+ require 'application/treebook'
14
15
  require 'application/window'
15
16
 
16
17
  module Redcar
@@ -81,6 +82,9 @@ module Redcar
81
82
  end
82
83
  @window_handlers[window].each {|h| window.remove_listener(h) }
83
84
  @window_handlers.delete(window)
85
+ if windows.length == 0 and [:linux, :windows].include?(Core.platform)
86
+ quit
87
+ end
84
88
  end
85
89
 
86
90
  def focussed_window
@@ -1,3 +1,4 @@
1
+
1
2
  module Redcar
2
3
  class Command
3
4
  class Executor
@@ -15,7 +16,7 @@ module Redcar
15
16
  def execute
16
17
  @command_instance.environment(Executor.current_environment)
17
18
  begin
18
- @command_instance.execute
19
+ result = @command_instance.execute
19
20
  rescue Object => e
20
21
  @command_instance.error = e
21
22
  log_error
@@ -24,6 +25,7 @@ module Redcar
24
25
  log_error
25
26
  end
26
27
  record
28
+ result
27
29
  end
28
30
 
29
31
  private
@@ -5,6 +5,11 @@ module Redcar
5
5
  def self.open_file(window, options)
6
6
  Redcar.gui.dialog_adapter.open_file(window, options)
7
7
  end
8
+
9
+ # Prompt the user with an open directory dialog. Returns a path.
10
+ def self.open_directory(window, options)
11
+ Redcar.gui.dialog_adapter.open_directory(window, options)
12
+ end
8
13
 
9
14
  # Prompt the user with an save file dialog. Returns a path.
10
15
  def self.save_file(window, options)
@@ -0,0 +1,30 @@
1
+ module Redcar
2
+ class Treebook
3
+ include Redcar::Observable
4
+ include Redcar::Model
5
+
6
+ attr_reader :trees
7
+
8
+ def initialize
9
+ @trees = []
10
+ end
11
+
12
+ # Add a tree to this treebook
13
+ #
14
+ # @param [Redcar::Tree]
15
+ def add_tree(tree)
16
+ @trees << tree
17
+ notify_listeners(:tree_added, tree)
18
+ end
19
+
20
+ # Remove a tree from this treebook
21
+ #
22
+ # @param [Redcar::Tree]
23
+ def remove_tree(tree)
24
+ if @trees.include?(tree)
25
+ @trees.delete(tree)
26
+ notify_listeners(:tree_removed, tree)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -10,15 +10,15 @@ module Redcar
10
10
  end
11
11
 
12
12
  attr_reader :notebooks, :notebook_orientation
13
- attr_reader :trees
14
-
13
+ attr_reader :treebook
14
+
15
15
  def initialize
16
16
  Window.all << self
17
17
  @visible = false
18
18
  @notebooks = []
19
- @trees = []
20
19
  @notebook_orientation = :horizontal
21
20
  create_notebook
21
+ @treebook = Treebook.new
22
22
  self.title = "Redcar"
23
23
  end
24
24
 
@@ -0,0 +1,27 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe Redcar::Treebook do
4
+
5
+ describe "a new treebook" do
6
+ before do
7
+ @treebook = Redcar::Treebook.new
8
+ end
9
+
10
+ it "has no trees" do
11
+ @treebook.trees.length.should == 0
12
+ end
13
+
14
+ it "accepts a tree and notifies listeners" do
15
+ tree = "mock tree"
16
+ tree_added = false
17
+ @treebook.add_listener(:tree_added) do |tree|
18
+ tree_added = tree
19
+ end
20
+
21
+ @treebook.add_tree(tree)
22
+
23
+ tree_added.should == tree
24
+ @treebook.trees.should == [tree]
25
+ end
26
+ end
27
+ end
@@ -16,8 +16,8 @@ describe Redcar::Window do
16
16
  @called_menu_changed.should be_true
17
17
  end
18
18
 
19
- it "has no trees" do
20
- @window.trees.length.should == 0
19
+ it "has a treebook" do
20
+ @window.treebook.should be_an_instance_of(Redcar::Treebook)
21
21
  end
22
22
 
23
23
  end
@@ -8,6 +8,7 @@ require "application_swt/notebook"
8
8
  require "application_swt/notebook/drag_and_drop_listener"
9
9
  require "application_swt/swt_wrapper"
10
10
  require "application_swt/tab"
11
+ require "application_swt/treebook"
11
12
  require "application_swt/window"
12
13
  require "application_swt/swt/grid_data"
13
14
 
@@ -5,6 +5,10 @@ module Redcar
5
5
  file_dialog(window, Swt::SWT::OPEN, options)
6
6
  end
7
7
 
8
+ def open_directory(window, options)
9
+ directory_dialog(window, options)
10
+ end
11
+
8
12
  def save_file(window, options)
9
13
  file_dialog(window, Swt::SWT::SAVE, options)
10
14
  end
@@ -18,6 +22,14 @@ module Redcar
18
22
  end
19
23
  dialog.open
20
24
  end
25
+
26
+ def directory_dialog(window, options)
27
+ dialog = Swt::Widgets::DirectoryDialog.new(window.controller.shell)
28
+ if options[:filter_path]
29
+ dialog.set_filter_path(options[:filter_path])
30
+ end
31
+ dialog.open
32
+ end
21
33
  end
22
34
  end
23
35
  end
@@ -38,6 +38,7 @@ module Swt
38
38
  import org.eclipse.swt.widgets.Composite
39
39
  import org.eclipse.swt.widgets.Display
40
40
  import org.eclipse.swt.widgets.Event
41
+ import org.eclipse.swt.widgets.DirectoryDialog
41
42
  import org.eclipse.swt.widgets.FileDialog
42
43
  import org.eclipse.swt.widgets.Label
43
44
  import org.eclipse.swt.widgets.Menu
@@ -52,6 +53,7 @@ module Swt
52
53
  import org.eclipse.swt.custom.CTabFolder
53
54
  import org.eclipse.swt.custom.CTabItem
54
55
  import org.eclipse.swt.custom.SashForm
56
+ import org.eclipse.swt.custom.StackLayout
55
57
  end
56
58
 
57
59
  module Layout
@@ -95,12 +97,7 @@ module JFace
95
97
  import org.eclipse.jface.viewers.TreeViewer
96
98
  import org.eclipse.jface.viewers.ITreeContentProvider
97
99
  import org.eclipse.jface.viewers.ILabelProvider
100
+ import org.eclipse.jface.viewers.ILazyTreeContentProvider
101
+ import org.eclipse.jface.viewers.ILabelProvider
98
102
  end
99
103
  end
100
-
101
-
102
-
103
-
104
-
105
-
106
-
@@ -0,0 +1,33 @@
1
+ module Redcar
2
+ class ApplicationSWT
3
+ class Treebook
4
+
5
+ def initialize(composite, layout, model)
6
+ @composite, @layout, @model = composite, layout, model
7
+ add_listeners
8
+ end
9
+
10
+ def add_listeners
11
+ @model.add_listener(:tree_added, &method(:tree_added))
12
+ @model.add_listener(:tree_removed, &method(:tree_removed))
13
+ end
14
+
15
+ def tree_added(tree)
16
+ create_tree_view(tree)
17
+ end
18
+
19
+ def tree_removed(tree)
20
+ tree.controller.close
21
+ end
22
+
23
+ def create_tree_view(tree)
24
+ tree_view = TreeViewSWT.new(@composite, tree)
25
+ tree.controller = tree_view
26
+ @layout.topControl = tree_view.control
27
+ @composite.layout
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+
@@ -36,9 +36,12 @@ module Redcar
36
36
  @window = window
37
37
  @notebook_handlers = Hash.new {|h,k| h[k] = []}
38
38
  create_shell
39
- create_sash(window)
39
+ create_sashes(window)
40
40
  new_notebook(window.notebooks.first)
41
41
  add_listeners
42
+ create_treebook_controller
43
+ reset_sash_widths
44
+ @treebook_unopened = true
42
45
  end
43
46
 
44
47
  def add_listeners
@@ -51,8 +54,28 @@ module Redcar
51
54
  method = method(:notebook_orientation_changed)
52
55
  @window.add_listener(:notebook_orientation_changed, &method)
53
56
  @window.add_listener(:focussed, &method(:focussed))
57
+
58
+ @window.treebook.add_listener(:tree_added) do
59
+ if @treebook_unopened
60
+ reset_sash_widths
61
+ @treebook_unopened = false
62
+ end
63
+ end
64
+
65
+ @window.treebook.add_listener(:tree_removed) do
66
+ reset_sash_widths
67
+ end
54
68
  end
55
69
 
70
+ def create_treebook_controller
71
+ treebook = @window.treebook
72
+ controller = ApplicationSWT::Treebook.new(
73
+ @tree_composite,
74
+ @tree_layout,
75
+ treebook)
76
+ treebook.controller = controller
77
+ end
78
+
56
79
  def show
57
80
  @shell.open
58
81
  @shell.text = window.title
@@ -68,10 +91,8 @@ module Redcar
68
91
  end
69
92
 
70
93
  def new_notebook(notebook_model)
71
- notebook_controller = ApplicationSWT::Notebook.new(notebook_model, @sash)
72
- width = (100/@window.notebooks.length).to_i
73
- widths = [width]*@window.notebooks.length
74
- @sash.setWeights(widths.to_java(:int))
94
+ notebook_controller = ApplicationSWT::Notebook.new(notebook_model, @notebook_sash)
95
+ reset_notebook_sash_widths
75
96
  end
76
97
 
77
98
  def notebook_removed(notebook_model)
@@ -80,14 +101,12 @@ module Redcar
80
101
  notebook_controller.remove_listener(h)
81
102
  end
82
103
  notebook_controller.dispose
83
- width = (100/@window.notebooks.length).to_i
84
- widths = [width]*@window.notebooks.length
85
- @sash.setWeights(widths.to_java(:int))
104
+ reset_notebook_sash_widths
86
105
  end
87
106
 
88
107
  def notebook_orientation_changed(new_orientation)
89
108
  orientation = horizontal_vertical(new_orientation)
90
- @sash.setOrientation(orientation)
109
+ @notebook_sash.setOrientation(orientation)
91
110
  end
92
111
 
93
112
  def focussed(_)
@@ -111,9 +130,12 @@ module Redcar
111
130
  def swt_event_activated
112
131
  @window.focus
113
132
  end
114
-
133
+
115
134
  private
116
135
 
136
+ SASH_WIDTH = 5
137
+ TREEBOOK_WIDTH = 20
138
+
117
139
  def create_shell
118
140
  @shell = Swt::Widgets::Shell.new(ApplicationSWT.display)
119
141
  @shell.layout = Swt::Layout::GridLayout.new(1, false)
@@ -121,12 +143,24 @@ module Redcar
121
143
  @shell.add_shell_listener(@shell_listener)
122
144
  end
123
145
 
124
- def create_sash(window_model)
146
+ def create_sashes(window_model)
125
147
  orientation = horizontal_vertical(window_model.notebook_orientation)
126
148
  @sash = Swt::Custom::SashForm.new(@shell, orientation)
127
149
  grid_data = Swt::Layout::GridData.new(Swt::Layout::GridData::FILL_BOTH)
128
150
  @sash.setLayoutData(grid_data)
129
- @sash.setSashWidth(10)
151
+ @sash.setSashWidth(0)
152
+
153
+ @tree_composite = Swt::Widgets::Composite.new(@sash, Swt::SWT::NONE)
154
+ @tree_layout = Swt::Custom::StackLayout.new
155
+ @tree_composite.setLayout(@tree_layout)
156
+ button = Swt::Widgets::Button.new(@tree_composite, Swt::SWT::PUSH)
157
+ button.setText("Button in pane2")
158
+ @tree_layout.topControl = button
159
+
160
+ @notebook_sash = Swt::Custom::SashForm.new(@sash, orientation)
161
+ grid_data = Swt::Layout::GridData.new(Swt::Layout::GridData::FILL_BOTH)
162
+ @notebook_sash.setLayoutData(grid_data)
163
+ @notebook_sash.setSashWidth(SASH_WIDTH)
130
164
  end
131
165
 
132
166
  def horizontal_vertical(symbol)
@@ -137,6 +171,23 @@ module Redcar
137
171
  Swt::SWT::VERTICAL
138
172
  end
139
173
  end
174
+
175
+ def reset_sash_widths
176
+ if @window.treebook.trees.any?
177
+ @sash.setWeights([TREEBOOK_WIDTH, 100 - TREEBOOK_WIDTH].to_java(:int))
178
+ @sash.setSashWidth(SASH_WIDTH)
179
+ else
180
+ @sash.setWeights([0,100].to_java(:int))
181
+ @sash.setSashWidth(0)
182
+ @treebook_unopened = true
183
+ end
184
+ end
185
+
186
+ def reset_notebook_sash_widths
187
+ width = (100/@window.notebooks.length).to_i
188
+ widths = [width]*@window.notebooks.length
189
+ @notebook_sash.setWeights(widths.to_java(:int))
190
+ end
140
191
  end
141
192
  end
142
193
  end