2016-04-04 10:14:57 +00:00
|
|
|
|
2017-04-19 08:40:53 +00:00
|
|
|
use gtk::prelude::*;
|
2016-04-04 10:14:57 +00:00
|
|
|
use gdk;
|
|
|
|
use gdk::EventKey;
|
|
|
|
use phf;
|
2017-04-19 08:40:53 +00:00
|
|
|
use neovim_lib::{Neovim, NeovimApi};
|
2016-04-04 10:14:57 +00:00
|
|
|
|
2017-04-02 19:09:03 +00:00
|
|
|
use std::ascii::AsciiExt;
|
|
|
|
|
2016-04-04 10:14:57 +00:00
|
|
|
include!(concat!(env!("OUT_DIR"), "/key_map_table.rs"));
|
|
|
|
|
|
|
|
|
2017-04-02 19:09:03 +00:00
|
|
|
pub fn keyval_to_input_string(in_str: &str, in_state: gdk::ModifierType) -> String {
|
2017-03-31 21:12:00 +00:00
|
|
|
let mut val = in_str;
|
2017-04-02 19:09:03 +00:00
|
|
|
let mut state = in_state;
|
2017-02-26 19:31:13 +00:00
|
|
|
let mut input = String::new();
|
|
|
|
|
2017-04-03 11:17:06 +00:00
|
|
|
debug!("keyval -> {}", in_str);
|
|
|
|
|
2017-03-31 21:12:00 +00:00
|
|
|
// CTRL-^ and CTRL-@ don't work in the normal way.
|
|
|
|
if state.contains(gdk::CONTROL_MASK) && !state.contains(gdk::SHIFT_MASK) &&
|
|
|
|
!state.contains(gdk::MOD1_MASK) {
|
|
|
|
if val == "6" {
|
|
|
|
val = "^";
|
|
|
|
} else if val == "2" {
|
|
|
|
val = "@";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-02 19:09:03 +00:00
|
|
|
let chars: Vec<char> = in_str.chars().collect();
|
|
|
|
|
|
|
|
if chars.len() == 1 {
|
|
|
|
let ch = chars[0];
|
|
|
|
|
|
|
|
// Remove SHIFT
|
|
|
|
if ch.is_ascii() && !ch.is_alphanumeric() {
|
|
|
|
state.remove(gdk::SHIFT_MASK);
|
2017-03-07 14:12:22 +00:00
|
|
|
}
|
2016-04-04 10:14:57 +00:00
|
|
|
}
|
2017-04-02 19:09:03 +00:00
|
|
|
|
|
|
|
if val == "<" {
|
|
|
|
val = "lt";
|
|
|
|
}
|
|
|
|
|
|
|
|
if state.contains(gdk::SHIFT_MASK) {
|
|
|
|
input.push_str("S-");
|
|
|
|
}
|
2016-06-23 14:32:30 +00:00
|
|
|
if state.contains(gdk::CONTROL_MASK) {
|
2016-04-04 10:14:57 +00:00
|
|
|
input.push_str("C-");
|
|
|
|
}
|
2016-06-23 14:32:30 +00:00
|
|
|
if state.contains(gdk::MOD1_MASK) {
|
2016-04-04 10:14:57 +00:00
|
|
|
input.push_str("A-");
|
|
|
|
}
|
2017-02-26 19:31:13 +00:00
|
|
|
|
2016-04-04 10:14:57 +00:00
|
|
|
input.push_str(val);
|
2017-02-26 19:31:13 +00:00
|
|
|
|
2017-03-12 15:11:43 +00:00
|
|
|
if input.chars().count() > 1 {
|
2017-02-26 19:31:13 +00:00
|
|
|
format!("<{}>", input)
|
|
|
|
} else {
|
|
|
|
input
|
|
|
|
}
|
2016-04-04 10:14:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn convert_key(ev: &EventKey) -> Option<String> {
|
|
|
|
let keyval = ev.get_keyval();
|
|
|
|
let state = ev.get_state();
|
|
|
|
if let Some(ref keyval_name) = gdk::keyval_name(keyval) {
|
|
|
|
if let Some(cnvt) = KEYVAL_MAP.get(keyval_name as &str).cloned() {
|
|
|
|
return Some(keyval_to_input_string(cnvt, state));
|
|
|
|
}
|
|
|
|
}
|
2016-05-03 10:34:36 +00:00
|
|
|
|
2016-04-04 10:14:57 +00:00
|
|
|
if let Some(ch) = gdk::keyval_to_unicode(keyval) {
|
2017-04-03 12:54:36 +00:00
|
|
|
Some(keyval_to_input_string(&ch.to_string(), state))
|
2016-05-03 10:34:36 +00:00
|
|
|
} else {
|
|
|
|
None
|
2016-04-04 10:14:57 +00:00
|
|
|
}
|
|
|
|
}
|
2017-04-19 08:40:53 +00:00
|
|
|
|
2017-06-02 14:54:24 +00:00
|
|
|
pub fn im_input(nvim: &mut Neovim, input: &str) {
|
|
|
|
debug!("nvim_input -> {}", input);
|
2017-09-11 15:31:15 +00:00
|
|
|
nvim.input(input).expect("Error run input command to nvim");
|
2017-06-02 14:54:24 +00:00
|
|
|
}
|
|
|
|
|
2017-04-19 08:40:53 +00:00
|
|
|
pub fn gtk_key_press(nvim: &mut Neovim, ev: &EventKey) -> Inhibit {
|
|
|
|
if let Some(input) = convert_key(ev) {
|
|
|
|
debug!("nvim_input -> {}", input);
|
2017-06-02 14:54:24 +00:00
|
|
|
nvim.input(&input).expect("Error run input command to nvim");
|
2017-04-19 08:40:53 +00:00
|
|
|
Inhibit(true)
|
|
|
|
} else {
|
|
|
|
Inhibit(false)
|
|
|
|
}
|
|
|
|
}
|