1use std::rc::Rc;
2
3use derive_builder::Builder;
4
5use crate::helper::item_reader::SkimItemReader;
6use crate::reader::CommandCollector;
7use crate::{CaseMatching, FuzzyAlgorithm, MatchEngineFactory, Selector};
8use std::cell::RefCell;
9use std::sync::Arc;
10
11#[derive(Builder)]
12#[builder(build_fn(name = "final_build"))]
13#[builder(default)]
14pub struct SkimOptions<'a> {
15 pub bind: Vec<&'a str>,
16 pub multi: bool,
17 pub prompt: Option<&'a str>,
18 pub cmd_prompt: Option<&'a str>,
19 pub expect: Option<String>,
20 pub tac: bool,
21 pub nosort: bool,
22 pub tiebreak: Option<String>,
23 pub exact: bool,
24 pub disabled: bool,
25 pub cmd: Option<&'a str>,
26 pub interactive: bool,
27 pub query: Option<&'a str>,
28 pub cmd_query: Option<&'a str>,
29 pub regex: bool,
30 pub delimiter: Option<&'a str>,
31 pub replstr: Option<&'a str>,
32 pub color: Option<&'a str>,
33 pub margin: Option<&'a str>,
34 pub no_height: bool,
35 pub no_clear: bool,
36 pub no_clear_start: bool,
37 pub min_height: Option<&'a str>,
38 pub height: Option<&'a str>,
39 pub preview: Option<&'a str>,
40 pub preview_window: Option<&'a str>,
41 pub reverse: bool,
42 pub tabstop: Option<&'a str>,
43 pub no_hscroll: bool,
44 pub no_mouse: bool,
45 pub inline_info: bool,
46 pub header: Option<&'a str>,
47 pub header_lines: usize,
48 pub layout: &'a str,
49 pub algorithm: FuzzyAlgorithm,
50 pub case: CaseMatching,
51 pub engine_factory: Option<Rc<dyn MatchEngineFactory>>,
52 pub query_history: &'a [String],
53 pub cmd_history: &'a [String],
54 pub cmd_collector: Rc<RefCell<dyn CommandCollector>>,
55 pub keep_right: bool,
56 pub skip_to_pattern: &'a str,
57 pub select1: bool,
58 pub exit0: bool,
59 pub sync: bool,
60 pub selector: Option<Arc<dyn Selector>>,
61 pub no_clear_if_empty: bool,
62}
63
64impl<'a> Default for SkimOptions<'a> {
65 fn default() -> Self {
66 Self {
67 bind: vec![],
68 multi: false,
69 prompt: Some("> "),
70 cmd_prompt: Some("c> "),
71 expect: None,
72 tac: false,
73 nosort: false,
74 tiebreak: None,
75 exact: false,
76 disabled: false,
77 cmd: None,
78 interactive: false,
79 query: None,
80 cmd_query: None,
81 regex: false,
82 delimiter: None,
83 replstr: Some("{}"),
84 color: None,
85 margin: Some("0,0,0,0"),
86 no_height: false,
87 no_clear: false,
88 no_clear_start: false,
89 min_height: Some("10"),
90 height: Some("100%"),
91 preview: None,
92 preview_window: Some("right:50%"),
93 reverse: false,
94 tabstop: None,
95 no_hscroll: false,
96 no_mouse: false,
97 inline_info: false,
98 header: None,
99 header_lines: 0,
100 layout: "",
101 algorithm: FuzzyAlgorithm::default(),
102 case: CaseMatching::default(),
103 engine_factory: None,
104 query_history: &[],
105 cmd_history: &[],
106 cmd_collector: Rc::new(RefCell::new(SkimItemReader::new(Default::default()))),
107 keep_right: false,
108 skip_to_pattern: "",
109 select1: false,
110 exit0: false,
111 sync: false,
112 selector: None,
113 no_clear_if_empty: false,
114 }
115 }
116}
117
118impl<'a> Drop for SkimOptionsBuilder<'a> {
119 fn drop(&mut self) {
120 self.cmd_collector.take();
121 self.engine_factory.take();
122 }
123}
124
125impl<'a> SkimOptionsBuilder<'a> {
126 pub fn build(&mut self) -> Result<SkimOptions<'a>, SkimOptionsBuilderError> {
127 if let Some(true) = self.no_height {
128 self.height = Some(Some("100%"));
129 }
130
131 if let Some(true) = self.reverse {
132 self.layout = Some("reverse");
133 }
134
135 self.final_build()
136 }
137}