Repository: sxyazi/yazi (language: rust)

Issue:
The cursor disappears in the preview panel when resizing yazi.
### What system are you running Yazi on?

Linux Wayland

### What terminal are you running Yazi in?

kitty 0.35.2

### `yazi --debug` output

```Shell
Yazi
    Version: 0.3.0 (4150f401 2024-08-09)
    Debug  : false
    OS     : linux-x86_64 (unix)

Ya
    Version: 0.3.0

Emulator
    Emulator.via_env: ("xterm-kitty", "")
    Emulator.via_csi: Ok(Kitty)
    Emulator.detect : Kitty

Adapter
    Adapter.matches: Kitty

Desktop
    XDG_SESSION_TYPE: Some("wayland")
    WAYLAND_DISPLAY : Some("wayland-0")
    DISPLAY         : Some(":0")

SSH
    shared.in_ssh_connection: false

WSL
    /proc/sys/fs/binfmt_misc/WSLInterop: false

Variables
    SHELL              : Some("/usr/bin/fish")
    EDITOR             : Some("nvim")
    YAZI_FILE_ONE      : None
    YAZI_CONFIG_HOME   : None
    ZELLIJ_SESSION_NAME: None

Text Opener
    default: Some(Opener { run: "${EDITOR:-vi} \"$@\"", block: true, orphan: false, desc: "$EDITOR", for_: None, spread: true })
    block  : Some(Opener { run: "${EDITOR:-vi} \"$@\"", block: true, orphan: false, desc: "$EDITOR", for_: None, spread: true })

tmux
    TMUX   : false
    Version: 3.4

Dependencies
    file             : 5.45
    ueberzugpp       : 2.9.6
    ffmpegthumbnailer: 2.2.2
    magick           : 7.1.1-36
    fzf              : 0.54.3
    fd               : 10.1.0
    rg               : 14.1.0
    chafa            : 1.14.1
    zoxide           : 0.9.4
    7z               : 17.05
    7zz              : No such file or directory (os error 2)
    jq               : 1.7.1


--------------------------------------------------
When reporting a bug, please also upload the `yazi.log` log file - only upload the most recent content by time.
You can find it in the "/home/tlss/.local/state/yazi" directory.
```


### Did you try the latest nightly build to see if the problem got fixed?

Yes, and I updated the debug information above (`yazi --debug`) to the nightly that I tried

### Describe the bug

When the window size is reduced, the out-of-bounds cursor cannot be displayed in the preview pane.

Preview panel cursor shows in fullscreen.
![屏幕截图_20240810_154511](https://github.com/user-attachments/assets/4add4c97-4416-475b-9265-2529c86810ae)

Preview panel cursor disappears after resizing the window.
![屏幕截图_20240810_154538](https://github.com/user-attachments/assets/ab07f8ba-d29d-4213-9124-19f5cf970786)



### Minimal reproducer

1. Open yazi in fullscreen.
2. Enter the directory with a bunch of files.
3. Go to the bottom of this directory.
4. Resize the yazi window.

### Anything else?

_No response_


Discussion / hints:
Anyone wants to give it a go?

When the terminal size changes, the `resize` command is triggered:

https://github.com/sxyazi/yazi/blob/dac72eb39a846d15db7f1a7c54e9261675a90e53/yazi-fm/src/app/commands/resize.rs#L16

and this method calls `self.current_or_mut(opt.tab).repos`:

https://github.com/sxyazi/yazi/blob/dac72eb39a846d15db7f1a7c54e9261675a90e53/yazi-fm/src/app/commands/resize.rs#L21

https://github.com/sxyazi/yazi/blob/dac72eb39a846d15db7f1a7c54e9261675a90e53/yazi-core/src/manager/commands/hover.rs#L30

I think we can handle it there.
I noticed that the cursor disappears in both the preview and current panels when resizing the window.

Thanks for the hint. I checked the `repos` code, which should reposition the cursor, but it doesn't seem to fix the issue.

From what I understand, the cursor's position is correct after resizing, but the displayed content isn't. I noticed that the `offset` variable represents the starting position of the first file shown in the current panel within the entire file list. I managed to fix the cursor disappearing in the current panel by adjusting the offset value, but the issue persists in the preview panel.

Fix patch:
diff --git a/yazi-fs/src/folder.rs b/yazi-fs/src/folder.rs
index d6be66525..be6727aab 100644
--- a/yazi-fs/src/folder.rs
+++ b/yazi-fs/src/folder.rs
@@ -63,7 +63,7 @@ impl Folder {
 
 	pub fn arrow(&mut self, step: impl Into<Step>) -> bool {
 		let step = step.into() as Step;
-		let b = if self.files.is_empty() {
+		let mut b = if self.files.is_empty() {
 			(self.cursor, self.offset, self.tracing) = (0, 0, false);
 			false
 		} else if step.is_positive() {
@@ -72,8 +72,10 @@ impl Folder {
 			self.prev(step)
 		};
 
-		self.sync_page(false);
 		self.tracing |= b;
+		b |= self.squeeze_offset();
+
+		self.sync_page(false);
 		b
 	}
 
@@ -111,10 +113,10 @@ impl Folder {
 		let scrolloff = (limit / 2).min(MANAGER.scrolloff as usize);
 
 		self.cursor = step.add(self.cursor, limit).min(len.saturating_sub(1));
-		self.offset = if self.cursor >= (self.offset + limit).min(len).saturating_sub(scrolloff) {
-			len.saturating_sub(limit).min(self.offset + self.cursor - old.0)
-		} else {
+		self.offset = if self.cursor < (self.offset + limit).min(len).saturating_sub(scrolloff) {
 			self.offset.min(len.saturating_sub(1))
+		} else {
+			len.saturating_sub(limit).min(self.offset + self.cursor - old.0)
 		};
 
 		old != (self.cursor, self.offset)
@@ -136,6 +138,22 @@ impl Folder {
 
 		old != (self.cursor, self.offset)
 	}
+
+	fn squeeze_offset(&mut self) -> bool {
+		let old = self.offset;
+		let len = self.files.len();
+
+		let limit = LAYOUT.load().current.height as usize;
+		let scrolloff = (limit / 2).min(MANAGER.scrolloff as usize);
+
+		self.offset = if self.cursor < (self.offset + limit).min(len).saturating_sub(scrolloff) {
+			len.saturating_sub(limit).min(self.offset)
+		} else {
+			len.saturating_sub(limit).min(self.cursor.saturating_sub(limit) + scrolloff)
+		};
+
+		old != self.offset
+	}
 }
 
 impl Folder {


Test patch: