redcar 0.11.0dev → 0.11

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 (139) hide show
  1. data/CHANGES +14 -1
  2. data/README.md +28 -8
  3. data/Rakefile +23 -18
  4. data/bin/redcar +9 -4
  5. data/lib/redcar.rb +42 -4
  6. data/lib/redcar/installer.rb +7 -2
  7. data/lib/redcar/logger.rb +64 -0
  8. data/lib/redcar/runner.rb +17 -8
  9. data/lib/redcar/usage.rb +2 -0
  10. data/plugins/application/features/step_definitions/tree_steps.rb +4 -4
  11. data/plugins/application/features/support/env.rb +6 -6
  12. data/plugins/application/lib/application.rb +31 -3
  13. data/plugins/application/lib/application/command.rb +6 -0
  14. data/plugins/application/lib/application/command/executor.rb +0 -1
  15. data/plugins/application/lib/application/commands/application_commands.rb +21 -0
  16. data/plugins/application/lib/application/commands/notebook_commands.rb +73 -0
  17. data/plugins/application/lib/application/commands/tab_commands.rb +105 -0
  18. data/plugins/application/lib/application/commands/treebook_commands.rb +117 -0
  19. data/plugins/application/lib/application/commands/window_commands.rb +68 -0
  20. data/plugins/{tree/lib → application/lib/application}/tree.rb +0 -4
  21. data/plugins/{tree/lib → application/lib/application}/tree/command.rb +0 -0
  22. data/plugins/{tree/lib → application/lib/application}/tree/controller.rb +0 -0
  23. data/plugins/{tree/lib → application/lib/application}/tree/mirror.rb +0 -0
  24. data/plugins/application/spec/application/keymap/builder_spec.rb +1 -1
  25. data/plugins/application/spec/application/menu/builder_spec.rb +2 -2
  26. data/plugins/application_swt/lib/application_swt.rb +4 -2
  27. data/plugins/application_swt/lib/swt/vtab_label.rb +6 -3
  28. data/plugins/auto_indenter/lib/auto_indenter/document_controller.rb +6 -3
  29. data/plugins/clojure/lib/clojure.rb +2 -2
  30. data/plugins/core/lib/core.rb +0 -4
  31. data/plugins/core/lib/core/gui.rb +2 -4
  32. data/plugins/core/lib/core/plugin/storage.rb +68 -21
  33. data/plugins/core/spec/core/base_storage_spec.rb +81 -0
  34. data/plugins/core/spec/core/shared_storage_spec.rb +49 -0
  35. data/plugins/core/spec/core/storage_spec.rb +13 -63
  36. data/plugins/declarations/lib/declarations.rb +3 -1
  37. data/plugins/document_search/features/replace.feature +29 -20
  38. data/plugins/document_search/lib/document_search/find_speedbar.rb +4 -1
  39. data/plugins/edit_view/features/indentation_commands.feature +6 -5
  40. data/plugins/edit_view/features/step_definitions/notebook_steps.rb +4 -4
  41. data/plugins/edit_view/features/step_definitions/tab_steps.rb +7 -7
  42. data/plugins/edit_view/features/step_definitions/window_steps.rb +2 -2
  43. data/plugins/edit_view/lib/edit_view.rb +15 -1
  44. data/plugins/edit_view/lib/edit_view/modified_tabs_checker.rb +7 -7
  45. data/plugins/edit_view_swt/lib/edit_view_swt.rb +7 -6
  46. data/plugins/execute_current_tab/lib/execute_current_tab.rb +1 -1
  47. data/plugins/groovy/lib/groovy.rb +3 -3
  48. data/plugins/groovy/lib/groovy/commands.rb +1 -1
  49. data/plugins/help/lib/help/view_controller.rb +5 -0
  50. data/plugins/help/views/index.html.erb +10 -1
  51. data/plugins/html_view/features/step_definitions/html_view_steps.rb +1 -1
  52. data/plugins/html_view/features/support/env.rb +0 -15
  53. data/plugins/html_view/lib/html_view.rb +3 -4
  54. data/plugins/html_view/lib/html_view/commands.rb +1 -1
  55. data/plugins/key_bindings/lib/key_bindings.rb +34 -0
  56. data/plugins/key_bindings/plugin.rb +8 -0
  57. data/plugins/{tree → key_bindings}/spec/spec_helper.rb +0 -0
  58. data/plugins/line_tools/features/lower_text.feature +3 -4
  59. data/plugins/line_tools/lib/line_tools.rb +6 -5
  60. data/plugins/mirah/lib/mirah.rb +2 -2
  61. data/plugins/pair_highlighter/lib/pair_highlighter/document_controller.rb +5 -3
  62. data/plugins/project/features/open_directory_tree.feature +1 -1
  63. data/plugins/project/features/step_definitions/file_steps.rb +5 -5
  64. data/plugins/project/features/step_definitions/find_file_steps.rb +2 -3
  65. data/plugins/project/features/support/env.rb +4 -0
  66. data/plugins/project/lib/project.rb +15 -9
  67. data/plugins/project/lib/project/commands.rb +46 -16
  68. data/plugins/project/lib/project/dir_controller.rb +1 -1
  69. data/plugins/project/lib/project/dir_mirror.rb +3 -2
  70. data/plugins/project/lib/project/drb_service.rb +3 -1
  71. data/plugins/project/lib/project/file_list.rb +99 -21
  72. data/plugins/project/lib/project/find_file_dialog.rb +8 -24
  73. data/plugins/project/lib/project/manager.rb +68 -12
  74. data/plugins/project/lib/project/project_tree_controller.rb +1 -1
  75. data/plugins/project/plugin.rb +1 -2
  76. data/plugins/project_search/features/word_search.feature +1 -1
  77. data/plugins/project_search/lib/project_search.rb +16 -6
  78. data/plugins/project_search/lib/project_search/commands.rb +15 -28
  79. data/plugins/project_search/lib/project_search/hit.rb +4 -0
  80. data/plugins/project_search/lib/project_search/lucene_index.rb +14 -4
  81. data/plugins/project_search/lib/project_search/views/_file.html.erb +11 -11
  82. data/plugins/project_search/lib/project_search/word_search.rb +22 -4
  83. data/plugins/project_search/spec/project_search/word_search_spec.rb +2 -2
  84. data/plugins/redcar/redcar.rb +140 -588
  85. data/plugins/repl/features/step_definitions/repl_steps.rb +3 -3
  86. data/plugins/repl/features/support/fake_repl.rb +1 -1
  87. data/plugins/ruby/lib/ruby.rb +4 -4
  88. data/plugins/runnables/features/fixtures/alternate.ruby +1 -0
  89. data/plugins/runnables/features/fixtures/line_app.rb +1 -0
  90. data/plugins/runnables/features/fixtures/name_app.rb +1 -0
  91. data/plugins/runnables/features/fixtures/params_app.rb +1 -0
  92. data/plugins/runnables/features/fixtures/runnable_app.rb +1 -0
  93. data/plugins/runnables/lib/runnables.rb +21 -0
  94. data/plugins/runnables/lib/runnables/command_output_controller.rb +14 -9
  95. data/plugins/runnables/lib/runnables/output_processor.rb +4 -4
  96. data/plugins/runnables/lib/runnables/running_process_checker.rb +6 -6
  97. data/plugins/runnables/plugin.rb +1 -2
  98. data/plugins/scm/lib/scm.rb +18 -18
  99. data/plugins/scm/lib/scm/commit_mirror.rb +2 -2
  100. data/plugins/scm/lib/scm/scm_changes_controller.rb +1 -1
  101. data/plugins/scm_hg/lib/scm_hg.rb +1 -1
  102. data/plugins/snippets/lib/snippets/document_controller.rb +46 -40
  103. data/plugins/swt/lib/swt.rb +2 -0
  104. data/plugins/test_runner/lib/test_runner.rb +1 -0
  105. data/plugins/test_runner/lib/test_runner/jasmine_test_runner.rb +15 -0
  106. data/plugins/test_runner/lib/test_runner/runnable_test_runner.rb +21 -5
  107. data/plugins/textmate/lib/textmate.rb +5 -1
  108. data/plugins/textmate/lib/textmate/preference.rb +4 -0
  109. data/plugins/textmate/lib/textmate/snippet.rb +0 -2
  110. data/plugins/textmate/lib/textmate/tree_mirror.rb +6 -5
  111. data/plugins/textmate/plugin.rb +1 -1
  112. data/plugins/textmate/vendor/redcar-bundles/Bundles/C.tmbundle/Syntaxes/C.plist +2 -2
  113. data/plugins/textmate/vendor/redcar-bundles/Bundles/Clojure.tmbundle/info.plist +2 -0
  114. data/plugins/textmate/vendor/redcar-bundles/Bundles/Cucumber.tmbundle/Syntaxes/Cucumber_Plain_Text_Feature.tmLanguage +0 -4
  115. data/plugins/textmate/vendor/redcar-bundles/Bundles/Cucumber.tmbundle/info.plist +2 -0
  116. data/plugins/textmate/vendor/redcar-bundles/Bundles/Mirah.tmbundle/info.plist +3 -1
  117. data/plugins/textmate/vendor/redcar-bundles/Bundles/Palm-WebOS-Development.tmbundle/info.plist +2 -0
  118. data/plugins/textmate/vendor/redcar-bundles/Bundles/RedcarRepl.tmbundle/info.plist +2 -0
  119. data/plugins/textmate/vendor/redcar-bundles/Bundles/SQL.tmbundle/info.plist +2 -0
  120. data/plugins/textmate/vendor/redcar-bundles/Bundles/Scala.tmbundle/info.plist +2 -0
  121. data/plugins/textmate/vendor/redcar-bundles/Bundles/Smalltalk.tmbundle/Preferences/GNU_Smalltalk.tmPreferences +1 -1
  122. data/plugins/textmate/vendor/redcar-bundles/Bundles/Smalltalk.tmbundle/Preferences/MIST_Smalltalk_Format.tmPreferences +1 -1
  123. data/plugins/textmate/vendor/redcar-bundles/Bundles/Smalltalk.tmbundle/info.plist +2 -0
  124. data/plugins/textmate/vendor/redcar-bundles/Bundles/Vala.tmbundle/info.plist +4 -2
  125. data/plugins/textmate/vendor/redcar-bundles/Bundles/Webrat.tmbundle/info.plist +2 -0
  126. data/plugins/textmate/vendor/redcar-bundles/Bundles/YAML.tmbundle/Syntaxes/YAML.plist +1 -0
  127. data/plugins/textmate/vendor/redcar-bundles/Bundles/groovy.tmbundle/info.plist +2 -0
  128. data/plugins/textmate/vendor/redcar-bundles/Themes/Twilight.tmTheme +0 -2
  129. data/plugins/todo_list/lib/todo_list.rb +3 -3
  130. data/plugins/todo_list/lib/todo_list/todo_controller.rb +1 -1
  131. data/plugins/web_bookmarks/features/step_definitions/web_steps.rb +1 -1
  132. data/plugins/web_bookmarks/lib/web_bookmarks.rb +11 -4
  133. data/plugins/web_bookmarks/lib/web_bookmarks/commands.rb +1 -1
  134. data/plugins/web_bookmarks/plugin.rb +1 -2
  135. metadata +29 -20
  136. data/plugins/core/lib/core/logger.rb +0 -28
  137. data/plugins/file_parser/lib/file_parser.rb +0 -125
  138. data/plugins/file_parser/plugin.rb +0 -7
  139. data/plugins/tree/plugin.rb +0 -9
