1extern crate mio;
4#[macro_use]
5extern crate tokio_core;
6extern crate libc;
7extern crate nix;
8extern crate termios;
9extern crate futures;
10
11mod raw;
12
13pub use raw::*;
14
15use std::io::{self, Read, Write};
16use futures::{Async, AsyncSink};
17
18use futures::sync::BiLock;
19
20pub struct Line {
21 pub line : Vec<u8>,
22 pub text_last_nl : bool,
23}
24
25struct ReadlineInner {
26 stdin : raw::PollFd,
27 stdout : raw::PollFd,
28
29 line : Vec<u8>,
30
31 lines_ready : Vec<Vec<u8>>,
32
33 text_last_nl : bool,
34
35
36 wr_pending: Vec<u8>,
37}
38
39pub struct Lines {
40 inner : BiLock<ReadlineInner>,
41}
42
43pub struct Writer {
44 inner : BiLock<ReadlineInner>,
45}
46
47impl ReadlineInner {
48 fn clear_line(&mut self) -> io::Result<()> {
49 write!(self.wr_pending, "\x1b[2K")?;
50 write!(self.wr_pending, "\x1b[1000D")?;
51 Ok(())
52 }
53
54 fn redraw_line(&mut self) -> io::Result<()> {
55 write!(self.wr_pending, "\x1b[2K")?;
56 write!(self.wr_pending, "\x1b[1000D")?;
57 write!(self.wr_pending, "> {}", String::from_utf8_lossy(&self.line))?;
58 Ok(())
59 }
60
61 fn leave_prompt(&mut self) -> io::Result<()> {
62 self.clear_line()?;
63 self.restore_original()?;
64 if !self.text_last_nl {
65 write!(self.wr_pending, "\x1b[1B")?;
66 write!(self.wr_pending, "\x1b[1A")?;
67 }
68 Ok(())
69 }
70
71 fn enter_prompt(&mut self) -> io::Result<()> {
72 self.save_original()?;
73 if !self.text_last_nl {
74 write!(self.wr_pending, "\n")?;
76 self.clear_line()?;
77 }
78 Ok(())
79 }
80
81 fn save_original(&mut self) -> io::Result<()> {
82 write!(self.wr_pending, "\x1b[s")?;
83 Ok(())
84 }
85
86 fn restore_original(&mut self) -> io::Result<()> {
87 write!(self.wr_pending, "\x1b[u")?;
88 Ok(())
89 }
90
91 fn wr_pending_flush(&mut self) -> io::Result<()> {
92 let n = self.stdout.write(&self.wr_pending)?;
93 self.wr_pending.drain(..n);
94 self.stdout.flush()?;
95 Ok(())
96 }
97
98 fn handle_char(&mut self, ch : u8) {
99 match ch {
100 13 => self.lines_ready.push(std::mem::replace(&mut self.line, vec![])),
101 127 => {
102 let _ = self.line.pop();
103 },
104 _ => self.line.push(ch),
105 }
106 }
107
108 fn poll_command(&mut self) -> futures::Poll<Option<Line>, io::Error> {
109 let mut tmp_buf = [0u8; 16];
110
111 loop {
112 let _ = self.wr_pending_flush();
113
114 if let Some(line) = self.lines_ready.pop() {
115 self.clear_line()?;
116 let _ = self.wr_pending_flush();
117 return Ok(
118 Async::Ready(Some(
119 Line {
120 line: line,
121 text_last_nl: self.text_last_nl
122 }
123 ))
124 )
125 }
126
127 let bytes_read = try_nb!(self.stdin.read(&mut tmp_buf));
129
130 for ch in &tmp_buf[..bytes_read] {
131 self.handle_char(*ch)
132 }
133
134 self.redraw_line()?;
135 }
136 }
137
138 fn start_write(&mut self, mut item: Vec<u8>) -> futures::StartSend<Vec<u8>, io::Error> {
139 if item.len() > 0 {
140 self.leave_prompt()?;
141 self.text_last_nl = item[item.len() - 1] == 10;
142 self.wr_pending.append(&mut item);
143 self.enter_prompt()?;
144 self.redraw_line()?;
145 }
146 Ok(AsyncSink::Ready)
147 }
148
149 fn poll_write_complete(&mut self) -> futures::Poll<(), io::Error> {
150 loop {
151 try_nb!(self.wr_pending_flush());
152
153 if self.wr_pending.len() == 0 {
154 return Ok(Async::Ready(()));
155 }
156
157 }
158 }
159}
160
161impl futures::Stream for Lines {
162 type Item = Line;
163 type Error = io::Error;
164
165 fn poll(&mut self) -> futures::Poll<Option<Self::Item>, Self::Error> {
166 if let Async::Ready(mut guard) = self.inner.poll_lock() {
167 guard.poll_command()
168 } else {
169 Ok(Async::NotReady)
170 }
171
172 }
173}
174
175impl futures::Sink for Writer {
176 type SinkItem = Vec<u8>;
177 type SinkError = io::Error;
178
179 fn start_send(&mut self, item: Self::SinkItem) -> futures::StartSend<Self::SinkItem, io::Error> {
180 if let Async::Ready(mut guard) = self.inner.poll_lock() {
181 guard.start_write(item)
182 } else {
183 Ok(AsyncSink::NotReady(item))
184 }
185 }
186
187 fn poll_complete(&mut self) -> futures::Poll<(), io::Error> {
188 if let Async::Ready(mut guard) = self.inner.poll_lock() {
189 guard.poll_write_complete()
190 } else {
191 Ok(Async::NotReady)
192 }
193 }
194}
195
196pub fn init(stdin : PollFd, stdout : PollFd) -> (Lines, Writer) {
197 let mut inner = ReadlineInner {
198 stdin: stdin,
199 stdout : stdout,
200 line: vec![],
201 text_last_nl: true,
202 wr_pending : vec!(),
203 lines_ready : vec![],
204 };
205
206 let _ = inner.enter_prompt();
207
208 let (l1, l2) = BiLock::new(inner);
209
210
211
212 let writer = Writer { inner: l1 };
213 let lines = Lines { inner: l2 };
214 (lines, writer)
215}
216
217#[cfg(test)]
218mod tests {
219 #[test]
220 fn it_works() {
221 }
222}