1#![allow(unused)]
2pub mod errors;
3use std::borrow::Cow;
4
5pub use errors::{Error, Result};
6use sexprs_formatter::highlight;
7use sexprs_parser::parse_source;
8use sexprs_util::dbg;
9use sexprs_vm::VirtualMachine;
10use rustyline::completion::{Candidate, Completer};
11use rustyline::highlight::{CmdKind, Highlighter};
12use rustyline::hint::{Hint, Hinter};
13use rustyline::line_buffer::LineBuffer;
14use rustyline::validate::{ValidationContext, ValidationResult, Validator};
15use rustyline::{Changeset, CompletionType, Context, Helper};
16
17pub struct VirtualMachinePrompt<'c> {
18 pub vm: &'c VirtualMachine<'c>,
19}
20impl<'c> VirtualMachinePrompt<'c> {
21 pub fn new(vm: &VirtualMachine<'c>) -> VirtualMachinePrompt<'c> {
22 VirtualMachinePrompt {
23 vm: unsafe {
24 std::mem::transmute::<&VirtualMachine, &'c VirtualMachine>(vm)
25 },
26 }
27 }
28}
29impl<'c> Highlighter for VirtualMachinePrompt<'c> {
30 fn highlight<'l>(&self, line: &'l str, pos: usize) -> Cow<'l, str> {
31 Cow::from(
32 highlight(line.to_string(), "lisp")
33 .unwrap_or_else(|_| line.to_string()),
34 )
35 }
36
37 fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
38 &'s self,
39 prompt: &'p str,
40 default: bool,
41 ) -> Cow<'b, str> {
42 Cow::from(prompt)
45 }
46
47 fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> {
48 Cow::from(
51 highlight(hint.to_string(), "list")
52 .unwrap_or_else(|_| hint.to_string()),
53 )
54 }
55
56 fn highlight_candidate<'h>(
57 &self,
58 candidate: &'h str,
59 completion: CompletionType,
60 ) -> Cow<'h, str> {
61 dbg!(candidate, completion);
62 Cow::from(candidate)
63 }
64
65 fn highlight_char(&self, line: &str, pos: usize, kind: CmdKind) -> bool {
66 false
69 }
70}
71
72pub struct DummyHint {
73 display: String,
74 completion: String,
75}
76impl DummyHint {
77 pub fn new(display: String, completion: String) -> DummyHint {
78 DummyHint {
79 display,
80 completion,
81 }
82 }
83}
84
85impl Hint for DummyHint {
86 fn display(&self) -> &str {
87 self.display.clone().leak()
88 }
89
90 fn completion(&self) -> Option<&str> {
91 Some(self.completion.clone().leak())
92 }
93}
94
95impl<'c> Hinter for VirtualMachinePrompt<'c> {
96 type Hint = DummyHint;
97
98 fn hint(
99 &self,
100 line: &str,
101 pos: usize,
102 ctx: &Context<'_>,
103 ) -> Option<Self::Hint> {
104 None
105 }
111}
112
113pub struct DummyCandidate {
114 display: String,
115 replacement: String,
116}
117impl DummyCandidate {
118 pub fn new(display: String, replacement: String) -> DummyCandidate {
119 DummyCandidate {
120 display,
121 replacement,
122 }
123 }
124}
125
126impl Candidate for DummyCandidate {
127 fn display(&self) -> &str {
128 self.display.clone().leak()
129 }
130
131 fn replacement(&self) -> &str {
132 self.replacement.clone().leak()
133 }
134}
135
136impl<'c> Completer for VirtualMachinePrompt<'c> {
137 type Candidate = DummyCandidate;
138
139 fn complete(
140 &self,
141 line: &str,
142 pos: usize,
143 ctx: &Context<'_>,
144 ) -> rustyline::Result<(usize, Vec<Self::Candidate>)> {
145 Ok((0, Vec::new()))
159 }
160
161 fn update(
162 &self,
163 line: &mut LineBuffer,
164 start: usize,
165 elected: &str,
166 cl: &mut Changeset,
167 ) {
168 dbg!(line, start, elected);
169 }
170}
171
172impl<'c> Validator for VirtualMachinePrompt<'c> {
173 fn validate(
174 &self,
175 ctx: &mut ValidationContext<'_>,
176 ) -> rustyline::Result<ValidationResult> {
177 match parse_source(ctx.input()) {
182 Ok(value) => Ok(ValidationResult::Valid(None)),
183 Err(e) => Ok(ValidationResult::Invalid(Some(e.to_string()))),
185 }
186 }
187
188 fn validate_while_typing(&self) -> bool {
189 true
190 }
191}
192
193impl<'c> Helper for VirtualMachinePrompt<'c> {}