Repository: cantino/mcfly (language: rust)

Issue:
Strange "illegal byte sequence" results when using Mcfly
M1 Mac: 12.1 (Monterey)
iTerm: 3.4.15
zsh: 5.8
mcfly version: 0.5.11
zsh plugins: {zsh} | -z, -autosuggestions, autojump, git, vi-mode
other plugins: tldr

When I run `mcfly search {keyword}` the history bar pops up like normal. However, any attempt to complete something from this menu results in a strange "illegal byte sequence" error. The `zvm_update_repeat_commands` error is the result of `vi-mode` choking on the byte sequences (but removing that plugin does not resolve the issue). I have removed all plugins and witnessed the same behavior.

Please see the two screenshots I have added below.

<img width="1418" alt="Screen Shot 2022-01-09 at 10 23 15 AM" src="https://user-images.githubusercontent.com/22321529/148695310-e5d02ece-5f06-4da5-803f-f91a2f5a4cde.png">

After hitting `Enter` or `Tab`

<img width="1418" alt="Screen Shot 2022-01-09 at 10 23 37 AM" src="https://user-images.githubusercontent.com/22321529/148695328-fc0f7cd3-40dd-49a4-ab82-f2a6e4293ad7.png">




Discussion / hints:
I see something similar - it shows question marks instead (with bash)

```console
18:43 $ mcfly search
18:43 $ ????????????????
-bash: $'\317\317\317\317\317\317\317\317\317\317\317\317\317\317\317\317': command not found
18:44 $ mcfly --version
McFly 0.5.11
```

Hi, I'm getting the same with the latest git version (0.5.12); also on an M1 and installed via brew. 

Don't really know much about rust or ioctl calls, but for what it is worth I played around with the source code a bit and fake_typer:use_tiocsti does get the correct string, so perhaps the issue is somewhere in the ioctl call? I did try calling ioctl using python on the same computer and there it works
```
In [2]: import fcntl
In [3]: import termios
In [4]: import sys
In [5]: for c in "test":
   ...:     fcntl.ioctl(sys.stdin, termios.TIOCSTI, c)
test
In [6]: test
```
Not sure if this is helpful. Looking forward to getting this bug fixed though ;) Also happy to try things out on my laptop if that helps.


played around a bit more and this seems to work for me:
fake_typer.rs
```
use libc;
extern {
    pub fn ioctl(fd: libc::c_int, req: libc::c_ulong, ...) -> libc::c_int;
}

pub fn use_tiocsti(string: &str) {
    for byte in string.as_bytes() {
	let a: *const u8 = byte;
        if unsafe { ioctl(0, libc::TIOCSTI, a) } < 0 {
            panic!("Error encountered when calling ioctl");
        }
    }
}
```
Note: first time rust user, so I really have no idea what I'm doing here ;)


Fix patch:
diff --git a/src/fake_typer.rs b/src/fake_typer.rs
index 5962da38..18c0b817 100644
--- a/src/fake_typer.rs
+++ b/src/fake_typer.rs
@@ -1,12 +1,16 @@
+use libc;
+use std::convert::TryInto;
+
 // Should we be using https://docs.rs/libc/0.2.44/libc/fn.ioctl.html instead?
 extern "C" {
-    pub fn ioctl(fd: i8, request: u32, arg: *const u8) -> i8;
+    pub fn ioctl(fd: libc::c_int, request: libc::c_ulong, arg: ...) -> libc::c_int;
 }
 
+#[allow(clippy::useless_conversion)]
 pub fn use_tiocsti(string: &str) {
     for byte in string.as_bytes() {
         let a: *const u8 = byte;
-        if unsafe { ioctl(0, libc::TIOCSTI as u32, a) } < 0 {
+        if unsafe { ioctl(0, libc::TIOCSTI.try_into().unwrap(), a) } < 0 {
             panic!("Error encountered when calling ioctl");
         }
     }
diff --git a/src/interface.rs b/src/interface.rs
index d11a3c3c..c246c783 100644
--- a/src/interface.rs
+++ b/src/interface.rs
@@ -138,12 +138,12 @@ impl<'a> Interface<'a> {
             screen,
             "{hide}{cursor}{clear}{fg}{bg}{text:width$}{reset_bg}",
             hide = cursor::Hide,
-            fg = color::Fg(color::LightWhite).to_string(),
+            fg = color::Fg(color::LightWhite),
             bg = self.menu_mode.bg(),
             cursor = cursor::Goto(1, self.info_line_index()),
             clear = clear::CurrentLine,
             text = self.menu_mode.text(self),
-            reset_bg = color::Bg(color::Reset).to_string(),
+            reset_bg = color::Bg(color::Reset),
             width = width as usize
         )
         .unwrap();


Test patch: