forked from nushell/reedline
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cwd_aware.rs
100 lines (92 loc) · 2.99 KB
/
cwd_aware.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#[cfg(any(feature = "sqlite", feature = "sqlite-dynlib"))]
use crate::{history::SearchQuery, Hinter, History};
#[cfg(any(feature = "sqlite", feature = "sqlite-dynlib"))]
use nu_ansi_term::{Color, Style};
/// A hinter that uses the completions or the history to show a hint to the user
/// NOTE: Only use this with `SqliteBackedHistory`!
/// Similar to `fish` autosuggestins
#[cfg(any(feature = "sqlite", feature = "sqlite-dynlib"))]
pub struct CwdAwareHinter {
style: Style,
current_hint: String,
min_chars: usize,
}
#[cfg(any(feature = "sqlite", feature = "sqlite-dynlib"))]
impl Hinter for CwdAwareHinter {
fn handle(
&mut self,
line: &str,
#[allow(unused_variables)] pos: usize,
history: &dyn History,
use_ansi_coloring: bool,
) -> String {
self.current_hint = if line.chars().count() >= self.min_chars {
history
.search(SearchQuery::last_with_prefix_and_cwd(
line.to_string(),
history.session(),
))
.expect("todo: error handling")
.get(0)
.map_or_else(String::new, |entry| {
entry
.command_line
.get(line.len()..)
.unwrap_or_default()
.to_string()
})
} else {
String::new()
};
if use_ansi_coloring && !self.current_hint.is_empty() {
self.style.paint(&self.current_hint).to_string()
} else {
self.current_hint.clone()
}
}
fn complete_hint(&self) -> String {
self.current_hint.clone()
}
fn next_hint_token(&self) -> String {
let mut reached_content = false;
let result: String = self
.current_hint
.chars()
.take_while(|c| match (c.is_whitespace(), reached_content) {
(true, true) => false,
(true, false) => true,
(false, true) => true,
(false, false) => {
reached_content = true;
true
}
})
.collect();
result
}
}
#[cfg(any(feature = "sqlite", feature = "sqlite-dynlib"))]
impl Default for CwdAwareHinter {
fn default() -> Self {
CwdAwareHinter {
style: Style::new().fg(Color::LightGray),
current_hint: String::new(),
min_chars: 1,
}
}
}
#[cfg(any(feature = "sqlite", feature = "sqlite-dynlib"))]
impl CwdAwareHinter {
/// A builder that sets the style applied to the hint as part of the buffer
#[must_use]
pub fn with_style(mut self, style: Style) -> Self {
self.style = style;
self
}
/// A builder that sets the number of characters that have to be present to enable history hints
#[must_use]
pub fn with_min_chars(mut self, min_chars: usize) -> Self {
self.min_chars = min_chars;
self
}
}