reedline/hinter/
cwd_aware.rs1use crate::{
2 hinter::get_first_token,
3 history::SearchQuery,
4 result::{ReedlineError, ReedlineErrorVariants::HistoryFeatureUnsupported},
5 Hinter, History,
6};
7use nu_ansi_term::{Color, Style};
8
9pub struct CwdAwareHinter {
13 style: Style,
14 current_hint: String,
15 min_chars: usize,
16}
17
18impl Hinter for CwdAwareHinter {
19 fn handle(
20 &mut self,
21 line: &str,
22 #[allow(unused_variables)] pos: usize,
23 history: &dyn History,
24 use_ansi_coloring: bool,
25 ) -> String {
26 self.current_hint = if line.chars().count() >= self.min_chars {
27 let with_cwd = history
28 .search(SearchQuery::last_with_prefix_and_cwd(
29 line.to_string(),
30 history.session(),
31 ))
32 .or_else(|err| {
33 if let ReedlineError(HistoryFeatureUnsupported { .. }) = err {
34 history.search(SearchQuery::last_with_prefix(
35 line.to_string(),
36 history.session(),
37 ))
38 } else {
39 Err(err)
40 }
41 })
42 .unwrap_or_default();
43 if !with_cwd.is_empty() {
44 with_cwd[0]
45 .command_line
46 .get(line.len()..)
47 .unwrap_or_default()
48 .to_string()
49 } else {
50 history
51 .search(SearchQuery::last_with_prefix(
52 line.to_string(),
53 history.session(),
54 ))
55 .unwrap_or_default()
56 .first()
57 .map_or_else(String::new, |entry| {
58 entry
59 .command_line
60 .get(line.len()..)
61 .unwrap_or_default()
62 .to_string()
63 })
64 }
65 } else {
66 String::new()
67 };
68
69 if use_ansi_coloring && !self.current_hint.is_empty() {
70 self.style.paint(&self.current_hint).to_string()
71 } else {
72 self.current_hint.clone()
73 }
74 }
75
76 fn complete_hint(&self) -> String {
77 self.current_hint.clone()
78 }
79
80 fn next_hint_token(&self) -> String {
81 get_first_token(&self.current_hint)
82 }
83}
84
85impl Default for CwdAwareHinter {
86 fn default() -> Self {
87 CwdAwareHinter {
88 style: Style::new().fg(Color::LightGray),
89 current_hint: String::new(),
90 min_chars: 1,
91 }
92 }
93}
94
95impl CwdAwareHinter {
96 #[must_use]
98 pub fn with_style(mut self, style: Style) -> Self {
99 self.style = style;
100 self
101 }
102
103 #[must_use]
105 pub fn with_min_chars(mut self, min_chars: usize) -> Self {
106 self.min_chars = min_chars;
107 self
108 }
109}