2016-03-31 10:09:34 +00:00
|
|
|
use std::cell::RefCell;
|
|
|
|
use std::thread;
|
2016-03-31 16:19:08 +00:00
|
|
|
|
2016-03-16 15:25:25 +00:00
|
|
|
use gtk;
|
2017-03-15 15:33:47 +00:00
|
|
|
use gtk_sys;
|
2016-03-16 15:25:25 +00:00
|
|
|
use gtk::prelude::*;
|
2017-03-16 10:18:13 +00:00
|
|
|
use gtk::{ApplicationWindow, HeaderBar, ToolButton, Image};
|
|
|
|
use gdk::Event;
|
2017-03-15 15:33:47 +00:00
|
|
|
|
2017-03-16 10:18:13 +00:00
|
|
|
use neovim_lib::NeovimApi;
|
2016-03-16 15:25:25 +00:00
|
|
|
|
2017-03-13 15:03:32 +00:00
|
|
|
use settings;
|
2017-03-15 15:33:47 +00:00
|
|
|
use shell::{Shell, NvimMode};
|
2017-03-16 10:18:13 +00:00
|
|
|
use nvim::ErrorReport;
|
2016-03-19 08:47:23 +00:00
|
|
|
|
2016-04-01 21:14:22 +00:00
|
|
|
|
2017-03-13 15:03:32 +00:00
|
|
|
macro_rules! ui_thread_var {
|
|
|
|
($id:ident, $ty:ty, $expr:expr) => (thread_local!(pub static $id: RefCell<$ty> = {
|
|
|
|
let thread = thread::current();
|
|
|
|
let current_thread_name = thread.name();
|
|
|
|
if current_thread_name != Some("main") {
|
|
|
|
panic!("Can create UI only from main thread, {:?}", current_thread_name);
|
|
|
|
}
|
|
|
|
RefCell::new($expr)
|
|
|
|
});)
|
|
|
|
}
|
|
|
|
|
2017-03-15 15:33:47 +00:00
|
|
|
ui_thread_var!(UI, Ui, Ui::new());
|
|
|
|
ui_thread_var!(SET, settings::Settings, settings::Settings::new());
|
2016-03-31 10:09:34 +00:00
|
|
|
|
2016-05-04 06:23:39 +00:00
|
|
|
|
2016-03-19 10:27:39 +00:00
|
|
|
pub struct Ui {
|
2017-03-14 20:12:31 +00:00
|
|
|
pub initialized: bool,
|
2017-03-15 15:33:47 +00:00
|
|
|
pub window: Option<ApplicationWindow>,
|
2017-03-07 14:12:22 +00:00
|
|
|
header_bar: HeaderBar,
|
2017-03-15 15:33:47 +00:00
|
|
|
pub shell: Shell,
|
2016-03-19 10:27:39 +00:00
|
|
|
}
|
2016-03-16 15:25:25 +00:00
|
|
|
|
|
|
|
impl Ui {
|
|
|
|
pub fn new() -> Ui {
|
2016-03-19 10:27:39 +00:00
|
|
|
Ui {
|
2017-03-06 13:58:10 +00:00
|
|
|
window: None,
|
2017-03-07 14:12:22 +00:00
|
|
|
header_bar: HeaderBar::new(),
|
2017-03-14 20:12:31 +00:00
|
|
|
initialized: false,
|
2017-03-15 15:33:47 +00:00
|
|
|
shell: Shell::new(),
|
2016-03-19 10:27:39 +00:00
|
|
|
}
|
2016-03-16 15:25:25 +00:00
|
|
|
}
|
|
|
|
|
2017-03-16 10:18:13 +00:00
|
|
|
pub fn close_window(&self) {
|
2017-03-06 13:58:10 +00:00
|
|
|
self.window.as_ref().unwrap().destroy();
|
|
|
|
}
|
|
|
|
|
2017-03-16 10:18:13 +00:00
|
|
|
pub fn destroy(&mut self) {
|
|
|
|
self.close_window();
|
|
|
|
self.shell.nvim().ui_detach().expect("Error in ui_detach");
|
|
|
|
}
|
|
|
|
|
2017-03-06 13:58:10 +00:00
|
|
|
pub fn init(&mut self, app: >k::Application) {
|
2017-03-15 15:33:47 +00:00
|
|
|
if self.initialized {
|
|
|
|
return;
|
2017-03-14 20:12:31 +00:00
|
|
|
}
|
|
|
|
self.initialized = true;
|
|
|
|
|
2017-03-13 15:03:32 +00:00
|
|
|
SET.with(|settings| {
|
|
|
|
let mut settings = settings.borrow_mut();
|
|
|
|
settings.init(self);
|
|
|
|
});
|
2017-03-12 19:50:03 +00:00
|
|
|
|
2017-03-07 14:12:22 +00:00
|
|
|
self.header_bar.set_show_close_button(true);
|
2016-03-17 13:58:21 +00:00
|
|
|
|
2017-03-09 10:19:44 +00:00
|
|
|
let save_image = Image::new_from_icon_name("document-save",
|
|
|
|
gtk_sys::GTK_ICON_SIZE_SMALL_TOOLBAR as i32);
|
2016-03-17 13:58:21 +00:00
|
|
|
let save_btn = ToolButton::new(Some(&save_image), None);
|
2017-03-07 14:12:22 +00:00
|
|
|
save_btn.connect_clicked(|_| edit_save_all());
|
|
|
|
self.header_bar.pack_start(&save_btn);
|
2016-03-17 13:58:21 +00:00
|
|
|
|
2017-03-09 10:19:44 +00:00
|
|
|
let paste_image = Image::new_from_icon_name("edit-paste",
|
|
|
|
gtk_sys::GTK_ICON_SIZE_SMALL_TOOLBAR as i32);
|
2017-03-07 14:12:22 +00:00
|
|
|
let paste_btn = ToolButton::new(Some(&paste_image), None);
|
|
|
|
paste_btn.connect_clicked(|_| edit_paste());
|
|
|
|
self.header_bar.pack_start(&paste_btn);
|
2016-03-17 13:58:21 +00:00
|
|
|
|
2017-03-15 15:33:47 +00:00
|
|
|
self.shell.init();
|
2016-03-16 15:25:25 +00:00
|
|
|
|
2017-03-06 13:58:10 +00:00
|
|
|
self.window = Some(ApplicationWindow::new(app));
|
|
|
|
let window = self.window.as_ref().unwrap();
|
|
|
|
|
2017-03-07 14:12:22 +00:00
|
|
|
window.set_titlebar(Some(&self.header_bar));
|
2017-03-15 15:33:47 +00:00
|
|
|
window.add(&self.shell.drawing_area);
|
2017-03-06 13:58:10 +00:00
|
|
|
window.show_all();
|
|
|
|
window.connect_delete_event(gtk_delete);
|
2017-03-06 14:13:32 +00:00
|
|
|
window.set_title("Neovim-gtk");
|
2017-03-06 21:05:48 +00:00
|
|
|
|
2017-03-15 15:33:47 +00:00
|
|
|
self.shell.add_configure_event();
|
2017-03-06 21:05:48 +00:00
|
|
|
}
|
2017-03-10 13:50:37 +00:00
|
|
|
|
2016-05-04 14:59:51 +00:00
|
|
|
}
|
|
|
|
|
2017-03-07 14:12:22 +00:00
|
|
|
fn edit_paste() {
|
2017-03-08 19:22:58 +00:00
|
|
|
UI.with(|ui_cell| {
|
2017-03-07 14:12:22 +00:00
|
|
|
let mut ui = ui_cell.borrow_mut();
|
|
|
|
|
2017-03-15 15:33:47 +00:00
|
|
|
let paste_command = if ui.shell.mode == NvimMode::Normal {
|
2017-03-08 19:22:58 +00:00
|
|
|
"\"*p"
|
|
|
|
} else {
|
2017-03-14 19:51:26 +00:00
|
|
|
"<Esc>\"*pa"
|
2017-03-08 19:22:58 +00:00
|
|
|
};
|
|
|
|
|
2017-03-15 15:33:47 +00:00
|
|
|
let mut nvim = ui.shell.nvim();
|
2017-03-09 13:18:13 +00:00
|
|
|
nvim.input(paste_command).report_err(nvim);
|
2017-03-07 14:12:22 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
fn edit_save_all() {
|
2017-03-07 10:52:01 +00:00
|
|
|
UI.with(|ui_cell| {
|
|
|
|
let mut ui = ui_cell.borrow_mut();
|
|
|
|
|
2017-03-15 15:33:47 +00:00
|
|
|
let mut nvim = ui.shell.nvim();
|
2017-03-09 13:18:13 +00:00
|
|
|
nvim.command(":wa").report_err(nvim);
|
2017-03-07 10:52:01 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-05-05 13:48:21 +00:00
|
|
|
fn quit() {
|
2016-05-04 08:52:57 +00:00
|
|
|
UI.with(|ui_cell| {
|
|
|
|
let mut ui = ui_cell.borrow_mut();
|
2017-03-06 13:58:10 +00:00
|
|
|
ui.destroy();
|
2016-05-04 08:52:57 +00:00
|
|
|
});
|
2016-05-05 13:48:21 +00:00
|
|
|
}
|
|
|
|
|
2017-03-06 13:58:10 +00:00
|
|
|
fn gtk_delete(_: &ApplicationWindow, _: &Event) -> Inhibit {
|
2016-05-05 13:48:21 +00:00
|
|
|
quit();
|
2016-05-04 08:52:57 +00:00
|
|
|
Inhibit(false)
|
|
|
|
}
|
|
|
|
|