mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-27 19:26:09 +00:00
Use special key detection for pancurses
Shared with the ncurses backend code
This commit is contained in:
parent
767e225db0
commit
99046d10c3
@ -48,7 +48,7 @@ version = "5.91.0"
|
|||||||
[dependencies.pancurses]
|
[dependencies.pancurses]
|
||||||
features = ["wide"]
|
features = ["wide"]
|
||||||
optional = true
|
optional = true
|
||||||
version = "0.13"
|
version = "0.14"
|
||||||
|
|
||||||
[dependencies.pulldown-cmark]
|
[dependencies.pulldown-cmark]
|
||||||
default-features = false
|
default-features = false
|
||||||
@ -67,7 +67,7 @@ blt-backend = ["bear-lib-terminal"]
|
|||||||
default = ["ncurses-backend"]
|
default = ["ncurses-backend"]
|
||||||
markdown = ["pulldown-cmark"]
|
markdown = ["pulldown-cmark"]
|
||||||
ncurses-backend = ["ncurses", "maplit"]
|
ncurses-backend = ["ncurses", "maplit"]
|
||||||
pancurses-backend = ["pancurses"]
|
pancurses-backend = ["pancurses", "maplit"]
|
||||||
termion-backend = ["termion", "chan", "chan-signal"]
|
termion-backend = ["termion", "chan", "chan-signal"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
use theme::{BaseColor, Color};
|
use theme::{BaseColor, Color};
|
||||||
|
use event::{Event, Key};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[cfg(feature = "ncurses")]
|
#[cfg(feature = "ncurses")]
|
||||||
mod n;
|
mod n;
|
||||||
@ -14,6 +16,51 @@ fn split_i32(code: i32) -> Vec<u8> {
|
|||||||
(0..4).map(|i| ((code >> (8 * i)) & 0xFF) as u8).collect()
|
(0..4).map(|i| ((code >> (8 * i)) & 0xFF) as u8).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fill_key_codes<F>(target: &mut HashMap<i32, Event>, f: F)
|
||||||
|
where
|
||||||
|
F: Fn(i32) -> Option<String>,
|
||||||
|
{
|
||||||
|
let key_names = hashmap!{
|
||||||
|
"DC" => Key::Del,
|
||||||
|
"DN" => Key::Down,
|
||||||
|
"END" => Key::End,
|
||||||
|
"HOM" => Key::Home,
|
||||||
|
"IC" => Key::Ins,
|
||||||
|
"LFT" => Key::Left,
|
||||||
|
"NXT" => Key::PageDown,
|
||||||
|
"PRV" => Key::PageUp,
|
||||||
|
"RIT" => Key::Right,
|
||||||
|
"UP" => Key::Up,
|
||||||
|
};
|
||||||
|
|
||||||
|
for code in 512..1024 {
|
||||||
|
let name = match f(code) {
|
||||||
|
Some(name) => name,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
if !name.starts_with('k') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (key_name, modifier) = name[1..].split_at(name.len() - 2);
|
||||||
|
let key = match key_names.get(key_name) {
|
||||||
|
Some(&key) => key,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
let event = match modifier {
|
||||||
|
"3" => Event::Alt(key),
|
||||||
|
"4" => Event::AltShift(key),
|
||||||
|
"5" => Event::Ctrl(key),
|
||||||
|
"6" => Event::CtrlShift(key),
|
||||||
|
"7" => Event::CtrlAlt(key),
|
||||||
|
_ => continue,
|
||||||
|
};
|
||||||
|
target.insert(code, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
fn find_closest(color: &Color) -> i16 {
|
fn find_closest(color: &Color) -> i16 {
|
||||||
match *color {
|
match *color {
|
||||||
Color::TerminalDefault => -1,
|
Color::TerminalDefault => -1,
|
||||||
|
@ -13,7 +13,6 @@ use vec::Vec2;
|
|||||||
|
|
||||||
pub struct Concrete {
|
pub struct Concrete {
|
||||||
current_style: Cell<ColorPair>,
|
current_style: Cell<ColorPair>,
|
||||||
|
|
||||||
pairs: RefCell<HashMap<ColorPair, i16>>,
|
pairs: RefCell<HashMap<ColorPair, i16>>,
|
||||||
|
|
||||||
key_codes: HashMap<i32, Event>,
|
key_codes: HashMap<i32, Event>,
|
||||||
@ -446,45 +445,7 @@ fn initialize_keymap() -> HashMap<i32, Event> {
|
|||||||
add_fn(313, Event::Alt, &mut map);
|
add_fn(313, Event::Alt, &mut map);
|
||||||
|
|
||||||
// Those codes actually vary between ncurses versions...
|
// Those codes actually vary between ncurses versions...
|
||||||
|
super::fill_key_codes(&mut map, ncurses::keyname);
|
||||||
let key_names = hashmap!{
|
|
||||||
"DC" => Key::Del,
|
|
||||||
"DN" => Key::Down,
|
|
||||||
"END" => Key::End,
|
|
||||||
"HOM" => Key::Home,
|
|
||||||
"IC" => Key::Ins,
|
|
||||||
"LFT" => Key::Left,
|
|
||||||
"NXT" => Key::PageDown,
|
|
||||||
"PRV" => Key::PageUp,
|
|
||||||
"RIT" => Key::Right,
|
|
||||||
"UP" => Key::Up,
|
|
||||||
};
|
|
||||||
|
|
||||||
for code in 512..1024 {
|
|
||||||
let name = match ncurses::keyname(code) {
|
|
||||||
Some(name) => name,
|
|
||||||
None => continue,
|
|
||||||
};
|
|
||||||
|
|
||||||
if !name.starts_with('k') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (key_name, modifier) = name[1..].split_at(name.len() - 2);
|
|
||||||
let key = match key_names.get(key_name) {
|
|
||||||
Some(&key) => key,
|
|
||||||
None => continue,
|
|
||||||
};
|
|
||||||
let event = match modifier {
|
|
||||||
"3" => Event::Alt(key),
|
|
||||||
"4" => Event::AltShift(key),
|
|
||||||
"5" => Event::Ctrl(key),
|
|
||||||
"6" => Event::CtrlShift(key),
|
|
||||||
"7" => Event::CtrlAlt(key),
|
|
||||||
_ => continue,
|
|
||||||
};
|
|
||||||
map.insert(code, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,17 @@ use utf8;
|
|||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
|
|
||||||
pub struct Concrete {
|
pub struct Concrete {
|
||||||
|
// Used
|
||||||
current_style: Cell<ColorPair>,
|
current_style: Cell<ColorPair>,
|
||||||
pairs: RefCell<HashMap<ColorPair, i32>>,
|
pairs: RefCell<HashMap<ColorPair, i32>>,
|
||||||
window: pancurses::Window,
|
|
||||||
|
key_codes: HashMap<i32, Event>,
|
||||||
|
|
||||||
last_mouse_button: Option<MouseButton>,
|
last_mouse_button: Option<MouseButton>,
|
||||||
event_queue: Vec<Event>,
|
event_queue: Vec<Event>,
|
||||||
|
|
||||||
|
// pancurses needs a handle to the current window.
|
||||||
|
window: pancurses::Window,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Concrete {
|
impl Concrete {
|
||||||
@ -157,6 +162,7 @@ impl backend::Backend for Concrete {
|
|||||||
window: window,
|
window: window,
|
||||||
last_mouse_button: None,
|
last_mouse_button: None,
|
||||||
event_queue: Vec::new(),
|
event_queue: Vec::new(),
|
||||||
|
key_codes: initialize_keymap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,6 +247,8 @@ impl backend::Backend for Concrete {
|
|||||||
pancurses::Input::Character(c)
|
pancurses::Input::Character(c)
|
||||||
if 32 <= (c as u32) && (c as u32) <= 255 =>
|
if 32 <= (c as u32) && (c as u32) <= 255 =>
|
||||||
{
|
{
|
||||||
|
// TODO: pancurses may start parsing the input.
|
||||||
|
// In this case, return as-is.
|
||||||
utf8::read_char(c as u8, || {
|
utf8::read_char(c as u8, || {
|
||||||
self.window.getch().and_then(|i| match i {
|
self.window.getch().and_then(|i| match i {
|
||||||
pancurses::Input::Character(c) => {
|
pancurses::Input::Character(c) => {
|
||||||
@ -265,53 +273,14 @@ impl backend::Backend for Concrete {
|
|||||||
}
|
}
|
||||||
// TODO: Some key combos are not recognized by pancurses,
|
// TODO: Some key combos are not recognized by pancurses,
|
||||||
// but are sent as Unknown. We could still parse them here.
|
// but are sent as Unknown. We could still parse them here.
|
||||||
pancurses::Input::Unknown(code) => match code {
|
pancurses::Input::Unknown(code) => self.key_codes
|
||||||
220 => Event::Ctrl(Key::Del),
|
// pancurses does some weird keycode mapping
|
||||||
|
.get(&(code + 256 + 48))
|
||||||
224 => Event::Alt(Key::Down),
|
.cloned()
|
||||||
225 => Event::AltShift(Key::Down),
|
.unwrap_or_else(|| {
|
||||||
226 => Event::Ctrl(Key::Down),
|
warn!("Unknown: {}", code);
|
||||||
227 => Event::CtrlShift(Key::Down),
|
Event::Unknown(split_i32(code))
|
||||||
|
}),
|
||||||
229 => Event::Alt(Key::End),
|
|
||||||
230 => Event::AltShift(Key::End),
|
|
||||||
231 => Event::Ctrl(Key::End),
|
|
||||||
232 => Event::CtrlShift(Key::End),
|
|
||||||
|
|
||||||
235 => Event::Alt(Key::Home),
|
|
||||||
236 => Event::AltShift(Key::Home),
|
|
||||||
237 => Event::Ctrl(Key::Home),
|
|
||||||
238 => Event::CtrlShift(Key::Home),
|
|
||||||
|
|
||||||
246 => Event::Alt(Key::Left),
|
|
||||||
247 => Event::AltShift(Key::Left),
|
|
||||||
248 => Event::Ctrl(Key::Left),
|
|
||||||
249 => Event::CtrlShift(Key::Left),
|
|
||||||
|
|
||||||
251 => Event::Alt(Key::PageDown),
|
|
||||||
252 => Event::AltShift(Key::PageDown),
|
|
||||||
253 => Event::Ctrl(Key::PageDown),
|
|
||||||
254 => Event::CtrlShift(Key::PageDown),
|
|
||||||
|
|
||||||
256 => Event::Alt(Key::PageUp),
|
|
||||||
257 => Event::AltShift(Key::PageUp),
|
|
||||||
258 => Event::Ctrl(Key::PageUp),
|
|
||||||
259 => Event::CtrlShift(Key::PageUp),
|
|
||||||
|
|
||||||
261 => Event::Alt(Key::Right),
|
|
||||||
262 => Event::AltShift(Key::Right),
|
|
||||||
263 => Event::Ctrl(Key::Right),
|
|
||||||
264 => Event::CtrlShift(Key::Right),
|
|
||||||
|
|
||||||
267 => Event::Alt(Key::Up),
|
|
||||||
268 => Event::AltShift(Key::Up),
|
|
||||||
269 => Event::Ctrl(Key::Up),
|
|
||||||
270 => Event::CtrlShift(Key::Up),
|
|
||||||
other => {
|
|
||||||
warn!("Unknown: {}", other);
|
|
||||||
Event::Unknown(split_i32(other))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// TODO: I honestly have no fucking idea what KeyCodeYes is
|
// TODO: I honestly have no fucking idea what KeyCodeYes is
|
||||||
pancurses::Input::KeyCodeYes => Event::Refresh,
|
pancurses::Input::KeyCodeYes => Event::Refresh,
|
||||||
pancurses::Input::KeyBreak => Event::Key(Key::PauseBreak),
|
pancurses::Input::KeyBreak => Event::Key(Key::PauseBreak),
|
||||||
@ -536,3 +505,12 @@ fn get_mouse_button(bare_event: mmask_t) -> MouseButton {
|
|||||||
_ => MouseButton::Other,
|
_ => MouseButton::Other,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn initialize_keymap() -> HashMap<i32, Event> {
|
||||||
|
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
|
||||||
|
super::fill_key_codes(&mut map, pancurses::keyname);
|
||||||
|
|
||||||
|
map
|
||||||
|
}
|
||||||
|
@ -68,7 +68,7 @@ extern crate enumset;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
#[cfg(feature = "ncurses")]
|
#[cfg(any(feature = "ncurses", feature = "pancurses"))]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate maplit;
|
extern crate maplit;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user