Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'master' of git://github.com/danlucraft/redcar

  • Loading branch information...
commit a693646466b9f6f8516632207a8140c8baa7d293 2 parents cc86bf7 + de092f4
@dbyrne authored
Showing with 651 additions and 389 deletions.
  1. +1 −0  .gitignore
  2. +4 −4 .gitmodules
  3. +1 −3 README.md
  4. +1 −1  lib/redcar/installer.rb
  5. +1 −1  lib/redcar/runner.rb
  6. +5 −3 plugins/application/features/step_definitions/dialog_steps.rb
  7. +21 −2 plugins/application/features/support/env.rb
  8. +28 −7 plugins/application/lib/application/dialog.rb
  9. +2 −2 plugins/application/lib/application/dialogs/filter_list_dialog.rb
  10. +1 −0  plugins/application/lib/application/menu/builder/group.rb
  11. +1 −1  plugins/application/plugin.rb
  12. +30 −4 plugins/application_swt/lib/application_swt/dialog_adapter.rb
  13. +28 −19 plugins/application_swt/lib/application_swt/speedbar.rb
  14. +22 −0 plugins/connection_manager/lib/connection_manager.rb
  15. +38 −0 plugins/connection_manager/lib/connection_manager/filter_dialog.rb
  16. +1 −1  plugins/declarations/lib/declarations.rb
  17. +14 −0 plugins/document_search/Readme.md
  18. +114 −0 plugins/document_search/features/replace.feature
  19. +20 −1 plugins/document_search/lib/document_search.rb
  20. +81 −0 plugins/document_search/lib/document_search/replace.rb
  21. +5 −5 plugins/{search_and_replace/lib → document_search/lib/document_search}/search.rb
  22. +84 −0 plugins/document_search/lib/document_search/search_and_replace.rb
  23. +0 −1  plugins/edit_view/features/step_definitions/editing_steps.rb
  24. +13 −0 plugins/plugin_manager_ui/lib/plugin_manager_ui.rb
  25. +3 −2 plugins/plugin_manager_ui/plugin.rb
  26. +4 −2 plugins/project/lib/project.rb
  27. +11 −29 plugins/project/lib/project/commands.rb
  28. +11 −1 plugins/project/lib/project/dir_controller.rb
  29. +32 −1 plugins/project/lib/project/manager.rb
  30. +4 −2 plugins/project/plugin.rb
  31. +2 −2 plugins/project/spec/project/adapters/remote_protocols/ftp_spec.rb
  32. +3 −3 plugins/project/spec/project/adapters/remote_protocols/sftp_spec.rb
  33. +1 −2  plugins/project/spec/project/file_list_spec.rb
  34. +1 −1  plugins/redcar/plugin.rb
  35. +35 −48 plugins/redcar/redcar.rb
  36. +12 −0 plugins/runnables/lib/runnables.rb
  37. +1 −1  plugins/runnables/plugin.rb
  38. +0 −41 plugins/search_and_replace/Readme.md
  39. +0 −68 plugins/search_and_replace/lib/replace.rb
  40. +0 −112 plugins/search_and_replace/lib/search_and_replace.rb
  41. +0 −7 plugins/search_and_replace/plugin.rb
  42. +1 −1  plugins/textmate/lib/textmate.rb
  43. +1 −1  plugins/textmate/vendor/redcar-bundles
  44. +9 −0 plugins/view_shortcuts/lib/view_shortcuts.rb
  45. +4 −10 plugins/view_shortcuts/views/index.html.erb
