Support font setup. Small improvements
This commit is contained in:
parent
fb8c55a4f0
commit
7f2e5835e4
@ -1,2 +1,8 @@
|
|||||||
# neovim-gtk
|
# neovim-gtk
|
||||||
gtk ui for neovim written in rust. Use gtk-rs bindings. Because gtk-rs bindins still in development, this gui used toy cairo font api.
|
GTK ui for neovim written in rust using gtk-rs bindings.
|
||||||
|
|
||||||
|
## Font settings
|
||||||
|
To setup font call:
|
||||||
|
```
|
||||||
|
call rpcnotify(1, 'Gui', 'Font', 'DejaVu Sans Mono 12')
|
||||||
|
```
|
||||||
|
124
src/nvim.rs
124
src/nvim.rs
@ -37,6 +37,10 @@ pub trait RedrawEvents {
|
|||||||
fn on_mouse_off(&mut self);
|
fn on_mouse_off(&mut self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait GuiApi {
|
||||||
|
fn set_font(&mut self, font_desc: &str);
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! try_str {
|
macro_rules! try_str {
|
||||||
($exp:expr) => (match $exp {
|
($exp:expr) => (match $exp {
|
||||||
Value::String(ref val) => val,
|
Value::String(ref val) => val,
|
||||||
@ -79,16 +83,18 @@ pub fn initialize(ui: &mut Ui) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn nvim_cb(method: &str, params: Vec<Value>) {
|
fn nvim_cb(method: &str, params: Vec<Value>) {
|
||||||
if method == "redraw" {
|
match method {
|
||||||
for ev in params {
|
"redraw" => {
|
||||||
if let Value::Array(ev_args) = ev {
|
safe_call(move |ui| {
|
||||||
|
for ev in ¶ms {
|
||||||
|
if let &Value::Array(ref ev_args) = ev {
|
||||||
if let Value::String(ref ev_name) = ev_args[0] {
|
if let Value::String(ref ev_name) = ev_args[0] {
|
||||||
for ref local_args in ev_args.iter().skip(1) {
|
for ref local_args in ev_args.iter().skip(1) {
|
||||||
let args = match *local_args {
|
let args = match *local_args {
|
||||||
&Value::Array(ref ar) => ar.clone(),
|
&Value::Array(ref ar) => ar.clone(),
|
||||||
_ => vec![],
|
_ => vec![],
|
||||||
};
|
};
|
||||||
call(ev_name, args);
|
call(ui, ev_name, &args)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
println!("Unsupported event {:?}", ev_args);
|
println!("Unsupported event {:?}", ev_args);
|
||||||
@ -98,43 +104,47 @@ fn nvim_cb(method: &str, params: Vec<Value>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui.on_redraw();
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"Gui" => {
|
||||||
|
if params.len() > 0 {
|
||||||
|
if let Value::String(ev_name) = params[0].clone() {
|
||||||
|
let args = params.iter().skip(1).cloned().collect();
|
||||||
safe_call(move |ui| {
|
safe_call(move |ui| {
|
||||||
|
call_gui_event(ui, &ev_name, &args)?;
|
||||||
ui.on_redraw();
|
ui.on_redraw();
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
println!("Notification {}", method);
|
println!("Unsupported event {:?}", params);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("Unsupported event {:?}", params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
println!("Notification {}({:?})", method, params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(method: &str, args: Vec<Value>) {
|
fn call_gui_event(ui: &mut Ui, method: &str, args: &Vec<Value>) -> result::Result<(), String> {
|
||||||
match method {
|
match method {
|
||||||
"cursor_goto" => {
|
"Font" => ui.set_font(try_str!(args[0])),
|
||||||
safe_call(move |ui| {
|
_ => return Err(format!("Unsupported event {}({:?})", method, args)),
|
||||||
ui.on_cursor_goto(try_uint!(args[0]), try_uint!(args[1]));
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
"put" => {
|
|
||||||
safe_call(move |ui| {
|
|
||||||
ui.on_put(try_str!(args[0]));
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
}
|
||||||
}
|
|
||||||
"clear" => {
|
fn call(ui: &mut Ui, method: &str, args: &Vec<Value>) -> result::Result<(), String> {
|
||||||
safe_call(move |ui| {
|
match method {
|
||||||
ui.on_clear();
|
"cursor_goto" => ui.on_cursor_goto(try_uint!(args[0]), try_uint!(args[1])),
|
||||||
Ok(())
|
"put" => ui.on_put(try_str!(args[0])),
|
||||||
})
|
"clear" => ui.on_clear(),
|
||||||
}
|
"resize" => ui.on_resize(try_uint!(args[0]), try_uint!(args[1])),
|
||||||
"resize" => {
|
|
||||||
safe_call(move |ui| {
|
|
||||||
ui.on_resize(try_uint!(args[0]), try_uint!(args[1]));
|
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
"highlight_set" => {
|
"highlight_set" => {
|
||||||
safe_call(move |ui| {
|
|
||||||
if let Value::Map(ref attrs) = args[0] {
|
if let Value::Map(ref attrs) = args[0] {
|
||||||
let attrs_map: HashMap<String, Value> = attrs.iter()
|
let attrs_map: HashMap<String, Value> = attrs.iter()
|
||||||
.map(|v| match v {
|
.map(|v| match v {
|
||||||
@ -146,62 +156,24 @@ fn call(method: &str, args: Vec<Value>) {
|
|||||||
} else {
|
} else {
|
||||||
panic!("Supports only map value as argument");
|
panic!("Supports only map value as argument");
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
"eol_clear" => {
|
|
||||||
safe_call(move |ui| {
|
|
||||||
ui.on_eol_clear();
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
"eol_clear" => ui.on_eol_clear(),
|
||||||
"set_scroll_region" => {
|
"set_scroll_region" => {
|
||||||
safe_call(move |ui| {
|
|
||||||
ui.on_set_scroll_region(try_uint!(args[0]),
|
ui.on_set_scroll_region(try_uint!(args[0]),
|
||||||
try_uint!(args[1]),
|
try_uint!(args[1]),
|
||||||
try_uint!(args[2]),
|
try_uint!(args[2]),
|
||||||
try_uint!(args[3]));
|
try_uint!(args[3]));
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
"scroll" => {
|
|
||||||
safe_call(move |ui| {
|
|
||||||
ui.on_scroll(try_int!(args[0]));
|
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
"update_bg" => {
|
|
||||||
safe_call(move |ui| {
|
|
||||||
ui.on_update_bg(try_int!(args[0]));
|
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
"update_fg" => {
|
|
||||||
safe_call(move |ui| {
|
|
||||||
ui.on_update_fg(try_int!(args[0]));
|
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
"mode_change" => {
|
|
||||||
safe_call(move |ui| {
|
|
||||||
ui.on_mode_change(try_str!(args[0]));
|
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
"mouse_on" => {
|
|
||||||
safe_call(move |ui| {
|
|
||||||
ui.on_mouse_on();
|
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
"mouse_off" => {
|
|
||||||
safe_call(move |ui| {
|
|
||||||
ui.on_mouse_off();
|
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
"scroll" => ui.on_scroll(try_int!(args[0])),
|
||||||
|
"update_bg" => ui.on_update_bg(try_int!(args[0])),
|
||||||
|
"update_fg" => ui.on_update_fg(try_int!(args[0])),
|
||||||
|
"mode_change" => ui.on_mode_change(try_str!(args[0])),
|
||||||
|
"mouse_on" => ui.on_mouse_on(),
|
||||||
|
"mouse_off" => ui.on_mouse_off(),
|
||||||
_ => println!("Event {}({:?})", method, args),
|
_ => println!("Event {}({:?})", method, args),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn safe_call<F>(cb: F)
|
fn safe_call<F>(cb: F)
|
||||||
|
30
src/ui.rs
30
src/ui.rs
@ -16,7 +16,7 @@ use glib;
|
|||||||
use neovim_lib::{Neovim, NeovimApi, Value, Integer};
|
use neovim_lib::{Neovim, NeovimApi, Value, Integer};
|
||||||
|
|
||||||
use ui_model::{UiModel, Attrs, Color, COLOR_BLACK, COLOR_WHITE};
|
use ui_model::{UiModel, Attrs, Color, COLOR_BLACK, COLOR_WHITE};
|
||||||
use nvim::RedrawEvents;
|
use nvim::{RedrawEvents, GuiApi};
|
||||||
|
|
||||||
use input::{convert_key, keyval_to_input_string};
|
use input::{convert_key, keyval_to_input_string};
|
||||||
|
|
||||||
@ -55,6 +55,7 @@ pub struct Ui {
|
|||||||
mode: NvimMode,
|
mode: NvimMode,
|
||||||
mouse_enabled: bool,
|
mouse_enabled: bool,
|
||||||
mouse_pressed: bool,
|
mouse_pressed: bool,
|
||||||
|
font_desc: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ui {
|
impl Ui {
|
||||||
@ -73,6 +74,7 @@ impl Ui {
|
|||||||
mode: NvimMode::Normal,
|
mode: NvimMode::Normal,
|
||||||
mouse_enabled: false,
|
mouse_enabled: false,
|
||||||
mouse_pressed: false,
|
mouse_pressed: false,
|
||||||
|
font_desc: FONT_NAME.to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +137,14 @@ impl Ui {
|
|||||||
window.set_title("Neovim-gtk");
|
window.set_title("Neovim-gtk");
|
||||||
self.drawing_area.connect_configure_event(gtk_configure_event);
|
self.drawing_area.connect_configure_event(gtk_configure_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_pango_font(&self) -> FontDescription {
|
||||||
|
FontDescription::from_string(&self.font_desc)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_font_desc(&mut self, desc: &str) {
|
||||||
|
self.font_desc = desc.to_owned();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gtk_button_press(_: &DrawingArea, ev: &EventButton) -> Inhibit {
|
fn gtk_button_press(_: &DrawingArea, ev: &EventButton) -> Inhibit {
|
||||||
@ -217,7 +227,7 @@ fn gtk_draw(_: &DrawingArea, ctx: &cairo::Context) -> Inhibit {
|
|||||||
UI.with(|ui_cell| {
|
UI.with(|ui_cell| {
|
||||||
let mut ui = ui_cell.borrow_mut();
|
let mut ui = ui_cell.borrow_mut();
|
||||||
|
|
||||||
let (width, height) = calc_char_bounds(ctx);
|
let (width, height) = calc_char_bounds(&*ui, ctx);
|
||||||
ui.line_height = Some(height as f64);
|
ui.line_height = Some(height as f64);
|
||||||
ui.char_width = Some(width as f64);
|
ui.char_width = Some(width as f64);
|
||||||
|
|
||||||
@ -260,10 +270,6 @@ fn gtk_configure_event(_: &DrawingArea, ev: &EventConfigure) -> bool {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn font_description() -> FontDescription {
|
|
||||||
FontDescription::from_string(FONT_NAME)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw(ui: &Ui, ctx: &cairo::Context) {
|
fn draw(ui: &Ui, ctx: &cairo::Context) {
|
||||||
ctx.set_source_rgb(ui.bg_color.0, ui.bg_color.1, ui.bg_color.2);
|
ctx.set_source_rgb(ui.bg_color.0, ui.bg_color.1, ui.bg_color.2);
|
||||||
ctx.paint();
|
ctx.paint();
|
||||||
@ -319,7 +325,7 @@ fn draw(ui: &Ui, ctx: &cairo::Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !cell.ch.is_whitespace() {
|
if !cell.ch.is_whitespace() {
|
||||||
let mut desc = font_description();
|
let mut desc = ui.create_pango_font();
|
||||||
if cell.attrs.italic {
|
if cell.attrs.italic {
|
||||||
desc.set_style(pango::Style::Italic);
|
desc.set_style(pango::Style::Italic);
|
||||||
}
|
}
|
||||||
@ -346,10 +352,10 @@ fn draw(ui: &Ui, ctx: &cairo::Context) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calc_char_bounds(ctx: &cairo::Context) -> (i32, i32) {
|
fn calc_char_bounds(ui: &Ui, ctx: &cairo::Context) -> (i32, i32) {
|
||||||
let layout = pc::create_layout(ctx);
|
let layout = pc::create_layout(ctx);
|
||||||
|
|
||||||
let desc = font_description();
|
let desc = ui.create_pango_font();
|
||||||
layout.set_font_description(Some(&desc));
|
layout.set_font_description(Some(&desc));
|
||||||
layout.set_text("A", -1);
|
layout.set_text("A", -1);
|
||||||
|
|
||||||
@ -375,6 +381,12 @@ fn request_width(ui: &Ui) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GuiApi for Ui {
|
||||||
|
fn set_font(&mut self, font_desc: &str) {
|
||||||
|
self.set_font_desc(font_desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl RedrawEvents for Ui {
|
impl RedrawEvents for Ui {
|
||||||
fn on_cursor_goto(&mut self, row: u64, col: u64) {
|
fn on_cursor_goto(&mut self, row: u64, col: u64) {
|
||||||
self.model.set_cursor(row, col);
|
self.model.set_cursor(row, col);
|
||||||
|
Loading…
Reference in New Issue
Block a user