use std::cell::RefCell; use ui::{Components, UiMutex}; use shell::Shell; use neovim_lib::{NeovimApi, CallError, Value}; use gtk; use gtk::prelude::*; use gtk::{MessageDialog, MessageType, ButtonsType}; pub fn can_close_window(comps: &UiMutex, shell: &RefCell) -> 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, shell: &Shell, changed_bufs: &[String]) -> bool { let mut changed_files = changed_bufs .iter() .map(|n| if n.is_empty() { "" } 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), ); const SAVE_ID: i32 = 0; const CLOSE_WITHOUT_SAVE: i32 = 1; const CANCEL_ID: i32 = 2; dlg.add_buttons( &[ ("_Yes", SAVE_ID), ("_No", CLOSE_WITHOUT_SAVE), ("_Cancel", CANCEL_ID), ], ); let res = match dlg.run() { SAVE_ID => { let state = shell.state.borrow(); let mut nvim = state.nvim().unwrap(); match nvim.command("wa") { Err(ref err) => { error!("Error: {}", err); false } _ => true, } } CLOSE_WITHOUT_SAVE => true, CANCEL_ID | _ => false, }; dlg.destroy(); res } fn get_changed_buffers(shell: &Shell) -> Result, 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 ); "".to_owned() } }, ) }) .filter(|e| e.0) .map(|e| e.1) .collect(), ) } else { Ok(vec![]) } }