@@ -8,7 +8,7 @@ module Redcar
8
8
  end
9
9
 
10
10
  class Project
11
- class FileOpenCommand < Command
11
+ class OpenFileCommand < Command
12
12
  def initialize(path = nil, adapter = Adapters::Local.new)
13
13
  @path = path
14
14
  @adapter = adapter
@@ -17,7 +17,15 @@ module Redcar
17
17
  def execute
18
18
  path = get_path
19
19
  if path
20
- Manager.open_file(path, @adapter)
20
+ if File.readable? path
21
+ Manager.open_file(path, @adapter)
22
+ else
23
+ Application::Dialog.message_box(
24
+ "Can't read #{path}, you don't have the permissions.",
25
+ :type => :error,
26
+ :buttons => :ok
27
+ )
28
+ end
21
29
  end
22
30
  end
23
31
 
@@ -134,23 +142,34 @@ module Redcar
134
142
  # end
135
143
  #end
136
144
 
137
- class FileSaveCommand < EditTabCommand
145
+ class SaveFileCommand < EditTabCommand
138
146
  def initialize(tab=nil)
139
147
  @tab = tab
140
148
  end
141
149
 
142
150
  def execute
143
151
  if tab.edit_view.document.mirror
144
- tab.edit_view.document.save!
145
- Project::Manager.refresh_modified_file(tab.edit_view.document.mirror.path)
152
+ if File.writable? tab.edit_view.document.mirror.path
153
+ tab.edit_view.document.save!
154
+ Project::Manager.refresh_modified_file(tab.edit_view.document.mirror.path)
155
+ else
156
+ Application::Dialog.message_box(
157
+ "Can't save #{tab.edit_view.document.mirror.path}, you don't have the permissions.",
158
+ :type => :error,
159
+ :buttons => :ok
160
+ )
161
+ result = false
162
+ end
146
163
  else
