redcar 0.2.9dev → 0.3.0dev
Sign up to get free protection for your applications and to get access to all the features.
- data/ROADMAP.md +2 -2
- data/Rakefile +4 -4
- data/lib/redcar/boot.rb +3 -0
- data/lib/redcar/install.rb +3 -3
- data/lib/redcar/runner.rb +1 -1
- data/lib/redcar/usage.rb +5 -0
- data/plugins/application/features/step_definitions/tree_steps.rb +6 -0
- data/plugins/application/features/support/env.rb +59 -1
- data/plugins/application/icons/darwin-file.png +0 -0
- data/plugins/application/icons/darwin-folder.png +0 -0
- data/plugins/application/lib/application.rb +4 -0
- data/plugins/application/lib/application/command/executor.rb +3 -1
- data/plugins/application/lib/application/dialog.rb +5 -0
- data/plugins/application/lib/application/treebook.rb +30 -0
- data/plugins/application/lib/application/window.rb +3 -3
- data/plugins/application/spec/application/treebook_spec.rb +27 -0
- data/plugins/application/spec/application/window_spec.rb +2 -2
- data/plugins/application_swt/lib/application_swt.rb +1 -0
- data/plugins/application_swt/lib/application_swt/dialog_adapter.rb +12 -0
- data/plugins/application_swt/lib/application_swt/swt_wrapper.rb +4 -7
- data/plugins/application_swt/lib/application_swt/treebook.rb +33 -0
- data/plugins/application_swt/lib/application_swt/window.rb +63 -12
- data/plugins/auto_indenter/lib/auto_indenter.rb +12 -0
- data/plugins/auto_indenter/lib/auto_indenter/document_controller.rb +27 -0
- data/plugins/auto_indenter/plugin.yaml +12 -0
- data/plugins/edit_view/features/step_definitions/notebook_steps.rb +1 -1
- data/plugins/edit_view/features/step_definitions/tab_steps.rb +11 -0
- data/plugins/edit_view/features/step_definitions/window_steps.rb +2 -2
- data/plugins/edit_view/features/support/env.rb +4 -26
- data/plugins/edit_view/lib/edit_view.rb +2 -1
- data/plugins/edit_view/lib/edit_view/document.rb +46 -14
- data/plugins/edit_view/lib/edit_view/document/controller.rb +30 -0
- data/plugins/edit_view/lib/edit_view/{mirror.rb → document/mirror.rb} +1 -1
- data/plugins/edit_view_swt/lib/edit_view_swt.rb +22 -0
- data/plugins/edit_view_swt/lib/edit_view_swt/document.rb +29 -0
- data/plugins/project/features/open_directory_tree.feature +17 -0
- data/plugins/project/features/step_definitions/directory_steps.rb +4 -0
- data/plugins/project/lib/project.rb +51 -0
- data/plugins/project/lib/project/dir_controller.rb +14 -0
- data/plugins/project/lib/project/dir_mirror.rb +18 -3
- data/plugins/project/lib/project/file_mirror.rb +1 -1
- data/plugins/redcar/redcar.rb +3 -0
- data/plugins/repl/lib/repl/internal_mirror.rb +1 -1
- data/plugins/tree/lib/tree.rb +17 -0
- data/plugins/tree/lib/tree/controller.rb +12 -0
- data/plugins/{tree_view/lib/tree_view → tree/lib/tree}/mirror.rb +1 -1
- data/plugins/{tree_view → tree}/plugin.yaml +4 -4
- data/plugins/{tree_view → tree}/spec/spec_helper.rb +0 -0
- data/plugins/tree_view_swt/lib/tree_view_swt.rb +122 -0
- metadata +21 -7
- data/plugins/tree_view/lib/tree_view.rb +0 -7
@@ -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: "*"
|
@@ -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.
|
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.
|
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.
|
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
|
@@ -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
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
@@ -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
|
+
|
@@ -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
|