neovim-gtk/src/shell_dlg.rs

104 lines
3.0 KiB
Rust
Raw Normal View History

use std::cell::RefCell;
use ui::{Components, UiMutex};
use shell::Shell;
2017-04-01 10:00:14 +00:00
use neovim_lib::{NeovimApi, CallError, Value};
use gtk;
2017-04-01 18:25:33 +00:00
use gtk::prelude::*;
use gtk::{MessageDialog, MessageType, ButtonsType};
2017-04-01 10:00:14 +00:00
pub fn can_close_window(comps: &UiMutex<Components>, shell: &RefCell<Shell>) -> bool {
let shell = shell.borrow();
match get_changed_buffers(&*shell) {
2017-04-01 10:00:14 +00:00
Ok(vec) => {
if !vec.is_empty() {
show_not_saved_dlg(comps, &*shell, &vec)
2017-04-01 10:00:14 +00:00
} else {
true
}
}
2017-04-01 10:00:14 +00:00
Err(ref err) => {
println!("Error getting info from nvim: {}", err);
true
}
}
}
fn show_not_saved_dlg(comps: &UiMutex<Components>,
shell: &Shell,
2017-07-25 14:55:31 +00:00
changed_bufs: &[String])
-> bool {
let mut changed_files = changed_bufs
.iter()
2017-04-01 17:32:14 +00:00
.map(|n| if n.is_empty() { "<No name>" } else { n })
.fold(String::new(), |acc, v| acc + v + "\n");
changed_files.pop();
2017-04-01 10:00:14 +00:00
let flags = gtk::DIALOG_MODAL | gtk::DIALOG_DESTROY_WITH_PARENT;
let dlg = MessageDialog::new(Some(comps.borrow().window()),
2017-04-01 17:32:14 +00:00
flags,
MessageType::Question,
ButtonsType::None,
&format!("Save changes to '{}'?", changed_files));
2017-04-01 18:25:33 +00:00
const SAVE_ID: i32 = 0;
const CLOSE_WITHOUT_SAVE: i32 = 1;
const CANCEL_ID: i32 = 2;
2017-04-01 10:00:14 +00:00
dlg.add_buttons(&[("_Yes", SAVE_ID),
("_No", CLOSE_WITHOUT_SAVE),
("_Cancel", CANCEL_ID)]);
2017-04-01 10:00:14 +00:00
2017-04-01 18:25:33 +00:00
let res = match dlg.run() {
SAVE_ID => {
let state = shell.state.borrow();
let mut nvim = state.nvim();
match nvim.command("wa") {
Err(ref err) => {
println!("Error: {}", err);
false
2017-04-01 18:25:33 +00:00
}
_ => true,
}
}
2017-04-01 18:25:33 +00:00
CLOSE_WITHOUT_SAVE => true,
2017-07-25 14:55:31 +00:00
CANCEL_ID | _ => false,
2017-04-01 18:25:33 +00:00
};
dlg.destroy();
res
2017-04-01 10:00:14 +00:00
}
fn get_changed_buffers(shell: &Shell) -> Result<Vec<String>, CallError> {
let state = shell.state.borrow();
let mut nvim = state.nvim();
2017-05-21 12:47:29 +00:00
let buffers = nvim.list_bufs().unwrap();
2017-04-01 10:00:14 +00:00
Ok(buffers
2017-07-25 14:55:31 +00:00
.iter()
.map(|buf| {
(match buf.get_option(&mut nvim, "modified") {
Ok(Value::Boolean(val)) => val,
Ok(_) => {
println!("Value must be boolean");
false
}
Err(ref err) => {
println!("Something going wrong while getting buffer option: {}", err);
false
}
},
match buf.get_name(&mut nvim) {
Ok(name) => name,
Err(ref err) => {
println!("Something going wrong while getting buffer name: {}", err);
"<Error>".to_owned()
}
})
})
.filter(|e| e.0)
.map(|e| e.1)
.collect())
2017-04-01 10:00:14 +00:00
}