147
- FileSaveAsCommand.new.run
164
+ result = SaveFileAsCommand.new.run
148
165
  end
149
166
  tab.update_for_file_changes
167
+ result ||= true
168
+ return result
150
169
  end
151
170
  end
152
171
 
153
- class FileSaveAsCommand < EditTabCommand
172
+ class SaveFileAsCommand < EditTabCommand
154
173
 
155
174
  def initialize(tab=nil, path=nil)
156
175
  @tab = tab
@@ -160,12 +179,23 @@ module Redcar
160
179
  def execute
161
180
  path = get_path
162
181
  if path
163
- contents = tab.edit_view.document.to_s
164
- new_mirror = FileMirror.new(path)
165
- new_mirror.commit(contents)
166
- tab.edit_view.document.mirror = new_mirror
167
- Project::Manager.refresh_modified_file(tab.edit_view.document.mirror.path)
182
+ if File.exists?(path) ? File.writable?(path) : File.writable?(File.dirname(path))
183
+ contents = tab.edit_view.document.to_s
184
+ new_mirror = FileMirror.new(path)
185
+ new_mirror.commit(contents)
186
+ tab.edit_view.document.mirror = new_mirror
187
+ Project::Manager.refresh_modified_file(tab.edit_view.document.mirror.path)
188
+ else
189
+ Application::Dialog.message_box(
190
+ "Can't save #{path}, you don't have the permissions.",
191
+ :type => :error,
192
+ :buttons => :ok
193
+ )
194
+ result = false
195
+ end
168
196
  end
