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
@@ -0,0 +1,12 @@
1
+
2
+ require 'auto_indenter/document_controller'
3
+
4
+ module Redcar
5
+ class AutoIndenter
6
+
7
+ def self.load
8
+ Document.register_controller_type(AutoIndenter::DocumentController)
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,27 @@
1
+
2
+ module Redcar
3
+ class AutoIndenter
4
+ class DocumentController
5
+ include Redcar::Document::Controller
6
+ include Redcar::Document::Controller::NewlineCallback
7
+
8
+ def after_newline(line_ix)
9
+ if line_ix > 0
10
+ previous_line = document.get_line(line_ix - 1)
11
+ whitespace_prefix = whitespace_prefix(previous_line)
12
+ offset = document.offset_at_line(line_ix)
13
+ document.insert(offset, whitespace_prefix)
14
+ if document.cursor_offset == offset
15
+ document.cursor_offset = offset + whitespace_prefix.length
16
+ end
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def whitespace_prefix(string)
23
+ string[/^(\s*)(?:[^\s]|$)/, 1]
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ --- !ruby/object:FreeBASE::PluginConfiguration
2
+ name: auto_indenter
3
+ description: Automatic indenter
4
+ version: 1.0
5
+ author: Daniel Lucraft
6
+ autoload: true
7
+ require_path: auto_indenter/lib/auto_indenter.rb
8
+ startup_module: Redcar::AutoIndenter
9
+ load_dependencies:
10
+ edit_view: "*"
11
+ start_dependencies:
12
+ edit_view: "*"
@@ -5,7 +5,7 @@ module NotebookSwtHelper
5
5
  end
6
6
 
7
7
  def ctab_folders
8
- sash.children.to_a.select do |c|
8
+ sash.children.to_a[1].children.to_a.select do |c|
9
9
  c.class == Java::OrgEclipseSwtCustom::CTabFolder
10
10
  end
11
11
  end
@@ -1,4 +1,15 @@
1
1
 
2
+ Given /^there is an edit tab containing "([^\"]*)"$/ do |contents|
3
+ contents = eval(contents.inspect.gsub("\\\\", "\\"))
4
+ tab = Redcar::Top::NewCommand.new.run
5
+ cursor_offset = (contents =~ /<c>/)
6
+ contents = contents.gsub("<c>", "")
7
+ tab.edit_view.document.text = contents
8
+ if cursor_offset
9
+ tab.edit_view.document.cursor_offset = cursor_offset
10
+ end
11
+ end
12
+
2
13
  When /^I open a new edit tab$/ do
3
14
  Redcar::Top::NewCommand.new.run
4
15
  end
@@ -73,8 +73,8 @@ Then /the window "(.*)" should have (\d+) tabs?/ do |win_title, tab_num|
73
73
  display = Swt::Widgets::Display.get_current
74
74
  shells = display.get_shells.to_a
75
75
  shell = shells.detect {|s| s.text == win_title}
76
- sash_form = shell.getChildren.to_a.first
77
- tab_folders = sash_form.children.to_a.select{|c| c.is_a? Swt::Custom::CTabFolder}
76
+ sash_form = shell.children.to_a.first
77
+ tab_folders = sash_form.children.to_a[1].children.select{|c| c.is_a? Swt::Custom::CTabFolder}
78
78
  items = tab_folders.map{|f| f.getItems.to_a}.flatten
79
79
  items.map {|i| model_tab_for_item(i)}.length.should == tab_num
80
80
  end
@@ -4,8 +4,8 @@ module SwtTabHelpers
4
4
  def get_tab_folder
5
5
  display = Redcar::ApplicationSWT.display
6
6
  shell = display.get_shells.to_a.first
7
- sash_form = shell.getChildren.to_a.first
8
- tab_folders = sash_form.children.to_a
7
+ sash_form = shell.children.to_a.first
8
+ tab_folders = sash_form.children.to_a[1].children.to_a
9
9
  tab_folders.length.should == 1
10
10
  tab_folders.first
11
11
  end
@@ -18,8 +18,8 @@ module SwtTabHelpers
18
18
  def get_tabs
19
19
  display = Redcar::ApplicationSWT.display
20
20
  shell = display.get_shells.to_a.first
21
- sash_form = shell.getChildren.to_a.first
22
- tab_folders = sash_form.children.to_a.select{|c| c.is_a? Swt::Custom::CTabFolder}
21
+ sash_form = shell.children.to_a.first
22
+ tab_folders = sash_form.children.to_a[1].children.to_a.select{|c| c.is_a? Swt::Custom::CTabFolder}
23
23
  items = tab_folders.map{|f| f.getItems.to_a}.flatten
24
24
  items.map {|i| model_tab_for_item(i)}
25
25
  end
@@ -42,25 +42,3 @@ def putsall
42
42
  p Redcar.app.windows.first.notebooks.first.tabs
43
43
  p Redcar.app.windows.first.notebooks.last.tabs
