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