197
+ result ||= true
198
+ return result
169
199
  end
170
200
 
171
201
  private
@@ -189,7 +219,7 @@ module Redcar
189
219
  def execute
190
220
  if path = get_path
191
221
  project = Manager.open_project_for_path(path)
192
- project.refresh
222
+ project.refresh if project
193
223
  end
194
224
  end
195
225
 
@@ -232,9 +262,9 @@ module Redcar
232
262
 
233
263
  class RevealInProjectCommand < ProjectCommand
234
264
  def execute
235
- if Project::Manager.reveal_file?(project)
265
+ if project
236
266
  tab = Redcar.app.focussed_window.focussed_notebook_tab
237
- if tab.is_a?(EditTab)
267
+ if tab.is_a?(EditTab)
238
268
  return unless mirror = tab.edit_view.document.mirror and mirror.respond_to? :path
239
269
  else
240
270
  return
@@ -401,4 +431,4 @@ module Redcar
401
431
  end
402
432
  end
403
433
  end
404
- end
434
+ end
@@ -10,7 +10,7 @@ module Redcar
10
10
 
11
11
  def activated(tree, node)
12
12
  if node.leaf?
13
- FileOpenCommand.new(node.path, node.adapter).run
13
+ OpenFileCommand.new(node.path, node.adapter).run
14
14
  end
15
15
  end
16
16
 
@@ -78,9 +78,10 @@ module Redcar
78
78
 
79
79
  def self.create_all_from_path(adapter, path)
80
80
  fs = adapter.fetch_contents(path)
81
- fs = fs.reject {|f| [".", ".."].include?(File.basename(f[:fullname]))}
81
+ fs.reject! { |f| [".", ".."].include?(File.basename(f[:fullname])) }
82
82
  unless DirMirror.show_hidden_files?
83
- fs = fs.reject {|f| File.basename(f[:fullname]) =~ /^\./ }
83
+ fs.reject! { |f| f[:type] == :file and Project::FileList.hide_file?(f[:fullname]) }
84
+ fs.reject! { |f| f[:type] == :dir and Project::FileList.hide_directory? f[:fullname] }
84
85
  end
85
86
  fs.sort_by do |f|
