on master help sign in
Remove State from a few more signatures.
59e6024Blaž Hrastnik
helix-core/src/comment.rs+10−8
@@ -1,4 +1,6 @@
1+use crate::{
1−use crate::{find_first_non_whitespace_char2, Change, RopeSlice, State, Tendril, Transaction};
2+ find_first_non_whitespace_char2, Change, Rope, RopeSlice, Selection, Tendril, Transaction,
3+};
2use core::ops::Range;
4use core::ops::Range;
3use std::borrow::Cow;
5use std::borrow::Cow;
4
6
@@ -35,14 +37,14 @@ fn find_line_comment(
35 (commented, skipped, min)
37 (commented, skipped, min)
36}
38}
37
39
38−pub fn toggle_line_comments(state: &State) -> Transaction {
40+pub fn toggle_line_comments(doc: &Rope, selection: &Selection) -> Transaction {
39− let text = state.doc.slice(..);
41+ let text = doc.slice(..);
40 let mut changes: Vec<Change> = Vec::new();
42 let mut changes: Vec<Change> = Vec::new();
41
43
42 let token = "//";
44 let token = "//";
43 let comment = Tendril::from(format!("{} ", token));
45 let comment = Tendril::from(format!("{} ", token));
44
46
45− for selection in state.selection.ranges() {
47+ for selection in selection.ranges() {
46 let start = text.char_to_line(selection.from());
48 let start = text.char_to_line(selection.from());
47 let end = text.char_to_line(selection.to());
49 let end = text.char_to_line(selection.to());
48 let lines = start..end + 1;
50 let lines = start..end + 1;
@@ -67,7 +69,7 @@ pub fn toggle_line_comments(state: &State) -> Transaction {
67 }
69 }
68 }
70 }
69 }
71 }
70− Transaction::change(&state.doc, changes.into_iter())
72+ Transaction::change(doc, changes.into_iter())
71}
73}
72
74
73#[cfg(test)]
75#[cfg(test)]
@@ -76,7 +78,7 @@ mod test {
76
78
77 #[test]
79 #[test]
78 fn test_find_line_comment() {
80 fn test_find_line_comment() {
79− use crate::{Rope, Selection};
81+ use crate::State;
80
82
81 // four lines, two space indented, except for line 1 which is blank.
83 // four lines, two space indented, except for line 1 which is blank.
82 let doc = Rope::from(" 1\n\n 2\n 3");
84 let doc = Rope::from(" 1\n\n 2\n 3");
@@ -92,13 +94,13 @@ mod test {
92 assert_eq!(res, (false, vec![1], 2));
94 assert_eq!(res, (false, vec![1], 2));
93
95
94 // comment
96 // comment
95− let transaction = toggle_line_comments(&state);
97+ let transaction = toggle_line_comments(&state.doc, &state.selection);
96 transaction.apply(&mut state);
98 transaction.apply(&mut state);
97
99
98 assert_eq!(state.doc, " // 1\n\n // 2\n // 3");
100 assert_eq!(state.doc, " // 1\n\n // 2\n // 3");
99
101
100 // uncomment
102 // uncomment
101− let transaction = toggle_line_comments(&state);
103+ let transaction = toggle_line_comments(&state.doc, &state.selection);
102 transaction.apply(&mut state);
104 transaction.apply(&mut state);
103 assert_eq!(state.doc, " 1\n\n 2\n 3");
105 assert_eq!(state.doc, " 1\n\n 2\n 3");
104
106
helix-core/src/indent.rs+13−14
@@ -2,7 +2,7 @@ use crate::{
2 find_first_non_whitespace_char,
2 find_first_non_whitespace_char,
3 syntax::Syntax,
3 syntax::Syntax,
4 tree_sitter::{Node, Tree},
4 tree_sitter::{Node, Tree},
5− Rope, RopeSlice, State,
5+ Rope, RopeSlice,
6};
6};
7
7
8/// To determine indentation of a newly inserted line, figure out the indentation at the last col
8/// To determine indentation of a newly inserted line, figure out the indentation at the last col
@@ -162,12 +162,12 @@ fn calculate_indentation(node: Option<Node>, newline: bool) -> usize {
162 increment as usize
162 increment as usize
163}
163}
164
164
165−fn suggested_indent_for_line(syntax: Option<&Syntax>, state: &State, line_num: usize) -> usize {
165+fn suggested_indent_for_line(syntax: Option<&Syntax>, text: RopeSlice, line_num: usize) -> usize {
166− let line = state.doc.line(line_num);
166+ let line = text.line(line_num);
167 let current = indent_level_for_line(line);
167 let current = indent_level_for_line(line);
168
168
169− if let Some(start) = find_first_non_whitespace_char(state.doc.slice(..), line_num) {
169+ if let Some(start) = find_first_non_whitespace_char(text, line_num) {
170− return suggested_indent_for_pos(syntax, state, start, false);
170+ return suggested_indent_for_pos(syntax, text, start, false);
171 };
171 };
172
172
173 // if the line is blank, indent should be zero
173 // if the line is blank, indent should be zero
@@ -179,12 +179,12 @@ fn suggested_indent_for_line(syntax: Option<&Syntax>, state: &State, line_num: u
179// - it should look up the wrapper node and count it too when we press o/O
179// - it should look up the wrapper node and count it too when we press o/O
180pub fn suggested_indent_for_pos(
180pub fn suggested_indent_for_pos(
181 syntax: Option<&Syntax>,
181 syntax: Option<&Syntax>,
182− state: &State,
182+ text: RopeSlice,
183 pos: usize,
183 pos: usize,
184 new_line: bool,
184 new_line: bool,
185) -> usize {
185) -> usize {
186 if let Some(syntax) = syntax {
186 if let Some(syntax) = syntax {
187− let byte_start = state.doc.char_to_byte(pos);
187+ let byte_start = text.char_to_byte(pos);
188 let node = get_highest_syntax_node_at_bytepos(syntax, byte_start);
188 let node = get_highest_syntax_node_at_bytepos(syntax, byte_start);
189
189
190 // TODO: special case for comments
190 // TODO: special case for comments
@@ -279,7 +279,7 @@ std::panic::set_hook(Box::new(move |info| {
279 1
279 1
280}}}
280}}}
281
281
282−pub fn change<I>(state: &State, changes: I) -> Self
282+pub fn change<I>(document: &Document, changes: I) -> Self
283where
283where
284 I: IntoIterator<Item = Change> + ExactSizeIterator,
284 I: IntoIterator<Item = Change> + ExactSizeIterator,
285{
285{
@@ -288,20 +288,19 @@ where
288",
288",
289 );
289 );
290
290
291− let state = State::new(doc);
291+ let doc = Rope::from(doc);
292− // TODO: set_language
293 let language_config = crate::syntax::LOADER
292 let language_config = crate::syntax::LOADER
294 .language_config_for_scope("source.rust")
293 .language_config_for_scope("source.rust")
295 .unwrap();
294 .unwrap();
296 let highlight_config = language_config.highlight_config(&[]).unwrap();
295 let highlight_config = language_config.highlight_config(&[]).unwrap();
297− let syntax = Syntax::new(&state.doc, highlight_config.clone());
296+ let syntax = Syntax::new(&doc, highlight_config.clone());
298− let text = state.doc.slice(..);
297+ let text = doc.slice(..);
299
298
300− for i in 0..state.doc.len_lines() {
299+ for i in 0..doc.len_lines() {
301 let line = text.line(i);
300 let line = text.line(i);
302 let indent = indent_level_for_line(line);
301 let indent = indent_level_for_line(line);
303 assert_eq!(
302 assert_eq!(
304− suggested_indent_for_line(Some(&syntax), &state, i),
303+ suggested_indent_for_line(Some(&syntax), text, i),
305 indent,
304 indent,
306 "line {}: {}",
305 "line {}: {}",
307 i,
306 i,
helix-core/src/transaction.rs+13−11
@@ -409,9 +409,9 @@ pub struct Transaction {
409
409
410impl Transaction {
410impl Transaction {
411 /// Create a new, empty transaction.
411 /// Create a new, empty transaction.
412− pub fn new(state: &mut State) -> Self {
412+ pub fn new(doc: &Rope) -> Self {
413 Self {
413 Self {
414− changes: ChangeSet::new(&state.doc),
414+ changes: ChangeSet::new(doc),
415 selection: None,
415 selection: None,
416 }
416 }
417 }
417 }
@@ -490,16 +490,18 @@ impl Transaction {
490 }
490 }
491
491
492 /// Generate a transaction with a change per selection range.
492 /// Generate a transaction with a change per selection range.
493− pub fn change_by_selection<F>(state: &State, f: F) -> Self
493+ pub fn change_by_selection<F>(doc: &Rope, selection: &Selection, f: F) -> Self
494 where
494 where
495 F: FnMut(&Range) -> Change,
495 F: FnMut(&Range) -> Change,
496 {
496 {
497− Self::change(&state.doc, state.selection.ranges().iter().map(f))
497+ Self::change(doc, selection.ranges().iter().map(f))
498 }
498 }
499
499
500 /// Insert text at each selection head.
500 /// Insert text at each selection head.
501− pub fn insert(state: &State, text: Tendril) -> Self {
501+ pub fn insert(doc: &Rope, selection: &Selection, text: Tendril) -> Self {
502+ Self::change_by_selection(doc, selection, |range| {
502− Self::change_by_selection(state, |range| (range.head, range.head, Some(text.clone())))
503+ (range.head, range.head, Some(text.clone()))
504+ })
503 }
505 }
504}
506}
505
507
@@ -628,15 +630,15 @@ mod test {
628 #[test]
630 #[test]
629 fn optimized_composition() {
631 fn optimized_composition() {
630 let mut state = State::new("".into());
632 let mut state = State::new("".into());
631− let t1 = Transaction::insert(&state, Tendril::from_char('h'));
633+ let t1 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('h'));
632 t1.apply(&mut state);
634 t1.apply(&mut state);
633− let t2 = Transaction::insert(&state, Tendril::from_char('e'));
635+ let t2 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('e'));
634 t2.apply(&mut state);
636 t2.apply(&mut state);
635− let t3 = Transaction::insert(&state, Tendril::from_char('l'));
637+ let t3 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l'));
636 t3.apply(&mut state);
638 t3.apply(&mut state);
637− let t4 = Transaction::insert(&state, Tendril::from_char('l'));
639+ let t4 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l'));
638 t4.apply(&mut state);
640 t4.apply(&mut state);
639− let t5 = Transaction::insert(&state, Tendril::from_char('o'));
641+ let t5 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('o'));
640 t5.apply(&mut state);
642 t5.apply(&mut state);
641
643
642 assert_eq!(state.doc, Rope::from_str("hello"));
644 assert_eq!(state.doc, Rope::from_str("hello"));
helix-lsp/src/lib.rs+6−9
@@ -30,7 +30,7 @@ pub enum Error {
30
30
31pub mod util {
31pub mod util {
32 use super::*;
32 use super::*;
33− use helix_core::{Range, RopeSlice, State, Transaction};
33+ use helix_core::{Range, Rope, RopeSlice, Transaction};
34
34
35 pub fn lsp_pos_to_pos(doc: RopeSlice, pos: lsp::Position) -> usize {
35 pub fn lsp_pos_to_pos(doc: RopeSlice, pos: lsp::Position) -> usize {
36 let line = doc.line_to_char(pos.line as usize);
36 let line = doc.line_to_char(pos.line as usize);
@@ -52,13 +52,10 @@ pub mod util {
52 lsp::Range::new(start, end)
52 lsp::Range::new(start, end)
53 }
53 }
54
54
55− pub fn generate_transaction_from_edits(
55+ pub fn generate_transaction_from_edits(doc: &Rope, edits: Vec<lsp::TextEdit>) -> Transaction {
56− state: &State,
56+ let text = doc.slice(..); // would be unnecessary if Transaction::change took Rope | RopeSlice
57− edits: Vec<lsp::TextEdit>,
58− ) -> Transaction {
59− let doc = state.doc.slice(..);
60 Transaction::change(
57 Transaction::change(
61− &state.doc,
58+ doc,
62 edits.into_iter().map(|edit| {
59 edits.into_iter().map(|edit| {
63 // simplify "" into None for cleaner changesets
60 // simplify "" into None for cleaner changesets
64 let replacement = if !edit.new_text.is_empty() {
61 let replacement = if !edit.new_text.is_empty() {
@@ -67,8 +64,8 @@ pub mod util {
67 None
64 None
68 };
65 };
69
66
70− let start = lsp_pos_to_pos(doc, edit.range.start);
67+ let start = lsp_pos_to_pos(text, edit.range.start);
71− let end = lsp_pos_to_pos(doc, edit.range.end);
68+ let end = lsp_pos_to_pos(text, edit.range.end);
72 (start, end, replacement)
69 (start, end, replacement)
73 }),
70 }),
74 )
71 )
helix-term/src/commands.rs+25−22
@@ -4,8 +4,8 @@ use helix_core::{
4 movement, object, pos_at_coords,
4 movement, object, pos_at_coords,
5 regex::{self, Regex},
5 regex::{self, Regex},
6 register, search, selection,
6 register, search, selection,
7− state::{Direction, Granularity, State},
7+ state::{Direction, Granularity},
8− Change, ChangeSet, Position, Range, RopeSlice, Selection, Tendril, Transaction,
8+ Change, ChangeSet, Position, Range, Rope, RopeSlice, Selection, Tendril, Transaction,
9};
9};
10
10
11use once_cell::sync::Lazy;
11use once_cell::sync::Lazy;
@@ -107,7 +107,7 @@ pub fn move_line_down(cx: &mut Context) {
107
107
108pub fn move_line_end(cx: &mut Context) {
108pub fn move_line_end(cx: &mut Context) {
109 let doc = cx.doc();
109 let doc = cx.doc();
110− let lines = selection_lines(&doc.state);
110+ let lines = selection_lines(doc.text(), doc.selection());
111
111
112 let positions = lines
112 let positions = lines
113 .into_iter()
113 .into_iter()
@@ -127,7 +127,7 @@ pub fn move_line_end(cx: &mut Context) {
127
127
128pub fn move_line_start(cx: &mut Context) {
128pub fn move_line_start(cx: &mut Context) {
129 let doc = cx.doc();
129 let doc = cx.doc();
130− let lines = selection_lines(&doc.state);
130+ let lines = selection_lines(doc.text(), doc.selection());
131
131
132 let positions = lines
132 let positions = lines
133 .into_iter()
133 .into_iter()
@@ -586,8 +586,9 @@ pub fn extend_line(cx: &mut Context) {
586// heuristic: append changes to history after each command, unless we're in insert mode
586// heuristic: append changes to history after each command, unless we're in insert mode
587
587
588fn _delete_selection(doc: &mut Document) {
588fn _delete_selection(doc: &mut Document) {
589− let transaction =
590− Transaction::change_by_selection(&doc.state, |range| (range.from(), range.to() + 1, None));
589+ let transaction = Transaction::change_by_selection(doc.text(), doc.selection(), |range| {
590+ (range.from(), range.to() + 1, None)
591+ });
591 doc.apply(&transaction);
592 doc.apply(&transaction);
592}
593}
593
594
@@ -722,12 +723,11 @@ pub fn buffer_picker(cx: &mut Context) {
722}
723}
723
724
724// calculate line numbers for each selection range
725// calculate line numbers for each selection range
725−fn selection_lines(state: &State) -> Vec<usize> {
726+fn selection_lines(doc: &Rope, selection: &Selection) -> Vec<usize> {
726− let mut lines = state
727− .selection
727+ let mut lines = selection
728 .ranges()
728 .ranges()
729 .iter()
729 .iter()
730− .map(|range| state.doc.char_to_line(range.head))
730+ .map(|range| doc.char_to_line(range.head))
731 .collect::<Vec<_>>();
731 .collect::<Vec<_>>();
732
732
733 lines.sort_unstable(); // sorting by usize so _unstable is preferred
733 lines.sort_unstable(); // sorting by usize so _unstable is preferred
@@ -758,19 +758,21 @@ pub fn open_below(cx: &mut Context) {
758 let doc = cx.doc();
758 let doc = cx.doc();
759 enter_insert_mode(doc);
759 enter_insert_mode(doc);
760
760
761− let lines = selection_lines(&doc.state);
761+ let lines = selection_lines(doc.text(), doc.selection());
762
762
763 let positions = lines.into_iter().map(|index| {
763 let positions = lines.into_iter().map(|index| {
764 // adjust all positions to the end of the line (next line minus one)
764 // adjust all positions to the end of the line (next line minus one)
765 doc.text().line_to_char(index + 1).saturating_sub(1)
765 doc.text().line_to_char(index + 1).saturating_sub(1)
766 });
766 });
767
767
768+ let text = doc.text().slice(..);
769+
768 let changes: Vec<Change> = positions
770 let changes: Vec<Change> = positions
769 .map(|index| {
771 .map(|index| {
770 // TODO: share logic with insert_newline for indentation
772 // TODO: share logic with insert_newline for indentation
771 let indent_level = helix_core::indent::suggested_indent_for_pos(
773 let indent_level = helix_core::indent::suggested_indent_for_pos(
772 doc.syntax.as_ref(),
774 doc.syntax.as_ref(),
773− &doc.state,
775+ text,
774 index,
776 index,
775 true,
777 true,
776 );
778 );
@@ -955,7 +957,7 @@ pub mod insert {
955 pub fn insert_char(cx: &mut Context, c: char) {
957 pub fn insert_char(cx: &mut Context, c: char) {
956 let doc = cx.doc();
958 let doc = cx.doc();
957 let c = Tendril::from_char(c);
959 let c = Tendril::from_char(c);
958− let transaction = Transaction::insert(&doc.state, c);
960+ let transaction = Transaction::insert(doc.text(), doc.selection(), c);
959
961
960 doc.apply(&transaction);
962 doc.apply(&transaction);
961 }
963 }
@@ -966,10 +968,11 @@ pub mod insert {
966
968
967 pub fn insert_newline(cx: &mut Context) {
969 pub fn insert_newline(cx: &mut Context) {
968 let doc = cx.doc();
970 let doc = cx.doc();
971+ let text = doc.text().slice(..);
969− let transaction = Transaction::change_by_selection(&doc.state, |range| {
972+ let transaction = Transaction::change_by_selection(doc.text(), doc.selection(), |range| {
970 let indent_level = helix_core::indent::suggested_indent_for_pos(
973 let indent_level = helix_core::indent::suggested_indent_for_pos(
971 doc.syntax.as_ref(),
974 doc.syntax.as_ref(),
972− &doc.state,
975+ text,
973 range.head,
976 range.head,
974 true,
977 true,
975 );
978 );
@@ -987,7 +990,7 @@ pub mod insert {
987 let count = cx.count;
990 let count = cx.count;
988 let doc = cx.doc();
991 let doc = cx.doc();
989 let text = doc.text().slice(..);
992 let text = doc.text().slice(..);
990− let transaction = Transaction::change_by_selection(&doc.state, |range| {
993+ let transaction = Transaction::change_by_selection(doc.text(), doc.selection(), |range| {
991 (
994 (
992 graphemes::nth_prev_grapheme_boundary(text, range.head, count),
995 graphemes::nth_prev_grapheme_boundary(text, range.head, count),
993 range.head,
996 range.head,
@@ -1001,7 +1004,7 @@ pub mod insert {
1001 let count = cx.count;
1004 let count = cx.count;
1002 let doc = cx.doc();
1005 let doc = cx.doc();
1003 let text = doc.text().slice(..);
1006 let text = doc.text().slice(..);
1004− let transaction = Transaction::change_by_selection(&doc.state, |range| {
1007+ let transaction = Transaction::change_by_selection(doc.text(), doc.selection(), |range| {
1005 (
1008 (
1006 range.head,
1009 range.head,
1007 graphemes::nth_next_grapheme_boundary(text, range.head, count),
1010 graphemes::nth_next_grapheme_boundary(text, range.head, count),
@@ -1076,12 +1079,12 @@ pub fn paste(cx: &mut Context) {
1076 // paste on the next line
1079 // paste on the next line
1077 // TODO: can simply take a range + modifier and compute the right pos without ifs
1080 // TODO: can simply take a range + modifier and compute the right pos without ifs
1078 let text = doc.text();
1081 let text = doc.text();
1079− Transaction::change_by_selection(&doc.state, |range| {
1082+ Transaction::change_by_selection(doc.text(), doc.selection(), |range| {
1080 let line_end = text.line_to_char(text.char_to_line(range.head) + 1);
1083 let line_end = text.line_to_char(text.char_to_line(range.head) + 1);
1081 (line_end, line_end, Some(values.next().unwrap()))
1084 (line_end, line_end, Some(values.next().unwrap()))
1082 })
1085 })
1083 } else {
1086 } else {
1084− Transaction::change_by_selection(&doc.state, |range| {
1087+ Transaction::change_by_selection(doc.text(), doc.selection(), |range| {
1085 (range.head + 1, range.head + 1, Some(values.next().unwrap()))
1088 (range.head + 1, range.head + 1, Some(values.next().unwrap()))
1086 })
1089 })
1087 };
1090 };
@@ -1190,7 +1193,7 @@ pub fn format_selections(cx: &mut Context) {
1190 ))
1193 ))
1191 .unwrap_or_default();
1194 .unwrap_or_default();
1192
1195
1193− let transaction = helix_lsp::util::generate_transaction_from_edits(&doc.state, edits);
1196+ let transaction = helix_lsp::util::generate_transaction_from_edits(doc.text(), edits);
1194
1197
1195 doc.apply(&transaction);
1198 doc.apply(&transaction);
1196 }
1199 }
@@ -1352,7 +1355,7 @@ pub fn completion(cx: &mut Context) {
1352
1355
1353 // TODO: <-- if state has changed by further input, transaction will panic on len
1356 // TODO: <-- if state has changed by further input, transaction will panic on len
1354 let transaction =
1357 let transaction =
1355− util::generate_transaction_from_edits(&doc.state, vec![edit]);
1358+ util::generate_transaction_from_edits(doc.text(), vec![edit]);
1356 doc.apply(&transaction);
1359 doc.apply(&transaction);
1357 // TODO: doc.append_changes_to_history(); if not in insert mode?
1360 // TODO: doc.append_changes_to_history(); if not in insert mode?
1358 }
1361 }
@@ -1421,7 +1424,7 @@ pub fn next_view(cx: &mut Context) {
1421// comments
1424// comments
1422pub fn toggle_comments(cx: &mut Context) {
1425pub fn toggle_comments(cx: &mut Context) {
1423 let doc = cx.doc();
1426 let doc = cx.doc();
1424− let transaction = comment::toggle_line_comments(&doc.state);
1427+ let transaction = comment::toggle_line_comments(doc.text(), doc.selection());
1425
1428
1426 doc.apply(&transaction);
1429 doc.apply(&transaction);
1427}
1430}
helix-term/src/ui/editor.rs+1−1
@@ -6,7 +6,7 @@ use crate::ui::text_color;
6use helix_core::{
6use helix_core::{
7 indent::TAB_WIDTH,
7 indent::TAB_WIDTH,
8 syntax::{self, HighlightEvent},
8 syntax::{self, HighlightEvent},
9− Position, Range, State,
9+ Position, Range,
10};
10};
11use helix_view::{document::Mode, Document, Editor, Theme, View};
11use helix_view::{document::Mode, Document, Editor, Theme, View};
12use std::borrow::Cow;
12use std::borrow::Cow;
helix-view/src/document.rs+1−1
@@ -346,7 +346,7 @@ mod test {
346
346
347 // insert
347 // insert
348
348
349− let transaction = Transaction::insert(&doc.state, " world".into());
349+ let transaction = Transaction::insert(doc.text(), doc.selection(), " world".into());
350 let old_doc = doc.state.clone();
350 let old_doc = doc.state.clone();
351 doc.apply(&transaction);
351 doc.apply(&transaction);
352 let changes = Client::changeset_to_changes(&old_doc.doc, doc.text(), transaction.changes());
352 let changes = Client::changeset_to_changes(&old_doc.doc, doc.text(), transaction.changes());