(&mut self, path: P) -> Result<()>
67 | where
68 | P: AsRef (&self, pos: P) -> Absolute
124 | where
125 | P: Position,
126 | {
127 | pos.absolute(&self)
128 | }
129 | pub fn position_to_point (&self, pos: P) -> Point
130 | where
131 | P: Position,
132 | {
133 | pos.point(&self)
134 | }
135 |
136 | pub fn len(&self) -> Absolute {
137 | self.rope.len_bytes().into()
138 | }
139 |
140 | pub fn len_lines(&self) -> usize {
141 | self.rope.len_lines()
142 | }
143 |
144 | pub fn point (&self, pos: P) -> char
182 | where
183 | P: Position,
184 | {
185 | let a = pos.absolute(&self);
186 | self.rope.char(self.rope.byte_to_char(a.index))
187 | }
188 |
189 | pub fn backward(&mut self, expand_selection: bool, word_boundary: bool) {
190 | let b = self.clone();
191 | for s in &mut self.carets.iter_mut() {
192 | // TODO: Found a way to not clone, even if it's cheap
193 | s.move_backward(expand_selection, word_boundary, &b);
194 | }
195 |
196 | self.carets.merge();
197 | }
198 |
199 | pub fn forward(&mut self, expand_selection: bool, word_boundary: bool) {
200 | let b = self.clone();
201 | for s in &mut self.carets.iter_mut() {
202 | s.move_forward(expand_selection, word_boundary, &b);
203 | }
204 |
205 | self.carets.merge();
206 | }
207 |
208 | pub fn up(&mut self, expand_selection: bool) {
209 | let b = self.clone();
210 | for s in &mut self.carets.iter_mut() {
211 | s.move_up(expand_selection, &b);
212 | }
213 |
214 | self.carets.merge();
215 | }
216 | pub fn down(&mut self, expand_selection: bool) {
217 | let b = self.clone();
218 | for s in &mut self.carets.iter_mut() {
219 | s.move_down(expand_selection, &b);
220 | }
221 |
222 | self.carets.merge();
223 | }
224 | pub fn duplicate_down(&mut self) {
225 | self.carets.sort_unstable();
226 |
227 | if let Some(c) = self.carets.last().and_then(|c| c.duplicate_down(&self)) {
228 | self.carets.push(c);
229 | }
230 | self.carets.merge();
231 | }
232 |
233 | pub fn duplicate_up(&mut self) {
234 | self.carets.sort_unstable();
235 |
236 | if let Some(c) = self.carets.first().and_then(|c| c.duplicate_up(&self)) {
237 | self.carets.push(c);
238 | }
239 | self.carets.merge();
240 | }
241 |
242 | pub fn have_selection(&self) -> bool {
243 | self.carets.iter().any(|c| !c.selection_is_empty())
244 | }
245 |
246 | pub fn end(&mut self, expand_selection: bool) {
247 | let b = self.clone();
248 | for s in &mut self.carets.iter_mut() {
249 | s.move_end(expand_selection, &b);
250 | }
251 |
252 | self.carets.merge();
253 | }
254 |
255 | pub fn home(&mut self, expand_selection: bool) {
256 | let b = self.clone();
257 | for s in &mut self.carets.iter_mut() {
258 | s.move_home(expand_selection, &b);
259 | }
260 | self.carets.merge();
261 | }
262 |
263 | pub fn insert(&mut self, text: &str, expand_selection: bool) {
264 | for i in 0..self.carets.len() {
265 | let r = self.carets[i].range();
266 | self.edit(&r, text);
267 | let b = self.clone();
268 | self.carets[i].set_index(r.start + text.len(), !expand_selection, true, &b);
269 | }
270 | self.carets.merge();
271 | }
272 |
273 | pub fn backspace(&mut self) -> bool {
274 | let mut did_nothing = true;
275 | for i in 0..self.carets.len() {
276 | if !self.carets[i].selection_is_empty() {
277 | // delete all the selection
278 | let r = self.carets[i].range();
279 | self.edit(&r, "");
280 | let b = self.clone();
281 | self.carets[i].set_index(r.start, true, true, &b);
282 |
283 | did_nothing = false;
284 | } else if self.carets[i].index > 0.into() {
285 | // delete the preceding grapheme
286 | let r = rope_utils::prev_grapheme_boundary(&self.rope.slice(..), self.carets[i].index).into()
287 | ..self.carets[i].index;
288 | self.edit(&r, "");
289 | let b = self.clone();
290 | self.carets[i].set_index(r.start, true, true, &b);
291 |
292 | did_nothing = false;
293 | } else {
294 | continue;
295 | }
296 | }
297 | if !did_nothing {
298 | self.carets.merge();
299 | return true;
300 | }
301 | false
302 | }
303 |
304 | pub fn delete(&mut self) -> bool {
305 | let mut did_nothing = true;
306 | for i in 0..self.carets.len() {
307 | if !self.carets[i].selection_is_empty() {
308 | let r = self.carets[i].range();
309 | self.edit(&r, "");
310 | let b = self.clone();
311 | self.carets[i].set_index(r.start, true, true, &b);
312 |
313 | did_nothing = false;
314 | } else if self.carets[i].index < self.rope.len_bytes().into() {
315 | let r = self.carets[i].index
316 | ..rope_utils::next_grapheme_boundary(&self.rope.slice(..), self.carets[i].index).into();
317 | self.edit(&r, "");
318 | let b = self.clone();
319 | self.carets[i].set_index(r.start, true, true, &b);
320 |
321 | did_nothing = false;
322 | } else {
323 | continue;
324 | }
325 | }
326 | if !did_nothing {
327 | self.carets.merge();
328 | return true;
329 | }
330 | false
331 | }
332 |
333 | pub fn tab(&mut self, indentation: Indentation) {
334 | for i in 0..self.carets.len() {
335 | match self.carets[i].selected_lines_range(&self) {
336 | Some(line_range) if line_range.start() != line_range.end() => {
337 | // TODO: Find a better way to iterate over line of a selection
338 | for line_idx in line_range.start().index..line_range.end().index + 1 {
339 | let line_start: Absolute = self.rope.line_to_byte(line_idx).into();
340 | let r = line_start..line_start;
341 | let text = match indentation {
342 | Indentation::Space(n) => " ".repeat(n).to_owned(),
343 | Indentation::Tab(_) => "\t".to_owned(),
344 | };
345 | self.edit(&r, &text);
346 | }
347 | }
348 | _ => {
349 | let r = self.carets[i].range();
350 | let text = match indentation {
351 | Indentation::Space(n) => {
352 | let start: usize = self.carets[i].col().into();
353 | let nb_space = n - start % n;
354 | " ".repeat(nb_space).to_owned()
355 | }
356 | Indentation::Tab(_) => "\t".to_owned(),
357 | };
358 | self.edit(&r, &text);
359 | let b = self.clone();
360 | self.carets[i].set_index(r.start + Relative::from(text.len()), true, true, &b);
361 | }
362 | }
363 | }
364 | self.carets.merge();
365 | }
366 |
367 | pub fn indent(&mut self, indentation: Indentation) {
368 | if self.have_selection() {
369 | return;
370 | }
371 | for i in 0..self.carets.len() {
372 | match self.carets[i].index.line(&self).index {
373 | 0 => (),
374 | max if max == self.len_lines() => (),
375 | l => {
376 | let l = Line::from(l);
377 | let indent = l.prev().unwrap().indentation(&self);
378 | let text = match indentation {
379 | Indentation::Space(_) => {
380 | " ".repeat(indent.into()).to_owned()
381 | }
382 | Indentation::Tab(_) => "\t".repeat(indent.index / indentation.visible_len()).to_owned(),
383 | };
384 | self.edit(&Range{start: l.start(&self),end: l.start(&self)}, &text );
385 | let b = self.clone();
386 | self.carets[i].set_index(l.start(&b) + Relative::from(text.len()), true, true, &b);
387 | }
388 |
389 | }
390 | }
391 | }
392 |
393 | pub fn edit(&mut self, range: &Range (&mut self, pos: P, expand_selection: bool, word_boundary: bool)
496 | where
497 | P: Position,
498 | {
499 | let p = self.position_to_absolute(pos);
500 | self.cancel_mutli_carets();
501 | let b = self.clone();
502 | if word_boundary {
503 | let start = self.word_end(p);
504 | let end = self.word_start(p);
505 | if expand_selection {
506 | if self.carets[0].index == self.carets[0].start() {
507 | self.carets[0].set_index(start, !expand_selection, true, &b);
508 | } else {
509 | self.carets[0].set_index(end, !expand_selection, true, &b);
510 | }
511 | } else {
512 | self.carets[0].set_index(start, true, true, &b);
513 | self.carets[0].set_index(end, false, true, &b);
514 | }
515 | } else {
516 | self.carets[0].set_index(p, !expand_selection, true, &b);
517 | }
518 | }
519 |
520 | pub fn selected_text(&self, line_feed: LineFeed) -> String {
521 | let mut s = String::new();
522 | let multi = self.carets.len() > 1;
523 | for c in self.carets.iter() {
524 | for chuck in self
525 | .rope
526 | .slice(self.rope.byte_to_char(c.start().index)..self.rope.byte_to_char(c.end().index))
527 | .chunks()
528 | {
529 | s.push_str(chuck)
530 | }
531 | if multi {
532 | s.push_str(&line_feed.to_str())
533 | }
534 | }
535 | s
536 | }
537 |
538 | pub fn main_cursor_selected_text(&self) -> String {
539 | let mut s = String::new();
540 | let c = self.main_caret();
541 | for chuck in self
542 | .rope
543 | .slice(self.rope.byte_to_char(c.start().index)..self.rope.byte_to_char(c.end().index))
544 | .chunks()
545 | {
546 | s.push_str(chuck)
547 | }
548 | s
549 | }
550 |
551 | pub fn cancel_selection(&mut self) {
552 | for c in &mut self.carets.iter_mut() {
553 | c.cancel_selection();
554 | }
555 | }
556 |
557 | pub fn select_all(&mut self) {
558 | self.cancel_mutli_carets();
559 | self.cancel_selection();
560 | self.move_main_caret_to(Absolute::from(0), false, false);
561 | self.move_main_caret_to(self.len(), true, false);
562 | }
563 |
564 | pub fn select_line(&mut self, line: Line, expand_selection: bool) {
565 | self.cancel_mutli_carets();
566 |
567 | if !expand_selection {
568 | self.cancel_selection();
569 | self.move_main_caret_to(line.start(&self), false, false);
570 | self.move_main_caret_to(line.end(&self), true, false);
571 | } else if self.main_caret().start() == self.main_caret().index {
572 | self.move_main_caret_to(line.start(&self), true, false);
573 | } else {
574 | self.move_main_caret_to(line.end(&self), true, false);
575 | }
576 | }
577 |
578 | pub fn caret_display_info(&self) -> String {
579 | if !self.has_many_carets() {
580 | format!(
581 | "Ln {}, Col {}",
582 | self.carets[0].line().index + 1,
583 | self.carets[0].col().index + 1
584 | )
585 | } else {
586 | format!("{} selections", self.carets.len())
587 | }
588 | }
589 | }
590 |
591 | impl ToString for Buffer {
592 | fn to_string(&self) -> String {
593 | self.rope.to_string()
594 | }
595 | }
596 |
597 | #[inline(always)]
598 | pub(super) fn start_bound_to_num(b: Bound<&Absolute>) -> Option(self, visitor: S) -> Result