redcar 0.12.1 → 0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. data/CHANGES +18 -0
  2. data/bin/redcar +1 -0
  3. data/lib/redcar.rb +4 -5
  4. data/lib/redcar/usage.rb +0 -1
  5. data/lib/redcar_quick_start.rb +3 -1
  6. data/plugins/application/lib/application.rb +1 -0
  7. data/plugins/application/lib/application/commands/treebook_commands.rb +11 -18
  8. data/plugins/application/lib/application/dialog.rb +1 -1
  9. data/plugins/application/lib/application/dialogs/filter_list_dialog.rb +13 -5
  10. data/plugins/application/lib/application/global_state.rb +21 -0
  11. data/plugins/application/lib/application/menu/item.rb +37 -11
  12. data/plugins/application/lib/application/notebook.rb +12 -0
  13. data/plugins/application/lib/application/tree/mirror.rb +0 -11
  14. data/plugins/application/lib/application/window.rb +32 -7
  15. data/plugins/application_swt/lib/application_swt.rb +1 -1
  16. data/plugins/application_swt/lib/application_swt/dialogs/filter_list_dialog_controller.rb +35 -10
  17. data/plugins/application_swt/lib/application_swt/icon.rb +1 -1
  18. data/plugins/application_swt/lib/application_swt/menu.rb +47 -15
  19. data/plugins/application_swt/lib/application_swt/notebook.rb +11 -2
  20. data/plugins/application_swt/lib/application_swt/window.rb +37 -34
  21. data/plugins/auto_indenter/lib/auto_indenter/analyzer.rb +1 -1
  22. data/plugins/auto_indenter/spec/auto_indenter/analyzer_spec.rb +9 -0
  23. data/plugins/declarations/lib/declarations.rb +31 -66
  24. data/plugins/declarations/lib/declarations/commands.rb +142 -0
  25. data/plugins/declarations/lib/declarations/file.rb +1 -1
  26. data/plugins/{outline_view → declarations}/spec/fixtures/some_project/javascript.js +0 -0
  27. data/plugins/{outline_view → declarations}/spec/fixtures/some_project/nothing_to_see.rb +0 -0
  28. data/plugins/{outline_view → declarations}/spec/fixtures/some_project/one_lonely_class.rb +0 -0
  29. data/plugins/{outline_view → declarations}/spec/fixtures/some_project/similar_names.rb +0 -0
  30. data/plugins/{outline_view → declarations}/spec/fixtures/some_project/something_fancy.rb +0 -0
  31. data/plugins/{outline_view → declarations}/spec/fixtures/some_project/trailing_space.rb +0 -0
  32. data/plugins/edit_view/lib/edit_view.rb +35 -2
  33. data/plugins/edit_view/lib/edit_view/commands/change_language_command.rb +31 -0
  34. data/plugins/edit_view/lib/edit_view/commands/language_settings_commands.rb +45 -0
  35. data/plugins/edit_view/lib/edit_view/document/command.rb +1 -1
  36. data/plugins/edit_view/lib/edit_view/edit_tab.rb +11 -13
  37. data/plugins/key_bindings/lib/key_bindings.rb +6 -2
  38. data/plugins/project/lib/project.rb +27 -32
  39. data/plugins/project/lib/project/commands.rb +3 -88
  40. data/plugins/project/lib/project/dir_controller.rb +12 -18
  41. data/plugins/project/lib/project/dir_mirror.rb +20 -25
  42. data/plugins/project/lib/project/file_mirror.rb +10 -10
  43. data/plugins/project/lib/project/find_file_dialog.rb +20 -18
  44. data/plugins/project/lib/project/find_recent_dialog.rb +6 -3
  45. data/plugins/project/lib/project/{adapters/local.rb → local_filesystem.rb} +35 -35
  46. data/plugins/project/lib/project/manager.rb +21 -75
  47. data/plugins/project/lib/project/sub_project.rb +3 -3
  48. data/plugins/project/plugin.rb +0 -1
  49. data/plugins/project_search/lib/project_search/lucene_refresh.rb +0 -1
  50. data/plugins/redcar/plugin.rb +2 -2
  51. data/plugins/redcar/redcar.rb +34 -42
  52. data/plugins/ruby/lib/ruby/syntax_checker.rb +27 -7
  53. data/plugins/scm/lib/scm.rb +1 -12
  54. data/plugins/sessions/lib/sessions.rb +22 -0
  55. data/plugins/sessions/lib/sessions/cursor_saver.rb +162 -0
  56. data/plugins/sessions/lib/sessions/loader.rb +99 -0
  57. data/plugins/sessions/lib/sessions/memory.rb +59 -0
  58. data/plugins/sessions/plugin.rb +8 -0
  59. data/plugins/strip_trailing_spaces/lib/strip_trailing_spaces.rb +2 -2
  60. data/plugins/syntax_check/lib/syntax_check.rb +2 -2
  61. data/plugins/tree_view_swt/lib/tree_view_swt.rb +1 -3
  62. data/redcar.gemspec +1 -1
  63. metadata +195 -291
  64. data/plugins/connection_manager/lib/connection_manager.rb +0 -57
  65. data/plugins/connection_manager/lib/connection_manager/commands.rb +0 -14
  66. data/plugins/connection_manager/lib/connection_manager/connection_store.rb +0 -87
  67. data/plugins/connection_manager/lib/connection_manager/controller.rb +0 -100
  68. data/plugins/connection_manager/lib/connection_manager/filter_dialog.rb +0 -38
  69. data/plugins/connection_manager/lib/connection_manager/private_key_store.rb +0 -93
  70. data/plugins/connection_manager/plugin.rb +0 -12
  71. data/plugins/connection_manager/views/index.html.erb +0 -284
  72. data/plugins/edit_view/lib/edit_view/info_speedbar.rb +0 -98
  73. data/plugins/outline_view/features/outline_view.feature +0 -79
  74. data/plugins/outline_view/features/project_outline.feature +0 -23
  75. data/plugins/outline_view/features/step_definitions/outline_steps.rb +0 -61
  76. data/plugins/outline_view/lib/outline_view.rb +0 -97
  77. data/plugins/outline_view/lib/outline_view/commands.rb +0 -19
  78. data/plugins/outline_view/plugin.rb +0 -10
  79. data/plugins/outline_view_swt/lib/outline_view_swt.rb +0 -79
  80. data/plugins/outline_view_swt/plugin.rb +0 -7
  81. data/plugins/project/lib/project/adapters/remote.rb +0 -96
  82. data/plugins/project/lib/project/adapters/remote_protocols/ftp.rb +0 -93
  83. data/plugins/project/lib/project/adapters/remote_protocols/protocol.rb +0 -94
  84. data/plugins/project/lib/project/adapters/remote_protocols/sftp.rb +0 -181
