mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-23 01:46:18 +04:00
Fully drop State references.
This commit is contained in:
parent
dfc17becd5
commit
9eaef6e333
@ -96,13 +96,15 @@ fn test_find_line_comment() {
|
|||||||
|
|
||||||
// comment
|
// comment
|
||||||
let transaction = toggle_line_comments(&state.doc, &state.selection);
|
let transaction = toggle_line_comments(&state.doc, &state.selection);
|
||||||
transaction.apply(&mut state);
|
transaction.apply(&mut state.doc);
|
||||||
|
state.selection = state.selection.clone().map(transaction.changes());
|
||||||
|
|
||||||
assert_eq!(state.doc, " // 1\n\n // 2\n // 3");
|
assert_eq!(state.doc, " // 1\n\n // 2\n // 3");
|
||||||
|
|
||||||
// uncomment
|
// uncomment
|
||||||
let transaction = toggle_line_comments(&state.doc, &state.selection);
|
let transaction = toggle_line_comments(&state.doc, &state.selection);
|
||||||
transaction.apply(&mut state);
|
transaction.apply(&mut state.doc);
|
||||||
|
state.selection = state.selection.clone().map(transaction.changes());
|
||||||
assert_eq!(state.doc, " 1\n\n 2\n 3");
|
assert_eq!(state.doc, " 1\n\n 2\n 3");
|
||||||
|
|
||||||
// TODO: account for no margin after comment
|
// TODO: account for no margin after comment
|
||||||
|
@ -33,7 +33,10 @@ fn default() -> Self {
|
|||||||
impl History {
|
impl History {
|
||||||
pub fn commit_revision(&mut self, transaction: &Transaction, original: &State) {
|
pub fn commit_revision(&mut self, transaction: &Transaction, original: &State) {
|
||||||
// TODO: could store a single transaction, if deletes also stored the text they delete
|
// TODO: could store a single transaction, if deletes also stored the text they delete
|
||||||
let revert = transaction.invert(original);
|
let revert = transaction
|
||||||
|
.invert(&original.doc)
|
||||||
|
// Store the current cursor position
|
||||||
|
.with_selection(original.selection.clone());
|
||||||
|
|
||||||
let new_cursor = self.revisions.len();
|
let new_cursor = self.revisions.len();
|
||||||
self.revisions.push(Revision {
|
self.revisions.push(Revision {
|
||||||
@ -100,7 +103,7 @@ fn test_undo_redo() {
|
|||||||
|
|
||||||
// Need to commit before applying!
|
// Need to commit before applying!
|
||||||
history.commit_revision(&transaction1, &state);
|
history.commit_revision(&transaction1, &state);
|
||||||
transaction1.apply(&mut state);
|
transaction1.apply(&mut state.doc);
|
||||||
assert_eq!("hello world!", state.doc);
|
assert_eq!("hello world!", state.doc);
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
@ -110,18 +113,18 @@ fn test_undo_redo() {
|
|||||||
|
|
||||||
// Need to commit before applying!
|
// Need to commit before applying!
|
||||||
history.commit_revision(&transaction2, &state);
|
history.commit_revision(&transaction2, &state);
|
||||||
transaction2.apply(&mut state);
|
transaction2.apply(&mut state.doc);
|
||||||
assert_eq!("hello 世界!", state.doc);
|
assert_eq!("hello 世界!", state.doc);
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
fn undo(history: &mut History, state: &mut State) {
|
fn undo(history: &mut History, state: &mut State) {
|
||||||
if let Some(transaction) = history.undo() {
|
if let Some(transaction) = history.undo() {
|
||||||
transaction.apply(state);
|
transaction.apply(&mut state.doc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn redo(history: &mut History, state: &mut State) {
|
fn redo(history: &mut History, state: &mut State) {
|
||||||
if let Some(transaction) = history.redo() {
|
if let Some(transaction) = history.redo() {
|
||||||
transaction.apply(state);
|
transaction.apply(&mut state.doc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1593,7 +1593,7 @@ fn test_input_edits() {
|
|||||||
&state.doc,
|
&state.doc,
|
||||||
vec![(6, 11, Some("test".into())), (12, 17, None)].into_iter(),
|
vec![(6, 11, Some("test".into())), (12, 17, None)].into_iter(),
|
||||||
);
|
);
|
||||||
let edits = LanguageLayer::generate_edits(state.doc.slice(..), &transaction.changes);
|
let edits = LanguageLayer::generate_edits(state.doc.slice(..), transaction.changes());
|
||||||
// transaction.apply(&mut state);
|
// transaction.apply(&mut state);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -1622,8 +1622,8 @@ fn test_input_edits() {
|
|||||||
let mut state = State::new("fn test() {}".into());
|
let mut state = State::new("fn test() {}".into());
|
||||||
let transaction =
|
let transaction =
|
||||||
Transaction::change(&state.doc, vec![(8, 8, Some("a: u32".into()))].into_iter());
|
Transaction::change(&state.doc, vec![(8, 8, Some("a: u32".into()))].into_iter());
|
||||||
let edits = LanguageLayer::generate_edits(state.doc.slice(..), &transaction.changes);
|
let edits = LanguageLayer::generate_edits(state.doc.slice(..), transaction.changes());
|
||||||
transaction.apply(&mut state);
|
transaction.apply(&mut state.doc);
|
||||||
|
|
||||||
assert_eq!(state.doc, "fn test(a: u32) {}");
|
assert_eq!(state.doc, "fn test(a: u32) {}");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -400,9 +400,7 @@ pub fn changes_iter(&self) -> ChangeIterator {
|
|||||||
/// a single transaction.
|
/// a single transaction.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Transaction {
|
pub struct Transaction {
|
||||||
/// Changes made to the buffer.
|
changes: ChangeSet,
|
||||||
pub(crate) changes: ChangeSet,
|
|
||||||
/// When set, explicitly updates the selection.
|
|
||||||
selection: Option<Selection>,
|
selection: Option<Selection>,
|
||||||
// effects, annotations
|
// effects, annotations
|
||||||
// scroll_into_view
|
// scroll_into_view
|
||||||
@ -417,40 +415,35 @@ pub fn new(doc: &Rope) -> Self {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Changes made to the buffer.
|
||||||
pub fn changes(&self) -> &ChangeSet {
|
pub fn changes(&self) -> &ChangeSet {
|
||||||
&self.changes
|
&self.changes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// When set, explicitly updates the selection.
|
||||||
|
pub fn selection(&self) -> Option<&Selection> {
|
||||||
|
self.selection.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if applied successfully.
|
/// Returns true if applied successfully.
|
||||||
pub fn apply(&self, state: &mut State) -> bool {
|
pub fn apply(&self, doc: &mut Rope) -> bool {
|
||||||
if !self.changes.is_empty() {
|
if !self.changes.is_empty() {
|
||||||
// apply changes to the document
|
// apply changes to the document
|
||||||
if !self.changes.apply(&mut state.doc) {
|
if !self.changes.apply(doc) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: also avoid mapping the selection if not necessary
|
|
||||||
|
|
||||||
// update the selection: either take the selection specified in the transaction, or map the
|
|
||||||
// current selection through changes.
|
|
||||||
state.selection = self
|
|
||||||
.selection
|
|
||||||
.clone()
|
|
||||||
.unwrap_or_else(|| state.selection.clone().map(&self.changes));
|
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate a transaction that reverts this one.
|
/// Generate a transaction that reverts this one.
|
||||||
pub fn invert(&self, original: &State) -> Self {
|
pub fn invert(&self, original: &Rope) -> Self {
|
||||||
let changes = self.changes.invert(&original.doc);
|
let changes = self.changes.invert(original);
|
||||||
// Store the current cursor position
|
|
||||||
let selection = original.selection.clone();
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
changes,
|
changes,
|
||||||
selection: Some(selection),
|
selection: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,7 +668,7 @@ fn transaction_change() {
|
|||||||
// (1, 1, None) is a useless 0-width delete
|
// (1, 1, None) is a useless 0-width delete
|
||||||
vec![(1, 1, None), (6, 11, Some("void".into())), (12, 17, None)].into_iter(),
|
vec![(1, 1, None), (6, 11, Some("void".into())), (12, 17, None)].into_iter(),
|
||||||
);
|
);
|
||||||
transaction.apply(&mut state);
|
transaction.apply(&mut state.doc);
|
||||||
assert_eq!(state.doc, Rope::from_str("hello void! 123"));
|
assert_eq!(state.doc, Rope::from_str("hello void! 123"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -691,15 +684,20 @@ fn changes_iter() {
|
|||||||
fn optimized_composition() {
|
fn optimized_composition() {
|
||||||
let mut state = State::new("".into());
|
let mut state = State::new("".into());
|
||||||
let t1 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('h'));
|
let t1 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('h'));
|
||||||
t1.apply(&mut state);
|
t1.apply(&mut state.doc);
|
||||||
|
state.selection = state.selection.clone().map(t1.changes());
|
||||||
let t2 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('e'));
|
let t2 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('e'));
|
||||||
t2.apply(&mut state);
|
t2.apply(&mut state.doc);
|
||||||
|
state.selection = state.selection.clone().map(t2.changes());
|
||||||
let t3 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l'));
|
let t3 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l'));
|
||||||
t3.apply(&mut state);
|
t3.apply(&mut state.doc);
|
||||||
|
state.selection = state.selection.clone().map(t3.changes());
|
||||||
let t4 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l'));
|
let t4 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l'));
|
||||||
t4.apply(&mut state);
|
t4.apply(&mut state.doc);
|
||||||
|
state.selection = state.selection.clone().map(t4.changes());
|
||||||
let t5 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('o'));
|
let t5 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('o'));
|
||||||
t5.apply(&mut state);
|
t5.apply(&mut state.doc);
|
||||||
|
state.selection = state.selection.clone().map(t5.changes());
|
||||||
|
|
||||||
assert_eq!(state.doc, Rope::from_str("hello"));
|
assert_eq!(state.doc, Rope::from_str("hello"));
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ pub struct Document {
|
|||||||
// rope + selection
|
// rope + selection
|
||||||
pub(crate) id: DocumentId,
|
pub(crate) id: DocumentId,
|
||||||
state: State,
|
state: State,
|
||||||
|
|
||||||
path: Option<PathBuf>,
|
path: Option<PathBuf>,
|
||||||
|
|
||||||
/// Current editing mode.
|
/// Current editing mode.
|
||||||
@ -185,9 +186,16 @@ pub fn set_selection(&mut self, selection: Selection) {
|
|||||||
fn _apply(&mut self, transaction: &Transaction) -> bool {
|
fn _apply(&mut self, transaction: &Transaction) -> bool {
|
||||||
let old_doc = self.text().clone();
|
let old_doc = self.text().clone();
|
||||||
|
|
||||||
let success = transaction.apply(&mut self.state);
|
let success = transaction.changes().apply(&mut self.state.doc);
|
||||||
|
|
||||||
if !transaction.changes().is_empty() {
|
if !transaction.changes().is_empty() {
|
||||||
|
// update the selection: either take the selection specified in the transaction, or map the
|
||||||
|
// current selection through changes.
|
||||||
|
self.state.selection = transaction
|
||||||
|
.selection()
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_else(|| self.selection().clone().map(transaction.changes()));
|
||||||
|
|
||||||
self.version += 1;
|
self.version += 1;
|
||||||
|
|
||||||
// update tree-sitter syntax tree
|
// update tree-sitter syntax tree
|
||||||
@ -415,7 +423,7 @@ fn changeset_to_changes() {
|
|||||||
|
|
||||||
// delete
|
// delete
|
||||||
|
|
||||||
let transaction = transaction.invert(&old_doc);
|
let transaction = transaction.invert(&old_doc.doc);
|
||||||
let old_doc = doc.state.clone();
|
let old_doc = doc.state.clone();
|
||||||
doc.apply(&transaction);
|
doc.apply(&transaction);
|
||||||
let changes = Client::changeset_to_changes(&old_doc.doc, doc.text(), transaction.changes());
|
let changes = Client::changeset_to_changes(&old_doc.doc, doc.text(), transaction.changes());
|
||||||
|
Loading…
Reference in New Issue
Block a user