+static int CYConsoleKeyTab(int count, int key) {
+ char *before(CYmemrchr(rl_line_buffer, '\n', rl_point));
+ if (before == NULL) complete:
+ return rl_complete_internal(rl_completion_mode(&CYConsoleKeyTab));
+ int start(before + 1 - rl_line_buffer);
+ for (int i(start); i != rl_point; ++i)
+ if (rl_line_buffer[i] != ' ')
+ goto complete;
+ return rl_insert(4 - (rl_point - start) % 4, ' ');
+}
+
+static void CYConsoleRemapBind(Keymap map, rl_command_func_t *from, rl_command_func_t *to) {
+ char **keyseqs(rl_invoking_keyseqs_in_map(from, map));
+ if (keyseqs == NULL)
+ return;
+ for (char **keyseq(keyseqs); *keyseq != NULL; ++keyseq) {
+ rl_bind_keyseq_in_map(*keyseq, to, map);
+ free(*keyseq);
+ }
+ free(keyseqs);
+}
+
+static void CYConsoleRemapKeys(Keymap map) {
+ CYConsoleRemapBind(map, &rl_beg_of_line, &CYConsoleLineBegin);
+ CYConsoleRemapBind(map, &rl_end_of_line, &CYConsoleLineEnd);
+
+ CYConsoleRemapBind(map, &rl_get_previous_history, &CYConsoleKeyUp);
+ CYConsoleRemapBind(map, &rl_get_next_history, &CYConsoleKeyDown);
+
+ CYConsoleRemapBind(map, &rl_rubout, &CYConsoleKeyBack);
+ CYConsoleRemapBind(map, &rl_complete, &CYConsoleKeyTab);
+}
+
+static void CYConsolePrepTerm(int meta) {
+ rl_prep_terminal(meta);
+
+ CYConsoleRemapKeys(emacs_standard_keymap);
+ CYConsoleRemapKeys(emacs_meta_keymap);
+ CYConsoleRemapKeys(emacs_ctlx_keymap);
+ CYConsoleRemapKeys(vi_insertion_keymap);
+ CYConsoleRemapKeys(vi_movement_keymap);
+}
+