mirror of
https://github.com/lotabout/skim.git
synced 2026-09-10 07:16:23 -04:00
[options] custom keymap: support binding keys
This commit is contained in:
parent
e8c7366811
commit
eae4dd6e2e
|
|
@ -6,3 +6,4 @@ authors = ["Mark Wallace <lotabout@gmail.com>"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "*"
|
libc = "*"
|
||||||
ncurses = "*"
|
ncurses = "*"
|
||||||
|
getopts = "0.2"
|
||||||
|
|
|
||||||
41
src/event.rs
41
src/event.rs
|
|
@ -54,3 +54,44 @@ pub enum Event {
|
||||||
EvActUp,
|
EvActUp,
|
||||||
EvActYank,
|
EvActYank,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_action(action: &str) -> Option<Event> {
|
||||||
|
match action {
|
||||||
|
"abort" => Some(Event::EvActAbort),
|
||||||
|
"accept" => Some(Event::EvActAccept),
|
||||||
|
"backward-char" => Some(Event::EvActBackwardChar),
|
||||||
|
"backward-delete-char" => Some(Event::EvActBackwardDeleteChar),
|
||||||
|
"backward-kill-word" => Some(Event::EvActBackwardKillWord),
|
||||||
|
"backward-word" => Some(Event::EvActBackwardWord),
|
||||||
|
"beginning-of-line" => Some(Event::EvActBeginningOfLine),
|
||||||
|
"cancel" => Some(Event::EvActCancel),
|
||||||
|
"clear-screen" => Some(Event::EvActClearScreen),
|
||||||
|
"delete-char" => Some(Event::EvActDeleteChar),
|
||||||
|
"delete-charEOF" => Some(Event::EvActDeleteCharEOF),
|
||||||
|
"deselect-all" => Some(Event::EvActDeselectAll),
|
||||||
|
"down" => Some(Event::EvActDown),
|
||||||
|
"end-of-line" => Some(Event::EvActEndOfLine),
|
||||||
|
"forward-char" => Some(Event::EvActForwardChar),
|
||||||
|
"forward-word" => Some(Event::EvActForwardWord),
|
||||||
|
"ignore" => Some(Event::EvActIgnore),
|
||||||
|
"kill-line" => Some(Event::EvActKillLine),
|
||||||
|
"kill-word" => Some(Event::EvActKillWord),
|
||||||
|
"next-history" => Some(Event::EvActNextHistory),
|
||||||
|
"page-down" => Some(Event::EvActPageDown),
|
||||||
|
"page-up" => Some(Event::EvActPageUp),
|
||||||
|
"previous-history" => Some(Event::EvActPreviousHistory),
|
||||||
|
"select-all" => Some(Event::EvActSelectAll),
|
||||||
|
"toggle" => Some(Event::EvActToggle),
|
||||||
|
"toggle-all" => Some(Event::EvActToggleAll),
|
||||||
|
"toggle-down" => Some(Event::EvActToggleDown),
|
||||||
|
"toggle-in" => Some(Event::EvActToggleIn),
|
||||||
|
"toggle-out" => Some(Event::EvActToggleOut),
|
||||||
|
"toggle-sort" => Some(Event::EvActToggleSort),
|
||||||
|
"toggle-up" => Some(Event::EvActToggleUp),
|
||||||
|
"unix-line-discard" => Some(Event::EvActUnixLineDiscard),
|
||||||
|
"unix-word-rubout" => Some(Event::EvActUnixWordRubout),
|
||||||
|
"up" => Some(Event::EvActUp),
|
||||||
|
"yank" => Some(Event::EvActYank),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
181
src/input.rs
181
src/input.rs
|
|
@ -11,7 +11,7 @@ use std::collections::VecDeque;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use util::eventbox::EventBox;
|
use util::eventbox::EventBox;
|
||||||
use event::Event;
|
use event::{Event, parse_action};
|
||||||
|
|
||||||
use ncurses::*;
|
use ncurses::*;
|
||||||
|
|
||||||
|
|
@ -52,6 +52,33 @@ impl Input {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bind(&mut self, key: &str, action: &str) {
|
||||||
|
let key = parse_key(key);
|
||||||
|
let action = parse_action(action);
|
||||||
|
if key == None || action == None {return;}
|
||||||
|
|
||||||
|
let key = key.unwrap();
|
||||||
|
let act = action.unwrap();
|
||||||
|
|
||||||
|
// remove the key for existing keymap;
|
||||||
|
let _ = self.keymap.remove(&key);
|
||||||
|
self.keymap.entry(key).or_insert(act);
|
||||||
|
}
|
||||||
|
|
||||||
|
// keymap is comma separated: 'ctrl-j:accept,ctrl-k:kill-line'
|
||||||
|
pub fn parse_keymap(&mut self, keymap: Option<String>) {
|
||||||
|
if let Some(key_action) = keymap {
|
||||||
|
for pair in key_action.split(',') {
|
||||||
|
let vec: Vec<&str> = pair.split(':').collect();
|
||||||
|
if vec.len() != 2 {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
self.bind(vec[0], vec[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct KeyBoard {
|
struct KeyBoard {
|
||||||
|
|
@ -268,32 +295,8 @@ impl KeyBoard {
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Hash, Debug)]
|
#[derive(Eq, PartialEq, Hash, Debug)]
|
||||||
pub enum Key {
|
pub enum Key {
|
||||||
CtrlA,
|
CtrlA, CtrlB, CtrlC, CtrlD, CtrlE, CtrlF, CtrlG, CtrlH, Tab, CtrlJ, CtrlK, CtrlL, Enter,
|
||||||
CtrlB,
|
CtrlN, CtrlO, CtrlP, CtrlQ, CtrlR, CtrlS, CtrlT, CtrlU, CtrlV, CtrlW, CtrlX, CtrlY, CtrlZ,
|
||||||
CtrlC,
|
|
||||||
CtrlD,
|
|
||||||
CtrlE,
|
|
||||||
CtrlF,
|
|
||||||
CtrlG,
|
|
||||||
CtrlH,
|
|
||||||
Tab,
|
|
||||||
CtrlJ,
|
|
||||||
CtrlK,
|
|
||||||
CtrlL,
|
|
||||||
Enter,
|
|
||||||
CtrlN,
|
|
||||||
CtrlO,
|
|
||||||
CtrlP,
|
|
||||||
CtrlQ,
|
|
||||||
CtrlR,
|
|
||||||
CtrlS,
|
|
||||||
CtrlT,
|
|
||||||
CtrlU,
|
|
||||||
CtrlV,
|
|
||||||
CtrlW,
|
|
||||||
CtrlX,
|
|
||||||
CtrlY,
|
|
||||||
CtrlZ,
|
|
||||||
ESC,
|
ESC,
|
||||||
|
|
||||||
Mouse,
|
Mouse,
|
||||||
|
|
@ -314,35 +317,106 @@ pub enum Key {
|
||||||
AltSpace,
|
AltSpace,
|
||||||
AltSlash,
|
AltSlash,
|
||||||
AltBS,
|
AltBS,
|
||||||
AltA,
|
|
||||||
AltB,
|
AltA, AltB, AltC, AltD, AltE, AltF, AltG, AltH, AltI, AltJ, AltK, AltL, AltM,
|
||||||
AltC,
|
AltN, AltO, AltP, AltQ, AltR, AltS, AltT, AltU, AltV, AltW, AltX, AltY, AltZ,
|
||||||
AltD,
|
|
||||||
AltE,
|
|
||||||
AltF,
|
|
||||||
AltG,
|
|
||||||
AltH,
|
|
||||||
AltI,
|
|
||||||
AltJ,
|
|
||||||
AltK,
|
|
||||||
AltL,
|
|
||||||
AltM,
|
|
||||||
AltN,
|
|
||||||
AltO,
|
|
||||||
AltP,
|
|
||||||
AltQ,
|
|
||||||
AltR,
|
|
||||||
AltS,
|
|
||||||
AltT,
|
|
||||||
AltU,
|
|
||||||
AltV,
|
|
||||||
AltW,
|
|
||||||
AltX,
|
|
||||||
AltY,
|
|
||||||
AltZ,
|
|
||||||
Char(char),
|
Char(char),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_key(key: &str) -> Option<Key> {
|
||||||
|
match key {
|
||||||
|
"ctrl-a" => Some(Key::CtrlA),
|
||||||
|
"ctrl-b" => Some(Key::CtrlB),
|
||||||
|
"ctrl-c" => Some(Key::CtrlC),
|
||||||
|
"ctrl-d" => Some(Key::CtrlD),
|
||||||
|
"ctrl-e" => Some(Key::CtrlE),
|
||||||
|
"ctrl-f" => Some(Key::CtrlF),
|
||||||
|
"ctrl-g" => Some(Key::CtrlG),
|
||||||
|
"ctrl-h" => Some(Key::CtrlH),
|
||||||
|
"tab" | "ctrl-i" => Some(Key::Tab),
|
||||||
|
"ctrl-j" => Some(Key::CtrlJ),
|
||||||
|
"ctrl-k" => Some(Key::CtrlK),
|
||||||
|
"ctrl-l" => Some(Key::CtrlL),
|
||||||
|
"enter" | "return" | "ctrl-m" => Some(Key::Enter),
|
||||||
|
"ctrl-n" => Some(Key::CtrlN),
|
||||||
|
"ctrl-o" => Some(Key::CtrlO),
|
||||||
|
"ctrl-p" => Some(Key::CtrlP),
|
||||||
|
"ctrl-q" => Some(Key::CtrlQ),
|
||||||
|
"ctrl-r" => Some(Key::CtrlR),
|
||||||
|
"ctrl-s" => Some(Key::CtrlS),
|
||||||
|
"ctrl-t" => Some(Key::CtrlT),
|
||||||
|
"ctrl-u" => Some(Key::CtrlU),
|
||||||
|
"ctrl-v" => Some(Key::CtrlV),
|
||||||
|
"ctrl-w" => Some(Key::CtrlW),
|
||||||
|
"ctrl-x" => Some(Key::CtrlX),
|
||||||
|
"ctrl-y" => Some(Key::CtrlY),
|
||||||
|
"ctrl-z" => Some(Key::CtrlZ),
|
||||||
|
|
||||||
|
"esc" => Some(Key::ESC),
|
||||||
|
"mouse" => Some(Key::Mouse),
|
||||||
|
"doubleclick" => Some(Key::DoubleClick),
|
||||||
|
"btab" | "shift-tab" => Some(Key::BTab),
|
||||||
|
"bspace" | "bs" => Some(Key::BSpace),
|
||||||
|
"del" => Some(Key::Del),
|
||||||
|
"pgup" | "page-up" => Some(Key::PgUp),
|
||||||
|
"pgdn" | "page-down" => Some(Key::PgDn),
|
||||||
|
"up" => Some(Key::Up),
|
||||||
|
"down" => Some(Key::Down),
|
||||||
|
"left" => Some(Key::Left),
|
||||||
|
"right" => Some(Key::Right),
|
||||||
|
"home" => Some(Key::Home),
|
||||||
|
"end" => Some(Key::End),
|
||||||
|
"shift-left" => Some(Key::SLeft),
|
||||||
|
"shift-right" => Some(Key::SRight),
|
||||||
|
|
||||||
|
"f1" => Some(Key::F1),
|
||||||
|
"f2" => Some(Key::F2),
|
||||||
|
"f3" => Some(Key::F3),
|
||||||
|
"f4" => Some(Key::F4),
|
||||||
|
"f5" => Some(Key::F5),
|
||||||
|
"f6" => Some(Key::F6),
|
||||||
|
"f7" => Some(Key::F7),
|
||||||
|
"f8" => Some(Key::F8),
|
||||||
|
"f9" => Some(Key::F9),
|
||||||
|
"f10" => Some(Key::F10),
|
||||||
|
"f11" => Some(Key::F11),
|
||||||
|
"f12" => Some(Key::F12),
|
||||||
|
|
||||||
|
"altenter" => Some(Key::AltEnter),
|
||||||
|
"altspace" => Some(Key::AltSpace),
|
||||||
|
"altslash" => Some(Key::AltSlash),
|
||||||
|
"alt-bs" | "alt-bspace" => Some(Key::AltBS),
|
||||||
|
|
||||||
|
"alt-a" => Some(Key::AltA),
|
||||||
|
"alt-b" => Some(Key::AltB),
|
||||||
|
"alt-c" => Some(Key::AltC),
|
||||||
|
"alt-d" => Some(Key::AltD),
|
||||||
|
"alt-e" => Some(Key::AltE),
|
||||||
|
"alt-f" => Some(Key::AltF),
|
||||||
|
"alt-g" => Some(Key::AltG),
|
||||||
|
"alt-h" => Some(Key::AltH),
|
||||||
|
"alt-i" => Some(Key::AltI),
|
||||||
|
"alt-j" => Some(Key::AltJ),
|
||||||
|
"alt-k" => Some(Key::AltK),
|
||||||
|
"alt-l" => Some(Key::AltL),
|
||||||
|
"alt-m" => Some(Key::AltM),
|
||||||
|
"alt-n" => Some(Key::AltN),
|
||||||
|
"alt-o" => Some(Key::AltO),
|
||||||
|
"alt-p" => Some(Key::AltP),
|
||||||
|
"alt-q" => Some(Key::AltQ),
|
||||||
|
"alt-r" => Some(Key::AltR),
|
||||||
|
"alt-s" => Some(Key::AltS),
|
||||||
|
"alt-t" => Some(Key::AltT),
|
||||||
|
"alt-u" => Some(Key::AltU),
|
||||||
|
"alt-v" => Some(Key::AltV),
|
||||||
|
"alt-w" => Some(Key::AltW),
|
||||||
|
"alt-x" => Some(Key::AltX),
|
||||||
|
"alt-y" => Some(Key::AltY),
|
||||||
|
"alt-z" => Some(Key::AltZ),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_default_key_map() -> HashMap<Key, Event> {
|
fn get_default_key_map() -> HashMap<Key, Event> {
|
||||||
let mut ret = HashMap::new();
|
let mut ret = HashMap::new();
|
||||||
ret.insert(Key::ESC, Event::EvActAbort);
|
ret.insert(Key::ESC, Event::EvActAbort);
|
||||||
|
|
@ -407,3 +481,4 @@ fn get_default_key_map() -> HashMap<Key, Event> {
|
||||||
ret.insert(Key::CtrlY, Event::EvActYank);
|
ret.insert(Key::CtrlY, Event::EvActYank);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
28
src/main.rs
28
src/main.rs
|
|
@ -1,6 +1,7 @@
|
||||||
#![feature(io)]
|
#![feature(io)]
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate ncurses;
|
extern crate ncurses;
|
||||||
|
extern crate getopts;
|
||||||
mod util;
|
mod util;
|
||||||
mod item;
|
mod item;
|
||||||
mod reader;
|
mod reader;
|
||||||
|
|
@ -29,9 +30,30 @@ use matcher::Matcher;
|
||||||
use model::Model;
|
use model::Model;
|
||||||
use libc::{sigemptyset, sigaddset, sigwait, pthread_sigmask};
|
use libc::{sigemptyset, sigaddset, sigwait, pthread_sigmask};
|
||||||
use curses::{ColorTheme, Curses};
|
use curses::{ColorTheme, Curses};
|
||||||
|
use getopts::Options;
|
||||||
|
use std::env;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
|
// option parsing
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
let program = args[0].clone();
|
||||||
|
|
||||||
|
let mut opts = Options::new();
|
||||||
|
opts.optopt("b", "bind", "comma seperated keybindings", "ctrl-j:accept,ctrl-k:kill-line");
|
||||||
|
opts.optflag("h", "help", "print this help menu");
|
||||||
|
|
||||||
|
let options = match opts.parse(&args[1..]) {
|
||||||
|
Ok(m) => { m }
|
||||||
|
Err(f) => { panic!(f.to_string()) }
|
||||||
|
};
|
||||||
|
|
||||||
|
// print help message
|
||||||
|
if options.opt_present("h") {
|
||||||
|
print_usage(&program, opts);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let theme = curses::ColorTheme::new();
|
let theme = curses::ColorTheme::new();
|
||||||
let mut curse = Curses::new();
|
let mut curse = Curses::new();
|
||||||
curse.init(Some(&theme), false, false);
|
curse.init(Some(&theme), false, false);
|
||||||
|
|
@ -54,6 +76,7 @@ fn main() {
|
||||||
|
|
||||||
let eb_clone_input = eb.clone();
|
let eb_clone_input = eb.clone();
|
||||||
let mut input = Input::new(eb_clone_input);
|
let mut input = Input::new(eb_clone_input);
|
||||||
|
input.parse_keymap(options.opt_str("b"));
|
||||||
|
|
||||||
// register terminal resize event, `pthread_sigmask` should be run before any thread.
|
// register terminal resize event, `pthread_sigmask` should be run before any thread.
|
||||||
let mut sigset = unsafe {mem::uninitialized()};
|
let mut sigset = unsafe {mem::uninitialized()};
|
||||||
|
|
@ -192,3 +215,8 @@ fn main() {
|
||||||
endwin();
|
endwin();
|
||||||
model.output();
|
model.output();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_usage(program: &str, opts: Options) {
|
||||||
|
let brief = format!("Usage: {} [options]", program);
|
||||||
|
print!("{}", opts.usage(&brief));
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue