@@ -50,12 +50,13 @@ use crate::core::{
50
50
Rectangle , Shell , Size , SmolStr , Theme , Vector ,
51
51
} ;
52
52
53
+ use std:: borrow:: Cow ;
53
54
use std:: cell:: RefCell ;
54
55
use std:: fmt;
55
56
use std:: ops:: DerefMut ;
56
57
use std:: sync:: Arc ;
57
58
58
- pub use text:: editor:: { Action , Edit , Motion } ;
59
+ pub use text:: editor:: { Action , Edit , Line , LineEnding , Motion } ;
59
60
60
61
/// A multi-line text input.
61
62
///
@@ -349,69 +350,47 @@ where
349
350
}
350
351
351
352
/// Returns the text of the line at the given index, if it exists.
352
- pub fn line (
353
- & self ,
354
- index : usize ,
355
- ) -> Option < impl std:: ops:: Deref < Target = str > + ' _ > {
356
- std:: cell:: Ref :: filter_map ( self . 0 . borrow ( ) , |internal| {
357
- internal. editor . line ( index)
353
+ pub fn line ( & self , index : usize ) -> Option < Line < ' _ > > {
354
+ let internal = self . 0 . borrow ( ) ;
355
+ let line = internal. editor . line ( index) ?;
356
+
357
+ Some ( Line {
358
+ text : Cow :: Owned ( line. text . into_owned ( ) ) ,
359
+ ending : line. ending ,
358
360
} )
359
- . ok ( )
360
361
}
361
362
362
363
/// Returns an iterator of the text of the lines in the [`Content`].
363
- pub fn lines (
364
- & self ,
365
- ) -> impl Iterator < Item = impl std:: ops:: Deref < Target = str > + ' _ > {
366
- struct Lines < ' a , Renderer : text:: Renderer > {
367
- internal : std:: cell:: Ref < ' a , Internal < Renderer > > ,
368
- current : usize ,
369
- }
370
-
371
- impl < ' a , Renderer : text:: Renderer > Iterator for Lines < ' a , Renderer > {
372
- type Item = std:: cell:: Ref < ' a , str > ;
373
-
374
- fn next ( & mut self ) -> Option < Self :: Item > {
375
- let line = std:: cell:: Ref :: filter_map (
376
- std:: cell:: Ref :: clone ( & self . internal ) ,
377
- |internal| internal. editor . line ( self . current ) ,
378
- )
379
- . ok ( ) ?;
380
-
381
- self . current += 1 ;
382
-
383
- Some ( line)
384
- }
385
- }
386
-
387
- Lines {
388
- internal : self . 0 . borrow ( ) ,
389
- current : 0 ,
390
- }
364
+ pub fn lines ( & self ) -> impl Iterator < Item = Line < ' _ > > {
365
+ ( 0 ..)
366
+ . map ( |i| self . line ( i) )
367
+ . take_while ( Option :: is_some)
368
+ . flatten ( )
391
369
}
392
370
393
371
/// Returns the text of the [`Content`].
394
- ///
395
- /// Lines are joined with `'\n'`.
396
372
pub fn text ( & self ) -> String {
397
- let mut text = self . lines ( ) . enumerate ( ) . fold (
398
- String :: new ( ) ,
399
- |mut contents, ( i, line) | {
400
- if i > 0 {
401
- contents. push ( '\n' ) ;
402
- }
373
+ let mut contents = String :: new ( ) ;
374
+ let mut lines = self . lines ( ) . peekable ( ) ;
403
375
404
- contents. push_str ( & line) ;
376
+ while let Some ( line) = lines. next ( ) {
377
+ contents. push_str ( & line. text ) ;
405
378
406
- contents
407
- } ,
408
- ) ;
409
-
410
- if !text. ends_with ( '\n' ) {
411
- text. push ( '\n' ) ;
379
+ if lines. peek ( ) . is_some ( ) {
380
+ contents. push_str ( if line. ending == LineEnding :: None {
381
+ LineEnding :: default ( ) . as_str ( )
382
+ } else {
383
+ line. ending . as_str ( )
384
+ } ) ;
385
+ }
412
386
}
413
387
414
- text
388
+ contents
389
+ }
390
+
391
+ /// Returns the kind of [`LineEnding`] used for separating lines in the [`Content`].
392
+ pub fn line_ending ( & self ) -> Option < LineEnding > {
393
+ Some ( self . line ( 0 ) ?. ending )
415
394
}
416
395
417
396
/// Returns the selected text of the [`Content`].
0 commit comments