86
87
  File.basename(f[:fullname]).downcase
@@ -3,7 +3,9 @@ module Redcar
3
3
  class DrbService
4
4
  def initialize
5
5
  address = "druby://127.0.0.1:#{DRB_PORT}"
6
- @drb = DRb.start_service(address, self)
6
+ Redcar.log.benchmark("start drb service") do
7
+ @drb = DRb.start_service(address, self)
8
+ end
7
9
  rescue Errno::EADDRINUSE => e
8
10
  puts 'warning--not starting listener (perhaps theres another Redcar already open?)' + e + ' ' + address
9
11
  end
@@ -3,6 +3,77 @@ module Redcar
3
3
  class FileList
4
4
  attr_reader :path
5
5
 
6
+ def self.shared_storage
7
+ @shared_storage ||= begin
8
+ storage = Plugin::SharedStorage.new('shared__ignored_files')
9
+ storage.set_or_update_default('ignored_file_patterns', [/^\./, /\.rbc$/])
10
+ storage.set_or_update_default('not_hidden_files', ['.gitignore', '.gemtest'])
11
+ storage.set_or_update_default('ignored_directory_patterns', [/^\./, /^\.(git|yardoc|svn)$/])
12
+ storage.set_or_update_default('not_hidden_directories', ['.directory_that_should_not_be_hidden'])
13
+ storage.save
14
+ end
15
+ end
16
+
17
+ def self.hidden_files_pattern
18
+ ignored_file_patterns
19
+ end
20
+
21
+ def self.ignored_file_patterns
22
+ shared_storage['ignored_file_patterns']
23
+ end
24
+
25
+ def self.not_hidden_files
26
+ shared_storage['not_hidden_files']
27
+ end
28
+
29
+ def self.hide_file?(file)
30
+ file = File.basename(file)
31
+ return false if not_hidden_files.include?(file)
32
+ ignored_file_patterns.any? { |re| file =~ re }
33
+ end
34
+
35
+ def self.ignored_directory_patterns
36
+ shared_storage['ignored_directory_patterns']
37
+ end
38
+
39
+ def self.not_hidden_directories
40
+ shared_storage['not_hidden_directories']
41
+ end
42
+
43
+ def self.hide_directory?(dir)
44
+ dir = File.basename(dir)
45
+ return false if not_hidden_directories.include?(dir)
46
+ ignored_directory_patterns.any? { |re| dir =~ re }
47
+ end
48
+
49
+ def self.hide_file_path?(file_path)
50
+ basename = File.basename(file_path)
51
+ if ignored_file_patterns.any? { |re| basename =~ re } and
52
+ !not_hidden_files.include?(basename)
53
+ return true
54
+ end
55
+
56
+ dirs = file_path.split("/")[0..-2]
57
+ if ignored_directory_patterns.any? { |re| dirs.any? { |dir| dir =~ re } }
58
+ return true
59
+ end
60
+ false
61
+ end
62
+
63
+ # Adds a pattern to the ignored_file_patterns option
64
+ #
65
+ # @param [String] file_pattern pattern of the file
66
+ def self.add_hide_file_pattern(file_pattern)
67
+ shared_storage['ignored_file_patterns'] = shared_storage['ignored_file_patterns'] + [Regexp.new(file_pattern)]
68
+ end
69
+
70
+ # Adds a pattern to the ignored_directory_patterns option
71
+ #
72
+ # @param [String] directory_pattern pattern of the directory
73
+ def self.add_hide_directory_pattern(directory_pattern)
74
+ shared_storage['ignored_directory_patterns'] = shared_storage['ignored_directory_patterns'] + [Regexp.new(directory_pattern)]
75
+ end
76
+
6
77
  def initialize(path)
7
78
  @path = File.expand_path(path)
8
79
  @files = {}
@@ -48,28 +119,35 @@ module Redcar
48
119
  else
49
120
  stat = File.lstat(file)
50
121
  end
