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
use std::cell::RefCell; use glib::translate::FromGlib; use gtk; use gtk::prelude::*; use gtk::{ButtonsType, MessageDialog, MessageType}; use neovim_lib::{CallError, NeovimApi, Value}; use crate::shell::Shell; use crate::ui::{Components, UiMutex}; pub fn can_close_window(comps: &UiMutex<Components>, shell: &RefCell<Shell>) -> bool { let shell = shell.borrow(); match get_changed_buffers(&*shell) { Ok(vec) => { if !vec.is_empty() { show_not_saved_dlg(comps, &*shell, &vec) } else { true } } Err(ref err) => { error!("Error getting info from nvim: {}", err); true } } } fn show_not_saved_dlg(comps: &UiMutex<Components>, shell: &Shell, changed_bufs: &[String]) -> bool { let mut changed_files = changed_bufs .iter() .map(|n| if n.is_empty() { "<No name>" } else { n }) .fold(String::new(), |acc, v| acc + v + "\n"); changed_files.pop(); let flags = gtk::DialogFlags::MODAL | gtk::DialogFlags::DESTROY_WITH_PARENT; let dlg = MessageDialog::new( Some(comps.borrow().window()), flags, MessageType::Question, ButtonsType::None, &format!("Save changes to '{}'?", changed_files), ); dlg.add_buttons(&[ ("_Yes", gtk::ResponseType::Yes), ("_No", gtk::ResponseType::No), ("_Cancel", gtk::ResponseType::Cancel), ]); let res = match gtk::ResponseType::from_glib(dlg.run()) { gtk::ResponseType::Yes => { let state = shell.state.borrow(); let mut nvim = state.nvim().unwrap(); match nvim.command("wa") { Err(ref err) => { error!("Error: {}", err); false } _ => true, } } gtk::ResponseType::No => true, gtk::ResponseType::Cancel | _ => false, }; dlg.destroy(); res } fn get_changed_buffers(shell: &Shell) -> Result<Vec<String>, CallError> { let state = shell.state.borrow(); let nvim = state.nvim(); if let Some(mut nvim) = nvim { let buffers = nvim.list_bufs().unwrap(); Ok(buffers .iter() .map(|buf| { ( match buf.get_option(&mut nvim, "modified") { Ok(Value::Boolean(val)) => val, Ok(_) => { warn!("Value must be boolean"); false } Err(ref err) => { error!("Something going wrong while getting buffer option: {}", err); false } }, match buf.get_name(&mut nvim) { Ok(name) => name, Err(ref err) => { error!("Something going wrong while getting buffer name: {}", err); "<Error>".to_owned() } }, ) }) .filter(|e| e.0) .map(|e| e.1) .collect()) } else { Ok(vec![]) } }