vamolessa / pepper

simple and opinionated modal code editor for your terminal
https://vamolessa.github.io/pepper/
373 stars 15 forks source link

pepper panics when opening a file #18

Closed malte-v closed 2 years ago

malte-v commented 2 years ago

Most of the time, I can't open any file with pepper (latest git rev as of writing, pepper binary from the mine crate). The following is written to pepper-crash.txt:

panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }', pepper/src/application.rs:351:55

Judging from the source code, the problem seems to have something to do with updating the display upon opening a file. No idea how to fix it though :/

malte-v commented 2 years ago
Linux nixos 5.10.62 #1-NixOS SMP Fri Sep 3 08:09:31 UTC 2021 x86_64 GNU/Linux

FYI

btw, this project looks so cool! it's like Kakoune but with the ability to write plugins in Rust instead of shell script. can't wait to try it!

vamolessa commented 2 years ago

Hi, thanks for trying it out!

Would it work (at least not crash) if you change these two .unwraps() to let _ = ...? on lines 351 and 371?

pub fn update<'a>(
        &'a mut self,
        resize: Option<(usize, usize)>,
        keys: &[Key],
        stdin_bytes: Option<&[u8]>,
        server_bytes: &[u8],
    ) -> (bool, &'a [u8]) {
        use io::Write;

        self.server_write_buf.clear();

        if let Some((width, height)) = resize {
            ClientEvent::Resize(width as _, height as _).serialize(&mut self.server_write_buf);
        }

        for key in keys {
            ClientEvent::Key(self.target_client, *key).serialize(&mut self.server_write_buf);
        }

        if let Some(bytes) = stdin_bytes {
            ClientEvent::StdinInput(self.target_client, bytes)
                .serialize(&mut self.server_write_buf);
        }

        let mut suspend = false;
        if !server_bytes.is_empty() {
            self.server_read_buf.extend_from_slice(server_bytes);
            let mut read_slice = &self.server_read_buf[..];

            loop {
                let previous_slice = read_slice;
                match ServerEvent::deserialize(&mut read_slice) {
                    Ok(ServerEvent::Display(display)) => {
                        if let Some(output) = &mut self.output {
                            //output.write_all(display).unwrap();
                            let _ = output.write_all(display);
                        }
                    }
                    Ok(ServerEvent::Suspend) => suspend = true,
                    Ok(ServerEvent::StdoutOutput(bytes)) => {
                        self.stdout_buf.clear();
                        self.stdout_buf.extend_from_slice(bytes);
                    }
                    Err(DeserializeError::InsufficientData) => {
                        let read_len = self.server_read_buf.len() - previous_slice.len();
                        self.server_read_buf.drain(..read_len);
                        break;
                    }
                    Err(DeserializeError::InvalidData) => {
                        panic!("client received invalid data from server")
                    }
                }
            }

            if let Some(output) = &mut self.output {
                //output.flush().unwrap();
                let _ = output.flush();
            }
        }

        (suspend, self.server_write_buf.as_slice())
    }

I certainly did not expect a would block when writing to stdout. Were you piping into/out of pepper by any chance?

malte-v commented 2 years ago

It doesn't crash anymore, but it has huge problems updating the display. It's really glitchy and updates the screen at random intervals in random regions. I'm not piping anything into or out of pepper.

malte-v commented 2 years ago

https://user-images.githubusercontent.com/34393802/139454149-4a72005e-7c2b-48b5-b718-17a1f995e01e.mp4

Here's a video illustrating the behaviour.

vamolessa commented 2 years ago

Would you mind cheking the latest commit on master? I noticed I was opening dev/tty with NONBLOCK. Somehow it always worked on wsl.

malte-v commented 2 years ago

That fixed it. Thank you!