1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
#![allow(non_camel_case_types)]
use std::{fs::OpenOptions, path::PathBuf};
use super::Builtin;
use crate::*;
pub struct cd;
impl Builtin for cd {
fn name(&self) -> &str {
"cd"
}
fn mod_session(&self, _: &mut Session, args: &[BString]) {
let target: &Path = match args.get(0).map(|v| &v[..]) {
Some(b"-") => todo!("prev"),
Some(path) => OsStr::from_bytes(path).as_ref(),
None => todo!("homedir"),
};
// TODO: let mod_session builtins return nonzero exit code
let _ = std::env::set_current_dir(target);
}
}
pub struct clear;
impl Builtin for clear {
fn name(&self) -> &str {
"clear"
}
fn mod_session(&self, _: &mut Session, _: &[BString]) {
print!("\x1B[2J\x1B[1;1H");
}
}
/// restart shell
pub struct re;
impl Builtin for re {
fn name(&self) -> &str {
"re"
}
fn mod_session(&self, session: &mut Session, _args: &[BString]) {
session.raw.disable();
crate::reload::begin_reload();
session.raw.enable(); // something went wrong, let's restore raw mode
}
}
pub struct Sink {
name: &'static str,
append: bool,
}
impl Builtin for Sink {
fn name(&self) -> &str {
self.name
}
fn io(
&self,
args: &[BString],
stdin: &mut dyn Read,
_stdout: &mut dyn Write,
) -> std::io::Result<()> {
let Some(path) = args.get(0) else {
// TODO exit code
return Ok(());
};
let path = PathBuf::from(OsStr::from_bytes(path));
let mut file = OpenOptions::new()
.write(true)
.create(true)
.append(self.append)
.open(path)?;
std::io::copy(stdin, &mut file)?;
Ok(())
}
}
pub const fn sink(name: &'static str, append: bool) -> Sink {
Sink { name, append }
}
// TODO
// from" => todo!("read from file"),
pub struct from;
impl Builtin for from {
fn name(&self) -> &str {
"from"
}
fn io(
&self,
args: &[BString],
_stdin: &mut dyn Read,
stdout: &mut dyn Write,
) -> std::io::Result<()> {
let Some(path) = args.get(0) else {
// TODO exit code
return Ok(());
};
let path = PathBuf::from(OsStr::from_bytes(path));
let mut file = OpenOptions::new().read(true).open(path)?;
std::io::copy(&mut file, stdout)?;
Ok(())
}
}
pub struct _type;
impl Builtin for _type {
fn name(&self) -> &str {
"type"
}
fn io(
&self,
args: &[BString],
_stdin: &mut dyn Read,
stdout: &mut dyn Write,
) -> std::io::Result<()> {
for arg in args {
let kind = "todo";
writeln!(stdout, "{} is {}", String::from_utf8_lossy(arg), kind)?;
}
Ok(())
}
}
pub struct builtins;
impl Builtin for builtins {
fn name(&self) -> &str {
"builtins"
}
fn io(
&self,
_args: &[BString],
_stdin: &mut dyn Read,
stdout: &mut dyn Write,
) -> std::io::Result<()> {
for b in super::BUILTINS {
write!(stdout, "{} ", b.name())?;
}
writeln!(stdout)
}
}
|