Skip to content

Commit

Permalink
Implemented soft tabs for block selection modes
Browse files Browse the repository at this point in the history
  • Loading branch information
danlucraft committed Feb 21, 2010
1 parent 1af7f2b commit 5bdf0c3
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 82 deletions.
1 change: 0 additions & 1 deletion README.md
Expand Up @@ -32,7 +32,6 @@ Usage:
--theme=THEME Choose Textmate theme

## INSTALLING FROM SOURCE

Download from github, checkout the submodules and build JavaMateView. You will need Ant
installed, and RSpec and Cucumber installed as JRuby gems.

Expand Down
52 changes: 1 addition & 51 deletions plugins/edit_view/features/soft_tabs.feature
@@ -1,55 +1,5 @@
Feature: Soft and hard tabs

Scenario: Inserts hard tab at the start of a line
When I open a new edit tab
And tabs are hard
And I press the Tab key in the edit tab
Then the contents of the edit tab should be "\t"

Scenario: Inserts hard tab at the end of a line
When I open a new edit tab
And tabs are hard
And I replace the contents with "Hacker"
And I move the cursor to 6
And I press the Tab key in the edit tab
Then the contents of the edit tab should be "Hacker\t"

Scenario: Inserts 2 space soft tab at the start of a line
When I open a new edit tab
And tabs are soft, 2 spaces
And I press the Tab key in the edit tab
Then the contents of the edit tab should be " "

Scenario: Inserts 2 space soft tab at the end of a line
When I open a new edit tab
And tabs are soft, 2 spaces
And I replace the contents with "Hacker"
And I move the cursor to 6
And I press the Tab key in the edit tab
Then the contents of the edit tab should be "Hacker "

Scenario: Inserts 4 space soft tab at the start of a line
When I open a new edit tab
And tabs are soft, 4 spaces
And I press the Tab key in the edit tab
Then the contents of the edit tab should be " "

Scenario: Inserts 4 space soft tab at the end of a line
When I open a new edit tab
And tabs are soft, 4 spaces
And I replace the contents with "Hacker"
And I move the cursor to 6
And I press the Tab key in the edit tab
Then the contents of the edit tab should be "Hacker "

Scenario: Inserts 4 space soft tab at the end of a line, with a tab character
When I open a new edit tab
And tabs are soft, 4 spaces
And I replace the contents with "\tHacker"
And I move the cursor to 7
And I press the Tab key in the edit tab
Then the contents of the edit tab should be "\tHacker "

Scenario: Move left through soft tabs
When I open a new edit tab
And tabs are soft, 2 spaces
Expand Down Expand Up @@ -290,4 +240,4 @@ Feature: Soft and hard tabs
And I move the cursor to 0
And I press the Delete key in the edit tab
Then the cursor should be at 0


17 changes: 17 additions & 0 deletions plugins/edit_view/features/step_definitions/editing_steps.rb
Expand Up @@ -98,4 +98,21 @@
Redcar::EditView.focussed_edit_view_document.to_s.should == text
end

When /^I block select from (\d+) to (\d+)$/ do |from_str, to_str|
doc = Redcar::EditView.focussed_edit_view_document
doc.block_selection_mode = true
doc.set_selection_range(from_str.to_i, to_str.to_i)
end

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
end





146 changes: 146 additions & 0 deletions plugins/edit_view/features/tabs.feature
@@ -0,0 +1,146 @@
Feature: Insert a tab

Scenario: Inserts hard tab at the start of a line
When I open a new edit tab
And tabs are hard
And I press the Tab key in the edit tab
Then the contents of the edit tab should be "\t"

Scenario: Inserts hard tab at the end of a line
When I open a new edit tab
And tabs are hard
And I replace the contents with "Hacker"
And I move the cursor to 6
And I press the Tab key in the edit tab
Then the contents of the edit tab should be "Hacker\t"

Scenario: Inserts 2 space soft tab at the start of a line
When I open a new edit tab
And tabs are soft, 2 spaces
And I press the Tab key in the edit tab
Then the contents of the edit tab should be " "

Scenario: Inserts 2 space soft tab at the end of a line
When I open a new edit tab
And tabs are soft, 2 spaces
And I replace the contents with "Hacker"
And I move the cursor to 6
And I press the Tab key in the edit tab
Then the contents of the edit tab should be "Hacker "

