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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
mod editor;
mod menu;
mod picker;
mod popup;
mod prompt;
pub use editor::EditorView;
pub use menu::Menu;
pub use picker::Picker;
pub use popup::Popup;
pub use prompt::{Prompt, PromptEvent};
pub use tui::layout::Rect;
pub use tui::style::{Color, Modifier, Style};
use helix_core::regex::Regex;
use helix_view::{Document, Editor};
// TODO: temp
#[inline(always)]
pub fn text_color() -> Style {
Style::default().fg(Color::Rgb(219, 191, 239)) // lilac
}
pub fn regex_prompt(
cx: &mut crate::commands::Context,
prompt: String,
fun: impl Fn(&mut Document, Regex) + 'static,
) -> Prompt {
let snapshot = cx.doc().state.clone();
Prompt::new(
prompt,
|input: &str| Vec::new(), // this is fine because Vec::new() doesn't allocate
move |editor: &mut Editor, input: &str, event: PromptEvent| {
match event {
PromptEvent::Abort => {
// revert state
let doc = &mut editor.view_mut().doc;
doc.state = snapshot.clone();
}
PromptEvent::Validate => {
//
}
PromptEvent::Update => {
match Regex::new(input) {
Ok(regex) => {
let view = &mut editor.view_mut();
let doc = &mut view.doc;
// revert state to what it was before the last update
doc.state = snapshot.clone();
fun(doc, regex);
view.ensure_cursor_in_view();
}
Err(_err) => (), // TODO: mark command line as error
}
}
}
},
)
}
use std::path::{Path, PathBuf};
pub fn file_picker(root: &str, ex: &'static smol::Executor) -> Picker<PathBuf> {
use ignore::Walk;
// TODO: determine root based on git root
let files = Walk::new(root).filter_map(|entry| match entry {
Ok(entry) => {
// filter dirs, but we might need special handling for symlinks!
if !entry.file_type().unwrap().is_dir() {
Some(entry.into_path())
} else {
None
}
}
Err(_err) => None,
});
const MAX: usize = 1024;
use helix_view::Editor;
Picker::new(
files.take(MAX).collect(),
|path: &PathBuf| {
// format_fn
path.strip_prefix("./").unwrap().to_str().unwrap().into()
},
move |editor: &mut Editor, path: &PathBuf| {
editor.open(path.into(), ex);
},
)
}
use helix_view::View;
pub fn buffer_picker(views: &[View], current: usize) -> Picker<(Option<PathBuf>, usize)> {
unimplemented!();
// use helix_view::Editor;
// Picker::new(
// views
// .iter()
// .enumerate()
// .map(|(i, view)| (view.doc.relative_path().map(Path::to_path_buf), i))
// .collect(),
// move |(path, index): &(Option<PathBuf>, usize)| {
// // format_fn
// match path {
// Some(path) => {
// if *index == current {
// format!("{} (*)", path.to_str().unwrap()).into()
// } else {
// path.to_str().unwrap().into()
// }
// }
// None => "[NEW]".into(),
// }
// },
// |editor: &mut Editor, &(_, index): &(Option<PathBuf>, usize)| {
// if index < editor.views.len() {
// editor.focus = index;
// }
// },
// )
}
|