@@ -91,7 +91,7 @@ use std::collections::HashMap;
9191pub use crossterm::event::{KeyCode, KeyEvent as Key, KeyModifiers as Modifiers};
9292
9393// TODO: could be trie based
94−pub type Keymap = HashMap<Vec<Key>, Command>;
94+pub type Keymap = HashMap<Key, Command>;
9595pub type Keymaps = HashMap<Mode, Keymap>;
9696
9797macro_rules! key {
@@ -131,125 +131,180 @@ macro_rules! alt {
131131}
132132
133133pub fn default() -> Keymaps {
134+ let normal = hashmap!(
135+ key!('h') => commands::move_char_left as Command,
136+ key!('j') => commands::move_line_down,
137+ key!('k') => commands::move_line_up,
138+ key!('l') => commands::move_char_right,
139+
140+ // key!('t') => commands::till_next_char,
141+ // key!('f') => commands::find_next_char,
142+ // key!('T') => commands::till_prev_char,
143+ // key!('f') => commands::find_prev_char,
144+ // and matching set for select mode (extend)
145+
146+ key!('0') => commands::move_line_start,
147+ key!('$') => commands::move_line_end,
148+
149+ key!('w') => commands::move_next_word_start,
150+ key!('b') => commands::move_prev_word_start,
151+ key!('e') => commands::move_next_word_end,
152+
153+ key!('v') => commands::select_mode,
154+ key!('g') => commands::goto_mode,
155+ key!(':') => commands::command_mode,
156+
157+ key!('i') => commands::insert_mode,
158+ shift!('I') => commands::prepend_to_line,
159+ key!('a') => commands::append_mode,
160+ shift!('A') => commands::append_to_line,
161+ key!('o') => commands::open_below,
162+ // key!('O') => commands::open_above,
163+ // [<space> ]<space> equivalents too (add blank new line, no edit)
164+
165+
166+ key!('d') => commands::delete_selection,
167+ // TODO: also delete without yanking
168+ key!('c') => commands::change_selection,
169+ // TODO: also change delete without yanking
170+
171+ // key!('r') => commands::replace_with_char,
172+
173+ key!('s') => commands::select_regex,
174+ alt!('s') => commands::split_selection_on_newline,
175+ shift!('S') => commands::split_selection,
176+ key!(';') => commands::collapse_selection,
177+ alt!(';') => commands::flip_selections,
178+ key!('%') => commands::select_all,
179+ key!('x') => commands::select_line,
180+ // key!('X') => commands::extend_line,
181+ // or select mode X?
182+ // extend_to_whole_line, crop_to_whole_line
183+
184+ // key!('m') => commands::select_to_matching,
185+ // key!('M') => commands::back_select_to_matching,
186+ // select mode extend equivalents
187+
188+ // key!('.') => commands::repeat_insert,
189+ // repeat_select
190+
191+ // TODO: figure out what key to use
192+ key!('[') => commands::expand_selection,
193+
194+ key!('/') => commands::search,
195+ key!('n') => commands::search_next,
196+ key!('*') => commands::search_selection,
197+
198+ key!('u') => commands::undo,
199+ shift!('U') => commands::redo,
200+
201+ key!('y') => commands::yank,
202+ // yank_all
203+ key!('p') => commands::paste,
204+ // paste_all
205+
206+ key!('>') => commands::indent,
207+ key!('<') => commands::unindent,
208+ key!('=') => commands::format_selections,
209+ shift!('J') => commands::join_selections,
210+ shift!('K') => commands::keep_selections,
211+
212+ // key!('q') => commands::record_macro,
213+ // key!('Q') => commands::replay_macro,
214+
215+ // ~ / apostrophe => change case
216+ // & align selections
217+ // _ trim selections
218+
219+ // C / altC = copy (repeat) selections on prev/next lines
220+
221+ Key {
222+ code: KeyCode::Esc,
223+ modifiers: Modifiers::NONE
224+ } => commands::normal_mode,
225+ Key {
226+ code: KeyCode::PageUp,
227+ modifiers: Modifiers::NONE
228+ } => commands::page_up,
229+ Key {
230+ code: KeyCode::PageDown,
231+ modifiers: Modifiers::NONE
232+ } => commands::page_down,
233+ ctrl!('u') => commands::half_page_up,
234+ ctrl!('d') => commands::half_page_down,
235+
236+ ctrl!('p') => commands::file_picker,
237+ ctrl!('b') => commands::buffer_picker,
238+ Key {
239+ code: KeyCode::Tab,
240+ modifiers: Modifiers::NONE
241+ } => commands::next_view,
242+
243+ // move under <space>c
244+ ctrl!('c') => commands::toggle_comments,
245+ ctrl!('K') => commands::hover,
246+
247+ // z family for save/restore/combine from/to sels from register
248+ );
249+ // TODO: decide whether we want normal mode to also be select mode (kakoune-like), or whether
250+ // we keep this separate select mode. More keys can fit into normal mode then, but it's weird
251+ // because some selection operations can now be done from normal mode, some from select mode.
252+ let mut select = normal.clone();
253+ select.extend(
254+ hashmap!(
255+ key!('h') => commands::extend_char_left as Command,
256+ key!('j') => commands::extend_line_down,
257+ key!('k') => commands::extend_line_up,
258+ key!('l') => commands::extend_char_right,
259+
260+ key!('w') => commands::extend_next_word_start,
261+ key!('b') => commands::extend_prev_word_start,
262+ key!('e') => commands::extend_next_word_end,
263+
264+ Key {
265+ code: KeyCode::Esc,
266+ modifiers: Modifiers::NONE
267+ } => commands::exit_select_mode as Command,
268+ )
269+ .into_iter(),
270+ );
271+
134272 hashmap!(
135− Mode::Normal =>
136− // as long as you cast the first item, rust is able to infer the other cases
137− hashmap!(
138− vec![key!('h')] => commands::move_char_left as Command,
139− vec![key!('j')] => commands::move_line_down,
140− vec![key!('k')] => commands::move_line_up,
141− vec![key!('l')] => commands::move_char_right,
142−
143− vec![key!('0')] => commands::move_line_start,
144− vec![key!('$')] => commands::move_line_end,
145−
146− vec![shift!('H')] => commands::extend_char_left,
147− vec![shift!('J')] => commands::extend_line_down,
148− vec![shift!('K')] => commands::extend_line_up,
149− vec![shift!('L')] => commands::extend_char_right,
150−
151− vec![key!('w')] => commands::move_next_word_start,
152− vec![shift!('W')] => commands::extend_next_word_start,
153− vec![key!('b')] => commands::move_prev_word_start,
154− vec![shift!('B')] => commands::extend_prev_word_start,
155− vec![key!('e')] => commands::move_next_word_end,
156− vec![key!('E')] => commands::extend_next_word_end,
157−
158− vec![key!('g')] => commands::goto_mode,
159− vec![key!(':')] => commands::command_mode,
160−
161− vec![key!('i')] => commands::insert_mode,
162− vec![shift!('I')] => commands::prepend_to_line,
163− vec![key!('a')] => commands::append_mode,
164− vec![shift!('A')] => commands::append_to_line,
165− vec![key!('o')] => commands::open_below,
166−
167− vec![key!('d')] => commands::delete_selection,
168− vec![key!('c')] => commands::change_selection,
169−
170− vec![key!('s')] => commands::select_regex,
171− vec![alt!('s')] => commands::split_selection_on_newline,
172− vec![shift!('S')] => commands::split_selection,
173− vec![key!(';')] => commands::collapse_selection,
174− vec![alt!(';')] => commands::flip_selections,
175− vec![key!('%')] => commands::select_all,
176− vec![key!('x')] => commands::select_line,
177−
178− // TODO: figure out what key to use
179− vec![key!('[')] => commands::expand_selection,
180−
181− vec![key!('/')] => commands::search,
182− vec![key!('n')] => commands::search_next,
183− vec![key!('*')] => commands::search_selection,
184−
185− vec![key!('u')] => commands::undo,
186− vec![shift!('U')] => commands::redo,
187−
188− vec![key!('y')] => commands::yank,
189− vec![key!('p')] => commands::paste,
190−
191− vec![key!('>')] => commands::indent,
192− vec![key!('<')] => commands::unindent,
193− vec![key!('=')] => commands::format_selections,
194− vec![ctrl!('j')] => commands::join_selections,
195− vec![Key {
196− code: KeyCode::Esc,
197− modifiers: Modifiers::NONE
198− }] => commands::normal_mode,
199− vec![Key {
200− code: KeyCode::PageUp,
201− modifiers: Modifiers::NONE
202− }] => commands::page_up,
203− vec![Key {
204− code: KeyCode::PageDown,
205− modifiers: Modifiers::NONE
206− }] => commands::page_down,
207− vec![ctrl!('u')] => commands::half_page_up,
208− vec![ctrl!('d')] => commands::half_page_down,
209−
210− vec![ctrl!('p')] => commands::file_picker,
211− vec![ctrl!('b')] => commands::buffer_picker,
212− vec![Key {
213− code: KeyCode::Tab,
214− modifiers: Modifiers::NONE
215− }] => commands::next_view,
216−
217− // move under <space>c
218− vec![ctrl!('c')] => commands::toggle_comments,
219− // was K, figure out a key
220− vec![ctrl!('k')] => commands::hover,
221− ),
222− Mode::Insert => hashmap!(
223− vec![Key {
224− code: KeyCode::Esc,
225− modifiers: Modifiers::NONE
226− }] => commands::normal_mode as Command,
227− vec![Key {
228− code: KeyCode::Backspace,
229− modifiers: Modifiers::NONE
230− }] => commands::insert::delete_char_backward,
231− vec![Key {
232− code: KeyCode::Delete,
233− modifiers: Modifiers::NONE
234− }] => commands::insert::delete_char_forward,
235− vec![Key {
236− code: KeyCode::Enter,
237− modifiers: Modifiers::NONE
238− }] => commands::insert::insert_newline,
239− vec![Key {
240− code: KeyCode::Tab,
241− modifiers: Modifiers::NONE
242− }] => commands::insert::insert_tab,
243−
244− vec![ctrl!('x')] => commands::completion,
245− ),
246− Mode::Goto => hashmap!(
247− vec![Key {
248− code: KeyCode::Esc,
249− modifiers: Modifiers::NONE
250− }] => commands::normal_mode as Command,
251− vec![key!('g')] => commands::move_file_start as Command,
252− vec![key!('e')] => commands::move_file_end as Command,
253− ),
273+ // as long as you cast the first item, rust is able to infer the other cases
274+ // TODO: select could be normal mode with some bindings merged over
275+ Mode::Normal => normal,
276+ Mode::Select => select,
277+ Mode::Insert => hashmap!(
278+ Key {
279+ code: KeyCode::Esc,
280+ modifiers: Modifiers::NONE
281+ } => commands::normal_mode as Command,
282+ Key {
283+ code: KeyCode::Backspace,
284+ modifiers: Modifiers::NONE
285+ } => commands::insert::delete_char_backward,
286+ Key {
287+ code: KeyCode::Delete,
288+ modifiers: Modifiers::NONE
289+ } => commands::insert::delete_char_forward,
290+ Key {
291+ code: KeyCode::Enter,
292+ modifiers: Modifiers::NONE
293+ } => commands::insert::insert_newline,
294+ Key {
295+ code: KeyCode::Tab,
296+ modifiers: Modifiers::NONE
297+ } => commands::insert::insert_tab,
298+
299+ ctrl!('x') => commands::completion,
300+ ),
301+ Mode::Goto => hashmap!(
302+ Key {
303+ code: KeyCode::Esc,
304+ modifiers: Modifiers::NONE
305+ } => commands::normal_mode as Command,
306+ key!('g') => commands::move_file_start as Command,
307+ key!('e') => commands::move_file_end as Command,
308+ ),
254309 )
255310}