51
- unless file =~ /\.git|\.yardoc|\.svn/
52
- unless stat.directory?
53
- files[file.dup] = stat.mtime
54
- end
55
- next unless File.exist? file
56
- if stat.directory?
57
- d = Dir.open(file)
58
- begin
59
- for f in d
60
- next if f == "." or f == ".."
61
- if File::ALT_SEPARATOR and file =~ /^(?:[\/\\]|[A-Za-z]:[\/\\]?)$/
62
- f = file + f
63
- elsif file == "/"
64
- f = "/" + f
65
- else
66
- f = File.join(file, f)
67
- end
68
- paths.unshift f.untaint
122
+
123
+ if stat.directory?
124
+ next if FileList.hide_directory?(file)
125
+ else
126
+ next if FileList.hide_file?(file)
127
+ end
128
+
129
+ unless stat.directory?
130
+ files[file.dup] = stat.mtime
131
+ end
132
+
133
+ next unless File.exist?(file)
134
+
135
+ if stat.directory?
136
+ d = Dir.open(file)
137
+ begin
138
+ for f in d
139
+ next if f == "." or f == ".."
140
+ if File::ALT_SEPARATOR and file =~ /^(?:[\/\\]|[A-Za-z]:[\/\\]?)$/
141
+ f = file + f
142
+ elsif file == "/"
143
+ f = "/" + f
144
+ else
145
+ f = File.join(file, f)
69
146
  end
70
- ensure
71
- d.close
147
+ paths.unshift f.untaint
72
148
  end
149
+ ensure
150
+ d.close
73
151
  end
74
152
  end
75
153
  rescue Errno::ENOENT, Errno::EACCES
@@ -79,4 +157,4 @@ module Redcar
79
157
  end
80
158
  end
81
159
  end
82
- end
160
+ end
@@ -1,19 +1,9 @@
1
1
  require 'set'
2
2
 
3
3
  module Redcar
4
- class Project
4
+ class Project
5
5
 
6
6
  class FindFileDialog < FilterListDialog
7
- def self.storage
8
- @storage ||= begin
9
- storage = Plugin::Storage.new('find_file_dialog')
10
- storage.set_default('ignore_file_patterns', false)
11
- storage.set_default('ignore_files_that_match_these_regexes', [])
12
- storage.set_default('ignore_files_that_match_these_regexes_example_for_reference', [/.*\.class/i])
13
- storage
14
- end
15
- end
16
-
17
7
  attr_reader :project
18
8
 
19
9
  def initialize(project)
@@ -55,7 +45,7 @@ module Redcar
55
45
  def selected(text, ix, closing=false)
56
46
  if @last_list
57
47
  close
58
- FileOpenCommand.new(@last_list[ix]).run
48
+ OpenFileCommand.new(@last_list[ix]).run
59
49
  end
60
50
  end
61
51
 
@@ -90,25 +80,19 @@ module Redcar
90
80
  end
91
81
  end
92
82
 
93
- def ignore_regexes
94
- self.class.storage['ignore_files_that_match_these_regexes']
95
- end
96
-
97
- def ignore_file?(filename)
98
- if self.class.storage['ignore_file_patterns']
99
- ignore_regexes.any? {|re| re =~ filename }
100
- end
101
- end
102
-
103
83
  def find_files_from_list(text, file_list)
104
84
  re = make_regex(text)
105
85
  file_list.select do |fn|
106
- not ignore_file?(fn) and match_substring(fn) =~ re
86
+ match_substring(fn) =~ re
107
87
  end
108
88
  end
109
89
 
110
90
  def find_files(text, directories)
111
- files = project.all_files.sort.select {|fn| not ignore_file?(fn)}
91
+ begin
92
+ files = project.all_files.sort
93
+ rescue => e
94
+ p e
95
+ end
112
96
  filter_and_rank_by(files, text) {|fn| match_substring(fn) }
113
97
  end
114
98
 
@@ -80,9 +80,10 @@ module Redcar
80
80
 
81
81
  def self.init_window_closed_hooks
82
82
  Redcar.app.add_listener(:window_about_to_close) do |win|
83
- project = in_window(win)
84
- project.close if project
85
- self.save_file_list(win)
83
+ if project = in_window(win)
84
+ project.close
85
+ self.save_file_list(win)
86
+ end
86
87
  end
87
88
  end
88
89
 
@@ -113,7 +114,7 @@ module Redcar
113
114
  end
114
115
 
115
116
  def self.reveal_file?(project)
116
- if project and tree = project.tree
117
+ if project and project.window and tree = project.tree
117
118
  if reveal_files? and project.window.trees_visible?
118
119
  ftree = project.window.treebook.focussed_tree
