mirror of https://github.com/lapce/lapce.git
make undo more granular
This commit is contained in:
parent
7744f76ce6
commit
c5f1692ec7
|
@ -19,18 +19,30 @@
|
|||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum EditType {
|
||||
Other,
|
||||
InsertChars,
|
||||
InsertNewline,
|
||||
Delete,
|
||||
DeleteSelection,
|
||||
InsertNewline,
|
||||
Cut,
|
||||
Paste,
|
||||
Indent,
|
||||
Outdent,
|
||||
ToggleComment,
|
||||
MoveLine,
|
||||
Completion,
|
||||
DeleteWord,
|
||||
DeleteToBeginningOfLine,
|
||||
MotionDelete,
|
||||
Undo,
|
||||
Redo,
|
||||
Other,
|
||||
}
|
||||
|
||||
impl EditType {
|
||||
/// Checks whether a new undo group should be created between two edits.
|
||||
pub fn breaks_undo_group(self, previous: EditType) -> bool {
|
||||
self == EditType::Other || self != previous
|
||||
!((self == EditType::InsertChars || self == EditType::Delete)
|
||||
&& self == previous)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,7 +368,7 @@ fn format_start_end(
|
|||
);
|
||||
let selection = Selection::region(start, end);
|
||||
let (delta, inval_lines) =
|
||||
buffer.edit(&[(&selection, "")], EditType::Delete);
|
||||
buffer.edit(&[(&selection, "")], EditType::MotionDelete);
|
||||
cursor.apply_delta(&delta);
|
||||
deltas.push((delta, inval_lines));
|
||||
}
|
||||
|
@ -407,8 +419,8 @@ pub fn do_paste(
|
|||
}
|
||||
};
|
||||
let after = cursor.is_insert() || !data.content.contains('\n');
|
||||
let (delta, inval_lines) = buffer
|
||||
.edit(&[(&selection, &data.content)], EditType::InsertChars);
|
||||
let (delta, inval_lines) =
|
||||
buffer.edit(&[(&selection, &data.content)], EditType::Paste);
|
||||
let selection =
|
||||
selection.apply_delta(&delta, after, InsertDrift::Default);
|
||||
deltas.push((delta, inval_lines));
|
||||
|
@ -459,7 +471,7 @@ pub fn do_paste(
|
|||
}
|
||||
};
|
||||
let (delta, inval_lines) =
|
||||
buffer.edit(&[(&selection, &content)], EditType::InsertChars);
|
||||
buffer.edit(&[(&selection, &content)], EditType::Paste);
|
||||
let selection = selection.apply_delta(
|
||||
&delta,
|
||||
cursor.is_insert(),
|
||||
|
@ -519,7 +531,7 @@ fn do_indent(
|
|||
}
|
||||
}
|
||||
|
||||
buffer.edit(&edits, EditType::InsertChars)
|
||||
buffer.edit(&edits, EditType::Indent)
|
||||
}
|
||||
|
||||
fn do_outdent(
|
||||
|
@ -557,7 +569,7 @@ fn do_outdent(
|
|||
}
|
||||
}
|
||||
|
||||
buffer.edit(&edits, EditType::Delete)
|
||||
buffer.edit(&edits, EditType::Outdent)
|
||||
}
|
||||
|
||||
pub fn do_edit<T: Clipboard>(
|
||||
|
@ -595,7 +607,7 @@ pub fn do_edit<T: Clipboard>(
|
|||
&content,
|
||||
),
|
||||
],
|
||||
EditType::InsertChars,
|
||||
EditType::MoveLine,
|
||||
);
|
||||
deltas.push((delta, inval_lines));
|
||||
region.start -= previous_line_len;
|
||||
|
@ -631,7 +643,7 @@ pub fn do_edit<T: Clipboard>(
|
|||
),
|
||||
(&Selection::region(start, end), ""),
|
||||
],
|
||||
EditType::InsertChars,
|
||||
EditType::MoveLine,
|
||||
);
|
||||
deltas.push((delta, inval_lines));
|
||||
region.start += next_line_len;
|
||||
|
@ -773,7 +785,7 @@ pub fn do_edit<T: Clipboard>(
|
|||
None,
|
||||
))
|
||||
}
|
||||
buffer.edit(&[(&selection, "")], EditType::Delete)
|
||||
buffer.edit(&[(&selection, "")], EditType::ToggleComment)
|
||||
} else {
|
||||
let mut selection = Selection::new();
|
||||
for (line, _, _) in lines.iter() {
|
||||
|
@ -782,7 +794,7 @@ pub fn do_edit<T: Clipboard>(
|
|||
}
|
||||
buffer.edit(
|
||||
&[(&selection, &format!("{comment_token} "))],
|
||||
EditType::InsertChars,
|
||||
EditType::ToggleComment,
|
||||
)
|
||||
};
|
||||
cursor.apply_delta(&delta);
|
||||
|
@ -868,7 +880,7 @@ pub fn do_edit<T: Clipboard>(
|
|||
};
|
||||
|
||||
let (delta, inval_lines) =
|
||||
buffer.edit(&[(&selection, "")], EditType::Delete);
|
||||
buffer.edit(&[(&selection, "")], EditType::Cut);
|
||||
let selection =
|
||||
selection.apply_delta(&delta, true, InsertDrift::Default);
|
||||
cursor.update_selection(buffer, selection);
|
||||
|
@ -928,13 +940,21 @@ pub fn do_edit<T: Clipboard>(
|
|||
Self::insert_new_line(buffer, cursor, Selection::caret(offset))
|
||||
}
|
||||
DeleteBackward => {
|
||||
let selection = match cursor.mode {
|
||||
CursorMode::Normal(_) | CursorMode::Visual { .. } => {
|
||||
cursor.edit_selection(buffer)
|
||||
let (selection, edit_type) = match cursor.mode {
|
||||
CursorMode::Normal(_) => {
|
||||
(cursor.edit_selection(buffer), EditType::Delete)
|
||||
}
|
||||
CursorMode::Visual { .. } => {
|
||||
(cursor.edit_selection(buffer), EditType::DeleteSelection)
|
||||
}
|
||||
CursorMode::Insert(_) => {
|
||||
let indent = buffer.indent_unit();
|
||||
let selection = cursor.edit_selection(buffer);
|
||||
let edit_type = if selection.is_caret() {
|
||||
EditType::Delete
|
||||
} else {
|
||||
EditType::DeleteSelection
|
||||
};
|
||||
let indent = buffer.indent_unit();
|
||||
let mut new_selection = Selection::new();
|
||||
for region in selection.regions() {
|
||||
let new_region = if region.is_caret() {
|
||||
|
@ -1005,23 +1025,31 @@ pub fn do_edit<T: Clipboard>(
|
|||
}
|
||||
}
|
||||
}
|
||||
selection
|
||||
(selection, edit_type)
|
||||
}
|
||||
};
|
||||
let (delta, inval_lines) =
|
||||
buffer.edit(&[(&selection, "")], EditType::Delete);
|
||||
buffer.edit(&[(&selection, "")], edit_type);
|
||||
let selection =
|
||||
selection.apply_delta(&delta, true, InsertDrift::Default);
|
||||
cursor.update_selection(buffer, selection);
|
||||
vec![(delta, inval_lines)]
|
||||
}
|
||||
DeleteForward => {
|
||||
let selection = match cursor.mode {
|
||||
CursorMode::Normal(_) | CursorMode::Visual { .. } => {
|
||||
cursor.edit_selection(buffer)
|
||||
let (selection, edit_type) = match cursor.mode {
|
||||
CursorMode::Normal(_) => {
|
||||
(cursor.edit_selection(buffer), EditType::Delete)
|
||||
}
|
||||
CursorMode::Visual { .. } => {
|
||||
(cursor.edit_selection(buffer), EditType::DeleteSelection)
|
||||
}
|
||||
CursorMode::Insert(_) => {
|
||||
let selection = cursor.edit_selection(buffer);
|
||||
let edit_type = if selection.is_caret() {
|
||||
EditType::Delete
|
||||
} else {
|
||||
EditType::DeleteSelection
|
||||
};
|
||||
let mut new_selection = Selection::new();
|
||||
for region in selection.regions() {
|
||||
let new_region = if region.is_caret() {
|
||||
|
@ -1033,11 +1061,11 @@ pub fn do_edit<T: Clipboard>(
|
|||
};
|
||||
new_selection.add_region(new_region);
|
||||
}
|
||||
new_selection
|
||||
(new_selection, edit_type)
|
||||
}
|
||||
};
|
||||
let (delta, inval_lines) =
|
||||
buffer.edit(&[(&selection, "")], EditType::Delete);
|
||||
buffer.edit(&[(&selection, "")], edit_type);
|
||||
let selection =
|
||||
selection.apply_delta(&delta, true, InsertDrift::Default);
|
||||
cursor.update_selection(buffer, selection);
|
||||
|
@ -1062,7 +1090,7 @@ pub fn do_edit<T: Clipboard>(
|
|||
}
|
||||
};
|
||||
let (delta, inval_lines) =
|
||||
buffer.edit(&[(&selection, "")], EditType::Delete);
|
||||
buffer.edit(&[(&selection, "")], EditType::DeleteWord);
|
||||
let selection =
|
||||
selection.apply_delta(&delta, true, InsertDrift::Default);
|
||||
cursor.update_selection(buffer, selection);
|
||||
|
@ -1087,7 +1115,7 @@ pub fn do_edit<T: Clipboard>(
|
|||
}
|
||||
};
|
||||
let (delta, inval_lines) =
|
||||
buffer.edit(&[(&selection, "")], EditType::Delete);
|
||||
buffer.edit(&[(&selection, "")], EditType::DeleteWord);
|
||||
let selection =
|
||||
selection.apply_delta(&delta, true, InsertDrift::Default);
|
||||
cursor.update_selection(buffer, selection);
|
||||
|
@ -1112,8 +1140,8 @@ pub fn do_edit<T: Clipboard>(
|
|||
new_selection
|
||||
}
|
||||
};
|
||||
let (delta, inval_lines) =
|
||||
buffer.edit(&[(&selection, "")], EditType::Delete);
|
||||
let (delta, inval_lines) = buffer
|
||||
.edit(&[(&selection, "")], EditType::DeleteToBeginningOfLine);
|
||||
let selection =
|
||||
selection.apply_delta(&delta, true, InsertDrift::Default);
|
||||
cursor.update_selection(buffer, selection);
|
||||
|
|
|
@ -172,6 +172,15 @@ pub fn len(&self) -> usize {
|
|||
self.regions.len()
|
||||
}
|
||||
|
||||
pub fn is_caret(&self) -> bool {
|
||||
for region in self.regions.iter() {
|
||||
if !region.is_caret() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
|
|
@ -39,7 +39,10 @@
|
|||
use lapce_core::command::{
|
||||
EditCommand, FocusCommand, MotionModeCommand, MultiSelectionCommand,
|
||||
};
|
||||
use lapce_core::editor::EditType;
|
||||
use lapce_core::mode::{Mode, MotionMode};
|
||||
use lapce_core::selection::InsertDrift;
|
||||
use lapce_core::selection::Selection;
|
||||
pub use lapce_core::syntax::Syntax;
|
||||
use lsp_types::request::GotoTypeDefinitionResponse;
|
||||
use lsp_types::CodeActionOrCommand;
|
||||
|
@ -324,12 +327,12 @@ pub fn apply_completion_item(&mut self, item: &CompletionItem) -> Result<()> {
|
|||
&additional_edit[..],
|
||||
]
|
||||
.concat(),
|
||||
lapce_core::editor::EditType::InsertChars,
|
||||
EditType::Completion,
|
||||
);
|
||||
let selection = selection.apply_delta(
|
||||
&delta,
|
||||
true,
|
||||
lapce_core::selection::InsertDrift::Default,
|
||||
InsertDrift::Default,
|
||||
);
|
||||
Arc::make_mut(&mut self.editor)
|
||||
.cursor
|
||||
|
@ -347,12 +350,12 @@ pub fn apply_completion_item(&mut self, item: &CompletionItem) -> Result<()> {
|
|||
&additional_edit[..],
|
||||
]
|
||||
.concat(),
|
||||
lapce_core::editor::EditType::InsertChars,
|
||||
EditType::Completion,
|
||||
);
|
||||
let selection = selection.apply_delta(
|
||||
&delta,
|
||||
true,
|
||||
lapce_core::selection::InsertDrift::Default,
|
||||
InsertDrift::Default,
|
||||
);
|
||||
|
||||
let mut transformer = Transformer::new(&delta);
|
||||
|
@ -393,8 +396,7 @@ pub fn apply_completion_item(&mut self, item: &CompletionItem) -> Result<()> {
|
|||
let offset = self.editor.cursor.offset();
|
||||
let start_offset = self.doc.buffer().prev_code_boundary(offset);
|
||||
let end_offset = self.doc.buffer().next_code_boundary(offset);
|
||||
let selection =
|
||||
lapce_core::selection::Selection::region(start_offset, end_offset);
|
||||
let selection = Selection::region(start_offset, end_offset);
|
||||
|
||||
let (delta, inval_lines) = Arc::make_mut(&mut self.doc).do_raw_edit(
|
||||
&[
|
||||
|
@ -405,13 +407,9 @@ pub fn apply_completion_item(&mut self, item: &CompletionItem) -> Result<()> {
|
|||
&additional_edit[..],
|
||||
]
|
||||
.concat(),
|
||||
lapce_core::editor::EditType::InsertChars,
|
||||
);
|
||||
let selection = selection.apply_delta(
|
||||
&delta,
|
||||
true,
|
||||
lapce_core::selection::InsertDrift::Default,
|
||||
EditType::Completion,
|
||||
);
|
||||
let selection = selection.apply_delta(&delta, true, InsertDrift::Default);
|
||||
Arc::make_mut(&mut self.editor)
|
||||
.cursor
|
||||
.update_selection(self.doc.buffer(), selection);
|
||||
|
|
Loading…
Reference in New Issue