Fix terminal sizes
This commit is contained in:
parent
033ada554c
commit
7fb37a8f35
|
@ -8,16 +8,45 @@ version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.3.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.149"
|
version = "0.2.149"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
|
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.4.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "multiview"
|
name = "multiview"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"pty-process",
|
||||||
"termion",
|
"termion",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -27,13 +56,23 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
|
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pty-process"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8749b545e244c90bf74a5767764cc2194f1888bb42f84015486a64c82bea5cc0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rustix",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -45,6 +84,20 @@ dependencies = [
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "0.38.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.4.1",
|
||||||
|
"errno",
|
||||||
|
"itoa",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termion"
|
name = "termion"
|
||||||
version = "2.0.1"
|
version = "2.0.1"
|
||||||
|
@ -56,3 +109,69 @@ dependencies = [
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"redox_termios",
|
"redox_termios",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.48.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
|
@ -6,4 +6,5 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
pty-process = "0.4.0"
|
||||||
termion = "2.0.1"
|
termion = "2.0.1"
|
||||||
|
|
193
src/lib.rs
193
src/lib.rs
|
@ -1,8 +1,11 @@
|
||||||
use std::io::{self, stdin, stdout, BufRead, BufReader, Write};
|
use std::io::{self, stdin, stdout, Read, Write};
|
||||||
use std::process::{Command, Stdio};
|
use std::process::Stdio;
|
||||||
use std::sync::mpsc::{channel, Sender};
|
use std::sync::mpsc::{channel, Sender};
|
||||||
use std::{env, thread};
|
use std::{env, thread};
|
||||||
|
|
||||||
|
use pty_process::blocking::Command;
|
||||||
|
use pty_process::blocking::Pty;
|
||||||
|
|
||||||
use termion::event::{Event, Key, MouseEvent};
|
use termion::event::{Event, Key, MouseEvent};
|
||||||
use termion::input::{MouseTerminal, TermRead};
|
use termion::input::{MouseTerminal, TermRead};
|
||||||
use termion::raw::IntoRawMode;
|
use termion::raw::IntoRawMode;
|
||||||
|
@ -136,73 +139,103 @@ pub struct Tile {
|
||||||
///
|
///
|
||||||
/// We put both stdout and stderr here to avoid dealing with order between stdout and stderr.
|
/// We put both stdout and stderr here to avoid dealing with order between stdout and stderr.
|
||||||
pub stdout: Vec<String>,
|
pub stdout: Vec<String>,
|
||||||
|
|
||||||
|
/// The sender for the communication with the multiview.
|
||||||
|
pub sender: Sender<Msg>,
|
||||||
|
|
||||||
|
/// Coordinates of the tile.
|
||||||
|
pub coords: (u16, u16),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tile {
|
impl Tile {
|
||||||
/// Creates a new empty tile.
|
/// Creates a new empty tile.
|
||||||
pub fn new(command: &[String], i: u16, j: u16, sender: Sender<Msg>) -> Tile {
|
pub fn new(command: &[String], i: u16, j: u16, sender: Sender<Msg>) -> Tile {
|
||||||
let command = command
|
Tile {
|
||||||
|
command: command
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|x| x.to_string())
|
.map(|x| x.to_string())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
stdout: vec![],
|
||||||
|
sender,
|
||||||
|
coords: (i, j),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Starts the commands.
|
||||||
|
pub fn start(&mut self, width: u16, height: u16) {
|
||||||
|
let command = self
|
||||||
|
.command
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.to_string())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let coords = self.coords;
|
||||||
let clone = command.clone();
|
let clone = command.clone();
|
||||||
|
let sender = self.sender.clone();
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
|
let pty = Pty::new().unwrap();
|
||||||
|
pty.resize(pty_process::Size::new(height - 4, width - 4))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut child = Command::new(&clone[0])
|
let mut child = Command::new(&clone[0])
|
||||||
.args(&clone[1..])
|
.args(&clone[1..])
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.spawn()
|
.spawn(&pty.pts().unwrap())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let stdout = child.stdout.take().unwrap();
|
let mut stdout = child.stdout.take().unwrap();
|
||||||
|
let mut stderr = child.stderr.take().unwrap();
|
||||||
let stderr = child.stderr.take().unwrap();
|
|
||||||
let stderr_sender = sender.clone();
|
let stderr_sender = sender.clone();
|
||||||
|
|
||||||
thread::spawn(move || {
|
let coords = coords;
|
||||||
let reader = BufReader::new(stderr);
|
|
||||||
let mut lines = reader.lines();
|
|
||||||
|
|
||||||
loop {
|
thread::spawn(move || loop {
|
||||||
match lines.next() {
|
let mut buffer = [0; 256];
|
||||||
Some(Ok(line)) => {
|
let result = stderr.read(&mut buffer);
|
||||||
stderr_sender.send(Msg::Stderr(i, j, line)).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(Err(_)) => {
|
match result {
|
||||||
break;
|
Ok(0) => break,
|
||||||
}
|
|
||||||
|
|
||||||
None => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Ok(n) => {
|
||||||
stderr_sender
|
stderr_sender
|
||||||
.send(Msg::Stdout(i, j, String::new()))
|
.send(Msg::Stderr(
|
||||||
|
coords.0,
|
||||||
|
coords.1,
|
||||||
|
String::from_utf8_lossy(&buffer[0..n]).to_string(),
|
||||||
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(_) => break,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let reader = BufReader::new(stdout);
|
|
||||||
|
|
||||||
let mut lines = reader.lines();
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match lines.next() {
|
let mut buffer = [0; 256];
|
||||||
Some(Ok(line)) => {
|
let result = stdout.read(&mut buffer);
|
||||||
sender.send(Msg::Stdout(i, j, line)).unwrap();
|
|
||||||
|
match result {
|
||||||
|
Ok(0) => break,
|
||||||
|
|
||||||
|
Ok(n) => {
|
||||||
|
sender
|
||||||
|
.send(Msg::Stderr(
|
||||||
|
coords.0,
|
||||||
|
coords.1,
|
||||||
|
String::from_utf8_lossy(&buffer[0..n]).to_string(),
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Err(_)) => {
|
Err(_) => break,
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
None => break,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sender.send(Msg::Stdout(i, j, String::new())).unwrap();
|
sender
|
||||||
|
.send(Msg::Stdout(coords.0, coords.1, String::new()))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let code = child.wait().unwrap().code().unwrap();
|
let code = child.wait().unwrap().code().unwrap();
|
||||||
|
|
||||||
|
@ -219,16 +252,10 @@ impl Tile {
|
||||||
color::Reset.fg_str()
|
color::Reset.fg_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
sender.send(Msg::Stdout(i, j, exit_string)).unwrap();
|
sender
|
||||||
|
.send(Msg::Stdout(coords.0, coords.1, exit_string))
|
||||||
|
.unwrap();
|
||||||
});
|
});
|
||||||
|
|
||||||
Tile {
|
|
||||||
command: command
|
|
||||||
.into_iter()
|
|
||||||
.map(|x| x.to_string())
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
stdout: vec![],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,47 +373,66 @@ impl<W: Write> Multiview<W> {
|
||||||
|
|
||||||
write!(
|
write!(
|
||||||
self.stdout,
|
self.stdout,
|
||||||
"{}{} {}Command: {}{}",
|
"{}{} {}Command: {}{}{}",
|
||||||
color::Reset.fg_str(),
|
color::Reset.fg_str(),
|
||||||
cursor::Goto(x1 + 1, y1 + 1),
|
cursor::Goto(x1 + 1, y1 + 1),
|
||||||
style::Bold,
|
style::Bold,
|
||||||
command_str,
|
command_str,
|
||||||
style::Reset,
|
style::Reset,
|
||||||
|
cursor::Goto(x1 + 2, y1 + 3),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let mut counting = true;
|
||||||
let mut line_index = 0;
|
let mut line_index = 0;
|
||||||
for line in lines {
|
|
||||||
let mut len = str_len(&line) as i32;
|
|
||||||
let mut current_char_index = 0;
|
let mut current_char_index = 0;
|
||||||
|
|
||||||
if len == 0 {
|
for line in lines {
|
||||||
line_index += 1;
|
for c in line.chars() {
|
||||||
continue;
|
if c == '\x1b' {
|
||||||
|
counting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while len > 0 {
|
match c {
|
||||||
let sub = sub_str(
|
'\n' => {
|
||||||
&line,
|
line_index += 1;
|
||||||
current_char_index,
|
current_char_index = 0;
|
||||||
current_char_index + term_size.0 - 4,
|
|
||||||
);
|
|
||||||
write!(
|
write!(
|
||||||
self.stdout,
|
self.stdout,
|
||||||
"{}{}",
|
"{}",
|
||||||
cursor::Goto(x1 + 2, y1 + 3 + line_index as u16),
|
cursor::Goto(x1 + 2, y1 + 3 + line_index as u16)
|
||||||
sub.replace(
|
|
||||||
"\r",
|
|
||||||
&format!("{}", cursor::Goto(x1 + 2, y1 + 3 + line_index as u16))
|
|
||||||
),
|
|
||||||
)?;
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
// if sub.contains(|x| x == '\r') {
|
'\r' => {
|
||||||
// line_index -= 1;
|
current_char_index = 0;
|
||||||
// }
|
write!(
|
||||||
|
self.stdout,
|
||||||
|
"{}",
|
||||||
|
cursor::Goto(x1 + 2, y1 + 3 + line_index as u16)
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
if counting {
|
||||||
|
current_char_index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if current_char_index == w - 3 {
|
||||||
line_index += 1;
|
line_index += 1;
|
||||||
len -= (term_size.0 - 4) as i32;
|
current_char_index = 1;
|
||||||
current_char_index += term_size.0 - 4;
|
write!(
|
||||||
|
self.stdout,
|
||||||
|
"{}",
|
||||||
|
cursor::Goto(x1 + 2, y1 + 3 + line_index as u16)
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
write!(self.stdout, "{}", c)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if c == 'm' {
|
||||||
|
counting = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,6 +516,17 @@ pub fn main() -> io::Result<()> {
|
||||||
let mut multiview = Multiview::new(stdout, tiles)?;
|
let mut multiview = Multiview::new(stdout, tiles)?;
|
||||||
multiview.render(term_size)?;
|
multiview.render(term_size)?;
|
||||||
|
|
||||||
|
let tile_size = (
|
||||||
|
term_size.0 / multiview.tiles[0].len() as u16,
|
||||||
|
term_size.1 / multiview.tiles.len() as u16,
|
||||||
|
);
|
||||||
|
|
||||||
|
for row in &mut multiview.tiles {
|
||||||
|
for tile in row {
|
||||||
|
tile.start(tile_size.0, tile_size.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
for c in stdin.events() {
|
for c in stdin.events() {
|
||||||
let evt = c.unwrap();
|
let evt = c.unwrap();
|
||||||
|
|
Loading…
Reference in New Issue