@@ -15,18 +15,30 @@ extension TextViewController {
1515 if isPostingCursorNotification { return }
1616 var newSelectedRanges : [ NSRange ] = [ ]
1717 for position in positions {
18- let line = position. line
19- let column = position. column
20- guard ( line > 0 && column > 0 ) || ( position. range != . notFound) else { continue }
18+ guard ( position. start. isPositive && position. end? . isPositive ?? true )
19+ || ( position. range != . notFound) else {
20+ continue
21+ }
2122
2223 if position. range == . notFound {
2324 if textView. textStorage. length == 0 {
2425 // If the file is blank, automatically place the cursor in the first index.
2526 newSelectedRanges. append ( NSRange ( location: 0 , length: 0 ) )
26- } else if let linePosition = textView. layoutManager. textLineForIndex ( line - 1 ) {
27+ } else if let linePosition = textView. layoutManager. textLineForIndex ( position . start . line - 1 ) {
2728 // If this is a valid line, set the new position
28- let index = linePosition. range. lowerBound + min( linePosition. range. upperBound, column - 1 )
29- newSelectedRanges. append ( NSRange ( location: index, length: 0 ) )
29+ let startCharacter = linePosition. range. lowerBound + min(
30+ linePosition. range. upperBound,
31+ position. start. column - 1
32+ )
33+ if let end = position. end, let endLine = textView. layoutManager. textLineForIndex ( end. line - 1 ) {
34+ let endCharacter = endLine. range. lowerBound + min(
35+ endLine. range. upperBound,
36+ end. column - 1
37+ )
38+ newSelectedRanges. append ( NSRange ( start: startCharacter, end: endCharacter) )
39+ } else {
40+ newSelectedRanges. append ( NSRange ( location: startCharacter, length: 0 ) )
41+ }
3042 }
3143 } else {
3244 newSelectedRanges. append ( position. range)
@@ -46,9 +58,20 @@ extension TextViewController {
4658 guard let linePosition = textView. layoutManager. textLineForOffset ( selectedRange. range. location) else {
4759 continue
4860 }
49- let column = ( selectedRange. range. location - linePosition. range. location) + 1
50- let line = linePosition. index + 1
51- positions. append ( CursorPosition ( range: selectedRange. range, line: line, column: column) )
61+ let start = CursorPosition . Position (
62+ line: linePosition. index + 1 ,
63+ column: ( selectedRange. range. location - linePosition. range. location) + 1
64+ )
65+ let end = if !selectedRange. range. isEmpty,
66+ let endPosition = textView. layoutManager. textLineForOffset ( selectedRange. range. max) {
67+ CursorPosition . Position (
68+ line: endPosition. index + 1 ,
69+ column: selectedRange. range. max - endPosition. range. location + 1
70+ )
71+ } else {
72+ CursorPosition . Position? . none
73+ }
74+ positions. append ( CursorPosition ( range: selectedRange. range, start: start, end: end) )
5275 }
5376
5477 isPostingCursorNotification = true
@@ -66,26 +89,43 @@ extension TextViewController {
6689
6790 /// Fills out all properties on the given cursor position if it's missing either the range or line/column
6891 /// information.
69- func resolveCursorPosition( _ position: CursorPosition ) -> CursorPosition ? {
92+ public func resolveCursorPosition( _ position: CursorPosition ) -> CursorPosition ? {
7093 var range = position. range
7194 if range == . notFound {
72- guard position. line > 0 , position. column > 0 ,
73- let linePosition = textView. layoutManager. textLineForIndex ( position. line - 1 ) else {
95+ guard position. start . line > 0 , position. start . column > 0 ,
96+ let linePosition = textView. layoutManager. textLineForIndex ( position. start . line - 1 ) else {
7497 return nil
7598 }
76- range = NSRange ( location: linePosition. range. location + position. column, length: 0 )
99+ if let end = position. end, let endPosition = textView. layoutManager. textLineForIndex ( end. line - 1 ) {
100+ range = NSRange (
101+ location: linePosition. range. location + position. start. column,
102+ length: linePosition. range. max
103+ )
104+ } else {
105+ range = NSRange ( location: linePosition. range. location + position. start. column, length: 0 )
106+ }
77107 }
78108
79- var line = position. line
80- var column = position. column
81- if position. line <= 0 || position. column <= 0 {
82- guard range != . notFound, let linePosition = textView. layoutManager. textLineForOffset ( range. location) else {
83- return nil
84- }
85- column = ( range. location - linePosition. range. location) + 1
86- line = linePosition. index + 1
109+ var start : CursorPosition . Position
110+ var end : CursorPosition . Position ?
111+
112+ guard let startLinePosition = textView. layoutManager. textLineForOffset ( range. location) else {
113+ return nil
114+ }
115+
116+ start = CursorPosition . Position (
117+ line: startLinePosition. index + 1 ,
118+ column: ( range. location - startLinePosition. range. location) + 1
119+ )
120+
121+ if !range. isEmpty {
122+ guard let endLinePosition = textView. layoutManager. textLineForOffset ( range. max) else { return nil }
123+ end = CursorPosition . Position (
124+ line: endLinePosition. index + 1 ,
125+ column: ( range. max - endLinePosition. range. location) + 1
126+ )
87127 }
88128
89- return CursorPosition ( range: range, line : line , column : column )
129+ return CursorPosition ( range: range, start : start , end : end )
90130 }
91131}
0 commit comments