rustyline/
config.rs

1//! Customize line editor
2use std::default::Default;
3
4/// User preferences
5#[derive(Clone, Copy, Debug, PartialEq, Eq)]
6pub struct Config {
7    /// Maximum number of entries in History.
8    max_history_size: usize, // history_max_entries
9    history_duplicates: HistoryDuplicates,
10    history_ignore_space: bool,
11    completion_type: CompletionType,
12    /// When listing completion alternatives, only display
13    /// one screen of possibilities at a time.
14    completion_prompt_limit: usize,
15    /// Duration (milliseconds) Rustyline will wait for a character when
16    /// reading an ambiguous key sequence.
17    keyseq_timeout: i32,
18    /// Emacs or Vi mode
19    edit_mode: EditMode,
20    /// If true, each nonblank line returned by `readline` will be
21    /// automatically added to the history.
22    auto_add_history: bool,
23    /// if colors should be enabled.
24    color_mode: ColorMode,
25    /// Whether to use stdout or stderr
26    output_stream: OutputStreamType,
27}
28
29impl Config {
30    pub fn builder() -> Builder {
31        Builder::new()
32    }
33
34    /// Tell the maximum length (i.e. number of entries) for the history.
35    pub fn max_history_size(&self) -> usize {
36        self.max_history_size
37    }
38
39    pub(crate) fn set_max_history_size(&mut self, max_size: usize) {
40        self.max_history_size = max_size;
41    }
42
43    /// Tell if lines which match the previous history entry are saved or not
44    /// in the history list.
45    ///
46    /// By default, they are ignored.
47    pub fn history_duplicates(&self) -> HistoryDuplicates {
48        self.history_duplicates
49    }
50
51    pub(crate) fn set_history_ignore_dups(&mut self, yes: bool) {
52        self.history_duplicates = if yes {
53            HistoryDuplicates::IgnoreConsecutive
54        } else {
55            HistoryDuplicates::AlwaysAdd
56        };
57    }
58
59    /// Tell if lines which begin with a space character are saved or not in
60    /// the history list.
61    ///
62    /// By default, they are saved.
63    pub fn history_ignore_space(&self) -> bool {
64        self.history_ignore_space
65    }
66
67    pub(crate) fn set_history_ignore_space(&mut self, yes: bool) {
68        self.history_ignore_space = yes;
69    }
70
71    pub fn completion_type(&self) -> CompletionType {
72        self.completion_type
73    }
74
75    pub fn completion_prompt_limit(&self) -> usize {
76        self.completion_prompt_limit
77    }
78
79    pub fn keyseq_timeout(&self) -> i32 {
80        self.keyseq_timeout
81    }
82
83    pub fn edit_mode(&self) -> EditMode {
84        self.edit_mode
85    }
86
87    /// Tell if lines are automatically added to the history.
88    ///
89    /// By default, they are not.
90    pub fn auto_add_history(&self) -> bool {
91        self.auto_add_history
92    }
93
94    /// Tell if colors should be enabled.
95    ///
96    /// By default, they are except if stdout is not a tty.
97    pub fn color_mode(&self) -> ColorMode {
98        self.color_mode
99    }
100
101    pub(crate) fn set_color_mode(&mut self, color_mode: ColorMode) {
102        self.color_mode = color_mode;
103    }
104
105    pub fn output_stream(&self) -> OutputStreamType {
106        self.output_stream
107    }
108
109    pub(crate) fn set_output_stream(&mut self, stream: OutputStreamType) {
110        self.output_stream = stream;
111    }
112}
113
114impl Default for Config {
115    fn default() -> Config {
116        Config {
117            max_history_size: 100,
118            history_duplicates: HistoryDuplicates::IgnoreConsecutive,
119            history_ignore_space: false,
120            completion_type: CompletionType::Circular, // TODO Validate
121            completion_prompt_limit: 100,
122            keyseq_timeout: -1,
123            edit_mode: EditMode::Emacs,
124            auto_add_history: false,
125            color_mode: ColorMode::Enabled,
126            output_stream: OutputStreamType::Stdout,
127        }
128    }
129}
130
131#[derive(Clone, Copy, Debug, PartialEq, Eq)]
132pub enum HistoryDuplicates {
133    AlwaysAdd,
134    /// a line will not be added to the history if it matches the previous entry
135    IgnoreConsecutive,
136}
137
138#[derive(Clone, Copy, Debug, PartialEq, Eq)]
139pub enum CompletionType {
140    /// Complete the next full match (like in Vim by default)
141    Circular,
142    /// Complete till longest match.
143    /// When more than one match, list all matches
144    /// (like in Bash/Readline).
145    List,
146}
147
148/// Style of editing / Standard keymaps
149#[derive(Clone, Copy, Debug, PartialEq, Eq)]
150pub enum EditMode {
151    Emacs,
152    Vi,
153}
154
155/// Colorization mode
156#[derive(Clone, Copy, Debug, PartialEq, Eq)]
157pub enum ColorMode {
158    Enabled,
159    Forced,
160    Disabled,
161}
162
163/// Should the editor use stdout or stderr
164#[derive(Clone, Copy, Debug, PartialEq, Eq)]
165pub enum OutputStreamType {
166    Stderr,
167    Stdout,
168}
169
170/// Configuration builder
171#[derive(Debug, Default)]
172pub struct Builder {
173    p: Config,
174}
175
176impl Builder {
177    pub fn new() -> Builder {
178        Builder {
179            p: Config::default(),
180        }
181    }
182
183    /// Set the maximum length for the history.
184    pub fn max_history_size(mut self, max_size: usize) -> Builder {
185        self.set_max_history_size(max_size);
186        self
187    }
188
189    /// Tell if lines which match the previous history entry are saved or not
190    /// in the history list.
191    ///
192    /// By default, they are ignored.
193    pub fn history_ignore_dups(mut self, yes: bool) -> Builder {
194        self.set_history_ignore_dups(yes);
195        self
196    }
197
198    /// Tell if lines which begin with a space character are saved or not in
199    /// the history list.
200    ///
201    /// By default, they are saved.
202    pub fn history_ignore_space(mut self, yes: bool) -> Builder {
203        self.set_history_ignore_space(yes);
204        self
205    }
206
207    /// Set `completion_type`.
208    pub fn completion_type(mut self, completion_type: CompletionType) -> Builder {
209        self.set_completion_type(completion_type);
210        self
211    }
212
213    /// The number of possible completions that determines when the user is
214    /// asked whether the list of possibilities should be displayed.
215    pub fn completion_prompt_limit(mut self, completion_prompt_limit: usize) -> Builder {
216        self.set_completion_prompt_limit(completion_prompt_limit);
217        self
218    }
219
220    /// Timeout for ambiguous key sequences in milliseconds.
221    /// Currently, it is used only to distinguish a single ESC from an ESC
222    /// sequence.
223    /// After seeing an ESC key, wait at most `keyseq_timeout_ms` for another
224    /// byte.
225    pub fn keyseq_timeout(mut self, keyseq_timeout_ms: i32) -> Builder {
226        self.set_keyseq_timeout(keyseq_timeout_ms);
227        self
228    }
229
230    /// Choose between Emacs or Vi mode.
231    pub fn edit_mode(mut self, edit_mode: EditMode) -> Builder {
232        self.set_edit_mode(edit_mode);
233        self
234    }
235
236    /// Tell if lines are automatically added to the history.
237    ///
238    /// By default, they are not.
239    pub fn auto_add_history(mut self, yes: bool) -> Builder {
240        self.set_auto_add_history(yes);
241        self
242    }
243
244    /// Forces colorization on or off.
245    ///
246    /// By default, colorization is on except if stdout is not a tty.
247    pub fn color_mode(mut self, color_mode: ColorMode) -> Builder {
248        self.set_color_mode(color_mode);
249        self
250    }
251
252    /// Whether to use stdout or stderr.
253    ///
254    /// Be default, use stdout
255    pub fn output_stream(mut self, stream: OutputStreamType) -> Builder {
256        self.set_output_stream(stream);
257        self
258    }
259
260    pub fn build(self) -> Config {
261        self.p
262    }
263}
264
265impl Configurer for Builder {
266    fn config_mut(&mut self) -> &mut Config {
267        &mut self.p
268    }
269}
270
271pub trait Configurer {
272    fn config_mut(&mut self) -> &mut Config;
273
274    /// Set the maximum length for the history.
275    fn set_max_history_size(&mut self, max_size: usize) {
276        self.config_mut().set_max_history_size(max_size);
277    }
278
279    /// Tell if lines which match the previous history entry are saved or not
280    /// in the history list.
281    ///
282    /// By default, they are ignored.
283    fn set_history_ignore_dups(&mut self, yes: bool) {
284        self.config_mut().set_history_ignore_dups(yes);
285    }
286
287    /// Tell if lines which begin with a space character are saved or not in
288    /// the history list.
289    ///
290    /// By default, they are saved.
291    fn set_history_ignore_space(&mut self, yes: bool) {
292        self.config_mut().set_history_ignore_space(yes);
293    }
294    /// Set `completion_type`.
295    fn set_completion_type(&mut self, completion_type: CompletionType) {
296        self.config_mut().completion_type = completion_type;
297    }
298
299    /// The number of possible completions that determines when the user is
300    /// asked whether the list of possibilities should be displayed.
301    fn set_completion_prompt_limit(&mut self, completion_prompt_limit: usize) {
302        self.config_mut().completion_prompt_limit = completion_prompt_limit;
303    }
304
305    /// Timeout for ambiguous key sequences in milliseconds.
306    fn set_keyseq_timeout(&mut self, keyseq_timeout_ms: i32) {
307        self.config_mut().keyseq_timeout = keyseq_timeout_ms;
308    }
309
310    /// Choose between Emacs or Vi mode.
311    fn set_edit_mode(&mut self, edit_mode: EditMode) {
312        self.config_mut().edit_mode = edit_mode;
313        match edit_mode {
314            EditMode::Emacs => self.set_keyseq_timeout(-1), // no timeout
315            EditMode::Vi => self.set_keyseq_timeout(500),
316        }
317    }
318
319    /// Tell if lines are automatically added to the history.
320    ///
321    /// By default, they are not.
322    fn set_auto_add_history(&mut self, yes: bool) {
323        self.config_mut().auto_add_history = yes;
324    }
325
326    /// Forces colorization on or off.
327    ///
328    /// By default, colorization is on except if stdout is not a tty.
329    fn set_color_mode(&mut self, color_mode: ColorMode) {
330        self.config_mut().set_color_mode(color_mode);
331    }
332
333    /// Whether to use stdout or stderr
334    ///
335    /// By default, use stdout
336    fn set_output_stream(&mut self, stream: OutputStreamType) {
337        self.config_mut().set_output_stream(stream);
338    }
339}