@@ -1,21 +1,21 @@
1
1
  require 'java'
2
2
 
3
+ import org.jruby.parser.Parser
4
+ import org.jruby.parser.ParserConfiguration
5
+ import org.jruby.CompatVersion
6
+
3
7
  module Redcar
4
8
  class Ruby
5
9
  class SyntaxChecker < Redcar::SyntaxCheck::Checker
6
10
  supported_grammars "Ruby", "Ruby on Rails", "RSpec"
7
11
 
8
12
  def check(*args)
9
- path = manifest_path(doc)
10
- file = File.basename(path)
11
- runtime = org.jruby.Ruby.global_runtime
12
- io = java.io.FileInputStream.new(java.io.File.new(path))
13
+ path = manifest_path(doc)
14
+ file = File.basename(path)
13
15
  begin
14
- runtime.parse_from_main(io, file)
16
+ parser.parse(file, doc.to_s.to_java.get_bytes, config_19.scope, config_19)
15
17
  rescue SyntaxError => e
16
18
  create_syntax_error(doc, e.exception.message, file).annotate
17
- ensure
18
- io.close
19
19
  end
20
20
  end
21
21
 
@@ -25,6 +25,26 @@ module Redcar
25
25
  message = $2
26
26
  Redcar::SyntaxCheck::Error.new(doc, line, message)
