mirror of
https://github.com/ilyakooo0/helix.git
synced 2024-09-11 16:07:00 +03:00
Add command for resetting diff hunks (#5736)
This commit is contained in:
parent
8c2e447b16
commit
48b6aa9a69
@ -76,3 +76,4 @@
|
|||||||
| `:pipe` | Pipe each selection to the shell command. |
|
| `:pipe` | Pipe each selection to the shell command. |
|
||||||
| `:pipe-to` | Pipe each selection to the shell command, ignoring output. |
|
| `:pipe-to` | Pipe each selection to the shell command, ignoring output. |
|
||||||
| `:run-shell-command`, `:sh` | Run a shell command |
|
| `:run-shell-command`, `:sh` | Run a shell command |
|
||||||
|
| `:reset-diff-change`, `:diffget`, `:diffg` | Reset the diff change at the cursor position. |
|
||||||
|
@ -3011,13 +3011,13 @@ fn goto_first_change_impl(cx: &mut Context, reverse: bool) {
|
|||||||
let (view, doc) = current!(editor);
|
let (view, doc) = current!(editor);
|
||||||
if let Some(handle) = doc.diff_handle() {
|
if let Some(handle) = doc.diff_handle() {
|
||||||
let hunk = {
|
let hunk = {
|
||||||
let hunks = handle.hunks();
|
let diff = handle.load();
|
||||||
let idx = if reverse {
|
let idx = if reverse {
|
||||||
hunks.len().saturating_sub(1)
|
diff.len().saturating_sub(1)
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
hunks.nth_hunk(idx)
|
diff.nth_hunk(idx)
|
||||||
};
|
};
|
||||||
if hunk != Hunk::NONE {
|
if hunk != Hunk::NONE {
|
||||||
let range = hunk_range(hunk, doc.text().slice(..));
|
let range = hunk_range(hunk, doc.text().slice(..));
|
||||||
@ -3049,19 +3049,19 @@ fn goto_next_change_impl(cx: &mut Context, direction: Direction) {
|
|||||||
let selection = doc.selection(view.id).clone().transform(|range| {
|
let selection = doc.selection(view.id).clone().transform(|range| {
|
||||||
let cursor_line = range.cursor_line(doc_text) as u32;
|
let cursor_line = range.cursor_line(doc_text) as u32;
|
||||||
|
|
||||||
let hunks = diff_handle.hunks();
|
let diff = diff_handle.load();
|
||||||
let hunk_idx = match direction {
|
let hunk_idx = match direction {
|
||||||
Direction::Forward => hunks
|
Direction::Forward => diff
|
||||||
.next_hunk(cursor_line)
|
.next_hunk(cursor_line)
|
||||||
.map(|idx| (idx + count).min(hunks.len() - 1)),
|
.map(|idx| (idx + count).min(diff.len() - 1)),
|
||||||
Direction::Backward => hunks
|
Direction::Backward => diff
|
||||||
.prev_hunk(cursor_line)
|
.prev_hunk(cursor_line)
|
||||||
.map(|idx| idx.saturating_sub(count)),
|
.map(|idx| idx.saturating_sub(count)),
|
||||||
};
|
};
|
||||||
let Some(hunk_idx) = hunk_idx else {
|
let Some(hunk_idx) = hunk_idx else {
|
||||||
return range;
|
return range;
|
||||||
};
|
};
|
||||||
let hunk = hunks.nth_hunk(hunk_idx);
|
let hunk = diff.nth_hunk(hunk_idx);
|
||||||
let new_range = hunk_range(hunk, doc_text);
|
let new_range = hunk_range(hunk, doc_text);
|
||||||
if editor.mode == Mode::Select {
|
if editor.mode == Mode::Select {
|
||||||
let head = if new_range.head < range.anchor {
|
let head = if new_range.head < range.anchor {
|
||||||
@ -4721,14 +4721,14 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {
|
|||||||
|
|
||||||
let textobject_change = |range: Range| -> Range {
|
let textobject_change = |range: Range| -> Range {
|
||||||
let diff_handle = doc.diff_handle().unwrap();
|
let diff_handle = doc.diff_handle().unwrap();
|
||||||
let hunks = diff_handle.hunks();
|
let diff = diff_handle.load();
|
||||||
let line = range.cursor_line(text);
|
let line = range.cursor_line(text);
|
||||||
let hunk_idx = if let Some(hunk_idx) = hunks.hunk_at(line as u32, false) {
|
let hunk_idx = if let Some(hunk_idx) = diff.hunk_at(line as u32, false) {
|
||||||
hunk_idx
|
hunk_idx
|
||||||
} else {
|
} else {
|
||||||
return range;
|
return range;
|
||||||
};
|
};
|
||||||
let hunk = hunks.nth_hunk(hunk_idx).after;
|
let hunk = diff.nth_hunk(hunk_idx).after;
|
||||||
|
|
||||||
let start = text.line_to_char(hunk.start as usize);
|
let start = text.line_to_char(hunk.start as usize);
|
||||||
let end = text.line_to_char(hunk.end as usize);
|
let end = text.line_to_char(hunk.end as usize);
|
||||||
|
@ -2033,6 +2033,64 @@ fn run_shell_command(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn reset_diff_change(
|
||||||
|
cx: &mut compositor::Context,
|
||||||
|
args: &[Cow<str>],
|
||||||
|
event: PromptEvent,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
if event != PromptEvent::Validate {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
ensure!(args.is_empty(), ":reset-diff-change takes no arguments");
|
||||||
|
|
||||||
|
let editor = &mut cx.editor;
|
||||||
|
let scrolloff = editor.config().scrolloff;
|
||||||
|
|
||||||
|
let (view, doc) = current!(editor);
|
||||||
|
// TODO refactor to use let..else once MSRV is raised to 1.65
|
||||||
|
let handle = match doc.diff_handle() {
|
||||||
|
Some(handle) => handle,
|
||||||
|
None => bail!("Diff is not available in the current buffer"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let diff = handle.load();
|
||||||
|
let doc_text = doc.text().slice(..);
|
||||||
|
let line = doc.selection(view.id).primary().cursor_line(doc_text);
|
||||||
|
|
||||||
|
// TODO refactor to use let..else once MSRV is raised to 1.65
|
||||||
|
let hunk_idx = match diff.hunk_at(line as u32, true) {
|
||||||
|
Some(hunk_idx) => hunk_idx,
|
||||||
|
None => bail!("There is no change at the cursor"),
|
||||||
|
};
|
||||||
|
let hunk = diff.nth_hunk(hunk_idx);
|
||||||
|
let diff_base = diff.diff_base();
|
||||||
|
let before_start = diff_base.line_to_char(hunk.before.start as usize);
|
||||||
|
let before_end = diff_base.line_to_char(hunk.before.end as usize);
|
||||||
|
let text: Tendril = diff
|
||||||
|
.diff_base()
|
||||||
|
.slice(before_start..before_end)
|
||||||
|
.chunks()
|
||||||
|
.collect();
|
||||||
|
let anchor = doc_text.line_to_char(hunk.after.start as usize);
|
||||||
|
let transaction = Transaction::change(
|
||||||
|
doc.text(),
|
||||||
|
[(
|
||||||
|
anchor,
|
||||||
|
doc_text.line_to_char(hunk.after.end as usize),
|
||||||
|
(!text.is_empty()).then_some(text),
|
||||||
|
)]
|
||||||
|
.into_iter(),
|
||||||
|
);
|
||||||
|
drop(diff); // make borrow check happy
|
||||||
|
doc.apply(&transaction, view.id);
|
||||||
|
// select inserted text
|
||||||
|
let text_len = before_end - before_start;
|
||||||
|
doc.set_selection(view.id, Selection::single(anchor, anchor + text_len));
|
||||||
|
doc.append_changes_to_history(view);
|
||||||
|
view.ensure_cursor_in_view(doc, scrolloff);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
|
pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
|
||||||
TypableCommand {
|
TypableCommand {
|
||||||
name: "quit",
|
name: "quit",
|
||||||
@ -2569,6 +2627,13 @@ fn run_shell_command(
|
|||||||
fun: run_shell_command,
|
fun: run_shell_command,
|
||||||
completer: Some(completers::filename),
|
completer: Some(completers::filename),
|
||||||
},
|
},
|
||||||
|
TypableCommand {
|
||||||
|
name: "reset-diff-change",
|
||||||
|
aliases: &["diffget", "diffg"],
|
||||||
|
doc: "Reset the diff change at the cursor position.",
|
||||||
|
fun: reset_diff_change,
|
||||||
|
completer: None,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableCommand>> =
|
pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableCommand>> =
|
||||||
|
@ -28,11 +28,18 @@ struct Event {
|
|||||||
render_lock: Option<RenderLock>,
|
render_lock: Option<RenderLock>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
struct DiffInner {
|
||||||
|
diff_base: Rope,
|
||||||
|
doc: Rope,
|
||||||
|
hunks: Vec<Hunk>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DiffHandle {
|
pub struct DiffHandle {
|
||||||
channel: UnboundedSender<Event>,
|
channel: UnboundedSender<Event>,
|
||||||
render_lock: Arc<RwLock<()>>,
|
render_lock: Arc<RwLock<()>>,
|
||||||
hunks: Arc<Mutex<Vec<Hunk>>>,
|
diff: Arc<Mutex<DiffInner>>,
|
||||||
inverted: bool,
|
inverted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,10 +54,10 @@ fn new_with_handle(
|
|||||||
redraw_handle: RedrawHandle,
|
redraw_handle: RedrawHandle,
|
||||||
) -> (DiffHandle, JoinHandle<()>) {
|
) -> (DiffHandle, JoinHandle<()>) {
|
||||||
let (sender, receiver) = unbounded_channel();
|
let (sender, receiver) = unbounded_channel();
|
||||||
let hunks: Arc<Mutex<Vec<Hunk>>> = Arc::default();
|
let diff: Arc<Mutex<DiffInner>> = Arc::default();
|
||||||
let worker = DiffWorker {
|
let worker = DiffWorker {
|
||||||
channel: receiver,
|
channel: receiver,
|
||||||
hunks: hunks.clone(),
|
diff: diff.clone(),
|
||||||
new_hunks: Vec::default(),
|
new_hunks: Vec::default(),
|
||||||
redraw_notify: redraw_handle.0,
|
redraw_notify: redraw_handle.0,
|
||||||
diff_finished_notify: Arc::default(),
|
diff_finished_notify: Arc::default(),
|
||||||
@ -58,7 +65,7 @@ fn new_with_handle(
|
|||||||
let handle = tokio::spawn(worker.run(diff_base, doc));
|
let handle = tokio::spawn(worker.run(diff_base, doc));
|
||||||
let differ = DiffHandle {
|
let differ = DiffHandle {
|
||||||
channel: sender,
|
channel: sender,
|
||||||
hunks,
|
diff,
|
||||||
inverted: false,
|
inverted: false,
|
||||||
render_lock: redraw_handle.1,
|
render_lock: redraw_handle.1,
|
||||||
};
|
};
|
||||||
@ -69,9 +76,9 @@ pub fn invert(&mut self) {
|
|||||||
self.inverted = !self.inverted;
|
self.inverted = !self.inverted;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hunks(&self) -> FileHunks {
|
pub fn load(&self) -> Diff {
|
||||||
FileHunks {
|
Diff {
|
||||||
hunks: self.hunks.lock(),
|
diff: self.diff.lock(),
|
||||||
inverted: self.inverted,
|
inverted: self.inverted,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,12 +175,28 @@ pub fn is_pure_removal(&self) -> bool {
|
|||||||
/// A list of changes in a file sorted in ascending
|
/// A list of changes in a file sorted in ascending
|
||||||
/// non-overlapping order
|
/// non-overlapping order
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FileHunks<'a> {
|
pub struct Diff<'a> {
|
||||||
hunks: MutexGuard<'a, Vec<Hunk>>,
|
diff: MutexGuard<'a, DiffInner>,
|
||||||
inverted: bool,
|
inverted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileHunks<'_> {
|
impl Diff<'_> {
|
||||||
|
pub fn diff_base(&self) -> &Rope {
|
||||||
|
if self.inverted {
|
||||||
|
&self.diff.doc
|
||||||
|
} else {
|
||||||
|
&self.diff.diff_base
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn doc(&self) -> &Rope {
|
||||||
|
if self.inverted {
|
||||||
|
&self.diff.diff_base
|
||||||
|
} else {
|
||||||
|
&self.diff.doc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_inverted(&self) -> bool {
|
pub fn is_inverted(&self) -> bool {
|
||||||
self.inverted
|
self.inverted
|
||||||
}
|
}
|
||||||
@ -181,7 +204,7 @@ pub fn is_inverted(&self) -> bool {
|
|||||||
/// Returns the `Hunk` for the `n`th change in this file.
|
/// Returns the `Hunk` for the `n`th change in this file.
|
||||||
/// if there is no `n`th change `Hunk::NONE` is returned instead.
|
/// if there is no `n`th change `Hunk::NONE` is returned instead.
|
||||||
pub fn nth_hunk(&self, n: u32) -> Hunk {
|
pub fn nth_hunk(&self, n: u32) -> Hunk {
|
||||||
match self.hunks.get(n as usize) {
|
match self.diff.hunks.get(n as usize) {
|
||||||
Some(hunk) if self.inverted => hunk.invert(),
|
Some(hunk) if self.inverted => hunk.invert(),
|
||||||
Some(hunk) => hunk.clone(),
|
Some(hunk) => hunk.clone(),
|
||||||
None => Hunk::NONE,
|
None => Hunk::NONE,
|
||||||
@ -189,7 +212,7 @@ pub fn nth_hunk(&self, n: u32) -> Hunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> u32 {
|
pub fn len(&self) -> u32 {
|
||||||
self.hunks.len() as u32
|
self.diff.hunks.len() as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
@ -204,19 +227,20 @@ pub fn next_hunk(&self, line: u32) -> Option<u32> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let res = self
|
let res = self
|
||||||
|
.diff
|
||||||
.hunks
|
.hunks
|
||||||
.binary_search_by_key(&line, |hunk| hunk_range(hunk).start);
|
.binary_search_by_key(&line, |hunk| hunk_range(hunk).start);
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
// Search found a hunk that starts exactly at this line, return the next hunk if it exists.
|
// Search found a hunk that starts exactly at this line, return the next hunk if it exists.
|
||||||
Ok(pos) if pos + 1 == self.hunks.len() => None,
|
Ok(pos) if pos + 1 == self.diff.hunks.len() => None,
|
||||||
Ok(pos) => Some(pos as u32 + 1),
|
Ok(pos) => Some(pos as u32 + 1),
|
||||||
|
|
||||||
// No hunk starts exactly at this line, so the search returns
|
// No hunk starts exactly at this line, so the search returns
|
||||||
// the position where a hunk starting at this line should be inserted.
|
// the position where a hunk starting at this line should be inserted.
|
||||||
// That position is exactly the position of the next hunk or the end
|
// That position is exactly the position of the next hunk or the end
|
||||||
// of the list if no such hunk exists
|
// of the list if no such hunk exists
|
||||||
Err(pos) if pos == self.hunks.len() => None,
|
Err(pos) if pos == self.diff.hunks.len() => None,
|
||||||
Err(pos) => Some(pos as u32),
|
Err(pos) => Some(pos as u32),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,6 +252,7 @@ pub fn prev_hunk(&self, line: u32) -> Option<u32> {
|
|||||||
|hunk: &Hunk| hunk.after.clone()
|
|hunk: &Hunk| hunk.after.clone()
|
||||||
};
|
};
|
||||||
let res = self
|
let res = self
|
||||||
|
.diff
|
||||||
.hunks
|
.hunks
|
||||||
.binary_search_by_key(&line, |hunk| hunk_range(hunk).end);
|
.binary_search_by_key(&line, |hunk| hunk_range(hunk).end);
|
||||||
|
|
||||||
@ -237,7 +262,7 @@ pub fn prev_hunk(&self, line: u32) -> Option<u32> {
|
|||||||
// which represents a pure removal.
|
// which represents a pure removal.
|
||||||
// Removals are technically empty but are still shown as single line hunks
|
// Removals are technically empty but are still shown as single line hunks
|
||||||
// and as such we must jump to the previous hunk (if it exists) if we are already inside the removal
|
// and as such we must jump to the previous hunk (if it exists) if we are already inside the removal
|
||||||
Ok(pos) if !hunk_range(&self.hunks[pos]).is_empty() => Some(pos as u32),
|
Ok(pos) if !hunk_range(&self.diff.hunks[pos]).is_empty() => Some(pos as u32),
|
||||||
|
|
||||||
// No hunk ends exactly at this line, so the search returns
|
// No hunk ends exactly at this line, so the search returns
|
||||||
// the position where a hunk ending at this line should be inserted.
|
// the position where a hunk ending at this line should be inserted.
|
||||||
@ -255,6 +280,7 @@ pub fn hunk_at(&self, line: u32, include_removal: bool) -> Option<u32> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let res = self
|
let res = self
|
||||||
|
.diff
|
||||||
.hunks
|
.hunks
|
||||||
.binary_search_by_key(&line, |hunk| hunk_range(hunk).start);
|
.binary_search_by_key(&line, |hunk| hunk_range(hunk).start);
|
||||||
|
|
||||||
@ -267,7 +293,7 @@ pub fn hunk_at(&self, line: u32, include_removal: bool) -> Option<u32> {
|
|||||||
// The previous hunk contains this hunk if it exists and doesn't end before this line
|
// The previous hunk contains this hunk if it exists and doesn't end before this line
|
||||||
Err(0) => None,
|
Err(0) => None,
|
||||||
Err(pos) => {
|
Err(pos) => {
|
||||||
let hunk = hunk_range(&self.hunks[pos - 1]);
|
let hunk = hunk_range(&self.diff.hunks[pos - 1]);
|
||||||
if hunk.end > line || include_removal && hunk.start == line && hunk.is_empty() {
|
if hunk.end > line || include_removal && hunk.start == line && hunk.is_empty() {
|
||||||
Some(pos as u32 - 1)
|
Some(pos as u32 - 1)
|
||||||
} else {
|
} else {
|
||||||
|
@ -43,6 +43,14 @@ pub fn new(diff_base: Rope, doc: Rope) -> InternedRopeLines {
|
|||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn doc(&self) -> Rope {
|
||||||
|
self.doc.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn diff_base(&self) -> Rope {
|
||||||
|
self.diff_base.clone()
|
||||||
|
}
|
||||||
|
|
||||||
/// Updates the `diff_base` and optionally the document if `doc` is not None
|
/// Updates the `diff_base` and optionally the document if `doc` is not None
|
||||||
pub fn update_diff_base(&mut self, diff_base: Rope, doc: Option<Rope>) {
|
pub fn update_diff_base(&mut self, diff_base: Rope, doc: Option<Rope>) {
|
||||||
self.interned.clear();
|
self.interned.clear();
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
use tokio::time::{timeout, timeout_at, Duration};
|
use tokio::time::{timeout, timeout_at, Duration};
|
||||||
|
|
||||||
use crate::diff::{
|
use crate::diff::{
|
||||||
Event, RenderLock, ALGORITHM, DIFF_DEBOUNCE_TIME_ASYNC, DIFF_DEBOUNCE_TIME_SYNC,
|
DiffInner, Event, RenderLock, ALGORITHM, DIFF_DEBOUNCE_TIME_ASYNC, DIFF_DEBOUNCE_TIME_SYNC,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::line_cache::InternedRopeLines;
|
use super::line_cache::InternedRopeLines;
|
||||||
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
pub(super) struct DiffWorker {
|
pub(super) struct DiffWorker {
|
||||||
pub channel: UnboundedReceiver<Event>,
|
pub channel: UnboundedReceiver<Event>,
|
||||||
pub hunks: Arc<Mutex<Vec<Hunk>>>,
|
pub diff: Arc<Mutex<DiffInner>>,
|
||||||
pub new_hunks: Vec<Hunk>,
|
pub new_hunks: Vec<Hunk>,
|
||||||
pub redraw_notify: Arc<Notify>,
|
pub redraw_notify: Arc<Notify>,
|
||||||
pub diff_finished_notify: Arc<Notify>,
|
pub diff_finished_notify: Arc<Notify>,
|
||||||
@ -46,7 +46,7 @@ pub async fn run(mut self, diff_base: Rope, doc: Rope) {
|
|||||||
if let Some(lines) = interner.interned_lines() {
|
if let Some(lines) = interner.interned_lines() {
|
||||||
self.perform_diff(lines);
|
self.perform_diff(lines);
|
||||||
}
|
}
|
||||||
self.apply_hunks();
|
self.apply_hunks(interner.diff_base(), interner.doc());
|
||||||
while let Some(event) = self.channel.recv().await {
|
while let Some(event) = self.channel.recv().await {
|
||||||
let (doc, diff_base) = self.accumulate_events(event).await;
|
let (doc, diff_base) = self.accumulate_events(event).await;
|
||||||
|
|
||||||
@ -70,15 +70,18 @@ pub async fn run(mut self, diff_base: Rope, doc: Rope) {
|
|||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
tokio::task::block_in_place(process_accumulated_events);
|
tokio::task::block_in_place(process_accumulated_events);
|
||||||
|
|
||||||
self.apply_hunks();
|
self.apply_hunks(interner.diff_base(), interner.doc());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// update the hunks (used by the gutter) by replacing it with `self.new_hunks`.
|
/// update the hunks (used by the gutter) by replacing it with `self.new_hunks`.
|
||||||
/// `self.new_hunks` is always empty after this function runs.
|
/// `self.new_hunks` is always empty after this function runs.
|
||||||
/// To improve performance this function tries to reuse the allocation of the old diff previously stored in `self.line_diffs`
|
/// To improve performance this function tries to reuse the allocation of the old diff previously stored in `self.line_diffs`
|
||||||
fn apply_hunks(&mut self) {
|
fn apply_hunks(&mut self, diff_base: Rope, doc: Rope) {
|
||||||
swap(&mut *self.hunks.lock(), &mut self.new_hunks);
|
let mut diff = self.diff.lock();
|
||||||
|
diff.diff_base = diff_base;
|
||||||
|
diff.doc = doc;
|
||||||
|
swap(&mut diff.hunks, &mut self.new_hunks);
|
||||||
self.diff_finished_notify.notify_waiters();
|
self.diff_finished_notify.notify_waiters();
|
||||||
self.new_hunks.clear();
|
self.new_hunks.clear();
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,12 @@ fn new_test(diff_base: &str, doc: &str) -> (DiffHandle, JoinHandle<()>) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
async fn into_diff(self, handle: JoinHandle<()>) -> Vec<Hunk> {
|
async fn into_diff(self, handle: JoinHandle<()>) -> Vec<Hunk> {
|
||||||
let hunks = self.hunks;
|
let diff = self.diff;
|
||||||
// dropping the channel terminates the task
|
// dropping the channel terminates the task
|
||||||
drop(self.channel);
|
drop(self.channel);
|
||||||
handle.await.unwrap();
|
handle.await.unwrap();
|
||||||
let hunks = hunks.lock();
|
let diff = diff.lock();
|
||||||
Vec::clone(&*hunks)
|
Vec::clone(&diff.hunks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ pub fn diff<'doc>(
|
|||||||
let deleted = theme.get("diff.minus");
|
let deleted = theme.get("diff.minus");
|
||||||
let modified = theme.get("diff.delta");
|
let modified = theme.get("diff.delta");
|
||||||
if let Some(diff_handle) = doc.diff_handle() {
|
if let Some(diff_handle) = doc.diff_handle() {
|
||||||
let hunks = diff_handle.hunks();
|
let hunks = diff_handle.load();
|
||||||
let mut hunk_i = 0;
|
let mut hunk_i = 0;
|
||||||
let mut hunk = hunks.nth_hunk(hunk_i);
|
let mut hunk = hunks.nth_hunk(hunk_i);
|
||||||
Box::new(
|
Box::new(
|
||||||
|
Loading…
Reference in New Issue
Block a user