-
Notifications
You must be signed in to change notification settings - Fork 5
/
builder.rs
78 lines (69 loc) · 2.4 KB
/
builder.rs
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
use std::marker::PhantomData;
use clap::Parser;
use nu_ansi_term::{Color, Style};
use reedline::{
default_emacs_keybindings, DefaultHinter, DefaultPrompt, EditMode, Emacs, IdeMenu,
KeyModifiers, MenuBuilder, Prompt, Reedline, ReedlineEvent, ReedlineMenu,
};
use crate::{ClapEditor, ReedCompleter};
pub struct ClapEditorBuilder<C: Parser + Send + Sync + 'static> {
prompt: Box<dyn Prompt>,
edit_mode: Box<dyn EditMode>,
hook: Box<dyn FnOnce(Reedline) -> Reedline>,
c_phantom: PhantomData<C>,
}
impl<C: Parser + Send + Sync + 'static> ClapEditorBuilder<C> {
pub(crate) fn new() -> Self {
Self {
prompt: Box::<DefaultPrompt>::default(),
edit_mode: {
let mut keybindings = default_emacs_keybindings();
keybindings.add_binding(
KeyModifiers::NONE,
reedline::KeyCode::Tab,
ReedlineEvent::UntilFound(vec![
ReedlineEvent::Menu("completion_menu".to_string()),
ReedlineEvent::MenuNext,
]),
);
Box::new(Emacs::new(keybindings))
},
hook: Box::new(|e| e),
c_phantom: PhantomData,
}
}
pub fn with_prompt(mut self, prompt: Box<dyn Prompt>) -> Self {
self.prompt = prompt;
self
}
pub fn with_edit_mode(mut self, edit_mode: Box<dyn EditMode>) -> Self {
self.edit_mode = edit_mode;
self
}
pub fn with_editor_hook(mut self, hook: impl FnOnce(Reedline) -> Reedline + 'static) -> Self {
self.hook = Box::new(hook);
self
}
pub fn build(self) -> ClapEditor<C> {
let completion_menu = Box::new(
IdeMenu::default()
.with_default_border()
.with_name("completion_menu"),
);
let rl = Reedline::create()
.with_completer(Box::new(ReedCompleter::<C> {
c_phantom: PhantomData,
}))
.with_menu(ReedlineMenu::EngineCompleter(completion_menu))
.with_hinter(Box::new(
DefaultHinter::default().with_style(Style::new().italic().fg(Color::DarkGray)),
))
.with_edit_mode(self.edit_mode);
let rl = (self.hook)(rl);
ClapEditor {
rl,
prompt: self.prompt,
c_phantom: PhantomData,
}
}
}