aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/SPTextView.m116
1 files changed, 67 insertions, 49 deletions
diff --git a/Source/SPTextView.m b/Source/SPTextView.m
index a045a4ad..ef649da3 100644
--- a/Source/SPTextView.m
+++ b/Source/SPTextView.m
@@ -1063,9 +1063,6 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
{
NSString *textViewString = [[self textStorage] string];
NSRange currentLineRange;
- NSArray *lineRanges;
- NSString *tabString = @"\t";
- NSUInteger i, indentedLinesLength = 0;
if ([self selectedRange].location == NSNotFound || ![self isEditable]) return NO;
@@ -1076,33 +1073,47 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
currentLineRange = [textViewString lineRangeForRange:[self selectedRange]];
// Register the indent for undo
- [self shouldChangeTextInRange:NSMakeRange(currentLineRange.location, 0) replacementString:tabString];
+ [self shouldChangeTextInRange:NSMakeRange(currentLineRange.location, 0) replacementString:@"\t"];
// Insert the new tab
- [self replaceCharactersInRange:NSMakeRange(currentLineRange.location, 0) withString:tabString];
+ [self replaceCharactersInRange:NSMakeRange(currentLineRange.location, 0) withString:@"\t"];
return YES;
}
- // Otherwise, the selection has a length - get an array of current line ranges for the specified selection
- lineRanges = [textViewString lineRangesForRange:[self selectedRange]];
+ // Otherwise, something is selected
+ NSRange firstLineRange = [textViewString lineRangeForRange:NSMakeRange([self selectedRange].location,0)];
+ NSUInteger lastLineMaxRange = NSMaxRange([textViewString lineRangeForRange:NSMakeRange(NSMaxRange([self selectedRange])-1,0)]);
+
+ // Expand selection for first and last line to begin and end resp. but not the last line ending
+ NSRange blockRange = NSMakeRange(firstLineRange.location, lastLineMaxRange - firstLineRange.location);
+ if([textViewString characterAtIndex:NSMaxRange(blockRange)-1] == '\n' || [textViewString characterAtIndex:NSMaxRange(blockRange)-1] == '\r')
+ blockRange.length--;
+
+ // Replace \n by \n\t of all lines in blockRange
+ NSString *newString;
+ // check for line ending
+ if([textViewString characterAtIndex:NSMaxRange(firstLineRange)-1] == '\r')
+ newString = [[NSString stringWithString:@"\t"] stringByAppendingString:
+ [[textViewString substringWithRange:blockRange]
+ stringByReplacingOccurrencesOfString:@"\r" withString:@"\r\t"]];
+ else
+ newString = [[NSString stringWithString:@"\t"] stringByAppendingString:
+ [[textViewString substringWithRange:blockRange]
+ stringByReplacingOccurrencesOfString:@"\n" withString:@"\n\t"]];
- // Loop through the ranges, storing a count of the overall length.
- for (i = 0; i < [lineRanges count]; i++) {
- currentLineRange = NSRangeFromString([lineRanges objectAtIndex:i]);
- indentedLinesLength += currentLineRange.length + 1;
+ // Register the indent for undo
+ [self shouldChangeTextInRange:blockRange replacementString:newString];
- // Register the indent for undo
- [self shouldChangeTextInRange:NSMakeRange(currentLineRange.location+i, 0) replacementString:tabString];
+ [self replaceCharactersInRange:blockRange withString:newString];
- // Insert the new tab
- [self replaceCharactersInRange:NSMakeRange(currentLineRange.location+i, 0) withString:tabString];
- }
+ [self setSelectedRange:NSMakeRange(blockRange.location, [newString length])];
- // Select the entirety of the new range
- [self setSelectedRange:NSMakeRange(NSRangeFromString([lineRanges objectAtIndex:0]).location, indentedLinesLength)];
+ if(blockRange.length == [newString length])
+ return NO;
+ else
+ return YES;
- return YES;
}
@@ -1116,10 +1127,8 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
{
NSString *textViewString = [[self textStorage] string];
NSRange currentLineRange;
- NSArray *lineRanges;
- NSUInteger i, unindentedLines = 0, unindentedLinesLength = 0;
- if ([self selectedRange].location == NSNotFound) return NO;
+ if ([self selectedRange].location == NSNotFound || ![self isEditable]) return NO;
// Undent the currently selected line if the caret is within a single line
if ([self selectedRange].length == 0) {
@@ -1129,7 +1138,7 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
// Ensure that the line has length and that the first character is a tab
if (currentLineRange.length < 1
- || [textViewString characterAtIndex:currentLineRange.location] != '\t')
+ || ([textViewString characterAtIndex:currentLineRange.location] != '\t' && [textViewString characterAtIndex:currentLineRange.location] != ' '))
return NO;
// Register the undent for undo
@@ -1141,37 +1150,46 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse)
return YES;
}
- // Otherwise, the selection has a length - get an array of current line ranges for the specified selection
- lineRanges = [textViewString lineRangesForRange:[self selectedRange]];
+ // Otherwise, something is selected
+ NSRange firstLineRange = [textViewString lineRangeForRange:NSMakeRange([self selectedRange].location,0)];
+ NSUInteger lastLineMaxRange = NSMaxRange([textViewString lineRangeForRange:NSMakeRange(NSMaxRange([self selectedRange])-1,0)]);
+
+ // Expand selection for first and last line to begin and end resp. but the last line ending
+ NSRange blockRange = NSMakeRange(firstLineRange.location, lastLineMaxRange - firstLineRange.location);
+ if([textViewString characterAtIndex:NSMaxRange(blockRange)-1] == '\n' || [textViewString characterAtIndex:NSMaxRange(blockRange)-1] == '\r')
+ blockRange.length--;
+
+ // Check if blockRange starts with SPACE or TAB
+ // (this also catches the first line of the entire text buffer or
+ // if only one line is selected)
+ NSInteger leading = 0;
+ if([textViewString characterAtIndex:blockRange.location] == ' '
+ || [textViewString characterAtIndex:blockRange.location] == '\t')
+ leading++;
+
+ // Replace \n[ \t] by \n of all lines in blockRange
+ NSString *newString;
+ // check for line ending
+ if([textViewString characterAtIndex:NSMaxRange(firstLineRange)-1] == '\r')
+ newString = [[[textViewString substringWithRange:NSMakeRange(blockRange.location+leading, blockRange.length-leading)]
+ stringByReplacingOccurrencesOfString:@"\r\t" withString:@"\r"]
+ stringByReplacingOccurrencesOfString:@"\r " withString:@"\r"];
+ else
+ newString = [[[textViewString substringWithRange:NSMakeRange(blockRange.location+leading, blockRange.length-leading)]
+ stringByReplacingOccurrencesOfString:@"\n\t" withString:@"\n"]
+ stringByReplacingOccurrencesOfString:@"\n " withString:@"\n"];
- // Loop through the ranges, storing a count of the total lines changed and the new length.
- for (i = 0; i < [lineRanges count]; i++) {
- currentLineRange = NSRangeFromString([lineRanges objectAtIndex:i]);
- unindentedLinesLength += currentLineRange.length;
-
- // Ensure that the line has length and that the first character is a tab
- if (currentLineRange.length < 1
- || [textViewString characterAtIndex:currentLineRange.location-unindentedLines] != '\t')
- continue;
+ // Register the unindent for undo
+ [self shouldChangeTextInRange:blockRange replacementString:newString];
- // Register the undent for undo
- [self shouldChangeTextInRange:NSMakeRange(currentLineRange.location-unindentedLines, 1) replacementString:@""];
+ [self replaceCharactersInRange:blockRange withString:newString];
- // Remove the tab
- [self replaceCharactersInRange:NSMakeRange(currentLineRange.location-unindentedLines, 1) withString:@""];
-
- // As a line has been unindented, modify counts and lengths
- unindentedLines++;
- unindentedLinesLength--;
- }
+ [self setSelectedRange:NSMakeRange(blockRange.location, [newString length])];
- // If a change was made, select the entirety of the new range and return success
- if (unindentedLines) {
- [self setSelectedRange:NSMakeRange(NSRangeFromString([lineRanges objectAtIndex:0]).location, unindentedLinesLength)];
+ if(blockRange.length == [newString length])
+ return NO;
+ else
return YES;
- }
-
- return NO;
}
#pragma mark -