/rust/registry/src/index.crates.io-6f17d22bba15001f/rustyline-11.0.0/src/config.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Customize line editor |
2 | | use crate::Result; |
3 | | use std::default::Default; |
4 | | |
5 | | /// User preferences |
6 | | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
7 | | pub struct Config { |
8 | | /// Maximum number of entries in History. |
9 | | max_history_size: usize, // history_max_entries |
10 | | history_duplicates: HistoryDuplicates, |
11 | | history_ignore_space: bool, |
12 | | completion_type: CompletionType, |
13 | | /// When listing completion alternatives, only display |
14 | | /// one screen of possibilities at a time. |
15 | | completion_prompt_limit: usize, |
16 | | /// Duration (milliseconds) Rustyline will wait for a character when |
17 | | /// reading an ambiguous key sequence. |
18 | | keyseq_timeout: i32, |
19 | | /// Emacs or Vi mode |
20 | | edit_mode: EditMode, |
21 | | /// If true, each nonblank line returned by `readline` will be |
22 | | /// automatically added to the history. |
23 | | auto_add_history: bool, |
24 | | /// Beep or Flash or nothing |
25 | | bell_style: BellStyle, |
26 | | /// if colors should be enabled. |
27 | | color_mode: ColorMode, |
28 | | /// Whether to use stdio or not |
29 | | behavior: Behavior, |
30 | | /// Horizontal space taken by a tab. |
31 | | tab_stop: usize, |
32 | | /// Indentation size for indent/dedent commands |
33 | | indent_size: usize, |
34 | | /// Check if cursor position is at leftmost before displaying prompt |
35 | | check_cursor_position: bool, |
36 | | /// Bracketed paste on unix platform |
37 | | enable_bracketed_paste: bool, |
38 | | } |
39 | | |
40 | | impl Config { |
41 | | /// Returns a `Config` builder. |
42 | | #[must_use] |
43 | 0 | pub fn builder() -> Builder { |
44 | 0 | Builder::new() |
45 | 0 | } |
46 | | |
47 | | /// Tell the maximum length (i.e. number of entries) for the history. |
48 | | #[must_use] |
49 | 0 | pub fn max_history_size(&self) -> usize { |
50 | 0 | self.max_history_size |
51 | 0 | } |
52 | | |
53 | 0 | pub(crate) fn set_max_history_size(&mut self, max_size: usize) { |
54 | 0 | self.max_history_size = max_size; |
55 | 0 | } |
56 | | |
57 | | /// Tell if lines which match the previous history entry are saved or not |
58 | | /// in the history list. |
59 | | /// |
60 | | /// By default, they are ignored. |
61 | | #[must_use] |
62 | 0 | pub fn history_duplicates(&self) -> HistoryDuplicates { |
63 | 0 | self.history_duplicates |
64 | 0 | } |
65 | | |
66 | 0 | pub(crate) fn set_history_ignore_dups(&mut self, yes: bool) { |
67 | 0 | self.history_duplicates = if yes { |
68 | 0 | HistoryDuplicates::IgnoreConsecutive |
69 | | } else { |
70 | 0 | HistoryDuplicates::AlwaysAdd |
71 | | }; |
72 | 0 | } |
73 | | |
74 | | /// Tell if lines which begin with a space character are saved or not in |
75 | | /// the history list. |
76 | | /// |
77 | | /// By default, they are saved. |
78 | | #[must_use] |
79 | 0 | pub fn history_ignore_space(&self) -> bool { |
80 | 0 | self.history_ignore_space |
81 | 0 | } |
82 | | |
83 | 0 | pub(crate) fn set_history_ignore_space(&mut self, yes: bool) { |
84 | 0 | self.history_ignore_space = yes; |
85 | 0 | } |
86 | | |
87 | | /// Completion behaviour. |
88 | | /// |
89 | | /// By default, `CompletionType::Circular`. |
90 | | #[must_use] |
91 | 0 | pub fn completion_type(&self) -> CompletionType { |
92 | 0 | self.completion_type |
93 | 0 | } |
94 | | |
95 | | /// When listing completion alternatives, only display |
96 | | /// one screen of possibilities at a time (used for `CompletionType::List` |
97 | | /// mode). |
98 | | #[must_use] |
99 | 0 | pub fn completion_prompt_limit(&self) -> usize { |
100 | 0 | self.completion_prompt_limit |
101 | 0 | } |
102 | | |
103 | | /// Duration (milliseconds) Rustyline will wait for a character when |
104 | | /// reading an ambiguous key sequence (used for `EditMode::Vi` mode on unix |
105 | | /// platform). |
106 | | /// |
107 | | /// By default, no timeout (-1) or 500ms if `EditMode::Vi` is activated. |
108 | | #[must_use] |
109 | 0 | pub fn keyseq_timeout(&self) -> i32 { |
110 | 0 | self.keyseq_timeout |
111 | 0 | } |
112 | | |
113 | | /// Emacs or Vi mode |
114 | | #[must_use] |
115 | 0 | pub fn edit_mode(&self) -> EditMode { |
116 | 0 | self.edit_mode |
117 | 0 | } |
118 | | |
119 | | /// Tell if lines are automatically added to the history. |
120 | | /// |
121 | | /// By default, they are not. |
122 | | #[must_use] |
123 | 0 | pub fn auto_add_history(&self) -> bool { |
124 | 0 | self.auto_add_history |
125 | 0 | } |
126 | | |
127 | | /// Bell style: beep, flash or nothing. |
128 | | #[must_use] |
129 | 0 | pub fn bell_style(&self) -> BellStyle { |
130 | 0 | self.bell_style |
131 | 0 | } |
132 | | |
133 | | /// Tell if colors should be enabled. |
134 | | /// |
135 | | /// By default, they are except if stdout is not a TTY. |
136 | | #[must_use] |
137 | 0 | pub fn color_mode(&self) -> ColorMode { |
138 | 0 | self.color_mode |
139 | 0 | } |
140 | | |
141 | 0 | pub(crate) fn set_color_mode(&mut self, color_mode: ColorMode) { |
142 | 0 | self.color_mode = color_mode; |
143 | 0 | } |
144 | | |
145 | | /// Whether to use stdio or not |
146 | | /// |
147 | | /// By default, stdio is used. |
148 | | #[must_use] |
149 | 0 | pub fn behavior(&self) -> Behavior { |
150 | 0 | self.behavior |
151 | 0 | } |
152 | | |
153 | 0 | pub(crate) fn set_behavior(&mut self, behavior: Behavior) { |
154 | 0 | self.behavior = behavior; |
155 | 0 | } |
156 | | |
157 | | /// Horizontal space taken by a tab. |
158 | | /// |
159 | | /// By default, 8. |
160 | | #[must_use] |
161 | 0 | pub fn tab_stop(&self) -> usize { |
162 | 0 | self.tab_stop |
163 | 0 | } |
164 | | |
165 | 0 | pub(crate) fn set_tab_stop(&mut self, tab_stop: usize) { |
166 | 0 | self.tab_stop = tab_stop; |
167 | 0 | } |
168 | | |
169 | | /// Check if cursor position is at leftmost before displaying prompt. |
170 | | /// |
171 | | /// By default, we don't check. |
172 | | #[must_use] |
173 | 0 | pub fn check_cursor_position(&self) -> bool { |
174 | 0 | self.check_cursor_position |
175 | 0 | } |
176 | | |
177 | | /// Indentation size used by indentation commands |
178 | | /// |
179 | | /// By default, 2. |
180 | | #[must_use] |
181 | 0 | pub fn indent_size(&self) -> usize { |
182 | 0 | self.indent_size |
183 | 0 | } |
184 | | |
185 | 0 | pub(crate) fn set_indent_size(&mut self, indent_size: usize) { |
186 | 0 | self.indent_size = indent_size; |
187 | 0 | } |
188 | | |
189 | | /// Bracketed paste on unix platform |
190 | | /// |
191 | | /// By default, it's enabled. |
192 | | #[must_use] |
193 | 0 | pub fn enable_bracketed_paste(&self) -> bool { |
194 | 0 | self.enable_bracketed_paste |
195 | 0 | } |
196 | | } |
197 | | |
198 | | impl Default for Config { |
199 | 0 | fn default() -> Self { |
200 | 0 | Self { |
201 | 0 | max_history_size: 100, |
202 | 0 | history_duplicates: HistoryDuplicates::IgnoreConsecutive, |
203 | 0 | history_ignore_space: false, |
204 | 0 | completion_type: CompletionType::Circular, // TODO Validate |
205 | 0 | completion_prompt_limit: 100, |
206 | 0 | keyseq_timeout: -1, |
207 | 0 | edit_mode: EditMode::Emacs, |
208 | 0 | auto_add_history: false, |
209 | 0 | bell_style: BellStyle::default(), |
210 | 0 | color_mode: ColorMode::Enabled, |
211 | 0 | behavior: Behavior::default(), |
212 | 0 | tab_stop: 8, |
213 | 0 | indent_size: 2, |
214 | 0 | check_cursor_position: false, |
215 | 0 | enable_bracketed_paste: true, |
216 | 0 | } |
217 | 0 | } |
218 | | } |
219 | | |
220 | | /// Beep or flash or nothing |
221 | | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
222 | | pub enum BellStyle { |
223 | | /// Beep |
224 | | Audible, |
225 | | /// Silent |
226 | | None, |
227 | | /// Flash screen (not supported) |
228 | | Visible, |
229 | | } |
230 | | |
231 | | /// `Audible` by default on unix (overridden by current Terminal settings). |
232 | | /// `None` on windows. |
233 | | impl Default for BellStyle { |
234 | | #[cfg(any(windows, target_arch = "wasm32"))] |
235 | | fn default() -> Self { |
236 | | BellStyle::None |
237 | | } |
238 | | |
239 | | #[cfg(unix)] |
240 | 0 | fn default() -> Self { |
241 | 0 | BellStyle::Audible |
242 | 0 | } |
243 | | } |
244 | | |
245 | | /// History filter |
246 | | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
247 | | pub enum HistoryDuplicates { |
248 | | /// No filter |
249 | | AlwaysAdd, |
250 | | /// a line will not be added to the history if it matches the previous entry |
251 | | IgnoreConsecutive, |
252 | | } |
253 | | |
254 | | /// Tab completion style |
255 | | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
256 | | #[non_exhaustive] |
257 | | pub enum CompletionType { |
258 | | /// Complete the next full match (like in Vim by default) |
259 | | Circular, |
260 | | /// Complete till longest match. |
261 | | /// When more than one match, list all matches |
262 | | /// (like in Bash/Readline). |
263 | | List, |
264 | | |
265 | | /// Complete the match using fuzzy search and selection |
266 | | /// (like fzf and plugins) |
267 | | /// Currently only available for unix platforms as dependency on |
268 | | /// skim->tuikit Compile with `--features=fuzzy` to enable |
269 | | #[cfg(all(unix, feature = "with-fuzzy"))] |
270 | | Fuzzy, |
271 | | } |
272 | | |
273 | | /// Style of editing / Standard keymaps |
274 | | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
275 | | #[non_exhaustive] |
276 | | pub enum EditMode { |
277 | | /// Emacs keymap |
278 | | Emacs, |
279 | | /// Vi keymap |
280 | | Vi, |
281 | | } |
282 | | |
283 | | /// Colorization mode |
284 | | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
285 | | #[non_exhaustive] |
286 | | pub enum ColorMode { |
287 | | /// Activate highlighting if platform/terminal is supported. |
288 | | Enabled, |
289 | | /// Activate highlighting even if platform is not supported (windows < 10). |
290 | | Forced, |
291 | | /// Deactivate highlighting even if platform/terminal is supported. |
292 | | Disabled, |
293 | | } |
294 | | |
295 | | /// Should the editor use stdio |
296 | | #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] |
297 | | #[non_exhaustive] |
298 | | pub enum Behavior { |
299 | | /// Use stdin / stdout |
300 | | #[default] |
301 | | Stdio, |
302 | | /// Use terminal-style interaction whenever possible, even if 'stdin' and/or |
303 | | /// 'stdout' are not terminals. |
304 | | PreferTerm, |
305 | | // TODO |
306 | | // Use file-style interaction, reading input from the given file. |
307 | | // useFile |
308 | | } |
309 | | |
310 | | /// Configuration builder |
311 | | #[derive(Clone, Debug, Default)] |
312 | | pub struct Builder { |
313 | | p: Config, |
314 | | } |
315 | | |
316 | | impl Builder { |
317 | | /// Returns a `Config` builder. |
318 | | #[must_use] |
319 | 0 | pub fn new() -> Self { |
320 | 0 | Self { |
321 | 0 | p: Config::default(), |
322 | 0 | } |
323 | 0 | } |
324 | | |
325 | | /// Set the maximum length for the history. |
326 | 0 | pub fn max_history_size(mut self, max_size: usize) -> Result<Self> { |
327 | 0 | self.set_max_history_size(max_size)?; |
328 | 0 | Ok(self) |
329 | 0 | } |
330 | | |
331 | | /// Tell if lines which match the previous history entry are saved or not |
332 | | /// in the history list. |
333 | | /// |
334 | | /// By default, they are ignored. |
335 | 0 | pub fn history_ignore_dups(mut self, yes: bool) -> Result<Self> { |
336 | 0 | self.set_history_ignore_dups(yes)?; |
337 | 0 | Ok(self) |
338 | 0 | } |
339 | | |
340 | | /// Tell if lines which begin with a space character are saved or not in |
341 | | /// the history list. |
342 | | /// |
343 | | /// By default, they are saved. |
344 | | #[must_use] |
345 | 0 | pub fn history_ignore_space(mut self, yes: bool) -> Self { |
346 | 0 | self.set_history_ignore_space(yes); |
347 | 0 | self |
348 | 0 | } |
349 | | |
350 | | /// Set `completion_type`. |
351 | | #[must_use] |
352 | 0 | pub fn completion_type(mut self, completion_type: CompletionType) -> Self { |
353 | 0 | self.set_completion_type(completion_type); |
354 | 0 | self |
355 | 0 | } |
356 | | |
357 | | /// The number of possible completions that determines when the user is |
358 | | /// asked whether the list of possibilities should be displayed. |
359 | | #[must_use] |
360 | 0 | pub fn completion_prompt_limit(mut self, completion_prompt_limit: usize) -> Self { |
361 | 0 | self.set_completion_prompt_limit(completion_prompt_limit); |
362 | 0 | self |
363 | 0 | } |
364 | | |
365 | | /// Timeout for ambiguous key sequences in milliseconds. |
366 | | /// Currently, it is used only to distinguish a single ESC from an ESC |
367 | | /// sequence. |
368 | | /// After seeing an ESC key, wait at most `keyseq_timeout_ms` for another |
369 | | /// byte. |
370 | | #[must_use] |
371 | 0 | pub fn keyseq_timeout(mut self, keyseq_timeout_ms: i32) -> Self { |
372 | 0 | self.set_keyseq_timeout(keyseq_timeout_ms); |
373 | 0 | self |
374 | 0 | } |
375 | | |
376 | | /// Choose between Emacs or Vi mode. |
377 | | #[must_use] |
378 | 0 | pub fn edit_mode(mut self, edit_mode: EditMode) -> Self { |
379 | 0 | self.set_edit_mode(edit_mode); |
380 | 0 | self |
381 | 0 | } |
382 | | |
383 | | /// Tell if lines are automatically added to the history. |
384 | | /// |
385 | | /// By default, they are not. |
386 | | #[must_use] |
387 | 0 | pub fn auto_add_history(mut self, yes: bool) -> Self { |
388 | 0 | self.set_auto_add_history(yes); |
389 | 0 | self |
390 | 0 | } |
391 | | |
392 | | /// Set bell style: beep, flash or nothing. |
393 | | #[must_use] |
394 | 0 | pub fn bell_style(mut self, bell_style: BellStyle) -> Self { |
395 | 0 | self.set_bell_style(bell_style); |
396 | 0 | self |
397 | 0 | } |
398 | | |
399 | | /// Forces colorization on or off. |
400 | | /// |
401 | | /// By default, colorization is on except if stdout is not a TTY. |
402 | | #[must_use] |
403 | 0 | pub fn color_mode(mut self, color_mode: ColorMode) -> Self { |
404 | 0 | self.set_color_mode(color_mode); |
405 | 0 | self |
406 | 0 | } |
407 | | |
408 | | /// Whether to use stdio or not |
409 | | /// |
410 | | /// By default, stdio is used. |
411 | | #[must_use] |
412 | 0 | pub fn behavior(mut self, behavior: Behavior) -> Self { |
413 | 0 | self.set_behavior(behavior); |
414 | 0 | self |
415 | 0 | } |
416 | | |
417 | | /// Horizontal space taken by a tab. |
418 | | /// |
419 | | /// By default, `8` |
420 | | #[must_use] |
421 | 0 | pub fn tab_stop(mut self, tab_stop: usize) -> Self { |
422 | 0 | self.set_tab_stop(tab_stop); |
423 | 0 | self |
424 | 0 | } |
425 | | |
426 | | /// Check if cursor position is at leftmost before displaying prompt. |
427 | | /// |
428 | | /// By default, we don't check. |
429 | | #[must_use] |
430 | 0 | pub fn check_cursor_position(mut self, yes: bool) -> Self { |
431 | 0 | self.set_check_cursor_position(yes); |
432 | 0 | self |
433 | 0 | } |
434 | | |
435 | | /// Indentation size |
436 | | /// |
437 | | /// By default, `2` |
438 | | #[must_use] |
439 | 0 | pub fn indent_size(mut self, indent_size: usize) -> Self { |
440 | 0 | self.set_indent_size(indent_size); |
441 | 0 | self |
442 | 0 | } |
443 | | |
444 | | /// Enable or disable bracketed paste on unix platform |
445 | | /// |
446 | | /// By default, it's enabled. |
447 | | #[must_use] |
448 | 0 | pub fn bracketed_paste(mut self, enabled: bool) -> Self { |
449 | 0 | self.enable_bracketed_paste(enabled); |
450 | 0 | self |
451 | 0 | } |
452 | | |
453 | | /// Builds a `Config` with the settings specified so far. |
454 | | #[must_use] |
455 | 0 | pub fn build(self) -> Config { |
456 | 0 | self.p |
457 | 0 | } |
458 | | } |
459 | | |
460 | | impl Configurer for Builder { |
461 | 0 | fn config_mut(&mut self) -> &mut Config { |
462 | 0 | &mut self.p |
463 | 0 | } |
464 | | } |
465 | | |
466 | | /// Trait for component that holds a `Config`. |
467 | | pub trait Configurer { |
468 | | /// `Config` accessor. |
469 | | fn config_mut(&mut self) -> &mut Config; |
470 | | |
471 | | /// Set the maximum length for the history. |
472 | 0 | fn set_max_history_size(&mut self, max_size: usize) -> Result<()> { |
473 | 0 | self.config_mut().set_max_history_size(max_size); |
474 | 0 | Ok(()) |
475 | 0 | } |
476 | | |
477 | | /// Tell if lines which match the previous history entry are saved or not |
478 | | /// in the history list. |
479 | | /// |
480 | | /// By default, they are ignored. |
481 | 0 | fn set_history_ignore_dups(&mut self, yes: bool) -> Result<()> { |
482 | 0 | self.config_mut().set_history_ignore_dups(yes); |
483 | 0 | Ok(()) |
484 | 0 | } |
485 | | |
486 | | /// Tell if lines which begin with a space character are saved or not in |
487 | | /// the history list. |
488 | | /// |
489 | | /// By default, they are saved. |
490 | 0 | fn set_history_ignore_space(&mut self, yes: bool) { |
491 | 0 | self.config_mut().set_history_ignore_space(yes); |
492 | 0 | } |
493 | | /// Set `completion_type`. |
494 | 0 | fn set_completion_type(&mut self, completion_type: CompletionType) { |
495 | 0 | self.config_mut().completion_type = completion_type; |
496 | 0 | } |
497 | | |
498 | | /// The number of possible completions that determines when the user is |
499 | | /// asked whether the list of possibilities should be displayed. |
500 | 0 | fn set_completion_prompt_limit(&mut self, completion_prompt_limit: usize) { |
501 | 0 | self.config_mut().completion_prompt_limit = completion_prompt_limit; |
502 | 0 | } |
503 | | |
504 | | /// Timeout for ambiguous key sequences in milliseconds. |
505 | 0 | fn set_keyseq_timeout(&mut self, keyseq_timeout_ms: i32) { |
506 | 0 | self.config_mut().keyseq_timeout = keyseq_timeout_ms; |
507 | 0 | } |
508 | | |
509 | | /// Choose between Emacs or Vi mode. |
510 | 0 | fn set_edit_mode(&mut self, edit_mode: EditMode) { |
511 | 0 | self.config_mut().edit_mode = edit_mode; |
512 | 0 | match edit_mode { |
513 | 0 | EditMode::Emacs => self.set_keyseq_timeout(-1), // no timeout |
514 | 0 | EditMode::Vi => self.set_keyseq_timeout(500), |
515 | | } |
516 | 0 | } |
517 | | |
518 | | /// Tell if lines are automatically added to the history. |
519 | | /// |
520 | | /// By default, they are not. |
521 | 0 | fn set_auto_add_history(&mut self, yes: bool) { |
522 | 0 | self.config_mut().auto_add_history = yes; |
523 | 0 | } |
524 | | |
525 | | /// Set bell style: beep, flash or nothing. |
526 | 0 | fn set_bell_style(&mut self, bell_style: BellStyle) { |
527 | 0 | self.config_mut().bell_style = bell_style; |
528 | 0 | } |
529 | | |
530 | | /// Forces colorization on or off. |
531 | | /// |
532 | | /// By default, colorization is on except if stdout is not a TTY. |
533 | 0 | fn set_color_mode(&mut self, color_mode: ColorMode) { |
534 | 0 | self.config_mut().set_color_mode(color_mode); |
535 | 0 | } |
536 | | |
537 | | /// Whether to use stdio or not |
538 | | /// |
539 | | /// By default, stdio is used. |
540 | 0 | fn set_behavior(&mut self, behavior: Behavior) { |
541 | 0 | self.config_mut().set_behavior(behavior); |
542 | 0 | } |
543 | | |
544 | | /// Horizontal space taken by a tab. |
545 | | /// |
546 | | /// By default, `8` |
547 | 0 | fn set_tab_stop(&mut self, tab_stop: usize) { |
548 | 0 | self.config_mut().set_tab_stop(tab_stop); |
549 | 0 | } |
550 | | |
551 | | /// Check if cursor position is at leftmost before displaying prompt. |
552 | | /// |
553 | | /// By default, we don't check. |
554 | 0 | fn set_check_cursor_position(&mut self, yes: bool) { |
555 | 0 | self.config_mut().check_cursor_position = yes; |
556 | 0 | } |
557 | | /// Indentation size for indent/dedent commands |
558 | | /// |
559 | | /// By default, `2` |
560 | 0 | fn set_indent_size(&mut self, size: usize) { |
561 | 0 | self.config_mut().set_indent_size(size); |
562 | 0 | } |
563 | | |
564 | | /// Enable or disable bracketed paste on unix platform |
565 | | /// |
566 | | /// By default, it's enabled. |
567 | 0 | fn enable_bracketed_paste(&mut self, enabled: bool) { |
568 | 0 | self.config_mut().enable_bracketed_paste = enabled; |
569 | 0 | } |
570 | | } |