27
27
  end
28
+
29
+ private
30
+
31
+ def runtime
32
+ org.jruby.Ruby.global_runtime
33
+ end
34
+
35
+ def parser
36
+ @parser ||= Parser.new(runtime)
37
+ end
38
+
39
+ def config_19
40
+ @config_19 ||= ParserConfiguration.new(runtime, 0, false, CompatVersion::RUBY1_9)
41
+ end
42
+
43
+ def config_18
44
+ @config_18 ||= ParserConfiguration.new(runtime, 0, false, CompatVersion::RUBY1_8)
45
+ end
28
46
  end
29
47
  end
30
48
  end
49
+
50
+
@@ -126,9 +126,6 @@ module Redcar
126
126
  end
127
127
 
128
128
  def self.project_loaded(project)
129
- # for now we only want to attempt to handle the local case
130
- return if project.remote?
131
-
132
129
  Redcar.log.debug "SCM #{modules.count} SCM modules loaded."
133
130
 
134
131
  repo = modules_instance.find do |m|
@@ -149,15 +146,7 @@ module Redcar
149
146
  begin
150
147
  # associate this repository with a project internally
151
148
  project_repositories[project] = {'repo' => repo}
152
-
153
- # load the repository and inject adapter if there is one
154
149
  repo.load(project.path)
155
- adapter = repo.adapter(project.adapter)
156
- if not adapter.nil?
157
- Redcar.log.debug "SCM Attaching a custom adapter to the project."
158
- project.adapter = adapter
159
- end
160
-
161
150
  project_repositories[project]['trees'] = []
162
151
  rescue
163
152
  # cleanup
@@ -265,7 +254,7 @@ module Redcar
265
254
  end
266
255
  }
267
256
 
268
- item branch, :type => :radio, :active => (branch == current), &action
257
+ item branch, :type => :radio, :checked => (branch == current), &action
269
258
  end
270
259
  end
271
260
  end
