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.
- data/CHANGES +18 -0
- data/bin/redcar +1 -0
- data/lib/redcar.rb +4 -5
- data/lib/redcar/usage.rb +0 -1
- data/lib/redcar_quick_start.rb +3 -1
- data/plugins/application/lib/application.rb +1 -0
- data/plugins/application/lib/application/commands/treebook_commands.rb +11 -18
- data/plugins/application/lib/application/dialog.rb +1 -1
- data/plugins/application/lib/application/dialogs/filter_list_dialog.rb +13 -5
- data/plugins/application/lib/application/global_state.rb +21 -0
- data/plugins/application/lib/application/menu/item.rb +37 -11
- data/plugins/application/lib/application/notebook.rb +12 -0
- data/plugins/application/lib/application/tree/mirror.rb +0 -11
- data/plugins/application/lib/application/window.rb +32 -7
- data/plugins/application_swt/lib/application_swt.rb +1 -1
- data/plugins/application_swt/lib/application_swt/dialogs/filter_list_dialog_controller.rb +35 -10
- data/plugins/application_swt/lib/application_swt/icon.rb +1 -1
- data/plugins/application_swt/lib/application_swt/menu.rb +47 -15
- data/plugins/application_swt/lib/application_swt/notebook.rb +11 -2
- data/plugins/application_swt/lib/application_swt/window.rb +37 -34
- data/plugins/auto_indenter/lib/auto_indenter/analyzer.rb +1 -1
- data/plugins/auto_indenter/spec/auto_indenter/analyzer_spec.rb +9 -0
- data/plugins/declarations/lib/declarations.rb +31 -66
- data/plugins/declarations/lib/declarations/commands.rb +142 -0
- data/plugins/declarations/lib/declarations/file.rb +1 -1
- data/plugins/{outline_view → declarations}/spec/fixtures/some_project/javascript.js +0 -0
- data/plugins/{outline_view → declarations}/spec/fixtures/some_project/nothing_to_see.rb +0 -0
- data/plugins/{outline_view → declarations}/spec/fixtures/some_project/one_lonely_class.rb +0 -0
- data/plugins/{outline_view → declarations}/spec/fixtures/some_project/similar_names.rb +0 -0
- data/plugins/{outline_view → declarations}/spec/fixtures/some_project/something_fancy.rb +0 -0
- data/plugins/{outline_view → declarations}/spec/fixtures/some_project/trailing_space.rb +0 -0
- data/plugins/edit_view/lib/edit_view.rb +35 -2
- data/plugins/edit_view/lib/edit_view/commands/change_language_command.rb +31 -0
- data/plugins/edit_view/lib/edit_view/commands/language_settings_commands.rb +45 -0
- data/plugins/edit_view/lib/edit_view/document/command.rb +1 -1
- data/plugins/edit_view/lib/edit_view/edit_tab.rb +11 -13
- data/plugins/key_bindings/lib/key_bindings.rb +6 -2
- data/plugins/project/lib/project.rb +27 -32
- data/plugins/project/lib/project/commands.rb +3 -88
- data/plugins/project/lib/project/dir_controller.rb +12 -18
- data/plugins/project/lib/project/dir_mirror.rb +20 -25
- data/plugins/project/lib/project/file_mirror.rb +10 -10
- data/plugins/project/lib/project/find_file_dialog.rb +20 -18
- data/plugins/project/lib/project/find_recent_dialog.rb +6 -3
- data/plugins/project/lib/project/{adapters/local.rb → local_filesystem.rb} +35 -35
- data/plugins/project/lib/project/manager.rb +21 -75
- data/plugins/project/lib/project/sub_project.rb +3 -3
- data/plugins/project/plugin.rb +0 -1
- data/plugins/project_search/lib/project_search/lucene_refresh.rb +0 -1
- data/plugins/redcar/plugin.rb +2 -2
- data/plugins/redcar/redcar.rb +34 -42
- data/plugins/ruby/lib/ruby/syntax_checker.rb +27 -7
- data/plugins/scm/lib/scm.rb +1 -12
- data/plugins/sessions/lib/sessions.rb +22 -0
- data/plugins/sessions/lib/sessions/cursor_saver.rb +162 -0
- data/plugins/sessions/lib/sessions/loader.rb +99 -0
- data/plugins/sessions/lib/sessions/memory.rb +59 -0
- data/plugins/sessions/plugin.rb +8 -0
- data/plugins/strip_trailing_spaces/lib/strip_trailing_spaces.rb +2 -2
- data/plugins/syntax_check/lib/syntax_check.rb +2 -2
- data/plugins/tree_view_swt/lib/tree_view_swt.rb +1 -3
- data/redcar.gemspec +1 -1
- metadata +195 -291
- data/plugins/connection_manager/lib/connection_manager.rb +0 -57
- data/plugins/connection_manager/lib/connection_manager/commands.rb +0 -14
- data/plugins/connection_manager/lib/connection_manager/connection_store.rb +0 -87
- data/plugins/connection_manager/lib/connection_manager/controller.rb +0 -100
- data/plugins/connection_manager/lib/connection_manager/filter_dialog.rb +0 -38
- data/plugins/connection_manager/lib/connection_manager/private_key_store.rb +0 -93
- data/plugins/connection_manager/plugin.rb +0 -12
- data/plugins/connection_manager/views/index.html.erb +0 -284
- data/plugins/edit_view/lib/edit_view/info_speedbar.rb +0 -98
- data/plugins/outline_view/features/outline_view.feature +0 -79
- data/plugins/outline_view/features/project_outline.feature +0 -23
- data/plugins/outline_view/features/step_definitions/outline_steps.rb +0 -61
- data/plugins/outline_view/lib/outline_view.rb +0 -97
- data/plugins/outline_view/lib/outline_view/commands.rb +0 -19
- data/plugins/outline_view/plugin.rb +0 -10
- data/plugins/outline_view_swt/lib/outline_view_swt.rb +0 -79
- data/plugins/outline_view_swt/plugin.rb +0 -7
- data/plugins/project/lib/project/adapters/remote.rb +0 -96
- data/plugins/project/lib/project/adapters/remote_protocols/ftp.rb +0 -93
- data/plugins/project/lib/project/adapters/remote_protocols/protocol.rb +0 -94
- 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 | 
| 10 | 
            -
                    file | 
| 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 | 
            -
                       | 
| 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 | 
            +
             | 
    
        data/plugins/scm/lib/scm.rb
    CHANGED
    
    | @@ -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, : | 
| 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
         | 
| @@ -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", | 
| 34 | 
            -
                        item "Strip Blank Lines", :command => ToggleStripBlankLines, | 
| 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
         |