Repository: zellij-org/zellij
File: default-plugins/strider/src/main.rs (Rust)

Code before:
                Key::Up | Key::Char('k') => {
                    *self.selected_mut() = self.selected().saturating_sub(1);
                }
                Key::Down | Key::Char('j') => {
                    let next = self.selected().saturating_add(1);
                    *self.selected_mut() = min(self.files.len() - 1, next);
                }
                Key::Right | Key::Char('\n') | Key::Char('l') if !self.files.is_empty() => {
                    self.traverse_dir_or_open_file();
                    self.ev_history.clear();
                }
                Key::Left | Key::Char('h') => {
                    self.path.pop();
                    refresh_directory(self);
                }
                Key::Char('.') => {
                    self.toggle_hidden_files();
                    refresh_directory(self);
                }

                _ => (),
            },
            Event::Mouse(mouse_event) => match mouse_event {
                Mouse::ScrollDown(_) => {
                    let next = self.selected().saturating_add(1);
                    *self.selected_mut() = min(self.files.len() - 1, next);
                }
                Mouse::ScrollUp(_) => {
                    *self.selected_mut() = self.selected().saturating_sub(1);
                }
                Mouse::MouseRelease(Some((line, _))) => {
                    if line < 0 {
                        return;
                    }
                    let mut should_select = true;
                    if let Some((Event::Mouse(Mouse::MouseRelease(Some((prev_line, _)))), t)) =
                        prev_event
                    {
                        if prev_line == line
                            && Instant::now().saturating_duration_since(t).as_millis() < 400
                        {
                            self.traverse_dir_or_open_file();
                            self.ev_history.clear();
                            should_select = false;
                        }
                    }
                    if should_select && self.scroll() + (line as usize) < self.files.len() {
                        *self.selected_mut() = self.scroll() + (line as usize);
                    }
                }
                _ => {}

Review comment (bug):
This crashes if you try to scroll down in an empty folder :)
```
DEBUG  |strider                  | 2021-09-06 14:01:16.548 [id: 1     ] thread 'main' panicked at 'attempt to subtract with overflow', default-plugins/strider/src/main.rs:50:48 
DEBUG  |strider                  | 2021-09-06 14:01:16.548 [id: 1     ] note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace 
```
A `saturating_sub` with the `len` should fix things :)

Code after:
                Key::Up | Key::Char('k') => {
                    *self.selected_mut() = self.selected().saturating_sub(1);
                }
                Key::Down | Key::Char('j') => {
                    let next = self.selected().saturating_add(1);
                    *self.selected_mut() = min(self.files.len() - 1, next);
                }
                Key::Right | Key::Char('\n') | Key::Char('l') if !self.files.is_empty() => {
                    self.traverse_dir_or_open_file();
                    self.ev_history.clear();
                }
                Key::Left | Key::Char('h') => {
                    if self.path.components().count() > 2 {
                        // don't descend into /host
                        // the reason this is a hard-coded number (2) and not "== ROOT"
                        // or some such is that there are certain cases in which self.path
                        // is empty and this will work then too
                        self.path.pop();
                        refresh_directory(self);
                    }
                }
                Key::Char('.') => {
                    self.toggle_hidden_files();
                    refresh_directory(self);
                }

                _ => (),
            },
            Event::Mouse(mouse_event) => match mouse_event {
                Mouse::ScrollDown(_) => {
                    let next = self.selected().saturating_add(1);
                    *self.selected_mut() = min(self.files.len().saturating_sub(1), next);
                }
                Mouse::ScrollUp(_) => {
                    *self.selected_mut() = self.selected().saturating_sub(1);
                }
                Mouse::MouseRelease(Some((line, _))) => {
                    if line < 0 {
                        return;
                    }
                    let mut should_select = true;
                    if let Some((Event::Mouse(Mouse::MouseRelease(Some((prev_line, _)))), t)) =
                        prev_event
                    {
                        if prev_line == line
                            && Instant::now().saturating_duration_since(t).as_millis() < 400
                        {
                            self.traverse_dir_or_open_file();
                            self.ev_history.clear();
                            should_select = false;
                        }