44
44
  end
45
-
46
- After do
47
- Redcar.app.windows.each do |win|
48
- win.notebooks.each do |notebook|
49
- while tab = notebook.tabs.first
50
- Redcar::ApplicationSWT.sync_exec do
51
- tab.close
52
- end
53
- end
54
- end
55
- if win.notebooks.length == 2
56
- Redcar::ApplicationSWT.sync_exec do
57
- win.close_notebook
58
- end
59
- end
60
- end
61
- while Redcar.app.windows.length > 1
62
- Redcar::ApplicationSWT.sync_exec do
63
- Redcar.app.windows.last.close
64
- end
65
- end
66
- end
@@ -1,7 +1,8 @@
1
1
 
2
2
  require "edit_view/command"
3
3
  require "edit_view/document"
4
- require "edit_view/mirror"
4
+ require "edit_view/document/controller"
5
+ require "edit_view/document/mirror"
5
6
  require "edit_view/edit_tab"
6
7
 
7
8
  module Redcar
@@ -8,31 +8,44 @@ module Redcar
8
8
  class Document
9
9
  include Redcar::Model
10
10
  include Redcar::Observable
11
+ extend Forwardable
12
+
13
+ def_delegators :controller,
14
+ :length, :line_count, :to_s, :text=,
15
+ :line_at_offset, :get_line, :offset_at_line,
16
+ :insert, :cursor_offset, :cursor_offset=
17
+
18
+ def self.register_controller_type(controller_type)
19
+ unless controller_type.ancestors.include?(Document::Controller)
20
+ raise "expected #{Document::Controller}"
21
+ end
22
+ (@document_controller_types ||= []) << controller_type
23
+ end
11
24
 
12
25
  class << self
13
26
  attr_accessor :default_mirror
27
+ attr_reader :document_controller_types
14
28
  end
15
29
 
16
30
  attr_reader :mirror
17
31
 
18
32
  def initialize(edit_view)
19
33
  @edit_view = edit_view
34
+ get_controllers
20
35
  end
21
36
 
22
- def to_s
23
- controller.to_s
24
- end
25
-
26
- def text=(text)
27
- controller.text = text
28
- end
29
-
30
- def length
31
- controller.length
32
- end
33
-
34
- def line_count
35
- controller.line_count
37
+ def get_controllers
38
+ @controllers = {
39
+ Controller::ModificationCallbacks => [],
40
+ Controller::NewlineCallback => []
41
+ }
42
+ Document.document_controller_types.each do |type|
43
+ @controllers.each do |key, value|
44
+ if type.ancestors.include?(key)
45
+ value << type.new(self)
46
+ end
47
+ end
48
+ end
36
49
  end
37
50
 
38
51
  def save!
@@ -53,6 +66,25 @@ module Redcar
53
66
  end
54
67
  end
55
68
 
69
+ def verify_text(start_offset, end_offset, text)
70
+ @change = [start_offset, end_offset, text]
71
+ @controllers[Controller::ModificationCallbacks].each do |controller|
72
+ controller.before_modify(start_offset, end_offset, text)
73
+ end
74
+ end
75
+
76
+ def modify_text
77
+ @controllers[Controller::ModificationCallbacks].each do |controller|
78
+ controller.after_modify
79
+ end
80
+ @controllers[Controller::NewlineCallback].each do |controller|
81
+ if @change[2] == "\n"
82
+ controller.after_newline(line_at_offset(@change[1]) + 1)
83
+ end
84
+ end
85
+ @change = nil
86
+ end
87
+
56
88
  private
57
89
 
58
90
  def update_from_mirror
@@ -0,0 +1,30 @@
1
+
2
+ module Redcar
3
+ class Document
4
+ module Controller
5
+ def initialize(document)
6
+ @document = document
7
+ end
8
+
9
+ def document
10
+ @document
11
+ end
12
+
13
+ module ModificationCallbacks
14
+ def before_modify(start_offset, end_offset, text)
15
+ raise "not implemented"
16
+ end
17
+
18
+ def after_modify
19
+ raise "not implemented"
20
+ end
21
+ end
22
+
23
+ module NewlineCallback
24
+ def after_newline(line_ix)
25
+ raise "not implemented"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Redcar
3
- class EditView
3
+ class Document
4
4
  # Abstract interface. A Mirror allows an EditView contents to reflect
5
5
  # some other resource. They have methods for loading the contents from the
6
6
  # resource and commiting changes.
@@ -98,6 +98,8 @@ module Redcar
98
98
  &method(:update_grammar))
99
99
  h2 = @model.add_listener(:grammar_changed, &method(:model_grammar_changed))
100
100
  @mate_text.getTextWidget.addFocusListener(FocusListener.new(self))
101
+ @mate_text.getTextWidget.addVerifyListener(VerifyListener.new(@model.document, self))
102
+ @mate_text.getTextWidget.addModifyListener(ModifyListener.new(@model.document, self))
101
103
  @handlers << [@model.document, h1] << [@model, h2]
102
104
  end
103
105
 
@@ -166,5 +168,25 @@ module Redcar
166
168
 
167
169
  def focusLost(_); end
168
170
  end
171
+
172
+ class VerifyListener
173
+ def initialize(document, obj)
174
+ @document, @obj = document, obj
175
+ end
176
+
177
+ def verify_text(e)
178
+ @document.verify_text(e.start, e.end, e.text)
179
+ end
180
+ end
181
+
182
+ class ModifyListener
183
+ def initialize(document, obj)
184
+ @document, @obj = document, obj
185
+ end
186
+
187
+ def modify_text(_)
188
+ @document.modify_text
189
+ end
190
+ end
169
191
  end
170
192
  end
@@ -22,6 +22,35 @@ module Redcar
22
22
  @swt_document.get_number_of_lines
23
23
  end
24
24
 
25
+ def line_at_offset(offset)
26
+ jface.get_line_of_offset(offset)
27
+ end
28
+
29
+ def offset_at_line(line_ix)
30
+ jface.get_line_offset(line_ix)
31
+ end
32
+
33
+ def get_line(line_ix)
34
+ line_info = jface.get_line_information(line_ix)
35
+ jface.get(line_info.offset, line_info.length)
36
+ end
37
+
38
+ def insert(offset, text)
39
+ jface.replace(offset, 0, text)
40
+ end
41
+
42
+ def cursor_offset
43
+ @swt_document.styledText.get_caret_offset
44
+ end
45
+
46
+ def cursor_offset=(offset)
47
+ @swt_document.styledText.set_caret_offset(offset)
48
+ end
49
+
50
+ def jface
51
+ @swt_document.getJFaceDocument
52
+ end
53
+
25
54
  def text=(text)
26
55
  @swt_document.set(text)
27
56
  notify_listeners(:set_text)
@@ -0,0 +1,17 @@
1
+ Feature: Open directory tree
2
+
3
+ Scenario: Open directory
4
+ Given I will choose "." from the "open_directory" dialog
5
+ When I open a directory
6
+ Then I should see "bin,config,lib,plugins" in the tree
7
+
8
+ Scenario: Open directory then another directory
9
+ Given I will choose "." from the "open_directory" dialog
10
+ When I open a directory
11
+ Given I will choose "plugins" from the "open_directory" dialog
12
+ When I open a directory
13
+ Then I should see "core,application,tree" in the tree
14
+
15
+
16
+
17
+
@@ -0,0 +1,4 @@
1
+
2
+ When /I open a directory/ do
3
+ Redcar::Project::DirectoryOpenCommand.new.run
4
+ end
@@ -1,9 +1,32 @@
1
1
 
2
2
  require "project/file_mirror"
3
3
  require "project/dir_mirror"
4
+ require "project/dir_controller"
4
5
 
5
6
  module Redcar
6
7
  class Project
8
+ def self.open_tree(win, tree)
9
+ @window_trees ||= {}
10
+ if @window_trees[win]
11
+ old_tree = @window_trees[win]
12
+ set_tree(win, tree)
13
+ win.treebook.remove_tree(old_tree)
14
+ else
15
+ set_tree(win, tree)
16
+ end
17
+ end
18
+
19
+ def self.close_tree(win)
20
+ win.treebook.remove_tree(@window_trees[win])
21
+ end
22
+
23
+ private
24
+
25
+ def self.set_tree(win, tree)
26
+ @window_trees[win] = tree
27
+ win.treebook.add_tree(tree)
28
+ end
29
+
7
30
  class FileOpenCommand < Command
8
31
  key :osx => "Cmd+O",
9
32
  :linux => "Ctrl+O",
@@ -75,5 +98,33 @@ module Redcar
75
98
  end
76
99
  end
77
100
  end
101
+
102
+ class DirectoryOpenCommand < Command
103
+ key :osx => "Cmd+Shift+O",
104
+ :linux => "Ctrl+Shift+O",
105
+ :windows => "Ctrl+Shift+O"
106
+
107
+ def execute
108
+ tree = Tree.new(Project::DirMirror.new(get_path),
109
+ Project::DirController.new)
110
+ Project.open_tree(win, tree)
111
+ end
112
+
113
+ private
114
+
115
+ def get_path
116
+ @path || begin
117
+ path = Application::Dialog.open_directory(win, :filter_path => File.expand_path("~"))
118
+ File.expand_path(path)
119
+ end
120
+ end
121
+ end
122
+
123
+ class DirectoryCloseCommand < Command
124
+
125
+ def execute
126
+ Project.close_tree(win)
127
+ end
128
+ end
78
129
  end
79
130
  end
@@ -0,0 +1,14 @@
1
+
2
+ module Redcar
3
+ class Project
4
+ class DirController
5
+ def activated(node)
6
+ if node.leaf?
7
+ FileOpenCommand.new(node.path).run
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+