Scenario: Inserts 4 space soft tab at the start of a line
When I open a new edit tab
And tabs are soft, 4 spaces
And I press the Tab key in the edit tab
Then the contents of the edit tab should be " "

Scenario: Inserts 4 space soft tab at the end of a line
When I open a new edit tab
And tabs are soft, 4 spaces
And I replace the contents with "Hacker"
And I move the cursor to 6
And I press the Tab key in the edit tab
Then the contents of the edit tab should be "Hacker "

Scenario: Inserts soft tabs correctly if there is selected text
When I open a new edit tab
And tabs are soft, 4 spaces
And I replace the contents with "Ha"
And I move the cursor to 0
And I press Shift+Right key in the edit tab
And I press Shift+Right key in the edit tab
And I press the Tab key in the edit tab
Then the contents of the edit tab should be " "

Scenario: Inserts hard tabs correctly if there is selected text
When I open a new edit tab
And tabs are hard
And I replace the contents with "Ha"
And I move the cursor to 0
And I press Shift+Right key in the edit tab
And I press Shift+Right key in the edit tab
And I press the Tab key in the edit tab
Then the contents of the edit tab should be "\t"

Scenario: Inserts soft tabs correctly if there is selected text that covers a tab
When I open a new edit tab
And tabs are soft, 4 spaces
And I replace the contents with "H\t"
And I move the cursor to 0
And I press Shift+Right key in the edit tab
And I press Shift+Right key in the edit tab
And I press the Tab key in the edit tab
Then the contents of the edit tab should be " "

Scenario: Inserts 4 space soft tab at the end of a line, with a tab character
When I open a new edit tab
And tabs are soft, 4 spaces
And I replace the contents with "\tHacker"
And I move the cursor to 7
And I press the Tab key in the edit tab
Then the contents of the edit tab should be "\tHacker "

@block_selection
Scenario: In block selection mode inserts 4 space soft tab on 1 line
When I open a new edit tab
And tabs are soft, 4 spaces
And I replace the contents with "Jim\nHacker"
And I block select from 0 to 0
And I press the Tab key in the edit tab
Then the contents of the edit tab should be " Jim\nHacker"
And the selection range should be from 4 to 4

@block_selection
Scenario: In block selection mode inserts 4 space soft tab on 2 lines
When I open a new edit tab
And tabs are soft, 4 spaces
And I replace the contents with "Jim\nHacker"
And I block select from 0 to 4
And I press the Tab key in the edit tab
Then the contents of the edit tab should be " Jim\n Hacker"
And the selection range should be from 4 to 12

@block_selection
Scenario: In block selection mode inserts 4 space soft tab on 3 lines
When I open a new edit tab
And tabs are soft, 4 spaces
And I replace the contents with "Jim\nHacker\nMP"
And I block select from 0 to 11
And I press the Tab key in the edit tab
Then the contents of the edit tab should be " Jim\n Hacker\n MP"
And the selection range should be from 4 to 23

@block_selection
Scenario: In block selection mode inserts 4 space soft tab overwriting text on 1 line
When I open a new edit tab
And tabs are soft, 4 spaces
And I replace the contents with "Jim\nHacker"
And I block select from 0 to 2
And I press the Tab key in the edit tab
Then the contents of the edit tab should be " m\nHacker"
And the selection range should be from 4 to 4

@block_selection
Scenario: In block selection mode inserts 4 space soft tab overwriting text on 2 lines
When I open a new edit tab
And tabs are soft, 4 spaces
And I replace the contents with "Jim\nHacker"
And I block select from 0 to 6
And I press the Tab key in the edit tab
Then the contents of the edit tab should be " m\n cker"
And the selection range should be from 4 to 10

@block_selection
Scenario: In block selection mode inserts 4 space soft tab overwriting text on 3 lines
When I open a new edit tab
And tabs are soft, 4 spaces
And I replace the contents with "Jim\nHacker\nMP"
And I block select from 0 to 13
And I press the Tab key in the edit tab
Then the contents of the edit tab should be " m\n cker\n "
And the selection range should be from 4 to 19





