nvim_gtk/plug_manager/
plugin_settings_dlg.rs1use gtk;
2use gtk::prelude::*;
3
4use super::store;
5
6pub struct Builder<'a> {
7 title: &'a str,
8}
9
10impl<'a> Builder<'a> {
11 pub fn new(title: &'a str) -> Self {
12 Builder { title }
13 }
14
15 pub fn show<F: IsA<gtk::Window>>(&self, parent: &F) -> Option<store::PlugInfo> {
16 let dlg = gtk::Dialog::new_with_buttons(
17 Some(self.title),
18 Some(parent),
19 gtk::DialogFlags::USE_HEADER_BAR | gtk::DialogFlags::DESTROY_WITH_PARENT,
20 &[
21 ("Cancel", gtk::ResponseType::Cancel),
22 ("Ok", gtk::ResponseType::Ok),
23 ],
24 );
25
26 let content = dlg.get_content_area();
27 let border = gtk::Box::new(gtk::Orientation::Horizontal, 0);
28 border.set_border_width(12);
29
30 let list = gtk::ListBox::new();
31 list.set_selection_mode(gtk::SelectionMode::None);
32
33 let path = gtk::Box::new(gtk::Orientation::Horizontal, 5);
34 path.set_border_width(5);
35 let path_lbl = gtk::Label::new(Some("Repo"));
36 let path_e = gtk::Entry::new();
37 path_e.set_placeholder_text(Some("user_name/repo_name"));
38
39 path.pack_start(&path_lbl, true, true, 0);
40 path.pack_end(&path_e, false, true, 0);
41
42 list.add(&path);
43
44 let name = gtk::Box::new(gtk::Orientation::Horizontal, 5);
45 name.set_border_width(5);
46 let name_lbl = gtk::Label::new(Some("Name"));
47 let name_e = gtk::Entry::new();
48
49 name.pack_start(&name_lbl, true, true, 0);
50 name.pack_end(&name_e, false, true, 0);
51
52 list.add(&name);
53
54 border.pack_start(&list, true, true, 0);
55 content.add(&border);
56 content.show_all();
57
58 path_e.connect_changed(clone!(name_e => move |p| {
59 if let Some(name) = p.get_text().and_then(|t| extract_name(&t)) {
60 name_e.set_text(&name);
61 }
62 }));
63
64 let res = if dlg.run() == gtk::ResponseType::Ok {
65 path_e.get_text().map(|path| {
66 let name = name_e
67 .get_text()
68 .map(String::from)
69 .and_then(|name| {
70 if name.trim().is_empty() {
71 None
72 } else {
73 Some(name.to_owned())
74 }
75 })
76 .or_else(|| extract_name(path.as_str()))
77 .unwrap_or_else(|| path.as_str().to_owned());
78
79 store::PlugInfo::new(name, path.to_owned())
80 })
81 } else {
82 None
83 };
84
85 dlg.destroy();
86
87 res
88 }
89}
90
91fn extract_name(path: &str) -> Option<String> {
92 if let Some(idx) = path.rfind(|c| c == '/' || c == '\\') {
93 if idx < path.len() - 1 {
94 let path = path.trim_end_matches(".git");
95 Some(path[idx + 1..].to_owned())
96 } else {
97 None
98 }
99 } else {
100 None
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107
108 #[test]
109 fn test_extract_name() {
110 assert_eq!(
111 Some("plugin_name".to_owned()),
112 extract_name("http://github.com/somebody/plugin_name.git")
113 );
114 }
115}