init
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/target
|
||||
/result*
|
||||
69
Cargo.lock
generated
Normal file
69
Cargo.lock
generated
Normal file
@@ -0,0 +1,69 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "cfg_aliases"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.180"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.30.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustty"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"vte",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vte"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5924018406ce0063cd67f8e008104968b74b563ee1b85dde3ed1f7cb87d3dbd"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"memchr",
|
||||
]
|
||||
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "rustty"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
nix = {default-features = false, features=["term","process","fs"], version="0.30.1"}
|
||||
vte = "0.15.0"
|
||||
87
flake.lock
generated
Normal file
87
flake.lock
generated
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"nodes": {
|
||||
"fenix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"naersk",
|
||||
"nixpkgs"
|
||||
],
|
||||
"rust-analyzer-src": "rust-analyzer-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1752475459,
|
||||
"narHash": "sha256-z6QEu4ZFuHiqdOPbYss4/Q8B0BFhacR8ts6jO/F/aOU=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "bf0d6f70f4c9a9cf8845f992105652173f4b617f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"naersk": {
|
||||
"inputs": {
|
||||
"fenix": "fenix",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1763384566,
|
||||
"narHash": "sha256-r+wgI+WvNaSdxQmqaM58lVNvJYJ16zoq+tKN20cLst4=",
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"rev": "d4155d6ebb70fbe2314959842f744aa7cabbbf6a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1768305791,
|
||||
"narHash": "sha256-AIdl6WAn9aymeaH/NvBj0H9qM+XuAuYbGMZaP0zcXAQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "1412caf7bf9e660f2f962917c14b1ea1c3bc695e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-unstable",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"naersk": "naersk",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"rust-analyzer-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1752428706,
|
||||
"narHash": "sha256-EJcdxw3aXfP8Ex1Nm3s0awyH9egQvB2Gu+QEnJn2Sfg=",
|
||||
"owner": "rust-lang",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "591e3b7624be97e4443ea7b5542c191311aa141d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "rust-lang",
|
||||
"ref": "nightly",
|
||||
"repo": "rust-analyzer",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
23
flake.nix
Normal file
23
flake.nix
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "nixpkgs/nixos-unstable";
|
||||
naersk = {
|
||||
url = "github:nix-community/naersk";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
outputs = {
|
||||
nixpkgs,
|
||||
naersk,
|
||||
...
|
||||
}: let
|
||||
system = "x86_64-linux";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in {
|
||||
packages.${system} = {
|
||||
default = pkgs.callPackage ./package.nix {
|
||||
naersk = pkgs.callPackage naersk {};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
38
package.nix
Normal file
38
package.nix
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
fontconfig,
|
||||
freetype,
|
||||
lib,
|
||||
libGL,
|
||||
libxkbcommon,
|
||||
makeWrapper,
|
||||
naersk,
|
||||
pkg-config,
|
||||
wayland,
|
||||
...
|
||||
}:
|
||||
naersk.buildPackage rec {
|
||||
name = "rustty";
|
||||
src = ./.;
|
||||
buildInputs = [
|
||||
# fonts
|
||||
fontconfig
|
||||
freetype
|
||||
freetype.dev
|
||||
|
||||
# wayland graphics
|
||||
libGL
|
||||
libxkbcommon
|
||||
wayland
|
||||
];
|
||||
nativeBuildInputs = [
|
||||
pkg-config
|
||||
makeWrapper
|
||||
];
|
||||
postInstall = ''
|
||||
wrapProgram "$out/bin/${meta.mainProgram}" --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath buildInputs}"
|
||||
'';
|
||||
meta = {
|
||||
mainProgram = "rustty";
|
||||
homepage = "https://mtgmonkey.net";
|
||||
};
|
||||
}
|
||||
98
src/main.rs
Normal file
98
src/main.rs
Normal file
@@ -0,0 +1,98 @@
|
||||
use nix::pty::{ForkptyResult, forkpty, PtyMaster};
|
||||
use nix::unistd::read;
|
||||
|
||||
use std::vec::Vec;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::process::Command;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use vte::{Params, Parser, Perform};
|
||||
|
||||
struct Performer;
|
||||
impl Perform for Performer {
|
||||
fn print(&mut self, c: char) {
|
||||
println!("[print] {:?}", c);
|
||||
}
|
||||
|
||||
fn execute(&mut self, byte: u8) {
|
||||
println!("[execute] {:02x}", byte);
|
||||
}
|
||||
|
||||
fn hook(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: char) {
|
||||
println!(
|
||||
"[hook] params={:?}, intermediates={:?}, ignore={:?}, char={:?}",
|
||||
params, intermediates, ignore, c
|
||||
);
|
||||
}
|
||||
|
||||
fn put(&mut self, byte: u8) {
|
||||
println!("[put] {:02x}", byte);
|
||||
}
|
||||
|
||||
fn unhook(&mut self) {
|
||||
println!("[unhook]");
|
||||
}
|
||||
|
||||
fn osc_dispatch(&mut self, params: &[&[u8]], bell_terminated: bool) {
|
||||
println!("[osc_dispatch] params={:?} bell_terminated={}", params, bell_terminated);
|
||||
}
|
||||
|
||||
fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: char) {
|
||||
println!(
|
||||
"[csi_dispatch] params={:#?}, intermediates={:?}, ignore={:?}, char={:?}",
|
||||
params, intermediates, ignore, c
|
||||
);
|
||||
}
|
||||
|
||||
fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) {
|
||||
println!(
|
||||
"[esc_dispatch] intermediates={:?}, ignore={:?}, byte={:02x}",
|
||||
intermediates, ignore, byte
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
// TODO get rid of hard coded `sh` path
|
||||
let mut pty = spawn_pty("/home/andromeda/.nix-profile/bin/sh").unwrap();
|
||||
println!("{:?}", &pty);
|
||||
|
||||
let input = io::stdin();
|
||||
let mut handle = input.lock();
|
||||
|
||||
let mut statemachine = Parser::new();
|
||||
let mut performer = Performer;
|
||||
let mut buf = [0u8; 2048];
|
||||
|
||||
while true {
|
||||
match read(&pty, &mut buf) {
|
||||
Ok(0) => break,
|
||||
Ok(n) => {
|
||||
statemachine.advance(&mut performer, &buf[..n]);
|
||||
},
|
||||
Err(_e) => break,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// forks a new pty and returns file descriptor of the master
|
||||
fn spawn_pty(shell: &str) -> Option<PtyMaster> {
|
||||
// SAFETY safe unless os out of PTYs; incredibly unlikely
|
||||
match unsafe {forkpty(None, None)} {
|
||||
Ok(fork_pty_res) => match fork_pty_res {
|
||||
ForkptyResult::Parent {master, ..} => {
|
||||
// SAFETY `master` is a valid PtyMaster
|
||||
return Some(unsafe{PtyMaster::from_owned_fd(master)});
|
||||
}
|
||||
ForkptyResult::Child =>{
|
||||
Command::new(shell).spawn();
|
||||
// TODO come up with an elegant solution
|
||||
thread::sleep(Duration::MAX);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
Err(_e) => return None,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user