28 changes: 22 additions & 6 deletions plugins/edit_view/lib/edit_view/actions/tab.rb
Expand Up @@ -7,28 +7,44 @@ def self.handle(edit_view, modifiers)
doc = edit_view.document
if doc.block_selection_mode?
if edit_view.soft_tabs?
line = doc.get_line(doc.cursor_line)
width = edit_view.tab_width
imaginary_cursor_offset = ArrowHandler.real_offset_to_imaginary(line, width, doc.cursor_line_offset)
next_tab_stop_offset = (imaginary_cursor_offset/width + 1)*width
insert_string = " "*(next_tab_stop_offset - imaginary_cursor_offset)
selections = doc.selection_ranges.map do |selection_range|
line = doc.line_at_offset(selection_range.begin)
line_offset = doc.offset_at_line(line)
line_offset_start = selection_range.begin - line_offset
line_offset_end = selection_range.end - line_offset
[line, line_offset_start, line_offset_end]
end
length = 0
selections.each do |line, line_offset_start, line_offset_end|
line_offset = doc.offset_at_line(line)
doc.replace(line_offset + line_offset_start, line_offset_end - line_offset_start, " "*(line_offset_end - line_offset_start))
length = line_offset_end - line_offset_start
end
line = doc.get_line(doc.cursor_line)
width = edit_view.tab_width
imaginary_cursor_offset = ArrowHandler.real_offset_to_imaginary(line, width, doc.cursor_line_offset)
next_tab_stop_offset = (imaginary_cursor_offset/width + 1)*width
insert_string = " "*(next_tab_stop_offset - imaginary_cursor_offset)
selections.each do |line, line_offset_start, line_offset_end|
line_offset = doc.offset_at_line(line)
doc.delete(line_offset + line_offset_start, line_offset_end - line_offset_start)
doc.insert(line_offset + line_offset_start, insert_string)
end
new_selection_ranges = selections.map do |line, line_offset_start, line_offset_end|
offset = doc.offset_at_line(line) + line_offset_end + insert_string.length
[offset, offset]
end
doc.set_selection_range(new_selection_ranges.last.last, new_selection_ranges.first.first)
true
else
false
end
else
if doc.selection?
bits = [doc.cursor_offset, doc.selection_offset].sort
start = bits.first
length = bits.last - bits.first
doc.delete(start, length)
end
if edit_view.soft_tabs?
line = doc.get_line(doc.cursor_line)
width = edit_view.tab_width
Expand Down
46 changes: 23 additions & 23 deletions plugins/edit_view/lib/edit_view/document.rb
Expand Up @@ -115,29 +115,6 @@ def single_line?
controller.single_line?
end

# The line index the cursor is on (zero-based)
#
# @return [Integer]
def cursor_line
line_at_offset(cursor_offset)
end

def cursor_line_start_offset
offset_at_line(cursor_line)
end

def cursor_line_end_offset
offset_at_line_end(cursor_line)
end

def offset_at_line_end(line_ix)
if line_ix == line_count - 1
end_offset = length
else
end_offset = offset_at_line(line_ix + 1)
end
end

# Is there any text selected? (Or equivalently, is the length
# of the selection equal to 0)
#
Expand Down Expand Up @@ -239,6 +216,29 @@ def cursor_offset=(offset)
controller.cursor_offset = offset
end

# The line index the cursor is on (zero-based)
#
# @return [Integer]
def cursor_line
line_at_offset(cursor_offset)
end

def cursor_line_start_offset
offset_at_line(cursor_line)
end

def cursor_line_end_offset
offset_at_line_end(cursor_line)
end

def offset_at_line_end(line_ix)
if line_ix == line_count - 1
end_offset = length
else
end_offset = offset_at_line(line_ix + 1)
end
end

# The range of text selected by the user.
#
# @return [Range<Integer>] a range between two character offsets
Expand Down
14 changes: 13 additions & 1 deletion plugins/edit_view_swt/lib/edit_view_swt/document.rb
Expand Up @@ -91,7 +91,19 @@ def selection_ranges
end

def set_selection_range(cursor_offset, selection_offset)
styledText.set_selection_range(selection_offset, cursor_offset - selection_offset)
if block_selection_mode?
start_offset, end_offset = *[cursor_offset, selection_offset].sort
start_location = styledText.getLocationAtOffset(start_offset)
end_location = styledText.getLocationAtOffset(end_offset)
styledText.set_block_selection_bounds(
start_location.x,
start_location.y,
end_location.x - start_location.x,
end_location.y - start_location.y + styledText.get_line_height
)
else
styledText.set_selection_range(selection_offset, cursor_offset - selection_offset)
end
@model.selection_range_changed(cursor_offset, selection_offset)
end

Expand Down

0 comments on commit 5bdf0c3

Please sign in to comment.