@@ -3,7 +3,8 @@ use crate::event::{Error, Event, Result, Status, UndoMgmt};
33use crate :: map:: { form_map, CharMap } ;
44use crate :: searching:: { Match , Searcher } ;
55use crate :: utils:: {
6- get_range, modeline, tab_boundaries_backward, tab_boundaries_forward, trim, width, Loc , Size ,
6+ get_absolute_path, get_range, modeline, tab_boundaries_backward, tab_boundaries_forward, trim,
7+ width, Loc , Size ,
78} ;
89use ropey:: Rope ;
910use std:: fs:: File ;
@@ -101,6 +102,7 @@ impl Document {
101102 pub fn open < S : Into < String > > ( size : Size , file_name : S ) -> Result < Self > {
102103 let file_name = file_name. into ( ) ;
103104 let file = Rope :: from_reader ( BufReader :: new ( File :: open ( & file_name) ?) ) ?;
105+ let file_name = get_absolute_path ( & file_name) ;
104106 let mut this = Self {
105107 info : DocumentInfo {
106108 loaded_to : 0 ,
@@ -115,7 +117,7 @@ impl Document {
115117 lines : vec ! [ ] ,
116118 dbl_map : CharMap :: default ( ) ,
117119 tab_map : CharMap :: default ( ) ,
118- file_name : Some ( file_name ) ,
120+ file_name,
119121 cursor : Cursor :: default ( ) ,
120122 offset : Loc :: default ( ) ,
121123 size,
@@ -622,14 +624,42 @@ impl Document {
622624
623625 /// Move up by 1 page
624626 pub fn move_page_up ( & mut self ) {
625- self . move_to_y ( self . cursor . loc . y . saturating_sub ( self . size . h ) ) ;
627+ // Set x to 0
628+ self . cursor . loc . x = 0 ;
629+ self . char_ptr = 0 ;
626630 self . old_cursor = 0 ;
631+ // Calculate where to move the cursor
632+ let new_cursor_y = self . cursor . loc . y . saturating_sub ( self . size . h ) ;
633+ // Move to the new location and shift down offset proportionally
634+ self . cursor . loc . y = new_cursor_y;
635+ self . offset . y = self . offset . y . saturating_sub ( self . size . h ) ;
636+ // Clean up
637+ self . cancel_selection ( ) ;
627638 }
628639
629640 /// Move down by 1 page
630641 pub fn move_page_down ( & mut self ) {
631- self . move_to_y ( self . cursor . loc . y + self . size . h ) ;
642+ // Set x to 0
643+ self . cursor . loc . x = 0 ;
644+ self . char_ptr = 0 ;
632645 self . old_cursor = 0 ;
646+ // Calculate where to move the cursor
647+ let new_cursor_y = self . cursor . loc . y + self . size . h ;
648+ if new_cursor_y <= self . len_lines ( ) {
649+ // Cursor is in range, move to the new location and shift down offset proportionally
650+ self . cursor . loc . y = new_cursor_y;
651+ self . offset . y += self . size . h ;
652+ } else if self . len_lines ( ) < self . offset . y + self . size . h {
653+ // End line is in view, no need to move offset
654+ self . cursor . loc . y = self . len_lines ( ) . saturating_sub ( 1 ) ;
655+ } else {
656+ // Cursor would be out of range (adjust to bottom of document)
657+ self . cursor . loc . y = self . len_lines ( ) . saturating_sub ( 1 ) ;
658+ self . offset . y = self . len_lines ( ) . saturating_sub ( self . size . h ) ;
659+ }
660+ // Clean up
661+ self . load_to ( self . offset . y + self . size . h ) ;
662+ self . cancel_selection ( ) ;
633663 }
634664
635665 /// Moves to the previous word in the document
@@ -638,17 +668,23 @@ impl Document {
638668 if x == 0 && y != 0 {
639669 return Status :: StartOfLine ;
640670 }
641- let re = format ! ( "(\t | {{{}}}|^|\\ W| )" , self . tab_width) ;
642- if let Some ( mut mtch) = self . prev_match ( & re) {
643- let len = mtch. text . chars ( ) . count ( ) ;
644- let same = mtch. loc . x + len == x;
645- if !same {
646- mtch. loc . x += len;
671+ let re = format ! ( "(\t | {{{}}}|^|\\ W|$| )" , self . tab_width) ;
672+ let mut searcher = Searcher :: new ( & re) ;
673+ let line = self
674+ . line ( y)
675+ . unwrap_or_default ( )
676+ . chars ( )
677+ . take ( x)
678+ . collect :: < String > ( ) ;
679+ let mut matches = searcher. rfinds ( & line) ;
680+ if let Some ( mtch) = matches. first ( ) {
681+ if mtch. loc . x == x {
682+ matches. remove ( 0 ) ;
647683 }
684+ }
685+ if let Some ( mtch) = matches. first_mut ( ) {
686+ mtch. loc . y = self . loc ( ) . y ;
648687 self . move_to ( & mtch. loc ) ;
649- if same && self . loc ( ) . x != 0 {
650- return self . move_prev_word ( ) ;
651- }
652688 }
653689 self . old_cursor = self . loc ( ) . x ;
654690 Status :: None
@@ -1084,7 +1120,7 @@ impl Document {
10841120 x : self . cursor . loc . x . saturating_sub ( self . offset . x ) ,
10851121 y : self . cursor . loc . y . saturating_sub ( self . offset . y ) ,
10861122 } ;
1087- if result. x > self . size . w || result. y > self . size . h {
1123+ if result. x > self . size . w || result. y >= self . size . h {
10881124 return None ;
10891125 }
10901126 Some ( result)
0 commit comments