1use matchmaker_partial_macros::partial;
5
6pub use crate::config_types::*;
7pub use crate::utils::{Percentage, serde::StringOrVec};
8
9use crate::{
10 MAX_SPLITS,
11 tui::IoStream,
12 utils::serde::{escaped_opt_char, escaped_opt_string, serde_duration_ms},
13};
14
15use cba::serde::transform::{camelcase_normalized, camelcase_normalized_option};
16use ratatui::{
17 style::{Color, Modifier, Style},
18 text::Span,
19 widgets::{BorderType, Borders},
20};
21
22use serde::{Deserialize, Serialize};
23
24#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
28#[partial(recurse, path, derive(Debug, Deserialize))]
29pub struct MatcherConfig {
30 #[serde(flatten)]
31 #[partial(skip)]
32 pub matcher: NucleoMatcherConfig,
33 #[serde(flatten)]
34 pub worker: WorkerConfig,
35}
36
37#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
41#[serde(default)]
42#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
43pub struct WorkerConfig {
44 #[serde(alias = "sort")]
46 pub sort_threshold: u32,
47 #[partial(alias = "r")]
49 pub raw: bool,
50 pub track: bool,
52 pub reverse: bool, }
55
56#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
59#[serde(default, deny_unknown_fields)]
60#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
61pub struct StartConfig {
62 #[serde(deserialize_with = "escaped_opt_char")]
63 #[partial(alias = "is")]
64 pub input_separator: Option<char>,
65 #[serde(deserialize_with = "escaped_opt_char")]
67 #[partial(alias = "ps")]
68 pub command_input_separator: Option<char>,
69 #[serde(deserialize_with = "escaped_opt_string")]
70 #[partial(alias = "os")]
71 pub output_separator: Option<String>,
72
73 #[partial(alias = "ot")]
75 #[serde(alias = "output")]
76 pub output_template: Option<String>,
77
78 #[partial(alias = "cmd", alias = "x")]
80 pub command: String,
81 #[partial(alias = "ax")]
83 pub additional_commands: Vec<String>,
84 pub sync: bool,
85
86 #[partial(alias = "a")]
88 pub ansi: bool,
89 #[partial(alias = "t")]
91 pub trim: bool,
92}
93
94#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
96#[serde(default, deny_unknown_fields)]
97#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
98pub struct ExitConfig {
99 pub select_1: bool,
101 pub allow_empty: bool,
103 pub abort_empty: bool,
105 pub last_key_path: Option<std::path::PathBuf>,
108}
109
110impl Default for ExitConfig {
111 fn default() -> Self {
112 Self {
113 select_1: false,
114 allow_empty: false,
115 abort_empty: true,
116 last_key_path: None,
117 }
118 }
119}
120
121#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
123#[serde(default, deny_unknown_fields)]
124#[partial(recurse, path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
125pub struct RenderConfig {
126 pub ui: UiConfig,
128 #[partial(alias = "q")]
130 pub query: QueryConfig,
131 #[partial(alias = "r")]
133 pub results: ResultsConfig,
134
135 pub status: StatusConfig,
137 #[partial(alias = "p")]
139 pub preview: PreviewConfig,
140 #[partial(alias = "f")]
141 pub footer: DisplayConfig,
142 #[partial(alias = "h")]
143 pub header: DisplayConfig,
144}
145
146impl RenderConfig {
147 pub fn tick_rate(&self) -> u8 {
148 self.ui.tick_rate
149 }
150}
151
152#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
154#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
155#[serde(default, deny_unknown_fields)]
156pub struct TerminalConfig {
157 pub stream: IoStream, pub restore_fullscreen: bool,
159 pub redraw_on_resize: bool,
160 pub extended_keys: bool,
162 #[serde(with = "serde_duration_ms")]
163 pub sleep_ms: std::time::Duration, #[serde(flatten)]
165 #[partial(recurse)]
166 pub layout: Option<TerminalLayoutSettings>, pub clear_on_exit: bool,
168 pub move_up_on_exit: bool,
170}
171
172impl Default for TerminalConfig {
173 fn default() -> Self {
174 Self {
175 stream: IoStream::default(),
176 restore_fullscreen: true,
177 redraw_on_resize: bool::default(),
178 sleep_ms: std::time::Duration::default(),
179 layout: Option::default(),
180 extended_keys: true,
181 clear_on_exit: true,
182 move_up_on_exit: false,
183 }
184 }
185}
186
187#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
189#[serde(default, deny_unknown_fields)]
190#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
191pub struct UiConfig {
192 #[partial(recurse)]
193 #[partial(alias = "b")]
194 pub border: BorderSetting,
195 pub tick_rate: u8, }
197
198impl Default for UiConfig {
199 fn default() -> Self {
200 Self {
201 border: Default::default(),
202 tick_rate: 60,
203 }
204 }
205}
206
207#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
209#[serde(default, deny_unknown_fields)]
210#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
211pub struct QueryConfig {
212 #[partial(recurse)]
213 #[partial(alias = "b")]
214 pub border: BorderSetting,
215
216 #[partial(recurse)]
218 pub style: StyleSetting,
219
220 #[partial(recurse)]
221 pub prompt_style: StyleSetting,
222
223 #[serde(deserialize_with = "deserialize_string_or_char_as_double_width")]
225 pub prompt: String,
226 pub cursor: CursorSetting,
228
229 #[partial(alias = "i")]
231 pub initial: String,
232
233 pub scroll_padding: bool,
235}
236
237impl Default for QueryConfig {
238 fn default() -> Self {
239 Self {
240 border: Default::default(),
241 style: Default::default(),
242 prompt_style: Default::default(),
243 prompt: "> ".to_string(),
244 cursor: Default::default(),
245 initial: Default::default(),
246
247 scroll_padding: true,
248 }
249 }
250}
251
252impl QueryConfig {}
253
254#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
255#[serde(default, deny_unknown_fields)]
256#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
257pub struct OverlayConfig {
258 #[partial(recurse)]
259 #[partial(alias = "b")]
260 pub border: BorderSetting,
261 pub outer_dim: bool,
262 pub layout: OverlayLayoutSettings,
263}
264
265#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
266#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
267pub struct OverlayLayoutSettings {
268 #[partial(alias = "p")]
270 pub percentage: [Percentage; 2],
271 pub min: [u16; 2],
273 pub max: [u16; 2],
275
276 pub y_offset: Percentage,
278}
279
280impl Default for OverlayLayoutSettings {
281 fn default() -> Self {
282 Self {
283 percentage: [Percentage::new(60), Percentage::new(30)],
284 min: [10, 10],
285 max: [200, 30],
286 y_offset: Percentage::new(55),
287 }
288 }
289}
290
291#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
294#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
295#[serde(default, deny_unknown_fields)]
296pub struct AutoscrollSettings {
297 #[partial(alias = "i")]
299 pub initial_preserved: usize,
300 #[partial(alias = "a")]
302 pub enabled: bool,
303 #[partial(alias = "c")]
305 pub context: usize,
306 #[partial(alias = "e")]
308 pub end: bool,
309}
310
311impl Default for AutoscrollSettings {
312 fn default() -> Self {
313 Self {
314 initial_preserved: 0,
315 enabled: true,
316 context: 4,
317 end: false,
318 }
319 }
320}
321
322#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
323#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
324#[serde(default, deny_unknown_fields)]
325pub struct ResultsConfig {
326 #[partial(recurse)]
327 #[partial(alias = "b")]
328 pub border: BorderSetting,
329
330 #[serde(deserialize_with = "deserialize_string_or_char_as_double_width")]
332 pub multi_prefix: String,
333 pub default_prefix: String,
334
335 pub multi: bool,
337
338 #[partial(recurse)]
340 pub style: StyleSetting,
341
342 #[partial(recurse)]
344 pub inactive: StyleSetting,
345
346 #[partial(recurse)]
348 pub inactive_current: StyleSetting,
349
350 #[partial(recurse)]
351 pub match_style: StyleSetting,
352
353 #[partial(recurse)]
355 pub current: StyleSetting,
356
357 #[serde(deserialize_with = "camelcase_normalized")]
362 pub row_connection: RowConnectionStyle,
363
364 #[partial(alias = "c")]
366 #[serde(alias = "cycle")]
367 pub scroll_wrap: bool,
368 #[partial(alias = "sp")]
369 pub scroll_padding: u16,
370 #[partial(alias = "r")]
371 pub reverse: Option<bool>,
372
373 #[partial(alias = "w")]
375 pub wrap: bool,
376 pub min_wrap_width: u16,
377
378 #[partial(recurse, alias = "a")]
380 pub autoscroll: AutoscrollSettings,
381
382 pub column_spacing: Count,
386 pub current_prefix: String,
387
388 pub max_height: usize,
391 pub show_skipped: bool,
392 pub vscroll_current_only: bool,
394
395 #[partial(alias = "ra")]
397 pub right_align_last: bool,
398 #[partial(alias = "v")]
399 #[serde(alias = "vertical")]
400 pub stacked_columns: bool,
401
402 #[serde(alias = "hr")]
403 #[serde(deserialize_with = "camelcase_normalized")]
404 pub separator: HorizontalSeparator,
405 pub separator_style: StyleSetting,
406}
407
408impl Default for ResultsConfig {
409 fn default() -> Self {
410 ResultsConfig {
411 border: Default::default(),
412
413 multi_prefix: "▌ ".to_string(),
414 default_prefix: Default::default(),
415 multi: true,
416
417 style: Default::default(),
418 inactive: Default::default(),
419 inactive_current: StyleSetting {
420 fg: Color::DarkGray,
421 bg: Color::Black,
422 ..Default::default()
423 },
424
425 match_style: StyleSetting {
426 fg: Color::Green,
427 modifier: Modifier::ITALIC,
428 ..Default::default()
429 },
430
431 current: StyleSetting {
432 bg: Color::Black,
433 modifier: Modifier::BOLD,
434 ..Default::default()
435 },
436
437 row_connection: RowConnectionStyle::Capped,
438
439 scroll_wrap: true,
440 scroll_padding: 2,
441 reverse: Default::default(),
442
443 wrap: Default::default(),
444 min_wrap_width: 4,
445 max_height: 0,
446
447 autoscroll: Default::default(),
448
449 column_spacing: Default::default(),
450 current_prefix: Default::default(),
451 right_align_last: false,
452 stacked_columns: false,
453 separator: Default::default(),
454 separator_style: Default::default(),
455 show_skipped: true,
456 vscroll_current_only: true,
457 }
458 }
459}
460
461#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
462#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
463#[serde(default, deny_unknown_fields)]
464pub struct StatusConfig {
465 #[partial(recurse)]
466 pub style: StyleSetting,
467
468 pub show: bool,
470 pub match_indent: bool,
472
473 #[partial(alias = "t")]
482 pub template: String,
483
484 pub row_connection: RowConnectionStyle,
488}
489impl Default for StatusConfig {
490 fn default() -> Self {
491 Self {
492 style: StyleSetting {
493 fg: Color::Green,
494 modifier: Modifier::ITALIC,
495 ..Default::default()
496 },
497 show: true,
498 match_indent: true,
499 template: String::new(),
500 row_connection: RowConnectionStyle::Full,
501 }
502 }
503}
504
505impl StatusConfig {}
506
507#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
508#[serde(default, deny_unknown_fields)]
509#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
510pub struct DisplayConfig {
511 #[partial(recurse)]
512 #[partial(alias = "b")]
513 pub border: BorderSetting,
514
515 #[partial(recurse)]
516 pub style: StyleSetting,
517
518 pub match_indent: bool,
520 pub wrap: bool,
522
523 pub content: Option<StringOrVec>,
525
526 #[serde(deserialize_with = "camelcase_normalized")]
536 pub row_connection: RowConnectionStyle,
537
538 #[partial(alias = "h")]
540 pub header_lines: usize,
541}
542
543impl Default for DisplayConfig {
544 fn default() -> Self {
545 DisplayConfig {
546 border: Default::default(),
547 match_indent: true,
548 style: StyleSetting {
549 fg: Color::Green,
550 modifier: Modifier::ITALIC,
551 ..Default::default()
552 },
553 wrap: false,
554 row_connection: Default::default(),
555 content: None,
556 header_lines: 0,
557 }
558 }
559}
560
561#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
577#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
578#[serde(default, deny_unknown_fields)]
579pub struct PreviewConfig {
580 #[partial(recurse)]
581 #[partial(alias = "b")]
582 pub border: BorderSetting,
583 #[partial(recurse, set = "recurse")]
584 #[partial(alias = "l")]
585 pub layout: Vec<PreviewSetting>,
586 #[serde(alias = "scroll")]
587 #[partial(recurse)]
588 #[partial(alias = "i")]
589 pub initial: PreviewInitialSetting,
590 #[partial(alias = "c")]
592 #[serde(alias = "cycle")]
593 pub scroll_wrap: bool,
594 pub wrap: bool,
595 pub show: ShowCondition,
598
599 pub reevaluate_show_on_resize: bool,
600}
601
602impl Default for PreviewConfig {
603 fn default() -> Self {
604 PreviewConfig {
605 border: BorderSetting {
606 padding: Padding(ratatui::widgets::Padding::left(2)),
607 ..Default::default()
608 },
609 initial: Default::default(),
610 layout: Default::default(),
611 scroll_wrap: true,
612 wrap: Default::default(),
613 show: Default::default(),
614 reevaluate_show_on_resize: false,
615 }
616 }
617}
618
619#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
621#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
622#[serde(default, deny_unknown_fields)]
623pub struct PreviewInitialSetting {
624 pub index: Option<StringValue>,
627 #[partial(alias = "o")]
629 pub offset: isize,
630 #[partial(alias = "p")]
632 pub percentage: Percentage,
633 #[partial(alias = "h")]
635 pub header_lines: usize,
636}
637
638impl Default for PreviewInitialSetting {
639 fn default() -> Self {
640 Self {
641 index: Default::default(),
642 offset: -1,
643 percentage: Default::default(),
644 header_lines: Default::default(),
645 }
646 }
647}
648
649#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
650#[serde(default, deny_unknown_fields)]
651pub struct PreviewerConfig {
652 pub try_lossy: bool,
653
654 pub cache: u8,
656
657 pub help_colors: HelpColorConfig,
658}
659
660#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
662pub struct HelpColorConfig {
663 #[serde(deserialize_with = "camelcase_normalized")]
664 pub section: Color,
665 #[serde(deserialize_with = "camelcase_normalized")]
666 pub key: Color,
667 #[serde(deserialize_with = "camelcase_normalized")]
668 pub value: Color,
669}
670
671impl Default for HelpColorConfig {
672 fn default() -> Self {
673 Self {
674 section: Color::Blue,
675 key: Color::Green,
676 value: Color::White,
677 }
678 }
679}
680
681#[derive(Default, Debug, Clone, PartialEq, Deserialize, Serialize)]
684#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
685#[serde(default, deny_unknown_fields)]
686pub struct BorderSetting {
687 #[serde(deserialize_with = "camelcase_normalized_option")]
688 pub r#type: Option<BorderType>,
689 #[serde(deserialize_with = "camelcase_normalized")]
690 pub color: Color,
691 pub sides: Option<Borders>,
700 pub padding: Padding,
708 pub title: String,
709 pub title_modifier: Modifier,
711 pub modifier: Modifier,
712 #[serde(deserialize_with = "camelcase_normalized")]
713 pub bg: Color,
714}
715
716impl BorderSetting {
717 pub fn as_block(&self) -> ratatui::widgets::Block<'_> {
718 let mut ret = ratatui::widgets::Block::default()
719 .padding(self.padding.0)
720 .style(Style::default().bg(self.bg).add_modifier(self.modifier));
721
722 if !self.title.is_empty() {
723 let title = Span::styled(
724 &self.title,
725 Style::default().add_modifier(self.title_modifier),
726 );
727
728 ret = ret.title(title)
729 };
730
731 if !self.is_empty() {
732 ret = ret
733 .borders(self.sides())
734 .border_type(self.r#type.unwrap_or_default())
735 .border_style(ratatui::style::Style::default().fg(self.color))
736 }
737
738 ret
739 }
740
741 pub fn sides(&self) -> Borders {
742 if let Some(s) = self.sides {
743 s
744 } else if self.color != Default::default() || self.r#type != Default::default() {
745 Borders::ALL
746 } else {
747 Borders::NONE
748 }
749 }
750
751 pub fn as_static_block(&self) -> ratatui::widgets::Block<'static> {
752 let mut ret = ratatui::widgets::Block::default()
753 .padding(self.padding.0)
754 .style(Style::default().bg(self.bg).add_modifier(self.modifier));
755
756 if !self.title.is_empty() {
757 let title: Span<'static> = Span::styled(
758 self.title.clone(),
759 Style::default().add_modifier(self.title_modifier),
760 );
761
762 ret = ret.title(title)
763 };
764
765 if !self.is_empty() {
766 ret = ret
767 .borders(self.sides())
768 .border_type(self.r#type.unwrap_or_default())
769 .border_style(ratatui::style::Style::default().fg(self.color))
770 }
771
772 ret
773 }
774
775 pub fn is_empty(&self) -> bool {
776 self.sides() == Borders::NONE
777 }
778
779 pub fn height(&self) -> u16 {
780 let mut height = 0;
781 height += 2 * !self.is_empty() as u16;
782 height += self.padding.top + self.padding.bottom;
783 height += (!self.title.is_empty() as u16).saturating_sub(!self.is_empty() as u16);
784
785 height
786 }
787
788 pub fn width(&self) -> u16 {
789 let mut width = 0;
790 width += 2 * !self.is_empty() as u16;
791 width += self.padding.left + self.padding.right;
792
793 width
794 }
795
796 pub fn left(&self) -> u16 {
797 let mut width = 0;
798 width += !self.is_empty() as u16;
799 width += self.padding.left;
800
801 width
802 }
803
804 pub fn top(&self) -> u16 {
805 let mut height = 0;
806 height += !self.is_empty() as u16;
807 height += self.padding.top;
808 height += (!self.title.is_empty() as u16).saturating_sub(!self.is_empty() as u16);
809
810 height
811 }
812}
813
814#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
816#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
817pub struct TerminalLayoutSettings {
818 #[partial(alias = "p")]
820 pub percentage: Percentage,
821 pub min: u16,
822 pub max: u16, }
824
825impl Default for TerminalLayoutSettings {
826 fn default() -> Self {
827 Self {
828 percentage: Percentage::new(50),
829 min: 10,
830 max: 120,
831 }
832 }
833}
834
835#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
836#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
837#[serde(default)]
838pub struct PreviewSetting {
839 #[serde(flatten)]
840 #[partial(recurse)]
841 pub layout: PreviewLayout,
842 #[partial(recurse)]
843 pub border: Option<BorderSetting>,
844 #[serde(default, alias = "cmd", alias = "x")]
845 pub command: String,
846}
847
848#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
849#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
850#[serde(default)]
851pub struct PreviewLayout {
852 pub side: Side,
853 #[serde(alias = "p")]
855 pub percentage: Percentage,
857 pub min: i16,
858 pub max: i16,
859}
860
861impl Default for PreviewLayout {
862 fn default() -> Self {
863 Self {
864 side: Side::Right,
865 percentage: Percentage::new(60),
866 min: 15,
867 max: 120,
868 }
869 }
870}
871
872use crate::utils::serde::bounded_usize;
873#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
874#[serde(default, deny_unknown_fields)]
875#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
876pub struct ColumnsConfig {
877 #[partial(alias = "s")]
879 pub split: Split,
880 #[partial(alias = "n")]
882 pub names: Vec<ColumnSetting>,
883 #[serde(deserialize_with = "bounded_usize::<_, 1, {crate::MAX_SPLITS}>")]
885 #[partial(alias = "mc")]
886 max: usize,
887 #[partial(alias = "i")]
888 pub default: Option<StringValue>,
889 pub names_from_zero: bool,
891}
892
893impl ColumnsConfig {
894 pub fn max_cols(&self) -> usize {
895 self.max.min(MAX_SPLITS).max(1)
896 }
897}
898
899impl Default for ColumnsConfig {
900 fn default() -> Self {
901 Self {
902 split: Default::default(),
903 names: Default::default(),
904 max: 6,
905 default: None,
906 names_from_zero: false,
907 }
908 }
909}
910
911#[derive(Debug, Clone, PartialEq)]
913pub struct NucleoMatcherConfig(pub nucleo::Config);
914
915impl Default for NucleoMatcherConfig {
916 fn default() -> Self {
917 Self(nucleo::Config::DEFAULT)
918 }
919}
920
921#[derive(Debug, Clone, Serialize, Deserialize)]
922#[serde(default)]
923#[derive(Default)]
924struct MatcherConfigHelper {
925 pub normalize: Option<bool>,
926 pub ignore_case: Option<bool>,
927 pub prefer_prefix: Option<bool>,
928}
929
930impl serde::Serialize for NucleoMatcherConfig {
931 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
932 where
933 S: serde::Serializer,
934 {
935 let helper = MatcherConfigHelper {
936 normalize: Some(self.0.normalize),
937 ignore_case: Some(self.0.ignore_case),
938 prefer_prefix: Some(self.0.prefer_prefix),
939 };
940 helper.serialize(serializer)
941 }
942}
943
944impl<'de> Deserialize<'de> for NucleoMatcherConfig {
945 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
946 where
947 D: serde::Deserializer<'de>,
948 {
949 let helper = MatcherConfigHelper::deserialize(deserializer)?;
950 let mut config = nucleo::Config::DEFAULT;
951
952 if let Some(norm) = helper.normalize {
953 config.normalize = norm;
954 }
955 if let Some(ic) = helper.ignore_case {
956 config.ignore_case = ic;
957 }
958 if let Some(pp) = helper.prefer_prefix {
959 config.prefer_prefix = pp;
960 }
961
962 Ok(NucleoMatcherConfig(config))
963 }
964}