View
1  .gitignore
@@ -47,3 +47,4 @@ plugins/repl/vendor/clojure.jar
plugins/repl/vendor/clojure-contrib.jar
plugins/repl/vendor/org-enclojure-repl-server.jar
tags
+vendor/swtbot
View
8 .gitmodules
@@ -12,16 +12,16 @@
url = git://github.com/danlucraft/jruby-prof.git
[submodule "lib/json"]
path = lib/json
- url = http://github.com/flori/json.git
+ url = git://github.com/flori/json.git
[submodule "plugins/project/vendor/net-ssh"]
path = plugins/project/vendor/net-ssh
- url = http://github.com/net-ssh/net-ssh.git
+ url = git://github.com/net-ssh/net-ssh.git
[submodule "plugins/project/vendor/net-sftp"]
path = plugins/project/vendor/net-sftp
- url = http://github.com/net-ssh/net-sftp.git
+ url = git://github.com/net-ssh/net-sftp.git
[submodule "plugins/project/vendor/net-ftp-list"]
path = plugins/project/vendor/net-ftp-list
- url = http://github.com/fcoury/net-ftp-list.git
+ url = git://github.com/fcoury/net-ftp-list.git
[submodule "plugins/textmate/vendor/redcar-bundles"]
path = plugins/textmate/vendor/redcar-bundles
url = git://github.com/danlucraft/redcar-bundles.git
View
4 README.md
@@ -79,9 +79,7 @@ To run all specs and features:
$ jruby -S rake
-NB. Features work with Cucumber version 0.4.2, you may have problems with
-other versions because for the moment we are patching Cucumber dynamically
-to support dependencies between sets of features.
+NB. You must leave the test window focussed while the features run. Some of the tests will fail if the test process is in the background.
## TESTS (specs)
View
2  lib/redcar/installer.rb
@@ -90,7 +90,7 @@ def redcar_jars_dir
"/jruby/joni.jar"
]
- JRUBY << "http://jruby.org.s3.amazonaws.com/downloads/1.5.0/jruby-complete-1.5.0.jar"
+ JRUBY << "http://jruby.org.s3.amazonaws.com/downloads/1.5.1/jruby-complete-1.5.1.jar"
JOPENSSL_DIR = File.expand_path(File.join(File.dirname(__FILE__), "..", "openssl/lib/"))
JOPENSSL = {
View
2  lib/redcar/runner.rb
@@ -7,7 +7,7 @@ class Runner
# our vendored jarred one (useful for gems).
def spin_up
bin = "#{File.dirname(__FILE__)}/../../bin/redcar"
- jruby_complete = File.expand_path(File.join(File.dirname(__FILE__), "..", "jruby-complete-1.5.0.jar"))
+ jruby_complete = File.expand_path(File.join(File.dirname(__FILE__), "..", "jruby-complete-1.5.1.jar"))
unless File.exist?(jruby_complete)
puts "\nCan't find jruby jar at #{jruby_complete}, did you run 'redcar install' ?"
exit 1
View
8 plugins/application/features/step_definitions/dialog_steps.rb
@@ -1,10 +1,12 @@
Given /^I will choose "([^\"]*)" from the "([^\"]*)" dialog$/ do |path, type|
- Redcar.gui.register_dialog_adapter(FakeDialogAdapter.new)
Redcar.gui.dialog_adapter.set(type.to_sym, path)
end
Then /^I should not see a "([^\"]*)" dialog for the rest of the feature/ do |type|
- Redcar.gui.register_dialog_adapter(FakeDialogAdapter.new)
Redcar.gui.dialog_adapter.set(type.to_sym, :raise_error)
-end
+end
+
+Then /^I should see a message box containing "([^"]*)"$/ do |arg1|
+ Redcar.gui.dialog_adapter.should_get_message(arg1)
+end
View
23 plugins/application/features/support/env.rb
@@ -1,3 +1,6 @@
+class TestingError < StandardError
+end
+
module SwtHelper
def main_menu
display = Redcar::ApplicationSWT.display
@@ -54,6 +57,10 @@ def set(method, value)
@responses[method] = value
end
+ def should_get_message(message)
+ @message = message
+ end
+
def open_file(*args)
check_for_raise(@responses[:open_file])
end
@@ -67,12 +74,19 @@ def save_file(*args)
end
def message_box(*args)
- check_for_raise(@responses[:message_box].to_sym)
+ if @message
+ unless @message == args.first
+ raise TestingError.new("expected the message #{@message.inspect} got #{args.first.inspect}")
+ end
+ @message = nil
+ else
+ raise TestingError.new("got a message box showing #{args.first.inspect} when I didn't expect one")
+ end
end
def check_for_raise(result)
if result == :raise_error
- raise "did not expect dialog"
+ raise TestingError.new("did not expect dialog")
end
result
end
@@ -80,6 +94,10 @@ def check_for_raise(result)
def available_message_box_button_combos
Redcar::ApplicationSWT::DialogAdapter.new.available_message_box_button_combos
end
+
+ def available_message_box_types
+ Redcar::ApplicationSWT::DialogAdapter.new.available_message_box_types
+ end
end
World(SwtHelper)
@@ -122,6 +140,7 @@ def close_everything
Before do
close_everything
Redcar::ApplicationSWT::FilterListDialogController.test_mode = true
+ Redcar.gui.register_dialog_adapter(FakeDialogAdapter.new)
end
After do
View
35 plugins/application/lib/application/dialog.rb
@@ -1,19 +1,32 @@
module Redcar
class Application
class Dialog
+ # Is the application currently showing a modal dialog?
+ def self.in_dialog?
+ @in_dialog
+ end
+
+ # Do not call
+ def self.in_dialog
+ @in_dialog = true
+ r = yield
+ @in_dialog = false
+ r
+ end
+
# Prompt the user with an open file dialog. Returns a path.
def self.open_file(options)
- Redcar.gui.dialog_adapter.open_file(options)
+ in_dialog { Redcar.gui.dialog_adapter.open_file(options) }
end
# Prompt the user with an open directory dialog. Returns a path.
def self.open_directory(options)
- Redcar.gui.dialog_adapter.open_directory(options)
+ in_dialog { Redcar.gui.dialog_adapter.open_directory(options) }
end
# Prompt the user with an save file dialog. Returns a path.
def self.save_file(options)
- Redcar.gui.dialog_adapter.save_file(options)
+ in_dialog { Redcar.gui.dialog_adapter.save_file(options) }
end
# Show a message to the user. Requires a message and
@@ -36,19 +49,19 @@ def self.message_box(text, options={})
if type = options[:type] and !available_message_box_types.include?(type)
raise "option :type must be in #{available_message_box_button_types.inspect}"
end
- Redcar.gui.dialog_adapter.message_box(text, options)
+ in_dialog { Redcar.gui.dialog_adapter.message_box(text, options) }
end
# Returns the list of valid button combos that can be passed
# as an option to message_box.
def self.available_message_box_button_combos
- Redcar.gui.dialog_adapter.available_message_box_button_combos
+ in_dialog { Redcar.gui.dialog_adapter.available_message_box_button_combos }
end
# Returns the list of valid message box types that can be passed
# as an option to message_box
def self.available_message_box_types
- Redcar.gui.dialog_adapter.available_message_box_types
+ in_dialog { Redcar.gui.dialog_adapter.available_message_box_types }
end
# Show a dialog containing a text entry box to the user, and blocks
@@ -71,7 +84,15 @@ def self.available_message_box_types
#
# The return value is a hash containing :button and :value.
def self.input(title, message, initial_value="", &validator)
- Redcar.gui.dialog_adapter.input(title, message, initial_value, &validator)
+ in_dialog { Redcar.gui.dialog_adapter.input(title, message, initial_value, &validator) }
+ end
+
+ # Show a dialog containing a password entry box to the user, and blocks
+ # until they dismiss it.
+ #
+ # The return value is a hash containing :button and :value.
+ def self.password_input(title, message)
+ in_dialog { Redcar.gui.dialog_adapter.password_input(title, message) }
end
# Shows a tool tip to the user, at the cursor location.
View
4 plugins/application/lib/application/dialogs/filter_list_dialog.rb
@@ -47,13 +47,13 @@ def selected(text, ix)
# @param [Array<A>] list the list to filter
# @param [String] query the fuzzy string to match on
# @param [Integer] max_length the length of the resulting list (default 20)
- # @block A -> String turns an element from the list into a string to match on
+ # @block A -> String optionally turns an element from the list into a string to match on
def filter_and_rank_by(list, query, max_length=20)
re = make_regex(query)
score_match_pairs = []
cutoff = 100000000
results = list.each do |element|
- bit = yield(element)
+ bit = block_given? ? yield(element) : element
begin
if m = bit.match(re)
cs = []
View
1  plugins/application/lib/application/menu/builder/group.rb
@@ -22,6 +22,7 @@ def initialize(builder, options={}, &block)
end
def item(text, options={}, &block)
+ options = {:command => options} if not options.respond_to?('[]')
@builder.item(text, @defaults.merge(options), &block)
end
View
2  plugins/application/plugin.rb
@@ -1,7 +1,7 @@
Plugin.define do
name "application"
- version "1.0"
+ version "1.1"
file "lib", "application"
object "Redcar::Application"
dependencies "core", ">0"
View
34 plugins/application_swt/lib/application_swt/dialog_adapter.rb
@@ -68,12 +68,31 @@ def available_message_box_button_combos
MESSAGE_BOX_BUTTON_COMBOS.keys
end
- class InputDialog < JFace::Dialogs::InputDialog
- def initialize(parentShell, dialogTitle, dialogMessage, initialValue, &block)
- super(parentShell, dialogTitle, dialogMessage, initialValue, block)
+ class PasswordDialog < JFace::Dialogs::Dialog
+ def initialize(parent_shell, title, message)
+ super(parent_shell)
+ @title, @message = title, message
end
- def createShell
+ def createDialogArea(parent)
+ composite = super(parent)
+
+ passwordLabel = Swt::Widgets::Label.new(composite, Swt::SWT::RIGHT)
+ passwordLabel.setText(@message)
+
+ @passwordField = Swt::Widgets::Text.new(composite, Swt::SWT::SINGLE | Swt::SWT::PASSWORD)
+ data = Swt::Layout::GridData.new(Swt::Layout::GridData::FILL_HORIZONTAL)
+ @passwordField.setLayoutData(data)
+
+ getShell.setText(@title)
+ end
+
+ def value
+ @password
+ end
+
+ def close
+ @password = @passwordField.getText
super
end
end
@@ -89,6 +108,13 @@ def input(title, message, initial_value, &block)
{:button => button, :value => dialog.getValue}
end
+ def password_input(title, message)
+ dialog = PasswordDialog.new(parent_shell, title, message)
+ code = dialog.open
+ button = (code == 0 ? :ok : :cancel)
+ {:button => button, :value => dialog.value}
+ end
+
def tool_tip(message, location)
tool_tip = Swt::Widgets::ToolTip.new(parent_shell, Swt::SWT::ICON_INFORMATION)
tool_tip.set_message(message)
View
47 plugins/application_swt/lib/application_swt/speedbar.rb
@@ -72,21 +72,21 @@ def create_bar_widget
image = Swt::Graphics::Image.new(ApplicationSWT.display, Redcar::Speedbar.close_image_path)
label = Swt::Widgets::Label.new(@composite, 0)
label.set_image(image)
-
- label.add_mouse_listener(MouseListener.new(self))
- end
-
- def execute_listener_in_model(item, *args)
- if item.listener
- begin
- @model.instance_exec(*args, &item.listener)
- rescue => err
- error_in_listener(err)
+
+ label.add_mouse_listener(MouseListener.new(self))
+ end
+
+ def execute_listener_in_model(item, *args)
+ if item.listener
+ begin
+ @model.instance_exec(*args, &item.listener)
+ rescue => err
+ error_in_listener(err)
+ end
end
end
- end
-
- def create_item_widgets
+
+ def create_item_widgets
@model.__items.each do |item|
case item
when Redcar::Speedbar::LabelItem
@@ -192,10 +192,10 @@ def initialize(speedbar)
end
def key_pressed(e)
+ @speedbar.key_press(e)
end
def key_released(e)
- @speedbar.key_press(e)
end
end
@@ -224,6 +224,7 @@ def close_pressed
end
def key_press(e)
+ return if Application::Dialog.in_dialog?
key_string = Menu::BindingTranslator.key_string(e)
if key_string == "\e"
@window_model.close_speedbar
@@ -245,15 +246,23 @@ def rescue_speedbar_errors
begin
yield
rescue Object => e
- puts "*** Error in speedbar"
- puts e.class.to_s + ": " + e.message
- puts e.backtrace
+ if e.class.name == "TestingError"
+ raise e
+ else
+ puts "*** Error in speedbar"
+ puts e.class.to_s + ": " + e.message
+ puts e.backtrace
+ end
end
end
def error_in_listener(e)
- puts "*** Error in speedbar listener: #{e.message}"
- puts e.backtrace.map {|l| " " + l}
+ if e.class.name == "TestingError"
+ raise e
+ else
+ puts "*** Error in speedbar listener: #{e.message}"
+ puts e.backtrace.map {|l| " " + l}
+ end
end
end
end
View
22 plugins/connection_manager/lib/connection_manager.rb
@@ -3,12 +3,17 @@
require 'connection_manager/commands'
require 'connection_manager/connection_store'
require 'connection_manager/controller'
+require 'connection_manager/filter_dialog'
require 'connection_manager/private_key_store'
module Redcar
class ConnectionManager
CONNECTION_SUPER_CLASS ||= Struct.new(:name, :protocol, :host, :port, :user, :path)
+ def self.open_connection(c)
+ Project::Manager.connect_to_remote(c.protocol, c.host, c.user, c.path, PrivateKeyStore.paths)
+ end
+
class Connection < CONNECTION_SUPER_CLASS
def to_hash
{
@@ -21,12 +26,29 @@ def to_hash
}
end
end
+
+ class OpenRemoteFilter < Command
+ def execute
+ FilterDialog.new.open
+ end
+ end
+ def self.keymaps
+ osx = Redcar::Keymap.build("main", :osx) do
+ link "Cmd+P", OpenRemoteFilter
+ end
+ linwin = Redcar::Keymap.build("main", [:linux, :windows]) do
+ link "Ctrl+P", OpenRemoteFilter
+ end
+ [osx, linwin]
+ end
+
def self.menus
Menu::Builder.build do
sub_menu "Plugins" do
sub_menu "Connections" do
item "Manage", OpenCommand
+ item "Remote Filter", OpenRemoteFilter
end
end
end
View
38 plugins/connection_manager/lib/connection_manager/filter_dialog.rb
@@ -0,0 +1,38 @@
+module Redcar
+ class ConnectionManager
+ class FilterDialog < FilterListDialog
+ MANAGER_NAME = "(Connection Manager)"
+
+ def initialize
+ super
+ end
+
+ def update_list(query)
+ if query == ""
+ connection_names
+ else
+ filter_and_rank_by(connection_names, query, 1000)
+ end
+ end
+
+ def selected(text, _)
+ close
+ open_connection(text)
+ end
+
+ private
+
+ def open_connection(name)
+ ConnectionManager.open_connection(store.find(name))
+ end
+
+ def store
+ ConnectionManager::ConnectionStore.new
+ end
+
+ def connection_names
+ ["(Connection Manager)"] + store.connections.map {|con| con.name }
+ end
+ end
+ end
+end
View
2  plugins/declarations/lib/declarations.rb
@@ -32,7 +32,7 @@ def self.autocompletion_source_types
end
def self.file_path(project)
- ::File.join(project.path, 'tags')
+ ::File.join(project.config_dir, 'tags')
end
class ProjectRefresh < Task
View
14 plugins/document_search/Readme.md
@@ -0,0 +1,14 @@
+
+Todo List
+---
+1. Store last n search and replace results in memory
+1. Optionally store the search and replace results in configuration file.
+1. Pre-populate seach box with selected text
+1. Adding a shortcut keystroke.
+1. Better error handling
+1. Advanced Search and Replace - Across all open files or across all files in a project
+1. RSpec Tests
+1. Regex handling for replace (groups, etc..)
+1. Fix same line bug - doesn't go back and seach to left of cursor.
+
+Comments or suggestions wcherry69@gmail.com
View
114 plugins/document_search/features/replace.feature
@@ -0,0 +1,114 @@
+
+@speedbar
+Feature: Replace in file
+
+ Background:
+ Given I open a new edit tab
+
+ Scenario: Open replace speedbar
+ When I replace the contents with "Foo\nBar\nBaz"
+ And I move the cursor to 0
+ And I run the command DocumentSearch::SearchAndReplaceCommand
+ Then the DocumentSearch::SearchAndReplaceSpeedbar speedbar should be open
+
+ Scenario: Replace next occurrence on the same line
+ When I replace the contents with "Foo\nBar Rab Rab\nBaz"
+ And I move the cursor to 4
+ And I run the command DocumentSearch::SearchAndReplaceCommand
+ And I type "Rab" into the "Search" field in the speedbar
+ And I type "RAB" into the "Replace" field in the speedbar
+ And I press "Replace" in the speedbar
+ Then the contents should be "Foo\nBar RAB Rab\nBaz"
+ And the selected text should be "RAB"
+ And the selection range should be from 8 to 11
+
+ Scenario: Replace next occurrence on the same line twice
+ When I replace the contents with "Foo\nBar Rab Rab\nBaz"
+ And I move the cursor to 4
+ And I run the command DocumentSearch::SearchAndReplaceCommand
+ And I type "Rab" into the "Search" field in the speedbar
+ And I type "RAB" into the "Replace" field in the speedbar
+ And I press "Replace" in the speedbar
+ And I press "Replace" in the speedbar
+ Then the contents should be "Foo\nBar RAB RAB\nBaz"
+ And the selected text should be "RAB"
+ And the selection range should be from 12 to 15
+
+ Scenario: Replace next occurrence
+ When I replace the contents with "Foo\nBar\nBaz\nBar\nQux"
+ And I move the cursor to 0
+ And I run the command DocumentSearch::SearchAndReplaceCommand
+ And I type "Bar" into the "Search" field in the speedbar
+ And I type "Rab" into the "Replace" field in the speedbar
+ And I press "Replace" in the speedbar
+ Then the contents should be "Foo\nRab\nBaz\nBar\nQux"
+ And the selected text should be "Rab"
+ And the selection should be on line 1
+
+ Scenario: Replace next occurrence twice
+ When I replace the contents with "Foo\nBar\nBaz\nBar\nQux"
+ And I move the cursor to 0
+ And I run the command DocumentSearch::SearchAndReplaceCommand
+ And I type "Bar" into the "Search" field in the speedbar
+ And I type "Rab" into the "Replace" field in the speedbar
+ And I press "Replace" in the speedbar
+ Then the contents should be "Foo\nRab\nBaz\nBar\nQux"
+ When I press "Replace" in the speedbar
+ Then the contents should be "Foo\nRab\nBaz\nRab\nQux"
+ And the selected text should be "Rab"
+ And the selection should be on line 3
+
+ Scenario: Replace next occurrence wraps
+ When I replace the contents with "Foo\nBar\nBaz"
+ And I move the cursor to 8
+ And I run the command DocumentSearch::SearchAndReplaceCommand
+ And I type "Bar" into the "Search" field in the speedbar
+ And I type "Rab" into the "Replace" field in the speedbar
+ When I press "Replace" in the speedbar
+ Then the contents should be "Foo\nRab\nBaz"
+ And the selected text should be "Rab"
+
+ Scenario: Replace all replaces one
+ When I replace the contents with "Foo\nBar\nBaz"
+ And I move the cursor to 0
+ And I run the command DocumentSearch::SearchAndReplaceCommand
+ And I type "Bar" into the "Search" field in the speedbar
+ And I type "Rab" into the "Replace" field in the speedbar
+ Then I should see a message box containing "Replaced 1 occurrence"
+ When I press "Replace All" in the speedbar
+ Then the contents should be "Foo\nRab\nBaz"
+ And the selected text should be "Rab"
+ And the selection should be on line 1
+
+ Scenario: Replace all replaces two
+ When I replace the contents with "Foo\nBar\nBaz\nBar\nQux"
+ And I move the cursor to 0
+ And I run the command DocumentSearch::SearchAndReplaceCommand
+ And I type "Bar" into the "Search" field in the speedbar
+ And I type "Rab" into the "Replace" field in the speedbar
+ Then I should see a message box containing "Replaced 2 occurrences"
+ When I press "Replace All" in the speedbar
+ Then the contents should be "Foo\nRab\nBaz\nRab\nQux"
+ And the selected text should be "Rab"
+ And the selection should be on line 3
+
+ Scenario: Replace next occurrence test bug
+ When I replace the contents with "the\n* Speedbars have access to the properties of the widgets in them."
+ And I move the cursor to 0
+ And I run the command DocumentSearch::SearchAndReplaceCommand
+ And I type "the" into the "Search" field in the speedbar
+ And I type "THE" into the "Replace" field in the speedbar
+ And I press "Replace" in the speedbar
+ Then the contents should be "THE\n* Speedbars have access to the properties of the widgets in them."
+ And the selection range should be from 0 to 3
+ And I press "Replace" in the speedbar
+ Then the contents should be "THE\n* Speedbars have access to THE properties of the widgets in them."
+ And the selection range should be from 31 to 34
+ And I press "Replace" in the speedbar
+ Then the contents should be "THE\n* Speedbars have access to THE properties of THE widgets in them."
+ And the selection range should be from 49 to 52
+ And I press "Replace" in the speedbar
+ Then the contents should be "THE\n* Speedbars have access to THE properties of THE widgets in THEm."
+ And the selection range should be from 64 to 67
+
+
View
21 plugins/document_search/lib/document_search.rb
@@ -1,6 +1,18 @@
+require "document_search/search"
+require "document_search/replace"
+require "document_search/search_and_replace"
module DocumentSearch
-
+ def self.menus
+ Redcar::Menu::Builder.build do
+ sub_menu "Edit" do
+ item "Regex Search", SearchForwardCommand
+ item "Repeat Last Search", RepeatPreviousSearchForwardCommand
+ item "Search and Replace", SearchAndReplaceCommand
+ end
+ end
+ end
+
class SearchSpeedbar < Redcar::Speedbar
class << self
attr_accessor :previous_query
@@ -63,6 +75,13 @@ def execute
end
end
+ class SearchAndReplaceCommand < Redcar::EditTabCommand
+ def execute
+ @speedbar = SearchAndReplaceSpeedbar.new
+ win.open_speedbar(@speedbar)
+ end
+ end
+
class FindNextRegex < Redcar::EditTabCommand
def initialize(re, wrap=nil)
@re = re
View
81 plugins/document_search/lib/document_search/replace.rb
@@ -0,0 +1,81 @@
+module DocumentSearch
+ class Replace
+ def initialize(doc)
+ @doc = doc
+ end
+
+ def replace_next(query, replace, &body)
+ # Get the current line and then get the line segment from the cursor to the end of the line
+ curr_line = @doc.get_line(@doc.cursor_line)
+ cursor_line_offset = @doc.cursor_offset - @doc.offset_at_line(@doc.cursor_line)
+ line_seg = curr_line[cursor_line_offset..-1]
+
+ # Call the search method passed by the caller
+ new_line, startoff, endoff = body.call(line_seg, query, replace)
+
+ # The passed in method returns the string replacement or nil
+ if new_line
+ # Add the replacment to the end of the line, and then replace in the document
+ curr_line[cursor_line_offset..-1] = new_line
+ @doc.replace_line(@doc.cursor_line, curr_line.chomp)
+ line_offset = @doc.offset_at_line(@doc.cursor_line)
+ @doc.set_selection_range(cursor_line_offset + line_offset + startoff, cursor_line_offset + line_offset + endoff)
+ return 1
+ end
+
+ #Look at the rest of the lines starting at the next line
+ start_line = @doc.cursor_line
+ (start_line+1..@doc.line_count-1).each do |i|
+ new_line, startoff, endoff = body.call(@doc.get_line(i), query, replace)
+ if new_line
+ @doc.replace_line(i, new_line.chomp)
+ line_offset = @doc.offset_at_line(i)
+ @doc.set_selection_range(line_offset + startoff, line_offset + endoff)
+ @doc.ensure_visible(@doc.offset_at_line(i))
+ return 1
+ end
+ end
+
+ #Look at the rest of the lines starting at the beginning
+ start_line = @doc.cursor_line
+ (0..start_line-1).each do |i|
+ new_line, startoff, endoff = body.call(@doc.get_line(i), query, replace)
+
+ if new_line
+ @doc.replace_line(i, new_line.chomp)
+ line_offset = @doc.offset_at_line(i)
+ @doc.set_selection_range(line_offset + startoff, line_offset + endoff)
+ @doc.ensure_visible(@doc.offset_at_line(i))
+ return 1
+ end
+ end
+ 0
+ end
+
+ # Replace All starts at the begnning of the doc and iterates over all of the lines.
+ def replace_all(query, replace, &body)
+ count = 0
+ last_match_line = nil
+ startoff = nil
+ endoff = nil
+ (0..(@doc.line_count-1)).each do |i|
+ begin
+ line, a, b = body.call(@doc.get_line(i), query, replace)
+ if line
+ startoff = a
+ endoff = b
+ last_match_line = i
+ @doc.replace_line(i, line.chomp)
+ count += 1
+ end
+ end while line != nil
+ end
+ if last_match_line
+ line_offset = @doc.offset_at_line(last_match_line)
+ @doc.set_selection_range(line_offset + startoff, line_offset + endoff)
+ @doc.ensure_visible(@doc.offset_at_line(last_match_line))
+ end
+ count
+ end
+ end
+end
View
10 plugins/search_and_replace/lib/search.rb → ...ment_search/lib/document_search/search.rb
@@ -1,12 +1,12 @@
-module Redcar
+module DocumentSearch
class Search
# An instance of a search type method: Regular expression
def self.regex_search_method(line, query, replace)
- if line =~ /#{query}/o
+ if line =~ /#{query}/
startoff = $`.length
- endoff = (startoff + $&.length) -1
+ endoff = (startoff + $&.length) - 1
line[startoff..endoff] = replace
- return line
+ return line, startoff, startoff + replace.length
end
return nil
end
@@ -18,7 +18,7 @@ def self.plain_search_method(line, query, replace)
startoff = i
endoff = i + query.length - 1
line[startoff..endoff] = replace
- return line
+ return line, startoff, startoff + replace.length
end
return nil
end
View
84 plugins/document_search/lib/document_search/search_and_replace.rb
@@ -0,0 +1,84 @@
+
+module DocumentSearch
+ class SearchAndReplaceSpeedbar < Redcar::Speedbar
+ class << self
+ attr_accessor :previous_query
+ attr_accessor :previous_replace
+ attr_accessor :previous_search_type
+ end
+
+ def after_draw
+ self.query.value = SearchAndReplaceSpeedbar.previous_query || ""
+ self.replace.value = SearchAndReplaceSpeedbar.previous_replace || ""
+ self.search_type.value = SearchAndReplaceSpeedbar.previous_search_type
+ self.query.edit_view.document.select_all
+ end
+
+ label :label_search, "Search:"
+ textbox :query
+
+ label :label_replace, "Replace:"
+ textbox :replace
+
+ combo :search_type, ["Regex", "Plain", "Glob"], "RegEx" do |v|
+ SearchAndReplaceSpeedbar.previous_search_type = v
+ end
+
+ button :single_replace, "Replace", "Return" do
+ SearchAndReplaceSpeedbar.previous_query = query.value
+ SearchAndReplaceSpeedbar.previous_replace = replace.value
+ SearchAndReplaceSpeedbar.previous_search_type = search_type.value || "Regex" # Hack to work around fact that default value not being picked up
+ success = SearchAndReplaceSpeedbar.search_replace
+ end
+
+ button :all_replace, "Replace All", nil do
+ SearchAndReplaceSpeedbar.previous_query = query.value
+ SearchAndReplaceSpeedbar.previous_replace = replace.value
+ SearchAndReplaceSpeedbar.previous_search_type = search_type.value || "Regex" # Hack to work around fact that default value not being picked up
+ success = SearchAndReplaceSpeedbar.search_replace_all
+ end
+
+ def self.search_replace
+ current_query = @previous_query
+ current_replace = @previous_replace
+ case @previous_search_type
+ when "Regex"
+ search_method = Search.method(:regex_search_method)
+ when "Plain"
+ search_method = Search.method(:plain_search_method)
+ when "Glob"
+ search_method = Search.method(:glob_search_method)
+ else
+ search_method = Search.method(:regex_search_method)
+ end
+ adoc = Redcar.app.focussed_notebook_tab.document
+ count = Replace.new(adoc).replace_next(current_query, current_replace, &search_method)
+ if count == 0
+ Redcar::Application::Dialog.message_box("No instance of the search string were found", {:type => :info, :buttons => :ok})
+ end
+ end
+
+ def self.search_replace_all
+ current_query = @previous_query
+ current_replace = @previous_replace
+ case @previous_search_type
+ when "Regex"
+ search_method = Search.method(:regex_search_method)
+ when "Plain"
+ search_method = Search.method(:plain_search_method)
+ when "Glob"
+ search_method = Search.method(:glob_search_method)
+ else
+ search_method = Search.method(:regex_search_method)
+ end
+ adoc = Redcar.app.focussed_notebook_tab.document
+ count = Replace.new(adoc).replace_all(current_query, current_replace, &search_method)
+ if count == 0 or count > 1
+ message = "Replaced #{count} occurrences"
+ else
+ message = "Replaced #{count} occurrence"
+ end
+ Redcar::Application::Dialog.message_box(message, {:type => :info, :buttons => :ok})
+ end
+ end
+end
View
1  plugins/edit_view/features/step_definitions/editing_steps.rb
@@ -127,7 +127,6 @@ def unescape_text(text)
Then /^the selection range should be from (\d+) to (\d+)$/ do |from_str, to_str|
doc = Redcar::EditView.focussed_edit_view_document
- doc.block_selection_mode = true
r = doc.selection_range
r.begin.should == from_str.to_i
r.end.should == to_str.to_i
View
13 plugins/plugin_manager_ui/lib/plugin_manager_ui.rb
@@ -7,6 +7,19 @@ class << self
attr_accessor :last_reloaded
end
+ def self.menus
+ Menu::Builder.build do
+ sub_menu "Plugins", :priority => 40 do
+ group(:priority => :first) {
+ item "Plugin Manager", PluginManagerUi::OpenCommand
+ item "Reload Again", PluginManagerUi::ReloadLastReloadedCommand
+ item("Edit Preferences") { Project::Manager.open_project_for_path(Redcar::Plugin::Storage.storage_dir) }
+ separator
+ }
+ end
+ end
+ end
+
class ReloadLastReloadedCommand < Redcar::Command
def execute
View
5 plugins/plugin_manager_ui/plugin.rb
@@ -7,6 +7,7 @@
file "lib", "plugin_manager_ui"
dependencies "core", ">0",
- "HTML View", ">=0.3.2"
+ "HTML View", ">=0.3.2",
+ "application", ">=1.1"
-end
+end
View
6 plugins/project/lib/project.rb
@@ -142,9 +142,11 @@ def gained_focus
end
def config_dir
- File.join(path, ".redcar")
+ dir = File.join(path, ".redcar")
+ FileUtils.mkdir_p(dir)
+ dir
end
-
+
def home_dir
@path
end
View
40 plugins/project/lib/project/commands.rb
@@ -61,43 +61,33 @@ class OpenRemoteSpeedbar < Redcar::Speedbar
class << self
attr_accessor :connection
- def storage
- Redcar::Plugin::Storage.new('user_connections') || {}
- end
-
def connections
- connections = storage[:connections]
+ ConnectionManager::ConnectionStore.new.connections
end
def connection_names
if connections && connections.any?
- ['Select...', connections.map { |c| c[:name] }].flatten
- else
- # TODO
- ['Add a new connection...']
+ ['Select...', connections.map { |c| c.name }].flatten
end
end
-
- def last_selected
- storage[:last_selected] || 'Selected...'
- end
+ end
+
+ def initialize
+ connection.items = self.class.connection_names
end
label :connection_label, 'Connect to:'
- combo :connection, connection_names, last_selected
+ combo :connection
button :connect, "Connect", "Return" do
- selected = self.class.connections.find { |c| c[:name] == connection.value }
-
- self.class.storage[:last_selected] = connection.value
- self.class.storage.save
+ selected = self.class.connections.find { |c| c.name == connection.value }
Manager.connect_to_remote(
selected[:protocol],
selected[:host],
selected[:user],
selected[:path],
- PrivateKeyStore.paths
+ ConnectionManager::PrivateKeyStore.paths
)
end
@@ -108,12 +98,7 @@ def last_selected
button :manage, "Connections Manager", "Ctrl+M" do
Redcar.app.focussed_window.close_speedbar
- Redcar::ConnectionsManager::OpenCommand.new.run
- end
-
- def after_draw
- connection.items = self.class.connection_names
- connection.value = self.class.last_selected
+ Redcar::ConnectionManager::OpenCommand.new.run
end
end
@@ -134,9 +119,6 @@ class << self
label :user_label, "User:"
textbox :user
- label :password_label, "Password:"
- textbox :password
-
label :path_label, "Path:"
textbox :path
@@ -146,7 +128,7 @@ class << self
host.value,
user.value,
path.value,
- PrivateKeyStore.paths
+ ConnectionManager::PrivateKeyStore.paths
)
end
end
View
12 plugins/project/lib/project/dir_controller.rb
@@ -93,7 +93,17 @@ def right_click(tree, node)
menu = Menu.new
Redcar.plugin_manager.objects_implementing(:project_context_menus).each do |object|
- menu.merge(object.project_context_menus(tree, node, controller))
+ # a lot of plugins will only really care about the node that was clicked
+ case object.method(:project_context_menus).arity
+ when 1
+ menu.merge(object.project_context_menus(node))
+ when 2
+ menu.merge(object.project_context_menus(tree, node))
+ when 3
+ menu.merge(object.project_context_menus(tree, node, controller))
+ else
+ puts("Invalid project_context_menus hook detected in "+object.class.name)
+ end
end
Application::Dialog.popup_menu(menu, :pointer)
View
33 plugins/project/lib/project/manager.rb
@@ -27,7 +27,7 @@ def self.connect_to_remote(protocol, host, user, path, private_key_files = [])
end
def self.get_password
- result = Redcar::Application::Dialog.input("Password", "Enter password")
+ result = Redcar::Application::Dialog.password_input("Remote Connection", "Enter password")
result[:value] if result
end
@@ -280,6 +280,37 @@ def self.refresh_modified_file(path)
end
end
+ def self.menus
+ Menu::Builder.build do
+ sub_menu "File", :priority => :first do
+ group(:priority => 0) {
+ item "Open", Project::FileOpenCommand
+ item "Reload File", Project::FileReloadCommand
+ item "Open Directory", Project::DirectoryOpenCommand
+ item "Open Remote...", Project::OpenRemoteCommand
+ lazy_sub_menu "Open Recent" do
+ Project::RecentDirectories.generate_menu(self)
+ end
+
+ separator
+ item "Save", Project::FileSaveCommand
+ item "Save As", Project::FileSaveAsCommand
+ }
+
+ group(:priority => 11) {
+ item "Close Directory", Project::DirectoryCloseCommand
+ item "Reveal in Project", Project::RevealInProjectCommand
+ }
+ end
+ sub_menu "Project", :priority => 15 do
+ group(:priority => :first) {
+ item "Find File", Project::FindFileCommand
+ item "Refresh Directory", Project::RefreshDirectoryCommand
+ }
+ end
+ end
+ end
+
# Uses our own context menu hook to provide context menu entries
# @return [Menu]
def self.project_context_menus(tree, node, controller)
View
6 plugins/project/plugin.rb
@@ -5,5 +5,7 @@
file "lib", "project"
object "Redcar::Project::Manager"
dependencies "edit_view", ">0",
- "HTML View", ">0"
-end
+ "HTML View", ">0",
+ "connection_manager", ">0",
+ "application", ">=1.1"
+end
View
4 plugins/project/spec/project/adapters/remote_protocols/ftp_spec.rb
@@ -4,7 +4,7 @@ class Redcar::Project
describe Adapters::RemoteProtocols::FTP do
let(:conn) { double('connection') }
subject do
- Adapters::RemoteProtocols::FTP.new('server', 'user', 'secret', '/creation')
+ Adapters::RemoteProtocols::FTP.new('server', 'user', 'secret', nil, '/creation')
end
before(:each) do
@@ -20,7 +20,7 @@ class Redcar::Project
describe 'methods' do
subject do
- Adapters::RemoteProtocols::FTP.new('server', 'user', 'secret', '/creation').tap do |ftp|
+ Adapters::RemoteProtocols::FTP.new('server', 'user', 'secret', nil, '/creation').tap do |ftp|
ftp.stub!(:connection).and_return(conn)
end
end
View
6 plugins/project/spec/project/adapters/remote_protocols/sftp_spec.rb
@@ -4,7 +4,7 @@ class Redcar::Project
describe Adapters::RemoteProtocols::SFTP do
let(:conn) { double('connection').as_null_object }
subject do
- Adapters::RemoteProtocols::SFTP.new('server', 'user', 'secret', '/home/fcoury')
+ Adapters::RemoteProtocols::SFTP.new('server', 'user', 'secret', nil, '/home/fcoury')
end
before(:each) do
@@ -69,7 +69,7 @@ class Redcar::Project
let(:sftp) { double('sftp connection').as_null_object }
subject do
- Adapters::RemoteProtocols::SFTP.new('server', 'user', 'secret', '/home/fcoury').tap do |protocol|
+ Adapters::RemoteProtocols::SFTP.new('server', 'user', 'secret', nil, '/home/fcoury').tap do |protocol|
conn.stub!(:sftp).and_return(sftp)
protocol.stub!(:connection).and_return(conn)
end
@@ -103,7 +103,7 @@ class Redcar::Project
let(:sftp) { double('sftp connection').as_null_object }
subject do
- Adapters::RemoteProtocols::SFTP.new('server', 'user', 'secret', '/home/fcoury').tap do |protocol|
+ Adapters::RemoteProtocols::SFTP.new('server', 'user', 'secret', nil, '/home/fcoury').tap do |protocol|
conn.stub!(:sftp).and_return(sftp)
protocol.stub!(:connection).and_return(conn)
end
View
3  plugins/project/spec/project/file_list_spec.rb
@@ -14,7 +14,7 @@ def relative_path(*path)
before do
@file_list = FileList.new(fixture_path)
- FileUtils.rm_f(relative_path("tags"))
+ FileUtils.rm_f(relative_path(".redcar"))
end
it "should return an empty list initially" do
@@ -29,7 +29,6 @@ def relative_path(*path)
it "should return a list of files in the directory" do
@file_list.all_files.include?(relative_path("README")).should be_true
@file_list.all_files.include?(relative_path("lib", "foo_lib.rb")).should be_true
- @file_list.all_files.length.should == 3
end
end
View
2  plugins/redcar/plugin.rb
@@ -5,7 +5,7 @@
file "redcar"
object "Redcar::Top"
dependencies "core", ">0", # includes Storage
- "application", ">0",
+ "application", ">=1.1",
"project", ">0",
"Auto Completer", ">0",
"auto_indenter", ">0",
View
83 plugins/redcar/redcar.rb
@@ -718,7 +718,8 @@ def self.keymaps
link "Cmd+Shift+I", AutoIndenter::IndentCommand
link "Cmd+L", GotoLineCommand
link "Cmd+F", DocumentSearch::SearchForwardCommand
- link "Cmd+Shift+F", DocumentSearch::RepeatPreviousSearchForwardCommand
+ link "Cmd+Shift+F", DocumentSearch::RepeatPreviousSearchForwardCommand
+ link "Cmd+Ctrl+F", DocumentSearch::SearchAndReplaceCommand
link "Cmd+A", SelectAllCommand
link "Ctrl+W", SelectWordCommand
link "Cmd+B", ToggleBlockSelectionCommand
@@ -816,30 +817,25 @@ def self.keymaps
def self.menus
Menu::Builder.build do
- sub_menu "File" do
- item "New", NewCommand
- item "New Window", NewWindowCommand
- item "Open", Project::FileOpenCommand
- item "Reload File", Project::FileReloadCommand
- item "Open Directory", Project::DirectoryOpenCommand
- item "Open Remote...", Project::OpenRemoteCommand
- lazy_sub_menu "Open Recent" do
- Project::RecentDirectories.generate_menu(self)
- end
+ sub_menu "File", :priority => :first do
+ group(:priority => :first) {
+ item "New", NewCommand
+ item "New Window", NewWindowCommand
+ }
- separator
- item "Save", Project::FileSaveCommand
- item "Save As", Project::FileSaveAsCommand
- separator
- item "Close Tab", CloseTabCommand
- item "Close Tree", CloseTreeCommand
- item "Close Window", CloseWindowCommand
- item "Close Directory", Project::DirectoryCloseCommand
- item "Reveal in Project", Project::RevealInProjectCommand
- separator
- item "Quit", QuitCommand
+ group(:priority => 10) {
+ separator
+ item "Close Tab", CloseTabCommand
+ item "Close Tree", CloseTreeCommand
+ item "Close Window", CloseWindowCommand
+ }
+
+ group(:priority => :last) {
+ separator
+ item "Quit", QuitCommand
+ }
end
- sub_menu "Edit" do
+ sub_menu "Edit", :priority => 5 do
item "Tab Info", EditView::InfoSpeedbarCommand
separator
item "Undo", UndoCommand
@@ -860,8 +856,6 @@ def self.menus
item "Indent", AutoIndenter::IndentCommand
separator
item "Goto Line", GotoLineCommand
- item "Regex Search", DocumentSearch::SearchForwardCommand
- item "Repeat Last Search", DocumentSearch::RepeatPreviousSearchForwardCommand
separator
sub_menu "Select" do
item "All", SelectAllCommand
@@ -872,20 +866,13 @@ def self.menus
item "Auto Complete", AutoCompleter::AutoCompleteCommand
item "Menu Auto Complete", AutoCompleter::MenuAutoCompleterCommand
end
- sub_menu "Project" do
- item "Find File", Project::FindFileCommand
- item "Refresh Directory", Project::RefreshDirectoryCommand
- separator
- item "Runnables", Runnables::ShowRunnables
- item "Run Tab", Runnables::RunEditTabCommand
- end
- sub_menu "Debug" do
+ sub_menu "Debug", :priority => 20 do
item "Task Manager", TaskManager::OpenCommand
separator
#item "Print Scope Tree", PrintScopeTreeCommand
item "Print Scope at Cursor", PrintScopeCommand
end
- sub_menu "View" do
+ sub_menu "View", :priority => 30 do
sub_menu "Appearance" do
item "Font", SelectNewFont
item "Font Size", SelectFontSize
@@ -912,21 +899,21 @@ def self.menus
item "Toggle Line Numbers", ToggleLineNumbers
item "Toggle Annotations", ToggleAnnotations
end
- sub_menu "Plugins" do
- item "Plugin Manager", PluginManagerUi::OpenCommand
- item "Reload Again", PluginManagerUi::ReloadLastReloadedCommand
- item("Edit Preferences") { Project::Manager.open_project_for_path(Redcar::Plugin::Storage.storage_dir) }
- separator
- end
- sub_menu "Bundles" do
- item "Find Snippet", Snippets::OpenSnippetExplorer
- item "Installed Bundles", Textmate::InstalledBundles
- separator
- Textmate.attach_menus(self)
+ sub_menu "Bundles", :priority => 45 do
+ group(:priority => :first) {
+ item "Find Snippet", Snippets::OpenSnippetExplorer
+ item "Installed Bundles", Textmate::InstalledBundles
+ }
+ group(:priority => 15) {
+ separator
+ Textmate.attach_menus(self)
+ }
end
- sub_menu "Help" do
- item "About", AboutCommand
- item "New In This Version", ChangelogCommand
+ sub_menu "Help", :priority => :last do
+ group(:priority => :first) {
+ item "About", AboutCommand
+ item "New In This Version", ChangelogCommand
+ }
end
end
end
View
12 plugins/runnables/lib/runnables.rb
@@ -24,6 +24,18 @@ def self.run_process(path, command, title, output)
end
end
+ def self.menus
+ Menu::Builder.build do
+ sub_menu "Project", :priority => 15 do
+ group(:priority => 15) {
+ separator
+ item "Runnables", Runnables::ShowRunnables
+ item "Run Tab", Runnables::RunEditTabCommand
+ }
+ end
+ end
+ end
+
class TreeMirror
include Redcar::Tree::Mirror
View
2  plugins/runnables/plugin.rb
@@ -5,6 +5,6 @@
file "lib", "runnables"
object "Redcar::Runnables"
dependencies "tree", ">0",
- "application", ">0",
+ "application", ">=1.1",
"HTML View", ">0"
end
View
41 plugins/search_and_replace/Readme.md
@@ -1,41 +0,0 @@
-Readme
-===
-
-The Search and Replace plugin provides search and replace capablites to Redcar.
-To use the Search and replace plugin select Search and Repleace from the Edit menu.
-
-Installation Instructions
----
-1. Clone the repoistory using git into the ~/.redcar/plugins directory
-1. Start Redcar
-
-Usage Instructions
----
-The Search and Replace speedbar can be accessed by selecting Search and Replace from
-the Edit menu. Once selected a new speedbar should be displayed.
-
-
-Currently implemented
----
-1. Command class and menu entry
-1. Implement search and replace - replaces first one without prompt
-1. Implement search and replace all - even eiaser then single
-1. Make undoable - provided by Redcar itself, nothing to implement.
-1. Prettfy UI - got rid of the clunky dialog box
-1. Provide options to select the type of search (regex, glob, plain)
-1. Refactor code - broke code up by functional concern
-1. Use the same search methodlogy as Search - Search current line, rest of lines, and then from start of file.
-
-Todo List
----
-1. Store last n search and replace results in memory
-1. Optionally store the search and replace results in configuration file.
-1. Pre-populate seach box with selected text
-1. Adding a shortcut keystroke.
-1. Better error handling
-1. Advanced Search and Replace - Across all open files or across all files in a project
-1. RSpec Tests
-1. Regex handling for replace (groups, etc..)
-1. Fix same line bug - doesn't go back and seach to left of cursor.
-
-Comments or suggestions wcherry69@gmail.com
View
68 plugins/search_and_replace/lib/replace.rb
@@ -1,68 +0,0 @@
-module Redcar
- class Replace
- def initialize(doc)
- @doc = doc
- end
-
- def replace_next(query, replace, &body)
- # Get the current line and then get the line segment from the cursor to the end of the line
- curr_line = @doc.get_line(@doc.cursor_line)
- cursor_line_offset = @doc.cursor_offset - @doc.offset_at_line(@doc.cursor_line)
- line_seg = curr_line[cursor_line_offset..-1]
-
- # Call the search method passed by the caller
- new_line = body.call(line_seg, query, replace)
-
- # The passed in method returns the string replacement or nil
- if new_line
- # Add the replacment to the end of the line, and then replace in the document
- curr_line[cursor_line_offset..-1] = new_line
- @doc.replace_line(@doc.cursor_line, curr_line.chomp)
- return 1
- end
-
- #Look at the rest of the lines starting at the next line
- start_line = @doc.cursor_line
- (start_line+1..@doc.line_count-1).each do |i|
- new_line = body.call(@doc.get_line(i), query, replace)
-
- if new_line
- @doc.replace_line(i, new_line.chomp)
- @doc.ensure_visible(@doc.offset_at_line(i))
- return 1
- end
- end
-
- #Look at the rest of the lines starting at the beginning
- start_line = @doc.cursor_line
- (0..start_line-1).each do |i|
- new_line = body.call(@doc.get_line(i), query, replace)
-
- if new_line
- @doc.replace_line(i, new_line.chomp)
- @doc.ensure_visible(@doc.offset_at_line(i))
- return 1
- end
- end
- puts "Not found"
- return 0
- end
-
- # Replace All starts at the begnning of the doc and iterates over all of the lines.
- def replace_all(query, replace, &body)
- count = 0
- (0..@doc.line_count-1).each do |i|
- begin
- line = body.call(@doc.get_line(i), query, replace)
-
- if line
- @doc.replace_line(i, line.chomp)
- count+=1
- end
- end while line != nil
- end
- puts count
- return count
- end
- end
-end
View
112 plugins/search_and_replace/lib/search_and_replace.rb
@@ -1,112 +0,0 @@
-require "search"
-require "replace"
-
-module Redcar
- # This class implements the search-and-replace command
- class SearchAndReplace
- # Create the search and replace menu item
- def self.menus
- # Here's how the plugin menus are drawn. Try adding more
- # items or sub_menus.
- Menu::Builder.build do
- sub_menu "Edit" do
- item "Search and Replace", SearchAndReplaceCommand
- end
- end
- end
-
- # Search-and-Replace command.
- class SearchAndReplaceCommand < Redcar::EditTabCommand
- # The execution reuses the same dialog.
- def execute
- @speedbar = SearchAndReplaceSpeedbar.new
- win.open_speedbar(@speedbar)
- end
-
- class SearchAndReplaceSpeedbar < Redcar::Speedbar
- class << self
- attr_accessor :previous_query
- attr_accessor :previous_replace
- attr_accessor :previous_search_type
-# attr_accessor :previous_match_case
- end
-
- def after_draw
- self.query.value = SearchAndReplaceSpeedbar.previous_query || ""
- self.replace.value = SearchAndReplaceSpeedbar.previous_replace || ""
- self.search_type.value = SearchAndReplaceSpeedbar.previous_search_type
- # self.match_case.value = SearchAndReplaceSpeedbar.previous_match_case
- self.query.edit_view.document.select_all
- end
-
- label :label_search, "Search:"
- textbox :query
-
- label :label_replace, "Replace:"
- textbox :replace
-
- combo :search_type, ["Regex", "Plain", "Glob"], "RegEx" do |v|
- SearchAndReplaceSpeedbar.previous_search_type = v
- end
-
- #toggle :match_case, 'Match case', nil, false do |v|
- # SearchAndReplaceSpeedbar.previous_match_case = v
- #end
-
- button :single_replace, "Replace", "Return" do
- SearchAndReplaceSpeedbar.previous_query = query.value
- SearchAndReplaceSpeedbar.previous_replace = replace.value
- #SearchAndReplaceSpeedbar.previous_match_case = match_case.value
- SearchAndReplaceSpeedbar.previous_search_type = search_type.value || "Regex" # Hack to work around fact that default value not being picked up
- success = SearchAndReplaceSpeedbar.search_replace
- end
-
- button :all_replace, "Replace All", "Return" do
- SearchAndReplaceSpeedbar.previous_query = query.value
- SearchAndReplaceSpeedbar.previous_replace = replace.value
- #SearchAndReplaceSpeedbar.previous_match_case = match_case.value
- SearchAndReplaceSpeedbar.previous_search_type = search_type.value || "Regex" # Hack to work around fact that default value not being picked up
- success = SearchAndReplaceSpeedbar.search_replace_all
- end
-
- def self.search_replace
- puts "query = '#{@previous_query}', replace = '#{@previous_replace}', search_type = '#{@previous_search_type}', match_case = '#{@previous_match_case}' "
- current_query = @previous_query
- current_replace = @previous_replace
- case @previous_search_type
- when "Regex"
- search_method = Search.method(:regex_search_method)
- when "Plain"
- search_method = Search.method(:plain_search_method)
- when "Glob"
- search_method = Search.method(:glob_search_method)
- else
- search_method = Search.method(:regex_search_method)
- end
- adoc = Redcar::app.focussed_notebook_tab.document
- count = Replace.new(adoc).replace_next(current_query, current_replace, &search_method)
- if count == 0 then Application::Dialog.message_box("No instance of the search string were found", {:type => :info, :buttons => :ok}) end
- end
-
- def self.search_replace_all
- puts "query = '#{@previous_query}', replace = '#{@previous_replace}', search_type = '#{@previous_search_type}', match_case = '#{@previous_match_case}' "
- current_query = @previous_query
- current_replace = @previous_replace
- case @previous_search_type
- when "Regex"
- search_method = Search.method(:regex_search_method)
- when "Plain"
- search_method = Search.method(:plain_search_method)
- when "Glob"
- search_method = Search.method(:glob_search_method)
- else
- search_method = Search.method(:regex_search_method)
- end
- adoc = Redcar::app.focussed_notebook_tab.document
- count = Replace.new(adoc).replace_all(current_query, current_replace, &search_method)
- Application::Dialog.message_box("Replaced #{count} occurance(s)", {:type => :info, :buttons => :ok})
- end
- end
- end
- end
-end
View
7 plugins/search_and_replace/plugin.rb
@@ -1,7 +0,0 @@
-Plugin.define do
- name "search_and_replace"
- version "0.1"
- file "lib", "search_and_replace"
- object "Redcar::SearchAndReplace"
- dependencies "redcar", ">0"
-end
View
2  plugins/textmate/lib/textmate.rb
@@ -8,7 +8,7 @@
module Redcar
module Textmate
def self.all_bundle_paths
- Dir[File.join(Redcar.root, "textmate", "Bundles", "*")]
+ Dir[File.join(Redcar.root, "plugins", "textmate", "vendor", "redcar-bundles", "Bundles", "*")]
end
def self.uuid_hash
2  plugins/textmate/vendor/redcar-bundles
@@ -1 +1 @@
-Subproject commit c11e64a32bfb8dad8ee5cc9c131fa7b609d1ebfa
+Subproject commit 6d5ab75f21549c0629c2b6d5d8ced362cddf4903
View
9 plugins/view_shortcuts/lib/view_shortcuts.rb
@@ -28,6 +28,15 @@ def title
"Shortcuts"
end
+ def clean_name(command)
+ name = command.to_s.sub("Command","")
+ idx = name.rindex("::")
+ unless idx.nil?
+ name = name[idx+2,name.length]
+ end
+ name = name.split(/(?=[A-Z])/).map{|w| w}.join(" ").sub("R E P L","REPL")
+ end
+
def index
rhtml = ERB.new(File.read(File.join(File.dirname(__FILE__), "..", "views", "index.html.erb")))
rhtml.result(binding)
View
14 plugins/view_shortcuts/views/index.html.erb
@@ -10,16 +10,10 @@
<th>Shortcut</th>
</tr>
<% Redcar.app.main_keymap.map.each do |key, command| %>
- <% sant = command.to_s.sub("Command","") %>
- <% pls = sant.rindex("::") %>
- <% if !pls.nil? %>
- <% sant = sant[pls+2,sant.length] %>
- <% end %>
- <% sant = sant.split(/(?=[A-Z])/).map{|w| w}.join(" ") %>
- <tr>
- <td><%= sant %></td>
- <td><%= key%></td>
- </tr>
+ <tr>
+ <td><%= clean_name(command) %></td>
+ <td><%= key %></td>
+ </tr>
<% end %>
</table>
</html>
Please sign in to comment.
Something went wrong with that request. Please try again.