119
120
  unless tree != ftree and reveal_file_only_when_tree_focussed?
@@ -244,7 +245,7 @@ module Redcar
244
245
  end
245
246
 
246
247
  PROJECT_LOCKED_MESSAGE = "Project appears to be locked by another Redcar process!\nOpen anway?"
247
-
248
+
248
249
  # Opens a new Tree with a DirMirror and DirController for the given
249
250
  # path, in a new window.
250
251
  #
@@ -257,11 +258,11 @@ module Redcar
257
258
  end
258
259
  end
259
260
  project = Project.new(path)
260
- should_open = true
261
+ should_open = :yes
261
262
  if project.locked?
262
263
  should_open = Application::Dialog.message_box(PROJECT_LOCKED_MESSAGE, :type => :warning, :buttons => :yes_no)
263
264
  end
264
- if should_open
265
+ if should_open == :yes
265
266
  win = Redcar.app.focussed_window
266
267
  win = Redcar.app.new_window if !win or Manager.in_window(win)
267
268
  project.open(win) if project.ready?
@@ -395,17 +396,17 @@ module Redcar
395
396
  Menu::Builder.build do
396
397
  sub_menu "File" do
397
398
  group(:priority => 0) do
398
- item "Open", Project::FileOpenCommand
399
+ item "Open", Project::OpenFileCommand
399
400
  item "Reload File", Project::FileReloadCommand
400
401
  item "Open Directory", Project::DirectoryOpenCommand
401
402
  item "Open Recent...", Project::FindRecentCommand
402
-
403
+
403
404
  separator
404
- item "Save", Project::FileSaveCommand
405
- item "Save As", Project::FileSaveAsCommand
405
+ item "Save", Project::SaveFileCommand
406
+ item "Save As", Project::SaveFileAsCommand
406
407
  end
407
408
  end
408
-
409
+
409
410
  sub_menu "Project", :priority => 15 do
410
411
  group(:priority => :first) do
411
412
  item "Find File", Project::FindFileCommand
@@ -416,6 +417,32 @@ module Redcar
416
417
  end
417
418
  end
418
419
 
420
+ def self.close_tab_guard(tab)
421
+ if tab.respond_to?(:edit_view) && tab.edit_view.document.modified?
422
+ tab.focus
423
+ result = Application::Dialog.message_box(
424
+ "This tab has unsaved changes. \n\nSave before closing?",
425
+ :buttons => :yes_no_cancel
426
+ )
427
+ case result
428
+ when :yes
429
+ # check if the tab was saved properly,
430
+ # it would return false for example if the permission is not granted
431
+ if Project::SaveFileCommand.new(tab).run
432
+ true
433
+ else
434
+ false
435
+ end
436
+ when :no
437
+ true
438
+ when :cancel
439
+ false
440
+ end
441
+ else
442
+ true
443
+ end
444
+ end
445
+
419
446
  # Uses our own context menu hook to provide context menu entries
420
447
  # @return [Menu]
421
448
  def self.project_context_menus(tree, node, controller)
@@ -462,6 +489,35 @@ module Redcar
462
489
  end
463
490
  group(:priority => 75) do
464
491
  separator
492
+
493
+ if node and node.leaf?
494
+ item("Hide this file") do
495
+ input = Application::Dialog.input(
496
+ "Hide file",
497
+ "Please enter a pattern to hide this kind of files or press OK to hide this file only.",
498
+ '^' + Regexp.escape(node.text) + '$'
499
+ )
500
+ if input[:button] == :ok
501
+ Project::FileList.add_hide_file_pattern(input[:value])
502
+ Project::Manager.focussed_project.refresh
503
+ end
504
+ end
505
+ end
506
+
507
+ if node and node.directory?
508
+ item('Hide this directory') do
509
+ input = Application::Dialog.input(
510
+ 'Hide directory',
511
+ 'Please enter a pattern to hide this kind of directories or press OK to hide this directory only.',
512
+ '^' + Regexp.escape(node.text) + '$'
513
+ )
514
+ if input[:button] == :ok
515
+ Project::FileList.add_hide_directory_pattern(input[:value])
516
+ Project::Manager.focussed_project.refresh
517
+ end
518
+ end
519
+ end
520
+
465
521
  if DirMirror.show_hidden_files?
466
522
  item("Hide Hidden Files") do
467
523
  DirMirror.show_hidden_files = false