Skip to content
Snippets Groups Projects
Commit 0fc25a4b authored by George Nachman's avatar George Nachman
Browse files

Fix a bug where moving the start/end of the selection back/forward...

Fix a bug where moving the start/end of the selection back/forward (respectively) by one character would select two characters. Refactor the move-endpoint code to make it comprehensible. Issue 4482
parent 41259036
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -3722,296 +3722,343 @@ static double EuclideanDistance(NSPoint p1, NSPoint p2) {
return [self menuAtCoord:VT100GridCoordMake(-1, -1)];
}
 
- (void)moveSelectionEndpoint:(PTYTextViewSelectionEndpoint)endpoint
inDirection:(PTYTextViewSelectionExtensionDirection)direction
by:(PTYTextViewSelectionExtensionUnit)unit {
// Ensure the unit is valid, since it comes from preferences.
BOOL unitRecognized = NO;
- (VT100GridWindowedRange)rangeByMovingStartOfRangeBack:(VT100GridWindowedRange)existingRange
extractor:(iTermTextExtractor *)extractor
unit:(PTYTextViewSelectionExtensionUnit)unit {
VT100GridCoord coordBeforeStart =
[extractor predecessorOfCoordSkippingContiguousNulls:VT100GridWindowedRangeStart(existingRange)];
switch (unit) {
case kPTYTextViewSelectionExtensionUnitCharacter:
case kPTYTextViewSelectionExtensionUnitWord:
case kPTYTextViewSelectionExtensionUnitLine:
case kPTYTextViewSelectionExtensionUnitMark:
unitRecognized = YES;
break;
}
if (!unitRecognized) {
DLog(@"ERROR: Unrecognized unit enumerated value %@, treating as character.", @(unit));
NSLog(@"ERROR: Unrecognized unit enumerated value %@, treating as character.", @(unit));
unit = kPTYTextViewSelectionExtensionUnitCharacter;
case kPTYTextViewSelectionExtensionUnitCharacter: {
VT100GridWindowedRange rangeWithCharacterBeforeStart = existingRange;
rangeWithCharacterBeforeStart.coordRange.start = coordBeforeStart;
return rangeWithCharacterBeforeStart;
}
case kPTYTextViewSelectionExtensionUnitWord: {
VT100GridWindowedRange rangeWithWordBeforeStart =
[extractor rangeForWordAt:coordBeforeStart];
rangeWithWordBeforeStart.coordRange.end = existingRange.coordRange.end;
rangeWithWordBeforeStart.columnWindow = existingRange.columnWindow;
return rangeWithWordBeforeStart;
}
case kPTYTextViewSelectionExtensionUnitLine: {
VT100GridWindowedRange rangeWithLineBeforeStart = existingRange;
if (rangeWithLineBeforeStart.coordRange.start.y > 0) {
if (rangeWithLineBeforeStart.coordRange.start.x > rangeWithLineBeforeStart.columnWindow.location) {
rangeWithLineBeforeStart.coordRange.start.x = rangeWithLineBeforeStart.columnWindow.location;
} else {
rangeWithLineBeforeStart.coordRange.start.y--;
}
}
return rangeWithLineBeforeStart;
}
case kPTYTextViewSelectionExtensionUnitMark: {
VT100GridWindowedRange rangeWithLineBeforeStart = existingRange;
if (rangeWithLineBeforeStart.coordRange.start.y > 0) {
int previousMark = [_dataSource lineNumberOfMarkBeforeLine:existingRange.coordRange.start.y];
if (previousMark != -1) {
rangeWithLineBeforeStart.coordRange.start.y = previousMark + 1;
if (rangeWithLineBeforeStart.coordRange.start.y == existingRange.coordRange.start.y) {
previousMark = [_dataSource lineNumberOfMarkBeforeLine:existingRange.coordRange.start.y - 1];
if (previousMark != -1) {
rangeWithLineBeforeStart.coordRange.start.y = previousMark + 1;
}
}
}
rangeWithLineBeforeStart.coordRange.start.x = existingRange.columnWindow.location;
}
return rangeWithLineBeforeStart;
}
}
assert(false);
}
 
// Cancel a live selection if one is ongoing.
if (_selection.live) {
[_selection endLiveSelection];
- (VT100GridWindowedRange)rangeByMovingStartOfRangeForward:(VT100GridWindowedRange)existingRange
extractor:(iTermTextExtractor *)extractor
unit:(PTYTextViewSelectionExtensionUnit)unit {
VT100GridCoord coordAfterStart =
[extractor successorOfCoordSkippingContiguousNulls:VT100GridWindowedRangeStart(existingRange)];
switch (unit) {
case kPTYTextViewSelectionExtensionUnitCharacter: {
VT100GridWindowedRange rangeExcludingFirstCharacter = existingRange;
rangeExcludingFirstCharacter.coordRange.start = coordAfterStart;
return rangeExcludingFirstCharacter;
}
case kPTYTextViewSelectionExtensionUnitWord: {
VT100GridCoord startCoord = VT100GridWindowedRangeStart(existingRange);
BOOL startWasOnNull = [extractor characterAt:startCoord].code == 0;
VT100GridWindowedRange rangeExcludingWordAtStart = existingRange;
rangeExcludingWordAtStart.coordRange.start =
[extractor rangeForWordAt:startCoord].coordRange.end;
// If the start of range moved from a null to a null, skip to the end of the line or past all the nulls.
if (startWasOnNull &&
[extractor characterAt:rangeExcludingWordAtStart.coordRange.start].code == 0) {
rangeExcludingWordAtStart.coordRange.start =
[extractor successorOfCoordSkippingContiguousNulls:rangeExcludingWordAtStart.coordRange.start];
}
return rangeExcludingWordAtStart;
}
case kPTYTextViewSelectionExtensionUnitLine: {
VT100GridWindowedRange rangeExcludingFirstLine = existingRange;
rangeExcludingFirstLine.coordRange.start.x = existingRange.columnWindow.location;
rangeExcludingFirstLine.coordRange.start.y =
MIN(_dataSource.numberOfLines,
rangeExcludingFirstLine.coordRange.start.y + 1);
return rangeExcludingFirstLine;
}
case kPTYTextViewSelectionExtensionUnitMark: {
VT100GridWindowedRange rangeExcludingFirstLine = existingRange;
rangeExcludingFirstLine.coordRange.start.x = existingRange.columnWindow.location;
int nextMark = [_dataSource lineNumberOfMarkAfterLine:rangeExcludingFirstLine.coordRange.start.y - 1];
if (nextMark != -1) {
rangeExcludingFirstLine.coordRange.start.y =
MIN(_dataSource.numberOfLines, nextMark + 1);
}
return rangeExcludingFirstLine;
}
}
iTermSubSelection *sub = _selection.allSubSelections.lastObject;
iTermTextExtractor *extractor = [iTermTextExtractor textExtractorWithDataSource:_dataSource];
// Create a selection at the cursor if none exists.
if (!sub) {
VT100GridCoord coord =
VT100GridCoordMake(_dataSource.cursorX - 1,
_dataSource.numberOfScrollbackLines + _dataSource.cursorY - 1);
[_selection beginSelectionAt:coord
mode:kiTermSelectionModeCharacter
resume:NO
append:NO];
coord = [extractor successorOfCoord:coord];
[_selection moveSelectionEndpointTo:coord];
[_selection endLiveSelection];
assert(false);
}
 
sub = _selection.allSubSelections.lastObject;
- (VT100GridWindowedRange)rangeByMovingEndOfRangeBack:(VT100GridWindowedRange)existingRange
extractor:(iTermTextExtractor *)extractor
unit:(PTYTextViewSelectionExtensionUnit)unit {
VT100GridCoord coordBeforeEnd =
[extractor predecessorOfCoordSkippingContiguousNulls:VT100GridWindowedRangeEnd(existingRange)];
switch (unit) {
case kPTYTextViewSelectionExtensionUnitCharacter: {
VT100GridWindowedRange rangeExcludingLastCharacter = existingRange;
rangeExcludingLastCharacter.coordRange.end = coordBeforeEnd;
return rangeExcludingLastCharacter;
}
case kPTYTextViewSelectionExtensionUnitWord: {
VT100GridWindowedRange rangeExcludingWordAtEnd = existingRange;
rangeExcludingWordAtEnd.coordRange.end =
[extractor rangeForWordAt:coordBeforeEnd].coordRange.start;
rangeExcludingWordAtEnd.columnWindow = existingRange.columnWindow;
return rangeExcludingWordAtEnd;
}
case kPTYTextViewSelectionExtensionUnitLine: {
VT100GridWindowedRange rangeExcludingLastLine = existingRange;
if (existingRange.coordRange.end.x > existingRange.columnWindow.location) {
rangeExcludingLastLine.coordRange.end.x = existingRange.columnWindow.location;
} else {
rangeExcludingLastLine.coordRange.end.x = existingRange.columnWindow.location;
rangeExcludingLastLine.coordRange.end.y = MAX(1, existingRange.coordRange.end.y - 1);
}
return rangeExcludingLastLine;
}
case kPTYTextViewSelectionExtensionUnitMark: {
VT100GridWindowedRange rangeExcludingLastLine = existingRange;
int rightMargin;
if (existingRange.columnWindow.length) {
rightMargin = VT100GridRangeMax(existingRange.columnWindow) + 1;
} else {
rightMargin = _dataSource.width;
}
rangeExcludingLastLine.coordRange.end.x = rightMargin;
int n = [_dataSource lineNumberOfMarkBeforeLine:rangeExcludingLastLine.coordRange.end.y + 1];
if (n != -1) {
rangeExcludingLastLine.coordRange.end.y = MAX(1, n - 1);
}
return rangeExcludingLastLine;
}
}
assert(false);
}
 
VT100GridRange columnWindow = sub.range.columnWindow;
if (columnWindow.length > 0) {
extractor.logicalWindow = columnWindow;
- (VT100GridWindowedRange)rangeByMovingEndOfRangeForward:(VT100GridWindowedRange)existingRange
extractor:(iTermTextExtractor *)extractor
unit:(PTYTextViewSelectionExtensionUnit)unit {
VT100GridCoord endCoord = VT100GridWindowedRangeEnd(existingRange);
VT100GridCoord coordAfterEnd =
[extractor successorOfCoordSkippingContiguousNulls:endCoord];
switch (unit) {
case kPTYTextViewSelectionExtensionUnitCharacter: {
VT100GridWindowedRange rangeWithCharacterAfterEnd = existingRange;
rangeWithCharacterAfterEnd.coordRange.end = coordAfterEnd;
return rangeWithCharacterAfterEnd;
}
case kPTYTextViewSelectionExtensionUnitWord: {
VT100GridWindowedRange rangeWithWordAfterEnd;
if (endCoord.x > VT100GridRangeMax(existingRange.columnWindow)) {
rangeWithWordAfterEnd = [extractor rangeForWordAt:coordAfterEnd];
} else {
rangeWithWordAfterEnd = [extractor rangeForWordAt:endCoord];
}
rangeWithWordAfterEnd.coordRange.start = existingRange.coordRange.start;
rangeWithWordAfterEnd.columnWindow = existingRange.columnWindow;
return rangeWithWordAfterEnd;
}
case kPTYTextViewSelectionExtensionUnitLine: {
VT100GridWindowedRange rangeWithLineAfterEnd = existingRange;
int rightMargin;
if (existingRange.columnWindow.length) {
rightMargin = VT100GridRangeMax(existingRange.columnWindow) + 1;
} else {
rightMargin = _dataSource.width;
}
if (existingRange.coordRange.end.x < rightMargin) {
rangeWithLineAfterEnd.coordRange.end.x = rightMargin;
} else {
rangeWithLineAfterEnd.coordRange.end.x = rightMargin;
rangeWithLineAfterEnd.coordRange.end.y =
MIN(_dataSource.numberOfLines,
rangeWithLineAfterEnd.coordRange.end.y + 1);
}
return rangeWithLineAfterEnd;
}
case kPTYTextViewSelectionExtensionUnitMark: {
VT100GridWindowedRange rangeWithLineAfterEnd = existingRange;
int rightMargin;
if (existingRange.columnWindow.length) {
rightMargin = VT100GridRangeMax(existingRange.columnWindow) + 1;
} else {
rightMargin = _dataSource.width;
}
rangeWithLineAfterEnd.coordRange.end.x = rightMargin;
int nextMark =
[_dataSource lineNumberOfMarkAfterLine:rangeWithLineAfterEnd.coordRange.end.y];
if (nextMark != -1) {
rangeWithLineAfterEnd.coordRange.end.y =
MIN(_dataSource.numberOfLines,
nextMark - 1);
}
if (rangeWithLineAfterEnd.coordRange.end.y == existingRange.coordRange.end.y) {
int nextMark =
[_dataSource lineNumberOfMarkAfterLine:rangeWithLineAfterEnd.coordRange.end.y + 1];
if (nextMark != -1) {
rangeWithLineAfterEnd.coordRange.end.y =
MIN(_dataSource.numberOfLines, nextMark - 1);
}
}
return rangeWithLineAfterEnd;
}
}
assert(false);
}
 
const VT100GridWindowedRange existingRange = sub.range;
VT100GridWindowedRange newRange = existingRange;
- (VT100GridWindowedRange)rangeByExtendingRange:(VT100GridWindowedRange)existingRange
endpoint:(PTYTextViewSelectionEndpoint)endpoint
direction:(PTYTextViewSelectionExtensionDirection)direction
extractor:(iTermTextExtractor *)extractor
unit:(PTYTextViewSelectionExtensionUnit)unit {
switch (endpoint) {
case kPTYTextViewSelectionEndpointStart:
switch (direction) {
// Move start to the left
case kPTYTextViewSelectionExtensionDirectionLeft: {
VT100GridCoord coordBeforeStart =
[extractor predecessorOfCoordSkippingContiguousNulls:VT100GridWindowedRangeStart(existingRange)];
switch (unit) {
case kPTYTextViewSelectionExtensionUnitCharacter: {
VT100GridWindowedRange rangeWithCharacterBeforeStart = existingRange;
rangeWithCharacterBeforeStart.coordRange.start = coordBeforeStart;
newRange = rangeWithCharacterBeforeStart;
break;
}
case kPTYTextViewSelectionExtensionUnitWord: {
VT100GridWindowedRange rangeWithWordBeforeStart =
[extractor rangeForWordAt:coordBeforeStart];
rangeWithWordBeforeStart.coordRange.end = existingRange.coordRange.end;
rangeWithWordBeforeStart.columnWindow = existingRange.columnWindow;
newRange = rangeWithWordBeforeStart;
break;
}
case kPTYTextViewSelectionExtensionUnitLine: {
VT100GridWindowedRange rangeWithLineBeforeStart = existingRange;
if (rangeWithLineBeforeStart.coordRange.start.y > 0) {
if (rangeWithLineBeforeStart.coordRange.start.x > rangeWithLineBeforeStart.columnWindow.location) {
rangeWithLineBeforeStart.coordRange.start.x = rangeWithLineBeforeStart.columnWindow.location;
} else {
rangeWithLineBeforeStart.coordRange.start.y--;
}
}
newRange = rangeWithLineBeforeStart;
break;
}
case kPTYTextViewSelectionExtensionUnitMark: {
VT100GridWindowedRange rangeWithLineBeforeStart = existingRange;
if (rangeWithLineBeforeStart.coordRange.start.y > 0) {
rangeWithLineBeforeStart.coordRange.start.y = [_dataSource lineNumberOfMarkBeforeLine:existingRange.coordRange.start.y] + 1;
if (rangeWithLineBeforeStart.coordRange.start.y == existingRange.coordRange.start.y) {
rangeWithLineBeforeStart.coordRange.start.y = [_dataSource lineNumberOfMarkBeforeLine:existingRange.coordRange.start.y - 1] + 1;
}
rangeWithLineBeforeStart.coordRange.start.x = existingRange.columnWindow.location;
}
newRange = rangeWithLineBeforeStart;
break;
}
}
break;
}
// Move start to the right
case kPTYTextViewSelectionExtensionDirectionRight: {
VT100GridCoord coordAfterStart =
[extractor successorOfCoordSkippingContiguousNulls:VT100GridWindowedRangeStart(existingRange)];
switch (unit) {
case kPTYTextViewSelectionExtensionUnitCharacter: {
VT100GridWindowedRange rangeExcludingFirstCharacter = existingRange;
rangeExcludingFirstCharacter.coordRange.start = coordAfterStart;
newRange = rangeExcludingFirstCharacter;
break;
}
case kPTYTextViewSelectionExtensionUnitWord: {
VT100GridCoord startCoord = VT100GridWindowedRangeStart(existingRange);
BOOL startWasOnNull = [extractor characterAt:startCoord].code == 0;
VT100GridWindowedRange rangeExcludingWordAtStart = existingRange;
rangeExcludingWordAtStart.coordRange.start =
[extractor rangeForWordAt:startCoord].coordRange.end;
// If the start of range moved from a null to a null, skip to the end of the line or past all the nulls.
if (startWasOnNull &&
[extractor characterAt:rangeExcludingWordAtStart.coordRange.start].code == 0) {
rangeExcludingWordAtStart.coordRange.start =
[extractor successorOfCoordSkippingContiguousNulls:rangeExcludingWordAtStart.coordRange.start];
}
newRange = rangeExcludingWordAtStart;
break;
}
case kPTYTextViewSelectionExtensionUnitLine: {
VT100GridWindowedRange rangeExcludingFirstLine = existingRange;
rangeExcludingFirstLine.coordRange.start.x = existingRange.columnWindow.location;
rangeExcludingFirstLine.coordRange.start.y =
MIN(_dataSource.numberOfLines,
rangeExcludingFirstLine.coordRange.start.y + 1);
newRange = rangeExcludingFirstLine;
break;
}
case kPTYTextViewSelectionExtensionUnitMark: {
VT100GridWindowedRange rangeExcludingFirstLine = existingRange;
rangeExcludingFirstLine.coordRange.start.x = existingRange.columnWindow.location;
rangeExcludingFirstLine.coordRange.start.y =
MIN(_dataSource.numberOfLines,
[_dataSource lineNumberOfMarkAfterLine:rangeExcludingFirstLine.coordRange.start.y - 1] + 1);
newRange = rangeExcludingFirstLine;
break;
}
}
break;
}
case kPTYTextViewSelectionExtensionDirectionLeft:
return [self rangeByMovingStartOfRangeBack:existingRange
extractor:extractor
unit:unit];
case kPTYTextViewSelectionExtensionDirectionRight:
return [self rangeByMovingStartOfRangeForward:existingRange
extractor:extractor
unit:unit];
}
assert(false);
break;
case kPTYTextViewSelectionEndpointEnd:
switch (direction) {
// Move end to the left
case kPTYTextViewSelectionExtensionDirectionLeft: {
VT100GridCoord coordBeforeEnd =
[extractor predecessorOfCoordSkippingContiguousNulls:VT100GridWindowedRangeEnd(existingRange)];
switch (unit) {
case kPTYTextViewSelectionExtensionUnitCharacter: {
VT100GridWindowedRange rangeExcludingLastCharacter = existingRange;
rangeExcludingLastCharacter.coordRange.end = coordBeforeEnd;
newRange = rangeExcludingLastCharacter;
break;
}
case kPTYTextViewSelectionExtensionUnitWord: {
VT100GridWindowedRange rangeExcludingWordAtEnd = existingRange;
rangeExcludingWordAtEnd.coordRange.end =
[extractor rangeForWordAt:coordBeforeEnd].coordRange.start;
rangeExcludingWordAtEnd.columnWindow = existingRange.columnWindow;
newRange = rangeExcludingWordAtEnd;
break;
}
case kPTYTextViewSelectionExtensionUnitLine: {
VT100GridWindowedRange rangeExcludingLastLine = existingRange;
if (existingRange.coordRange.end.x > existingRange.columnWindow.location) {
rangeExcludingLastLine.coordRange.end.x = existingRange.columnWindow.location;
} else {
rangeExcludingLastLine.coordRange.end.x = existingRange.columnWindow.location;
rangeExcludingLastLine.coordRange.end.y = MAX(1, existingRange.coordRange.end.y - 1);
}
newRange = rangeExcludingLastLine;
break;
}
case kPTYTextViewSelectionExtensionUnitMark: {
VT100GridWindowedRange rangeExcludingLastLine = existingRange;
int rightMargin;
if (existingRange.columnWindow.length) {
rightMargin = VT100GridRangeMax(existingRange.columnWindow) + 1;
} else {
rightMargin = _dataSource.width;
}
rangeExcludingLastLine.coordRange.end.x = rightMargin;
int n = [_dataSource lineNumberOfMarkBeforeLine:rangeExcludingLastLine.coordRange.end.y + 1];
rangeExcludingLastLine.coordRange.end.y = MAX(1, n - 1);
newRange = rangeExcludingLastLine;
break;
}
}
break;
}
// Move end to the right
case kPTYTextViewSelectionExtensionDirectionRight: {
VT100GridCoord endCoord = VT100GridWindowedRangeEnd(existingRange);
VT100GridCoord coordAfterEnd =
[extractor successorOfCoordSkippingContiguousNulls:endCoord];
switch (unit) {
case kPTYTextViewSelectionExtensionUnitCharacter: {
VT100GridWindowedRange rangeWithCharacterAfterEnd = existingRange;
rangeWithCharacterAfterEnd.coordRange.end = coordAfterEnd;
newRange = rangeWithCharacterAfterEnd;
break;
}
case kPTYTextViewSelectionExtensionUnitWord: {
VT100GridWindowedRange rangeWithWordAfterEnd;
if (endCoord.x > VT100GridRangeMax(existingRange.columnWindow)) {
rangeWithWordAfterEnd = [extractor rangeForWordAt:coordAfterEnd];
} else {
rangeWithWordAfterEnd = [extractor rangeForWordAt:endCoord];
}
rangeWithWordAfterEnd.coordRange.start = existingRange.coordRange.start;
rangeWithWordAfterEnd.columnWindow = existingRange.columnWindow;
newRange = rangeWithWordAfterEnd;
break;
}
case kPTYTextViewSelectionExtensionUnitLine: {
VT100GridWindowedRange rangeWithLineAfterEnd = existingRange;
int rightMargin;
if (existingRange.columnWindow.length) {
rightMargin = VT100GridRangeMax(existingRange.columnWindow) + 1;
} else {
rightMargin = _dataSource.width;
}
if (existingRange.coordRange.end.x < rightMargin) {
rangeWithLineAfterEnd.coordRange.end.x = rightMargin;
} else {
rangeWithLineAfterEnd.coordRange.end.x = rightMargin;
rangeWithLineAfterEnd.coordRange.end.y =
MIN(_dataSource.numberOfLines,
rangeWithLineAfterEnd.coordRange.end.y + 1);
}
newRange = rangeWithLineAfterEnd;
break;
}
case kPTYTextViewSelectionExtensionUnitMark: {
VT100GridWindowedRange rangeWithLineAfterEnd = existingRange;
int rightMargin;
if (existingRange.columnWindow.length) {
rightMargin = VT100GridRangeMax(existingRange.columnWindow) + 1;
} else {
rightMargin = _dataSource.width;
}
rangeWithLineAfterEnd.coordRange.end.x = rightMargin;
rangeWithLineAfterEnd.coordRange.end.y =
MIN(_dataSource.numberOfLines,
[_dataSource lineNumberOfMarkAfterLine:rangeWithLineAfterEnd.coordRange.end.y] - 1);
if (rangeWithLineAfterEnd.coordRange.end.y == existingRange.coordRange.end.y) {
rangeWithLineAfterEnd.coordRange.end.y =
MIN(_dataSource.numberOfLines,
[_dataSource lineNumberOfMarkAfterLine:rangeWithLineAfterEnd.coordRange.end.y + 1] - 1);
}
newRange = rangeWithLineAfterEnd;
break;
}
}
break;
}
case kPTYTextViewSelectionExtensionDirectionLeft:
return [self rangeByMovingEndOfRangeBack:existingRange
extractor:extractor
unit:unit];
case kPTYTextViewSelectionExtensionDirectionRight:
return [self rangeByMovingEndOfRangeForward:existingRange
extractor:extractor
unit:unit];
}
assert(false);
break;
}
assert(false);
}
 
// Convert the mode into an iTermSelectionMode. Only a subset of iTermSelectionModes are
// possible which is why this uses its own enum.
iTermSelectionMode mode = kiTermSelectionModeCharacter;
- (iTermSelectionMode)selectionModeForExtensionUnit:(PTYTextViewSelectionExtensionUnit)unit {
switch (unit) {
case kPTYTextViewSelectionExtensionUnitCharacter:
mode = kiTermSelectionModeCharacter;
break;
return kiTermSelectionModeCharacter;
case kPTYTextViewSelectionExtensionUnitWord:
mode = kiTermSelectionModeWord;
break;
return kiTermSelectionModeWord;
case kPTYTextViewSelectionExtensionUnitLine:
mode = kiTermSelectionModeLine;
break;
return kiTermSelectionModeLine;
case kPTYTextViewSelectionExtensionUnitMark:
mode = kiTermSelectionModeLine;
break;
return kiTermSelectionModeLine;
}
 
if ([_selection coord:newRange.coordRange.start isBeforeCoord:newRange.coordRange.end]) {
return kiTermSelectionModeCharacter;
}
- (BOOL)unitIsValid:(PTYTextViewSelectionExtensionUnit)unit {
switch (unit) {
case kPTYTextViewSelectionExtensionUnitCharacter:
case kPTYTextViewSelectionExtensionUnitWord:
case kPTYTextViewSelectionExtensionUnitLine:
case kPTYTextViewSelectionExtensionUnitMark:
return YES;
}
return NO;
}
- (void)moveSelectionEndpoint:(PTYTextViewSelectionEndpoint)endpoint
inDirection:(PTYTextViewSelectionExtensionDirection)direction
by:(PTYTextViewSelectionExtensionUnit)unit {
// Ensure the unit is valid, since it comes from preferences.
if (![self unitIsValid:unit]) {
ELog(@"ERROR: Unrecognized unit enumerated value %@, treating as character.", @(unit));
unit = kPTYTextViewSelectionExtensionUnitCharacter;
}
// Cancel a live selection if one is ongoing.
if (_selection.live) {
[_selection endLiveSelection];
}
iTermSubSelection *sub = _selection.allSubSelections.lastObject;
iTermTextExtractor *extractor = [iTermTextExtractor textExtractorWithDataSource:_dataSource];
VT100GridWindowedRange existingRange;
// Create a selection at the cursor if none exists.
if (!sub) {
VT100GridCoord coord =
VT100GridCoordMake(_dataSource.cursorX - 1,
_dataSource.numberOfScrollbackLines + _dataSource.cursorY - 1);
VT100GridRange columnWindow = extractor.logicalWindow;
existingRange = VT100GridWindowedRangeMake(VT100GridCoordRangeMake(coord.x, coord.y, coord.x, coord.y),
columnWindow.location,
columnWindow.length);
} else {
VT100GridRange columnWindow = sub.range.columnWindow;
existingRange = sub.range;
if (columnWindow.length > 0) {
extractor.logicalWindow = columnWindow;
}
}
VT100GridWindowedRange newRange = [self rangeByExtendingRange:existingRange
endpoint:endpoint
direction:direction
extractor:extractor
unit:unit];
// Convert the mode into an iTermSelectionMode. Only a subset of iTermSelectionModes are
// possible which is why this uses its own enum.
iTermSelectionMode mode = [self selectionModeForExtensionUnit:unit];
if (!sub) {
[_selection beginSelectionAt:newRange.coordRange.start
mode:mode
resume:NO
append:NO];
if (unit == kPTYTextViewSelectionExtensionUnitCharacter ||
unit == kPTYTextViewSelectionExtensionUnitMark) {
[_selection moveSelectionEndpointTo:newRange.coordRange.end];
} else {
[_selection moveSelectionEndpointTo:newRange.coordRange.start];
}
[_selection endLiveSelection];
} else if ([_selection coord:newRange.coordRange.start isBeforeCoord:newRange.coordRange.end]) {
// Is a valid range
[_selection setLastRange:newRange mode:mode];
} else {
Loading
Loading
Loading
Loading
@@ -102,7 +102,11 @@
- (VT100GridCoordRange)coordRangeOfNote:(PTYNoteViewController *)note;
- (NSArray *)charactersWithNotesOnLine:(int)line;
- (VT100ScreenMark *)markOnLine:(int)line;
// return -1 if none
- (int)lineNumberOfMarkAfterLine:(int)line;
// return -1 if none
- (int)lineNumberOfMarkBeforeLine:(int)line;
 
- (NSString *)workingDirectoryOnLine:(int)line;
Loading
Loading
Loading
Loading
@@ -2093,7 +2093,7 @@ static NSString *const kInilineFileInset = @"inset"; // NSValue of NSEdgeInsets
}
objects = [enumerator nextObject];
}
return line;
return -1;
}
 
- (int)lineNumberOfMarkAfterLine:(int)line {
Loading
Loading
@@ -2109,7 +2109,7 @@ static NSString *const kInilineFileInset = @"inset"; // NSValue of NSEdgeInsets
}
objects = [enumerator nextObject];
}
return line;
return -1;
}
 
- (NSArray *)marksOrNotesBefore:(Interval *)location {
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment