nvim_gtk/
input.rs

1
2use gtk::prelude::*;
3use gdk;
4use gdk::EventKey;
5use phf;
6use neovim_lib::{Neovim, NeovimApi};
7
8include!(concat!(env!("OUT_DIR"), "/key_map_table.rs"));
9
10
11pub fn keyval_to_input_string(in_str: &str, in_state: gdk::ModifierType) -> String {
12    let mut val = in_str;
13    let mut state = in_state;
14    let mut input = String::new();
15
16    debug!("keyval -> {}", in_str);
17
18    // CTRL-^ and CTRL-@ don't work in the normal way.
19    if state.contains(gdk::ModifierType::CONTROL_MASK) && !state.contains(gdk::ModifierType::SHIFT_MASK) &&
20        !state.contains(gdk::ModifierType::MOD1_MASK)
21    {
22        if val == "6" {
23            val = "^";
24        } else if val == "2" {
25            val = "@";
26        }
27    }
28
29    let chars: Vec<char> = in_str.chars().collect();
30
31    if chars.len() == 1 {
32        let ch = chars[0];
33
34        // Remove SHIFT
35        if ch.is_ascii() && !ch.is_alphanumeric() {
36            state.remove(gdk::ModifierType::SHIFT_MASK);
37        }
38    }
39
40    if val == "<" {
41        val = "lt";
42    }
43
44    if state.contains(gdk::ModifierType::SHIFT_MASK) {
45        input.push_str("S-");
46    }
47    if state.contains(gdk::ModifierType::CONTROL_MASK) {
48        input.push_str("C-");
49    }
50    if state.contains(gdk::ModifierType::MOD1_MASK) {
51        input.push_str("A-");
52    }
53
54    input.push_str(val);
55
56    if input.chars().count() > 1 {
57        format!("<{}>", input)
58    } else {
59        input
60    }
61}
62
63pub fn convert_key(ev: &EventKey) -> Option<String> {
64    let keyval = ev.get_keyval();
65    let state = ev.get_state();
66    if let Some(ref keyval_name) = gdk::keyval_name(keyval) {
67        if let Some(cnvt) = KEYVAL_MAP.get(keyval_name as &str).cloned() {
68            return Some(keyval_to_input_string(cnvt, state));
69        }
70    }
71
72    if let Some(ch) = gdk::keyval_to_unicode(keyval) {
73        Some(keyval_to_input_string(&ch.to_string(), state))
74    } else {
75        None
76    }
77}
78
79pub fn im_input(nvim: &mut Neovim, input: &str) {
80    debug!("nvim_input -> {}", input);
81
82    let input: String = input
83        .chars()
84        .map(|ch| {
85            keyval_to_input_string(&ch.to_string(), gdk::ModifierType::empty())
86        })
87        .collect();
88    nvim.input(&input).expect("Error run input command to nvim");
89}
90
91pub fn gtk_key_press(nvim: &mut Neovim, ev: &EventKey) -> Inhibit {
92    if let Some(input) = convert_key(ev) {
93        debug!("nvim_input -> {}", input);
94        nvim.input(&input).expect("Error run input command to nvim");
95        Inhibit(true)
96    } else {
97        Inhibit(false)
98    }
99}