1use crate::{layout::GraphemeClusterMode, Result};
3use std::default::Default;
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub struct Config {
8 max_history_size: usize, history_duplicates: HistoryDuplicates,
11 history_ignore_space: bool,
12 completion_type: CompletionType,
13 completion_show_all_if_ambiguous: bool,
16 completion_prompt_limit: usize,
19 keyseq_timeout: Option<u16>,
22 edit_mode: EditMode,
24 auto_add_history: bool,
27 bell_style: BellStyle,
29 color_mode: ColorMode,
31 grapheme_cluster_mode: GraphemeClusterMode,
33 behavior: Behavior,
35 tab_stop: u8,
37 indent_size: u8,
39 check_cursor_position: bool,
41 enable_bracketed_paste: bool,
43 enable_synchronized_output: bool,
45 enable_signals: bool,
47}
48
49impl Config {
50 #[must_use]
52 pub fn builder() -> Builder {
53 Builder::new()
54 }
55
56 #[must_use]
58 pub fn max_history_size(&self) -> usize {
59 self.max_history_size
60 }
61
62 pub(crate) fn set_max_history_size(&mut self, max_size: usize) {
63 self.max_history_size = max_size;
64 }
65
66 #[must_use]
71 pub fn history_duplicates(&self) -> HistoryDuplicates {
72 self.history_duplicates
73 }
74
75 pub(crate) fn set_history_ignore_dups(&mut self, yes: bool) {
76 self.history_duplicates = if yes {
77 HistoryDuplicates::IgnoreConsecutive
78 } else {
79 HistoryDuplicates::AlwaysAdd
80 };
81 }
82
83 #[must_use]
88 pub fn history_ignore_space(&self) -> bool {
89 self.history_ignore_space
90 }
91
92 pub(crate) fn set_history_ignore_space(&mut self, yes: bool) {
93 self.history_ignore_space = yes;
94 }
95
96 #[must_use]
100 pub fn completion_type(&self) -> CompletionType {
101 self.completion_type
102 }
103
104 #[must_use]
108 pub fn completion_prompt_limit(&self) -> usize {
109 self.completion_prompt_limit
110 }
111
112 #[must_use]
116 pub fn completion_show_all_if_ambiguous(&self) -> bool {
117 self.completion_show_all_if_ambiguous
118 }
119
120 #[must_use]
126 pub fn keyseq_timeout(&self) -> Option<u16> {
127 self.keyseq_timeout
128 }
129
130 #[must_use]
132 pub fn edit_mode(&self) -> EditMode {
133 self.edit_mode
134 }
135
136 #[must_use]
140 pub fn auto_add_history(&self) -> bool {
141 self.auto_add_history
142 }
143
144 #[must_use]
146 pub fn bell_style(&self) -> BellStyle {
147 self.bell_style
148 }
149
150 #[must_use]
154 pub fn color_mode(&self) -> ColorMode {
155 self.color_mode
156 }
157
158 #[must_use]
160 pub fn grapheme_cluster_mode(&self) -> GraphemeClusterMode {
161 self.grapheme_cluster_mode
162 }
163
164 pub(crate) fn set_color_mode(&mut self, color_mode: ColorMode) {
165 self.color_mode = color_mode;
166 }
167
168 #[must_use]
172 pub fn behavior(&self) -> Behavior {
173 self.behavior
174 }
175
176 pub(crate) fn set_behavior(&mut self, behavior: Behavior) {
177 self.behavior = behavior;
178 }
179
180 #[must_use]
184 pub fn tab_stop(&self) -> u8 {
185 self.tab_stop
186 }
187
188 pub(crate) fn set_tab_stop(&mut self, tab_stop: u8) {
189 self.tab_stop = tab_stop;
190 }
191
192 #[must_use]
196 pub fn check_cursor_position(&self) -> bool {
197 self.check_cursor_position
198 }
199
200 #[must_use]
204 pub fn indent_size(&self) -> u8 {
205 self.indent_size
206 }
207
208 pub(crate) fn set_indent_size(&mut self, indent_size: u8) {
209 self.indent_size = indent_size;
210 }
211
212 #[must_use]
216 pub fn enable_bracketed_paste(&self) -> bool {
217 self.enable_bracketed_paste
218 }
219
220 #[must_use]
224 pub fn enable_synchronized_output(&self) -> bool {
225 self.enable_synchronized_output
226 }
227
228 #[must_use]
232 pub fn enable_signals(&self) -> bool {
233 self.enable_signals
234 }
235
236 pub(crate) fn set_enable_signals(&mut self, enable_signals: bool) {
237 self.enable_signals = enable_signals;
238 }
239}
240
241impl Default for Config {
242 fn default() -> Self {
243 Self {
244 max_history_size: 100,
245 history_duplicates: HistoryDuplicates::IgnoreConsecutive,
246 history_ignore_space: false,
247 completion_type: CompletionType::Circular, completion_prompt_limit: 100,
249 completion_show_all_if_ambiguous: false,
250 keyseq_timeout: None,
251 edit_mode: EditMode::Emacs,
252 auto_add_history: false,
253 bell_style: BellStyle::default(),
254 color_mode: ColorMode::Enabled,
255 grapheme_cluster_mode: GraphemeClusterMode::from_env(),
256 behavior: Behavior::default(),
257 tab_stop: 8,
258 indent_size: 2,
259 check_cursor_position: false,
260 enable_bracketed_paste: true,
261 enable_synchronized_output: true,
262 enable_signals: false,
263 }
264 }
265}
266
267#[derive(Clone, Copy, Debug, PartialEq, Eq)]
269pub enum BellStyle {
270 Audible,
272 None,
274 Visible,
276}
277
278impl Default for BellStyle {
281 #[cfg(any(windows, target_arch = "wasm32"))]
282 fn default() -> Self {
283 Self::None
284 }
285
286 #[cfg(unix)]
287 fn default() -> Self {
288 Self::Audible
289 }
290}
291
292#[derive(Clone, Copy, Debug, PartialEq, Eq)]
294pub enum HistoryDuplicates {
295 AlwaysAdd,
297 IgnoreConsecutive,
299}
300
301#[derive(Clone, Copy, Debug, PartialEq, Eq)]
303#[non_exhaustive]
304pub enum CompletionType {
305 Circular,
307 List,
311
312 #[cfg(all(unix, feature = "with-fuzzy"))]
317 Fuzzy,
318}
319
320#[derive(Clone, Copy, Debug, PartialEq, Eq)]
322#[non_exhaustive]
323pub enum EditMode {
324 Emacs,
326 Vi,
328}
329
330#[derive(Clone, Copy, Debug, PartialEq, Eq)]
332#[non_exhaustive]
333pub enum ColorMode {
334 Enabled,
336 Forced,
338 Disabled,
340}
341
342#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
344#[non_exhaustive]
345pub enum Behavior {
346 #[default]
348 Stdio,
349 PreferTerm,
352 }
356
357#[derive(Clone, Debug, Default)]
359pub struct Builder {
360 p: Config,
361}
362
363impl Builder {
364 #[must_use]
366 pub fn new() -> Self {
367 Self {
368 p: Config::default(),
369 }
370 }
371
372 pub fn max_history_size(mut self, max_size: usize) -> Result<Self> {
374 self.set_max_history_size(max_size)?;
375 Ok(self)
376 }
377
378 pub fn history_ignore_dups(mut self, yes: bool) -> Result<Self> {
383 self.set_history_ignore_dups(yes)?;
384 Ok(self)
385 }
386
387 #[must_use]
392 pub fn history_ignore_space(mut self, yes: bool) -> Self {
393 self.set_history_ignore_space(yes);
394 self
395 }
396
397 #[must_use]
399 pub fn completion_type(mut self, completion_type: CompletionType) -> Self {
400 self.set_completion_type(completion_type);
401 self
402 }
403
404 #[must_use]
407 pub fn completion_prompt_limit(mut self, completion_prompt_limit: usize) -> Self {
408 self.set_completion_prompt_limit(completion_prompt_limit);
409 self
410 }
411
412 #[must_use]
417 pub fn completion_show_all_if_ambiguous(
418 mut self,
419 completion_show_all_if_ambiguous: bool,
420 ) -> Self {
421 self.set_completion_show_all_if_ambiguous(completion_show_all_if_ambiguous);
422 self
423 }
424
425 #[must_use]
431 pub fn keyseq_timeout(mut self, keyseq_timeout_ms: Option<u16>) -> Self {
432 self.set_keyseq_timeout(keyseq_timeout_ms);
433 self
434 }
435
436 #[must_use]
438 pub fn edit_mode(mut self, edit_mode: EditMode) -> Self {
439 self.set_edit_mode(edit_mode);
440 self
441 }
442
443 #[must_use]
447 pub fn auto_add_history(mut self, yes: bool) -> Self {
448 self.set_auto_add_history(yes);
449 self
450 }
451
452 #[must_use]
454 pub fn bell_style(mut self, bell_style: BellStyle) -> Self {
455 self.set_bell_style(bell_style);
456 self
457 }
458
459 #[must_use]
463 pub fn color_mode(mut self, color_mode: ColorMode) -> Self {
464 self.set_color_mode(color_mode);
465 self
466 }
467
468 #[must_use]
470 pub fn grapheme_cluster_mode(mut self, grapheme_cluster_mode: GraphemeClusterMode) -> Self {
471 self.set_grapheme_cluster_mode(grapheme_cluster_mode);
472 self
473 }
474
475 #[must_use]
479 pub fn behavior(mut self, behavior: Behavior) -> Self {
480 self.set_behavior(behavior);
481 self
482 }
483
484 #[must_use]
488 pub fn tab_stop(mut self, tab_stop: u8) -> Self {
489 self.set_tab_stop(tab_stop);
490 self
491 }
492
493 #[must_use]
497 pub fn check_cursor_position(mut self, yes: bool) -> Self {
498 self.set_check_cursor_position(yes);
499 self
500 }
501
502 #[must_use]
506 pub fn indent_size(mut self, indent_size: u8) -> Self {
507 self.set_indent_size(indent_size);
508 self
509 }
510
511 #[must_use]
515 pub fn bracketed_paste(mut self, enabled: bool) -> Self {
516 self.enable_bracketed_paste(enabled);
517 self
518 }
519
520 #[must_use]
524 pub fn enable_signals(mut self, enable_signals: bool) -> Self {
525 self.p.set_enable_signals(enable_signals);
526 self
527 }
528
529 #[must_use]
531 pub fn build(self) -> Config {
532 self.p
533 }
534}
535
536impl Configurer for Builder {
537 fn config_mut(&mut self) -> &mut Config {
538 &mut self.p
539 }
540}
541
542pub trait Configurer {
544 fn config_mut(&mut self) -> &mut Config;
546
547 fn set_max_history_size(&mut self, max_size: usize) -> Result<()> {
549 self.config_mut().set_max_history_size(max_size);
550 Ok(())
551 }
552
553 fn set_history_ignore_dups(&mut self, yes: bool) -> Result<()> {
558 self.config_mut().set_history_ignore_dups(yes);
559 Ok(())
560 }
561
562 fn set_history_ignore_space(&mut self, yes: bool) {
567 self.config_mut().set_history_ignore_space(yes);
568 }
569 fn set_completion_type(&mut self, completion_type: CompletionType) {
571 self.config_mut().completion_type = completion_type;
572 }
573
574 fn set_completion_show_all_if_ambiguous(&mut self, completion_show_all_if_ambiguous: bool) {
579 self.config_mut().completion_show_all_if_ambiguous = completion_show_all_if_ambiguous;
580 }
581
582 fn set_completion_prompt_limit(&mut self, completion_prompt_limit: usize) {
585 self.config_mut().completion_prompt_limit = completion_prompt_limit;
586 }
587
588 fn set_keyseq_timeout(&mut self, keyseq_timeout_ms: Option<u16>) {
590 self.config_mut().keyseq_timeout = keyseq_timeout_ms;
591 }
592
593 fn set_edit_mode(&mut self, edit_mode: EditMode) {
595 self.config_mut().edit_mode = edit_mode;
596 match edit_mode {
597 EditMode::Emacs => self.set_keyseq_timeout(None), EditMode::Vi => self.set_keyseq_timeout(Some(500)),
599 }
600 }
601
602 fn set_auto_add_history(&mut self, yes: bool) {
606 self.config_mut().auto_add_history = yes;
607 }
608
609 fn set_bell_style(&mut self, bell_style: BellStyle) {
611 self.config_mut().bell_style = bell_style;
612 }
613
614 fn set_color_mode(&mut self, color_mode: ColorMode) {
618 self.config_mut().set_color_mode(color_mode);
619 }
620
621 fn set_grapheme_cluster_mode(&mut self, grapheme_cluster_mode: GraphemeClusterMode) {
623 self.config_mut().grapheme_cluster_mode = grapheme_cluster_mode;
624 }
625
626 fn set_behavior(&mut self, behavior: Behavior) {
630 self.config_mut().set_behavior(behavior);
631 }
632
633 fn set_tab_stop(&mut self, tab_stop: u8) {
637 self.config_mut().set_tab_stop(tab_stop);
638 }
639
640 fn set_check_cursor_position(&mut self, yes: bool) {
644 self.config_mut().check_cursor_position = yes;
645 }
646 fn set_indent_size(&mut self, size: u8) {
650 self.config_mut().set_indent_size(size);
651 }
652
653 fn enable_bracketed_paste(&mut self, enabled: bool) {
657 self.config_mut().enable_bracketed_paste = enabled;
658 }
659
660 fn enable_synchronized_output(&mut self, enabled: bool) {
664 self.config_mut().enable_synchronized_output = enabled;
665 }
666
667 fn set_enable_signals(&mut self, enable_signals: bool) {
671 self.config_mut().set_enable_signals(enable_signals);
672 }
673}