@@ -28,11 +28,18 @@ struct Event {
28
28
render_lock : Option < RenderLock > ,
29
29
}
30
30
31
+ #[ derive( Clone , Debug , Default ) ]
32
+ struct DiffInner {
33
+ diff_base : Rope ,
34
+ doc : Rope ,
35
+ hunks : Vec < Hunk > ,
36
+ }
37
+
31
38
#[ derive( Clone , Debug ) ]
32
39
pub struct DiffHandle {
33
40
channel : UnboundedSender < Event > ,
34
41
render_lock : Arc < RwLock < ( ) > > ,
35
- hunks : Arc < Mutex < Vec < Hunk > > > ,
42
+ diff : Arc < Mutex < DiffInner > > ,
36
43
inverted : bool ,
37
44
}
38
45
@@ -47,18 +54,18 @@ impl DiffHandle {
47
54
redraw_handle : RedrawHandle ,
48
55
) -> ( DiffHandle , JoinHandle < ( ) > ) {
49
56
let ( sender, receiver) = unbounded_channel ( ) ;
50
- let hunks : Arc < Mutex < Vec < Hunk > > > = Arc :: default ( ) ;
57
+ let diff : Arc < Mutex < DiffInner > > = Arc :: default ( ) ;
51
58
let worker = DiffWorker {
52
59
channel : receiver,
53
- hunks : hunks . clone ( ) ,
60
+ diff : diff . clone ( ) ,
54
61
new_hunks : Vec :: default ( ) ,
55
62
redraw_notify : redraw_handle. 0 ,
56
63
diff_finished_notify : Arc :: default ( ) ,
57
64
} ;
58
65
let handle = tokio:: spawn ( worker. run ( diff_base, doc) ) ;
59
66
let differ = DiffHandle {
60
67
channel : sender,
61
- hunks ,
68
+ diff ,
62
69
inverted : false ,
63
70
render_lock : redraw_handle. 1 ,
64
71
} ;
@@ -69,9 +76,9 @@ impl DiffHandle {
69
76
self . inverted = !self . inverted ;
70
77
}
71
78
72
- pub fn hunks ( & self ) -> FileHunks {
73
- FileHunks {
74
- hunks : self . hunks . lock ( ) ,
79
+ pub fn read ( & self ) -> Diff {
80
+ Diff {
81
+ diff : self . diff . lock ( ) ,
75
82
inverted : self . inverted ,
76
83
}
77
84
}
@@ -168,28 +175,44 @@ impl Hunk {
168
175
/// A list of changes in a file sorted in ascending
169
176
/// non-overlapping order
170
177
#[ derive( Debug ) ]
171
- pub struct FileHunks < ' a > {
172
- hunks : MutexGuard < ' a , Vec < Hunk > > ,
178
+ pub struct Diff < ' a > {
179
+ diff : MutexGuard < ' a , DiffInner > ,
173
180
inverted : bool ,
174
181
}
175
182
176
- impl FileHunks < ' _ > {
183
+ impl Diff < ' _ > {
184
+ pub fn diff_base ( & self ) -> & Rope {
185
+ if self . inverted {
186
+ & self . diff . doc
187
+ } else {
188
+ & self . diff . diff_base
189
+ }
190
+ }
191
+
192
+ pub fn doc ( & self ) -> & Rope {
193
+ if self . inverted {
194
+ & self . diff . diff_base
195
+ } else {
196
+ & self . diff . doc
197
+ }
198
+ }
199
+
177
200
pub fn is_inverted ( & self ) -> bool {
178
201
self . inverted
179
202
}
180
203
181
204
/// Returns the `Hunk` for the `n`th change in this file.
182
205
/// if there is no `n`th change `Hunk::NONE` is returned instead.
183
206
pub fn nth_hunk ( & self , n : u32 ) -> Hunk {
184
- match self . hunks . get ( n as usize ) {
207
+ match self . diff . hunks . get ( n as usize ) {
185
208
Some ( hunk) if self . inverted => hunk. invert ( ) ,
186
209
Some ( hunk) => hunk. clone ( ) ,
187
210
None => Hunk :: NONE ,
188
211
}
189
212
}
190
213
191
214
pub fn len ( & self ) -> u32 {
192
- self . hunks . len ( ) as u32
215
+ self . diff . hunks . len ( ) as u32
193
216
}
194
217
195
218
pub fn is_empty ( & self ) -> bool {
@@ -204,19 +227,20 @@ impl FileHunks<'_> {
204
227
} ;
205
228
206
229
let res = self
230
+ . diff
207
231
. hunks
208
232
. binary_search_by_key ( & line, |hunk| hunk_range ( hunk) . start ) ;
209
233
210
234
match res {
211
235
// Search found a hunk that starts exactly at this line, return the next hunk if it exists.
212
- Ok ( pos) if pos + 1 == self . hunks . len ( ) => None ,
236
+ Ok ( pos) if pos + 1 == self . diff . hunks . len ( ) => None ,
213
237
Ok ( pos) => Some ( pos as u32 + 1 ) ,
214
238
215
239
// No hunk starts exactly at this line, so the search returns
216
240
// the position where a hunk starting at this line should be inserted.
217
241
// That position is exactly the position of the next hunk or the end
218
242
// of the list if no such hunk exists
219
- Err ( pos) if pos == self . hunks . len ( ) => None ,
243
+ Err ( pos) if pos == self . diff . hunks . len ( ) => None ,
220
244
Err ( pos) => Some ( pos as u32 ) ,
221
245
}
222
246
}
@@ -228,6 +252,7 @@ impl FileHunks<'_> {
228
252
|hunk : & Hunk | hunk. after . clone ( )
229
253
} ;
230
254
let res = self
255
+ . diff
231
256
. hunks
232
257
. binary_search_by_key ( & line, |hunk| hunk_range ( hunk) . end ) ;
233
258
@@ -237,7 +262,7 @@ impl FileHunks<'_> {
237
262
// which represents a pure removal.
238
263
// Removals are technically empty but are still shown as single line hunks
239
264
// and as such we must jump to the previous hunk (if it exists) if we are already inside the removal
240
- Ok ( pos) if !hunk_range ( & self . hunks [ pos] ) . is_empty ( ) => Some ( pos as u32 ) ,
265
+ Ok ( pos) if !hunk_range ( & self . diff . hunks [ pos] ) . is_empty ( ) => Some ( pos as u32 ) ,
241
266
242
267
// No hunk ends exactly at this line, so the search returns
243
268
// the position where a hunk ending at this line should be inserted.
@@ -255,6 +280,7 @@ impl FileHunks<'_> {
255
280
} ;
256
281
257
282
let res = self
283
+ . diff
258
284
. hunks
259
285
. binary_search_by_key ( & line, |hunk| hunk_range ( hunk) . start ) ;
260
286
@@ -267,7 +293,7 @@ impl FileHunks<'_> {
267
293
// The previous hunk contains this hunk if it exists and doesn't end before this line
268
294
Err ( 0 ) => None ,
269
295
Err ( pos) => {
270
- let hunk = hunk_range ( & self . hunks [ pos - 1 ] ) ;
296
+ let hunk = hunk_range ( & self . diff . hunks [ pos - 1 ] ) ;
271
297
if hunk. end > line || include_removal && hunk. start == line && hunk. is_empty ( ) {
272
298
Some ( pos as u32 - 1 )
273
299
} else {
0 commit comments