redcar 0.11.0dev → 0.11

Sign up to get free protection for your applications and to get access to all the features.
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