@@ -0,0 +1,22 @@
1
+ require 'pathname'
2
+
3
+ require 'sessions/memory'
4
+ require 'sessions/loader'
5
+ require 'sessions/cursor_saver'
6
+
7
+ class Sessions
8
+ def self.project_loaded(project)
9
+ Sessions::Memory.project_loaded(project)
10
+ Sessions::Loader.project_loaded(project)
11
+ end
12
+
13
+ def self.project_closed(project, window)
14
+ Sessions::Memory.project_closed(project, window)
15
+ Sessions::Loader.project_closed(project, window)
16
+ Sessions::CursorSaver.project_closed(project, window)
17
+ end
18
+
19
+ def self.tab_added(tab)
20
+ Sessions::CursorSaver.tab_added(tab)
21
+ end
22
+ end
@@ -0,0 +1,162 @@
1
+ class Sessions
2
+ class CursorSaver
3
+
4
+ def self.project_closed(project, window)
5
+ open_tabs(project, window).each do |tab|
6
+ tab.remove_listener(tab_close_handlers.delete(tab))
7
+ save_cursor(tab.document, project)
8
+ end
9
+ end
10
+
11
+ def self.tab_added(tab)
12
+ if document = tab.document
13
+ document_new_mirror_handlers[tab] = document.add_listener(:new_mirror) do
14
+ document.remove_listener(document_new_mirror_handlers.delete(document))
15
+
16
+ if tab.document && tab.document.path
17
+ tab_focus_handlers[tab] = tab.add_listener(:focus) do
18
+ tab.remove_listener(tab_focus_handlers.delete(tab))
19
+ CursorSaver.restore_cursor(document)
20
+ end
21
+
22
+ tab_close_handlers[tab] = tab.add_listener(:before => :close) do
23
+ tab.remove_listener(tab_close_handlers.delete(tab))
24
+ CursorSaver.save_cursor(document) if document.path
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ def self.save_cursor(document, project = nil)
32
+ data = {
33
+ :path => document.path,
34
+ :cursor_offset => document.cursor_offset,
35
+ :timestamp => document.mirror.timestamp
36
+ }
37
+ if document.selection?
38
+ data[:selection_offset] = document.selection_offset
39
+ data[:block_selection_mode] = document.block_selection_mode?
40
+ end
41
+ restored_paths.delete(document.path) # FIXME(chrislwade): see note on <restored_paths>
42
+ Redcar.log.debug("Sessions::CursorSaver: saving cursor data: #{data.inspect}")
43
+ save_file_data(data, project)
44
+ end
45
+
46
+ def self.restore_cursor(document)
47
+ return if restored_paths[document.path] # FIXME(chrislwade): see note on <restored_paths>
48
+ data = get_file_data(document.path)
49
+ return if data.nil?
50
+ restored_paths[document.path] = true # FIXME(chrislwade): see note on <restored_paths>
51
+ Redcar.log.debug("Sessions::CursorSaver: restoring cursor data: #{data.inspect}")
52
+ if data[:cursor_offset] > document.length
53
+ Redcar.log.debug("Sessions::CursorSaver: offset #{data[:cursor_offset]} doesn't exist, truncated file? [max offset = #{document.length}]")
54
+ elsif user_storage['check_timestamps'] && data[:timestamp] != document.mirror.timestamp
55
+ Redcar.log.debug("Sessions::CursorSaver: timestamp #{data[:timestamp]} doesn't match! [new timestamp = #{document.mirror.timestamp}]")
56
+ else
57
+ if user_storage['restore_selection'] && data.has_key?(:selection_offset) && data[:selection_offset] <= document.length
58
+ document.set_selection_range(data[:cursor_offset], data[:selection_offset])
59
+ document.block_selection_mode = data[:block_selection_mode]
60
+ else
61
+ document.cursor_offset = data[:cursor_offset]
62
+ end
63
+ document.ensure_cursor_visible
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ # FIXME(chrislwade): find a better way to prevent "double restore"
70
+ # Helps prevent double-restore once Redcar is running. When files are opened via the
71
+ # project tree, the tab receives the :focus event twice. When they are opened programmatically,
72
+ # the tab only receives a single :focus event. Unfortunately, removing the :focus handler during
73
+ # handler itself doesn't prevent a second run!
74
+ def self.restored_paths
75
+ @restored_paths ||= {}
76
+ end
77
+
78
+ def self.document_new_mirror_handlers
79
+ @document_new_mirror_handlers ||= {}
80
+ end
81
+
82
+ def self.tab_close_handlers
83
+ @tab_close_handlers ||= {}
84
+ end
85
+
86
+ def self.tab_focus_handlers
87
+ @tab_focus_handlers ||= {}
88
+ end
89
+
90
+ def self.user_storage
91
+ @storage ||= begin
92
+ storage = Redcar::Plugin::Storage.new('cursor_saver')
93
+ storage.set_default('cursor_positions', [])
94
+ storage.set_default('files_to_retain', 200)
95
+ storage.set_default('check_timestamps', true)
96
+ storage.set_default('restore_selection', true)
97
+ storage
98
+ end
99
+ end
100
+
101
+ def self.project_storage(project)
102
+ storage = project.storage('cursor_saver')
103
+ storage.set_default('cursor_positions', [])
104
+ storage.set_default('files_to_retain', 0)
105
+ storage
106
+ end
107
+
108
+ def self.project_for_path(path)
109
+ Redcar.log.debug("Sessions::CursorSaver: searching for open project for #{path}")
110
+ project = Redcar::Project::Manager.find_projects_containing_path(path).last
111
+ Redcar.log.debug("Sessions::CursorSaver: found: #{project.inspect}")
112
+ project
113
+ end
114
+
115
+ def self.open_tabs(project, window)
116
+ window.all_tabs.select do |tab|
117
+ tab.is_a?(Redcar::EditTab) &&
118
+ tab.document.path &&
119
+ tab.document.path.start_with?(project.path)
120
+ end
121
+ end
122
+
123
+ def self.trim(storage)
124
+ if storage['files_to_retain'] && storage['files_to_retain'] > 0
125
+ while storage['cursor_positions'].length > storage['files_to_retain']
126
+ storage['cursor_positions'].shift
127
+ end
128
+ end
129
+ end
130
+
131
+ def self.save_file_data(data, project = nil)
132
+ if project ||= project_for_path(data[:path])
133
+ storage = project_storage(project)
134
+ data[:path] = data[:path][(project.path.length + 1) .. data[:path].length]
135
+ Redcar.log.debug("Sessions::CursorSaver: using project storage to store offset for #{data[:path]}")
136
+ else
137
+ storage = user_storage
138
+ pathname = Pathname.new(data[:path])
139
+ data[:path] = pathname.absolute? ? pathname.to_s : pathname.expand_path.to_s
140
+ Redcar.log.debug("Sessions::CursorSaver: using user storage to store offset for #{data[:path]}")
141
+ end
142
+ storage['cursor_positions'].delete_if {|obj| obj[:path] == data[:path]}
143
+ storage['cursor_positions'] << data
144
+ trim(storage)
145
+ storage.save
146
+ end
147
+
148
+ def self.get_file_data(path)
149
+ if project = project_for_path(path)
150
+ storage = project_storage(project)
151
+ scoped_path = path[(project.path.length + 1) .. path.length]
152
+ Redcar.log.debug("Sessions::CursorSaver: restoring offset from project storage for #{scoped_path}")
153
+ else
154
+ storage = user_storage
155
+ pathname = Pathname.new(path)
156
+ scoped_path = pathname.absolute? ? pathname.to_s : pathname.expand_path.to_s
157
+ Redcar.log.debug("Sessions::CursorSaver: restoring offset from user storage for #{scoped_path}")
158
+ end
159
+ storage['cursor_positions'].find {|obj| obj[:path] == scoped_path}
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,99 @@
1
+ class Sessions
2
+ class Loader
3
+ def self.loaders
4
+ @loaders ||= {}
5
+ end
6
+
7
+ def self.project_loaded(project)
8
+ loaders[project.path] = loader = self.new(project)
9
+ loader.restore if restore_files?
10
+ end
11
+
12
+ def self.project_closed(project, window)
13
+ loader = loaders.delete(project.path)
14
+ loader.save if save_files?
15
+ end
16
+
17
+ def self.storage
18
+ @storage ||= begin
19
+ storage = Redcar::Plugin::Storage.new('project_loader')
20
+ storage.set_default('restore_open_files_on_load', true)
21
+ storage.set_default('save_open_files_on_close', true)
22
+ storage
23
+ end
24
+ end
25
+
26
+ def self.restore_files?
27
+ storage['restore_open_files_on_load']
28
+ end
29
+
30
+ def self.restore_files=(toggle)
31
+ storage['restore_open_files_on_load'] = toggle
32
+ end
33
+
34
+ def self.restore_project_files(project)
35
+ loaders[project.path].restore
36
+ end
37
+
38
+ def self.save_files?
39
+ storage['save_open_files_on_close']
40
+ end
41
+
42
+ def self.save_files=(toggle)
43
+ storage['save_open_files_on_close'] = toggle
44
+ end
45
+
46
+ def self.save_project_files(project)
47
+ loaders[project.path].save
48
+ end
49
+
50
+ attr_accessor :project
51
+
52
+ def initialize(project)
53
+ @project = project
54
+ end
55
+
56
+ def storage
57
+ @storage ||= begin
58
+ storage = project.storage('project_loader')
59
+ storage.set_default('open_files', [])
60
+ storage
61
+ end
62
+ end
63
+
64
+ def open_files
65
+ Redcar.app.all_tabs.select do |tab|
66
+ tab.is_a?(Redcar::EditTab) &&
67
+ tab.document && tab.document.path &&
68
+ tab.document.path.start_with?(project.path)
69
+ end.collect do |tab|
70
+ path = tab.document.path
71
+ path = path[project.path.length + 1 .. path.length]
72
+ end
73
+ end
74
+
75
+ def saved_files
76
+ storage['open_files'] ||= []
77
+ end
78
+
79
+ def saved_files=(files)
80
+ storage['open_files'] = files
81
+ end
82
+
83
+ def restore
84
+ Redcar.log.info("Sessions::Loader: opening files last open for #{project.path}")
85
+ unless (files = saved_files).empty?
86
+ paths = files.each do |file|
87
+ path = Pathname.new(file).expand_path(project.path)
88
+ Redcar::Project::Manager.open_file(path.to_s) if path.exist?
89
+ end
90
+ Redcar::Project::Manager.find_open_file_tab(paths.first).andand.focus
91
+ end
92
+ end
93
+
94
+ def save
95
+ Redcar.log.info("Sessions::Loader: saving files last open for #{project.path}")
96
+ self.saved_files = open_files
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,59 @@
1
+ class Sessions
2
+ class Memory
3
+ def self.memories
4
+ @memories ||= []
5
+ end
6
+
7
+ def self.project_loaded(project)
8
+ memories << Sessions::Memory.new(project).recall
9
+ end
10
+
11
+ def self.project_closed(project, window)
12
+ memories.reject! do |mem|
13
+ mem.save window if mem.project == project
14
+ end
15
+ end
16
+
17
+ attr_reader :project, :storage
18
+
19
+ def initialize(project)
20
+ @project = project
21
+ @storage = project.storage('sessions')
22
+ end
23
+
24
+ def last_bounds
25
+ return unless storage["bounds"]
26
+ rect = storage["bounds"]
27
+ [rect["x"], rect["y"], rect["width"], rect["height"]]
28
+ end
29
+
30
+ def tree_width
31
+ return unless storage["tree_width"]
32
+ storage["tree_width"].to_i
33
+ end
34
+
35
+ def save(window)
36
+ bs = window.bounds
37
+ storage["bounds"] = {
38
+ "x" => bs[0],
39
+ "y" => bs[1],
40
+ "width" => bs[2],
41
+ "height" => bs[3]
42
+ }
43
+ storage["tree_width"] = window.treebook_width
44
+ storage.save
45
+ end
46
+
47
+ def recall
48
+ if last_bounds
49
+ project.window.bounds = last_bounds
50
+ end
51
+ if tree_width
52
+ project.window.treebook_width = tree_width
53
+ end
54
+ self
55
+ end
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,8 @@
1
+
2
+ Plugin.define do
3
+ name "sessions"
4
+ version "1.0"
5
+ file "lib", "sessions"
6
+ object "Sessions"
7
+ dependencies "project", ">0"
8
+ end
@@ -30,8 +30,8 @@ module Redcar
30
30
  Menu::Builder.build do
31
31
  sub_menu "Plugins" do
32
32
  sub_menu "Strip Trailing Spaces", :priority => 195 do
33
- item "Enabled", :command => ToggleStripTrailingSpaces, :type => :check, :active => StripTrailingSpaces.enabled?
34
- item "Strip Blank Lines", :command => ToggleStripBlankLines, :type => :check, :active => StripTrailingSpaces.strip_blank_lines?
33
+ item "Enabled", :command => ToggleStripTrailingSpaces, :type => :check, :checked => lambda { StripTrailingSpaces.enabled? }
34
+ item "Strip Blank Lines", :command => ToggleStripBlankLines, :type => :check, :checked => lambda { StripTrailingSpaces.strip_blank_lines? }
35
35
  end
36
36
  end
37
37
  end